| 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 | 7 import '../js_emitter.dart' show |
| 8 ClassStubGenerator, | 8 ClassStubGenerator, |
| 9 CodeEmitterTask, | 9 CodeEmitterTask, |
| 10 computeMixinClass, | 10 computeMixinClass, |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 // Interceptor class with implementations that directly call the | 362 // Interceptor class with implementations that directly call the |
| 363 // corresponding JavaScript member. We do not attempt to bind this when | 363 // corresponding JavaScript member. We do not attempt to bind this when |
| 364 // tearing off JavaScript methods as we cannot distinguish between calling | 364 // tearing off JavaScript methods as we cannot distinguish between calling |
| 365 // a regular getter that returns a JavaScript function and tearing off | 365 // a regular getter that returns a JavaScript function and tearing off |
| 366 // a method in the case where there exist multiple JavaScript classes | 366 // a method in the case where there exist multiple JavaScript classes |
| 367 // that conflict on whether the member is a getter or a method. | 367 // that conflict on whether the member is a getter or a method. |
| 368 var interceptorClass = _classes[backend.jsJavaScriptObjectClass]; | 368 var interceptorClass = _classes[backend.jsJavaScriptObjectClass]; |
| 369 var stubNames = new Set<String>(); | 369 var stubNames = new Set<String>(); |
| 370 librariesMap.forEach((LibraryElement library, List<Element> elements) { | 370 librariesMap.forEach((LibraryElement library, List<Element> elements) { |
| 371 for (Element e in elements) { | 371 for (Element e in elements) { |
| 372 if (e is ClassElement && e.isJsInterop) { | 372 if (e is ClassElement && backend.isJsInterop(e)) { |
| 373 e.declaration.forEachMember((_, Element member) { | 373 e.declaration.forEachMember((_, Element member) { |
| 374 if (!member.isInstanceMember) return; | 374 if (!member.isInstanceMember) return; |
| 375 if (member.isGetter || member.isField || member.isFunction) { | 375 if (member.isGetter || member.isField || member.isFunction) { |
| 376 var selectors = | 376 var selectors = |
| 377 _compiler.codegenWorld.getterInvocationsByName(member.name); | 377 _compiler.codegenWorld.getterInvocationsByName(member.name); |
| 378 if (selectors != null && !selectors.isEmpty) { | 378 if (selectors != null && !selectors.isEmpty) { |
| 379 for (var selector in selectors.keys) { | 379 for (var selector in selectors.keys) { |
| 380 var stubName = namer.invocationName(selector); | 380 var stubName = namer.invocationName(selector); |
| 381 if (stubNames.add(stubName.key)) { | 381 if (stubNames.add(stubName.key)) { |
| 382 interceptorClass.callStubs.add(_buildStubMethod( | 382 interceptorClass.callStubs.add(_buildStubMethod( |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 Class buildFieldsHackForIncrementalCompilation(ClassElement element) { | 474 Class buildFieldsHackForIncrementalCompilation(ClassElement element) { |
| 475 assert(_compiler.hasIncrementalSupport); | 475 assert(_compiler.hasIncrementalSupport); |
| 476 | 476 |
| 477 List<Field> instanceFields = _buildFields(element, false); | 477 List<Field> instanceFields = _buildFields(element, false); |
| 478 js.Name name = namer.className(element); | 478 js.Name name = namer.className(element); |
| 479 | 479 |
| 480 return new Class( | 480 return new Class( |
| 481 element, name, null, [], instanceFields, [], [], [], [], [], [], null, | 481 element, name, null, [], instanceFields, [], [], [], [], [], [], null, |
| 482 isDirectlyInstantiated: true, | 482 isDirectlyInstantiated: true, |
| 483 onlyForRti: false, | 483 onlyForRti: false, |
| 484 isNative: element.isNative); | 484 isNative: backend.isNative(element)); |
| 485 } | 485 } |
| 486 | 486 |
| 487 Class _buildClass(ClassElement element) { | 487 Class _buildClass(ClassElement element) { |
| 488 bool onlyForRti = collector.classesOnlyNeededForRti.contains(element); | 488 bool onlyForRti = collector.classesOnlyNeededForRti.contains(element); |
| 489 if (element.isJsInterop) { | 489 if (backend.isJsInterop(element)) { |
| 490 // TODO(jacobr): check whether the class has any active static fields | 490 // TODO(jacobr): check whether the class has any active static fields |
| 491 // if it does not we can suppress it completely. | 491 // if it does not we can suppress it completely. |
| 492 onlyForRti = true; | 492 onlyForRti = true; |
| 493 } | 493 } |
| 494 | 494 |
| 495 List<Method> methods = []; | 495 List<Method> methods = []; |
| 496 List<StubMethod> callStubs = <StubMethod>[]; | 496 List<StubMethod> callStubs = <StubMethod>[]; |
| 497 | 497 |
| 498 ClassStubGenerator classStubGenerator = | 498 ClassStubGenerator classStubGenerator = |
| 499 new ClassStubGenerator(_compiler, namer, backend); | 499 new ClassStubGenerator(_compiler, namer, backend); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 List<Field> staticFieldsForReflection = | 565 List<Field> staticFieldsForReflection = |
| 566 onlyForRti ? const <Field>[] : _buildFields(element, true); | 566 onlyForRti ? const <Field>[] : _buildFields(element, true); |
| 567 | 567 |
| 568 TypeTestProperties typeTests = | 568 TypeTestProperties typeTests = |
| 569 runtimeTypeGenerator.generateIsTests( | 569 runtimeTypeGenerator.generateIsTests( |
| 570 element, | 570 element, |
| 571 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata); | 571 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata); |
| 572 | 572 |
| 573 List<StubMethod> checkedSetters = <StubMethod>[]; | 573 List<StubMethod> checkedSetters = <StubMethod>[]; |
| 574 List<StubMethod> isChecks = <StubMethod>[]; | 574 List<StubMethod> isChecks = <StubMethod>[]; |
| 575 if (element.isJsInterop) { | 575 if (backend.isJsInterop(element)) { |
| 576 typeTests.properties.forEach((js.Name name, js.Node code) { | 576 typeTests.properties.forEach((js.Name name, js.Node code) { |
| 577 _classes[backend.jsInterceptorClass].isChecks.add( | 577 _classes[backend.jsInterceptorClass].isChecks.add( |
| 578 _buildStubMethod(name, code)); | 578 _buildStubMethod(name, code)); |
| 579 }); | 579 }); |
| 580 } else { | 580 } else { |
| 581 for (Field field in instanceFields) { | 581 for (Field field in instanceFields) { |
| 582 if (field.needsCheckedSetter) { | 582 if (field.needsCheckedSetter) { |
| 583 assert(!field.needsUncheckedSetter); | 583 assert(!field.needsUncheckedSetter); |
| 584 Element element = field.element; | 584 Element element = field.element; |
| 585 js.Expression code = backend.generatedCode[element]; | 585 js.Expression code = backend.generatedCode[element]; |
| 586 assert(code != null); | 586 assert(code != null); |
| 587 js.Name name = namer.deriveSetterName(field.accessorName); | 587 js.Name name = namer.deriveSetterName(field.accessorName); |
| 588 checkedSetters.add(_buildStubMethod(name, code, element: element)); | 588 checkedSetters.add(_buildStubMethod(name, code, element: element)); |
| 589 } | 589 } |
| 590 } | 590 } |
| 591 | 591 |
| 592 typeTests.properties.forEach((js.Name name, js.Node code) { | 592 typeTests.properties.forEach((js.Name name, js.Node code) { |
| 593 isChecks.add(_buildStubMethod(name, code)); | 593 isChecks.add(_buildStubMethod(name, code)); |
| 594 }); | 594 }); |
| 595 } | 595 } |
| 596 | 596 |
| 597 js.Name name = namer.className(element); | 597 js.Name name = namer.className(element); |
| 598 String holderName = namer.globalObjectFor(element); | 598 String holderName = namer.globalObjectFor(element); |
| 599 // TODO(floitsch): we shouldn't update the registry in the middle of | 599 // TODO(floitsch): we shouldn't update the registry in the middle of |
| 600 // building a class. | 600 // building a class. |
| 601 Holder holder = _registry.registerHolder(holderName); | 601 Holder holder = _registry.registerHolder(holderName); |
| 602 bool isInstantiated = !element.isJsInterop && | 602 bool isInstantiated = !backend.isJsInterop(element) && |
| 603 _compiler.codegenWorld.directlyInstantiatedClasses.contains(element); | 603 _compiler.codegenWorld.directlyInstantiatedClasses.contains(element); |
| 604 | 604 |
| 605 Class result; | 605 Class result; |
| 606 if (element.isMixinApplication && !onlyForRti) { | 606 if (element.isMixinApplication && !onlyForRti) { |
| 607 assert(!element.isNative); | 607 assert(!backend.isNative(element)); |
| 608 assert(methods.isEmpty); | 608 assert(methods.isEmpty); |
| 609 | 609 |
| 610 result = new MixinApplication(element, | 610 result = new MixinApplication(element, |
| 611 name, holder, | 611 name, holder, |
| 612 instanceFields, | 612 instanceFields, |
| 613 staticFieldsForReflection, | 613 staticFieldsForReflection, |
| 614 callStubs, | 614 callStubs, |
| 615 typeVariableReaderStubs, | 615 typeVariableReaderStubs, |
| 616 checkedSetters, | 616 checkedSetters, |
| 617 isChecks, | 617 isChecks, |
| 618 typeTests.functionTypeIndex, | 618 typeTests.functionTypeIndex, |
| 619 isDirectlyInstantiated: isInstantiated, | 619 isDirectlyInstantiated: isInstantiated, |
| 620 onlyForRti: onlyForRti); | 620 onlyForRti: onlyForRti); |
| 621 } else { | 621 } else { |
| 622 result = new Class(element, | 622 result = new Class(element, |
| 623 name, holder, methods, instanceFields, | 623 name, holder, methods, instanceFields, |
| 624 staticFieldsForReflection, | 624 staticFieldsForReflection, |
| 625 callStubs, | 625 callStubs, |
| 626 typeVariableReaderStubs, | 626 typeVariableReaderStubs, |
| 627 noSuchMethodStubs, | 627 noSuchMethodStubs, |
| 628 checkedSetters, | 628 checkedSetters, |
| 629 isChecks, | 629 isChecks, |
| 630 typeTests.functionTypeIndex, | 630 typeTests.functionTypeIndex, |
| 631 isDirectlyInstantiated: isInstantiated, | 631 isDirectlyInstantiated: isInstantiated, |
| 632 onlyForRti: onlyForRti, | 632 onlyForRti: onlyForRti, |
| 633 isNative: element.isNative); | 633 isNative: backend.isNative(element)); |
| 634 } | 634 } |
| 635 _classes[element] = result; | 635 _classes[element] = result; |
| 636 return result; | 636 return result; |
| 637 } | 637 } |
| 638 | 638 |
| 639 bool _methodNeedsStubs(FunctionElement method) { | 639 bool _methodNeedsStubs(FunctionElement method) { |
| 640 return !method.functionSignature.optionalParameters.isEmpty; | 640 return !method.functionSignature.optionalParameters.isEmpty; |
| 641 } | 641 } |
| 642 | 642 |
| 643 bool _methodCanBeReflected(FunctionElement method) { | 643 bool _methodCanBeReflected(FunctionElement method) { |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 961 Constant constant = new Constant(name, holder, constantValue); | 961 Constant constant = new Constant(name, holder, constantValue); |
| 962 _constants[constantValue] = constant; | 962 _constants[constantValue] = constant; |
| 963 } | 963 } |
| 964 } | 964 } |
| 965 | 965 |
| 966 Holder _registerStaticStateHolder() { | 966 Holder _registerStaticStateHolder() { |
| 967 return _registry.registerHolder( | 967 return _registry.registerHolder( |
| 968 namer.staticStateHolder, isStaticStateHolder: true); | 968 namer.staticStateHolder, isStaticStateHolder: true); |
| 969 } | 969 } |
| 970 } | 970 } |
| OLD | NEW |