@@ -9,8 +9,7 @@ import 'package:analyzer/src/dart/ast/ast.dart' show FunctionBodyImpl;
9
9
import 'package:analyzer/src/dart/ast/utilities.dart' show NodeReplacer;
10
10
import 'package:analyzer/src/dart/element/type.dart' show DynamicTypeImpl;
11
11
import 'package:analyzer/src/generated/parser.dart' show ResolutionCopier;
12
- import 'package:analyzer/src/task/strong/info.dart'
13
- show CoercionInfo, DownCast, DynamicInvoke;
12
+ import 'package:analyzer/src/task/strong/ast_properties.dart' as ast_properties;
14
13
import 'package:logging/logging.dart' as logger;
15
14
16
15
import 'ast_builder.dart' show AstBuilder, RawAstBuilder;
@@ -29,19 +28,36 @@ class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object> {
29
28
/// explicit coercion nodes in appropriate places.
30
29
static List <CompilationUnit > reify (List <CompilationUnit > units) {
31
30
var cr = new CoercionReifier ._();
32
- // Clone compilation units, so we don't modify the originals.
33
- units = units.map (cr._clone).toList (growable: false );
34
- units.forEach (cr.visitCompilationUnit);
35
- return units;
31
+ return units.map (cr.visitCompilationUnit).toList (growable: false );
32
+ }
33
+
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
44
@override
39
45
visitExpression (Expression node) {
40
- var coercion = CoercionInfo .get (node);
41
- if (coercion is DownCast ) {
42
- return _visitDownCast (coercion, node);
46
+ node.visitChildren (this );
47
+
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);
52
+ }
53
+
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);
45
61
}
46
62
47
63
@override
@@ -58,14 +74,13 @@ class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object> {
58
74
59
75
// If needed, assert a cast inside the body before the variable is read.
60
76
var variable = node.identifier ?? node.loopVariable.identifier;
61
- var coercion = CoercionInfo . get (variable);
62
- if (coercion is DownCast ) {
77
+ var castType = ast_properties. getImplicitCast (variable);
78
+ if (castType != null ) {
63
79
// Build the cast. We will place this cast in the body, so need to clone
64
80
// the variable's AST node and clear out its static type (otherwise we
65
81
// will optimize away the cast).
66
82
var cast = _castExpression (
67
- _clone (variable)..staticType = DynamicTypeImpl .instance,
68
- coercion.convertedType);
83
+ _clone (variable)..staticType = DynamicTypeImpl .instance, castType);
69
84
70
85
var body = node.body;
71
86
var blockBody = < Statement > [RawAstBuilder .expressionStatement (cast)];
@@ -78,11 +93,6 @@ class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object> {
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
96
void _replaceNode (AstNode parent, AstNode oldNode, AstNode newNode) {
87
97
if (! identical (oldNode, newNode)) {
88
98
var replaced = parent.accept (new NodeReplacer (oldNode, newNode));
@@ -92,19 +102,6 @@ class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object> {
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
105
Expression _castExpression (Expression e, DartType toType) {
109
106
// We use an empty name in the AST, because the JS code generator only cares
110
107
// about the target type. It does not look at the AST name.
@@ -124,9 +121,11 @@ class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object> {
124
121
125
122
class _TreeCloner extends analyzer.AstCloner {
126
123
void _cloneProperties (AstNode clone, AstNode node) {
127
- if (clone != null ) {
128
- CoercionInfo .set (clone, CoercionInfo .get (node));
129
- DynamicInvoke .set (clone, DynamicInvoke .get (node));
124
+ if (clone is Expression ) {
125
+ ast_properties.setImplicitCast (
126
+ clone, ast_properties.getImplicitCast (node));
127
+ ast_properties.setIsDynamicInvoke (
128
+ clone, ast_properties.isDynamicInvoke (node));
130
129
}
131
130
}
132
131
0 commit comments