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 |