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 abbb4ad607edf45773615d1a1e322dcc486364f0 Author: Josh Tynjala <[email protected]> AuthorDate: Mon Sep 26 14:28:48 2022 -0700 linter: unsafe-negation --- .../main/java/org/apache/royale/linter/LINTER.java | 4 ++ .../apache/royale/linter/config/Configuration.java | 16 +++++ .../royale/linter/rules/UnsafeNegationRule.java | 77 ++++++++++++++++++++++ 3 files changed, 97 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 af2d9cf35..09d6442a0 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.UnsafeNegationRule; import org.apache.royale.linter.rules.ValidTypeofRule; import org.apache.royale.linter.rules.WildcardImportRule; import org.apache.royale.linter.rules.WithRule; @@ -367,6 +368,9 @@ public class LINTER { if (configuration.getTrace()) { rules.add(new TraceRule()); } + if (configuration.getUnsafeNegation()) { + rules.add(new UnsafeNegationRule()); + } if (configuration.getValidTypeof()) { rules.add(new ValidTypeofRule()); } 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 6e555b13d..1faa79e85 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; } + // + // 'unsafe-negation' option + // + + private boolean unsafeNegation = false; + + public boolean getUnsafeNegation() { + return unsafeNegation; + } + + @Config + @Mapping("unsafe-negation") + public void setUnsafeNegation(ConfigurationValue cv, boolean b) { + this.unsafeNegation = b; + } + // // 'valid-typeof' option // diff --git a/linter/src/main/java/org/apache/royale/linter/rules/UnsafeNegationRule.java b/linter/src/main/java/org/apache/royale/linter/rules/UnsafeNegationRule.java new file mode 100644 index 000000000..ab766f584 --- /dev/null +++ b/linter/src/main/java/org/apache/royale/linter/rules/UnsafeNegationRule.java @@ -0,0 +1,77 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.Map; + +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.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 the left side of in, is, and instanceof is not negated unsafely. + */ +public class UnsafeNegationRule extends LinterRule { + @Override + public Map<ASTNodeID, NodeVisitor> getNodeVisitors() { + Map<ASTNodeID, NodeVisitor> result = new HashMap<>(); + result.put(ASTNodeID.Op_InID, (node, tokenQuery, problems) -> { + checkBinaryOperatorNode((IBinaryOperatorNode) node, tokenQuery, problems); + }); + result.put(ASTNodeID.Op_IsID, (node, tokenQuery, problems) -> { + checkBinaryOperatorNode((IBinaryOperatorNode) node, tokenQuery, problems); + }); + result.put(ASTNodeID.Op_InstanceOfID, (node, tokenQuery, problems) -> { + checkBinaryOperatorNode((IBinaryOperatorNode) node, tokenQuery, problems); + }); + return result; + } + + private void checkBinaryOperatorNode(IBinaryOperatorNode binaryOperatorNode, TokenQuery tokenQuery, + Collection<ICompilerProblem> problems) { + IExpressionNode leftSide = binaryOperatorNode.getLeftOperandNode(); + if (!(leftSide instanceof IUnaryOperatorNode)) { + return; + } + IUnaryOperatorNode unaryOpertor = (IUnaryOperatorNode) leftSide; + if (!OperatorType.LOGICAL_NOT.equals(unaryOpertor.getOperator())) { + return; + } + problems.add(new UnsafeNegationLinterProblem(binaryOperatorNode)); + } + + public static class UnsafeNegationLinterProblem extends CompilerProblem { + public static final String DESCRIPTION = "Must not use negation on left side of in, is, and instanceof operators. Did you mean to use parentheses?"; + + public UnsafeNegationLinterProblem(IASNode node) { + super(node); + } + } +}
