Skip to content

Commit 16619db

Browse files
author
emmanue1
committed
Add string concatenation in Java 9 support
1 parent cdb695a commit 16619db

File tree

11 files changed

+240
-165
lines changed

11 files changed

+240
-165
lines changed

src/main/java/org/jd/core/v1/api/printer/Printer.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@
99

1010

1111
public interface Printer {
12-
int UNKNOWN_LINE_NUMBER = 0;
12+
void start(int maxLineNumber, int majorVersion, int minorVersion);
13+
void end();
14+
15+
void printText(String text);
16+
void printNumericConstant(String constant);
17+
void printStringConstant(String constant, String ownerInternalName);
18+
void printKeyword(String keyword);
1319

1420
// Declaration & reference types
1521
int TYPE = 1;
@@ -19,30 +25,24 @@ public interface Printer {
1925
int PACKAGE = 5;
2026
int MODULE = 6;
2127

22-
// Marker types
23-
int COMMENT = 1;
24-
int JAVADOC = 2;
25-
int ERROR = 3;
26-
int IMPORT_STATEMENTS = 4;
27-
28-
void start(int maxLineNumber, int majorVersion, int minorVersion);
29-
void end();
30-
31-
void printText(String text);
32-
void printNumericConstant(String constant);
33-
void printStringConstant(String constant, String ownerInternalName);
34-
void printKeyword(String keyword);
35-
3628
void printDeclaration(int type, String internalTypeName, String name, String descriptor);
3729
void printReference(int type, String internalTypeName, String name, String descriptor, String ownerInternalName);
3830

3931
void indent();
4032
void unindent();
4133

34+
int UNKNOWN_LINE_NUMBER = 0;
35+
4236
void startLine(int lineNumber);
4337
void endLine();
4438
void extraLine(int count);
4539

40+
// Marker types
41+
int COMMENT = 1;
42+
int JAVADOC = 2;
43+
int ERROR = 3;
44+
int IMPORT_STATEMENTS = 4;
45+
4646
void startMarker(int type);
4747
void endMarker(int type);
4848
}

src/main/java/org/jd/core/v1/model/classfile/ConstantPool.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,19 @@ public <T extends Constant> T getConstant(int index) {
2222
return (T)constants[index];
2323
}
2424

25-
public String getConstantTypeName(int classIndex) {
26-
ConstantClass cc = (ConstantClass)constants[classIndex];
25+
public String getConstantTypeName(int index) {
26+
ConstantClass cc = (ConstantClass)constants[index];
2727
ConstantUtf8 cutf8 = (ConstantUtf8)constants[cc.getNameIndex()];
2828
return cutf8.getValue();
2929
}
3030

3131
public String getConstantString(int index) {
32+
ConstantString cString = (ConstantString)constants[index];
33+
ConstantUtf8 cutf8 = (ConstantUtf8)constants[cString.getStringIndex()];
34+
return cutf8.getValue();
35+
}
36+
37+
public String getConstantUtf8(int index) {
3238
ConstantUtf8 cutf8 = (ConstantUtf8)constants[index];
3339
return cutf8.getValue();
3440
}

src/main/java/org/jd/core/v1/model/javasyntax/expression/StringConstantExpression.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import org.jd.core.v1.model.javasyntax.type.Type;
1212

1313
public class StringConstantExpression extends AbstractLineNumberExpression {
14+
public static final StringConstantExpression EMPTY_STRING = new StringConstantExpression("");
15+
1416
protected String string;
1517

1618
public StringConstantExpression(String string) {

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

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -727,8 +727,8 @@ public void parse(BasicBlock basicBlock, Statements<Statement> statements, Defau
727727
typeName = constants.getConstantTypeName(constantMemberRef.getClassIndex());
728728
ot = objectTypeMaker.make(typeName);
729729
constantNameAndType = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
730-
name = constants.getConstantString(constantNameAndType.getNameIndex());
731-
descriptor = constants.getConstantString(constantNameAndType.getDescriptorIndex());
730+
name = constants.getConstantUtf8(constantNameAndType.getNameIndex());
731+
descriptor = constants.getConstantUtf8(constantNameAndType.getDescriptorIndex());
732732
BaseExpression parameters = getParameters(statements, stack, descriptor);
733733
Type returnedType = signatureParser.parseReturnedType(descriptor);
734734

@@ -777,7 +777,7 @@ public void parse(BasicBlock basicBlock, Statements<Statement> statements, Defau
777777
"toString".equals(name) && "()Ljava/lang/String;".equals(descriptor)) {
778778
typeName = constants.getConstantTypeName(constantMemberRef.getClassIndex());
779779
if ("java/lang/StringBuilder".equals(typeName) || "java/lang/StringBuffer".equals(typeName)) {
780-
stack.push(CreateConcatStringUtil.create(expression1, lineNumber, typeName));
780+
stack.push(StringConcatenationUtil.create(expression1, lineNumber, typeName));
781781
break;
782782
}
783783
}
@@ -1043,7 +1043,7 @@ private void parseLDC(DefaultStack<Expression> stack, ConstantPool constants, in
10431043
break;
10441044
case Constant.CONSTANT_String:
10451045
int stringIndex = ((ConstantString)constant).getStringIndex();
1046-
stack.push(new StringConstantExpression(lineNumber, constants.getConstantString(stringIndex)));
1046+
stack.push(new StringConstantExpression(lineNumber, constants.getConstantUtf8(stringIndex)));
10471047
break;
10481048
}
10491049
}
@@ -1273,27 +1273,39 @@ private void parseInvokeDynamic(Statements<Statement> statements, DefaultStack<E
12731273
}
12741274
}
12751275

1276-
// Create lambda expression
1276+
// Create expression
12771277
ConstantMemberRef constantMemberRef = constants.getConstant(index);
12781278

12791279
ConstantNameAndType indyCnat = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
1280-
//String indyMethodName = constants.getConstantString(indyCnat.getNameIndex());
1281-
String indyDescriptor = constants.getConstantString(indyCnat.getDescriptorIndex());
1280+
String indyMethodName = constants.getConstantUtf8(indyCnat.getNameIndex());
1281+
String indyDescriptor = constants.getConstantUtf8(indyCnat.getDescriptorIndex());
12821282
BaseExpression indyParameters = getParameters(statements, stack, indyDescriptor);
12831283
Type indyType = signatureParser.parseReturnedType(indyDescriptor);
12841284

12851285
BootstrapMethod bootstrapMethod = attributeBootstrapMethods.getBootstrapMethods()[constantMemberRef.getClassIndex()];
12861286
int[] bootstrapArguments = bootstrapMethod.getBootstrapArguments();
1287+
1288+
if ("makeConcatWithConstants".equals(indyMethodName)) {
1289+
// Create Java 9+ string concatenation
1290+
String recipe = constants.getConstantString(bootstrapArguments[0]);
1291+
stack.push(StringConcatenationUtil.create(recipe, indyParameters));
1292+
return;
1293+
} else if ("makeConcat".equals(indyMethodName)) {
1294+
// Create Java 9+ string concatenation
1295+
stack.push(StringConcatenationUtil.create(indyParameters));
1296+
return;
1297+
}
1298+
12871299
ConstantMethodType cmt0 = constants.getConstant(bootstrapArguments[0]);
1288-
String descriptor0 = constants.getConstantString(cmt0.getDescriptorIndex());
1300+
String descriptor0 = constants.getConstantUtf8(cmt0.getDescriptorIndex());
12891301
Type returnedType = signatureParser.parseReturnedType(descriptor0);
12901302
int parameterCount = signatureParser.parseParameterTypes(descriptor0).size();
12911303
ConstantMethodHandle constantMethodHandle1 = constants.getConstant(bootstrapArguments[1]);
12921304
ConstantMemberRef cmr1 = constants.getConstant(constantMethodHandle1.getReferenceIndex());
12931305
String typeName = constants.getConstantTypeName(cmr1.getClassIndex());
12941306
ConstantNameAndType cnat1 = constants.getConstant(cmr1.getNameAndTypeIndex());
1295-
String name1 = constants.getConstantString(cnat1.getNameIndex());
1296-
String descriptor1 = constants.getConstantString(cnat1.getDescriptorIndex());
1307+
String name1 = constants.getConstantUtf8(cnat1.getNameIndex());
1308+
String descriptor1 = constants.getConstantUtf8(cnat1.getDescriptorIndex());
12971309

12981310
if (typeName.equals(internalTypeName)) {
12991311
for (ClassFileConstructorOrMethodDeclaration methodDeclaration : bodyDeclaration.getMethodDeclarations()) {
@@ -1637,7 +1649,7 @@ private void parseGetStatic(DefaultStack<Expression> stack, ConstantPool constan
16371649
ConstantMemberRef constantMemberRef = constants.getConstant(index);
16381650
String typeName = constants.getConstantTypeName(constantMemberRef.getClassIndex());
16391651
ConstantNameAndType constantNameAndType = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
1640-
String name = constants.getConstantString(constantNameAndType.getNameIndex());
1652+
String name = constants.getConstantUtf8(constantNameAndType.getNameIndex());
16411653

16421654
if (name.equals("TYPE") && typeName.startsWith("java/lang/")) {
16431655
switch (typeName) {
@@ -1653,7 +1665,7 @@ private void parseGetStatic(DefaultStack<Expression> stack, ConstantPool constan
16531665
}
16541666
}
16551667

1656-
String descriptor = constants.getConstantString(constantNameAndType.getDescriptorIndex());
1668+
String descriptor = constants.getConstantUtf8(constantNameAndType.getDescriptorIndex());
16571669
Type type = signatureParser.parseTypeSignature(descriptor);
16581670
ObjectType ot = objectTypeMaker.make(typeName);
16591671
Expression objectRef = new ObjectTypeReferenceExpression(lineNumber, ot, !internalTypeName.equals(typeName) || localVariableMaker.containsName(name));
@@ -1665,8 +1677,8 @@ private void parsePutStatic(Statements statements, DefaultStack<Expression> stac
16651677
String typeName = constants.getConstantTypeName(constantMemberRef.getClassIndex());
16661678
ObjectType ot = objectTypeMaker.make(typeName);
16671679
ConstantNameAndType constantNameAndType = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
1668-
String name = constants.getConstantString(constantNameAndType.getNameIndex());
1669-
String descriptor = constants.getConstantString(constantNameAndType.getDescriptorIndex());
1680+
String name = constants.getConstantUtf8(constantNameAndType.getNameIndex());
1681+
String descriptor = constants.getConstantUtf8(constantNameAndType.getDescriptorIndex());
16701682
Type type = signatureParser.parseTypeSignature(descriptor);
16711683
Expression valueRef = stack.pop();
16721684
Expression objectRef = new ObjectTypeReferenceExpression(lineNumber, ot, !internalTypeName.equals(typeName) || localVariableMaker.containsName(name));
@@ -1679,8 +1691,8 @@ private void parseGetField(DefaultStack<Expression> stack, ConstantPool constant
16791691
String typeName = constants.getConstantTypeName(constantMemberRef.getClassIndex());
16801692
ObjectType ot = objectTypeMaker.make(typeName);
16811693
ConstantNameAndType constantNameAndType = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
1682-
String name = constants.getConstantString(constantNameAndType.getNameIndex());
1683-
String descriptor = constants.getConstantString(constantNameAndType.getDescriptorIndex());
1694+
String name = constants.getConstantUtf8(constantNameAndType.getNameIndex());
1695+
String descriptor = constants.getConstantUtf8(constantNameAndType.getDescriptorIndex());
16841696
Type type = signatureParser.parseTypeSignature(descriptor);
16851697
Expression objectRef = stack.pop();
16861698
stack.push(new FieldReferenceExpression(lineNumber, type, getFieldInstanceReference(objectRef, ot, name), typeName, name, descriptor));
@@ -1691,8 +1703,8 @@ private void parsePutField(Statements statements, DefaultStack<Expression> stack
16911703
String typeName = constants.getConstantTypeName(constantMemberRef.getClassIndex());
16921704
ObjectType ot = objectTypeMaker.make(typeName);
16931705
ConstantNameAndType constantNameAndType = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
1694-
String name = constants.getConstantString(constantNameAndType.getNameIndex());
1695-
String descriptor = constants.getConstantString(constantNameAndType.getDescriptorIndex());
1706+
String name = constants.getConstantUtf8(constantNameAndType.getNameIndex());
1707+
String descriptor = constants.getConstantUtf8(constantNameAndType.getDescriptorIndex());
16961708
Type type = signatureParser.parseTypeSignature(descriptor);
16971709
Expression valueRef = stack.pop();
16981710
Expression objectRef = stack.pop();
@@ -1942,12 +1954,12 @@ public static boolean isAssertCondition(String internalTypeName, BasicBlock basi
19421954
ConstantPool constants = method.getConstants();
19431955
ConstantMemberRef constantMemberRef = constants.getConstant( ((code[++offset] & 255) << 8) | (code[++offset] & 255) );
19441956
ConstantNameAndType constantNameAndType = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
1945-
String name = constants.getConstantString(constantNameAndType.getNameIndex());
1957+
String name = constants.getConstantUtf8(constantNameAndType.getNameIndex());
19461958

19471959
if (! "$assertionsDisabled".equals(name))
19481960
return false;
19491961

1950-
String descriptor = constants.getConstantString(constantNameAndType.getDescriptorIndex());
1962+
String descriptor = constants.getConstantUtf8(constantNameAndType.getDescriptorIndex());
19511963

19521964
if (! "Z".equals(descriptor))
19531965
return false;
@@ -2309,7 +2321,7 @@ public static int evalStackDepth(ConstantPool constants, byte[] code, BasicBlock
23092321
case 182: case 183: // INVOKEVIRTUAL, INVOKESPECIAL
23102322
constantMemberRef = constants.getConstant(((code[++offset] & 255) << 8) | (code[++offset] & 255));
23112323
constantNameAndType = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
2312-
descriptor = constants.getConstantString(constantNameAndType.getDescriptorIndex());
2324+
descriptor = constants.getConstantUtf8(constantNameAndType.getDescriptorIndex());
23132325
depth -= 1 + countMethodParameters(descriptor);
23142326

23152327
if (descriptor.charAt(descriptor.length()-1) != 'V') {
@@ -2319,7 +2331,7 @@ public static int evalStackDepth(ConstantPool constants, byte[] code, BasicBlock
23192331
case 184: // INVOKESTATIC
23202332
constantMemberRef = constants.getConstant(((code[++offset] & 255) << 8) | (code[++offset] & 255));
23212333
constantNameAndType = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
2322-
descriptor = constants.getConstantString(constantNameAndType.getDescriptorIndex());
2334+
descriptor = constants.getConstantUtf8(constantNameAndType.getDescriptorIndex());
23232335
depth -= countMethodParameters(descriptor);
23242336

23252337
if (descriptor.charAt(descriptor.length()-1) != 'V') {
@@ -2329,7 +2341,7 @@ public static int evalStackDepth(ConstantPool constants, byte[] code, BasicBlock
23292341
case 185: // INVOKEINTERFACE
23302342
constantMemberRef = constants.getConstant(((code[++offset] & 255) << 8) | (code[++offset] & 255));
23312343
constantNameAndType = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
2332-
descriptor = constants.getConstantString(constantNameAndType.getDescriptorIndex());
2344+
descriptor = constants.getConstantUtf8(constantNameAndType.getDescriptorIndex());
23332345
depth -= 1 + countMethodParameters(descriptor);
23342346
offset += 2; // Skip 'count' and one byte
23352347

@@ -2340,7 +2352,7 @@ public static int evalStackDepth(ConstantPool constants, byte[] code, BasicBlock
23402352
case 186: // INVOKEDYNAMIC
23412353
constantMemberRef = constants.getConstant(((code[++offset] & 255) << 8) | (code[++offset] & 255));
23422354
constantNameAndType = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
2343-
descriptor = constants.getConstantString(constantNameAndType.getDescriptorIndex());
2355+
descriptor = constants.getConstantUtf8(constantNameAndType.getDescriptorIndex());
23442356
depth -= countMethodParameters(descriptor);
23452357
offset += 2; // Skip 2 bytes
23462358

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -204,24 +204,24 @@ protected static void writeByteCode(String linePrefix, StringBuilder sb, Constan
204204
ConstantMemberRef constantMemberRef = constants.getConstant(((code[++offset] & 255) << 8) | (code[++offset] & 255));
205205
String typeName = constants.getConstantTypeName(constantMemberRef.getClassIndex());
206206
ConstantNameAndType constantNameAndType = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
207-
String name = constants.getConstantString(constantNameAndType.getNameIndex());
208-
String descriptor = constants.getConstantString(constantNameAndType.getDescriptorIndex());
207+
String name = constants.getConstantUtf8(constantNameAndType.getNameIndex());
208+
String descriptor = constants.getConstantUtf8(constantNameAndType.getDescriptorIndex());
209209

210210
sb.append(" ").append(typeName).append('.').append(name).append(" : ").append(descriptor);
211211
break;
212212
case 180: case 181: case 182: case 183: case 184: // GETFIELD, PUTFIELD, INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC
213213
constantMemberRef = constants.getConstant(((code[++offset] & 255) << 8) | (code[++offset] & 255));
214214
constantNameAndType = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
215-
name = constants.getConstantString(constantNameAndType.getNameIndex());
216-
descriptor = constants.getConstantString(constantNameAndType.getDescriptorIndex());
215+
name = constants.getConstantUtf8(constantNameAndType.getNameIndex());
216+
descriptor = constants.getConstantUtf8(constantNameAndType.getDescriptorIndex());
217217

218218
sb.append(" ").append(name).append(" : ").append(descriptor);
219219
break;
220220
case 185: case 186: // INVOKEINTERFACE, INVOKEDYNAMIC
221221
constantMemberRef = constants.getConstant(((code[++offset] & 255) << 8) | (code[++offset] & 255));
222222
constantNameAndType = constants.getConstant(constantMemberRef.getNameAndTypeIndex());
223-
name = constants.getConstantString(constantNameAndType.getNameIndex());
224-
descriptor = constants.getConstantString(constantNameAndType.getDescriptorIndex());
223+
name = constants.getConstantUtf8(constantNameAndType.getNameIndex());
224+
descriptor = constants.getConstantUtf8(constantNameAndType.getDescriptorIndex());
225225

226226
sb.append(" ").append(name).append(" : ").append(descriptor);
227227

@@ -302,7 +302,7 @@ protected static void writeLDC(StringBuilder sb, ConstantPool constants, Constan
302302
case Constant.CONSTANT_String:
303303
sb.append(" '");
304304
int stringIndex = ((ConstantString) constant).getStringIndex();
305-
String str = constants.getConstantString(stringIndex);
305+
String str = constants.getConstantUtf8(stringIndex);
306306

307307
for (char c : str.toCharArray()) {
308308
switch (c) {

0 commit comments

Comments
 (0)