Version 2.16.0-36.0.dev
Merge commit '6f59892b82f31c73fd866338e8c5dad62183e224' into 'dev'
diff --git a/pkg/front_end/analysis_options_no_lints.yaml b/pkg/front_end/analysis_options_no_lints.yaml
index d699e16..aca6b61 100644
--- a/pkg/front_end/analysis_options_no_lints.yaml
+++ b/pkg/front_end/analysis_options_no_lints.yaml
@@ -11,6 +11,7 @@
- test/extensions/data/**
- test/id_testing/data/**
- test/language_versioning/data/**
+ - test/macros/data/**
- test/patching/data/**
- test/predicates/data/**
- test/static_types/data/**
diff --git a/pkg/front_end/lib/src/testing/id_testing_helper.dart b/pkg/front_end/lib/src/testing/id_testing_helper.dart
index 2a8c8c8..77a6a44 100644
--- a/pkg/front_end/lib/src/testing/id_testing_helper.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_helper.dart
@@ -52,6 +52,7 @@
final Map<ExperimentalFlag, bool> explicitExperimentalFlags;
final AllowedExperimentalFlags? allowedExperimentalFlags;
final Uri? librariesSpecificationUri;
+ final Uri? packageConfigUri;
// TODO(johnniwinther): Tailor support to redefine selected platform
// classes/members only.
final bool compileSdk;
@@ -62,6 +63,7 @@
{this.explicitExperimentalFlags = const {},
this.allowedExperimentalFlags,
this.librariesSpecificationUri,
+ this.packageConfigUri,
this.compileSdk: false,
this.targetFlags: const TestTargetFlags(),
this.nnbdMode: NnbdMode.Weak});
@@ -322,6 +324,7 @@
options.compileSdk = config.compileSdk;
}
}
+ options.packagesFileUri = config.packageConfigUri;
config.customizeCompilerOptions(options, testData);
InternalCompilerResult compilerResult = await compileScript(
testData.memorySourceFiles,
diff --git a/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart b/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
index c282670..7e5d448 100644
--- a/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
import 'package:_fe_analyzer_shared/src/parser/parser.dart';
import 'package:_fe_analyzer_shared/src/parser/async_modifier.dart';
import 'package:_fe_analyzer_shared/src/scanner/scanner.dart';
@@ -540,7 +538,7 @@
}
void parseEntry(String source, List<String> expectedCalls,
- {bool inAsync, List<ExpectedError> errors, String expectAfter}) {
+ {bool? inAsync, List<ExpectedError>? errors, String? expectAfter}) {
final start = scanString(source).tokens;
final listener = new TestInfoListener();
final parser = new Parser(listener,
@@ -556,9 +554,9 @@
throw e;
}
if (expectAfter != null) {
- expect(lastConsumed.next.lexeme, expectAfter);
+ expect(lastConsumed.next!.lexeme, expectAfter);
} else {
- expect(lastConsumed.next.isEof, isTrue, reason: lastConsumed.lexeme);
+ expect(lastConsumed.next!.isEof, isTrue, reason: lastConsumed.lexeme);
}
}
}
@@ -838,7 +836,7 @@
}
void parseEntry(String source, List<String> expectedCalls,
- {bool inAsync, List<ExpectedError> errors, String expectAfter}) {
+ {bool? inAsync, List<ExpectedError>? errors, String? expectAfter}) {
final start = scanString(source).tokens;
final listener = new TestInfoListener();
final parser = new Parser(listener,
@@ -854,16 +852,16 @@
throw e;
}
if (expectAfter != null) {
- expect(lastConsumed.next.lexeme, expectAfter);
+ expect(lastConsumed.next!.lexeme, expectAfter);
} else {
- expect(lastConsumed.next.isEof, isTrue, reason: lastConsumed.lexeme);
+ expect(lastConsumed.next!.isEof, isTrue, reason: lastConsumed.lexeme);
}
}
}
class TestInfoListener implements Listener {
List<String> calls = <String>[];
- List<ExpectedError> errors;
+ List<ExpectedError>? errors;
@override
void beginBinaryExpression(Token token) {
@@ -876,7 +874,7 @@
}
@override
- void beginForControlFlow(Token awaitToken, Token forToken) {
+ void beginForControlFlow(Token? awaitToken, Token forToken) {
calls.add('beginForControlFlow $awaitToken $forToken');
}
@@ -907,7 +905,7 @@
@override
void beginVariablesDeclaration(
- Token token, Token lateToken, Token varFinalOrConst) {
+ Token token, Token? lateToken, Token? varFinalOrConst) {
// TODO(danrubel): update to include lateToken
calls.add('beginVariablesDeclaration $token $varFinalOrConst');
}
@@ -963,7 +961,7 @@
}
@override
- void endVariablesDeclaration(int count, Token endToken) {
+ void endVariablesDeclaration(int count, Token? endToken) {
calls.add('endVariablesDeclaration $count $endToken');
}
@@ -998,7 +996,7 @@
}
@override
- void handleForInLoopParts(Token awaitToken, Token forToken,
+ void handleForInLoopParts(Token? awaitToken, Token forToken,
Token leftParenthesis, Token inKeyword) {
calls.add('handleForInLoopParts '
'$awaitToken $forToken $leftParenthesis $inKeyword');
@@ -1028,7 +1026,7 @@
@override
void handleLiteralList(
- int count, Token leftBracket, Token constKeyword, Token rightBracket) {
+ int count, Token leftBracket, Token? constKeyword, Token rightBracket) {
calls.add(
'handleLiteralList $count, $leftBracket, $constKeyword, $rightBracket');
}
@@ -1037,7 +1035,7 @@
void handleLiteralSetOrMap(
int count,
Token leftBrace,
- Token constKeyword,
+ Token? constKeyword,
Token rightBrace,
// TODO(danrubel): hasSetEntry parameter exists for replicating existing
// behavior and will be removed once unified collection has been enabled
@@ -1080,9 +1078,9 @@
@override
void handleRecoverableError(
Message message, Token startToken, Token endToken) {
- errors ??= <ExpectedError>[];
int offset = startToken.charOffset;
- errors.add(error(message.code, offset, endToken.charEnd - offset));
+ (errors ??= <ExpectedError>[])
+ .add(error(message.code, offset, endToken.charEnd - offset));
}
@override
diff --git a/pkg/front_end/test/fasta/parser/token_stream_rewriter_test.dart b/pkg/front_end/test/fasta/parser/token_stream_rewriter_test.dart
index 24d01ca..6828c746 100644
--- a/pkg/front_end/test/fasta/parser/token_stream_rewriter_test.dart
+++ b/pkg/front_end/test/fasta/parser/token_stream_rewriter_test.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
import 'package:_fe_analyzer_shared/src/parser/token_stream_rewriter.dart';
import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
show ScannerResult, scanString;
@@ -39,7 +37,7 @@
TokenStreamRewriter rewriter = getTokenStreamRewriter();
Token openParen = rewriter.insertParens(a, false);
- Token closeParen = openParen.next;
+ Token closeParen = openParen.next!;
expect(openParen.lexeme, '(');
expect(closeParen.lexeme, ')');
@@ -64,8 +62,8 @@
TokenStreamRewriter rewriter = getTokenStreamRewriter();
Token openParen = rewriter.insertParens(a, true);
- Token identifier = openParen.next;
- Token closeParen = identifier.next;
+ Token identifier = openParen.next!;
+ Token closeParen = identifier.next!;
expect(openParen.lexeme, '(');
expect(identifier.lexeme, '');
@@ -180,7 +178,7 @@
expect(a.next, same(replacement));
expect(replacement.next, same(c));
- expect(c.next.isEof, true);
+ expect(c.next!.isEof, true);
normalTestDone(rewriter, a);
}
@@ -202,7 +200,7 @@
expect(replacement.replacedToken, same(b));
expect(a.next, same(replacement));
- expect(replacement.next.isEof, true);
+ expect(replacement.next!.isEof, true);
normalTestDone(rewriter, a);
}
@@ -226,11 +224,11 @@
expect(b.precedingComments, same(replacement.precedingComments));
expect(replacement.replacedToken, same(b));
expect(replacement.replacedToken.next, same(c));
- expect(replacement.replacedToken.next.next, same(d));
+ expect(replacement.replacedToken.next!.next, same(d));
expect(a.next, same(replacement));
expect(replacement.next, same(e));
- expect(e.next.isEof, true);
+ expect(e.next!.isEof, true);
normalTestDone(rewriter, a);
}
@@ -254,7 +252,7 @@
expect(replacement.replacedToken.next, same(c));
expect(a.next, same(replacement));
- expect(replacement.next.isEof, true);
+ expect(replacement.next!.isEof, true);
normalTestDone(rewriter, a);
}
@@ -265,18 +263,18 @@
Token firstToken = scanResult.tokens;
setupDone(firstToken);
- Token open = scanResult.tokens.next.next;
+ Token open = scanResult.tokens.next!.next!;
expect(open.lexeme, '(');
- Token close = open.endGroup;
+ Token close = open.endGroup!;
expect(close.isSynthetic, isTrue);
- expect(close.next.isEof, isTrue);
+ expect(close.next!.isEof, isTrue);
TokenStreamRewriter rewriter = getTokenStreamRewriter();
- Token result = rewriter.moveSynthetic(open.next, close);
+ Token result = rewriter.moveSynthetic(open.next!, close);
expect(result, close);
expect(open.endGroup, close);
- expect(open.next.next, close);
- expect(close.next.isEof, isFalse);
+ expect(open.next!.next, close);
+ expect(close.next!.isEof, isFalse);
normalTestDone(rewriter, firstToken);
}
@@ -340,7 +338,7 @@
}
StringToken _makeToken(int charOffset, String text) {
- return new StringToken.fromString(null, text, charOffset);
+ return new StringToken.fromString(TokenType.IDENTIFIER, text, charOffset);
}
}
@@ -384,34 +382,35 @@
TokenStreamRewriter getTokenStreamRewriter() =>
new UndoableTokenStreamRewriter();
- List<CachedTokenSetup> setup;
+ List<CachedTokenSetup>? setup;
@override
void setupDone(Token first) {
setup = [];
- Token token = first;
+ Token? token = first;
while (token != null && !token.isEof) {
- setup.add(new CachedTokenSetup(token));
+ setup!.add(new CachedTokenSetup(token));
token = token.next;
}
}
@override
void normalTestDone(TokenStreamRewriter rewriter, Token first) {
- UndoableTokenStreamRewriter undoableTokenStreamRewriter = rewriter;
+ UndoableTokenStreamRewriter undoableTokenStreamRewriter =
+ rewriter as UndoableTokenStreamRewriter;
undoableTokenStreamRewriter.undo();
List<CachedTokenSetup> now = [];
- Token token = first;
+ Token? token = first;
while (token != null && !token.isEof) {
now.add(new CachedTokenSetup(token));
token = token.next;
}
- if (setup.length != now.length) {
- throw "Different length: ${setup.length} vs ${now.length}";
+ if (setup!.length != now.length) {
+ throw "Different length: ${setup!.length} vs ${now.length}";
}
- for (int i = 0; i < setup.length; i++) {
- if (setup[i] != now[i]) {
- throw "Different at $i: ${setup[i]} vs ${now[i]}";
+ for (int i = 0; i < setup!.length; i++) {
+ if (setup![i] != now[i]) {
+ throw "Different at $i: ${setup![i]} vs ${now[i]}";
}
}
setup = null;
@@ -420,9 +419,9 @@
class CachedTokenSetup {
final Token token;
- final Token prev;
- final Token next;
- final Token precedingComments;
+ final Token? prev;
+ final Token? next;
+ final Token? precedingComments;
CachedTokenSetup(this.token)
: prev = token.previous,
diff --git a/pkg/front_end/test/fasta/tool_git_test.dart b/pkg/front_end/test/fasta/tool_git_test.dart
index 3755f18..6e4b231 100644
--- a/pkg/front_end/test/fasta/tool_git_test.dart
+++ b/pkg/front_end/test/fasta/tool_git_test.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
/// Tests the tool `pkg/front_end/tool/fasta`.
import "dart:io";
diff --git a/pkg/front_end/test/fasta/uri_translator_test.dart b/pkg/front_end/test/fasta/uri_translator_test.dart
index 37e3564..806a053 100644
--- a/pkg/front_end/test/fasta/uri_translator_test.dart
+++ b/pkg/front_end/test/fasta/uri_translator_test.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
import 'package:_fe_analyzer_shared/src/util/libraries_specification.dart';
import 'package:front_end/src/fasta/uri_translator.dart';
import 'package:package_config/package_config.dart';
diff --git a/pkg/front_end/test/macros/data/package_config.json b/pkg/front_end/test/macros/data/package_config.json
new file mode 100644
index 0000000..97031ce
--- /dev/null
+++ b/pkg/front_end/test/macros/data/package_config.json
@@ -0,0 +1,13 @@
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "macro",
+ "rootUri": "pkgs/macro/lib/"
+ },
+ {
+ "name": "macro_builder",
+ "rootUri": "pkgs/macro_builder/lib/"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/macros/data/pkgs/macro/lib/macro.dart b/pkg/front_end/test/macros/data/pkgs/macro/lib/macro.dart
new file mode 100644
index 0000000..bfe0285
--- /dev/null
+++ b/pkg/front_end/test/macros/data/pkgs/macro/lib/macro.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, 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.
+
+import 'package:macro_builder/macro_builder.dart';
+
+class Macro1 implements Macro {
+ const Macro1();
+}
+
+class Macro2 implements Macro {
+ const Macro2();
+}
+
+class Macro3 implements Macro {
+ const Macro3();
+}
+
+class NonMacro {
+ const NonMacro();
+}
diff --git a/pkg/front_end/test/macros/data/pkgs/macro_builder/lib/macro_builder.dart b/pkg/front_end/test/macros/data/pkgs/macro_builder/lib/macro_builder.dart
new file mode 100644
index 0000000..14354da
--- /dev/null
+++ b/pkg/front_end/test/macros/data/pkgs/macro_builder/lib/macro_builder.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2021, 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.
+
+export 'src/macro.dart';
diff --git a/pkg/front_end/test/macros/data/pkgs/macro_builder/lib/src/macro.dart b/pkg/front_end/test/macros/data/pkgs/macro_builder/lib/src/macro.dart
new file mode 100644
index 0000000..434331b
--- /dev/null
+++ b/pkg/front_end/test/macros/data/pkgs/macro_builder/lib/src/macro.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2021, 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.
+
+class Macro {}
diff --git a/pkg/front_end/test/macros/data/tests/declare_macro.dart b/pkg/front_end/test/macros/data/tests/declare_macro.dart
new file mode 100644
index 0000000..58edc63
--- /dev/null
+++ b/pkg/front_end/test/macros/data/tests/declare_macro.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2021, 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.
+
+/*library:
+ declaredMacros=[MyMacro],
+ macrosAreAvailable
+*/
+
+import 'package:macro_builder/macro_builder.dart';
+
+class MyMacro implements Macro {}
+
+void main() {}
diff --git a/pkg/front_end/test/macros/data/tests/direct_import.dart b/pkg/front_end/test/macros/data/tests/direct_import.dart
new file mode 100644
index 0000000..b2f6177
--- /dev/null
+++ b/pkg/front_end/test/macros/data/tests/direct_import.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2021, 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.
+
+/*library: macrosAreAvailable*/
+
+// ignore: unused_import
+import 'package:macro_builder/src/macro.dart';
+
+void main() {}
diff --git a/pkg/front_end/test/macros/data/tests/import_macro_builder.dart b/pkg/front_end/test/macros/data/tests/import_macro_builder.dart
new file mode 100644
index 0000000..14e5966c
--- /dev/null
+++ b/pkg/front_end/test/macros/data/tests/import_macro_builder.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2021, 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.
+
+/*library: macrosAreAvailable*/
+
+// ignore: unused_import
+import 'package:macro_builder/macro_builder.dart';
+
+void main() {}
diff --git a/pkg/front_end/test/macros/data/tests/import_macro_package.dart b/pkg/front_end/test/macros/data/tests/import_macro_package.dart
new file mode 100644
index 0000000..5e69df3
--- /dev/null
+++ b/pkg/front_end/test/macros/data/tests/import_macro_package.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2021, 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.
+
+/*library: macrosAreAvailable*/
+
+// ignore: unused_import
+import 'package:macro/macro.dart';
+
+void main() {}
diff --git a/pkg/front_end/test/macros/data/tests/import_macro_source/macro_lib.dart b/pkg/front_end/test/macros/data/tests/import_macro_source/macro_lib.dart
new file mode 100644
index 0000000..a05f387
--- /dev/null
+++ b/pkg/front_end/test/macros/data/tests/import_macro_source/macro_lib.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2021, 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.
+
+/*library:
+ declaredMacros=[Macro1],
+ macrosAreAvailable
+*/
+
+import 'package:macro_builder/macro_builder.dart';
+
+class Macro1 implements Macro {
+ const Macro1();
+}
diff --git a/pkg/front_end/test/macros/data/tests/import_macro_source/main.dart b/pkg/front_end/test/macros/data/tests/import_macro_source/main.dart
new file mode 100644
index 0000000..625315b
--- /dev/null
+++ b/pkg/front_end/test/macros/data/tests/import_macro_source/main.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2021, 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.
+
+/*library: macrosAreAvailable*/
+
+// ignore: unused_import
+import 'macro_lib.dart';
+
+void main() {}
diff --git a/pkg/front_end/test/macros/data/tests/marker.options b/pkg/front_end/test/macros/data/tests/marker.options
new file mode 100644
index 0000000..8416ef5
--- /dev/null
+++ b/pkg/front_end/test/macros/data/tests/marker.options
@@ -0,0 +1 @@
+cfe=pkg/front_end/test/macros/macro_test.dart
diff --git a/pkg/front_end/test/macros/data/tests/no_import.dart b/pkg/front_end/test/macros/data/tests/no_import.dart
new file mode 100644
index 0000000..e5c2fad
--- /dev/null
+++ b/pkg/front_end/test/macros/data/tests/no_import.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2021, 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.
+
+void main() {}
diff --git a/pkg/front_end/test/macros/data/tests/use_macro_package.dart b/pkg/front_end/test/macros/data/tests/use_macro_package.dart
new file mode 100644
index 0000000..09c2b3b
--- /dev/null
+++ b/pkg/front_end/test/macros/data/tests/use_macro_package.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2021, 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.
+
+/*library:
+ appliedMacros=[Macro3],
+ macrosAreApplied,
+ macrosAreAvailable
+*/
+@Macro3()
+library use_macro_package;
+
+import 'package:macro/macro.dart';
+
+@Macro1()
+/*member: main:appliedMacros=[Macro1]*/
+void main() {}
+
+@Macro2()
+/*class: Class1:
+ appliedMacros=[Macro2],
+ macrosAreApplied
+*/
+class Class1 {
+ @Macro1()
+ @Macro2()
+ /*member: Class1.method:appliedMacros=[
+ Macro1,
+ Macro2]*/
+ void method() {}
+}
+
+@NonMacro()
+class Class2 {}
+
+/*class: Class3:macrosAreApplied*/
+class Class3 {
+ @Macro3()
+ /*member: Class3.field:appliedMacros=[Macro3]*/
+ var field;
+}
+
+class Class4 {
+ @NonMacro()
+ var field;
+}
diff --git a/pkg/front_end/test/macros/data/tests/use_macro_source/macro_lib.dart b/pkg/front_end/test/macros/data/tests/use_macro_source/macro_lib.dart
new file mode 100644
index 0000000..3f926a8
--- /dev/null
+++ b/pkg/front_end/test/macros/data/tests/use_macro_source/macro_lib.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, 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.
+
+/*library:
+ declaredMacros=[
+ Macro1,
+ Macro2],
+ macrosAreAvailable
+*/
+
+import 'package:macro_builder/macro_builder.dart';
+
+class Macro1 implements Macro {
+ const Macro1();
+}
+
+class Macro2 implements Macro {
+ const Macro2();
+}
+
+class NonMacro {
+ const NonMacro();
+}
diff --git a/pkg/front_end/test/macros/data/tests/use_macro_source/main.dart b/pkg/front_end/test/macros/data/tests/use_macro_source/main.dart
new file mode 100644
index 0000000..f5a3e60
--- /dev/null
+++ b/pkg/front_end/test/macros/data/tests/use_macro_source/main.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2021, 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.
+
+/*library:
+ macrosAreApplied,
+ macrosAreAvailable
+*/
+
+import 'macro_lib.dart';
+
+@Macro1()
+/*member: main:appliedMacros=[Macro1]*/
+void main() {}
+
+@Macro2()
+/*class: Class1:
+ appliedMacros=[Macro2],
+ macrosAreApplied
+*/
+class Class1 {
+ @Macro1()
+ @Macro2()
+ /*member: Class1.method:appliedMacros=[
+ Macro1,
+ Macro2]*/
+ void method() {}
+}
+
+@NonMacro()
+class Class2 {}
+
+/*class: Class3:macrosAreApplied*/
+class Class3 {
+ @Macro1()
+ /*member: Class3.field:appliedMacros=[Macro1]*/
+ var field;
+}
+
+class Class4 {
+ @NonMacro()
+ var field;
+}
diff --git a/pkg/front_end/test/macros/macro_test.dart b/pkg/front_end/test/macros/macro_test.dart
new file mode 100644
index 0000000..98f0000
--- /dev/null
+++ b/pkg/front_end/test/macros/macro_test.dart
@@ -0,0 +1,291 @@
+// Copyright (c) 2021, 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.
+
+import 'dart:io' show Directory, Platform;
+
+import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
+import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
+
+import 'package:_fe_analyzer_shared/src/testing/features.dart';
+import 'package:front_end/src/testing/id_testing_helper.dart';
+import 'package:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/core_types.dart';
+
+Future<void> main(List<String> args) async {
+ Directory dataDir =
+ new Directory.fromUri(Platform.script.resolve('data/tests'));
+ await runTests<Features>(dataDir,
+ args: args,
+ createUriForFileName: createUriForFileName,
+ onFailure: onFailure,
+ runTest: runTestFor(const MacroDataComputer(), [
+ new TestConfig(cfeMarker, 'cfe',
+ packageConfigUri:
+ Platform.script.resolve('data/package_config.json'))
+ ]));
+}
+
+final Uri macroLibraryUri = Uri.parse('package:macro_builder/src/macro.dart');
+const String macroClassName = 'Macro';
+
+class MacroDeclarationData {
+ Class? macroClass;
+ Map<Library, List<Class>> macroDeclarations = {};
+ Set<Class> macroClasses = {};
+}
+
+MacroDeclarationData computeMacroDeclarationData(
+ Component component, ClassHierarchy classHierarchy) {
+ MacroDeclarationData data = new MacroDeclarationData();
+ Class? macroClass;
+ outer:
+ for (Library library in component.libraries) {
+ if (library.importUri == macroLibraryUri) {
+ for (Class cls in library.classes) {
+ if (cls.name == macroClassName) {
+ macroClass = cls;
+ break outer;
+ }
+ }
+ }
+ }
+ if (macroClass != null) {
+ data.macroClass = macroClass;
+ for (Library library in component.libraries) {
+ for (Class cls in library.classes) {
+ if (classHierarchy.isSubtypeOf(cls, macroClass)) {
+ (data.macroDeclarations[library] ??= []).add(cls);
+ data.macroClasses.add(cls);
+ }
+ }
+ }
+ }
+ return data;
+}
+
+class MacroApplications {
+ List<Class> macros = [];
+}
+
+class LibraryMacroApplicationData {
+ MacroApplications? libraryApplications;
+ Map<Class, ClassMacroApplicationData> classData = {};
+ Map<Typedef, MacroApplications> typedefApplications = {};
+ Map<Member, MacroApplications> memberApplications = {};
+}
+
+class ClassMacroApplicationData {
+ MacroApplications? classApplications;
+ Map<Member, MacroApplications> memberApplications = {};
+}
+
+MacroApplications? computeMacroApplications(
+ List<Expression> annotations, MacroDeclarationData macroDeclarationData) {
+ MacroApplications applications = new MacroApplications();
+ bool hasApplications = false;
+ for (Expression annotation in annotations) {
+ if (annotation is ConstantExpression) {
+ Constant constant = annotation.constant;
+ if (constant is InstanceConstant) {
+ if (macroDeclarationData.macroClasses.contains(constant.classNode)) {
+ applications.macros.add(constant.classNode);
+ hasApplications = true;
+ }
+ }
+ }
+ }
+ return hasApplications ? applications : null;
+}
+
+ClassMacroApplicationData? computeClassMacroApplicationData(
+ Class cls, MacroDeclarationData macroDeclarationData) {
+ ClassMacroApplicationData data = new ClassMacroApplicationData();
+ data.classApplications =
+ computeMacroApplications(cls.annotations, macroDeclarationData);
+ for (Member member in cls.members) {
+ MacroApplications? macroApplications =
+ computeMacroApplications(member.annotations, macroDeclarationData);
+ if (macroApplications != null) {
+ data.memberApplications[member] = macroApplications;
+ }
+ }
+ return data.classApplications != null || data.memberApplications.isNotEmpty
+ ? data
+ : null;
+}
+
+LibraryMacroApplicationData? computeLibraryMacroApplicationData(
+ Library library, MacroDeclarationData macroDeclarationData) {
+ LibraryMacroApplicationData data = new LibraryMacroApplicationData();
+ data.libraryApplications =
+ computeMacroApplications(library.annotations, macroDeclarationData);
+ for (Typedef typedef in library.typedefs) {
+ MacroApplications? macroApplications =
+ computeMacroApplications(typedef.annotations, macroDeclarationData);
+ if (macroApplications != null) {
+ data.typedefApplications[typedef] = macroApplications;
+ }
+ }
+ for (Member member in library.members) {
+ MacroApplications? macroApplications =
+ computeMacroApplications(member.annotations, macroDeclarationData);
+ if (macroApplications != null) {
+ data.memberApplications[member] = macroApplications;
+ }
+ }
+ for (Class cls in library.classes) {
+ ClassMacroApplicationData? classMacroApplicationData =
+ computeClassMacroApplicationData(cls, macroDeclarationData);
+ if (classMacroApplicationData != null) {
+ data.classData[cls] = classMacroApplicationData;
+ }
+ }
+ return data.libraryApplications != null ||
+ data.classData.isNotEmpty ||
+ data.memberApplications.isNotEmpty ||
+ data.typedefApplications.isNotEmpty
+ ? data
+ : null;
+}
+
+class MacroDataComputer extends DataComputer<Features> {
+ const MacroDataComputer();
+
+ @override
+ void computeMemberData(
+ TestConfig config,
+ InternalCompilerResult compilerResult,
+ Member member,
+ Map<Id, ActualData<Features>> actualMap,
+ {bool? verbose}) {
+ member.accept(new MacroDataExtractor(compilerResult, actualMap));
+ }
+
+ @override
+ void computeClassData(
+ TestConfig config,
+ InternalCompilerResult compilerResult,
+ Class cls,
+ Map<Id, ActualData<Features>> actualMap,
+ {bool? verbose}) {
+ new MacroDataExtractor(compilerResult, actualMap).computeForClass(cls);
+ }
+
+ @override
+ void computeLibraryData(
+ TestConfig config,
+ InternalCompilerResult compilerResult,
+ Library library,
+ Map<Id, ActualData<Features>> actualMap,
+ {bool? verbose}) {
+ new MacroDataExtractor(compilerResult, actualMap)
+ .computeForLibrary(library);
+ }
+
+ @override
+ DataInterpreter<Features> get dataValidator =>
+ const FeaturesDataInterpreter();
+}
+
+class Tags {
+ static const String macrosAreAvailable = 'macrosAreAvailable';
+ static const String macrosAreApplied = 'macrosAreApplied';
+ static const String declaredMacros = 'declaredMacros';
+ static const String appliedMacros = 'appliedMacros';
+}
+
+class MacroDataExtractor extends CfeDataExtractor<Features> {
+ late final ClassHierarchy classHierarchy;
+ late final MacroDeclarationData macroDeclarationData;
+
+ MacroDataExtractor(InternalCompilerResult compilerResult,
+ Map<Id, ActualData<Features>> actualMap)
+ : super(compilerResult, actualMap) {
+ // TODO(johnniwinther): Why isn't `_UserTag` available in the
+ // [ClassHierarchy] provided by the [compilerResult]?
+ classHierarchy = new ClassHierarchy(
+ compilerResult.component!, new CoreTypes(compilerResult.component!));
+ macroDeclarationData =
+ computeMacroDeclarationData(compilerResult.component!, classHierarchy);
+ }
+
+ LibraryMacroApplicationData? getLibraryMacroApplicationData(Library library) {
+ return computeLibraryMacroApplicationData(library, macroDeclarationData);
+ }
+
+ MacroApplications? getLibraryMacroApplications(Library library) {
+ return getLibraryMacroApplicationData(library)?.libraryApplications;
+ }
+
+ ClassMacroApplicationData? getClassMacroApplicationData(Class cls) {
+ LibraryMacroApplicationData? applicationData =
+ computeLibraryMacroApplicationData(
+ cls.enclosingLibrary, macroDeclarationData);
+ if (applicationData != null) {
+ return applicationData.classData[cls];
+ }
+ return null;
+ }
+
+ MacroApplications? getClassMacroApplications(Class cls) {
+ return getClassMacroApplicationData(cls)?.classApplications;
+ }
+
+ MacroApplications? getMemberMacroApplications(Member member) {
+ Class? enclosingClass = member.enclosingClass;
+ if (enclosingClass != null) {
+ return getClassMacroApplicationData(enclosingClass)
+ ?.memberApplications[member];
+ } else {
+ return getLibraryMacroApplicationData(member.enclosingLibrary)
+ ?.memberApplications[member];
+ }
+ }
+
+ void registerMacroApplications(
+ Features features, MacroApplications? macroApplications) {
+ if (macroApplications != null) {
+ for (Class cls in macroApplications.macros) {
+ features.addElement(Tags.appliedMacros, cls.name);
+ }
+ }
+ }
+
+ @override
+ Features computeLibraryValue(Id id, Library node) {
+ Features features = new Features();
+ if (macroDeclarationData.macroClass != null) {
+ features.add(Tags.macrosAreAvailable);
+ }
+ List<Class>? macroClasses = macroDeclarationData.macroDeclarations[node];
+ if (macroClasses != null) {
+ for (Class cls in macroClasses) {
+ features.addElement(Tags.declaredMacros, cls.name);
+ }
+ }
+ if (getLibraryMacroApplicationData(node) != null) {
+ features.add(Tags.macrosAreApplied);
+ }
+ registerMacroApplications(features, getLibraryMacroApplications(node));
+ return features;
+ }
+
+ @override
+ Features computeClassValue(Id id, Class node) {
+ Features features = new Features();
+ if (getClassMacroApplicationData(node) != null) {
+ features.add(Tags.macrosAreApplied);
+ }
+ registerMacroApplications(features, getClassMacroApplications(node));
+ return features;
+ }
+
+ @override
+ Features computeMemberValue(Id id, Member node) {
+ Features features = new Features();
+ registerMacroApplications(features, getMemberMacroApplications(node));
+ return features;
+ }
+}
diff --git a/pkg/front_end/test/scanner_fasta_test.dart b/pkg/front_end/test/scanner_fasta_test.dart
index b5c55b5..215423e 100644
--- a/pkg/front_end/test/scanner_fasta_test.dart
+++ b/pkg/front_end/test/scanner_fasta_test.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart=2.9
-
import 'dart:convert';
import 'package:_fe_analyzer_shared/src/scanner/error_token.dart' as fasta;
@@ -38,16 +36,16 @@
usedForFuzzTesting.ScannerResult result =
usedForFuzzTesting.scanString(source);
- expect(result?.hasErrors, isFalse);
- expect(result.tokens?.type, same(Keyword.CLASS));
+ expect(result.hasErrors, isFalse);
+ expect(result.tokens.type, same(Keyword.CLASS));
// UTF8 encode source with trailing zero
List<int> bytes = utf8.encode(source).toList();
bytes.add(0);
result = usedForFuzzTesting.scan(bytes);
- expect(result?.hasErrors, isFalse);
- expect(result.tokens?.type, same(Keyword.CLASS));
+ expect(result.hasErrors, isFalse);
+ expect(result.tokens.type, same(Keyword.CLASS));
}
}
@@ -55,7 +53,7 @@
class ScannerTest_Fasta_UTF8 extends ScannerTest_Fasta {
@override
Token scanWithListener(String source, ErrorListener listener,
- {ScannerConfiguration configuration}) {
+ {ScannerConfiguration? configuration}) {
var bytes = utf8.encode(source).toList()..add(0);
var result =
scan(bytes, configuration: configuration, includeComments: true);
@@ -65,10 +63,10 @@
if (result.hasErrors) {
while (token is ErrorToken) {
translateErrorToken(token,
- (ScannerErrorCode errorCode, int offset, List<Object> arguments) {
+ (ScannerErrorCode errorCode, int offset, List<Object>? arguments) {
listener.errors.add(new TestError(offset, errorCode, arguments));
});
- token = token.next;
+ token = token.next!;
}
}
@@ -113,7 +111,7 @@
class ScannerTest_Fasta extends ScannerTestBase {
@override
Token scanWithListener(String source, ErrorListener listener,
- {ScannerConfiguration configuration}) {
+ {ScannerConfiguration? configuration}) {
var result =
scanString(source, configuration: configuration, includeComments: true);
var token = result.tokens;
@@ -122,10 +120,10 @@
if (result.hasErrors) {
while (token is ErrorToken) {
translateErrorToken(token,
- (ScannerErrorCode errorCode, int offset, List<Object> arguments) {
+ (ScannerErrorCode errorCode, int offset, List<Object>? arguments) {
listener.errors.add(new TestError(offset, errorCode, arguments));
});
- token = token.next;
+ token = token.next!;
}
}
@@ -151,7 +149,7 @@
} // EOF comment
''';
- Token scanSource({bool includeComments}) {
+ Token scanSource({required bool includeComments}) {
return scanString(source, includeComments: includeComments).tokens;
}
@@ -162,7 +160,7 @@
// Assert no comments
expect(token.precedingComments, isNull);
expect(token.type.kind, isNot(fasta.COMMENT_TOKEN));
- token = token.next;
+ token = token.next!;
}
expect(token.precedingComments, isNull);
expect(tokenCount, 26);
@@ -175,13 +173,13 @@
while (!token.isEof) {
++tokenCount;
// Assert valid comments
- fasta.CommentToken comment = token.precedingComments;
+ fasta.CommentToken? comment = token.precedingComments;
while (comment != null) {
++commentTokenCount;
expect(comment.type.kind, fasta.COMMENT_TOKEN);
expect(comment.charOffset, greaterThanOrEqualTo(previousEnd));
previousEnd = comment.charOffset + comment.charCount;
- comment = comment.next;
+ comment = comment.next as fasta.CommentToken?;
}
expect(token.type.kind, isNot(fasta.COMMENT_TOKEN));
expect(token.charOffset, greaterThanOrEqualTo(previousEnd));
@@ -206,7 +204,7 @@
}
}
- token = token.next;
+ token = token.next!;
}
expect(tokenCount, 26);
expect(spotCheckCount, 3);
@@ -222,19 +220,19 @@
main() {}
''';
- Token token;
- fasta.CommentToken c1;
- fasta.CommentToken c2;
- fasta.CommentToken c3;
+ late Token token;
+ late fasta.CommentToken c1;
+ late fasta.CommentToken c2;
+ late fasta.CommentToken c3;
void prepareTokens() {
token = scanString(code, includeComments: true).tokens;
expect(token.type.kind, fasta.IDENTIFIER_TOKEN);
- c1 = token.precedingComments;
- c2 = c1.next;
- c3 = c2.next;
+ c1 = token.precedingComments!;
+ c2 = c1.next as fasta.CommentToken;
+ c3 = c2.next as fasta.CommentToken;
expect(c3.next, isNull);
expect(c1.parent, token);
@@ -287,7 +285,7 @@
// ... but the length does *not* include the additional character
// so as to be true to the original source.
expect(token.length, source.length);
- expect(token.next.isEof, isTrue);
+ expect(token.next!.isEof, isTrue);
expect(listener.errors, hasLength(1));
TestError error = listener.errors[0];
expect(error.errorCode, ScannerErrorCode.MISSING_DIGIT);
@@ -303,16 +301,16 @@
// where both ')' are synthetic
ErrorListener listener = new ErrorListener();
BeginToken interpolationStart =
- scanWithListener(r'"${({(}}"', listener).next;
- BeginToken openParen1 = interpolationStart.next;
- BeginToken openBrace = openParen1.next;
- BeginToken openParen2 = openBrace.next;
- var closeParen2 = openParen2.next;
- var closeBrace = closeParen2.next;
- var closeParen1 = closeBrace.next;
- var interpolationEnd = closeParen1.next;
- var stringEnd = interpolationEnd.next;
- expect(stringEnd.next.type, TokenType.EOF);
+ scanWithListener(r'"${({(}}"', listener).next as BeginToken;
+ BeginToken openParen1 = interpolationStart.next as BeginToken;
+ BeginToken openBrace = openParen1.next as BeginToken;
+ BeginToken openParen2 = openBrace.next as BeginToken;
+ var closeParen2 = openParen2.next!;
+ var closeBrace = closeParen2.next!;
+ var closeParen1 = closeBrace.next!;
+ var interpolationEnd = closeParen1.next!;
+ var stringEnd = interpolationEnd.next!;
+ expect(stringEnd.next!.type, TokenType.EOF);
expect(interpolationStart.endToken, same(interpolationEnd));
expect(openParen1.endToken, same(closeParen1));
expect(openBrace.endToken, same(closeBrace));
@@ -327,37 +325,37 @@
const source = 'int a; /*1*/ /*2*/ /*3*/ B f(){if (a < 2) {}}';
Token token = scanString(source, includeComments: true).tokens;
while (!token.isEof) {
- expect(token.next.previous, token);
- fasta.CommentToken commentToken = token.precedingComments;
+ expect(token.next!.previous, token);
+ fasta.CommentToken? commentToken = token.precedingComments;
while (commentToken != null) {
if (commentToken.next != null) {
- expect(commentToken.next.previous, commentToken);
+ expect(commentToken.next!.previous, commentToken);
}
- commentToken = commentToken.next;
+ commentToken = commentToken.next as fasta.CommentToken?;
}
- token = token.next;
+ token = token.next!;
}
}
void test_spread_operators() {
ErrorListener listener = new ErrorListener();
Token openBracket = scanWithListener('[ 1, ...[2], ...?[3], ]', listener);
- Token spreadToken = openBracket.next.next.next;
+ Token spreadToken = openBracket.next!.next!.next!;
expect(spreadToken.lexeme, '...');
- Token spreadQToken = spreadToken.next.next.next.next.next;
+ Token spreadQToken = spreadToken.next!.next!.next!.next!.next!;
expect(spreadQToken.lexeme, '...?');
}
@override
void test_unmatched_openers() {
ErrorListener listener = new ErrorListener();
- BeginToken openBrace = scanWithListener('{[(', listener);
- BeginToken openBracket = openBrace.next;
- BeginToken openParen = openBracket.next;
- var closeParen = openParen.next;
- var closeBracket = closeParen.next;
- var closeBrace = closeBracket.next;
- expect(closeBrace.next.type, TokenType.EOF);
+ BeginToken openBrace = scanWithListener('{[(', listener) as BeginToken;
+ BeginToken openBracket = openBrace.next as BeginToken;
+ BeginToken openParen = openBracket.next as BeginToken;
+ var closeParen = openParen.next!;
+ var closeBracket = closeParen.next!;
+ var closeBrace = closeBracket.next!;
+ expect(closeBrace.next!.type, TokenType.EOF);
expect(openBrace.endToken, same(closeBrace));
expect(openBracket.endToken, same(closeBracket));
expect(openParen.endToken, same(closeParen));
@@ -374,7 +372,7 @@
Token scan(String source);
void expectToken(Token token, TokenType type, int offset, int length,
- {bool isSynthetic: false, String lexeme}) {
+ {bool isSynthetic: false, String? lexeme}) {
String description = '${token.type} $token';
expect(token.type, type, reason: description);
expect(token.offset, offset, reason: description);
@@ -390,26 +388,26 @@
expect((token as fasta.ErrorToken).errorCode,
same(codeUnexpectedDollarInString));
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 0, 1, lexeme: "'");
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING_INTERPOLATION_IDENTIFIER, 1, 1);
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.IDENTIFIER, 2, 1, lexeme: 'x');
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 3, 0, lexeme: '', isSynthetic: true);
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING_INTERPOLATION_IDENTIFIER, 3, 1);
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.IDENTIFIER, 4, 0,
lexeme: '', isSynthetic: true);
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 4, 1, lexeme: "'");
}
@@ -418,28 +416,28 @@
expect((token as fasta.ErrorToken).errorCode, same(codeUnmatchedToken));
var interpolationStartErrorToken = token as fasta.UnmatchedToken;
- token = token.next;
+ token = token.next!;
expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
expect((token as fasta.UnterminatedString).start, '"');
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 0, 5, lexeme: '"foo ');
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING_INTERPOLATION_EXPRESSION, 5, 2);
- BeginToken interpolationStart = token;
+ BeginToken interpolationStart = token as BeginToken;
expect(interpolationStartErrorToken.begin, same(interpolationStart));
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.IDENTIFIER, 7, 3, lexeme: 'bar');
// Expect interpolation to be terminated before string is closed
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.CLOSE_CURLY_BRACKET, 10, 0,
isSynthetic: true, lexeme: '}');
expect(interpolationStart.endToken, same(token));
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 10, 0, isSynthetic: true, lexeme: '"');
}
@@ -448,58 +446,58 @@
expect((token as fasta.ErrorToken).errorCode, same(codeUnmatchedToken));
var openSquareBracketErrorToken = token as fasta.UnmatchedToken;
- token = token.next;
+ token = token.next!;
expect((token as fasta.ErrorToken).errorCode, same(codeUnmatchedToken));
var openParenErrorToken = token as fasta.UnmatchedToken;
- token = token.next;
+ token = token.next!;
expect((token as fasta.ErrorToken).errorCode, same(codeUnmatchedToken));
var interpolationStartErrorToken = token as fasta.UnmatchedToken;
- token = token.next;
+ token = token.next!;
expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
expect((token as fasta.UnterminatedString).start, '"');
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 0, 5, lexeme: '"foo ');
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING_INTERPOLATION_EXPRESSION, 5, 2);
- BeginToken interpolationStart = token;
+ BeginToken interpolationStart = token as BeginToken;
expect(interpolationStartErrorToken.begin, same(interpolationStart));
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.IDENTIFIER, 7, 3, lexeme: 'bar');
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.OPEN_PAREN, 10, 1);
- BeginToken openParen = token;
+ BeginToken openParen = token as BeginToken;
expect(openParenErrorToken.begin, same(openParen));
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.IDENTIFIER, 11, 3, lexeme: 'baz');
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.OPEN_SQUARE_BRACKET, 14, 1);
- BeginToken openSquareBracket = token;
+ BeginToken openSquareBracket = token as BeginToken;
expect(openSquareBracketErrorToken.begin, same(openSquareBracket));
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.CLOSE_SQUARE_BRACKET, 15, 0,
isSynthetic: true, lexeme: ']');
expect(openSquareBracket.endToken, same(token));
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.CLOSE_PAREN, 15, 0,
isSynthetic: true, lexeme: ')');
expect(openParen.endToken, same(token));
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.CLOSE_CURLY_BRACKET, 15, 0,
isSynthetic: true, lexeme: '}');
expect(interpolationStart.endToken, same(token));
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 15, 0, isSynthetic: true, lexeme: '"');
}
@@ -508,21 +506,21 @@
expect((token as fasta.ErrorToken).errorCode,
same(codeUnexpectedDollarInString));
- token = token.next;
+ token = token.next!;
expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
expect((token as fasta.UnterminatedString).start, '"');
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 0, 5, lexeme: '"foo ');
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING_INTERPOLATION_IDENTIFIER, 5, 1);
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.IDENTIFIER, 6, 0,
isSynthetic: true, lexeme: '');
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 6, 0, isSynthetic: true, lexeme: '"');
}
@@ -531,7 +529,7 @@
expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
expect((token as fasta.UnterminatedString).start, "'''");
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 0, 9,
lexeme: "'''string'''", isSynthetic: true);
}
@@ -541,7 +539,7 @@
expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
expect((token as fasta.UnterminatedString).start, "r'''");
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 0, 10,
lexeme: "r'''string'''", isSynthetic: true);
}
@@ -551,7 +549,7 @@
expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
expect((token as fasta.UnterminatedString).start, "r'");
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 0, 8,
lexeme: "r'string'", isSynthetic: true);
}
@@ -561,7 +559,7 @@
expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
expect((token as fasta.UnterminatedString).start, "r'");
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 0, 8,
lexeme: "r'string'", isSynthetic: true);
}
@@ -571,7 +569,7 @@
expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
expect((token as fasta.UnterminatedString).start, "'");
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 0, 7,
lexeme: "'string'", isSynthetic: true);
}
@@ -581,17 +579,17 @@
expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
expect((token as fasta.UnterminatedString).start, "'");
- token = token.next;
+ token = token.next!;
expectToken(token, TokenType.STRING, 0, 7,
lexeme: "'string'", isSynthetic: true);
}
void test_match_angle_brackets() {
var x = scan('x<y>');
- BeginToken lessThan = x.next;
- var y = lessThan.next;
- var greaterThan = y.next;
- expect(greaterThan.next.isEof, isTrue);
+ BeginToken lessThan = x.next as BeginToken;
+ var y = lessThan.next!;
+ var greaterThan = y.next!;
+ expect(greaterThan.next!.isEof, isTrue);
expect(lessThan.endGroup, same(greaterThan));
}
@@ -599,54 +597,54 @@
// When a ">>" appears in the token stream, Fasta's scanner matches it to
// the outer "<". The inner "<" is left unmatched.
var x = scan('x<y<z>>');
- BeginToken lessThan1 = x.next;
- var y = lessThan1.next;
- BeginToken lessThan2 = y.next;
- var z = lessThan2.next;
- var greaterThans = z.next;
- expect(greaterThans.next.isEof, isTrue);
+ BeginToken lessThan1 = x.next as BeginToken;
+ var y = lessThan1.next!;
+ BeginToken lessThan2 = y.next as BeginToken;
+ var z = lessThan2.next!;
+ var greaterThans = z.next!;
+ expect(greaterThans.next!.isEof, isTrue);
expect(lessThan1.endGroup, same(greaterThans));
expect(lessThan2.endGroup, isNull);
}
void test_match_angle_brackets_interrupted_by_close_brace() {
// A "}" appearing in the token stream interrupts matching of "<" and ">".
- BeginToken openBrace = scan('{x<y}>z');
- var x = openBrace.next;
- BeginToken lessThan = x.next;
- var y = lessThan.next;
- var closeBrace = y.next;
- var greaterThan = closeBrace.next;
- var z = greaterThan.next;
- expect(z.next.isEof, isTrue);
+ BeginToken openBrace = scan('{x<y}>z') as BeginToken;
+ var x = openBrace.next!;
+ BeginToken lessThan = x.next as BeginToken;
+ var y = lessThan.next!;
+ var closeBrace = y.next!;
+ var greaterThan = closeBrace.next!;
+ var z = greaterThan.next!;
+ expect(z.next!.isEof, isTrue);
expect(openBrace.endGroup, same(closeBrace));
expect(lessThan.endGroup, isNull);
}
void test_match_angle_brackets_interrupted_by_close_bracket() {
// A "]" appearing in the token stream interrupts matching of "<" and ">".
- BeginToken openBracket = scan('[x<y]>z');
- var x = openBracket.next;
- BeginToken lessThan = x.next;
- var y = lessThan.next;
- var closeBracket = y.next;
- var greaterThan = closeBracket.next;
- var z = greaterThan.next;
- expect(z.next.isEof, isTrue);
+ BeginToken openBracket = scan('[x<y]>z') as BeginToken;
+ var x = openBracket.next!;
+ BeginToken lessThan = x.next as BeginToken;
+ var y = lessThan.next!;
+ var closeBracket = y.next!;
+ var greaterThan = closeBracket.next!;
+ var z = greaterThan.next!;
+ expect(z.next!.isEof, isTrue);
expect(openBracket.endGroup, same(closeBracket));
expect(lessThan.endGroup, isNull);
}
void test_match_angle_brackets_interrupted_by_close_paren() {
// A ")" appearing in the token stream interrupts matching of "<" and ">".
- BeginToken openParen = scan('(x<y)>z');
- var x = openParen.next;
- BeginToken lessThan = x.next;
- var y = lessThan.next;
- var closeParen = y.next;
- var greaterThan = closeParen.next;
- var z = greaterThan.next;
- expect(z.next.isEof, isTrue);
+ BeginToken openParen = scan('(x<y)>z') as BeginToken;
+ var x = openParen.next!;
+ BeginToken lessThan = x.next as BeginToken;
+ var y = lessThan.next!;
+ var closeParen = y.next!;
+ var greaterThan = closeParen.next!;
+ var z = greaterThan.next!;
+ expect(z.next!.isEof, isTrue);
expect(openParen.endGroup, same(closeParen));
expect(lessThan.endGroup, isNull);
}
@@ -654,15 +652,15 @@
void test_match_angle_brackets_interrupted_by_interpolation_expr() {
// A "${" appearing in the token stream interrupts matching of "<" and ">".
var x = scan(r'x<"${y>z}"');
- BeginToken lessThan = x.next;
- var beginString = lessThan.next;
- BeginToken beginInterpolation = beginString.next;
- var y = beginInterpolation.next;
- var greaterThan = y.next;
- var z = greaterThan.next;
- var endInterpolation = z.next;
- var endString = endInterpolation.next;
- expect(endString.next.isEof, isTrue);
+ BeginToken lessThan = x.next as BeginToken;
+ var beginString = lessThan.next!;
+ BeginToken beginInterpolation = beginString.next as BeginToken;
+ var y = beginInterpolation.next!;
+ var greaterThan = y.next!;
+ var z = greaterThan.next!;
+ var endInterpolation = z.next!;
+ var endString = endInterpolation.next!;
+ expect(endString.next!.isEof, isTrue);
expect(lessThan.endGroup, isNull);
expect(beginInterpolation.endGroup, same(endInterpolation));
}
@@ -670,13 +668,13 @@
void test_match_angle_brackets_interrupted_by_open_brace() {
// A "{" appearing in the token stream interrupts matching of "<" and ">".
var x = scan('x<{y>z}');
- BeginToken lessThan = x.next;
- BeginToken openBrace = lessThan.next;
- var y = openBrace.next;
- var greaterThan = y.next;
- var z = greaterThan.next;
- var closeBrace = z.next;
- expect(closeBrace.next.isEof, isTrue);
+ BeginToken lessThan = x.next as BeginToken;
+ BeginToken openBrace = lessThan.next as BeginToken;
+ var y = openBrace.next!;
+ var greaterThan = y.next!;
+ var z = greaterThan.next!;
+ var closeBrace = z.next!;
+ expect(closeBrace.next!.isEof, isTrue);
expect(lessThan.endGroup, isNull);
expect(openBrace.endGroup, same(closeBrace));
}
@@ -684,14 +682,14 @@
void test_match_angle_brackets_interrupted_by_open_bracket() {
// A "[" appearing in the token stream interrupts matching of "<" and ">".
var x = scan('x<y[z>a]');
- BeginToken lessThan = x.next;
- var y = lessThan.next;
- BeginToken openBracket = y.next;
- var z = openBracket.next;
- var greaterThan = z.next;
- var a = greaterThan.next;
- var closeBracket = a.next;
- expect(closeBracket.next.isEof, isTrue);
+ BeginToken lessThan = x.next as BeginToken;
+ var y = lessThan.next!;
+ BeginToken openBracket = y.next as BeginToken;
+ var z = openBracket.next!;
+ var greaterThan = z.next!;
+ var a = greaterThan.next!;
+ var closeBracket = a.next!;
+ expect(closeBracket.next!.isEof, isTrue);
expect(lessThan.endGroup, isNull);
expect(openBracket.endGroup, same(closeBracket));
}
@@ -699,29 +697,29 @@
void test_match_angle_brackets_interrupted_by_open_paren() {
// A "(" appearing in the token stream interrupts matching of "<" and ">".
var x = scan('x<y(z>a)');
- BeginToken lessThan = x.next;
- var y = lessThan.next;
- BeginToken openParen = y.next;
- var z = openParen.next;
- var greaterThan = z.next;
- var a = greaterThan.next;
- var closeParen = a.next;
- expect(closeParen.next.isEof, isTrue);
+ BeginToken lessThan = x.next as BeginToken;
+ var y = lessThan.next!;
+ BeginToken openParen = y.next as BeginToken;
+ var z = openParen.next!;
+ var greaterThan = z.next!;
+ var a = greaterThan.next!;
+ var closeParen = a.next!;
+ expect(closeParen.next!.isEof, isTrue);
expect(lessThan.endGroup, isNull);
expect(openParen.endGroup, same(closeParen));
}
void test_match_angle_brackets_nested() {
var x = scan('x<y<z>,a>');
- BeginToken lessThan1 = x.next;
- var y = lessThan1.next;
- BeginToken lessThan2 = y.next;
- var z = lessThan2.next;
- var greaterThan1 = z.next;
- var comma = greaterThan1.next;
- var a = comma.next;
- var greaterThan2 = a.next;
- expect(greaterThan2.next.isEof, isTrue);
+ BeginToken lessThan1 = x.next as BeginToken;
+ var y = lessThan1.next!;
+ BeginToken lessThan2 = y.next as BeginToken;
+ var z = lessThan2.next!;
+ var greaterThan1 = z.next!;
+ var comma = greaterThan1.next!;
+ var a = comma.next!;
+ var greaterThan2 = a.next!;
+ expect(greaterThan2.next!.isEof, isTrue);
expect(lessThan1.endGroup, same(greaterThan2));
expect(lessThan2.endGroup, same(greaterThan1));
}
@@ -730,11 +728,11 @@
// When a ">>" appears in the token stream and there is no outer "<",
// Fasta's scanner leaves the inner "<" unmatched.
var x = scan('x<y>>z');
- BeginToken lessThan = x.next;
- var y = lessThan.next;
- var greaterThans = y.next;
- var z = greaterThans.next;
- expect(z.next.isEof, isTrue);
+ BeginToken lessThan = x.next as BeginToken;
+ var y = lessThan.next!;
+ var greaterThans = y.next!;
+ var z = greaterThans.next!;
+ expect(z.next!.isEof, isTrue);
expect(lessThan.endGroup, isNull);
}
}
@@ -755,7 +753,7 @@
/// Scanner tests that exercise the Fasta scanner directly.
@reflectiveTest
class ScannerTest_Fasta_Direct extends ScannerTest_Fasta_Base {
- fasta.LanguageVersionToken languageVersion;
+ fasta.LanguageVersionToken? languageVersion;
void languageVersionChanged(
Scanner scanner, fasta.LanguageVersionToken languageVersion) {
@@ -773,7 +771,7 @@
final Token first = result.tokens;
Token token = first;
while (!token.isEof) {
- Token next = token.next;
+ Token next = token.next!;
expect(token.next, next);
expect(next.previous, token);
if (next.isSynthetic && [')', ']', '}'].contains(next.lexeme)) {
@@ -802,8 +800,8 @@
import 'foo.dart';
main() {}
''');
- expect(languageVersion.major, 2);
- expect(languageVersion.minor, 3);
+ expect(languageVersion!.major, 2);
+ expect(languageVersion!.minor, 3);
expectComments(
result.tokens,
[
@@ -819,8 +817,8 @@
// @dart = 2.3
main() {}
''');
- expect(languageVersion.major, 2);
- expect(languageVersion.minor, 3);
+ expect(languageVersion!.major, 2);
+ expect(languageVersion!.minor, 3);
expectComments(result.tokens, ['// @dart = 2.3'], 0);
}
@@ -838,8 +836,8 @@
// @dart = 2.3
main() {}
''', includeComments: false);
- expect(languageVersion.major, 2);
- expect(languageVersion.minor, 3);
+ expect(languageVersion!.major, 2);
+ expect(languageVersion!.minor, 3);
expectComments(result.tokens, [], -1);
}
@@ -849,8 +847,8 @@
import 'foo.dart';
main() {}
''');
- expect(languageVersion.major, 2);
- expect(languageVersion.minor, 3);
+ expect(languageVersion!.major, 2);
+ expect(languageVersion!.minor, 3);
expectComments(result.tokens, ['// @dart = 2.3'], 0);
}
@@ -861,9 +859,9 @@
import 'foo.dart';
main() {}
''');
- expect(languageVersion.major, 2);
- expect(languageVersion.minor, 3);
- expectComments(result.tokens.next, ['// @dart = 2.3'], 0);
+ expect(languageVersion!.major, 2);
+ expect(languageVersion!.minor, 3);
+ expectComments(result.tokens.next!, ['// @dart = 2.3'], 0);
}
void test_languageVersion_beforeLibrary() {
@@ -872,8 +870,8 @@
library foo;
main() {}
''');
- expect(languageVersion.major, 2);
- expect(languageVersion.minor, 3);
+ expect(languageVersion!.major, 2);
+ expect(languageVersion!.minor, 3);
expectComments(result.tokens, ['// @dart = 2.3'], 0);
}
@@ -883,8 +881,8 @@
library foo;
main() {}
''');
- expect(languageVersion.major, 2);
- expect(languageVersion.minor, 3);
+ expect(languageVersion!.major, 2);
+ expect(languageVersion!.minor, 3);
expectComments(result.tokens, ['// @dart=2.3'], 0);
}
@@ -935,14 +933,14 @@
expect(token.charOffset, 14, reason: 'error token : $token, ${token.type}');
expect(token.charCount, 3, reason: 'error token : $token, ${token.type}');
- token = token.next;
+ token = token.next!;
expect(token.lexeme, 'var');
int index = 0;
while (!token.isEof) {
expect(token.charOffset, lineStarts[index],
reason: 'token # $index : $token, ${token.type}');
++index;
- token = token.next;
+ token = token.next!;
}
}
@@ -955,21 +953,21 @@
expect(token, const TypeMatcher<ErrorToken>());
expect(token.charOffset, 14, reason: 'token # 0 : $token, ${token.type}');
- token = token.next;
+ token = token.next!;
expect(token.lexeme, 'var');
int index = 0;
while (!token.isEof) {
expect(token.charOffset, lineStarts[index],
reason: 'token # $index : $token, ${token.type}');
++index;
- token = token.next;
+ token = token.next!;
}
}
void expectComments(
- Token token, List<String> expectedComments, int versionIndex) {
+ Token? token, List<String> expectedComments, int versionIndex) {
int index = 0;
- token = token.precedingComments;
+ token = token!.precedingComments;
while (token != null) {
if (index == versionIndex) {
if (token is! fasta.LanguageVersionToken) {
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 99bfae9..fcf3a64 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -723,6 +723,8 @@
lz
m
macos
+macro
+macros
maintaining
mangled
manipulation
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index e6c4cf0..86bfe96 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -643,6 +643,8 @@
lookahead
loopback
mac
+macro
+macros
maker
matters
mds
diff --git a/pkg/front_end/test/spell_checking_utils.dart b/pkg/front_end/test/spell_checking_utils.dart
index c560644..19347ef 100644
--- a/pkg/front_end/test/spell_checking_utils.dart
+++ b/pkg/front_end/test/spell_checking_utils.dart
@@ -51,13 +51,13 @@
}
}
if (!found) {
- wrongWords ??= <String>[];
+ wrongWords ??= [];
wrongWords.add(word);
- wrongWordsAlternatives ??= <List<String>>[];
+ wrongWordsAlternatives ??= [];
wrongWordsAlternatives.add(findAlternatives(word, dictionariesUnpacked));
- wrongWordsOffset ??= <int>[];
+ wrongWordsOffset ??= [];
wrongWordsOffset.add(offset);
- wrongWordDenylisted ??= <bool>[];
+ wrongWordDenylisted ??= [];
wrongWordDenylisted
.add(loadedDictionaries![Dictionaries.denylist]!.contains(word));
}
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index cc90a5b..3e12d26 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -466,6 +466,7 @@
"test/extensions/data/",
"test/id_testing/data/",
"test/language_versioning/data/",
+ "test/macros/data/",
"test/patching/data",
"test/predicates/data",
"test/static_types/data/",
diff --git a/tools/VERSION b/tools/VERSION
index dce1906..fdf498a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 16
PATCH 0
-PRERELEASE 35
+PRERELEASE 36
PRERELEASE_PATCH 0
\ No newline at end of file