Chromium Code Reviews| Index: lib/compiler/implementation/dart_backend/backend.dart |
| diff --git a/lib/compiler/implementation/dart_backend/backend.dart b/lib/compiler/implementation/dart_backend/backend.dart |
| index e945053271390603a7c9c4f74382329020eadcc0..e6729ff24f80fa088c32620c1162f3399aa72bb2 100644 |
| --- a/lib/compiler/implementation/dart_backend/backend.dart |
| +++ b/lib/compiler/implementation/dart_backend/backend.dart |
| @@ -14,12 +14,14 @@ class DartBackend extends Backend { |
| Map<Element, TreeElements> get resolvedElements() => |
| compiler.enqueuer.resolution.resolvedElements; |
| + Map<ClassElement, List<Element>> resolvedClasses; |
|
Anton Muhin
2012/07/10 09:50:12
resolvedClasses doesn't sound correct. That's rat
Anton Muhin
2012/07/10 09:50:12
should it be List<Element> or Set<Element>?
Roman
2012/07/10 10:45:15
renamed to resolvedClassMembers
Roman
2012/07/10 10:45:15
Correct! Changed to set
Anton Muhin
2012/07/10 11:31:40
I'd rather not see word resolved here. It's used
|
| DartBackend(Compiler compiler, [bool validateUnparse = false]) |
| : tasks = <CompilerTask>[], |
| unparseValidator = new UnparseValidator(compiler, validateUnparse), |
| super(compiler) { |
| tasks.add(unparseValidator); |
| + resolvedClasses = new HashMap<ClassElement, List<Element>>(); |
|
Anton Muhin
2012/07/10 09:50:12
no need to make default implementation explicit an
Roman
2012/07/10 10:45:15
Done.
|
| } |
| void enqueueHelpers(Enqueuer world) { |
| @@ -32,6 +34,59 @@ class DartBackend extends Backend { |
| Collection<LibraryElement> libraries) { |
| } |
| + /** |
| + * Adds given class element with its inner element to resolved classes |
| + * collections. |
| + */ |
| + void addResolvedElementForClass(Element element, ClassElement classElement) { |
| + if (element.enclosingElement !== classElement) { |
|
Anton Muhin
2012/07/10 09:50:12
assert?
Roman
2012/07/10 10:45:15
Done.
|
| + compiler.internalError( |
| + '${element} should have ${classElement} as enclosing'); |
| + } |
| + List<Element> resolvedElementsInClass = resolvedClasses[classElement]; |
| + if (resolvedElementsInClass == null) { |
|
Anton Muhin
2012/07/10 09:50:12
nit: there is putIfAbsent thing which may encode t
Roman
2012/07/10 10:45:15
Awesome thing, thanks!
|
| + resolvedElementsInClass = new List<Element>(); |
| + resolvedClasses[classElement] = resolvedElementsInClass; |
| + } |
| + resolvedElementsInClass.add(element); |
| + } |
| + |
| + /** |
| + * Resolves enclosing class for given elements and adds to a collection of |
| + * resolved classes, remembering the inner element. |
| + */ |
| + void resolveClass(Element element) { |
| + if (element.isTopLevel()) { |
|
Anton Muhin
2012/07/10 09:50:12
it rather should be an assert (see below regarding
Roman
2012/07/10 10:45:15
Done.
|
| + compiler.internalError( |
| + 'We should not resolve classes for top-level elements'); |
| + } |
| + var enclosingClass = element.enclosingElement; |
|
Anton Muhin
2012/07/10 09:50:12
it should probably be if (element.isMember())
Roman
2012/07/10 10:45:15
what do you mean by 'it'? This is a check whether
Anton Muhin
2012/07/10 11:31:40
Sorry. If I was to write this code, I would do th
Roman
2012/07/10 11:53:40
Removed processMember(), moved code to assemblePro
|
| + if (!enclosingClass.isClass()) { |
| + bailout('resolve $element with enclosing non-class element'); |
| + } |
| + addResolvedElementForClass(element, enclosingClass); |
| + if (!enclosingClass.isTopLevel()) { |
|
Anton Muhin
2012/07/10 09:50:12
I'd rather make it assert as classes must be top-l
Roman
2012/07/10 10:45:15
Done.
|
| + bailout('resolve $element with enclosing non-top-level class'); |
| + } |
| + } |
| + |
| + /** |
| + * Outputs given class element with given inner elements to a string buffer. |
| + */ |
| + void outputClass(ClassElement classElement, List<Element> innerElements, |
| + StringBuffer sb) { |
| + // TODO(smok): Very soon properly print out correct class declaration with |
| + // extends, implements, etc. |
| + sb.add('class '); |
| + sb.add(classElement.name.slowToString()); |
| + sb.add('{'); |
| + innerElements.forEach((element) { |
| + // TODO(smok): Filter out default constructors here. |
| + sb.add(element.parseNode(compiler).unparse()); |
| + }); |
| + sb.add('}'); |
| + } |
| + |
| void assembleProgram() { |
| resolvedElements.forEach((element, treeElements) { |
| unparseValidator.check(element); |
| @@ -56,7 +111,8 @@ class DartBackend extends Backend { |
| resolvedElements.forEach((element, treeElements) { |
| if (!shouldOutput(element)) return; |
| if (!element.isTopLevel()) { |
| - bailout('Cannot process non top-level $element'); |
| + resolveClass(element); |
|
Anton Muhin
2012/07/10 09:50:12
I would rather have something like:
if (element.i
Roman
2012/07/10 10:45:15
Done.
|
| + return; |
| } |
| if (element.isField()) { |
| @@ -79,6 +135,11 @@ class DartBackend extends Backend { |
| sb.add(element.parseNode(compiler).unparse()); |
| } |
| }); |
| + |
| + // Now output resolved classes with inner elements we met before. |
| + resolvedClasses.forEach((classElement, resolvedElements) { |
| + outputClass(classElement, resolvedElements, sb); |
|
Anton Muhin
2012/07/10 09:50:12
if you made outputClass a closure, you can have ni
Roman
2012/07/10 10:45:15
I would prefer to leave it this way, if you don't
|
| + }); |
| compiler.assembledCode = sb.toString(); |
| } catch (BailoutException e) { |
| compiler.assembledCode = ''' |