OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
6 | 6 |
| 7 import '../common.dart'; |
7 import '../compiler.dart'; | 8 import '../compiler.dart'; |
8 import '../constants/values.dart'; | 9 import '../constants/values.dart'; |
9 import '../diagnostics/invariant.dart'; | 10 import '../dart_types.dart'; |
10 import '../elements/elements.dart'; | 11 import '../elements/elements.dart'; |
11 import '../js_backend/js_backend.dart'; | 12 import '../js_backend/js_backend.dart'; |
12 import '../resolution/tree_elements.dart'; | 13 import '../resolution/tree_elements.dart'; |
13 import '../tree/tree.dart' as ast; | 14 import '../tree/tree.dart' as ast; |
14 import '../types/masks.dart'; | 15 import '../types/masks.dart'; |
15 import '../universe/call_structure.dart'; | 16 import '../universe/call_structure.dart'; |
16 import '../universe/selector.dart'; | 17 import '../universe/selector.dart'; |
17 import '../universe/side_effects.dart'; | 18 import '../universe/side_effects.dart'; |
18 | 19 |
19 import 'types.dart'; | 20 import 'types.dart'; |
20 | 21 |
21 /// A helper class that abstracts all accesses of the AST from Kernel nodes. | 22 /// A helper class that abstracts all accesses of the AST from Kernel nodes. |
22 /// | 23 /// |
23 /// The goal is to remove all need for the AST from the Kernel SSA builder. | 24 /// The goal is to remove all need for the AST from the Kernel SSA builder. |
24 class KernelAstAdapter { | 25 class KernelAstAdapter { |
25 final JavaScriptBackend _backend; | 26 final JavaScriptBackend _backend; |
26 final ResolvedAst _resolvedAst; | 27 final ResolvedAst _resolvedAst; |
27 final Map<ir.Node, ast.Node> _nodeToAst; | 28 final Map<ir.Node, ast.Node> _nodeToAst; |
28 final Map<ir.Node, Element> _nodeToElement; | 29 final Map<ir.Node, Element> _nodeToElement; |
| 30 DartTypeConverter _typeConverter; |
29 | 31 |
30 KernelAstAdapter( | 32 KernelAstAdapter( |
31 this._backend, | 33 this._backend, |
32 this._resolvedAst, | 34 this._resolvedAst, |
33 this._nodeToAst, | 35 this._nodeToAst, |
34 this._nodeToElement, | 36 this._nodeToElement, |
35 Map<FunctionElement, ir.Member> functions, | 37 Map<FunctionElement, ir.Member> functions, |
| 38 Map<ClassElement, ir.Class> classes, |
36 Map<LibraryElement, ir.Library> libraries) { | 39 Map<LibraryElement, ir.Library> libraries) { |
37 for (FunctionElement functionElement in functions.keys) { | 40 for (FunctionElement functionElement in functions.keys) { |
38 _nodeToElement[functions[functionElement]] = functionElement; | 41 _nodeToElement[functions[functionElement]] = functionElement; |
39 } | 42 } |
| 43 for (ClassElement classElement in classes.keys) { |
| 44 _nodeToElement[classes[classElement]] = classElement; |
| 45 } |
40 for (LibraryElement libraryElement in libraries.keys) { | 46 for (LibraryElement libraryElement in libraries.keys) { |
41 _nodeToElement[libraries[libraryElement]] = libraryElement; | 47 _nodeToElement[libraries[libraryElement]] = libraryElement; |
42 } | 48 } |
| 49 _typeConverter = new DartTypeConverter(this); |
43 } | 50 } |
44 | 51 |
45 Compiler get _compiler => _backend.compiler; | 52 Compiler get _compiler => _backend.compiler; |
46 TreeElements get _elements => _resolvedAst.elements; | 53 TreeElements get _elements => _resolvedAst.elements; |
47 | 54 |
48 ConstantValue getConstantForSymbol(ir.SymbolLiteral node) { | 55 ConstantValue getConstantForSymbol(ir.SymbolLiteral node) { |
49 ast.Node astNode = getNode(node); | 56 ast.Node astNode = getNode(node); |
50 ConstantValue constantValue = _backend.constants | 57 ConstantValue constantValue = _backend.constants |
51 .getConstantValueForNode(astNode, _resolvedAst.elements); | 58 .getConstantValueForNode(astNode, _resolvedAst.elements); |
52 assert(invariant(astNode, constantValue != null, | 59 assert(invariant(astNode, constantValue != null, |
(...skipping 20 matching lines...) Expand all Loading... |
73 | 80 |
74 TypeMask returnTypeOf(ir.Procedure node) { | 81 TypeMask returnTypeOf(ir.Procedure node) { |
75 return TypeMaskFactory.inferredReturnTypeForElement( | 82 return TypeMaskFactory.inferredReturnTypeForElement( |
76 getElement(node), _compiler); | 83 getElement(node), _compiler); |
77 } | 84 } |
78 | 85 |
79 SideEffects getSideEffects(ir.Node node) { | 86 SideEffects getSideEffects(ir.Node node) { |
80 return _compiler.world.getSideEffectsOfElement(getElement(node)); | 87 return _compiler.world.getSideEffectsOfElement(getElement(node)); |
81 } | 88 } |
82 | 89 |
| 90 CallStructure getCallStructure(ir.Arguments arguments) { |
| 91 int argumentCount = arguments.positional.length + arguments.named.length; |
| 92 List<String> namedArguments = arguments.named.map((e) => e.name).toList(); |
| 93 return new CallStructure(argumentCount, namedArguments); |
| 94 } |
| 95 |
83 // TODO(het): Create the selector directly from the invocation | 96 // TODO(het): Create the selector directly from the invocation |
84 Selector getSelector(ir.MethodInvocation invocation) { | 97 Selector getSelector(ir.MethodInvocation invocation) { |
85 SelectorKind kind = Elements.isOperatorName(invocation.name.name) | 98 SelectorKind kind = Elements.isOperatorName(invocation.name.name) |
86 ? SelectorKind.OPERATOR | 99 ? SelectorKind.OPERATOR |
87 : SelectorKind.CALL; | 100 : SelectorKind.CALL; |
88 | 101 |
89 ir.Name irName = invocation.name; | 102 ir.Name irName = invocation.name; |
90 Name name = new Name( | 103 Name name = new Name( |
91 irName.name, irName.isPrivate ? getElement(irName.library) : null); | 104 irName.name, irName.isPrivate ? getElement(irName.library) : null); |
92 | 105 CallStructure callStructure = getCallStructure(invocation.arguments); |
93 int argumentCount = invocation.arguments.positional.length + | |
94 invocation.arguments.named.length; | |
95 List<String> namedArguments = | |
96 invocation.arguments.named.map((e) => e.name).toList(); | |
97 CallStructure callStructure = | |
98 new CallStructure(argumentCount, namedArguments); | |
99 | 106 |
100 return new Selector(kind, name, callStructure); | 107 return new Selector(kind, name, callStructure); |
101 } | 108 } |
102 | 109 |
103 TypeMask typeOfInvocation(ir.MethodInvocation invocation) { | 110 TypeMask typeOfInvocation(ir.MethodInvocation invocation) { |
104 return _compiler.globalInference.results | 111 return _compiler.globalInference.results |
105 .typeOfSend(getNode(invocation), _elements); | 112 .typeOfSend(getNode(invocation), _elements); |
106 } | 113 } |
107 | 114 |
108 TypeMask selectorTypeOf(ir.MethodInvocation invocation) { | 115 TypeMask selectorTypeOf(ir.MethodInvocation invocation) { |
109 return TypeMaskFactory.inferredTypeForSelector( | 116 return TypeMaskFactory.inferredTypeForSelector( |
110 getSelector(invocation), typeOfInvocation(invocation), _compiler); | 117 getSelector(invocation), typeOfInvocation(invocation), _compiler); |
111 } | 118 } |
112 | 119 |
113 bool isIntercepted(ir.MethodInvocation invocation) { | 120 bool isIntercepted(ir.MethodInvocation invocation) { |
114 return _backend.isInterceptedSelector(getSelector(invocation)); | 121 return _backend.isInterceptedSelector(getSelector(invocation)); |
115 } | 122 } |
| 123 |
| 124 DartType getDartType(ir.DartType type) { |
| 125 return type.accept(_typeConverter); |
| 126 } |
116 } | 127 } |
| 128 |
| 129 class DartTypeConverter extends ir.DartTypeVisitor<DartType> { |
| 130 final KernelAstAdapter astAdapter; |
| 131 |
| 132 DartTypeConverter(this.astAdapter); |
| 133 |
| 134 List<DartType> visitTypes(List<ir.DartType> types) { |
| 135 return new List.generate( |
| 136 types.length, (int index) => types[index].accept(this)); |
| 137 } |
| 138 |
| 139 @override |
| 140 DartType visitTypeParameterType(ir.TypeParameterType node) { |
| 141 return new TypeVariableType(astAdapter.getElement(node.parameter)); |
| 142 } |
| 143 |
| 144 @override |
| 145 DartType visitFunctionType(ir.FunctionType node) { |
| 146 throw new UnimplementedError("Function types not currently supported"); |
| 147 } |
| 148 |
| 149 @override |
| 150 DartType visitInterfaceType(ir.InterfaceType node) { |
| 151 ClassElement cls = astAdapter.getElement(node.classNode); |
| 152 return new InterfaceType(cls, visitTypes(node.typeArguments)); |
| 153 } |
| 154 |
| 155 @override |
| 156 DartType visitVoidType(ir.VoidType node) { |
| 157 return const VoidType(); |
| 158 } |
| 159 |
| 160 @override |
| 161 DartType visitDynamicType(ir.DynamicType node) { |
| 162 return const DynamicType(); |
| 163 } |
| 164 |
| 165 @override |
| 166 DartType visitInvalidType(ir.InvalidType node) { |
| 167 throw new UnimplementedError("Invalid types not currently supported"); |
| 168 } |
| 169 } |
OLD | NEW |