OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library fasta.kernel_library_builder; | |
6 | |
7 import 'package:kernel/ast.dart'; | |
8 | |
9 import 'package:kernel/clone.dart' show | |
10 CloneVisitor; | |
11 | |
12 import '../errors.dart' show | |
13 internalError; | |
14 | |
15 import '../loader.dart' show | |
16 Loader; | |
17 | |
18 import '../modifier.dart' show | |
19 staticMask; | |
20 | |
21 import '../source/source_library_builder.dart' show | |
22 SourceLibraryBuilder; | |
23 | |
24 import '../source/source_class_builder.dart' show | |
25 SourceClassBuilder; | |
26 | |
27 import 'kernel_builder.dart' show | |
28 Builder, | |
29 ClassBuilder, | |
30 ConstructorReferenceBuilder, | |
31 DynamicTypeBuilder, | |
32 EnumBuilder, | |
33 FieldBuilder, | |
34 FormalParameterBuilder, | |
35 FunctionTypeAliasBuilder, | |
36 KernelEnumBuilder, | |
37 KernelFieldBuilder, | |
38 KernelFormalParameterBuilder, | |
39 KernelFunctionTypeAliasBuilder, | |
40 KernelInterfaceTypeBuilder, | |
41 KernelInvalidTypeBuilder, | |
42 KernelMixinApplicationBuilder, | |
43 KernelNamedMixinApplicationBuilder, | |
44 KernelProcedureBuilder, | |
45 KernelTypeBuilder, | |
46 KernelTypeVariableBuilder, | |
47 MemberBuilder, | |
48 MetadataBuilder, | |
49 MixedAccessor, | |
50 NamedMixinApplicationBuilder, | |
51 PrefixBuilder, | |
52 ProcedureBuilder, | |
53 TypeVariableBuilder; | |
54 | |
55 class KernelLibraryBuilder | |
56 extends SourceLibraryBuilder<KernelTypeBuilder, Library> { | |
57 final Library library; | |
58 | |
59 final List<Class> mixinApplicationClasses = <Class>[]; | |
60 | |
61 final List<List> argumentsWithMissingDefaultValues = <List>[]; | |
62 | |
63 KernelLibraryBuilder(Uri uri, Loader loader) | |
64 : library = new Library(uri), | |
65 super(loader); | |
66 | |
67 Uri get uri => library.importUri; | |
68 | |
69 KernelTypeBuilder addInterfaceType(String name, | |
70 List<KernelTypeBuilder> arguments) { | |
71 KernelInterfaceTypeBuilder type = | |
72 new KernelInterfaceTypeBuilder(name, arguments); | |
73 if (identical(name, "dynamic")) { | |
74 // TODO(ahe): Make const. | |
75 type.builder = new DynamicTypeBuilder(const DynamicType()); | |
76 } else { | |
77 addType(type); | |
78 } | |
79 return type; | |
80 } | |
81 | |
82 KernelTypeBuilder addMixinApplication(KernelTypeBuilder supertype, | |
83 List<KernelTypeBuilder> mixins) { | |
84 KernelTypeBuilder type = | |
85 new KernelMixinApplicationBuilder(supertype, mixins); | |
86 return addType(type); | |
87 } | |
88 | |
89 KernelTypeBuilder addVoidType() { | |
90 return new KernelInterfaceTypeBuilder("void", null); | |
91 } | |
92 | |
93 ClassBuilder addClass(List<MetadataBuilder> metadata, | |
94 int modifiers, String className, | |
95 List<TypeVariableBuilder> typeVariables, KernelTypeBuilder supertype, | |
96 List<KernelTypeBuilder> interfaces) { | |
97 ClassBuilder cls = new SourceClassBuilder(metadata, modifiers, className, | |
98 typeVariables, supertype, interfaces, classMembers, classTypes, this, | |
99 new List<ConstructorReferenceBuilder>.from(constructorReferences)); | |
100 constructorReferences.clear(); | |
101 classMembers.forEach((String name, MemberBuilder builder) { | |
102 while (builder != null) { | |
103 builder.parent = cls; | |
104 builder = builder.next; | |
105 } | |
106 }); | |
107 endNestedScope(); | |
Johnni Winther
2017/01/18 12:42:40
Add a comment of where the nested scope begins, i.
ahe
2017/01/18 15:21:50
Done.
| |
108 return addBuilder(className, cls); | |
109 } | |
110 | |
111 NamedMixinApplicationBuilder addNamedMixinApplication( | |
112 List<MetadataBuilder> metadata, String name, | |
113 List<TypeVariableBuilder> typeVariables, int modifiers, | |
114 KernelTypeBuilder mixinApplication, List<KernelTypeBuilder> interfaces) { | |
115 NamedMixinApplicationBuilder builder = | |
116 new KernelNamedMixinApplicationBuilder(metadata, name, typeVariables, | |
117 modifiers, mixinApplication, interfaces, classTypes, this); | |
118 endNestedScope(); | |
119 return addBuilder(name, builder); | |
120 } | |
121 | |
122 FieldBuilder addField(List<MetadataBuilder> metadata, | |
123 int modifiers, KernelTypeBuilder type, String name) { | |
124 return addBuilder(name, | |
125 new KernelFieldBuilder(metadata, type, name, modifiers)); | |
126 } | |
127 | |
128 ProcedureBuilder addProcedure(List<MetadataBuilder> metadata, | |
129 int modifiers, KernelTypeBuilder returnType, String name, | |
130 List<TypeVariableBuilder> typeVariables, | |
131 List<FormalParameterBuilder> formals, AsyncMarker asyncModifier, | |
132 ProcedureKind kind) { | |
133 return addBuilder(name, | |
134 new KernelProcedureBuilder(metadata, modifiers, returnType, name, | |
135 typeVariables, formals, asyncModifier, kind)); | |
136 } | |
137 | |
138 void addFactoryMethod(List<MetadataBuilder> metadata, | |
139 ConstructorReferenceBuilder constructorName, | |
140 List<FormalParameterBuilder> formals, AsyncMarker asyncModifier, | |
141 ConstructorReferenceBuilder redirectionTarget) { | |
142 String name = constructorName.name; | |
143 assert(constructorName.suffix == null); | |
144 addBuilder(name, | |
145 new KernelProcedureBuilder(metadata, staticMask, null, name, null, | |
146 formals, asyncModifier, ProcedureKind.Factory, redirectionTarget)); | |
147 } | |
148 | |
149 EnumBuilder addEnum(List<MetadataBuilder> metadata, String name, | |
150 List<String> constants) { | |
151 return addBuilder(name, | |
152 new KernelEnumBuilder(metadata, name, constants, this)); | |
153 } | |
154 | |
155 FunctionTypeAliasBuilder addFunctionTypeAlias(List<MetadataBuilder> metadata, | |
156 KernelTypeBuilder returnType, String name, | |
157 List<TypeVariableBuilder> typeVariables, | |
158 List<FormalParameterBuilder> formals) { | |
159 FunctionTypeAliasBuilder typedef = new KernelFunctionTypeAliasBuilder( | |
160 metadata, returnType, name, typeVariables, formals, classTypes, this); | |
161 endNestedScope(); | |
162 return addBuilder(name, typedef); | |
163 } | |
164 | |
165 KernelFormalParameterBuilder addFormalParameter( | |
166 List<MetadataBuilder> metadata, int modifiers, | |
167 KernelTypeBuilder type, String name, bool hasThis) { | |
168 return new KernelFormalParameterBuilder( | |
169 metadata, modifiers, type, name, hasThis); | |
170 } | |
171 | |
172 KernelTypeVariableBuilder addTypeVariable(String name, | |
173 KernelTypeBuilder bound) { | |
174 return new KernelTypeVariableBuilder(name, bound); | |
175 } | |
176 | |
177 void buildBuilder(Builder builder) { | |
178 if (builder is SourceClassBuilder) { | |
179 Class cls = builder.build(this); | |
180 library.addClass(cls); | |
181 Class superclass = cls.superclass; | |
182 if (superclass != null && superclass.isMixinApplication) { | |
183 List<Class> mixinApplications = <Class>[]; | |
184 mixinApplicationClasses.add(cls); | |
185 while (superclass != null && superclass.isMixinApplication) { | |
186 if (superclass.parent == null) { | |
187 mixinApplications.add(superclass); | |
188 } | |
189 superclass = superclass.superclass; | |
190 } | |
191 for (Class cls in mixinApplications.reversed) { | |
192 // TODO(ahe): Should be able to move this into the above loop as long | |
193 // as we don't care about matching dartk perfectly. | |
194 library.addClass(cls); | |
195 mixinApplicationClasses.add(cls); | |
196 } | |
197 } | |
198 } else if (builder is KernelFieldBuilder) { | |
199 library.addMember(builder.build(library)); | |
Johnni Winther
2017/01/18 12:42:40
Shouldn't this be tagged as static?
ahe
2017/01/18 15:21:50
Done.
| |
200 } else if (builder is KernelProcedureBuilder) { | |
201 library.addMember(builder.build(library)..isStatic = true); | |
Johnni Winther
2017/01/18 12:42:40
Shouldn't `isStatic = true` be given to the Kernel
ahe
2017/01/18 15:21:50
Not sure. Perhaps `isTopLevel = true`. Kernel mark
| |
202 } else if (builder is FunctionTypeAliasBuilder) { | |
203 // Kernel discard typedefs and use their corresponding function types | |
204 // directly. | |
205 } else if (builder is KernelEnumBuilder) { | |
206 library.addClass(builder.build(this)); | |
207 } else if (builder is PrefixBuilder) { | |
208 // Ignored. Kernel doesn't represent prefixes. | |
209 } else { | |
210 internalError("Unhandled builder: ${builder.runtimeType}"); | |
211 } | |
212 } | |
213 | |
214 Library build() { | |
215 super.build(); | |
216 library.name = name; | |
217 // TODO(ahe): Set fileUri. | |
218 // library.fileUri = "${fileUri ?? uri}"; | |
219 return library; | |
220 } | |
221 | |
222 Builder buildAmbiguousBuilder( | |
223 String name, Builder builder, Builder other) { | |
224 if (builder.next == null && other.next == null) { | |
225 if (builder.isGetter && other.isSetter) { | |
226 return new MixedAccessor(builder, other); | |
227 } else if (builder.isSetter && other.isGetter) { | |
228 return new MixedAccessor(other, builder); | |
229 } | |
230 } | |
231 return new KernelInvalidTypeBuilder(name, this); | |
232 } | |
233 | |
234 void addArgumentsWithMissingDefaultValues(Arguments arguments, | |
235 FunctionNode function) { | |
236 assert(partOfLibrary == null); | |
237 argumentsWithMissingDefaultValues.add([arguments, function]); | |
238 } | |
239 | |
240 int finishStaticInvocations() { | |
241 CloneVisitor cloner; | |
242 for (var list in argumentsWithMissingDefaultValues) { | |
243 final Arguments arguments = list[0]; | |
244 final FunctionNode function = list[1]; | |
245 | |
246 Expression defaultArgumentFrom(Expression expression) { | |
247 if (expression == null) { | |
248 return new NullLiteral(); | |
249 } | |
250 cloner ??= new CloneVisitor(); | |
251 return cloner.clone(expression); | |
252 } | |
253 | |
254 for (int i = function.requiredParameterCount; i < function.positionalParam eters.length; i++) { | |
Johnni Winther
2017/01/18 12:42:40
Long lines.
ahe
2017/01/18 15:21:50
Done.
| |
255 arguments.positional[i] ??= defaultArgumentFrom(function.positionalParam eters[i].initializer) | |
256 ..parent = arguments; | |
257 } | |
258 Map<String, VariableDeclaration> names; | |
259 for (NamedExpression expression in arguments.named) { | |
260 if (expression.value == null) { | |
261 if (names == null) { | |
262 names = <String, VariableDeclaration>{}; | |
263 for (VariableDeclaration parameter in function.namedParameters) { | |
264 names[parameter.name] = parameter; | |
265 } | |
266 } | |
267 expression.value = | |
268 defaultArgumentFrom(names[expression.name].initializer) | |
269 ..parent = expression; | |
270 } | |
271 } | |
272 } | |
273 return argumentsWithMissingDefaultValues.length; | |
274 } | |
275 } | |
OLD | NEW |