001 /* Copyright (c) 2014, Erik Hogeman <Erik.Hogemn@gmail.com> 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 * * Redistributions of source code must retain the above copyright notice, 008 * this list of conditions and the following disclaimer. 009 * * Redistributions in binary form must reproduce the above copyright 010 * notice, this list of conditions and the following disclaimer in the 011 * documentation and/or other materials provided with the distribution. 012 * * Neither the name of the Lund University nor the names of its 013 * contributors may be used to endorse or promote products derived from 014 * this software without specific prior written permission. 015 * 016 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 017 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 018 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 019 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 020 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 021 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 022 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 023 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 024 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 025 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 026 * POSSIBILITY OF SUCH DAMAGE. 027 */ 028 aspect Modifiers { 029 syn lazy boolean Modifiers.isDefault() = numModifier("default") != 0; 030 031 syn lazy boolean MethodDecl.isDefault() = getModifiers().isDefault(); 032 033 refine Modifiers 034 eq MethodDecl.isAbstract() { 035 return getModifiers().isAbstract() || (hostType().isInterfaceDecl() && !isStatic() && !isDefault()); 036 } 037 038 039 // 8.4.3 040 refine Enums 041 public void MethodDecl.checkModifiers() { 042 super.checkModifiers(); 043 if (hostType().isClassDecl()) { 044 // 8.4.3.1 045 if (!hostType().isEnumDecl() && isAbstract() && !hostType().isAbstract()) { 046 error("class must be abstract to include abstract methods"); 047 } 048 // 8.4.3.1 049 if (isAbstract() && isPrivate()) { 050 error("method may not be abstract and private"); 051 } 052 // 8.4.3.1 053 // 8.4.3.2 054 if (isAbstract() && isStatic()) { 055 error("method may not be abstract and static"); 056 } 057 if (isAbstract() && isSynchronized()) { 058 error("method may not be abstract and synchronized"); 059 } 060 // 8.4.3.4 061 if (isAbstract() && isNative()) { 062 error("method may not be abstract and native"); 063 } 064 if (isAbstract() && isStrictfp()) { 065 error("method may not be abstract and strictfp"); 066 } 067 if (isNative() && isStrictfp()) { 068 error("method may not be native and strictfp"); 069 } 070 if (isDefault()) { 071 error("non-interface methods may not use the default modifier"); 072 } 073 } 074 if (hostType().isInterfaceDecl()) { 075 // 9.4 076 if (isAbstract()) { 077 if (isStatic()) { 078 errorf("interface method %s in %s can not be both abstract and static", 079 signature(), hostType().typeName()); 080 } 081 if (isDefault()) { 082 errorf("interface method %s in %s can not be both abstract and default", 083 signature(), hostType().typeName()); 084 } 085 if (isStrictfp()) { 086 errorf("interface method %s in %s can not be both abstract and strictfp", 087 signature(), hostType().typeName()); 088 } 089 } 090 if (isStatic() && isDefault()) { 091 errorf("interface method %s in %s can not be both static and default", 092 signature(), hostType().typeName()); 093 } 094 if (isNative()) { 095 errorf("interface method %s in %s may not be native", signature(), hostType().typeName()); 096 } 097 if (isSynchronized()) { 098 errorf("interface method %s in %s may not be synchronized", 099 signature(), hostType().typeName()); 100 } 101 if (isProtected()) { 102 errorf("interface method %s in %s may not be protected", 103 signature(), hostType().typeName()); 104 } 105 if (isPrivate()) { 106 errorf("interface method %s in %s may not be private", signature(), hostType().typeName()); 107 } else if (isFinal()) { 108 errorf("interface method %s in %s may not be final", signature(), hostType().typeName()); 109 } 110 } 111 } 112 113 refine Modifiers 114 public void TypeDecl.checkModifiers() { 115 refined(); 116 if (getModifiers().numModifier("default") != 0) { 117 error("the default modifier is only legal for interface method declarations"); 118 } 119 } 120 121 // 8.4.3 122 refine Modifiers 123 public void Modifiers.checkModifiers() { 124 refined(); 125 if (numModifier("default") > 1) { 126 error("only one default allowed"); 127 } 128 } 129 130 }