Skip to content

Commit 2fa3794

Browse files
committed
GROOVY-9526, GROOVY-11719: pop field state on exception
1 parent f4cab49 commit 2fa3794

2 files changed

Lines changed: 183 additions & 139 deletions

File tree

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

Lines changed: 134 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -271,14 +271,15 @@ public void visitField(final FieldNode node) {
271271
if (!canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())) {
272272
genericParameterNames = Collections.emptyMap();
273273
}
274-
275-
if (!fieldTypesChecked.contains(node)) {
276-
ClassNode t = node.getOriginType();
277-
resolveOrFail(t, t);
274+
try {
275+
if (!fieldTypesChecked.contains(node)) {
276+
ClassNode t = node.getOriginType();
277+
resolveOrFail(t, t);
278+
}
279+
super.visitField(node);
280+
} finally {
281+
genericParameterNames = oldNames;
278282
}
279-
super.visitField(node);
280-
281-
genericParameterNames = oldNames;
282283
}
283284

284285
@Override
@@ -287,14 +288,15 @@ public void visitProperty(final PropertyNode node) {
287288
if (!canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())) {
288289
genericParameterNames = Collections.emptyMap();
289290
}
291+
try {
292+
ClassNode t = node.getOriginType();
293+
resolveOrFail(t, t);
294+
fieldTypesChecked.add(node.getField());
290295

291-
ClassNode t = node.getOriginType();
292-
resolveOrFail(t, t);
293-
fieldTypesChecked.add(node.getField());
294-
295-
super.visitProperty(node);
296-
297-
genericParameterNames = oldNames;
296+
super.visitProperty(node);
297+
} finally {
298+
genericParameterNames = oldNames;
299+
}
298300
}
299301

300302
private static boolean canSeeTypeVars(final int mods, final ClassNode node) {
@@ -303,39 +305,39 @@ private static boolean canSeeTypeVars(final int mods, final ClassNode node) {
303305

304306
@Override
305307
protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) {
308+
MethodNode oldMethod = currentMethod;
306309
VariableScope oldScope = currentScope;
307310
currentScope = node.getVariableScope();
308311
Map<GenericsTypeName, GenericsType> oldNames = genericParameterNames;
309312
genericParameterNames =
310313
canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())
311314
? new HashMap<>(genericParameterNames) : new HashMap<>();
315+
try {
316+
resolveGenericsHeader(node.getGenericsTypes());
312317

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

336-
currentMethod = oldCurrentMethod;
337-
genericParameterNames = oldNames;
338-
currentScope = oldScope;
334+
currentMethod = node;
335+
super.visitConstructorOrMethod(node, isConstructor);
336+
} finally {
337+
genericParameterNames = oldNames;
338+
currentMethod = oldMethod;
339+
currentScope = oldScope;
340+
}
339341
}
340342

341343
private void resolveOrFail(final ClassNode type, final ASTNode node) {
@@ -1249,107 +1251,112 @@ private void checkAnnotationMemberValue(final Expression value) {
12491251

12501252
@Override
12511253
public void visitClass(final ClassNode node) {
1252-
ClassNode oldNode = currentClass;
1253-
currentClass = node;
1254-
1255-
ModuleNode module = node.getModule();
1256-
if (!module.hasImportsResolved()) {
1257-
for (ImportNode importNode : module.getImports()) {
1258-
currentImport = importNode;
1259-
ClassNode type = importNode.getType();
1260-
if (resolve(type, false, false, true)) {
1261-
currentImport = null;
1262-
continue;
1263-
}
1264-
currentImport = null;
1265-
addError("unable to resolve class " + type.getName(), type);
1266-
}
1267-
for (ImportNode importNode : module.getStarImports()) {
1268-
if (importNode.getLineNumber() > 0) {
1254+
ClassNode oldNode = currentClass; currentClass = node;
1255+
Map<GenericsTypeName, GenericsType> outerNames = null;
1256+
try {
1257+
ModuleNode module = node.getModule();
1258+
if (!module.hasImportsResolved()) {
1259+
for (ImportNode importNode : module.getImports()) {
12691260
currentImport = importNode;
1270-
String importName = importNode.getPackageName();
1271-
importName = importName.substring(0, importName.length()-1);
1272-
ClassNode type = ClassHelper.makeWithoutCaching(importName);
1273-
if (resolve(type, false, false, true)) {
1274-
importNode.setType(type);
1261+
try {
1262+
ClassNode type = importNode.getType();
1263+
if (!resolve(type, false, false, true)) {
1264+
addError("unable to resolve class " + type.getName(), type);
1265+
}
1266+
} finally {
1267+
currentImport = null;
12751268
}
1276-
currentImport = null;
12771269
}
1278-
}
1279-
for (ImportNode importNode : module.getStaticImports().values()) {
1280-
ClassNode type = importNode.getType();
1281-
if (!resolve(type, true, true, true))
1282-
addError("unable to resolve class " + type.getName(), type);
1283-
}
1284-
for (ImportNode importNode : module.getStaticStarImports().values()) {
1285-
ClassNode type = importNode.getType();
1286-
if (!resolve(type, true, true, true))
1287-
addError("unable to resolve class " + type.getName(), type);
1288-
}
1270+
for (ImportNode importNode : module.getStarImports()) {
1271+
if (importNode.getLineNumber() > 0) {
1272+
currentImport = importNode;
1273+
try {
1274+
String importName = importNode.getPackageName();
1275+
importName = importName.substring(0, importName.length()-1);
1276+
ClassNode type = ClassHelper.makeWithoutCaching(importName);
1277+
if (resolve(type, false, false, true)) {
1278+
importNode.setType(type);
1279+
}
1280+
} finally {
1281+
currentImport = null;
1282+
}
1283+
}
1284+
}
1285+
for (ImportNode importNode : module.getStaticImports().values()) {
1286+
ClassNode type = importNode.getType();
1287+
if (!resolve(type, true, true, true))
1288+
addError("unable to resolve class " + type.getName(), type);
1289+
}
1290+
for (ImportNode importNode : module.getStaticStarImports().values()) {
1291+
ClassNode type = importNode.getType();
1292+
if (!resolve(type, true, true, true))
1293+
addError("unable to resolve class " + type.getName(), type);
1294+
}
12891295

1290-
module.setImportsResolved(true);
1291-
}
1296+
module.setImportsResolved(true);
1297+
}
12921298

1293-
//
1299+
//
12941300

1295-
if (phase < 2) node.putNodeMetaData(AnnotationNode[].class, new LinkedHashSet<>());
1301+
if (phase < 2) node.putNodeMetaData(AnnotationNode[].class, new LinkedHashSet<>());
12961302

1297-
Map<GenericsTypeName, GenericsType> outerNames = null;
1298-
if (node instanceof InnerClassNode) {
1299-
outerNames = genericParameterNames;
1300-
genericParameterNames = new HashMap<>();
1301-
if (!Modifier.isStatic(node.getModifiers()))
1302-
genericParameterNames.putAll(outerNames); // outer names visible
1303-
} else {
1304-
genericParameterNames.clear(); // outer class: new generic namespace
1305-
}
1306-
resolveGenericsHeader(node.getGenericsTypes());
1307-
switch (phase) { // GROOVY-9866, GROOVY-10466
1308-
case 0:
1309-
case 1:
1310-
ClassNode sn = node.getUnresolvedSuperClass();
1311-
if (sn != null) {
1312-
resolveOrFail(sn, "", node, true);
1313-
}
1314-
for (ClassNode in : node.getInterfaces()) {
1315-
resolveOrFail(in, "", node, true);
1303+
if (node instanceof InnerClassNode) {
1304+
outerNames = genericParameterNames;
1305+
genericParameterNames = new HashMap<>();
1306+
if (!Modifier.isStatic(node.getModifiers()))
1307+
genericParameterNames.putAll(outerNames); // outer names visible
1308+
} else {
1309+
genericParameterNames.clear(); // outer class: new generic namespace
13161310
}
1311+
resolveGenericsHeader(node.getGenericsTypes());
1312+
switch (phase) { // GROOVY-9866, GROOVY-10466
1313+
case 0:
1314+
case 1:
1315+
ClassNode sn = node.getUnresolvedSuperClass();
1316+
if (sn != null) {
1317+
resolveOrFail(sn, "", node, true);
1318+
}
1319+
for (ClassNode in : node.getInterfaces()) {
1320+
resolveOrFail(in, "", node, true);
1321+
}
13171322

1318-
if (sn != null) checkCyclicInheritance(node, sn);
1319-
for (ClassNode in : node.getInterfaces()) {
1320-
checkCyclicInheritance(node, in);
1321-
}
1322-
case 2:
1323-
// VariableScopeVisitor visits anon. inner class body inline, so resolve now
1324-
for (Iterator<InnerClassNode> it = node.getInnerClasses(); it.hasNext(); ) {
1325-
InnerClassNode cn = it.next();
1326-
if (cn.isAnonymous()) {
1327-
MethodNode enclosingMethod = cn.getEnclosingMethod();
1328-
if (enclosingMethod != null) {
1329-
resolveGenericsHeader(enclosingMethod.getGenericsTypes()); // GROOVY-6977
1323+
if (sn != null) checkCyclicInheritance(node, sn);
1324+
for (ClassNode in : node.getInterfaces()) {
1325+
checkCyclicInheritance(node, in);
1326+
}
1327+
case 2:
1328+
// VariableScopeVisitor visits anon. inner class body inline, so resolve now
1329+
for (Iterator<InnerClassNode> it = node.getInnerClasses(); it.hasNext(); ) {
1330+
InnerClassNode cn = it.next();
1331+
if (cn.isAnonymous()) {
1332+
MethodNode enclosingMethod = cn.getEnclosingMethod();
1333+
if (enclosingMethod != null) {
1334+
resolveGenericsHeader(enclosingMethod.getGenericsTypes()); // GROOVY-6977
1335+
}
1336+
resolveOrFail(cn.getUnresolvedSuperClass(false), cn); // GROOVY-9642
13301337
}
1331-
resolveOrFail(cn.getUnresolvedSuperClass(false), cn); // GROOVY-9642
13321338
}
1333-
}
1334-
if (phase == 1) break; // resolve other class headers before members, et al.
1339+
if (phase == 1) break; // resolve other class headers before members, et al.
13351340

1336-
// initialize scopes/variables now that imports and super types are resolved
1337-
new VariableScopeVisitor(source).visitClass(node);
1341+
// initialize scopes/variables now that imports and super types are resolved
1342+
new VariableScopeVisitor(source).visitClass(node);
13381343

1339-
visitPackage(node.getPackage());
1340-
visitImports(node.getModule());
1341-
visitAnnotations(node);
1344+
visitPackage(node.getPackage());
1345+
visitImports(node.getModule());
1346+
visitAnnotations(node);
13421347

1343-
@SuppressWarnings("unchecked") // grab the collected annotations and stop collecting
1344-
var headerAnnotations = (Set<AnnotationNode>) node.putNodeMetaData(AnnotationNode[].class, null);
1348+
@SuppressWarnings("unchecked") // grab the collected annotations and stop collecting
1349+
var headerAnnotations = (Set<AnnotationNode>) node.putNodeMetaData(AnnotationNode[].class, null);
13451350

1346-
node.visitContents(this);
1347-
visitObjectInitializerStatements(node);
1348-
// GROOVY-10750, GROOVY-11179: resolve and inline
1349-
headerAnnotations.forEach(this::visitAnnotation);
1351+
node.visitContents(this);
1352+
visitObjectInitializerStatements(node);
1353+
// GROOVY-10750, GROOVY-11179: resolve and inline
1354+
headerAnnotations.forEach(this::visitAnnotation);
1355+
}
1356+
} finally {
1357+
if (outerNames != null) genericParameterNames = outerNames;
1358+
currentClass = oldNode;
13501359
}
1351-
if (outerNames != null) genericParameterNames = outerNames;
1352-
currentClass = oldNode;
13531360
}
13541361

13551362
private void addFatalError(final String text, final ASTNode node) {
@@ -1401,8 +1408,11 @@ public void visitForLoop(final ForStatement forLoop) {
14011408
public void visitBlockStatement(final BlockStatement block) {
14021409
VariableScope oldScope = currentScope;
14031410
currentScope = block.getVariableScope();
1404-
super.visitBlockStatement(block);
1405-
currentScope = oldScope;
1411+
try {
1412+
super.visitBlockStatement(block);
1413+
} finally {
1414+
currentScope = oldScope;
1415+
}
14061416
}
14071417

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

0 commit comments

Comments
 (0)