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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
77 ClosedWorld closedWorld, Set<ClassElement> rtiNeededClasses) | 77 ClosedWorld closedWorld, Set<ClassElement> rtiNeededClasses) |
78 : this._compiler = compiler, | 78 : this._compiler = compiler, |
79 this.namer = namer, | 79 this.namer = namer, |
80 this.closedWorld = closedWorld, | 80 this.closedWorld = closedWorld, |
81 this.collector = new Collector( | 81 this.collector = new Collector( |
82 compiler, namer, closedWorld, rtiNeededClasses, emitter), | 82 compiler, namer, closedWorld, rtiNeededClasses, emitter), |
83 this._registry = new Registry(compiler); | 83 this._registry = new Registry(compiler); |
84 | 84 |
85 JavaScriptBackend get backend => _compiler.backend; | 85 JavaScriptBackend get backend => _compiler.backend; |
86 BackendHelpers get helpers => backend.helpers; | 86 BackendHelpers get helpers => backend.helpers; |
87 CodegenWorldBuilder get universe => _compiler.codegenWorld; | 87 CodegenWorldBuilder get worldBuilder => _compiler.codegenWorldBuilder; |
88 | 88 |
89 /// Mapping from [ClassElement] to constructed [Class]. We need this to | 89 /// Mapping from [ClassElement] to constructed [Class]. We need this to |
90 /// update the superclass in the [Class]. | 90 /// update the superclass in the [Class]. |
91 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; | 91 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; |
92 | 92 |
93 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to | 93 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to |
94 /// generate the deferredLoadingMap (to know which hunks to load). | 94 /// generate the deferredLoadingMap (to know which hunks to load). |
95 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; | 95 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; |
96 | 96 |
97 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to | 97 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
347 var interceptorClass = _classes[helpers.jsJavaScriptObjectClass]; | 347 var interceptorClass = _classes[helpers.jsJavaScriptObjectClass]; |
348 var stubNames = new Set<String>(); | 348 var stubNames = new Set<String>(); |
349 librariesMap.forEach((LibraryElement library, List<Element> elements) { | 349 librariesMap.forEach((LibraryElement library, List<Element> elements) { |
350 for (Element e in elements) { | 350 for (Element e in elements) { |
351 if (e is ClassElement && backend.isJsInterop(e)) { | 351 if (e is ClassElement && backend.isJsInterop(e)) { |
352 e.declaration.forEachMember((_, Element member) { | 352 e.declaration.forEachMember((_, Element member) { |
353 var jsName = | 353 var jsName = |
354 backend.nativeData.getUnescapedJSInteropName(member.name); | 354 backend.nativeData.getUnescapedJSInteropName(member.name); |
355 if (!member.isInstanceMember) return; | 355 if (!member.isInstanceMember) return; |
356 if (member.isGetter || member.isField || member.isFunction) { | 356 if (member.isGetter || member.isField || member.isFunction) { |
357 var selectors = | 357 var selectors = _compiler.codegenWorldBuilder |
Siggi Cherem (dart-lang)
2017/01/11 23:54:56
can we directly use worldBuilder here and everywhe
Johnni Winther
2017/01/12 12:20:13
Done.
| |
358 _compiler.codegenWorld.getterInvocationsByName(member.name); | 358 .getterInvocationsByName(member.name); |
359 if (selectors != null && !selectors.isEmpty) { | 359 if (selectors != null && !selectors.isEmpty) { |
360 for (var selector in selectors.keys) { | 360 for (var selector in selectors.keys) { |
361 var stubName = namer.invocationName(selector); | 361 var stubName = namer.invocationName(selector); |
362 if (stubNames.add(stubName.key)) { | 362 if (stubNames.add(stubName.key)) { |
363 interceptorClass.callStubs.add(_buildStubMethod(stubName, | 363 interceptorClass.callStubs.add(_buildStubMethod(stubName, |
364 js.js('function(obj) { return obj.# }', [jsName]), | 364 js.js('function(obj) { return obj.# }', [jsName]), |
365 element: member)); | 365 element: member)); |
366 } | 366 } |
367 } | 367 } |
368 } | 368 } |
369 } | 369 } |
370 | 370 |
371 if (member.isSetter || (member.isField && !member.isConst)) { | 371 if (member.isSetter || (member.isField && !member.isConst)) { |
372 var selectors = | 372 var selectors = _compiler.codegenWorldBuilder |
373 _compiler.codegenWorld.setterInvocationsByName(member.name); | 373 .setterInvocationsByName(member.name); |
374 if (selectors != null && !selectors.isEmpty) { | 374 if (selectors != null && !selectors.isEmpty) { |
375 var stubName = namer.setterForElement(member); | 375 var stubName = namer.setterForElement(member); |
376 if (stubNames.add(stubName.key)) { | 376 if (stubNames.add(stubName.key)) { |
377 interceptorClass.callStubs.add(_buildStubMethod(stubName, | 377 interceptorClass.callStubs.add(_buildStubMethod(stubName, |
378 js.js('function(obj, v) { return obj.# = v }', [jsName]), | 378 js.js('function(obj, v) { return obj.# = v }', [jsName]), |
379 element: member)); | 379 element: member)); |
380 } | 380 } |
381 } | 381 } |
382 } | 382 } |
383 | 383 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 int minArgs; | 417 int minArgs; |
418 int maxArgs; | 418 int maxArgs; |
419 if (functionType != null) { | 419 if (functionType != null) { |
420 minArgs = functionType.parameterTypes.length; | 420 minArgs = functionType.parameterTypes.length; |
421 maxArgs = minArgs + functionType.optionalParameterTypes.length; | 421 maxArgs = minArgs + functionType.optionalParameterTypes.length; |
422 } else { | 422 } else { |
423 minArgs = 0; | 423 minArgs = 0; |
424 maxArgs = 32767; | 424 maxArgs = 32767; |
425 } | 425 } |
426 var selectors = | 426 var selectors = |
427 _compiler.codegenWorld.invocationsByName(member.name); | 427 _compiler.codegenWorldBuilder.invocationsByName(member.name); |
428 // Named arguments are not yet supported. In the future we | 428 // Named arguments are not yet supported. In the future we |
429 // may want to map named arguments to an object literal containing | 429 // may want to map named arguments to an object literal containing |
430 // all named arguments. | 430 // all named arguments. |
431 if (selectors != null && !selectors.isEmpty) { | 431 if (selectors != null && !selectors.isEmpty) { |
432 for (var selector in selectors.keys) { | 432 for (var selector in selectors.keys) { |
433 // Check whether the arity matches this member. | 433 // Check whether the arity matches this member. |
434 var argumentCount = selector.argumentCount; | 434 var argumentCount = selector.argumentCount; |
435 // JS interop does not support named arguments. | 435 // JS interop does not support named arguments. |
436 if (selector.namedArgumentCount > 0) continue; | 436 if (selector.namedArgumentCount > 0) continue; |
437 if (argumentCount < minArgs) continue; | 437 if (argumentCount < minArgs) continue; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
515 if (backend.isJsInterop(element)) { | 515 if (backend.isJsInterop(element)) { |
516 // TODO(jacobr): check whether the class has any active static fields | 516 // TODO(jacobr): check whether the class has any active static fields |
517 // if it does not we can suppress it completely. | 517 // if it does not we can suppress it completely. |
518 onlyForRti = true; | 518 onlyForRti = true; |
519 } | 519 } |
520 | 520 |
521 List<Method> methods = []; | 521 List<Method> methods = []; |
522 List<StubMethod> callStubs = <StubMethod>[]; | 522 List<StubMethod> callStubs = <StubMethod>[]; |
523 | 523 |
524 ClassStubGenerator classStubGenerator = new ClassStubGenerator( | 524 ClassStubGenerator classStubGenerator = new ClassStubGenerator( |
525 namer, backend, universe, closedWorld, | 525 namer, backend, worldBuilder, closedWorld, |
526 enableMinification: _compiler.options.enableMinification); | 526 enableMinification: _compiler.options.enableMinification); |
527 RuntimeTypeGenerator runtimeTypeGenerator = | 527 RuntimeTypeGenerator runtimeTypeGenerator = |
528 new RuntimeTypeGenerator(_compiler, _task, namer); | 528 new RuntimeTypeGenerator(_compiler, _task, namer); |
529 | 529 |
530 void visitMember(ClassElement enclosing, Element member) { | 530 void visitMember(ClassElement enclosing, Element member) { |
531 assert(invariant(element, member.isDeclaration)); | 531 assert(invariant(element, member.isDeclaration)); |
532 assert(invariant(element, element == enclosing)); | 532 assert(invariant(element, element == enclosing)); |
533 | 533 |
534 if (Elements.isNonAbstractInstanceMember(member)) { | 534 if (Elements.isNonAbstractInstanceMember(member)) { |
535 // TODO(herhut): Remove once _buildMethod can no longer return null. | 535 // TODO(herhut): Remove once _buildMethod can no longer return null. |
536 Method method = _buildMethod(member); | 536 Method method = _buildMethod(member); |
537 if (method != null) methods.add(method); | 537 if (method != null) methods.add(method); |
538 } | 538 } |
539 if (member.isGetter || member.isField) { | 539 if (member.isGetter || member.isField) { |
540 Map<Selector, SelectorConstraints> selectors = | 540 Map<Selector, SelectorConstraints> selectors = |
541 _compiler.codegenWorld.invocationsByName(member.name); | 541 _compiler.codegenWorldBuilder.invocationsByName(member.name); |
542 if (selectors != null && !selectors.isEmpty) { | 542 if (selectors != null && !selectors.isEmpty) { |
543 Map<js.Name, js.Expression> callStubsForMember = | 543 Map<js.Name, js.Expression> callStubsForMember = |
544 classStubGenerator.generateCallStubsForGetter(member, selectors); | 544 classStubGenerator.generateCallStubsForGetter(member, selectors); |
545 callStubsForMember.forEach((js.Name name, js.Expression code) { | 545 callStubsForMember.forEach((js.Name name, js.Expression code) { |
546 callStubs.add(_buildStubMethod(name, code, element: member)); | 546 callStubs.add(_buildStubMethod(name, code, element: member)); |
547 }); | 547 }); |
548 } | 548 } |
549 } | 549 } |
550 } | 550 } |
551 | 551 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
617 isChecks.add(_buildStubMethod(name, code)); | 617 isChecks.add(_buildStubMethod(name, code)); |
618 }); | 618 }); |
619 } | 619 } |
620 | 620 |
621 js.Name name = namer.className(element); | 621 js.Name name = namer.className(element); |
622 String holderName = namer.globalObjectFor(element); | 622 String holderName = namer.globalObjectFor(element); |
623 // TODO(floitsch): we shouldn't update the registry in the middle of | 623 // TODO(floitsch): we shouldn't update the registry in the middle of |
624 // building a class. | 624 // building a class. |
625 Holder holder = _registry.registerHolder(holderName); | 625 Holder holder = _registry.registerHolder(holderName); |
626 bool isInstantiated = !backend.isJsInterop(element) && | 626 bool isInstantiated = !backend.isJsInterop(element) && |
627 _compiler.codegenWorld.directlyInstantiatedClasses.contains(element); | 627 _compiler.codegenWorldBuilder.directlyInstantiatedClasses |
628 .contains(element); | |
628 | 629 |
629 Class result; | 630 Class result; |
630 if (element.isMixinApplication && !onlyForRti) { | 631 if (element.isMixinApplication && !onlyForRti) { |
631 assert(!backend.isNative(element)); | 632 assert(!backend.isNative(element)); |
632 assert(methods.isEmpty); | 633 assert(methods.isEmpty); |
633 | 634 |
634 result = new MixinApplication( | 635 result = new MixinApplication( |
635 element, | 636 element, |
636 name, | 637 name, |
637 holder, | 638 holder, |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
734 : null; | 735 : null; |
735 | 736 |
736 if (isNotApplyTarget) { | 737 if (isNotApplyTarget) { |
737 canTearOff = false; | 738 canTearOff = false; |
738 } else { | 739 } else { |
739 if (element.enclosingClass.isClosure) { | 740 if (element.enclosingClass.isClosure) { |
740 canTearOff = false; | 741 canTearOff = false; |
741 isClosureCallMethod = true; | 742 isClosureCallMethod = true; |
742 } else { | 743 } else { |
743 // Careful with operators. | 744 // Careful with operators. |
744 canTearOff = universe.hasInvokedGetter(element, closedWorld) || | 745 canTearOff = worldBuilder.hasInvokedGetter(element, closedWorld) || |
745 (canBeReflected && !element.isOperator); | 746 (canBeReflected && !element.isOperator); |
746 assert(canTearOff || | 747 assert(canTearOff || |
747 !universe.methodsNeedingSuperGetter.contains(element)); | 748 !worldBuilder.methodsNeedingSuperGetter.contains(element)); |
748 tearOffName = namer.getterForElement(element); | 749 tearOffName = namer.getterForElement(element); |
749 } | 750 } |
750 } | 751 } |
751 | 752 |
752 if (canTearOff) { | 753 if (canTearOff) { |
753 assert(invariant(element, !element.isGenerativeConstructor)); | 754 assert(invariant(element, !element.isGenerativeConstructor)); |
754 assert(invariant(element, !element.isGenerativeConstructorBody)); | 755 assert(invariant(element, !element.isGenerativeConstructorBody)); |
755 assert(invariant(element, !element.isConstructor)); | 756 assert(invariant(element, !element.isConstructor)); |
756 } | 757 } |
757 | 758 |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
928 js.Name name = namer.methodPropertyName(element); | 929 js.Name name = namer.methodPropertyName(element); |
929 String holder = namer.globalObjectFor(element); | 930 String holder = namer.globalObjectFor(element); |
930 js.Expression code = backend.generatedCode[element]; | 931 js.Expression code = backend.generatedCode[element]; |
931 | 932 |
932 bool isApplyTarget = !element.isConstructor && !element.isAccessor; | 933 bool isApplyTarget = !element.isConstructor && !element.isAccessor; |
933 bool canBeApplied = _methodCanBeApplied(element); | 934 bool canBeApplied = _methodCanBeApplied(element); |
934 bool canBeReflected = _methodCanBeReflected(element); | 935 bool canBeReflected = _methodCanBeReflected(element); |
935 | 936 |
936 bool needsTearOff = isApplyTarget && | 937 bool needsTearOff = isApplyTarget && |
937 (canBeReflected || | 938 (canBeReflected || |
938 universe.staticFunctionsNeedingGetter.contains(element)); | 939 worldBuilder.staticFunctionsNeedingGetter.contains(element)); |
939 | 940 |
940 js.Name tearOffName = | 941 js.Name tearOffName = |
941 needsTearOff ? namer.staticClosureName(element) : null; | 942 needsTearOff ? namer.staticClosureName(element) : null; |
942 | 943 |
943 js.Name callName = null; | 944 js.Name callName = null; |
944 if (needsTearOff) { | 945 if (needsTearOff) { |
945 Selector callSelector = | 946 Selector callSelector = |
946 new Selector.fromElement(element).toCallSelector(); | 947 new Selector.fromElement(element).toCallSelector(); |
947 callName = namer.invocationName(callSelector); | 948 callName = namer.invocationName(callSelector); |
948 } | 949 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
990 Constant constant = new Constant(name, holder, constantValue); | 991 Constant constant = new Constant(name, holder, constantValue); |
991 _constants[constantValue] = constant; | 992 _constants[constantValue] = constant; |
992 } | 993 } |
993 } | 994 } |
994 | 995 |
995 Holder _registerStaticStateHolder() { | 996 Holder _registerStaticStateHolder() { |
996 return _registry.registerHolder(namer.staticStateHolder, | 997 return _registry.registerHolder(namer.staticStateHolder, |
997 isStaticStateHolder: true); | 998 isStaticStateHolder: true); |
998 } | 999 } |
999 } | 1000 } |
OLD | NEW |