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

Unified Diff: lib/src/codegen/reify_coercions.dart

Issue 1840713003: fix to run against latest analyzer (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 9 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: lib/src/codegen/reify_coercions.dart
diff --git a/lib/src/codegen/reify_coercions.dart b/lib/src/codegen/reify_coercions.dart
index 4ed5003fdbf6ab9e0cc53a63cbc53a8a342f273d..f38e039aba799c26b67fdb1bfadab7873455aaed 100644
--- a/lib/src/codegen/reify_coercions.dart
+++ b/lib/src/codegen/reify_coercions.dart
@@ -6,7 +6,10 @@ import 'package:analyzer/analyzer.dart' as analyzer;
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/ast.dart' show FunctionBodyImpl;
import 'package:analyzer/src/dart/ast/utilities.dart' show NodeReplacer;
+import 'package:analyzer/src/dart/element/type.dart' show DynamicTypeImpl;
+import 'package:analyzer/src/generated/parser.dart' show ResolutionCopier;
import 'package:analyzer/src/task/strong/info.dart';
import 'package:logging/logging.dart' as logger;
@@ -30,41 +33,71 @@ class NewTypeIdDesc {
// This class implements a pass which modifies (in place) the ast replacing
// abstract coercion nodes with their dart implementations.
class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object> {
+ final cloner = new _TreeCloner();
- CoercionReifier();
-
- /// This should be the entry point for this class.
+ /// Makes coercions explicit in the resolved AST, and returns the new AST.
///
- /// Entering via the visit functions directly may not do the right
- /// thing with respect to discharging the collected definitions.
+ /// This should be the entry point for this class.
+ /// Entering via the visit functions directly will incorrectly mutate the AST.
///
- /// Returns the set of new type identifiers added by the reifier
- void reify(List<CompilationUnit> units) {
+ /// Returns the new compilation units.
+ List<CompilationUnit> reify(List<CompilationUnit> units) {
+ // Copy the AST before modifying it.
+ units = units.map(_clone).toList();
+ // Visit the AST and make coercions explicit.
units.forEach(visitCompilationUnit);
+ return units;
}
@override
- Object visitExpression(Expression node) {
- var info = CoercionInfo.get(node);
- if (info is DownCast) {
- return _visitDownCast(info, node);
+ visitExpression(Expression node) {
+ var coercion = CoercionInfo.get(node);
+ if (coercion is DownCast) {
+ return _visitDownCast(coercion, node);
}
return super.visitExpression(node);
}
- ///////////////// Private //////////////////////////////////
+ @override
+ visitForEachStatement(ForEachStatement node) {
+ // Visit other children.
+ node.iterable.accept(this);
+ node.body.accept(this);
+
+ // If needed, assert a cast inside the body before the variable is read.
+ var variable = node.identifier ?? node.loopVariable.identifier;
+ var coercion = CoercionInfo.get(variable);
+ if (coercion is DownCast) {
+ // Build the cast. We will place this cast in the body, so need to clone
+ // the variable's AST node and clear out its static type (otherwise we
+ // will optimize away the cast).
+ var cast = _castExpression(
+ _clone(variable)..staticType = DynamicTypeImpl.instance,
+ coercion.convertedType);
+
+ var body = node.body;
+ var blockBody = <Statement>[RawAstBuilder.expressionStatement(cast)];
+ if (body is Block) {
+ blockBody.addAll(body.statements);
+ } else {
+ blockBody.add(body);
+ }
+ _replaceNode(node, body, RawAstBuilder.block(blockBody));
+ }
+ }
- Object _visitDownCast(DownCast node, Expression expr) {
- var parent = expr.parent;
+ void _visitDownCast(DownCast node, Expression expr) {
expr.visitChildren(this);
- Expression newE = coerceExpression(expr, node);
- if (!identical(expr, newE)) {
- var replaced = parent.accept(new NodeReplacer(expr, newE));
+ _replaceNode(expr.parent, expr, coerceExpression(expr, node));
+ }
+
+ void _replaceNode(AstNode parent, AstNode oldNode, AstNode newNode) {
+ if (!identical(oldNode, newNode)) {
+ var replaced = parent.accept(new NodeReplacer(oldNode, newNode));
// It looks like NodeReplacer will always return true.
// It does throw IllegalArgumentException though, if child is not found.
assert(replaced);
}
- return null;
}
/// Coerce [e] using [c], returning a new expression.
@@ -76,8 +109,6 @@ class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object> {
return _castExpression(e, node.convertedType);
}
- ///////////////// Private //////////////////////////////////
-
Expression _castExpression(Expression e, DartType toType) {
// We use an empty name in the AST, because the JS code generator only cares
// about the target type. It does not look at the AST name.
@@ -87,4 +118,53 @@ class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object> {
cast.staticType = toType;
return cast;
}
+
+ /*=T*/ _clone/*<T extends AstNode>*/(/*=T*/ node) {
+ var copy = node.accept(cloner);
+ ResolutionCopier.copyResolutionData(node, copy);
+ return copy;
+ }
+}
+
+class _TreeCloner extends analyzer.AstCloner {
+ void _cloneProperties(AstNode clone, AstNode node) {
+ if (clone != null) {
+ CoercionInfo.set(clone, CoercionInfo.get(node));
+ DynamicInvoke.set(clone, DynamicInvoke.get(node));
+ }
+ }
+
+ @override
+ AstNode cloneNode(AstNode node) {
+ var clone = super.cloneNode(node);
+ _cloneProperties(clone, node);
+ return clone;
+ }
+
+ @override
+ List cloneNodeList(List list) {
+ var clone = super.cloneNodeList(list);
+ for (int i = 0, len = list.length; i < len; i++) {
+ _cloneProperties(clone[i], list[i]);
+ }
+ return clone;
+ }
+
+ // TODO(jmesserly): ResolutionCopier is not copying this yet.
+ @override
+ BlockFunctionBody visitBlockFunctionBody(BlockFunctionBody node) {
+ var clone = super.visitBlockFunctionBody(node);
+ (clone as FunctionBodyImpl).localVariableInfo =
+ (node as FunctionBodyImpl).localVariableInfo;
+ return clone;
+ }
+
+ @override
+ ExpressionFunctionBody visitExpressionFunctionBody(
+ ExpressionFunctionBody node) {
+ var clone = super.visitExpressionFunctionBody(node);
+ (clone as FunctionBodyImpl).localVariableInfo =
+ (node as FunctionBodyImpl).localVariableInfo;
+ return clone;
+ }
}

Powered by Google App Engine
This is Rietveld 408576698