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 f8436915f549084f126612d43627f88d6f351c85..842d0302b6466bb3f6d0cb0dd4c009e503417c82 100644 |
| --- a/lib/compiler/implementation/dart_backend/backend.dart |
| +++ b/lib/compiler/implementation/dart_backend/backend.dart |
| @@ -89,6 +89,67 @@ class DartBackend extends Backend { |
| Map<Element, TreeElements> get resolvedElements => |
| compiler.enqueuer.resolution.resolvedElements; |
| + /** |
| + * Tells whether it is safe to remove type declarations from variables, functions |
|
Anton Muhin
2012/09/17 18:45:15
nit: isn't this string too long?
Roman
2012/09/18 10:24:08
Sorry, forgot to check long lines before sending t
|
| + * parameters. It becomes not safe if: |
| + * 1) TypeError is used somewhere in the code, |
| + * 2) The code has typedefs in right hand side of IS checks, |
| + * 3) The code has classes which extend typedefs, have type arguments typedefs |
| + * or type variable bounds typedefs. |
| + * These restrictions can be less strict. |
| + */ |
| + bool isSafeToRemoveTypeDeclarations(Map<ClassElement, Set<Element>> classMembers) { |
|
Anton Muhin
2012/09/17 18:45:15
generic question: why do you have to parse element
Roman
2012/09/18 10:24:08
Unfortunately, no. When I have:
class A extends B<
|
| + Set<DartType> processedTypes = new Set<DartType>(); |
| + List<DartType> workQueue = new List<DartType>(); |
| + workQueue.addAll(classMembers.getKeys().map((classElement) => classElement.type)); |
|
Anton Muhin
2012/09/17 18:45:15
ditto for this line and all the lines below
|
| + workQueue.addAll(compiler.resolverWorld.isChecks); |
| + DartType typeErrorType = compiler.coreLibrary.find(new SourceString('TypeError')).type; |
| + if (workQueue.indexOf(typeErrorType) != -1) { |
| + return true; |
| + } |
| + |
| + void processTypeArguments(Element classElement, NodeList typeArguments) { |
| + if (typeArguments == null) return; |
| + for (Node typeArgument in typeArguments.nodes.toList()) { |
|
Anton Muhin
2012/09/17 18:45:15
do you need .toList()?
Roman
2012/09/18 10:24:08
Indeed I don't, Link is iterable. Removed.
|
| + if (typeArgument is TypeVariable) { |
| + typeArgument = typeArgument.bound; |
| + } |
| + if (typeArgument == null) continue; |
| + assert(typeArgument is TypeAnnotation); |
| + DartType argumentType = compiler.resolveTypeAnnotation(classElement, typeArgument); |
| + assert(argumentType !== null); |
| + workQueue.add(argumentType); |
|
Anton Muhin
2012/09/17 18:45:15
shouldn't you check processedTypes before adding a
Roman
2012/09/18 10:24:08
Not necessary, when I pop next work element, I che
Anton Muhin
2012/09/18 10:27:03
Yes, I know, we can just consume less memory. Ove
Roman
2012/09/18 13:12:21
It is possible that we can add processed items sev
|
| + } |
| + } |
| + |
| + while (!workQueue.isEmpty()) { |
| + DartType type = workQueue.removeLast(); |
| + if (processedTypes.contains(type)) continue; |
| + processedTypes.add(type); |
| + if (type is TypedefType) return true; |
| + if (type is InterfaceType) { |
| + ClassElement element = type.element; |
| + ClassNode node = element.parseNode(compiler); |
| + // Check class type args. |
| + processTypeArguments(element, node.typeParameters); |
| + // Check superclass type args. |
| + if (node.superclass !== null) { |
| + NodeList typeArguments = node.superclass.typeArguments; |
| + processTypeArguments(element, node.superclass.typeArguments); |
| + } |
| + // Check interfaces type args. |
| + for (Node interfaceNode in node.interfaces) { |
| + processTypeArguments(element, (interfaceNode as TypeAnnotation).typeArguments); |
| + } |
| + // Check all supertypes. |
| + if (element.allSupertypes !== null) { |
| + workQueue.addAll(element.allSupertypes.toList()); |
| + } |
| + } |
| + } |
| + return false; |
| + } |
| + |
| DartBackend(Compiler compiler, this.cutDeclarationTypes) |
| : tasks = <CompilerTask>[], |
| super(compiler); |
| @@ -233,13 +294,14 @@ class DartBackend extends Backend { |
| } |
| } |
| topLevelElements.forEach(makePlaceholders); |
| - |
| // Create renames. |
| Map<Node, String> renames = new Map<Node, String>(); |
| Map<LibraryElement, String> imports = new Map<LibraryElement, String>(); |
| + bool shouldCutDeclarationTypes = |
| + cutDeclarationTypes || !isSafeToRemoveTypeDeclarations(classMembers); |
| renamePlaceholders( |
| compiler, collector, renames, imports, |
| - fixedMemberNames, cutDeclarationTypes); |
| + fixedMemberNames, shouldCutDeclarationTypes)); |
| // Sort elements. |
| final sortedTopLevels = sortElements(topLevelElements); |
| @@ -288,6 +350,21 @@ class DartBackend extends Backend { |
| log(String message) => compiler.log('[DartBackend] $message'); |
| } |
| +/* |
|
Anton Muhin
2012/09/17 18:45:15
commented out code
Roman
2012/09/18 10:24:08
That was my first emotional attempt to write anoth
|
| +class TypedefRhsChecker extends AbstractVisitor { |
| + static bool hasTypedefsRhs(Node node) { |
| + TypedefRhsChecker checker = new TypedefRhsChecker(); |
| + node.accept(checker); |
| + } |
| + |
| + visitNode(Node node) { node.visitChildren(this); } |
| + |
| + visitSend(Send node) { |
| + if (node.isOperator && node.op) |
| + } |
| +} |
| +*/ |
| + |
| /** |
| * Some elements are not recorded by resolver now, |
| * for example, typedefs or classes which are only |