This is an automated email from the ASF dual-hosted git repository.

joshtynjala pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-compiler.git


The following commit(s) were added to refs/heads/develop by this push:
     new 2454b69c7 FunctionNode: remove existing definitions from scope 
immediately before adding new definitions for parsed function body (references 
#249)
2454b69c7 is described below

commit 2454b69c710823e5be79f97f97770662a2b45c3d
Author: Josh Tynjala <[email protected]>
AuthorDate: Thu Jun 18 15:21:24 2026 -0700

    FunctionNode: remove existing definitions from scope immediately before 
adding new definitions for parsed function body (references #249)
    
    Followup to bad8386b0555df1b6304cec79267d67ce56bc32f and 
35eed62f13519c659e6346d26cca3f44afe3170f
    
    Removing the definitions in analyze() when hasBeenParsed() is false, 
instead of in parseFunctionBody() before post processing still resulted in 
weird states where a scope might not contain any non-parameter local 
definitions. This change basically avoids removing any definitions unless those 
definitions are guaranteed to be immediately replaced because the function body 
is in the process of being re-parsed. This seems to fix the original assertion 
failure, and also seems to prevent sc [...]
---
 .../compiler/internal/tree/as/FunctionNode.java    | 54 ++++++----------------
 1 file changed, 15 insertions(+), 39 deletions(-)

diff --git 
a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FunctionNode.java
 
b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FunctionNode.java
index f003f154b..0f6ab96af 100644
--- 
a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FunctionNode.java
+++ 
b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/FunctionNode.java
@@ -278,44 +278,7 @@ public class FunctionNode extends BaseTypedDefinitionNode 
implements IFunctionNo
                 // getters and setters
                 if (contents != null && scope != null)
                 {
-                    deferredBodyParsingLock.lock();
-                    try
-                    {
-                        // the compiler holds weak references to nodes in 
certain places
-                        // which allows them to be garbage collected. however, 
from time
-                        // to time, the compiler may need the node again 
later, after it
-                        // has been garbage collected, so that node needs to be
-                        // recreated.
-                        // when a function node is recreated, its scope may 
still be
-                        // populated with definitions from the old function 
node's body,
-                        // such as local variables. upon recreation, those 
local
-                        // definitions should be considered invalid because 
they will
-                        // be replaced with new definitions after parsing the 
new
-                        // function node's body.
-                        // to reiterate, removing the definitions below is not 
the same
-                        // case where a function node's discardFunctionBody() 
method is
-                        // called and the local definitions need to be 
removed. instead,
-                        // this is a separate case where a function node is 
garbage
-                        // collected and the body was never discarded, so the 
scope
-                        // still contains definitions from the old function 
node.
-                        if (!hasBeenParsed())
-                        {
-                            Collection<IDefinition> localDefs = 
scope.getAllLocalDefinitions();
-                            for (IDefinition def : localDefs)
-                            {
-                                if (! (def instanceof IParameterDefinition))
-                                {
-                                    scope.removeDefinition(def);
-                                }
-                            }
-                        }
-
-                        contents.reconnectScope(scope);
-                    }
-                    finally
-                    {
-                        deferredBodyParsingLock.unlock();
-                    }
+                    contents.reconnectScope(scope);
                 }
             }
         }
@@ -909,6 +872,19 @@ public class FunctionNode extends BaseTypedDefinitionNode 
implements IFunctionNo
                     sourceReader.skip(openT.getLocalEnd());
                 }
 
+                // if any non-parameter definitions already exist in this 
scope,
+                // remove them all because the freshly parsed function body 
will
+                // require new definitions to replace them.
+                ASScope asScope = contents.getASScope();
+                Collection<IDefinition> localDefs = 
asScope.getAllLocalDefinitions();
+                for (IDefinition def : localDefs)
+                {
+                    if (! (def instanceof IParameterDefinition))
+                    {
+                        asScope.removeDefinition(def);
+                    }
+                }
+
                 assert !anyNonParametersInScope(contents);
                 
                 // rebuild function body AST
@@ -944,7 +920,7 @@ public class FunctionNode extends BaseTypedDefinitionNode 
implements IFunctionNo
                     PostProcessStep.POPULATE_SCOPE,
                     PostProcessStep.RECONNECT_DEFINITIONS);
                 
-                problems.addAll(contents.runPostProcess(postProcess, 
contents.getASScope()));
+                problems.addAll(contents.runPostProcess(postProcess, asScope));
                 
                 // add implicit "arguments" argument to the local scope
                 tryAddDefaultArgument();

Reply via email to