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

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

Issue 2623033007: Fasta targets and loaders. (Closed)
Patch Set: 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
« pkg/fasta/lib/src/loader.dart ('K') | « pkg/fasta/lib/src/loader.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_loader;
6
7 import 'dart:async' show
8 Future;
9
10 import 'dart:io' show
11 FileSystemException;
12
13 import 'package:dart_scanner/io.dart' show
14 readBytesFromFile;
15
16 import 'package:dart_scanner/src/token.dart' show
17 Token;
18
19 import 'package:dart_scanner/dart_scanner.dart' show
20 scan;
21
22 import 'package:dart_parser/src/class_member_parser.dart' show
23 ClassMemberParser;
24
25 import 'package:kernel/ast.dart' show
26 Program;
27
28 import 'package:kernel/class_hierarchy.dart' show
29 ClassHierarchy;
30
31 import 'package:kernel/core_types.dart' show
32 CoreTypes;
33
34 import '../errors.dart' show
35 inputError;
36
37 import '../export.dart' show
38 Export;
39
40 import '../analyzer/element_store.dart' show
41 ElementStore;
42
43 import '../builder/builder.dart' show
44 Builder,
45 ClassBuilder,
46 LibraryBuilder;
47
48 import 'outline_builder.dart' show
49 OutlineBuilder;
50
51 import '../loader.dart' show
52 Loader;
53
54 import '../target_implementation.dart' show
55 TargetImplementation;
56
57 import 'diet_listener.dart' show
58 DietListener;
59
60 import 'diet_parser.dart' show
61 DietParser;
62
63 import 'source_library_builder.dart' show
64 SourceLibraryBuilder;
65
66 import '../ast_kind.dart' show
67 AstKind;
68
69 class SourceLoader<L> extends Loader<L> {
70 // Used when building directly to kernel.
71 ClassHierarchy hierarchy;
72 CoreTypes coreTypes;
73
74 // Used when building analyzer ASTs.
75 ElementStore elementStore;
76
77 SourceLoader(TargetImplementation target)
78 : super(target);
79
80 Future<Token> tokenize(SourceLibraryBuilder library) async {
81 Uri uri = library.uri;
82 if (uri.scheme != "file") {
83 uri = target.translateUri(uri);
84 if (uri == null) {
85 print("Skipping ${library.uri}");
86 return null;
87 }
88 library.fileUri = uri;
89 }
90 try {
91 List<int> bytes = await readBytesFromFile(uri);
92 byteCount += bytes.length - 1;
93 return scan(bytes).tokens;
94 } on FileSystemException catch (e) {
95 String message = e.message;
96 String osMessage = e.osError?.message;
97 if (osMessage != null && osMessage.isNotEmpty) {
98 message = osMessage;
99 }
100 return inputError(uri, -1, message);
101 }
102 }
103
104 Future<Null> buildOutline(SourceLibraryBuilder library) async {
105 Token tokens = await tokenize(library);
106 if (tokens == null) return;
107 OutlineBuilder listener = new OutlineBuilder(library);
108 new ClassMemberParser(listener).parseUnit(tokens);
109 }
110
111 Future<Null> buildBody(LibraryBuilder library, AstKind astKind) async {
112 if (library is SourceLibraryBuilder) {
113 Token tokens = await tokenize(library);
114 if (tokens == null) return;
115 DietListener listener = new DietListener(
116 library, elementStore, hierarchy, coreTypes, astKind);
117 DietParser parser = new DietParser(listener);
118 parser.parseUnit(tokens);
119 for (SourceLibraryBuilder part in library.parts) {
120 Token tokens = await tokenize(part);
121 if (tokens != null) {
122 parser.parseUnit(tokens);
123 }
124 }
125 }
126 }
127
128 void resolveParts() {
129 List<Uri> parts = <Uri>[];
130 builders.forEach((Uri uri, LibraryBuilder library) {
131 if (library is SourceLibraryBuilder) {
132 if (library.isPart) {
133 library.validatePart();
134 parts.add(uri);
135 } else {
136 library.includeParts();
137 }
138 }
139 });
140 parts.forEach(builders.remove);
141 ticker.logMs("Resolved parts");
142 }
143
144 void computeLibraryScopes() {
145 Set<LibraryBuilder> exporters = new Set<LibraryBuilder>();
146 Set<LibraryBuilder> exportees = new Set<LibraryBuilder>();
147 builders.forEach((Uri uri, LibraryBuilder library) {
148 if (library is SourceLibraryBuilder) {
149 library.buildInitialScopes();
150 }
151 if (library.exporters.isNotEmpty) {
152 exportees.add(library);
153 for (Export exporter in library.exporters) {
154 exporters.add(exporter.exporter);
155 }
156 }
157 });
158 Set<SourceLibraryBuilder> both = new Set<SourceLibraryBuilder>();
159 for (LibraryBuilder exported in exportees) {
160 if (exporters.contains(exported)) {
161 both.add(exported);
162 }
163 for (Export export in exported.exporters) {
164 exported.exports.forEach(export.addToExportScope);
165 }
166 }
167 bool wasChanged = false;
168 do {
169 wasChanged = false;
170 for (SourceLibraryBuilder exported in both) {
171 for (Export export in exported.exporters) {
172 SourceLibraryBuilder exporter = export.exporter;
173 exported.exports.forEach((String name, Builder member) {
174 if (exporter.addToExportScope(name, member)) {
175 wasChanged = true;
176 }
177 });
178 }
179 }
180 } while (wasChanged);
181 builders.forEach((Uri uri, LibraryBuilder library) {
182 if (library is SourceLibraryBuilder) {
183 library.addImportsToScope();
184 }
185 });
186 ticker.logMs("Computed library scopes");
187 // debugPrintExports();
188 }
189
190 void debugPrintExports() {
191 builders.forEach((Uri uri, SourceLibraryBuilder library) {
192 Set<Builder> members = new Set<Builder>();
193 library.members.forEach((String name, Builder member) {
194 while (member != null) {
195 members.add(member);
196 member = member.next;
197 }
198 });
199 List<String> exports = <String>[];
200 library.exports.forEach((String name, Builder member) {
201 while (member != null) {
202 if (!members.contains(member)) {
203 exports.add(name);
204 }
205 member = member.next;
206 }
207 });
208 if (exports.isNotEmpty) {
209 print("$uri exports $exports");
210 }
211 });
212 }
213
214 void resolveTypes() {
215 int typeCount = 0;
216 builders.forEach((Uri uri, LibraryBuilder library) {
217 typeCount += library.resolveTypes(null);
218 });
219 ticker.logMs("Resolved $typeCount types");
220 }
221
222 void convertConstructors() {
223 int count = 0;
224 builders.forEach((Uri uri, LibraryBuilder library) {
225 count += library.convertConstructors(null);
226 });
227 ticker.logMs("Converted $count constructors");
228 }
229
230 void finishStaticInvocations() {
231 int count = 0;
232 builders.forEach((Uri uri, LibraryBuilder library) {
233 count += library.finishStaticInvocations();
234 });
235 ticker.logMs("Finished static invocations $count");
236 }
237
238 void resolveConstructors() {
239 int count = 0;
240 builders.forEach((Uri uri, LibraryBuilder library) {
241 count += library.resolveConstructors(null);
242 });
243 ticker.logMs("Resolved $count constructors");
244 }
245
246 Set<ClassBuilder> allSupertypes(ClassBuilder cls) {
Johnni Winther 2017/01/19 09:21:34 Add dartdoc (it is strict supertypes, right?)
ahe 2017/01/19 10:48:31 Depends on what you mean by "strict". Since [cls]
247 int length = 0;
248 Set<ClassBuilder> result = new Set<ClassBuilder>()..add(cls);
249 while (length != result.length) {
250 length = result.length;
251 result.addAll(directSupertypes(result));
252 }
253 return result;
254 }
255
256 Set<ClassBuilder> directSupertypes(Iterable<ClassBuilder> classes) {
Johnni Winther 2017/01/19 09:21:34 Add dartdoc
ahe 2017/01/19 10:48:31 Done.
257 Set<ClassBuilder> result = new Set<ClassBuilder>();
258 for (ClassBuilder cls in classes) {
259 target.addDirectSupertype(cls, result);
260 }
261 return result;
262 }
263
264 Iterable<ClassBuilder> cyclicCandidates(Iterable<ClassBuilder> classes) {
Johnni Winther 2017/01/19 09:21:34 Document how/why this works.
ahe 2017/01/19 10:48:30 Done.
265 Iterable<ClassBuilder> input = const [];
266 Iterable<ClassBuilder> output = classes;
267 while (input.length != output.length) {
268 input = output;
269 output = directSupertypes(input);
270 }
271 return output;
272 }
273
274 void checkSemantics() {
275 List<ClassBuilder> allClasses = target.collectAllClasses();
276 Iterable<ClassBuilder> candidates = cyclicCandidates(allClasses);
Johnni Winther 2017/01/19 09:21:34 Return early if [candidate] is empty?
ahe 2017/01/19 10:48:30 Then it wouldn't print the log message.
277 Map<ClassBuilder, Set<ClassBuilder>> realCycles =
278 <ClassBuilder, Set<ClassBuilder>>{};
279 for (ClassBuilder cls in candidates) {
280 Set<ClassBuilder> cycles = cyclicCandidates(allSupertypes(cls));
281 if (cycles.isNotEmpty) {
282 realCycles[cls] = cycles;
283 }
284 }
285 Set<ClassBuilder> reported = new Set<ClassBuilder>();
286 realCycles.forEach((ClassBuilder cls, Set<ClassBuilder> cycles) {
287 target.breakCycle(cls);
288 if (reported.add(cls)) {
289 List<ClassBuilder> involved = <ClassBuilder>[];
290 for (ClassBuilder cls in cycles) {
291 if (realCycles.containsKey(cls)) {
292 involved.add(cls);
293 reported.add(cls);
294 }
295 }
296 print("${cls.name} is a supertype of itself via "
297 "${involved.map((c) => c.name).join(' ')}");
298 }
299 });
300 ticker.logMs("Found cycles");
301 }
302
303 void buildProgram() {
304 builders.forEach((Uri uri, LibraryBuilder library) {
305 if (library is SourceLibraryBuilder) {
306 libraries.add(library.build());
307 }
308 });
309 ticker.logMs("Built program");
310 }
311
312 void buildElementStore() {
313 elementStore = new ElementStore(coreLibrary, builders);
314 ticker.logMs("Built analyzer element model.");
315 }
316
317 void computeHierarchy(Program program) {
318 hierarchy = new ClassHierarchy(program);
319 ticker.logMs("Computed class hierarchy");
320 coreTypes = new CoreTypes(program);
321 ticker.logMs("Computed core types");
322 }
323 }
OLDNEW
« pkg/fasta/lib/src/loader.dart ('K') | « pkg/fasta/lib/src/loader.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698