| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 /// Represents an entry's position in one of the global metadata arrays. | 7 /// Represents an entry's position in one of the global metadata arrays. |
| 8 /// | 8 /// |
| 9 /// [_rc] is used to count the number of references of the token in the | 9 /// [_rc] is used to count the number of references of the token in the |
| 10 /// ast for a program. | 10 /// ast for a program. |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 } | 100 } |
| 101 | 101 |
| 102 jsAst.Expression get value { | 102 jsAst.Expression get value { |
| 103 assert(_value != null); | 103 assert(_value != null); |
| 104 return _value; | 104 return _value; |
| 105 } | 105 } |
| 106 | 106 |
| 107 int get precedenceLevel => js_precedence.PRIMARY; | 107 int get precedenceLevel => js_precedence.PRIMARY; |
| 108 } | 108 } |
| 109 | 109 |
| 110 class MetadataCollector { | 110 class MetadataCollector implements TokenFinalizer { |
| 111 final Compiler _compiler; | 111 final Compiler _compiler; |
| 112 final Emitter _emitter; | 112 final Emitter _emitter; |
| 113 | 113 |
| 114 /// A token for a list of expressions that represent metadata, parameter names | 114 /// A token for a list of expressions that represent metadata, parameter names |
| 115 /// and type variable types. | 115 /// and type variable types. |
| 116 final _MetadataList _globalMetadata = new _MetadataList(); | 116 final _MetadataList _globalMetadata = new _MetadataList(); |
| 117 jsAst.Expression get globalMetadata => _globalMetadata; | 117 jsAst.Expression get globalMetadata => _globalMetadata; |
| 118 | 118 |
| 119 /// A map used to canonicalize the entries of globalMetadata. | 119 /// A map used to canonicalize the entries of globalMetadata. |
| 120 Map<String, _BoundMetadataEntry> _globalMetadataMap; | 120 Map<String, _BoundMetadataEntry> _globalMetadataMap; |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 // TODO(ahe): Why is metadata sometimes null? | 290 // TODO(ahe): Why is metadata sometimes null? |
| 291 if (link != null) { | 291 if (link != null) { |
| 292 for (; !link.isEmpty; link = link.tail) { | 292 for (; !link.isEmpty; link = link.tail) { |
| 293 metadata.add(reifyMetadata(link.head)); | 293 metadata.add(reifyMetadata(link.head)); |
| 294 } | 294 } |
| 295 } | 295 } |
| 296 return metadata; | 296 return metadata; |
| 297 }); | 297 }); |
| 298 } | 298 } |
| 299 | 299 |
| 300 void countTokensInProgram(jsAst.Program program) { | 300 @override |
| 301 void countTokensInAst(jsAst.Node ast) { |
| 301 TokenCounter visitor = new TokenCounter(); | 302 TokenCounter visitor = new TokenCounter(); |
| 302 visitor.countTokens(program); | 303 visitor.countTokens(ast); |
| 303 } | 304 } |
| 304 | 305 |
| 306 @override |
| 305 void finalizeTokens() { | 307 void finalizeTokens() { |
| 306 bool checkTokensInTypes(OutputUnit outputUnit, entries) { | 308 bool checkTokensInTypes(OutputUnit outputUnit, entries) { |
| 307 UnBoundDebugger debugger = new UnBoundDebugger(outputUnit); | 309 UnBoundDebugger debugger = new UnBoundDebugger(outputUnit); |
| 308 for (_BoundMetadataEntry entry in entries) { | 310 for (_BoundMetadataEntry entry in entries) { |
| 309 if (!entry.isUsed) continue; | 311 if (!entry.isUsed) continue; |
| 310 if (debugger.findUnboundPlaceholders(entry.entry)) { | 312 if (debugger.findUnboundPlaceholders(entry.entry)) { |
| 311 return false; | 313 return false; |
| 312 } | 314 } |
| 313 } | 315 } |
| 314 return true; | 316 return true; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 assert(checkTokensInTypes(outputUnit, typesMap.values)); | 353 assert(checkTokensInTypes(outputUnit, typesMap.values)); |
| 352 countTokensInTypes(typesMap.values); | 354 countTokensInTypes(typesMap.values); |
| 353 token.setExpression(finalizeMap(typesMap)); | 355 token.setExpression(finalizeMap(typesMap)); |
| 354 } else { | 356 } else { |
| 355 token.setExpression(new jsAst.ArrayInitializer([])); | 357 token.setExpression(new jsAst.ArrayInitializer([])); |
| 356 } | 358 } |
| 357 }); | 359 }); |
| 358 } | 360 } |
| 359 } | 361 } |
| 360 | 362 |
| 363 /// Interface for ast nodes that encapsulate an ast that needs to be |
| 364 /// traversed when counting tokens. |
| 365 /// |
| 366 /// TODO(herhut): Find a shared place once namer also uses tokens. |
| 367 abstract class AstContainer implements jsAst.Node { |
| 368 jsAst.Node get ast; |
| 369 } |
| 370 |
| 371 abstract class TokenFinalizer { |
| 372 void countTokensInAst(jsAst.Node ast); |
| 373 void finalizeTokens(); |
| 374 } |
| 375 |
| 361 class TokenCounter extends jsAst.BaseVisitor { | 376 class TokenCounter extends jsAst.BaseVisitor { |
| 362 @override | 377 @override |
| 378 visitNode(jsAst.Node node) { |
| 379 if (node is AstContainer) { |
| 380 node.ast.accept(this); |
| 381 } else { |
| 382 super.visitNode(node); |
| 383 } |
| 384 } |
| 385 |
| 386 @override |
| 363 visitDeferredNumber(jsAst.DeferredNumber token) { | 387 visitDeferredNumber(jsAst.DeferredNumber token) { |
| 364 if (token is _MetadataEntry) { | 388 if (token is _MetadataEntry) { |
| 365 token.markSeen(this); | 389 token.markSeen(this); |
| 366 } | 390 } |
| 367 } | 391 } |
| 368 | 392 |
| 369 void countTokens(jsAst.Node node) => node.accept(this); | 393 void countTokens(jsAst.Node node) => node.accept(this); |
| 370 } | 394 } |
| 371 | 395 |
| 372 class UnBoundDebugger extends jsAst.BaseVisitor { | 396 class UnBoundDebugger extends jsAst.BaseVisitor { |
| 373 OutputUnit outputUnit; | 397 OutputUnit outputUnit; |
| 374 bool _foundUnboundToken = false; | 398 bool _foundUnboundToken = false; |
| 375 | 399 |
| 376 UnBoundDebugger(this.outputUnit); | 400 UnBoundDebugger(this.outputUnit); |
| 377 | 401 |
| 378 @override | 402 @override |
| 379 visitDeferredNumber(jsAst.DeferredNumber token) { | 403 visitDeferredNumber(jsAst.DeferredNumber token) { |
| 380 if (token is _ForwardingMetadataEntry && !token.isBound) { | 404 if (token is _ForwardingMetadataEntry && !token.isBound) { |
| 381 _foundUnboundToken = true; | 405 _foundUnboundToken = true; |
| 382 } | 406 } |
| 383 } | 407 } |
| 384 | 408 |
| 385 bool findUnboundPlaceholders(jsAst.Node node) { | 409 bool findUnboundPlaceholders(jsAst.Node node) { |
| 386 node.accept(this); | 410 node.accept(this); |
| 387 return _foundUnboundToken; | 411 return _foundUnboundToken; |
| 388 } | 412 } |
| 389 } | 413 } |
| OLD | NEW |