Skip to content

Commit ad96d10

Browse files
author
emmanue1
committed
Fix generic cast missing
1 parent e46f9dc commit ad96d10

File tree

5 files changed

+193
-5
lines changed

5 files changed

+193
-5
lines changed

src/main/java/org/jd/core/v1/model/javasyntax/declaration/FieldDeclaration.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ public Type getType() {
4747
return type;
4848
}
4949

50+
public void setType(Type type) {
51+
this.type = type;
52+
}
53+
5054
public BaseFieldDeclarator getFieldDeclarators() {
5155
return fieldDeclarators;
5256
}

src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/processor/UpdateJavaSyntaxTreeProcessor.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.jd.core.v1.model.message.Message;
1212
import org.jd.core.v1.model.processor.Processor;
1313
import org.jd.core.v1.service.converter.classfiletojavasyntax.util.TypeMaker;
14+
import org.jd.core.v1.service.converter.classfiletojavasyntax.visitor.UpdateJavaSyntaxTreeStep0Visitor;
1415
import org.jd.core.v1.service.converter.classfiletojavasyntax.visitor.UpdateJavaSyntaxTreeStep1Visitor;
1516
import org.jd.core.v1.service.converter.classfiletojavasyntax.visitor.UpdateJavaSyntaxTreeStep2Visitor;
1617

@@ -27,10 +28,8 @@ public void process(Message message) throws Exception {
2728
TypeMaker typeMaker = message.getHeader("typeMaker");
2829
CompilationUnit compilationUnit = message.getBody();
2930

30-
UpdateJavaSyntaxTreeStep1Visitor updateJavaSyntaxTreeStep1Visitor = new UpdateJavaSyntaxTreeStep1Visitor(typeMaker);
31-
updateJavaSyntaxTreeStep1Visitor.visit(compilationUnit);
32-
33-
UpdateJavaSyntaxTreeStep2Visitor updateJavaSyntaxTreeStep2Visitor = new UpdateJavaSyntaxTreeStep2Visitor(typeMaker);
34-
updateJavaSyntaxTreeStep2Visitor.visit(compilationUnit);
31+
new UpdateJavaSyntaxTreeStep0Visitor(typeMaker).visit(compilationUnit);
32+
new UpdateJavaSyntaxTreeStep1Visitor(typeMaker).visit(compilationUnit);
33+
new UpdateJavaSyntaxTreeStep2Visitor(typeMaker).visit(compilationUnit);
3534
}
3635
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,11 @@ private TypeTypes makeTypeTypes(String internalTypeName, byte[] data) throws Exc
11381138
return typeTypes;
11391139
}
11401140

1141+
public void setFieldType(String internalTypeName, String fieldName, Type type) {
1142+
String key = internalTypeName + ':' + fieldName;
1143+
internalTypeNameFieldNameToType.put(key, type);
1144+
}
1145+
11411146
public Type makeFieldType(String internalTypeName, String fieldName, String descriptor) {
11421147
Type type = loadFieldType(internalTypeName, fieldName, descriptor);
11431148

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2008, 2019 Emmanuel Dupuy.
3+
* This project is distributed under the GPLv3 license.
4+
* This is a Copyleft license that gives the user the right to use,
5+
* copy and modify the code freely for non-commercial purposes.
6+
*/
7+
8+
package org.jd.core.v1.service.converter.classfiletojavasyntax.visitor;
9+
10+
import org.jd.core.v1.model.javasyntax.AbstractJavaSyntaxVisitor;
11+
import org.jd.core.v1.model.javasyntax.declaration.*;
12+
import org.jd.core.v1.service.converter.classfiletojavasyntax.util.TypeMaker;
13+
14+
public class UpdateJavaSyntaxTreeStep0Visitor extends AbstractJavaSyntaxVisitor {
15+
protected UpdateOuterFieldTypeVisitor updateSyntheticMemberVisitor;
16+
17+
public UpdateJavaSyntaxTreeStep0Visitor(TypeMaker typeMaker) {
18+
updateSyntheticMemberVisitor = new UpdateOuterFieldTypeVisitor(typeMaker);
19+
}
20+
21+
@Override
22+
public void visit(BodyDeclaration declaration) {
23+
updateSyntheticMemberVisitor.visit(declaration);
24+
}
25+
26+
@Override
27+
public void visit(ClassDeclaration declaration) {
28+
safeAccept(declaration.getBodyDeclaration());
29+
}
30+
31+
@Override
32+
public void visit(InterfaceDeclaration declaration) {
33+
safeAccept(declaration.getBodyDeclaration());
34+
}
35+
36+
@Override public void visit(AnnotationDeclaration declaration) {}
37+
@Override public void visit(EnumDeclaration declaration) {}
38+
}
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/*
2+
* Copyright (c) 2008, 2019 Emmanuel Dupuy.
3+
* This project is distributed under the GPLv3 license.
4+
* This is a Copyleft license that gives the user the right to use,
5+
* copy and modify the code freely for non-commercial purposes.
6+
*/
7+
8+
package org.jd.core.v1.service.converter.classfiletojavasyntax.visitor;
9+
10+
import org.jd.core.v1.model.classfile.ClassFile;
11+
import org.jd.core.v1.model.classfile.ConstantPool;
12+
import org.jd.core.v1.model.classfile.Method;
13+
import org.jd.core.v1.model.classfile.attribute.AttributeCode;
14+
import org.jd.core.v1.model.classfile.constant.ConstantMemberRef;
15+
import org.jd.core.v1.model.classfile.constant.ConstantNameAndType;
16+
import org.jd.core.v1.model.javasyntax.AbstractJavaSyntaxVisitor;
17+
import org.jd.core.v1.model.javasyntax.declaration.*;
18+
import org.jd.core.v1.model.javasyntax.type.BaseTypeArgument;
19+
import org.jd.core.v1.model.javasyntax.type.GenericType;
20+
import org.jd.core.v1.model.javasyntax.type.TypeArguments;
21+
import org.jd.core.v1.model.javasyntax.type.TypeParameter;
22+
import org.jd.core.v1.service.converter.classfiletojavasyntax.model.javasyntax.declaration.ClassFileBodyDeclaration;
23+
import org.jd.core.v1.service.converter.classfiletojavasyntax.model.javasyntax.declaration.ClassFileConstructorDeclaration;
24+
import org.jd.core.v1.service.converter.classfiletojavasyntax.model.javasyntax.declaration.ClassFileFieldDeclaration;
25+
import org.jd.core.v1.service.converter.classfiletojavasyntax.util.TypeMaker;
26+
27+
import static org.jd.core.v1.model.classfile.Constants.ACC_STATIC;
28+
29+
public class UpdateOuterFieldTypeVisitor extends AbstractJavaSyntaxVisitor {
30+
protected TypeMaker typeMaker;
31+
protected SearchFieldVisitor searchFieldVisitor = new SearchFieldVisitor();
32+
33+
public UpdateOuterFieldTypeVisitor(TypeMaker typeMaker) {
34+
this.typeMaker = typeMaker;
35+
}
36+
37+
@Override
38+
public void visit(BodyDeclaration declaration) {
39+
ClassFileBodyDeclaration bodyDeclaration = (ClassFileBodyDeclaration)declaration;
40+
boolean genericTypesSupported = (bodyDeclaration.getClassFile().getMajorVersion() >= 49); // (majorVersion >= Java 5)
41+
42+
if (genericTypesSupported) {
43+
safeAcceptListDeclaration(bodyDeclaration.getMethodDeclarations());
44+
safeAcceptListDeclaration(bodyDeclaration.getInnerTypeDeclarations());
45+
}
46+
}
47+
48+
@Override
49+
public void visit(ConstructorDeclaration declaration) {
50+
ClassFileConstructorDeclaration cfcd = (ClassFileConstructorDeclaration) declaration;
51+
ClassFile classFile = cfcd.getClassFile();
52+
53+
if ((classFile.getOuterClassFile() != null) && !classFile.matchAccessFlags(ACC_STATIC)) {
54+
Method method = cfcd.getMethod();
55+
byte[] code = method.<AttributeCode>getAttribute("Code").getCode();
56+
int offset = 0;
57+
int opcode = code[offset] & 255;
58+
59+
if (opcode != 42) { // ALOAD_0
60+
return;
61+
}
62+
63+
opcode = code[++offset] & 255;
64+
65+
if (opcode != 43) { // ALOAD_1
66+
return;
67+
}
68+
69+
opcode = code[++offset] & 255;
70+
71+
if (opcode != 181) { // PUTFIELD
72+
return;
73+
}
74+
75+
int index = ((code[++offset] & 255) << 8) | (code[++offset] & 255);
76+
ConstantPool constants = method.getConstants();
77+
ConstantMemberRef constantMemberRef = constants.getConstant(index);
78+
String typeName = constants.getConstantTypeName(constantMemberRef.getClassIndex());
79+
ConstantNameAndType constantNameAndType = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
80+
String descriptor = constants.getConstantUtf8(constantNameAndType.getDescriptorIndex());
81+
TypeMaker.TypeTypes typeTypes = typeMaker.makeTypeTypes(descriptor.substring(1, descriptor.length()-1));
82+
83+
if (typeTypes.typeParameters != null) {
84+
String name = constants.getConstantUtf8(constantNameAndType.getNameIndex());
85+
searchFieldVisitor.init(name);
86+
87+
for (ClassFileFieldDeclaration field : cfcd.getBodyDeclaration().getFieldDeclarations()) {
88+
field.getFieldDeclarators().accept(searchFieldVisitor);
89+
if (searchFieldVisitor.found()) {
90+
BaseTypeArgument typeArguments;
91+
92+
if (typeTypes.typeParameters.isList()) {
93+
TypeArguments tas = new TypeArguments(typeTypes.typeParameters.size());
94+
for (TypeParameter typeParameter : typeTypes.typeParameters) {
95+
tas.add(new GenericType(typeParameter.getIdentifier()));
96+
}
97+
typeArguments = tas;
98+
} else {
99+
typeArguments = new GenericType(typeTypes.typeParameters.getFirst().getIdentifier());
100+
}
101+
102+
// Update generic type of outer field reference
103+
typeMaker.setFieldType(typeName, name, typeTypes.thisType.createType(typeArguments));
104+
break;
105+
}
106+
}
107+
}
108+
}
109+
}
110+
111+
@Override
112+
public void visit(ClassDeclaration declaration) {
113+
safeAccept(declaration.getBodyDeclaration());
114+
}
115+
116+
@Override
117+
public void visit(InterfaceDeclaration declaration) {
118+
safeAccept(declaration.getBodyDeclaration());
119+
}
120+
121+
@Override public void visit(AnnotationDeclaration declaration) {}
122+
@Override public void visit(EnumDeclaration declaration) {}
123+
124+
protected static class SearchFieldVisitor extends AbstractJavaSyntaxVisitor {
125+
protected String name;
126+
protected boolean found;
127+
128+
public void init(String name) {
129+
this.name = name;
130+
this.found = false;
131+
}
132+
133+
public boolean found() {
134+
return found;
135+
}
136+
137+
@Override
138+
public void visit(FieldDeclarator declaration) {
139+
found |= declaration.getName().equals(name);
140+
}
141+
}
142+
}

0 commit comments

Comments
 (0)