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 ffead0a8ead70d4294ee3ce1da92e5a69a167590 Author: Alex Harui <aha...@apache.org> AuthorDate: Mon Jan 7 22:20:57 2019 -0800 try to resolve types more intelligently in order to allow top-level conversion functions with the same name as an interface. For example, the browser MouseEvent takes a MouseEventInit interface, but we want a conversion function called MouseEventInit so it looks and behaves more like XML's conversion function. It appears that the canEscapeWith flag can be used to choose the function over the interface definition --- .../internal/definitions/AmbiguousDefinition.java | 23 +++++++++++++++++++++- .../references/ResolvedQualifiersReference.java | 2 +- .../royale/compiler/internal/scopes/ASScope.java | 4 ++-- .../compiler/internal/scopes/ASScopeCache.java | 12 ++++++----- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/AmbiguousDefinition.java b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/AmbiguousDefinition.java index b51b8c5..91e0d5e 100644 --- a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/AmbiguousDefinition.java +++ b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/AmbiguousDefinition.java @@ -95,10 +95,11 @@ public final class AmbiguousDefinition extends DefinitionBase implements IDefini * * @param project The Project to use to resolve things * @param defs an Array of definitions to compare + * @param favorTypes * @return the definition to use as the result of the lookup, if the * ambiguity was successfully resolved, otherwise null */ - public static IDefinition resolveAmbiguities(ICompilerProject project, List<IDefinition> defs) + public static IDefinition resolveAmbiguities(ICompilerProject project, List<IDefinition> defs, boolean favorTypes) { IDefinition resolvedDef = null; @@ -111,6 +112,26 @@ public final class AmbiguousDefinition extends DefinitionBase implements IDefini resolvedDef = defs.get(0); } + // this is used to favor type definitions over function definitions + // when resolving the type of a variable (which can't be a function) + if (resolvedDef == null && defs.size() == 2) + { + IDefinition def0 = defs.get(0); + IDefinition def1 = defs.get(1); + if (def0 instanceof FunctionDefinition && + (def1 instanceof ClassDefinition || + (def1 instanceof InterfaceDefinition))) + { + resolvedDef = favorTypes ? def1 : def0; + } + else if (def1 instanceof FunctionDefinition && + (def0 instanceof ClassDefinition || + (def0 instanceof InterfaceDefinition))) + { + resolvedDef = favorTypes ? def0 : def1; + } + } + if (resolvedDef == null) { // check for redeclared variables and functions diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/references/ResolvedQualifiersReference.java b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/references/ResolvedQualifiersReference.java index 1561d13..bf2ac97 100644 --- a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/references/ResolvedQualifiersReference.java +++ b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/references/ResolvedQualifiersReference.java @@ -128,7 +128,7 @@ public class ResolvedQualifiersReference implements IResolvedQualifiersReference } default: { - IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs); + IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs, false); if (d == null) return AmbiguousDefinition.get(); return d; diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScope.java b/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScope.java index 434a2d9..b229304 100644 --- a/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScope.java +++ b/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScope.java @@ -1425,7 +1425,7 @@ public abstract class ASScope extends ASScopeBase assert baseName.indexOf('.') == -1 : "baseName must not be any sort of qname"; CompilerProject compilerProject = (CompilerProject)project; ASScopeCache scopeCache = compilerProject.getCacheForScope(this); - return filterWith(scopeCache.findProperty(baseName, dt), canEscapeWith); + return filterWith(scopeCache.findProperty(baseName, dt, canEscapeWith), canEscapeWith); } /** @@ -1487,7 +1487,7 @@ public abstract class ASScope extends ASScopeBase assert def.isInProject(project); break; default: - IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs); + IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs, false); if (d != null) def = d; else diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScopeCache.java b/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScopeCache.java index fb43722..7d3563a 100644 --- a/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScopeCache.java +++ b/compiler/src/main/java/org/apache/royale/compiler/internal/scopes/ASScopeCache.java @@ -131,7 +131,7 @@ public class ASScopeCache * @param dt Which type of dependency to introduce when we do the lookup * @return The IDefinition for the property, or null if it wasn't found */ - IDefinition findProperty(String name, DependencyType dt) + IDefinition findProperty(String name, DependencyType dt, boolean favorTypes) { ConcurrentMap<String, IDefinition> map = getScopeChainMap(); @@ -148,6 +148,7 @@ public class ASScopeCache // the benefit is that we avoid any sort of locking, which was proving expensive (time wise, // and memory wise). + boolean wasAmbiguous = false; IDefinition def = null; Set<INamespaceDefinition> namespaceSet = scope.getNamespaceSetForName(project, name); // Look for the definition in the scope @@ -164,7 +165,8 @@ public class ASScopeCache assert def.isInProject(project); break; default: - IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs); + wasAmbiguous = true; + IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs, favorTypes); if (d != null) def = d; else { @@ -186,7 +188,7 @@ public class ASScopeCache // If the dependency type is null we can't cache the name // resolution result, because the name resolution cache will not // be properly invalidated when the file containing the definition changes. - if (dt != null) + if (dt != null && !wasAmbiguous) { result = map.putIfAbsent(name, def); if (result == null) @@ -294,7 +296,7 @@ public class ASScopeCache break; default: - IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs); + IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs, false); if (d != null) def = d; else @@ -361,7 +363,7 @@ public class ASScopeCache assert def.isInProject(project); break; default: - IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs); + IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs, false); if (d != null) def = d; else