OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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.program_builder; | 5 library dart2js.js_emitter.program_builder; |
6 | 6 |
7 import '../../closure.dart' show ClosureFieldElement; | 7 import '../../closure.dart' show ClosureFieldElement; |
8 import '../../common.dart'; | 8 import '../../common.dart'; |
9 import '../../common/names.dart' show Names, Selectors; | 9 import '../../common/names.dart' show Names, Selectors; |
10 import '../../compiler.dart' show Compiler; | 10 import '../../compiler.dart' show Compiler; |
(...skipping 24 matching lines...) Expand all Loading... |
35 import '../../js/js.dart' as js; | 35 import '../../js/js.dart' as js; |
36 import '../../js_backend/backend.dart' | 36 import '../../js_backend/backend.dart' |
37 show | 37 show |
38 JavaScriptBackend, | 38 JavaScriptBackend, |
39 RuntimeTypesEncoder, | 39 RuntimeTypesEncoder, |
40 RuntimeTypesNeed, | 40 RuntimeTypesNeed, |
41 SuperMemberData; | 41 SuperMemberData; |
42 import '../../js_backend/backend_usage.dart'; | 42 import '../../js_backend/backend_usage.dart'; |
43 import '../../js_backend/constant_handler_javascript.dart' | 43 import '../../js_backend/constant_handler_javascript.dart' |
44 show JavaScriptConstantCompiler; | 44 show JavaScriptConstantCompiler; |
| 45 import '../../js_backend/custom_elements_analysis.dart'; |
45 import '../../js_backend/namer.dart' show Namer, StringBackedName; | 46 import '../../js_backend/namer.dart' show Namer, StringBackedName; |
46 import '../../js_backend/native_data.dart'; | 47 import '../../js_backend/native_data.dart'; |
47 import '../../js_backend/interceptor_data.dart'; | 48 import '../../js_backend/interceptor_data.dart'; |
48 import '../../js_backend/mirrors_data.dart'; | 49 import '../../js_backend/mirrors_data.dart'; |
49 import '../../native/enqueue.dart' show NativeCodegenEnqueuer; | 50 import '../../native/enqueue.dart' show NativeCodegenEnqueuer; |
50 import '../../options.dart'; | 51 import '../../options.dart'; |
51 import '../../universe/selector.dart' show Selector; | 52 import '../../universe/selector.dart' show Selector; |
52 import '../../universe/world_builder.dart' | 53 import '../../universe/world_builder.dart' |
53 show CodegenWorldBuilder, SelectorConstraints; | 54 show CodegenWorldBuilder, SelectorConstraints; |
54 import '../../world.dart' show ClosedWorld; | 55 import '../../world.dart' show ClosedWorld; |
(...skipping 11 matching lines...) Expand all Loading... |
66 import '../model.dart'; | 67 import '../model.dart'; |
67 | 68 |
68 part 'collector.dart'; | 69 part 'collector.dart'; |
69 part 'field_visitor.dart'; | 70 part 'field_visitor.dart'; |
70 part 'registry.dart'; | 71 part 'registry.dart'; |
71 | 72 |
72 /// Builds a self-contained representation of the program that can then be | 73 /// Builds a self-contained representation of the program that can then be |
73 /// emitted more easily by the individual emitters. | 74 /// emitted more easily by the individual emitters. |
74 class ProgramBuilder { | 75 class ProgramBuilder { |
75 final Compiler _compiler; | 76 final Compiler _compiler; |
76 final Namer namer; | 77 final Namer _namer; |
77 final CodeEmitterTask _task; | 78 final CodeEmitterTask _task; |
78 final ClosedWorld closedWorld; | 79 final ClosedWorld _closedWorld; |
79 | 80 |
80 /// Contains the collected information the program builder used to build | 81 /// Contains the collected information the program builder used to build |
81 /// the model. | 82 /// the model. |
82 // The collector will be filled on the first call to `buildProgram`. | 83 // The collector will be filled on the first call to `buildProgram`. |
83 // It is stored and publicly exposed for backwards compatibility. New code | 84 // It is stored and publicly exposed for backwards compatibility. New code |
84 // (and in particular new emitters) should not use it. | 85 // (and in particular new emitters) should not use it. |
85 final Collector collector; | 86 final Collector collector; |
86 | 87 |
87 final Registry _registry; | 88 final Registry _registry; |
88 | 89 |
89 /// True if the program should store function types in the metadata. | 90 /// True if the program should store function types in the metadata. |
90 bool _storeFunctionTypesInMetadata = false; | 91 bool _storeFunctionTypesInMetadata = false; |
91 | 92 |
92 ProgramBuilder(Compiler compiler, Namer namer, this._task, Emitter emitter, | 93 ProgramBuilder(Compiler compiler, Namer _namer, this._task, Emitter emitter, |
93 ClosedWorld closedWorld, Set<ClassElement> rtiNeededClasses) | 94 ClosedWorld closedWorld, Set<ClassElement> rtiNeededClasses) |
94 : this._compiler = compiler, | 95 : this._compiler = compiler, |
95 this.namer = namer, | 96 this._namer = _namer, |
96 this.closedWorld = closedWorld, | 97 this._closedWorld = closedWorld, |
97 this.collector = new Collector( | 98 this.collector = new Collector( |
98 compiler, namer, closedWorld, rtiNeededClasses, emitter), | 99 compiler, _namer, closedWorld, rtiNeededClasses, emitter), |
99 this._registry = new Registry(compiler); | 100 this._registry = new Registry(compiler); |
100 | 101 |
101 JavaScriptBackend get _backend => _compiler.backend; | 102 JavaScriptBackend get _backend => _compiler.backend; |
102 CodegenWorldBuilder get _worldBuilder => _compiler.codegenWorldBuilder; | 103 CodegenWorldBuilder get _worldBuilder => _compiler.codegenWorldBuilder; |
103 DeferredLoadTask get _deferredLoadTask => _compiler.deferredLoadTask; | 104 DeferredLoadTask get _deferredLoadTask => _compiler.deferredLoadTask; |
104 Types get _types => _compiler.types; | 105 Types get _types => _compiler.types; |
105 CommonElements get _commonElements => _compiler.commonElements; | 106 CommonElements get _commonElements => _compiler.commonElements; |
106 CompilerOptions get _options => _compiler.options; | 107 CompilerOptions get _options => _compiler.options; |
107 NativeCodegenEnqueuer get _nativeCodegenEnqueuer => | 108 NativeCodegenEnqueuer get _nativeCodegenEnqueuer => |
108 _backend.nativeCodegenEnqueuer; | 109 _backend.nativeCodegenEnqueuer; |
109 Namer get _namer => _backend.namer; | |
110 BackendUsage get _backendUsage => _backend.backendUsage; | 110 BackendUsage get _backendUsage => _backend.backendUsage; |
111 CodeEmitterTask get _emitter => _backend.emitter; | 111 CodeEmitterTask get _emitter => _backend.emitter; |
112 JavaScriptConstantCompiler get _constantHandler => _backend.constants; | 112 JavaScriptConstantCompiler get _constantHandler => _backend.constants; |
113 NativeData get _nativeData => _backend.nativeData; | 113 NativeData get _nativeData => _backend.nativeData; |
114 RuntimeTypesNeed get _rtiNeed => _backend.rtiNeed; | 114 RuntimeTypesNeed get _rtiNeed => _backend.rtiNeed; |
115 MirrorsData get _mirrorsData => _backend.mirrorsData; | 115 MirrorsData get _mirrorsData => _backend.mirrorsData; |
116 InterceptorData get _interceptorData => _backend.interceptorData; | 116 InterceptorData get _interceptorData => _backend.interceptorData; |
117 SuperMemberData get _superMemberData => _backend.superMemberData; | 117 SuperMemberData get _superMemberData => _backend.superMemberData; |
118 RuntimeTypesEncoder get _rtiEncoder => _backend.rtiEncoder; | 118 RuntimeTypesEncoder get _rtiEncoder => _backend.rtiEncoder; |
119 OneShotInterceptorData get _oneShotInterceptorData => | 119 OneShotInterceptorData get _oneShotInterceptorData => |
120 _backend.oneShotInterceptorData; | 120 _backend.oneShotInterceptorData; |
| 121 CustomElementsCodegenAnalysis get _customElementsCodegenAnalysis => |
| 122 _backend.customElementsCodegenAnalysis; |
121 | 123 |
122 /// Mapping from [ClassElement] to constructed [Class]. We need this to | 124 /// Mapping from [ClassElement] to constructed [Class]. We need this to |
123 /// update the superclass in the [Class]. | 125 /// update the superclass in the [Class]. |
124 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; | 126 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; |
125 | 127 |
126 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to | 128 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to |
127 /// generate the deferredLoadingMap (to know which hunks to load). | 129 /// generate the deferredLoadingMap (to know which hunks to load). |
128 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; | 130 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; |
129 | 131 |
130 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to | 132 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 _deferredLoadTask.hunksToLoad | 235 _deferredLoadTask.hunksToLoad |
234 .forEach((String loadId, List<OutputUnit> outputUnits) { | 236 .forEach((String loadId, List<OutputUnit> outputUnits) { |
235 loadMap[loadId] = outputUnits | 237 loadMap[loadId] = outputUnits |
236 .map((OutputUnit unit) => _outputs[unit]) | 238 .map((OutputUnit unit) => _outputs[unit]) |
237 .toList(growable: false); | 239 .toList(growable: false); |
238 }); | 240 }); |
239 return loadMap; | 241 return loadMap; |
240 } | 242 } |
241 | 243 |
242 js.Expression _buildTypeToInterceptorMap() { | 244 js.Expression _buildTypeToInterceptorMap() { |
243 InterceptorStubGenerator stubGenerator = | 245 InterceptorStubGenerator stubGenerator = new InterceptorStubGenerator( |
244 new InterceptorStubGenerator(_compiler, namer, _backend, closedWorld); | 246 _options, |
| 247 _commonElements, |
| 248 _emitter, |
| 249 _nativeCodegenEnqueuer, |
| 250 _constantHandler, |
| 251 _namer, |
| 252 _nativeData, |
| 253 _interceptorData, |
| 254 _oneShotInterceptorData, |
| 255 _customElementsCodegenAnalysis, |
| 256 _worldBuilder, |
| 257 _closedWorld); |
245 return stubGenerator.generateTypeToInterceptorMap(); | 258 return stubGenerator.generateTypeToInterceptorMap(); |
246 } | 259 } |
247 | 260 |
248 MainFragment _buildMainFragment(LibrariesMap librariesMap) { | 261 MainFragment _buildMainFragment(LibrariesMap librariesMap) { |
249 // Construct the main output from the libraries and the registered holders. | 262 // Construct the main output from the libraries and the registered holders. |
250 MainFragment result = new MainFragment( | 263 MainFragment result = new MainFragment( |
251 librariesMap.outputUnit, | 264 librariesMap.outputUnit, |
252 "", // The empty string is the name for the main output file. | 265 "", // The empty string is the name for the main output file. |
253 _buildInvokeMain(), | 266 _buildInvokeMain(), |
254 _buildLibraries(librariesMap), | 267 _buildLibraries(librariesMap), |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 if (staticNonFinalFields == null) return const <StaticField>[]; | 308 if (staticNonFinalFields == null) return const <StaticField>[]; |
296 | 309 |
297 return staticNonFinalFields.map(_buildStaticField).toList(growable: false); | 310 return staticNonFinalFields.map(_buildStaticField).toList(growable: false); |
298 } | 311 } |
299 | 312 |
300 StaticField _buildStaticField(FieldElement element) { | 313 StaticField _buildStaticField(FieldElement element) { |
301 ConstantValue initialValue = | 314 ConstantValue initialValue = |
302 _constantHandler.getConstantValue(element.constant); | 315 _constantHandler.getConstantValue(element.constant); |
303 // TODO(zarah): The holder should not be registered during building of | 316 // TODO(zarah): The holder should not be registered during building of |
304 // a static field. | 317 // a static field. |
305 _registry.registerHolder(namer.globalObjectForConstant(initialValue), | 318 _registry.registerHolder(_namer.globalObjectForConstant(initialValue), |
306 isConstantsHolder: true); | 319 isConstantsHolder: true); |
307 js.Expression code = _task.emitter.constantReference(initialValue); | 320 js.Expression code = _task.emitter.constantReference(initialValue); |
308 js.Name name = namer.globalPropertyName(element); | 321 js.Name name = _namer.globalPropertyName(element); |
309 bool isFinal = false; | 322 bool isFinal = false; |
310 bool isLazy = false; | 323 bool isLazy = false; |
311 | 324 |
312 // TODO(floitsch): we shouldn't update the registry in the middle of | 325 // TODO(floitsch): we shouldn't update the registry in the middle of |
313 // building a static field. (Note that the static-state holder was | 326 // building a static field. (Note that the static-state holder was |
314 // already registered earlier, and that we just call the register to get | 327 // already registered earlier, and that we just call the register to get |
315 // the holder-instance. | 328 // the holder-instance. |
316 return new StaticField( | 329 return new StaticField( |
317 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); | 330 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); |
318 } | 331 } |
(...skipping 12 matching lines...) Expand all Loading... |
331 .toList(growable: false); | 344 .toList(growable: false); |
332 } | 345 } |
333 | 346 |
334 StaticField _buildLazyField(FieldElement element) { | 347 StaticField _buildLazyField(FieldElement element) { |
335 js.Expression code = _backend.generatedCode[element]; | 348 js.Expression code = _backend.generatedCode[element]; |
336 // The code is null if we ended up not needing the lazily | 349 // The code is null if we ended up not needing the lazily |
337 // initialized field after all because of constant folding | 350 // initialized field after all because of constant folding |
338 // before code generation. | 351 // before code generation. |
339 if (code == null) return null; | 352 if (code == null) return null; |
340 | 353 |
341 js.Name name = namer.globalPropertyName(element); | 354 js.Name name = _namer.globalPropertyName(element); |
342 bool isFinal = element.isFinal; | 355 bool isFinal = element.isFinal; |
343 bool isLazy = true; | 356 bool isLazy = true; |
344 // TODO(floitsch): we shouldn't update the registry in the middle of | 357 // TODO(floitsch): we shouldn't update the registry in the middle of |
345 // building a static field. (Note that the static-state holder was | 358 // building a static field. (Note that the static-state holder was |
346 // already registered earlier, and that we just call the register to get | 359 // already registered earlier, and that we just call the register to get |
347 // the holder-instance. | 360 // the holder-instance. |
348 return new StaticField( | 361 return new StaticField( |
349 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); | 362 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); |
350 } | 363 } |
351 | 364 |
352 List<Library> _buildLibraries(LibrariesMap librariesMap) { | 365 List<Library> _buildLibraries(LibrariesMap librariesMap) { |
353 List<Library> libraries = new List<Library>(librariesMap.length); | 366 List<Library> libraries = new List<Library>(librariesMap.length); |
354 int count = 0; | 367 int count = 0; |
355 librariesMap.forEach((LibraryElement library, List<Element> elements) { | 368 librariesMap.forEach((LibraryElement library, List<Element> elements) { |
356 libraries[count++] = _buildLibrary(library, elements); | 369 libraries[count++] = _buildLibrary(library, elements); |
357 }); | 370 }); |
358 return libraries; | 371 return libraries; |
359 } | 372 } |
360 | 373 |
361 void _addJsInteropStubs(LibrariesMap librariesMap) { | 374 void _addJsInteropStubs(LibrariesMap librariesMap) { |
362 if (_classes.containsKey(_commonElements.objectClass)) { | 375 if (_classes.containsKey(_commonElements.objectClass)) { |
363 var toStringInvocation = namer.invocationName(Selectors.toString_); | 376 var toStringInvocation = _namer.invocationName(Selectors.toString_); |
364 // TODO(jacobr): register toString as used so that it is always accessible | 377 // TODO(jacobr): register toString as used so that it is always accessible |
365 // from JavaScript. | 378 // from JavaScript. |
366 _classes[_commonElements.objectClass].callStubs.add(_buildStubMethod( | 379 _classes[_commonElements.objectClass].callStubs.add(_buildStubMethod( |
367 new StringBackedName("toString"), | 380 new StringBackedName("toString"), |
368 js.js('function() { return this.#(this) }', toStringInvocation))); | 381 js.js('function() { return this.#(this) }', toStringInvocation))); |
369 } | 382 } |
370 | 383 |
371 // We add all members from classes marked with isJsInterop to the base | 384 // We add all members from classes marked with isJsInterop to the base |
372 // Interceptor class with implementations that directly call the | 385 // Interceptor class with implementations that directly call the |
373 // corresponding JavaScript member. We do not attempt to bind this when | 386 // corresponding JavaScript member. We do not attempt to bind this when |
374 // tearing off JavaScript methods as we cannot distinguish between calling | 387 // tearing off JavaScript methods as we cannot distinguish between calling |
375 // a regular getter that returns a JavaScript function and tearing off | 388 // a regular getter that returns a JavaScript function and tearing off |
376 // a method in the case where there exist multiple JavaScript classes | 389 // a method in the case where there exist multiple JavaScript classes |
377 // that conflict on whether the member is a getter or a method. | 390 // that conflict on whether the member is a getter or a method. |
378 var interceptorClass = _classes[_commonElements.jsJavaScriptObjectClass]; | 391 var interceptorClass = _classes[_commonElements.jsJavaScriptObjectClass]; |
379 var stubNames = new Set<String>(); | 392 var stubNames = new Set<String>(); |
380 librariesMap.forEach((LibraryElement library, List<Element> elements) { | 393 librariesMap.forEach((LibraryElement library, List<Element> elements) { |
381 for (Element e in elements) { | 394 for (Element e in elements) { |
382 if (e is ClassElement && _nativeData.isJsInteropClass(e)) { | 395 if (e is ClassElement && _nativeData.isJsInteropClass(e)) { |
383 e.declaration.forEachMember((_, Element member) { | 396 e.declaration.forEachMember((_, Element member) { |
384 var jsName = _nativeData.computeUnescapedJSInteropName(member.name); | 397 var jsName = _nativeData.computeUnescapedJSInteropName(member.name); |
385 if (!member.isInstanceMember) return; | 398 if (!member.isInstanceMember) return; |
386 if (member.isGetter || member.isField || member.isFunction) { | 399 if (member.isGetter || member.isField || member.isFunction) { |
387 var selectors = | 400 var selectors = |
388 _worldBuilder.getterInvocationsByName(member.name); | 401 _worldBuilder.getterInvocationsByName(member.name); |
389 if (selectors != null && !selectors.isEmpty) { | 402 if (selectors != null && !selectors.isEmpty) { |
390 for (var selector in selectors.keys) { | 403 for (var selector in selectors.keys) { |
391 var stubName = namer.invocationName(selector); | 404 var stubName = _namer.invocationName(selector); |
392 if (stubNames.add(stubName.key)) { | 405 if (stubNames.add(stubName.key)) { |
393 interceptorClass.callStubs.add(_buildStubMethod(stubName, | 406 interceptorClass.callStubs.add(_buildStubMethod(stubName, |
394 js.js('function(obj) { return obj.# }', [jsName]), | 407 js.js('function(obj) { return obj.# }', [jsName]), |
395 element: member)); | 408 element: member)); |
396 } | 409 } |
397 } | 410 } |
398 } | 411 } |
399 } | 412 } |
400 | 413 |
401 if (member.isSetter || (member.isField && !member.isConst)) { | 414 if (member.isSetter || (member.isField && !member.isConst)) { |
402 var selectors = | 415 var selectors = |
403 _worldBuilder.setterInvocationsByName(member.name); | 416 _worldBuilder.setterInvocationsByName(member.name); |
404 if (selectors != null && !selectors.isEmpty) { | 417 if (selectors != null && !selectors.isEmpty) { |
405 var stubName = namer.setterForElement(member); | 418 var stubName = _namer.setterForElement(member); |
406 if (stubNames.add(stubName.key)) { | 419 if (stubNames.add(stubName.key)) { |
407 interceptorClass.callStubs.add(_buildStubMethod(stubName, | 420 interceptorClass.callStubs.add(_buildStubMethod(stubName, |
408 js.js('function(obj, v) { return obj.# = v }', [jsName]), | 421 js.js('function(obj, v) { return obj.# = v }', [jsName]), |
409 element: member)); | 422 element: member)); |
410 } | 423 } |
411 } | 424 } |
412 } | 425 } |
413 | 426 |
414 // Generating stubs for direct calls and stubs for call-through | 427 // Generating stubs for direct calls and stubs for call-through |
415 // of getters that happen to be functions. | 428 // of getters that happen to be functions. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 // may want to map named arguments to an object literal containing | 473 // may want to map named arguments to an object literal containing |
461 // all named arguments. | 474 // all named arguments. |
462 if (selectors != null && !selectors.isEmpty) { | 475 if (selectors != null && !selectors.isEmpty) { |
463 for (var selector in selectors.keys) { | 476 for (var selector in selectors.keys) { |
464 // Check whether the arity matches this member. | 477 // Check whether the arity matches this member. |
465 var argumentCount = selector.argumentCount; | 478 var argumentCount = selector.argumentCount; |
466 // JS interop does not support named arguments. | 479 // JS interop does not support named arguments. |
467 if (selector.namedArgumentCount > 0) continue; | 480 if (selector.namedArgumentCount > 0) continue; |
468 if (argumentCount < minArgs) continue; | 481 if (argumentCount < minArgs) continue; |
469 if (argumentCount > maxArgs) continue; | 482 if (argumentCount > maxArgs) continue; |
470 var stubName = namer.invocationName(selector); | 483 var stubName = _namer.invocationName(selector); |
471 if (!stubNames.add(stubName.key)) continue; | 484 if (!stubNames.add(stubName.key)) continue; |
472 var parameters = | 485 var parameters = |
473 new List<String>.generate(argumentCount, (i) => 'p$i'); | 486 new List<String>.generate(argumentCount, (i) => 'p$i'); |
474 | 487 |
475 // We intentionally generate the same stub method for direct | 488 // We intentionally generate the same stub method for direct |
476 // calls and call-throughs of getters so that calling a | 489 // calls and call-throughs of getters so that calling a |
477 // getter that returns a function behaves the same as calling | 490 // getter that returns a function behaves the same as calling |
478 // a method. This is helpful as many typed JavaScript APIs | 491 // a method. This is helpful as many typed JavaScript APIs |
479 // specify member functions with getters that return | 492 // specify member functions with getters that return |
480 // functions. The behavior of this solution matches JavaScript | 493 // functions. The behavior of this solution matches JavaScript |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 if (_nativeData.isJsInteropClass(element)) { | 543 if (_nativeData.isJsInteropClass(element)) { |
531 // TODO(jacobr): check whether the class has any active static fields | 544 // TODO(jacobr): check whether the class has any active static fields |
532 // if it does not we can suppress it completely. | 545 // if it does not we can suppress it completely. |
533 onlyForRti = true; | 546 onlyForRti = true; |
534 } | 547 } |
535 | 548 |
536 List<Method> methods = []; | 549 List<Method> methods = []; |
537 List<StubMethod> callStubs = <StubMethod>[]; | 550 List<StubMethod> callStubs = <StubMethod>[]; |
538 | 551 |
539 ClassStubGenerator classStubGenerator = new ClassStubGenerator( | 552 ClassStubGenerator classStubGenerator = new ClassStubGenerator( |
540 namer, _backend, _worldBuilder, closedWorld, | 553 _namer, _backend, _worldBuilder, _closedWorld, |
541 enableMinification: _options.enableMinification); | 554 enableMinification: _options.enableMinification); |
542 RuntimeTypeGenerator runtimeTypeGenerator = | 555 RuntimeTypeGenerator runtimeTypeGenerator = |
543 new RuntimeTypeGenerator(_compiler, _task, namer); | 556 new RuntimeTypeGenerator(_compiler, _task, _namer); |
544 | 557 |
545 void visitMember(ClassElement enclosing, MemberElement member) { | 558 void visitMember(ClassElement enclosing, MemberElement member) { |
546 assert(invariant(element, member.isDeclaration)); | 559 assert(invariant(element, member.isDeclaration)); |
547 assert(invariant(element, element == enclosing)); | 560 assert(invariant(element, element == enclosing)); |
548 | 561 |
549 if (Elements.isNonAbstractInstanceMember(member)) { | 562 if (Elements.isNonAbstractInstanceMember(member)) { |
550 // TODO(herhut): Remove once _buildMethod can no longer return null. | 563 // TODO(herhut): Remove once _buildMethod can no longer return null. |
551 Method method = _buildMethod(member); | 564 Method method = _buildMethod(member); |
552 if (method != null) methods.add(method); | 565 if (method != null) methods.add(method); |
553 } | 566 } |
(...skipping 23 matching lines...) Expand all Loading... |
577 _symbolsMap[name] = selectorName; | 590 _symbolsMap[name] = selectorName; |
578 } | 591 } |
579 noSuchMethodStubs.add( | 592 noSuchMethodStubs.add( |
580 classStubGenerator.generateStubForNoSuchMethod(name, selector)); | 593 classStubGenerator.generateStubForNoSuchMethod(name, selector)); |
581 }); | 594 }); |
582 } | 595 } |
583 | 596 |
584 if (element == _commonElements.closureClass) { | 597 if (element == _commonElements.closureClass) { |
585 // We add a special getter here to allow for tearing off a closure from | 598 // We add a special getter here to allow for tearing off a closure from |
586 // itself. | 599 // itself. |
587 js.Name name = namer.getterForMember(Names.call); | 600 js.Name name = _namer.getterForMember(Names.call); |
588 js.Fun function = js.js('function() { return this; }'); | 601 js.Fun function = js.js('function() { return this; }'); |
589 callStubs.add(_buildStubMethod(name, function)); | 602 callStubs.add(_buildStubMethod(name, function)); |
590 } | 603 } |
591 | 604 |
592 ClassElement implementation = element.implementation; | 605 ClassElement implementation = element.implementation; |
593 | 606 |
594 // MixinApplications run through the members of their mixin. Here, we are | 607 // MixinApplications run through the members of their mixin. Here, we are |
595 // only interested in direct members. | 608 // only interested in direct members. |
596 if (!onlyForRti && !element.isMixinApplication) { | 609 if (!onlyForRti && !element.isMixinApplication) { |
597 implementation.forEachMember(visitMember, includeBackendMembers: true); | 610 implementation.forEachMember(visitMember, includeBackendMembers: true); |
(...skipping 19 matching lines...) Expand all Loading... |
617 .isChecks | 630 .isChecks |
618 .add(_buildStubMethod(name, code)); | 631 .add(_buildStubMethod(name, code)); |
619 }); | 632 }); |
620 } else { | 633 } else { |
621 for (Field field in instanceFields) { | 634 for (Field field in instanceFields) { |
622 if (field.needsCheckedSetter) { | 635 if (field.needsCheckedSetter) { |
623 assert(!field.needsUncheckedSetter); | 636 assert(!field.needsUncheckedSetter); |
624 FieldElement element = field.element; | 637 FieldElement element = field.element; |
625 js.Expression code = _backend.generatedCode[element]; | 638 js.Expression code = _backend.generatedCode[element]; |
626 assert(code != null); | 639 assert(code != null); |
627 js.Name name = namer.deriveSetterName(field.accessorName); | 640 js.Name name = _namer.deriveSetterName(field.accessorName); |
628 checkedSetters.add(_buildStubMethod(name, code, element: element)); | 641 checkedSetters.add(_buildStubMethod(name, code, element: element)); |
629 } | 642 } |
630 } | 643 } |
631 | 644 |
632 typeTests.properties.forEach((js.Name name, js.Node code) { | 645 typeTests.properties.forEach((js.Name name, js.Node code) { |
633 isChecks.add(_buildStubMethod(name, code)); | 646 isChecks.add(_buildStubMethod(name, code)); |
634 }); | 647 }); |
635 } | 648 } |
636 | 649 |
637 js.Name name = namer.className(element); | 650 js.Name name = _namer.className(element); |
638 String holderName = namer.globalObjectFor(element); | 651 String holderName = _namer.globalObjectFor(element); |
639 // TODO(floitsch): we shouldn't update the registry in the middle of | 652 // TODO(floitsch): we shouldn't update the registry in the middle of |
640 // building a class. | 653 // building a class. |
641 Holder holder = _registry.registerHolder(holderName); | 654 Holder holder = _registry.registerHolder(holderName); |
642 bool isInstantiated = !_nativeData.isJsInteropClass(element) && | 655 bool isInstantiated = !_nativeData.isJsInteropClass(element) && |
643 _worldBuilder.directlyInstantiatedClasses.contains(element); | 656 _worldBuilder.directlyInstantiatedClasses.contains(element); |
644 | 657 |
645 Class result; | 658 Class result; |
646 if (element.isMixinApplication && !onlyForRti) { | 659 if (element.isMixinApplication && !onlyForRti) { |
647 assert(!_nativeData.isNativeClass(element)); | 660 assert(!_nativeData.isNativeClass(element)); |
648 assert(methods.isEmpty); | 661 assert(methods.isEmpty); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 bool _methodNeedsStubs(FunctionElement method) { | 698 bool _methodNeedsStubs(FunctionElement method) { |
686 return !method.functionSignature.optionalParameters.isEmpty; | 699 return !method.functionSignature.optionalParameters.isEmpty; |
687 } | 700 } |
688 | 701 |
689 bool _methodCanBeReflected(MethodElement method) { | 702 bool _methodCanBeReflected(MethodElement method) { |
690 return _mirrorsData.isMemberAccessibleByReflection(method); | 703 return _mirrorsData.isMemberAccessibleByReflection(method); |
691 } | 704 } |
692 | 705 |
693 bool _methodCanBeApplied(FunctionElement method) { | 706 bool _methodCanBeApplied(FunctionElement method) { |
694 return _backendUsage.isFunctionApplyUsed && | 707 return _backendUsage.isFunctionApplyUsed && |
695 closedWorld.getMightBePassedToApply(method); | 708 _closedWorld.getMightBePassedToApply(method); |
696 } | 709 } |
697 | 710 |
698 /* Map | List */ _computeParameterDefaultValues(FunctionSignature signature) { | 711 /* Map | List */ _computeParameterDefaultValues(FunctionSignature signature) { |
699 var /* Map | List */ optionalParameterDefaultValues; | 712 var /* Map | List */ optionalParameterDefaultValues; |
700 if (signature.optionalParametersAreNamed) { | 713 if (signature.optionalParametersAreNamed) { |
701 optionalParameterDefaultValues = new Map<String, ConstantValue>(); | 714 optionalParameterDefaultValues = new Map<String, ConstantValue>(); |
702 signature.forEachOptionalParameter((ParameterElement parameter) { | 715 signature.forEachOptionalParameter((ParameterElement parameter) { |
703 ConstantValue def = | 716 ConstantValue def = |
704 _constantHandler.getConstantValue(parameter.constant); | 717 _constantHandler.getConstantValue(parameter.constant); |
705 optionalParameterDefaultValues[parameter.name] = def; | 718 optionalParameterDefaultValues[parameter.name] = def; |
706 }); | 719 }); |
707 } else { | 720 } else { |
708 optionalParameterDefaultValues = <ConstantValue>[]; | 721 optionalParameterDefaultValues = <ConstantValue>[]; |
709 signature.forEachOptionalParameter((ParameterElement parameter) { | 722 signature.forEachOptionalParameter((ParameterElement parameter) { |
710 ConstantValue def = | 723 ConstantValue def = |
711 _constantHandler.getConstantValue(parameter.constant); | 724 _constantHandler.getConstantValue(parameter.constant); |
712 optionalParameterDefaultValues.add(def); | 725 optionalParameterDefaultValues.add(def); |
713 }); | 726 }); |
714 } | 727 } |
715 return optionalParameterDefaultValues; | 728 return optionalParameterDefaultValues; |
716 } | 729 } |
717 | 730 |
718 DartMethod _buildMethod(MethodElement element) { | 731 DartMethod _buildMethod(MethodElement element) { |
719 assert(element.isDeclaration); | 732 assert(element.isDeclaration); |
720 js.Name name = namer.methodPropertyName(element); | 733 js.Name name = _namer.methodPropertyName(element); |
721 js.Expression code = _backend.generatedCode[element]; | 734 js.Expression code = _backend.generatedCode[element]; |
722 | 735 |
723 // TODO(kasperl): Figure out under which conditions code is null. | 736 // TODO(kasperl): Figure out under which conditions code is null. |
724 if (code == null) return null; | 737 if (code == null) return null; |
725 | 738 |
726 bool canTearOff = false; | 739 bool canTearOff = false; |
727 js.Name tearOffName; | 740 js.Name tearOffName; |
728 bool isClosureCallMethod = false; | 741 bool isClosureCallMethod = false; |
729 bool isNotApplyTarget = !element.isFunction || element.isAccessor; | 742 bool isNotApplyTarget = !element.isFunction || element.isAccessor; |
730 | 743 |
731 bool canBeReflected = _methodCanBeReflected(element); | 744 bool canBeReflected = _methodCanBeReflected(element); |
732 bool canBeApplied = _methodCanBeApplied(element); | 745 bool canBeApplied = _methodCanBeApplied(element); |
733 | 746 |
734 js.Name aliasName = _superMemberData.isAliasedSuperMember(element) | 747 js.Name aliasName = _superMemberData.isAliasedSuperMember(element) |
735 ? namer.aliasedSuperMemberPropertyName(element) | 748 ? _namer.aliasedSuperMemberPropertyName(element) |
736 : null; | 749 : null; |
737 | 750 |
738 if (isNotApplyTarget) { | 751 if (isNotApplyTarget) { |
739 canTearOff = false; | 752 canTearOff = false; |
740 } else { | 753 } else { |
741 if (element.enclosingClass.isClosure) { | 754 if (element.enclosingClass.isClosure) { |
742 canTearOff = false; | 755 canTearOff = false; |
743 isClosureCallMethod = true; | 756 isClosureCallMethod = true; |
744 } else { | 757 } else { |
745 // Careful with operators. | 758 // Careful with operators. |
746 canTearOff = _worldBuilder.hasInvokedGetter(element, closedWorld) || | 759 canTearOff = _worldBuilder.hasInvokedGetter(element, _closedWorld) || |
747 (canBeReflected && !element.isOperator); | 760 (canBeReflected && !element.isOperator); |
748 assert(canTearOff || | 761 assert(canTearOff || |
749 !_worldBuilder.methodsNeedingSuperGetter.contains(element)); | 762 !_worldBuilder.methodsNeedingSuperGetter.contains(element)); |
750 tearOffName = namer.getterForElement(element); | 763 tearOffName = _namer.getterForElement(element); |
751 } | 764 } |
752 } | 765 } |
753 | 766 |
754 if (canTearOff) { | 767 if (canTearOff) { |
755 assert(invariant(element, !element.isGenerativeConstructor)); | 768 assert(invariant(element, !element.isGenerativeConstructor)); |
756 assert(invariant(element, !element.isGenerativeConstructorBody)); | 769 assert(invariant(element, !element.isGenerativeConstructorBody)); |
757 assert(invariant(element, !element.isConstructor)); | 770 assert(invariant(element, !element.isConstructor)); |
758 } | 771 } |
759 | 772 |
760 js.Name callName = null; | 773 js.Name callName = null; |
761 if (canTearOff) { | 774 if (canTearOff) { |
762 Selector callSelector = | 775 Selector callSelector = |
763 new Selector.fromElement(element).toCallSelector(); | 776 new Selector.fromElement(element).toCallSelector(); |
764 callName = namer.invocationName(callSelector); | 777 callName = _namer.invocationName(callSelector); |
765 } | 778 } |
766 | 779 |
767 ResolutionDartType memberType; | 780 ResolutionDartType memberType; |
768 if (element.isGenerativeConstructorBody) { | 781 if (element.isGenerativeConstructorBody) { |
769 // TODO(herhut): Why does this need to be normalized away? We never need | 782 // TODO(herhut): Why does this need to be normalized away? We never need |
770 // this information anyway as they cannot be torn off or | 783 // this information anyway as they cannot be torn off or |
771 // reflected. | 784 // reflected. |
772 var body = element; | 785 var body = element; |
773 memberType = body.constructor.type; | 786 memberType = body.constructor.type; |
774 } else { | 787 } else { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
813 return _emitter.metadataCollector | 826 return _emitter.metadataCollector |
814 .reifyTypeForOutputUnit(type, outputUnit); | 827 .reifyTypeForOutputUnit(type, outputUnit); |
815 } | 828 } |
816 } | 829 } |
817 | 830 |
818 List<ParameterStubMethod> _generateParameterStubs( | 831 List<ParameterStubMethod> _generateParameterStubs( |
819 MethodElement element, bool canTearOff) { | 832 MethodElement element, bool canTearOff) { |
820 if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[]; | 833 if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[]; |
821 | 834 |
822 ParameterStubGenerator generator = | 835 ParameterStubGenerator generator = |
823 new ParameterStubGenerator(_compiler, namer, _backend, closedWorld); | 836 new ParameterStubGenerator(_compiler, _namer, _backend, _closedWorld); |
824 return generator.generateParameterStubs(element, canTearOff: canTearOff); | 837 return generator.generateParameterStubs(element, canTearOff: canTearOff); |
825 } | 838 } |
826 | 839 |
827 /// Builds a stub method. | 840 /// Builds a stub method. |
828 /// | 841 /// |
829 /// Stub methods may have an element that can be used for code-size | 842 /// Stub methods may have an element that can be used for code-size |
830 /// attribution. | 843 /// attribution. |
831 Method _buildStubMethod(js.Name name, js.Expression code, | 844 Method _buildStubMethod(js.Name name, js.Expression code, |
832 {MemberElement element}) { | 845 {MemberElement element}) { |
833 return new StubMethod(name, code, element: element); | 846 return new StubMethod(name, code, element: element); |
834 } | 847 } |
835 | 848 |
836 // The getInterceptor methods directly access the prototype of classes. | 849 // The getInterceptor methods directly access the prototype of classes. |
837 // We must evaluate these classes eagerly so that the prototype is | 850 // We must evaluate these classes eagerly so that the prototype is |
838 // accessible. | 851 // accessible. |
839 void _markEagerInterceptorClasses() { | 852 void _markEagerInterceptorClasses() { |
840 Iterable<js.Name> names = | 853 Iterable<js.Name> names = |
841 _oneShotInterceptorData.specializedGetInterceptorNames; | 854 _oneShotInterceptorData.specializedGetInterceptorNames; |
842 for (js.Name name in names) { | 855 for (js.Name name in names) { |
843 for (ClassElement element | 856 for (ClassElement element |
844 in _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name)) { | 857 in _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name)) { |
845 Class cls = _classes[element]; | 858 Class cls = _classes[element]; |
846 if (cls != null) cls.isEager = true; | 859 if (cls != null) cls.isEager = true; |
847 } | 860 } |
848 } | 861 } |
849 } | 862 } |
850 | 863 |
851 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { | 864 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { |
852 InterceptorStubGenerator stubGenerator = | 865 InterceptorStubGenerator stubGenerator = new InterceptorStubGenerator( |
853 new InterceptorStubGenerator(_compiler, namer, _backend, closedWorld); | 866 _options, |
| 867 _commonElements, |
| 868 _emitter, |
| 869 _nativeCodegenEnqueuer, |
| 870 _constantHandler, |
| 871 _namer, |
| 872 _nativeData, |
| 873 _interceptorData, |
| 874 _oneShotInterceptorData, |
| 875 _customElementsCodegenAnalysis, |
| 876 _worldBuilder, |
| 877 _closedWorld); |
854 | 878 |
855 String holderName = | 879 String holderName = |
856 namer.globalObjectForLibrary(_commonElements.interceptorsLibrary); | 880 _namer.globalObjectForLibrary(_commonElements.interceptorsLibrary); |
857 // TODO(floitsch): we shouldn't update the registry in the middle of | 881 // TODO(floitsch): we shouldn't update the registry in the middle of |
858 // generating the interceptor methods. | 882 // generating the interceptor methods. |
859 Holder holder = _registry.registerHolder(holderName); | 883 Holder holder = _registry.registerHolder(holderName); |
860 | 884 |
861 Iterable<js.Name> names = | 885 Iterable<js.Name> names = |
862 _oneShotInterceptorData.specializedGetInterceptorNames; | 886 _oneShotInterceptorData.specializedGetInterceptorNames; |
863 return names.map((js.Name name) { | 887 return names.map((js.Name name) { |
864 Set<ClassEntity> classes = | 888 Set<ClassEntity> classes = |
865 _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name); | 889 _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name); |
866 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes); | 890 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes); |
867 return new StaticStubMethod(name, holder, code); | 891 return new StaticStubMethod(name, holder, code); |
868 }); | 892 }); |
869 } | 893 } |
870 | 894 |
871 List<Field> _buildFields(Element holder, | 895 List<Field> _buildFields(Element holder, |
872 {bool visitStatics, bool isHolderInterceptedClass: false}) { | 896 {bool visitStatics, bool isHolderInterceptedClass: false}) { |
873 List<Field> fields = <Field>[]; | 897 List<Field> fields = <Field>[]; |
874 new FieldVisitor(_compiler, namer, closedWorld) | 898 new FieldVisitor(_compiler, _namer, _closedWorld) |
875 .visitFields(holder, visitStatics, (FieldElement field, | 899 .visitFields(holder, visitStatics, (FieldElement field, |
876 js.Name name, | 900 js.Name name, |
877 js.Name accessorName, | 901 js.Name accessorName, |
878 bool needsGetter, | 902 bool needsGetter, |
879 bool needsSetter, | 903 bool needsSetter, |
880 bool needsCheckedSetter) { | 904 bool needsCheckedSetter) { |
881 assert(invariant(field, field.isDeclaration)); | 905 assert(invariant(field, field.isDeclaration)); |
882 | 906 |
883 int getterFlags = 0; | 907 int getterFlags = 0; |
884 if (needsGetter) { | 908 if (needsGetter) { |
(...skipping 25 matching lines...) Expand all Loading... |
910 } | 934 } |
911 | 935 |
912 fields.add(new Field(field, name, accessorName, getterFlags, setterFlags, | 936 fields.add(new Field(field, name, accessorName, getterFlags, setterFlags, |
913 needsCheckedSetter)); | 937 needsCheckedSetter)); |
914 }); | 938 }); |
915 | 939 |
916 return fields; | 940 return fields; |
917 } | 941 } |
918 | 942 |
919 Iterable<StaticStubMethod> _generateOneShotInterceptors() { | 943 Iterable<StaticStubMethod> _generateOneShotInterceptors() { |
920 InterceptorStubGenerator stubGenerator = | 944 InterceptorStubGenerator stubGenerator = new InterceptorStubGenerator( |
921 new InterceptorStubGenerator(_compiler, namer, _backend, closedWorld); | 945 _options, |
| 946 _commonElements, |
| 947 _emitter, |
| 948 _nativeCodegenEnqueuer, |
| 949 _constantHandler, |
| 950 _namer, |
| 951 _nativeData, |
| 952 _interceptorData, |
| 953 _oneShotInterceptorData, |
| 954 _customElementsCodegenAnalysis, |
| 955 _worldBuilder, |
| 956 _closedWorld); |
922 | 957 |
923 String holderName = | 958 String holderName = |
924 namer.globalObjectForLibrary(_commonElements.interceptorsLibrary); | 959 _namer.globalObjectForLibrary(_commonElements.interceptorsLibrary); |
925 // TODO(floitsch): we shouldn't update the registry in the middle of | 960 // TODO(floitsch): we shouldn't update the registry in the middle of |
926 // generating the interceptor methods. | 961 // generating the interceptor methods. |
927 Holder holder = _registry.registerHolder(holderName); | 962 Holder holder = _registry.registerHolder(holderName); |
928 | 963 |
929 List<js.Name> names = _oneShotInterceptorData.oneShotInterceptorNames; | 964 List<js.Name> names = _oneShotInterceptorData.oneShotInterceptorNames; |
930 return names.map((js.Name name) { | 965 return names.map((js.Name name) { |
931 js.Expression code = stubGenerator.generateOneShotInterceptor(name); | 966 js.Expression code = stubGenerator.generateOneShotInterceptor(name); |
932 return new StaticStubMethod(name, holder, code); | 967 return new StaticStubMethod(name, holder, code); |
933 }); | 968 }); |
934 } | 969 } |
935 | 970 |
936 StaticDartMethod _buildStaticMethod(MethodElement element) { | 971 StaticDartMethod _buildStaticMethod(MethodElement element) { |
937 js.Name name = namer.methodPropertyName(element); | 972 js.Name name = _namer.methodPropertyName(element); |
938 String holder = namer.globalObjectFor(element); | 973 String holder = _namer.globalObjectFor(element); |
939 js.Expression code = _backend.generatedCode[element]; | 974 js.Expression code = _backend.generatedCode[element]; |
940 | 975 |
941 bool isApplyTarget = !element.isConstructor && !element.isAccessor; | 976 bool isApplyTarget = !element.isConstructor && !element.isAccessor; |
942 bool canBeApplied = _methodCanBeApplied(element); | 977 bool canBeApplied = _methodCanBeApplied(element); |
943 bool canBeReflected = _methodCanBeReflected(element); | 978 bool canBeReflected = _methodCanBeReflected(element); |
944 | 979 |
945 bool needsTearOff = isApplyTarget && | 980 bool needsTearOff = isApplyTarget && |
946 (canBeReflected || | 981 (canBeReflected || |
947 _worldBuilder.staticFunctionsNeedingGetter.contains(element)); | 982 _worldBuilder.staticFunctionsNeedingGetter.contains(element)); |
948 | 983 |
949 js.Name tearOffName = | 984 js.Name tearOffName = |
950 needsTearOff ? namer.staticClosureName(element) : null; | 985 needsTearOff ? _namer.staticClosureName(element) : null; |
951 | 986 |
952 js.Name callName = null; | 987 js.Name callName = null; |
953 if (needsTearOff) { | 988 if (needsTearOff) { |
954 Selector callSelector = | 989 Selector callSelector = |
955 new Selector.fromElement(element).toCallSelector(); | 990 new Selector.fromElement(element).toCallSelector(); |
956 callName = namer.invocationName(callSelector); | 991 callName = _namer.invocationName(callSelector); |
957 } | 992 } |
958 js.Expression functionType; | 993 js.Expression functionType; |
959 ResolutionDartType type = element.type; | 994 ResolutionDartType type = element.type; |
960 if (needsTearOff || canBeReflected) { | 995 if (needsTearOff || canBeReflected) { |
961 OutputUnit outputUnit = _deferredLoadTask.outputUnitForElement(element); | 996 OutputUnit outputUnit = _deferredLoadTask.outputUnitForElement(element); |
962 functionType = _generateFunctionType(type, outputUnit); | 997 functionType = _generateFunctionType(type, outputUnit); |
963 } | 998 } |
964 | 999 |
965 int requiredParameterCount; | 1000 int requiredParameterCount; |
966 var /* List | Map */ optionalParameterDefaultValues; | 1001 var /* List | Map */ optionalParameterDefaultValues; |
(...skipping 17 matching lines...) Expand all Loading... |
984 functionType: functionType); | 1019 functionType: functionType); |
985 } | 1020 } |
986 | 1021 |
987 void _registerConstants( | 1022 void _registerConstants( |
988 OutputUnit outputUnit, Iterable<ConstantValue> constantValues) { | 1023 OutputUnit outputUnit, Iterable<ConstantValue> constantValues) { |
989 // `constantValues` is null if an outputUnit doesn't contain any constants. | 1024 // `constantValues` is null if an outputUnit doesn't contain any constants. |
990 if (constantValues == null) return; | 1025 if (constantValues == null) return; |
991 for (ConstantValue constantValue in constantValues) { | 1026 for (ConstantValue constantValue in constantValues) { |
992 _registry.registerConstant(outputUnit, constantValue); | 1027 _registry.registerConstant(outputUnit, constantValue); |
993 assert(!_constants.containsKey(constantValue)); | 1028 assert(!_constants.containsKey(constantValue)); |
994 js.Name name = namer.constantName(constantValue); | 1029 js.Name name = _namer.constantName(constantValue); |
995 String constantObject = namer.globalObjectForConstant(constantValue); | 1030 String constantObject = _namer.globalObjectForConstant(constantValue); |
996 Holder holder = | 1031 Holder holder = |
997 _registry.registerHolder(constantObject, isConstantsHolder: true); | 1032 _registry.registerHolder(constantObject, isConstantsHolder: true); |
998 Constant constant = new Constant(name, holder, constantValue); | 1033 Constant constant = new Constant(name, holder, constantValue); |
999 _constants[constantValue] = constant; | 1034 _constants[constantValue] = constant; |
1000 } | 1035 } |
1001 } | 1036 } |
1002 | 1037 |
1003 Holder _registerStaticStateHolder() { | 1038 Holder _registerStaticStateHolder() { |
1004 return _registry.registerHolder(namer.staticStateHolder, | 1039 return _registry.registerHolder(_namer.staticStateHolder, |
1005 isStaticStateHolder: true); | 1040 isStaticStateHolder: true); |
1006 } | 1041 } |
1007 } | 1042 } |
OLD | NEW |