Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: pkg/fasta/lib/src/source/source_library_builder.dart

Issue 2627223005: Fasta source builders. (Closed)
Patch Set: Add TODO about shared interface. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/fasta/lib/src/source/source_class_builder.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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.source_library_builder;
6
7 import 'package:kernel/ast.dart' show
8 AsyncMarker,
9 ProcedureKind;
10
11 import '../combinator.dart' show
12 Combinator;
13
14 import '../errors.dart' show
15 inputError,
16 internalError;
17
18 import '../import.dart' show
19 Import;
20
21 import 'source_loader.dart' show
22 SourceLoader;
23
24 import '../builder/scope.dart' show
25 Scope;
26
27 import '../builder/builder.dart' show
28 Builder,
29 ClassBuilder,
30 ConstructorReferenceBuilder,
31 EnumBuilder,
32 FieldBuilder,
33 FormalParameterBuilder,
34 FunctionTypeAliasBuilder,
35 LibraryBuilder,
36 MemberBuilder,
37 MetadataBuilder,
38 NamedMixinApplicationBuilder,
39 PrefixBuilder,
40 ProcedureBuilder,
41 TypeBuilder,
42 TypeDeclarationBuilder,
43 TypeVariableBuilder,
44 Unhandled;
45
46 abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
47 extends LibraryBuilder<T, R> {
48 final SourceLoader loader;
49
50 final Map<String, Builder> members = <String, Builder>{};
51
52 final List<T> types = <T>[];
53
54 final List<ConstructorReferenceBuilder> constructorReferences =
55 <ConstructorReferenceBuilder>[];
56
57 final List<LibraryBuilder> parts = <LibraryBuilder>[];
58
59 final List<Import> imports = <Import>[];
60
61 final Map<String, Builder> exports = <String, Builder>{};
62
63 final Scope scope = new Scope(<String, Builder>{}, null, isModifiable: false);
64
65 String name;
66
67 String partOf;
68
69 Uri fileUri;
70
71 List<MetadataBuilder> metadata;
72
73 Map<String, MemberBuilder> classMembers;
74
75 // TODO(ahe): Rename this. It's not just for classes.
76 List<T> classTypes;
77
78 SourceLibraryBuilder(this.loader);
79
80 Uri get uri;
81
82 bool get isPart => partOf != null;
83
84 T addInterfaceType(String name, List<T> arguments);
85
86 T addMixinApplication(T supertype, List<T> mixins);
87
88 T addType(T type) {
89 List<T> types = classTypes ?? this.types;
90 types.add(type);
91 return type;
92 }
93
94 T addVoidType();
95
96 ConstructorReferenceBuilder addConstructorReference(
97 String name, List<T> typeArguments, String suffix) {
98 ConstructorReferenceBuilder ref =
99 new ConstructorReferenceBuilder(name, typeArguments, suffix);
100 constructorReferences.add(ref);
101 return ref;
102 }
103
104 void beginNestedScope() {
105 classMembers = <String, MemberBuilder>{};
106 classTypes = <T>[];
107 }
108
109 void endNestedScope() {
110 classMembers = null;
111 classTypes = null;
112 }
113
114 Uri resolve(String path) => uri.resolve(path);
115
116 void addExport(List<MetadataBuilder> metadata, String uri,
117 Unhandled conditionalUris, List<Combinator> combinators) {
118 loader.read(resolve(uri)).addExporter(this, combinators);
119 }
120
121 void addImport(List<MetadataBuilder> metadata, String uri,
122 Unhandled conditionalUris, String prefix, List<Combinator> combinators,
123 bool deferred) {
124 imports.add(new Import(loader.read(resolve(uri)), prefix, combinators));
125 }
126
127 void addPart(List<MetadataBuilder> metadata, String uri) {
128 parts.add(loader.read(resolve(uri)));
129 }
130
131 void addPartOf(List<MetadataBuilder> metadata, String name) {
132 partOf = name;
133 }
134
135 ClassBuilder addClass(List<MetadataBuilder> metadata,
136 int modifiers, String name,
137 List<TypeVariableBuilder> typeVariables, T supertype,
138 List<T> interfaces);
139
140 NamedMixinApplicationBuilder addNamedMixinApplication(
141 List<MetadataBuilder> metadata, String name,
142 List<TypeVariableBuilder> typeVariables, int modifiers,
143 T mixinApplication, List<T> interfaces);
144
145 FieldBuilder addField(List<MetadataBuilder> metadata,
146 int modifiers, T type, String name);
147
148 void addFields(List<MetadataBuilder> metadata, int modifiers,
149 T type, List<String> names) {
150 for (String name in names) {
151 addField(metadata, modifiers, type, name);
152 }
153 }
154
155 ProcedureBuilder addProcedure(List<MetadataBuilder> metadata,
156 int modifiers, T returnType, String name,
157 List<TypeVariableBuilder> typeVariables,
158 List<FormalParameterBuilder> formals, AsyncMarker asyncModifier,
159 ProcedureKind kind);
160
161 EnumBuilder addEnum(List<MetadataBuilder> metadata, String name,
162 List<String> constants);
163
164 FunctionTypeAliasBuilder addFunctionTypeAlias(List<MetadataBuilder> metadata,
165 T returnType, String name,
166 List<TypeVariableBuilder> typeVariables,
167 List<FormalParameterBuilder> formals);
168
169 void addFactoryMethod(List<MetadataBuilder> metadata,
170 ConstructorReferenceBuilder name, List<FormalParameterBuilder> formals,
171 AsyncMarker asyncModifier, ConstructorReferenceBuilder redirectionTarget);
172
173 FormalParameterBuilder addFormalParameter(
174 List<MetadataBuilder> metadata, int modifiers,
175 T type, String name, bool hasThis);
176
177 TypeVariableBuilder addTypeVariable(String name, T bound);
178
179 Builder addBuilder(String name, Builder builder) {
180 // TODO(ahe): Set the parent correctly here. Could then change the
181 // implementation of MemberBuilder.isTopLevel to test explicitly for a
182 // LibraryBuilder.
183 if (classMembers == null) {
184 if (builder is MemberBuilder) {
185 builder.parent = this;
186 } else if (builder is TypeDeclarationBuilder) {
187 builder.parent = this;
188 } else if (builder is PrefixBuilder) {
189 assert(builder.parent == this);
190 } else {
191 return internalError("Unhandled: ${builder.runtimeType}");
192 }
193 }
194 Map<String, Builder> members = classMembers ?? this.members;
195 Builder existing = members[name];
196 builder.next = existing;
197 if (builder is PrefixBuilder && existing is PrefixBuilder) {
198 assert(existing.next == null);
199 builder.exports.forEach((String name, Builder builder) {
200 Builder other = existing.exports.putIfAbsent(name, () => builder);
201 if (other != builder) {
202 existing.exports[name] =
203 other.combineAmbiguousImport(name, builder, this);
204 }
205 });
206 return existing;
207 } else if (existing != null && (existing.next != null ||
208 ((!existing.isGetter || !builder.isSetter) &&
209 (!existing.isSetter || !builder.isGetter)))) {
210 return inputError(uri, -1, "Duplicated definition of $name");
211 }
212 return members[name] = builder;
213 }
214
215 void buildBuilder(Builder builder);
216
217 R build() {
218 members.forEach((String name, Builder builder) {
219 do {
220 buildBuilder(builder);
221 builder = builder.next;
222 } while (builder != null);
223 });
224 return null;
225 }
226
227 void validatePart() {
228 if (parts.isNotEmpty) {
229 internalError("Part with parts: $uri");
230 }
231 if (exporters.isNotEmpty) {
232 internalError(
233 "${exporters.first.exporter.uri} attempts to export the part $uri.");
234 }
235 }
236
237 void includeParts() {
238 for (LibraryBuilder part in parts.toList()) {
239 includePart(part);
240 }
241 }
242
243 void includePart(SourceLibraryBuilder part) {
244 if (name != null) {
245 if (part.partOf == null) {
246 print("${part.uri} has no 'part of' declaration but is used as a part "
247 "by ${name} ($uri)");
248 parts.remove(part);
249 return;
250 }
251 if (part.partOf != name) {
252 print("${part.uri} is part of '${part.partOf}' but is used as a part "
253 "by '${name}' ($uri)");
254 parts.remove(part);
255 return;
256 }
257 }
258 part.members.forEach(addBuilder);
259 types.addAll(part.types);
260 constructorReferences.addAll(part.constructorReferences);
261 part.partOfLibrary = this;
262 // TODO(ahe): Include metadata from part?
263 }
264
265 void buildInitialScopes() {
266 members.forEach(addToExportScope);
267 members.forEach(addToScope);
268 }
269
270 void addImportsToScope() {
271 bool explicitCoreImport = this == loader.coreLibrary;
272 for (Import import in imports) {
273 if (import.imported == loader.coreLibrary) {
274 explicitCoreImport = true;
275 }
276 import.finalizeImports(this);
277 }
278 if (!explicitCoreImport) {
279 loader.coreLibrary.exports.forEach(addToScope);
280 }
281 }
282
283 void addToScope(String name, Builder member) {
284 Builder existing = scope.lookup(name);
285 if (existing != null) {
286 if (existing != member) {
287 scope.local[name] = existing.combineAmbiguousImport(name, member, this);
288 }
289 // TODO(ahe): handle duplicated names.
290 } else {
291 scope.local[name] = member;
292 }
293 }
294
295 bool addToExportScope(String name, Builder member) {
296 if (name.startsWith("_")) return false;
297 if (member is PrefixBuilder) return false;
298 Builder existing = exports[name];
299 if (existing != null) {
300 // TODO(ahe): handle duplicated names.
301 return false;
302 } else {
303 exports[name] = member;
304 }
305 return true;
306 }
307
308 int resolveTypes(_) {
309 int typeCount = types.length;
310 for (T t in types) {
311 t.resolveIn(scope);
312 }
313 members.forEach((String name, Builder member) {
314 typeCount += member.resolveTypes(this);
315 });
316 return typeCount;
317 }
318
319 int convertConstructors(_) {
320 int count = 0;
321 members.forEach((String name, Builder member) {
322 count += member.convertConstructors(this);
323 });
324 return count;
325 }
326
327 int resolveConstructors(_) {
328 int count = 0;
329 members.forEach((String name, Builder member) {
330 count += member.resolveConstructors(this);
331 });
332 return count;
333 }
334 }
OLDNEW
« no previous file with comments | « pkg/fasta/lib/src/source/source_class_builder.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698