@@ -20,6 +20,8 @@ import grails.compiler.DelegatingMethod
2020import grails.transaction.Rollback
2121import groovy.transform.TypeChecked
2222import org.codehaus.groovy.ast.stmt.Statement
23+ import org.codehaus.groovy.classgen.VariableScopeVisitor
24+ import org.codehaus.groovy.control.ErrorCollector
2325import org.springframework.beans.factory.annotation.Autowired
2426import org.springframework.beans.factory.annotation.Qualifier
2527import org.springframework.transaction.annotation.Propagation
@@ -292,14 +294,26 @@ class TransactionalTransform implements ASTTransformation{
292294 final transactionStatusParameter = new Parameter (ClassHelper . make(TransactionStatus ), " transactionStatus" )
293295 def newParameters = methodNode. getParameters() ? (copyParameters(((methodNode. getParameters() as List ) + [transactionStatusParameter]) as Parameter [])) : [transactionStatusParameter] as Parameter []
294296
297+
298+ def body = methodNode. code
295299 MethodNode renamedMethodNode = new MethodNode (
296300 renamedMethodName,
297301 Modifier . PROTECTED , methodNode. getReturnType(). getPlainNodeReference(),
298302 newParameters,
299303 GrailsArtefactClassInjector . EMPTY_CLASS_ARRAY ,
300- methodNode . code
304+ body
301305 );
302306
307+
308+ def newVariableScope = new VariableScope ()
309+ for (p in newParameters) {
310+ newVariableScope. putDeclaredVariable(p)
311+ }
312+
313+ renamedMethodNode. setVariableScope(
314+ newVariableScope
315+ )
316+
303317 // GrailsCompileStatic and GrailsTypeChecked are not explicitly addressed
304318 // here but they will be picked up because they are @AnnotationCollector annotations
305319 // which use CompileStatic and TypeChecked...
@@ -309,14 +323,19 @@ class TransactionalTransform implements ASTTransformation{
309323 methodNode. setCode(null )
310324 classNode. addMethod(renamedMethodNode)
311325
312- if ( ! isSpockTest(classNode) ) {
313- processVariableScopes(source, classNode, renamedMethodNode)
326+ // Use a dummy source unit to process the variable scopes to avoid the issue where this is run twice producing an error
327+ VariableScopeVisitor scopeVisitor = new VariableScopeVisitor (new SourceUnit (" dummy" , " dummy" , source. getConfiguration(), source. getClassLoader(), new ErrorCollector (source. getConfiguration())));
328+ if (methodNode == null ) {
329+ scopeVisitor. visitClass(classNode);
330+ } else {
331+ scopeVisitor. prepareVisit(classNode);
332+ scopeVisitor. visitMethod(renamedMethodNode);
314333 }
315334
316335 final originalMethodCall = new MethodCallExpression (new VariableExpression (" this" ), renamedMethodName, new ArgumentListExpression (renamedMethodNode. parameters))
317336 originalMethodCall. setImplicitThis(false )
318337 originalMethodCall. setMethodTarget(renamedMethodNode)
319-
338+
320339 originalMethodCall
321340 }
322341
0 commit comments