Skip to content

Commit c787196

Browse files
author
emmanue1
committed
Improve the generation of generic local variables
1 parent 068c2b9 commit c787196

File tree

5 files changed

+45
-31
lines changed

5 files changed

+45
-31
lines changed

src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/GenericLocalVariable.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ public String toString() {
6161
@Override public boolean isAssignableFrom(Type otherType) {
6262
return type.equals(otherType);
6363
}
64-
6564
@Override public void typeOnRight(Type type) {}
6665
@Override public void typeOnLeft(Type type) {}
6766

src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/ObjectLocalVariable.java

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -83,21 +83,21 @@ public boolean isAssignableFrom(Type type) {
8383
if ((type == TYPE_UNDEFINED_OBJECT) || (this.type == TYPE_UNDEFINED_OBJECT) || (this.type == TYPE_OBJECT) || this.type.equals(type)) {
8484
return true;
8585
} else if ((this.type.getDimension() == type.getDimension()) && this.type.isObject()) {
86-
ObjectType ot1 = (ObjectType) this.type;
86+
ObjectType thisObjectType = (ObjectType) this.type;
8787

8888
if (type.isObject()) {
89-
ObjectType ot2 = (ObjectType) type;
89+
ObjectType otherObjectType = (ObjectType) type;
9090

91-
if (ot1.getInternalName().equals(ot2.getInternalName()) && (ot1.getTypeArguments() != null) && (ot2.getTypeArguments() != null)) {
92-
return ot1.getTypeArguments().isTypeArgumentAssignableFrom(ot2.getTypeArguments());
91+
if (thisObjectType.getInternalName().equals(otherObjectType.getInternalName()) && (thisObjectType.getTypeArguments() != null) && (otherObjectType.getTypeArguments() != null)) {
92+
return thisObjectType.getTypeArguments().isTypeArgumentAssignableFrom(otherObjectType.getTypeArguments());
9393
}
9494

9595
if (type.getDimension() == 0) {
96-
if ((ot1.getTypeArguments() == null) ? (ot2.getTypeArguments() == null) : ot1.getTypeArguments().equals(ot2.getTypeArguments())) {
97-
return objectTypeMaker.isAssignable(ot1, ot2);
96+
if ((thisObjectType.getTypeArguments() == null) ? (otherObjectType.getTypeArguments() == null) : thisObjectType.getTypeArguments().equals(otherObjectType.getTypeArguments())) {
97+
return objectTypeMaker.isAssignable(thisObjectType, otherObjectType);
9898
}
9999
}
100-
} else if (ot1.getInternalName().equals(TYPE_OBJECT.getInternalName())) {
100+
} else if (thisObjectType.getInternalName().equals(TYPE_OBJECT.getInternalName())) {
101101
return true;
102102
}
103103
}
@@ -115,8 +115,9 @@ public void typeOnRight(Type type) {
115115
assert !this.type.isPrimitive() && !type.isPrimitive() : "ObjectLocalVariable.typeOnRight(type) : unexpected type";
116116

117117
if (this.type.isObject()) {
118+
ObjectType thisObjectType = (ObjectType) this.type;
119+
118120
if (type.isObject()) {
119-
ObjectType thisObjectType = (ObjectType) this.type;
120121
ObjectType otherObjectType = (ObjectType) type;
121122

122123
if (thisObjectType.getInternalName().equals(otherObjectType.getInternalName())) {
@@ -133,7 +134,7 @@ public void typeOnRight(Type type) {
133134
fireChangeEvent();
134135
}
135136
}
136-
} else if (type.isGeneric() && (this.type == TYPE_OBJECT)) {
137+
} else if (type.isGeneric() && thisObjectType.getInternalName().equals(TYPE_OBJECT.getInternalName())) {
137138
this.type = type;
138139
fireChangeEvent();
139140
}
@@ -150,23 +151,29 @@ public void typeOnLeft(Type type) {
150151
} else if ((this.type.getDimension() == 0) && (type.getDimension() == 0)) {
151152
assert !this.type.isPrimitive() && !type.isPrimitive() : "unexpected type in ObjectLocalVariable.typeOnLeft(type)";
152153

153-
if (this.type.isObject() && type.isObject()) {
154-
ObjectType thisObjectType = (ObjectType)this.type;
155-
ObjectType otherObjectType = (ObjectType)type;
154+
if (this.type.isObject()) {
155+
ObjectType thisObjectType = (ObjectType) this.type;
156156

157-
if (thisObjectType.getInternalName().equals(otherObjectType.getInternalName())) {
158-
if ((thisObjectType.getTypeArguments() == null) && (otherObjectType.getTypeArguments() != null)) {
159-
// Keep type, update type arguments
160-
this.type = otherObjectType;
161-
fireChangeEvent();
162-
}
163-
} else if (objectTypeMaker.isAssignable(otherObjectType, thisObjectType)) {
164-
// Assignable types
165-
if ((thisObjectType.getTypeArguments() == null) && (otherObjectType.getTypeArguments() != null)) {
166-
// Keep type, update type arguments
167-
this.type = thisObjectType.createType(otherObjectType.getTypeArguments());
168-
fireChangeEvent();
157+
if (type.isObject()) {
158+
ObjectType otherObjectType = (ObjectType) type;
159+
160+
if (thisObjectType.getInternalName().equals(otherObjectType.getInternalName())) {
161+
if ((thisObjectType.getTypeArguments() == null) && (otherObjectType.getTypeArguments() != null)) {
162+
// Keep type, update type arguments
163+
this.type = otherObjectType;
164+
fireChangeEvent();
165+
}
166+
} else if (objectTypeMaker.isAssignable(otherObjectType, thisObjectType)) {
167+
// Assignable types
168+
if ((thisObjectType.getTypeArguments() == null) && (otherObjectType.getTypeArguments() != null)) {
169+
// Keep type, update type arguments
170+
this.type = thisObjectType.createType(otherObjectType.getTypeArguments());
171+
fireChangeEvent();
172+
}
169173
}
174+
} else if (type.isGeneric() && thisObjectType.getInternalName().equals(TYPE_OBJECT.getInternalName())) {
175+
this.type = type;
176+
fireChangeEvent();
170177
}
171178
}
172179
}

src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/util/ByteCodeParser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1419,7 +1419,7 @@ private void parseASTORE(Statements<Statement> statements, DefaultStack<Expressi
14191419
valueRef = NewArrayMaker.make(statements, (NewArray)valueRef);
14201420
}
14211421

1422-
if (!localVariable.isAssignableFrom(valueRef.getType())) {
1422+
if (!localVariable.isAssignableFrom(valueRef.getType()) && !localVariableMaker.isAssignableFrom(localVariable, valueRef.getType())) {
14231423
valueRef = new CastExpression(valueRef.getLineNumber(), localVariable.getType(), valueRef);
14241424
}
14251425

src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/util/LocalVariableMaker.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,14 @@ protected AbstractLocalVariable searchLocalVariable(int index, int offset) {
335335
return lv;
336336
}
337337

338-
protected boolean isAssignableFrom(AbstractLocalVariable lv, Type valueType) {
338+
public boolean isAssignableFrom(AbstractLocalVariable lv, Type valueType) {
339339
if (lv.getType().isObject() && valueType.isObject() && (lv.getType().getDimension() == valueType.getDimension())) {
340-
return objectTypeMaker.isAssignable((ObjectType)lv.getType(), (ObjectType)valueType);
340+
ObjectType lvObjectType = (ObjectType)lv.getType();
341+
ObjectType valueObjectType = (ObjectType)valueType;
342+
343+
if ((lvObjectType.getTypeArguments() == null) || (valueObjectType.getTypeArguments() == null)) {
344+
return objectTypeMaker.isAssignable(lvObjectType, valueObjectType);
345+
}
341346
}
342347

343348
return false;
@@ -352,7 +357,7 @@ public AbstractLocalVariable getLocalVariableInAssignment(int index, int offset,
352357
valueType.accept(createLocalVariableVisitor);
353358
lv = createLocalVariableVisitor.getLocalVariable();
354359
} else if (lv.isAssignableFrom(valueType) || isAssignableFrom(lv, valueType)) {
355-
// Reduce type
360+
// Assignable, reduce type
356361
lv.typeOnRight(valueType);
357362
} else if (!lv.getType().isGeneric() || (ObjectType.TYPE_OBJECT != valueType)) {
358363
// Not assignable -> Create a new local variable
@@ -401,15 +406,15 @@ public AbstractLocalVariable getLocalVariableInAssignment(int index, int offset,
401406
valueLocalVariable.accept(createLocalVariableVisitor);
402407
lv = createLocalVariableVisitor.getLocalVariable();
403408
} else if (lv.isAssignableFrom(valueLocalVariable) || isAssignableFrom(lv, valueLocalVariable.getType())) {
404-
// Reduce type
405-
lv.variableOnRight(valueLocalVariable);
409+
// Assignable
406410
} else if (!lv.getType().isGeneric() || (ObjectType.TYPE_OBJECT != valueLocalVariable.getType())) {
407411
// Not assignable -> Create a new local variable
408412
createLocalVariableVisitor.init(index, offset);
409413
valueLocalVariable.accept(createLocalVariableVisitor);
410414
lv = createLocalVariableVisitor.getLocalVariable();
411415
}
412416

417+
lv.variableOnRight(valueLocalVariable);
413418
lv.setToOffset(offset);
414419
store(lv);
415420

src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/util/LoopStatementMaker.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ protected static Statement makeForEachArray(LocalVariableMaker localVariableMake
441441
return null;
442442
}
443443

444+
Type arrayType = boe.getRightExpression().getType();
444445
Expression array = boe.getRightExpression();
445446

446447
// i$ = 0;
@@ -501,6 +502,8 @@ protected static Statement makeForEachArray(LocalVariableMaker localVariableMake
501502
subStatements.removeLast();
502503

503504
item.setDeclared(true);
505+
Type itemType = arrayType.createType(arrayType.getDimension()-1);
506+
item.typeOnRight(itemType);
504507

505508
localVariableMaker.removeLocalVariable(syntheticArray);
506509
localVariableMaker.removeLocalVariable(syntheticIndex);

0 commit comments

Comments
 (0)