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

Side by Side Diff: dart/pkg/compiler/lib/src/library_loader.dart

Issue 811583004: Recover from incorrectly ordered library tags. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Typo Created 6 years 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
« no previous file with comments | « no previous file | dart/pkg/compiler/lib/src/warnings.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 library dart2js.library_loader; 5 library dart2js.library_loader;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart2jslib.dart' 8
9 show Compiler, 9 import 'dart2jslib.dart' show
10 CompilerTask, 10 Compiler,
11 MessageKind, 11 CompilerTask,
12 Script, 12 DiagnosticListener,
13 invariant; 13 MessageKind,
14 import 'elements/elements.dart' 14 Script,
15 show CompilationUnitElement, 15 invariant;
16 Element, 16
17 LibraryElement, 17 import 'elements/elements.dart' show
18 PrefixElement; 18 CompilationUnitElement,
19 import 'elements/modelx.dart' 19 Element,
20 show CompilationUnitElementX, 20 LibraryElement,
21 DeferredLoaderGetterElementX, 21 PrefixElement;
22 ErroneousElementX, 22
23 LibraryElementX, 23 import 'elements/modelx.dart' show
24 PrefixElementX; 24 CompilationUnitElementX,
25 DeferredLoaderGetterElementX,
26 ErroneousElementX,
27 LibraryElementX,
28 PrefixElementX;
29
25 import 'helpers/helpers.dart'; // Included for debug helpers. 30 import 'helpers/helpers.dart'; // Included for debug helpers.
31
26 import 'native/native.dart' as native; 32 import 'native/native.dart' as native;
33
27 import 'tree/tree.dart'; 34 import 'tree/tree.dart';
28 import 'util/util.dart' show Link, LinkBuilder; 35
36 import 'util/util.dart' show
37 Link,
38 LinkBuilder;
29 39
30 /** 40 /**
31 * [CompilerTask] for loading libraries and setting up the import/export scopes. 41 * [CompilerTask] for loading libraries and setting up the import/export scopes.
32 * 42 *
33 * The library loader uses four different kinds of URIs in different parts of 43 * The library loader uses four different kinds of URIs in different parts of
34 * the loading process. 44 * the loading process.
35 * 45 *
36 * ## User URI ## 46 * ## User URI ##
37 * 47 *
38 * A 'user URI' is a URI provided by the user in code and as the main entry URI 48 * A 'user URI' is a URI provided by the user in code and as the main entry URI
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 } 365 }
356 366
357 /** 367 /**
358 * Processes the library tags in [library]. 368 * Processes the library tags in [library].
359 * 369 *
360 * The imported/exported libraries are loaded and processed recursively but 370 * The imported/exported libraries are loaded and processed recursively but
361 * the import/export scopes are not set up. 371 * the import/export scopes are not set up.
362 */ 372 */
363 Future processLibraryTags(LibraryDependencyHandler handler, 373 Future processLibraryTags(LibraryDependencyHandler handler,
364 LibraryElement library) { 374 LibraryElement library) {
365 int tagState = TagState.NO_TAG_SEEN; 375 TagState tagState = new TagState();
366
367 /**
368 * If [value] is less than [tagState] complain and return
369 * [tagState]. Otherwise return the new value for [tagState]
370 * (transition function for state machine).
371 */
372 int checkTag(int value, LibraryTag tag) {
373 if (tagState > value) {
374 compiler.reportFatalError(
375 tag,
376 MessageKind.GENERIC, {'text': 'Error: Out of order.'});
377 return tagState;
378 }
379 return TagState.NEXT[value];
380 }
381 376
382 bool importsDartCore = false; 377 bool importsDartCore = false;
383 var libraryDependencies = new LinkBuilder<LibraryDependency>(); 378 var libraryDependencies = new LinkBuilder<LibraryDependency>();
384 Uri base = library.entryCompilationUnit.script.readableUri; 379 Uri base = library.entryCompilationUnit.script.readableUri;
385 380
386 return Future.forEach(library.tags, (LibraryTag tag) { 381 return Future.forEach(library.tags, (LibraryTag tag) {
387 return compiler.withCurrentElement(library, () { 382 return compiler.withCurrentElement(library, () {
388 if (tag.isImport) { 383 if (tag.isImport) {
389 Import import = tag; 384 Import import = tag;
390 tagState = checkTag(TagState.IMPORT_OR_EXPORT, import); 385 tagState.checkTag(TagState.IMPORT_OR_EXPORT, import, compiler);
391 if (import.uri.dartString.slowToString() == 'dart:core') { 386 if (import.uri.dartString.slowToString() == 'dart:core') {
392 importsDartCore = true; 387 importsDartCore = true;
393 } 388 }
394 libraryDependencies.addLast(import); 389 libraryDependencies.addLast(import);
395 } else if (tag.isExport) { 390 } else if (tag.isExport) {
396 tagState = checkTag(TagState.IMPORT_OR_EXPORT, tag); 391 tagState.checkTag(TagState.IMPORT_OR_EXPORT, tag, compiler);
397 libraryDependencies.addLast(tag); 392 libraryDependencies.addLast(tag);
398 } else if (tag.isLibraryName) { 393 } else if (tag.isLibraryName) {
399 tagState = checkTag(TagState.LIBRARY, tag); 394 tagState.checkTag(TagState.LIBRARY, tag, compiler);
400 if (library.libraryTag != null) { 395 if (library.libraryTag == null) {
401 compiler.internalError(tag, "Duplicated library declaration."); 396 // Use the first if there are multiple (which is reported as an
402 } else { 397 // error in [TagState.checkTag]).
403 library.libraryTag = tag; 398 library.libraryTag = tag;
404 } 399 }
405 } else if (tag.isPart) { 400 } else if (tag.isPart) {
406 Part part = tag; 401 Part part = tag;
407 StringNode uri = part.uri; 402 StringNode uri = part.uri;
408 Uri resolvedUri = base.resolve(uri.dartString.slowToString()); 403 Uri resolvedUri = base.resolve(uri.dartString.slowToString());
409 tagState = checkTag(TagState.SOURCE, part); 404 tagState.checkTag(TagState.PART, part, compiler);
410 return scanPart(part, resolvedUri, library); 405 return scanPart(part, resolvedUri, library);
411 } else { 406 } else {
412 compiler.internalError(tag, "Unhandled library tag."); 407 compiler.internalError(tag, "Unhandled library tag.");
413 } 408 }
414 }); 409 });
415 }).then((_) { 410 }).then((_) {
416 return compiler.onLibraryScanned(library, handler); 411 return compiler.onLibraryScanned(library, handler);
417 }).then((_) { 412 }).then((_) {
418 return compiler.withCurrentElement(library, () { 413 return compiler.withCurrentElement(library, () {
419 checkDuplicatedLibraryName(library); 414 checkDuplicatedLibraryName(library);
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 libraryCanonicalUriMap[resolvedUri] = element; 560 libraryCanonicalUriMap[resolvedUri] = element;
566 } 561 }
567 native.maybeEnableNative(compiler, element); 562 native.maybeEnableNative(compiler, element);
568 compiler.scanner.scanLibrary(element); 563 compiler.scanner.scanLibrary(element);
569 return element; 564 return element;
570 }); 565 });
571 } 566 }
572 } 567 }
573 568
574 569
575 /** 570 /// A state machine for checking script tags come in the correct order.
576 * The fields of this class models a state machine for checking script
577 * tags come in the correct order.
578 */
579 class TagState { 571 class TagState {
572 /// Initial state.
580 static const int NO_TAG_SEEN = 0; 573 static const int NO_TAG_SEEN = 0;
574
575 /// Passed to [checkTag] when a library declaration (the syntax "library
576 /// name;") has been seen. Not an actual state.
581 static const int LIBRARY = 1; 577 static const int LIBRARY = 1;
582 static const int IMPORT_OR_EXPORT = 2;
583 static const int SOURCE = 3;
584 static const int RESOURCE = 4;
585 578
586 /** Next state. */ 579 /// The state after the first library declaration.
587 static const List<int> NEXT = 580 static const int AFTER_LIBRARY_DECLARATION = 2;
588 const <int>[NO_TAG_SEEN, 581
589 IMPORT_OR_EXPORT, // Only one library tag is allowed. 582 /// The state after a import or export declaration has been seen, but before
590 IMPORT_OR_EXPORT, 583 /// a part tag has been seen.
591 SOURCE, 584 static const int IMPORT_OR_EXPORT = 3;
592 RESOURCE]; 585
586 /// The state after a part tag has been seen.
587 static const int PART = 4;
588
589 /// Encodes transition function for state machine.
590 static const List<int> NEXT = const <int>[
591 NO_TAG_SEEN,
592 AFTER_LIBRARY_DECLARATION, // Only one library tag is allowed.
593 IMPORT_OR_EXPORT,
594 IMPORT_OR_EXPORT,
595 PART,
596 ];
597
598 int tagState = TagState.NO_TAG_SEEN;
599
600 bool hasLibraryDeclaration = false;
601
602 /// If [value] is less than [tagState] complain. Regardless, update
603 /// [tagState] using transition function for state machine.
604 void checkTag(int value, LibraryTag tag, DiagnosticListener listener) {
605 if (tagState > value) {
606 MessageKind kind;
607 switch (value) {
608 case LIBRARY:
609 if (hasLibraryDeclaration) {
610 kind = MessageKind.ONLY_ONE_LIBRARY_TAG;
611 } else {
612 kind = MessageKind.LIBRARY_TAG_MUST_BE_FIRST;
613 }
614 break;
615
616 case IMPORT_OR_EXPORT:
617 if (tag.isImport) {
618 kind = MessageKind.IMPORT_BEFORE_PARTS;
619 } else if (tag.isExport) {
620 kind = MessageKind.EXPORT_BEFORE_PARTS;
621 } else {
622 listener.internalError(tag, "Expected import or export.");
623 }
624 break;
625
626 default:
627 listener.internalError(tag, "Unexpected order of library tags.");
628 }
629 listener.reportError(tag, kind);
630 }
631 tagState = NEXT[value];
632 if (value == LIBRARY) {
633 hasLibraryDeclaration = true;
634 }
635 }
593 } 636 }
594 637
595 /** 638 /**
596 * An [import] tag and the [importedLibrary] imported through [import]. 639 * An [import] tag and the [importedLibrary] imported through [import].
597 */ 640 */
598 class ImportLink { 641 class ImportLink {
599 final Import import; 642 final Import import;
600 final LibraryElement importedLibrary; 643 final LibraryElement importedLibrary;
601 644
602 ImportLink(this.import, this.importedLibrary); 645 ImportLink(this.import, this.importedLibrary);
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 } 1184 }
1142 suffixes.add(const Link<Uri>().prepend(canonicalUri)); 1185 suffixes.add(const Link<Uri>().prepend(canonicalUri));
1143 } 1186 }
1144 suffixChainMap[library] = suffixes; 1187 suffixChainMap[library] = suffixes;
1145 return; 1188 return;
1146 } 1189 }
1147 1190
1148 computeSuffixes(rootLibrary, const Link<Uri>()); 1191 computeSuffixes(rootLibrary, const Link<Uri>());
1149 } 1192 }
1150 } 1193 }
OLDNEW
« no previous file with comments | « no previous file | dart/pkg/compiler/lib/src/warnings.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698