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 ce91df79d043ca2281f29ebd7f45f3b557472732 Author: Josh Tynjala <[email protected]> AuthorDate: Mon Sep 26 13:07:29 2022 -0700 linter: missing-constructor-super --- .../main/java/org/apache/royale/linter/LINTER.java | 4 + .../apache/royale/linter/config/Configuration.java | 16 ++++ .../linter/rules/MissingConstructorSuperRule.java | 93 ++++++++++++++++++++++ 3 files changed, 113 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 c60aed272..ba4de97ca 100644 --- a/linter/src/main/java/org/apache/royale/linter/LINTER.java +++ b/linter/src/main/java/org/apache/royale/linter/LINTER.java @@ -71,6 +71,7 @@ import org.apache.royale.linter.rules.MXMLIDRule; import org.apache.royale.linter.rules.MaxBlockDepthRule; import org.apache.royale.linter.rules.MaxParametersRule; import org.apache.royale.linter.rules.MissingASDocRule; +import org.apache.royale.linter.rules.MissingConstructorSuperRule; import org.apache.royale.linter.rules.MissingNamespaceRule; import org.apache.royale.linter.rules.MissingSemicolonRule; import org.apache.royale.linter.rules.MissingTypeRule; @@ -321,6 +322,9 @@ public class LINTER { if (configuration.getMissingAsdoc()) { rules.add(new MissingASDocRule()); } + if (configuration.getMissingConstructorSuper()) { + rules.add(new MissingConstructorSuperRule()); + } if (configuration.getMissingNamespace()) { rules.add(new MissingNamespaceRule()); } 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 07b3378cd..5d1975128 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 @@ -554,6 +554,22 @@ public class Configuration { this.missingAsdoc = b; } + // + // 'missing-constructor-super' option + // + + private boolean missingConstructorSuper = false; + + public boolean getMissingConstructorSuper() { + return missingConstructorSuper; + } + + @Config + @Mapping("missing-constructor-super") + public void setMissingConstructorSuper(ConfigurationValue cv, boolean b) { + this.missingConstructorSuper = b; + } + // // 'missing-namespace' option // diff --git a/linter/src/main/java/org/apache/royale/linter/rules/MissingConstructorSuperRule.java b/linter/src/main/java/org/apache/royale/linter/rules/MissingConstructorSuperRule.java new file mode 100644 index 000000000..f2863b768 --- /dev/null +++ b/linter/src/main/java/org/apache/royale/linter/rules/MissingConstructorSuperRule.java @@ -0,0 +1,93 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.IExpressionNode; +import org.apache.royale.compiler.tree.as.IFunctionCallNode; +import org.apache.royale.compiler.tree.as.IFunctionNode; +import org.apache.royale.compiler.tree.as.ILanguageIdentifierNode; +import org.apache.royale.compiler.tree.as.ILanguageIdentifierNode.LanguageIdentifierKind; +import org.apache.royale.linter.LinterRule; +import org.apache.royale.linter.NodeVisitor; +import org.apache.royale.linter.TokenQuery; + +/** + * Check that all constructors include a call to super(). + */ +public class MissingConstructorSuperRule extends LinterRule { + @Override + public Map<ASTNodeID, NodeVisitor> getNodeVisitors() { + Map<ASTNodeID, NodeVisitor> result = new HashMap<>(); + result.put(ASTNodeID.FunctionID, (node, tokenQuery, problems) -> { + checkFunctionNode((IFunctionNode) node, tokenQuery, problems); + }); + return result; + } + + private void checkFunctionNode(IFunctionNode functionNode, TokenQuery tokenQuery, Collection<ICompilerProblem> problems) { + if (!functionNode.isConstructor()) { + return; + } + if (hasSuperCall(functionNode.getScopedNode())) { + return; + } + problems.add(new MissingConstructorSuperLinterProblem(functionNode)); + } + + private boolean hasSuperCall(IASNode node) { + if (node instanceof IFunctionCallNode) { + IFunctionCallNode functionCallNode = (IFunctionCallNode) node; + IExpressionNode nameNode = functionCallNode.getNameNode(); + if (nameNode instanceof ILanguageIdentifierNode) { + ILanguageIdentifierNode identifierNode = (ILanguageIdentifierNode) nameNode; + if (LanguageIdentifierKind.SUPER.equals(identifierNode.getKind())) { + return true; + } + } + } + for (int i = 0; i < node.getChildCount(); i++) { + IASNode child = node.getChild(i); + if (hasSuperCall(child)) { + return true; + } + } + return false; + } + + public static class MissingConstructorSuperLinterProblem extends CompilerProblem { + public static final String DESCRIPTION = "Constructor '${functionName}' does not include 'super()' call"; + + public MissingConstructorSuperLinterProblem(IFunctionNode node) + { + super(node.getNameExpressionNode()); + functionName = node.getName(); + } + + public String functionName; + } +}
