Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Unified Diff: pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart

Issue 2933733002: Throw NSM on unresolved factory redirection. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
diff --git a/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart b/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
index ee0c60543366bc7f36bd9e31e03b5b68c68dffbb..1fa7dd80fbc534085ebc48ef3453523d81fadbc0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
@@ -6,38 +6,67 @@ library fasta.redirecting_factory_body;
import 'package:kernel/ast.dart'
show
+ Expression,
ExpressionStatement,
+ FunctionNode,
InvalidExpression,
Let,
Member,
Procedure,
StaticGet,
+ StringLiteral,
VariableDeclaration;
+const String letName = "#redirecting_factory";
+
class RedirectingFactoryBody extends ExpressionStatement {
- RedirectingFactoryBody(Member target)
- : super(new Let(new VariableDeclaration.forValue(new StaticGet(target)),
+ RedirectingFactoryBody.internal(Expression value)
Paul Berry 2017/06/12 20:55:41 Nit: I prefer to name internal constructors like t
ahe 2017/06/13 07:11:41 Acknowledged.
+ : super(new Let(new VariableDeclaration(letName, initializer: value),
new InvalidExpression()));
+ RedirectingFactoryBody(Member target) : this.internal(new StaticGet(target));
+
+ RedirectingFactoryBody.unresolved(String name)
+ : this.internal(new StringLiteral(name));
+
Member get target {
- Let let = expression;
- StaticGet staticGet = let.variable.initializer;
- return staticGet.target;
+ var value = getValue(expression);
+ return value is StaticGet ? value.target : null;
}
-}
-bool isRedirectingFactory(Member member) {
- return member is Procedure && member.function.body is RedirectingFactoryBody;
-}
+ String get unresolvedName {
+ var value = getValue(expression);
+ return value is StringLiteral ? value.value : null;
+ }
-Member getImmediateRedirectionTarget(Member member) {
- if (isRedirectingFactory(member)) {
- Procedure procedure = member;
- RedirectingFactoryBody body = procedure.function.body;
- return body.target;
- } else {
+ bool get isUnresolved => unresolvedName != null;
+
+ static getValue(Expression expression) {
+ if (expression is Let) {
+ VariableDeclaration variable = expression.variable;
+ if (variable.name == letName) {
+ return variable.initializer;
+ }
+ }
return null;
}
+
+ static void restoreFromDill(Procedure factory) {
+ // This is a hack / work around for storing redirecting constructors in
+ // dill files. See `KernelClassBuilder.addRedirectingConstructor` in
+ // [kernel_class_builder.dart](kernel_class_builder.dart).
+ FunctionNode function = factory.function;
+ ExpressionStatement statement = function.body;
+ function.body =
+ new RedirectingFactoryBody.internal(getValue(statement.expression))
Paul Berry 2017/06/12 20:55:41 Nit: I think we should report an internalError if
ahe 2017/06/13 07:11:41 I think I want to iterate more on this. I'll follo
+ ..parent = function;
+ }
+}
+
+RedirectingFactoryBody getRedirectingFactoryBody(Member member) {
+ return member is Procedure && member.function.body is RedirectingFactoryBody
+ ? member.function.body
+ : null;
}
Member getRedirectionTarget(Procedure member) {
@@ -45,11 +74,15 @@ Member getRedirectionTarget(Procedure member) {
// (https://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare) to
// handle cycles.
Member tortoise = member;
- Member hare = getImmediateRedirectionTarget(member);
+ RedirectingFactoryBody tortoiseBody = getRedirectingFactoryBody(tortoise);
+ Member hare = tortoiseBody?.target;
+ RedirectingFactoryBody hareBody = getRedirectingFactoryBody(hare);
while (tortoise != hare) {
- if (!isRedirectingFactory(tortoise)) return tortoise;
- tortoise = getImmediateRedirectionTarget(tortoise);
- hare = getImmediateRedirectionTarget(getImmediateRedirectionTarget(hare));
+ if (tortoiseBody?.isUnresolved ?? true) return tortoise;
+ tortoise = tortoiseBody.target;
+ tortoiseBody = getRedirectingFactoryBody(tortoise);
+ hare = getRedirectingFactoryBody(hareBody?.target)?.target;
+ hareBody = getRedirectingFactoryBody(hare);
}
return null;
}

Powered by Google App Engine
This is Rietveld 408576698