IDEA-127533 int field is displayed as char

master
Egor.Ushakov 8 years ago
parent 195dabf6e6
commit e44ba9905e
  1. 5
      src/org/jetbrains/java/decompiler/main/ClassWriter.java
  2. 4
      src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java
  3. 6
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java
  4. 15
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
  5. 13
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java
  6. 1
      test/org/jetbrains/java/decompiler/SingleClassesTest.java
  7. BIN
      testData/classes/pkg/TestConstType.class
  8. 4
      testData/results/TestClassLoop.dec
  9. 337
      testData/results/TestConstType.dec
  10. 106
      testData/src/pkg/TestConstType.java

@ -442,6 +442,11 @@ public class ClassWriter {
} }
else { else {
buffer.append(" = "); buffer.append(" = ");
if (initializer.type == Exprent.EXPRENT_CONST) {
((ConstExprent) initializer).adjustConstType(fieldType);
}
// FIXME: special case field initializer. Can map to more than one method (constructor) and bytecode intruction. // FIXME: special case field initializer. Can map to more than one method (constructor) and bytecode intruction.
buffer.append(initializer.toJava(indent, tracer)); buffer.append(initializer.toJava(indent, tracer));
} }

@ -885,6 +885,10 @@ public class ExprProcessor implements CodeConstants {
if (quote) buffer.append('('); if (quote) buffer.append('(');
if (exprent.type == Exprent.EXPRENT_CONST) {
((ConstExprent) exprent).adjustConstType(leftType);
}
buffer.append(exprent.toJava(indent, tracer)); buffer.append(exprent.toJava(indent, tracer));
if (quote) buffer.append(')'); if (quote) buffer.append(')');

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2014 JetBrains s.r.o. * Copyright 2000-2017 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -138,6 +138,10 @@ public class AssignmentExprent extends Exprent {
buffer.append(left.toJava(indent, tracer)); buffer.append(left.toJava(indent, tracer));
} }
if (right.type == EXPRENT_CONST) {
((ConstExprent) right).adjustConstType(leftType);
}
TextBuffer res = right.toJava(indent, tracer); TextBuffer res = right.toJava(indent, tracer);
if (condType == CONDITION_NONE && if (condType == CONDITION_NONE &&

@ -367,6 +367,21 @@ public class ConstExprent extends Exprent {
this.constType = constType; this.constType = constType;
} }
public void adjustConstType(VarType expectedType) {
// BYTECHAR and SHORTCHAR => CHAR in the CHAR context
if (expectedType.equals(VarType.VARTYPE_CHAR) &&
(constType.equals(VarType.VARTYPE_BYTECHAR) || constType.equals(VarType.VARTYPE_SHORTCHAR))) {
if (getIntValue() != 0) {
setConstType(VarType.VARTYPE_CHAR);
}
}
// CHAR => INT in the INT context
else if (expectedType.equals(VarType.VARTYPE_INT) &&
constType.equals(VarType.VARTYPE_CHAR)) {
setConstType(VarType.VARTYPE_INT);
}
}
public Object getValue() { public Object getValue() {
return value; return value;
} }

@ -459,7 +459,20 @@ public class FunctionExprent extends Exprent {
.append(wrapOperandString(lstOperands.get(1), true, indent, tracer)); .append(wrapOperandString(lstOperands.get(1), true, indent, tracer));
} }
// try to determine more accurate type for 'char' literals
if (funcType >= FUNCTION_EQ) { if (funcType >= FUNCTION_EQ) {
if (funcType <= FUNCTION_LE) {
Exprent left = lstOperands.get(0);
Exprent right = lstOperands.get(1);
if (right.type == EXPRENT_CONST) {
((ConstExprent) right).adjustConstType(left.getExprType());
}
else if (left.type == EXPRENT_CONST) {
((ConstExprent) left).adjustConstType(right.getExprType());
}
}
return wrapOperandString(lstOperands.get(0), false, indent, tracer) return wrapOperandString(lstOperands.get(0), false, indent, tracer)
.append(OPERATORS[funcType - FUNCTION_EQ + 11]) .append(OPERATORS[funcType - FUNCTION_EQ + 11])
.append(wrapOperandString(lstOperands.get(1), true, indent, tracer)); .append(wrapOperandString(lstOperands.get(1), true, indent, tracer));

@ -113,6 +113,7 @@ public class SingleClassesTest {
@Test public void testLambdaParams() { doTest("pkg/TestLambdaParams"); } @Test public void testLambdaParams() { doTest("pkg/TestLambdaParams"); }
@Test public void testInterfaceMethods() { doTest("pkg/TestInterfaceMethods"); } @Test public void testInterfaceMethods() { doTest("pkg/TestInterfaceMethods"); }
//@Test public void testUnionType() { doTest("pkg/TestUnionType"); } //TODO: fix //@Test public void testUnionType() { doTest("pkg/TestUnionType"); } //TODO: fix
@Test public void testConstType() { doTest("pkg/TestConstType"); }
private void doTest(String testFile, String... companionFiles) { private void doTest(String testFile, String... companionFiles) {
ConsoleDecompiler decompiler = fixture.getDecompiler(); ConsoleDecompiler decompiler = fixture.getDecompiler();

@ -51,10 +51,10 @@ public class TestClassLoop {
for(boolean var8 = false; var2 < var1; ++var2) {// 70 73 90 for(boolean var8 = false; var2 < var1; ++var2) {// 70 73 90
char var6 = var0.charAt(var2);// 74 char var6 = var0.charAt(var2);// 74
if (var6 == 48) {// 75 if (var6 == '0') {// 75
++var7;// 76 ++var7;// 76
} else { } else {
if (var6 != 46) {// 77 if (var6 != '.') {// 77
break; break;
} }

@ -0,0 +1,337 @@
package pkg;
public class TestConstType {
private char lineBreak = '\n';
private char zero = 0;
public void setLineBreak(char os) {
switch(os) {// 8
case 'u':
this.lineBreak = '\r';// 10
break;// 11
case 'w':
this.lineBreak = '\n';// 14
}
}// 17
public void init() {
this.setLineBreak('w');// 20
}// 21
public String convertIndentation(String text) {
if (text.charAt(0) == '\t') {// 24
text = text.replace('\t', ' ');// 25
}
return text;// 27
}
public void printalot() {
System.out.println('a');// 31
System.out.println('\t');// 32
System.out.println(0);// 34
System.out.println(65);// 35
System.out.println(120);// 36
System.out.println(32760);// 37
System.out.println(32761);// 38
System.out.println(35000);// 39
System.out.println(50000);// 40
System.out.println(128000);// 41
System.out.println(60793);// 42
System.out.println(60737);// 43
System.out.println(60777);// 44
System.out.println(60785);// 45
System.out.println(60835);// 46
System.out.println(60843);// 47
System.out.println(60851);// 48
System.out.println(60859);// 49
System.out.println(1048576);// 50
System.out.println(49152);// 51
System.out.println(44100);// 52
System.out.println(44101);// 53
System.out.println(44102);// 54
System.out.println(44103);// 55
System.out.println(60000);// 56
System.out.println(64000);// 57
System.out.println(65000);// 58
System.out.println(45000);// 59
}// 60
public char guessType(int val) {
if (0 <= val && val <= 127) {// 63
return 'X';// 64
} else if (-128 <= val && val <= 127) {// 66
return 'B';// 67
} else if (128 <= val && val <= 32767) {// 69
return 'Y';// 70
} else if (-32768 <= val && val <= 32767) {// 72
return 'S';// 73
} else {
return (char)(32768 <= val && val <= 65535 ? 'C' : 'I');// 75 76 79
}
}
public int getTypeMaxValue(char type) {
int maxValue;
switch(type) {// 85
case 'B':
maxValue = 127;// 90
break;// 91
case 'C':
maxValue = 65535;// 99
break;// 100
case 'S':
maxValue = 32767;// 96
break;// 97
case 'X':
maxValue = 128;// 87
break;// 88
case 'Y':
maxValue = 32768;// 93
break;// 94
default:
maxValue = 2147483647;// 102
}
return maxValue;// 104
}
}
class 'pkg/TestConstType' {
method 'setLineBreak (C)V' {
1 7
1d 9
1f 9
22 10
26 12
28 12
2b 15
}
method 'init ()V' {
1 18
3 18
6 19
}
method 'convertIndentation (Ljava/lang/String;)Ljava/lang/String;' {
1 22
2 22
5 22
7 22
b 23
d 23
f 23
12 23
14 26
}
method 'printalot ()V' {
0 30
3 30
5 30
8 31
b 31
d 31
10 32
13 32
14 32
17 33
1a 33
1c 33
1f 34
22 34
24 34
27 35
2a 35
2d 35
30 36
33 36
36 36
39 37
3c 37
3e 37
41 38
44 38
46 38
49 39
4c 39
4e 39
51 40
54 40
56 40
59 41
5c 41
5e 41
61 42
64 42
66 42
69 43
6c 43
6e 43
71 44
74 44
76 44
79 45
7c 45
7e 45
81 46
84 46
86 46
89 47
8c 47
8e 47
91 48
94 48
96 48
99 49
9c 49
9e 49
a1 50
a4 50
a6 50
a9 51
ac 51
ae 51
b1 52
b4 52
b6 52
b9 53
bc 53
be 53
c1 54
c4 54
c6 54
c9 55
cc 55
ce 55
d1 56
d4 56
d6 56
d9 57
dc 57
de 57
e1 58
}
method 'guessType (I)C' {
0 61
2 61
6 61
8 61
b 62
d 62
e 63
11 63
15 63
17 63
1a 64
1c 64
1d 65
21 65
25 65
28 65
2b 66
2d 66
2e 67
32 67
36 67
39 67
3c 68
3e 68
3f 70
42 70
46 70
48 70
4b 70
4e 70
}
method 'getTypeMaxValue (C)I' {
1 76
34 87
37 87
38 88
3b 78
3d 78
3e 79
41 90
43 90
44 91
47 84
4a 84
4b 85
4e 81
50 81
51 82
54 93
56 93
58 96
}
}
Lines mapping:
8 <-> 8
10 <-> 10
11 <-> 11
14 <-> 13
17 <-> 16
20 <-> 19
21 <-> 20
24 <-> 23
25 <-> 24
27 <-> 27
31 <-> 31
32 <-> 32
34 <-> 33
35 <-> 34
36 <-> 35
37 <-> 36
38 <-> 37
39 <-> 38
40 <-> 39
41 <-> 40
42 <-> 41
43 <-> 42
44 <-> 43
45 <-> 44
46 <-> 45
47 <-> 46
48 <-> 47
49 <-> 48
50 <-> 49
51 <-> 50
52 <-> 51
53 <-> 52
54 <-> 53
55 <-> 54
56 <-> 55
57 <-> 56
58 <-> 57
59 <-> 58
60 <-> 59
63 <-> 62
64 <-> 63
66 <-> 64
67 <-> 65
69 <-> 66
70 <-> 67
72 <-> 68
73 <-> 69
75 <-> 71
76 <-> 71
79 <-> 71
85 <-> 77
87 <-> 88
88 <-> 89
90 <-> 79
91 <-> 80
93 <-> 91
94 <-> 92
96 <-> 85
97 <-> 86
99 <-> 82
100 <-> 83
102 <-> 94
104 <-> 97

@ -0,0 +1,106 @@
package pkg;
public class TestConstType {
private char lineBreak = '\n';
private char zero = 0;
public void setLineBreak(char os) {
switch (os) {
case 'u':
lineBreak = '\r';
break;
case 'w':
lineBreak = '\n';
break;
}
}
public void init() {
setLineBreak('w');
}
public String convertIndentation(String text) {
if (text.charAt(0) == '\t') {
text = text.replace('\t', ' ');
}
return text;
}
public void printalot() {
System.out.println('a');
System.out.println('\t');
System.out.println(0);
System.out.println(65);
System.out.println(120);
System.out.println(32760);
System.out.println(32761);
System.out.println(35000);
System.out.println(50000);
System.out.println(128000);
System.out.println(60793);
System.out.println(60737);
System.out.println(60777);
System.out.println(60785);
System.out.println(60835);
System.out.println(60843);
System.out.println(60851);
System.out.println(60859);
System.out.println(1048576);
System.out.println(49152);
System.out.println(44100);
System.out.println(44101);
System.out.println(44102);
System.out.println(44103);
System.out.println(60000);
System.out.println(64000);
System.out.println(65000);
System.out.println(45000);
}
public char guessType(int val) {
if (0 <= val && val <= 127) {
return 'X';
}
else if (-128 <= val && val <= 127) {
return 'B';
}
else if (128 <= val && val <= 32767) {
return 'Y';
}
else if (-32768 <= val && val <= 32767) {
return 'S';
}
else if (32768 <= val && val <= 0xFFFF) {
return 'C';
}
else {
return 'I';
}
}
public int getTypeMaxValue(char type) {
int maxValue;
switch (type) {
case 'X':
maxValue = 128;
break;
case 'B':
maxValue = 127;
break;
case 'Y':
maxValue = 32768;
break;
case 'S':
maxValue = 32767;
break;
case 'C':
maxValue = 0xFFFF;
break;
default:
maxValue = Integer.MAX_VALUE;
}
return maxValue;
}
}
Loading…
Cancel
Save