OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 kernel.tree_shaker; | 5 library kernel.tree_shaker; |
6 | 6 |
7 import '../ast.dart'; | 7 import '../ast.dart'; |
8 import '../class_hierarchy.dart'; | 8 import '../class_hierarchy.dart'; |
9 import '../core_types.dart'; | 9 import '../core_types.dart'; |
10 import '../type_environment.dart'; | 10 import '../type_environment.dart'; |
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
889 class _TreeShakingTransformer extends Transformer { | 889 class _TreeShakingTransformer extends Transformer { |
890 final TreeShaker shaker; | 890 final TreeShaker shaker; |
891 | 891 |
892 _TreeShakingTransformer(this.shaker); | 892 _TreeShakingTransformer(this.shaker); |
893 | 893 |
894 Member _translateInterfaceTarget(Member target) { | 894 Member _translateInterfaceTarget(Member target) { |
895 return target != null && shaker.isMemberUsed(target) ? target : null; | 895 return target != null && shaker.isMemberUsed(target) ? target : null; |
896 } | 896 } |
897 | 897 |
898 void transform(Program program) { | 898 void transform(Program program) { |
899 for (var library in program.libraries) { | |
900 if (!shaker.forceShaking && library.importUri.scheme == 'dart') { | |
901 // The backend expects certain things to be present in the core | |
902 // libraries, so we currently don't shake off anything there. | |
903 continue; | |
904 } | |
905 library.transformChildren(this); | |
906 // Note: we can't shake off empty libraries yet since we don't check if | |
907 // there are private names that use the library. | |
908 } | |
909 for (Expression node in shaker._typedCalls) { | 899 for (Expression node in shaker._typedCalls) { |
910 // We should not leave dangling references, so if the target of a typed | 900 // We should not leave dangling references, so if the target of a typed |
911 // call has been removed, we must remove the reference. The receiver of | 901 // call has been removed, we must remove the reference. The receiver of |
912 // such a call can only be null. | 902 // such a call can only be null. |
913 // TODO(asgerf): Rewrite to a NSM call instead of adding dynamic calls. | 903 // TODO(asgerf): Rewrite to a NSM call instead of adding dynamic calls. |
914 if (node is MethodInvocation) { | 904 if (node is MethodInvocation) { |
915 node.interfaceTarget = _translateInterfaceTarget(node.interfaceTarget); | 905 node.interfaceTarget = _translateInterfaceTarget(node.interfaceTarget); |
916 } else if (node is PropertyGet) { | 906 } else if (node is PropertyGet) { |
917 node.interfaceTarget = _translateInterfaceTarget(node.interfaceTarget); | 907 node.interfaceTarget = _translateInterfaceTarget(node.interfaceTarget); |
918 } else if (node is PropertySet) { | 908 } else if (node is PropertySet) { |
919 node.interfaceTarget = _translateInterfaceTarget(node.interfaceTarget); | 909 node.interfaceTarget = _translateInterfaceTarget(node.interfaceTarget); |
920 } | 910 } |
921 } | 911 } |
| 912 for (var library in program.libraries) { |
| 913 if (!shaker.forceShaking && library.importUri.scheme == 'dart') { |
| 914 // The backend expects certain things to be present in the core |
| 915 // libraries, so we currently don't shake off anything there. |
| 916 continue; |
| 917 } |
| 918 library.transformChildren(this); |
| 919 // Note: we can't shake off empty libraries yet since we don't check if |
| 920 // there are private names that use the library. |
| 921 } |
922 } | 922 } |
923 | 923 |
924 Class visitClass(Class node) { | 924 Class visitClass(Class node) { |
925 switch (shaker.getClassRetention(node)) { | 925 switch (shaker.getClassRetention(node)) { |
926 case ClassRetention.None: | 926 case ClassRetention.None: |
| 927 node.canonicalName?.unbind(); |
927 return null; // Remove the class. | 928 return null; // Remove the class. |
928 | 929 |
929 case ClassRetention.Namespace: | 930 case ClassRetention.Namespace: |
930 // The class is only a namespace for static members. Remove its | 931 // The class is only a namespace for static members. Remove its |
931 // hierarchy information. This is mandatory, since these references | 932 // hierarchy information. This is mandatory, since these references |
932 // might otherwise become dangling. | 933 // might otherwise become dangling. |
933 node.supertype = shaker.coreTypes.objectClass.asRawSupertype; | 934 node.supertype = shaker.coreTypes.objectClass.asRawSupertype; |
934 node.implementedTypes.clear(); | 935 node.implementedTypes.clear(); |
935 node.typeParameters.clear(); | 936 node.typeParameters.clear(); |
936 node.isAbstract = true; | 937 node.isAbstract = true; |
(...skipping 10 matching lines...) Expand all Loading... |
947 case ClassRetention.ExternalInstance: | 948 case ClassRetention.ExternalInstance: |
948 break; | 949 break; |
949 } | 950 } |
950 node.transformChildren(this); | 951 node.transformChildren(this); |
951 return node; | 952 return node; |
952 } | 953 } |
953 | 954 |
954 Member defaultMember(Member node) { | 955 Member defaultMember(Member node) { |
955 if (!shaker.isMemberBodyUsed(node)) { | 956 if (!shaker.isMemberBodyUsed(node)) { |
956 if (!shaker.isMemberOverridden(node)) { | 957 if (!shaker.isMemberOverridden(node)) { |
| 958 node.canonicalName?.unbind(); |
957 return null; | 959 return null; |
958 } | 960 } |
959 if (node is Procedure) { | 961 if (node is Procedure) { |
960 // Remove body of unused member. | 962 // Remove body of unused member. |
961 if (node.enclosingClass.isAbstract) { | 963 if (node.enclosingClass.isAbstract) { |
962 node.isAbstract = true; | 964 node.isAbstract = true; |
963 node.function.body = null; | 965 node.function.body = null; |
964 } else { | 966 } else { |
965 // If the enclosing class is not abstract, the method should still | 967 // If the enclosing class is not abstract, the method should still |
966 // have a body even if it can never be called. | 968 // have a body even if it can never be called. |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 } | 1113 } |
1112 break; | 1114 break; |
1113 case ProgramRootKind.Other: | 1115 case ProgramRootKind.Other: |
1114 return member; | 1116 return member; |
1115 default: | 1117 default: |
1116 } | 1118 } |
1117 } | 1119 } |
1118 } | 1120 } |
1119 throw "$root not found!"; | 1121 throw "$root not found!"; |
1120 } | 1122 } |
OLD | NEW |