You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2017/04/07 13:30:55 UTC
[12/50] [abbrv] groovy git commit: GROOVY-7248:
MissingPropertyException: No such property in finally block (closes #501)
GROOVY-7248: MissingPropertyException: No such property in finally block (closes #501)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/d5169447
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/d5169447
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/d5169447
Branch: refs/heads/parrot
Commit: d51694473e921c7360061f6a4bfe876ea6a401cf
Parents: b32ce96
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Mar 5 10:39:38 2017 -0800
Committer: John Wagenleitner <jw...@apache.org>
Committed: Thu Mar 9 05:18:29 2017 -0800
----------------------------------------------------------------------
.../classgen/asm/OptimizingStatementWriter.java | 18 +++++-
src/test/groovy/bugs/Groovy7248Bug.groovy | 67 ++++++++++++++++++++
2 files changed, 83 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/d5169447/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java b/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
index 134600d..8696637 100644
--- a/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
+++ b/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
@@ -55,6 +55,7 @@ public class OptimizingStatementWriter extends StatementWriter {
private boolean optimize=false;
protected MethodNode target;
protected ClassNode type;
+ protected VariableExpression declaredVariableExpression;
protected boolean[] involvedTypes = new boolean[typeMapKeyNames.length];
public void chainInvolvedTypes(OptimizeFlagsCollector opt) {
for (int i=0; i<typeMapKeyNames.length; i++) {
@@ -304,6 +305,10 @@ public class OptimizingStatementWriter extends StatementWriter {
} else {
StatementMeta meta = (StatementMeta) statement.getNodeMetaData(StatementMeta.class);
if (isNewPathFork(meta) && writeDeclarationExtraction(statement)) {
+ if (meta.declaredVariableExpression != null) {
+ // declaration was replaced by assignment so we need to define the variable
+ controller.getCompileStack().defineVariable(meta.declaredVariableExpression, false);
+ }
FastPathData fastPathData = writeGuards(meta, statement);
boolean oldFastPathBlock = fastPathBlocked;
@@ -342,6 +347,10 @@ public class OptimizingStatementWriter extends StatementWriter {
// the only case we need to handle is then (2).
if (isNewPathFork(meta) && writeDeclarationExtraction(statement)) {
+ if (meta.declaredVariableExpression != null) {
+ // declaration was replaced by assignment so we need to define the variable
+ controller.getCompileStack().defineVariable(meta.declaredVariableExpression, false);
+ }
FastPathData fastPathData = writeGuards(meta, statement);
boolean oldFastPathBlock = fastPathBlocked;
@@ -375,8 +384,13 @@ public class OptimizingStatementWriter extends StatementWriter {
ex = declaration.getLeftExpression();
if (ex instanceof TupleExpression) return false;
- // do declaration
- controller.getCompileStack().defineVariable(declaration.getVariableExpression(), false);
+ // stash declared variable in case we do subsequent visits after we
+ // change to assignment only
+ StatementMeta meta = statement.getNodeMetaData(StatementMeta.class);
+ if (meta != null) {
+ meta.declaredVariableExpression = declaration.getVariableExpression();
+ }
+
// change statement to do assignment only
BinaryExpression assignment = new BinaryExpression(
declaration.getLeftExpression(),
http://git-wip-us.apache.org/repos/asf/groovy/blob/d5169447/src/test/groovy/bugs/Groovy7248Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy7248Bug.groovy b/src/test/groovy/bugs/Groovy7248Bug.groovy
new file mode 100644
index 0000000..b8057fb
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy7248Bug.groovy
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package groovy.bugs
+
+/**
+ * StatementWriter.writeTryCatchFinally visits the finally block
+ * twice, once for the normal path and once again for the "catch all"
+ * path. When the OptimizingStatementWriter is used DeclarationExpressions
+ * are rewritten to BinaryExpressions to allow splitting between fast and
+ * slow paths. Because the expression is modified variable declarations
+ * are lost if the statement is visited more than once.
+ *
+ * This is not a problem for scripts because the property call that is
+ * generated will succeed because of the script context. So to reproduce
+ * the issue it must be contained in a class.
+ */
+class Groovy7248Bug extends GroovyTestCase {
+
+ void testFinallyDeclaredVariableExpression() {
+ assertScript '''
+ class Test {
+ long run() {
+ long dur = 0
+ long start = 0
+ try {
+ start++
+ } finally {
+ long end = 2
+ long time = end - start
+ dur = time
+ }
+ dur
+ }
+ }
+ assert new Test().run() == 1
+ '''
+ }
+
+ void testReturnStatementDeclaration() {
+ assertScript '''
+ class Foo {
+ int test() {
+ int x = 2
+ int y = x - 1
+ }
+ }
+ assert new Foo().test() == 1
+ '''
+ }
+
+}