Skip to content

Commit 7aec64d

Browse files
committed
GROOVY-9526, GROOVY-11719: pop field state on exception
4_0_X backport
1 parent 23bd97d commit 7aec64d

2 files changed

Lines changed: 173 additions & 130 deletions

File tree

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

Lines changed: 129 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
9595
// note: BigInteger and BigDecimal are also imported by default
9696
// `java.util` is used much frequently than other two java packages(`java.io` and `java.net`), so place java.util before the two packages
9797
public static final String[] DEFAULT_IMPORTS = {"java.lang.", "java.util.", "java.io.", "java.net.", "groovy.lang.", "groovy.util."};
98-
public static final String[] EMPTY_STRING_ARRAY = new String[0];
98+
public static final String[] EMPTY_STRING_ARRAY = {};
9999
public static final String QUESTION_MARK = "?";
100100

101101
private final CompilationUnit compilationUnit;
@@ -269,13 +269,14 @@ public void visitField(final FieldNode node) {
269269
if (!canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())) {
270270
genericParameterNames = Collections.emptyMap();
271271
}
272-
273-
if (!fieldTypesChecked.contains(node)) {
274-
resolveOrFail(node.getType(), node);
272+
try {
273+
if (!fieldTypesChecked.contains(node)) {
274+
resolveOrFail(node.getType(), node);
275+
}
276+
super.visitField(node);
277+
} finally {
278+
genericParameterNames = oldNames;
275279
}
276-
super.visitField(node);
277-
278-
genericParameterNames = oldNames;
279280
}
280281

281282
@Override
@@ -284,13 +285,14 @@ public void visitProperty(final PropertyNode node) {
284285
if (!canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())) {
285286
genericParameterNames = Collections.emptyMap();
286287
}
288+
try {
289+
resolveOrFail(node.getType(), node);
290+
fieldTypesChecked.add(node.getField());
287291

288-
resolveOrFail(node.getType(), node);
289-
fieldTypesChecked.add(node.getField());
290-
291-
super.visitProperty(node);
292-
293-
genericParameterNames = oldNames;
292+
super.visitProperty(node);
293+
} finally {
294+
genericParameterNames = oldNames;
295+
}
294296
}
295297

296298
private static boolean canSeeTypeVars(final int mods, final ClassNode node) {
@@ -299,38 +301,38 @@ private static boolean canSeeTypeVars(final int mods, final ClassNode node) {
299301

300302
@Override
301303
protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) {
304+
MethodNode oldMethod = currentMethod;
302305
VariableScope oldScope = currentScope;
303306
currentScope = node.getVariableScope();
304307
Map<GenericsTypeName, GenericsType> oldNames = genericParameterNames;
305308
genericParameterNames =
306309
canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())
307310
? new HashMap<>(genericParameterNames) : new HashMap<>();
311+
try {
312+
resolveGenericsHeader(node.getGenericsTypes());
308313

309-
resolveGenericsHeader(node.getGenericsTypes());
310-
311-
resolveOrFail(node.getReturnType(), node);
312-
for (Parameter p : node.getParameters()) {
313-
p.setInitialExpression(transform(p.getInitialExpression()));
314-
ClassNode t = p.getType();
315-
resolveOrFail(t, t);
316-
visitAnnotations(p);
317-
}
318-
if (node.getExceptions() != null) {
319-
for (ClassNode t : node.getExceptions()) {
314+
resolveOrFail(node.getReturnType(), node);
315+
for (Parameter p : node.getParameters()) {
316+
p.setInitialExpression(transform(p.getInitialExpression()));
317+
ClassNode t = p.getType();
320318
resolveOrFail(t, t);
319+
visitAnnotations(p);
320+
}
321+
if (node.getExceptions() != null) {
322+
for (ClassNode t : node.getExceptions()) {
323+
resolveOrFail(t, t);
324+
}
321325
}
322-
}
323-
324-
checkGenericsCyclicInheritance(node.getGenericsTypes());
325-
326-
MethodNode oldCurrentMethod = currentMethod;
327-
currentMethod = node;
328326

329-
super.visitConstructorOrMethod(node, isConstructor);
327+
checkGenericsCyclicInheritance(node.getGenericsTypes());
330328

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

336338
private void resolveOrFail(final ClassNode type, final ASTNode node) {
@@ -1047,7 +1049,7 @@ protected Expression transformVariableExpression(final VariableExpression ve) {
10471049
}
10481050

10491051
private static boolean testVanillaNameForClass(final String name) {
1050-
if (name == null || name.length() == 0) return false;
1052+
if (name == null || name.isEmpty()) return false;
10511053
return !Character.isLowerCase(name.charAt(0));
10521054
}
10531055

@@ -1229,106 +1231,110 @@ private void checkAnnotationMemberValue(final Expression value) {
12291231

12301232
@Override
12311233
public void visitClass(final ClassNode node) {
1232-
ClassNode oldNode = currentClass;
1233-
currentClass = node;
1234-
1235-
ModuleNode module = node.getModule();
1236-
if (!module.hasImportsResolved()) {
1237-
for (ImportNode importNode : module.getImports()) {
1238-
currentImport = importNode;
1239-
ClassNode type = importNode.getType();
1240-
if (resolve(type, false, false, true)) {
1241-
currentImport = null;
1242-
continue;
1243-
}
1244-
currentImport = null;
1245-
addError("unable to resolve class " + type.getName(), type);
1246-
}
1247-
for (ImportNode importNode : module.getStarImports()) {
1248-
if (importNode.getLineNumber() > 0) {
1234+
ClassNode oldNode = currentClass; currentClass = node;
1235+
Map<GenericsTypeName, GenericsType> outerNames = null;
1236+
try {
1237+
ModuleNode module = node.getModule();
1238+
if (!module.hasImportsResolved()) {
1239+
for (ImportNode importNode : module.getImports()) {
12491240
currentImport = importNode;
1250-
String importName = importNode.getPackageName();
1251-
importName = importName.substring(0, importName.length()-1);
1252-
ClassNode type = ClassHelper.makeWithoutCaching(importName);
1253-
if (resolve(type, false, false, true)) {
1254-
importNode.setType(type);
1241+
try {
1242+
ClassNode type = importNode.getType();
1243+
if (!resolve(type, false, false, true)) {
1244+
addError("unable to resolve class " + type.getName(), type);
1245+
}
1246+
} finally {
1247+
currentImport = null;
12551248
}
1256-
currentImport = null;
12571249
}
1258-
}
1259-
for (ImportNode importNode : module.getStaticImports().values()) {
1260-
ClassNode type = importNode.getType();
1261-
if (!resolve(type, true, true, true))
1262-
addError("unable to resolve class " + type.getName(), type);
1263-
}
1264-
for (ImportNode importNode : module.getStaticStarImports().values()) {
1265-
ClassNode type = importNode.getType();
1266-
if (!resolve(type, true, true, true))
1267-
addError("unable to resolve class " + type.getName(), type);
1268-
}
1250+
for (ImportNode importNode : module.getStarImports()) {
1251+
if (importNode.getLineNumber() > 0) {
1252+
currentImport = importNode;
1253+
try {
1254+
String importName = importNode.getPackageName();
1255+
importName = importName.substring(0, importName.length()-1);
1256+
ClassNode type = ClassHelper.makeWithoutCaching(importName);
1257+
if (resolve(type, false, false, true)) {
1258+
importNode.setType(type);
1259+
}
1260+
} finally {
1261+
currentImport = null;
1262+
}
1263+
}
1264+
}
1265+
for (ImportNode importNode : module.getStaticImports().values()) {
1266+
ClassNode type = importNode.getType();
1267+
if (!resolve(type, true, true, true))
1268+
addError("unable to resolve class " + type.getName(), type);
1269+
}
1270+
for (ImportNode importNode : module.getStaticStarImports().values()) {
1271+
ClassNode type = importNode.getType();
1272+
if (!resolve(type, true, true, true))
1273+
addError("unable to resolve class " + type.getName(), type);
1274+
}
12691275

1270-
module.setImportsResolved(true);
1271-
}
1276+
module.setImportsResolved(true);
1277+
}
12721278

1273-
//
1279+
//
12741280

1275-
Map<GenericsTypeName, GenericsType> outerNames = null;
1276-
if (node instanceof InnerClassNode) {
1277-
outerNames = genericParameterNames;
1278-
genericParameterNames = new HashMap<>();
1279-
if (!Modifier.isStatic(node.getModifiers()))
1280-
genericParameterNames.putAll(outerNames); // outer names visible
1281-
} else {
1282-
genericParameterNames.clear(); // outer class: new generic namespace
1283-
}
1284-
resolveGenericsHeader(node.getGenericsTypes());
1285-
switch (phase) { // GROOVY-9866, GROOVY-10466
1286-
case 0:
1287-
case 1:
1288-
ClassNode sn = node.getUnresolvedSuperClass();
1289-
if (sn != null) {
1290-
resolveOrFail(sn, "", node, true);
1291-
}
1292-
for (ClassNode in : node.getInterfaces()) {
1293-
resolveOrFail(in, "", node, true);
1281+
if (node instanceof InnerClassNode) {
1282+
outerNames = genericParameterNames;
1283+
genericParameterNames = new HashMap<>();
1284+
if (!Modifier.isStatic(node.getModifiers()))
1285+
genericParameterNames.putAll(outerNames); // outer names visible
1286+
} else {
1287+
genericParameterNames.clear(); // outer class: new generic namespace
12941288
}
1289+
resolveGenericsHeader(node.getGenericsTypes());
1290+
switch (phase) { // GROOVY-9866, GROOVY-10466
1291+
case 0:
1292+
case 1:
1293+
ClassNode sn = node.getUnresolvedSuperClass();
1294+
if (sn != null) {
1295+
resolveOrFail(sn, "", node, true);
1296+
}
1297+
for (ClassNode in : node.getInterfaces()) {
1298+
resolveOrFail(in, "", node, true);
1299+
}
12951300

1296-
if (sn != null) checkCyclicInheritance(node, sn);
1297-
for (ClassNode in : node.getInterfaces()) {
1298-
checkCyclicInheritance(node, in);
1299-
}
1300-
checkGenericsCyclicInheritance(node.getGenericsTypes());
1301-
case 2:
1302-
// VariableScopeVisitor visits anon. inner class body inline, so resolve now
1303-
for (Iterator<InnerClassNode> it = node.getInnerClasses(); it.hasNext(); ) {
1304-
InnerClassNode cn = it.next();
1305-
if (cn.isAnonymous()) {
1306-
MethodNode enclosingMethod = cn.getEnclosingMethod();
1307-
if (enclosingMethod != null) {
1308-
resolveGenericsHeader(enclosingMethod.getGenericsTypes()); // GROOVY-6977
1301+
if (sn != null) checkCyclicInheritance(node, sn);
1302+
for (ClassNode in : node.getInterfaces()) {
1303+
checkCyclicInheritance(node, in);
1304+
}
1305+
checkGenericsCyclicInheritance(node.getGenericsTypes());
1306+
case 2:
1307+
// VariableScopeVisitor visits anon. inner class body inline, so resolve now
1308+
for (Iterator<InnerClassNode> it = node.getInnerClasses(); it.hasNext(); ) {
1309+
InnerClassNode cn = it.next();
1310+
if (cn.isAnonymous()) {
1311+
MethodNode enclosingMethod = cn.getEnclosingMethod();
1312+
if (enclosingMethod != null) {
1313+
resolveGenericsHeader(enclosingMethod.getGenericsTypes()); // GROOVY-6977
1314+
}
1315+
resolveOrFail(cn.getUnresolvedSuperClass(false), cn); // GROOVY-9642
13091316
}
1310-
resolveOrFail(cn.getUnresolvedSuperClass(false), cn); // GROOVY-9642
13111317
}
1312-
}
1313-
if (phase == 1) break; // resolve other class headers before members, et al.
1318+
if (phase == 1) break; // resolve other class headers before members, et al.
13141319

1315-
// initialize scopes/variables now that imports and super types are resolved
1316-
new VariableScopeVisitor(source).visitClass(node);
1320+
// initialize scopes/variables now that imports and super types are resolved
1321+
new VariableScopeVisitor(source).visitClass(node);
13171322

1318-
visitPackage(node.getPackage());
1319-
visitImports(node.getModule());
1323+
visitPackage(node.getPackage());
1324+
visitImports(node.getModule());
13201325

1321-
node.visitContents(this);
1322-
visitObjectInitializerStatements(node);
1323-
visitAnnotations(node); // GROOVY-10750, GROOVY-11206
1326+
node.visitContents(this);
1327+
visitObjectInitializerStatements(node);
1328+
visitAnnotations(node); // GROOVY-10750, GROOVY-11206
1329+
}
1330+
} finally {
1331+
if (outerNames != null) genericParameterNames = outerNames;
1332+
currentClass = oldNode;
13241333
}
1325-
if (outerNames != null) genericParameterNames = outerNames;
1326-
currentClass = oldNode;
13271334
}
13281335

1329-
private void checkGenericsCyclicInheritance(GenericsType[] genericsTypes) {
1336+
private void checkGenericsCyclicInheritance(final GenericsType[] genericsTypes) {
13301337
if (genericsTypes == null) return;
1331-
13321338
for (GenericsType gt : genericsTypes) {
13331339
if (gt == null) continue;
13341340
ClassNode[] upperBounds = gt.getUpperBounds();
@@ -1390,8 +1396,11 @@ public void visitForLoop(final ForStatement forLoop) {
13901396
public void visitBlockStatement(final BlockStatement block) {
13911397
VariableScope oldScope = currentScope;
13921398
currentScope = block.getVariableScope();
1393-
super.visitBlockStatement(block);
1394-
currentScope = oldScope;
1399+
try {
1400+
super.visitBlockStatement(block);
1401+
} finally {
1402+
currentScope = oldScope;
1403+
}
13951404
}
13961405

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

0 commit comments

Comments
 (0)