001 /* Copyright (c) 2005-2008, Torbjorn Ekman 002 * 2013, Jesper Öqvist <jesper.oqvist@cs.lth.se> 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without 006 * modification, are permitted provided that the following conditions are met: 007 * 008 * 1. Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * 2. Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * 3. Neither the name of the copyright holder nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 029 * POSSIBILITY OF SUCH DAMAGE. 030 */ 031 032 aspect ConstantPoolNames { 033 034 /** 035 * For a top-level type the constant pool name of the type is the same as the 036 * canonical name but with dots replaced by solidus. 037 * 038 * <p>For nested types the constant pool name is based on the enclosing top-level 039 * types constant pool name followed by a dollar sign and a unique index and/or 040 * the type name. 041 * 042 * @return constant pool name of this type 043 */ 044 syn lazy String TypeDecl.constantPoolName() { 045 String packageName = packageName(); 046 if (!packageName.equals("")) { 047 packageName = packageName.replace('.', '/') + "/"; 048 } 049 return packageName + uniqueName(); 050 } 051 052 /** 053 * Computes a unique name for this type in the enclosing package. 054 * <p>For top-level types the unique name is just the type name. For nested 055 * types it is the enclosing types unique name followed by a dollar sign and 056 * a unique index and/or the type name. 057 * 058 * @return a name for this type that is unique in the enclosing package 059 */ 060 syn lazy String TypeDecl.uniqueName() { 061 if (!isNestedType()) { 062 return getID(); 063 } else { 064 String prefix = enclosingType().uniqueName(); 065 if (isAnonymous()) { 066 return prefix + "$" + uniqueIndex(); 067 } else if (isLocalClass()) { 068 return prefix + "$" + uniqueIndex() + getID(); 069 } else { 070 return prefix + "$" + getID(); 071 } 072 } 073 } 074 075 syn lazy String ArrayDecl.constantPoolName() = typeDescriptor(); 076 077 syn lazy String TypeDecl.typeDescriptor() { 078 throw new Error("Can not compute typeDescriptor for " + getClass().getName()); 079 } 080 eq ClassDecl.typeDescriptor() = "L" + constantPoolName() + ";"; 081 eq InterfaceDecl.typeDescriptor() = "L" + constantPoolName() + ";"; 082 eq BooleanType.typeDescriptor() = "Z"; 083 eq ByteType.typeDescriptor() = "B"; 084 eq ShortType.typeDescriptor() = "S"; 085 eq IntType.typeDescriptor() = "I"; 086 eq LongType.typeDescriptor() = "J"; 087 eq CharType.typeDescriptor() = "C"; 088 eq FloatType.typeDescriptor() = "F"; 089 eq DoubleType.typeDescriptor() = "D"; 090 eq VoidType.typeDescriptor() = "V"; 091 eq ArrayDecl.typeDescriptor() { 092 StringBuilder dim = new StringBuilder(); 093 for (int i = 0; i < dimension(); i++) { 094 dim.append("["); 095 } 096 dim.append(elementType().typeDescriptor()); 097 return dim.toString(); 098 } 099 eq UnknownType.typeDescriptor() { 100 throw new Error("Trying to make a typeDescriptor() of Unknown"); 101 } 102 103 syn lazy String MethodDecl.descName() { 104 StringBuilder b = new StringBuilder(); 105 b.append("("); 106 for (int i=0; i<getNumParameter(); i++) { 107 b.append(getParameter(i).type().typeDescriptor()); 108 } 109 b.append(")"); 110 if (type().elementType().isUnknown()) { 111 System.err.println(getTypeAccess().dumpTree()); 112 throw new Error("Error generating descName for " + signature() + ", did not expect unknown return type"); 113 } 114 b.append(type().typeDescriptor()); 115 return b.toString(); 116 } 117 118 syn lazy String ConstructorDecl.descName() { 119 StringBuilder b = new StringBuilder(); 120 b.append("("); 121 // this$0 122 if (needsEnclosing()) { 123 b.append(enclosing().typeDescriptor()); 124 } 125 if (needsSuperEnclosing()) { 126 b.append(superEnclosing().typeDescriptor()); 127 } 128 // args 129 for (int i=0; i<getNumParameter(); i++) { 130 b.append(getParameter(i).type().typeDescriptor()); 131 } 132 b.append(")V"); 133 return b.toString(); 134 } 135 136 /** 137 * Computes the path to the parent directory of the source file of this 138 * compilation unit. 139 * 140 * <p>If the parent directory of the source file could not be computed 141 * the path to the working directory is returned. 142 * 143 * @return The path to the parent directory of the source file for this 144 * compilation unit, or "." if the path could not be computed. 145 */ 146 syn lazy String CompilationUnit.destinationPath() { 147 String parentPath = new File(pathName()).getParent(); 148 if (parentPath == null) { 149 return "."; 150 } else { 151 return parentPath; 152 } 153 } 154 155 /** 156 * @return The path to the classfiles that should be generated for this type. 157 */ 158 syn lazy String TypeDecl.destinationPath() { 159 if (program().options().hasValueForOption("-d")) { 160 return program().options().getValueForOption("-d") + File.separator 161 + constantPoolName() + ".class"; 162 } else { 163 return compilationUnit().destinationPath() + File.separator 164 + uniqueName() + ".class"; 165 } 166 } 167 }