Version 2.1.0-dev.9.1
Cherry-pick commit 0fe448a99643e149acb2e7e32d7a30eba7dd646d to dev
Cherry-pick commit 45d070d437bb1b596516edd3717e6ee614c5f9ac to dev
Cherry-pick commit 00f27a32cf52834b3e9e1f52889b6f1c83ad338c to dev
Cherry-pick commit 523353d28017fced825581ea327509c620eed67e to dev
Cherry-pick commit db4271378f56a66528a87f2f920c678162d59a35 to dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1b5b04a..cd8adc1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+## 2.1.0-dev.9.1
+
+Cherry-pick commit 0fe448a99643e149acb2e7e32d7a30eba7dd646d to update the analysis server edit.dartfix protocol.
+
+Cherry-pick commit 45d070d437bb1b596516edd3717e6ee614c5f9ac to update linter to version 0.1.71.
+
+Cherry-pick commit 00f27a32cf52834b3e9e1f52889b6f1c83ad338c to fix usage of mixins in dart dev compiler.
+
+Cherry-pick commit 523353d28017fced825581ea327509c620eed67e to fix the ARM 32-bit build.
+
+Cherry-pick commit db4271378f56a66528a87f2f920c678162d59a35 to fix an
+issue with coverage
+
## 2.1.0-dev.9.0
## 2.1.0-dev.8.0
diff --git a/DEPS b/DEPS
index 3ded0c6..5323847 100644
--- a/DEPS
+++ b/DEPS
@@ -95,7 +95,7 @@
"intl_tag": "0.15.7",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "2.0.9",
- "linter_tag": "0.1.70",
+ "linter_tag": "0.1.71",
"logging_tag": "0.11.3+2",
"markdown_tag": "2.0.2",
"matcher_tag": "0.12.3",
diff --git a/build/.gitignore b/build/.gitignore
index 0c6f306..869cdb4 100644
--- a/build/.gitignore
+++ b/build/.gitignore
@@ -4,7 +4,5 @@
# Pulled Debian wheezy sysroots
linux/debian_jessie_arm-sysroot
linux/debian_jessie_arm64-sysroot
-linux/debian_wheezy_amd64-sysroot
linux/debian_jessie_amd64-sysroot
-linux/debian_wheezy_arm-sysroot
-linux/debian_wheezy_i386-sysroot
+linux/debian_jessie_i386-sysroot
diff --git a/build/config/linux/BUILD.gn b/build/config/linux/BUILD.gn
index 215025b..62f7524 100644
--- a/build/config/linux/BUILD.gn
+++ b/build/config/linux/BUILD.gn
@@ -18,12 +18,12 @@
],
"value") ]
- # When using the pulled wheezy sysroot with gcc, we have to specify these
+ # When using the pulled Debian sysroot with gcc, we have to specify these
# excplicitly.
- if (dart_use_wheezy_sysroot && !is_clang) {
+ if (dart_use_debian_sysroot && !is_clang) {
cflags += [
- "-I=/usr/include/c++/4.6",
- "-I=/usr/include/c++/4.6/i486-linux-gnu",
+ "-I=/usr/include/c++/4.8",
+ "-I=/usr/include/c++/4.8/i486-linux-gnu",
]
}
}
diff --git a/build/config/sysroot.gni b/build/config/sysroot.gni
index b1acdf6..a4364ac 100644
--- a/build/config/sysroot.gni
+++ b/build/config/sysroot.gni
@@ -10,25 +10,21 @@
# the target toolchain.
target_sysroot = ""
- # Whether the Debian wheezy sysroot should be used.
- dart_use_wheezy_sysroot = false
+ # Whether the Debian sysroot should be used.
+ dart_use_debian_sysroot = false
}
-if (is_linux && dart_use_wheezy_sysroot) {
+if (is_linux && dart_use_debian_sysroot) {
if (current_cpu == "x86") {
- target_sysroot = rebase_path("//build/linux/debian_wheezy_i386-sysroot", root_build_dir)
+ target_sysroot = rebase_path("//build/linux/debian_jessie_i386-sysroot", root_build_dir)
} else if (current_cpu == "x64") {
- if (is_asan || is_lsan || is_msan || is_tsan) {
- target_sysroot = rebase_path("//build/linux/debian_jessie_amd64-sysroot", root_build_dir)
- } else {
- target_sysroot = rebase_path("//build/linux/debian_wheezy_amd64-sysroot", root_build_dir)
- }
+ target_sysroot = rebase_path("//build/linux/debian_jessie_amd64-sysroot", root_build_dir)
} else if (current_cpu == "arm") {
- target_sysroot = rebase_path("//build/linux/debian_wheezy_arm-sysroot", root_build_dir)
+ target_sysroot = rebase_path("//build/linux/debian_jessie_arm-sysroot", root_build_dir)
} else if (current_cpu == "arm64") {
target_sysroot = rebase_path("//build/linux/debian_jessie_arm64-sysroot", root_build_dir)
} else {
- print("There is no Debian wheezy sysroot present for $current_cpu")
+ print("There is no Debian sysroot present for $current_cpu")
assert(false)
}
}
diff --git a/build/linux/sysroot_scripts/install-sysroot.py b/build/linux/sysroot_scripts/install-sysroot.py
index 88bdd62..4500023 100755
--- a/build/linux/sysroot_scripts/install-sysroot.py
+++ b/build/linux/sysroot_scripts/install-sysroot.py
@@ -95,16 +95,15 @@
def InstallDefaultSysrootForArch(target_arch):
if target_arch == 'amd64':
- InstallSysroot('Wheezy', 'amd64')
InstallSysroot('Jessie', 'amd64')
elif target_arch == 'arm':
- InstallSysroot('Wheezy', 'arm')
+ InstallSysroot('Jessie', 'arm')
elif target_arch == 'arm64':
InstallSysroot('Jessie', 'arm64')
elif target_arch == 'i386':
- InstallSysroot('Wheezy', 'i386')
+ InstallSysroot('Jessie', 'i386')
elif target_arch == 'mips':
- InstallSysroot('Wheezy', 'mips')
+ InstallSysroot('Jessie', 'mips')
else:
raise Error('Unknown architecture: %s' % target_arch)
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 15e83c4..5af3aa0 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -2660,6 +2660,7 @@
+
<dl><dt class="typeDefinition"><a name="type_AddContentOverlay">AddContentOverlay: object</a></dt><dd>
<p>
A directive to begin overlaying the contents of a file. The supplied
@@ -4379,9 +4380,9 @@
</dd></dl></dd><dt class="typeDefinition"><a name="type_RuntimeCompletionExpression">RuntimeCompletionExpression: object</a></dt><dd>
<p>
An expression for which we want to know its runtime type.
- In expressions like `a.b.c.where((e) => e.^)` we want to know the
- runtime type of `a.b.c` to enforce it statically at the time when we
- compute completion suggestions, and get better type for `e`.
+ In expressions like 'a.b.c.where((e) => e.^)' we want to know the
+ runtime type of 'a.b.c' to enforce it statically at the time when we
+ compute completion suggestions, and get better type for 'e'.
</p>
<dl><dt class="field"><b>offset: int</b></dt><dd>
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 9d85d08..1280460 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -173,11 +173,10 @@
const String EDIT_REQUEST_ORGANIZE_DIRECTIVES_FILE = 'file';
const String EDIT_REQUEST_SORT_MEMBERS = 'edit.sortMembers';
const String EDIT_REQUEST_SORT_MEMBERS_FILE = 'file';
-const String EDIT_RESPONSE_DARTFIX_DESCRIPTION_OF_FIXES = 'descriptionOfFixes';
-const String EDIT_RESPONSE_DARTFIX_FIXES = 'fixes';
+const String EDIT_RESPONSE_DARTFIX_EDITS = 'edits';
const String EDIT_RESPONSE_DARTFIX_HAS_ERRORS = 'hasErrors';
-const String EDIT_RESPONSE_DARTFIX_OTHER_RECOMMENDATIONS =
- 'otherRecommendations';
+const String EDIT_RESPONSE_DARTFIX_OTHER_SUGGESTIONS = 'otherSuggestions';
+const String EDIT_RESPONSE_DARTFIX_SUGGESTIONS = 'suggestions';
const String EDIT_RESPONSE_FORMAT_EDITS = 'edits';
const String EDIT_RESPONSE_FORMAT_SELECTION_LENGTH = 'selectionLength';
const String EDIT_RESPONSE_FORMAT_SELECTION_OFFSET = 'selectionOffset';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index cb7d946..3a0a480 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -5932,6 +5932,105 @@
}
/**
+ * DartFixSuggestion
+ *
+ * {
+ * "description": String
+ * "location": optional Location
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class DartFixSuggestion implements HasToJson {
+ String _description;
+
+ Location _location;
+
+ /**
+ * A human readable description of the suggested change.
+ */
+ String get description => _description;
+
+ /**
+ * A human readable description of the suggested change.
+ */
+ void set description(String value) {
+ assert(value != null);
+ this._description = value;
+ }
+
+ /**
+ * The location of the suggested change.
+ */
+ Location get location => _location;
+
+ /**
+ * The location of the suggested change.
+ */
+ void set location(Location value) {
+ this._location = value;
+ }
+
+ DartFixSuggestion(String description, {Location location}) {
+ this.description = description;
+ this.location = location;
+ }
+
+ factory DartFixSuggestion.fromJson(
+ JsonDecoder jsonDecoder, String jsonPath, Object json) {
+ if (json == null) {
+ json = {};
+ }
+ if (json is Map) {
+ String description;
+ if (json.containsKey("description")) {
+ description = jsonDecoder.decodeString(
+ jsonPath + ".description", json["description"]);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "description");
+ }
+ Location location;
+ if (json.containsKey("location")) {
+ location = new Location.fromJson(
+ jsonDecoder, jsonPath + ".location", json["location"]);
+ }
+ return new DartFixSuggestion(description, location: location);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "DartFixSuggestion", json);
+ }
+ }
+
+ @override
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> result = {};
+ result["description"] = description;
+ if (location != null) {
+ result["location"] = location.toJson();
+ }
+ return result;
+ }
+
+ @override
+ String toString() => json.encode(toJson());
+
+ @override
+ bool operator ==(other) {
+ if (other is DartFixSuggestion) {
+ return description == other.description && location == other.location;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, description.hashCode);
+ hash = JenkinsSmiHash.combine(hash, location.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+}
+
+/**
* diagnostic.getDiagnostics params
*
* Clients may not extend, implement or mix-in this class.
@@ -6268,60 +6367,60 @@
* edit.dartfix result
*
* {
- * "descriptionOfFixes": List<String>
- * "otherRecommendations": List<String>
+ * "suggestions": List<DartFixSuggestion>
+ * "otherSuggestions": List<DartFixSuggestion>
* "hasErrors": bool
- * "fixes": List<SourceFileEdit>
+ * "edits": List<SourceFileEdit>
* }
*
* Clients may not extend, implement or mix-in this class.
*/
class EditDartfixResult implements ResponseResult {
- List<String> _descriptionOfFixes;
+ List<DartFixSuggestion> _suggestions;
- List<String> _otherRecommendations;
+ List<DartFixSuggestion> _otherSuggestions;
bool _hasErrors;
- List<SourceFileEdit> _fixes;
+ List<SourceFileEdit> _edits;
/**
- * A list of human readable changes made by applying the fixes.
+ * A list of recommended changes that can be automatically made by applying
+ * the 'edits' included in this response.
*/
- List<String> get descriptionOfFixes => _descriptionOfFixes;
+ List<DartFixSuggestion> get suggestions => _suggestions;
/**
- * A list of human readable changes made by applying the fixes.
+ * A list of recommended changes that can be automatically made by applying
+ * the 'edits' included in this response.
*/
- void set descriptionOfFixes(List<String> value) {
+ void set suggestions(List<DartFixSuggestion> value) {
assert(value != null);
- this._descriptionOfFixes = value;
+ this._suggestions = value;
}
/**
- * A list of human readable recommended changes that cannot be made
- * automatically.
+ * A list of recommended changes that could not be automatically made.
*/
- List<String> get otherRecommendations => _otherRecommendations;
+ List<DartFixSuggestion> get otherSuggestions => _otherSuggestions;
/**
- * A list of human readable recommended changes that cannot be made
- * automatically.
+ * A list of recommended changes that could not be automatically made.
*/
- void set otherRecommendations(List<String> value) {
+ void set otherSuggestions(List<DartFixSuggestion> value) {
assert(value != null);
- this._otherRecommendations = value;
+ this._otherSuggestions = value;
}
/**
* True if the analyzed source contains errors that might impact the
- * correctness of the recommended fixes that can be automatically applied.
+ * correctness of the recommended changes that can be automatically applied.
*/
bool get hasErrors => _hasErrors;
/**
* True if the analyzed source contains errors that might impact the
- * correctness of the recommended fixes that can be automatically applied.
+ * correctness of the recommended changes that can be automatically applied.
*/
void set hasErrors(bool value) {
assert(value != null);
@@ -6329,27 +6428,27 @@
}
/**
- * The suggested fixes.
+ * A list of source edits to apply the recommended changes.
*/
- List<SourceFileEdit> get fixes => _fixes;
+ List<SourceFileEdit> get edits => _edits;
/**
- * The suggested fixes.
+ * A list of source edits to apply the recommended changes.
*/
- void set fixes(List<SourceFileEdit> value) {
+ void set edits(List<SourceFileEdit> value) {
assert(value != null);
- this._fixes = value;
+ this._edits = value;
}
EditDartfixResult(
- List<String> descriptionOfFixes,
- List<String> otherRecommendations,
+ List<DartFixSuggestion> suggestions,
+ List<DartFixSuggestion> otherSuggestions,
bool hasErrors,
- List<SourceFileEdit> fixes) {
- this.descriptionOfFixes = descriptionOfFixes;
- this.otherRecommendations = otherRecommendations;
+ List<SourceFileEdit> edits) {
+ this.suggestions = suggestions;
+ this.otherSuggestions = otherSuggestions;
this.hasErrors = hasErrors;
- this.fixes = fixes;
+ this.edits = edits;
}
factory EditDartfixResult.fromJson(
@@ -6358,23 +6457,25 @@
json = {};
}
if (json is Map) {
- List<String> descriptionOfFixes;
- if (json.containsKey("descriptionOfFixes")) {
- descriptionOfFixes = jsonDecoder.decodeList(
- jsonPath + ".descriptionOfFixes",
- json["descriptionOfFixes"],
- jsonDecoder.decodeString);
+ List<DartFixSuggestion> suggestions;
+ if (json.containsKey("suggestions")) {
+ suggestions = jsonDecoder.decodeList(
+ jsonPath + ".suggestions",
+ json["suggestions"],
+ (String jsonPath, Object json) =>
+ new DartFixSuggestion.fromJson(jsonDecoder, jsonPath, json));
} else {
- throw jsonDecoder.mismatch(jsonPath, "descriptionOfFixes");
+ throw jsonDecoder.mismatch(jsonPath, "suggestions");
}
- List<String> otherRecommendations;
- if (json.containsKey("otherRecommendations")) {
- otherRecommendations = jsonDecoder.decodeList(
- jsonPath + ".otherRecommendations",
- json["otherRecommendations"],
- jsonDecoder.decodeString);
+ List<DartFixSuggestion> otherSuggestions;
+ if (json.containsKey("otherSuggestions")) {
+ otherSuggestions = jsonDecoder.decodeList(
+ jsonPath + ".otherSuggestions",
+ json["otherSuggestions"],
+ (String jsonPath, Object json) =>
+ new DartFixSuggestion.fromJson(jsonDecoder, jsonPath, json));
} else {
- throw jsonDecoder.mismatch(jsonPath, "otherRecommendations");
+ throw jsonDecoder.mismatch(jsonPath, "otherSuggestions");
}
bool hasErrors;
if (json.containsKey("hasErrors")) {
@@ -6383,18 +6484,18 @@
} else {
throw jsonDecoder.mismatch(jsonPath, "hasErrors");
}
- List<SourceFileEdit> fixes;
- if (json.containsKey("fixes")) {
- fixes = jsonDecoder.decodeList(
- jsonPath + ".fixes",
- json["fixes"],
+ List<SourceFileEdit> edits;
+ if (json.containsKey("edits")) {
+ edits = jsonDecoder.decodeList(
+ jsonPath + ".edits",
+ json["edits"],
(String jsonPath, Object json) =>
new SourceFileEdit.fromJson(jsonDecoder, jsonPath, json));
} else {
- throw jsonDecoder.mismatch(jsonPath, "fixes");
+ throw jsonDecoder.mismatch(jsonPath, "edits");
}
return new EditDartfixResult(
- descriptionOfFixes, otherRecommendations, hasErrors, fixes);
+ suggestions, otherSuggestions, hasErrors, edits);
} else {
throw jsonDecoder.mismatch(jsonPath, "edit.dartfix result", json);
}
@@ -6410,11 +6511,14 @@
@override
Map<String, dynamic> toJson() {
Map<String, dynamic> result = {};
- result["descriptionOfFixes"] = descriptionOfFixes;
- result["otherRecommendations"] = otherRecommendations;
+ result["suggestions"] =
+ suggestions.map((DartFixSuggestion value) => value.toJson()).toList();
+ result["otherSuggestions"] = otherSuggestions
+ .map((DartFixSuggestion value) => value.toJson())
+ .toList();
result["hasErrors"] = hasErrors;
- result["fixes"] =
- fixes.map((SourceFileEdit value) => value.toJson()).toList();
+ result["edits"] =
+ edits.map((SourceFileEdit value) => value.toJson()).toList();
return result;
}
@@ -6429,12 +6533,12 @@
@override
bool operator ==(other) {
if (other is EditDartfixResult) {
- return listEqual(descriptionOfFixes, other.descriptionOfFixes,
- (String a, String b) => a == b) &&
- listEqual(otherRecommendations, other.otherRecommendations,
- (String a, String b) => a == b) &&
+ return listEqual(suggestions, other.suggestions,
+ (DartFixSuggestion a, DartFixSuggestion b) => a == b) &&
+ listEqual(otherSuggestions, other.otherSuggestions,
+ (DartFixSuggestion a, DartFixSuggestion b) => a == b) &&
hasErrors == other.hasErrors &&
- listEqual(fixes, other.fixes,
+ listEqual(edits, other.edits,
(SourceFileEdit a, SourceFileEdit b) => a == b);
}
return false;
@@ -6443,10 +6547,10 @@
@override
int get hashCode {
int hash = 0;
- hash = JenkinsSmiHash.combine(hash, descriptionOfFixes.hashCode);
- hash = JenkinsSmiHash.combine(hash, otherRecommendations.hashCode);
+ hash = JenkinsSmiHash.combine(hash, suggestions.hashCode);
+ hash = JenkinsSmiHash.combine(hash, otherSuggestions.hashCode);
hash = JenkinsSmiHash.combine(hash, hasErrors.hashCode);
- hash = JenkinsSmiHash.combine(hash, fixes.hashCode);
+ hash = JenkinsSmiHash.combine(hash, edits.hashCode);
return JenkinsSmiHash.finish(hash);
}
}
diff --git a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
index 3a8e344..6673fb4 100644
--- a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
@@ -23,7 +23,7 @@
import 'package:analyzer/src/lint/registry.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
- show SourceChange, SourceEdit, SourceFileEdit;
+ show Location, SourceChange, SourceEdit, SourceFileEdit;
import 'package:front_end/src/fasta/fasta_codes.dart';
import 'package:front_end/src/scanner/token.dart';
import 'package:source_span/src/span.dart';
@@ -34,14 +34,14 @@
final fixFolders = <Folder>[];
final fixFiles = <File>[];
- List<String> descriptionOfFixes;
- List<String> otherRecommendations;
+ List<DartFixSuggestion> suggestions;
+ List<DartFixSuggestion> otherSuggestions;
SourceChange sourceChange;
EditDartFix(this.server, this.request);
- void addFix(String description, SourceChange change) {
- descriptionOfFixes.add(description);
+ void addFix(String description, Location location, SourceChange change) {
+ suggestions.add(new DartFixSuggestion(description, location: location));
for (SourceFileEdit fileEdit in change.edits) {
for (SourceEdit sourceEdit in fileEdit.edits) {
sourceChange.addEdit(fileEdit.file, fileEdit.fileStamp, sourceEdit);
@@ -49,8 +49,9 @@
}
}
- void addRecommendation(String recommendation) {
- otherRecommendations.add(recommendation);
+ void addRecommendation(String description, [Location location]) {
+ otherSuggestions
+ .add(new DartFixSuggestion(description, location: location));
}
Future<Response> compute() async {
@@ -125,8 +126,8 @@
for (String rootPath in contextManager.includedPaths) {
resources.add(resourceProvider.getResource(rootPath));
}
- descriptionOfFixes = <String>[];
- otherRecommendations = <String>[];
+ suggestions = <DartFixSuggestion>[];
+ otherSuggestions = <DartFixSuggestion>[];
sourceChange = new SourceChange('dartfix');
bool hasErrors = false;
while (resources.isNotEmpty) {
@@ -186,8 +187,8 @@
await fix.applyRemainingFixes();
}
- return new EditDartfixResult(descriptionOfFixes, otherRecommendations,
- hasErrors, sourceChange.edits)
+ return new EditDartfixResult(
+ suggestions, otherSuggestions, hasErrors, sourceChange.edits)
.toResponse(request.id);
}
@@ -204,7 +205,6 @@
return false;
}
- final location = '${locationDescription(result, error.offset)}';
final dartContext = new DartFixContextImpl(
new FixContextImpl(
server.resourceProvider, result.driver, error, result.errors),
@@ -212,12 +212,13 @@
result.unit);
final processor = new FixProcessor(dartContext);
Fix fix = await processor.computeFix();
+ final location = locationFor(result, error.offset, error.length);
if (fix != null) {
- addFix('${fix.change.message} in $location', fix.change);
+ addFix(fix.change.message, location, fix.change);
} else {
// TODO(danrubel): Determine why the fix could not be applied
// and report that in the description.
- addRecommendation('Could not fix "${error.message}" in $location');
+ addRecommendation('Could not fix "${error.message}"', location);
}
return true;
}
@@ -240,29 +241,11 @@
return false;
}
- /// Return a human readable description of the specified offset and file.
- String locationDescription(AnalysisResult result, int offset) {
- // TODO(danrubel): Pass the location back to the client along with the
- // message indicating what was or was not automatically fixed
- // rather than interpreting and integrating the location into the message.
- final description = new StringBuffer();
- // Determine the relative path
- for (Folder folder in fixFolders) {
- if (folder.contains(result.path)) {
- description.write(server.resourceProvider.pathContext
- .relative(result.path, from: folder.path));
- break;
- }
- }
- if (description.isEmpty) {
- description.write(result.path);
- }
- // Determine the line and column number
- if (offset >= 0) {
- final loc = result.unit.lineInfo.getLocation(offset);
- description.write(':${loc.lineNumber}');
- }
- return description.toString();
+ Location locationFor(AnalysisResult result, int offset, int length) {
+ final locInfo = result.unit.lineInfo.getLocation(offset);
+ final location = new Location(
+ result.path, offset, length, locInfo.lineNumber, locInfo.columnNumber);
+ return location;
}
}
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart
index 81758f9..52dda1f 100644
--- a/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart
@@ -23,18 +23,18 @@
new EditDartFixAssistContext(dartFix, source, result.unit, literal));
List<Assist> assists =
await processor.computeAssist(DartAssistKind.CONVERT_TO_INT_LITERAL);
- final location = dartFix.locationDescription(result, literal.offset);
+ final location =
+ dartFix.locationFor(result, literal.offset, literal.length);
if (assists.isNotEmpty) {
for (Assist assist in assists) {
- dartFix.addFix(
- 'Replace a double literal with an int literal in $location',
- assist.change);
+ dartFix.addFix('Replace a double literal with an int literal',
+ location, assist.change);
}
} else {
// TODO(danrubel): If assists is empty, then determine why
// assist could not be performed and report that in the description.
- dartFix.addRecommendation('Could not replace'
- ' a double literal with an int literal in $location');
+ dartFix.addRecommendation(
+ 'Could not replace a double literal with an int literal', location);
}
}
}
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
index 5e2aad1..52f924a 100644
--- a/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
@@ -41,11 +41,11 @@
dartFix, elem.source, result.unit, declaration.name));
List<Assist> assists = await processor
.computeAssist(DartAssistKind.CONVERT_CLASS_TO_MIXIN);
- final location = dartFix.locationDescription(result, elem.nameOffset);
+ final location =
+ dartFix.locationFor(result, elem.nameOffset, elem.nameLength);
if (assists.isNotEmpty) {
for (Assist assist in assists) {
- dartFix.addFix(
- 'Convert ${elem.displayName} to a mixin in $location',
+ dartFix.addFix('Convert ${elem.displayName} to a mixin', location,
assist.change);
}
} else {
@@ -53,7 +53,8 @@
// assist could not be performed and report that in the description.
dartFix.addRecommendation(
'Could not convert ${elem.displayName} to a mixin'
- ' because the class contains a constructor in $location');
+ ' because the class contains a constructor',
+ location);
}
}
}
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index 3976d6c..401723d 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -1517,23 +1517,24 @@
*
* Returns
*
- * descriptionOfFixes: List<String>
+ * suggestions: List<DartFixSuggestion>
*
- * A list of human readable changes made by applying the fixes.
+ * A list of recommended changes that can be automatically made by applying
+ * the 'edits' included in this response.
*
- * otherRecommendations: List<String>
+ * otherSuggestions: List<DartFixSuggestion>
*
- * A list of human readable recommended changes that cannot be made
- * automatically.
+ * A list of recommended changes that could not be automatically made.
*
* hasErrors: bool
*
* True if the analyzed source contains errors that might impact the
- * correctness of the recommended fixes that can be automatically applied.
+ * correctness of the recommended changes that can be automatically
+ * applied.
*
- * fixes: List<SourceFileEdit>
+ * edits: List<SourceFileEdit>
*
- * The suggested fixes.
+ * A list of source edits to apply the recommended changes.
*/
Future<EditDartfixResult> sendEditDartfix(List<String> included) async {
var params = new EditDartfixParams(included).toJson();
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index db9505f..13ba921 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -298,6 +298,18 @@
}));
/**
+ * DartFixSuggestion
+ *
+ * {
+ * "description": String
+ * "location": optional Location
+ * }
+ */
+final Matcher isDartFixSuggestion = new LazyMatcher(() => new MatchesJsonObject(
+ "DartFixSuggestion", {"description": isString},
+ optionalFields: {"location": isLocation}));
+
+/**
* Element
*
* {
@@ -2131,18 +2143,18 @@
* edit.dartfix result
*
* {
- * "descriptionOfFixes": List<String>
- * "otherRecommendations": List<String>
+ * "suggestions": List<DartFixSuggestion>
+ * "otherSuggestions": List<DartFixSuggestion>
* "hasErrors": bool
- * "fixes": List<SourceFileEdit>
+ * "edits": List<SourceFileEdit>
* }
*/
final Matcher isEditDartfixResult =
new LazyMatcher(() => new MatchesJsonObject("edit.dartfix result", {
- "descriptionOfFixes": isListOf(isString),
- "otherRecommendations": isListOf(isString),
+ "suggestions": isListOf(isDartFixSuggestion),
+ "otherSuggestions": isListOf(isDartFixSuggestion),
"hasErrors": isBool,
- "fixes": isListOf(isSourceFileEdit)
+ "edits": isListOf(isSourceFileEdit)
}));
/**
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/DartFixSuggestion.java b/pkg/analysis_server/tool/spec/generated/java/types/DartFixSuggestion.java
new file mode 100644
index 0000000..7a106f8
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/DartFixSuggestion.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * for details. All rights reserved. Use of this source code is governed by a
+ * BSD-style license that can be found in the LICENSE file.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Lists;
+import com.google.dart.server.utilities.general.JsonUtilities;
+import com.google.dart.server.utilities.general.ObjectUtilities;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * A suggestion from an edit.dartfix request.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class DartFixSuggestion {
+
+ public static final DartFixSuggestion[] EMPTY_ARRAY = new DartFixSuggestion[0];
+
+ public static final List<DartFixSuggestion> EMPTY_LIST = Lists.newArrayList();
+
+ /**
+ * A human readable description of the suggested change.
+ */
+ private final String description;
+
+ /**
+ * The location of the suggested change.
+ */
+ private final Location location;
+
+ /**
+ * Constructor for {@link DartFixSuggestion}.
+ */
+ public DartFixSuggestion(String description, Location location) {
+ this.description = description;
+ this.location = location;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof DartFixSuggestion) {
+ DartFixSuggestion other = (DartFixSuggestion) obj;
+ return
+ ObjectUtilities.equals(other.description, description) &&
+ ObjectUtilities.equals(other.location, location);
+ }
+ return false;
+ }
+
+ public static DartFixSuggestion fromJson(JsonObject jsonObject) {
+ String description = jsonObject.get("description").getAsString();
+ Location location = jsonObject.get("location") == null ? null : Location.fromJson(jsonObject.get("location").getAsJsonObject());
+ return new DartFixSuggestion(description, location);
+ }
+
+ public static List<DartFixSuggestion> fromJsonArray(JsonArray jsonArray) {
+ if (jsonArray == null) {
+ return EMPTY_LIST;
+ }
+ ArrayList<DartFixSuggestion> list = new ArrayList<DartFixSuggestion>(jsonArray.size());
+ Iterator<JsonElement> iterator = jsonArray.iterator();
+ while (iterator.hasNext()) {
+ list.add(fromJson(iterator.next().getAsJsonObject()));
+ }
+ return list;
+ }
+
+ /**
+ * A human readable description of the suggested change.
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * The location of the suggested change.
+ */
+ public Location getLocation() {
+ return location;
+ }
+
+ @Override
+ public int hashCode() {
+ HashCodeBuilder builder = new HashCodeBuilder();
+ builder.append(description);
+ builder.append(location);
+ return builder.toHashCode();
+ }
+
+ public JsonObject toJson() {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("description", description);
+ if (location != null) {
+ jsonObject.add("location", location.toJson());
+ }
+ return jsonObject;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("[");
+ builder.append("description=");
+ builder.append(description + ", ");
+ builder.append("location=");
+ builder.append(location);
+ builder.append("]");
+ return builder.toString();
+ }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpression.java b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpression.java
index eb6b0f0..b2d6b70 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpression.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpression.java
@@ -24,9 +24,9 @@
import org.apache.commons.lang3.StringUtils;
/**
- * An expression for which we want to know its runtime type. In expressions like `a.b.c.where((e)
- * => e.^)` we want to know the runtime type of `a.b.c` to enforce it statically at the time
- * when we compute completion suggestions, and get better type for `e`.
+ * An expression for which we want to know its runtime type. In expressions like 'a.b.c.where((e)
+ * => e.^)' we want to know the runtime type of 'a.b.c' to enforce it statically at the time
+ * when we compute completion suggestions, and get better type for 'e'.
*
* @coverage dart.server.generated.types
*/
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 8eced61..2f66a93 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -1958,35 +1958,36 @@
</field>
</params>
<result>
- <field name="descriptionOfFixes">
+ <field name="suggestions">
<list>
- <ref>String</ref>
+ <ref>DartFixSuggestion</ref>
</list>
<p>
- A list of human readable changes made by applying the fixes.
+ A list of recommended changes that can be automatically made
+ by applying the 'edits' included in this response.
</p>
</field>
- <field name="otherRecommendations">
+ <field name="otherSuggestions">
<list>
- <ref>String</ref>
+ <ref>DartFixSuggestion</ref>
</list>
<p>
- A list of human readable recommended changes that cannot be made automatically.
+ A list of recommended changes that could not be automatically made.
</p>
</field>
<field name="hasErrors">
<ref>bool</ref>
<p>
True if the analyzed source contains errors that might impact the correctness
- of the recommended fixes that can be automatically applied.
+ of the recommended changes that can be automatically applied.
</p>
</field>
- <field name="fixes">
+ <field name="edits">
<list>
<ref>SourceFileEdit</ref>
</list>
<p>
- The suggested fixes.
+ A list of source edits to apply the recommended changes.
</p>
</field>
</result>
@@ -3313,9 +3314,9 @@
<type name="RuntimeCompletionExpression">
<p>
An expression for which we want to know its runtime type.
- In expressions like `a.b.c.where((e) => e.^)` we want to know the
- runtime type of `a.b.c` to enforce it statically at the time when we
- compute completion suggestions, and get better type for `e`.
+ In expressions like 'a.b.c.where((e) => e.^)' we want to know the
+ runtime type of 'a.b.c' to enforce it statically at the time when we
+ compute completion suggestions, and get better type for 'e'.
</p>
<object>
<field name="offset">
@@ -4232,6 +4233,25 @@
request.
</p>
</type>
+ <type name="DartFixSuggestion" experimental="true">
+ <p>
+ A suggestion from an edit.dartfix request.
+ </p>
+ <object>
+ <field name="description">
+ <ref>String</ref>
+ <p>
+ A human readable description of the suggested change.
+ </p>
+ </field>
+ <field name="location" optional="true">
+ <ref>Location</ref>
+ <p>
+ The location of the suggested change.
+ </p>
+ </field>
+ </object>
+ </type>
<type name="SearchResult">
<p>
A single result from a search request.
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
index 9d85d08..1280460 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -173,11 +173,10 @@
const String EDIT_REQUEST_ORGANIZE_DIRECTIVES_FILE = 'file';
const String EDIT_REQUEST_SORT_MEMBERS = 'edit.sortMembers';
const String EDIT_REQUEST_SORT_MEMBERS_FILE = 'file';
-const String EDIT_RESPONSE_DARTFIX_DESCRIPTION_OF_FIXES = 'descriptionOfFixes';
-const String EDIT_RESPONSE_DARTFIX_FIXES = 'fixes';
+const String EDIT_RESPONSE_DARTFIX_EDITS = 'edits';
const String EDIT_RESPONSE_DARTFIX_HAS_ERRORS = 'hasErrors';
-const String EDIT_RESPONSE_DARTFIX_OTHER_RECOMMENDATIONS =
- 'otherRecommendations';
+const String EDIT_RESPONSE_DARTFIX_OTHER_SUGGESTIONS = 'otherSuggestions';
+const String EDIT_RESPONSE_DARTFIX_SUGGESTIONS = 'suggestions';
const String EDIT_RESPONSE_FORMAT_EDITS = 'edits';
const String EDIT_RESPONSE_FORMAT_SELECTION_LENGTH = 'selectionLength';
const String EDIT_RESPONSE_FORMAT_SELECTION_OFFSET = 'selectionOffset';
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
index 2bbf169..9fabb4c 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -5932,6 +5932,105 @@
}
/**
+ * DartFixSuggestion
+ *
+ * {
+ * "description": String
+ * "location": optional Location
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class DartFixSuggestion implements HasToJson {
+ String _description;
+
+ Location _location;
+
+ /**
+ * A human readable description of the suggested change.
+ */
+ String get description => _description;
+
+ /**
+ * A human readable description of the suggested change.
+ */
+ void set description(String value) {
+ assert(value != null);
+ this._description = value;
+ }
+
+ /**
+ * The location of the suggested change.
+ */
+ Location get location => _location;
+
+ /**
+ * The location of the suggested change.
+ */
+ void set location(Location value) {
+ this._location = value;
+ }
+
+ DartFixSuggestion(String description, {Location location}) {
+ this.description = description;
+ this.location = location;
+ }
+
+ factory DartFixSuggestion.fromJson(
+ JsonDecoder jsonDecoder, String jsonPath, Object json) {
+ if (json == null) {
+ json = {};
+ }
+ if (json is Map) {
+ String description;
+ if (json.containsKey("description")) {
+ description = jsonDecoder.decodeString(
+ jsonPath + ".description", json["description"]);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "description");
+ }
+ Location location;
+ if (json.containsKey("location")) {
+ location = new Location.fromJson(
+ jsonDecoder, jsonPath + ".location", json["location"]);
+ }
+ return new DartFixSuggestion(description, location: location);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "DartFixSuggestion", json);
+ }
+ }
+
+ @override
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> result = {};
+ result["description"] = description;
+ if (location != null) {
+ result["location"] = location.toJson();
+ }
+ return result;
+ }
+
+ @override
+ String toString() => json.encode(toJson());
+
+ @override
+ bool operator ==(other) {
+ if (other is DartFixSuggestion) {
+ return description == other.description && location == other.location;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, description.hashCode);
+ hash = JenkinsSmiHash.combine(hash, location.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+}
+
+/**
* diagnostic.getDiagnostics params
*
* Clients may not extend, implement or mix-in this class.
@@ -6268,60 +6367,60 @@
* edit.dartfix result
*
* {
- * "descriptionOfFixes": List<String>
- * "otherRecommendations": List<String>
+ * "suggestions": List<DartFixSuggestion>
+ * "otherSuggestions": List<DartFixSuggestion>
* "hasErrors": bool
- * "fixes": List<SourceFileEdit>
+ * "edits": List<SourceFileEdit>
* }
*
* Clients may not extend, implement or mix-in this class.
*/
class EditDartfixResult implements ResponseResult {
- List<String> _descriptionOfFixes;
+ List<DartFixSuggestion> _suggestions;
- List<String> _otherRecommendations;
+ List<DartFixSuggestion> _otherSuggestions;
bool _hasErrors;
- List<SourceFileEdit> _fixes;
+ List<SourceFileEdit> _edits;
/**
- * A list of human readable changes made by applying the fixes.
+ * A list of recommended changes that can be automatically made by applying
+ * the 'edits' included in this response.
*/
- List<String> get descriptionOfFixes => _descriptionOfFixes;
+ List<DartFixSuggestion> get suggestions => _suggestions;
/**
- * A list of human readable changes made by applying the fixes.
+ * A list of recommended changes that can be automatically made by applying
+ * the 'edits' included in this response.
*/
- void set descriptionOfFixes(List<String> value) {
+ void set suggestions(List<DartFixSuggestion> value) {
assert(value != null);
- this._descriptionOfFixes = value;
+ this._suggestions = value;
}
/**
- * A list of human readable recommended changes that cannot be made
- * automatically.
+ * A list of recommended changes that could not be automatically made.
*/
- List<String> get otherRecommendations => _otherRecommendations;
+ List<DartFixSuggestion> get otherSuggestions => _otherSuggestions;
/**
- * A list of human readable recommended changes that cannot be made
- * automatically.
+ * A list of recommended changes that could not be automatically made.
*/
- void set otherRecommendations(List<String> value) {
+ void set otherSuggestions(List<DartFixSuggestion> value) {
assert(value != null);
- this._otherRecommendations = value;
+ this._otherSuggestions = value;
}
/**
* True if the analyzed source contains errors that might impact the
- * correctness of the recommended fixes that can be automatically applied.
+ * correctness of the recommended changes that can be automatically applied.
*/
bool get hasErrors => _hasErrors;
/**
* True if the analyzed source contains errors that might impact the
- * correctness of the recommended fixes that can be automatically applied.
+ * correctness of the recommended changes that can be automatically applied.
*/
void set hasErrors(bool value) {
assert(value != null);
@@ -6329,27 +6428,27 @@
}
/**
- * The suggested fixes.
+ * A list of source edits to apply the recommended changes.
*/
- List<SourceFileEdit> get fixes => _fixes;
+ List<SourceFileEdit> get edits => _edits;
/**
- * The suggested fixes.
+ * A list of source edits to apply the recommended changes.
*/
- void set fixes(List<SourceFileEdit> value) {
+ void set edits(List<SourceFileEdit> value) {
assert(value != null);
- this._fixes = value;
+ this._edits = value;
}
EditDartfixResult(
- List<String> descriptionOfFixes,
- List<String> otherRecommendations,
+ List<DartFixSuggestion> suggestions,
+ List<DartFixSuggestion> otherSuggestions,
bool hasErrors,
- List<SourceFileEdit> fixes) {
- this.descriptionOfFixes = descriptionOfFixes;
- this.otherRecommendations = otherRecommendations;
+ List<SourceFileEdit> edits) {
+ this.suggestions = suggestions;
+ this.otherSuggestions = otherSuggestions;
this.hasErrors = hasErrors;
- this.fixes = fixes;
+ this.edits = edits;
}
factory EditDartfixResult.fromJson(
@@ -6358,23 +6457,25 @@
json = {};
}
if (json is Map) {
- List<String> descriptionOfFixes;
- if (json.containsKey("descriptionOfFixes")) {
- descriptionOfFixes = jsonDecoder.decodeList(
- jsonPath + ".descriptionOfFixes",
- json["descriptionOfFixes"],
- jsonDecoder.decodeString);
+ List<DartFixSuggestion> suggestions;
+ if (json.containsKey("suggestions")) {
+ suggestions = jsonDecoder.decodeList(
+ jsonPath + ".suggestions",
+ json["suggestions"],
+ (String jsonPath, Object json) =>
+ new DartFixSuggestion.fromJson(jsonDecoder, jsonPath, json));
} else {
- throw jsonDecoder.mismatch(jsonPath, "descriptionOfFixes");
+ throw jsonDecoder.mismatch(jsonPath, "suggestions");
}
- List<String> otherRecommendations;
- if (json.containsKey("otherRecommendations")) {
- otherRecommendations = jsonDecoder.decodeList(
- jsonPath + ".otherRecommendations",
- json["otherRecommendations"],
- jsonDecoder.decodeString);
+ List<DartFixSuggestion> otherSuggestions;
+ if (json.containsKey("otherSuggestions")) {
+ otherSuggestions = jsonDecoder.decodeList(
+ jsonPath + ".otherSuggestions",
+ json["otherSuggestions"],
+ (String jsonPath, Object json) =>
+ new DartFixSuggestion.fromJson(jsonDecoder, jsonPath, json));
} else {
- throw jsonDecoder.mismatch(jsonPath, "otherRecommendations");
+ throw jsonDecoder.mismatch(jsonPath, "otherSuggestions");
}
bool hasErrors;
if (json.containsKey("hasErrors")) {
@@ -6383,18 +6484,18 @@
} else {
throw jsonDecoder.mismatch(jsonPath, "hasErrors");
}
- List<SourceFileEdit> fixes;
- if (json.containsKey("fixes")) {
- fixes = jsonDecoder.decodeList(
- jsonPath + ".fixes",
- json["fixes"],
+ List<SourceFileEdit> edits;
+ if (json.containsKey("edits")) {
+ edits = jsonDecoder.decodeList(
+ jsonPath + ".edits",
+ json["edits"],
(String jsonPath, Object json) =>
new SourceFileEdit.fromJson(jsonDecoder, jsonPath, json));
} else {
- throw jsonDecoder.mismatch(jsonPath, "fixes");
+ throw jsonDecoder.mismatch(jsonPath, "edits");
}
return new EditDartfixResult(
- descriptionOfFixes, otherRecommendations, hasErrors, fixes);
+ suggestions, otherSuggestions, hasErrors, edits);
} else {
throw jsonDecoder.mismatch(jsonPath, "edit.dartfix result", json);
}
@@ -6410,11 +6511,14 @@
@override
Map<String, dynamic> toJson() {
Map<String, dynamic> result = {};
- result["descriptionOfFixes"] = descriptionOfFixes;
- result["otherRecommendations"] = otherRecommendations;
+ result["suggestions"] =
+ suggestions.map((DartFixSuggestion value) => value.toJson()).toList();
+ result["otherSuggestions"] = otherSuggestions
+ .map((DartFixSuggestion value) => value.toJson())
+ .toList();
result["hasErrors"] = hasErrors;
- result["fixes"] =
- fixes.map((SourceFileEdit value) => value.toJson()).toList();
+ result["edits"] =
+ edits.map((SourceFileEdit value) => value.toJson()).toList();
return result;
}
@@ -6429,12 +6533,12 @@
@override
bool operator ==(other) {
if (other is EditDartfixResult) {
- return listEqual(descriptionOfFixes, other.descriptionOfFixes,
- (String a, String b) => a == b) &&
- listEqual(otherRecommendations, other.otherRecommendations,
- (String a, String b) => a == b) &&
+ return listEqual(suggestions, other.suggestions,
+ (DartFixSuggestion a, DartFixSuggestion b) => a == b) &&
+ listEqual(otherSuggestions, other.otherSuggestions,
+ (DartFixSuggestion a, DartFixSuggestion b) => a == b) &&
hasErrors == other.hasErrors &&
- listEqual(fixes, other.fixes,
+ listEqual(edits, other.edits,
(SourceFileEdit a, SourceFileEdit b) => a == b);
}
return false;
@@ -6443,10 +6547,10 @@
@override
int get hashCode {
int hash = 0;
- hash = JenkinsSmiHash.combine(hash, descriptionOfFixes.hashCode);
- hash = JenkinsSmiHash.combine(hash, otherRecommendations.hashCode);
+ hash = JenkinsSmiHash.combine(hash, suggestions.hashCode);
+ hash = JenkinsSmiHash.combine(hash, otherSuggestions.hashCode);
hash = JenkinsSmiHash.combine(hash, hasErrors.hashCode);
- hash = JenkinsSmiHash.combine(hash, fixes.hashCode);
+ hash = JenkinsSmiHash.combine(hash, edits.hashCode);
return JenkinsSmiHash.finish(hash);
}
}
diff --git a/pkg/dartfix/lib/src/driver.dart b/pkg/dartfix/lib/src/driver.dart
index 80b6c11..80e7a05 100644
--- a/pkg/dartfix/lib/src/driver.dart
+++ b/pkg/dartfix/lib/src/driver.dart
@@ -122,25 +122,23 @@
}
Future applyFixes(EditDartfixResult result) async {
- showDescriptions('Recommended changes', result.descriptionOfFixes);
- showDescriptions(
- 'Recommended changes that cannot not be automatically applied',
- result.otherRecommendations,
- );
- if (result.descriptionOfFixes.isEmpty) {
+ showDescriptions('Recommended changes', result.suggestions);
+ showDescriptions('Recommended changes that cannot be automatically applied',
+ result.otherSuggestions);
+ if (result.suggestions.isEmpty) {
logger.stdout('');
- logger.stdout(result.otherRecommendations.isNotEmpty
- ? 'No recommended changes that cannot be automatically applied.'
+ logger.stdout(result.otherSuggestions.isNotEmpty
+ ? 'None of the recommended changes can be automatically applied.'
: 'No recommended changes.');
return;
}
logger.stdout('');
logger.stdout(ansi.emphasized('Files to be changed:'));
- for (SourceFileEdit fileEdit in result.fixes) {
+ for (SourceFileEdit fileEdit in result.edits) {
logger.stdout(' ${_relativePath(fileEdit.file)}');
}
if (shouldApplyChanges(result)) {
- for (SourceFileEdit fileEdit in result.fixes) {
+ for (SourceFileEdit fileEdit in result.edits) {
final file = new File(fileEdit.file);
String code = await file.readAsString();
for (SourceEdit edit in fileEdit.edits) {
@@ -152,13 +150,16 @@
}
}
- void showDescriptions(String title, List<String> descriptions) {
- if (descriptions.isNotEmpty) {
+ void showDescriptions(String title, List<DartFixSuggestion> suggestions) {
+ if (suggestions.isNotEmpty) {
logger.stdout('');
logger.stdout(ansi.emphasized('$title:'));
- List<String> sorted = new List.from(descriptions)..sort();
- for (String line in sorted) {
- logger.stdout(' $line');
+ List<DartFixSuggestion> sorted = new List.from(suggestions)
+ ..sort(compareSuggestions);
+ for (DartFixSuggestion suggestion in sorted) {
+ Location loc = suggestion.location;
+ logger.stdout(' ${_toSentenceFragment(suggestion.description)}'
+ '${loc == null ? "" : " • ${loc.startLine}:${loc.startColumn}"}');
}
}
}
@@ -327,6 +328,14 @@
}
}
+ int compareSuggestions(DartFixSuggestion s1, DartFixSuggestion s2) {
+ int result = s1.description.compareTo(s2.description);
+ if (result != 0) {
+ return result;
+ }
+ return (s2.location?.offset ?? 0) - (s1.location?.offset ?? 0);
+ }
+
bool shouldFilterError(AnalysisError error) {
// Do not show TODOs or errors that will be automatically fixed.
diff --git a/pkg/dev_compiler/lib/src/analyzer/property_model.dart b/pkg/dev_compiler/lib/src/analyzer/property_model.dart
index 1691857..b7dc784 100644
--- a/pkg/dev_compiler/lib/src/analyzer/property_model.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/property_model.dart
@@ -58,22 +58,27 @@
final _extensiblePrivateClasses = HashSet<ClassElement>();
_LibraryVirtualFieldModel.build(LibraryElement library) {
- var allTypes = library.units.expand((u) => u.types).toList();
+ var allClasses = Set<ClassElement>();
+ for (var libraryPart in library.units) {
+ allClasses.addAll(libraryPart.types);
+ allClasses.addAll(libraryPart.mixins);
+ }
// The set of public types is our initial extensible type set.
// From there, visit all immediate private types in this library, and so on
// from those private types, marking them as extensible.
- var typesToVisit =
- Queue<ClassElement>.from(allTypes.where((t) => t.isPublic));
- while (typesToVisit.isNotEmpty) {
- var extensibleType = typesToVisit.removeFirst();
+ var classesToVisit =
+ Queue<ClassElement>.from(allClasses.where((t) => t.isPublic));
+ while (classesToVisit.isNotEmpty) {
+ var extensibleClass = classesToVisit.removeFirst();
// For each supertype of a public type in this library,
// if we encounter a private class, we mark it as being extended, and
// add it to our work set if this is the first time we've visited it.
- for (var type in getImmediateSuperclasses(extensibleType)) {
- if (!type.isPublic && type.library == library) {
- if (_extensiblePrivateClasses.add(type)) typesToVisit.add(type);
+ for (var superclass in getImmediateSuperclasses(extensibleClass)) {
+ if (!superclass.isPublic && superclass.library == library) {
+ if (_extensiblePrivateClasses.add(superclass))
+ classesToVisit.add(superclass);
}
}
}
@@ -88,43 +93,44 @@
}
var allFields =
- HashMap.fromIterables(allTypes, allTypes.map(getInstanceFieldMap));
+ HashMap.fromIterables(allClasses, allClasses.map(getInstanceFieldMap));
- for (var type in allTypes) {
- Set<ClassElement> supertypes = null;
+ for (var class_ in allClasses) {
+ Set<ClassElement> superclasses;
// Visit accessors in the current class, and see if they override an
// otherwise private field.
- for (var accessor in type.accessors) {
+ for (var accessor in class_.accessors) {
// For getter/setter pairs only process them once.
if (accessor.correspondingGetter != null) continue;
// Ignore abstract or static accessors.
if (accessor.isAbstract || accessor.isStatic) continue;
// Ignore public accessors in extensible classes.
if (accessor.isPublic &&
- (type.isPublic || _extensiblePrivateClasses.contains(type))) {
+ (class_.isPublic || _extensiblePrivateClasses.contains(class_))) {
continue;
}
- if (supertypes == null) {
- supertypes = Set();
- void collectSupertypes(ClassElement cls) {
- if (!supertypes.add(cls)) return;
+ if (superclasses == null) {
+ superclasses = Set();
+ void collectSuperclasses(ClassElement cls) {
+ if (!superclasses.add(cls)) return;
var s = cls.supertype?.element;
- if (s != null) collectSupertypes(s);
- cls.mixins.forEach((m) => collectSupertypes(m.element));
+ if (s != null) collectSuperclasses(s);
+ cls.mixins.forEach((m) => collectSuperclasses(m.element));
}
- collectSupertypes(type);
- supertypes.remove(type);
- supertypes.removeWhere((c) => c.library != type.library);
+ collectSuperclasses(class_);
+ superclasses.remove(class_);
+ superclasses.removeWhere((c) => c.library != library);
}
// Look in all super classes to see if we're overriding a field in our
// library, if so mark that field as overridden.
var name = accessor.variable.name;
- _overriddenPrivateFields.addAll(
- supertypes.map((c) => allFields[c][name]).where((f) => f != null));
+ _overriddenPrivateFields.addAll(superclasses
+ .map((c) => allFields[c][name])
+ .where((f) => f != null));
}
}
}
diff --git a/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart b/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
index e004f89..0921e35 100644
--- a/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
+++ b/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
@@ -186,6 +186,7 @@
library ??= visitLibraryElement(e.library);
library.addClass(class_);
+ class_.isMixinDeclaration = e.isMixin;
class_.typeParameters
.addAll(e.typeParameters.map(visitTypeParameterElement));
@@ -504,6 +505,9 @@
for (var t in u.types) {
visitClassElement(t, library);
}
+ for (var t in u.mixins) {
+ visitClassElement(t, library);
+ }
for (var t in u.functionTypeAliases) {
visitFunctionTypeAliasElement(t, library);
}
diff --git a/pkg/dev_compiler/lib/src/kernel/property_model.dart b/pkg/dev_compiler/lib/src/kernel/property_model.dart
index 4242554..df0444b 100644
--- a/pkg/dev_compiler/lib/src/kernel/property_model.dart
+++ b/pkg/dev_compiler/lib/src/kernel/property_model.dart
@@ -92,7 +92,7 @@
HashMap.fromIterables(allClasses, allClasses.map(getInstanceFieldMap));
for (var class_ in allClasses) {
- Set<Class> superclasses = null;
+ Set<Class> superclasses;
// Visit accessors in the current class, and see if they override an
// otherwise private field.
@@ -124,8 +124,7 @@
collectSupertypes(class_);
superclasses.remove(class_);
- superclasses.removeWhere(
- (s) => s.enclosingLibrary != class_.enclosingLibrary);
+ superclasses.removeWhere((s) => s.enclosingLibrary != library);
}
// Look in all super classes to see if we're overriding a field in our
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 50b44d9..0bcef13 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -112,15 +112,18 @@
}
intptr_t SourceReport::GetScriptIndex(const Script& script) {
+ ScriptTableEntry wrapper;
const String& url = String::Handle(zone(), script.url());
- ScriptTableEntry* pair = script_table_.LookupValue(&url);
+ wrapper.key = &url;
+ wrapper.script = &Script::Handle(zone(), script.raw());
+ ScriptTableEntry* pair = script_table_.LookupValue(&wrapper);
if (pair != NULL) {
return pair->index;
}
ScriptTableEntry* tmp = new ScriptTableEntry();
tmp->key = &url;
tmp->index = next_script_index_++;
- tmp->script = &Script::Handle(zone(), script.raw());
+ tmp->script = wrapper.script;
script_table_entries_.Add(tmp);
script_table_.Insert(tmp);
ASSERT(script_table_entries_.length() == next_script_index_);
@@ -139,7 +142,10 @@
ASSERT(i == index);
const String& url2 = String::Handle(zone(), script->url());
ASSERT(url2.Equals(*url));
- ScriptTableEntry* pair = script_table_.LookupValue(&url2);
+ ScriptTableEntry wrapper;
+ wrapper.key = &url2;
+ wrapper.script = &Script::Handle(zone(), script->raw());
+ ScriptTableEntry* pair = script_table_.LookupValue(&wrapper);
ASSERT(i == pair->index);
}
}
diff --git a/runtime/vm/source_report.h b/runtime/vm/source_report.h
index 8db2418..5ab147f 100644
--- a/runtime/vm/source_report.h
+++ b/runtime/vm/source_report.h
@@ -94,17 +94,17 @@
// Needed for DirectChainedHashMap.
struct ScriptTableTrait {
typedef ScriptTableEntry* Value;
- typedef const String* Key;
+ typedef const ScriptTableEntry* Key;
typedef ScriptTableEntry* Pair;
- static Key KeyOf(Pair kv) { return kv->key; }
+ static Key KeyOf(Pair kv) { return kv; }
static Value ValueOf(Pair kv) { return kv; }
- static inline intptr_t Hashcode(Key key) { return key->Hash(); }
+ static inline intptr_t Hashcode(Key key) { return key->key->Hash(); }
static inline bool IsKeyEqual(Pair kv, Key key) {
- return kv->key->Equals(*key);
+ return kv->script->raw() == key->script->raw();
}
};
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_syntax_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_syntax_test.dart
index 9bfc38f..aba4640 100644
--- a/tests/language_2/mixin_declaration/mixin_declaration_syntax_test.dart
+++ b/tests/language_2/mixin_declaration/mixin_declaration_syntax_test.dart
@@ -402,4 +402,19 @@
}
Expect.equals(CeOwithM().toString(), CwithM().toString());
+
+ {
+ // Regression test for private fields.
+ var c = PrivateFieldClass();
+ Expect.equals(42, c._foo);
+ }
+}
+
+
+mixin PrivateFieldMixin {
+ int _foo = 40;
+}
+
+class PrivateFieldClass with PrivateFieldMixin {
+ int get _foo => super._foo + 2;
}
diff --git a/tools/VERSION b/tools/VERSION
index 804d4a7..4f5aa1c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
MINOR 1
PATCH 0
PRERELEASE 9
-PRERELEASE_PATCH 0
+PRERELEASE_PATCH 1
diff --git a/tools/gn.py b/tools/gn.py
index 50740ef..9b34862 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -248,7 +248,7 @@
# Setup the user-defined sysroot.
if UseSysroot(args, gn_args):
- gn_args['dart_use_wheezy_sysroot'] = True
+ gn_args['dart_use_debian_sysroot'] = True
else:
sysroot = TargetSysroot(args)
if sysroot:
diff --git a/tools/set_ia32_sysroot.sh b/tools/set_ia32_sysroot.sh
index c7156ce..1944330 100755
--- a/tools/set_ia32_sysroot.sh
+++ b/tools/set_ia32_sysroot.sh
@@ -4,16 +4,16 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
-# Sets the compiler environment variables to use a downloaded wheezy sysroot
+# Sets the compiler environment variables to use a downloaded Debian sysroot
# when building Dart with architecture ia32.
-# Run this in the same working directory that you have run
+# Run this in the same working directory that you have run
# sdk/tools/download_chromium_sysroot.sh in.
# Must be sourced, not run in a subshell, to modify the environment.
# Run with the command ". sdk/tools/set_ia32_sysroot.sh"
# Only tested and used on Ubuntu trusty linux. Used to build dart with
# no requirement for glibc greater than version 2.14.
-export CXXFLAGS="--sysroot=$PWD/build/linux/debian_wheezy_i386-sysroot -I=/usr/include/c++/4.6 -I=/usr/include/c++/4.6/i486-linux-gnu"
+export CXXFLAGS="--sysroot=$PWD/build/linux/debian_jessie_i386-sysroot -I=/usr/include/c++/4.8 -I=/usr/include/c++/4.8/i486-linux-gnu"
-export LDFLAGS=--sysroot=$PWD/build/linux/debian_wheezy_i386-sysroot
-export CFLAGS=--sysroot=$PWD/build/linux/debian_wheezy_i386-sysroot
+export LDFLAGS=--sysroot=$PWD/build/linux/debian_jessie_i386-sysroot
+export CFLAGS=--sysroot=$PWD/build/linux/debian_jessie_i386-sysroot
diff --git a/tools/set_x64_sysroot.sh b/tools/set_x64_sysroot.sh
index bc28961..9c199ff 100755
--- a/tools/set_x64_sysroot.sh
+++ b/tools/set_x64_sysroot.sh
@@ -4,16 +4,16 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
-# Sets the compiler environment variables to use a downloaded wheezy sysroot
+# Sets the compiler environment variables to use a downloaded Debian sysroot
# when building Dart with architecture x64.
-# Run this in the same working directory that you have run
+# Run this in the same working directory that you have run
# sdk/tools/download_chromium_sysroot.sh in.
# Must be sourced, not run in a subshell, to modify the environment.
# Run with the command ". sdk/tools/set_x64_sysroot.sh"
# Only tested and used on Ubuntu trusty linux. Used to build dart with
# no requirement for glibc greater than version 2.14.
-export CXXFLAGS="--sysroot=$PWD/build/linux/debian_wheezy_amd64-sysroot -I=/usr/include/c++/4.6 -I=/usr/include/c++/4.6/x86_64-linux-gnu"
+export CXXFLAGS="--sysroot=$PWD/build/linux/debian_jessie_amd64-sysroot -I=/usr/include/c++/4.8 -I=/usr/include/c++/4.8/x86_64-linux-gnu"
-export LDFLAGS=--sysroot=$PWD/build/linux/debian_wheezy_amd64-sysroot
-export CFLAGS=--sysroot=$PWD/build/linux/debian_wheezy_amd64-sysroot
+export LDFLAGS=--sysroot=$PWD/build/linux/debian_jessie_amd64-sysroot
+export CFLAGS=--sysroot=$PWD/build/linux/debian_jessie_amd64-sysroot