List<DecompiledLocalVariable> (VirtualMachineProxyImpl vm, Location location, MultiMap<Integer, String> namesMap) { if (!vm.canGetBytecodes()) { return Collections.emptyList(); } try { LOG.assertTrue(location != null); final com.sun.jdi.Method method = location.method(); final Location methodLocation = method.location(); if (methodLocation == null || methodLocation.codeIndex() < 0) { // native or abstract method return Collections.emptyList(); } long codeIndex = location.codeIndex(); if (codeIndex > 0) { final byte[] bytecodes = method.bytecodes(); if (bytecodes != null && bytecodes.length > 0) { final int firstLocalVariableSlot = getFirstLocalsSlot(method); final HashMap<Integer, DecompiledLocalVariable> usedVars = new HashMap<>(); MethodBytecodeUtil.visit(method, codeIndex, new MethodVisitor(Opcodes.API_VERSION) { @Override public void visitVarInsn(int opcode, int slot) { if (slot >= firstLocalVariableSlot) { DecompiledLocalVariable variable = usedVars.get(slot); String typeSignature = MethodBytecodeUtil.getVarInstructionType(opcode).getDescriptor(); if (variable == null || !typeSignature.equals(variable.signature())) { variable = new DecompiledLocalVariable(slot, false, typeSignature, namesMap.get(slot)); usedVars.put(slot, variable); } } } }, false); if (usedVars.isEmpty()) { return Collections.emptyList(); } List<DecompiledLocalVariable> vars = new ArrayList<>(usedVars.values()); vars.sort(Comparator.comparingInt(DecompiledLocalVariable::slot)); return vars; } } } catch (UnsupportedOperationException ignored) { } catch (VMDisconnectedException e) { throw e; } catch (Exception e) { if (!vm.canBeModified()) { // do not care in read only vms LOG.debug(e); } else { LOG.warn(e); } } return Collections.emptyList(); }