| OLD | NEW | 
|---|
|  | (Empty) | 
| 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 |  | 
| 3 // BSD-style license that can be found in the LICENSE file. |  | 
| 4 |  | 
| 5 class ScannerTask extends CompilerTask { |  | 
| 6   ScannerTask(Compiler compiler) : super(compiler); |  | 
| 7   String get name() => 'Scanner'; |  | 
| 8 |  | 
| 9   void scan(CompilationUnitElement compilationUnit) { |  | 
| 10     measure(() { |  | 
| 11       if (compilationUnit.kind === ElementKind.LIBRARY) { |  | 
| 12         compiler.log("scanning library ${compilationUnit.script.name}"); |  | 
| 13       } |  | 
| 14       scanElements(compilationUnit); |  | 
| 15       if (compilationUnit.kind === ElementKind.LIBRARY) { |  | 
| 16         processScriptTags(compilationUnit); |  | 
| 17       } |  | 
| 18     }); |  | 
| 19   } |  | 
| 20 |  | 
| 21   void processScriptTags(LibraryElement library) { |  | 
| 22     int tagState = TagState.NO_TAG_SEEN; |  | 
| 23 |  | 
| 24     /** |  | 
| 25      * If [value] is less than [tagState] complain and return |  | 
| 26      * [tagState]. Otherwise return the new value for [tagState] |  | 
| 27      * (transition function for state machine). |  | 
| 28      */ |  | 
| 29     int checkTag(int value, ScriptTag tag) { |  | 
| 30       if (tagState > value) { |  | 
| 31         compiler.reportError(tag, 'out of order'); |  | 
| 32         return tagState; |  | 
| 33       } |  | 
| 34       return TagState.NEXT[value]; |  | 
| 35     } |  | 
| 36 |  | 
| 37     LinkBuilder<ScriptTag> imports = new LinkBuilder<ScriptTag>(); |  | 
| 38     Uri cwd = new Uri(scheme: 'file', path: compiler.currentDirectory); |  | 
| 39     Uri base = cwd.resolve(library.script.name.toString()); |  | 
| 40     for (ScriptTag tag in library.tags.reverse()) { |  | 
| 41       StringNode argument = tag.argument; |  | 
| 42       // TODO(lrn): Support interpolations here. We need access to the |  | 
| 43       // special constants that can be inserted into script tag strings. |  | 
| 44       Uri resolved = base.resolve(argument.dartString.slowToString()); |  | 
| 45       if (tag.isImport()) { |  | 
| 46         tagState = checkTag(TagState.IMPORT, tag); |  | 
| 47         // It is not safe to import other libraries at this point as |  | 
| 48         // another library could then observe the current library |  | 
| 49         // before it fully declares all the members that are sourced |  | 
| 50         // in. |  | 
| 51         imports.addLast(tag); |  | 
| 52       } else if (tag.isLibrary()) { |  | 
| 53         tagState = checkTag(TagState.LIBRARY, tag); |  | 
| 54         if (library.libraryTag !== null) { |  | 
| 55           compiler.cancel("duplicated library declaration", node: tag); |  | 
| 56         } else { |  | 
| 57           library.libraryTag = tag; |  | 
| 58         } |  | 
| 59       } else if (tag.isSource()) { |  | 
| 60         tagState = checkTag(TagState.SOURCE, tag); |  | 
| 61         Script script = compiler.readScript(resolved, tag); |  | 
| 62         CompilationUnitElement unit = |  | 
| 63           new CompilationUnitElement(script, library); |  | 
| 64         compiler.withCurrentElement(unit, () => scan(unit)); |  | 
| 65       } else if (tag.isResource()) { |  | 
| 66         tagState = checkTag(TagState.RESOURCE, tag); |  | 
| 67         compiler.reportWarning(tag, 'ignoring resource tag'); |  | 
| 68       } else { |  | 
| 69         compiler.cancel("illegal script tag: ${tag.tag}", node: tag); |  | 
| 70       } |  | 
| 71     } |  | 
| 72     // TODO(ahe): During Compiler.scanBuiltinLibraries, |  | 
| 73     // compiler.coreLibrary is null. Clean this up when there is a |  | 
| 74     // better way to access "dart:core". |  | 
| 75     bool implicitlyImportCoreLibrary = compiler.coreLibrary !== null; |  | 
| 76     for (ScriptTag tag in imports.toLink()) { |  | 
| 77       // Now that we have processed all the source tags, it is safe to |  | 
| 78       // start loading other libraries. |  | 
| 79       StringNode argument = tag.argument; |  | 
| 80       Uri resolved = base.resolve(argument.dartString.slowToString()); |  | 
| 81       if (resolved.toString() == "dart:core") { |  | 
| 82         implicitlyImportCoreLibrary = false; |  | 
| 83       } |  | 
| 84       importLibrary(library, loadLibrary(resolved, tag), tag); |  | 
| 85     } |  | 
| 86     if (implicitlyImportCoreLibrary) { |  | 
| 87       importLibrary(library, compiler.coreLibrary, null); |  | 
| 88     } |  | 
| 89   } |  | 
| 90 |  | 
| 91   void scanElements(CompilationUnitElement compilationUnit) { |  | 
| 92     Script script = compilationUnit.script; |  | 
| 93     Token tokens; |  | 
| 94     try { |  | 
| 95       tokens = new StringScanner(script.text).tokenize(); |  | 
| 96     } catch (MalformedInputException ex) { |  | 
| 97       Token token; |  | 
| 98       var message; |  | 
| 99       if (ex.position is num) { |  | 
| 100         // TODO(ahe): Always use tokens in MalformedInputException. |  | 
| 101         token = new Token(EOF_INFO, ex.position); |  | 
| 102       } else { |  | 
| 103         token = ex.position; |  | 
| 104       } |  | 
| 105       compiler.cancel(ex.message, token: token); |  | 
| 106     } |  | 
| 107     compiler.dietParser.dietParse(compilationUnit, tokens); |  | 
| 108   } |  | 
| 109 |  | 
| 110   LibraryElement loadLibrary(Uri uri, ScriptTag node) { |  | 
| 111     bool newLibrary = false; |  | 
| 112     LibraryElement library = |  | 
| 113       compiler.universe.libraries.putIfAbsent(uri.toString(), () { |  | 
| 114           newLibrary = true; |  | 
| 115           Script script = compiler.readScript(uri, node); |  | 
| 116           LibraryElement element = new LibraryElement(script); |  | 
| 117           native.maybeEnableNative(compiler, element, uri); |  | 
| 118           return element; |  | 
| 119         }); |  | 
| 120     if (newLibrary) { |  | 
| 121       compiler.withCurrentElement(library, () => scan(library)); |  | 
| 122       compiler.onLibraryLoaded(library, uri); |  | 
| 123     } |  | 
| 124     return library; |  | 
| 125   } |  | 
| 126 |  | 
| 127   void importLibrary(LibraryElement library, LibraryElement imported, |  | 
| 128                      ScriptTag tag) { |  | 
| 129     if (!imported.hasLibraryName()) { |  | 
| 130       compiler.withCurrentElement(library, () { |  | 
| 131         compiler.reportError(tag, |  | 
| 132                              'no #library tag found in ${imported.script.uri}'); |  | 
| 133       }); |  | 
| 134     } |  | 
| 135     if (tag !== null && tag.prefix !== null) { |  | 
| 136       SourceString prefix = |  | 
| 137           new SourceString(tag.prefix.dartString.slowToString()); |  | 
| 138       Element e = library.find(prefix); |  | 
| 139       if (e === null) { |  | 
| 140         e = new PrefixElement(prefix, library, tag.getBeginToken()); |  | 
| 141         library.define(e, compiler); |  | 
| 142       } |  | 
| 143       if (e.kind !== ElementKind.PREFIX) { |  | 
| 144         compiler.withCurrentElement(e, () { |  | 
| 145           compiler.reportWarning(new Identifier(e.position()), |  | 
| 146                                  'duplicated definition'); |  | 
| 147         }); |  | 
| 148         compiler.reportError(tag.prefix, 'duplicate defintion'); |  | 
| 149       } |  | 
| 150       imported.forEachExport((Element element) { |  | 
| 151         Element existing = e.imported.putIfAbsent(element.name, () => element); |  | 
| 152         if (existing !== element) { |  | 
| 153           compiler.withCurrentElement(existing, () { |  | 
| 154             compiler.reportWarning(new Identifier(existing.position()), |  | 
| 155                                    'duplicated import'); |  | 
| 156           }); |  | 
| 157           compiler.withCurrentElement(element, () { |  | 
| 158             compiler.reportError(new Identifier(element.position()), |  | 
| 159                                  'duplicated import'); |  | 
| 160           }); |  | 
| 161         } |  | 
| 162       }); |  | 
| 163     } else { |  | 
| 164       imported.forEachExport((Element element) { |  | 
| 165         compiler.withCurrentElement(element, () { |  | 
| 166           library.define(element, compiler); |  | 
| 167         }); |  | 
| 168       }); |  | 
| 169     } |  | 
| 170   } |  | 
| 171 } |  | 
| 172 |  | 
| 173 class DietParserTask extends CompilerTask { |  | 
| 174   DietParserTask(Compiler compiler) : super(compiler); |  | 
| 175   final String name = 'Diet Parser'; |  | 
| 176 |  | 
| 177   dietParse(CompilationUnitElement compilationUnit, Token tokens) { |  | 
| 178     measure(() { |  | 
| 179       ElementListener listener = new ElementListener(compiler, compilationUnit); |  | 
| 180       PartialParser parser = new PartialParser(listener); |  | 
| 181       parser.parseUnit(tokens); |  | 
| 182     }); |  | 
| 183   } |  | 
| 184 } |  | 
| 185 |  | 
| 186 /** |  | 
| 187  * The fields of this class models a state machine for checking script |  | 
| 188  * tags come in the correct order. |  | 
| 189  */ |  | 
| 190 class TagState { |  | 
| 191   static final int NO_TAG_SEEN = 0; |  | 
| 192   static final int LIBRARY = 1; |  | 
| 193   static final int IMPORT = 2; |  | 
| 194   static final int SOURCE = 3; |  | 
| 195   static final int RESOURCE = 4; |  | 
| 196 |  | 
| 197   /** Next state. */ |  | 
| 198   static final List<int> NEXT = |  | 
| 199       const <int>[NO_TAG_SEEN, |  | 
| 200                   IMPORT, // Only one library tag is allowed. |  | 
| 201                   IMPORT, |  | 
| 202                   SOURCE, |  | 
| 203                   RESOURCE]; |  | 
| 204 } |  | 
| OLD | NEW | 
|---|