001 /* Copyright (c) 2005-2008, Torbjorn Ekman 002 * All rights reserved. 003 * 004 * Redistribution and use in source and binary forms, with or without 005 * modification, are permitted provided that the following conditions are met: 006 * 007 * 1. Redistributions of source code must retain the above copyright notice, 008 * this list of conditions and the following disclaimer. 009 * 010 * 2. Redistributions in binary form must reproduce the above copyright notice, 011 * this list of conditions and the following disclaimer in the documentation 012 * and/or other materials provided with the distribution. 013 * 014 * 3. Neither the name of the copyright holder nor the names of its 015 * contributors may be used to endorse or promote products derived from this 016 * software without specific prior written permission. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 028 * POSSIBILITY OF SUCH DAMAGE. 029 */ 030 031 aspect AnonymousClasses { 032 033 inh TypeDecl AnonymousDecl.superType(); 034 eq ClassInstanceExpr.getTypeDecl().superType() = getAccess().type(); 035 eq Program.getChild().superType() = null; 036 037 inh ConstructorDecl AnonymousDecl.constructorDecl(); 038 039 eq ClassInstanceExpr.getTypeDecl().constructorDecl() { 040 Collection<ConstructorDecl> c = getAccess().type().constructors(); 041 SimpleSet maxSpecific = mostSpecificConstructor(c); 042 if (maxSpecific.size() == 1) { 043 return (ConstructorDecl) maxSpecific.iterator().next(); 044 } 045 return unknownConstructor(); 046 } 047 048 eq Program.getChild().constructorDecl() = unknownConstructor(); 049 050 public int TypeDecl.anonymousIndex = 0; 051 052 eq AnonymousDecl.isCircular() = false; 053 054 syn lazy Opt AnonymousDecl.getSuperClassOpt() { 055 if (superType().isInterfaceDecl()) { 056 return new Opt(typeObject().createQualifiedAccess()); 057 } else { 058 return new Opt(superType().createBoundAccess()); 059 } 060 } 061 062 syn lazy List AnonymousDecl.getImplementsList() { 063 if (superType().isInterfaceDecl()) { 064 return new List().add(superType().createBoundAccess()); 065 } else { 066 return new List(); 067 } 068 } 069 070 public int TypeDecl.nextAnonymousIndex() { 071 if (isNestedType()) { 072 return enclosingType().nextAnonymousIndex(); 073 } 074 return anonymousIndex++; 075 } 076 077 /** 078 * Create the list of parameters for the anonymous class constructor. 079 */ 080 protected List AnonymousDecl.constructorParameterList(ConstructorDecl decl) { 081 List parameterList = new List(); 082 for (int i = 0; i < decl.getNumParameter(); i++) { 083 ParameterDeclaration param = decl.getParameter(i); 084 parameterList.add( 085 new ParameterDeclaration( 086 param.type().createBoundAccess(), 087 param.name() 088 ) 089 ); 090 } 091 092 return parameterList; 093 } 094 095 inh TypeDecl AnonymousDecl.typeNullPointerException(); 096 097 syn lazy Collection FieldDeclaration.exceptions() { 098 HashSet set = new HashSet(); 099 if (isInstanceVariable() && hasInit()) { 100 collectExceptions(set, this); 101 for (Iterator iter = set.iterator(); iter.hasNext(); ) { 102 TypeDecl typeDecl = (TypeDecl) iter.next(); 103 if (!getInit().reachedException(typeDecl)) { 104 iter.remove(); 105 } 106 } 107 } 108 return set; 109 } 110 111 syn lazy Collection InstanceInitializer.exceptions() { 112 HashSet set = new HashSet(); 113 collectExceptions(set, this); 114 for (Iterator iter = set.iterator(); iter.hasNext(); ) { 115 TypeDecl typeDecl = (TypeDecl) iter.next(); 116 if (!getBlock().reachedException(typeDecl)) { 117 iter.remove(); 118 } 119 } 120 return set; 121 } 122 123 protected void ASTNode.collectExceptions(Collection c, ASTNode target) { 124 for (int i = 0; i < getNumChild(); i++) { 125 getChild(i).collectExceptions(c, target); 126 } 127 } 128 129 protected void ThrowStmt.collectExceptions(Collection c, ASTNode target) { 130 super.collectExceptions(c, target); 131 TypeDecl exceptionType = getExpr().type(); 132 if (exceptionType == typeNull()) { 133 exceptionType = typeNullPointerException(); 134 } 135 c.add(exceptionType); 136 } 137 138 protected void MethodAccess.collectExceptions(Collection c, ASTNode target) { 139 super.collectExceptions(c, target); 140 for (int i = 0; i < decl().getNumException(); i++) { 141 c.add(decl().getException(i).type()); 142 } 143 } 144 145 }