| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 part of dart2js.js_emitter.startup_emitter.model_emitter; | 5 part of dart2js.js_emitter.startup_emitter.model_emitter; |
| 6 | 6 |
| 7 /// The name of the property that stores the tear-off getter on a static | 7 /// The name of the property that stores the tear-off getter on a static |
| 8 /// function. | 8 /// function. |
| 9 /// | 9 /// |
| 10 /// This property is only used when isolates are used. | 10 /// This property is only used when isolates are used. |
| (...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 } | 836 } |
| 837 | 837 |
| 838 return properties; | 838 return properties; |
| 839 } | 839 } |
| 840 | 840 |
| 841 /// Emits the inheritance block of the fragment. | 841 /// Emits the inheritance block of the fragment. |
| 842 /// | 842 /// |
| 843 /// In this section prototype chains are updated and mixin functions are | 843 /// In this section prototype chains are updated and mixin functions are |
| 844 /// copied. | 844 /// copied. |
| 845 js.Statement emitInheritance(Fragment fragment) { | 845 js.Statement emitInheritance(Fragment fragment) { |
| 846 List<js.Expression> inheritCalls = <js.Expression>[]; | 846 List<js.Statement> inheritCalls = <js.Statement>[]; |
| 847 List<js.Expression> mixinCalls = <js.Expression>[]; | 847 List<js.Statement> mixinCalls = <js.Statement>[]; |
| 848 | 848 |
| 849 Set<Class> classesInFragment = new Set<Class>(); | 849 Set<Class> classesInFragment = new Set<Class>(); |
| 850 for (Library library in fragment.libraries) { | 850 for (Library library in fragment.libraries) { |
| 851 classesInFragment.addAll(library.classes); | 851 classesInFragment.addAll(library.classes); |
| 852 } | 852 } |
| 853 | 853 |
| 854 Set<Class> emittedClasses = new Set<Class>(); | 854 Map<Class, List<Class>> subclasses = <Class, List<Class>>{}; |
| 855 Set<Class> seen = new Set<Class>(); |
| 855 | 856 |
| 856 void emitInheritanceForClass(cls) { | 857 void collect(cls) { |
| 857 if (cls == null || emittedClasses.contains(cls)) return; | 858 if (cls == null || seen.contains(cls)) return; |
| 858 | 859 |
| 859 Class superclass = cls.superclass; | 860 Class superclass = cls.superclass; |
| 860 if (classesInFragment.contains(superclass)) { | 861 if (classesInFragment.contains(superclass)) { |
| 861 emitInheritanceForClass(superclass); | 862 collect(superclass); |
| 862 } | 863 } |
| 863 | 864 |
| 864 js.Expression superclassReference = (superclass == null) | 865 subclasses.putIfAbsent(superclass, () => <Class>[]).add(cls); |
| 865 ? new js.LiteralNull() | |
| 866 : classReference(superclass); | |
| 867 | 866 |
| 868 inheritCalls.add( | 867 seen.add(cls); |
| 869 js.js('inherit(#, #)', [classReference(cls), superclassReference])); | |
| 870 | |
| 871 emittedClasses.add(cls); | |
| 872 } | 868 } |
| 873 | 869 |
| 874 for (Library library in fragment.libraries) { | 870 for (Library library in fragment.libraries) { |
| 875 for (Class cls in library.classes) { | 871 for (Class cls in library.classes) { |
| 876 emitInheritanceForClass(cls); | 872 collect(cls); |
| 877 | 873 |
| 878 if (cls.isMixinApplication) { | 874 if (cls.isMixinApplication) { |
| 879 MixinApplication mixin = cls; | 875 MixinApplication mixin = cls; |
| 880 mixinCalls.add(js.js('mixin(#, #)', | 876 mixinCalls.add(js.js.statement('mixin(#, #)', |
| 881 [classReference(cls), classReference(mixin.mixinClass)])); | 877 [classReference(cls), classReference(mixin.mixinClass)])); |
| 882 } | 878 } |
| 883 } | 879 } |
| 884 } | 880 } |
| 885 | 881 |
| 882 js.Expression temp = null; |
| 883 for (Class superclass in subclasses.keys) { |
| 884 List<Class> list = subclasses[superclass]; |
| 885 js.Expression superclassReference = (superclass == null) |
| 886 ? new js.LiteralNull() |
| 887 : classReference(superclass); |
| 888 if (list.length == 1) { |
| 889 inheritCalls.add(js.js.statement('inherit(#, #)', |
| 890 [classReference(list.single), superclassReference])); |
| 891 } else { |
| 892 // Hold common superclass in temporary for sequence of calls. |
| 893 if (temp == null) { |
| 894 String tempName = '_'; |
| 895 temp = new js.VariableUse(tempName); |
| 896 var declaration = new js.VariableDeclaration(tempName); |
| 897 inheritCalls.add( |
| 898 js.js.statement('var # = #', [declaration, superclassReference])); |
| 899 } else { |
| 900 inheritCalls |
| 901 .add(js.js.statement('# = #', [temp, superclassReference])); |
| 902 } |
| 903 for (Class cls in list) { |
| 904 inheritCalls.add( |
| 905 js.js.statement('inherit(#, #)', [classReference(cls), temp])); |
| 906 } |
| 907 } |
| 908 } |
| 909 |
| 886 return wrapPhase( | 910 return wrapPhase( |
| 887 'inheritance', | 911 'inheritance', js.js.statement('{#; #;}', [inheritCalls, mixinCalls])); |
| 888 js.js.statement('{#; #;}', [ | |
| 889 inheritCalls.map((e) => new js.ExpressionStatement(e)), | |
| 890 mixinCalls.map((e) => new js.ExpressionStatement(e)) | |
| 891 ])); | |
| 892 } | 912 } |
| 893 | 913 |
| 894 /// Emits the setup of method aliases. | 914 /// Emits the setup of method aliases. |
| 895 /// | 915 /// |
| 896 /// This step consists of simply copying JavaScript functions to their | 916 /// This step consists of simply copying JavaScript functions to their |
| 897 /// aliased names so they point to the same function. | 917 /// aliased names so they point to the same function. |
| 898 js.Statement emitInstanceMethodAliases(Fragment fragment) { | 918 js.Statement emitInstanceMethodAliases(Fragment fragment) { |
| 899 List<js.Statement> assignments = <js.Statement>[]; | 919 List<js.Statement> assignments = <js.Statement>[]; |
| 900 | 920 |
| 901 for (Library library in fragment.libraries) { | 921 for (Library library in fragment.libraries) { |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1413 } | 1433 } |
| 1414 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", | 1434 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", |
| 1415 js.objectLiteral(interceptorsByTag))); | 1435 js.objectLiteral(interceptorsByTag))); |
| 1416 statements.add( | 1436 statements.add( |
| 1417 js.js.statement("setOrUpdateLeafTags(#);", js.objectLiteral(leafTags))); | 1437 js.js.statement("setOrUpdateLeafTags(#);", js.objectLiteral(leafTags))); |
| 1418 statements.addAll(subclassAssignments); | 1438 statements.addAll(subclassAssignments); |
| 1419 | 1439 |
| 1420 return wrapPhase('nativeSupport', new js.Block(statements)); | 1440 return wrapPhase('nativeSupport', new js.Block(statements)); |
| 1421 } | 1441 } |
| 1422 } | 1442 } |
| OLD | NEW |