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