[cfe] Support class member augmentation directly

This adds direct support for class member augmentation, including checks
that the 'augment' modifier is used correctly. Different from the patch
member support, non-augment members added in augment classes are now
part of the interface of the class and can therefore be used outside
the augmentation library.

The CL includes support for using the 'import augment' syntax to import
libraries as augmentation libraries. The enable direct testing of the
augmentation features in expectation tests.

Change-Id: I9961e15862dba827050bec4aceb7dfc45e053d7d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/234520
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther
2022-02-28 15:07:18 +00:00
committed by Commit Bot
parent fbfea6e022
commit 345dfd34ac
24 changed files with 953 additions and 36 deletions
@@ -7814,6 +7814,46 @@ Message _withArgumentsNonAsciiWhitespace(int codePoint) {
arguments: {'unicode': codePoint});
}
// 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;
@@ -10394,6 +10434,35 @@ const MessageCode messageUnexpectedTokens = const MessageCode(
index: 123,
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 =
@@ -1374,7 +1374,7 @@ class ClassMembersNodeBuilder {
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) {
+14
View File
@@ -809,6 +809,15 @@ mixin ErroneousMemberBuilderMixin implements SourceMemberBuilder {
@override
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 @@ mixin ErroneousMemberBuilderMixin implements SourceMemberBuilder {
SourceLibraryBuilder library, TypeEnvironment typeEnvironment) {
assert(false, "Unexpected call to $runtimeType.checkVariance.");
}
@override
bool get isAugmentation {
throw new UnsupportedError('AmbiguousMemberBuilder.isAugmentation');
}
}
class AmbiguousMemberBuilder extends AmbiguousBuilder
@@ -158,15 +158,17 @@ class SourceClassBuilder extends ClassBuilderImpl
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 @@ class SourceClassBuilder extends ClassBuilderImpl
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 @@ class SourceClassBuilder extends ClassBuilderImpl
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) {
@@ -798,7 +798,10 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
}
} 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(
@@ -321,7 +321,8 @@ class SourceLoader extends Loader {
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 @@ class SourceLoader extends Loader {
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 @@ class SourceLoader extends Loader {
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 @@ class SourceLoader extends Loader {
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 @@ class SourceLoader extends Loader {
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 @@ class SourceLoader extends Loader {
{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 @@ class SourceLoader extends Loader {
fileUri,
origin as SourceLibraryBuilder?,
referencesFrom,
referenceIsPartOwner);
referenceIsPartOwner,
isAugmentation);
}
_builders[uri] = libraryBuilder;
}
@@ -14,6 +14,7 @@ import '../builder/declaration_builder.dart';
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 @@ abstract class SourceMemberBuilder implements MemberBuilder {
/// 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 @@ mixin SourceMemberBuilderMixin implements SourceMemberBuilder {
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 @@ abstract class SourceMemberBuilderImpl extends MemberBuilderImpl
bool get isRedirectingGenerativeConstructor => false;
@override
bool get isAugmentation => modifiers & augmentMask != 0;
bool? _isConflictingSetter;
@override
@@ -81,6 +105,20 @@ abstract class SourceMemberBuilderImpl extends MemberBuilderImpl
_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);
+4
View File
@@ -644,6 +644,8 @@ NonAgnosticConstant/analyzerCode: Fail
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/analyzerCode: Fail
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
+12
View File
@@ -5507,3 +5507,15 @@ EnumImplementerContainsValuesDeclaration:
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
@@ -15,8 +15,10 @@ class Macro2 implements ClassDeclarationsMacro {
@override
FutureOr<void> buildDeclarationsForClass(ClassDeclaration clazz,
ClassMemberDeclarationBuilder builder) {
builder.declareInClass(new DeclarationCode.fromString('''
if (isMacro) {
builder.declareInClass(new DeclarationCode.fromString('''
hasMacro() => true;
'''));
}
}
}
@@ -12,7 +12,7 @@ class A extends core::Object {
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 @@ class B extends core::Object {
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}})";
}
}
@@ -16,6 +16,9 @@ adjusting
api
argument(s)
assigning
augment
augmentation
augmented
b
c
compilercontext.runincontext
@@ -41,6 +41,7 @@ asserter
assure
asterisk
atomic
augmented
auth
authority
autobianchi
@@ -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);
}
@@ -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;
}
@@ -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;
}
@@ -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() {}
@@ -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;
}
@@ -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;
}
@@ -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
;
@@ -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;
}
@@ -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;
}
@@ -162,6 +162,7 @@ late_lowering/override_getter_setter: FormatterCrash
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
+4 -2
View File
@@ -918,7 +918,8 @@ class DocTestSourceLoader extends SourceLoader {
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 @@ class DocTestSourceLoader extends SourceLoader {
packageLanguageVersion: packageLanguageVersion,
origin: origin,
referencesFrom: referencesFrom,
referenceIsPartOwner: referenceIsPartOwner);
referenceIsPartOwner: referenceIsPartOwner,
isAugmentation: isAugmentation);
}
}