Chromium Code Reviews| 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<jsAst.Expression> globalMetadata = <jsAst.Expression>[]; |
| 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 map with lists of JS expressions, one list for each output unit. The | 18 /// A map with lists of JS expressions, one list for each output unit. The |
| 19 /// entries represent types including function types and typedefs. | 19 /// entries represent types including function types and typedefs. |
| 20 final Map<OutputUnit, List<String>> types = <OutputUnit, List<String>>{}; | 20 final Map<OutputUnit, List<jsAst.Expression>> types = |
| 21 <OutputUnit, List<jsAst.Expression>>{}; | |
| 21 | 22 |
| 22 /// A map used to canonicalize the entries of types. | 23 /// A map used to canonicalize the entries of types. |
| 23 final Map<OutputUnit, Map<String, int>> _typesMap = | 24 final Map<OutputUnit, Map<String, int>> _typesMap = |
| 24 <OutputUnit, Map<String, int>>{}; | 25 <OutputUnit, Map<String, int>>{}; |
| 25 | 26 |
| 26 MetadataCollector(this._compiler, this._emitter); | 27 MetadataCollector(this._compiler, this._emitter); |
| 27 | 28 |
| 28 JavaScriptBackend get _backend => _compiler.backend; | 29 JavaScriptBackend get _backend => _compiler.backend; |
| 29 TypeVariableHandler get _typeVariableHandler => _backend.typeVariableHandler; | 30 TypeVariableHandler get _typeVariableHandler => _backend.typeVariableHandler; |
| 30 | 31 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 63 }); | 64 }); |
| 64 } | 65 } |
| 65 | 66 |
| 66 List<int> reifyDefaultArguments(FunctionElement function) { | 67 List<int> reifyDefaultArguments(FunctionElement function) { |
| 67 FunctionSignature signature = function.functionSignature; | 68 FunctionSignature signature = function.functionSignature; |
| 68 if (signature.optionalParameterCount == 0) return const []; | 69 if (signature.optionalParameterCount == 0) return const []; |
| 69 List<int> defaultValues = <int>[]; | 70 List<int> defaultValues = <int>[]; |
| 70 for (ParameterElement element in signature.optionalParameters) { | 71 for (ParameterElement element in signature.optionalParameters) { |
| 71 ConstantExpression constant = | 72 ConstantExpression constant = |
| 72 _backend.constants.getConstantForVariable(element); | 73 _backend.constants.getConstantForVariable(element); |
| 73 String stringRepresentation = (constant == null) | 74 jsAst.Expression expression = constant == null |
|
floitsch
2015/05/07 01:14:29
please keep the "(" ")" around the condition.
Siggi Cherem (dart-lang)
2015/05/07 16:29:23
Done.
| |
| 74 ? "null" | 75 ? null |
| 75 : jsAst.prettyPrint( | 76 : _emitter.constantReference(constant.value); |
| 76 _emitter.constantReference(constant.value), _compiler).getText(); | 77 defaultValues.add(addGlobalMetadata(expression)); |
| 77 defaultValues.add(addGlobalMetadata(stringRepresentation)); | |
| 78 } | 78 } |
| 79 return defaultValues; | 79 return defaultValues; |
| 80 } | 80 } |
| 81 | 81 |
| 82 int reifyMetadata(MetadataAnnotation annotation) { | 82 int reifyMetadata(MetadataAnnotation annotation) { |
| 83 ConstantExpression constant = | 83 ConstantExpression constant = |
| 84 _backend.constants.getConstantForMetadata(annotation); | 84 _backend.constants.getConstantForMetadata(annotation); |
| 85 if (constant == null) { | 85 if (constant == null) { |
| 86 _compiler.internalError(annotation, 'Annotation value is null.'); | 86 _compiler.internalError(annotation, 'Annotation value is null.'); |
| 87 return -1; | 87 return -1; |
| 88 } | 88 } |
| 89 return addGlobalMetadata( | 89 return addGlobalMetadata(_emitter.constantReference(constant.value)); |
| 90 jsAst.prettyPrint( | |
| 91 _emitter.constantReference(constant.value), _compiler).getText()); | |
| 92 } | 90 } |
| 93 | 91 |
| 94 int reifyType(DartType type, {bool ignoreTypeVariables: false}) { | 92 int reifyType(DartType type, {bool ignoreTypeVariables: false}) { |
| 95 return reifyTypeForOutputUnit(type, | 93 return reifyTypeForOutputUnit(type, |
| 96 _compiler.deferredLoadTask.mainOutputUnit, | 94 _compiler.deferredLoadTask.mainOutputUnit, |
| 97 ignoreTypeVariables: ignoreTypeVariables); | 95 ignoreTypeVariables: ignoreTypeVariables); |
| 98 } | 96 } |
| 99 | 97 |
| 100 int reifyTypeForOutputUnit(DartType type, OutputUnit outputUnit, | 98 int reifyTypeForOutputUnit(DartType type, OutputUnit outputUnit, |
| 101 {bool ignoreTypeVariables: false}) { | 99 {bool ignoreTypeVariables: false}) { |
| 102 jsAst.Expression representation = | 100 jsAst.Expression representation = |
| 103 _backend.rti.getTypeRepresentation( | 101 _backend.rti.getTypeRepresentation( |
| 104 type, | 102 type, |
| 105 (variable) { | 103 (variable) { |
| 106 if (ignoreTypeVariables) return new jsAst.LiteralNull(); | 104 if (ignoreTypeVariables) return new jsAst.LiteralNull(); |
| 107 return js.number( | 105 return js.number( |
| 108 _typeVariableHandler.reifyTypeVariable( | 106 _typeVariableHandler.reifyTypeVariable( |
| 109 variable.element)); | 107 variable.element)); |
| 110 }, | 108 }, |
| 111 (TypedefType typedef) { | 109 (TypedefType typedef) { |
| 112 return _backend.isAccessibleByReflection(typedef.element); | 110 return _backend.isAccessibleByReflection(typedef.element); |
| 113 }); | 111 }); |
| 114 | 112 |
| 115 return addTypeInOutputUnit( | 113 return addTypeInOutputUnit(representation, outputUnit); |
| 116 jsAst.prettyPrint(representation, _compiler).getText(), outputUnit); | |
| 117 } | 114 } |
| 118 | 115 |
| 119 int reifyName(String name) { | 116 int reifyName(String name) { |
| 120 return addGlobalMetadata('"$name"'); | 117 return addGlobalMetadata(js('"$name"')); |
| 121 } | 118 } |
| 122 | 119 |
| 123 int addGlobalMetadata(String string) { | 120 int addGlobalMetadata(jsAst.Expression expression) { |
| 121 // TODO(sigmund): consider adding an effient way to compare expressions | |
| 122 String string = jsAst.prettyPrint(expression, _compiler).getText(); | |
| 124 return _globalMetadataMap.putIfAbsent(string, () { | 123 return _globalMetadataMap.putIfAbsent(string, () { |
| 125 globalMetadata.add(string); | 124 globalMetadata.add(expression); |
|
floitsch
2015/05/07 01:14:28
easier than expected :)
Siggi Cherem (dart-lang)
2015/05/07 16:29:23
:) totally
| |
| 126 return globalMetadata.length - 1; | 125 return globalMetadata.length - 1; |
| 127 }); | 126 }); |
| 128 } | 127 } |
| 129 | 128 |
| 130 int addTypeInOutputUnit(String compiledType, OutputUnit outputUnit) { | 129 int addTypeInOutputUnit(jsAst.Expression compiledType, OutputUnit outputUnit) { |
|
floitsch
2015/05/07 01:14:29
I think the "compiled" refers to the fact that it
Siggi Cherem (dart-lang)
2015/05/07 16:29:23
Done.
| |
| 130 String string = jsAst.prettyPrint(compiledType, _compiler).getText(); | |
| 131 if (_typesMap[outputUnit] == null) { | 131 if (_typesMap[outputUnit] == null) { |
| 132 _typesMap[outputUnit] = <String, int>{}; | 132 _typesMap[outputUnit] = <String, int>{}; |
| 133 } | 133 } |
| 134 return _typesMap[outputUnit].putIfAbsent(compiledType, () { | 134 return _typesMap[outputUnit].putIfAbsent(string, () { |
| 135 | 135 |
| 136 if (types[outputUnit] == null) | 136 if (types[outputUnit] == null) |
| 137 types[outputUnit] = <String>[]; | 137 types[outputUnit] = <jsAst.Expression>[]; |
| 138 | 138 |
| 139 types[outputUnit].add(compiledType); | 139 types[outputUnit].add(compiledType); |
| 140 return types[outputUnit].length - 1; | 140 return types[outputUnit].length - 1; |
| 141 }); | 141 }); |
| 142 } | 142 } |
| 143 | 143 |
| 144 List<int> computeMetadata(FunctionElement element) { | 144 List<int> computeMetadata(FunctionElement element) { |
| 145 return _compiler.withCurrentElement(element, () { | 145 return _compiler.withCurrentElement(element, () { |
| 146 if (!_mustEmitMetadataFor(element)) return const <int>[]; | 146 if (!_mustEmitMetadataFor(element)) return const <int>[]; |
| 147 List<int> metadata = <int>[]; | 147 List<int> metadata = <int>[]; |
| 148 Link link = element.metadata; | 148 Link link = element.metadata; |
| 149 // TODO(ahe): Why is metadata sometimes null? | 149 // TODO(ahe): Why is metadata sometimes null? |
| 150 if (link != null) { | 150 if (link != null) { |
| 151 for (; !link.isEmpty; link = link.tail) { | 151 for (; !link.isEmpty; link = link.tail) { |
| 152 metadata.add(reifyMetadata(link.head)); | 152 metadata.add(reifyMetadata(link.head)); |
| 153 } | 153 } |
| 154 } | 154 } |
| 155 return metadata; | 155 return metadata; |
| 156 }); | 156 }); |
| 157 } | 157 } |
| 158 } | 158 } |
| OLD | NEW |