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    }