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 'js_emitter.dart' show computeMixinClass; | 7 import 'js_emitter.dart' show computeMixinClass; |
8 import 'model.dart'; | 8 import 'model.dart'; |
9 | 9 |
10 import '../common.dart'; | 10 import '../common.dart'; |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 .toList(growable: false); | 207 .toList(growable: false); |
208 } | 208 } |
209 | 209 |
210 StaticField _buildStaticField(Element element) { | 210 StaticField _buildStaticField(Element element) { |
211 JavaScriptConstantCompiler handler = backend.constants; | 211 JavaScriptConstantCompiler handler = backend.constants; |
212 ConstantValue initialValue = handler.getInitialValueFor(element); | 212 ConstantValue initialValue = handler.getInitialValueFor(element); |
213 // TODO(zarah): The holder should not be registered during building of | 213 // TODO(zarah): The holder should not be registered during building of |
214 // a static field. | 214 // a static field. |
215 _registry.registerHolder(namer.globalObjectForConstant(initialValue)); | 215 _registry.registerHolder(namer.globalObjectForConstant(initialValue)); |
216 js.Expression code = _task.emitter.constantReference(initialValue); | 216 js.Expression code = _task.emitter.constantReference(initialValue); |
217 String name = namer.globalPropertyName(element); | 217 js.Name name = namer.globalPropertyName(element); |
218 bool isFinal = false; | 218 bool isFinal = false; |
219 bool isLazy = false; | 219 bool isLazy = false; |
220 | 220 |
221 // TODO(floitsch): we shouldn't update the registry in the middle of | 221 // TODO(floitsch): we shouldn't update the registry in the middle of |
222 // building a static field. (Note that the $ holder is already registered | 222 // building a static field. (Note that the $ holder is already registered |
223 // earlier). | 223 // earlier). |
224 return new StaticField(element, | 224 return new StaticField(element, |
225 name, _registry.registerHolder(r'$'), code, | 225 name, _registry.registerHolder(r'$'), code, |
226 isFinal, isLazy); | 226 isFinal, isLazy); |
227 } | 227 } |
(...skipping 15 matching lines...) Expand all Loading... |
243 .toList(growable: false); | 243 .toList(growable: false); |
244 } | 244 } |
245 | 245 |
246 StaticField _buildLazyField(Element element) { | 246 StaticField _buildLazyField(Element element) { |
247 js.Expression code = backend.generatedCode[element]; | 247 js.Expression code = backend.generatedCode[element]; |
248 // The code is null if we ended up not needing the lazily | 248 // The code is null if we ended up not needing the lazily |
249 // initialized field after all because of constant folding | 249 // initialized field after all because of constant folding |
250 // before code generation. | 250 // before code generation. |
251 if (code == null) return null; | 251 if (code == null) return null; |
252 | 252 |
253 String name = namer.globalPropertyName(element); | 253 js.Name name = namer.globalPropertyName(element); |
254 bool isFinal = element.isFinal; | 254 bool isFinal = element.isFinal; |
255 bool isLazy = true; | 255 bool isLazy = true; |
256 // TODO(floitsch): we shouldn't update the registry in the middle of | 256 // TODO(floitsch): we shouldn't update the registry in the middle of |
257 // building a static field. (Note that the $ holder is already registered | 257 // building a static field. (Note that the $ holder is already registered |
258 // earlier). | 258 // earlier). |
259 return new StaticField(element, | 259 return new StaticField(element, |
260 name, _registry.registerHolder(r'$'), code, | 260 name, _registry.registerHolder(r'$'), code, |
261 isFinal, isLazy); | 261 isFinal, isLazy); |
262 } | 262 } |
263 | 263 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 staticFieldsForReflection); | 299 staticFieldsForReflection); |
300 } | 300 } |
301 | 301 |
302 /// HACK for Incremental Compilation. | 302 /// HACK for Incremental Compilation. |
303 /// | 303 /// |
304 /// Returns a class that contains the fields of a class. | 304 /// Returns a class that contains the fields of a class. |
305 Class buildFieldsHackForIncrementalCompilation(ClassElement element) { | 305 Class buildFieldsHackForIncrementalCompilation(ClassElement element) { |
306 assert(_compiler.hasIncrementalSupport); | 306 assert(_compiler.hasIncrementalSupport); |
307 | 307 |
308 List<Field> instanceFields = _buildFields(element, false); | 308 List<Field> instanceFields = _buildFields(element, false); |
309 String name = namer.className(element); | 309 js.Name name = namer.className(element); |
310 | 310 |
311 return new Class( | 311 return new Class( |
312 element, name, null, [], instanceFields, [], [], [], [], [], null, | 312 element, name, null, [], instanceFields, [], [], [], [], [], null, |
313 isDirectlyInstantiated: true, | 313 isDirectlyInstantiated: true, |
314 onlyForRti: false, | 314 onlyForRti: false, |
315 isNative: element.isNative); | 315 isNative: element.isNative); |
316 } | 316 } |
317 | 317 |
318 Class _buildClass(ClassElement element) { | 318 Class _buildClass(ClassElement element) { |
319 bool onlyForRti = _task.typeTestRegistry.rtiNeededClasses.contains(element); | 319 bool onlyForRti = _task.typeTestRegistry.rtiNeededClasses.contains(element); |
(...skipping 13 matching lines...) Expand all Loading... |
333 if (Elements.isNonAbstractInstanceMember(member)) { | 333 if (Elements.isNonAbstractInstanceMember(member)) { |
334 // TODO(herhut): Remove once _buildMethod can no longer return null. | 334 // TODO(herhut): Remove once _buildMethod can no longer return null. |
335 Method method = _buildMethod(member); | 335 Method method = _buildMethod(member); |
336 if (method != null) methods.add(method); | 336 if (method != null) methods.add(method); |
337 } | 337 } |
338 if (member.isGetter || member.isField) { | 338 if (member.isGetter || member.isField) { |
339 Map<Selector, TypeMaskSet> selectors = | 339 Map<Selector, TypeMaskSet> selectors = |
340 _compiler.codegenWorld.invocationsByName(member.name); | 340 _compiler.codegenWorld.invocationsByName(member.name); |
341 if (selectors != null && !selectors.isEmpty) { | 341 if (selectors != null && !selectors.isEmpty) { |
342 | 342 |
343 Map<String, js.Expression> callStubsForMember = | 343 Map<js.Name, js.Expression> callStubsForMember = |
344 classStubGenerator.generateCallStubsForGetter(member, selectors); | 344 classStubGenerator.generateCallStubsForGetter(member, selectors); |
345 callStubsForMember.forEach((String name, js.Expression code) { | 345 callStubsForMember.forEach((js.Name name, js.Expression code) { |
346 callStubs.add(_buildStubMethod(name, code, element: member)); | 346 callStubs.add(_buildStubMethod(name, code, element: member)); |
347 }); | 347 }); |
348 } | 348 } |
349 } | 349 } |
350 } | 350 } |
351 | 351 |
352 List<StubMethod> typeVariableReaderStubs = | 352 List<StubMethod> typeVariableReaderStubs = |
353 runtimeTypeGenerator.generateTypeVariableReaderStubs(element); | 353 runtimeTypeGenerator.generateTypeVariableReaderStubs(element); |
354 | 354 |
355 List<StubMethod> noSuchMethodStubs = <StubMethod>[]; | 355 List<StubMethod> noSuchMethodStubs = <StubMethod>[]; |
356 if (backend.enabledNoSuchMethod && element == _compiler.objectClass) { | 356 if (backend.enabledNoSuchMethod && element == _compiler.objectClass) { |
357 Map<String, Selector> selectors = | 357 Map<js.Name, Selector> selectors = |
358 classStubGenerator.computeSelectorsForNsmHandlers(); | 358 classStubGenerator.computeSelectorsForNsmHandlers(); |
359 selectors.forEach((String name, Selector selector) { | 359 selectors.forEach((js.Name name, Selector selector) { |
360 noSuchMethodStubs | 360 noSuchMethodStubs |
361 .add(classStubGenerator.generateStubForNoSuchMethod(name, | 361 .add(classStubGenerator.generateStubForNoSuchMethod(name, |
362 selector)); | 362 selector)); |
363 }); | 363 }); |
364 } | 364 } |
365 | 365 |
366 if (element == backend.closureClass) { | 366 if (element == backend.closureClass) { |
367 // We add a special getter here to allow for tearing off a closure from | 367 // We add a special getter here to allow for tearing off a closure from |
368 // itself. | 368 // itself. |
369 String name = namer.getterForMember(Selector.CALL_NAME); | 369 js.Name name = namer.getterForMember(Selector.CALL_NAME); |
370 js.Fun function = js.js('function() { return this; }'); | 370 js.Fun function = js.js('function() { return this; }'); |
371 callStubs.add(_buildStubMethod(name, function)); | 371 callStubs.add(_buildStubMethod(name, function)); |
372 } | 372 } |
373 | 373 |
374 ClassElement implementation = element.implementation; | 374 ClassElement implementation = element.implementation; |
375 | 375 |
376 // MixinApplications run through the members of their mixin. Here, we are | 376 // MixinApplications run through the members of their mixin. Here, we are |
377 // only interested in direct members. | 377 // only interested in direct members. |
378 if (!onlyForRti && !element.isMixinApplication) { | 378 if (!onlyForRti && !element.isMixinApplication) { |
379 implementation.forEachMember(visitMember, includeBackendMembers: true); | 379 implementation.forEachMember(visitMember, includeBackendMembers: true); |
380 } | 380 } |
381 | 381 |
382 List<Field> instanceFields = | 382 List<Field> instanceFields = |
383 onlyForRti ? const <Field>[] : _buildFields(element, false); | 383 onlyForRti ? const <Field>[] : _buildFields(element, false); |
384 List<Field> staticFieldsForReflection = | 384 List<Field> staticFieldsForReflection = |
385 onlyForRti ? const <Field>[] : _buildFields(element, true); | 385 onlyForRti ? const <Field>[] : _buildFields(element, true); |
386 | 386 |
387 TypeTestProperties typeTests = | 387 TypeTestProperties typeTests = |
388 runtimeTypeGenerator.generateIsTests( | 388 runtimeTypeGenerator.generateIsTests( |
389 element, | 389 element, |
390 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata); | 390 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata); |
391 | 391 |
392 List<StubMethod> isChecks = <StubMethod>[]; | 392 List<StubMethod> isChecks = <StubMethod>[]; |
393 typeTests.properties.forEach((String name, js.Node code) { | 393 typeTests.properties.forEach((js.Name name, js.Node code) { |
394 isChecks.add(_buildStubMethod(name, code)); | 394 isChecks.add(_buildStubMethod(name, code)); |
395 }); | 395 }); |
396 | 396 |
397 String name = namer.className(element); | 397 js.Name name = namer.className(element); |
398 String holderName = namer.globalObjectFor(element); | 398 String holderName = namer.globalObjectFor(element); |
399 // TODO(floitsch): we shouldn't update the registry in the middle of | 399 // TODO(floitsch): we shouldn't update the registry in the middle of |
400 // building a class. | 400 // building a class. |
401 Holder holder = _registry.registerHolder(holderName); | 401 Holder holder = _registry.registerHolder(holderName); |
402 bool isInstantiated = | 402 bool isInstantiated = |
403 _compiler.codegenWorld.directlyInstantiatedClasses.contains(element); | 403 _compiler.codegenWorld.directlyInstantiatedClasses.contains(element); |
404 | 404 |
405 Class result; | 405 Class result; |
406 if (element.isMixinApplication && !onlyForRti) { | 406 if (element.isMixinApplication && !onlyForRti) { |
407 assert(!element.isNative); | 407 assert(!element.isNative); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 signature.forEachOptionalParameter((ParameterElement parameter) { | 474 signature.forEachOptionalParameter((ParameterElement parameter) { |
475 ConstantValue def = | 475 ConstantValue def = |
476 backend.constants.getConstantValueForVariable(parameter); | 476 backend.constants.getConstantValueForVariable(parameter); |
477 optionalParameterDefaultValues.add(def); | 477 optionalParameterDefaultValues.add(def); |
478 }); | 478 }); |
479 } | 479 } |
480 return optionalParameterDefaultValues; | 480 return optionalParameterDefaultValues; |
481 } | 481 } |
482 | 482 |
483 DartMethod _buildMethod(MethodElement element) { | 483 DartMethod _buildMethod(MethodElement element) { |
484 String name = namer.methodPropertyName(element); | 484 js.Name name = namer.methodPropertyName(element); |
485 js.Expression code = backend.generatedCode[element]; | 485 js.Expression code = backend.generatedCode[element]; |
486 | 486 |
487 // TODO(kasperl): Figure out under which conditions code is null. | 487 // TODO(kasperl): Figure out under which conditions code is null. |
488 if (code == null) return null; | 488 if (code == null) return null; |
489 | 489 |
490 bool canTearOff = false; | 490 bool canTearOff = false; |
491 String tearOffName; | 491 js.Name tearOffName; |
492 bool isClosure = false; | 492 bool isClosure = false; |
493 bool isNotApplyTarget = !element.isFunction || element.isAccessor; | 493 bool isNotApplyTarget = !element.isFunction || element.isAccessor; |
494 | 494 |
495 bool canBeReflected = _methodCanBeReflected(element); | 495 bool canBeReflected = _methodCanBeReflected(element); |
496 bool canBeApplied = _methodCanBeApplied(element); | 496 bool canBeApplied = _methodCanBeApplied(element); |
497 | 497 |
498 String aliasName = backend.isAliasedSuperMember(element) | 498 js.Name aliasName = backend.isAliasedSuperMember(element) |
499 ? namer.aliasedSuperMemberPropertyName(element) | 499 ? namer.aliasedSuperMemberPropertyName(element) |
500 : null; | 500 : null; |
501 | 501 |
502 if (isNotApplyTarget) { | 502 if (isNotApplyTarget) { |
503 canTearOff = false; | 503 canTearOff = false; |
504 } else { | 504 } else { |
505 if (element.enclosingClass.isClosure) { | 505 if (element.enclosingClass.isClosure) { |
506 canTearOff = false; | 506 canTearOff = false; |
507 isClosure = true; | 507 isClosure = true; |
508 } else { | 508 } else { |
509 // Careful with operators. | 509 // Careful with operators. |
510 canTearOff = universe.hasInvokedGetter(element, _compiler.world) || | 510 canTearOff = universe.hasInvokedGetter(element, _compiler.world) || |
511 (canBeReflected && !element.isOperator); | 511 (canBeReflected && !element.isOperator); |
512 assert(canTearOff || | 512 assert(canTearOff || |
513 !universe.methodsNeedingSuperGetter.contains(element)); | 513 !universe.methodsNeedingSuperGetter.contains(element)); |
514 tearOffName = namer.getterForElement(element); | 514 tearOffName = namer.getterForElement(element); |
515 } | 515 } |
516 } | 516 } |
517 | 517 |
518 if (canTearOff) { | 518 if (canTearOff) { |
519 assert(invariant(element, !element.isGenerativeConstructor)); | 519 assert(invariant(element, !element.isGenerativeConstructor)); |
520 assert(invariant(element, !element.isGenerativeConstructorBody)); | 520 assert(invariant(element, !element.isGenerativeConstructorBody)); |
521 assert(invariant(element, !element.isConstructor)); | 521 assert(invariant(element, !element.isConstructor)); |
522 } | 522 } |
523 | 523 |
524 String callName = null; | 524 js.Name callName = null; |
525 if (canTearOff) { | 525 if (canTearOff) { |
526 Selector callSelector = | 526 Selector callSelector = |
527 new Selector.fromElement(element).toCallSelector(); | 527 new Selector.fromElement(element).toCallSelector(); |
528 callName = namer.invocationName(callSelector); | 528 callName = namer.invocationName(callSelector); |
529 } | 529 } |
530 | 530 |
531 DartType memberType; | 531 DartType memberType; |
532 if (element.isGenerativeConstructorBody) { | 532 if (element.isGenerativeConstructorBody) { |
533 // TODO(herhut): Why does this need to be normalized away? We never need | 533 // TODO(herhut): Why does this need to be normalized away? We never need |
534 // this information anyway as they cannot be torn off or | 534 // this information anyway as they cannot be torn off or |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 | 582 |
583 ParameterStubGenerator generator = | 583 ParameterStubGenerator generator = |
584 new ParameterStubGenerator(_compiler, namer, backend); | 584 new ParameterStubGenerator(_compiler, namer, backend); |
585 return generator.generateParameterStubs(element, canTearOff: canTearOff); | 585 return generator.generateParameterStubs(element, canTearOff: canTearOff); |
586 } | 586 } |
587 | 587 |
588 /// Builds a stub method. | 588 /// Builds a stub method. |
589 /// | 589 /// |
590 /// Stub methods may have an element that can be used for code-size | 590 /// Stub methods may have an element that can be used for code-size |
591 /// attribution. | 591 /// attribution. |
592 Method _buildStubMethod(String name, js.Expression code, | 592 Method _buildStubMethod(js.Name name, js.Expression code, |
593 {Element element}) { | 593 {Element element}) { |
594 return new StubMethod(name, code, element: element); | 594 return new StubMethod(name, code, element: element); |
595 } | 595 } |
596 | 596 |
597 // The getInterceptor methods directly access the prototype of classes. | 597 // The getInterceptor methods directly access the prototype of classes. |
598 // We must evaluate these classes eagerly so that the prototype is | 598 // We must evaluate these classes eagerly so that the prototype is |
599 // accessible. | 599 // accessible. |
600 void _markEagerInterceptorClasses() { | 600 void _markEagerInterceptorClasses() { |
601 Map<String, Set<ClassElement>> specializedGetInterceptors = | 601 Map<js.Name, Set<ClassElement>> specializedGetInterceptors = |
602 backend.specializedGetInterceptors; | 602 backend.specializedGetInterceptors; |
603 for (Set<ClassElement> classes in specializedGetInterceptors.values) { | 603 for (Set<ClassElement> classes in specializedGetInterceptors.values) { |
604 for (ClassElement element in classes) { | 604 for (ClassElement element in classes) { |
605 Class cls = _classes[element]; | 605 Class cls = _classes[element]; |
606 if (cls != null) cls.isEager = true; | 606 if (cls != null) cls.isEager = true; |
607 } | 607 } |
608 } | 608 } |
609 } | 609 } |
610 | 610 |
611 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { | 611 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { |
612 InterceptorStubGenerator stubGenerator = | 612 InterceptorStubGenerator stubGenerator = |
613 new InterceptorStubGenerator(_compiler, namer, backend); | 613 new InterceptorStubGenerator(_compiler, namer, backend); |
614 | 614 |
615 String holderName = namer.globalObjectFor(backend.interceptorsLibrary); | 615 String holderName = namer.globalObjectFor(backend.interceptorsLibrary); |
616 // TODO(floitsch): we shouldn't update the registry in the middle of | 616 // TODO(floitsch): we shouldn't update the registry in the middle of |
617 // generating the interceptor methods. | 617 // generating the interceptor methods. |
618 Holder holder = _registry.registerHolder(holderName); | 618 Holder holder = _registry.registerHolder(holderName); |
619 | 619 |
620 Map<String, Set<ClassElement>> specializedGetInterceptors = | 620 Map<js.Name, Set<ClassElement>> specializedGetInterceptors = |
621 backend.specializedGetInterceptors; | 621 backend.specializedGetInterceptors; |
622 List<String> names = specializedGetInterceptors.keys.toList()..sort(); | 622 List<js.Name> names = specializedGetInterceptors.keys.toList()..sort(); |
623 return names.map((String name) { | 623 return names.map((js.Name name) { |
624 Set<ClassElement> classes = specializedGetInterceptors[name]; | 624 Set<ClassElement> classes = specializedGetInterceptors[name]; |
625 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes); | 625 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes); |
626 return new StaticStubMethod(name, holder, code); | 626 return new StaticStubMethod(name, holder, code); |
627 }); | 627 }); |
628 } | 628 } |
629 | 629 |
630 List<Field> _buildFields(Element holder, bool visitStatics) { | 630 List<Field> _buildFields(Element holder, bool visitStatics) { |
631 List<Field> fields = <Field>[]; | 631 List<Field> fields = <Field>[]; |
632 _task.oldEmitter.classEmitter.visitFields( | 632 _task.oldEmitter.classEmitter.visitFields( |
633 holder, visitStatics, (VariableElement field, | 633 holder, visitStatics, (VariableElement field, |
634 String name, | 634 js.Name name, |
635 String accessorName, | 635 js.Name accessorName, |
636 bool needsGetter, | 636 bool needsGetter, |
637 bool needsSetter, | 637 bool needsSetter, |
638 bool needsCheckedSetter) { | 638 bool needsCheckedSetter) { |
639 assert(invariant(field, field.isDeclaration)); | 639 assert(invariant(field, field.isDeclaration)); |
640 | 640 |
641 int getterFlags = 0; | 641 int getterFlags = 0; |
642 if (needsGetter) { | 642 if (needsGetter) { |
643 if (visitStatics || !backend.fieldHasInterceptedGetter(field)) { | 643 if (visitStatics || !backend.fieldHasInterceptedGetter(field)) { |
644 getterFlags = 1; | 644 getterFlags = 1; |
645 } else { | 645 } else { |
(...skipping 29 matching lines...) Expand all Loading... |
675 | 675 |
676 Iterable<StaticStubMethod> _generateOneShotInterceptors() { | 676 Iterable<StaticStubMethod> _generateOneShotInterceptors() { |
677 InterceptorStubGenerator stubGenerator = | 677 InterceptorStubGenerator stubGenerator = |
678 new InterceptorStubGenerator(_compiler, namer, backend); | 678 new InterceptorStubGenerator(_compiler, namer, backend); |
679 | 679 |
680 String holderName = namer.globalObjectFor(backend.interceptorsLibrary); | 680 String holderName = namer.globalObjectFor(backend.interceptorsLibrary); |
681 // TODO(floitsch): we shouldn't update the registry in the middle of | 681 // TODO(floitsch): we shouldn't update the registry in the middle of |
682 // generating the interceptor methods. | 682 // generating the interceptor methods. |
683 Holder holder = _registry.registerHolder(holderName); | 683 Holder holder = _registry.registerHolder(holderName); |
684 | 684 |
685 List<String> names = backend.oneShotInterceptors.keys.toList()..sort(); | 685 List<js.Name> names = backend.oneShotInterceptors.keys.toList()..sort(); |
686 return names.map((String name) { | 686 return names.map((js.Name name) { |
687 js.Expression code = stubGenerator.generateOneShotInterceptor(name); | 687 js.Expression code = stubGenerator.generateOneShotInterceptor(name); |
688 return new StaticStubMethod(name, holder, code); | 688 return new StaticStubMethod(name, holder, code); |
689 }); | 689 }); |
690 } | 690 } |
691 | 691 |
692 StaticDartMethod _buildStaticMethod(FunctionElement element) { | 692 StaticDartMethod _buildStaticMethod(FunctionElement element) { |
693 String name = namer.methodPropertyName(element); | 693 js.Name name = namer.methodPropertyName(element); |
694 String holder = namer.globalObjectFor(element); | 694 String holder = namer.globalObjectFor(element); |
695 js.Expression code = backend.generatedCode[element]; | 695 js.Expression code = backend.generatedCode[element]; |
696 | 696 |
697 bool isApplyTarget = !element.isConstructor && !element.isAccessor; | 697 bool isApplyTarget = !element.isConstructor && !element.isAccessor; |
698 bool canBeApplied = _methodCanBeApplied(element); | 698 bool canBeApplied = _methodCanBeApplied(element); |
699 bool canBeReflected = _methodCanBeReflected(element); | 699 bool canBeReflected = _methodCanBeReflected(element); |
700 | 700 |
701 bool needsTearOff = isApplyTarget && | 701 bool needsTearOff = isApplyTarget && |
702 (canBeReflected || | 702 (canBeReflected || |
703 universe.staticFunctionsNeedingGetter.contains(element)); | 703 universe.staticFunctionsNeedingGetter.contains(element)); |
704 | 704 |
705 String tearOffName = | 705 js.Name tearOffName = |
706 needsTearOff ? namer.staticClosureName(element) : null; | 706 needsTearOff ? namer.staticClosureName(element) : null; |
707 | 707 |
708 | 708 |
709 String callName = null; | 709 js.Name callName = null; |
710 if (needsTearOff) { | 710 if (needsTearOff) { |
711 Selector callSelector = | 711 Selector callSelector = |
712 new Selector.fromElement(element).toCallSelector(); | 712 new Selector.fromElement(element).toCallSelector(); |
713 callName = namer.invocationName(callSelector); | 713 callName = namer.invocationName(callSelector); |
714 } | 714 } |
715 js.Expression functionType; | 715 js.Expression functionType; |
716 DartType type = element.type; | 716 DartType type = element.type; |
717 if (needsTearOff || canBeReflected) { | 717 if (needsTearOff || canBeReflected) { |
718 OutputUnit outputUnit = | 718 OutputUnit outputUnit = |
719 _compiler.deferredLoadTask.outputUnitForElement(element); | 719 _compiler.deferredLoadTask.outputUnitForElement(element); |
(...skipping 25 matching lines...) Expand all Loading... |
745 functionType: functionType); | 745 functionType: functionType); |
746 } | 746 } |
747 | 747 |
748 void _registerConstants(OutputUnit outputUnit, | 748 void _registerConstants(OutputUnit outputUnit, |
749 Iterable<ConstantValue> constantValues) { | 749 Iterable<ConstantValue> constantValues) { |
750 // `constantValues` is null if an outputUnit doesn't contain any constants. | 750 // `constantValues` is null if an outputUnit doesn't contain any constants. |
751 if (constantValues == null) return; | 751 if (constantValues == null) return; |
752 for (ConstantValue constantValue in constantValues) { | 752 for (ConstantValue constantValue in constantValues) { |
753 _registry.registerConstant(outputUnit, constantValue); | 753 _registry.registerConstant(outputUnit, constantValue); |
754 assert(!_constants.containsKey(constantValue)); | 754 assert(!_constants.containsKey(constantValue)); |
755 String name = namer.constantName(constantValue); | 755 js.Name name = namer.constantName(constantValue); |
756 String constantObject = namer.globalObjectForConstant(constantValue); | 756 String constantObject = namer.globalObjectForConstant(constantValue); |
757 Holder holder = _registry.registerHolder(constantObject); | 757 Holder holder = _registry.registerHolder(constantObject); |
758 Constant constant = new Constant(name, holder, constantValue); | 758 Constant constant = new Constant(name, holder, constantValue); |
759 _constants[constantValue] = constant; | 759 _constants[constantValue] = constant; |
760 } | 760 } |
761 } | 761 } |
762 } | 762 } |
OLD | NEW |