forked from phoedos/pmd
Make getText @NoAttribute
This commit is contained in:
@@ -9,6 +9,8 @@ import org.antlr.v4.runtime.RuleContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.TextAvailableNode;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.NoAttribute;
|
||||
import net.sourceforge.pmd.util.DataMap;
|
||||
import net.sourceforge.pmd.util.DataMap.DataKey;
|
||||
|
||||
@@ -44,10 +46,10 @@ public abstract class AntlrBaseInnerNode<
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO @NoAttribute (port swift rules)
|
||||
* @see TextAvailableNode
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("PMD.UselessOverridingMethod")
|
||||
@NoAttribute
|
||||
public String getText() {
|
||||
return super.getText();
|
||||
}
|
||||
|
@@ -13,7 +13,15 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class AntlrNameDictionary implements Vocabulary {
|
||||
/**
|
||||
* Stores the XPath name of antlr terminals. I found no simple way to
|
||||
* give names to punctuation (we could add a lexer rule, but it may
|
||||
* conflict with other tokens). So their names are hardcoded here.
|
||||
*
|
||||
* <p>Terminal names start with {@code "T-"} in XPath to avoid conflicts
|
||||
* with other stuff.
|
||||
*/
|
||||
public class AntlrNameDictionary {
|
||||
|
||||
private final String[] xpathNames;
|
||||
private final Vocabulary vocabulary;
|
||||
@@ -47,23 +55,77 @@ public class AntlrNameDictionary implements Vocabulary {
|
||||
|
||||
|
||||
assert Stream.of(xpathNames).distinct().count() == xpathNames.length
|
||||
: "Duplicate names in "+ Arrays.toString(xpathNames);
|
||||
: "Duplicate names in " + Arrays.toString(xpathNames);
|
||||
}
|
||||
|
||||
private static @Nullable String maybePunctName(String s) {
|
||||
public Vocabulary getVocabulary() {
|
||||
return vocabulary;
|
||||
}
|
||||
|
||||
protected @Nullable String maybePunctName(String s) {
|
||||
// these are hardcoded, but it's overridable
|
||||
// here we try to avoid semantic overtones, because
|
||||
// a-priori the same terminal may mean several things
|
||||
// in different contexts.
|
||||
switch (s) {
|
||||
case "!": return "bang";
|
||||
case "!!": return "double-bang";
|
||||
|
||||
case "?": return "question";
|
||||
case "??": return "double-question";
|
||||
case "?:": return "elvis";
|
||||
case "?.": return "question-dot";
|
||||
|
||||
case ":": return "colon";
|
||||
case ";": return "semi";
|
||||
case ",": return "comma";
|
||||
|
||||
case "(": return "lparen";
|
||||
case ")": return "rparen";
|
||||
case "[": return "lbracket";
|
||||
case "]": return "rbracket";
|
||||
case "{": return "lbrace";
|
||||
case "}": return "rbrace";
|
||||
|
||||
case "_": return "underscore";
|
||||
|
||||
case ".": return "dot";
|
||||
case "..": return "double-dot";
|
||||
case "...": return "ellipsis";
|
||||
|
||||
case "@": return "at-symbol";
|
||||
case "$": return "dollar";
|
||||
|
||||
case "\\": return "backslash";
|
||||
case "/": return "slash";
|
||||
case "//": return "double-slash";
|
||||
case "`": return "backtick";
|
||||
case "'": return "squote";
|
||||
case "\"": return "dquote";
|
||||
|
||||
case ">": return "gt";
|
||||
case ">=": return "ge";
|
||||
case "<": return "lt";
|
||||
case "<=": return "le";
|
||||
|
||||
case "=": return "eq";
|
||||
case "==": return "double-eq";
|
||||
case "===": return "triple-eq";
|
||||
case "!=": return "not-eq";
|
||||
|
||||
case ">>": return "double-gt";
|
||||
case "<<": return "double-lt";
|
||||
case ">>>": return "triple-gt";
|
||||
case "<<<": return "triple-lt";
|
||||
|
||||
case "*": return "star";
|
||||
case "**": return "double-star";
|
||||
|
||||
case "+": return "plus";
|
||||
case "-": return "minus";
|
||||
|
||||
case "->": return "rarrow";
|
||||
case "<-": return "larrow";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -80,23 +142,7 @@ public class AntlrNameDictionary implements Vocabulary {
|
||||
throw new IllegalArgumentException("I don't know token type " + tokenType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxTokenType() {
|
||||
return vocabulary.getMaxTokenType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLiteralName(int tokenType) {
|
||||
return vocabulary.getLiteralName(tokenType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSymbolicName(int tokenType) {
|
||||
return vocabulary.getSymbolicName(tokenType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName(int tokenType) {
|
||||
return vocabulary.getDisplayName(tokenType);
|
||||
}
|
||||
}
|
||||
|
@@ -6,15 +6,14 @@ package net.sourceforge.pmd.lang.ast.impl.antlr4;
|
||||
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.ast.NodeStream;
|
||||
import net.sourceforge.pmd.lang.ast.TextAvailableNode;
|
||||
|
||||
/**
|
||||
* Base interface for all Antlr-based implementation of Node interface.
|
||||
* <p>
|
||||
* Initially all the methods implemented here will be no-op due to scope limitations
|
||||
*/
|
||||
public interface AntlrNode extends Node, ParseTree {
|
||||
public interface AntlrNode extends ParseTree, TextAvailableNode {
|
||||
|
||||
|
||||
@Override
|
||||
@@ -23,13 +22,4 @@ public interface AntlrNode extends Node, ParseTree {
|
||||
|
||||
@Override
|
||||
AntlrNode getParent();
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
default NodeStream<? extends AntlrNode> children() {
|
||||
return (NodeStream<? extends AntlrNode>) Node.super.children();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -25,6 +25,12 @@ public abstract class PmdAntlrTerminalNode extends TerminalNodeImpl implements A
|
||||
this.dico = dico;
|
||||
}
|
||||
|
||||
// not @NoAttribute
|
||||
@Override
|
||||
public String getText() {
|
||||
return super.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AntlrNode getChild(int i) {
|
||||
return null;
|
||||
|
@@ -1,62 +0,0 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.swift.rule.bestpractices;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.RuleContext;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.swift.AbstractSwiftRule;
|
||||
import net.sourceforge.pmd.lang.swift.ast.SwiftBaseVisitor;
|
||||
import net.sourceforge.pmd.lang.swift.ast.SwiftParser.AttributeContext;
|
||||
import net.sourceforge.pmd.lang.swift.ast.SwiftParser.FunctionHeadContext;
|
||||
import net.sourceforge.pmd.lang.swift.ast.SwiftParser.VariableDeclarationHeadContext;
|
||||
|
||||
public class ProhibitedInterfaceBuilderRule extends AbstractSwiftRule {
|
||||
|
||||
private static final String IBACTION = "@IBAction";
|
||||
private static final String IBOUTLET = "@IBOutlet";
|
||||
|
||||
public ProhibitedInterfaceBuilderRule() {
|
||||
super();
|
||||
addRuleChainVisit(FunctionHeadContext.class);
|
||||
addRuleChainVisit(VariableDeclarationHeadContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SwiftBaseVisitor<Void> buildVisitor(RuleContext ruleCtx) {
|
||||
return new SwiftBaseVisitor<Void>() {
|
||||
|
||||
@Override
|
||||
public Void visitFunctionHead(FunctionHeadContext ctx) {
|
||||
if (ctx == null || ctx.attributes() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return visitDeclarationHead(ctx, ctx.attributes().attribute(), IBACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitVariableDeclarationHead(final VariableDeclarationHeadContext ctx) {
|
||||
if (ctx == null || ctx.attributes() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return visitDeclarationHead(ctx, ctx.attributes().attribute(), IBOUTLET);
|
||||
}
|
||||
|
||||
private Void visitDeclarationHead(final Node node, final List<AttributeContext> attributes,
|
||||
final String match) {
|
||||
|
||||
final boolean violate = attributes.stream().anyMatch(atr -> match.equals(atr.getText()));
|
||||
if (violate) {
|
||||
addViolation(ruleCtx, node);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -26,9 +26,9 @@ Rules which enforce generally accepted best practices.
|
||||
<property name="version" value="2.0" />
|
||||
<property name="xpath">
|
||||
<value>
|
||||
//VariableDeclarationHead/Attributes/Attribute[T-at-symbol and AttributeName/@Text = "IBOutlet"]
|
||||
//VariableDeclarationHead/Attributes/Attribute[T-at-symbol and AttributeName/*/T-Identifier/@Text = "IBOutlet"]
|
||||
|
|
||||
//FunctionHead/Attributes/Attribute[T-at-symbol and AttributeName/@Text = "IBAction"]
|
||||
//FunctionHead/Attributes/Attribute[T-at-symbol and AttributeName/*/T-Identifier/@Text = "IBAction"]
|
||||
</value>
|
||||
</property>
|
||||
</properties>
|
||||
|
@@ -16,8 +16,7 @@ class ViewController: UIViewController {
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
<source-type>swift</source-type>
|
||||
</test-code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
Good example #2
|
||||
@@ -35,8 +34,7 @@ func jsonValue(_ jsonString: String) -> NSObject {
|
||||
fatalError()
|
||||
}
|
||||
]]></code>
|
||||
<source-type>swift</source-type>
|
||||
</test-code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
Bad example #1
|
||||
@@ -49,8 +47,7 @@ class ViewController: UIViewController {
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
<source-type>swift</source-type>
|
||||
</test-code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
Bad example #2
|
||||
@@ -61,6 +58,5 @@ func doSomething() {
|
||||
fatalError("doSomething() has not been implemented")
|
||||
}
|
||||
]]></code>
|
||||
<source-type>swift</source-type>
|
||||
</test-code>
|
||||
</test-code>
|
||||
</test-data>
|
Reference in New Issue
Block a user