IDEA-130708 Incorrect locals names
This commit is contained in:
@@ -61,7 +61,7 @@ public class StructMember {
|
||||
if (StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TABLE.equals(name) && attributes.containsKey(name)) {
|
||||
// merge all variable tables
|
||||
StructLocalVariableTableAttribute table = (StructLocalVariableTableAttribute)attributes.getWithKey(name);
|
||||
table.addLocalVariableTable((StructLocalVariableTableAttribute)attribute);
|
||||
table.add((StructLocalVariableTableAttribute)attribute);
|
||||
}
|
||||
else if (StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE.equals(name) && attributes.containsKey(name)) {
|
||||
// merge all variable tables
|
||||
|
||||
@@ -19,9 +19,12 @@ import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
|
||||
import org.jetbrains.java.decompiler.util.DataInputFullStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/*
|
||||
u2 local_variable_table_length;
|
||||
@@ -34,32 +37,70 @@ import java.util.Map;
|
||||
}
|
||||
*/
|
||||
public class StructLocalVariableTableAttribute extends StructGeneralAttribute {
|
||||
|
||||
private Map<Integer, String> mapVarNames = Collections.emptyMap();
|
||||
private List<LocalVariable> localVariables = Collections.emptyList();
|
||||
|
||||
@Override
|
||||
public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException {
|
||||
int len = data.readUnsignedShort();
|
||||
if (len > 0) {
|
||||
mapVarNames = new HashMap<>(len);
|
||||
localVariables = new ArrayList<>(len);
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
data.discard(4);
|
||||
int start_pc = data.readUnsignedShort();
|
||||
int length = data.readUnsignedShort();
|
||||
int nameIndex = data.readUnsignedShort();
|
||||
data.discard(2);
|
||||
int descriptorIndex = data.readUnsignedShort();
|
||||
int varIndex = data.readUnsignedShort();
|
||||
mapVarNames.put(varIndex, pool.getPrimitiveConstant(nameIndex).getString());
|
||||
localVariables.add(new LocalVariable(start_pc,
|
||||
length,
|
||||
pool.getPrimitiveConstant(nameIndex).getString(),
|
||||
pool.getPrimitiveConstant(descriptorIndex).getString(),
|
||||
varIndex));
|
||||
}
|
||||
}
|
||||
else {
|
||||
mapVarNames = Collections.emptyMap();
|
||||
localVariables = Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
public void addLocalVariableTable(StructLocalVariableTableAttribute attr) {
|
||||
mapVarNames.putAll(attr.getMapVarNames());
|
||||
public void add(StructLocalVariableTableAttribute attr) {
|
||||
localVariables.addAll(attr.localVariables);
|
||||
}
|
||||
|
||||
public Map<Integer, String> getMapVarNames() {
|
||||
return mapVarNames;
|
||||
public String getName(int index, int visibleOffset) {
|
||||
return matchingVars(index, visibleOffset).map(v -> v.name).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public String getDescriptor(int index, int visibleOffset) {
|
||||
return matchingVars(index, visibleOffset).map(v -> v.descriptor).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
private Stream<LocalVariable> matchingVars(int index, int visibleOffset) {
|
||||
return localVariables.stream()
|
||||
.filter(v -> v.index == index && (visibleOffset >= v.start_pc && visibleOffset < v.start_pc + v.length));
|
||||
}
|
||||
|
||||
public boolean containsName(String name) {
|
||||
return localVariables.stream().anyMatch(v -> v.name == name);
|
||||
}
|
||||
|
||||
public Map<Integer, String> getMapParamNames() {
|
||||
return localVariables.stream().filter(v -> v.start_pc == 0).collect(Collectors.toMap(v -> v.index, v -> v.name, (n1, n2) -> n2));
|
||||
}
|
||||
|
||||
private static class LocalVariable {
|
||||
final int start_pc;
|
||||
final int length;
|
||||
final String name;
|
||||
final String descriptor;
|
||||
final int index;
|
||||
|
||||
private LocalVariable(int start_pc, int length, String name, String descriptor, int index) {
|
||||
this.start_pc = start_pc;
|
||||
this.length = length;
|
||||
this.name = name;
|
||||
this.descriptor = descriptor;
|
||||
this.index = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,7 @@ import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
|
||||
import org.jetbrains.java.decompiler.util.DataInputFullStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/*
|
||||
u2 local_variable_type_table_length;
|
||||
@@ -33,31 +31,19 @@ import java.util.Map;
|
||||
} local_variable_type_table[local_variable_type_table_length];
|
||||
*/
|
||||
public class StructLocalVariableTypeTableAttribute extends StructGeneralAttribute {
|
||||
|
||||
private Map<Integer, String> mapVarSignatures = Collections.emptyMap();
|
||||
// store signature instead of descriptor
|
||||
private final StructLocalVariableTableAttribute backingAttribute = new StructLocalVariableTableAttribute();
|
||||
|
||||
@Override
|
||||
public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException {
|
||||
int len = data.readUnsignedShort();
|
||||
if (len > 0) {
|
||||
mapVarSignatures = new HashMap<>(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
data.discard(6);
|
||||
int signatureIndex = data.readUnsignedShort();
|
||||
int varIndex = data.readUnsignedShort();
|
||||
mapVarSignatures.put(varIndex, pool.getPrimitiveConstant(signatureIndex).getString());
|
||||
}
|
||||
}
|
||||
else {
|
||||
mapVarSignatures = Collections.emptyMap();
|
||||
}
|
||||
backingAttribute.initContent(data, pool);
|
||||
}
|
||||
|
||||
public void add(StructLocalVariableTypeTableAttribute attr) {
|
||||
mapVarSignatures.putAll(attr.getMapVarSignatures());
|
||||
backingAttribute.add(attr.backingAttribute);
|
||||
}
|
||||
|
||||
public Map<Integer, String> getMapVarSignatures() {
|
||||
return mapVarSignatures;
|
||||
public String getSignature(int index, int visibleOffset) {
|
||||
return backingAttribute.getDescriptor(index, visibleOffset);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user