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

joshtynjala pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-compiler.git

commit 9b76d240677d6e0c5726fb3baccd20a8782bf8b2
Author: Josh Tynjala <joshtynj...@apache.org>
AuthorDate: Mon Sep 26 14:04:56 2022 -0700

    linter: valid-typeof
---
 .../main/java/org/apache/royale/linter/LINTER.java |   4 +
 .../apache/royale/linter/config/Configuration.java |  16 +++
 .../royale/linter/rules/ValidTypeofRule.java       | 110 +++++++++++++++++++++
 3 files changed, 130 insertions(+)

diff --git a/linter/src/main/java/org/apache/royale/linter/LINTER.java 
b/linter/src/main/java/org/apache/royale/linter/LINTER.java
index e8ca277ea..af2d9cf35 100644
--- a/linter/src/main/java/org/apache/royale/linter/LINTER.java
+++ b/linter/src/main/java/org/apache/royale/linter/LINTER.java
@@ -86,6 +86,7 @@ import org.apache.royale.linter.rules.StringEventNameRule;
 import org.apache.royale.linter.rules.SwitchWithoutDefaultRule;
 import org.apache.royale.linter.rules.ThisInClosureRule;
 import org.apache.royale.linter.rules.TraceRule;
+import org.apache.royale.linter.rules.ValidTypeofRule;
 import org.apache.royale.linter.rules.WildcardImportRule;
 import org.apache.royale.linter.rules.WithRule;
 import org.apache.royale.utils.FilenameNormalization;
@@ -366,6 +367,9 @@ public class LINTER {
                        if (configuration.getTrace()) {
                                rules.add(new TraceRule());
                        }
+                       if (configuration.getValidTypeof()) {
+                               rules.add(new ValidTypeofRule());
+                       }
                        if (configuration.getWildcardImport()) {
                                rules.add(new WildcardImportRule());
                        }
diff --git 
a/linter/src/main/java/org/apache/royale/linter/config/Configuration.java 
b/linter/src/main/java/org/apache/royale/linter/config/Configuration.java
index 0e02a0e95..6e555b13d 100644
--- a/linter/src/main/java/org/apache/royale/linter/config/Configuration.java
+++ b/linter/src/main/java/org/apache/royale/linter/config/Configuration.java
@@ -826,6 +826,22 @@ public class Configuration {
         this.trace = b;
     }
 
+    //
+    // 'valid-typeof' option
+    //
+
+    private boolean validTypeof = false;
+
+    public boolean getValidTypeof() {
+        return validTypeof;
+    }
+
+    @Config
+    @Mapping("valid-typeof")
+    public void setValidTypeof(ConfigurationValue cv, boolean b) {
+        this.validTypeof = b;
+    }
+
     //
     // 'wildcard-import' option
     //
diff --git 
a/linter/src/main/java/org/apache/royale/linter/rules/ValidTypeofRule.java 
b/linter/src/main/java/org/apache/royale/linter/rules/ValidTypeofRule.java
new file mode 100644
index 000000000..0e3821597
--- /dev/null
+++ b/linter/src/main/java/org/apache/royale/linter/rules/ValidTypeofRule.java
@@ -0,0 +1,110 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.linter.rules;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.royale.compiler.problems.CompilerProblem;
+import org.apache.royale.compiler.problems.ICompilerProblem;
+import org.apache.royale.compiler.tree.ASTNodeID;
+import org.apache.royale.compiler.tree.as.IASNode;
+import org.apache.royale.compiler.tree.as.IBinaryOperatorNode;
+import org.apache.royale.compiler.tree.as.IExpressionNode;
+import org.apache.royale.compiler.tree.as.ILiteralNode;
+import org.apache.royale.compiler.tree.as.ILiteralNode.LiteralType;
+import org.apache.royale.compiler.tree.as.IOperatorNode.OperatorType;
+import org.apache.royale.compiler.tree.as.IUnaryOperatorNode;
+import org.apache.royale.linter.LinterRule;
+import org.apache.royale.linter.NodeVisitor;
+import org.apache.royale.linter.TokenQuery;
+
+/**
+ * Check that an array literal contains no empty slots (multiple repeating
+ * commas with no values).
+ */
+public class ValidTypeofRule extends LinterRule {
+       private static final Set<String> VALID_RESULTS = new HashSet<>();
+       {
+               VALID_RESULTS.add("boolean");
+               VALID_RESULTS.add("function");
+               VALID_RESULTS.add("number");
+               VALID_RESULTS.add("object");
+               VALID_RESULTS.add("string");
+               VALID_RESULTS.add("xml");
+               VALID_RESULTS.add("undefined");
+       }
+
+       @Override
+       public Map<ASTNodeID, NodeVisitor> getNodeVisitors() {
+               Map<ASTNodeID, NodeVisitor> result = new HashMap<>();
+               result.put(ASTNodeID.Op_TypeOfID, (node, tokenQuery, problems) 
-> {
+                       checkUnaryOperatorNode((IUnaryOperatorNode) node, 
tokenQuery, problems);
+               });
+               return result;
+       }
+
+       private void checkUnaryOperatorNode(IUnaryOperatorNode typeofNode, 
TokenQuery tokenQuery,
+                       Collection<ICompilerProblem> problems) {
+               if (!OperatorType.TYPEOF.equals(typeofNode.getOperator())) {
+                       return;
+               }
+               IASNode parentNode = typeofNode.getParent();
+               if (!(parentNode instanceof IBinaryOperatorNode)) {
+                       return;
+               }
+               IBinaryOperatorNode binaryOperatorNode = (IBinaryOperatorNode) 
parentNode;
+               OperatorType parentOperatorType = 
binaryOperatorNode.getOperator();
+               if (!OperatorType.EQUAL.equals(parentOperatorType)
+                               && 
!OperatorType.NOT_EQUAL.equals(parentOperatorType)
+                               && 
!OperatorType.STRICT_EQUAL.equals(parentOperatorType)
+                               && 
!OperatorType.STRICT_NOT_EQUAL.equals(parentOperatorType)) {
+                       return;
+               }
+               IExpressionNode otherNode = 
binaryOperatorNode.getLeftOperandNode() == typeofNode
+                               ? binaryOperatorNode.getRightOperandNode()
+                               : binaryOperatorNode.getLeftOperandNode();
+               if (!(otherNode instanceof ILiteralNode)) {
+                       return;
+               }
+               ILiteralNode stringLiteral = (ILiteralNode) otherNode;
+               if (!LiteralType.STRING.equals(stringLiteral.getLiteralType())) 
{
+                       return;
+               }
+               if (VALID_RESULTS.contains(stringLiteral.getValue())) {
+                       return;
+               }
+               problems.add(new ValidTypeofLinterProblem(stringLiteral));
+       }
+
+       public static class ValidTypeofLinterProblem extends CompilerProblem {
+               public static final String DESCRIPTION = "String '${value}' is 
not a valid result for typeof operator";
+
+               public ValidTypeofLinterProblem(ILiteralNode node) {
+                       super(node);
+                       value = node.getValue();
+               }
+
+               public String value;
+       }
+}

Reply via email to