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