Clone metadata in BodyBuilder instead of type inference
Change-Id: Iaf1344455c45693902d89c866c93395670e56251
Reviewed-on: https://dart-review.googlesource.com/c/85711
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Peter von der Ahé <ahe@google.com>
Auto-Submit: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index d08726b..7f9c44d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -216,6 +216,14 @@
/// invocations are to be resolved in a separate step.
final List<Expression> redirectingFactoryInvocations = <Expression>[];
+ /// Variables with metadata. Their types need to be inferred late, for
+ /// example, in [finishFunction].
+ List<VariableDeclaration> variablesWithMetadata;
+
+ /// More than one variable declared in a single statement that has metadata.
+ /// Their types need to be inferred late, for example, in [finishFunction].
+ List<List<VariableDeclaration>> multiVariablesWithMetadata;
+
BodyBuilder(
this.library,
this.member,
@@ -547,7 +555,9 @@
_typeInferrer.inferMetadata(this, annotations);
Field field = fields.first.target;
// The first (and often only field) will not get a clone.
- annotations.forEach((annotation) => field.addAnnotation(annotation));
+ for (int i = 0; i < annotations.length; i++) {
+ field.addAnnotation(annotations[i]);
+ }
for (int i = 1; i < fields.length; i++) {
// We have to clone the annotations on the remaining fields.
field = fields[i].target;
@@ -559,6 +569,7 @@
}
resolveRedirectingFactoryTargets();
+ finishVariableMetadata();
}
@override
@@ -833,6 +844,7 @@
}
resolveRedirectingFactoryTargets();
+ finishVariableMetadata();
}
void resolveRedirectingFactoryTargets() {
@@ -924,6 +936,36 @@
redirectingFactoryInvocations.clear();
}
+ void finishVariableMetadata() {
+ List<VariableDeclaration> variablesWithMetadata =
+ this.variablesWithMetadata;
+ this.variablesWithMetadata = null;
+ List<List<VariableDeclaration>> multiVariablesWithMetadata =
+ this.multiVariablesWithMetadata;
+ this.multiVariablesWithMetadata = null;
+
+ if (variablesWithMetadata != null) {
+ for (int i = 0; i < variablesWithMetadata.length; i++) {
+ _typeInferrer?.inferMetadata(
+ this, variablesWithMetadata[i].annotations);
+ }
+ }
+ if (multiVariablesWithMetadata != null) {
+ for (int i = 0; i < multiVariablesWithMetadata.length; i++) {
+ List<VariableDeclaration> variables = multiVariablesWithMetadata[i];
+ List<Expression> annotations = variables.first.annotations;
+ _typeInferrer?.inferMetadata(this, annotations);
+ for (int i = 1; i < variables.length; i++) {
+ cloner ??= new CloneVisitor();
+ VariableDeclaration variable = variables[i];
+ for (int i = 0; i < annotations.length; i++) {
+ variable.addAnnotation(cloner.clone(annotations[i]));
+ }
+ }
+ }
+ }
+ }
+
@override
List<Expression> finishMetadata(TreeNode parent) {
List<Expression> expressions = pop();
@@ -972,6 +1014,7 @@
temporaryParent = new ListLiteral(expressions);
}
resolveRedirectingFactoryTargets();
+ finishVariableMetadata();
return temporaryParent != null ? temporaryParent.expressions : expressions;
}
@@ -2042,9 +2085,10 @@
}
VariableDeclaration variable = node;
if (annotations != null) {
- for (Expression annotation in annotations) {
- variable.addAnnotation(annotation);
+ for (int i = 0; i < annotations.length; i++) {
+ variable.addAnnotation(annotations[i]);
}
+ (variablesWithMetadata ??= <VariableDeclaration>[]).add(variable);
}
push(variable);
} else {
@@ -2059,17 +2103,12 @@
return;
}
if (annotations != null) {
- bool isFirstVariable = true;
- for (VariableDeclarationJudgment variable in variables) {
- for (Expression annotation in annotations) {
- variable.addAnnotation(annotation);
- }
- if (isFirstVariable) {
- isFirstVariable = false;
- } else {
- variable.infersAnnotations = false;
- }
+ VariableDeclaration first = variables.first;
+ for (int i = 0; i < annotations.length; i++) {
+ first.addAnnotation(annotations[i]);
}
+ (multiVariablesWithMetadata ??= <List<VariableDeclaration>>[])
+ .add(variables);
}
push(forest.variablesDeclaration(variables, uri));
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 3b44e55..ea35492 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -312,7 +312,6 @@
..parent = node;
}
if (node._declaresVariable) {
- inferrer.inferMetadataKeepingHelper(variable.annotations);
var tempVar =
new VariableDeclaration(null, type: inferredType, isFinal: true);
var variableGet = new VariableGet(tempVar)
@@ -1261,30 +1260,6 @@
}
void visitVariableDeclarationJudgment(VariableDeclarationJudgment node) {
- if (node.annotationJudgments.isNotEmpty) {
- if (node.infersAnnotations) {
- inferrer.inferMetadataKeepingHelper(node.annotationJudgments);
- }
-
- // After the inference was done on the annotations, we may clone them for
- // this instance of VariableDeclaration in order to avoid having the same
- // annotation node for two VariableDeclaration nodes in a situation like
- // the following:
- //
- // class Foo { const Foo(List<String> list); }
- //
- // @Foo(const [])
- // var x, y;
- CloneVisitor cloner = new CloneVisitor();
- for (int i = 0; i < node.annotations.length; ++i) {
- kernel.Expression annotation = node.annotations[i];
- if (annotation.parent != node) {
- node.annotations[i] = cloner.clone(annotation);
- node.annotations[i].parent = node;
- }
- }
- }
-
var initializerJudgment = node.initializerJudgment;
var declaredType = node._implicitlyTyped ? const UnknownType() : node.type;
DartType inferredType;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index a78410a..13d3a98 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -24,8 +24,6 @@
import 'package:kernel/ast.dart';
-import 'package:kernel/clone.dart' show CloneVisitor;
-
import 'package:kernel/type_algebra.dart' show Substitution;
import '../../base/instrumentation.dart'
@@ -1800,12 +1798,6 @@
// TODO(ahe): Investigate if this can be removed.
final bool _isLocalFunction;
- /// The same [annotations] list is used for all [VariableDeclarationJudgment]s
- /// of a variable declaration statement. But we need to perform inference
- /// only once. So, we set this flag to `false` for the second and subsequent
- /// judgments.
- bool infersAnnotations = true;
-
VariableDeclarationJudgment(String name, this._functionNestingLevel,
{this.forSyntheticToken: false,
Expression initializer,
@@ -1839,8 +1831,6 @@
_isLocalFunction = false,
super.forValue(initializer);
- List<Expression> get annotationJudgments => annotations;
-
Expression get initializerJudgment => initializer;
@override