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

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

Issue 2362563004: re-land fix #27110 with proper DDC side of changes (Closed)
Patch Set: add tests Created 4 years, 3 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
« no previous file with comments | « pkg/dev_compiler/lib/src/compiler/code_generator.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
(...skipping 13 matching lines...) Expand all
24 24
25 CoercionReifier._(); 25 CoercionReifier._();
26 26
27 /// Transforms the given compilation units, and returns a new AST with 27 /// Transforms the given compilation units, and returns a new AST with
28 /// explicit coercion nodes in appropriate places. 28 /// explicit coercion nodes in appropriate places.
29 static List<CompilationUnit> reify(List<CompilationUnit> units) { 29 static List<CompilationUnit> reify(List<CompilationUnit> units) {
30 var cr = new CoercionReifier._(); 30 var cr = new CoercionReifier._();
31 return units.map(cr.visitCompilationUnit).toList(growable: false); 31 return units.map(cr.visitCompilationUnit).toList(growable: false);
32 } 32 }
33 33
34
35 /// Returns true if the `as` [node] was created by this class.
36 // TODO(sra): Find a better way to recognize reified coercion, since we
37 // can't set the isSynthetic attribute.
38 static bool isImplicitCast(AsExpression node) => node.asOperator.offset == 0;
39
40 /// Creates an implicit cast for expression [e] to [toType].
41 static Expression castExpression(Expression e, DartType toType) {
42 // We use an empty name in the AST, because the JS code generator only cares
43 // about the target type. It does not look at the AST name.
44 var typeName = new TypeName(AstBuilder.identifierFromString(''), null);
45 typeName.type = toType;
46 var cast = AstBuilder.asExpression(e, typeName);
47 cast.staticType = toType;
48 return cast;
49 }
50
34 @override 51 @override
35 CompilationUnit visitCompilationUnit(CompilationUnit node) { 52 CompilationUnit visitCompilationUnit(CompilationUnit node) {
36 if (ast_properties.hasImplicitCasts(node)) { 53 if (ast_properties.hasImplicitCasts(node)) {
37 // Clone compilation unit, so we don't modify the originals. 54 // Clone compilation unit, so we don't modify the originals.
38 node = _clone(node); 55 node = _clone(node);
39 super.visitCompilationUnit(node); 56 super.visitCompilationUnit(node);
40 } 57 }
41 return node; 58 return node;
42 } 59 }
43 60
44 @override 61 @override
45 visitExpression(Expression node) { 62 visitExpression(Expression node) {
46 node.visitChildren(this); 63 node.visitChildren(this);
47 64
48 var castType = ast_properties.getImplicitCast(node); 65 var castType = ast_properties.getImplicitCast(node);
49 if (castType != null) { 66 if (castType != null) {
50 _replaceNode(node.parent, node, _castExpression(node, castType)); 67 _replaceNode(node.parent, node, castExpression(node, castType));
51 } 68 }
52 } 69 }
53 70
54 @override 71 @override
55 visitMethodInvocation(MethodInvocation node) { 72 visitMethodInvocation(MethodInvocation node) {
56 if (isInlineJS(node.methodName.staticElement)) { 73 if (isInlineJS(node.methodName.staticElement)) {
57 // Don't cast our inline-JS code in SDK. 74 // Don't cast our inline-JS code in SDK.
58 ast_properties.setImplicitCast(node, null); 75 ast_properties.setImplicitCast(node, null);
59 } 76 }
60 visitExpression(node); 77 visitExpression(node);
(...skipping 11 matching lines...) Expand all
72 node.iterable.accept(this); 89 node.iterable.accept(this);
73 node.body.accept(this); 90 node.body.accept(this);
74 91
75 // If needed, assert a cast inside the body before the variable is read. 92 // If needed, assert a cast inside the body before the variable is read.
76 var variable = node.identifier ?? node.loopVariable.identifier; 93 var variable = node.identifier ?? node.loopVariable.identifier;
77 var castType = ast_properties.getImplicitCast(variable); 94 var castType = ast_properties.getImplicitCast(variable);
78 if (castType != null) { 95 if (castType != null) {
79 // Build the cast. We will place this cast in the body, so need to clone 96 // Build the cast. We will place this cast in the body, so need to clone
80 // the variable's AST node and clear out its static type (otherwise we 97 // the variable's AST node and clear out its static type (otherwise we
81 // will optimize away the cast). 98 // will optimize away the cast).
82 var cast = _castExpression( 99 var cast = castExpression(
83 _clone(variable)..staticType = DynamicTypeImpl.instance, castType); 100 _clone(variable)..staticType = DynamicTypeImpl.instance, castType);
84 101
85 var body = node.body; 102 var body = node.body;
86 var blockBody = <Statement>[RawAstBuilder.expressionStatement(cast)]; 103 var blockBody = <Statement>[RawAstBuilder.expressionStatement(cast)];
87 if (body is Block) { 104 if (body is Block) {
88 blockBody.addAll(body.statements); 105 blockBody.addAll(body.statements);
89 } else { 106 } else {
90 blockBody.add(body); 107 blockBody.add(body);
91 } 108 }
92 _replaceNode(node, body, RawAstBuilder.block(blockBody)); 109 _replaceNode(node, body, RawAstBuilder.block(blockBody));
93 } 110 }
94 } 111 }
95 112
96 void _replaceNode(AstNode parent, AstNode oldNode, AstNode newNode) { 113 void _replaceNode(AstNode parent, AstNode oldNode, AstNode newNode) {
97 if (!identical(oldNode, newNode)) { 114 if (!identical(oldNode, newNode)) {
98 var replaced = parent.accept(new NodeReplacer(oldNode, newNode)); 115 var replaced = parent.accept(new NodeReplacer(oldNode, newNode));
99 // It looks like NodeReplacer will always return true. 116 // It looks like NodeReplacer will always return true.
100 // It does throw IllegalArgumentException though, if child is not found. 117 // It does throw IllegalArgumentException though, if child is not found.
101 assert(replaced); 118 assert(replaced);
102 } 119 }
103 } 120 }
104 121
105 Expression _castExpression(Expression e, DartType toType) {
106 // We use an empty name in the AST, because the JS code generator only cares
107 // about the target type. It does not look at the AST name.
108 var typeName = new TypeName(AstBuilder.identifierFromString(''), null);
109 typeName.type = toType;
110 var cast = AstBuilder.asExpression(e, typeName);
111 cast.staticType = toType;
112 return cast;
113 }
114
115 /*=T*/ _clone/*<T extends AstNode>*/(/*=T*/ node) { 122 /*=T*/ _clone/*<T extends AstNode>*/(/*=T*/ node) {
116 var copy = node.accept(cloner) as dynamic/*=T*/; 123 var copy = node.accept(cloner) as dynamic/*=T*/;
117 ResolutionCopier.copyResolutionData(node, copy); 124 ResolutionCopier.copyResolutionData(node, copy);
118 return copy; 125 return copy;
119 } 126 }
120 } 127 }
121 128
122 class _TreeCloner extends analyzer.AstCloner { 129 class _TreeCloner extends analyzer.AstCloner {
123 void _cloneProperties(AstNode clone, AstNode node) { 130 void _cloneProperties(AstNode clone, AstNode node) {
124 if (clone is Expression) { 131 if (clone is Expression) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 172
166 // TODO(jmesserly): workaround for 173 // TODO(jmesserly): workaround for
167 // https://github.com/dart-lang/sdk/issues/26368 174 // https://github.com/dart-lang/sdk/issues/26368
168 @override 175 @override
169 TypeName visitTypeName(TypeName node) { 176 TypeName visitTypeName(TypeName node) {
170 var clone = super.visitTypeName(node); 177 var clone = super.visitTypeName(node);
171 clone.type = node.type; 178 clone.type = node.type;
172 return clone; 179 return clone;
173 } 180 }
174 } 181 }
OLDNEW
« no previous file with comments | « pkg/dev_compiler/lib/src/compiler/code_generator.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698