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

Unified Diff: pkg/kernel/lib/analyzer/ast_from_analyzer.dart

Issue 2617963002: Option to include redirecting factories. (Closed)
Patch Set: Changed upstream branch, no code changes. Created 3 years, 11 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
« no previous file with comments | « no previous file | pkg/kernel/lib/analyzer/loader.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/kernel/lib/analyzer/ast_from_analyzer.dart
diff --git a/pkg/kernel/lib/analyzer/ast_from_analyzer.dart b/pkg/kernel/lib/analyzer/ast_from_analyzer.dart
index 25add69328fc71ba8c719477e8919ce22c694f2e..8f978fc32e621b68efa6c4e1ffe32353f53b34df 100644
--- a/pkg/kernel/lib/analyzer/ast_from_analyzer.dart
+++ b/pkg/kernel/lib/analyzer/ast_from_analyzer.dart
@@ -2352,12 +2352,13 @@ class ClassBodyBuilder extends GeneralizingAstVisitor<Null> {
/// This is true for redirecting factories with a resolved target. These are
/// always bypassed at the call site.
bool _isIgnoredMember(ClassMember node) {
- return node is ConstructorDeclaration &&
- node.factoryKeyword != null &&
- resolutionMap
- .elementDeclaredByConstructorDeclaration(node)
- .redirectedConstructor !=
- null;
+ if (node is ConstructorDeclaration && node.factoryKeyword != null) {
+ var element = resolutionMap.elementDeclaredByConstructorDeclaration(node);
+ return element.redirectedConstructor != null &&
+ (element.isSynthetic || scope.loader.ignoreRedirectingFactories);
+ } else {
+ return false;
+ }
}
visitClassDeclaration(ClassDeclaration node) {
@@ -2673,21 +2674,65 @@ class MemberBodyBuilder extends GeneralizingAstVisitor<Null> {
procedure.function = function..parent = procedure;
handleNativeBody(node.body);
if (node.redirectedConstructor != null) {
- // Redirecting factories with resolved targets don't show up here.
- assert(resolutionMap
- .elementDeclaredByConstructorDeclaration(node)
- .redirectedConstructor ==
- null);
- var function = procedure.function;
- var name = node.redirectedConstructor.type.name.name;
- if (node.redirectedConstructor.name != null) {
- name += '.' + node.redirectedConstructor.name.name;
+ // Add a new synthetic field to [classNode] for representing factory
+ // constructors. This is used by the new frontend engine to support
+ // resolving source code.
+ //
+ // The synthetic field looks like this:
+ //
+ // final _redirecting# = [c1, ..., cn];
+ //
+ // Where each c1 ... cn are an instance of [StaticGet] whose target is
+ // the redirecting factory created above. The new frontend engine reads
+ // this field and rewrites them.
+ //
+ // TODO(ahe): Generate the correct factory body instead. This requires
+ // access to default values from other files, we'll probably never do
+ // that in this file, and instead rely on the new compiler for this.
+ var element = resolutionMap.elementDeclaredByConstructorDeclaration(node);
+ assert(!element.isSynthetic);
+ var expression;
+ if (node.element.redirectedConstructor != null) {
+ assert(!scope.loader.ignoreRedirectingFactories);
+ ConstructorElement element = node.element.redirectedConstructor;
+ while (element.isFactory && element.redirectedConstructor != null) {
+ element = element.redirectedConstructor;
+ }
+ ast.Member target = scope.getMemberReference(element);
+ assert(target != null);
+ expression = new ast.Let(
+ new ast.VariableDeclaration.forValue(new ast.StaticGet(target)),
+ new ast.InvalidExpression());
+ ast.Name constructors =
+ new ast.Name("_redirecting#", scope.currentLibrary);
+ ast.Field constructorsField;
+ for (ast.Field field in classNode.fields) {
+ if (field.name == constructors) {
+ constructorsField = field;
+ break;
+ }
+ }
+ if (constructorsField == null) {
+ ast.ListLiteral literal = new ast.ListLiteral(<ast.Expression>[]);
+ constructorsField = new ast.Field(constructors, isStatic: true,
+ initializer: literal, fileUri: classNode.fileUri)
+ ..fileOffset = classNode.fileOffset;
+ classNode.addMember(constructorsField);
+ }
+ ast.ListLiteral literal = constructorsField.initializer;
+ literal.expressions.add(new ast.StaticGet(procedure)..parent = literal);
+ } else {
+ var name = node.redirectedConstructor.type.name.name;
+ if (node.redirectedConstructor.name != null) {
+ name += '.' + node.redirectedConstructor.name.name;
+ }
+ // TODO(asgerf): Sometimes a TypeError should be thrown.
+ expression = scope.buildThrowNoSuchMethodError(
+ new ast.NullLiteral(), name, new ast.Arguments.empty());
}
- // TODO(asgerf): Sometimes a TypeError should be thrown.
- function.body = new ast.ExpressionStatement(
- scope.buildThrowNoSuchMethodError(
- new ast.NullLiteral(), name, new ast.Arguments.empty()))
- ..parent = function;
+ var function = procedure.function;
+ function.body = new ast.ExpressionStatement(expression)
+ ..parent = function;
}
}
« no previous file with comments | « no previous file | pkg/kernel/lib/analyzer/loader.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698