001 /* 002 * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered 003 * by the modified BSD License. You should have received a copy of the 004 * modified BSD license with this compiler. 005 * 006 * Copyright (c) 2005-2008, Torbjorn Ekman 007 * All rights reserved. 008 */ 009 010 aspect AnonymousClasses { 011 012 //eq ParameterDeclaration.getTypeAccess().hostType() = hostType().isAnonymous() ? ((ClassDecl)hostType()).superclass() : hostType(); 013 014 inh TypeDecl AnonymousDecl.superType(); 015 eq ClassInstanceExpr.getTypeDecl().superType() = getAccess().type(); 016 eq Program.getChild().superType() = null; 017 018 inh ConstructorDecl AnonymousDecl.constructorDecl(); 019 eq ClassInstanceExpr.getTypeDecl().constructorDecl() { 020 Collection c = getAccess().type().constructors(); 021 SimpleSet maxSpecific = mostSpecificConstructor(c); 022 if(maxSpecific.size() == 1) 023 return (ConstructorDecl)maxSpecific.iterator().next(); 024 return unknownConstructor(); 025 } 026 eq Program.getChild().constructorDecl() = null; 027 028 public int TypeDecl.anonymousIndex = 0; 029 030 eq AnonymousDecl.isCircular() = false; 031 032 syn lazy Opt AnonymousDecl.getSuperClassAccessOpt() { 033 if(superType().isInterfaceDecl()) 034 return new Opt(typeObject().createQualifiedAccess()); 035 else 036 return new Opt(superType().createBoundAccess()); 037 } 038 syn lazy List AnonymousDecl.getImplementsList() { 039 if(superType().isInterfaceDecl()) 040 return new List().add(superType().createBoundAccess()); 041 else 042 return new List(); 043 } 044 045 public int TypeDecl.nextAnonymousIndex() { 046 if(isNestedType()) 047 return enclosingType().nextAnonymousIndex(); 048 return anonymousIndex++; 049 } 050 051 /** 052 * Create the list of parameters for the anonymous class constructor. 053 */ 054 protected List AnonymousDecl.constructorParameterList(ConstructorDecl decl) { 055 List parameterList = new List(); 056 for(int i = 0; i < decl.getNumParameter(); i++) { 057 ParameterDeclaration param = decl.getParameter(i); 058 parameterList.add( 059 new ParameterDeclaration( 060 param.type().createBoundAccess(), 061 param.name() 062 ) 063 ); 064 } 065 066 return parameterList; 067 } 068 069 rewrite AnonymousDecl { 070 when(noConstructor()) 071 to AnonymousDecl { 072 setModifiers(new Modifiers(new List().add(new Modifier("final")))); 073 074 ConstructorDecl decl = constructorDecl(); 075 Modifiers modifiers = (Modifiers)decl.getModifiers().fullCopy(); 076 String anonName = "Anonymous" + nextAnonymousIndex(); 077 078 ConstructorDecl constructor = new ConstructorDecl(modifiers, anonName, 079 constructorParameterList(decl), new List(), new Opt(), new Block()); 080 constructor.setDefaultConstructor(); 081 addBodyDecl(constructor); 082 083 setID(anonName); 084 085 List argList = new List(); 086 for(int i = 0; i < constructor.getNumParameter(); i++) { 087 argList.add(new VarAccess(constructor.getParameter(i).name())); 088 } 089 090 constructor.setConstructorInvocation( 091 new ExprStmt( 092 new SuperConstructorAccess("super", argList) 093 ) 094 ); 095 096 HashSet set = new HashSet(); 097 for(int i = 0; i < getNumBodyDecl(); i++) { 098 if(getBodyDecl(i) instanceof InstanceInitializer) { 099 InstanceInitializer init = (InstanceInitializer)getBodyDecl(i); 100 set.addAll(init.exceptions()); 101 } 102 else if(getBodyDecl(i) instanceof FieldDeclaration) { 103 FieldDeclaration f = (FieldDeclaration)getBodyDecl(i); 104 if(f.isInstanceVariable()) { 105 set.addAll(f.exceptions()); 106 } 107 } 108 } 109 List exceptionList = new List(); 110 for(Iterator iter = set.iterator(); iter.hasNext(); ) { 111 TypeDecl exceptionType = (TypeDecl)iter.next(); 112 if(exceptionType.isNull()) 113 exceptionType = typeNullPointerException(); 114 exceptionList.add(exceptionType.createQualifiedAccess()); 115 } 116 constructor.setExceptionList(exceptionList); 117 return this; 118 /* 119 setModifiers(new Modifiers(new List().add(new Modifier("final")))); 120 121 ConstructorDecl constructor = new ConstructorDecl(); 122 addBodyDecl(constructor); 123 124 constructor.setModifiers((Modifiers)constructorDecl().getModifiers().fullCopy()); 125 String name = "Anonymous" + nextAnonymousIndex(); 126 setID(name); 127 constructor.setID(name); 128 129 List parameterList = new List(); 130 for(int i = 0; i < constructorDecl().getNumParameter(); i++) { 131 parameterList.add( 132 new ParameterDeclaration( 133 constructorDecl().getParameter(i).type().createBoundAccess(), 134 constructorDecl().getParameter(i).name() 135 ) 136 ); 137 } 138 constructor.setParameterList(parameterList); 139 140 List argList = new List(); 141 for(int i = 0; i < constructor.getNumParameter(); i++) 142 argList.add(new VarAccess(constructor.getParameter(i).name())); 143 constructor.setConstructorInvocation( 144 new ExprStmt( 145 new SuperConstructorAccess("super", argList) 146 ) 147 ); 148 constructor.setBlock(new Block()); 149 150 HashSet set = new HashSet(); 151 for(int i = 0; i < getNumBodyDecl(); i++) { 152 if(getBodyDecl(i) instanceof InstanceInitializer) { 153 InstanceInitializer init = (InstanceInitializer)getBodyDecl(i); 154 set.addAll(init.exceptions()); 155 } 156 else if(getBodyDecl(i) instanceof FieldDeclaration) { 157 FieldDeclaration f = (FieldDeclaration)getBodyDecl(i); 158 if(f.isInstanceVariable()) { 159 set.addAll(f.exceptions()); 160 } 161 } 162 } 163 List exceptionList = new List(); 164 for(Iterator iter = set.iterator(); iter.hasNext(); ) { 165 TypeDecl exceptionType = (TypeDecl)iter.next(); 166 if(exceptionType.isNull()) 167 exceptionType = typeNullPointerException(); 168 exceptionList.add(exceptionType.createQualifiedAccess()); 169 } 170 constructor.setExceptionList(exceptionList); 171 return this; 172 */ 173 } 174 } 175 inh TypeDecl AnonymousDecl.typeNullPointerException(); 176 177 178 syn lazy Collection FieldDeclaration.exceptions() { 179 HashSet set = new HashSet(); 180 if(isInstanceVariable() && hasInit()) { 181 collectExceptions(set, this); 182 for(Iterator iter = set.iterator(); iter.hasNext(); ) { 183 TypeDecl typeDecl = (TypeDecl)iter.next(); 184 if(!getInit().reachedException(typeDecl)) 185 iter.remove(); 186 } 187 } 188 return set; 189 } 190 191 syn lazy Collection InstanceInitializer.exceptions() { 192 HashSet set = new HashSet(); 193 collectExceptions(set, this); 194 for(Iterator iter = set.iterator(); iter.hasNext(); ) { 195 TypeDecl typeDecl = (TypeDecl)iter.next(); 196 if(!getBlock().reachedException(typeDecl)) 197 iter.remove(); 198 } 199 return set; 200 } 201 202 protected void ASTNode.collectExceptions(Collection c, ASTNode target) { 203 for(int i = 0; i < getNumChild(); i++) 204 getChild(i).collectExceptions(c, target); 205 } 206 207 protected void ThrowStmt.collectExceptions(Collection c, ASTNode target) { 208 super.collectExceptions(c, target); 209 TypeDecl exceptionType = getExpr().type(); 210 if(exceptionType == typeNull()) 211 exceptionType = typeNullPointerException(); 212 c.add(exceptionType); 213 } 214 215 protected void MethodAccess.collectExceptions(Collection c, ASTNode target) { 216 super.collectExceptions(c, target); 217 for(int i = 0; i < decl().getNumException(); i++) 218 c.add(decl().getException(i).type()); 219 } 220 221 }