Version 2.17.0-154.0.dev
Merge commit 'f8ef1b7f427371e62297b60a18eb96ede01464fa' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3be94d5..d06a699 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -84,6 +84,16 @@
The standalone `dartdoc` tool has been removed as
previously announced. Its replacement is the `dart doc` command.
+- The template names used in the `dart create` command have been simplified,
+ and the current template names are now the set shown below. (Note: for
+ backwards compatibility the former template names can still be used.)
+```
+ [console] (default) A command-line application.
+ [package] A package containing shared Dart libraries.
+ [server-shelf] A server app using package:shelf.
+ [web] A web app that uses only core Dart libraries.
+```
+
## 2.16.1 - 2022-02-09
This is a patch release that fixes an AOT precompiler crash when building some
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index 7248789..779de84 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -7815,6 +7815,46 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ String
+ name)> templateNonAugmentationClassMemberConflict = const Template<
+ Message Function(String name)>(
+ problemMessageTemplate:
+ r"""Member '#name' conflicts with an existing member of the same name in the augmented class.""",
+ correctionMessageTemplate:
+ r"""Try changing the name to an existing member or adding an 'augment' modifier.""",
+ withArguments: _withArgumentsNonAugmentationClassMemberConflict);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)>
+ codeNonAugmentationClassMemberConflict =
+ const Code<Message Function(String name)>(
+ "NonAugmentationClassMemberConflict",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsNonAugmentationClassMemberConflict(String name) {
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ return new Message(codeNonAugmentationClassMemberConflict,
+ problemMessage:
+ """Member '${name}' conflicts with an existing member of the same name in the augmented class.""",
+ correctionMessage: """Try changing the name to an existing member or adding an 'augment' modifier.""",
+ arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeNonAugmentationClassMemberConflictCause =
+ messageNonAugmentationClassMemberConflictCause;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageNonAugmentationClassMemberConflictCause =
+ const MessageCode("NonAugmentationClassMemberConflictCause",
+ severity: Severity.context,
+ problemMessage: r"""This is the existing member.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeNonConstConstructor = messageNonConstConstructor;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -10395,6 +10435,35 @@
problemMessage: r"""Unexpected tokens.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ String
+ name)> templateUnmatchedAugmentationClassMember = const Template<
+ Message Function(String name)>(
+ problemMessageTemplate:
+ r"""Augmentation member '#name' doesn't match a member in the augmented class.""",
+ correctionMessageTemplate:
+ r"""Try changing the name to an existing member or removing the 'augment' modifier.""",
+ withArguments: _withArgumentsUnmatchedAugmentationClassMember);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeUnmatchedAugmentationClassMember =
+ const Code<Message Function(String name)>(
+ "UnmatchedAugmentationClassMember",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsUnmatchedAugmentationClassMember(String name) {
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ return new Message(codeUnmatchedAugmentationClassMember,
+ problemMessage:
+ """Augmentation member '${name}' doesn't match a member in the augmented class.""",
+ correctionMessage: """Try changing the name to an existing member or removing the 'augment' modifier.""",
+ arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String string, Token token)>
templateUnmatchedToken =
const Template<Message Function(String string, Token token)>(
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index f67b886..f64f323 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -450,7 +450,13 @@
// Add in any snippets.
final snippetsEnabled =
server.clientConfiguration.forResource(unit.path).enableSnippets;
- if (capabilities.completionSnippets && snippetsEnabled) {
+ // We can only produce edits with edit builders for files inside
+ // the root, so skip snippets entirely if not.
+ final isEditableFile =
+ unit.session.analysisContext.contextRoot.isAnalyzed(unit.path);
+ if (capabilities.completionSnippets &&
+ snippetsEnabled &&
+ isEditableFile) {
results.addAll(await _getDartSnippetItems(
clientCapabilities: capabilities,
unit: unit,
diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
index 565b9a8..5aaf8ad 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
@@ -52,7 +52,9 @@
}
// method
var field = element.variable;
- if (field is FieldElement && field.enclosingElement is ClassElement) {
+ if (field is FieldElement &&
+ (field.enclosingElement is ClassElement ||
+ field.enclosingElement is ExtensionElement)) {
var elements = await getHierarchyMembers(searchEngine, field);
await Future.forEach(elements, (ClassMemberElement member) async {
if (member is FieldElement) {
diff --git a/pkg/analysis_server/lib/src/services/snippets/dart/flutter_snippet_producers.dart b/pkg/analysis_server/lib/src/services/snippets/dart/flutter_snippet_producers.dart
index b5e210a..1a6a9ec 100644
--- a/pkg/analysis_server/lib/src/services/snippets/dart/flutter_snippet_producers.dart
+++ b/pkg/analysis_server/lib/src/services/snippets/dart/flutter_snippet_producers.dart
@@ -29,7 +29,7 @@
return false;
}
- return true;
+ return super.isValid();
}
Future<ClassElement?> _getClass(String name) =>
@@ -152,7 +152,7 @@
return Snippet(
prefix,
label,
- 'Insert a StatelessWidget',
+ 'Insert a StatefulWidget',
builder.sourceChange,
);
}
diff --git a/pkg/analysis_server/lib/src/services/snippets/dart/snippet_manager.dart b/pkg/analysis_server/lib/src/services/snippets/dart/snippet_manager.dart
index e3c1588..34dc40b 100644
--- a/pkg/analysis_server/lib/src/services/snippets/dart/snippet_manager.dart
+++ b/pkg/analysis_server/lib/src/services/snippets/dart/snippet_manager.dart
@@ -184,5 +184,10 @@
Future<Snippet> compute();
- Future<bool> isValid();
+ Future<bool> isValid() async {
+ // File edit builders will not produce edits for files outside of the
+ // analysis roots so we should not try to produce any snippets.
+ final analysisContext = request.analysisSession.analysisContext;
+ return analysisContext.contextRoot.isAnalyzed(request.filePath);
+ }
}
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
index f77603ba..d22c4da 100644
--- a/pkg/analysis_server/test/lsp/completion_dart_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -2622,6 +2622,19 @@
FlutterStatelessWidgetSnippetProducer.prefix,
);
}
+
+ Future<void> test_snippets_flutterStateless_outsideAnalysisRoot() async {
+ final content = '''
+stle^
+''';
+
+ await initializeWithSnippetSupportAndPreviewFlag();
+ final otherFileUri = Uri.file('/other/file.dart');
+ await openFile(otherFileUri, withoutMarkers(content));
+ final res = await getCompletion(otherFileUri, positionFromMarker(content));
+ final snippetItems = res.where((c) => c.kind == CompletionItemKind.Snippet);
+ expect(snippetItems, hasLength(0));
+ }
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
index 8b090db..ee79e97 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
@@ -20,6 +20,28 @@
@override
late ConvertGetterToMethodRefactoring refactoring;
+ Future<void> test_change_extensionMethod() async {
+ await indexTestUnit('''
+extension A on String {
+ int get test => 1;
+}
+void f(String a) {
+ var va = a.test;
+}
+''');
+ var element = findElement.getter('test', of: 'A');
+ _createRefactoringForElement(element);
+ // apply refactoring
+ return _assertSuccessfulRefactoring('''
+extension A on String {
+ int test() => 1;
+}
+void f(String a) {
+ var va = a.test();
+}
+''');
+ }
+
Future<void> test_change_function() async {
await indexTestUnit('''
int get test => 42;
diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart
index f93f47e..e4a2839 100644
--- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart
@@ -1374,7 +1374,7 @@
if (classBuilder is SourceClassBuilder && !declaredMember.isStatic) {
assert(
declaredMember.isSourceDeclaration &&
- declaredMember.classBuilder == classBuilder,
+ declaredMember.classBuilder.origin == classBuilder,
"Only declared members can override: ${declaredMember}");
hasDeclaredMembers = true;
if (declaredMember.isProperty) {
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index ef90973..ab0037c 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -810,6 +810,15 @@
bool get isConflictingSetter => false;
@override
+ bool get isConflictingAugmentationMember => false;
+
+ @override
+ void set isConflictingAugmentationMember(bool value) {
+ throw new UnsupportedError(
+ 'AmbiguousMemberBuilder.isConflictingAugmentationMember=');
+ }
+
+ @override
void set parent(Builder? value) {
throw new UnsupportedError('AmbiguousMemberBuilder.parent=');
}
@@ -861,6 +870,11 @@
SourceLibraryBuilder library, TypeEnvironment typeEnvironment) {
assert(false, "Unexpected call to $runtimeType.checkVariance.");
}
+
+ @override
+ bool get isAugmentation {
+ throw new UnsupportedError('AmbiguousMemberBuilder.isAugmentation');
+ }
}
class AmbiguousMemberBuilder extends AmbiguousBuilder
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 102db7f..f24406d 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -158,15 +158,17 @@
void buildBuilders(String name, Builder? declaration) {
while (declaration != null) {
if (declaration.parent != this) {
- if (fileUri != declaration.parent?.fileUri) {
- unexpected("$fileUri", "${declaration.parent?.fileUri}", charOffset,
- fileUri);
- } else {
- unexpected(
- fullNameForErrors,
- declaration.parent?.fullNameForErrors ?? '',
- charOffset,
- fileUri);
+ if (declaration.parent?.origin != this) {
+ if (fileUri != declaration.parent?.fileUri) {
+ unexpected("$fileUri", "${declaration.parent?.fileUri}",
+ charOffset, fileUri);
+ } else {
+ unexpected(
+ fullNameForErrors,
+ declaration.parent?.fullNameForErrors ?? '',
+ charOffset,
+ fileUri);
+ }
}
} else if (declaration is SourceMemberBuilder) {
SourceMemberBuilder memberBuilder = declaration;
@@ -175,7 +177,8 @@
member.parent = cls;
if (!memberBuilder.isPatch &&
!memberBuilder.isDuplicate &&
- !memberBuilder.isConflictingSetter) {
+ !memberBuilder.isConflictingSetter &&
+ !memberBuilder.isConflictingAugmentationMember) {
if (member is Procedure) {
cls.addProcedure(member);
} else if (member is Field) {
@@ -602,21 +605,71 @@
if (patch is SourceClassBuilder) {
patch.actualOrigin = this;
(_patches ??= []).add(patch);
- // TODO(ahe): Complain if `patch.supertype` isn't null.
- scope.forEachLocalMember((String name, Builder member) {
- Builder? memberPatch =
- patch.scope.lookupLocalMember(name, setter: false);
- if (memberPatch != null) {
- member.applyPatch(memberPatch);
+
+ void applyAugmentation(String name, SourceMemberBuilder patchMember,
+ {required bool setter}) {
+ Builder? originMember = scope.lookupLocalMember(name, setter: setter);
+ if (patch.isAugmentation) {
+ if (originMember != null) {
+ if (patchMember.isAugmentation) {
+ originMember.applyPatch(patchMember);
+ } else {
+ patchMember.isConflictingAugmentationMember = true;
+ library.addProblem(
+ templateNonAugmentationClassMemberConflict
+ .withArguments(name),
+ patchMember.charOffset,
+ name.length,
+ patchMember.fileUri,
+ context: [
+ messageNonAugmentationClassMemberConflictCause.withLocation(
+ originMember.fileUri!,
+ originMember.charOffset,
+ name.length)
+ ]);
+ }
+ } else {
+ if (patchMember.isAugmentation) {
+ library.addProblem(
+ templateUnmatchedAugmentationClassMember.withArguments(name),
+ patchMember.charOffset,
+ name.length,
+ patchMember.fileUri);
+ } else {
+ scope.addLocalMember(name, patchMember, setter: setter);
+ }
+ }
+ } else {
+ if (originMember != null) {
+ // Patch class implicitly assume matching members are patch
+ // members.
+ originMember.applyPatch(patchMember);
+ } else {
+ // Members injected into patch are not part of the origin scope.
+ }
+ }
+ }
+
+ patch.scope.forEachLocalMember((String name, Builder patchMember) {
+ if (patchMember is SourceMemberBuilder) {
+ applyAugmentation(name, patchMember, setter: false);
+ } else {
+ assert(false,
+ "Unexpected member ${patchMember} (${patchMember.runtimeType})");
}
});
- scope.forEachLocalSetter((String name, Builder member) {
- Builder? memberPatch =
- patch.scope.lookupLocalMember(name, setter: true);
- if (memberPatch != null) {
- member.applyPatch(memberPatch);
+
+ patch.scope.forEachLocalSetter((String name, Builder patchMember) {
+ if (patchMember is SourceMemberBuilder) {
+ applyAugmentation(name, patchMember, setter: true);
+ } else {
+ assert(false,
+ "Unexpected member ${patchMember} (${patchMember.runtimeType})");
}
});
+
+ // TODO(johnniwinther): Should we support constructor augmentation?
+ // Currently the syntax doesn't allow it.
constructors.local.forEach((String name, Builder member) {
Builder? memberPatch = patch.constructors.local[name];
if (memberPatch != null) {
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index bb1a2546..ce1548c 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -798,7 +798,10 @@
}
} else {
resolvedUri = resolve(this.importUri, uri, uriOffset);
- builder = loader.read(resolvedUri, uriOffset, accessor: this);
+ builder = loader.read(resolvedUri, uriOffset,
+ origin: isAugmentationImport ? this : null,
+ accessor: this,
+ isAugmentation: isAugmentationImport);
}
imports.add(new Import(
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 68f2d84..257a4b8 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -321,7 +321,8 @@
required LanguageVersion packageLanguageVersion,
SourceLibraryBuilder? origin,
Library? referencesFrom,
- bool? referenceIsPartOwner}) {
+ bool? referenceIsPartOwner,
+ bool isAugmentation: false}) {
return new SourceLibraryBuilder(
importUri: importUri,
fileUri: fileUri,
@@ -334,7 +335,7 @@
isUnsupported: origin?.library.isUnsupported ??
importUri.isScheme('dart') &&
!target.uriTranslator.isLibrarySupported(importUri.path),
- isAugmentation: false);
+ isAugmentation: isAugmentation);
}
/// Return `"true"` if the [dottedName] is a 'dart.library.*' qualifier for a
@@ -364,7 +365,8 @@
Uri? fileUri,
SourceLibraryBuilder? origin,
Library? referencesFrom,
- bool? referenceIsPartOwner) {
+ bool? referenceIsPartOwner,
+ bool isAugmentation) {
if (fileUri != null &&
(fileUri.isScheme("dart") ||
fileUri.isScheme("package") ||
@@ -444,7 +446,8 @@
packageLanguageVersion: packageLanguageVersion,
origin: origin,
referencesFrom: referencesFrom,
- referenceIsPartOwner: referenceIsPartOwner);
+ referenceIsPartOwner: referenceIsPartOwner,
+ isAugmentation: isAugmentation);
if (packageLanguageVersionProblem != null) {
libraryBuilder.addPostponedProblem(
packageLanguageVersionProblem, 0, noLength, libraryBuilder.fileUri);
@@ -556,12 +559,14 @@
required LibraryBuilder accessor,
LibraryBuilder? origin,
Library? referencesFrom,
- bool? referenceIsPartOwner}) {
+ bool? referenceIsPartOwner,
+ bool isAugmentation: false}) {
LibraryBuilder libraryBuilder = _read(uri,
fileUri: fileUri,
origin: origin,
referencesFrom: referencesFrom,
- referenceIsPartOwner: referenceIsPartOwner);
+ referenceIsPartOwner: referenceIsPartOwner,
+ isAugmentation: isAugmentation);
libraryBuilder.recordAccess(charOffset, noLength, accessor.fileUri);
if (!_hasLibraryAccess(imported: uri, importer: accessor.importUri) &&
!accessor.isPatch) {
@@ -617,7 +622,8 @@
{Uri? fileUri,
LibraryBuilder? origin,
Library? referencesFrom,
- bool? referenceIsPartOwner}) {
+ bool? referenceIsPartOwner,
+ bool isAugmentation: false}) {
LibraryBuilder? libraryBuilder = _builders[uri];
if (libraryBuilder == null) {
if (target.dillTarget.isLoaded) {
@@ -629,7 +635,8 @@
fileUri,
origin as SourceLibraryBuilder?,
referencesFrom,
- referenceIsPartOwner);
+ referenceIsPartOwner,
+ isAugmentation);
}
_builders[uri] = libraryBuilder;
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_member_builder.dart b/pkg/front_end/lib/src/fasta/source/source_member_builder.dart
index fcdfb76..f4cf938 100644
--- a/pkg/front_end/lib/src/fasta/source/source_member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_member_builder.dart
@@ -14,6 +14,7 @@
import '../builder/library_builder.dart';
import '../builder/member_builder.dart';
import '../kernel/kernel_helper.dart';
+import '../modifier.dart';
import '../problems.dart' show unsupported;
import '../source/source_library_builder.dart';
import '../type_inference/type_inference_engine.dart'
@@ -42,6 +43,14 @@
/// Checks the signature types of this member.
void checkTypes(
SourceLibraryBuilder library, TypeEnvironment typeEnvironment);
+
+ /// Returns `true` if this member is an augmentation.
+ bool get isAugmentation;
+
+ /// Returns `true` if this member is a member declared in an augmentation
+ /// library that conflicts with a member in the origin library.
+ bool get isConflictingAugmentationMember;
+ void set isConflictingAugmentationMember(bool value);
}
mixin SourceMemberBuilderMixin implements SourceMemberBuilder {
@@ -54,6 +63,18 @@
SourceLibraryBuilder library, void Function(Member, BuiltMemberKind) f) {
assert(false, "Unexpected call to $runtimeType.buildMembers.");
}
+
+ @override
+ bool get isAugmentation => false;
+
+ @override
+ bool get isConflictingAugmentationMember => false;
+
+ @override
+ void set isConflictingAugmentationMember(bool value) {
+ assert(false,
+ "Unexpected call to $runtimeType.isConflictingAugmentationMember=");
+ }
}
abstract class SourceMemberBuilderImpl extends MemberBuilderImpl
@@ -68,6 +89,9 @@
bool get isRedirectingGenerativeConstructor => false;
+ @override
+ bool get isAugmentation => modifiers & augmentMask != 0;
+
bool? _isConflictingSetter;
@override
@@ -81,6 +105,20 @@
_isConflictingSetter = value;
}
+ bool? _isConflictingAugmentationMember;
+
+ @override
+ bool get isConflictingAugmentationMember {
+ return _isConflictingAugmentationMember ??= false;
+ }
+
+ @override
+ void set isConflictingAugmentationMember(bool value) {
+ assert(_isConflictingAugmentationMember == null,
+ '$this.isConflictingAugmentationMember has already been fixed.');
+ _isConflictingAugmentationMember = value;
+ }
+
// TODO(johnniwinther): Remove this and create a [ProcedureBuilder] interface.
@override
ProcedureKind? get kind => unsupported("kind", charOffset, fileUri);
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index b2e67dc..5ff0e55 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -644,6 +644,8 @@
NonAgnosticConstant/example: Fail
NonAsciiIdentifier/expression: Fail
NonAsciiIdentifier/part_wrapped_expression: Fail
+NonAugmentationClassMemberConflict/analyzerCode: Fail
+NonAugmentationClassMemberConflict/example: Fail
NonConstConstructor/example: Fail
NonConstFactory/example: Fail
NonInstanceTypeVariableUse/example: Fail
@@ -849,6 +851,8 @@
UndefinedExtensionSetter/example: Fail
UnexpectedToken/part_wrapped_script1: Fail
UnexpectedToken/script1: Fail
+UnmatchedAugmentationClassMember/analyzerCode: Fail
+UnmatchedAugmentationClassMember/example: Fail
UnmatchedToken/part_wrapped_script1: Fail
UnmatchedToken/part_wrapped_script3: Fail
UnmatchedToken/script1: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index b3403f3..8e6f415 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -5507,3 +5507,15 @@
MacroClassNotDeclaredMacro:
problemMessage: "Non-abstract class '#name' implements 'Macro' but isn't declared as a macro class."
correctionMessage: "Try adding the 'macro' class modifier."
+
+UnmatchedAugmentationClassMember:
+ problemMessage: "Augmentation member '#name' doesn't match a member in the augmented class."
+ correctionMessage: "Try changing the name to an existing member or removing the 'augment' modifier."
+
+NonAugmentationClassMemberConflict:
+ problemMessage: "Member '#name' conflicts with an existing member of the same name in the augmented class."
+ correctionMessage: "Try changing the name to an existing member or adding an 'augment' modifier."
+
+NonAugmentationClassMemberConflictCause:
+ problemMessage: "This is the existing member."
+ severity: CONTEXT
diff --git a/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro2.dart b/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro2.dart
index a444cf0..6173f58 100644
--- a/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro2.dart
+++ b/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro2.dart
@@ -15,8 +15,10 @@
@override
FutureOr<void> buildDeclarationsForClass(ClassDeclaration clazz,
ClassMemberDeclarationBuilder builder) {
- builder.declareInClass(new DeclarationCode.fromString('''
+ if (isMacro) {
+ builder.declareInClass(new DeclarationCode.fromString('''
hasMacro() => true;
'''));
+ }
}
}
diff --git a/pkg/front_end/test/macro_application/data/tests/to_string.dart.expect b/pkg/front_end/test/macro_application/data/tests/to_string.dart.expect
index 3a56029..68d6ea1 100644
--- a/pkg/front_end/test/macro_application/data/tests/to_string.dart.expect
+++ b/pkg/front_end/test/macro_application/data/tests/to_string.dart.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- method /* from org-dartlang-augmentation:/a/b/c/main.dart-0 */ toString() → dynamic {
+ method /* from org-dartlang-augmentation:/a/b/c/main.dart-0 */ toString() → core::String {
return "A(a=${this.{self::A::a}{dynamic}},b=${this.{self::A::b}{dynamic}})";
}
}
@@ -24,7 +24,7 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- method /* from org-dartlang-augmentation:/a/b/c/main.dart-1 */ toString() → dynamic {
+ method /* from org-dartlang-augmentation:/a/b/c/main.dart-1 */ toString() → core::String {
return "B(c=${this.{self::B::c}{dynamic}},d=${this.{self::B::d}{dynamic}},e=${this.{self::B::e}{dynamic}})";
}
}
diff --git a/pkg/front_end/test/spell_checking_list_messages.txt b/pkg/front_end/test/spell_checking_list_messages.txt
index e6964cd..664608e 100644
--- a/pkg/front_end/test/spell_checking_list_messages.txt
+++ b/pkg/front_end/test/spell_checking_list_messages.txt
@@ -16,6 +16,9 @@
api
argument(s)
assigning
+augment
+augmentation
+augmented
b
c
compilercontext.runincontext
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 7313d71..0a0575a 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -41,6 +41,7 @@
assure
asterisk
atomic
+augmented
auth
authority
autobianchi
diff --git a/pkg/front_end/testcases/macros/class_members.dart b/pkg/front_end/testcases/macros/class_members.dart
new file mode 100644
index 0000000..12aa818
--- /dev/null
+++ b/pkg/front_end/testcases/macros/class_members.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2022, 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 augment 'class_members_lib.dart';
+
+class Class {
+ void existingMethod() {
+ print('existingMethod-origin');
+ }
+
+ external void augmentedMethod();
+
+ void set existingSetter(_) {
+ print('existingSetter-origin');
+ }
+
+ external void set augmentedSetter(_);
+}
+
+test(Class c) {
+ c.orphanedMethod();
+ c.orphanedSetter = 0;
+}
+
+main() {
+ Class c = new Class();
+ c.augmentedMethod();
+ c.injectedMethod();
+ c.existingMethod();
+
+ c.augmentedSetter = 0;
+ c.injectedSetter = 0;
+ c.existingSetter = 0;
+
+ injectedMethod(c);
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/macros/class_members.dart.strong.expect b/pkg/front_end/testcases/macros/class_members.dart.strong.expect
new file mode 100644
index 0000000..52ceeba
--- /dev/null
+++ b/pkg/front_end/testcases/macros/class_members.dart.strong.expect
@@ -0,0 +1,111 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:9:8: Error: Member 'existingMethod' conflicts with an existing member of the same name in the augmented class.
+// Try changing the name to an existing member or adding an 'augment' modifier.
+// void existingMethod() {
+// ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/class_members.dart:8:8: Context: This is the existing member.
+// void existingMethod() {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:15:16: Error: Augmentation member 'orphanedMethod' doesn't match a member in the augmented class.
+// Try changing the name to an existing member or removing the 'augment' modifier.
+// augment void orphanedMethod() {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:21:12: Error: Member 'existingSetter' conflicts with an existing member of the same name in the augmented class.
+// Try changing the name to an existing member or adding an 'augment' modifier.
+// void set existingSetter(_) {
+// ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/class_members.dart:14:12: Context: This is the existing member.
+// void set existingSetter(_) {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:27:20: Error: Augmentation member 'orphanedSetter' doesn't match a member in the augmented class.
+// Try changing the name to an existing member or removing the 'augment' modifier.
+// augment void set orphanedSetter(_) {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members.dart:22:5: Error: The method 'orphanedMethod' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'orphanedMethod'.
+// c.orphanedMethod();
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members.dart:23:5: Error: The setter 'orphanedSetter' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'orphanedSetter'.
+// c.orphanedSetter = 0;
+// ^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///class_members.dart";
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ method existingMethod() → void {
+ core::print("existingMethod-origin");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ augmentedMethod() → void {
+ core::print("augmentedMethod");
+ }
+ set existingSetter(dynamic _) → void {
+ core::print("existingSetter-origin");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ augmentedSetter(dynamic _) → void {
+ core::print("augmentedSetter");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ injectedMethod() → void {
+ core::print("injectedMethod");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ orphanedMethod() → void {
+ core::print("orphanedMethod");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ injectedSetter(dynamic _) → void {
+ core::print("injectedSetter");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ orphanedSetter(dynamic _) → void {
+ core::print("orphanedSetter");
+ }
+}
+static method test(self::Class c) → dynamic {
+ invalid-expression "pkg/front_end/testcases/macros/class_members.dart:22:5: Error: The method 'orphanedMethod' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'orphanedMethod'.
+ c.orphanedMethod();
+ ^^^^^^^^^^^^^^" in c{<unresolved>}.orphanedMethod();
+ invalid-expression "pkg/front_end/testcases/macros/class_members.dart:23:5: Error: The setter 'orphanedSetter' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'orphanedSetter'.
+ c.orphanedSetter = 0;
+ ^^^^^^^^^^^^^^" in c{<unresolved>}.orphanedSetter = 0;
+}
+static method main() → dynamic {
+ self::Class c = new self::Class::•();
+ c.{self::Class::augmentedMethod}(){() → void};
+ c.{self::Class::injectedMethod}(){() → void};
+ c.{self::Class::existingMethod}(){() → void};
+ c.{self::Class::augmentedSetter} = 0;
+ c.{self::Class::injectedSetter} = 0;
+ c.{self::Class::existingSetter} = 0;
+ self::injectedMethod(c);
+}
+static method /* from org-dartlang-testcase:///class_members_lib.dart */ augmentTest(self::Class c) → void {
+ c.{self::Class::orphanedMethod}(){() → void};
+ c.{self::Class::orphanedMethod}(){() → void};
+ c.{self::Class::orphanedSetter} = 0;
+}
+static method /* from org-dartlang-testcase:///class_members_lib.dart */ injectedMethod(self::Class c) → void {
+ c.{self::Class::augmentedMethod}(){() → void};
+ c.{self::Class::injectedMethod}(){() → void};
+ c.{self::Class::existingMethod}(){() → void};
+ c.{self::Class::augmentedSetter} = 0;
+ c.{self::Class::injectedSetter} = 0;
+ c.{self::Class::existingSetter} = 0;
+}
diff --git a/pkg/front_end/testcases/macros/class_members.dart.strong.transformed.expect b/pkg/front_end/testcases/macros/class_members.dart.strong.transformed.expect
new file mode 100644
index 0000000..52ceeba
--- /dev/null
+++ b/pkg/front_end/testcases/macros/class_members.dart.strong.transformed.expect
@@ -0,0 +1,111 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:9:8: Error: Member 'existingMethod' conflicts with an existing member of the same name in the augmented class.
+// Try changing the name to an existing member or adding an 'augment' modifier.
+// void existingMethod() {
+// ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/class_members.dart:8:8: Context: This is the existing member.
+// void existingMethod() {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:15:16: Error: Augmentation member 'orphanedMethod' doesn't match a member in the augmented class.
+// Try changing the name to an existing member or removing the 'augment' modifier.
+// augment void orphanedMethod() {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:21:12: Error: Member 'existingSetter' conflicts with an existing member of the same name in the augmented class.
+// Try changing the name to an existing member or adding an 'augment' modifier.
+// void set existingSetter(_) {
+// ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/class_members.dart:14:12: Context: This is the existing member.
+// void set existingSetter(_) {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:27:20: Error: Augmentation member 'orphanedSetter' doesn't match a member in the augmented class.
+// Try changing the name to an existing member or removing the 'augment' modifier.
+// augment void set orphanedSetter(_) {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members.dart:22:5: Error: The method 'orphanedMethod' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'orphanedMethod'.
+// c.orphanedMethod();
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members.dart:23:5: Error: The setter 'orphanedSetter' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'orphanedSetter'.
+// c.orphanedSetter = 0;
+// ^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///class_members.dart";
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ method existingMethod() → void {
+ core::print("existingMethod-origin");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ augmentedMethod() → void {
+ core::print("augmentedMethod");
+ }
+ set existingSetter(dynamic _) → void {
+ core::print("existingSetter-origin");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ augmentedSetter(dynamic _) → void {
+ core::print("augmentedSetter");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ injectedMethod() → void {
+ core::print("injectedMethod");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ orphanedMethod() → void {
+ core::print("orphanedMethod");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ injectedSetter(dynamic _) → void {
+ core::print("injectedSetter");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ orphanedSetter(dynamic _) → void {
+ core::print("orphanedSetter");
+ }
+}
+static method test(self::Class c) → dynamic {
+ invalid-expression "pkg/front_end/testcases/macros/class_members.dart:22:5: Error: The method 'orphanedMethod' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'orphanedMethod'.
+ c.orphanedMethod();
+ ^^^^^^^^^^^^^^" in c{<unresolved>}.orphanedMethod();
+ invalid-expression "pkg/front_end/testcases/macros/class_members.dart:23:5: Error: The setter 'orphanedSetter' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'orphanedSetter'.
+ c.orphanedSetter = 0;
+ ^^^^^^^^^^^^^^" in c{<unresolved>}.orphanedSetter = 0;
+}
+static method main() → dynamic {
+ self::Class c = new self::Class::•();
+ c.{self::Class::augmentedMethod}(){() → void};
+ c.{self::Class::injectedMethod}(){() → void};
+ c.{self::Class::existingMethod}(){() → void};
+ c.{self::Class::augmentedSetter} = 0;
+ c.{self::Class::injectedSetter} = 0;
+ c.{self::Class::existingSetter} = 0;
+ self::injectedMethod(c);
+}
+static method /* from org-dartlang-testcase:///class_members_lib.dart */ augmentTest(self::Class c) → void {
+ c.{self::Class::orphanedMethod}(){() → void};
+ c.{self::Class::orphanedMethod}(){() → void};
+ c.{self::Class::orphanedSetter} = 0;
+}
+static method /* from org-dartlang-testcase:///class_members_lib.dart */ injectedMethod(self::Class c) → void {
+ c.{self::Class::augmentedMethod}(){() → void};
+ c.{self::Class::injectedMethod}(){() → void};
+ c.{self::Class::existingMethod}(){() → void};
+ c.{self::Class::augmentedSetter} = 0;
+ c.{self::Class::injectedSetter} = 0;
+ c.{self::Class::existingSetter} = 0;
+}
diff --git a/pkg/front_end/testcases/macros/class_members.dart.textual_outline.expect b/pkg/front_end/testcases/macros/class_members.dart.textual_outline.expect
new file mode 100644
index 0000000..c5c8d44
--- /dev/null
+++ b/pkg/front_end/testcases/macros/class_members.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import augment 'class_members_lib.dart';
+class Class {
+ void existingMethod() {}
+ external void augmentedMethod();
+ void set existingSetter(_) {}
+ external void set augmentedSetter(_);
+}
+test(Class c) {}
+main() {}
diff --git a/pkg/front_end/testcases/macros/class_members.dart.weak.expect b/pkg/front_end/testcases/macros/class_members.dart.weak.expect
new file mode 100644
index 0000000..52ceeba
--- /dev/null
+++ b/pkg/front_end/testcases/macros/class_members.dart.weak.expect
@@ -0,0 +1,111 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:9:8: Error: Member 'existingMethod' conflicts with an existing member of the same name in the augmented class.
+// Try changing the name to an existing member or adding an 'augment' modifier.
+// void existingMethod() {
+// ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/class_members.dart:8:8: Context: This is the existing member.
+// void existingMethod() {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:15:16: Error: Augmentation member 'orphanedMethod' doesn't match a member in the augmented class.
+// Try changing the name to an existing member or removing the 'augment' modifier.
+// augment void orphanedMethod() {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:21:12: Error: Member 'existingSetter' conflicts with an existing member of the same name in the augmented class.
+// Try changing the name to an existing member or adding an 'augment' modifier.
+// void set existingSetter(_) {
+// ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/class_members.dart:14:12: Context: This is the existing member.
+// void set existingSetter(_) {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:27:20: Error: Augmentation member 'orphanedSetter' doesn't match a member in the augmented class.
+// Try changing the name to an existing member or removing the 'augment' modifier.
+// augment void set orphanedSetter(_) {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members.dart:22:5: Error: The method 'orphanedMethod' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'orphanedMethod'.
+// c.orphanedMethod();
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members.dart:23:5: Error: The setter 'orphanedSetter' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'orphanedSetter'.
+// c.orphanedSetter = 0;
+// ^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///class_members.dart";
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ method existingMethod() → void {
+ core::print("existingMethod-origin");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ augmentedMethod() → void {
+ core::print("augmentedMethod");
+ }
+ set existingSetter(dynamic _) → void {
+ core::print("existingSetter-origin");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ augmentedSetter(dynamic _) → void {
+ core::print("augmentedSetter");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ injectedMethod() → void {
+ core::print("injectedMethod");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ orphanedMethod() → void {
+ core::print("orphanedMethod");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ injectedSetter(dynamic _) → void {
+ core::print("injectedSetter");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ orphanedSetter(dynamic _) → void {
+ core::print("orphanedSetter");
+ }
+}
+static method test(self::Class c) → dynamic {
+ invalid-expression "pkg/front_end/testcases/macros/class_members.dart:22:5: Error: The method 'orphanedMethod' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'orphanedMethod'.
+ c.orphanedMethod();
+ ^^^^^^^^^^^^^^" in c{<unresolved>}.orphanedMethod();
+ invalid-expression "pkg/front_end/testcases/macros/class_members.dart:23:5: Error: The setter 'orphanedSetter' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'orphanedSetter'.
+ c.orphanedSetter = 0;
+ ^^^^^^^^^^^^^^" in c{<unresolved>}.orphanedSetter = 0;
+}
+static method main() → dynamic {
+ self::Class c = new self::Class::•();
+ c.{self::Class::augmentedMethod}(){() → void};
+ c.{self::Class::injectedMethod}(){() → void};
+ c.{self::Class::existingMethod}(){() → void};
+ c.{self::Class::augmentedSetter} = 0;
+ c.{self::Class::injectedSetter} = 0;
+ c.{self::Class::existingSetter} = 0;
+ self::injectedMethod(c);
+}
+static method /* from org-dartlang-testcase:///class_members_lib.dart */ augmentTest(self::Class c) → void {
+ c.{self::Class::orphanedMethod}(){() → void};
+ c.{self::Class::orphanedMethod}(){() → void};
+ c.{self::Class::orphanedSetter} = 0;
+}
+static method /* from org-dartlang-testcase:///class_members_lib.dart */ injectedMethod(self::Class c) → void {
+ c.{self::Class::augmentedMethod}(){() → void};
+ c.{self::Class::injectedMethod}(){() → void};
+ c.{self::Class::existingMethod}(){() → void};
+ c.{self::Class::augmentedSetter} = 0;
+ c.{self::Class::injectedSetter} = 0;
+ c.{self::Class::existingSetter} = 0;
+}
diff --git a/pkg/front_end/testcases/macros/class_members.dart.weak.modular.expect b/pkg/front_end/testcases/macros/class_members.dart.weak.modular.expect
new file mode 100644
index 0000000..52ceeba
--- /dev/null
+++ b/pkg/front_end/testcases/macros/class_members.dart.weak.modular.expect
@@ -0,0 +1,111 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:9:8: Error: Member 'existingMethod' conflicts with an existing member of the same name in the augmented class.
+// Try changing the name to an existing member or adding an 'augment' modifier.
+// void existingMethod() {
+// ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/class_members.dart:8:8: Context: This is the existing member.
+// void existingMethod() {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:15:16: Error: Augmentation member 'orphanedMethod' doesn't match a member in the augmented class.
+// Try changing the name to an existing member or removing the 'augment' modifier.
+// augment void orphanedMethod() {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:21:12: Error: Member 'existingSetter' conflicts with an existing member of the same name in the augmented class.
+// Try changing the name to an existing member or adding an 'augment' modifier.
+// void set existingSetter(_) {
+// ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/class_members.dart:14:12: Context: This is the existing member.
+// void set existingSetter(_) {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:27:20: Error: Augmentation member 'orphanedSetter' doesn't match a member in the augmented class.
+// Try changing the name to an existing member or removing the 'augment' modifier.
+// augment void set orphanedSetter(_) {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members.dart:22:5: Error: The method 'orphanedMethod' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'orphanedMethod'.
+// c.orphanedMethod();
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members.dart:23:5: Error: The setter 'orphanedSetter' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'orphanedSetter'.
+// c.orphanedSetter = 0;
+// ^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///class_members.dart";
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ method existingMethod() → void {
+ core::print("existingMethod-origin");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ augmentedMethod() → void {
+ core::print("augmentedMethod");
+ }
+ set existingSetter(dynamic _) → void {
+ core::print("existingSetter-origin");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ augmentedSetter(dynamic _) → void {
+ core::print("augmentedSetter");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ injectedMethod() → void {
+ core::print("injectedMethod");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ orphanedMethod() → void {
+ core::print("orphanedMethod");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ injectedSetter(dynamic _) → void {
+ core::print("injectedSetter");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ orphanedSetter(dynamic _) → void {
+ core::print("orphanedSetter");
+ }
+}
+static method test(self::Class c) → dynamic {
+ invalid-expression "pkg/front_end/testcases/macros/class_members.dart:22:5: Error: The method 'orphanedMethod' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'orphanedMethod'.
+ c.orphanedMethod();
+ ^^^^^^^^^^^^^^" in c{<unresolved>}.orphanedMethod();
+ invalid-expression "pkg/front_end/testcases/macros/class_members.dart:23:5: Error: The setter 'orphanedSetter' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'orphanedSetter'.
+ c.orphanedSetter = 0;
+ ^^^^^^^^^^^^^^" in c{<unresolved>}.orphanedSetter = 0;
+}
+static method main() → dynamic {
+ self::Class c = new self::Class::•();
+ c.{self::Class::augmentedMethod}(){() → void};
+ c.{self::Class::injectedMethod}(){() → void};
+ c.{self::Class::existingMethod}(){() → void};
+ c.{self::Class::augmentedSetter} = 0;
+ c.{self::Class::injectedSetter} = 0;
+ c.{self::Class::existingSetter} = 0;
+ self::injectedMethod(c);
+}
+static method /* from org-dartlang-testcase:///class_members_lib.dart */ augmentTest(self::Class c) → void {
+ c.{self::Class::orphanedMethod}(){() → void};
+ c.{self::Class::orphanedMethod}(){() → void};
+ c.{self::Class::orphanedSetter} = 0;
+}
+static method /* from org-dartlang-testcase:///class_members_lib.dart */ injectedMethod(self::Class c) → void {
+ c.{self::Class::augmentedMethod}(){() → void};
+ c.{self::Class::injectedMethod}(){() → void};
+ c.{self::Class::existingMethod}(){() → void};
+ c.{self::Class::augmentedSetter} = 0;
+ c.{self::Class::injectedSetter} = 0;
+ c.{self::Class::existingSetter} = 0;
+}
diff --git a/pkg/front_end/testcases/macros/class_members.dart.weak.outline.expect b/pkg/front_end/testcases/macros/class_members.dart.weak.outline.expect
new file mode 100644
index 0000000..49e7b51
--- /dev/null
+++ b/pkg/front_end/testcases/macros/class_members.dart.weak.outline.expect
@@ -0,0 +1,61 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:9:8: Error: Member 'existingMethod' conflicts with an existing member of the same name in the augmented class.
+// Try changing the name to an existing member or adding an 'augment' modifier.
+// void existingMethod() {
+// ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/class_members.dart:8:8: Context: This is the existing member.
+// void existingMethod() {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:15:16: Error: Augmentation member 'orphanedMethod' doesn't match a member in the augmented class.
+// Try changing the name to an existing member or removing the 'augment' modifier.
+// augment void orphanedMethod() {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:21:12: Error: Member 'existingSetter' conflicts with an existing member of the same name in the augmented class.
+// Try changing the name to an existing member or adding an 'augment' modifier.
+// void set existingSetter(_) {
+// ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/class_members.dart:14:12: Context: This is the existing member.
+// void set existingSetter(_) {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:27:20: Error: Augmentation member 'orphanedSetter' doesn't match a member in the augmented class.
+// Try changing the name to an existing member or removing the 'augment' modifier.
+// augment void set orphanedSetter(_) {
+// ^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///class_members.dart";
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class
+ ;
+ method existingMethod() → void
+ ;
+ external method augmentedMethod() → void;
+ set existingSetter(dynamic _) → void
+ ;
+ external set augmentedSetter(dynamic _) → void;
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ injectedMethod() → void
+ ;
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ orphanedMethod() → void
+ ;
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ injectedSetter(dynamic _) → void
+ ;
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ orphanedSetter(dynamic _) → void
+ ;
+}
+static method test(self::Class c) → dynamic
+ ;
+static method main() → dynamic
+ ;
+static method /* from org-dartlang-testcase:///class_members_lib.dart */ augmentTest(self::Class c) → void
+ ;
+static method /* from org-dartlang-testcase:///class_members_lib.dart */ injectedMethod(self::Class c) → void
+ ;
diff --git a/pkg/front_end/testcases/macros/class_members.dart.weak.transformed.expect b/pkg/front_end/testcases/macros/class_members.dart.weak.transformed.expect
new file mode 100644
index 0000000..52ceeba
--- /dev/null
+++ b/pkg/front_end/testcases/macros/class_members.dart.weak.transformed.expect
@@ -0,0 +1,111 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:9:8: Error: Member 'existingMethod' conflicts with an existing member of the same name in the augmented class.
+// Try changing the name to an existing member or adding an 'augment' modifier.
+// void existingMethod() {
+// ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/class_members.dart:8:8: Context: This is the existing member.
+// void existingMethod() {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:15:16: Error: Augmentation member 'orphanedMethod' doesn't match a member in the augmented class.
+// Try changing the name to an existing member or removing the 'augment' modifier.
+// augment void orphanedMethod() {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:21:12: Error: Member 'existingSetter' conflicts with an existing member of the same name in the augmented class.
+// Try changing the name to an existing member or adding an 'augment' modifier.
+// void set existingSetter(_) {
+// ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/class_members.dart:14:12: Context: This is the existing member.
+// void set existingSetter(_) {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members_lib.dart:27:20: Error: Augmentation member 'orphanedSetter' doesn't match a member in the augmented class.
+// Try changing the name to an existing member or removing the 'augment' modifier.
+// augment void set orphanedSetter(_) {
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members.dart:22:5: Error: The method 'orphanedMethod' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'orphanedMethod'.
+// c.orphanedMethod();
+// ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/class_members.dart:23:5: Error: The setter 'orphanedSetter' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'orphanedSetter'.
+// c.orphanedSetter = 0;
+// ^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///class_members.dart";
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ method existingMethod() → void {
+ core::print("existingMethod-origin");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ augmentedMethod() → void {
+ core::print("augmentedMethod");
+ }
+ set existingSetter(dynamic _) → void {
+ core::print("existingSetter-origin");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ augmentedSetter(dynamic _) → void {
+ core::print("augmentedSetter");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ injectedMethod() → void {
+ core::print("injectedMethod");
+ }
+ method /* from org-dartlang-testcase:///class_members_lib.dart */ orphanedMethod() → void {
+ core::print("orphanedMethod");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ injectedSetter(dynamic _) → void {
+ core::print("injectedSetter");
+ }
+ set /* from org-dartlang-testcase:///class_members_lib.dart */ orphanedSetter(dynamic _) → void {
+ core::print("orphanedSetter");
+ }
+}
+static method test(self::Class c) → dynamic {
+ invalid-expression "pkg/front_end/testcases/macros/class_members.dart:22:5: Error: The method 'orphanedMethod' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'orphanedMethod'.
+ c.orphanedMethod();
+ ^^^^^^^^^^^^^^" in c{<unresolved>}.orphanedMethod();
+ invalid-expression "pkg/front_end/testcases/macros/class_members.dart:23:5: Error: The setter 'orphanedSetter' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/macros/class_members.dart'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'orphanedSetter'.
+ c.orphanedSetter = 0;
+ ^^^^^^^^^^^^^^" in c{<unresolved>}.orphanedSetter = 0;
+}
+static method main() → dynamic {
+ self::Class c = new self::Class::•();
+ c.{self::Class::augmentedMethod}(){() → void};
+ c.{self::Class::injectedMethod}(){() → void};
+ c.{self::Class::existingMethod}(){() → void};
+ c.{self::Class::augmentedSetter} = 0;
+ c.{self::Class::injectedSetter} = 0;
+ c.{self::Class::existingSetter} = 0;
+ self::injectedMethod(c);
+}
+static method /* from org-dartlang-testcase:///class_members_lib.dart */ augmentTest(self::Class c) → void {
+ c.{self::Class::orphanedMethod}(){() → void};
+ c.{self::Class::orphanedMethod}(){() → void};
+ c.{self::Class::orphanedSetter} = 0;
+}
+static method /* from org-dartlang-testcase:///class_members_lib.dart */ injectedMethod(self::Class c) → void {
+ c.{self::Class::augmentedMethod}(){() → void};
+ c.{self::Class::injectedMethod}(){() → void};
+ c.{self::Class::existingMethod}(){() → void};
+ c.{self::Class::augmentedSetter} = 0;
+ c.{self::Class::injectedSetter} = 0;
+ c.{self::Class::existingSetter} = 0;
+}
diff --git a/pkg/front_end/testcases/macros/class_members_lib.dart b/pkg/front_end/testcases/macros/class_members_lib.dart
new file mode 100644
index 0000000..a5952d5
--- /dev/null
+++ b/pkg/front_end/testcases/macros/class_members_lib.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2022, 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.
+
+augment class Class {
+ augment void augmentedMethod() {
+ print('augmentedMethod');
+ }
+ void existingMethod() {
+ print('existingMethod-duplicate');
+ }
+ void injectedMethod() {
+ print('injectedMethod');
+ }
+ augment void orphanedMethod() {
+ print('orphanedMethod');
+ }
+ augment void set augmentedSetter(_) {
+ print('augmentedSetter');
+ }
+ void set existingSetter(_) {
+ print('existingSetter-duplicate');
+ }
+ void set injectedSetter(_) {
+ print('injectedSetter');
+ }
+ augment void set orphanedSetter(_) {
+ print('orphanedSetter');
+ }
+}
+
+void augmentTest(Class c) {
+ c.orphanedMethod();
+ c.orphanedMethod();
+ c.orphanedSetter = 0;
+}
+
+void injectedMethod(Class c) {
+ c.augmentedMethod();
+ c.injectedMethod();
+ c.existingMethod();
+
+ c.augmentedSetter = 0;
+ c.injectedSetter = 0;
+ c.existingSetter = 0;
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index afa3f8a..fbb0de5 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -162,6 +162,7 @@
late_lowering/skip_late_final_uninitialized_instance_fields/main: FormatterCrash
late_lowering/uninitialized_non_nullable_late_fields: FormatterCrash
macros/augment_class: FormatterCrash
+macros/class_members: FormatterCrash
macros/macro_class: FormatterCrash
nnbd/abstract_field_errors: FormatterCrash
nnbd/covariant_late_field: FormatterCrash
diff --git a/pkg/front_end/tool/dart_doctest_impl.dart b/pkg/front_end/tool/dart_doctest_impl.dart
index 5706ec9..544345d 100644
--- a/pkg/front_end/tool/dart_doctest_impl.dart
+++ b/pkg/front_end/tool/dart_doctest_impl.dart
@@ -918,7 +918,8 @@
required LanguageVersion packageLanguageVersion,
SourceLibraryBuilder? origin,
kernel.Library? referencesFrom,
- bool? referenceIsPartOwner}) {
+ bool? referenceIsPartOwner,
+ bool isAugmentation: false}) {
if (importUri == DocTestIncrementalCompiler.dartDocTestUri) {
HybridFileSystem hfs = target.fileSystem as HybridFileSystem;
MemoryFileSystem fs = hfs.memory;
@@ -935,6 +936,7 @@
packageLanguageVersion: packageLanguageVersion,
origin: origin,
referencesFrom: referencesFrom,
- referenceIsPartOwner: referenceIsPartOwner);
+ referenceIsPartOwner: referenceIsPartOwner,
+ isAugmentation: isAugmentation);
}
}
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 22ff2d3..360d454 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -2410,6 +2410,8 @@
Definition* replacement = current->Canonicalize(this);
ASSERT(replacement != nullptr);
+ RELEASE_ASSERT(unmatched_representations_allowed() ||
+ !replacement->HasUnmatchedInputRepresentations());
if (replacement != current) {
current->ReplaceUsesWith(replacement);
it.RemoveCurrentFromGraph();
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.cc b/runtime/vm/compiler/backend/flow_graph_checker.cc
index 140ee55..4fa26ee 100644
--- a/runtime/vm/compiler/backend/flow_graph_checker.cc
+++ b/runtime/vm/compiler/backend/flow_graph_checker.cc
@@ -333,6 +333,9 @@
}
}
}
+ ASSERT1(flow_graph_->unmatched_representations_allowed() ||
+ !instruction->HasUnmatchedInputRepresentations(),
+ instruction);
// Check all regular inputs.
for (intptr_t i = 0, n = instruction->InputCount(); i < n; ++i) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index c063152..7677166 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -676,6 +676,13 @@
Instruction* instr = it.Current();
set_current_instruction(instr);
StatsBegin(instr);
+ // Unoptimized code always stores boxed values on the expression stack.
+ // However, unboxed representation is allowed for instruction inputs and
+ // outputs of certain types (e.g. for doubles).
+ // Unboxed inputs/outputs are handled in the instruction prologue
+ // and epilogue, but flagged as a mismatch on the IL level.
+ RELEASE_ASSERT(!is_optimizing() ||
+ !instr->HasUnmatchedInputRepresentations());
if (FLAG_code_comments || FLAG_disassemble ||
FLAG_disassemble_optimized) {
diff --git a/runtime/vm/isolate_test.cc b/runtime/vm/isolate_test.cc
index 0a53fbb..dd1c919 100644
--- a/runtime/vm/isolate_test.cc
+++ b/runtime/vm/isolate_test.cc
@@ -23,7 +23,7 @@
// Test to ensure that an exception is thrown if no isolate creation
// callback has been set by the embedder when an isolate is spawned.
void IsolateSpawn(const char* platform_script_value) {
- const char* kScriptChars = OS::SCreate(
+ char* scriptChars = OS::SCreate(
nullptr,
"import 'dart:isolate';\n"
// Ignores printed lines.
@@ -40,7 +40,9 @@
"}\n",
platform_script_value);
- Dart_Handle test_lib = TestCase::LoadTestScript(kScriptChars, NULL);
+ Dart_Handle test_lib = TestCase::LoadTestScript(scriptChars, NULL);
+
+ free(scriptChars);
// Setup the internal library's 'internalPrint' function.
// Necessary because asynchronous errors use "print" to print their
diff --git a/tools/VERSION b/tools/VERSION
index 8bbd500..5169cdd 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 153
+PRERELEASE 154
PRERELEASE_PATCH 0
\ No newline at end of file