langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java

Print this page

        

*** 27,36 **** --- 27,37 ---- import java.io.*; import java.net.URI; import java.net.URISyntaxException; import java.nio.CharBuffer; + import java.util.Arrays; import java.util.EnumSet; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.lang.model.SourceVersion;
*** 189,198 **** --- 190,204 ---- /** Switch: debug output for JSR 308-related operations. */ boolean debugJSR308; + /** A table to hold the constant pool indices for method parameter + * names, as given in LocalVariableTable attributes. + */ + int[] parameterNameIndices; + /** Get the ClassReader instance for this invocation. */ public static ClassReader instance(Context context) { ClassReader instance = context.get(classReaderKey); if (instance == null) instance = new ClassReader(context, true);
*** 921,956 **** new AttributeReader(names.LocalVariableTable, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) { void read(Symbol sym, int attrLen) { int newbp = bp + attrLen; if (saveParameterNames) { // pick up parameter names from the variable table - List<Name> parameterNames = List.nil(); - int firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0; - int endParam = firstParam + Code.width(sym.type.getParameterTypes()); int numEntries = nextChar(); ! for (int i=0; i<numEntries; i++) { int start_pc = nextChar(); int length = nextChar(); int nameIndex = nextChar(); int sigIndex = nextChar(); int register = nextChar(); ! if (start_pc == 0 && ! firstParam <= register && ! register < endParam) { ! int index = firstParam; ! for (Type t : sym.type.getParameterTypes()) { ! if (index == register) { ! parameterNames = parameterNames.prepend(readName(nameIndex)); ! break; } ! index += Code.width(t); } } } - parameterNames = parameterNames.reverse(); - ((MethodSymbol)sym).savedParameterNames = parameterNames; - } bp = newbp; } }, new AttributeReader(names.SourceFile, V45_3, CLASS_ATTRIBUTE) { --- 927,954 ---- new AttributeReader(names.LocalVariableTable, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) { void read(Symbol sym, int attrLen) { int newbp = bp + attrLen; if (saveParameterNames) { // pick up parameter names from the variable table int numEntries = nextChar(); ! for (int i = 0; i < numEntries; i++) { int start_pc = nextChar(); int length = nextChar(); int nameIndex = nextChar(); int sigIndex = nextChar(); int register = nextChar(); ! if (start_pc == 0) { ! // ensure array large enough ! if (register >= parameterNameIndices.length) { ! int newSize = Math.max(register, parameterNameIndices.length + 8); ! parameterNameIndices = ! Arrays.copyOf(parameterNameIndices, newSize); } ! parameterNameIndices[register] = nameIndex; } } } bp = newbp; } }, new AttributeReader(names.SourceFile, V45_3, CLASS_ATTRIBUTE) {
*** 1837,1856 **** --- 1835,1909 ---- type.getReturnType(), type.getThrownTypes(), syms.methodClass); } MethodSymbol m = new MethodSymbol(flags, name, type, currentOwner); + if (saveParameterNames) + initParameterNames(m); Symbol prevOwner = currentOwner; currentOwner = m; try { readMemberAttrs(m); } finally { currentOwner = prevOwner; } + if (saveParameterNames) + setParameterNames(m, type); return m; } + void initParameterNames(MethodSymbol sym) { + // make allowance for synthetic parameters. + final int excessSlots = 4; + int expectedParameterSlots = + Code.width(sym.type.getParameterTypes()) + excessSlots; + if (parameterNameIndices == null + || parameterNameIndices.length < expectedParameterSlots) { + parameterNameIndices = new int[expectedParameterSlots]; + } else + Arrays.fill(parameterNameIndices, 0); + } + + void setParameterNames(MethodSymbol sym, Type jvmType) { + int firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0; + // the code in readMethod may have skipped the first parameter when + // setting up the MethodType. If so, we make a corresponding allowance + // here for the position of the first parameter. Note that this + // assumes the skipped parameter has a width of 1 -- i.e. it is not + // a double width type (long or double.) + if (sym.name == names.init && currentOwner.hasOuterInstance()) { + // Sometimes anonymous classes don't have an outer + // instance, however, there is no reliable way to tell so + // we never strip this$n + if (!currentOwner.name.isEmpty()) + firstParam += 1; + } + + if (sym.type != jvmType) { + // reading the method attributes has caused the symbol's type to + // be changed. (i.e. the Signature attribute.) This may happen if + // there are hidden (synthetic) parameters in the descriptor, but + // not in the Signature. The position of these hidden parameters + // is unspecified; for now, assume they are at the beginning, and + // so skip over them. The primary case for this is two hidden + // parameters passed into Enum constructors. + int skip = Code.width(jvmType.getParameterTypes()) + - Code.width(sym.type.getParameterTypes()); + firstParam += skip; + } + List<Name> paramNames = List.nil(); + int index = firstParam; + for (Type t: sym.type.getParameterTypes()) { + int nameIdx = (index < parameterNameIndices.length + ? parameterNameIndices[index] : 0); + Name name = nameIdx == 0 ? names.empty : readName(nameIdx); + paramNames = paramNames.prepend(name); + index += Code.width(t); + } + sym.savedParameterNames = paramNames.reverse(); + } + /** Skip a field or method */ void skipMember() { bp = bp + 6; char ac = nextChar();