OLD | NEW |
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 part of dart2js; | 5 part of dart2js; |
6 | 6 |
7 /** | 7 /** |
8 * If true, print a warning for each method that was resolved, but not | 8 * If true, print a warning for each method that was resolved, but not |
9 * compiled. | 9 * compiled. |
10 */ | 10 */ |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 void dumpInferredTypes() {} | 96 void dumpInferredTypes() {} |
97 | 97 |
98 ItemCompilationContext createItemCompilationContext() { | 98 ItemCompilationContext createItemCompilationContext() { |
99 return new ItemCompilationContext(); | 99 return new ItemCompilationContext(); |
100 } | 100 } |
101 | 101 |
102 SourceString getCheckedModeHelper(DartType type) => null; | 102 SourceString getCheckedModeHelper(DartType type) => null; |
103 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) {} | 103 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) {} |
104 } | 104 } |
105 | 105 |
| 106 /** |
| 107 * Key class used in [TokenMap] in which the hash code for a token is based |
| 108 * on the [charOffset]. |
| 109 */ |
| 110 class TokenKey { |
| 111 final Token token; |
| 112 TokenKey(this.token); |
| 113 int get hashCode => token.charOffset; |
| 114 operator==(other) => other is TokenKey && token == other.token; |
| 115 } |
| 116 |
| 117 /// Map of tokens and the first associated comment. |
| 118 /* |
| 119 * This implementation was chosen among several candidates for its space/time |
| 120 * efficiency by empirical tests of running dartdoc on dartdoc itself. Time |
| 121 * measurements for the use of [Compiler.commentMap]: |
| 122 * |
| 123 * 1) Using [TokenKey] as key (this class): ~80 msec |
| 124 * 2) Using [TokenKey] as key + storing a separate map in each script: ~120 msec |
| 125 * 3) Using [Token] as key in a [Map]: ~38000 msec |
| 126 * 4) Storing comments is new field in [Token]: ~20 msec |
| 127 * (Abandoned due to the increased memory usage) |
| 128 * 5) Storing comments in an [Expando]: ~14000 msec |
| 129 * 6) Storing token/comments pairs in a linked list: ~5400 msec |
| 130 */ |
| 131 class TokenMap { |
| 132 Map<TokenKey,Token> comments = new Map<TokenKey,Token>(); |
| 133 |
| 134 Token operator[] (Token key) { |
| 135 return comments[new TokenKey(key)]; |
| 136 } |
| 137 |
| 138 void operator[]= (Token key, Token value) { |
| 139 comments[new TokenKey(key)] = value; |
| 140 } |
| 141 } |
| 142 |
106 abstract class Compiler implements DiagnosticListener { | 143 abstract class Compiler implements DiagnosticListener { |
107 final Map<String, LibraryElement> libraries; | 144 final Map<String, LibraryElement> libraries; |
108 final Stopwatch totalCompileTime = new Stopwatch(); | 145 final Stopwatch totalCompileTime = new Stopwatch(); |
109 int nextFreeClassId = 0; | 146 int nextFreeClassId = 0; |
110 World world; | 147 World world; |
111 String assembledCode; | 148 String assembledCode; |
112 Types types; | 149 Types types; |
113 | 150 |
| 151 /** |
| 152 * Map from token to the first preceeding comment token. |
| 153 */ |
| 154 final TokenMap commentMap = new TokenMap(); |
| 155 |
114 final bool enableMinification; | 156 final bool enableMinification; |
115 final bool enableTypeAssertions; | 157 final bool enableTypeAssertions; |
116 final bool enableUserAssertions; | 158 final bool enableUserAssertions; |
117 final bool enableConcreteTypeInference; | 159 final bool enableConcreteTypeInference; |
118 /** | 160 /** |
119 * The maximum size of a concrete type before it widens to dynamic during | 161 * The maximum size of a concrete type before it widens to dynamic during |
120 * concrete type inference. | 162 * concrete type inference. |
121 */ | 163 */ |
122 final int maxConcreteTypeSize; | 164 final int maxConcreteTypeSize; |
123 final bool analyzeAll; | 165 final bool analyzeAll; |
124 final bool enableNativeLiveTypeAnalysis; | 166 final bool enableNativeLiveTypeAnalysis; |
125 final bool rejectDeprecatedFeatures; | 167 final bool rejectDeprecatedFeatures; |
126 final bool checkDeprecationInSdk; | 168 final bool checkDeprecationInSdk; |
127 | 169 |
| 170 /** |
| 171 * If [:true:], comment tokens are collected in [commentMap] during scanning. |
| 172 */ |
| 173 final bool preserveComments; |
| 174 |
128 bool disableInlining = false; | 175 bool disableInlining = false; |
129 | 176 |
130 final Tracer tracer; | 177 final Tracer tracer; |
131 | 178 |
132 CompilerTask measuredTask; | 179 CompilerTask measuredTask; |
133 Element _currentElement; | 180 Element _currentElement; |
134 LibraryElement coreLibrary; | 181 LibraryElement coreLibrary; |
135 LibraryElement isolateLibrary; | 182 LibraryElement isolateLibrary; |
136 LibraryElement isolateHelperLibrary; | 183 LibraryElement isolateHelperLibrary; |
137 LibraryElement jsHelperLibrary; | 184 LibraryElement jsHelperLibrary; |
138 LibraryElement interceptorsLibrary; | 185 LibraryElement interceptorsLibrary; |
139 LibraryElement foreignLibrary; | 186 LibraryElement foreignLibrary; |
140 LibraryElement mainApp; | 187 LibraryElement mainApp; |
141 | 188 |
142 ClassElement objectClass; | 189 ClassElement objectClass; |
143 ClassElement closureClass; | 190 ClassElement closureClass; |
144 ClassElement dynamicClass; | 191 ClassElement dynamicClass; |
145 ClassElement boolClass; | 192 ClassElement boolClass; |
146 ClassElement numClass; | 193 ClassElement numClass; |
147 ClassElement intClass; | 194 ClassElement intClass; |
148 ClassElement doubleClass; | 195 ClassElement doubleClass; |
149 ClassElement stringClass; | 196 ClassElement stringClass; |
150 ClassElement functionClass; | 197 ClassElement functionClass; |
151 ClassElement nullClass; | 198 ClassElement nullClass; |
152 ClassElement listClass; | 199 ClassElement listClass; |
153 ClassElement typeClass; | 200 ClassElement typeClass; |
154 ClassElement mapClass; | 201 ClassElement mapClass; |
155 ClassElement jsInvocationMirrorClass; | 202 ClassElement jsInvocationMirrorClass; |
| 203 /// Document class from dart:mirrors. |
| 204 ClassElement documentClass; |
156 Element assertMethod; | 205 Element assertMethod; |
157 Element identicalFunction; | 206 Element identicalFunction; |
158 Element functionApplyMethod; | 207 Element functionApplyMethod; |
159 Element invokeOnMethod; | 208 Element invokeOnMethod; |
160 Element createInvocationMirrorElement; | 209 Element createInvocationMirrorElement; |
161 | 210 |
162 Element get currentElement => _currentElement; | 211 Element get currentElement => _currentElement; |
163 withCurrentElement(Element element, f()) { | 212 withCurrentElement(Element element, f()) { |
164 Element old = currentElement; | 213 Element old = currentElement; |
165 _currentElement = element; | 214 _currentElement = element; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 this.enableConcreteTypeInference: false, | 289 this.enableConcreteTypeInference: false, |
241 this.maxConcreteTypeSize: 5, | 290 this.maxConcreteTypeSize: 5, |
242 this.enableMinification: false, | 291 this.enableMinification: false, |
243 this.enableNativeLiveTypeAnalysis: false, | 292 this.enableNativeLiveTypeAnalysis: false, |
244 bool emitJavaScript: true, | 293 bool emitJavaScript: true, |
245 bool generateSourceMap: true, | 294 bool generateSourceMap: true, |
246 bool disallowUnsafeEval: false, | 295 bool disallowUnsafeEval: false, |
247 this.analyzeAll: false, | 296 this.analyzeAll: false, |
248 this.rejectDeprecatedFeatures: false, | 297 this.rejectDeprecatedFeatures: false, |
249 this.checkDeprecationInSdk: false, | 298 this.checkDeprecationInSdk: false, |
| 299 this.preserveComments: false, |
250 List<String> strips: const []}) | 300 List<String> strips: const []}) |
251 : libraries = new Map<String, LibraryElement>(), | 301 : libraries = new Map<String, LibraryElement>(), |
252 progress = new Stopwatch() { | 302 progress = new Stopwatch() { |
253 progress.start(); | 303 progress.start(); |
254 world = new World(this); | 304 world = new World(this); |
255 | 305 |
256 closureMapping.ClosureNamer closureNamer; | 306 closureMapping.ClosureNamer closureNamer; |
257 if (emitJavaScript) { | 307 if (emitJavaScript) { |
258 js_backend.JavaScriptBackend jsBackend = | 308 js_backend.JavaScriptBackend jsBackend = |
259 new js_backend.JavaScriptBackend(this, generateSourceMap, | 309 new js_backend.JavaScriptBackend(this, generateSourceMap, |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 identicalFunction = coreLibrary.find(const SourceString('identical')); | 546 identicalFunction = coreLibrary.find(const SourceString('identical')); |
497 | 547 |
498 initializeSpecialClasses(); | 548 initializeSpecialClasses(); |
499 | 549 |
500 functionClass.ensureResolved(this); | 550 functionClass.ensureResolved(this); |
501 functionApplyMethod = | 551 functionApplyMethod = |
502 functionClass.lookupLocalMember(const SourceString('apply')); | 552 functionClass.lookupLocalMember(const SourceString('apply')); |
503 jsInvocationMirrorClass.ensureResolved(this); | 553 jsInvocationMirrorClass.ensureResolved(this); |
504 invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember( | 554 invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember( |
505 const SourceString('invokeOn')); | 555 const SourceString('invokeOn')); |
| 556 |
| 557 if (preserveComments) { |
| 558 var uri = new Uri.fromComponents(scheme: 'dart', path: 'mirrors'); |
| 559 LibraryElement libraryElement = |
| 560 libraryLoader.loadLibrary(uri, null, uri); |
| 561 documentClass = libraryElement.find(const SourceString('Comment')); |
| 562 } |
506 } | 563 } |
507 | 564 |
508 void importHelperLibrary(LibraryElement library) { | 565 void importHelperLibrary(LibraryElement library) { |
509 if (jsHelperLibrary != null) { | 566 if (jsHelperLibrary != null) { |
510 libraryLoader.importLibrary(library, jsHelperLibrary, null); | 567 libraryLoader.importLibrary(library, jsHelperLibrary, null); |
511 } | 568 } |
512 } | 569 } |
513 | 570 |
514 /** | 571 /** |
515 * Get an [Uri] pointing to a patch for the dart: library with | 572 * Get an [Uri] pointing to a patch for the dart: library with |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 } | 952 } |
896 | 953 |
897 // TODO(karlklose): split into findHelperFunction and findHelperClass and | 954 // TODO(karlklose): split into findHelperFunction and findHelperClass and |
898 // add a check that the element has the expected kind. | 955 // add a check that the element has the expected kind. |
899 Element findHelper(SourceString name) | 956 Element findHelper(SourceString name) |
900 => jsHelperLibrary.findLocal(name); | 957 => jsHelperLibrary.findLocal(name); |
901 Element findInterceptor(SourceString name) | 958 Element findInterceptor(SourceString name) |
902 => interceptorsLibrary.findLocal(name); | 959 => interceptorsLibrary.findLocal(name); |
903 | 960 |
904 bool get isMockCompilation => false; | 961 bool get isMockCompilation => false; |
| 962 |
| 963 Token processAndStripComments(Token currentToken) { |
| 964 Token firstToken = currentToken; |
| 965 Token prevToken; |
| 966 while (currentToken.kind != EOF_TOKEN) { |
| 967 if (identical(currentToken.kind, COMMENT_TOKEN)) { |
| 968 Token firstCommentToken = currentToken; |
| 969 while (identical(currentToken.kind, COMMENT_TOKEN)) { |
| 970 currentToken = currentToken.next; |
| 971 } |
| 972 commentMap[currentToken] = firstCommentToken; |
| 973 if (prevToken == null) { |
| 974 firstToken = currentToken; |
| 975 } else { |
| 976 prevToken.next = currentToken; |
| 977 } |
| 978 } |
| 979 prevToken = currentToken; |
| 980 currentToken = currentToken.next; |
| 981 } |
| 982 return firstToken; |
| 983 } |
905 } | 984 } |
906 | 985 |
907 class CompilerTask { | 986 class CompilerTask { |
908 final Compiler compiler; | 987 final Compiler compiler; |
909 final Stopwatch watch; | 988 final Stopwatch watch; |
910 | 989 |
911 CompilerTask(this.compiler) : watch = new Stopwatch(); | 990 CompilerTask(this.compiler) : watch = new Stopwatch(); |
912 | 991 |
913 String get name => 'Unknown task'; | 992 String get name => 'Unknown task'; |
914 int get timing => watch.elapsedMilliseconds; | 993 int get timing => watch.elapsedMilliseconds; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
991 // TODO(johnniwinther): Use [spannable] and [message] to provide better | 1070 // TODO(johnniwinther): Use [spannable] and [message] to provide better |
992 // information on assertion errors. | 1071 // information on assertion errors. |
993 if (condition is Function){ | 1072 if (condition is Function){ |
994 condition = condition(); | 1073 condition = condition(); |
995 } | 1074 } |
996 if (spannable == null || !condition) { | 1075 if (spannable == null || !condition) { |
997 throw new SpannableAssertionFailure(spannable, message); | 1076 throw new SpannableAssertionFailure(spannable, message); |
998 } | 1077 } |
999 return true; | 1078 return true; |
1000 } | 1079 } |
OLD | NEW |