| 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 |