Skip to content

Commit a26cf5b

Browse files
committed
GROOVY-9526, GROOVY-11719: pop field state on exception
3_0_X backport
1 parent 3f13cee commit a26cf5b

2 files changed

Lines changed: 235 additions & 223 deletions

File tree

src/main/java/org/codehaus/groovy/control/ResolveVisitor.java

Lines changed: 119 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,8 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
102102
// note: BigInteger and BigDecimal are also imported by default
103103
// `java.util` is used much frequently than other two java packages(`java.io` and `java.net`), so place java.util before the two packages
104104
public static final String[] DEFAULT_IMPORTS = {"java.lang.", "java.util.", "java.io.", "java.net.", "groovy.lang.", "groovy.util."};
105-
private static final String BIGINTEGER_STR = "BigInteger";
106-
private static final String BIGDECIMAL_STR = "BigDecimal";
107-
public static final String QUESTION_MARK = "?";
108-
public static final String[] EMPTY_STRING_ARRAY = new String[0];
105+
public static final String[] EMPTY_STRING_ARRAY = {};
106+
public static final String QUESTION_MARK = "?";
109107

110108
private ClassNode currentClass;
111109
private final CompilationUnit compilationUnit;
@@ -273,13 +271,14 @@ public void visitField(final FieldNode node) {
273271
if (!canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())) {
274272
genericParameterNames = Collections.emptyMap();
275273
}
276-
277-
if (!fieldTypesChecked.contains(node)) {
278-
resolveOrFail(node.getType(), node);
274+
try {
275+
if (!fieldTypesChecked.contains(node)) {
276+
resolveOrFail(node.getType(), node);
277+
}
278+
super.visitField(node);
279+
} finally {
280+
genericParameterNames = oldNames;
279281
}
280-
super.visitField(node);
281-
282-
genericParameterNames = oldNames;
283282
}
284283

285284
@Override
@@ -288,13 +287,14 @@ public void visitProperty(final PropertyNode node) {
288287
if (!canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())) {
289288
genericParameterNames = Collections.emptyMap();
290289
}
290+
try {
291+
resolveOrFail(node.getType(), node);
292+
fieldTypesChecked.add(node.getField());
291293

292-
resolveOrFail(node.getType(), node);
293-
fieldTypesChecked.add(node.getField());
294-
295-
super.visitProperty(node);
296-
297-
genericParameterNames = oldNames;
294+
super.visitProperty(node);
295+
} finally {
296+
genericParameterNames = oldNames;
297+
}
298298
}
299299

300300
private static boolean canSeeTypeVars(final int mods, final ClassNode node) {
@@ -303,36 +303,36 @@ private static boolean canSeeTypeVars(final int mods, final ClassNode node) {
303303

304304
@Override
305305
protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) {
306+
MethodNode oldMethod = currentMethod;
306307
VariableScope oldScope = currentScope;
307308
currentScope = node.getVariableScope();
308309
Map<GenericsTypeName, GenericsType> oldNames = genericParameterNames;
309310
genericParameterNames =
310311
canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())
311312
? new HashMap<>(genericParameterNames) : new HashMap<>();
313+
try {
314+
resolveGenericsHeader(node.getGenericsTypes());
312315

313-
resolveGenericsHeader(node.getGenericsTypes());
314-
315-
resolveOrFail(node.getReturnType(), node);
316-
for (Parameter p : node.getParameters()) {
317-
p.setInitialExpression(transform(p.getInitialExpression()));
318-
ClassNode t = p.getType();
319-
resolveOrFail(t, t);
320-
visitAnnotations(p);
321-
}
322-
if (node.getExceptions() != null) {
323-
for (ClassNode t : node.getExceptions()) {
316+
resolveOrFail(node.getReturnType(), node);
317+
for (Parameter p : node.getParameters()) {
318+
p.setInitialExpression(transform(p.getInitialExpression()));
319+
ClassNode t = p.getType();
324320
resolveOrFail(t, t);
321+
visitAnnotations(p);
322+
}
323+
if (node.getExceptions() != null) {
324+
for (ClassNode t : node.getExceptions()) {
325+
resolveOrFail(t, t);
326+
}
325327
}
326-
}
327-
328-
MethodNode oldCurrentMethod = currentMethod;
329-
currentMethod = node;
330-
331-
super.visitConstructorOrMethod(node, isConstructor);
332328

333-
currentMethod = oldCurrentMethod;
334-
genericParameterNames = oldNames;
335-
currentScope = oldScope;
329+
currentMethod = node;
330+
super.visitConstructorOrMethod(node, isConstructor);
331+
} finally {
332+
genericParameterNames = oldNames;
333+
currentMethod = oldMethod;
334+
currentScope = oldScope;
335+
}
336336
}
337337

338338
private void resolveOrFail(final ClassNode type, final ASTNode node) {
@@ -650,11 +650,11 @@ protected boolean resolveFromDefaultImports(final ClassNode type) {
650650
if (resolveFromDefaultImports(type, DEFAULT_IMPORTS)) {
651651
return true;
652652
}
653-
if (BIGINTEGER_STR.equals(typeName)) {
653+
if ("BigInteger".equals(typeName)) {
654654
type.setRedirect(ClassHelper.BigInteger_TYPE);
655655
return true;
656656
}
657-
if (BIGDECIMAL_STR.equals(typeName)) {
657+
if ("BigDecimal".equals(typeName)) {
658658
type.setRedirect(ClassHelper.BigDecimal_TYPE);
659659
return true;
660660
}
@@ -1155,7 +1155,7 @@ protected Expression transformVariableExpression(final VariableExpression ve) {
11551155
}
11561156

11571157
private static boolean testVanillaNameForClass(final String name) {
1158-
if (name == null || name.length() == 0) return false;
1158+
if (name == null || name.isEmpty()) return false;
11591159
return !Character.isLowerCase(name.charAt(0));
11601160
}
11611161

@@ -1410,92 +1410,98 @@ private void checkAnnotationMemberValue(final Expression newValue) {
14101410
public void visitClass(final ClassNode node) {
14111411
ClassNode oldNode = currentClass; currentClass = node;
14121412
Map<GenericsTypeName, GenericsType> outerNames = null;
1413-
if (node instanceof InnerClassNode) {
1414-
outerNames = genericParameterNames;
1415-
genericParameterNames = new HashMap<>();
1416-
if (!Modifier.isStatic(node.getModifiers())) {
1417-
genericParameterNames.putAll(outerNames); // outer names visible
1418-
}
1419-
InnerClassNode innerClass = (InnerClassNode) node;
1420-
if (innerClass.isAnonymous()) {
1421-
MethodNode enclosingMethod = innerClass.getEnclosingMethod();
1422-
if (enclosingMethod != null) {
1423-
resolveGenericsHeader(enclosingMethod.getGenericsTypes());
1413+
try {
1414+
if (node instanceof InnerClassNode) {
1415+
outerNames = genericParameterNames;
1416+
genericParameterNames = new HashMap<>();
1417+
if (!Modifier.isStatic(node.getModifiers())) {
1418+
genericParameterNames.putAll(outerNames); // outer names visible
14241419
}
1420+
InnerClassNode innerClass = (InnerClassNode) node;
1421+
if (innerClass.isAnonymous()) {
1422+
MethodNode enclosingMethod = innerClass.getEnclosingMethod();
1423+
if (enclosingMethod != null) {
1424+
resolveGenericsHeader(enclosingMethod.getGenericsTypes());
1425+
}
1426+
}
1427+
} else {
1428+
genericParameterNames.clear(); // outer class: new generic namespace
14251429
}
1426-
} else {
1427-
genericParameterNames.clear(); // outer class: new generic namespace
1428-
}
14291430

1430-
resolveGenericsHeader(node.getGenericsTypes());
1431+
resolveGenericsHeader(node.getGenericsTypes());
14311432

1432-
ModuleNode module = node.getModule();
1433-
if (!module.hasImportsResolved()) {
1434-
for (ImportNode importNode : module.getImports()) {
1435-
currImportNode = importNode;
1436-
ClassNode type = importNode.getType();
1437-
if (resolve(type, false, false, true)) {
1438-
currImportNode = null;
1439-
continue;
1440-
}
1441-
currImportNode = null;
1442-
addError("unable to resolve class " + type.getName(), type);
1443-
}
1444-
for (ImportNode importNode : module.getStarImports()) {
1445-
if (importNode.getLineNumber() > 0) {
1433+
ModuleNode module = node.getModule();
1434+
if (!module.hasImportsResolved()) {
1435+
for (ImportNode importNode : module.getImports()) {
14461436
currImportNode = importNode;
1447-
String importName = importNode.getPackageName();
1448-
importName = importName.substring(0, importName.length()-1);
1449-
ClassNode type = ClassHelper.makeWithoutCaching(importName);
1450-
if (resolve(type, false, false, true)) {
1451-
importNode.setType(type);
1437+
try {
1438+
ClassNode type = importNode.getType();
1439+
if (!resolve(type, false, false, true)) {
1440+
addError("unable to resolve class " + type.getName(), type);
1441+
}
1442+
} finally {
1443+
currImportNode = null;
14521444
}
1453-
currImportNode = null;
14541445
}
1446+
for (ImportNode importNode : module.getStarImports()) {
1447+
if (importNode.getLineNumber() > 0) {
1448+
currImportNode = importNode;
1449+
try {
1450+
String importName = importNode.getPackageName();
1451+
importName = importName.substring(0, importName.length()-1);
1452+
ClassNode type = ClassHelper.makeWithoutCaching(importName);
1453+
if (resolve(type, false, false, true)) {
1454+
importNode.setType(type);
1455+
}
1456+
} finally {
1457+
currImportNode = null;
1458+
}
1459+
}
1460+
}
1461+
for (ImportNode importNode : module.getStaticImports().values()) {
1462+
ClassNode type = importNode.getType();
1463+
if (!resolve(type, true, true, true))
1464+
addError("unable to resolve class " + type.getName(), type);
1465+
}
1466+
for (ImportNode importNode : module.getStaticStarImports().values()) {
1467+
ClassNode type = importNode.getType();
1468+
if (!resolve(type, true, true, true))
1469+
addError("unable to resolve class " + type.getName(), type);
1470+
}
1471+
module.setImportsResolved(true);
14551472
}
1456-
for (ImportNode importNode : module.getStaticImports().values()) {
1457-
ClassNode type = importNode.getType();
1458-
if (!resolve(type, true, true, true))
1459-
addError("unable to resolve class " + type.getName(), type);
1473+
1474+
ClassNode sn = node.getUnresolvedSuperClass();
1475+
if (sn != null) {
1476+
resolveOrFail(sn, "", node, true);
14601477
}
1461-
for (ImportNode importNode : module.getStaticStarImports().values()) {
1462-
ClassNode type = importNode.getType();
1463-
if (!resolve(type, true, true, true))
1464-
addError("unable to resolve class " + type.getName(), type);
1478+
for (ClassNode in : node.getInterfaces()) {
1479+
resolveOrFail(in, "", node, true);
14651480
}
1466-
module.setImportsResolved(true);
1467-
}
1468-
1469-
ClassNode sn = node.getUnresolvedSuperClass();
1470-
if (sn != null) {
1471-
resolveOrFail(sn, "", node, true);
1472-
}
1473-
for (ClassNode in : node.getInterfaces()) {
1474-
resolveOrFail(in, "", node, true);
1475-
}
14761481

1477-
if (sn != null) checkCyclicInheritance(node, sn);
1478-
for (ClassNode in : node.getInterfaces()) {
1479-
checkCyclicInheritance(node, in);
1480-
}
1481-
if (node.getGenericsTypes() != null) {
1482-
for (GenericsType gt : node.getGenericsTypes()) {
1483-
if (gt != null && gt.getUpperBounds() != null) {
1484-
for (ClassNode variant : gt.getUpperBounds()) {
1485-
if (variant.isGenericsPlaceHolder()) checkCyclicInheritance(variant, gt.getType());
1482+
if (sn != null) checkCyclicInheritance(node, sn);
1483+
for (ClassNode in : node.getInterfaces()) {
1484+
checkCyclicInheritance(node, in);
1485+
}
1486+
if (node.getGenericsTypes() != null) {
1487+
for (GenericsType gt : node.getGenericsTypes()) {
1488+
if (gt != null && gt.getUpperBounds() != null) {
1489+
for (ClassNode variant : gt.getUpperBounds()) {
1490+
if (variant.isGenericsPlaceHolder()) checkCyclicInheritance(variant, gt.getType());
1491+
}
14861492
}
14871493
}
14881494
}
1489-
}
1490-
1491-
super.visitClass(node);
14921495

1493-
resolveOuterNestedClassFurther(node);
1496+
super.visitClass(node);
14941497

1495-
if (outerNames != null) // GROOVY-11711
1496-
genericParameterNames = outerNames;
1498+
resolveOuterNestedClassFurther(node);
1499+
} finally {
1500+
if (outerNames != null) // GROOVY-11711
1501+
genericParameterNames = outerNames;
14971502

1498-
currentClass = oldNode;
1503+
currentClass = oldNode;
1504+
}
14991505
}
15001506

15011507
private void checkCyclicInheritance(final ClassNode node, final ClassNode type) {
@@ -1574,8 +1580,11 @@ public void visitForLoop(final ForStatement forLoop) {
15741580
public void visitBlockStatement(final BlockStatement block) {
15751581
VariableScope oldScope = currentScope;
15761582
currentScope = block.getVariableScope();
1577-
super.visitBlockStatement(block);
1578-
currentScope = oldScope;
1583+
try {
1584+
super.visitBlockStatement(block);
1585+
} finally {
1586+
currentScope = oldScope;
1587+
}
15791588
}
15801589

15811590
private boolean resolveGenericsTypes(final GenericsType[] types) {

0 commit comments

Comments
 (0)