001    /* Copyright (c) 2011, Jesper Öqvist <jesper.oqvist@cs.lth.se>
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    /**
032     * The @Override annotation was changed in Java 6.
033     *
034     * The specification of the @Override annotation since Java 6:
035     *
036     * "If a method declaration is annotated with the annotation @Override,
037     * but the method does not override or implement a method declared in a
038     * supertype, or is not override-equivalent to a public method of Object,
039     * a compile-time error will occur.
040     *
041     * In Java 5 the Override annotation was allowed for methods implementing
042     * an interface-declared method.
043     */
044    aspect Annotations {
045      refine Annotations
046      public void Annotation.checkOverride() {
047        if (decl().fullName().equals("java.lang.Override") &&
048            enclosingBodyDecl() instanceof MethodDecl) {
049    
050          MethodDecl method = (MethodDecl)enclosingBodyDecl();
051          TypeDecl host = method.hostType();
052          SimpleSet ancestors = host.ancestorMethods(method.signature());
053          boolean found = false;
054          for (Iterator iter = ancestors.iterator(); iter.hasNext(); ) {
055            MethodDecl decl = (MethodDecl)iter.next();
056            if (method.overrides(decl)) {
057              found = true;
058              break;
059            }
060          }
061          if (!found) {
062            TypeDecl typeObject = lookupType("java.lang", "Object");
063            SimpleSet overrides = typeObject.localMethodsSignature(method.signature());
064            if (overrides.isEmpty() ||
065                !((MethodDecl) overrides.iterator().next()).isPublic())
066              error("method does not override a method from a supertype");
067          }
068        }
069      }
070    }