@@ -100,6 +100,12 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th
100100
101101 // Consider which variables are captured from the outer scope
102102 val stmtBlockAst = if (isClosure || isSingletonObjectMethod) {
103+ // create closure local used for capturing
104+ createClosureBindingInformation(scope.lookupSelfInOuterScope.toSet)
105+ .collect { case (_, name, _, Some (closureBindingId)) =>
106+ val capturingLocal = localNode(node.body, name, name, Defines .Any , closureBindingId = Option (closureBindingId))
107+ scope.addToScope(capturingLocal.name, capturingLocal)
108+ }
103109 val baseStmtBlockAst = astForMethodBody(node.body, optionalStatementList)
104110 transformAsClosureBody(node.body, refs, baseStmtBlockAst)
105111 } else {
@@ -214,22 +220,25 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th
214220 private def transformAsClosureBody (originNode : RubyExpression , refs : List [Ast ], baseStmtBlockAst : Ast ) = {
215221 // Determine which locals are captured
216222 val capturedLocalNodes = baseStmtBlockAst.nodes
217- .collect { case x : NewIdentifier => x }
223+ .collect { case x : NewIdentifier if x.name != Defines . Self => x }
218224 .distinctBy(_.name)
219225 .map {
220- case i if i.name == " self " => scope.lookupSelfInOuterScope // we only need to bind to the closest self in scope
221- case i => scope.lookupVariableInOuterScope(i.name)
226+ case i if i.name == Defines . Self => scope.lookupSelfInOuterScope
227+ case i => scope.lookupVariableInOuterScope(i.name)
222228 }
223229 .filter(_.iterator.nonEmpty)
224230 .flatten
225231 .toSet
226232
233+ val selfLocal = scope.lookupSelfInOuterScope.toSet
234+ val capturedNodes = capturedLocalNodes ++ selfLocal
235+
227236 val capturedIdentifiers = baseStmtBlockAst.nodes.collect {
228- case i : NewIdentifier if capturedLocalNodes .map(_.name).contains(i.name) => i
237+ case i : NewIdentifier if capturedNodes .map(_.name).contains(i.name) => i
229238 }
230239 // Copy AST block detaching the REF nodes between parent locals/params and identifiers, with the closures' one
231240 val capturedBlockAst = baseStmtBlockAst.copy(refEdges = baseStmtBlockAst.refEdges.filterNot {
232- case AstEdge (_ : NewIdentifier , dst : DeclarationNew ) => capturedLocalNodes .contains(dst)
241+ case AstEdge (_ : NewIdentifier , dst : DeclarationNew ) => capturedNodes .contains(dst)
233242 case _ => false
234243 })
235244
@@ -238,15 +247,8 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th
238247 val astChildren = mutable.Buffer .empty[NewNode ]
239248 val refEdges = mutable.Buffer .empty[(NewNode , NewNode )]
240249 val captureEdges = mutable.Buffer .empty[(NewNode , NewNode )]
241- capturedLocalNodes
242- .collect {
243- case local : NewLocal =>
244- val closureBindingId = scope.variableScopeFullName(local.name).map(x => s " $x. ${local.name}" )
245- (local, local.name, local.code, closureBindingId)
246- case param : NewMethodParameterIn =>
247- val closureBindingId = scope.variableScopeFullName(param.name).map(x => s " $x. ${param.name}" )
248- (param, param.name, param.code, closureBindingId)
249- }
250+
251+ createClosureBindingInformation(capturedNodes)
250252 .collect { case (capturedLocal, name, code, Some (closureBindingId)) =>
251253 val capturingLocal =
252254 localNode(originNode, name, name, Defines .Any , closureBindingId = Option (closureBindingId))
@@ -624,4 +626,16 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th
624626 case _ => false
625627 }
626628 }
629+
630+ private def createClosureBindingInformation (capturedNodes : Set [DeclarationNew ]): Set [(DeclarationNew , String , String , Option [String ])] = {
631+ capturedNodes
632+ .collect {
633+ case local : NewLocal =>
634+ val closureBindingId = scope.variableScopeFullName(local.name).map(x => s " $x. ${local.name}" )
635+ (local, local.name, local.code, closureBindingId)
636+ case param : NewMethodParameterIn =>
637+ val closureBindingId = scope.variableScopeFullName(param.name).map(x => s " $x. ${param.name}" )
638+ (param, param.name, param.code, closureBindingId)
639+ }
640+ }
627641}
0 commit comments