| 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 /// Represents an entry's position in one of the global metadata arrays. | 7 /// Represents an entry's position in one of the global metadata arrays. |
| 8 /// | 8 /// |
| 9 /// [_rc] is used to count the number of references of the token in the | 9 /// [_rc] is used to count the number of references of the token in the |
| 10 /// ast for a program. | 10 /// ast for a program. |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 // this. | 138 // this. |
| 139 int _globalMetadataCounter = 0; | 139 int _globalMetadataCounter = 0; |
| 140 int _globalTypesCounter = 0; | 140 int _globalTypesCounter = 0; |
| 141 | 141 |
| 142 MetadataCollector(this._compiler, this._emitter) { | 142 MetadataCollector(this._compiler, this._emitter) { |
| 143 _globalMetadataMap = new Map<String, _BoundMetadataEntry>(); | 143 _globalMetadataMap = new Map<String, _BoundMetadataEntry>(); |
| 144 } | 144 } |
| 145 | 145 |
| 146 JavaScriptBackend get _backend => _compiler.backend; | 146 JavaScriptBackend get _backend => _compiler.backend; |
| 147 TypeVariableHandler get _typeVariableHandler => _backend.typeVariableHandler; | 147 TypeVariableHandler get _typeVariableHandler => _backend.typeVariableHandler; |
| 148 DiagnosticReporter get reporter => _compiler.reporter; |
| 148 | 149 |
| 149 bool _mustEmitMetadataFor(Element element) { | 150 bool _mustEmitMetadataFor(Element element) { |
| 150 return _backend.mustRetainMetadata && | 151 return _backend.mustRetainMetadata && |
| 151 _backend.referencedFromMirrorSystem(element); | 152 _backend.referencedFromMirrorSystem(element); |
| 152 } | 153 } |
| 153 | 154 |
| 154 /// The metadata function returns the metadata associated with | 155 /// The metadata function returns the metadata associated with |
| 155 /// [element] in generated code. The metadata needs to be wrapped | 156 /// [element] in generated code. The metadata needs to be wrapped |
| 156 /// in a function as it refers to constants that may not have been | 157 /// in a function as it refers to constants that may not have been |
| 157 /// constructed yet. For example, a class is allowed to be | 158 /// constructed yet. For example, a class is allowed to be |
| 158 /// annotated with itself. The metadata function is used by | 159 /// annotated with itself. The metadata function is used by |
| 159 /// mirrors_patch to implement DeclarationMirror.metadata. | 160 /// mirrors_patch to implement DeclarationMirror.metadata. |
| 160 jsAst.Fun buildMetadataFunction(Element element) { | 161 jsAst.Fun buildMetadataFunction(Element element) { |
| 161 if (!_mustEmitMetadataFor(element)) return null; | 162 if (!_mustEmitMetadataFor(element)) return null; |
| 162 return _compiler.withCurrentElement(element, () { | 163 return reporter.withCurrentElement(element, () { |
| 163 List<jsAst.Expression> metadata = <jsAst.Expression>[]; | 164 List<jsAst.Expression> metadata = <jsAst.Expression>[]; |
| 164 for (MetadataAnnotation annotation in element.metadata) { | 165 for (MetadataAnnotation annotation in element.metadata) { |
| 165 ConstantValue constant = | 166 ConstantValue constant = |
| 166 _backend.constants.getConstantValueForMetadata(annotation); | 167 _backend.constants.getConstantValueForMetadata(annotation); |
| 167 if (constant == null) { | 168 if (constant == null) { |
| 168 _compiler.internalError(annotation, 'Annotation value is null.'); | 169 reporter.internalError(annotation, 'Annotation value is null.'); |
| 169 } else { | 170 } else { |
| 170 metadata.add(_emitter.constantReference(constant)); | 171 metadata.add(_emitter.constantReference(constant)); |
| 171 } | 172 } |
| 172 } | 173 } |
| 173 if (metadata.isEmpty) return null; | 174 if (metadata.isEmpty) return null; |
| 174 return js('function() { return # }', | 175 return js('function() { return # }', |
| 175 new jsAst.ArrayInitializer(metadata)); | 176 new jsAst.ArrayInitializer(metadata)); |
| 176 }); | 177 }); |
| 177 } | 178 } |
| 178 | 179 |
| 179 List<jsAst.DeferredNumber> reifyDefaultArguments(FunctionElement function) { | 180 List<jsAst.DeferredNumber> reifyDefaultArguments(FunctionElement function) { |
| 180 FunctionSignature signature = function.functionSignature; | 181 FunctionSignature signature = function.functionSignature; |
| 181 if (signature.optionalParameterCount == 0) return const []; | 182 if (signature.optionalParameterCount == 0) return const []; |
| 182 List<jsAst.DeferredNumber> defaultValues = <jsAst.DeferredNumber>[]; | 183 List<jsAst.DeferredNumber> defaultValues = <jsAst.DeferredNumber>[]; |
| 183 for (ParameterElement element in signature.optionalParameters) { | 184 for (ParameterElement element in signature.optionalParameters) { |
| 184 ConstantValue constant = | 185 ConstantValue constant = |
| 185 _backend.constants.getConstantValueForVariable(element); | 186 _backend.constants.getConstantValueForVariable(element); |
| 186 jsAst.Expression expression = (constant == null) | 187 jsAst.Expression expression = (constant == null) |
| 187 ? new jsAst.LiteralNull() | 188 ? new jsAst.LiteralNull() |
| 188 : _emitter.constantReference(constant); | 189 : _emitter.constantReference(constant); |
| 189 defaultValues.add(_addGlobalMetadata(expression)); | 190 defaultValues.add(_addGlobalMetadata(expression)); |
| 190 } | 191 } |
| 191 return defaultValues; | 192 return defaultValues; |
| 192 } | 193 } |
| 193 | 194 |
| 194 jsAst.Expression reifyMetadata(MetadataAnnotation annotation) { | 195 jsAst.Expression reifyMetadata(MetadataAnnotation annotation) { |
| 195 ConstantValue constant = | 196 ConstantValue constant = |
| 196 _backend.constants.getConstantValueForMetadata(annotation); | 197 _backend.constants.getConstantValueForMetadata(annotation); |
| 197 if (constant == null) { | 198 if (constant == null) { |
| 198 _compiler.internalError(annotation, 'Annotation value is null.'); | 199 reporter.internalError(annotation, 'Annotation value is null.'); |
| 199 return null; | 200 return null; |
| 200 } | 201 } |
| 201 return _addGlobalMetadata(_emitter.constantReference(constant)); | 202 return _addGlobalMetadata(_emitter.constantReference(constant)); |
| 202 } | 203 } |
| 203 | 204 |
| 204 jsAst.Expression reifyType(DartType type, {ignoreTypeVariables: false}) { | 205 jsAst.Expression reifyType(DartType type, {ignoreTypeVariables: false}) { |
| 205 return reifyTypeForOutputUnit(type, | 206 return reifyTypeForOutputUnit(type, |
| 206 _compiler.deferredLoadTask.mainOutputUnit, | 207 _compiler.deferredLoadTask.mainOutputUnit, |
| 207 ignoreTypeVariables: ignoreTypeVariables); | 208 ignoreTypeVariables: ignoreTypeVariables); |
| 208 } | 209 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 if (ignoreTypeVariables) return new jsAst.LiteralNull(); | 249 if (ignoreTypeVariables) return new jsAst.LiteralNull(); |
| 249 return _typeVariableHandler.reifyTypeVariable(variable.element); | 250 return _typeVariableHandler.reifyTypeVariable(variable.element); |
| 250 }, | 251 }, |
| 251 (TypedefType typedef) { | 252 (TypedefType typedef) { |
| 252 return _backend.isAccessibleByReflection(typedef.element); | 253 return _backend.isAccessibleByReflection(typedef.element); |
| 253 }); | 254 }); |
| 254 | 255 |
| 255 if (representation is jsAst.LiteralString) { | 256 if (representation is jsAst.LiteralString) { |
| 256 // We don't want the representation to be a string, since we use | 257 // We don't want the representation to be a string, since we use |
| 257 // strings as indicator for non-initialized types in the lazy emitter. | 258 // strings as indicator for non-initialized types in the lazy emitter. |
| 258 _compiler.internalError( | 259 reporter.internalError( |
| 259 NO_LOCATION_SPANNABLE, 'reified types should not be strings.'); | 260 NO_LOCATION_SPANNABLE, 'reified types should not be strings.'); |
| 260 } | 261 } |
| 261 | 262 |
| 262 return representation; | 263 return representation; |
| 263 | 264 |
| 264 } | 265 } |
| 265 | 266 |
| 266 jsAst.Expression addTypeInOutputUnit(DartType type, | 267 jsAst.Expression addTypeInOutputUnit(DartType type, |
| 267 OutputUnit outputUnit, | 268 OutputUnit outputUnit, |
| 268 {ignoreTypeVariables: false}) { | 269 {ignoreTypeVariables: false}) { |
| 269 if (_typesMap[outputUnit] == null) { | 270 if (_typesMap[outputUnit] == null) { |
| 270 _typesMap[outputUnit] = new Map<DartType, _BoundMetadataEntry>(); | 271 _typesMap[outputUnit] = new Map<DartType, _BoundMetadataEntry>(); |
| 271 } | 272 } |
| 272 return _typesMap[outputUnit].putIfAbsent(type, () { | 273 return _typesMap[outputUnit].putIfAbsent(type, () { |
| 273 _BoundMetadataEntry result = new _BoundMetadataEntry( | 274 _BoundMetadataEntry result = new _BoundMetadataEntry( |
| 274 _computeTypeRepresentation(type, | 275 _computeTypeRepresentation(type, |
| 275 ignoreTypeVariables: ignoreTypeVariables)); | 276 ignoreTypeVariables: ignoreTypeVariables)); |
| 276 if (_compiler.hasIncrementalSupport) { | 277 if (_compiler.hasIncrementalSupport) { |
| 277 result.finalize(_globalTypesCounter++); | 278 result.finalize(_globalTypesCounter++); |
| 278 } | 279 } |
| 279 return result; | 280 return result; |
| 280 }); | 281 }); |
| 281 } | 282 } |
| 282 | 283 |
| 283 List<jsAst.DeferredNumber> computeMetadata(FunctionElement element) { | 284 List<jsAst.DeferredNumber> computeMetadata(FunctionElement element) { |
| 284 return _compiler.withCurrentElement(element, () { | 285 return reporter.withCurrentElement(element, () { |
| 285 if (!_mustEmitMetadataFor(element)) return const <jsAst.DeferredNumber>[]; | 286 if (!_mustEmitMetadataFor(element)) return const <jsAst.DeferredNumber>[]; |
| 286 List<jsAst.DeferredNumber> metadata = <jsAst.DeferredNumber>[]; | 287 List<jsAst.DeferredNumber> metadata = <jsAst.DeferredNumber>[]; |
| 287 for (MetadataAnnotation annotation in element.metadata) { | 288 for (MetadataAnnotation annotation in element.metadata) { |
| 288 metadata.add(reifyMetadata(annotation)); | 289 metadata.add(reifyMetadata(annotation)); |
| 289 } | 290 } |
| 290 return metadata; | 291 return metadata; |
| 291 }); | 292 }); |
| 292 } | 293 } |
| 293 | 294 |
| 294 @override | 295 @override |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 if (token is _ForwardingMetadataEntry && !token.isBound) { | 360 if (token is _ForwardingMetadataEntry && !token.isBound) { |
| 360 _foundUnboundToken = true; | 361 _foundUnboundToken = true; |
| 361 } | 362 } |
| 362 } | 363 } |
| 363 | 364 |
| 364 bool findUnboundPlaceholders(jsAst.Node node) { | 365 bool findUnboundPlaceholders(jsAst.Node node) { |
| 365 node.accept(this); | 366 node.accept(this); |
| 366 return _foundUnboundToken; | 367 return _foundUnboundToken; |
| 367 } | 368 } |
| 368 } | 369 } |
| OLD | NEW |