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 AccessControl { 011 // 6.6 Access Control 012 013 syn lazy boolean ArrayDecl.accessibleFrom(TypeDecl type) = elementType().accessibleFrom(type); 014 015 syn lazy boolean TypeDecl.accessibleFromPackage(String packageName) = 016 !isPrivate() && (isPublic() || hostPackage().equals(packageName)); 017 018 syn lazy boolean TypeDecl.accessibleFromExtend(TypeDecl type) { 019 if(type == this) 020 return true; 021 if(isInnerType()) { 022 if(!enclosingType().accessibleFrom(type)) { 023 return false; 024 } 025 } 026 if(isPublic()) 027 return true; 028 else if(isProtected()) { 029 // isProtected implies a nested type 030 if(hostPackage().equals(type.hostPackage())) { 031 return true; 032 } 033 if(type.isNestedType() && type.enclosingType().withinBodyThatSubclasses(enclosingType()) != null) 034 return true; 035 return false; 036 } 037 else if(isPrivate()) { 038 return topLevelType() == type.topLevelType(); 039 } 040 else 041 return hostPackage().equals(type.hostPackage()); 042 } 043 044 syn lazy boolean TypeDecl.accessibleFrom(TypeDecl type) { 045 if(type == this) 046 return true; 047 if(isInnerType()) { 048 if(!enclosingType().accessibleFrom(type)) { 049 return false; 050 } 051 } 052 if(isPublic()) { 053 return true; 054 } 055 else if(isProtected()) { 056 if(hostPackage().equals(type.hostPackage())) { 057 return true; 058 } 059 if(isMemberType()) { 060 TypeDecl typeDecl = type; 061 while(typeDecl != null && !typeDecl.instanceOf(enclosingType())) 062 typeDecl = typeDecl.enclosingType(); 063 if(typeDecl != null) { 064 return true; 065 } 066 } 067 return false; 068 } 069 else if(isPrivate()) { 070 return topLevelType() == type.topLevelType(); 071 } 072 else { 073 return hostPackage().equals(type.hostPackage()); 074 } 075 } 076 077 syn lazy boolean MethodDecl.accessibleFrom(TypeDecl type) { 078 if(isPublic()) { 079 return true; 080 } 081 else if(isProtected()) { 082 if(hostPackage().equals(type.hostPackage())) 083 return true; 084 if(type.withinBodyThatSubclasses(hostType()) != null) 085 return true; 086 return false; 087 } 088 else if(isPrivate()) 089 return hostType().topLevelType() == type.topLevelType(); 090 else 091 return hostPackage().equals(type.hostPackage()); 092 } 093 094 syn lazy boolean ConstructorDecl.accessibleFrom(TypeDecl type) { 095 if(!hostType().accessibleFrom(type)) 096 return false; 097 else if(isPublic()) 098 return true; 099 else if(isProtected()) { 100 return true; 101 } 102 else if(isPrivate()) { 103 return hostType().topLevelType() == type.topLevelType(); 104 } 105 else 106 return hostPackage().equals(type.hostPackage()); 107 } 108 109 syn lazy boolean FieldDeclaration.accessibleFrom(TypeDecl type) { 110 if(isPublic()) 111 return true; 112 else if(isProtected()) { 113 if(hostPackage().equals(type.hostPackage())) 114 return true; 115 if(type.withinBodyThatSubclasses(hostType()) != null) 116 return true; 117 return false; 118 } 119 else if(isPrivate()) 120 return hostType().topLevelType() == type.topLevelType(); 121 else 122 return hostPackage().equals(type.hostPackage()); 123 } 124 125 public void ASTNode.accessControl() { 126 } 127 128 public void TypeAccess.accessControl() { 129 super.accessControl(); 130 TypeDecl hostType = hostType(); 131 if(hostType != null && !hostType.isUnknown() && !type().accessibleFrom(hostType)) { 132 error("" + this + " in " + hostType().fullName() + " can not access type " + type().fullName()); 133 } 134 else if((hostType == null || hostType.isUnknown()) && !type().accessibleFromPackage(hostPackage())) { 135 error("" + this + " can not access type " + type().fullName()); 136 } 137 } 138 139 public void ClassInstanceExpr.accessControl() { 140 super.accessControl(); 141 if(type().isAbstract()) 142 error("Can not instantiate abstract class " + type().fullName()); 143 if(!decl().accessibleFrom(hostType())) 144 error("constructor " + decl().signature() + " is not accessible"); 145 } 146 147 public void ClassDecl.accessControl() { 148 super.accessControl(); 149 150 // 8.1.1.2 final Classes 151 TypeDecl typeDecl = hasSuperclass() ? superclass() : null; 152 if(typeDecl != null && !typeDecl.accessibleFromExtend(this)) 153 //if(typeDecl != null && !isCircular() && !typeDecl.accessibleFrom(this)) 154 error("class " + fullName() + " may not extend non accessible type " + typeDecl.fullName()); 155 156 if(hasSuperclass() && !superclass().accessibleFrom(this)) 157 error("a superclass must be accessible which " + superclass().name() + " is not"); 158 159 // 8.1.4 160 for(int i = 0; i < getNumImplements(); i++) { 161 TypeDecl decl = getImplements(i).type(); 162 if(!decl.isCircular() && !decl.accessibleFrom(this)) 163 error("class " + fullName() + " can not implement non accessible type " + decl.fullName()); 164 } 165 } 166 167 public void InterfaceDecl.accessControl() { 168 super.accessControl(); 169 170 if(!isCircular()) { 171 // 9.1.2 172 HashSet set = new HashSet(); 173 for(int i = 0; i < getNumSuperInterfaceId(); i++) { 174 TypeDecl decl = getSuperInterfaceId(i).type(); 175 176 if(!decl.isInterfaceDecl() && !decl.isUnknown()) 177 error("interface " + fullName() + " tries to extend non interface type " + decl.fullName()); 178 if(!decl.isCircular() && !decl.accessibleFrom(this)) 179 error("interface " + fullName() + " can not extend non accessible type " + decl.fullName()); 180 181 if(set.contains(decl)) 182 error("extended interface " + decl.fullName() + " mentionened multiple times in extends clause"); 183 set.add(decl); 184 } 185 } 186 } 187 }