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 class WorkItem { | 5 class WorkItem { |
6 final Element element; | 6 final Element element; |
7 TreeElements resolutionTree; | 7 TreeElements resolutionTree; |
8 bool allowSpeculativeOptimization = true; | 8 bool allowSpeculativeOptimization = true; |
9 List<HTypeGuard> guards = const <HTypeGuard>[]; | 9 List<HTypeGuard> guards = const <HTypeGuard>[]; |
10 | 10 |
11 WorkItem(this.element, this.resolutionTree); | 11 WorkItem(this.element, this.resolutionTree); |
12 | 12 |
13 bool isAnalyzed() => resolutionTree !== null; | 13 bool isAnalyzed() => resolutionTree !== null; |
14 | 14 |
15 String run(Compiler compiler, Enqueuer world) { | 15 String run(Compiler compiler, Enqueuer world) { |
16 String code = world.universe.generatedCode[element]; | 16 String code = world.universe.generatedCode[element]; |
17 if (code !== null) return code; | 17 if (code !== null) return code; |
18 if (!isAnalyzed()) compiler.analyze(this); | 18 if (!isAnalyzed()) { |
19 resolutionTree = world.getCachedElements(element); | |
kasperl
2012/06/12 05:50:12
So getCachedElements has the side-effect that this
ahe
2012/06/12 06:22:48
getCachedElements does not have side-effects. Assi
| |
20 if (!isAnalyzed()) compiler.analyze(this); | |
21 } | |
22 if (world.isFirstQueue) { | |
23 world.resolvedElements[element] = resolutionTree; | |
24 return null; | |
25 } | |
26 if (resolutionTree === null) { | |
27 compiler.internalError('Error: unresolved element', element: element); | |
28 } | |
19 return compiler.codegen(this); | 29 return compiler.codegen(this); |
20 } | 30 } |
21 } | 31 } |
22 | 32 |
23 class Backend { | 33 class Backend { |
24 final Compiler compiler; | 34 final Compiler compiler; |
25 | 35 |
26 Backend(this.compiler); | 36 Backend(this.compiler); |
27 | 37 |
28 abstract String codegen(WorkItem work); | 38 abstract String codegen(WorkItem work); |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
359 FunctionSignature parameters = mainMethod.computeSignature(this); | 369 FunctionSignature parameters = mainMethod.computeSignature(this); |
360 parameters.forEachParameter((Element parameter) { | 370 parameters.forEachParameter((Element parameter) { |
361 reportFatalError('main cannot have parameters', parameter); | 371 reportFatalError('main cannot have parameters', parameter); |
362 }); | 372 }); |
363 } | 373 } |
364 | 374 |
365 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution | 375 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution |
366 // should know this. | 376 // should know this. |
367 world.populate(this, libraries.getValues()); | 377 world.populate(this, libraries.getValues()); |
368 | 378 |
369 // Not yet ready to process the enqueuer.resolution queue... | 379 log('Resolving'); |
370 // processQueue(enqueuer.resolution); | 380 processQueue(enqueuer.resolution, main); |
381 log('Resolved ${enqueuer.resolution.resolvedElements.length} elements.'); | |
382 | |
383 log('Compiling'); | |
371 processQueue(enqueuer.codegen, main); | 384 processQueue(enqueuer.codegen, main); |
372 | 385 |
373 backend.assembleProgram(); | 386 backend.assembleProgram(); |
374 if (!enqueuer.codegen.queue.isEmpty()) { | 387 enqueuer.codegen.forEach((WorkItem work) { |
375 internalErrorOnElement(enqueuer.codegen.queue.first().element, | 388 internalErrorOnElement(work.element, "work list is not empty"); |
376 "work list is not empty"); | 389 }); |
377 } | |
378 } | 390 } |
379 | 391 |
380 processQueue(Enqueuer world, Element main) { | 392 processQueue(Enqueuer world, Element main) { |
381 backend.processNativeClasses(world, libraries.getValues()); | 393 backend.processNativeClasses(world, libraries.getValues()); |
382 world.addToWorkList(main); | 394 world.addToWorkList(main); |
383 codegenProgress.reset(); | 395 codegenProgress.reset(); |
384 while (!world.queue.isEmpty()) { | 396 world.forEach((WorkItem work) { |
385 WorkItem work = world.queue.removeLast(); | |
386 withCurrentElement(work.element, () => work.run(this, world)); | 397 withCurrentElement(work.element, () => work.run(this, world)); |
387 } | 398 }); |
388 world.queueIsClosed = true; | 399 world.queueIsClosed = true; |
389 assert(world.checkNoEnqueuedInvokedInstanceMethods()); | 400 assert(world.checkNoEnqueuedInvokedInstanceMethods()); |
390 world.registerFieldClosureInvocations(); | 401 world.registerFieldClosureInvocations(); |
391 } | 402 } |
392 | 403 |
393 TreeElements analyzeElement(Element element) { | 404 TreeElements analyzeElement(Element element) { |
405 if (element is AbstractFieldElement) { | |
406 return null; | |
407 } | |
408 final int allowed = ElementCategory.VARIABLE | ElementCategory.FUNCTION | |
409 | ElementCategory.FACTORY; | |
410 if (!element.isAccessor() && (element.kind.category & allowed) == 0) { | |
411 return null; | |
412 } | |
394 assert(parser !== null); | 413 assert(parser !== null); |
395 Node tree = parser.parse(element); | 414 Node tree = parser.parse(element); |
396 validator.validate(tree); | 415 validator.validate(tree); |
397 unparseValidator.check(element); | 416 unparseValidator.check(element); |
398 TreeElements elements = resolver.resolve(element); | 417 TreeElements elements = resolver.resolve(element); |
399 checker.check(tree, elements); | 418 checker.check(tree, elements); |
400 return elements; | 419 return elements; |
401 } | 420 } |
402 | 421 |
403 TreeElements analyze(WorkItem work) { | 422 TreeElements analyze(WorkItem work) { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
502 // not a good error location, but cancel really is "internal | 521 // not a good error location, but cancel really is "internal |
503 // error" or "not implemented yet", so the vicinity is good | 522 // error" or "not implemented yet", so the vicinity is good |
504 // enough for now. | 523 // enough for now. |
505 element = element.enclosingElement; | 524 element = element.enclosingElement; |
506 // TODO(ahe): I plan to overhaul this infrastructure anyways. | 525 // TODO(ahe): I plan to overhaul this infrastructure anyways. |
507 } | 526 } |
508 if (element === null) { | 527 if (element === null) { |
509 element = currentElement; | 528 element = currentElement; |
510 } | 529 } |
511 Token position = element.position(); | 530 Token position = element.position(); |
531 Uri uri = element.getCompilationUnit().script.uri; | |
512 if (position === null) { | 532 if (position === null) { |
513 Uri uri = element.getCompilationUnit().script.uri; | |
514 return new SourceSpan(uri, 0, 0); | 533 return new SourceSpan(uri, 0, 0); |
534 } else { | |
535 return SourceSpan.withOffsets( | |
536 position, position, | |
537 (beginOffset, endOffset) { | |
538 return new SourceSpan(uri, beginOffset, endOffset); | |
539 }); | |
515 } | 540 } |
516 return spanFromTokens(position, position); | |
517 } | 541 } |
518 | 542 |
519 Script readScript(Uri uri, [ScriptTag node]) { | 543 Script readScript(Uri uri, [ScriptTag node]) { |
520 unimplemented('Compiler.readScript'); | 544 unimplemented('Compiler.readScript'); |
521 } | 545 } |
522 | 546 |
523 String get legDirectory() { | 547 String get legDirectory() { |
524 unimplemented('Compiler.legDirectory'); | 548 unimplemented('Compiler.legDirectory'); |
525 } | 549 } |
526 | 550 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
595 // invariant that endOffset > beginOffset, but for EOF the | 619 // invariant that endOffset > beginOffset, but for EOF the |
596 // charoffset of the next token may be [beginOffset]. This can | 620 // charoffset of the next token may be [beginOffset]. This can |
597 // also happen for synthetized tokens that are produced during | 621 // also happen for synthetized tokens that are produced during |
598 // error handling. | 622 // error handling. |
599 final endOffset = | 623 final endOffset = |
600 Math.max((end.next !== null) ? end.next.charOffset : 0, beginOffset + 1); | 624 Math.max((end.next !== null) ? end.next.charOffset : 0, beginOffset + 1); |
601 assert(endOffset > beginOffset); | 625 assert(endOffset > beginOffset); |
602 return f(beginOffset, endOffset); | 626 return f(beginOffset, endOffset); |
603 } | 627 } |
604 } | 628 } |
OLD | NEW |