You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by ah...@apache.org on 2018/10/29 17:41:25 UTC
[royale-compiler] 01/02: add checks for conflicting definitions and
add -allow-private-name-conflicts option. This required adjusting the
externs since they had conflicting definitions
This is an automated email from the ASF dual-hosted git repository.
aharui pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-compiler.git
commit 97dc7275c398d86bec6186e02e973ce0e49011bc
Author: Alex Harui <ah...@apache.org>
AuthorDate: Mon Oct 29 00:18:20 2018 -0700
add checks for conflicting definitions and add -allow-private-name-conflicts option. This required adjusting the externs since they had conflicting definitions
---
.../royale/compiler/config/Configuration.java | 25 ++++++++++++++
.../royale/compiler/projects/ICompilerProject.java | 5 +++
.../src/test/config/externc-config.xml | 28 ++++++++++++++++
.../codegen/typedefs/TypedefsTestUtils.java | 7 ++++
.../royale/compiler/codegen/js/IJSEmitter.java | 1 +
.../compiler/internal/codegen/js/JSEmitter.java | 6 ++++
.../internal/codegen/js/jx/ClassEmitter.java | 6 +++-
.../internal/codegen/js/jx/FieldEmitter.java | 6 +++-
.../internal/codegen/js/jx/IdentifierEmitter.java | 6 +++-
.../codegen/js/royale/JSRoyaleEmitter.java | 8 +++--
.../internal/definitions/FunctionDefinition.java | 28 +++++++++++++++-
.../internal/parsing/as/ConfigProcessor.java | 6 ++++
.../compiler/internal/projects/ASCProject.java | 6 ++++
.../compiler/internal/projects/RoyaleProject.java | 15 +++++++++
.../projects/RoyaleProjectConfigurator.java | 1 +
.../problems/ConflictingDefinitionProblem.java | 38 ++++++++++------------
16 files changed, 166 insertions(+), 26 deletions(-)
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/config/Configuration.java b/compiler-common/src/main/java/org/apache/royale/compiler/config/Configuration.java
index 40433c9..85f779f 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/config/Configuration.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/config/Configuration.java
@@ -1460,6 +1460,31 @@ public class Configuration
}
//
+ // 'compiler.allow-private-name-conflicts' option
+ //
+
+ private boolean allowPrivateNameConflicts = true;
+
+ public boolean getCompilerAllowPrivateNameConflicts()
+ {
+ return allowPrivateNameConflicts;
+ }
+
+ /**
+ * Whether the compiler will allow a subclass to have a variable/property/method with the
+ * same name as a private variable/property/method in the base classes. The compiler
+ * will always report an error if the subclass has an API that conflicts with public/protected
+ * APIs in the base classes.
+ */
+ @Config
+ @Mapping({ "compiler", "allow-private-name-conflicts" })
+ @RoyaleOnly
+ public void setCompilerAllowPrivateNameConflicts(ConfigurationValue cv, boolean allow)
+ {
+ this.allowPrivateNameConflicts = allow;
+ }
+
+ //
// 'compiler.actionscript-file-encoding' option
//
diff --git a/compiler-common/src/main/java/org/apache/royale/compiler/projects/ICompilerProject.java b/compiler-common/src/main/java/org/apache/royale/compiler/projects/ICompilerProject.java
index 85fc156..332576a 100644
--- a/compiler-common/src/main/java/org/apache/royale/compiler/projects/ICompilerProject.java
+++ b/compiler-common/src/main/java/org/apache/royale/compiler/projects/ICompilerProject.java
@@ -261,5 +261,10 @@ public interface ICompilerProject
boolean isParameterCountMismatchAllowed(
IFunctionDefinition functionDefinition, int formalCount,
int actualCount);
+
+ /**
+ * @return True if a subclass can have a private API with the same name as a private API in its base classes.
+ */
+ boolean getAllowPrivateNameConflicts();
}
diff --git a/compiler-externc/src/test/config/externc-config.xml b/compiler-externc/src/test/config/externc-config.xml
index ab2a1c0..3171696 100644
--- a/compiler-externc/src/test/config/externc-config.xml
+++ b/compiler-externc/src/test/config/externc-config.xml
@@ -128,6 +128,34 @@
<class>String</class>
<name>raw</name>
</exclude>
+ <exclude>
+ <class>Document</class>
+ <name>loadXML</name>
+ </exclude>
+ <exclude>
+ <class>Event</class>
+ <name>initUIEvent</name>
+ </exclude>
+ <exclude>
+ <class>Event</class>
+ <name>initMessageEvent</name>
+ </exclude>
+ <exclude>
+ <class>Element</class>
+ <name>load</name>
+ </exclude>
+ <exclude>
+ <class>Document</class>
+ <name>open</name>
+ </exclude>
+ <exclude>
+ <class>Document</class>
+ <name>close</name>
+ </exclude>
+ <exclude>
+ <class>Document</class>
+ <name>createTreeWalker</name>
+ </exclude>
<!-- SVG -->
<exclude><class>SVGStylable</class><name>className</name></exclude>
<exclude><class>SVGStylable</class><name>style</name></exclude>
diff --git a/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TypedefsTestUtils.java b/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TypedefsTestUtils.java
index 3d04b7c..87daab5 100644
--- a/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TypedefsTestUtils.java
+++ b/compiler-externc/src/test/java/org/apache/royale/compiler/internal/codegen/typedefs/TypedefsTestUtils.java
@@ -95,6 +95,13 @@ public class TypedefsTestUtils
config.addExclude("Date", "valueOf");
config.addExclude("String", "valueOf");
config.addExclude("String", "raw");
+ config.addExclude("Document", "loadXML");
+ config.addExclude("Document", "open");
+ config.addExclude("Document", "close");
+ config.addExclude("Document", "createTreeWalker");
+ config.addExclude("Event", "initUIEvent");
+ config.addExclude("Event", "initMessageEvent");
+ config.addExclude("Element", "load");
// SVG
config.addExclude("SVGStylable", "className");
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IJSEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IJSEmitter.java
index ae36a77..5dffb4d 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IJSEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IJSEmitter.java
@@ -39,6 +39,7 @@ public interface IJSEmitter extends IASEmitter, IMappingEmitter
JSSessionModel getModel();
String formatQualifiedName(String name);
+ String formatPrivateName(String className, String name);
void emitSourceMapDirective(ITypeNode node);
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java
index bc2649a..ae8768a 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java
@@ -499,4 +499,10 @@ public class JSEmitter extends ASEmitter implements IJSEmitter
}
}
+ @Override
+ public String formatPrivateName(String className, String name) {
+ // TODO Auto-generated method stub
+ return className.replace(".", "_") + "_" + name;
+ }
+
}
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ClassEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ClassEmitter.java
index ee80893..6c3ddda 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ClassEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ClassEmitter.java
@@ -244,7 +244,11 @@ public class ClassEmitter extends JSSubEmitter implements
writeNewline();
write(ASEmitterTokens.THIS);
write(ASEmitterTokens.MEMBER_ACCESS);
- write(dnode.getName());
+ String dname = dnode.getName();
+ IDefinition dDef = dnode.getDefinition();
+ if (dDef != null && dDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
+ dname = getEmitter().formatPrivateName(dDef.getParent().getQualifiedName(), dname);
+ write(dname);
if (dnode.getNodeID() == ASTNodeID.BindableVariableID)
{
write("_");
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FieldEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FieldEmitter.java
index 13876ca..c9dddc4 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FieldEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FieldEmitter.java
@@ -101,7 +101,11 @@ public class FieldEmitter extends JSSubEmitter implements
className = getEmitter().formatQualifiedName(definition.getQualifiedName());
write(className
+ ASEmitterTokens.MEMBER_ACCESS.getToken() + root);
- write(node.getName());
+ String qname = node.getName();
+ IDefinition nodeDef = node.getDefinition();
+ if (nodeDef != null && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
+ qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname);
+ write(qname);
endMapping(node.getNameExpressionNode());
}
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java
index e7e19a8..49fcc0c 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java
@@ -328,8 +328,12 @@ public class IdentifierEmitter extends JSSubEmitter implements
{
write("[\"" + qname + "\"]");
}
- else
+ else
+ {
+ if (nodeDef != null && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
+ qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname);
write(qname);
+ }
endMapping(node);
}
else if (grandparentNodeId == ASTNodeID.E4XFilterID &&
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java
index 2171d8e..f258b16 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java
@@ -523,13 +523,13 @@ public class JSRoyaleEmitter extends JSGoogEmitter implements IJSRoyaleEmitter
@Override
public void emitMemberName(IDefinitionNode node)
{
+ ICompilerProject project = getWalker().getProject();
if (node.getNodeID() == ASTNodeID.FunctionID)
{
FunctionNode fn = (FunctionNode)node;
if (isCustomNamespace(fn))
{
INamespaceDecorationNode ns = ((FunctionNode)node).getActualNamespaceNode();
- ICompilerProject project = getWalker().getProject();
INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
formatQualifiedName(nsDef.getQualifiedName()); // register with used names
String s = nsDef.getURI();
@@ -537,7 +537,11 @@ public class JSRoyaleEmitter extends JSGoogEmitter implements IJSRoyaleEmitter
return;
}
}
- write(node.getName());
+ String qname = node.getName();
+ IDefinition nodeDef = node.getDefinition();
+ if (nodeDef != null && nodeDef.isPrivate() && project.getAllowPrivateNameConflicts())
+ qname = formatPrivateName(nodeDef.getParent().getQualifiedName(), qname);
+ write(qname);
}
@Override
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/FunctionDefinition.java b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/FunctionDefinition.java
index 9ebf0b9..fdcbf80 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/FunctionDefinition.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/FunctionDefinition.java
@@ -43,6 +43,8 @@ import org.apache.royale.compiler.definitions.references.INamespaceReference;
import org.apache.royale.compiler.definitions.metadata.IMetaTag;
import org.apache.royale.compiler.definitions.references.IReference;
import org.apache.royale.compiler.internal.projects.CompilerProject;
+import org.apache.royale.compiler.problems.AmbiguousReferenceProblem;
+import org.apache.royale.compiler.problems.ConflictingDefinitionProblem;
import org.apache.royale.compiler.projects.ICompilerProject;
import org.apache.royale.compiler.scopes.IASScope;
import org.apache.royale.compiler.scopes.IDefinitionSet;
@@ -51,6 +53,8 @@ import org.apache.royale.compiler.tree.as.IContainerNode;
import org.apache.royale.compiler.tree.as.IDefinitionNode;
import org.apache.royale.compiler.tree.as.IFunctionNode;
+import com.google.common.base.Predicate;
+
/**
* Each instance of this class represents the definition of an ActionScript
* function in the symbol table.
@@ -302,7 +306,11 @@ public class FunctionDefinition extends ScopedDefinitionBase implements IFunctio
IDefinition baseFunc = base.getContainedScope().getQualifiedPropertyFromDef(
project, base, this.getBaseName(), namespace, false);
- return baseFunc instanceof FunctionDefinition ? (FunctionDefinition)baseFunc : null;
+ if (baseFunc instanceof FunctionDefinition) return (FunctionDefinition)baseFunc;
+
+ IDefinition anyDef = base.getContainedScope().getPropertyFromDef(project, base, this.getBaseName(), new PrivatePredicate(!project.getAllowPrivateNameConflicts()), false);
+ if (anyDef != null) // there might be a variable or a function in a different namespace (private vs protected)
+ project.getProblems().add(new ConflictingDefinitionProblem(this.getFunctionNode(), this.getBaseName(), anyDef.getParent().getQualifiedName()));
}
return null;
}
@@ -628,4 +636,22 @@ public class FunctionDefinition extends ScopedDefinitionBase implements IFunctio
sb.append(returnType);
}
}
+
+ private static class PrivatePredicate implements Predicate<IDefinition>
+ {
+ private boolean findPrivates;
+
+ public PrivatePredicate(boolean b)
+ {
+ this.findPrivates = b;
+ }
+
+ @Override
+ public boolean apply(IDefinition definition)
+ {
+ if (!definition.isPrivate()) return true;
+ return findPrivates;
+ }
+ }
+
}
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ConfigProcessor.java b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ConfigProcessor.java
index 5966459..3d30c7d 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ConfigProcessor.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ConfigProcessor.java
@@ -153,6 +153,12 @@ public class ConfigProcessor
removeCompilationUnits(Collections.<ICompilationUnit> singletonList(cu));
}
+
+ @Override
+ public boolean getAllowPrivateNameConflicts() {
+ // TODO Auto-generated method stub
+ return false;
+ }
}
/**
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/ASCProject.java b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/ASCProject.java
index 209755c..f6b78fa 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/ASCProject.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/ASCProject.java
@@ -74,4 +74,10 @@ public class ASCProject extends CompilerProject implements IASCProject
{
return false;
}
+
+ @Override
+ public boolean getAllowPrivateNameConflicts() {
+ // TODO Auto-generated method stub
+ return false;
+ }
}
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProject.java b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProject.java
index 903889d..e787d6c 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProject.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProject.java
@@ -2415,6 +2415,21 @@ public class RoyaleProject extends ASProject implements IRoyaleProject, ICompile
return list;
}
+ private boolean allowPrivateNameConflicts;
+
+ /**
+ * List of compiler defines so it can be overridden
+ */
+ @Override
+ public boolean getAllowPrivateNameConflicts()
+ {
+ return allowPrivateNameConflicts;
+ }
+ public void setAllowPrivateNameConflicts(boolean allow)
+ {
+ allowPrivateNameConflicts = allow;
+ }
+
@Override
public boolean isPlatformRule(ICSSRule rule) {
return true;
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProjectConfigurator.java b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProjectConfigurator.java
index 31295fd..df8d4fa 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProjectConfigurator.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProjectConfigurator.java
@@ -261,6 +261,7 @@ public class RoyaleProjectConfigurator extends Configurator
project.setProxyBaseClass(configValue);
project.setStrictXML(configuration.isStrictXML());
+ project.setAllowPrivateNameConflicts(configuration.getCompilerAllowPrivateNameConflicts());
DataTranscoder.embedClassName = configuration.getByteArrayEmbedClass();
}
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IJSEmitter.java b/compiler/src/main/java/org/apache/royale/compiler/problems/ConflictingDefinitionProblem.java
similarity index 51%
copy from compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IJSEmitter.java
copy to compiler/src/main/java/org/apache/royale/compiler/problems/ConflictingDefinitionProblem.java
index ae36a77..bf0a91c 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IJSEmitter.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/problems/ConflictingDefinitionProblem.java
@@ -17,31 +17,29 @@
*
*/
-package org.apache.royale.compiler.codegen.js;
+package org.apache.royale.compiler.problems;
-import java.io.Writer;
-
-import org.apache.royale.compiler.codegen.as.IASEmitter;
-import org.apache.royale.compiler.definitions.IDefinition;
-import org.apache.royale.compiler.internal.codegen.js.JSSessionModel;
import org.apache.royale.compiler.tree.as.IASNode;
-import org.apache.royale.compiler.tree.as.ITypeNode;
-import org.apache.royale.compiler.visitor.IASNodeStrategy;
/**
- * The {@link IJSEmitter} interface allows abstraction between the
- * {@link IASNodeStrategy} and the current output buffer {@link Writer}.
- *
- * @author Michael Schmalle
+ * Diagnostic emitted when the code generator detects
+ * a definition that conflicts with an inherited definition
+ * from a superclass.
*/
-public interface IJSEmitter extends IASEmitter, IMappingEmitter
+public final class ConflictingDefinitionProblem extends SemanticProblem
{
- JSSessionModel getModel();
-
- String formatQualifiedName(String name);
-
- void emitSourceMapDirective(ITypeNode node);
+ public static final String DESCRIPTION =
+ "A conflict exists with inherited definition ${declName} in class ${className}.";
+
+ public static final int errorCode = 1554;
+
+ public ConflictingDefinitionProblem(IASNode site, String declName, String className)
+ {
+ super(site);
+ this.declName = declName;
+ this.className = className;
+ }
- void emitClosureStart();
- void emitClosureEnd(IASNode node, IDefinition nodeDef);
+ public final String declName;
+ public final String className;
}