| 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 library dart2js.js_emitter.metadata_collector; | 5 library dart2js.js_emitter.metadata_collector; |
| 6 | 6 |
| 7 import 'package:js_ast/src/precedence.dart' as js_precedence; | 7 import 'package:js_ast/src/precedence.dart' as js_precedence; |
| 8 | 8 |
| 9 import '../common.dart'; | 9 import '../common.dart'; |
| 10 import '../compiler.dart' show Compiler; | 10 import '../compiler.dart' show Compiler; |
| 11 import '../constants/values.dart'; | 11 import '../constants/values.dart'; |
| 12 import '../elements/resolution_types.dart' | 12 import '../elements/resolution_types.dart' |
| 13 show ResolutionDartType, ResolutionTypedefType; | 13 show ResolutionDartType, ResolutionTypedefType; |
| 14 import '../deferred_load.dart' show OutputUnit; | 14 import '../deferred_load.dart' show OutputUnit; |
| 15 import '../elements/elements.dart' | 15 import '../elements/elements.dart' |
| 16 show | 16 show |
| 17 ClassElement, |
| 17 ConstructorElement, | 18 ConstructorElement, |
| 18 Element, | 19 Element, |
| 20 FieldElement, |
| 19 FunctionElement, | 21 FunctionElement, |
| 20 FunctionSignature, | 22 FunctionSignature, |
| 23 LibraryElement, |
| 24 MemberElement, |
| 25 MethodElement, |
| 21 MetadataAnnotation, | 26 MetadataAnnotation, |
| 22 ParameterElement; | 27 ParameterElement; |
| 23 import '../js/js.dart' as jsAst; | 28 import '../js/js.dart' as jsAst; |
| 24 import '../js/js.dart' show js; | 29 import '../js/js.dart' show js; |
| 25 import '../js_backend/js_backend.dart' | 30 import '../js_backend/js_backend.dart' |
| 26 show JavaScriptBackend, TypeVariableCodegenAnalysis; | 31 show JavaScriptBackend, TypeVariableCodegenAnalysis; |
| 27 | 32 |
| 28 import 'code_emitter_task.dart' show Emitter; | 33 import 'code_emitter_task.dart' show Emitter; |
| 29 | 34 |
| 30 /// Represents an entry's position in one of the global metadata arrays. | 35 /// Represents an entry's position in one of the global metadata arrays. |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 | 162 |
| 158 MetadataCollector(this._compiler, this._emitter) { | 163 MetadataCollector(this._compiler, this._emitter) { |
| 159 _globalMetadataMap = new Map<String, _BoundMetadataEntry>(); | 164 _globalMetadataMap = new Map<String, _BoundMetadataEntry>(); |
| 160 } | 165 } |
| 161 | 166 |
| 162 JavaScriptBackend get _backend => _compiler.backend; | 167 JavaScriptBackend get _backend => _compiler.backend; |
| 163 TypeVariableCodegenAnalysis get _typeVariableCodegenAnalysis => | 168 TypeVariableCodegenAnalysis get _typeVariableCodegenAnalysis => |
| 164 _backend.typeVariableCodegenAnalysis; | 169 _backend.typeVariableCodegenAnalysis; |
| 165 DiagnosticReporter get reporter => _compiler.reporter; | 170 DiagnosticReporter get reporter => _compiler.reporter; |
| 166 | 171 |
| 167 bool _mustEmitMetadataFor(Element element) { | 172 jsAst.Fun buildLibraryMetadataFunction(LibraryElement element) { |
| 173 if (!_backend.mirrorsData.mustRetainMetadata || |
| 174 !_backend.mirrorsData.isLibraryReferencedFromMirrorSystem(element)) { |
| 175 return null; |
| 176 } |
| 177 return _buildMetadataFunction(element); |
| 178 } |
| 179 |
| 180 jsAst.Fun buildClassMetadataFunction(ClassElement element) { |
| 181 if (!_backend.mirrorsData.mustRetainMetadata || |
| 182 !_backend.mirrorsData.isClassReferencedFromMirrorSystem(element)) { |
| 183 return null; |
| 184 } |
| 185 return _buildMetadataFunction(element); |
| 186 } |
| 187 |
| 188 bool _mustEmitMetadataForMember(MemberElement element) { |
| 168 return _backend.mirrorsData.mustRetainMetadata && | 189 return _backend.mirrorsData.mustRetainMetadata && |
| 169 _backend.mirrorsData.referencedFromMirrorSystem(element); | 190 _backend.mirrorsData.isMemberReferencedFromMirrorSystem(element); |
| 191 } |
| 192 |
| 193 jsAst.Fun buildFieldMetadataFunction(FieldElement element) { |
| 194 if (!_mustEmitMetadataForMember(element)) return null; |
| 195 return _buildMetadataFunction(element); |
| 170 } | 196 } |
| 171 | 197 |
| 172 /// The metadata function returns the metadata associated with | 198 /// The metadata function returns the metadata associated with |
| 173 /// [element] in generated code. The metadata needs to be wrapped | 199 /// [element] in generated code. The metadata needs to be wrapped |
| 174 /// in a function as it refers to constants that may not have been | 200 /// in a function as it refers to constants that may not have been |
| 175 /// constructed yet. For example, a class is allowed to be | 201 /// constructed yet. For example, a class is allowed to be |
| 176 /// annotated with itself. The metadata function is used by | 202 /// annotated with itself. The metadata function is used by |
| 177 /// mirrors_patch to implement DeclarationMirror.metadata. | 203 /// mirrors_patch to implement DeclarationMirror.metadata. |
| 178 jsAst.Fun buildMetadataFunction(Element element) { | 204 jsAst.Fun _buildMetadataFunction(Element element) { |
| 179 if (!_mustEmitMetadataFor(element)) return null; | |
| 180 return reporter.withCurrentElement(element, () { | 205 return reporter.withCurrentElement(element, () { |
| 181 List<jsAst.Expression> metadata = <jsAst.Expression>[]; | 206 List<jsAst.Expression> metadata = <jsAst.Expression>[]; |
| 182 for (MetadataAnnotation annotation in element.metadata) { | 207 for (MetadataAnnotation annotation in element.metadata) { |
| 183 ConstantValue constant = | 208 ConstantValue constant = |
| 184 _backend.constants.getConstantValueForMetadata(annotation); | 209 _backend.constants.getConstantValueForMetadata(annotation); |
| 185 if (constant == null) { | 210 if (constant == null) { |
| 186 reporter.internalError(annotation, 'Annotation value is null.'); | 211 reporter.internalError(annotation, 'Annotation value is null.'); |
| 187 } else { | 212 } else { |
| 188 metadata.add(_emitter.constantReference(constant)); | 213 metadata.add(_emitter.constantReference(constant)); |
| 189 } | 214 } |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 }); | 343 }); |
| 319 } | 344 } |
| 320 | 345 |
| 321 jsAst.Expression _computeTypeRepresentation(ResolutionDartType type, | 346 jsAst.Expression _computeTypeRepresentation(ResolutionDartType type, |
| 322 {ignoreTypeVariables: false}) { | 347 {ignoreTypeVariables: false}) { |
| 323 jsAst.Expression representation = | 348 jsAst.Expression representation = |
| 324 _backend.rtiEncoder.getTypeRepresentation(type, (variable) { | 349 _backend.rtiEncoder.getTypeRepresentation(type, (variable) { |
| 325 if (ignoreTypeVariables) return new jsAst.LiteralNull(); | 350 if (ignoreTypeVariables) return new jsAst.LiteralNull(); |
| 326 return _typeVariableCodegenAnalysis.reifyTypeVariable(variable.element); | 351 return _typeVariableCodegenAnalysis.reifyTypeVariable(variable.element); |
| 327 }, (ResolutionTypedefType typedef) { | 352 }, (ResolutionTypedefType typedef) { |
| 328 return _backend.mirrorsData.isAccessibleByReflection(typedef.element); | 353 return _backend.mirrorsData |
| 354 .isTypedefAccessibleByReflection(typedef.element); |
| 329 }); | 355 }); |
| 330 | 356 |
| 331 if (representation is jsAst.LiteralString) { | 357 if (representation is jsAst.LiteralString) { |
| 332 // We don't want the representation to be a string, since we use | 358 // We don't want the representation to be a string, since we use |
| 333 // strings as indicator for non-initialized types in the lazy emitter. | 359 // strings as indicator for non-initialized types in the lazy emitter. |
| 334 reporter.internalError( | 360 reporter.internalError( |
| 335 NO_LOCATION_SPANNABLE, 'reified types should not be strings.'); | 361 NO_LOCATION_SPANNABLE, 'reified types should not be strings.'); |
| 336 } | 362 } |
| 337 | 363 |
| 338 return representation; | 364 return representation; |
| 339 } | 365 } |
| 340 | 366 |
| 341 jsAst.Expression addTypeInOutputUnit( | 367 jsAst.Expression addTypeInOutputUnit( |
| 342 ResolutionDartType type, OutputUnit outputUnit, | 368 ResolutionDartType type, OutputUnit outputUnit, |
| 343 {ignoreTypeVariables: false}) { | 369 {ignoreTypeVariables: false}) { |
| 344 if (_typesMap[outputUnit] == null) { | 370 if (_typesMap[outputUnit] == null) { |
| 345 _typesMap[outputUnit] = | 371 _typesMap[outputUnit] = |
| 346 new Map<ResolutionDartType, _BoundMetadataEntry>(); | 372 new Map<ResolutionDartType, _BoundMetadataEntry>(); |
| 347 } | 373 } |
| 348 return _typesMap[outputUnit].putIfAbsent(type, () { | 374 return _typesMap[outputUnit].putIfAbsent(type, () { |
| 349 return new _BoundMetadataEntry(_computeTypeRepresentation(type, | 375 return new _BoundMetadataEntry(_computeTypeRepresentation(type, |
| 350 ignoreTypeVariables: ignoreTypeVariables)); | 376 ignoreTypeVariables: ignoreTypeVariables)); |
| 351 }); | 377 }); |
| 352 } | 378 } |
| 353 | 379 |
| 354 List<jsAst.DeferredNumber> computeMetadata(FunctionElement element) { | 380 List<jsAst.DeferredNumber> computeMetadata(MethodElement element) { |
| 355 return reporter.withCurrentElement(element, () { | 381 return reporter.withCurrentElement(element, () { |
| 356 if (!_mustEmitMetadataFor(element)) return const <jsAst.DeferredNumber>[]; | 382 if (!_mustEmitMetadataForMember(element)) |
| 383 return const <jsAst.DeferredNumber>[]; |
| 357 List<jsAst.DeferredNumber> metadata = <jsAst.DeferredNumber>[]; | 384 List<jsAst.DeferredNumber> metadata = <jsAst.DeferredNumber>[]; |
| 358 for (MetadataAnnotation annotation in element.metadata) { | 385 for (MetadataAnnotation annotation in element.metadata) { |
| 359 metadata.add(reifyMetadata(annotation)); | 386 metadata.add(reifyMetadata(annotation)); |
| 360 } | 387 } |
| 361 return metadata; | 388 return metadata; |
| 362 }); | 389 }); |
| 363 } | 390 } |
| 364 | 391 |
| 365 @override | 392 @override |
| 366 void finalizeTokens() { | 393 void finalizeTokens() { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 if (token is _ForwardingMetadataEntry && !token.isBound) { | 454 if (token is _ForwardingMetadataEntry && !token.isBound) { |
| 428 _foundUnboundToken = true; | 455 _foundUnboundToken = true; |
| 429 } | 456 } |
| 430 } | 457 } |
| 431 | 458 |
| 432 bool findUnboundPlaceholders(jsAst.Node node) { | 459 bool findUnboundPlaceholders(jsAst.Node node) { |
| 433 node.accept(this); | 460 node.accept(this); |
| 434 return _foundUnboundToken; | 461 return _foundUnboundToken; |
| 435 } | 462 } |
| 436 } | 463 } |
| OLD | NEW |