Skip to content

Commit 0c8ded7

Browse files
johnniwintherCommit Queue
authored and
Commit Queue
committed
[cfe] Add FileUriConstantExpression
This adds FileUriConstantExpression, a subclass of ConstantExpression, to support correct file offset of annotations for augmentations and patches. The FileUriExpression is used to carry the file uri of the expression before constant evaluation. TEST=general/patch_annotations Change-Id: I0dc8a0cb97dd530fd1960785d38c2d5e4883c3dd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311660 Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Jens Johansen <[email protected]> Reviewed-by: Alexander Markov <[email protected]>
1 parent cfd4200 commit 0c8ded7

File tree

120 files changed

+816
-257
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+816
-257
lines changed

pkg/front_end/lib/src/fasta/builder/metadata_builder.dart

+10-3
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,22 @@ class MetadataBuilder {
2525
BodyBuilderContext bodyBuilderContext,
2626
SourceLibraryBuilder library,
2727
Uri fileUri,
28-
Scope scope) {
28+
Scope scope,
29+
{bool createFileUriExpression = false}) {
2930
if (metadata == null) return;
3031
BodyBuilder bodyBuilder = library.loader
3132
.createBodyBuilderForOutlineExpression(
3233
library, bodyBuilderContext, scope, fileUri);
3334
for (int i = 0; i < metadata.length; ++i) {
3435
MetadataBuilder annotationBuilder = metadata[i];
35-
parent.addAnnotation(
36-
bodyBuilder.parseAnnotation(annotationBuilder.beginToken));
36+
Expression annotation =
37+
bodyBuilder.parseAnnotation(annotationBuilder.beginToken);
38+
if (createFileUriExpression) {
39+
parent.addAnnotation(new FileUriExpression(annotation, fileUri)
40+
..fileOffset = annotationBuilder.beginToken.charOffset);
41+
} else {
42+
parent.addAnnotation(annotation);
43+
}
3744
}
3845
bodyBuilder.inferAnnotations(parent, parent.annotations);
3946
bodyBuilder.performBacklogComputations(allowFurtherDelays: false);

pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart

+9-3
Original file line numberDiff line numberDiff line change
@@ -2225,9 +2225,15 @@ class ConstantsTransformer extends RemovingTransformer {
22252225
constant.expression is InvalidExpression) {
22262226
return constant.expression;
22272227
}
2228-
return new ConstantExpression(
2229-
constant, node.getStaticType(staticTypeContext))
2230-
..fileOffset = node.fileOffset;
2228+
ConstantExpression constantExpression =
2229+
new ConstantExpression(constant, node.getStaticType(staticTypeContext))
2230+
..fileOffset = node.fileOffset;
2231+
if (node is FileUriExpression) {
2232+
return new FileUriConstantExpression(constantExpression.constant,
2233+
type: constantExpression.type, fileUri: node.fileUri)
2234+
..fileOffset = node.fileOffset;
2235+
}
2236+
return constantExpression;
22312237
}
22322238

22332239
bool shouldInline(Expression initializer) {

pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart

+20-6
Original file line numberDiff line numberDiff line change
@@ -301,37 +301,51 @@ class TypeDependency {
301301
}
302302
}
303303

304+
/// Removes [FileUriExpression] nodes for annotations whose file URI is
305+
/// [annotatableFileUri], the file URI of the [annotatable].
306+
///
307+
/// This is an optimization to avoid unnecessary [FileUriConstantExpression]
308+
/// nodes in the generated AST.
309+
void adjustAnnotationFileUri(Annotatable annotatable, Uri annotatableFileUri) {
310+
List<Expression> annotations = annotatable.annotations;
311+
for (int i = 0; i < annotations.length; i++) {
312+
Expression annotation = annotations[i];
313+
if (annotation is FileUriExpression &&
314+
annotation.fileUri == annotatableFileUri) {
315+
annotations[i] = annotation.expression..parent = annotatable;
316+
}
317+
}
318+
}
319+
304320
/// Copies properties, function parameters and body from the [patch] constructor
305321
/// to its [origin].
306322
void finishConstructorPatch(Constructor origin, Constructor patch) {
307-
// TODO(ahe): restore file-offset once we track both origin and patch file
308-
// URIs. See https://github.com/dart-lang/sdk/issues/31579
309323
origin.fileUri = patch.fileUri;
310324
origin.startFileOffset = patch.startFileOffset;
311325
origin.fileOffset = patch.fileOffset;
312326
origin.fileEndOffset = patch.fileEndOffset;
313-
origin.annotations.forEach((m) => m.fileOffset = patch.fileOffset);
314327

315328
origin.isExternal = patch.isExternal;
316329
origin.function = patch.function;
317330
origin.function.parent = origin;
318331
origin.initializers = patch.initializers;
319332
setParents(origin.initializers, origin);
333+
334+
adjustAnnotationFileUri(origin, origin.fileUri);
320335
}
321336

322337
/// Copies properties, function parameters and body from the [patch] procedure
323338
/// to its [origin].
324339
void finishProcedurePatch(Procedure origin, Procedure patch) {
325-
// TODO(ahe): restore file-offset once we track both origin and patch file
326-
// URIs. See https://github.com/dart-lang/sdk/issues/31579
327340
origin.fileUri = patch.fileUri;
328341
origin.fileStartOffset = patch.fileStartOffset;
329342
origin.fileOffset = patch.fileOffset;
330343
origin.fileEndOffset = patch.fileEndOffset;
331-
origin.annotations.forEach((m) => m.fileOffset = patch.fileOffset);
332344

333345
origin.isAbstract = patch.isAbstract;
334346
origin.isExternal = patch.isExternal;
335347
origin.function = patch.function;
336348
origin.function.parent = origin;
349+
350+
adjustAnnotationFileUri(origin, origin.fileUri);
337351
}

pkg/front_end/lib/src/fasta/source/source_class_builder.dart

+3-6
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,8 @@ class SourceClassBuilder extends ClassBuilderImpl
372372
}
373373

374374
MetadataBuilder.buildAnnotations(isPatch ? origin.cls : cls, metadata,
375-
bodyBuilderContext, libraryBuilder, fileUri, libraryBuilder.scope);
375+
bodyBuilderContext, libraryBuilder, fileUri, libraryBuilder.scope,
376+
createFileUriExpression: isPatch);
376377
if (typeVariables != null) {
377378
for (int i = 0; i < typeVariables!.length; i++) {
378379
typeVariables![i].buildOutlineExpressions(
@@ -1116,11 +1117,7 @@ class SourceClassBuilder extends ClassBuilderImpl
11161117
}
11171118

11181119
int buildBodyNodes() {
1119-
// TODO(ahe): restore file-offset once we track both origin and patch file
1120-
// URIs. See https://github.com/dart-lang/sdk/issues/31579
1121-
if (isPatch) {
1122-
cls.annotations.forEach((m) => m.fileOffset = origin.cls.fileOffset);
1123-
}
1120+
adjustAnnotationFileUri(cls, cls.fileUri);
11241121

11251122
int count = 0;
11261123

pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart

+12
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,15 @@ class DeclaredSourceConstructorBuilder
932932
// TODO(johnniwinther): Add annotations to tear-offs.
933933
@override
934934
Iterable<Annotatable> get annotatables => [constructor];
935+
936+
@override
937+
bool get isAugmented {
938+
if (isPatch) {
939+
return origin._patches!.last != this;
940+
} else {
941+
return _patches != null;
942+
}
943+
}
935944
}
936945

937946
class SyntheticSourceConstructorBuilder extends DillConstructorBuilder
@@ -1293,6 +1302,9 @@ class SourceInlineClassConstructorBuilder
12931302
// TODO(johnniwinther): Add annotations to tear-offs.
12941303
@override
12951304
Iterable<Annotatable> get annotatables => [_constructor];
1305+
1306+
@override
1307+
bool get isAugmented => false;
12961308
}
12971309

12981310
class InlineClassInitializerToStatementConverter

pkg/front_end/lib/src/fasta/source/source_factory_builder.dart

+9
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,15 @@ class SourceFactoryBuilder extends SourceFunctionBuilderImpl {
321321
// TODO(johnniwinther): Add annotations to tear-offs.
322322
@override
323323
Iterable<Annotatable> get annotatables => [_procedure];
324+
325+
@override
326+
bool get isAugmented {
327+
if (isPatch) {
328+
return origin._patches!.last != this;
329+
} else {
330+
return _patches != null;
331+
}
332+
}
324333
}
325334

326335
class RedirectingFactoryBuilder extends SourceFactoryBuilder {

pkg/front_end/lib/src/fasta/source/source_function_builder.dart

+6-1
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ abstract class SourceFunctionBuilderImpl extends SourceMemberBuilderImpl
206206
@override
207207
bool get isAssignable => false;
208208

209+
/// Returns `true` if this member is augmented, either by being the origin
210+
/// of a augmented member or by not being the last among augmentations.
211+
bool get isAugmented;
212+
209213
@override
210214
Scope computeFormalParameterScope(Scope parent) {
211215
if (formals == null) return parent;
@@ -479,7 +483,8 @@ abstract class SourceFunctionBuilderImpl extends SourceMemberBuilderImpl
479483
classOrExtensionBuilder?.scope ?? libraryBuilder.scope;
480484
for (Annotatable annotatable in annotatables) {
481485
MetadataBuilder.buildAnnotations(annotatable, metadata,
482-
bodyBuilderContext, libraryBuilder, fileUri, parentScope);
486+
bodyBuilderContext, libraryBuilder, fileUri, parentScope,
487+
createFileUriExpression: isAugmented);
483488
}
484489
if (typeVariables != null) {
485490
for (int i = 0; i < typeVariables!.length; i++) {

pkg/front_end/lib/src/fasta/source/source_library_builder.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -3343,7 +3343,8 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
33433343
}
33443344

33453345
MetadataBuilder.buildAnnotations(
3346-
library, metadata, bodyBuilderContext, this, fileUri, scope);
3346+
library, metadata, bodyBuilderContext, this, fileUri, scope,
3347+
createFileUriExpression: isPatch);
33473348

33483349
Iterator<Builder> iterator = localMembersIterator;
33493350
while (iterator.moveNext()) {

pkg/front_end/lib/src/fasta/source/source_loader.dart

+2
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,8 @@ severity: $severity
933933
// and the VM does not support that. Also, what would, for instance,
934934
// setting a breakpoint on line 42 of some import uri mean, if the uri
935935
// represented several files?
936+
// TODO(johnniwinther): Replace this with something that supports
937+
// augmentation libraries.
936938
List<String> newPathSegments =
937939
new List<String>.of(importUri.pathSegments);
938940
newPathSegments.add(libraryBuilder.fileUri.pathSegments.last);

pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart

+9
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,15 @@ class SourceProcedureBuilder extends SourceFunctionBuilderImpl
640640
// TODO(johnniwinther): Add annotations to tear-offs.
641641
@override
642642
Iterable<Annotatable> get annotatables => [procedure];
643+
644+
@override
645+
bool get isAugmented {
646+
if (isPatch) {
647+
return origin._patches!.last != this;
648+
} else {
649+
return _patches != null;
650+
}
651+
}
643652
}
644653

645654
class SourceProcedureMember extends BuilderClassMember {

pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart

+4-1
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase
526526
@override
527527
ExpressionInferenceResult visitFileUriExpression(
528528
FileUriExpression node, DartType typeContext) {
529-
return _unhandledExpression(node, typeContext);
529+
ExpressionInferenceResult result =
530+
inferExpression(node.expression, typeContext);
531+
node.expression = result.expression..parent = node;
532+
return new ExpressionInferenceResult(result.inferredType, node);
530533
}
531534

532535
@override

pkg/front_end/test/utils/kernel_chain.dart

+1
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ class ComponentResult {
518518
}
519519

520520
bool isUserLibraryImportUri(Uri? importUri) {
521+
// TODO(johnniwinther): Support patch libraries user libraries.
521522
return userLibraries.contains(importUri);
522523
}
523524

pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.expect

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import "dart:_internal";
2929

3030
typedef Alias<T extends core::num> = test::Class<T>;
3131
typedef AliasImpl<T extends core::num> = test::ClassImpl<T>;
32-
@#C13
32+
@/* from org-dartlang-testcase:///patch_lib.dart */ #C13
3333
class Class<T extends core::Object? = dynamic> extends core::Object {
3434
@#C13
3535
constructor •({core::bool defaultValue = #C14, required test::Class::T% value = #C15}) → test::Class<test::Class::T%>
@@ -54,7 +54,7 @@ class Class<T extends core::Object? = dynamic> extends core::Object {
5454
static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C14, required test::Class::_#redirect2#tearOff::T% value = #C15}) → test::Class<test::Class::_#redirect2#tearOff::T%>
5555
return new test::ClassImpl::patched<test::Class::_#redirect2#tearOff::T%>(defaultValue: defaultValue, value: value);
5656
}
57-
@#C13
57+
@/* from org-dartlang-testcase:///patch_lib.dart */ #C13
5858
class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements test::Class<test::ClassImpl::T%> {
5959
constructor •({core::bool defaultValue = #C14, required test::ClassImpl::T% value = #C15}) → test::ClassImpl<test::ClassImpl::T%>
6060
: super core::Object::•()

pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.expect

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import "dart:_internal";
2929

3030
typedef Alias<T extends core::num> = test::Class<T>;
3131
typedef AliasImpl<T extends core::num> = test::ClassImpl<T>;
32-
@#C13
32+
@/* from org-dartlang-testcase:///patch_lib.dart */ #C13
3333
class Class<T extends core::Object? = dynamic> extends core::Object {
3434
@#C13
3535
constructor •({core::bool defaultValue = #C14, required test::Class::T% value = #C15}) → test::Class<test::Class::T%>
@@ -54,7 +54,7 @@ class Class<T extends core::Object? = dynamic> extends core::Object {
5454
static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C14, required test::Class::_#redirect2#tearOff::T% value = #C15}) → test::Class<test::Class::_#redirect2#tearOff::T%>
5555
return new test::ClassImpl::patched<test::Class::_#redirect2#tearOff::T%>(defaultValue: defaultValue, value: value);
5656
}
57-
@#C13
57+
@/* from org-dartlang-testcase:///patch_lib.dart */ #C13
5858
class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements test::Class<test::ClassImpl::T%> {
5959
constructor •({core::bool defaultValue = #C14, required test::ClassImpl::T% value = #C15}) → test::ClassImpl<test::ClassImpl::T%>
6060
: super core::Object::•()

pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.modular.expect

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import "dart:_internal";
2929

3030
typedef Alias<T extends core::num> = test::Class<T>;
3131
typedef AliasImpl<T extends core::num> = test::ClassImpl<T>;
32-
@#C13
32+
@/* from org-dartlang-testcase:///patch_lib.dart */ #C13
3333
class Class<T extends core::Object? = dynamic> extends core::Object {
3434
@#C13
3535
constructor •({core::bool defaultValue = #C14, required test::Class::T% value = #C15}) → test::Class<test::Class::T%>
@@ -54,7 +54,7 @@ class Class<T extends core::Object? = dynamic> extends core::Object {
5454
static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C14, required test::Class::_#redirect2#tearOff::T% value = #C15}) → test::Class<test::Class::_#redirect2#tearOff::T%>
5555
return new test::ClassImpl::patched<test::Class::_#redirect2#tearOff::T%>(defaultValue: defaultValue, value: value);
5656
}
57-
@#C13
57+
@/* from org-dartlang-testcase:///patch_lib.dart */ #C13
5858
class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements test::Class<test::ClassImpl::T%> {
5959
constructor •({core::bool defaultValue = #C14, required test::ClassImpl::T% value = #C15}) → test::ClassImpl<test::ClassImpl::T%>
6060
: super core::Object::•()

pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.outline.expect

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ static method _#AliasImpl#patched#tearOff<T extends core::num>({has-declared-ini
6262

6363

6464
Extra constant evaluation status:
65-
Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:6:46 -> InstanceConstant(const _Patch{})
65+
Evaluated: FileUriExpression @ org-dartlang-testcase:///patch_lib.dart:8:1 -> InstanceConstant(const _Patch{})
6666
Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:7:8 -> InstanceConstant(const _Patch{})
6767
Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:8:27 -> InstanceConstant(const _Patch{})
6868
Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:12:21 -> InstanceConstant(const _Patch{})
6969
Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:15:10 -> InstanceConstant(const _Patch{})
70-
Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:18:36 -> InstanceConstant(const _Patch{})
70+
Evaluated: FileUriExpression @ org-dartlang-testcase:///patch_lib.dart:27:1 -> InstanceConstant(const _Patch{})
7171
Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:19:45 -> InstanceConstant(const _Patch{})
7272
Extra constant evaluation: evaluated: 49, effectively constant: 7

pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.expect

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import "dart:core" as core;
1515

1616
import "dart:_internal";
1717

18-
@#C1
18+
@/* from org-dartlang-testcase:///patch_lib.dart */ #C1
1919
class Class extends core::Object {
2020
final field core::bool defaultValue /* from org-dartlang-testcase:///patch_lib.dart */;
2121
const constructor _internal({core::bool defaultValue = #C2}) → test::Class

pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.expect

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import "dart:core" as core;
1515

1616
import "dart:_internal";
1717

18-
@#C1
18+
@/* from org-dartlang-testcase:///patch_lib.dart */ #C1
1919
class Class extends core::Object {
2020
final field core::bool defaultValue /* from org-dartlang-testcase:///patch_lib.dart */;
2121
const constructor _internal({core::bool defaultValue = #C2}) → test::Class

pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.modular.expect

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import "dart:core" as core;
1515

1616
import "dart:_internal";
1717

18-
@#C1
18+
@/* from org-dartlang-testcase:///patch_lib.dart */ #C1
1919
class Class extends core::Object {
2020
final field core::bool defaultValue /* from org-dartlang-testcase:///patch_lib.dart */;
2121
const constructor _internal({core::bool defaultValue = #C2}) → test::Class

pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.outline.expect

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class Class extends core::Object {
3333

3434

3535
Extra constant evaluation status:
36-
Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:6:49 -> InstanceConstant(const _Patch{})
36+
Evaluated: FileUriExpression @ org-dartlang-testcase:///patch_lib.dart:8:1 -> InstanceConstant(const _Patch{})
3737
Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:8:26 -> InstanceConstant(const _Patch{})
3838
Evaluated: StaticGet @ (unknown position in org-dartlang-testcase:///origin_lib.dart) -> InstanceConstant(const _Patch{})
3939
Extra constant evaluation: evaluated: 10, effectively constant: 3

pkg/front_end/testcases/general/constructor_patch/main.dart.strong.expect

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import "dart:core" as core;
3535

3636
import "dart:_internal";
3737

38-
@#C3
38+
@/* from org-dartlang-testcase:///patch_lib.dart */ #C3
3939
class Class extends core::Object /*hasConstConstructor*/ {
4040
final field core::bool defaultValue /* from org-dartlang-testcase:///patch_lib.dart */;
4141
constructor _privateInjected() → test::Class
@@ -60,7 +60,7 @@ class Class extends core::Object /*hasConstConstructor*/ {
6060
: test::Class::defaultValue = true, super core::Object::•()
6161
;
6262
}
63-
@#C3
63+
@/* from org-dartlang-testcase:///patch_lib.dart */ #C3
6464
class Class2 extends core::Object {
6565
final field core::int injectedField /* from org-dartlang-testcase:///patch_lib.dart */;
6666
field core::int field;

pkg/front_end/testcases/general/constructor_patch/main.dart.weak.expect

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import "dart:core" as core;
3535

3636
import "dart:_internal";
3737

38-
@#C3
38+
@/* from org-dartlang-testcase:///patch_lib.dart */ #C3
3939
class Class extends core::Object /*hasConstConstructor*/ {
4040
final field core::bool defaultValue /* from org-dartlang-testcase:///patch_lib.dart */;
4141
constructor _privateInjected() → test::Class
@@ -60,7 +60,7 @@ class Class extends core::Object /*hasConstConstructor*/ {
6060
: test::Class::defaultValue = true, super core::Object::•()
6161
;
6262
}
63-
@#C3
63+
@/* from org-dartlang-testcase:///patch_lib.dart */ #C3
6464
class Class2 extends core::Object {
6565
final field core::int injectedField /* from org-dartlang-testcase:///patch_lib.dart */;
6666
field core::int field;

0 commit comments

Comments
 (0)