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

gregdove 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 bbb47bc  Fix for #191. And related improvement in compiler-jx code for 
Multi-Catch support.
bbb47bc is described below

commit bbb47bca49238215c68d83e77d8fd4a4f375efaa
Author: greg-dove <[email protected]>
AuthorDate: Tue Jan 4 14:55:17 2022 +1300

    Fix for #191. And related improvement in compiler-jx code for Multi-Catch 
support.
---
 .../internal/codegen/js/jx/TryEmitter.java         | 45 +++++++++++++++++--
 .../compiler/internal/scopes/CatchScope.java       | 52 +++++++++++++++++++++-
 2 files changed, 91 insertions(+), 6 deletions(-)

diff --git 
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/TryEmitter.java
 
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/TryEmitter.java
index 39cdfb5..3665b4e 100644
--- 
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/TryEmitter.java
+++ 
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/TryEmitter.java
@@ -24,6 +24,7 @@ import org.apache.royale.compiler.codegen.js.IJSEmitter;
 import org.apache.royale.compiler.constants.IASLanguageConstants;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.royale.compiler.internal.definitions.VariableDefinition;
 import org.apache.royale.compiler.internal.parsing.as.ASToken;
 import org.apache.royale.compiler.internal.parsing.as.ASTokenTypes;
 import org.apache.royale.compiler.internal.scopes.ASScope;
@@ -160,7 +161,7 @@ public class TryEmitter extends JSSubEmitter implements
         name.setSourceLocation(parameterNode.getNameExpressionNode());
         ExpressionNodeBase type = 
parameterNode.getTypeNode().copyForInitializer(originalCatch);
         
-        VariableNode varNode = new VariableNode(name,type);
+        VariableNode varNode = new ReplacementCatchParam(name,type);
         varNode.setAssignedValue(null, assignedValue);
 
         content.addChild(varNode);
@@ -178,7 +179,6 @@ public class TryEmitter extends JSSubEmitter implements
         check.setParent(conditionalNode);
 
         addVarStartToRewrittenCatch(parameterNode, hoistedError, 
conditionalNode, (PseudoCatchBlock)conditionalNode.getContentsNode(), 
originalCatch );
-
         return conditionalNode;
     }
 
@@ -219,8 +219,9 @@ public class TryEmitter extends JSSubEmitter implements
 
 
 /**
- * The following mainly exists because the original catch scope allows for 
multiple 'same name' catch parameter definitions
- * that would otherwise clash if they were hoisted to the containing scope.
+ * The following mainly exists because the original catch scope allows for 
multiple 'same name' catch parameter definitions,
+ * when considered from within the containing scope of the catch clauses.
+ * Those names would otherwise clash if they were hoisted to the containing 
scope.
  * This serves to simulate the same thing for the rewritten catch parameter 
definitions.
  */
 class PseudoCatchBlock extends BlockNode implements IScopedNode {
@@ -283,3 +284,39 @@ class PseudoCatchAllParam extends TerminalNode{
         this.contentsNode = new PseudoCatchBlock(scope);
     }
 }
+
+class ReplacementCatchParam extends VariableNode{
+
+
+    public ReplacementCatchParam(IdentifierNode nameNode, ExpressionNodeBase 
typeNode) {
+        super(nameNode, typeNode);
+    }
+
+
+    @Override
+    protected void analyze(EnumSet<PostProcessStep> set, ASScope scope, 
Collection<ICompilerProblem> problems)
+    {
+        if (set.contains(PostProcessStep.POPULATE_SCOPE))
+        {
+
+            String definitionName = ((IdentifierNode) nameNode).getName();
+
+            VariableDefinition definition =
+                    new VariableDefinition(definitionName);
+
+            fillinDefinition(definition);
+
+            definition.setDeclaredInControlFlow(true);
+
+            definition.setInitializer(this.getAssignedValueNode());
+
+            setDefinition(definition);
+            ((CatchScope) scope).displaceParameter(definition);
+            //don't run the super's POPULATE_SCOPE:
+            set = set.clone();
+            set.remove(PostProcessStep.POPULATE_SCOPE);
+        }
+
+        super.analyze(set, scope, problems);
+    }
+}
diff --git 
a/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/CatchScope.java
 
b/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/CatchScope.java
index 56b5f62..cb62f2a 100644
--- 
a/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/CatchScope.java
+++ 
b/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/CatchScope.java
@@ -19,13 +19,16 @@
 
 package org.apache.royale.compiler.internal.scopes;
 
+import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.definitions.IParameterDefinition;
-import org.apache.royale.compiler.scopes.IASScope;
+import org.apache.royale.compiler.scopes.IDefinitionSet;
+
+import java.util.Objects;
 
 /**
  * {@link ASScope} subclass for Catch block scopes.
  */
-public final class CatchScope extends NoDefinitionScope implements IASScope
+public final class CatchScope extends NoDefinitionScope
 {
     /**
      * 
@@ -44,5 +47,50 @@ public final class CatchScope extends NoDefinitionScope 
implements IASScope
     public void setParameterDefinition(IParameterDefinition param)
     {
         this.addDefinitionToThisScope(param);
+        parameterDefinition = param;
+    }
+
+    private IParameterDefinition parameterDefinition;
+
+    @Override
+    public void addDefinition(IDefinition d)
+    {
+        if (Objects.equals(d.getBaseName(), 
parameterDefinition.getBaseName())) {
+            //this should ensure that declarations inside a catch clause that 
conflict with the parameter definition (i.e. create ambiguity) cause a compiler 
error
+            this.addDefinitionToThisScope(d);
+        } else {
+            super.addDefinition(d);
+        }
+    }
+
+
+    /**
+     * Advanced use only
+     * Used only for implementations that require 're-writing' of the default 
behavior (for example in runtimes that don't
+     * have native support for multiple catch clauses).
+     * This removes a potential conflicting name definition from the local 
catch scope (which is usually only reserved for the
+     * parameter definition).
+     * @param d
+     */
+    public void displaceParameter(IDefinition d)
+    {
+        this.removeDefinition(parameterDefinition);
+        this.addDefinitionToThisScope(d);
+    }
+
+
+    @Override
+    public IDefinitionSet getLocalDefinitionSetByName(String baseName)
+    {
+        //overrides the base class to return baseName definition(s) from the 
local set when the catch param is being requested, otherwise get the 
definitions from the containing scope.
+        IDefinitionSet returnSet;
+        IDefinitionSet localSet = super.getLocalDefinitionSetByName(baseName);
+        if (localSet != null && !localSet.isEmpty()) {
+            returnSet = localSet;
+        } else {
+            returnSet = 
getContainingScope().getLocalDefinitionSetByName(baseName);
+        }
+
+        return returnSet;
     }
 }

Reply via email to