Skip to content

Commit

Permalink
Version 2.17.0-96.0.dev
Browse files Browse the repository at this point in the history
Merge commit '69396286219e8b8dd5c76e0ac22bc9734fddd5a6' into 'dev'
  • Loading branch information
Dart CI committed Feb 10, 2022
2 parents 0041431 + 6939628 commit 0005ff0
Show file tree
Hide file tree
Showing 25 changed files with 328 additions and 45 deletions.
37 changes: 36 additions & 1 deletion pkg/_fe_analyzer_shared/lib/src/macros/executor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ abstract class MacroExecutor {
/// The [resolveIdentifier] argument should return the import uri to be used
/// for that identifier.
String buildAugmentationLibrary(Iterable<MacroExecutionResult> macroResults,
Uri Function(Identifier) resolveIdentifier);
ResolvedIdentifier Function(Identifier) resolveIdentifier);

/// Tell the executor to shut down and clean up any resources it may have
/// allocated.
Expand Down Expand Up @@ -220,6 +220,41 @@ class Arguments implements Serializable {
}
}

/// A resolved [Identifier], this is used when creating augmentation libraries
/// to qualify identifiers where needed.
class ResolvedIdentifier extends Identifier {
/// The import URI for the library that defines the member that is referenced
/// by this identifier.
final Uri uri;

/// Type type of identifier this is (instance, static, top level).
final IdentifierKind kind;

/// The unqualified name of this identifier.
@override
final String name;

/// If this is a static member, then the name of the fully qualified scope
/// surrounding this member. Should not contain a trailing `.`.
///
/// Typically this would just be the name of a type.
final String? staticScope;

ResolvedIdentifier({
required this.kind,
required this.name,
required this.staticScope,
required this.uri,
});
}

/// The types of identifiers.
enum IdentifierKind {
instanceMember,
staticInstanceMember,
topLevelMember,
}

/// An opaque identifier for a macro class, retrieved by
/// [MacroExecutor.loadMacro].
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,44 @@ import '../executor.dart';
mixin AugmentationLibraryBuilder on MacroExecutor {
@override
String buildAugmentationLibrary(Iterable<MacroExecutionResult> macroResults,
Uri Function(Identifier) resolveIdentifier) {
ResolvedIdentifier Function(Identifier) resolveIdentifier) {
StringBuffer importsBuffer = new StringBuffer();
StringBuffer directivesBuffer = new StringBuffer();
Map<Uri, String> importPrefixes = {};
int nextPrefix = 0;

// Keeps track of the last part written in `lastDirectivePart`.
String lastDirectivePart = '';
void writeDirectivePart(String part) {
lastDirectivePart = part;
directivesBuffer.write(part);
}

void buildCode(Code code) {
for (Object part in code.parts) {
if (part is String) {
directivesBuffer.write(part);
writeDirectivePart(part);
} else if (part is Code) {
buildCode(part);
} else if (part is Identifier) {
Uri uri = resolveIdentifier(part);
String prefix = importPrefixes.putIfAbsent(uri, () {
ResolvedIdentifier resolved = resolveIdentifier(part);
String prefix = importPrefixes.putIfAbsent(resolved.uri, () {
String prefix = 'i${nextPrefix++}';
importsBuffer.writeln("import '$uri' as $prefix;");
importsBuffer.writeln("import '${resolved.uri}' as $prefix;");
return prefix;
});
directivesBuffer.write('$prefix.${part.name}');
if (resolved.kind == IdentifierKind.instanceMember) {
// Qualify with `this.` if we don't have a receiver.
if (!lastDirectivePart.trimRight().endsWith('.')) {
writeDirectivePart('this.');
}
} else {
writeDirectivePart('${prefix}.');
}
if (resolved.kind == IdentifierKind.staticInstanceMember) {
writeDirectivePart('${resolved.staticScope!}.');
}
writeDirectivePart('${part.name}');
} else {
throw new ArgumentError(
'Code objects only support String, Identifier, and Code '
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ class _SingleIsolatedMacroExecutor extends MacroExecutor {
/// These calls are handled by the higher level executor.
@override
String buildAugmentationLibrary(Iterable<MacroExecutionResult> macroResults,
Uri Function(Identifier) resolveIdentifier) =>
ResolvedIdentifier Function(Identifier) resolveIdentifier) =>
throw new StateError('Unreachable');

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ void main() {
]),
];
var library = _TestExecutor().buildAugmentationLibrary(
results, (Identifier i) => (i as TestIdentifier).libraryImportUri);
results, (Identifier i) => (i as TestIdentifier).resolved);
expect(library, equalsIgnoringWhitespace('''
augment class Foo00 {
int get i => 0;
Expand Down Expand Up @@ -68,15 +68,33 @@ void main() {
var fooIdentifier = TestIdentifier(
id: RemoteInstance.uniqueId,
name: 'Foo',
libraryImportUri: Uri.parse('package:foo/foo.dart'));
kind: IdentifierKind.topLevelMember,
staticScope: null,
uri: Uri.parse('package:foo/foo.dart'));
var barIdentifier = TestIdentifier(
id: RemoteInstance.uniqueId,
name: 'Bar',
libraryImportUri: Uri.parse('package:bar/bar.dart'));
kind: IdentifierKind.topLevelMember,
staticScope: null,
uri: Uri.parse('package:bar/bar.dart'));
var builderIdentifier = TestIdentifier(
id: RemoteInstance.uniqueId,
name: 'Builder',
libraryImportUri: Uri.parse('package:builder/builder.dart'));
kind: IdentifierKind.topLevelMember,
staticScope: null,
uri: Uri.parse('package:builder/builder.dart'));
var barInstanceMember = TestIdentifier(
id: RemoteInstance.uniqueId,
name: 'baz',
kind: IdentifierKind.instanceMember,
staticScope: null,
uri: Uri.parse('package:bar/bar.dart'));
var barStaticMember = TestIdentifier(
id: RemoteInstance.uniqueId,
name: 'zap',
kind: IdentifierKind.staticInstanceMember,
staticScope: 'Bar',
uri: Uri.parse('package:bar/bar.dart'));
var results = [
MacroExecutionResultImpl(augmentations: [
DeclarationCode.fromParts([
Expand All @@ -87,24 +105,32 @@ void main() {
'<',
barIdentifier,
'<T>> {\n',
'late int ${barInstanceMember.name};\n',
barIdentifier,
'<T> build() => new ',
barIdentifier,
'();\n}',
'()..',
barInstanceMember,
' = ',
barStaticMember,
';',
'\n}',
]),
], newTypeNames: [
'FooBuilder',
])
];
var library = _TestExecutor().buildAugmentationLibrary(
results, (Identifier i) => (i as TestIdentifier).libraryImportUri);
results, (Identifier i) => (i as TestIdentifier).resolved);
expect(library, equalsIgnoringWhitespace('''
import 'package:foo/foo.dart' as i0;
import 'package:builder/builder.dart' as i1;
import 'package:bar/bar.dart' as i2;
class FooBuilder<T extends i0.Foo> implements i1.Builder<i2.Bar<T>> {
i2.Bar<T> build() => new i2.Bar();
late int baz;
i2.Bar<T> build() => new i2.Bar()..baz = i2.Bar.zap;
}
'''));
});
Expand Down
22 changes: 16 additions & 6 deletions pkg/_fe_analyzer_shared/test/macros/util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import 'dart:mirrors';

import 'package:_fe_analyzer_shared/src/macros/api.dart';
import 'package:_fe_analyzer_shared/src/macros/executor.dart';
import 'package:_fe_analyzer_shared/src/macros/executor_shared/introspection_impls.dart';
import 'package:_fe_analyzer_shared/src/macros/executor_shared/remote_instance.dart';

Expand Down Expand Up @@ -108,13 +109,22 @@ class TestNamedStaticType implements NamedStaticType {
(library == other.library && identifier.name == other.identifier.name);
}

/// An identifier that knows what URI should be used to import it.
/// An identifier that knows the resolved version of itself.
class TestIdentifier extends IdentifierImpl {
final Uri libraryImportUri;

TestIdentifier(
{required int id, required String name, required this.libraryImportUri})
: super(id: id, name: name);
final ResolvedIdentifier resolved;

TestIdentifier({
required int id,
required String name,
required IdentifierKind kind,
required Uri uri,
required String? staticScope,
}) : resolved = ResolvedIdentifier(
kind: kind, name: name, staticScope: staticScope, uri: uri),
super(
id: id,
name: name,
);
}

extension DebugCodeString on Code {
Expand Down
4 changes: 3 additions & 1 deletion pkg/front_end/lib/src/fasta/kernel/body_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1622,7 +1622,8 @@ class BodyBuilder extends ScopeListener<JumpTarget>
return fakeReturn.expression!;
}

void parseInitializers(Token token, {bool doFinishConstructor = true}) {
List<Initializer>? parseInitializers(Token token,
{bool doFinishConstructor = true}) {
Parser parser = new Parser(this,
useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
if (!token.isEof) {
Expand All @@ -1635,6 +1636,7 @@ class BodyBuilder extends ScopeListener<JumpTarget>
finishConstructor(
member as DeclaredSourceConstructorBuilder, AsyncMarker.Sync, null);
}
return _initializers;
}

Expression parseFieldInitializer(Token token) {
Expand Down
27 changes: 17 additions & 10 deletions pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -238,22 +238,24 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
}

if (_hasSuperInitializingFormals) {
List<Initializer>? initializers;
if (beginInitializers != null) {
BodyBuilder bodyBuilder = library.loader
.createBodyBuilderForOutlineExpression(
library, classBuilder, this, classBuilder.scope, fileUri);
bodyBuilder.constantContext = ConstantContext.required;
bodyBuilder.parseInitializers(beginInitializers!,
initializers = bodyBuilder.parseInitializers(beginInitializers!,
doFinishConstructor: false);
}
finalizeSuperInitializingFormals(
classHierarchy, _superParameterDefaultValueCloners);
classHierarchy, _superParameterDefaultValueCloners, initializers);
}
}
_hasFormalsInferred = true;
}

ConstructorBuilder? _computeSuperTargetBuilder() {
ConstructorBuilder? _computeSuperTargetBuilder(
List<Initializer>? initializers) {
Constructor superTarget;
ClassBuilder superclassBuilder;

Expand All @@ -279,9 +281,10 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
return null;
}

if (constructor.initializers.isNotEmpty &&
constructor.initializers.last is SuperInitializer) {
superTarget = (constructor.initializers.last as SuperInitializer).target;
if (initializers != null &&
initializers.isNotEmpty &&
initializers.last is SuperInitializer) {
superTarget = (initializers.last as SuperInitializer).target;
} else {
MemberBuilder? memberBuilder = superclassBuilder.constructors
.lookup("", charOffset, library.fileUri);
Expand All @@ -299,8 +302,10 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
return constructorBuilder is ConstructorBuilder ? constructorBuilder : null;
}

void finalizeSuperInitializingFormals(ClassHierarchy classHierarchy,
List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
void finalizeSuperInitializingFormals(
ClassHierarchy classHierarchy,
List<SynthesizedFunctionNode> synthesizedFunctionNodes,
List<Initializer>? initializers) {
if (formals == null) return;
if (!_hasSuperInitializingFormals) return;

Expand All @@ -312,7 +317,8 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
}
}

ConstructorBuilder? superTargetBuilder = _computeSuperTargetBuilder();
ConstructorBuilder? superTargetBuilder =
_computeSuperTargetBuilder(initializers);
Constructor superTarget;
List<FormalParameterBuilder>? superFormals;
if (superTargetBuilder is DeclaredSourceConstructorBuilder) {
Expand Down Expand Up @@ -468,7 +474,8 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl

void addSuperParameterDefaultValueCloners(
List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
ConstructorBuilder? superTargetBuilder = _computeSuperTargetBuilder();
ConstructorBuilder? superTargetBuilder =
_computeSuperTargetBuilder(constructor.initializers);
if (superTargetBuilder is DeclaredSourceConstructorBuilder) {
superTargetBuilder
.addSuperParameterDefaultValueCloners(synthesizedFunctionNodes);
Expand Down
2 changes: 1 addition & 1 deletion pkg/front_end/test/macros/macro_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ class TestMacroExecutor implements MacroExecutor {

@override
String buildAugmentationLibrary(Iterable<MacroExecutionResult> macroResults,
Uri Function(Identifier) resolveIdentifier) {
ResolvedIdentifier Function(Identifier) resolveIdentifier) {
// TODO: implement buildAugmentationLibrary
throw UnimplementedError();
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/front_end/test/spell_checking_list_code.txt
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,7 @@ q'i
qi
qm
quad
qualify
quantified
queries
quick
Expand Down Expand Up @@ -1369,6 +1370,7 @@ unordered
unpaired
unparsed
unpleasant
unqualified
unreachable
unseen
unset
Expand Down
18 changes: 18 additions & 0 deletions pkg/front_end/testcases/super_parameters/issue48286.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// 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.

class S<T> {
num n;
T t;
S(this.n, this.t);
S.named(this.t, this.n);
}

class C<T> extends S<T> {
C.constr1(super.n, String s, super.t);
C.constr2(int i, super.n, String s, super.t) : super();
C.constr3(int i, super.t, String s, super.n) : super.named();
}

main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

class S<T extends core::Object? = dynamic> extends core::Object {
field core::num n;
covariant-by-class field self::S::T% t;
constructor •(core::num n, self::S::T% t) → self::S<self::S::T%>
: self::S::n = n, self::S::t = t, super core::Object::•()
;
constructor named(self::S::T% t, core::num n) → self::S<self::S::T%>
: self::S::t = t, self::S::n = n, super core::Object::•()
;
}
class C<T extends core::Object? = dynamic> extends self::S<self::C::T%> {
constructor constr1(core::num n, core::String s, self::C::T% t) → self::C<self::C::T%>
: super self::S::•(n, t)
;
constructor constr2(core::int i, core::num n, core::String s, self::C::T% t) → self::C<self::C::T%>
: super self::S::•(n, t)
;
constructor constr3(core::int i, self::C::T% t, core::String s, core::num n) → self::C<self::C::T%>
: super self::S::named(t, n)
;
}
static method main() → dynamic {}
Loading

0 comments on commit 0005ff0

Please sign in to comment.