You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by pi...@apache.org on 2019/09/16 08:07:09 UTC
[royale-compiler] 02/06: compiler: warn when using this in a
function closure (references #90)
This is an automated email from the ASF dual-hosted git repository.
piotrz pushed a commit to branch release/0.9.6
in repository https://gitbox.apache.org/repos/asf/royale-compiler.git
commit 5c9bf227eaf866cb0da66f0b1b54dd951ec95a00
Author: Josh Tynjala <jo...@apache.org>
AuthorDate: Wed Sep 11 13:18:52 2019 -0700
compiler: warn when using this in a function closure (references #90)
(cherry picked from commit 7e7b269bc922080e9084f757e3eecfa5c94697b9)
---
.../semantics/MethodBodySemanticChecker.java | 26 ++++++++++++++
.../compiler/internal/semantics/SemanticUtils.java | 16 +++++++++
.../problems/ThisUsedInClosureProblem.java | 40 ++++++++++++++++++++++
3 files changed, 82 insertions(+)
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/MethodBodySemanticChecker.java b/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/MethodBodySemanticChecker.java
index 610da6d..c455528 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/MethodBodySemanticChecker.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/MethodBodySemanticChecker.java
@@ -789,6 +789,14 @@ public class MethodBodySemanticChecker
{
FunctionNode func = (FunctionNode)iNode;
+ if (SemanticUtils.isFunctionClosure(func))
+ {
+ for (IASNode thisNode : findThisIdentifierNodes(func))
+ {
+ addProblem(new ThisUsedInClosureProblem(thisNode));
+ }
+ }
+
IDefinition def = func.getDefinition();
if ( project.getAllowAbstractClasses()
@@ -810,6 +818,24 @@ public class MethodBodySemanticChecker
}
}
+ private static List<IASNode> findThisIdentifierNodes(IASNode iNode)
+ {
+ List<IASNode> result = new ArrayList<IASNode>();
+ for(int i = 0, count = iNode.getChildCount(); i < count; i++)
+ {
+ IASNode child = iNode.getChild(i);
+ if(SemanticUtils.isThisKeyword(child))
+ {
+ result.add(child);
+ }
+ else if(!child.isTerminal() && !(child instanceof IFunctionNode))
+ {
+ result.addAll(findThisIdentifierNodes(child));
+ }
+ }
+ return result;
+ }
+
public void checkNativeMethod(IASNode iNode)
{
if( iNode instanceof FunctionNode )
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/SemanticUtils.java b/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/SemanticUtils.java
index 20b3747..d22d291 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/SemanticUtils.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/SemanticUtils.java
@@ -129,6 +129,7 @@ import org.apache.royale.compiler.tree.as.IMemberAccessExpressionNode;
import org.apache.royale.compiler.tree.as.INamespaceDecorationNode;
import org.apache.royale.compiler.tree.as.INumericLiteralNode;
import org.apache.royale.compiler.tree.as.IParameterNode;
+import org.apache.royale.compiler.tree.as.IScopedNode;
import org.apache.royale.compiler.tree.as.ITryNode;
import org.apache.royale.compiler.tree.as.IVariableNode;
import org.apache.royale.compiler.tree.mxml.IMXMLEventSpecifierNode;
@@ -1324,6 +1325,21 @@ public class SemanticUtils
}
/**
+ * Is this function node contained within another function node?
+ * @param iNode - the node of interest.
+ * @return true if the function node is a closure
+ */
+ public static boolean isFunctionClosure(IFunctionNode functionNode)
+ {
+ IScopedNode containingScope = functionNode.getContainingScope();
+ if (containingScope == null)
+ {
+ return false;
+ }
+ return containingScope.getParent() instanceof IFunctionNode;
+ }
+
+ /**
* Is the given node in a class with a base class definition?
* @param iNode - the node of interest.
* @return true if the node is in a class with a base class.
diff --git a/compiler/src/main/java/org/apache/royale/compiler/problems/ThisUsedInClosureProblem.java b/compiler/src/main/java/org/apache/royale/compiler/problems/ThisUsedInClosureProblem.java
new file mode 100644
index 0000000..8a2dc28
--- /dev/null
+++ b/compiler/src/main/java/org/apache/royale/compiler/problems/ThisUsedInClosureProblem.java
@@ -0,0 +1,40 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.royale.compiler.problems;
+
+import org.apache.royale.compiler.tree.as.IASNode;
+
+/**
+ * Diagnostic emitted when the method body semantic checker detects
+ * a reference to "this" in a closure
+ */
+public final class ThisUsedInClosureProblem extends SemanticWarningProblem
+{
+ public static final String DESCRIPTION =
+ "Encountered ${THIS} keyword within closure. Value of ${THIS} will not be the same as enclosing scope.";
+
+ public ThisUsedInClosureProblem(IASNode site)
+ {
+ super(site);
+ }
+
+ // Prevent these from being localized.
+ public final String THIS = "this";
+}