| 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 |