mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-282934 [java-decompiler] - supported the case when the temp pattern variable is in the outer scope
GitOrigin-RevId: a00f7d0a99913f01260689b7c970e34df8477cfb
This commit is contained in:
committed by
intellij-monorepo-bot
parent
436eee6cf4
commit
2c16bcb81e
+44
-16
@@ -1,11 +1,15 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.java.decompiler.modules.decompiler;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.java.decompiler.modules.decompiler.exps.*;
|
||||
import org.jetbrains.java.decompiler.modules.decompiler.stats.*;
|
||||
import org.jetbrains.java.decompiler.struct.StructClass;
|
||||
import org.jetbrains.java.decompiler.struct.gen.VarType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PatternHelper {
|
||||
|
||||
@@ -17,12 +21,16 @@ public class PatternHelper {
|
||||
* @param statement root statement to start traversal
|
||||
* @param structClass owner class of <code>statement</code>
|
||||
*/
|
||||
public static void replaceAssignmentsWithPatternVariables(RootStatement statement, StructClass structClass) {
|
||||
if (!structClass.isVersion16()) return;
|
||||
replaceAssignmentsWithPatternVariables(statement);
|
||||
public static void replaceAssignmentsWithPatternVariables(@NotNull RootStatement statement, @NotNull StructClass structClass) {
|
||||
if (!structClass.hasPatternsInInstanceofSupport()) return;
|
||||
// todo VarExprent overrides equals, but not hashCode, duplicates are possible
|
||||
Map<VarExprent, Statement> tempVarAssignments = new HashMap<>();
|
||||
replaceAssignmentsWithPatternVariables(statement, tempVarAssignments);
|
||||
SwitchHelper.removeTempVariableDeclarations(tempVarAssignments);
|
||||
}
|
||||
|
||||
private static void replaceAssignmentsWithPatternVariables(Statement statement) {
|
||||
private static void replaceAssignmentsWithPatternVariables(@NotNull Statement statement,
|
||||
@NotNull Map<VarExprent, Statement> tempVarAssignments) {
|
||||
if (statement instanceof IfStatement) {
|
||||
IfStatement ifStatement = (IfStatement)statement;
|
||||
FunctionExprent instanceOfExprent = findInstanceofExprent(ifStatement);
|
||||
@@ -34,29 +42,34 @@ public class PatternHelper {
|
||||
ConstExprent checkType = (ConstExprent)operands.get(1);
|
||||
|
||||
PatternVariableCandidate patternVarCandidate = findPatternVarCandidate(ifStatement.getIfstat(), operand, checkType);
|
||||
if (patternVarCandidate == null) {
|
||||
if (patternVarCandidate == null && ifStatement.getElsestat() != null) {
|
||||
patternVarCandidate = findPatternVarCandidate(ifStatement.getElsestat(), operand, checkType);
|
||||
}
|
||||
if (patternVarCandidate == null) return;
|
||||
|
||||
instanceOfExprent.getLstOperands().remove(1);
|
||||
instanceOfExprent.getLstOperands().add(patternVarCandidate.varExprent);
|
||||
operands.remove(1);
|
||||
if (!patternVarCandidate.varExprent.isDefinition()) {
|
||||
patternVarCandidate.varExprent.setDefinition(true);
|
||||
tempVarAssignments.put(patternVarCandidate.varExprent, ifStatement);
|
||||
}
|
||||
operands.add(patternVarCandidate.varExprent);
|
||||
patternVarCandidate.ifElseStat.getExprents().remove(patternVarCandidate.assignmentExprent);
|
||||
return;
|
||||
}
|
||||
for (Statement child : statement.getStats()) {
|
||||
replaceAssignmentsWithPatternVariables(child);
|
||||
replaceAssignmentsWithPatternVariables(child, tempVarAssignments);
|
||||
}
|
||||
}
|
||||
|
||||
private static FunctionExprent findInstanceofExprent(IfStatement ifStat) {
|
||||
private static FunctionExprent findInstanceofExprent(@NotNull IfStatement ifStat) {
|
||||
return ifStat.getHeadexprent().getAllExprents(true).stream()
|
||||
.filter(expr -> expr.type == Exprent.EXPRENT_FUNCTION).map(expr -> (FunctionExprent)expr)
|
||||
.filter(expr -> expr.getFuncType() == FunctionExprent.FUNCTION_INSTANCEOF)
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
private static PatternVariableCandidate findPatternVarCandidate(Statement ifElseStat, VarExprent operand, ConstExprent checkType) {
|
||||
private static PatternVariableCandidate findPatternVarCandidate(@NotNull Statement ifElseStat,
|
||||
@NotNull VarExprent operand,
|
||||
@NotNull ConstExprent checkType) {
|
||||
if (ifElseStat instanceof BasicBlockStatement) {
|
||||
List<Exprent> ifElseExprents = ifElseStat.getExprents();
|
||||
if (ifElseExprents.isEmpty() || ifElseExprents.get(0).type != Exprent.EXPRENT_ASSIGNMENT) return null;
|
||||
@@ -64,11 +77,24 @@ public class PatternHelper {
|
||||
AssignmentExprent assignmentExprent = (AssignmentExprent)ifElseExprents.get(0);
|
||||
if (assignmentExprent.getLeft().type != Exprent.EXPRENT_VAR) return null;
|
||||
VarExprent varExprent = (VarExprent)assignmentExprent.getLeft();
|
||||
if (!varExprent.isDefinition()) return null;
|
||||
if (assignmentExprent.getRight().type != Exprent.EXPRENT_FUNCTION) return null;
|
||||
FunctionExprent castExprent = (FunctionExprent)assignmentExprent.getRight();
|
||||
if (castExprent.getFuncType() != FunctionExprent.FUNCTION_CAST) return null;
|
||||
|
||||
if (!varExprent.isDefinition()) {
|
||||
Exprent leftAssignmentPart = assignmentExprent.getLeft();
|
||||
Exprent rightAssignmentPart = assignmentExprent.getRight();
|
||||
if (leftAssignmentPart.type != Exprent.EXPRENT_VAR || rightAssignmentPart.type != Exprent.EXPRENT_FUNCTION ||
|
||||
((FunctionExprent)rightAssignmentPart).getFuncType() != FunctionExprent.FUNCTION_CAST) {
|
||||
return null;
|
||||
}
|
||||
varExprent = ((VarExprent)leftAssignmentPart);
|
||||
List<Exprent> castOperands = ((FunctionExprent)rightAssignmentPart).getLstOperands();
|
||||
if (castOperands.size() != 2 || castOperands.get(1).type != Exprent.EXPRENT_CONST) return null;
|
||||
VarType castType = ((ConstExprent)castOperands.get(1)).getConstType();
|
||||
varExprent.setVarType(castType);
|
||||
}
|
||||
|
||||
List<Exprent> castExprents = castExprent.getAllExprents();
|
||||
if (castExprents.size() == 2 && operand.equals(castExprents.get(0)) && checkType.equals(castExprents.get(1))) {
|
||||
return new PatternVariableCandidate(ifElseStat, assignmentExprent, varExprent);
|
||||
@@ -82,11 +108,13 @@ public class PatternHelper {
|
||||
}
|
||||
|
||||
private static class PatternVariableCandidate {
|
||||
private final Statement ifElseStat;
|
||||
private final AssignmentExprent assignmentExprent;
|
||||
private final VarExprent varExprent;
|
||||
private final @NotNull Statement ifElseStat;
|
||||
private final @NotNull AssignmentExprent assignmentExprent;
|
||||
private final @NotNull VarExprent varExprent;
|
||||
|
||||
private PatternVariableCandidate(Statement ifElseStat, AssignmentExprent assignmentExprent, VarExprent varExprent) {
|
||||
private PatternVariableCandidate(@NotNull Statement ifElseStat,
|
||||
@NotNull AssignmentExprent assignmentExprent,
|
||||
@NotNull VarExprent varExprent) {
|
||||
this.ifElseStat = ifElseStat;
|
||||
this.assignmentExprent = assignmentExprent;
|
||||
this.varExprent = varExprent;
|
||||
|
||||
+28
-21
@@ -138,32 +138,39 @@ public final class SwitchHelper {
|
||||
(index instanceof InvocationExprent && ((InvocationExprent)index).getName().equals("ordinal")));
|
||||
}
|
||||
|
||||
private static void removeTempVariableDeclarations(@NotNull Map<VarExprent, Statement> tempVarAssignments) {
|
||||
static void removeTempVariableDeclarations(@NotNull Map<VarExprent, Statement> tempVarAssignments) {
|
||||
if (tempVarAssignments.isEmpty()) return;
|
||||
for (Statement statement : new HashSet<>(tempVarAssignments.values())) {
|
||||
Statement parent = statement;
|
||||
while (parent != null) {
|
||||
boolean removed = false;
|
||||
Statement firstStatement = parent.getFirst();
|
||||
if (firstStatement.type == Statement.TYPE_BASIC_BLOCK) {
|
||||
for (int i = 0; i < firstStatement.getExprents().size(); i++) {
|
||||
Exprent exprent = firstStatement.getExprents().get(i);
|
||||
Exprent assignmentExprent = null;
|
||||
if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) {
|
||||
assignmentExprent = exprent;
|
||||
exprent = ((AssignmentExprent)exprent).getLeft();
|
||||
}
|
||||
if (exprent.type != Exprent.EXPRENT_VAR) continue;
|
||||
VarExprent varExprent = (VarExprent)exprent;
|
||||
if (varExprent.isDefinition() && tempVarAssignments.keySet().stream()
|
||||
.anyMatch(expr -> expr.getIndex() == varExprent.getIndex() && expr.getVersion() == varExprent.getVersion())) {
|
||||
firstStatement.getExprents().remove(assignmentExprent == null ? varExprent : assignmentExprent);
|
||||
removed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (removed) break;
|
||||
List<Exprent> varExprents;
|
||||
if (parent.getFirst().type == Statement.TYPE_BASIC_BLOCK) {
|
||||
varExprents = parent.getFirst().getExprents();
|
||||
}
|
||||
else if (parent.type == Statement.TYPE_TRY_CATCH) {
|
||||
varExprents = parent.getVarDefinitions();
|
||||
}
|
||||
else {
|
||||
varExprents = Collections.emptyList();
|
||||
}
|
||||
for (int i = 0; i < varExprents.size(); i++) {
|
||||
Exprent exprent = varExprents.get(i);
|
||||
Exprent assignmentExprent = null;
|
||||
if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) {
|
||||
assignmentExprent = exprent;
|
||||
exprent = ((AssignmentExprent)exprent).getLeft();
|
||||
}
|
||||
if (exprent.type != Exprent.EXPRENT_VAR) continue;
|
||||
VarExprent varExprent = (VarExprent)exprent;
|
||||
if (varExprent.isDefinition() && tempVarAssignments.keySet().stream()
|
||||
.anyMatch(expr -> expr.getIndex() == varExprent.getIndex() && expr.getVersion() == varExprent.getVersion())) {
|
||||
varExprents.remove(assignmentExprent == null ? varExprent : assignmentExprent);
|
||||
removed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (removed) break;
|
||||
parent = parent.getParent();
|
||||
}
|
||||
}
|
||||
@@ -176,7 +183,7 @@ public final class SwitchHelper {
|
||||
|
||||
@NotNull
|
||||
Set<Object> findRealCaseValuesHashCodes(@NotNull SwitchStatement switchStatement) {
|
||||
//noinspection SSBasedInspection,ConstantConditions
|
||||
// noinspection SSBasedInspection
|
||||
return switchStatement.getCaseValues().stream()
|
||||
// We take only buckets that don't contain null value.
|
||||
// null value represents default branch and no temp variable is assigned there.
|
||||
|
||||
+20
-4
@@ -204,16 +204,32 @@ public class StructClass extends StructMember {
|
||||
return majorVersion >= CodeConstants.BYTECODE_JAVA_8;
|
||||
}
|
||||
|
||||
public boolean hasSealedClassesSupport() {
|
||||
return majorVersion >= CodeConstants.BYTECODE_JAVA_17 || (majorVersion >= CodeConstants.BYTECODE_JAVA_15 && isPreviewVersion());
|
||||
public boolean isVersion14() {
|
||||
return majorVersion >= CodeConstants.BYTECODE_JAVA_14;
|
||||
}
|
||||
|
||||
public boolean isVersion15() {
|
||||
return majorVersion >= CodeConstants.BYTECODE_JAVA_15;
|
||||
}
|
||||
|
||||
public boolean isVersion16() {
|
||||
return majorVersion >= CodeConstants.BYTECODE_JAVA_16;
|
||||
}
|
||||
|
||||
public boolean isVersion17() {
|
||||
return majorVersion >= CodeConstants.BYTECODE_JAVA_17;
|
||||
}
|
||||
|
||||
public boolean isPreviewVersion() {
|
||||
return minorVersion == 0xFFFF;
|
||||
}
|
||||
|
||||
public boolean isVersion16() {
|
||||
return majorVersion >= CodeConstants.BYTECODE_JAVA_16;
|
||||
public boolean hasSealedClassesSupport() {
|
||||
return isVersion17() || (isVersion15() && isPreviewVersion());
|
||||
}
|
||||
|
||||
public boolean hasPatternsInInstanceofSupport() {
|
||||
return isVersion16() || (isVersion14() && isPreviewVersion());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-16
@@ -212,24 +212,13 @@ public class SingleClassesTest {
|
||||
@Test public void testInheritanceChainCycle() { doTest("pkg/TestInheritanceChainCycle"); }
|
||||
@Test public void testDynamicConstantPoolEntry() { doTest("java11/TestDynamicConstantPoolEntry"); }
|
||||
|
||||
@Test
|
||||
public void testInstanceof() {
|
||||
doTest("patterns/TestInstanceof");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvertedInstanceof() {
|
||||
doTest("patterns/TestInvertedInstanceof");
|
||||
@Test public void testInstanceofWithPattern() {
|
||||
doTest("patterns/TestInstanceofWithPattern");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInstanceofBinaryExpr() {
|
||||
doTest("patterns/TestInstanceofBinaryExpr");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInstanceofVarNotSupported() {
|
||||
doTest("patterns/TestInstanceofVarNotSupported");
|
||||
@Test public void testInstanceofVarNotSupported() {
|
||||
// bytecode version of this test data doesn't support patterns in instanceof, so no modifications regarding that are applied
|
||||
doTest("patterns/TestInstanceofPatternNotSupported");
|
||||
}
|
||||
|
||||
@Test(expected = ClassFormatException.class)
|
||||
|
||||
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
@@ -1,31 +0,0 @@
|
||||
package patterns;
|
||||
|
||||
public class TestInstanceof {
|
||||
void typePattern(Object str) {
|
||||
if (str instanceof String s) {// 6
|
||||
System.out.println(s);// 7
|
||||
} else {
|
||||
System.out.println("no");// 9
|
||||
}
|
||||
|
||||
}// 11
|
||||
}
|
||||
|
||||
class 'patterns/TestInstanceof' {
|
||||
method 'typePattern (Ljava/lang/Object;)V' {
|
||||
3 4
|
||||
6 4
|
||||
e 5
|
||||
12 5
|
||||
18 7
|
||||
1b 7
|
||||
1d 7
|
||||
20 10
|
||||
}
|
||||
}
|
||||
|
||||
Lines mapping:
|
||||
6 <-> 5
|
||||
7 <-> 6
|
||||
9 <-> 8
|
||||
11 <-> 11
|
||||
@@ -1,39 +0,0 @@
|
||||
package patterns;
|
||||
|
||||
public class TestInstanceofBinaryExpr {
|
||||
void typePattern(Object str) {
|
||||
if (str instanceof String s) {// 6
|
||||
if (s.length() > 1 || s.startsWith("a")) {
|
||||
System.out.println(s);// 7
|
||||
return;// 11
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("no");// 9
|
||||
}
|
||||
}
|
||||
|
||||
class 'patterns/TestInstanceofBinaryExpr' {
|
||||
method 'typePattern (Ljava/lang/Object;)V' {
|
||||
3 4
|
||||
6 4
|
||||
f 5
|
||||
12 5
|
||||
13 5
|
||||
17 5
|
||||
19 5
|
||||
1c 5
|
||||
1f 6
|
||||
23 6
|
||||
29 11
|
||||
2c 11
|
||||
2e 11
|
||||
31 7
|
||||
}
|
||||
}
|
||||
|
||||
Lines mapping:
|
||||
6 <-> 5
|
||||
7 <-> 7
|
||||
9 <-> 12
|
||||
11 <-> 8
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
package patterns;
|
||||
package decompiler;
|
||||
|
||||
public class TestInstanceofVarNotSupported {
|
||||
public class TestInstanceofPatternNotSupported {
|
||||
void typePattern(Object str) {
|
||||
if (!(str instanceof String)) {// 5
|
||||
System.out.println("no");// 6
|
||||
@@ -16,7 +16,7 @@ public class TestInstanceofVarNotSupported {
|
||||
}// 7 15
|
||||
}
|
||||
|
||||
class 'patterns/TestInstanceofVarNotSupported' {
|
||||
class 'decompiler/TestInstanceofPatternNotSupported' {
|
||||
method 'typePattern (Ljava/lang/Object;)V' {
|
||||
1 4
|
||||
4 4
|
||||
@@ -0,0 +1,235 @@
|
||||
package decompiler;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class TestInstanceofWithPattern {
|
||||
void typePattern1(Object str) {
|
||||
if (str instanceof String s) {// 9
|
||||
System.out.println(s);// 10
|
||||
} else {
|
||||
System.out.println("no");// 12
|
||||
}
|
||||
|
||||
}// 14
|
||||
|
||||
void typePattern2(Object str) {
|
||||
if (!(str instanceof String s)) {// 17
|
||||
System.out.println("no");// 18
|
||||
} else {
|
||||
if (s.length() > 3) {// 22
|
||||
System.out.println(s);// 23
|
||||
} else if (s.startsWith("a")) {// 24
|
||||
System.out.println("" + s);// 25
|
||||
}
|
||||
|
||||
}
|
||||
}// 19 27
|
||||
|
||||
void typePatternInBinaryExpr(Object str) {
|
||||
if (str instanceof String s) {// 30
|
||||
if (s.length() > 1 || s.startsWith("a")) {
|
||||
System.out.println(s);// 31
|
||||
return;// 35
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("no");// 33
|
||||
}
|
||||
|
||||
String returnInstanceof(Object obj) {
|
||||
if (obj instanceof String s) {// 38
|
||||
if (s.length() > 50) {
|
||||
return "\"" + s.substring(0, 50) + "...\"";// 39
|
||||
}
|
||||
}
|
||||
|
||||
if (obj instanceof String s) {// 41
|
||||
return "\"" + s + "\"";// 42
|
||||
} else if (obj instanceof Collection<?> c) {// 44
|
||||
return "Collection (size = " + c.size() + ")";// 45
|
||||
} else {
|
||||
return obj.toString();// 47
|
||||
}
|
||||
}
|
||||
|
||||
String complex(Object obj1, Object obj2) {
|
||||
while(true) {
|
||||
try {
|
||||
if (obj1 instanceof String s) {// 53
|
||||
while(!s.startsWith("a")) {// 55
|
||||
}
|
||||
|
||||
return s;// 56
|
||||
}
|
||||
|
||||
if (obj2 instanceof Collection<?> c) {// 59
|
||||
return c.toString();// 60
|
||||
}
|
||||
} catch (Exception var7) {// 62
|
||||
if (obj2 instanceof String s) {// 63
|
||||
while(!s.startsWith("b")) {// 65
|
||||
}
|
||||
|
||||
return s + "b";// 66
|
||||
}
|
||||
|
||||
if (obj2 instanceof List<?> l) {// 69
|
||||
String var10000 = this.getStr();// 70
|
||||
return var10000 + l.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String getStr() {
|
||||
return null;// 77
|
||||
}
|
||||
}
|
||||
|
||||
class 'decompiler/TestInstanceofWithPattern' {
|
||||
method 'typePattern1 (Ljava/lang/Object;)V' {
|
||||
3 7
|
||||
6 7
|
||||
e 8
|
||||
12 8
|
||||
18 10
|
||||
1b 10
|
||||
1d 10
|
||||
20 13
|
||||
}
|
||||
|
||||
method 'typePattern2 (Ljava/lang/Object;)V' {
|
||||
1 16
|
||||
4 16
|
||||
7 17
|
||||
a 17
|
||||
c 17
|
||||
f 26
|
||||
16 19
|
||||
19 19
|
||||
1a 19
|
||||
1d 20
|
||||
21 20
|
||||
28 21
|
||||
2a 21
|
||||
2d 21
|
||||
30 22
|
||||
34 22
|
||||
39 22
|
||||
3c 26
|
||||
}
|
||||
|
||||
method 'typePatternInBinaryExpr (Ljava/lang/Object;)V' {
|
||||
3 29
|
||||
6 29
|
||||
f 30
|
||||
12 30
|
||||
13 30
|
||||
17 30
|
||||
19 30
|
||||
1c 30
|
||||
1f 31
|
||||
23 31
|
||||
29 36
|
||||
2c 36
|
||||
2e 36
|
||||
31 32
|
||||
}
|
||||
|
||||
method 'returnInstanceof (Ljava/lang/Object;)Ljava/lang/String;' {
|
||||
3 40
|
||||
6 40
|
||||
f 41
|
||||
12 41
|
||||
14 41
|
||||
18 42
|
||||
19 42
|
||||
1b 42
|
||||
1e 42
|
||||
23 42
|
||||
27 46
|
||||
2a 46
|
||||
33 47
|
||||
38 47
|
||||
3c 48
|
||||
3f 48
|
||||
48 49
|
||||
4d 49
|
||||
52 49
|
||||
54 51
|
||||
57 51
|
||||
}
|
||||
|
||||
method 'complex (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/String;' {
|
||||
5 58
|
||||
8 58
|
||||
14 59
|
||||
16 59
|
||||
19 59
|
||||
1e 62
|
||||
24 65
|
||||
27 65
|
||||
31 66
|
||||
34 66
|
||||
38 68
|
||||
3e 69
|
||||
41 69
|
||||
4d 70
|
||||
4f 70
|
||||
52 70
|
||||
57 73
|
||||
5c 73
|
||||
62 76
|
||||
65 76
|
||||
70 77
|
||||
75 78
|
||||
7a 78
|
||||
7f 78
|
||||
}
|
||||
|
||||
method 'getStr ()Ljava/lang/String;' {
|
||||
0 85
|
||||
1 85
|
||||
}
|
||||
}
|
||||
|
||||
Lines mapping:
|
||||
9 <-> 8
|
||||
10 <-> 9
|
||||
12 <-> 11
|
||||
14 <-> 14
|
||||
17 <-> 17
|
||||
18 <-> 18
|
||||
19 <-> 27
|
||||
22 <-> 20
|
||||
23 <-> 21
|
||||
24 <-> 22
|
||||
25 <-> 23
|
||||
27 <-> 27
|
||||
30 <-> 30
|
||||
31 <-> 32
|
||||
33 <-> 37
|
||||
35 <-> 33
|
||||
38 <-> 41
|
||||
39 <-> 43
|
||||
41 <-> 47
|
||||
42 <-> 48
|
||||
44 <-> 49
|
||||
45 <-> 50
|
||||
47 <-> 52
|
||||
53 <-> 59
|
||||
55 <-> 60
|
||||
56 <-> 63
|
||||
59 <-> 66
|
||||
60 <-> 67
|
||||
62 <-> 69
|
||||
63 <-> 70
|
||||
65 <-> 71
|
||||
66 <-> 74
|
||||
69 <-> 77
|
||||
70 <-> 78
|
||||
77 <-> 86
|
||||
Not mapped:
|
||||
21
|
||||
72
|
||||
@@ -1,51 +0,0 @@
|
||||
package patterns;
|
||||
|
||||
public class TestInvertedInstanceof {
|
||||
void typePattern(Object str) {
|
||||
if (!(str instanceof String s)) {// 5
|
||||
System.out.println("no");// 6
|
||||
} else {
|
||||
if (s.length() > 3) {// 10
|
||||
System.out.println(s);// 11
|
||||
} else if (s.startsWith("a")) {// 12
|
||||
System.out.println("" + s);// 13
|
||||
}
|
||||
|
||||
}
|
||||
}// 7 15
|
||||
}
|
||||
|
||||
class 'patterns/TestInvertedInstanceof' {
|
||||
method 'typePattern (Ljava/lang/Object;)V' {
|
||||
1 4
|
||||
4 4
|
||||
7 5
|
||||
a 5
|
||||
c 5
|
||||
f 14
|
||||
16 7
|
||||
19 7
|
||||
1a 7
|
||||
1d 8
|
||||
21 8
|
||||
28 9
|
||||
2a 9
|
||||
2d 9
|
||||
30 10
|
||||
34 10
|
||||
39 10
|
||||
3c 14
|
||||
}
|
||||
}
|
||||
|
||||
Lines mapping:
|
||||
5 <-> 5
|
||||
6 <-> 6
|
||||
7 <-> 15
|
||||
10 <-> 8
|
||||
11 <-> 9
|
||||
12 <-> 10
|
||||
13 <-> 11
|
||||
15 <-> 15
|
||||
Not mapped:
|
||||
9
|
||||
@@ -1,12 +0,0 @@
|
||||
package patterns;
|
||||
|
||||
public class TestInstanceof {
|
||||
|
||||
void typePattern(Object str) {
|
||||
if (str instanceof String s) {
|
||||
System.out.println(s);
|
||||
} else {
|
||||
System.out.println("no");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package patterns;
|
||||
|
||||
public class TestInstanceofBinaryExpr {
|
||||
|
||||
void typePattern(Object str) {
|
||||
if (str instanceof String s && (s.length() > 1 || s.startsWith("a"))) {
|
||||
System.out.println(s);
|
||||
} else {
|
||||
System.out.println("no");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package decompiler;
|
||||
|
||||
public class TestInstanceofVarNotSupported {
|
||||
public class TestInstanceofPatternNotSupported {
|
||||
void typePattern(Object str) {
|
||||
if (!(str instanceof String)) {
|
||||
System.out.println("no");
|
||||
@@ -0,0 +1,79 @@
|
||||
package patterns;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class TestInstanceofWithPattern {
|
||||
|
||||
void typePattern1(Object str) {
|
||||
if (str instanceof String s) {
|
||||
System.out.println(s);
|
||||
} else {
|
||||
System.out.println("no");
|
||||
}
|
||||
}
|
||||
|
||||
void typePattern2(Object str) {
|
||||
if (!(str instanceof String)) {
|
||||
System.out.println("no");
|
||||
return;
|
||||
}
|
||||
String s = (String) str;
|
||||
if (s.length() > 3) {
|
||||
System.out.println(s);
|
||||
} else if (s.startsWith("a")) {
|
||||
System.out.println(s + "");
|
||||
}
|
||||
}
|
||||
|
||||
void typePatternInBinaryExpr(Object str) {
|
||||
if (str instanceof String s && (s.length() > 1 || s.startsWith("a"))) {
|
||||
System.out.println(s);
|
||||
} else {
|
||||
System.out.println("no");
|
||||
}
|
||||
}
|
||||
|
||||
String returnInstanceof(Object obj) {
|
||||
if (obj instanceof String s && s.length() > 50) {
|
||||
return '"' + s.substring(0, 50) + "...\"";
|
||||
}
|
||||
if (obj instanceof String s) {
|
||||
return '"' + s + '"';
|
||||
}
|
||||
if (obj instanceof Collection<?> c) {
|
||||
return "Collection (size = " + c.size() + ")";
|
||||
}
|
||||
return obj.toString();
|
||||
}
|
||||
|
||||
String complex(Object obj1, Object obj2) {
|
||||
while(true) {
|
||||
try {
|
||||
if (obj1 instanceof String s) {
|
||||
while (true) {
|
||||
if (s.startsWith("a")) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
} else if (obj2 instanceof Collection<?> c) {
|
||||
return c.toString();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (obj2 instanceof String s) {
|
||||
while (true) {
|
||||
if (s.startsWith("b")) {
|
||||
return s + "b";
|
||||
}
|
||||
}
|
||||
} else if (obj2 instanceof List<?> l) {
|
||||
return getStr() + l.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String getStr() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package patterns;
|
||||
|
||||
public class TestInvertedInstanceof {
|
||||
void typePattern(Object str) {
|
||||
if (!(str instanceof String)) {
|
||||
System.out.println("no");
|
||||
return;
|
||||
}
|
||||
String s = (String) str;
|
||||
if (s.length() > 3) {
|
||||
System.out.println(s);
|
||||
} else if (s.startsWith("a")) {
|
||||
System.out.println(s + "");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user