public static LocalVariableAnnotation getLocalVariableAnnotation( Method method, int local, int position1, int position2) { LocalVariableTable localVariableTable = method.getLocalVariableTable(); String localName = "?"; if (localVariableTable != null) { LocalVariable lv1 = localVariableTable.getLocalVariable(local, position1); if (lv1 == null) { lv1 = localVariableTable.getLocalVariable(local, position2); position1 = position2; } if (lv1 != null) localName = lv1.getName(); else for (LocalVariable lv : localVariableTable.getLocalVariableTable()) { if (lv.getIndex() == local) { if (!localName.equals("?") && !localName.equals(lv.getName())) { // not a single consistent name localName = "?"; break; } localName = lv.getName(); } } } LineNumberTable lineNumbers = method.getLineNumberTable(); if (lineNumbers == null) return new LocalVariableAnnotation(localName, local, position1); int line = lineNumbers.getSourceLine(position1); return new LocalVariableAnnotation(localName, local, position1, line); }
/** * looks for methods that have it's parameters all follow the form arg0, arg1, arg2, or parm0, * parm1, parm2 etc, where the method actually has code in it * * @param cls the class to check */ private void checkIDEGeneratedParmNames(JavaClass cls) { methods: for (Method m : cls.getMethods()) { if (!m.isPublic()) { continue; } String name = m.getName(); if (Values.CONSTRUCTOR.equals(name) || Values.STATIC_INITIALIZER.equals(name)) { continue; } LocalVariableTable lvt = m.getLocalVariableTable(); if (lvt == null) { continue; } if (m.getCode().getCode().length <= MAX_EMPTY_METHOD_SIZE) { continue; } int numArgs = m.getArgumentTypes().length; if (numArgs == 0) { continue; } int offset = m.isStatic() ? 0 : 1; for (int i = 0; i < numArgs; i++) { LocalVariable lv = lvt.getLocalVariable(offset + i, 0); if ((lv == null) || (lv.getName() == null)) { continue methods; } Matcher ma = ARG_PATTERN.matcher(lv.getName()); if (!ma.matches()) { continue methods; } } bugReporter.reportBug( new BugInstance( this, BugType.IMC_IMMATURE_CLASS_IDE_GENERATED_PARAMETER_NAMES.name(), NORMAL_PRIORITY) .addClass(cls) .addMethod(cls, m)); return; } }
/** * Loads the names of the local variables. * * <p>NOTE: BCEL only gives us a list of all *named* locals, which might not include all local * vars (temporaries, like StringBuilder). Note that we have to fill this with "?" in order to * make the returned array correspond with slot numbers */ protected String[] loadLocalVariableNames(Method m) { Code c = m.getCode(); if (c == null) { return null; } LocalVariableTable lvt = c.getLocalVariableTable(); if (lvt == null) { if (!warnedLocalInfo && !ci.isSystemClass()) { Debug.println(Debug.WARNING); Debug.println(Debug.WARNING, "No local variable information available"); Debug.println(Debug.WARNING, "for " + getCompleteName()); Debug.println(Debug.WARNING, "Recompile with -g to include this information"); Debug.println(Debug.WARNING); warnedLocalInfo = true; } return null; } LocalVariable[] lv = lvt.getLocalVariableTable(); int length = lv.length; String[] v = new String[c.getMaxLocals()]; for (int i = 0; i < length; i++) { v[lv[i].getIndex()] = lv[i].getName(); } for (int i = 0; i < v.length; i++) { if (v[i] == null) { v[i] = "?"; } } return v; }