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 GenericsParTypeDecl {
032    
033      eq ParTypeDecl.fullName() {
034        if (isNestedType()) {
035          return enclosingType().fullName() + "." + nameWithArgs();
036        }
037        String packageName = packageName();
038        if (packageName.equals("")) {
039          return nameWithArgs();
040        }
041        return packageName + "." + nameWithArgs();
042      }
043    
044      eq ParTypeDecl.typeName() {
045        if (isNestedType()) {
046          return enclosingType().typeName() + "." + nameWithArgs();
047        }
048        String packageName = packageName();
049        if (packageName.equals("") || packageName.equals(PRIMITIVE_PACKAGE_NAME)) {
050          return nameWithArgs();
051        }
052        return packageName + "." + nameWithArgs();
053      }
054    
055      syn String ParTypeDecl.nameWithArgs() {
056        StringBuilder sb = new StringBuilder();
057        sb.append(name());
058        sb.append("<");
059        for (int i = 0; i < getNumArgument(); i++) {
060          if (i != 0) {
061            sb.append(", ");
062          }
063          sb.append(getArgument(i).type().fullName());
064        }
065        sb.append(">");
066        return sb.toString();
067      }
068      eq RawClassDecl.nameWithArgs() = name();
069      eq RawInterfaceDecl.nameWithArgs() = name();
070    
071      inh lazy TypeDecl ParTypeDecl.genericDecl();
072      eq Program.getChild().genericDecl() = null;
073      eq GenericClassDecl.getChild().genericDecl() = this;
074      eq GenericInterfaceDecl.getChild().genericDecl() = this;
075      eq ParClassDecl.getBodyDecl(int index).genericDecl() {
076        if (getBodyDecl(index) instanceof MemberTypeDecl) {
077          MemberTypeDecl m = (MemberTypeDecl) getBodyDecl(index);
078          return extractSingleType(genericDecl().memberTypes(m.typeDecl().name()));
079        }
080        return genericDecl();
081      }
082      eq ParInterfaceDecl.getBodyDecl(int index).genericDecl() {
083        if (getBodyDecl(index) instanceof MemberTypeDecl) {
084          MemberTypeDecl m = (MemberTypeDecl) getBodyDecl(index);
085          return extractSingleType(genericDecl().memberTypes(m.typeDecl().name()));
086        }
087        return genericDecl();
088      }
089    
090      syn boolean BodyDecl.visibleTypeParameters() = true;
091      eq MethodDecl.visibleTypeParameters() = !isStatic();
092      eq FieldDeclaration.visibleTypeParameters() = !isStatic();
093      eq StaticInitializer.visibleTypeParameters() = false;
094      eq MemberTypeDecl.visibleTypeParameters() = !isStatic();
095    
096      syn boolean TypeDecl.isTypeVariable() = false;
097      eq TypeVariable.isTypeVariable() = true;
098    
099      public Access ParTypeDecl.createQualifiedAccess() {
100        List typeArgumentList = new List();
101        for (int i = 0; i < getNumArgument(); i++) {
102          Access a = (Access) getArgument(i);
103          if (a instanceof TypeAccess) {
104            typeArgumentList.add(a.type().createQualifiedAccess());
105          } else {
106            typeArgumentList.add(a.treeCopyNoTransform());
107          }
108        }
109        if (!isTopLevelType()) {
110          if (isRawType()) {
111            return enclosingType().createQualifiedAccess().qualifiesAccess(
112              new TypeAccess("", getID())
113            );
114          } else {
115            return enclosingType().createQualifiedAccess().qualifiesAccess(
116              new ParTypeAccess(new TypeAccess("", getID()), typeArgumentList)
117            );
118          }
119        } else {
120          if (isRawType()) {
121            return new TypeAccess(packageName(), getID());
122          } else {
123            return new ParTypeAccess(new TypeAccess(packageName(), getID()), typeArgumentList);
124          }
125        }
126      }
127    }
128