Version 2.12.0-244.0.dev
Merge commit '15cd98f5119833d36a24faab71bb770d8a84450c' into 'dev'
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index e2ca9ea..8b4b43a 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -380,7 +380,9 @@
var type = node.inDeclarationContext()
? HighlightRegionType.PARAMETER_DECLARATION
: HighlightRegionType.PARAMETER_REFERENCE;
- return _addRegion_node(node, type);
+ var modifiers =
+ node.parent is Label ? {CustomSemanticTokenModifiers.label} : null;
+ return _addRegion_node(node, type, semanticTokenModifiers: modifiers);
}
bool _addIdentifierRegion_typeParameter(SimpleIdentifier node) {
@@ -459,10 +461,21 @@
}
}
- bool _addRegion_node(AstNode node, HighlightRegionType type) {
+ bool _addRegion_node(
+ AstNode node,
+ HighlightRegionType type, {
+ SemanticTokenTypes semanticTokenType,
+ Set<SemanticTokenModifiers> semanticTokenModifiers,
+ }) {
var offset = node.offset;
var length = node.length;
- _addRegion(offset, length, type);
+ _addRegion(
+ offset,
+ length,
+ type,
+ semanticTokenType: semanticTokenType,
+ semanticTokenModifiers: semanticTokenModifiers,
+ );
return true;
}
diff --git a/pkg/analysis_server/lib/src/lsp/constants.dart b/pkg/analysis_server/lib/src/lsp/constants.dart
index ebc2978..8e751a4 100644
--- a/pkg/analysis_server/lib/src/lsp/constants.dart
+++ b/pkg/analysis_server/lib/src/lsp/constants.dart
@@ -100,15 +100,23 @@
}
abstract class CustomSemanticTokenModifiers {
- // A modifier applied to control keywords like if/for/etc. so they can be
- // coloured differently to other keywords (void, import, etc), matching the
- // original Dart textmate grammar.
- // https://github.com/dart-lang/dart-syntax-highlight/blob/84a8e84f79bc917ebd959a4587349c865dc945e0/grammars/dart.json#L244-L261
+ /// A modifier applied to control keywords like if/for/etc. so they can be
+ /// coloured differently to other keywords (void, import, etc), matching the
+ /// original Dart textmate grammar.
+ /// https://github.com/dart-lang/dart-syntax-highlight/blob/84a8e84f79bc917ebd959a4587349c865dc945e0/grammars/dart.json#L244-L261
static const control = SemanticTokenModifiers('control');
+ /// A modifier applied to parameter references to indicate they are the name/label
+ /// to allow theming them differently to the values. For example in the code
+ /// `foo({String a}) => foo(a: a)` the a's will be differentiated as:
+ /// - parameter.declaration
+ /// - parameter.label
+ /// - parameter
+ static const label = SemanticTokenModifiers('label');
+
/// All custom semantic token modifiers, used to populate the LSP Legend which must
/// include all used modifiers.
- static const values = [control];
+ static const values = [control, label];
}
abstract class CustomSemanticTokenTypes {
diff --git a/pkg/analysis_server/test/lsp/semantic_tokens_test.dart b/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
index 3886184..dfd4324 100644
--- a/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
+++ b/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
@@ -600,6 +600,33 @@
expect(decoded, equals(expected));
}
+ Future<void> test_namedArguments() async {
+ final content = '''
+ f({String a}) {
+ f(a: a);
+ }
+ ''';
+
+ final expected = [
+ _Token('f', SemanticTokenTypes.function,
+ [SemanticTokenModifiers.declaration, SemanticTokenModifiers.static]),
+ _Token('String', SemanticTokenTypes.class_),
+ _Token('a', SemanticTokenTypes.parameter,
+ [SemanticTokenModifiers.declaration]),
+ _Token('f', SemanticTokenTypes.function),
+ _Token('a', SemanticTokenTypes.parameter,
+ [CustomSemanticTokenModifiers.label]),
+ _Token('a', SemanticTokenTypes.parameter),
+ ];
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(content));
+
+ final tokens = await getSemanticTokens(mainFileUri);
+ final decoded = decodeSemanticTokens(content, tokens);
+ expect(decoded, equals(expected));
+ }
+
Future<void> test_range() async {
final content = '''
/// class docs
diff --git a/pkg/nnbd_migration/lib/migration_cli.dart b/pkg/nnbd_migration/lib/migration_cli.dart
index 785b5a6..df8da53 100644
--- a/pkg/nnbd_migration/lib/migration_cli.dart
+++ b/pkg/nnbd_migration/lib/migration_cli.dart
@@ -813,25 +813,7 @@
/// return additional paths that aren't inside the user's project, but doesn't
/// override this method, then those additional paths will be analyzed but not
/// migrated.
- bool shouldBeMigrated(String path) => shouldBeMigrated2(path);
-
- /// Determines whether a migrated version of the file at [path] should be
- /// output by the migration too. May be overridden by a derived class.
- ///
- /// This method should return `false` for files that are being considered by
- /// the migration tool for information only (for example generated files, or
- /// usages of the code-to-be-migrated by one one of its clients).
- ///
- /// By default returns `true` if the file is contained within the context
- /// root. This means that if a client overrides [computePathsToProcess] to
- /// return additional paths that aren't inside the user's project, but doesn't
- /// override this method, then those additional paths will be analyzed but not
- /// migrated.
- ///
- /// Note: in a future version of the code, this method will be removed;
- /// clients that are overriding this method should switch to overriding
- /// [shouldBeMigrated] instead.
- bool shouldBeMigrated2(String path) {
+ bool shouldBeMigrated(String path) {
return analysisContext.contextRoot.isAnalyzed(path);
}
diff --git a/pkg/nnbd_migration/lib/src/preview/preview_site.dart b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
index 0a58fbe..9799335 100644
--- a/pkg/nnbd_migration/lib/src/preview/preview_site.dart
+++ b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
@@ -179,6 +179,10 @@
var index = 0;
+ // Returns the next line and updates [index].
+ //
+ // After this function returns, [index] points to the character after the
+ // end of the line which was returned.
String getLine() {
var nextIndex = code.indexOf('\n', index);
if (nextIndex < 0) {
@@ -220,24 +224,37 @@
// [code] consists _only_ of one comment line.
return '$code$newline$newline// @dart=2.9$newline';
}
- line = getLine();
- lineStart = line.indexOf(_nonWhitespaceChar);
- while (lineStart >= 0 &&
- line.length > lineStart + 1 &&
- line.codeUnitAt(lineStart) == $slash &&
- line.codeUnitAt(lineStart + 1) == $slash) {
- // Another comment line.
+ var previousLineIndex = index;
+ while (true) {
+ previousLineIndex = index;
line = getLine();
- if (index == length) {
- // [code] consists _only_ of this block comment.
- return '$code$newline$newline// @dart=2.9$newline';
- }
lineStart = line.indexOf(_nonWhitespaceChar);
+ if (lineStart < 0) {
+ // Line of whitespace; end of block comment.
+ break;
+ }
+ if (line.length <= lineStart + 1) {
+ // Only one character; not a comment; end of block comment.
+ break;
+ }
+ if (line.codeUnitAt(lineStart) == $slash &&
+ line.codeUnitAt(lineStart + 1) == $slash) {
+ // Comment line.
+ if (index == length) {
+ // [code] consists _only_ of this block comment.
+ return '$code$newline$newline// @dart=2.9$newline';
+ }
+ continue;
+ } else {
+ // Non-blank, non-comment line.
+ break;
+ }
}
- // [index] points to the start of [line], which is the first
+ // [previousLineIndex] points to the start of [line], which is the first
// non-comment line following the first comment.
- return '${code.substring(0, index)}$newline// @dart=2.9$newline$newline'
- '${code.substring(index)}';
+ return '${code.substring(0, previousLineIndex)}$newline'
+ '// @dart=2.9$newline$newline'
+ '${code.substring(previousLineIndex)}';
} else {
// [code] does not start with a block comment.
return '// @dart=2.9$newline$newline$code';
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
index 6121240..f065da9 100644
--- a/pkg/nnbd_migration/test/migration_cli_test.dart
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -185,9 +185,9 @@
}
@override
- bool shouldBeMigrated2(String path) =>
+ bool shouldBeMigrated(String path) =>
cli._test.overrideShouldBeMigrated?.call(path) ??
- super.shouldBeMigrated2(path);
+ super.shouldBeMigrated(path);
/// Sorts the paths in [paths] for repeatability of migration tests.
Set<String> _sortPaths(Set<String> paths) {
diff --git a/pkg/nnbd_migration/test/preview/preview_site_test.dart b/pkg/nnbd_migration/test/preview/preview_site_test.dart
index 9ec1b23f..ca9348c 100644
--- a/pkg/nnbd_migration/test/preview/preview_site_test.dart
+++ b/pkg/nnbd_migration/test/preview/preview_site_test.dart
@@ -156,14 +156,29 @@
void test_optOutOfNullSafety_commentThenCode() {
expect(
IncrementalPlan.optCodeOutOfNullSafety('// comment\n\nvoid main() {}'),
- equals('// comment\n\n\n// @dart=2.9\n\nvoid main() {}'));
+ equals('// comment\n\n// @dart=2.9\n\n\nvoid main() {}'));
}
void test_optOutOfNullSafety_commentThenCode_windows() {
expect(
IncrementalPlan.optCodeOutOfNullSafety(
'// comment\r\n\r\nvoid main() {}'),
- equals('// comment\r\n\r\n\r\n// @dart=2.9\r\n\r\nvoid main() {}'));
+ equals('// comment\r\n\r\n// @dart=2.9\r\n\r\n\r\nvoid main() {}'));
+ }
+
+ void test_optOutOfNullSafety_commentThenDirective() {
+ expect(
+ IncrementalPlan.optCodeOutOfNullSafety(
+ '// comment\nimport "dart:core";'),
+ equals('// comment\n\n// @dart=2.9\n\nimport "dart:core";'));
+ }
+
+ void test_optOutOfNullSafety_commentThenDirective_multiLine() {
+ expect(
+ IncrementalPlan.optCodeOutOfNullSafety(
+ '// comment\n// comment\nimport "dart:core";'),
+ equals(
+ '// comment\n// comment\n\n// @dart=2.9\n\nimport "dart:core";'));
}
void test_optOutOfNullSafety_empty() {
diff --git a/tools/VERSION b/tools/VERSION
index 2bbd3fd..1113dfc 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 243
+PRERELEASE 244
PRERELEASE_PATCH 0
\ No newline at end of file