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;
}
}