OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 import '../common.dart'; | 5 import '../common.dart'; |
6 import '../common_elements.dart'; | 6 import '../common_elements.dart'; |
7 import '../constants/values.dart'; | 7 import '../constants/values.dart'; |
| 8 import '../elements/resolution_types.dart'; |
8 import '../elements/elements.dart'; | 9 import '../elements/elements.dart'; |
9 import '../elements/entities.dart'; | |
10 import '../elements/resolution_types.dart'; | |
11 import '../io/code_output.dart'; | 10 import '../io/code_output.dart'; |
12 import '../js/js.dart' as jsAst; | 11 import '../js/js.dart' as jsAst; |
13 import '../js/js.dart' show js; | 12 import '../js/js.dart' show js; |
14 import '../js_emitter/code_emitter_task.dart'; | 13 import '../js_emitter/code_emitter_task.dart'; |
15 import '../options.dart'; | 14 import '../options.dart'; |
16 import '../universe/world_builder.dart'; | |
17 import 'constant_system_javascript.dart'; | 15 import 'constant_system_javascript.dart'; |
18 import 'js_backend.dart'; | 16 import 'js_backend.dart'; |
19 import 'namer.dart'; | 17 import 'namer.dart'; |
20 import 'runtime_types.dart'; | 18 import 'runtime_types.dart'; |
21 | 19 |
22 typedef jsAst.Expression _ConstantReferenceGenerator(ConstantValue constant); | 20 typedef jsAst.Expression _ConstantReferenceGenerator(ConstantValue constant); |
23 | 21 |
24 typedef jsAst.Expression _ConstantListGenerator(jsAst.Expression array); | 22 typedef jsAst.Expression _ConstantListGenerator(jsAst.Expression array); |
25 | 23 |
26 /** | 24 /** |
27 * Generates the JavaScript expressions for constants. | 25 * Generates the JavaScript expressions for constants. |
28 * | 26 * |
29 * It uses a given [constantReferenceGenerator] to reference nested constants | 27 * It uses a given [constantReferenceGenerator] to reference nested constants |
30 * (if there are some). It is hence up to that function to decide which | 28 * (if there are some). It is hence up to that function to decide which |
31 * constants should be inlined or not. | 29 * constants should be inlined or not. |
32 */ | 30 */ |
33 class ConstantEmitter implements ConstantValueVisitor<jsAst.Expression, Null> { | 31 class ConstantEmitter implements ConstantValueVisitor<jsAst.Expression, Null> { |
34 // Matches blank lines, comment lines and trailing comments that can't be part | 32 // Matches blank lines, comment lines and trailing comments that can't be part |
35 // of a string. | 33 // of a string. |
36 static final RegExp COMMENT_RE = | 34 static final RegExp COMMENT_RE = |
37 new RegExp(r'''^ *(//.*)?\n| *//[^''"\n]*$''', multiLine: true); | 35 new RegExp(r'''^ *(//.*)?\n| *//[^''"\n]*$''', multiLine: true); |
38 | 36 |
39 final CompilerOptions _options; | 37 final CompilerOptions _options; |
40 final CommonElements _commonElements; | 38 final CommonElements _commonElements; |
41 final CodegenWorldBuilder _worldBuilder; | |
42 final RuntimeTypesNeed _rtiNeed; | 39 final RuntimeTypesNeed _rtiNeed; |
43 final RuntimeTypesEncoder _rtiEncoder; | 40 final RuntimeTypesEncoder _rtiEncoder; |
44 final Namer _namer; | 41 final Namer _namer; |
45 final CodeEmitterTask _task; | 42 final CodeEmitterTask _task; |
46 final _ConstantReferenceGenerator constantReferenceGenerator; | 43 final _ConstantReferenceGenerator constantReferenceGenerator; |
47 final _ConstantListGenerator makeConstantList; | 44 final _ConstantListGenerator makeConstantList; |
48 | 45 |
49 /** | 46 /** |
50 * The given [constantReferenceGenerator] function must, when invoked with a | 47 * The given [constantReferenceGenerator] function must, when invoked with a |
51 * constant, either return a reference or return its literal expression if it | 48 * constant, either return a reference or return its literal expression if it |
52 * can be inlined. | 49 * can be inlined. |
53 */ | 50 */ |
54 ConstantEmitter( | 51 ConstantEmitter( |
55 this._options, | 52 this._options, |
56 this._commonElements, | 53 this._commonElements, |
57 this._worldBuilder, | |
58 this._rtiNeed, | 54 this._rtiNeed, |
59 this._rtiEncoder, | 55 this._rtiEncoder, |
60 this._namer, | 56 this._namer, |
61 this._task, | 57 this._task, |
62 this.constantReferenceGenerator, | 58 this.constantReferenceGenerator, |
63 this.makeConstantList); | 59 this.makeConstantList); |
64 | 60 |
65 Emitter get _emitter => _task.emitter; | 61 Emitter get _emitter => _task.emitter; |
66 | 62 |
67 /** | 63 /** |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 @override | 276 @override |
281 jsAst.Expression visitType(TypeConstantValue constant, [_]) { | 277 jsAst.Expression visitType(TypeConstantValue constant, [_]) { |
282 ResolutionDartType type = constant.representedType; | 278 ResolutionDartType type = constant.representedType; |
283 jsAst.Name typeName = _namer.runtimeTypeName(type.element); | 279 jsAst.Name typeName = _namer.runtimeTypeName(type.element); |
284 return new jsAst.Call(getHelperProperty(_commonElements.createRuntimeType), | 280 return new jsAst.Call(getHelperProperty(_commonElements.createRuntimeType), |
285 [js.quoteName(typeName)]); | 281 [js.quoteName(typeName)]); |
286 } | 282 } |
287 | 283 |
288 @override | 284 @override |
289 jsAst.Expression visitInterceptor(InterceptorConstantValue constant, [_]) { | 285 jsAst.Expression visitInterceptor(InterceptorConstantValue constant, [_]) { |
290 ClassEntity interceptorClass = constant.cls; | 286 ClassElement interceptorClass = constant.cls; |
291 return _task.interceptorPrototypeAccess(interceptorClass); | 287 return _task.interceptorPrototypeAccess(interceptorClass); |
292 } | 288 } |
293 | 289 |
294 @override | 290 @override |
295 jsAst.Expression visitSynthetic(SyntheticConstantValue constant, [_]) { | 291 jsAst.Expression visitSynthetic(SyntheticConstantValue constant, [_]) { |
296 switch (constant.valueKind) { | 292 switch (constant.valueKind) { |
297 case SyntheticConstantKind.DUMMY_INTERCEPTOR: | 293 case SyntheticConstantKind.DUMMY_INTERCEPTOR: |
298 case SyntheticConstantKind.EMPTY_VALUE: | 294 case SyntheticConstantKind.EMPTY_VALUE: |
299 return new jsAst.LiteralNumber('0'); | 295 return new jsAst.LiteralNumber('0'); |
300 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: | 296 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: |
301 case SyntheticConstantKind.NAME: | 297 case SyntheticConstantKind.NAME: |
302 return constant.payload; | 298 return constant.payload; |
303 default: | 299 default: |
304 throw new SpannableAssertionFailure(NO_LOCATION_SPANNABLE, | 300 throw new SpannableAssertionFailure(NO_LOCATION_SPANNABLE, |
305 "Unexpected DummyConstantKind ${constant.kind}"); | 301 "Unexpected DummyConstantKind ${constant.kind}"); |
306 } | 302 } |
307 } | 303 } |
308 | 304 |
309 @override | 305 @override |
310 jsAst.Expression visitConstructed(ConstructedConstantValue constant, [_]) { | 306 jsAst.Expression visitConstructed(ConstructedConstantValue constant, [_]) { |
311 ClassEntity element = constant.type.element; | 307 ClassElement element = constant.type.element; |
312 if (element == _commonElements.jsConstClass) { | 308 if (element == _commonElements.jsConstClass) { |
313 StringConstantValue str = constant.fields.values.single; | 309 StringConstantValue str = constant.fields.values.single; |
314 String value = str.primitiveValue; | 310 String value = str.primitiveValue; |
315 return new jsAst.LiteralExpression(stripComments(value)); | 311 return new jsAst.LiteralExpression(stripComments(value)); |
316 } | 312 } |
317 jsAst.Expression constructor = | 313 jsAst.Expression constructor = |
318 _emitter.constructorAccess(constant.type.element); | 314 _emitter.constructorAccess(constant.type.element); |
319 List<jsAst.Expression> fields = <jsAst.Expression>[]; | 315 List<jsAst.Expression> fields = <jsAst.Expression>[]; |
320 _worldBuilder.forEachInstanceField(element, (_, FieldEntity field) { | 316 element.forEachInstanceField((_, FieldElement field) { |
321 fields.add(constantReferenceGenerator(constant.fields[field])); | 317 fields.add(constantReferenceGenerator(constant.fields[field])); |
322 }); | 318 }, includeSuperAndInjectedMembers: true); |
323 if (_rtiNeed.classNeedsRtiField(constant.type.element)) { | 319 if (_rtiNeed.classNeedsRtiField(constant.type.element)) { |
324 fields.add(_reifiedTypeArguments(constant.type)); | 320 fields.add(_reifiedTypeArguments(constant.type)); |
325 } | 321 } |
326 jsAst.New instantiation = new jsAst.New(constructor, fields); | 322 jsAst.New instantiation = new jsAst.New(constructor, fields); |
327 return instantiation; | 323 return instantiation; |
328 } | 324 } |
329 | 325 |
330 String stripComments(String rawJavaScript) { | 326 String stripComments(String rawJavaScript) { |
331 return rawJavaScript.replaceAll(COMMENT_RE, ''); | 327 return rawJavaScript.replaceAll(COMMENT_RE, ''); |
332 } | 328 } |
(...skipping 24 matching lines...) Expand all Loading... |
357 _rtiEncoder.getTypeRepresentation(_emitter, argument, unexpected)); | 353 _rtiEncoder.getTypeRepresentation(_emitter, argument, unexpected)); |
358 } | 354 } |
359 return new jsAst.ArrayInitializer(arguments); | 355 return new jsAst.ArrayInitializer(arguments); |
360 } | 356 } |
361 | 357 |
362 @override | 358 @override |
363 jsAst.Expression visitDeferred(DeferredConstantValue constant, [_]) { | 359 jsAst.Expression visitDeferred(DeferredConstantValue constant, [_]) { |
364 return constantReferenceGenerator(constant.referenced); | 360 return constantReferenceGenerator(constant.referenced); |
365 } | 361 } |
366 } | 362 } |
OLD | NEW |