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 Modifiers { 032 void ASTNode.checkModifiers() { 033 } 034 035 syn lazy boolean TypeDecl.hasAbstract() = false; 036 037 syn lazy Collection TypeDecl.unimplementedMethods() = Collections.EMPTY_LIST; 038 eq ClassDecl.unimplementedMethods() { 039 Collection c = new ArrayList(); 040 for (Iterator iter = interfacesMethodsIterator(); iter.hasNext(); ) { 041 MethodDecl m = (MethodDecl) iter.next(); 042 boolean implemented = false; 043 SimpleSet set = (SimpleSet) localMethodsSignature(m.signature()); 044 if (set.size() == 1) { 045 MethodDecl n = (MethodDecl) set.iterator().next(); 046 if (!n.isAbstract()) { 047 implemented = true; 048 } 049 } 050 if (!implemented) { 051 set = ancestorMethods(m.signature()); 052 for (Iterator i2 = set.iterator(); i2.hasNext(); ) { 053 MethodDecl n = (MethodDecl) i2.next(); 054 if (!n.isAbstract() && n.isPublic()) { 055 implemented = true; 056 break; 057 } 058 } 059 } 060 if (!implemented) { 061 c.add(m); 062 } 063 } 064 065 if (hasSuperclass()) { 066 for (Iterator iter = superclass().unimplementedMethods().iterator(); iter.hasNext(); ) { 067 MethodDecl m = (MethodDecl) iter.next(); 068 SimpleSet set = (SimpleSet) localMethodsSignature(m.signature()); 069 if (set.size() == 1) { 070 MethodDecl n = (MethodDecl) set.iterator().next(); 071 if (n.isAbstract() || !n.overrides(m)) { 072 c.add(m); 073 } 074 } else { 075 c.add(m); 076 } 077 } 078 } 079 080 for (Iterator iter = localMethodsIterator(); iter.hasNext(); ) { 081 MethodDecl m = (MethodDecl) iter.next(); 082 if (m.isAbstract()) { 083 c.add(m); 084 } 085 } 086 return c; 087 } 088 089 eq ClassDecl.hasAbstract() = !unimplementedMethods().isEmpty(); 090 091 public void TypeDecl.checkModifiers() { 092 super.checkModifiers(); 093 // 8.1.1 094 if (isPublic() && !isTopLevelType() && !isMemberType()) { 095 error("public pertains only to top level types and member types"); 096 } 097 098 // 8.1.1 099 if ((isProtected() || isPrivate()) && !(isMemberType() && enclosingType().isClassDecl())) { 100 error("protected and private may only be used on member types within a directly enclosing class declaration"); 101 } 102 103 // 8.1.1 104 if (isStatic() && !isMemberType()) { 105 error("static pertains only to member types"); 106 } 107 108 109 // 8.4.3.1 110 // 8.1.1.1 111 if (!isAbstract() && hasAbstract()) { 112 StringBuilder sb = new StringBuilder(); 113 sb.append("" + name() + " is not declared abstract but contains abstract members: \n"); 114 for (Iterator iter = unimplementedMethods().iterator(); iter.hasNext(); ) { 115 MethodDecl m = (MethodDecl) iter.next(); 116 sb.append(" " + m.signature() + " in " + m.hostType().typeName() + "\n"); 117 } 118 error(sb.toString()); 119 } 120 } 121 122 public void ClassDecl.checkModifiers() { 123 super.checkModifiers(); 124 // 8.1.1.2 final Classes 125 TypeDecl typeDecl = superclass(); 126 if (!typeDecl.isUnknown() && typeDecl.isFinal()) { 127 errorf("class %s may not extend final class %s", fullName(), typeDecl.fullName()); 128 } 129 130 } 131 132 public void InterfaceDecl.checkModifiers() { 133 super.checkModifiers(); 134 } 135 136 public void ConstructorDecl.checkModifiers() { 137 super.checkModifiers(); 138 } 139 140 public void FieldDeclaration.checkModifiers() { 141 super.checkModifiers(); 142 if (hostType().isInterfaceDecl()) { 143 if (isProtected()) { 144 error("an interface field may not be protected"); 145 } 146 if (isPrivate()) { 147 error("an interface field may not be private"); 148 } 149 if (isTransient()) { 150 error("an interface field may not be transient"); 151 } 152 if (isVolatile()) { 153 error("an interface field may not be volatile"); 154 } 155 } 156 } 157 158 // 8.4.3 159 public void MethodDecl.checkModifiers() { 160 super.checkModifiers(); 161 if (hostType().isClassDecl()) { 162 // 8.4.3.1 163 if (isAbstract() && !hostType().isAbstract()) { 164 error("class must be abstract to include abstract methods"); 165 } 166 // 8.4.3.1 167 if (isAbstract() && isPrivate()) { 168 error("method may not be abstract and private"); 169 } 170 // 8.4.3.1 171 // 8.4.3.2 172 if (isAbstract() && isStatic()) { 173 error("method may not be abstract and static"); 174 } 175 if (isAbstract() && isSynchronized()) { 176 error("method may not be abstract and synchronized"); 177 } 178 // 8.4.3.4 179 if (isAbstract() && isNative()) { 180 error("method may not be abstract and native"); 181 } 182 if (isAbstract() && isStrictfp()) { 183 error("method may not be abstract and strictfp"); 184 } 185 if (isNative() && isStrictfp()) { 186 error("method may not be native and strictfp"); 187 } 188 } 189 if (hostType().isInterfaceDecl()) { 190 // 9.4 191 if (isStatic()) { 192 errorf("interface method %s in %s may not be static", signature(), hostType().typeName()); 193 } 194 if (isStrictfp()) { 195 errorf("interface method %s in %s may not be strictfp", signature(), hostType().typeName()); 196 } 197 if (isNative()) { 198 errorf("interface method %s in %s may not be native", signature(), hostType().typeName()); 199 } 200 if (isSynchronized()) { 201 errorf("interface method %s in %s may not be synchronized", signature(), 202 hostType().typeName()); 203 } 204 if (isProtected()) { 205 errorf("interface method %s in %s may not be protected", signature(), 206 hostType().typeName()); 207 } 208 if (isPrivate()) { 209 errorf("interface method %s in %s may not be private", signature(), hostType().typeName()); 210 } else if (isFinal()) { 211 errorf("interface method %s in %s may not be final", signature(), hostType().typeName()); 212 } 213 } 214 } 215 216 // 8.1.2 217 public void StaticInitializer.checkModifiers() { 218 super.checkModifiers(); 219 if (hostType().isInnerClass()) { 220 error("*** Inner classes may not declare static initializers"); 221 } 222 } 223 224 // 8.1.2 225 public void MemberInterfaceDecl.checkModifiers() { 226 super.checkModifiers(); 227 if (hostType().isInnerClass()) { 228 error("*** Inner classes may not declare member interfaces"); 229 } 230 } 231 232 public void MemberDecl.checkModifiers() { 233 if (!isSynthetic()) { 234 super.checkModifiers(); 235 if (isStatic() && hostType().isInnerClass() && !isConstant()) { 236 error("*** Inner classes may not declare static members, unless they are compile-time constant fields"); 237 } 238 } 239 } 240 241 syn lazy boolean TypeDecl.isPublic() = getModifiers().isPublic() || isMemberType() && enclosingType().isInterfaceDecl(); 242 //eq InterfaceDecl.isPublic() = !isProtected() && !isPrivate(); 243 syn boolean TypeDecl.isPrivate() = getModifiers().isPrivate(); 244 syn boolean TypeDecl.isProtected() = getModifiers().isProtected(); 245 syn boolean TypeDecl.isAbstract() = getModifiers().isAbstract(); 246 eq InterfaceDecl.isAbstract() = true; 247 syn lazy boolean TypeDecl.isStatic() = getModifiers().isStatic() || isMemberType() && enclosingType().isInterfaceDecl(); 248 // 8.5.2 249 eq InterfaceDecl.isStatic() = getModifiers().isStatic() || isMemberType(); 250 syn boolean TypeDecl.isFinal() = getModifiers().isFinal(); 251 syn boolean TypeDecl.isStrictfp() = getModifiers().isStrictfp(); 252 253 syn boolean TypeDecl.isSynthetic() = getModifiers().isSynthetic(); 254 255 syn boolean MemberDecl.isSynthetic() = false; 256 eq MethodDecl.isSynthetic() = getModifiers().isSynthetic(); 257 eq FieldDeclaration.isSynthetic() = getModifiers().isSynthetic(); 258 syn boolean ConstructorDecl.isSynthetic() = getModifiers().isSynthetic(); 259 260 syn boolean VariableDeclaration.isSynthetic() = getModifiers().isSynthetic(); 261 syn boolean ParameterDeclaration.isSynthetic() = getModifiers().isSynthetic(); 262 263 syn boolean MemberDecl.isStatic(); 264 265 syn boolean MethodDecl.isPublic() = getModifiers().isPublic() || hostType().isInterfaceDecl(); 266 syn boolean MethodDecl.isPrivate() = getModifiers().isPrivate(); 267 syn boolean MethodDecl.isProtected() = getModifiers().isProtected(); 268 syn boolean MethodDecl.isAbstract() = getModifiers().isAbstract() || hostType().isInterfaceDecl(); 269 syn boolean MethodDecl.isStatic() = getModifiers().isStatic(); 270 // 8.4.3.3 271 syn boolean MethodDecl.isFinal() = getModifiers().isFinal() || hostType().isFinal() || isPrivate(); 272 syn boolean MethodDecl.isSynchronized() = getModifiers().isSynchronized(); 273 syn boolean MethodDecl.isNative() = getModifiers().isNative(); 274 syn boolean MethodDecl.isStrictfp() = getModifiers().isStrictfp(); 275 276 syn boolean ConstructorDecl.isPublic() = getModifiers().isPublic(); 277 syn boolean ConstructorDecl.isPrivate() = getModifiers().isPrivate(); 278 syn boolean ConstructorDecl.isProtected() = getModifiers().isProtected(); 279 280 syn boolean FieldDeclaration.isPublic() = getModifiers().isPublic() || hostType().isInterfaceDecl(); 281 syn boolean FieldDeclaration.isPrivate() = getModifiers().isPrivate(); 282 syn boolean FieldDeclaration.isProtected() = getModifiers().isProtected(); 283 syn boolean FieldDeclaration.isStatic() = getModifiers().isStatic() || hostType().isInterfaceDecl(); 284 syn boolean FieldDecl.isStatic() = getModifiers().isStatic(); 285 syn boolean FieldDeclaration.isFinal() = getModifiers().isFinal() || hostType().isInterfaceDecl(); 286 syn boolean FieldDeclaration.isTransient() = getModifiers().isTransient(); 287 syn boolean FieldDeclaration.isVolatile() = getModifiers().isVolatile(); 288 289 eq MemberTypeDecl.isStatic() = typeDecl().isStatic(); 290 291 // 8.1.1 & 9.1.1 292 eq TypeDecl.getModifiers().mayBePublic() = true; 293 eq TypeDecl.getModifiers().mayBeProtected() = true; 294 eq TypeDecl.getModifiers().mayBePrivate() = true; 295 eq TypeDecl.getModifiers().mayBeAbstract() = true; 296 eq TypeDecl.getModifiers().mayBeStatic() = true; 297 eq TypeDecl.getModifiers().mayBeStrictfp() = true; 298 299 // 8.1.1 300 eq ClassDecl.getModifiers().mayBeFinal() = true; 301 302 // 8.3.1 303 eq FieldDeclaration.getModifiers().mayBePublic() = true; 304 eq FieldDeclaration.getModifiers().mayBeProtected() = true; 305 eq FieldDeclaration.getModifiers().mayBePrivate() = true; 306 eq FieldDeclaration.getModifiers().mayBeStatic() = true; 307 eq FieldDeclaration.getModifiers().mayBeFinal() = true; 308 eq FieldDeclaration.getModifiers().mayBeTransient() = true; 309 eq FieldDeclaration.getModifiers().mayBeVolatile() = true; 310 311 // 8.4.3 312 eq MethodDecl.getModifiers().mayBePublic() = true; 313 eq MethodDecl.getModifiers().mayBeProtected() = true; 314 eq MethodDecl.getModifiers().mayBePrivate() = true; 315 eq MethodDecl.getModifiers().mayBeAbstract() = true; 316 eq MethodDecl.getModifiers().mayBeStatic() = true; 317 eq MethodDecl.getModifiers().mayBeFinal() = true; 318 eq MethodDecl.getModifiers().mayBeSynchronized() = true; 319 eq MethodDecl.getModifiers().mayBeNative() = true; 320 eq MethodDecl.getModifiers().mayBeStrictfp() = true; 321 322 // 8.8.3 323 eq ConstructorDecl.getModifiers().mayBePublic() = true; 324 eq ConstructorDecl.getModifiers().mayBeProtected() = true; 325 eq ConstructorDecl.getModifiers().mayBePrivate() = true; 326 327 eq VariableDeclaration.getModifiers().mayBeFinal() = true; 328 329 eq ParameterDeclaration.getModifiers().mayBeFinal() = true; 330 331 eq Program.getChild().mayBePublic() = false; 332 eq Program.getChild().mayBeProtected() = false; 333 eq Program.getChild().mayBePrivate() = false; 334 eq Program.getChild().mayBeStatic() = false; 335 eq Program.getChild().mayBeFinal() = false; 336 eq Program.getChild().mayBeAbstract() = false; 337 eq Program.getChild().mayBeVolatile() = false; 338 eq Program.getChild().mayBeTransient() = false; 339 eq Program.getChild().mayBeStrictfp() = false; 340 eq Program.getChild().mayBeSynchronized() = false; 341 eq Program.getChild().mayBeNative() = false; 342 eq TypeDecl.getBodyDecl().mayBePublic() = false; 343 eq TypeDecl.getBodyDecl().mayBeProtected() = false; 344 eq TypeDecl.getBodyDecl().mayBePrivate() = false; 345 eq TypeDecl.getBodyDecl().mayBeStatic() = false; 346 eq TypeDecl.getBodyDecl().mayBeFinal() = false; 347 eq TypeDecl.getBodyDecl().mayBeAbstract() = false; 348 eq TypeDecl.getBodyDecl().mayBeVolatile() = false; 349 eq TypeDecl.getBodyDecl().mayBeTransient() = false; 350 eq TypeDecl.getBodyDecl().mayBeStrictfp() = false; 351 eq TypeDecl.getBodyDecl().mayBeSynchronized() = false; 352 eq TypeDecl.getBodyDecl().mayBeNative() = false; 353 354 // 8.4.3 355 public void Modifiers.checkModifiers() { 356 super.checkModifiers(); 357 if (numProtectionModifiers() > 1) { 358 error("only one public, protected, private allowed"); 359 } 360 if (numModifier("static") > 1) { 361 error("only one static allowed"); 362 } 363 // 8.4.3.1 364 // 8.4.3.2 365 // 8.1.1.2 366 if (numCompletenessModifiers() > 1) { 367 error("only one of final, abstract, volatile allowed"); 368 } 369 if (numModifier("synchronized") > 1) { 370 error("only one synchronized allowed"); 371 } 372 if (numModifier("transient") > 1) { 373 error("only one transient allowed"); 374 } 375 if (numModifier("native") > 1) { 376 error("only one native allowed"); 377 } 378 if (numModifier("strictfp") > 1) { 379 error("only one strictfp allowed"); 380 } 381 382 if (isPublic() && !mayBePublic()) { 383 error("modifier public not allowed in this context"); 384 } 385 if (isPrivate() && !mayBePrivate()) { 386 error("modifier private not allowed in this context"); 387 } 388 if (isProtected() && !mayBeProtected()) { 389 error("modifier protected not allowed in this context"); 390 } 391 if (isStatic() && !mayBeStatic()) { 392 error("modifier static not allowed in this context"); 393 } 394 if (isFinal() && !mayBeFinal()) { 395 error("modifier final not allowed in this context"); 396 } 397 if (isAbstract() && !mayBeAbstract()) { 398 error("modifier abstract not allowed in this context"); 399 } 400 if (isVolatile() && !mayBeVolatile()) { 401 error("modifier volatile not allowed in this context"); 402 } 403 if (isTransient() && !mayBeTransient()) { 404 error("modifier transient not allowed in this context"); 405 } 406 if (isStrictfp() && !mayBeStrictfp()) { 407 error("modifier strictfp not allowed in this context"); 408 } 409 if (isSynchronized() && !mayBeSynchronized()) { 410 error("modifier synchronized not allowed in this context"); 411 } 412 if (isNative() && !mayBeNative()) { 413 error("modifier native not allowed in this context"); 414 } 415 } 416 417 inh TypeDecl Modifiers.hostType(); 418 419 inh boolean Modifiers.mayBePublic(); 420 inh boolean Modifiers.mayBePrivate(); 421 inh boolean Modifiers.mayBeProtected(); 422 inh boolean Modifiers.mayBeStatic(); 423 inh boolean Modifiers.mayBeFinal(); 424 inh boolean Modifiers.mayBeAbstract(); 425 inh boolean Modifiers.mayBeVolatile(); 426 inh boolean Modifiers.mayBeTransient(); 427 inh boolean Modifiers.mayBeStrictfp(); 428 inh boolean Modifiers.mayBeSynchronized(); 429 inh boolean Modifiers.mayBeNative(); 430 431 syn lazy boolean Modifiers.isPublic() = numModifier("public") != 0; 432 syn lazy boolean Modifiers.isPrivate() = numModifier("private") != 0; 433 syn lazy boolean Modifiers.isProtected() = numModifier("protected") != 0; 434 syn lazy boolean Modifiers.isStatic() = numModifier("static") != 0; 435 syn lazy boolean Modifiers.isFinal() = numModifier("final") != 0; 436 syn lazy boolean Modifiers.isAbstract() = numModifier("abstract") != 0; 437 syn lazy boolean Modifiers.isVolatile() = numModifier("volatile") != 0; 438 syn lazy boolean Modifiers.isTransient() = numModifier("transient") != 0; 439 syn lazy boolean Modifiers.isStrictfp() = numModifier("strictfp") != 0; 440 syn lazy boolean Modifiers.isSynchronized() = numModifier("synchronized") != 0; 441 syn lazy boolean Modifiers.isNative() = numModifier("native") != 0; 442 443 syn lazy boolean Modifiers.isSynthetic() = numModifier("synthetic") != 0; 444 445 syn int Modifiers.numProtectionModifiers() = 446 numModifier("public") + numModifier("protected") + numModifier("private"); 447 448 syn int Modifiers.numCompletenessModifiers() = 449 numModifier("abstract") + numModifier("final") + numModifier("volatile"); 450 451 syn lazy int Modifiers.numModifier(String name) { 452 int n = 0; 453 for (int i = 0; i < getNumModifier(); i++) { 454 String s = getModifier(i).getID(); 455 if (s.equals(name)) { 456 n++; 457 } 458 } 459 return n; 460 } 461 462 }