| OLD | NEW |
| 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 library dev_compiler.src.codegen.reify_coercions; | 5 library dev_compiler.src.codegen.reify_coercions; |
| 6 | 6 |
| 7 import 'package:analyzer/analyzer.dart' as analyzer; | 7 import 'package:analyzer/analyzer.dart' as analyzer; |
| 8 import 'package:analyzer/src/generated/ast.dart'; | 8 import 'package:analyzer/src/generated/ast.dart'; |
| 9 import 'package:analyzer/src/generated/element.dart'; | 9 import 'package:analyzer/src/generated/element.dart'; |
| 10 import 'package:logging/logging.dart' as logger; | 10 import 'package:logging/logging.dart' as logger; |
| 11 | 11 |
| 12 import 'package:dev_compiler/devc.dart' show AbstractCompiler; | 12 import 'package:dev_compiler/devc.dart' show AbstractCompiler; |
| 13 import 'package:dev_compiler/src/checker/rules.dart'; | 13 import 'package:dev_compiler/src/checker/rules.dart'; |
| 14 import 'package:dev_compiler/src/info.dart'; | 14 import 'package:dev_compiler/src/info.dart'; |
| 15 import 'package:dev_compiler/src/options.dart' show CompilerOptions; | |
| 16 | 15 |
| 17 import 'ast_builder.dart'; | 16 import 'ast_builder.dart'; |
| 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 // TODO(leafp) Factor this out or use an existing library | 20 // TODO(leafp) Factor this out or use an existing library |
| 22 class Tuple2<T0, T1> { | 21 class Tuple2<T0, T1> { |
| 23 final T0 e0; | 22 final T0 e0; |
| 24 final T1 e1; | 23 final T1 e1; |
| 25 Tuple2(this.e0, this.e1); | 24 Tuple2(this.e0, this.e1); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 } | 89 } |
| 91 | 90 |
| 92 // This class implements a pass which modifies (in place) the ast replacing | 91 // This class implements a pass which modifies (in place) the ast replacing |
| 93 // abstract coercion nodes with their dart implementations. | 92 // abstract coercion nodes with their dart implementations. |
| 94 class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object> | 93 class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object> |
| 95 with ConversionVisitor<Object> { | 94 with ConversionVisitor<Object> { |
| 96 final CoercionManager _cm; | 95 final CoercionManager _cm; |
| 97 final TypeManager _tm; | 96 final TypeManager _tm; |
| 98 final VariableManager _vm; | 97 final VariableManager _vm; |
| 99 final LibraryUnit _library; | 98 final LibraryUnit _library; |
| 100 bool _skipCoercions = false; | |
| 101 final _Inference _inferrer; | 99 final _Inference _inferrer; |
| 102 final CompilerOptions _options; | |
| 103 | 100 |
| 104 CoercionReifier._(this._cm, this._tm, this._vm, this._library, this._inferrer, | 101 CoercionReifier._( |
| 105 this._options); | 102 this._cm, this._tm, this._vm, this._library, this._inferrer); |
| 106 | 103 |
| 107 factory CoercionReifier(LibraryUnit library, AbstractCompiler compiler) { | 104 factory CoercionReifier(LibraryUnit library, AbstractCompiler compiler) { |
| 108 var vm = new VariableManager(); | 105 var vm = new VariableManager(); |
| 109 var tm = new TypeManager(library.library.element.enclosingElement, vm); | 106 var tm = new TypeManager(library.library.element.enclosingElement, vm); |
| 110 var cm = new CoercionManager(vm, tm); | 107 var cm = new CoercionManager(vm, tm); |
| 111 var inferrer = new _Inference(compiler.rules, tm); | 108 var inferrer = new _Inference(compiler.rules, tm); |
| 112 var options = compiler.options; | 109 return new CoercionReifier._(cm, tm, vm, library, inferrer); |
| 113 return new CoercionReifier._(cm, tm, vm, library, inferrer, options); | |
| 114 } | 110 } |
| 115 | 111 |
| 116 // This should be the entry point for this class. Entering via the | 112 // This should be the entry point for this class. Entering via the |
| 117 // visit functions directly may not do the right thing with respect | 113 // visit functions directly may not do the right thing with respect |
| 118 // to discharging the collected definitions. | 114 // to discharging the collected definitions. |
| 119 // Returns the set of new type identifiers added by the reifier | 115 // Returns the set of new type identifiers added by the reifier |
| 120 Map<Identifier, NewTypeIdDesc> reify() { | 116 Map<Identifier, NewTypeIdDesc> reify() { |
| 121 _library.partsThenLibrary.forEach(generateUnit); | 117 _library.partsThenLibrary.forEach(generateUnit); |
| 122 return _tm.addedTypes; | 118 return _tm.addedTypes; |
| 123 } | 119 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 135 assert(b); | 131 assert(b); |
| 136 if (!NodeReplacer.replace(node, expr)) { | 132 if (!NodeReplacer.replace(node, expr)) { |
| 137 _log.severe("Failed to replace node for InferredType"); | 133 _log.severe("Failed to replace node for InferredType"); |
| 138 } | 134 } |
| 139 expr.accept(this); | 135 expr.accept(this); |
| 140 return null; | 136 return null; |
| 141 } | 137 } |
| 142 | 138 |
| 143 @override | 139 @override |
| 144 Object visitDownCast(DownCast node) { | 140 Object visitDownCast(DownCast node) { |
| 145 if (_skipCoercions && !_options.allowConstCasts) { | |
| 146 _log.severe("Skipping runtime downcast in constant context"); | |
| 147 return null; | |
| 148 } | |
| 149 Expression castNode = _cm.coerceExpression(node.node, node.cast); | 141 Expression castNode = _cm.coerceExpression(node.node, node.cast); |
| 150 if (!NodeReplacer.replace(node, castNode)) { | 142 if (!NodeReplacer.replace(node, castNode)) { |
| 151 _log.severe("Failed to replace node for DownCast"); | 143 _log.severe("Failed to replace node for DownCast"); |
| 152 } | 144 } |
| 153 castNode.accept(this); | 145 castNode.accept(this); |
| 154 return null; | 146 return null; |
| 155 } | 147 } |
| 156 | 148 |
| 157 // TODO(leafp): Bind the coercions at the top level | 149 // TODO(leafp): Bind the coercions at the top level |
| 158 @override | 150 @override |
| 159 Object visitClosureWrapBase(ClosureWrapBase node) { | 151 Object visitClosureWrapBase(ClosureWrapBase node) { |
| 160 if (_skipCoercions && !_options.allowConstCasts) { | |
| 161 _log.severe("Skipping coercion wrap in constant context"); | |
| 162 return null; | |
| 163 } | |
| 164 Expression newE = _cm.coerceExpression(node.node, node.wrapper); | 152 Expression newE = _cm.coerceExpression(node.node, node.wrapper); |
| 165 if (!NodeReplacer.replace(node, newE)) { | 153 if (!NodeReplacer.replace(node, newE)) { |
| 166 _log.severe("Failed to replace node for Closure Wrap"); | 154 _log.severe("Failed to replace node for Closure Wrap"); |
| 167 } | 155 } |
| 168 newE.accept(this); | 156 newE.accept(this); |
| 169 return null; | 157 return null; |
| 170 } | 158 } |
| 171 | 159 |
| 172 @override | |
| 173 Object visitNode(AstNode n) { | |
| 174 var o = _skipCoercions; | |
| 175 if (!o) { | |
| 176 if (n is VariableDeclarationList) { | |
| 177 _skipCoercions = o || n.isConst; | |
| 178 } else if (n is VariableDeclaration) { | |
| 179 _skipCoercions = o || n.isConst; | |
| 180 } else if (n is FormalParameter) { | |
| 181 _skipCoercions = o || n.isConst; | |
| 182 } else if (n is InstanceCreationExpression) { | |
| 183 _skipCoercions = o || n.isConst; | |
| 184 } else if (n is ConstructorDeclaration) { | |
| 185 _skipCoercions = o || n.element.isConst; | |
| 186 } | |
| 187 } | |
| 188 Object ret = super.visitNode(n); | |
| 189 _skipCoercions = o; | |
| 190 return ret; | |
| 191 } | |
| 192 | |
| 193 Object visitCompilationUnit(CompilationUnit unit) { | 160 Object visitCompilationUnit(CompilationUnit unit) { |
| 194 _cm.enterCompilationUnit(unit); | 161 _cm.enterCompilationUnit(unit); |
| 195 Object ret = super.visitCompilationUnit(unit); | 162 Object ret = super.visitCompilationUnit(unit); |
| 196 _cm.exitCompilationUnit(unit); | 163 _cm.exitCompilationUnit(unit); |
| 197 return ret; | 164 return ret; |
| 198 } | 165 } |
| 199 | 166 |
| 200 @override | 167 @override |
| 201 Object visitClassDeclaration(ClassDeclaration cl) { | 168 Object visitClassDeclaration(ClassDeclaration cl) { |
| 202 _cm.enterClass(); | 169 _cm.enterClass(); |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 var t = _mkNewTypeName(dType, id, args); | 681 var t = _mkNewTypeName(dType, id, args); |
| 715 return t; | 682 return t; |
| 716 } | 683 } |
| 717 | 684 |
| 718 TypeName _mkNewTypeName(DartType type, Identifier id, List<TypeName> args) { | 685 TypeName _mkNewTypeName(DartType type, Identifier id, List<TypeName> args) { |
| 719 var t = AstBuilder.typeName(id, args); | 686 var t = AstBuilder.typeName(id, args); |
| 720 t.type = type; | 687 t.type = type; |
| 721 return t; | 688 return t; |
| 722 } | 689 } |
| 723 } | 690 } |
| OLD | NEW |