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

Side by Side Diff: lib/src/compiler/reify_coercions.dart

Issue 2057373003: DDC changes for Analyzer src/task/strong/info.dart refactor (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'package:analyzer/analyzer.dart' as analyzer; 5 import 'package:analyzer/analyzer.dart' as analyzer;
6 import 'package:analyzer/dart/ast/ast.dart'; 6 import 'package:analyzer/dart/ast/ast.dart';
7 import 'package:analyzer/dart/element/type.dart' show DartType; 7 import 'package:analyzer/dart/element/type.dart' show DartType;
8 import 'package:analyzer/src/dart/ast/ast.dart' show FunctionBodyImpl; 8 import 'package:analyzer/src/dart/ast/ast.dart' show FunctionBodyImpl;
9 import 'package:analyzer/src/dart/ast/utilities.dart' show NodeReplacer; 9 import 'package:analyzer/src/dart/ast/utilities.dart' show NodeReplacer;
10 import 'package:analyzer/src/dart/element/type.dart' show DynamicTypeImpl; 10 import 'package:analyzer/src/dart/element/type.dart' show DynamicTypeImpl;
11 import 'package:analyzer/src/generated/parser.dart' show ResolutionCopier; 11 import 'package:analyzer/src/generated/parser.dart' show ResolutionCopier;
12 import 'package:analyzer/src/task/strong/info.dart' 12 import 'package:analyzer/src/task/strong/ast_properties.dart' as ast_properties;
13 show CoercionInfo, DownCast, DynamicInvoke;
14 import 'package:logging/logging.dart' as logger; 13 import 'package:logging/logging.dart' as logger;
15 14
16 import 'ast_builder.dart' show AstBuilder, RawAstBuilder; 15 import 'ast_builder.dart' show AstBuilder, RawAstBuilder;
17 import 'element_helpers.dart' show isInlineJS; 16 import 'element_helpers.dart' show isInlineJS;
18 17
19 final _log = new logger.Logger('dev_compiler.reify_coercions'); 18 final _log = new logger.Logger('dev_compiler.reify_coercions');
20 19
21 // This class implements a pass which modifies (in place) the ast replacing 20 // This class implements a pass which modifies (in place) the ast replacing
22 // abstract coercion nodes with their dart implementations. 21 // abstract coercion nodes with their dart implementations.
23 class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object> { 22 class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object> {
24 final cloner = new _TreeCloner(); 23 final cloner = new _TreeCloner();
25 24
26 CoercionReifier._(); 25 CoercionReifier._();
27 26
28 /// Transforms the given compilation units, and returns a new AST with 27 /// Transforms the given compilation units, and returns a new AST with
29 /// explicit coercion nodes in appropriate places. 28 /// explicit coercion nodes in appropriate places.
30 static List<CompilationUnit> reify(List<CompilationUnit> units) { 29 static List<CompilationUnit> reify(List<CompilationUnit> units) {
31 var cr = new CoercionReifier._(); 30 var cr = new CoercionReifier._();
32 // Clone compilation units, so we don't modify the originals. 31 return units.map(cr.visitCompilationUnit).toList(growable: false);
33 units = units.map(cr._clone).toList(growable: false); 32 }
34 units.forEach(cr.visitCompilationUnit); 33
35 return units; 34 @override
35 CompilationUnit visitCompilationUnit(CompilationUnit node) {
36 if (ast_properties.hasImplicitCasts(node)) {
37 // Clone compilation unit, so we don't modify the originals.
38 node = _clone(node);
39 super.visitCompilationUnit(node);
40 }
41 return node;
36 } 42 }
37 43
38 @override 44 @override
39 visitExpression(Expression node) { 45 visitExpression(Expression node) {
40 var coercion = CoercionInfo.get(node); 46 node.visitChildren(this);
41 if (coercion is DownCast) { 47
42 return _visitDownCast(coercion, node); 48 var castType = ast_properties.getImplicitCast(node);
49 if (castType != null) {
50 _replaceNode(node.parent, node, _castExpression(node, castType));
43 } 51 }
44 return super.visitExpression(node);
45 } 52 }
46 53
47 @override 54 @override
55 visitMethodInvocation(MethodInvocation node) {
56 if (isInlineJS(node.methodName.staticElement)) {
57 // Don't cast our inline-JS code in SDK.
58 ast_properties.setImplicitCast(node, null);
59 }
60 visitExpression(node);
61 }
62
63 @override
48 visitParenthesizedExpression(ParenthesizedExpression node) { 64 visitParenthesizedExpression(ParenthesizedExpression node) {
49 super.visitParenthesizedExpression(node); 65 super.visitParenthesizedExpression(node);
50 node.staticType = node.expression.staticType; 66 node.staticType = node.expression.staticType;
51 } 67 }
52 68
53 @override 69 @override
54 visitForEachStatement(ForEachStatement node) { 70 visitForEachStatement(ForEachStatement node) {
55 // Visit other children. 71 // Visit other children.
56 node.iterable.accept(this); 72 node.iterable.accept(this);
57 node.body.accept(this); 73 node.body.accept(this);
58 74
59 // If needed, assert a cast inside the body before the variable is read. 75 // If needed, assert a cast inside the body before the variable is read.
60 var variable = node.identifier ?? node.loopVariable.identifier; 76 var variable = node.identifier ?? node.loopVariable.identifier;
61 var coercion = CoercionInfo.get(variable); 77 var castType = ast_properties.getImplicitCast(variable);
62 if (coercion is DownCast) { 78 if (castType != null) {
63 // Build the cast. We will place this cast in the body, so need to clone 79 // Build the cast. We will place this cast in the body, so need to clone
64 // the variable's AST node and clear out its static type (otherwise we 80 // the variable's AST node and clear out its static type (otherwise we
65 // will optimize away the cast). 81 // will optimize away the cast).
66 var cast = _castExpression( 82 var cast = _castExpression(
67 _clone(variable)..staticType = DynamicTypeImpl.instance, 83 _clone(variable)..staticType = DynamicTypeImpl.instance, castType);
68 coercion.convertedType);
69 84
70 var body = node.body; 85 var body = node.body;
71 var blockBody = <Statement>[RawAstBuilder.expressionStatement(cast)]; 86 var blockBody = <Statement>[RawAstBuilder.expressionStatement(cast)];
72 if (body is Block) { 87 if (body is Block) {
73 blockBody.addAll(body.statements); 88 blockBody.addAll(body.statements);
74 } else { 89 } else {
75 blockBody.add(body); 90 blockBody.add(body);
76 } 91 }
77 _replaceNode(node, body, RawAstBuilder.block(blockBody)); 92 _replaceNode(node, body, RawAstBuilder.block(blockBody));
78 } 93 }
79 } 94 }
80 95
81 void _visitDownCast(DownCast node, Expression expr) {
82 expr.visitChildren(this);
83 _replaceNode(expr.parent, expr, coerceExpression(expr, node));
84 }
85
86 void _replaceNode(AstNode parent, AstNode oldNode, AstNode newNode) { 96 void _replaceNode(AstNode parent, AstNode oldNode, AstNode newNode) {
87 if (!identical(oldNode, newNode)) { 97 if (!identical(oldNode, newNode)) {
88 var replaced = parent.accept(new NodeReplacer(oldNode, newNode)); 98 var replaced = parent.accept(new NodeReplacer(oldNode, newNode));
89 // It looks like NodeReplacer will always return true. 99 // It looks like NodeReplacer will always return true.
90 // It does throw IllegalArgumentException though, if child is not found. 100 // It does throw IllegalArgumentException though, if child is not found.
91 assert(replaced); 101 assert(replaced);
92 } 102 }
93 } 103 }
94 104
95 /// Coerce [e] using [c], returning a new expression.
96 Expression coerceExpression(Expression e, DownCast node) {
97 if (e is NamedExpression) {
98 Expression inner = coerceExpression(e.expression, node);
99 return new NamedExpression(e.name, inner);
100 }
101 if (e is MethodInvocation && isInlineJS(e.methodName.staticElement)) {
102 // Inline JS code should not need casts.
103 return e;
104 }
105 return _castExpression(e, node.convertedType);
106 }
107
108 Expression _castExpression(Expression e, DartType toType) { 105 Expression _castExpression(Expression e, DartType toType) {
109 // We use an empty name in the AST, because the JS code generator only cares 106 // We use an empty name in the AST, because the JS code generator only cares
110 // about the target type. It does not look at the AST name. 107 // about the target type. It does not look at the AST name.
111 var typeName = new TypeName(AstBuilder.identifierFromString(''), null); 108 var typeName = new TypeName(AstBuilder.identifierFromString(''), null);
112 typeName.type = toType; 109 typeName.type = toType;
113 var cast = AstBuilder.asExpression(e, typeName); 110 var cast = AstBuilder.asExpression(e, typeName);
114 cast.staticType = toType; 111 cast.staticType = toType;
115 return cast; 112 return cast;
116 } 113 }
117 114
118 /*=T*/ _clone/*<T extends AstNode>*/(/*=T*/ node) { 115 /*=T*/ _clone/*<T extends AstNode>*/(/*=T*/ node) {
119 var copy = node.accept(cloner) as dynamic/*=T*/; 116 var copy = node.accept(cloner) as dynamic/*=T*/;
120 ResolutionCopier.copyResolutionData(node, copy); 117 ResolutionCopier.copyResolutionData(node, copy);
121 return copy; 118 return copy;
122 } 119 }
123 } 120 }
124 121
125 class _TreeCloner extends analyzer.AstCloner { 122 class _TreeCloner extends analyzer.AstCloner {
126 void _cloneProperties(AstNode clone, AstNode node) { 123 void _cloneProperties(AstNode clone, AstNode node) {
127 if (clone != null) { 124 if (clone is Expression) {
128 CoercionInfo.set(clone, CoercionInfo.get(node)); 125 ast_properties.setImplicitCast(
129 DynamicInvoke.set(clone, DynamicInvoke.get(node)); 126 clone, ast_properties.getImplicitCast(node));
127 ast_properties.setIsDynamicInvoke(
128 clone, ast_properties.isDynamicInvoke(node));
130 } 129 }
131 } 130 }
132 131
133 @override 132 @override
134 /*=E*/ cloneNode/*<E extends AstNode>*/(/*=E*/ node) { 133 /*=E*/ cloneNode/*<E extends AstNode>*/(/*=E*/ node) {
135 var clone = super.cloneNode(node); 134 var clone = super.cloneNode(node);
136 _cloneProperties(clone, node); 135 _cloneProperties(clone, node);
137 return clone; 136 return clone;
138 } 137 }
139 138
(...skipping 26 matching lines...) Expand all
166 165
167 // TODO(jmesserly): workaround for 166 // TODO(jmesserly): workaround for
168 // https://github.com/dart-lang/sdk/issues/26368 167 // https://github.com/dart-lang/sdk/issues/26368
169 @override 168 @override
170 TypeName visitTypeName(TypeName node) { 169 TypeName visitTypeName(TypeName node) {
171 var clone = super.visitTypeName(node); 170 var clone = super.visitTypeName(node);
172 clone.type = node.type; 171 clone.type = node.type;
173 return clone; 172 return clone;
174 } 173 }
175 } 174 }
OLDNEW
« no previous file with comments | « lib/src/compiler/code_generator.dart ('k') | pubspec.lock » ('j') | pubspec.yaml » ('J')

Powered by Google App Engine
This is Rietveld 408576698