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

Side by Side Diff: lib/compiler/implementation/scanner/scanner_task.dart

Issue 10990060: Added support for exports and re-exports. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 8 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 class ScannerTask extends CompilerTask { 5 class ScannerTask extends CompilerTask {
6 ScannerTask(Compiler compiler) : super(compiler); 6 ScannerTask(Compiler compiler) : super(compiler);
7 String get name => 'Scanner'; 7 String get name => 'Scanner';
8 8
9 final Map<String, LibraryElement> libraryNames =
10 new Map<String, LibraryElement>();
11
12 void scanLibrary(LibraryElement library) { 9 void scanLibrary(LibraryElement library) {
13 var compilationUnit = library.entryCompilationUnit; 10 var compilationUnit = library.entryCompilationUnit;
14 compiler.log("scanning library ${compilationUnit.script.name}"); 11 compiler.log("scanning library ${compilationUnit.script.name}");
15 scan(compilationUnit); 12 scan(compilationUnit);
16 processLibraryTags(library);
17 } 13 }
18 14
19 void scan(CompilationUnitElement compilationUnit) { 15 void scan(CompilationUnitElement compilationUnit) {
20 measure(() { 16 measure(() {
21 scanElements(compilationUnit); 17 scanElements(compilationUnit);
22 }); 18 });
23 } 19 }
24 20
25 void processLibraryTags(LibraryElement library) {
26 int tagState = TagState.NO_TAG_SEEN;
27
28 /**
29 * If [value] is less than [tagState] complain and return
30 * [tagState]. Otherwise return the new value for [tagState]
31 * (transition function for state machine).
32 */
33 int checkTag(int value, LibraryTag tag) {
34 if (tagState > value) {
35 compiler.reportError(tag, 'out of order');
36 return tagState;
37 }
38 return TagState.NEXT[value];
39 }
40
41 LinkBuilder<Import> imports = new LinkBuilder<Import>();
42 Uri base = library.entryCompilationUnit.script.uri;
43 for (LibraryTag tag in library.tags.reverse()) {
44 if (tag.isImport) {
45 tagState = checkTag(TagState.IMPORT, tag);
46 if (tag.combinators != null) {
47 compiler.unimplemented('combinators', node: tag.combinators);
48 }
49 // It is not safe to import other libraries at this point as
50 // another library could then observe the current library
51 // before it fully declares all the members that are sourced
52 // in.
53 imports.addLast(tag);
54 } else if (tag.isLibraryName) {
55 tagState = checkTag(TagState.LIBRARY, tag);
56 if (library.libraryTag !== null) {
57 compiler.cancel("duplicated library declaration", node: tag);
58 } else {
59 library.libraryTag = tag;
60 }
61 checkDuplicatedLibraryName(library);
62 } else if (tag.isPart) {
63 StringNode uri = tag.uri;
64 Uri resolved = base.resolve(uri.dartString.slowToString());
65 tagState = checkTag(TagState.SOURCE, tag);
66 loadPart(tag, resolved, library);
67 } else {
68 compiler.internalError("Unhandled library tag.", node: tag);
69 }
70 }
71
72 // Apply patch, if any.
73 if (library.uri.scheme == 'dart') {
74 compiler.patchDartLibrary(library, library.uri.path);
75 }
76
77 // Now that we have processed all the source tags, it is safe to
78 // start loading other libraries.
79
80 if (library.uri.scheme != 'dart' || library.uri.path != 'core') {
81 compiler.importCoreLibrary(library);
82 }
83
84 for (Import tag in imports.toLink()) {
85 importLibraryFromTag(tag, library.entryCompilationUnit);
86 }
87 }
88
89 void checkDuplicatedLibraryName(LibraryElement library) {
90 LibraryTag tag = library.libraryTag;
91 if (tag != null) {
92 String name = library.getLibraryOrScriptName();
93 LibraryElement existing =
94 libraryNames.putIfAbsent(name, () => library);
95 if (existing !== library) {
96 Uri uri = library.entryCompilationUnit.script.uri;
97 compiler.reportMessage(
98 compiler.spanFromNode(tag.name, uri),
99 MessageKind.DUPLICATED_LIBRARY_NAME.error([name]),
100 api_s.Diagnostic.WARNING);
101 Uri existingUri = existing.entryCompilationUnit.script.uri;
102 compiler.reportMessage(
103 compiler.spanFromNode(existing.libraryTag.name, existingUri),
104 MessageKind.DUPLICATED_LIBRARY_NAME.error([name]),
105 api_s.Diagnostic.WARNING);
106 }
107 }
108 }
109
110 /**
111 * Handle a part tag in the scope of [library]. The [path] given is used as
112 * is, any resolution should be done beforehand.
113 */
114 void loadPart(Part part, Uri path, LibraryElement library) {
115 Script sourceScript = compiler.readScript(path, part.uri);
116 CompilationUnitElement unit =
117 new CompilationUnitElement(sourceScript, library);
118 compiler.withCurrentElement(unit, () => compiler.scanner.scan(unit));
119 }
120
121 /**
122 * Handle an import script tag by importing the referenced library into the
123 * current library.
124 * Returns the resolved library [Uri].
125 */
126 Uri importLibraryFromTag(Import tag,
127 CompilationUnitElement compilationUnit) {
128 Uri base = compilationUnit.script.uri;
129 Uri resolved = base.resolve(tag.uri.dartString.slowToString());
130 LibraryElement importedLibrary = loadLibrary(resolved, tag.uri, resolved);
131 importLibrary(compilationUnit.getLibrary(),
132 importedLibrary,
133 tag,
134 compilationUnit);
135 return resolved;
136 }
137
138 void scanElements(CompilationUnitElement compilationUnit) { 21 void scanElements(CompilationUnitElement compilationUnit) {
139 Script script = compilationUnit.script; 22 Script script = compilationUnit.script;
140 Token tokens = new StringScanner(script.text).tokenize(); 23 Token tokens = new StringScanner(script.text).tokenize();
141 compiler.dietParser.dietParse(compilationUnit, tokens); 24 compiler.dietParser.dietParse(compilationUnit, tokens);
142 } 25 }
143
144 LibraryElement loadLibrary(Uri uri, Node node, Uri canonicalUri) {
145 bool newLibrary = false;
146 LibraryElement createLibrary() {
147 newLibrary = true;
148 Script script = compiler.readScript(uri, node);
149 LibraryElement element = new LibraryElement(script, canonicalUri);
150 native.maybeEnableNative(compiler, element, uri);
151 return element;
152 }
153 LibraryElement library;
154 if (canonicalUri === null) {
155 library = createLibrary();
156 } else {
157 library = compiler.libraries.putIfAbsent(canonicalUri.toString(),
158 createLibrary);
159 }
160 if (newLibrary) {
161 compiler.withCurrentElement(library, () {
162 scanLibrary(library);
163 compiler.onLibraryLoaded(library, uri);
164 });
165 }
166 return library;
167 }
168
169 void importLibrary(LibraryElement library, LibraryElement imported,
170 Import tag, [CompilationUnitElement compilationUnit]) {
171 if (!imported.hasLibraryName()) {
172 compiler.withCurrentElement(library, () {
173 compiler.reportError(tag === null ? null : tag.uri,
174 'no #library tag found in ${imported.uri}');
175 });
176 }
177 if (tag !== null && tag.prefix !== null) {
178 SourceString prefix = tag.prefix.source;
179 Element e = library.find(prefix);
180 if (e === null) {
181 if (compilationUnit === null) {
182 compilationUnit = library.entryCompilationUnit;
183 }
184 e = new PrefixElement(prefix, compilationUnit, tag.getBeginToken());
185 library.addToScope(e, compiler);
186 }
187 if (e.kind !== ElementKind.PREFIX) {
188 compiler.withCurrentElement(e, () {
189 compiler.reportWarning(new Identifier(e.position()),
190 'duplicated definition');
191 });
192 compiler.reportError(tag.prefix, 'duplicate defintion');
193 }
194 PrefixElement prefixElement = e;
195 imported.forEachExport((Element element) {
196 Element existing =
197 prefixElement.imported.putIfAbsent(element.name, () => element);
198 if (existing !== element) {
199 compiler.withCurrentElement(existing, () {
200 compiler.reportWarning(new Identifier(existing.position()),
201 'duplicated import');
202 });
203 compiler.withCurrentElement(element, () {
204 compiler.reportError(new Identifier(element.position()),
205 'duplicated import');
206 });
207 }
208 });
209 } else {
210 imported.forEachExport((Element element) {
211 compiler.withCurrentElement(element, () {
212 library.addImport(element, compiler);
213 });
214 });
215 }
216 }
217 } 26 }
218 27
219 class DietParserTask extends CompilerTask { 28 class DietParserTask extends CompilerTask {
220 DietParserTask(Compiler compiler) : super(compiler); 29 DietParserTask(Compiler compiler) : super(compiler);
221 final String name = 'Diet Parser'; 30 final String name = 'Diet Parser';
222 31
223 dietParse(CompilationUnitElement compilationUnit, Token tokens) { 32 dietParse(CompilationUnitElement compilationUnit, Token tokens) {
224 measure(() { 33 measure(() {
225 Function idGenerator = compiler.getNextFreeClassId; 34 Function idGenerator = compiler.getNextFreeClassId;
226 ElementListener listener = 35 ElementListener listener =
227 new ElementListener(compiler, compilationUnit, idGenerator); 36 new ElementListener(compiler, compilationUnit, idGenerator);
228 PartialParser parser = new PartialParser(listener); 37 PartialParser parser = new PartialParser(listener);
229 parser.parseUnit(tokens); 38 parser.parseUnit(tokens);
230 }); 39 });
231 } 40 }
232 } 41 }
233
234 /**
235 * The fields of this class models a state machine for checking script
236 * tags come in the correct order.
237 */
238 class TagState {
239 static const int NO_TAG_SEEN = 0;
240 static const int LIBRARY = 1;
241 static const int IMPORT = 2;
242 static const int SOURCE = 3;
243 static const int RESOURCE = 4;
244
245 /** Next state. */
246 static const List<int> NEXT =
247 const <int>[NO_TAG_SEEN,
248 IMPORT, // Only one library tag is allowed.
249 IMPORT,
250 SOURCE,
251 RESOURCE];
252 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/patch_parser.dart ('k') | lib/compiler/implementation/tree/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698