| 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 12 matching lines...) Expand all Loading... |
| 23 FunctionElement, | 23 FunctionElement, |
| 24 FunctionSignature, | 24 FunctionSignature, |
| 25 GetterElement, | 25 GetterElement, |
| 26 LibraryElement, | 26 LibraryElement, |
| 27 MemberElement, | 27 MemberElement, |
| 28 MethodElement, | 28 MethodElement, |
| 29 ParameterElement, | 29 ParameterElement, |
| 30 TypedefElement, | 30 TypedefElement, |
| 31 VariableElement; | 31 VariableElement; |
| 32 import '../../elements/entities.dart'; | 32 import '../../elements/entities.dart'; |
| 33 import '../../elements/resolution_types.dart' show Types; |
| 33 import '../../elements/types.dart' show DartType; | 34 import '../../elements/types.dart' show DartType; |
| 34 import '../../js/js.dart' as js; | 35 import '../../js/js.dart' as js; |
| 35 import '../../js_backend/js_backend.dart' | 36 import '../../js_backend/backend.dart' |
| 36 show Namer, JavaScriptBackend, JavaScriptConstantCompiler, StringBackedName; | 37 show |
| 38 JavaScriptBackend, |
| 39 RuntimeTypesEncoder, |
| 40 RuntimeTypesNeed, |
| 41 SuperMemberData; |
| 42 import '../../js_backend/backend_usage.dart'; |
| 43 import '../../js_backend/constant_handler_javascript.dart' |
| 44 show JavaScriptConstantCompiler; |
| 45 import '../../js_backend/namer.dart' show Namer, StringBackedName; |
| 46 import '../../js_backend/native_data.dart'; |
| 47 import '../../js_backend/interceptor_data.dart'; |
| 48 import '../../js_backend/mirrors_data.dart'; |
| 49 import '../../native/enqueue.dart' show NativeCodegenEnqueuer; |
| 50 import '../../options.dart'; |
| 37 import '../../universe/selector.dart' show Selector; | 51 import '../../universe/selector.dart' show Selector; |
| 38 import '../../universe/world_builder.dart' | 52 import '../../universe/world_builder.dart' |
| 39 show CodegenWorldBuilder, SelectorConstraints; | 53 show CodegenWorldBuilder, SelectorConstraints; |
| 40 import '../../world.dart' show ClosedWorld; | 54 import '../../world.dart' show ClosedWorld; |
| 41 import '../js_emitter.dart' | 55 import '../js_emitter.dart' |
| 42 show | 56 show |
| 43 ClassStubGenerator, | 57 ClassStubGenerator, |
| 44 CodeEmitterTask, | 58 CodeEmitterTask, |
| 45 computeMixinClass, | 59 computeMixinClass, |
| 46 Emitter, | 60 Emitter, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 77 | 91 |
| 78 ProgramBuilder(Compiler compiler, Namer namer, this._task, Emitter emitter, | 92 ProgramBuilder(Compiler compiler, Namer namer, this._task, Emitter emitter, |
| 79 ClosedWorld closedWorld, Set<ClassElement> rtiNeededClasses) | 93 ClosedWorld closedWorld, Set<ClassElement> rtiNeededClasses) |
| 80 : this._compiler = compiler, | 94 : this._compiler = compiler, |
| 81 this.namer = namer, | 95 this.namer = namer, |
| 82 this.closedWorld = closedWorld, | 96 this.closedWorld = closedWorld, |
| 83 this.collector = new Collector( | 97 this.collector = new Collector( |
| 84 compiler, namer, closedWorld, rtiNeededClasses, emitter), | 98 compiler, namer, closedWorld, rtiNeededClasses, emitter), |
| 85 this._registry = new Registry(compiler); | 99 this._registry = new Registry(compiler); |
| 86 | 100 |
| 87 JavaScriptBackend get backend => _compiler.backend; | 101 JavaScriptBackend get _backend => _compiler.backend; |
| 88 CodegenWorldBuilder get worldBuilder => _compiler.codegenWorldBuilder; | 102 CodegenWorldBuilder get _worldBuilder => _compiler.codegenWorldBuilder; |
| 103 DeferredLoadTask get _deferredLoadTask => _compiler.deferredLoadTask; |
| 104 Types get _types => _compiler.types; |
| 105 CommonElements get _commonElements => _compiler.commonElements; |
| 106 CompilerOptions get _options => _compiler.options; |
| 107 NativeCodegenEnqueuer get _nativeCodegenEnqueuer => |
| 108 _backend.nativeCodegenEnqueuer; |
| 109 Namer get _namer => _backend.namer; |
| 110 BackendUsage get _backendUsage => _backend.backendUsage; |
| 111 CodeEmitterTask get _emitter => _backend.emitter; |
| 112 JavaScriptConstantCompiler get _constantHandler => _backend.constants; |
| 113 NativeData get _nativeData => _backend.nativeData; |
| 114 RuntimeTypesNeed get _rtiNeed => _backend.rtiNeed; |
| 115 MirrorsData get _mirrorsData => _backend.mirrorsData; |
| 116 InterceptorData get _interceptorData => _backend.interceptorData; |
| 117 SuperMemberData get _superMemberData => _backend.superMemberData; |
| 118 RuntimeTypesEncoder get _rtiEncoder => _backend.rtiEncoder; |
| 119 OneShotInterceptorData get _oneShotInterceptorData => |
| 120 _backend.oneShotInterceptorData; |
| 89 | 121 |
| 90 /// Mapping from [ClassElement] to constructed [Class]. We need this to | 122 /// Mapping from [ClassElement] to constructed [Class]. We need this to |
| 91 /// update the superclass in the [Class]. | 123 /// update the superclass in the [Class]. |
| 92 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; | 124 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; |
| 93 | 125 |
| 94 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to | 126 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to |
| 95 /// generate the deferredLoadingMap (to know which hunks to load). | 127 /// generate the deferredLoadingMap (to know which hunks to load). |
| 96 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; | 128 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; |
| 97 | 129 |
| 98 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to | 130 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to |
| 99 /// update field-initializers to point to the ConstantModel. | 131 /// update field-initializers to point to the ConstantModel. |
| 100 final Map<ConstantValue, Constant> _constants = <ConstantValue, Constant>{}; | 132 final Map<ConstantValue, Constant> _constants = <ConstantValue, Constant>{}; |
| 101 | 133 |
| 102 /// Mapping from names to strings. | 134 /// Mapping from names to strings. |
| 103 /// | 135 /// |
| 104 /// This mapping is used to support `const Symbol` expressions. | 136 /// This mapping is used to support `const Symbol` expressions. |
| 105 /// | 137 /// |
| 106 /// This map is filled when building classes. | 138 /// This map is filled when building classes. |
| 107 final Map<js.Name, String> _symbolsMap = <js.Name, String>{}; | 139 final Map<js.Name, String> _symbolsMap = <js.Name, String>{}; |
| 108 | 140 |
| 109 Set<Class> _unneededNativeClasses; | 141 Set<Class> _unneededNativeClasses; |
| 110 | 142 |
| 111 Program buildProgram({bool storeFunctionTypesInMetadata: false}) { | 143 Program buildProgram({bool storeFunctionTypesInMetadata: false}) { |
| 112 collector.collect(); | 144 collector.collect(); |
| 113 | 145 |
| 114 this._storeFunctionTypesInMetadata = storeFunctionTypesInMetadata; | 146 this._storeFunctionTypesInMetadata = storeFunctionTypesInMetadata; |
| 115 // Note: In rare cases (mostly tests) output units can be empty. This | 147 // Note: In rare cases (mostly tests) output units can be empty. This |
| 116 // happens when the deferred code is dead-code eliminated but we still need | 148 // happens when the deferred code is dead-code eliminated but we still need |
| 117 // to check that the library has been loaded. | 149 // to check that the library has been loaded. |
| 118 _compiler.deferredLoadTask.allOutputUnits | 150 _deferredLoadTask.allOutputUnits.forEach(_registry.registerOutputUnit); |
| 119 .forEach(_registry.registerOutputUnit); | |
| 120 collector.outputClassLists.forEach(_registry.registerElements); | 151 collector.outputClassLists.forEach(_registry.registerElements); |
| 121 collector.outputStaticLists.forEach(_registry.registerElements); | 152 collector.outputStaticLists.forEach(_registry.registerElements); |
| 122 collector.outputConstantLists.forEach(_registerConstants); | 153 collector.outputConstantLists.forEach(_registerConstants); |
| 123 collector.outputStaticNonFinalFieldLists | 154 collector.outputStaticNonFinalFieldLists |
| 124 .forEach(_registry.registerElements); | 155 .forEach(_registry.registerElements); |
| 125 | 156 |
| 126 // We always add the current isolate holder. | 157 // We always add the current isolate holder. |
| 127 _registerStaticStateHolder(); | 158 _registerStaticStateHolder(); |
| 128 | 159 |
| 129 // We need to run the native-preparation before we build the output. The | 160 // We need to run the native-preparation before we build the output. The |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 | 199 |
| 169 List<Fragment> fragments = new List<Fragment>(_registry.librariesMapCount); | 200 List<Fragment> fragments = new List<Fragment>(_registry.librariesMapCount); |
| 170 fragments[0] = mainFragment; | 201 fragments[0] = mainFragment; |
| 171 fragments.setAll(1, deferredFragments); | 202 fragments.setAll(1, deferredFragments); |
| 172 | 203 |
| 173 _markEagerClasses(); | 204 _markEagerClasses(); |
| 174 | 205 |
| 175 List<Holder> holders = _registry.holders.toList(growable: false); | 206 List<Holder> holders = _registry.holders.toList(growable: false); |
| 176 | 207 |
| 177 bool needsNativeSupport = | 208 bool needsNativeSupport = |
| 178 backend.nativeCodegenEnqueuer.hasInstantiatedNativeClasses; | 209 _nativeCodegenEnqueuer.hasInstantiatedNativeClasses; |
| 179 | 210 |
| 180 assert(!needsNativeSupport || nativeClasses.isNotEmpty); | 211 assert(!needsNativeSupport || nativeClasses.isNotEmpty); |
| 181 | 212 |
| 182 List<js.TokenFinalizer> finalizers = [_task.metadataCollector]; | 213 List<js.TokenFinalizer> finalizers = [_task.metadataCollector]; |
| 183 if (backend.namer is js.TokenFinalizer) { | 214 if (_namer is js.TokenFinalizer) { |
| 184 var namingFinalizer = backend.namer; | 215 var namingFinalizer = _namer; |
| 185 finalizers.add(namingFinalizer as js.TokenFinalizer); | 216 finalizers.add(namingFinalizer as js.TokenFinalizer); |
| 186 } | 217 } |
| 187 | 218 |
| 188 return new Program(fragments, holders, _buildLoadMap(), _symbolsMap, | 219 return new Program(fragments, holders, _buildLoadMap(), _symbolsMap, |
| 189 _buildTypeToInterceptorMap(), _task.metadataCollector, finalizers, | 220 _buildTypeToInterceptorMap(), _task.metadataCollector, finalizers, |
| 190 needsNativeSupport: needsNativeSupport, | 221 needsNativeSupport: needsNativeSupport, |
| 191 outputContainsConstantList: collector.outputContainsConstantList, | 222 outputContainsConstantList: collector.outputContainsConstantList, |
| 192 hasIsolateSupport: backend.backendUsage.isIsolateInUse); | 223 hasIsolateSupport: _backendUsage.isIsolateInUse); |
| 193 } | 224 } |
| 194 | 225 |
| 195 void _markEagerClasses() { | 226 void _markEagerClasses() { |
| 196 _markEagerInterceptorClasses(); | 227 _markEagerInterceptorClasses(); |
| 197 } | 228 } |
| 198 | 229 |
| 199 /// Builds a map from loadId to outputs-to-load. | 230 /// Builds a map from loadId to outputs-to-load. |
| 200 Map<String, List<Fragment>> _buildLoadMap() { | 231 Map<String, List<Fragment>> _buildLoadMap() { |
| 201 Map<String, List<Fragment>> loadMap = <String, List<Fragment>>{}; | 232 Map<String, List<Fragment>> loadMap = <String, List<Fragment>>{}; |
| 202 _compiler.deferredLoadTask.hunksToLoad | 233 _deferredLoadTask.hunksToLoad |
| 203 .forEach((String loadId, List<OutputUnit> outputUnits) { | 234 .forEach((String loadId, List<OutputUnit> outputUnits) { |
| 204 loadMap[loadId] = outputUnits | 235 loadMap[loadId] = outputUnits |
| 205 .map((OutputUnit unit) => _outputs[unit]) | 236 .map((OutputUnit unit) => _outputs[unit]) |
| 206 .toList(growable: false); | 237 .toList(growable: false); |
| 207 }); | 238 }); |
| 208 return loadMap; | 239 return loadMap; |
| 209 } | 240 } |
| 210 | 241 |
| 211 js.Expression _buildTypeToInterceptorMap() { | 242 js.Expression _buildTypeToInterceptorMap() { |
| 212 InterceptorStubGenerator stubGenerator = | 243 InterceptorStubGenerator stubGenerator = |
| 213 new InterceptorStubGenerator(_compiler, namer, backend, closedWorld); | 244 new InterceptorStubGenerator(_compiler, namer, _backend, closedWorld); |
| 214 return stubGenerator.generateTypeToInterceptorMap(); | 245 return stubGenerator.generateTypeToInterceptorMap(); |
| 215 } | 246 } |
| 216 | 247 |
| 217 MainFragment _buildMainFragment(LibrariesMap librariesMap) { | 248 MainFragment _buildMainFragment(LibrariesMap librariesMap) { |
| 218 // Construct the main output from the libraries and the registered holders. | 249 // Construct the main output from the libraries and the registered holders. |
| 219 MainFragment result = new MainFragment( | 250 MainFragment result = new MainFragment( |
| 220 librariesMap.outputUnit, | 251 librariesMap.outputUnit, |
| 221 "", // The empty string is the name for the main output file. | 252 "", // The empty string is the name for the main output file. |
| 222 _buildInvokeMain(), | 253 _buildInvokeMain(), |
| 223 _buildLibraries(librariesMap), | 254 _buildLibraries(librariesMap), |
| 224 _buildStaticNonFinalFields(librariesMap), | 255 _buildStaticNonFinalFields(librariesMap), |
| 225 _buildStaticLazilyInitializedFields(librariesMap), | 256 _buildStaticLazilyInitializedFields(librariesMap), |
| 226 _buildConstants(librariesMap)); | 257 _buildConstants(librariesMap)); |
| 227 _outputs[librariesMap.outputUnit] = result; | 258 _outputs[librariesMap.outputUnit] = result; |
| 228 return result; | 259 return result; |
| 229 } | 260 } |
| 230 | 261 |
| 231 js.Statement _buildInvokeMain() { | 262 js.Statement _buildInvokeMain() { |
| 232 if (_compiler.isMockCompilation) return js.js.comment("Mock compilation"); | 263 if (_compiler.isMockCompilation) return js.js.comment("Mock compilation"); |
| 233 | 264 |
| 234 MainCallStubGenerator generator = | 265 MainCallStubGenerator generator = |
| 235 new MainCallStubGenerator(backend, backend.emitter); | 266 new MainCallStubGenerator(_backend, _emitter); |
| 236 return generator.generateInvokeMain(_compiler.mainFunction); | 267 return generator.generateInvokeMain(_compiler.mainFunction); |
| 237 } | 268 } |
| 238 | 269 |
| 239 DeferredFragment _buildDeferredFragment(LibrariesMap librariesMap) { | 270 DeferredFragment _buildDeferredFragment(LibrariesMap librariesMap) { |
| 240 DeferredFragment result = new DeferredFragment( | 271 DeferredFragment result = new DeferredFragment( |
| 241 librariesMap.outputUnit, | 272 librariesMap.outputUnit, |
| 242 backend.deferredPartFileName(librariesMap.name, addExtension: false), | 273 _backend.deferredPartFileName(librariesMap.name, addExtension: false), |
| 243 librariesMap.name, | 274 librariesMap.name, |
| 244 _buildLibraries(librariesMap), | 275 _buildLibraries(librariesMap), |
| 245 _buildStaticNonFinalFields(librariesMap), | 276 _buildStaticNonFinalFields(librariesMap), |
| 246 _buildStaticLazilyInitializedFields(librariesMap), | 277 _buildStaticLazilyInitializedFields(librariesMap), |
| 247 _buildConstants(librariesMap)); | 278 _buildConstants(librariesMap)); |
| 248 _outputs[librariesMap.outputUnit] = result; | 279 _outputs[librariesMap.outputUnit] = result; |
| 249 return result; | 280 return result; |
| 250 } | 281 } |
| 251 | 282 |
| 252 List<Constant> _buildConstants(LibrariesMap librariesMap) { | 283 List<Constant> _buildConstants(LibrariesMap librariesMap) { |
| 253 List<ConstantValue> constantValues = | 284 List<ConstantValue> constantValues = |
| 254 collector.outputConstantLists[librariesMap.outputUnit]; | 285 collector.outputConstantLists[librariesMap.outputUnit]; |
| 255 if (constantValues == null) return const <Constant>[]; | 286 if (constantValues == null) return const <Constant>[]; |
| 256 return constantValues | 287 return constantValues |
| 257 .map((ConstantValue value) => _constants[value]) | 288 .map((ConstantValue value) => _constants[value]) |
| 258 .toList(growable: false); | 289 .toList(growable: false); |
| 259 } | 290 } |
| 260 | 291 |
| 261 List<StaticField> _buildStaticNonFinalFields(LibrariesMap librariesMap) { | 292 List<StaticField> _buildStaticNonFinalFields(LibrariesMap librariesMap) { |
| 262 List<VariableElement> staticNonFinalFields = | 293 List<VariableElement> staticNonFinalFields = |
| 263 collector.outputStaticNonFinalFieldLists[librariesMap.outputUnit]; | 294 collector.outputStaticNonFinalFieldLists[librariesMap.outputUnit]; |
| 264 if (staticNonFinalFields == null) return const <StaticField>[]; | 295 if (staticNonFinalFields == null) return const <StaticField>[]; |
| 265 | 296 |
| 266 return staticNonFinalFields.map(_buildStaticField).toList(growable: false); | 297 return staticNonFinalFields.map(_buildStaticField).toList(growable: false); |
| 267 } | 298 } |
| 268 | 299 |
| 269 StaticField _buildStaticField(FieldElement element) { | 300 StaticField _buildStaticField(FieldElement element) { |
| 270 JavaScriptConstantCompiler handler = backend.constants; | 301 ConstantValue initialValue = |
| 271 ConstantValue initialValue = handler.getConstantValue(element.constant); | 302 _constantHandler.getConstantValue(element.constant); |
| 272 // TODO(zarah): The holder should not be registered during building of | 303 // TODO(zarah): The holder should not be registered during building of |
| 273 // a static field. | 304 // a static field. |
| 274 _registry.registerHolder(namer.globalObjectForConstant(initialValue), | 305 _registry.registerHolder(namer.globalObjectForConstant(initialValue), |
| 275 isConstantsHolder: true); | 306 isConstantsHolder: true); |
| 276 js.Expression code = _task.emitter.constantReference(initialValue); | 307 js.Expression code = _task.emitter.constantReference(initialValue); |
| 277 js.Name name = namer.globalPropertyName(element); | 308 js.Name name = namer.globalPropertyName(element); |
| 278 bool isFinal = false; | 309 bool isFinal = false; |
| 279 bool isLazy = false; | 310 bool isLazy = false; |
| 280 | 311 |
| 281 // TODO(floitsch): we shouldn't update the registry in the middle of | 312 // TODO(floitsch): we shouldn't update the registry in the middle of |
| 282 // building a static field. (Note that the static-state holder was | 313 // building a static field. (Note that the static-state holder was |
| 283 // already registered earlier, and that we just call the register to get | 314 // already registered earlier, and that we just call the register to get |
| 284 // the holder-instance. | 315 // the holder-instance. |
| 285 return new StaticField( | 316 return new StaticField( |
| 286 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); | 317 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); |
| 287 } | 318 } |
| 288 | 319 |
| 289 List<StaticField> _buildStaticLazilyInitializedFields( | 320 List<StaticField> _buildStaticLazilyInitializedFields( |
| 290 LibrariesMap librariesMap) { | 321 LibrariesMap librariesMap) { |
| 291 JavaScriptConstantCompiler handler = backend.constants; | 322 Iterable<FieldElement> lazyFields = _constantHandler |
| 292 DeferredLoadTask loadTask = _compiler.deferredLoadTask; | |
| 293 Iterable<FieldElement> lazyFields = handler | |
| 294 .getLazilyInitializedFieldsForEmission() | 323 .getLazilyInitializedFieldsForEmission() |
| 295 .where((element) => | 324 .where((element) => |
| 296 loadTask.outputUnitForElement(element) == librariesMap.outputUnit); | 325 _deferredLoadTask.outputUnitForElement(element) == |
| 326 librariesMap.outputUnit); |
| 297 return Elements | 327 return Elements |
| 298 .sortedByPosition(lazyFields) | 328 .sortedByPosition(lazyFields) |
| 299 .map(_buildLazyField) | 329 .map(_buildLazyField) |
| 300 .where((field) => field != null) // Happens when the field was unused. | 330 .where((field) => field != null) // Happens when the field was unused. |
| 301 .toList(growable: false); | 331 .toList(growable: false); |
| 302 } | 332 } |
| 303 | 333 |
| 304 StaticField _buildLazyField(FieldElement element) { | 334 StaticField _buildLazyField(FieldElement element) { |
| 305 js.Expression code = backend.generatedCode[element]; | 335 js.Expression code = _backend.generatedCode[element]; |
| 306 // The code is null if we ended up not needing the lazily | 336 // The code is null if we ended up not needing the lazily |
| 307 // initialized field after all because of constant folding | 337 // initialized field after all because of constant folding |
| 308 // before code generation. | 338 // before code generation. |
| 309 if (code == null) return null; | 339 if (code == null) return null; |
| 310 | 340 |
| 311 js.Name name = namer.globalPropertyName(element); | 341 js.Name name = namer.globalPropertyName(element); |
| 312 bool isFinal = element.isFinal; | 342 bool isFinal = element.isFinal; |
| 313 bool isLazy = true; | 343 bool isLazy = true; |
| 314 // TODO(floitsch): we shouldn't update the registry in the middle of | 344 // TODO(floitsch): we shouldn't update the registry in the middle of |
| 315 // building a static field. (Note that the static-state holder was | 345 // building a static field. (Note that the static-state holder was |
| 316 // already registered earlier, and that we just call the register to get | 346 // already registered earlier, and that we just call the register to get |
| 317 // the holder-instance. | 347 // the holder-instance. |
| 318 return new StaticField( | 348 return new StaticField( |
| 319 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); | 349 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); |
| 320 } | 350 } |
| 321 | 351 |
| 322 List<Library> _buildLibraries(LibrariesMap librariesMap) { | 352 List<Library> _buildLibraries(LibrariesMap librariesMap) { |
| 323 List<Library> libraries = new List<Library>(librariesMap.length); | 353 List<Library> libraries = new List<Library>(librariesMap.length); |
| 324 int count = 0; | 354 int count = 0; |
| 325 librariesMap.forEach((LibraryElement library, List<Element> elements) { | 355 librariesMap.forEach((LibraryElement library, List<Element> elements) { |
| 326 libraries[count++] = _buildLibrary(library, elements); | 356 libraries[count++] = _buildLibrary(library, elements); |
| 327 }); | 357 }); |
| 328 return libraries; | 358 return libraries; |
| 329 } | 359 } |
| 330 | 360 |
| 331 void _addJsInteropStubs(LibrariesMap librariesMap) { | 361 void _addJsInteropStubs(LibrariesMap librariesMap) { |
| 332 if (_classes.containsKey(_compiler.commonElements.objectClass)) { | 362 if (_classes.containsKey(_commonElements.objectClass)) { |
| 333 var toStringInvocation = namer.invocationName(Selectors.toString_); | 363 var toStringInvocation = namer.invocationName(Selectors.toString_); |
| 334 // TODO(jacobr): register toString as used so that it is always accessible | 364 // TODO(jacobr): register toString as used so that it is always accessible |
| 335 // from JavaScript. | 365 // from JavaScript. |
| 336 _classes[_compiler.commonElements.objectClass].callStubs.add( | 366 _classes[_commonElements.objectClass].callStubs.add(_buildStubMethod( |
| 337 _buildStubMethod(new StringBackedName("toString"), | 367 new StringBackedName("toString"), |
| 338 js.js('function() { return this.#(this) }', toStringInvocation))); | 368 js.js('function() { return this.#(this) }', toStringInvocation))); |
| 339 } | 369 } |
| 340 | 370 |
| 341 // We add all members from classes marked with isJsInterop to the base | 371 // We add all members from classes marked with isJsInterop to the base |
| 342 // Interceptor class with implementations that directly call the | 372 // Interceptor class with implementations that directly call the |
| 343 // corresponding JavaScript member. We do not attempt to bind this when | 373 // corresponding JavaScript member. We do not attempt to bind this when |
| 344 // tearing off JavaScript methods as we cannot distinguish between calling | 374 // tearing off JavaScript methods as we cannot distinguish between calling |
| 345 // a regular getter that returns a JavaScript function and tearing off | 375 // a regular getter that returns a JavaScript function and tearing off |
| 346 // a method in the case where there exist multiple JavaScript classes | 376 // a method in the case where there exist multiple JavaScript classes |
| 347 // that conflict on whether the member is a getter or a method. | 377 // that conflict on whether the member is a getter or a method. |
| 348 var interceptorClass = | 378 var interceptorClass = _classes[_commonElements.jsJavaScriptObjectClass]; |
| 349 _classes[_compiler.commonElements.jsJavaScriptObjectClass]; | |
| 350 var stubNames = new Set<String>(); | 379 var stubNames = new Set<String>(); |
| 351 librariesMap.forEach((LibraryElement library, List<Element> elements) { | 380 librariesMap.forEach((LibraryElement library, List<Element> elements) { |
| 352 for (Element e in elements) { | 381 for (Element e in elements) { |
| 353 if (e is ClassElement && backend.nativeData.isJsInteropClass(e)) { | 382 if (e is ClassElement && _nativeData.isJsInteropClass(e)) { |
| 354 e.declaration.forEachMember((_, Element member) { | 383 e.declaration.forEachMember((_, Element member) { |
| 355 var jsName = | 384 var jsName = _nativeData.computeUnescapedJSInteropName(member.name); |
| 356 backend.nativeData.computeUnescapedJSInteropName(member.name); | |
| 357 if (!member.isInstanceMember) return; | 385 if (!member.isInstanceMember) return; |
| 358 if (member.isGetter || member.isField || member.isFunction) { | 386 if (member.isGetter || member.isField || member.isFunction) { |
| 359 var selectors = worldBuilder.getterInvocationsByName(member.name); | 387 var selectors = |
| 388 _worldBuilder.getterInvocationsByName(member.name); |
| 360 if (selectors != null && !selectors.isEmpty) { | 389 if (selectors != null && !selectors.isEmpty) { |
| 361 for (var selector in selectors.keys) { | 390 for (var selector in selectors.keys) { |
| 362 var stubName = namer.invocationName(selector); | 391 var stubName = namer.invocationName(selector); |
| 363 if (stubNames.add(stubName.key)) { | 392 if (stubNames.add(stubName.key)) { |
| 364 interceptorClass.callStubs.add(_buildStubMethod(stubName, | 393 interceptorClass.callStubs.add(_buildStubMethod(stubName, |
| 365 js.js('function(obj) { return obj.# }', [jsName]), | 394 js.js('function(obj) { return obj.# }', [jsName]), |
| 366 element: member)); | 395 element: member)); |
| 367 } | 396 } |
| 368 } | 397 } |
| 369 } | 398 } |
| 370 } | 399 } |
| 371 | 400 |
| 372 if (member.isSetter || (member.isField && !member.isConst)) { | 401 if (member.isSetter || (member.isField && !member.isConst)) { |
| 373 var selectors = worldBuilder.setterInvocationsByName(member.name); | 402 var selectors = |
| 403 _worldBuilder.setterInvocationsByName(member.name); |
| 374 if (selectors != null && !selectors.isEmpty) { | 404 if (selectors != null && !selectors.isEmpty) { |
| 375 var stubName = namer.setterForElement(member); | 405 var stubName = namer.setterForElement(member); |
| 376 if (stubNames.add(stubName.key)) { | 406 if (stubNames.add(stubName.key)) { |
| 377 interceptorClass.callStubs.add(_buildStubMethod(stubName, | 407 interceptorClass.callStubs.add(_buildStubMethod(stubName, |
| 378 js.js('function(obj, v) { return obj.# = v }', [jsName]), | 408 js.js('function(obj, v) { return obj.# = v }', [jsName]), |
| 379 element: member)); | 409 element: member)); |
| 380 } | 410 } |
| 381 } | 411 } |
| 382 } | 412 } |
| 383 | 413 |
| 384 // Generating stubs for direct calls and stubs for call-through | 414 // Generating stubs for direct calls and stubs for call-through |
| 385 // of getters that happen to be functions. | 415 // of getters that happen to be functions. |
| 386 bool isFunctionLike = false; | 416 bool isFunctionLike = false; |
| 387 ResolutionFunctionType functionType = null; | 417 ResolutionFunctionType functionType = null; |
| 388 | 418 |
| 389 if (member.isFunction) { | 419 if (member.isFunction) { |
| 390 FunctionElement fn = member; | 420 FunctionElement fn = member; |
| 391 functionType = fn.type; | 421 functionType = fn.type; |
| 392 } else if (member.isGetter) { | 422 } else if (member.isGetter) { |
| 393 if (_compiler.options.trustTypeAnnotations) { | 423 if (_options.trustTypeAnnotations) { |
| 394 GetterElement getter = member; | 424 GetterElement getter = member; |
| 395 ResolutionDartType returnType = getter.type.returnType; | 425 ResolutionDartType returnType = getter.type.returnType; |
| 396 if (returnType.isFunctionType) { | 426 if (returnType.isFunctionType) { |
| 397 functionType = returnType; | 427 functionType = returnType; |
| 398 } else if (returnType.treatAsDynamic || | 428 } else if (returnType.treatAsDynamic || |
| 399 _compiler.types.isSubtype( | 429 _types.isSubtype( |
| 400 returnType, | 430 returnType, |
| 401 // ignore: UNNECESSARY_CAST | 431 // ignore: UNNECESSARY_CAST |
| 402 backend.commonElements.functionType as DartType)) { | 432 _commonElements.functionType as DartType)) { |
| 403 if (returnType.isTypedef) { | 433 if (returnType.isTypedef) { |
| 404 ResolutionTypedefType typedef = returnType; | 434 ResolutionTypedefType typedef = returnType; |
| 405 // TODO(jacobr): can we just use typdef.unaliased instead? | 435 // TODO(jacobr): can we just use typdef.unaliased instead? |
| 406 functionType = typedef.element.functionSignature.type; | 436 functionType = typedef.element.functionSignature.type; |
| 407 } else { | 437 } else { |
| 408 // Other misc function type such as commonElements.Function. | 438 // Other misc function type such as commonElements.Function. |
| 409 // Allow any number of arguments. | 439 // Allow any number of arguments. |
| 410 isFunctionLike = true; | 440 isFunctionLike = true; |
| 411 } | 441 } |
| 412 } | 442 } |
| 413 } else { | 443 } else { |
| 414 isFunctionLike = true; | 444 isFunctionLike = true; |
| 415 } | 445 } |
| 416 } // TODO(jacobr): handle field elements. | 446 } // TODO(jacobr): handle field elements. |
| 417 | 447 |
| 418 if (isFunctionLike || functionType != null) { | 448 if (isFunctionLike || functionType != null) { |
| 419 int minArgs; | 449 int minArgs; |
| 420 int maxArgs; | 450 int maxArgs; |
| 421 if (functionType != null) { | 451 if (functionType != null) { |
| 422 minArgs = functionType.parameterTypes.length; | 452 minArgs = functionType.parameterTypes.length; |
| 423 maxArgs = minArgs + functionType.optionalParameterTypes.length; | 453 maxArgs = minArgs + functionType.optionalParameterTypes.length; |
| 424 } else { | 454 } else { |
| 425 minArgs = 0; | 455 minArgs = 0; |
| 426 maxArgs = 32767; | 456 maxArgs = 32767; |
| 427 } | 457 } |
| 428 var selectors = worldBuilder.invocationsByName(member.name); | 458 var selectors = _worldBuilder.invocationsByName(member.name); |
| 429 // Named arguments are not yet supported. In the future we | 459 // Named arguments are not yet supported. In the future we |
| 430 // may want to map named arguments to an object literal containing | 460 // may want to map named arguments to an object literal containing |
| 431 // all named arguments. | 461 // all named arguments. |
| 432 if (selectors != null && !selectors.isEmpty) { | 462 if (selectors != null && !selectors.isEmpty) { |
| 433 for (var selector in selectors.keys) { | 463 for (var selector in selectors.keys) { |
| 434 // Check whether the arity matches this member. | 464 // Check whether the arity matches this member. |
| 435 var argumentCount = selector.argumentCount; | 465 var argumentCount = selector.argumentCount; |
| 436 // JS interop does not support named arguments. | 466 // JS interop does not support named arguments. |
| 437 if (selector.namedArgumentCount > 0) continue; | 467 if (selector.namedArgumentCount > 0) continue; |
| 438 if (argumentCount < minArgs) continue; | 468 if (argumentCount < minArgs) continue; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 467 // Note that a library-element may have multiple [Library]s, if it is split | 497 // Note that a library-element may have multiple [Library]s, if it is split |
| 468 // into multiple output units. | 498 // into multiple output units. |
| 469 Library _buildLibrary(LibraryElement library, List<Element> elements) { | 499 Library _buildLibrary(LibraryElement library, List<Element> elements) { |
| 470 String uri = library.canonicalUri.toString(); | 500 String uri = library.canonicalUri.toString(); |
| 471 | 501 |
| 472 List<StaticMethod> statics = elements | 502 List<StaticMethod> statics = elements |
| 473 .where((e) => e is FunctionElement) | 503 .where((e) => e is FunctionElement) |
| 474 .map(_buildStaticMethod) | 504 .map(_buildStaticMethod) |
| 475 .toList(); | 505 .toList(); |
| 476 | 506 |
| 477 if (library == _compiler.commonElements.interceptorsLibrary) { | 507 if (library == _commonElements.interceptorsLibrary) { |
| 478 statics.addAll(_generateGetInterceptorMethods()); | 508 statics.addAll(_generateGetInterceptorMethods()); |
| 479 statics.addAll(_generateOneShotInterceptors()); | 509 statics.addAll(_generateOneShotInterceptors()); |
| 480 } | 510 } |
| 481 | 511 |
| 482 List<Class> classes = elements | 512 List<Class> classes = elements |
| 483 .where((e) => e is ClassElement) | 513 .where((e) => e is ClassElement) |
| 484 .map((ClassElement classElement) => _classes[classElement]) | 514 .map((ClassElement classElement) => _classes[classElement]) |
| 485 .where((Class cls) => | 515 .where((Class cls) => |
| 486 !cls.isNative || !_unneededNativeClasses.contains(cls)) | 516 !cls.isNative || !_unneededNativeClasses.contains(cls)) |
| 487 .toList(growable: false); | 517 .toList(growable: false); |
| 488 | 518 |
| 489 bool visitStatics = true; | 519 bool visitStatics = true; |
| 490 List<Field> staticFieldsForReflection = | 520 List<Field> staticFieldsForReflection = |
| 491 _buildFields(library, visitStatics: visitStatics); | 521 _buildFields(library, visitStatics: visitStatics); |
| 492 | 522 |
| 493 return new Library( | 523 return new Library( |
| 494 library, uri, statics, classes, staticFieldsForReflection); | 524 library, uri, statics, classes, staticFieldsForReflection); |
| 495 } | 525 } |
| 496 | 526 |
| 497 Class _buildClass(ClassElement element) { | 527 Class _buildClass(ClassElement element) { |
| 498 bool onlyForRti = collector.classesOnlyNeededForRti.contains(element); | 528 bool onlyForRti = collector.classesOnlyNeededForRti.contains(element); |
| 499 bool hasRtiField = backend.rtiNeed.classNeedsRtiField(element); | 529 bool hasRtiField = _rtiNeed.classNeedsRtiField(element); |
| 500 if (backend.nativeData.isJsInteropClass(element)) { | 530 if (_nativeData.isJsInteropClass(element)) { |
| 501 // TODO(jacobr): check whether the class has any active static fields | 531 // TODO(jacobr): check whether the class has any active static fields |
| 502 // if it does not we can suppress it completely. | 532 // if it does not we can suppress it completely. |
| 503 onlyForRti = true; | 533 onlyForRti = true; |
| 504 } | 534 } |
| 505 | 535 |
| 506 List<Method> methods = []; | 536 List<Method> methods = []; |
| 507 List<StubMethod> callStubs = <StubMethod>[]; | 537 List<StubMethod> callStubs = <StubMethod>[]; |
| 508 | 538 |
| 509 ClassStubGenerator classStubGenerator = new ClassStubGenerator( | 539 ClassStubGenerator classStubGenerator = new ClassStubGenerator( |
| 510 namer, backend, worldBuilder, closedWorld, | 540 namer, _backend, _worldBuilder, closedWorld, |
| 511 enableMinification: _compiler.options.enableMinification); | 541 enableMinification: _options.enableMinification); |
| 512 RuntimeTypeGenerator runtimeTypeGenerator = | 542 RuntimeTypeGenerator runtimeTypeGenerator = |
| 513 new RuntimeTypeGenerator(_compiler, _task, namer); | 543 new RuntimeTypeGenerator(_compiler, _task, namer); |
| 514 | 544 |
| 515 void visitMember(ClassElement enclosing, MemberElement member) { | 545 void visitMember(ClassElement enclosing, MemberElement member) { |
| 516 assert(invariant(element, member.isDeclaration)); | 546 assert(invariant(element, member.isDeclaration)); |
| 517 assert(invariant(element, element == enclosing)); | 547 assert(invariant(element, element == enclosing)); |
| 518 | 548 |
| 519 if (Elements.isNonAbstractInstanceMember(member)) { | 549 if (Elements.isNonAbstractInstanceMember(member)) { |
| 520 // TODO(herhut): Remove once _buildMethod can no longer return null. | 550 // TODO(herhut): Remove once _buildMethod can no longer return null. |
| 521 Method method = _buildMethod(member); | 551 Method method = _buildMethod(member); |
| 522 if (method != null) methods.add(method); | 552 if (method != null) methods.add(method); |
| 523 } | 553 } |
| 524 if (member.isGetter || member.isField) { | 554 if (member.isGetter || member.isField) { |
| 525 Map<Selector, SelectorConstraints> selectors = | 555 Map<Selector, SelectorConstraints> selectors = |
| 526 worldBuilder.invocationsByName(member.name); | 556 _worldBuilder.invocationsByName(member.name); |
| 527 if (selectors != null && !selectors.isEmpty) { | 557 if (selectors != null && !selectors.isEmpty) { |
| 528 Map<js.Name, js.Expression> callStubsForMember = | 558 Map<js.Name, js.Expression> callStubsForMember = |
| 529 classStubGenerator.generateCallStubsForGetter(member, selectors); | 559 classStubGenerator.generateCallStubsForGetter(member, selectors); |
| 530 callStubsForMember.forEach((js.Name name, js.Expression code) { | 560 callStubsForMember.forEach((js.Name name, js.Expression code) { |
| 531 callStubs.add(_buildStubMethod(name, code, element: member)); | 561 callStubs.add(_buildStubMethod(name, code, element: member)); |
| 532 }); | 562 }); |
| 533 } | 563 } |
| 534 } | 564 } |
| 535 } | 565 } |
| 536 | 566 |
| 537 List<StubMethod> noSuchMethodStubs = <StubMethod>[]; | 567 List<StubMethod> noSuchMethodStubs = <StubMethod>[]; |
| 538 | 568 |
| 539 if (backend.backendUsage.isNoSuchMethodUsed && element.isObject) { | 569 if (_backendUsage.isNoSuchMethodUsed && element.isObject) { |
| 540 Map<js.Name, Selector> selectors = | 570 Map<js.Name, Selector> selectors = |
| 541 classStubGenerator.computeSelectorsForNsmHandlers(); | 571 classStubGenerator.computeSelectorsForNsmHandlers(); |
| 542 selectors.forEach((js.Name name, Selector selector) { | 572 selectors.forEach((js.Name name, Selector selector) { |
| 543 // If the program contains `const Symbol` names we have to retain them. | 573 // If the program contains `const Symbol` names we have to retain them. |
| 544 String selectorName = selector.name; | 574 String selectorName = selector.name; |
| 545 if (selector.isSetter) selectorName = "$selectorName="; | 575 if (selector.isSetter) selectorName = "$selectorName="; |
| 546 if (backend.mirrorsData.symbolsUsed.contains(selectorName)) { | 576 if (_mirrorsData.symbolsUsed.contains(selectorName)) { |
| 547 _symbolsMap[name] = selectorName; | 577 _symbolsMap[name] = selectorName; |
| 548 } | 578 } |
| 549 noSuchMethodStubs.add( | 579 noSuchMethodStubs.add( |
| 550 classStubGenerator.generateStubForNoSuchMethod(name, selector)); | 580 classStubGenerator.generateStubForNoSuchMethod(name, selector)); |
| 551 }); | 581 }); |
| 552 } | 582 } |
| 553 | 583 |
| 554 if (element == _compiler.commonElements.closureClass) { | 584 if (element == _commonElements.closureClass) { |
| 555 // We add a special getter here to allow for tearing off a closure from | 585 // We add a special getter here to allow for tearing off a closure from |
| 556 // itself. | 586 // itself. |
| 557 js.Name name = namer.getterForMember(Names.call); | 587 js.Name name = namer.getterForMember(Names.call); |
| 558 js.Fun function = js.js('function() { return this; }'); | 588 js.Fun function = js.js('function() { return this; }'); |
| 559 callStubs.add(_buildStubMethod(name, function)); | 589 callStubs.add(_buildStubMethod(name, function)); |
| 560 } | 590 } |
| 561 | 591 |
| 562 ClassElement implementation = element.implementation; | 592 ClassElement implementation = element.implementation; |
| 563 | 593 |
| 564 // MixinApplications run through the members of their mixin. Here, we are | 594 // MixinApplications run through the members of their mixin. Here, we are |
| 565 // only interested in direct members. | 595 // only interested in direct members. |
| 566 if (!onlyForRti && !element.isMixinApplication) { | 596 if (!onlyForRti && !element.isMixinApplication) { |
| 567 implementation.forEachMember(visitMember, includeBackendMembers: true); | 597 implementation.forEachMember(visitMember, includeBackendMembers: true); |
| 568 } | 598 } |
| 569 bool isInterceptedClass = | 599 bool isInterceptedClass = _interceptorData.isInterceptedClass(element); |
| 570 backend.interceptorData.isInterceptedClass(element); | |
| 571 List<Field> instanceFields = onlyForRti | 600 List<Field> instanceFields = onlyForRti |
| 572 ? const <Field>[] | 601 ? const <Field>[] |
| 573 : _buildFields(element, | 602 : _buildFields(element, |
| 574 visitStatics: false, isHolderInterceptedClass: isInterceptedClass); | 603 visitStatics: false, isHolderInterceptedClass: isInterceptedClass); |
| 575 List<Field> staticFieldsForReflection = onlyForRti | 604 List<Field> staticFieldsForReflection = onlyForRti |
| 576 ? const <Field>[] | 605 ? const <Field>[] |
| 577 : _buildFields(element, | 606 : _buildFields(element, |
| 578 visitStatics: true, isHolderInterceptedClass: isInterceptedClass); | 607 visitStatics: true, isHolderInterceptedClass: isInterceptedClass); |
| 579 | 608 |
| 580 TypeTestProperties typeTests = runtimeTypeGenerator.generateIsTests(element, | 609 TypeTestProperties typeTests = runtimeTypeGenerator.generateIsTests(element, |
| 581 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata); | 610 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata); |
| 582 | 611 |
| 583 List<StubMethod> checkedSetters = <StubMethod>[]; | 612 List<StubMethod> checkedSetters = <StubMethod>[]; |
| 584 List<StubMethod> isChecks = <StubMethod>[]; | 613 List<StubMethod> isChecks = <StubMethod>[]; |
| 585 if (backend.nativeData.isJsInteropClass(element)) { | 614 if (_nativeData.isJsInteropClass(element)) { |
| 586 typeTests.properties.forEach((js.Name name, js.Node code) { | 615 typeTests.properties.forEach((js.Name name, js.Node code) { |
| 587 _classes[_compiler.commonElements.jsInterceptorClass] | 616 _classes[_commonElements.jsInterceptorClass] |
| 588 .isChecks | 617 .isChecks |
| 589 .add(_buildStubMethod(name, code)); | 618 .add(_buildStubMethod(name, code)); |
| 590 }); | 619 }); |
| 591 } else { | 620 } else { |
| 592 for (Field field in instanceFields) { | 621 for (Field field in instanceFields) { |
| 593 if (field.needsCheckedSetter) { | 622 if (field.needsCheckedSetter) { |
| 594 assert(!field.needsUncheckedSetter); | 623 assert(!field.needsUncheckedSetter); |
| 595 FieldElement element = field.element; | 624 FieldElement element = field.element; |
| 596 js.Expression code = backend.generatedCode[element]; | 625 js.Expression code = _backend.generatedCode[element]; |
| 597 assert(code != null); | 626 assert(code != null); |
| 598 js.Name name = namer.deriveSetterName(field.accessorName); | 627 js.Name name = namer.deriveSetterName(field.accessorName); |
| 599 checkedSetters.add(_buildStubMethod(name, code, element: element)); | 628 checkedSetters.add(_buildStubMethod(name, code, element: element)); |
| 600 } | 629 } |
| 601 } | 630 } |
| 602 | 631 |
| 603 typeTests.properties.forEach((js.Name name, js.Node code) { | 632 typeTests.properties.forEach((js.Name name, js.Node code) { |
| 604 isChecks.add(_buildStubMethod(name, code)); | 633 isChecks.add(_buildStubMethod(name, code)); |
| 605 }); | 634 }); |
| 606 } | 635 } |
| 607 | 636 |
| 608 js.Name name = namer.className(element); | 637 js.Name name = namer.className(element); |
| 609 String holderName = namer.globalObjectFor(element); | 638 String holderName = namer.globalObjectFor(element); |
| 610 // TODO(floitsch): we shouldn't update the registry in the middle of | 639 // TODO(floitsch): we shouldn't update the registry in the middle of |
| 611 // building a class. | 640 // building a class. |
| 612 Holder holder = _registry.registerHolder(holderName); | 641 Holder holder = _registry.registerHolder(holderName); |
| 613 bool isInstantiated = !backend.nativeData.isJsInteropClass(element) && | 642 bool isInstantiated = !_nativeData.isJsInteropClass(element) && |
| 614 worldBuilder.directlyInstantiatedClasses.contains(element); | 643 _worldBuilder.directlyInstantiatedClasses.contains(element); |
| 615 | 644 |
| 616 Class result; | 645 Class result; |
| 617 if (element.isMixinApplication && !onlyForRti) { | 646 if (element.isMixinApplication && !onlyForRti) { |
| 618 assert(!backend.nativeData.isNativeClass(element)); | 647 assert(!_nativeData.isNativeClass(element)); |
| 619 assert(methods.isEmpty); | 648 assert(methods.isEmpty); |
| 620 | 649 |
| 621 result = new MixinApplication( | 650 result = new MixinApplication( |
| 622 element, | 651 element, |
| 623 name, | 652 name, |
| 624 holder, | 653 holder, |
| 625 instanceFields, | 654 instanceFields, |
| 626 staticFieldsForReflection, | 655 staticFieldsForReflection, |
| 627 callStubs, | 656 callStubs, |
| 628 checkedSetters, | 657 checkedSetters, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 640 instanceFields, | 669 instanceFields, |
| 641 staticFieldsForReflection, | 670 staticFieldsForReflection, |
| 642 callStubs, | 671 callStubs, |
| 643 noSuchMethodStubs, | 672 noSuchMethodStubs, |
| 644 checkedSetters, | 673 checkedSetters, |
| 645 isChecks, | 674 isChecks, |
| 646 typeTests.functionTypeIndex, | 675 typeTests.functionTypeIndex, |
| 647 isDirectlyInstantiated: isInstantiated, | 676 isDirectlyInstantiated: isInstantiated, |
| 648 hasRtiField: hasRtiField, | 677 hasRtiField: hasRtiField, |
| 649 onlyForRti: onlyForRti, | 678 onlyForRti: onlyForRti, |
| 650 isNative: backend.nativeData.isNativeClass(element)); | 679 isNative: _nativeData.isNativeClass(element)); |
| 651 } | 680 } |
| 652 _classes[element] = result; | 681 _classes[element] = result; |
| 653 return result; | 682 return result; |
| 654 } | 683 } |
| 655 | 684 |
| 656 bool _methodNeedsStubs(FunctionElement method) { | 685 bool _methodNeedsStubs(FunctionElement method) { |
| 657 return !method.functionSignature.optionalParameters.isEmpty; | 686 return !method.functionSignature.optionalParameters.isEmpty; |
| 658 } | 687 } |
| 659 | 688 |
| 660 bool _methodCanBeReflected(MethodElement method) { | 689 bool _methodCanBeReflected(MethodElement method) { |
| 661 return backend.mirrorsData.isMemberAccessibleByReflection(method); | 690 return _mirrorsData.isMemberAccessibleByReflection(method); |
| 662 } | 691 } |
| 663 | 692 |
| 664 bool _methodCanBeApplied(FunctionElement method) { | 693 bool _methodCanBeApplied(FunctionElement method) { |
| 665 return backend.backendUsage.isFunctionApplyUsed && | 694 return _backendUsage.isFunctionApplyUsed && |
| 666 closedWorld.getMightBePassedToApply(method); | 695 closedWorld.getMightBePassedToApply(method); |
| 667 } | 696 } |
| 668 | 697 |
| 669 /* Map | List */ _computeParameterDefaultValues(FunctionSignature signature) { | 698 /* Map | List */ _computeParameterDefaultValues(FunctionSignature signature) { |
| 670 var /* Map | List */ optionalParameterDefaultValues; | 699 var /* Map | List */ optionalParameterDefaultValues; |
| 671 if (signature.optionalParametersAreNamed) { | 700 if (signature.optionalParametersAreNamed) { |
| 672 optionalParameterDefaultValues = new Map<String, ConstantValue>(); | 701 optionalParameterDefaultValues = new Map<String, ConstantValue>(); |
| 673 signature.forEachOptionalParameter((ParameterElement parameter) { | 702 signature.forEachOptionalParameter((ParameterElement parameter) { |
| 674 ConstantValue def = | 703 ConstantValue def = |
| 675 backend.constants.getConstantValue(parameter.constant); | 704 _constantHandler.getConstantValue(parameter.constant); |
| 676 optionalParameterDefaultValues[parameter.name] = def; | 705 optionalParameterDefaultValues[parameter.name] = def; |
| 677 }); | 706 }); |
| 678 } else { | 707 } else { |
| 679 optionalParameterDefaultValues = <ConstantValue>[]; | 708 optionalParameterDefaultValues = <ConstantValue>[]; |
| 680 signature.forEachOptionalParameter((ParameterElement parameter) { | 709 signature.forEachOptionalParameter((ParameterElement parameter) { |
| 681 ConstantValue def = | 710 ConstantValue def = |
| 682 backend.constants.getConstantValue(parameter.constant); | 711 _constantHandler.getConstantValue(parameter.constant); |
| 683 optionalParameterDefaultValues.add(def); | 712 optionalParameterDefaultValues.add(def); |
| 684 }); | 713 }); |
| 685 } | 714 } |
| 686 return optionalParameterDefaultValues; | 715 return optionalParameterDefaultValues; |
| 687 } | 716 } |
| 688 | 717 |
| 689 DartMethod _buildMethod(MethodElement element) { | 718 DartMethod _buildMethod(MethodElement element) { |
| 690 assert(element.isDeclaration); | 719 assert(element.isDeclaration); |
| 691 js.Name name = namer.methodPropertyName(element); | 720 js.Name name = namer.methodPropertyName(element); |
| 692 js.Expression code = backend.generatedCode[element]; | 721 js.Expression code = _backend.generatedCode[element]; |
| 693 | 722 |
| 694 // TODO(kasperl): Figure out under which conditions code is null. | 723 // TODO(kasperl): Figure out under which conditions code is null. |
| 695 if (code == null) return null; | 724 if (code == null) return null; |
| 696 | 725 |
| 697 bool canTearOff = false; | 726 bool canTearOff = false; |
| 698 js.Name tearOffName; | 727 js.Name tearOffName; |
| 699 bool isClosureCallMethod = false; | 728 bool isClosureCallMethod = false; |
| 700 bool isNotApplyTarget = !element.isFunction || element.isAccessor; | 729 bool isNotApplyTarget = !element.isFunction || element.isAccessor; |
| 701 | 730 |
| 702 bool canBeReflected = _methodCanBeReflected(element); | 731 bool canBeReflected = _methodCanBeReflected(element); |
| 703 bool canBeApplied = _methodCanBeApplied(element); | 732 bool canBeApplied = _methodCanBeApplied(element); |
| 704 | 733 |
| 705 js.Name aliasName = backend.superMemberData.isAliasedSuperMember(element) | 734 js.Name aliasName = _superMemberData.isAliasedSuperMember(element) |
| 706 ? namer.aliasedSuperMemberPropertyName(element) | 735 ? namer.aliasedSuperMemberPropertyName(element) |
| 707 : null; | 736 : null; |
| 708 | 737 |
| 709 if (isNotApplyTarget) { | 738 if (isNotApplyTarget) { |
| 710 canTearOff = false; | 739 canTearOff = false; |
| 711 } else { | 740 } else { |
| 712 if (element.enclosingClass.isClosure) { | 741 if (element.enclosingClass.isClosure) { |
| 713 canTearOff = false; | 742 canTearOff = false; |
| 714 isClosureCallMethod = true; | 743 isClosureCallMethod = true; |
| 715 } else { | 744 } else { |
| 716 // Careful with operators. | 745 // Careful with operators. |
| 717 canTearOff = worldBuilder.hasInvokedGetter(element, closedWorld) || | 746 canTearOff = _worldBuilder.hasInvokedGetter(element, closedWorld) || |
| 718 (canBeReflected && !element.isOperator); | 747 (canBeReflected && !element.isOperator); |
| 719 assert(canTearOff || | 748 assert(canTearOff || |
| 720 !worldBuilder.methodsNeedingSuperGetter.contains(element)); | 749 !_worldBuilder.methodsNeedingSuperGetter.contains(element)); |
| 721 tearOffName = namer.getterForElement(element); | 750 tearOffName = namer.getterForElement(element); |
| 722 } | 751 } |
| 723 } | 752 } |
| 724 | 753 |
| 725 if (canTearOff) { | 754 if (canTearOff) { |
| 726 assert(invariant(element, !element.isGenerativeConstructor)); | 755 assert(invariant(element, !element.isGenerativeConstructor)); |
| 727 assert(invariant(element, !element.isGenerativeConstructorBody)); | 756 assert(invariant(element, !element.isGenerativeConstructorBody)); |
| 728 assert(invariant(element, !element.isConstructor)); | 757 assert(invariant(element, !element.isConstructor)); |
| 729 } | 758 } |
| 730 | 759 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 741 // this information anyway as they cannot be torn off or | 770 // this information anyway as they cannot be torn off or |
| 742 // reflected. | 771 // reflected. |
| 743 var body = element; | 772 var body = element; |
| 744 memberType = body.constructor.type; | 773 memberType = body.constructor.type; |
| 745 } else { | 774 } else { |
| 746 memberType = element.type; | 775 memberType = element.type; |
| 747 } | 776 } |
| 748 | 777 |
| 749 js.Expression functionType; | 778 js.Expression functionType; |
| 750 if (canTearOff || canBeReflected) { | 779 if (canTearOff || canBeReflected) { |
| 751 OutputUnit outputUnit = | 780 OutputUnit outputUnit = _deferredLoadTask.outputUnitForElement(element); |
| 752 _compiler.deferredLoadTask.outputUnitForElement(element); | |
| 753 functionType = _generateFunctionType(memberType, outputUnit); | 781 functionType = _generateFunctionType(memberType, outputUnit); |
| 754 } | 782 } |
| 755 | 783 |
| 756 int requiredParameterCount; | 784 int requiredParameterCount; |
| 757 var /* List | Map */ optionalParameterDefaultValues; | 785 var /* List | Map */ optionalParameterDefaultValues; |
| 758 if (canBeApplied || canBeReflected) { | 786 if (canBeApplied || canBeReflected) { |
| 759 FunctionSignature signature = element.functionSignature; | 787 FunctionSignature signature = element.functionSignature; |
| 760 requiredParameterCount = signature.requiredParameterCount; | 788 requiredParameterCount = signature.requiredParameterCount; |
| 761 optionalParameterDefaultValues = | 789 optionalParameterDefaultValues = |
| 762 _computeParameterDefaultValues(signature); | 790 _computeParameterDefaultValues(signature); |
| 763 } | 791 } |
| 764 | 792 |
| 765 return new InstanceMethod(element, name, code, | 793 return new InstanceMethod(element, name, code, |
| 766 _generateParameterStubs(element, canTearOff), callName, | 794 _generateParameterStubs(element, canTearOff), callName, |
| 767 needsTearOff: canTearOff, | 795 needsTearOff: canTearOff, |
| 768 tearOffName: tearOffName, | 796 tearOffName: tearOffName, |
| 769 isClosureCallMethod: isClosureCallMethod, | 797 isClosureCallMethod: isClosureCallMethod, |
| 770 aliasName: aliasName, | 798 aliasName: aliasName, |
| 771 canBeApplied: canBeApplied, | 799 canBeApplied: canBeApplied, |
| 772 canBeReflected: canBeReflected, | 800 canBeReflected: canBeReflected, |
| 773 requiredParameterCount: requiredParameterCount, | 801 requiredParameterCount: requiredParameterCount, |
| 774 optionalParameterDefaultValues: optionalParameterDefaultValues, | 802 optionalParameterDefaultValues: optionalParameterDefaultValues, |
| 775 functionType: functionType); | 803 functionType: functionType); |
| 776 } | 804 } |
| 777 | 805 |
| 778 js.Expression _generateFunctionType( | 806 js.Expression _generateFunctionType( |
| 779 ResolutionDartType type, OutputUnit outputUnit) { | 807 ResolutionDartType type, OutputUnit outputUnit) { |
| 780 if (type.containsTypeVariables) { | 808 if (type.containsTypeVariables) { |
| 781 js.Expression thisAccess = js.js(r'this.$receiver'); | 809 js.Expression thisAccess = js.js(r'this.$receiver'); |
| 782 return backend.rtiEncoder | 810 return _rtiEncoder.getSignatureEncoding( |
| 783 .getSignatureEncoding(backend.emitter.emitter, type, thisAccess); | 811 _emitter.emitter, type, thisAccess); |
| 784 } else { | 812 } else { |
| 785 return backend.emitter.metadataCollector | 813 return _emitter.metadataCollector |
| 786 .reifyTypeForOutputUnit(type, outputUnit); | 814 .reifyTypeForOutputUnit(type, outputUnit); |
| 787 } | 815 } |
| 788 } | 816 } |
| 789 | 817 |
| 790 List<ParameterStubMethod> _generateParameterStubs( | 818 List<ParameterStubMethod> _generateParameterStubs( |
| 791 MethodElement element, bool canTearOff) { | 819 MethodElement element, bool canTearOff) { |
| 792 if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[]; | 820 if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[]; |
| 793 | 821 |
| 794 ParameterStubGenerator generator = | 822 ParameterStubGenerator generator = |
| 795 new ParameterStubGenerator(_compiler, namer, backend, closedWorld); | 823 new ParameterStubGenerator(_compiler, namer, _backend, closedWorld); |
| 796 return generator.generateParameterStubs(element, canTearOff: canTearOff); | 824 return generator.generateParameterStubs(element, canTearOff: canTearOff); |
| 797 } | 825 } |
| 798 | 826 |
| 799 /// Builds a stub method. | 827 /// Builds a stub method. |
| 800 /// | 828 /// |
| 801 /// Stub methods may have an element that can be used for code-size | 829 /// Stub methods may have an element that can be used for code-size |
| 802 /// attribution. | 830 /// attribution. |
| 803 Method _buildStubMethod(js.Name name, js.Expression code, | 831 Method _buildStubMethod(js.Name name, js.Expression code, |
| 804 {MemberElement element}) { | 832 {MemberElement element}) { |
| 805 return new StubMethod(name, code, element: element); | 833 return new StubMethod(name, code, element: element); |
| 806 } | 834 } |
| 807 | 835 |
| 808 // The getInterceptor methods directly access the prototype of classes. | 836 // The getInterceptor methods directly access the prototype of classes. |
| 809 // We must evaluate these classes eagerly so that the prototype is | 837 // We must evaluate these classes eagerly so that the prototype is |
| 810 // accessible. | 838 // accessible. |
| 811 void _markEagerInterceptorClasses() { | 839 void _markEagerInterceptorClasses() { |
| 812 Iterable<js.Name> names = | 840 Iterable<js.Name> names = |
| 813 backend.oneShotInterceptorData.specializedGetInterceptorNames; | 841 _oneShotInterceptorData.specializedGetInterceptorNames; |
| 814 for (js.Name name in names) { | 842 for (js.Name name in names) { |
| 815 for (ClassElement element in backend.oneShotInterceptorData | 843 for (ClassElement element |
| 816 .getSpecializedGetInterceptorsFor(name)) { | 844 in _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name)) { |
| 817 Class cls = _classes[element]; | 845 Class cls = _classes[element]; |
| 818 if (cls != null) cls.isEager = true; | 846 if (cls != null) cls.isEager = true; |
| 819 } | 847 } |
| 820 } | 848 } |
| 821 } | 849 } |
| 822 | 850 |
| 823 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { | 851 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { |
| 824 InterceptorStubGenerator stubGenerator = | 852 InterceptorStubGenerator stubGenerator = |
| 825 new InterceptorStubGenerator(_compiler, namer, backend, closedWorld); | 853 new InterceptorStubGenerator(_compiler, namer, _backend, closedWorld); |
| 826 | 854 |
| 827 String holderName = namer | 855 String holderName = |
| 828 .globalObjectForLibrary(_compiler.commonElements.interceptorsLibrary); | 856 namer.globalObjectForLibrary(_commonElements.interceptorsLibrary); |
| 829 // TODO(floitsch): we shouldn't update the registry in the middle of | 857 // TODO(floitsch): we shouldn't update the registry in the middle of |
| 830 // generating the interceptor methods. | 858 // generating the interceptor methods. |
| 831 Holder holder = _registry.registerHolder(holderName); | 859 Holder holder = _registry.registerHolder(holderName); |
| 832 | 860 |
| 833 Iterable<js.Name> names = | 861 Iterable<js.Name> names = |
| 834 backend.oneShotInterceptorData.specializedGetInterceptorNames; | 862 _oneShotInterceptorData.specializedGetInterceptorNames; |
| 835 return names.map((js.Name name) { | 863 return names.map((js.Name name) { |
| 836 Set<ClassEntity> classes = | 864 Set<ClassEntity> classes = |
| 837 backend.oneShotInterceptorData.getSpecializedGetInterceptorsFor(name); | 865 _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name); |
| 838 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes); | 866 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes); |
| 839 return new StaticStubMethod(name, holder, code); | 867 return new StaticStubMethod(name, holder, code); |
| 840 }); | 868 }); |
| 841 } | 869 } |
| 842 | 870 |
| 843 List<Field> _buildFields(Element holder, | 871 List<Field> _buildFields(Element holder, |
| 844 {bool visitStatics, bool isHolderInterceptedClass: false}) { | 872 {bool visitStatics, bool isHolderInterceptedClass: false}) { |
| 845 List<Field> fields = <Field>[]; | 873 List<Field> fields = <Field>[]; |
| 846 new FieldVisitor(_compiler, namer, closedWorld) | 874 new FieldVisitor(_compiler, namer, closedWorld) |
| 847 .visitFields(holder, visitStatics, (FieldElement field, | 875 .visitFields(holder, visitStatics, (FieldElement field, |
| 848 js.Name name, | 876 js.Name name, |
| 849 js.Name accessorName, | 877 js.Name accessorName, |
| 850 bool needsGetter, | 878 bool needsGetter, |
| 851 bool needsSetter, | 879 bool needsSetter, |
| 852 bool needsCheckedSetter) { | 880 bool needsCheckedSetter) { |
| 853 assert(invariant(field, field.isDeclaration)); | 881 assert(invariant(field, field.isDeclaration)); |
| 854 | 882 |
| 855 int getterFlags = 0; | 883 int getterFlags = 0; |
| 856 if (needsGetter) { | 884 if (needsGetter) { |
| 857 if (visitStatics || | 885 if (visitStatics || |
| 858 !backend.interceptorData.fieldHasInterceptedGetter(field)) { | 886 !_interceptorData.fieldHasInterceptedGetter(field)) { |
| 859 getterFlags = 1; | 887 getterFlags = 1; |
| 860 } else { | 888 } else { |
| 861 getterFlags += 2; | 889 getterFlags += 2; |
| 862 // TODO(sra): 'isInterceptedClass' might not be the correct test | 890 // TODO(sra): 'isInterceptedClass' might not be the correct test |
| 863 // for methods forced to use the interceptor convention because | 891 // for methods forced to use the interceptor convention because |
| 864 // the method's class was elsewhere mixed-in to an interceptor. | 892 // the method's class was elsewhere mixed-in to an interceptor. |
| 865 if (!isHolderInterceptedClass) { | 893 if (!isHolderInterceptedClass) { |
| 866 getterFlags += 1; | 894 getterFlags += 1; |
| 867 } | 895 } |
| 868 } | 896 } |
| 869 } | 897 } |
| 870 | 898 |
| 871 int setterFlags = 0; | 899 int setterFlags = 0; |
| 872 if (needsSetter) { | 900 if (needsSetter) { |
| 873 if (visitStatics || | 901 if (visitStatics || |
| 874 !backend.interceptorData.fieldHasInterceptedSetter(field)) { | 902 !_interceptorData.fieldHasInterceptedSetter(field)) { |
| 875 setterFlags = 1; | 903 setterFlags = 1; |
| 876 } else { | 904 } else { |
| 877 setterFlags += 2; | 905 setterFlags += 2; |
| 878 if (!isHolderInterceptedClass) { | 906 if (!isHolderInterceptedClass) { |
| 879 setterFlags += 1; | 907 setterFlags += 1; |
| 880 } | 908 } |
| 881 } | 909 } |
| 882 } | 910 } |
| 883 | 911 |
| 884 fields.add(new Field(field, name, accessorName, getterFlags, setterFlags, | 912 fields.add(new Field(field, name, accessorName, getterFlags, setterFlags, |
| 885 needsCheckedSetter)); | 913 needsCheckedSetter)); |
| 886 }); | 914 }); |
| 887 | 915 |
| 888 return fields; | 916 return fields; |
| 889 } | 917 } |
| 890 | 918 |
| 891 Iterable<StaticStubMethod> _generateOneShotInterceptors() { | 919 Iterable<StaticStubMethod> _generateOneShotInterceptors() { |
| 892 InterceptorStubGenerator stubGenerator = | 920 InterceptorStubGenerator stubGenerator = |
| 893 new InterceptorStubGenerator(_compiler, namer, backend, closedWorld); | 921 new InterceptorStubGenerator(_compiler, namer, _backend, closedWorld); |
| 894 | 922 |
| 895 String holderName = namer | 923 String holderName = |
| 896 .globalObjectForLibrary(_compiler.commonElements.interceptorsLibrary); | 924 namer.globalObjectForLibrary(_commonElements.interceptorsLibrary); |
| 897 // TODO(floitsch): we shouldn't update the registry in the middle of | 925 // TODO(floitsch): we shouldn't update the registry in the middle of |
| 898 // generating the interceptor methods. | 926 // generating the interceptor methods. |
| 899 Holder holder = _registry.registerHolder(holderName); | 927 Holder holder = _registry.registerHolder(holderName); |
| 900 | 928 |
| 901 List<js.Name> names = | 929 List<js.Name> names = _oneShotInterceptorData.oneShotInterceptorNames; |
| 902 backend.oneShotInterceptorData.oneShotInterceptorNames; | |
| 903 return names.map((js.Name name) { | 930 return names.map((js.Name name) { |
| 904 js.Expression code = stubGenerator.generateOneShotInterceptor(name); | 931 js.Expression code = stubGenerator.generateOneShotInterceptor(name); |
| 905 return new StaticStubMethod(name, holder, code); | 932 return new StaticStubMethod(name, holder, code); |
| 906 }); | 933 }); |
| 907 } | 934 } |
| 908 | 935 |
| 909 StaticDartMethod _buildStaticMethod(MethodElement element) { | 936 StaticDartMethod _buildStaticMethod(MethodElement element) { |
| 910 js.Name name = namer.methodPropertyName(element); | 937 js.Name name = namer.methodPropertyName(element); |
| 911 String holder = namer.globalObjectFor(element); | 938 String holder = namer.globalObjectFor(element); |
| 912 js.Expression code = backend.generatedCode[element]; | 939 js.Expression code = _backend.generatedCode[element]; |
| 913 | 940 |
| 914 bool isApplyTarget = !element.isConstructor && !element.isAccessor; | 941 bool isApplyTarget = !element.isConstructor && !element.isAccessor; |
| 915 bool canBeApplied = _methodCanBeApplied(element); | 942 bool canBeApplied = _methodCanBeApplied(element); |
| 916 bool canBeReflected = _methodCanBeReflected(element); | 943 bool canBeReflected = _methodCanBeReflected(element); |
| 917 | 944 |
| 918 bool needsTearOff = isApplyTarget && | 945 bool needsTearOff = isApplyTarget && |
| 919 (canBeReflected || | 946 (canBeReflected || |
| 920 worldBuilder.staticFunctionsNeedingGetter.contains(element)); | 947 _worldBuilder.staticFunctionsNeedingGetter.contains(element)); |
| 921 | 948 |
| 922 js.Name tearOffName = | 949 js.Name tearOffName = |
| 923 needsTearOff ? namer.staticClosureName(element) : null; | 950 needsTearOff ? namer.staticClosureName(element) : null; |
| 924 | 951 |
| 925 js.Name callName = null; | 952 js.Name callName = null; |
| 926 if (needsTearOff) { | 953 if (needsTearOff) { |
| 927 Selector callSelector = | 954 Selector callSelector = |
| 928 new Selector.fromElement(element).toCallSelector(); | 955 new Selector.fromElement(element).toCallSelector(); |
| 929 callName = namer.invocationName(callSelector); | 956 callName = namer.invocationName(callSelector); |
| 930 } | 957 } |
| 931 js.Expression functionType; | 958 js.Expression functionType; |
| 932 ResolutionDartType type = element.type; | 959 ResolutionDartType type = element.type; |
| 933 if (needsTearOff || canBeReflected) { | 960 if (needsTearOff || canBeReflected) { |
| 934 OutputUnit outputUnit = | 961 OutputUnit outputUnit = _deferredLoadTask.outputUnitForElement(element); |
| 935 _compiler.deferredLoadTask.outputUnitForElement(element); | |
| 936 functionType = _generateFunctionType(type, outputUnit); | 962 functionType = _generateFunctionType(type, outputUnit); |
| 937 } | 963 } |
| 938 | 964 |
| 939 int requiredParameterCount; | 965 int requiredParameterCount; |
| 940 var /* List | Map */ optionalParameterDefaultValues; | 966 var /* List | Map */ optionalParameterDefaultValues; |
| 941 if (canBeApplied || canBeReflected) { | 967 if (canBeApplied || canBeReflected) { |
| 942 FunctionSignature signature = element.functionSignature; | 968 FunctionSignature signature = element.functionSignature; |
| 943 requiredParameterCount = signature.requiredParameterCount; | 969 requiredParameterCount = signature.requiredParameterCount; |
| 944 optionalParameterDefaultValues = | 970 optionalParameterDefaultValues = |
| 945 _computeParameterDefaultValues(signature); | 971 _computeParameterDefaultValues(signature); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 972 Constant constant = new Constant(name, holder, constantValue); | 998 Constant constant = new Constant(name, holder, constantValue); |
| 973 _constants[constantValue] = constant; | 999 _constants[constantValue] = constant; |
| 974 } | 1000 } |
| 975 } | 1001 } |
| 976 | 1002 |
| 977 Holder _registerStaticStateHolder() { | 1003 Holder _registerStaticStateHolder() { |
| 978 return _registry.registerHolder(namer.staticStateHolder, | 1004 return _registry.registerHolder(namer.staticStateHolder, |
| 979 isStaticStateHolder: true); | 1005 isStaticStateHolder: true); |
| 980 } | 1006 } |
| 981 } | 1007 } |
| OLD | NEW |