Add a binder mechanism to the Factory API for handling labels.
Some work needs to be done on both sides to hook up to the API:
- On the front end side, the individual labels need to be plumbed
through the body builder to the judgment objects (currently the body
builder discards individual label information). Follow-up work for
this will be tracked in
https://github.com/dart-lang/sdk/issues/33591.
- On the analyzer side, the label information needs to be stored by
ResolutionStorer and retrieved by ResolutionApplier (currently the
ResolutionApplier has its own scope resolution mechanism; we don't
want to keep this because it duplicates resolution logic in the
front end). Follw-up work for this will be tracked in
https://github.com/dart-lang/sdk/issues/33592.
Change-Id: I75afc2be16a277581b0e2ea49b6998e72054a40d
Reviewed-on: https://dart-review.googlesource.com/62000
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/lib/src/fasta/resolution_storer.dart b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
index 08a565e..af780b2 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_storer.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
@@ -137,8 +137,13 @@
Token literal, bool value, DartType inferredType) =>
genericExpression("boolLiteral", location, inferredType);
- void breakStatement(StatementJudgment judgment, Location location,
- Token breakKeyword, void label, Token semicolon) {}
+ void breakStatement(
+ StatementJudgment judgment,
+ Location location,
+ Token breakKeyword,
+ void label,
+ Token semicolon,
+ covariant Object labelBinder) {}
void cascadeExpression(
ExpressionJudgment judgment, Location location, DartType inferredType) {
@@ -198,11 +203,21 @@
_store(location, inferredType: inferredType, reference: expressionTarget);
}
- void continueStatement(StatementJudgment judgment, Location location,
- Token continueKeyword, void label, Token semicolon) {}
+ void continueStatement(
+ StatementJudgment judgment,
+ Location location,
+ Token continueKeyword,
+ void label,
+ Token semicolon,
+ covariant Object labelBinder) {}
- void continueSwitchStatement(StatementJudgment judgment, Location location,
- Token continueKeyword, void label, Token semicolon) {}
+ void continueSwitchStatement(
+ StatementJudgment judgment,
+ Location location,
+ Token continueKeyword,
+ void label,
+ Token semicolon,
+ covariant Object labelBinder) {}
void deferredCheck(ExpressionJudgment judgment, Location location,
DartType inferredType) =>
@@ -326,8 +341,12 @@
void invalidInitializer(InitializerJudgment judgment, Location location) {}
- void labeledStatement(StatementJudgment judgment, Location location,
- Token label, Token colon, void statement) {}
+ void labeledStatement(List<Object> labels, void statement) {}
+
+ void statementLabel(covariant void binder, Token label, Token colon) {}
+
+ void binderForStatementLabel(
+ StatementJudgment judgment, int fileOffset, String name) {}
void listLiteral(
ExpressionJudgment judgment,
@@ -552,6 +571,14 @@
Token constructorName,
covariant Object argumentList) {}
+ void switchCase(SwitchCaseJudgment judgment, List<Object> labels,
+ Token keyword, void expression, Token colon, List<void> statements) {}
+
+ void switchLabel(covariant void binder, Token label, Token colon) {}
+
+ void binderForSwitchLabel(
+ SwitchCaseJudgment judgment, int fileOffset, String name) {}
+
void switchStatement(
StatementJudgment judgment,
Location location,
diff --git a/pkg/front_end/lib/src/fasta/kernel/factory.dart b/pkg/front_end/lib/src/fasta/kernel/factory.dart
index 887b329..be008b7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/factory.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/factory.dart
@@ -9,7 +9,11 @@
import '../../scanner/token.dart' show Token;
import 'kernel_shadow_ast.dart'
- show ExpressionJudgment, InitializerJudgment, StatementJudgment;
+ show
+ ExpressionJudgment,
+ InitializerJudgment,
+ StatementJudgment,
+ SwitchCaseJudgment;
/// Abstract base class for factories that can construct trees of expressions,
/// statements, initializers, and literal types based on tokens, inferred types,
@@ -53,8 +57,13 @@
Expression boolLiteral(ExpressionJudgment judgment, int fileOffset,
Token literal, bool value, DartType inferredType);
- Statement breakStatement(StatementJudgment judgment, int fileOffset,
- Token breakKeyword, Expression label, Token semicolon);
+ Statement breakStatement(
+ StatementJudgment judgment,
+ int fileOffset,
+ Token breakKeyword,
+ Expression label,
+ Token semicolon,
+ covariant Object labelBinder);
Expression cascadeExpression(
ExpressionJudgment judgment, int fileOffset, DartType inferredType);
@@ -90,11 +99,21 @@
Expression constructorInvocation(ExpressionJudgment judgment, int fileOffset,
Node expressionTarget, DartType inferredType);
- Statement continueStatement(StatementJudgment judgment, int fileOffset,
- Token continueKeyword, Expression label, Token semicolon);
+ Statement continueStatement(
+ StatementJudgment judgment,
+ int fileOffset,
+ Token continueKeyword,
+ Expression label,
+ Token semicolon,
+ covariant Object labelBinder);
- Statement continueSwitchStatement(StatementJudgment judgment, int fileOffset,
- Token continueKeyword, Expression label, Token semicolon);
+ Statement continueSwitchStatement(
+ StatementJudgment judgment,
+ int fileOffset,
+ Token continueKeyword,
+ Expression label,
+ Token semicolon,
+ covariant Object labelBinder);
Expression deferredCheck(
ExpressionJudgment judgment, int fileOffset, DartType inferredType);
@@ -214,8 +233,12 @@
DartType testedType,
DartType inferredType);
- Statement labeledStatement(StatementJudgment judgment, int fileOffset,
- Token label, Token colon, Statement statement);
+ Statement labeledStatement(List<Object> labels, Statement statement);
+
+ Object statementLabel(covariant Object binder, Token label, Token colon);
+
+ Object binderForStatementLabel(
+ StatementJudgment judgment, int fileOffset, String name);
Expression listLiteral(
ExpressionJudgment judgment,
@@ -342,6 +365,19 @@
Token constructorName,
covariant Object argumentList);
+ Object switchCase(
+ SwitchCaseJudgment judgment,
+ List<Object> labels,
+ Token keyword,
+ Expression expression,
+ Token colon,
+ List<Statement> statements);
+
+ Object switchLabel(covariant Object binder, Token label, Token colon);
+
+ Object binderForSwitchLabel(
+ SwitchCaseJudgment judgment, int fileOffset, String name);
+
Statement switchStatement(
StatementJudgment judgment,
int fileOffset,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_factory.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_factory.dart
index 3377baf..32b2387 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_factory.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_factory.dart
@@ -11,8 +11,10 @@
Expression,
FunctionType,
Initializer,
+ LabeledStatement,
Node,
Statement,
+ SwitchCase,
VariableDeclaration;
import 'package:kernel/type_algebra.dart' show Substitution;
@@ -20,7 +22,11 @@
import 'factory.dart' show Factory;
import 'kernel_shadow_ast.dart'
- show ExpressionJudgment, InitializerJudgment, StatementJudgment;
+ show
+ ExpressionJudgment,
+ InitializerJudgment,
+ StatementJudgment,
+ SwitchCaseJudgment;
/// Implementation of [Factory] that builds source code into a kernel
/// representation.
@@ -83,8 +89,13 @@
}
@override
- Statement breakStatement(StatementJudgment judgment, int fileOffset,
- Token breakKeyword, Expression label, Token semicolon) {
+ Statement breakStatement(
+ StatementJudgment judgment,
+ int fileOffset,
+ Token breakKeyword,
+ Expression label,
+ Token semicolon,
+ covariant LabeledStatement labelBinder) {
return judgment;
}
@@ -135,14 +146,24 @@
}
@override
- Statement continueStatement(StatementJudgment judgment, int fileOffset,
- Token continueKeyword, Expression label, Token semicolon) {
+ Statement continueStatement(
+ StatementJudgment judgment,
+ int fileOffset,
+ Token continueKeyword,
+ Expression label,
+ Token semicolon,
+ covariant LabeledStatement labelBinder) {
return judgment;
}
@override
- Statement continueSwitchStatement(StatementJudgment judgment, int fileOffset,
- Token continueKeyword, Expression label, Token semicolon) {
+ Statement continueSwitchStatement(
+ StatementJudgment judgment,
+ int fileOffset,
+ Token continueKeyword,
+ Expression label,
+ Token semicolon,
+ covariant LabeledStatement labelBinder) {
return judgment;
}
@@ -316,8 +337,18 @@
}
@override
- Statement labeledStatement(StatementJudgment judgment, int fileOffset,
- Token label, Token colon, Statement statement) {
+ Statement labeledStatement(List<Object> labels, Statement statement) {
+ return labels[0];
+ }
+
+ Object statementLabel(
+ covariant StatementJudgment binder, Token label, Token colon) {
+ return binder;
+ }
+
+ @override
+ Object binderForStatementLabel(
+ StatementJudgment judgment, int fileOffset, String name) {
return judgment;
}
@@ -518,6 +549,26 @@
return judgment;
}
+ SwitchCase switchCase(
+ SwitchCaseJudgment judgment,
+ List<Object> labels,
+ Token keyword,
+ Expression expression,
+ Token colon,
+ List<Statement> statements) {
+ return judgment;
+ }
+
+ SwitchCase switchLabel(
+ covariant SwitchCase binder, Token label, Token colon) {
+ return binder;
+ }
+
+ SwitchCase binderForSwitchLabel(
+ SwitchCaseJudgment judgment, int fileOffset, String name) {
+ return judgment;
+ }
+
@override
Statement switchStatement(
StatementJudgment judgment,
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 383fd8e..2f41efc 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
@@ -326,12 +326,15 @@
class ContinueJudgment extends BreakStatement implements StatementJudgment {
ContinueJudgment(LabeledStatement target) : super(target);
+ LabeledStatementJudgment get targetJudgment => target;
+
@override
void infer<Expression, Statement, Initializer, Type>(
ShadowTypeInferrer inferrer,
Factory<Expression, Statement, Initializer, Type> factory) {
// No inference needs to be done.
- inferrer.listener.breakStatement(this, fileOffset, null, null, null);
+ inferrer.listener.breakStatement(this, fileOffset, null, null, null,
+ targetJudgment?.createBinder(inferrer));
}
}
@@ -841,13 +844,15 @@
implements StatementJudgment {
ContinueSwitchJudgment(SwitchCase target) : super(target);
+ SwitchCaseJudgment get targetJudgment => target;
+
@override
void infer<Expression, Statement, Initializer, Type>(
ShadowTypeInferrer inferrer,
Factory<Expression, Statement, Initializer, Type> factory) {
// No inference needs to be done.
- inferrer.listener
- .continueSwitchStatement(this, fileOffset, null, null, null);
+ inferrer.listener.continueSwitchStatement(this, fileOffset, null, null,
+ null, targetJudgment?.createBinder(inferrer));
}
}
@@ -1725,14 +1730,26 @@
implements StatementJudgment {
LabeledStatementJudgment(Statement body) : super(body);
+ Object binder;
+
StatementJudgment get judgment => body;
+ Object createBinder(ShadowTypeInferrer inferrer) {
+ // TODO(paulberry): we need one binder for each label
+ return binder ??=
+ inferrer.listener.binderForStatementLabel(this, fileOffset, null);
+ }
+
@override
void infer<Expression, Statement, Initializer, Type>(
ShadowTypeInferrer inferrer,
Factory<Expression, Statement, Initializer, Type> factory) {
inferrer.inferStatement(factory, judgment);
- inferrer.listener.labeledStatement(this, fileOffset, null, null, null);
+ // TODO(paulberry): support multiple labels.
+ List<Object> labels = <Object>[
+ inferrer.listener.statementLabel(createBinder(inferrer), null, null)
+ ];
+ inferrer.listener.labeledStatement(labels, null);
}
}
@@ -2575,6 +2592,8 @@
/// Concrete shadow object representing a switch case.
class SwitchCaseJudgment extends SwitchCase {
+ Object binder;
+
SwitchCaseJudgment(
List<Expression> expressions, List<int> expressionOffsets, Statement body,
{bool isDefault: false})
@@ -2587,6 +2606,12 @@
List<ExpressionJudgment> get expressionJudgments => expressions.cast();
StatementJudgment get bodyJudgment => body;
+
+ Object createBinder(ShadowTypeInferrer inferrer) {
+ // TODO(paulberry): we need one binder for each label
+ return binder ??=
+ inferrer.listener.binderForSwitchLabel(this, fileOffset, null);
+ }
}
/// Concrete shadow object representing a switch statement in kernel form.
@@ -2613,6 +2638,8 @@
factory, caseExpression, expressionType, false);
}
inferrer.inferStatement(factory, switchCase.bodyJudgment);
+ // TODO(paulberry): support labels.
+ inferrer.listener.switchCase(switchCase, null, null, null, null, null);
}
inferrer.listener.switchStatement(
this, fileOffset, null, null, expression, null, null, cases, null);
diff --git a/pkg/front_end/lib/src/fasta/kernel/toplevel_inference_factory.dart b/pkg/front_end/lib/src/fasta/kernel/toplevel_inference_factory.dart
index 6f885d1..67cc2bb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/toplevel_inference_factory.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/toplevel_inference_factory.dart
@@ -11,7 +11,11 @@
import 'factory.dart' show Factory;
import 'kernel_shadow_ast.dart'
- show ExpressionJudgment, InitializerJudgment, StatementJudgment;
+ show
+ ExpressionJudgment,
+ InitializerJudgment,
+ StatementJudgment,
+ SwitchCaseJudgment;
/// Implementation of [Factory] for use during top level type inference, when
/// no representation of the code semantics needs to be created (only the type
@@ -64,8 +68,13 @@
bool value, DartType inferredType) {}
@override
- void breakStatement(StatementJudgment judgment, int fileOffset,
- Token breakKeyword, void label, Token semicolon) {}
+ void breakStatement(
+ StatementJudgment judgment,
+ int fileOffset,
+ Token breakKeyword,
+ void label,
+ Token semicolon,
+ covariant void labelBinder) {}
@override
void cascadeExpression(
@@ -108,12 +117,22 @@
Node expressionTarget, DartType inferredType) {}
@override
- void continueStatement(StatementJudgment judgment, int fileOffset,
- Token continueKeyword, void label, Token semicolon) {}
+ void continueStatement(
+ StatementJudgment judgment,
+ int fileOffset,
+ Token continueKeyword,
+ void label,
+ Token semicolon,
+ covariant void labelBinder) {}
@override
- void continueSwitchStatement(StatementJudgment judgment, int fileOffset,
- Token continueKeyword, void label, Token semicolon) {}
+ void continueSwitchStatement(
+ StatementJudgment judgment,
+ int fileOffset,
+ Token continueKeyword,
+ void label,
+ Token semicolon,
+ covariant void labelBinder) {}
@override
void deferredCheck(
@@ -245,8 +264,14 @@
DartType inferredType) {}
@override
- void labeledStatement(StatementJudgment judgment, int fileOffset, Token label,
- Token colon, void statement) {}
+ void labeledStatement(List<Object> labels, void statement) {}
+
+ @override
+ void statementLabel(covariant void binder, Token label, Token colon) {}
+
+ @override
+ void binderForStatementLabel(
+ StatementJudgment judgment, int fileOffset, String name) {}
@override
void listLiteral(
@@ -402,6 +427,17 @@
Object argumentList) {}
@override
+ void switchCase(SwitchCaseJudgment judgment, List<Object> labels,
+ Token keyword, void expression, Token colon, List<void> statements) {}
+
+ @override
+ void switchLabel(covariant void binder, Token label, Token colon) {}
+
+ @override
+ void binderForSwitchLabel(
+ SwitchCaseJudgment judgment, int fileOffset, String name) {}
+
+ @override
void switchStatement(
StatementJudgment judgment,
int fileOffset,
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart
index 3871939..8f7c7c5 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart
@@ -9,7 +9,11 @@
import '../../scanner/token.dart' show Token;
import '../kernel/kernel_shadow_ast.dart'
- show ExpressionJudgment, InitializerJudgment, StatementJudgment;
+ show
+ ExpressionJudgment,
+ InitializerJudgment,
+ StatementJudgment,
+ SwitchCaseJudgment;
/// Callback interface used by [TypeInferrer] to report the results of type
/// inference to a client.
@@ -63,8 +67,13 @@
void boolLiteral(ExpressionJudgment judgment, Location location,
Token literal, bool value, DartType inferredType);
- void breakStatement(StatementJudgment judgment, Location location,
- Token breakKeyword, void label, Token semicolon);
+ void breakStatement(
+ StatementJudgment judgment,
+ Location location,
+ Token breakKeyword,
+ void label,
+ Token semicolon,
+ covariant Object labelBinder);
void cascadeExpression(
ExpressionJudgment judgment, Location location, DartType inferredType);
@@ -100,11 +109,21 @@
void constructorInvocation(ExpressionJudgment judgment, Location location,
Reference expressionTarget, DartType inferredType);
- void continueStatement(StatementJudgment judgment, Location location,
- Token continueKeyword, void label, Token semicolon);
+ void continueStatement(
+ StatementJudgment judgment,
+ Location location,
+ Token continueKeyword,
+ void label,
+ Token semicolon,
+ covariant Object labelBinder);
- void continueSwitchStatement(StatementJudgment judgment, Location location,
- Token continueKeyword, void label, Token semicolon);
+ void continueSwitchStatement(
+ StatementJudgment judgment,
+ Location location,
+ Token continueKeyword,
+ void label,
+ Token semicolon,
+ covariant Object labelBinder);
void deferredCheck(
ExpressionJudgment judgment, Location location, DartType inferredType);
@@ -218,8 +237,12 @@
DartType type,
DartType inferredType);
- void labeledStatement(StatementJudgment judgment, Location location,
- Token label, Token colon, void statement);
+ void labeledStatement(List<Object> labels, void statement);
+
+ Object statementLabel(covariant Object binder, Token label, Token colon);
+
+ Object binderForStatementLabel(
+ StatementJudgment judgment, int fileOffset, String name);
void listLiteral(
ExpressionJudgment judgment,
@@ -346,6 +369,14 @@
Token constructorName,
covariant Object argumentList);
+ Object switchCase(SwitchCaseJudgment switchCase, List<Object> labels,
+ Token keyword, void expression, Token colon, List<void> statements);
+
+ Object switchLabel(covariant Object binder, Token label, Token colon);
+
+ Object binderForSwitchLabel(
+ SwitchCaseJudgment judgment, int fileOffset, String name);
+
void switchStatement(
StatementJudgment judgment,
Location location,
@@ -469,7 +500,7 @@
@override
void breakStatement(StatementJudgment judgment, location, Token breakKeyword,
- void label, Token semicolon) {}
+ void label, Token semicolon, covariant void labelBinder) {}
@override
void cascadeExpression(
@@ -510,12 +541,22 @@
expressionTarget, DartType inferredType) {}
@override
- void continueStatement(StatementJudgment judgment, location,
- Token continueKeyword, void label, Token semicolon) {}
+ void continueStatement(
+ StatementJudgment judgment,
+ location,
+ Token continueKeyword,
+ void label,
+ Token semicolon,
+ covariant void labelBinder) {}
@override
- void continueSwitchStatement(StatementJudgment judgment, location,
- Token continueKeyword, void label, Token semicolon) {}
+ void continueSwitchStatement(
+ StatementJudgment judgment,
+ location,
+ Token continueKeyword,
+ void label,
+ Token semicolon,
+ covariant void labelBinder) {}
@override
void deferredCheck(
@@ -647,8 +688,14 @@
DartType inferredType) {}
@override
- void labeledStatement(StatementJudgment judgment, location, Token label,
- Token colon, void statement) {}
+ void labeledStatement(List<Object> labels, void statement) {}
+
+ @override
+ void statementLabel(covariant void binder, Token label, Token colon) {}
+
+ @override
+ void binderForStatementLabel(
+ StatementJudgment judgment, int fileOffset, String name) {}
@override
void listLiteral(
@@ -793,6 +840,17 @@
covariant Object argumentList) {}
@override
+ void switchCase(SwitchCaseJudgment switchCase, covariant List<Object> labels,
+ Token keyword, void expression, Token colon, List<void> statements) {}
+
+ @override
+ void switchLabel(covariant void binder, Token label, Token colon) {}
+
+ @override
+ void binderForSwitchLabel(
+ SwitchCaseJudgment judgment, int fileOffset, String name) {}
+
+ @override
void switchStatement(
StatementJudgment judgment,
location,