| 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 dart_tree_printer; | 5 library dart_tree_printer; |
| 6 | 6 |
| 7 import '../constants/values.dart' as values; | 7 import '../constants/values.dart' as values; |
| 8 import '../dart_types.dart' as types; | 8 import '../dart_types.dart' as types; |
| 9 import '../dart2jslib.dart' as dart2js; | 9 import '../dart2jslib.dart' as dart2js; |
| 10 import '../elements/elements.dart' as elements; | 10 import '../elements/elements.dart' as elements; |
| 11 import '../tree/tree.dart' as tree; | 11 import '../tree/tree.dart' as tree; |
| 12 import '../scanner/scannerlib.dart'; | 12 import '../scanner/scannerlib.dart'; |
| 13 import '../util/util.dart'; | 13 import '../util/util.dart'; |
| 14 import 'backend_ast_nodes.dart'; | 14 import 'backend_ast_nodes.dart'; |
| 15 import 'backend_ast_emitter.dart' show createTypeAnnotation; | 15 import 'backend_ast_emitter.dart' show TypeGenerator; |
| 16 | 16 |
| 17 /// Translates the backend AST to Dart frontend AST. | 17 /// Translates the backend AST to Dart frontend AST. |
| 18 tree.Node emit(dart2js.TreeElementMapping treeElements, | 18 tree.Node emit(dart2js.TreeElementMapping treeElements, |
| 19 ExecutableDefinition definition) { | 19 ExecutableDefinition definition) { |
| 20 return new TreePrinter(treeElements).makeDefinition(definition); | 20 return new TreePrinter(treeElements).makeDefinition(definition); |
| 21 } | 21 } |
| 22 | 22 |
| 23 /// If true, the unparser will insert a coment in front of every function | 23 /// If true, the unparser will insert a coment in front of every function |
| 24 /// it emits. This helps indicate which functions were translated by the new | 24 /// it emits. This helps indicate which functions were translated by the new |
| 25 /// backend. | 25 /// backend. |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 final Token tryToken = makeIdToken('try'); | 131 final Token tryToken = makeIdToken('try'); |
| 132 final Token catchToken = makeIdToken('catch'); | 132 final Token catchToken = makeIdToken('catch'); |
| 133 final Token onToken = makeIdToken('on'); | 133 final Token onToken = makeIdToken('on'); |
| 134 final Token finallyToken = makeIdToken('finally'); | 134 final Token finallyToken = makeIdToken('finally'); |
| 135 final Token getToken = makeIdToken('get'); | 135 final Token getToken = makeIdToken('get'); |
| 136 final Token setToken = makeIdToken('set'); | 136 final Token setToken = makeIdToken('set'); |
| 137 final Token classToken = makeIdToken('class'); | 137 final Token classToken = makeIdToken('class'); |
| 138 final Token extendsToken = makeIdToken('extends'); | 138 final Token extendsToken = makeIdToken('extends'); |
| 139 final Token withToken = makeIdToken('with'); | 139 final Token withToken = makeIdToken('with'); |
| 140 final Token implementsToken = makeIdToken('implements'); | 140 final Token implementsToken = makeIdToken('implements'); |
| 141 final Token typedefToken = makeIdToken('typedef'); |
| 141 | 142 |
| 142 static tree.Identifier makeIdentifier(String name) { | 143 static tree.Identifier makeIdentifier(String name) { |
| 143 return new tree.Identifier( | 144 return new tree.Identifier( |
| 144 new StringToken.fromString(IDENTIFIER_INFO, name, -1)); | 145 new StringToken.fromString(IDENTIFIER_INFO, name, -1)); |
| 145 } | 146 } |
| 146 | 147 |
| 147 static tree.Operator makeOperator(String name) { | 148 static tree.Operator makeOperator(String name) { |
| 148 return new tree.Operator( | 149 return new tree.Operator( |
| 149 new StringToken.fromString(IDENTIFIER_INFO, name, -1)); | 150 new StringToken.fromString(IDENTIFIER_INFO, name, -1)); |
| 150 } | 151 } |
| (...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 } | 1013 } |
| 1013 | 1014 |
| 1014 tree.Node makeNodeForClassElement(elements.ClassElement cls) { | 1015 tree.Node makeNodeForClassElement(elements.ClassElement cls) { |
| 1015 if (cls.isMixinApplication) { | 1016 if (cls.isMixinApplication) { |
| 1016 return makeNamedMixinApplication(cls); | 1017 return makeNamedMixinApplication(cls); |
| 1017 } else { | 1018 } else { |
| 1018 return makeClassNode(cls); | 1019 return makeClassNode(cls); |
| 1019 } | 1020 } |
| 1020 } | 1021 } |
| 1021 | 1022 |
| 1023 tree.Typedef makeTypedef(elements.TypedefElement typdef) { |
| 1024 types.FunctionType functionType = typdef.alias; |
| 1025 final tree.TypeAnnotation returnType = |
| 1026 makeType(TypeGenerator.createType(functionType.returnType)); |
| 1027 |
| 1028 final tree.Identifier name = makeIdentifier(typdef.name); |
| 1029 final tree.NodeList typeParameters = |
| 1030 makeTypeParameters(typdef.typeVariables); |
| 1031 final tree.NodeList formals = |
| 1032 makeParameters(TypeGenerator.createParametersFromType(functionType)); |
| 1033 |
| 1034 final Token typedefKeyword = typedefToken; |
| 1035 final Token endToken = semicolon; |
| 1036 |
| 1037 return new tree.Typedef(returnType, name, typeParameters, formals, |
| 1038 typedefKeyword, endToken); |
| 1039 } |
| 1040 |
| 1022 /// Create a [tree.NodeList] containing the type variable declarations in | 1041 /// Create a [tree.NodeList] containing the type variable declarations in |
| 1023 /// [typeVaraiables. | 1042 /// [typeVaraiables. |
| 1024 tree.NodeList makeTypeParameters(List<types.DartType> typeVariables) { | 1043 tree.NodeList makeTypeParameters(List<types.DartType> typeVariables) { |
| 1025 if (typeVariables.isEmpty) { | 1044 if (typeVariables.isEmpty) { |
| 1026 return new tree.NodeList.empty(); | 1045 return new tree.NodeList.empty(); |
| 1027 } else { | 1046 } else { |
| 1028 List<tree.Node> typeVariableList = <tree.Node>[]; | 1047 List<tree.Node> typeVariableList = <tree.Node>[]; |
| 1029 for (types.TypeVariableType typeVariable in typeVariables) { | 1048 for (types.TypeVariableType typeVariable in typeVariables) { |
| 1030 tree.Node id = makeIdentifier(typeVariable.name); | 1049 tree.Node id = makeIdentifier(typeVariable.name); |
| 1031 treeElements[id] = typeVariable.element; | 1050 treeElements[id] = typeVariable.element; |
| 1032 tree.Node bound; | 1051 tree.Node bound; |
| 1033 if (!typeVariable.element.bound.isObject) { | 1052 if (!typeVariable.element.bound.isObject) { |
| 1034 bound = makeType(createTypeAnnotation(typeVariable.element.bound)); | 1053 bound = |
| 1054 makeType(TypeGenerator.createType(typeVariable.element.bound)); |
| 1035 } | 1055 } |
| 1036 tree.TypeVariable node = new tree.TypeVariable(id, bound); | 1056 tree.TypeVariable node = new tree.TypeVariable(id, bound); |
| 1037 treeElements.setType(node, typeVariable); | 1057 treeElements.setType(node, typeVariable); |
| 1038 typeVariableList.add(node); | 1058 typeVariableList.add(node); |
| 1039 } | 1059 } |
| 1040 return makeList(',', typeVariableList, open: lt, close: gt); | 1060 return makeList(',', typeVariableList, open: lt, close: gt); |
| 1041 } | 1061 } |
| 1042 } | 1062 } |
| 1043 | 1063 |
| 1044 /// Create a [tree.NodeList] containing the declared interfaces. | 1064 /// Create a [tree.NodeList] containing the declared interfaces. |
| 1045 /// | 1065 /// |
| 1046 /// [interfaces] is from [elements.ClassElement] in reverse declaration order | 1066 /// [interfaces] is from [elements.ClassElement] in reverse declaration order |
| 1047 /// and it contains mixins. To produce a list of the declared interfaces only, | 1067 /// and it contains mixins. To produce a list of the declared interfaces only, |
| 1048 /// interfaces in [mixinTypes] are omitted. | 1068 /// interfaces in [mixinTypes] are omitted. |
| 1049 /// | 1069 /// |
| 1050 /// [forNamedMixinApplication] is because the structure of the [tree.NodeList] | 1070 /// [forNamedMixinApplication] is because the structure of the [tree.NodeList] |
| 1051 /// differs between [tree.NamedMixinApplication] and [tree.ClassNode]. | 1071 /// differs between [tree.NamedMixinApplication] and [tree.ClassNode]. |
| 1052 // TODO(johnniwinther): Normalize interfaces on[tree.NamedMixinApplication] | 1072 // TODO(johnniwinther): Normalize interfaces on[tree.NamedMixinApplication] |
| 1053 // and [tree.ClassNode]. | 1073 // and [tree.ClassNode]. |
| 1054 tree.NodeList makeInterfaces(Link<types.DartType> interfaces, | 1074 tree.NodeList makeInterfaces(Link<types.DartType> interfaces, |
| 1055 Set<types.DartType> mixinTypes, | 1075 Set<types.DartType> mixinTypes, |
| 1056 {bool forNamedMixinApplication: false}) { | 1076 {bool forNamedMixinApplication: false}) { |
| 1057 Link<tree.Node> typeAnnotations = const Link<tree.Node>(); | 1077 Link<tree.Node> typeAnnotations = const Link<tree.Node>(); |
| 1058 for (Link<types.DartType> link = interfaces; | 1078 for (Link<types.DartType> link = interfaces; |
| 1059 !link.isEmpty; | 1079 !link.isEmpty; |
| 1060 link = link.tail) { | 1080 link = link.tail) { |
| 1061 types.DartType interface = link.head; | 1081 types.DartType interface = link.head; |
| 1062 if (!mixinTypes.contains(interface)) { | 1082 if (!mixinTypes.contains(interface)) { |
| 1063 typeAnnotations = | 1083 typeAnnotations = typeAnnotations.prepend( |
| 1064 typeAnnotations.prepend(makeType(createTypeAnnotation(interface))); | 1084 makeType(TypeGenerator.createType(interface))); |
| 1065 } | 1085 } |
| 1066 } | 1086 } |
| 1067 if (typeAnnotations.isEmpty) { | 1087 if (typeAnnotations.isEmpty) { |
| 1068 return forNamedMixinApplication ? null : new tree.NodeList.empty(); | 1088 return forNamedMixinApplication ? null : new tree.NodeList.empty(); |
| 1069 } else { | 1089 } else { |
| 1070 return new tree.NodeList( | 1090 return new tree.NodeList( |
| 1071 forNamedMixinApplication ? null : implementsToken, | 1091 forNamedMixinApplication ? null : implementsToken, |
| 1072 typeAnnotations, null, ','); | 1092 typeAnnotations, null, ','); |
| 1073 } | 1093 } |
| 1074 } | 1094 } |
| 1075 | 1095 |
| 1076 /// Creates a [tree.NamedMixinApplication] node for [cls]. | 1096 /// Creates a [tree.NamedMixinApplication] node for [cls]. |
| 1077 // TODO(johnniwinther): Unify creation of mixin lists between | 1097 // TODO(johnniwinther): Unify creation of mixin lists between |
| 1078 // [NamedMixinApplicationElement] and [ClassElement]. | 1098 // [NamedMixinApplicationElement] and [ClassElement]. |
| 1079 tree.NamedMixinApplication makeNamedMixinApplication( | 1099 tree.NamedMixinApplication makeNamedMixinApplication( |
| 1080 elements.MixinApplicationElement cls) { | 1100 elements.MixinApplicationElement cls) { |
| 1081 | 1101 |
| 1082 assert(dart2js.invariant(cls, !cls.isUnnamedMixinApplication, | 1102 assert(dart2js.invariant(cls, !cls.isUnnamedMixinApplication, |
| 1083 message: "Cannot create ClassNode for unnamed mixin application " | 1103 message: "Cannot create ClassNode for unnamed mixin application " |
| 1084 "$cls.")); | 1104 "$cls.")); |
| 1085 tree.Modifiers modifiers = makeModifiers(isAbstract: cls.isAbstract); | 1105 tree.Modifiers modifiers = makeModifiers(isAbstract: cls.isAbstract); |
| 1086 tree.Identifier name = makeIdentifier(cls.name); | 1106 tree.Identifier name = makeIdentifier(cls.name); |
| 1087 tree.NodeList typeParameters = makeTypeParameters(cls.typeVariables); | 1107 tree.NodeList typeParameters = makeTypeParameters(cls.typeVariables); |
| 1088 | 1108 |
| 1089 Set<types.DartType> mixinTypes = new Set<types.DartType>(); | 1109 Set<types.DartType> mixinTypes = new Set<types.DartType>(); |
| 1090 Link<tree.Node> mixins = const Link<tree.Node>(); | 1110 Link<tree.Node> mixins = const Link<tree.Node>(); |
| 1091 | 1111 |
| 1092 void addMixin(types.DartType mixinType) { | 1112 void addMixin(types.DartType mixinType) { |
| 1093 mixinTypes.add(mixinType); | 1113 mixinTypes.add(mixinType); |
| 1094 mixins = mixins.prepend(makeType(createTypeAnnotation(mixinType))); | 1114 mixins = mixins.prepend(makeType(TypeGenerator.createType(mixinType))); |
| 1095 } | 1115 } |
| 1096 | 1116 |
| 1097 addMixin(cls.mixinType); | 1117 addMixin(cls.mixinType); |
| 1098 | 1118 |
| 1099 tree.Node superclass; | 1119 tree.Node superclass; |
| 1100 types.InterfaceType supertype = cls.supertype; | 1120 types.InterfaceType supertype = cls.supertype; |
| 1101 while (supertype.element.isUnnamedMixinApplication) { | 1121 while (supertype.element.isUnnamedMixinApplication) { |
| 1102 elements.MixinApplicationElement mixinApplication = supertype.element; | 1122 elements.MixinApplicationElement mixinApplication = supertype.element; |
| 1103 addMixin(cls.asInstanceOf(mixinApplication.mixin)); | 1123 addMixin(cls.asInstanceOf(mixinApplication.mixin)); |
| 1104 supertype = mixinApplication.supertype; | 1124 supertype = mixinApplication.supertype; |
| 1105 } | 1125 } |
| 1106 superclass = | 1126 superclass = |
| 1107 makeType(createTypeAnnotation(cls.asInstanceOf(supertype.element))); | 1127 makeType(TypeGenerator.createType(cls.asInstanceOf(supertype.element))); |
| 1108 tree.Node supernode = new tree.MixinApplication( | 1128 tree.Node supernode = new tree.MixinApplication( |
| 1109 superclass, new tree.NodeList(null, mixins, null, ',')); | 1129 superclass, new tree.NodeList(null, mixins, null, ',')); |
| 1110 | 1130 |
| 1111 tree.NodeList interfaces = makeInterfaces( | 1131 tree.NodeList interfaces = makeInterfaces( |
| 1112 cls.interfaces, mixinTypes, forNamedMixinApplication: true); | 1132 cls.interfaces, mixinTypes, forNamedMixinApplication: true); |
| 1113 | 1133 |
| 1114 return new tree.NamedMixinApplication( | 1134 return new tree.NamedMixinApplication( |
| 1115 name, typeParameters, modifiers, supernode, | 1135 name, typeParameters, modifiers, supernode, |
| 1116 interfaces, classToken, semicolon); | 1136 interfaces, classToken, semicolon); |
| 1117 } | 1137 } |
| 1118 | 1138 |
| 1119 /// Creates a [tree.ClassNode] node for [cls]. | 1139 /// Creates a [tree.ClassNode] node for [cls]. |
| 1120 tree.ClassNode makeClassNode(elements.ClassElement cls) { | 1140 tree.ClassNode makeClassNode(elements.ClassElement cls) { |
| 1121 assert(dart2js.invariant(cls, !cls.isUnnamedMixinApplication, | 1141 assert(dart2js.invariant(cls, !cls.isUnnamedMixinApplication, |
| 1122 message: "Cannot create ClassNode for unnamed mixin application " | 1142 message: "Cannot create ClassNode for unnamed mixin application " |
| 1123 "$cls.")); | 1143 "$cls.")); |
| 1124 tree.Modifiers modifiers = makeModifiers(isAbstract: cls.isAbstract); | 1144 tree.Modifiers modifiers = makeModifiers(isAbstract: cls.isAbstract); |
| 1125 tree.Identifier name = makeIdentifier(cls.name); | 1145 tree.Identifier name = makeIdentifier(cls.name); |
| 1126 tree.NodeList typeParameters = makeTypeParameters(cls.typeVariables); | 1146 tree.NodeList typeParameters = makeTypeParameters(cls.typeVariables); |
| 1127 tree.Node supernode; | 1147 tree.Node supernode; |
| 1128 types.InterfaceType supertype = cls.supertype; | 1148 types.InterfaceType supertype = cls.supertype; |
| 1129 Set<types.DartType> mixinTypes = new Set<types.DartType>(); | 1149 Set<types.DartType> mixinTypes = new Set<types.DartType>(); |
| 1130 Link<tree.Node> mixins = const Link<tree.Node>(); | 1150 Link<tree.Node> mixins = const Link<tree.Node>(); |
| 1131 | 1151 |
| 1132 void addMixin(types.DartType mixinType) { | 1152 void addMixin(types.DartType mixinType) { |
| 1133 mixinTypes.add(mixinType); | 1153 mixinTypes.add(mixinType); |
| 1134 mixins = mixins.prepend(makeType(createTypeAnnotation(mixinType))); | 1154 mixins = mixins.prepend(makeType(TypeGenerator.createType(mixinType))); |
| 1135 } | 1155 } |
| 1136 | 1156 |
| 1137 if (supertype != null) { | 1157 if (supertype != null) { |
| 1138 tree.Node superclass; | 1158 tree.Node superclass; |
| 1139 if (supertype.element.isUnnamedMixinApplication) { | 1159 if (supertype.element.isUnnamedMixinApplication) { |
| 1140 while (supertype.element.isUnnamedMixinApplication) { | 1160 while (supertype.element.isUnnamedMixinApplication) { |
| 1141 elements.MixinApplicationElement mixinApplication = supertype.element; | 1161 elements.MixinApplicationElement mixinApplication = supertype.element; |
| 1142 addMixin(cls.asInstanceOf(mixinApplication.mixin)); | 1162 addMixin(cls.asInstanceOf(mixinApplication.mixin)); |
| 1143 supertype = mixinApplication.supertype; | 1163 supertype = mixinApplication.supertype; |
| 1144 } | 1164 } |
| 1145 tree.Node superclass = | 1165 tree.Node superclass = makeType( |
| 1146 makeType(createTypeAnnotation(cls.asInstanceOf(supertype.element))); | 1166 TypeGenerator.createType(cls.asInstanceOf(supertype.element))); |
| 1147 supernode = new tree.MixinApplication( | 1167 supernode = new tree.MixinApplication( |
| 1148 superclass, new tree.NodeList(null, mixins, null, ',')); | 1168 superclass, new tree.NodeList(null, mixins, null, ',')); |
| 1149 } else if (!supertype.isObject) { | 1169 } else if (!supertype.isObject) { |
| 1150 supernode = makeType(createTypeAnnotation(supertype)); | 1170 supernode = makeType(TypeGenerator.createType(supertype)); |
| 1151 } | 1171 } |
| 1152 } | 1172 } |
| 1153 tree.NodeList interfaces = makeInterfaces( | 1173 tree.NodeList interfaces = makeInterfaces( |
| 1154 cls.interfaces, mixinTypes); | 1174 cls.interfaces, mixinTypes); |
| 1155 | 1175 |
| 1156 Token extendsKeyword = supernode != null ? extendsToken : null; | 1176 Token extendsKeyword = supernode != null ? extendsToken : null; |
| 1157 return new tree.ClassNode( | 1177 return new tree.ClassNode( |
| 1158 modifiers, name, typeParameters, supernode, | 1178 modifiers, name, typeParameters, supernode, |
| 1159 interfaces, openBrace, extendsKeyword, | 1179 interfaces, openBrace, extendsKeyword, |
| 1160 null, // No body. | 1180 null, // No body. |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1244 printStringChunk(chunk.previous), | 1264 printStringChunk(chunk.previous), |
| 1245 node); | 1265 node); |
| 1246 } else { | 1266 } else { |
| 1247 return node; | 1267 return node; |
| 1248 } | 1268 } |
| 1249 } | 1269 } |
| 1250 return printStringChunk(output.chunk); | 1270 return printStringChunk(output.chunk); |
| 1251 } | 1271 } |
| 1252 | 1272 |
| 1253 } | 1273 } |
| OLD | NEW |