OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
6 | 6 |
7 class MetadataCollector { | 7 class MetadataCollector { |
8 final Compiler _compiler; | 8 final Compiler _compiler; |
9 final Emitter _emitter; | 9 final Emitter _emitter; |
10 | 10 |
11 /// A list of JS expressions that represent metadata, parameter names and | 11 /// A list of JS expressions that represent metadata, parameter names and |
12 /// type variable types. | 12 /// type variable types. |
13 final List<String> globalMetadata = <String>[]; | 13 final List<String> globalMetadata = <String>[]; |
14 | 14 |
15 /// A map used to canonicalize the entries of globalMetadata. | 15 /// A map used to canonicalize the entries of globalMetadata. |
16 final Map<String, int> _globalMetadataMap = <String, int>{}; | 16 final Map<String, int> _globalMetadataMap = <String, int>{}; |
17 | 17 |
18 /// A list of JS expression representing types including function types and | 18 /// A map with lists of JS expressions, one list for each output unit. The |
19 /// typedefs. | 19 /// entries represent types including function types and typedefs. |
20 final List<String> types = <String>[]; | 20 final Map<OutputUnit, List<String>> types = <OutputUnit, List<String>>{}; |
21 | 21 |
22 /// A map used to canonicalize the entries of types. | 22 /// A map used to canonicalize the entries of types. |
23 final Map<String, int> _typesMap = <String, int>{}; | 23 final Map<OutputUnit, Map<String, int>> _typesMap = |
| 24 <OutputUnit, Map<String, int>>{}; |
24 | 25 |
25 MetadataCollector(this._compiler, this._emitter); | 26 MetadataCollector(this._compiler, this._emitter); |
26 | 27 |
27 JavaScriptBackend get _backend => _compiler.backend; | 28 JavaScriptBackend get _backend => _compiler.backend; |
28 TypeVariableHandler get _typeVariableHandler => _backend.typeVariableHandler; | 29 TypeVariableHandler get _typeVariableHandler => _backend.typeVariableHandler; |
29 | 30 |
30 bool _mustEmitMetadataFor(Element element) { | 31 bool _mustEmitMetadataFor(Element element) { |
31 return _backend.mustRetainMetadata && | 32 return _backend.mustRetainMetadata && |
32 _backend.referencedFromMirrorSystem(element); | 33 _backend.referencedFromMirrorSystem(element); |
33 } | 34 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 if (constant == null) { | 85 if (constant == null) { |
85 _compiler.internalError(annotation, 'Annotation value is null.'); | 86 _compiler.internalError(annotation, 'Annotation value is null.'); |
86 return -1; | 87 return -1; |
87 } | 88 } |
88 return addGlobalMetadata( | 89 return addGlobalMetadata( |
89 jsAst.prettyPrint( | 90 jsAst.prettyPrint( |
90 _emitter.constantReference(constant.value), _compiler).getText()); | 91 _emitter.constantReference(constant.value), _compiler).getText()); |
91 } | 92 } |
92 | 93 |
93 int reifyType(DartType type) { | 94 int reifyType(DartType type) { |
| 95 return reifyTypeForOutputUnit(type, |
| 96 _compiler.deferredLoadTask.mainOutputUnit); |
| 97 } |
| 98 |
| 99 int reifyTypeForOutputUnit(DartType type, OutputUnit outputUnit) { |
94 jsAst.Expression representation = | 100 jsAst.Expression representation = |
95 _backend.rti.getTypeRepresentation( | 101 _backend.rti.getTypeRepresentation( |
96 type, | 102 type, |
97 (variable) { | 103 (variable) { |
98 return js.number( | 104 return js.number( |
99 _typeVariableHandler.reifyTypeVariable( | 105 _typeVariableHandler.reifyTypeVariable( |
100 variable.element)); | 106 variable.element)); |
101 }, | 107 }, |
102 (TypedefType typedef) { | 108 (TypedefType typedef) { |
103 return _backend.isAccessibleByReflection(typedef.element); | 109 return _backend.isAccessibleByReflection(typedef.element); |
104 }); | 110 }); |
105 | 111 |
106 return addType( | 112 return addTypeInOutputUnit( |
107 jsAst.prettyPrint(representation, _compiler).getText()); | 113 jsAst.prettyPrint(representation, _compiler).getText(), outputUnit); |
108 } | 114 } |
109 | 115 |
110 int reifyName(String name) { | 116 int reifyName(String name) { |
111 return addGlobalMetadata('"$name"'); | 117 return addGlobalMetadata('"$name"'); |
112 } | 118 } |
113 | 119 |
114 int addGlobalMetadata(String string) { | 120 int addGlobalMetadata(String string) { |
115 return _globalMetadataMap.putIfAbsent(string, () { | 121 return _globalMetadataMap.putIfAbsent(string, () { |
116 globalMetadata.add(string); | 122 globalMetadata.add(string); |
117 return globalMetadata.length - 1; | 123 return globalMetadata.length - 1; |
118 }); | 124 }); |
119 } | 125 } |
120 | 126 |
121 int addType(String compiledType) { | 127 int addTypeInOutputUnit(String compiledType, OutputUnit outputUnit) { |
122 return _typesMap.putIfAbsent(compiledType, () { | 128 if (_typesMap[outputUnit] == null) { |
123 types.add(compiledType); | 129 _typesMap[outputUnit] = <String, int>{}; |
124 return types.length - 1; | 130 } |
| 131 return _typesMap[outputUnit].putIfAbsent(compiledType, () { |
| 132 |
| 133 if (types[outputUnit] == null) |
| 134 types[outputUnit] = <String>[]; |
| 135 |
| 136 types[outputUnit].add(compiledType); |
| 137 return types[outputUnit].length - 1; |
125 }); | 138 }); |
126 } | 139 } |
127 | 140 |
128 List<int> computeMetadata(FunctionElement element) { | 141 List<int> computeMetadata(FunctionElement element) { |
129 return _compiler.withCurrentElement(element, () { | 142 return _compiler.withCurrentElement(element, () { |
130 if (!_mustEmitMetadataFor(element)) return const <int>[]; | 143 if (!_mustEmitMetadataFor(element)) return const <int>[]; |
131 List<int> metadata = <int>[]; | 144 List<int> metadata = <int>[]; |
132 Link link = element.metadata; | 145 Link link = element.metadata; |
133 // TODO(ahe): Why is metadata sometimes null? | 146 // TODO(ahe): Why is metadata sometimes null? |
134 if (link != null) { | 147 if (link != null) { |
135 for (; !link.isEmpty; link = link.tail) { | 148 for (; !link.isEmpty; link = link.tail) { |
136 metadata.add(reifyMetadata(link.head)); | 149 metadata.add(reifyMetadata(link.head)); |
137 } | 150 } |
138 } | 151 } |
139 return metadata; | 152 return metadata; |
140 }); | 153 }); |
141 } | 154 } |
142 } | 155 } |
OLD | NEW |