From 61e8412afe8816c0383fd3222fd54d5b2e9e3299 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 24 Mar 2015 22:48:01 +0100 Subject: [PATCH] dogfood, whitespaces --- .../sourceforge/pmd/cli/PMDParameters.java | 2 +- .../pmd/cpd/AbstractTokenizer.java | 118 ++-- .../sourceforge/pmd/cpd/CPDConfiguration.java | 452 ++++++------ .../pmd/lang/LanguageRegistry.java | 20 +- .../net/sourceforge/pmd/lang/dfa/Linker.java | 659 +++++++++--------- .../sourceforge/pmd/lang/dfa/NodeType.java | 68 +- .../pmd/lang/dfa/SequenceChecker.java | 8 +- .../pmd/lang/rule/RuleReference.java | 504 +++++++------- 8 files changed, 912 insertions(+), 919 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java index 4c24aad9d8..abc2e83a94 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java @@ -81,7 +81,6 @@ public class PMDParameters { private static final char SEPARATOR = '='; public Properties convert(String value) { - Properties properties = new Properties(); int indexOfSeparator = value.indexOf(SEPARATOR); if (indexOfSeparator < 0) { throw new ParameterException( @@ -89,6 +88,7 @@ public class PMDParameters { } String propertyName = value.substring(0, indexOfSeparator); String propertyValue = value.substring(indexOfSeparator + 1); + Properties properties = new Properties(); properties.put(propertyName, propertyValue); return properties; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractTokenizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractTokenizer.java index bb8e191f4d..8aae763ad1 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractTokenizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractTokenizer.java @@ -12,44 +12,50 @@ import java.util.List; */ public abstract class AbstractTokenizer implements Tokenizer { - //FIXME depending on subclasses to assign local vars is rather fragile - better to make private and setup via explicit hook methods - - protected List stringToken; // List, should be set by sub classes - protected List ignorableCharacter; // List, should be set by sub classes - // FIXME:Maybe an array of 'char' would be better for performance ? - protected List ignorableStmt; // List, should be set by sub classes - protected char oneLineCommentChar = '#'; // Most script languages ( shell, ruby, python,...) use this symbol for comment line + // FIXME depending on subclasses to assign local vars is rather fragile - + // better to make private and setup via explicit hook methods - private List code; - private int lineNumber = 0; - private String currentLine; + protected List stringToken; // List, should be set by sub + // classes + protected List ignorableCharacter; // List, should be set by + // sub classes + // FIXME:Maybe an array of 'char' + // would be better for + // performance ? + protected List ignorableStmt; // List, should be set by sub + // classes + protected char oneLineCommentChar = '#'; // Most script languages ( shell, + // ruby, python,...) use this + // symbol for comment line - protected boolean spanMultipleLinesString = true; // Most languages do, so default is true - protected Character spanMultipleLinesLineContinuationCharacter = null; + private List code; + private int lineNumber = 0; + private String currentLine; - private boolean downcaseString = true; + protected boolean spanMultipleLinesString = true; // Most languages do, so + // default is true + protected Character spanMultipleLinesLineContinuationCharacter = null; + + private boolean downcaseString = true; public void tokenize(SourceCode tokens, Tokens tokenEntries) { code = tokens.getCode(); - for ( lineNumber = 0; lineNumber < code.size(); lineNumber++ ) { - currentLine = code.get(lineNumber); + for (lineNumber = 0; lineNumber < code.size(); lineNumber++) { + currentLine = code.get(lineNumber); int loc = 0; - while ( loc < currentLine.length() ) { + while (loc < currentLine.length()) { StringBuilder token = new StringBuilder(); - loc = getTokenFromLine(token,loc); + loc = getTokenFromLine(token, loc); if (token.length() > 0 && !isIgnorableString(token.toString())) { if (downcaseString) { token = new StringBuilder(token.toString().toLowerCase()); } -// need to re-think how to link this -// if ( CPD.debugEnable ) { -// System.out.println("Token added:" + token.toString()); -// } - tokenEntries.add(new TokenEntry(token.toString(), - tokens.getFileName(), - lineNumber) - ); + // need to re-think how to link this + // if ( CPD.debugEnable ) { + // System.out.println("Token added:" + token.toString()); + // } + tokenEntries.add(new TokenEntry(token.toString(), tokens.getFileName(), lineNumber)); } } @@ -69,7 +75,8 @@ public abstract class AbstractTokenizer implements Tokenizer { } } else if (isString(tok)) { if (token.length() > 0) { - return j; // we need to now parse the string as a separate token. + return j; // we need to now parse the string as a + // separate token. } else { // we are at the start of a string return parseString(token, j, tok); @@ -91,66 +98,67 @@ public abstract class AbstractTokenizer implements Tokenizer { boolean escaped = false; boolean done = false; char tok = ' '; // this will be replaced. - while ((loc < currentLine.length()) && ! done) { + while (loc < currentLine.length() && !done) { tok = currentLine.charAt(loc); if (escaped && tok == stringDelimiter) { // Found an escaped string escaped = false; - } else if (tok == stringDelimiter && (token.length() > 0)) { // We are done, we found the end of the string... + } else if (tok == stringDelimiter && token.length() > 0) { + // We are done, we found the end of the string... done = true; } else if (tok == '\\') { // Found an escaped char escaped = true; - } else { // Adding char... + } else { // Adding char... escaped = false; } - //Adding char to String:" + token.toString()); + // Adding char to String:" + token.toString()); token.append(tok); loc++; } // Handling multiple lines string - if ( ! done && // ... we didn't find the end of the string - loc >= currentLine.length() && // ... we have reach the end of the line ( the String is incomplete, for the moment at least) - spanMultipleLinesString && // ... the language allow multiple line span Strings - lineNumber < code.size() - 1 // ... there is still more lines to parse - ) { - // removes last character, if it is the line continuation (e.g. backslash) character + if (!done && // ... we didn't find the end of the string + loc >= currentLine.length() && // ... we have reach the end of + // the line ( the String is + // incomplete, for the moment at + // least) + spanMultipleLinesString && // ... the language allow multiple + // line span Strings + lineNumber < code.size() - 1 // ... there is still more lines to + // parse + ) { + // removes last character, if it is the line continuation (e.g. + // backslash) character if (spanMultipleLinesLineContinuationCharacter != null && token.length() > 0 && token.charAt(token.length() - 1) == spanMultipleLinesLineContinuationCharacter.charValue()) { token.deleteCharAt(token.length() - 1); } - // parsing new line - currentLine = code.get(++lineNumber); - // Warning : recursive call ! - loc = parseString(token, 0, stringDelimiter); + // parsing new line + currentLine = code.get(++lineNumber); + // Warning : recursive call ! + loc = parseString(token, 0, stringDelimiter); } return loc + 1; } - private boolean ignoreCharacter(char tok) - { - return ignorableCharacter.contains(String.valueOf(tok)); + private boolean ignoreCharacter(char tok) { + return ignorableCharacter.contains(String.valueOf(tok)); } - private boolean isString(char tok) - { - return stringToken.contains(String.valueOf(tok)); + private boolean isString(char tok) { + return stringToken.contains(String.valueOf(tok)); } - private boolean isComment(char tok) - { + private boolean isComment(char tok) { return tok == oneLineCommentChar; } - private int getCommentToken(StringBuilder token, int loc) - { - while (loc < currentLine.length()) - { + private int getCommentToken(StringBuilder token, int loc) { + while (loc < currentLine.length()) { token.append(currentLine.charAt(loc++)); } return loc; } - private boolean isIgnorableString(String token) - { - return ignorableStmt.contains(token); + private boolean isIgnorableString(String token) { + return ignorableStmt.contains(token); } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java index a0aa170400..8af6ac38b2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java @@ -31,120 +31,114 @@ import com.beust.jcommander.converters.FileConverter; */ public class CPDConfiguration extends AbstractConfiguration { - public final static String DEFAULT_LANGUAGE = "java"; + public final static String DEFAULT_LANGUAGE = "java"; - public final static String DEFAULT_RENDERER = "text"; + public final static String DEFAULT_RENDERER = "text"; - @Parameter(names = "--language", description = "Sources code language. Default value is " - + DEFAULT_LANGUAGE, required = false, converter = LanguageConverter.class) - private Language language; + @Parameter(names = "--language", description = "Sources code language. Default value is " + DEFAULT_LANGUAGE, required = false, converter = LanguageConverter.class) + private Language language; - @Parameter(names = "--minimum-tokens", description = "The minimum token length which should be reported as a duplicate.", required = true) - private int minimumTileSize; + @Parameter(names = "--minimum-tokens", description = "The minimum token length which should be reported as a duplicate.", required = true) + private int minimumTileSize; - @Parameter(names = "--skip-duplicate-files", description = "Ignore multiple copies of files of the same name and length in comparison", required = false) - private boolean skipDuplicates; + @Parameter(names = "--skip-duplicate-files", description = "Ignore multiple copies of files of the same name and length in comparison", required = false) + private boolean skipDuplicates; - @Parameter(names = "--format", description = "Report format. Default value is " - + DEFAULT_RENDERER, required = false) - private String rendererName; + @Parameter(names = "--format", description = "Report format. Default value is " + DEFAULT_RENDERER, required = false) + private String rendererName; - /** - * The actual renderer. constructed by using the {@link #rendererName}. - * This property is only valid after {@link #postContruct()} has been called! - */ - private Renderer renderer; + /** + * The actual renderer. constructed by using the {@link #rendererName}. This + * property is only valid after {@link #postContruct()} has been called! + */ + private Renderer renderer; - private String encoding; + private String encoding; - @Parameter(names = "--ignore-literals", description = "Ignore number values and string contents when comparing text", required = false) - private boolean ignoreLiterals; + @Parameter(names = "--ignore-literals", description = "Ignore number values and string contents when comparing text", required = false) + private boolean ignoreLiterals; - @Parameter(names = "--ignore-identifiers", description = "Ignore constant and variable names when comparing text", required = false) - private boolean ignoreIdentifiers; + @Parameter(names = "--ignore-identifiers", description = "Ignore constant and variable names when comparing text", required = false) + private boolean ignoreIdentifiers; - @Parameter(names = "--ignore-annotations", description = "Ignore language annotations when comparing text", required = false) - private boolean ignoreAnnotations; + @Parameter(names = "--ignore-annotations", description = "Ignore language annotations when comparing text", required = false) + private boolean ignoreAnnotations; - @Parameter(names = "--skip-lexical-errors", description = "Skip files which can't be tokenized due to invalid characters instead of aborting CPD", required = false) - private boolean skipLexicalErrors = false; + @Parameter(names = "--skip-lexical-errors", description = "Skip files which can't be tokenized due to invalid characters instead of aborting CPD", required = false) + private boolean skipLexicalErrors = false; - @Parameter(names = "--no-skip-blocks", description = "Do not skip code blocks marked with --skip-blocks-pattern (e.g. #if 0 until #endif)", required = false) - private boolean noSkipBlocks = false; + @Parameter(names = "--no-skip-blocks", description = "Do not skip code blocks marked with --skip-blocks-pattern (e.g. #if 0 until #endif)", required = false) + private boolean noSkipBlocks = false; - @Parameter(names = "--skip-blocks-pattern", description = "Pattern to find the blocks to skip. Start and End pattern separated by |. " - + "Default is \"" + Tokenizer.DEFAULT_SKIP_BLOCKS_PATTERN + "\".", required = false) - private String skipBlocksPattern = Tokenizer.DEFAULT_SKIP_BLOCKS_PATTERN; + @Parameter(names = "--skip-blocks-pattern", description = "Pattern to find the blocks to skip. Start and End pattern separated by |. " + + "Default is \"" + Tokenizer.DEFAULT_SKIP_BLOCKS_PATTERN + "\".", required = false) + private String skipBlocksPattern = Tokenizer.DEFAULT_SKIP_BLOCKS_PATTERN; - @Parameter(names = "--files", variableArity = true, description = "List of files and directories to process", required = false, converter = FileConverter.class) - private List files; + @Parameter(names = "--files", variableArity = true, description = "List of files and directories to process", required = false, converter = FileConverter.class) + private List files; - @Parameter(names = "--exclude", variableArity = true, description = "Files to be excluded from CPD check", required = false, converter = FileConverter.class) - private List excludes; + @Parameter(names = "--exclude", variableArity = true, description = "Files to be excluded from CPD check", required = false, converter = FileConverter.class) + private List excludes; - @Parameter(names = "--non-recursive", description = "Don't scan subdirectiories", required = false) - private boolean nonRecursive; + @Parameter(names = "--non-recursive", description = "Don't scan subdirectiories", required = false) + private boolean nonRecursive; - @Parameter(names = "--uri", description = "URI to process", required = false) - private String uri; + @Parameter(names = "--uri", description = "URI to process", required = false) + private String uri; - @Parameter(names = { "--help", "-h" }, description = "Print help text", required = false, help = true) - private boolean help; + @Parameter(names = { "--help", "-h" }, description = "Print help text", required = false, help = true) + private boolean help; - // this has to be a public static class, so that JCommander can use it! - public static class LanguageConverter implements IStringConverter { + // this has to be a public static class, so that JCommander can use it! + public static class LanguageConverter implements IStringConverter { + public Language convert(String languageString) { + if (languageString == null || "".equals(languageString)) { + languageString = DEFAULT_LANGUAGE; + } + return LanguageFactory.createLanguage(languageString); + } + } - public Language convert(String languageString) { - if (languageString == null || "".equals(languageString)) { - languageString = DEFAULT_LANGUAGE; - } - return LanguageFactory.createLanguage(languageString); - } - } + public CPDConfiguration() { + } - public CPDConfiguration() - { - } + @Deprecated + public CPDConfiguration(int minimumTileSize, Language language, String encoding) { + setMinimumTileSize(minimumTileSize); + setLanguage(language); + setEncoding(encoding); + } - @Deprecated - public CPDConfiguration(int minimumTileSize, Language language, String encoding) - { - setMinimumTileSize(minimumTileSize); - setLanguage(language); - setEncoding(encoding); - } + @Parameter(names = "--encoding", description = "Character encoding to use when processing files", required = false) + public void setEncoding(String encoding) { + this.encoding = encoding; + setSourceEncoding(encoding); + } + public SourceCode sourceCodeFor(File file) { + return new SourceCode(new SourceCode.FileCodeLoader(file, getSourceEncoding())); + } - @Parameter(names = "--encoding", description = "Character encoding to use when processing files", required = false) - public void setEncoding(String encoding) { - this.encoding = encoding; - setSourceEncoding(encoding); - } + public SourceCode sourceCodeFor(Reader reader, String sourceCodeName) { + return new SourceCode(new SourceCode.ReaderCodeLoader(reader, sourceCodeName)); + } - public SourceCode sourceCodeFor(File file) { - return new SourceCode(new SourceCode.FileCodeLoader(file, - getSourceEncoding())); - } - - public SourceCode sourceCodeFor(Reader reader, String sourceCodeName ) { - return new SourceCode(new SourceCode.ReaderCodeLoader(reader, sourceCodeName )); - } - - public void postContruct() { - if ( this.getLanguage() == null ) { - this.setLanguage(CPDConfiguration.getLanguageFromString(DEFAULT_LANGUAGE)); - } - if (this.getRendererName() == null ) { - this.setRendererName(DEFAULT_RENDERER); - } - if ( this.getRenderer() == null ) { - this.setRenderer(getRendererFromString(getRendererName(), this.getEncoding())); - } - } + public void postContruct() { + if (this.getLanguage() == null) { + this.setLanguage(CPDConfiguration.getLanguageFromString(DEFAULT_LANGUAGE)); + } + if (this.getRendererName() == null) { + this.setRendererName(DEFAULT_RENDERER); + } + if (this.getRenderer() == null) { + this.setRenderer(getRendererFromString(getRendererName(), this.getEncoding())); + } + } /** * Gets a renderer with the platform's default encoding. + * * @param name renderer name * @return a fresh renderer instance * @deprecated use {@link #getRendererFromString(String, String)} instead @@ -154,28 +148,29 @@ public class CPDConfiguration extends AbstractConfiguration { return getRendererFromString(name, System.getProperty("file.encoding")); } - private static final Map> renderers = new HashMap>(); + private static final Map> RENDERERS = new HashMap>(); static { - renderers.put(DEFAULT_RENDERER, SimpleRenderer.class); - renderers.put("xml", XMLRenderer.class); - renderers.put("csv", CSVRenderer.class); - renderers.put("csv_with_linecount_per_file", CSVWithLinecountPerFileRenderer.class); - renderers.put("vs", VSRenderer.class); + RENDERERS.put(DEFAULT_RENDERER, SimpleRenderer.class); + RENDERERS.put("xml", XMLRenderer.class); + RENDERERS.put("csv", CSVRenderer.class); + RENDERERS.put("csv_with_linecount_per_file", CSVWithLinecountPerFileRenderer.class); + RENDERERS.put("vs", VSRenderer.class); } - public static Renderer getRendererFromString(String name, String encoding) { - String clazzname = name; - if (clazzname == null || "".equals(clazzname)) { - clazzname = DEFAULT_RENDERER; - } - Class clazz = renderers.get(clazzname.toLowerCase(Locale.ROOT)); - if (clazz == null) { - try { - clazz = Class.forName(clazzname).asSubclass(Renderer.class); - } catch (ClassNotFoundException e) { - System.err.println("Can't find class '" + name + "', defaulting to SimpleRenderer."); - clazz = SimpleRenderer.class; - } - } + + public static Renderer getRendererFromString(String name, String encoding) { + String clazzname = name; + if (clazzname == null || "".equals(clazzname)) { + clazzname = DEFAULT_RENDERER; + } + Class clazz = RENDERERS.get(clazzname.toLowerCase(Locale.ROOT)); + if (clazz == null) { + try { + clazz = Class.forName(clazzname).asSubclass(Renderer.class); + } catch (ClassNotFoundException e) { + System.err.println("Can't find class '" + name + "', defaulting to SimpleRenderer."); + clazz = SimpleRenderer.class; + } + } try { Renderer renderer = clazz.getDeclaredConstructor().newInstance(); @@ -185,85 +180,86 @@ public class CPDConfiguration extends AbstractConfiguration { method.invoke(renderer, encoding); } return renderer; - } catch (Exception e) { - System.err.println("Couldn't instantiate renderer, defaulting to SimpleRenderer: " + e); - return new SimpleRenderer(); - } - } - public static String[] getRenderers() { - String[] result = renderers.keySet().toArray(new String[renderers.size()]); - Arrays.sort(result); - return result; - } + } catch (Exception e) { + System.err.println("Couldn't instantiate renderer, defaulting to SimpleRenderer: " + e); + return new SimpleRenderer(); + } + } - public static Language getLanguageFromString(String languageString) { - return LanguageFactory.createLanguage(languageString); - } + public static String[] getRenderers() { + String[] result = RENDERERS.keySet().toArray(new String[RENDERERS.size()]); + Arrays.sort(result); + return result; + } - public static void setSystemProperties(CPDConfiguration configuration) { - Properties properties = new Properties(); - if (configuration.isIgnoreLiterals()) { - properties.setProperty(Tokenizer.IGNORE_LITERALS, "true"); - } else { - properties.remove(Tokenizer.IGNORE_LITERALS); - } - if (configuration.isIgnoreIdentifiers()) { - properties.setProperty(Tokenizer.IGNORE_IDENTIFIERS, "true"); + public static Language getLanguageFromString(String languageString) { + return LanguageFactory.createLanguage(languageString); + } + + public static void setSystemProperties(CPDConfiguration configuration) { + Properties properties = new Properties(); + if (configuration.isIgnoreLiterals()) { + properties.setProperty(Tokenizer.IGNORE_LITERALS, "true"); + } else { + properties.remove(Tokenizer.IGNORE_LITERALS); + } + if (configuration.isIgnoreIdentifiers()) { + properties.setProperty(Tokenizer.IGNORE_IDENTIFIERS, "true"); } else { properties.remove(Tokenizer.IGNORE_IDENTIFIERS); - } - if (configuration.isIgnoreAnnotations()) { - properties.setProperty(Tokenizer.IGNORE_ANNOTATIONS, "true"); + } + if (configuration.isIgnoreAnnotations()) { + properties.setProperty(Tokenizer.IGNORE_ANNOTATIONS, "true"); } else { properties.remove(Tokenizer.IGNORE_ANNOTATIONS); - } - properties.setProperty(Tokenizer.OPTION_SKIP_BLOCKS, Boolean.toString(!configuration.isNoSkipBlocks())); - properties.setProperty(Tokenizer.OPTION_SKIP_BLOCKS_PATTERN, configuration.getSkipBlocksPattern()); - configuration.getLanguage().setProperties(properties); - } + } + properties.setProperty(Tokenizer.OPTION_SKIP_BLOCKS, Boolean.toString(!configuration.isNoSkipBlocks())); + properties.setProperty(Tokenizer.OPTION_SKIP_BLOCKS_PATTERN, configuration.getSkipBlocksPattern()); + configuration.getLanguage().setProperties(properties); + } - public Language getLanguage() { - return language; - } + public Language getLanguage() { + return language; + } - public void setLanguage(Language language) { - this.language = language; - } + public void setLanguage(Language language) { + this.language = language; + } - public int getMinimumTileSize() { - return minimumTileSize; - } + public int getMinimumTileSize() { + return minimumTileSize; + } - public void setMinimumTileSize(int minimumTileSize) { - this.minimumTileSize = minimumTileSize; - } + public void setMinimumTileSize(int minimumTileSize) { + this.minimumTileSize = minimumTileSize; + } - public boolean isSkipDuplicates() { - return skipDuplicates; - } + public boolean isSkipDuplicates() { + return skipDuplicates; + } - public void setSkipDuplicates(boolean skipDuplicates) { - this.skipDuplicates = skipDuplicates; - } + public void setSkipDuplicates(boolean skipDuplicates) { + this.skipDuplicates = skipDuplicates; + } - public String getRendererName() { - return rendererName; - } + public String getRendererName() { + return rendererName; + } - public void setRendererName(String rendererName) { - this.rendererName = rendererName; - } + public void setRendererName(String rendererName) { + this.rendererName = rendererName; + } - public Renderer getRenderer() { - return renderer; - } + public Renderer getRenderer() { + return renderer; + } - public Tokenizer tokenizer() { - if ( language == null ) { - throw new IllegalStateException("Language is null."); - } - return language.getTokenizer(); - } + public Tokenizer tokenizer() { + if (language == null) { + throw new IllegalStateException("Language is null."); + } + return language.getTokenizer(); + } public FilenameFilter filenameFilter() { if (language == null) { @@ -300,85 +296,85 @@ public class CPDConfiguration extends AbstractConfiguration { return filter; } - public void setRenderer(Renderer renderer) { - this.renderer = renderer; - } + public void setRenderer(Renderer renderer) { + this.renderer = renderer; + } - public boolean isIgnoreLiterals() { - return ignoreLiterals; - } + public boolean isIgnoreLiterals() { + return ignoreLiterals; + } - public void setIgnoreLiterals(boolean ignoreLiterals) { - this.ignoreLiterals = ignoreLiterals; - } + public void setIgnoreLiterals(boolean ignoreLiterals) { + this.ignoreLiterals = ignoreLiterals; + } - public boolean isIgnoreIdentifiers() { - return ignoreIdentifiers; - } + public boolean isIgnoreIdentifiers() { + return ignoreIdentifiers; + } - public void setIgnoreIdentifiers(boolean ignoreIdentifiers) { - this.ignoreIdentifiers = ignoreIdentifiers; - } + public void setIgnoreIdentifiers(boolean ignoreIdentifiers) { + this.ignoreIdentifiers = ignoreIdentifiers; + } - public boolean isIgnoreAnnotations() { - return ignoreAnnotations; - } + public boolean isIgnoreAnnotations() { + return ignoreAnnotations; + } - public void setIgnoreAnnotations(boolean ignoreAnnotations) { - this.ignoreAnnotations = ignoreAnnotations; - } + public void setIgnoreAnnotations(boolean ignoreAnnotations) { + this.ignoreAnnotations = ignoreAnnotations; + } - public boolean isSkipLexicalErrors() { - return skipLexicalErrors; - } + public boolean isSkipLexicalErrors() { + return skipLexicalErrors; + } - public void setSkipLexicalErrors(boolean skipLexicalErrors) { - this.skipLexicalErrors = skipLexicalErrors; - } + public void setSkipLexicalErrors(boolean skipLexicalErrors) { + this.skipLexicalErrors = skipLexicalErrors; + } - public List getFiles() { - return files; - } + public List getFiles() { + return files; + } - public void setFiles(List files) { - this.files = files; - } + public void setFiles(List files) { + this.files = files; + } - public String getURI() { - return uri; - } + public String getURI() { + return uri; + } - public void setURI(String uri) { - this.uri = uri; - } + public void setURI(String uri) { + this.uri = uri; + } - public List getExcludes() { - return excludes; - } + public List getExcludes() { + return excludes; + } - public void setExcludes(List excludes) { - this.excludes = excludes; - } + public void setExcludes(List excludes) { + this.excludes = excludes; + } - public boolean isNonRecursive() { - return nonRecursive; - } + public boolean isNonRecursive() { + return nonRecursive; + } - public void setNonRecursive(boolean nonRecursive) { - this.nonRecursive = nonRecursive; - } + public void setNonRecursive(boolean nonRecursive) { + this.nonRecursive = nonRecursive; + } - public boolean isHelp() { - return help; - } + public boolean isHelp() { + return help; + } - public void setHelp(boolean help) { - this.help = help; - } + public void setHelp(boolean help) { + this.help = help; + } - public String getEncoding() { - return encoding; - } + public String getEncoding() { + return encoding; + } public boolean isNoSkipBlocks() { return noSkipBlocks; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageRegistry.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageRegistry.java index 0177bd209a..927b069086 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageRegistry.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageRegistry.java @@ -15,7 +15,7 @@ import java.util.ServiceLoader; */ public final class LanguageRegistry { - private static LanguageRegistry instance; + private static LanguageRegistry instance = new LanguageRegistry(); private Map languages; @@ -27,10 +27,7 @@ public final class LanguageRegistry { } } - protected static LanguageRegistry getInstance() { - if(instance == null) { - instance = new LanguageRegistry(); - } + public static LanguageRegistry getInstance() { return instance; } @@ -57,13 +54,13 @@ public final class LanguageRegistry { public static LanguageVersion findLanguageVersionByTerseName(String terseName) { String version = null; - if(terseName.contains(" ")) { + if (terseName.contains(" ")) { version = terseName.substring(terseName.lastIndexOf(' ') + 1); terseName = terseName.substring(0, terseName.lastIndexOf(' ')); } Language language = findLanguageByTerseName(terseName); - if(language != null) { - if(version == null) { + if (language != null) { + if (version == null) { return language.getDefaultVersion(); } else { return language.getVersion(version); @@ -84,8 +81,8 @@ public final class LanguageRegistry { public static List findAllVersions() { List versions = new ArrayList(); - for(Language language : getLanguages()) { - for(LanguageVersion languageVersion : language.getVersions()) { + for (Language language : getLanguages()) { + for (LanguageVersion languageVersion : language.getVersions()) { versions.add(languageVersion); } } @@ -94,6 +91,7 @@ public final class LanguageRegistry { /** * A utility method to find the Languages which have Rule support. + * * @return A List of Languages with Rule support. */ public static List findWithRuleSupport() { @@ -124,7 +122,7 @@ public final class LanguageRegistry { StringBuilder builder = new StringBuilder(); builder.append(languageVersions.get(0).getTerseName()); - for (int i=1; i braceStack; private List continueBreakReturnStack; - public Linker(DataFlowHandler dataFlowHandler, List braceStack, List continueBreakReturnStack) { - this.dataFlowHandler = dataFlowHandler; - this.braceStack = braceStack; - this.continueBreakReturnStack = continueBreakReturnStack; + public Linker(DataFlowHandler dataFlowHandler, List braceStack, + List continueBreakReturnStack) { + this.dataFlowHandler = dataFlowHandler; + this.braceStack = braceStack; + this.continueBreakReturnStack = continueBreakReturnStack; } /** * Creates all the links between the data flow nodes. */ public void computePaths() throws LinkerException, SequenceException { - LOGGER.entering(CLASS_NAME,"computePaths"); - // Returns true if there are more sequences, computes the first and - // the last index of the sequence. + LOGGER.entering(CLASS_NAME, "computePaths"); + // Returns true if there are more sequences, computes the first and + // the last index of the sequence. LOGGER.fine("SequenceChecking continueBreakReturnStack elements"); - SequenceChecker sc = new SequenceChecker(braceStack); - while (!sc.run()) { - if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.fine("After sc.run - starting Sequence checking loop with firstIndex=" + sc.getFirstIndex() - + ", lastIndex " + sc.getLastIndex() - +" with this StackList "+dump("braceStack",braceStack) - ); - } - if (sc.getFirstIndex() < 0 || sc.getLastIndex() < 0) { - if (LOGGER.isLoggable(Level.SEVERE)) { - LOGGER.severe("Sequence Checker problem: getFirstIndex()==" - + sc.getFirstIndex() + ", getLastIndex()==" + sc.getLastIndex() - ); - } - throw new SequenceException("computePaths(): return index < 0"); - } + SequenceChecker sc = new SequenceChecker(braceStack); + while (!sc.run()) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("After sc.run - starting Sequence checking loop with firstIndex=" + sc.getFirstIndex() + + ", lastIndex " + sc.getLastIndex() + " with this StackList " + dump("braceStack", braceStack)); + } + if (sc.getFirstIndex() < 0 || sc.getLastIndex() < 0) { + if (LOGGER.isLoggable(Level.SEVERE)) { + LOGGER.severe("Sequence Checker problem: getFirstIndex()==" + sc.getFirstIndex() + + ", getLastIndex()==" + sc.getLastIndex()); + } + throw new SequenceException("computePaths(): return index < 0"); + } - StackObject firstStackObject = braceStack.get(sc.getFirstIndex()); + StackObject firstStackObject = braceStack.get(sc.getFirstIndex()); - if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.fine("Checking first braceStack element of type=="+ NodeType.stringFromType(firstStackObject.getType()) ); - } - switch (firstStackObject.getType()) { - case NodeType.IF_EXPR: + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Checking first braceStack element of type==" + + NodeType.stringFromType(firstStackObject.getType())); + } + switch (firstStackObject.getType()) { + case NodeType.IF_EXPR: LOGGER.finest("IF_EXPR"); - int x = sc.getLastIndex() - sc.getFirstIndex(); - if (x == 2) { - this.computeIf(sc.getFirstIndex(), sc.getFirstIndex() + 1, sc.getLastIndex()); - } else if (x == 1) { - this.computeIf(sc.getFirstIndex(), sc.getLastIndex()); - } else { + int x = sc.getLastIndex() - sc.getFirstIndex(); + if (x == 2) { + this.computeIf(sc.getFirstIndex(), sc.getFirstIndex() + 1, sc.getLastIndex()); + } else if (x == 1) { + this.computeIf(sc.getFirstIndex(), sc.getLastIndex()); + } else { LOGGER.severe("Error - computePaths 1"); - } - break; + } + break; - case NodeType.WHILE_EXPR: + case NodeType.WHILE_EXPR: LOGGER.finest("WHILE_EXPR"); - this.computeWhile(sc.getFirstIndex(), sc.getLastIndex()); - break; + this.computeWhile(sc.getFirstIndex(), sc.getLastIndex()); + break; - case NodeType.SWITCH_START: + case NodeType.SWITCH_START: LOGGER.finest("SWITCH_START"); - this.computeSwitch(sc.getFirstIndex(), sc.getLastIndex()); - break; + this.computeSwitch(sc.getFirstIndex(), sc.getLastIndex()); + break; - case NodeType.FOR_INIT: - case NodeType.FOR_EXPR: - case NodeType.FOR_UPDATE: - case NodeType.FOR_BEFORE_FIRST_STATEMENT: + case NodeType.FOR_INIT: + case NodeType.FOR_EXPR: + case NodeType.FOR_UPDATE: + case NodeType.FOR_BEFORE_FIRST_STATEMENT: LOGGER.finest("FOR_EXPR"); - this.computeFor(sc.getFirstIndex(), sc.getLastIndex()); - break; + this.computeFor(sc.getFirstIndex(), sc.getLastIndex()); + break; - case NodeType.DO_BEFORE_FIRST_STATEMENT: + case NodeType.DO_BEFORE_FIRST_STATEMENT: LOGGER.finest("DO_BEFORE_FIRST_STATEMENT"); - this.computeDo(sc.getFirstIndex(), sc.getLastIndex()); - break; + this.computeDo(sc.getFirstIndex(), sc.getLastIndex()); + break; - default: - } + default: + } - if (LOGGER.isLoggable(Level.FINEST)) { - LOGGER.finest("Removing braces from Last to first: " + sc.getLastIndex() + " to " + sc.getFirstIndex()); - } - for (int y = sc.getLastIndex(); y >= sc.getFirstIndex(); y--) { - if (LOGGER.isLoggable(Level.FINEST)) { - LOGGER.finest("Removing brace : " + y ); - } - braceStack.remove(y); - } - if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.fine("Completed Sequence checking loop" + braceStack ); - } - } - if (LOGGER.isLoggable(Level.FINER)) - { - LOGGER.log(Level.FINER, "After Sequence checking loop : remaining braces=={0}", - dump("braceStack", braceStack)); + if (LOGGER.isLoggable(Level.FINEST)) { + LOGGER.finest("Removing braces from Last to first: " + sc.getLastIndex() + " to " + sc.getFirstIndex()); + } + for (int y = sc.getLastIndex(); y >= sc.getFirstIndex(); y--) { + if (LOGGER.isLoggable(Level.FINEST)) { + LOGGER.finest("Removing brace : " + y); + } + braceStack.remove(y); + } + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Completed Sequence checking loop" + braceStack); + } + } + if (LOGGER.isLoggable(Level.FINER)) { + LOGGER.log(Level.FINER, "After Sequence checking loop : remaining braces=={0}", + dump("braceStack", braceStack)); } - LOGGER.fine("Processing continueBreakReturnStack elements"); - while (!continueBreakReturnStack.isEmpty()) { - LOGGER.fine("Starting continueBreakReturnStack processing loop" ); - StackObject stackObject = continueBreakReturnStack.get(0); - DataFlowNode node = stackObject.getDataFlowNode(); + while (!continueBreakReturnStack.isEmpty()) { + LOGGER.fine("Starting continueBreakReturnStack processing loop"); + StackObject stackObject = continueBreakReturnStack.get(0); + DataFlowNode node = stackObject.getDataFlowNode(); - switch (stackObject.getType()) { - case NodeType.THROW_STATEMENT: - LOGGER.finest("CBR: THROW_STATEMENT"); - // do the same like a return - case NodeType.RETURN_STATEMENT: - LOGGER.finest("CBR: RETURN_STATEMENT"); - // remove all children (should contain only one child) - node.removePathToChild(node.getChildren().get(0)); - DataFlowNode lastNode = node.getFlow().get(node.getFlow().size() - 1); - node.addPathToChild(lastNode); - continueBreakReturnStack.remove(0); - break; - case NodeType.BREAK_STATEMENT: + switch (stackObject.getType()) { + case NodeType.THROW_STATEMENT: + // do the same like a return + case NodeType.RETURN_STATEMENT: + if (LOGGER.isLoggable(Level.FINEST)) { + LOGGER.finest("CBR: " + NodeType.stringFromType(stackObject.getType())); + } + // remove all children (should contain only one child) + node.removePathToChild(node.getChildren().get(0)); + DataFlowNode lastNode = node.getFlow().get(node.getFlow().size() - 1); + node.addPathToChild(lastNode); + continueBreakReturnStack.remove(0); + break; + case NodeType.BREAK_STATEMENT: LOGGER.finest("CBR: BREAK_STATEMENT"); - DataFlowNode last = getNodeToBreakStatement(node); - node.removePathToChild(node.getChildren().get(0)); - node.addPathToChild(last); - continueBreakReturnStack.remove(0); - break; + DataFlowNode last = getNodeToBreakStatement(node); + node.removePathToChild(node.getChildren().get(0)); + node.addPathToChild(last); + continueBreakReturnStack.remove(0); + break; - case NodeType.CONTINUE_STATEMENT: + case NodeType.CONTINUE_STATEMENT: LOGGER.finest("CBR: CONTINUE_STATEMENT"); - //List cList = node.getFlow(); - /* traverse up the tree and find the first loop start node - */ - /* - for(int i = cList.indexOf(node)-1;i>=0;i--) { - IDataFlowNode n = (IDataFlowNode)cList.get(i); - - if(n.isType(NodeType.FOR_UPDATE) || - n.isType(NodeType.FOR_EXPR) || - n.isType(NodeType.WHILE_EXPR)) { - */ - /* - * while(..) { - * while(...) { - * ... - * } - * continue; - * } - * - * Without this Expression he continues the second - * WHILE loop. The continue statement and the while loop - * have to be in different scopes. - * - * TODO An error occurs if "continue" is even nested in - * scopes other than local loop scopes, like "if". - * The result is, that the data flow isn't build right - * and the pathfinder runs in invinity loop. - * */ - /* if(n.getNode().getScope().equals(node.getNode().getScope())) { - System.err.println("equals"); - continue; - } - else { - System.err.println("don't equals"); - } - - //remove all children (should contain only one child) - node.removePathToChild((IDataFlowNode)node.getChildren().get(0)); - - node.addPathToChild(n); - cbrStack.remove(0); - break; - - }else if(n.isType(NodeType.DO_BEFOR_FIRST_STATEMENT)) { - - IDataFlowNode inode = (IDataFlowNode)n.getFlow().get(n.getIndex()1); - - for(int j=0;j=0;i--) { IDataFlowNode n + * = (IDataFlowNode)cList.get(i); + * + * if(n.isType(NodeType.FOR_UPDATE) || + * n.isType(NodeType.FOR_EXPR) || n.isType(NodeType.WHILE_EXPR)) + * { + */ + /* + * while(..) { while(...) { ... } continue; } + * + * Without this Expression he continues the second WHILE loop. + * The continue statement and the while loop have to be in + * different scopes. + * + * TODO An error occurs if "continue" is even nested in scopes + * other than local loop scopes, like "if". The result is, that + * the data flow isn't build right and the pathfinder runs in + * invinity loop. + */ + /* + * if(n.getNode().getScope().equals(node.getNode().getScope())) + * { System.err.println("equals"); continue; } else { + * System.err.println("don't equals"); } + * + * //remove all children (should contain only one child) + * node.removePathToChild + * ((IDataFlowNode)node.getChildren().get(0)); + * + * node.addPathToChild(n); cbrStack.remove(0); break; + * + * }else if(n.isType(NodeType.DO_BEFOR_FIRST_STATEMENT)) { + * + * IDataFlowNode inode = + * (IDataFlowNode)n.getFlow().get(n.getIndex()1); + * + * for(int j=0;j bList = node.getFlow(); - int findEnds = 1; // ignore ends of other for's while's etc. + LOGGER.entering(CLASS_NAME, "getNodeToBreakStatement"); + // What about breaks to labels above if statements? + List bList = node.getFlow(); + int findEnds = 1; // ignore ends of other for's while's etc. - // find out index of the node where the path goes to after the break - int index = bList.indexOf(node); - for (; index < bList.size() - 2; index++) { - DataFlowNode n = bList.get(index); - if (n.isType(NodeType.DO_EXPR) || n.isType(NodeType.FOR_INIT) || n.isType(NodeType.WHILE_EXPR) - || n.isType(NodeType.SWITCH_START)) { - findEnds++; - } - if (n.isType(NodeType.WHILE_LAST_STATEMENT) || n.isType(NodeType.SWITCH_END) || n.isType(NodeType.FOR_END) - || n.isType(NodeType.DO_EXPR)) { - if (findEnds > 1) { - // thats not the right node - findEnds--; - } else { - break; - } - } + // find out index of the node where the path goes to after the break + int index = bList.indexOf(node); + for (; index < bList.size() - 2; index++) { + DataFlowNode n = bList.get(index); + if (n.isType(NodeType.DO_EXPR) || n.isType(NodeType.FOR_INIT) || n.isType(NodeType.WHILE_EXPR) + || n.isType(NodeType.SWITCH_START)) { + findEnds++; + } + if (n.isType(NodeType.WHILE_LAST_STATEMENT) || n.isType(NodeType.SWITCH_END) || n.isType(NodeType.FOR_END) + || n.isType(NodeType.DO_EXPR)) { + if (findEnds > 1) { + // thats not the right node + findEnds--; + } else { + break; + } + } - if (n.isType(NodeType.LABEL_LAST_STATEMENT)) { - Node parentNode = n.getNode().getFirstParentOfType(dataFlowHandler.getLabelStatementNodeClass()); - if (parentNode == null) { - break; - } else { - String label = node.getNode().getImage(); - if (label == null || label.equals(parentNode.getImage())) { - node.removePathToChild(node.getChildren().get(0)); - DataFlowNode last = bList.get(index + 1); - node.addPathToChild(last); - break; - } - } - } - } - LOGGER.exiting(CLASS_NAME,"getNodeToBreakSttement"); - return node.getFlow().get(index + 1); + if (n.isType(NodeType.LABEL_LAST_STATEMENT)) { + Node parentNode = n.getNode().getFirstParentOfType(dataFlowHandler.getLabelStatementNodeClass()); + if (parentNode == null) { + break; + } else { + String label = node.getNode().getImage(); + if (label == null || label.equals(parentNode.getImage())) { + node.removePathToChild(node.getChildren().get(0)); + DataFlowNode last = bList.get(index + 1); + node.addPathToChild(last); + break; + } + } + } + } + LOGGER.exiting(CLASS_NAME, "getNodeToBreakSttement"); + return node.getFlow().get(index + 1); } private void computeDo(int first, int last) { - LOGGER.entering(CLASS_NAME,"computeDo"); - DataFlowNode doSt = this.braceStack.get(first).getDataFlowNode(); - DataFlowNode doExpr = this.braceStack.get(last).getDataFlowNode(); - DataFlowNode doFirst = doSt.getFlow().get(doSt.getIndex() + 1); - if (doFirst.getIndex() != doExpr.getIndex()) { - doExpr.addPathToChild(doFirst); - } - LOGGER.exiting(CLASS_NAME,"computeDo"); + LOGGER.entering(CLASS_NAME, "computeDo"); + DataFlowNode doSt = this.braceStack.get(first).getDataFlowNode(); + DataFlowNode doExpr = this.braceStack.get(last).getDataFlowNode(); + DataFlowNode doFirst = doSt.getFlow().get(doSt.getIndex() + 1); + if (doFirst.getIndex() != doExpr.getIndex()) { + doExpr.addPathToChild(doFirst); + } + LOGGER.exiting(CLASS_NAME, "computeDo"); } private void computeFor(int firstIndex, int lastIndex) { - LOGGER.entering(CLASS_NAME,"computeFor"); - DataFlowNode fExpr = null; - DataFlowNode fUpdate = null; - DataFlowNode fSt = null; - DataFlowNode fEnd = null; - boolean isUpdate = false; + LOGGER.entering(CLASS_NAME, "computeFor"); + DataFlowNode fExpr = null; + DataFlowNode fUpdate = null; + DataFlowNode fSt = null; + DataFlowNode fEnd = null; + boolean isUpdate = false; - for (int i = firstIndex; i <= lastIndex; i++) { - StackObject so = this.braceStack.get(i); - DataFlowNode node = so.getDataFlowNode(); + for (int i = firstIndex; i <= lastIndex; i++) { + StackObject so = this.braceStack.get(i); + DataFlowNode node = so.getDataFlowNode(); - if (so.getType() == NodeType.FOR_EXPR) { - fExpr = node; - } else if (so.getType() == NodeType.FOR_UPDATE) { - fUpdate = node; - isUpdate = true; - } else if (so.getType() == NodeType.FOR_BEFORE_FIRST_STATEMENT) { - fSt = node; - } else if (so.getType() == NodeType.FOR_END) { - fEnd = node; - } - } - DataFlowNode end = fEnd.getFlow().get(fEnd.getIndex() + 1); + if (so.getType() == NodeType.FOR_EXPR) { + fExpr = node; + } else if (so.getType() == NodeType.FOR_UPDATE) { + fUpdate = node; + isUpdate = true; + } else if (so.getType() == NodeType.FOR_BEFORE_FIRST_STATEMENT) { + fSt = node; + } else if (so.getType() == NodeType.FOR_END) { + fEnd = node; + } + } + DataFlowNode end = fEnd.getFlow().get(fEnd.getIndex() + 1); - DataFlowNode firstSt = fSt.getChildren().get(0); + DataFlowNode firstSt = fSt.getChildren().get(0); - if (isUpdate) { - if (fSt.getIndex() != fEnd.getIndex()) { - end.reverseParentPathsTo(fUpdate); - fExpr.removePathToChild(fUpdate); - fUpdate.addPathToChild(fExpr); - fUpdate.removePathToChild(firstSt); - fExpr.addPathToChild(firstSt); - fExpr.addPathToChild(end); - } else { - fSt.removePathToChild(end); - fExpr.removePathToChild(fUpdate); - fUpdate.addPathToChild(fExpr); - fExpr.addPathToChild(fUpdate); - fExpr.addPathToChild(end); - } - } else { - if (fSt.getIndex() != fEnd.getIndex()) { - end.reverseParentPathsTo(fExpr); - fExpr.addPathToChild(end); - } - } - LOGGER.exiting(CLASS_NAME,"computeFor"); + if (isUpdate) { + if (fSt.getIndex() != fEnd.getIndex()) { + end.reverseParentPathsTo(fUpdate); + fExpr.removePathToChild(fUpdate); + fUpdate.addPathToChild(fExpr); + fUpdate.removePathToChild(firstSt); + fExpr.addPathToChild(firstSt); + fExpr.addPathToChild(end); + } else { + fSt.removePathToChild(end); + fExpr.removePathToChild(fUpdate); + fUpdate.addPathToChild(fExpr); + fExpr.addPathToChild(fUpdate); + fExpr.addPathToChild(end); + } + } else { + if (fSt.getIndex() != fEnd.getIndex()) { + end.reverseParentPathsTo(fExpr); + fExpr.addPathToChild(end); + } + } + LOGGER.exiting(CLASS_NAME, "computeFor"); } private void computeSwitch(int firstIndex, int lastIndex) { - LOGGER.entering(CLASS_NAME,"computeSwitch" ); + LOGGER.entering(CLASS_NAME, "computeSwitch"); - int diff = lastIndex - firstIndex; - boolean defaultStatement = false; + int diff = lastIndex - firstIndex; + boolean defaultStatement = false; - DataFlowNode sStart = this.braceStack.get(firstIndex).getDataFlowNode(); - DataFlowNode sEnd = this.braceStack.get(lastIndex).getDataFlowNode(); - DataFlowNode end = sEnd.getChildren().get(0); + DataFlowNode sStart = this.braceStack.get(firstIndex).getDataFlowNode(); + DataFlowNode sEnd = this.braceStack.get(lastIndex).getDataFlowNode(); + DataFlowNode end = sEnd.getChildren().get(0); - if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.fine( - "Stack(sStart)=>" + sStart - +",Stack(sEnd)=>" + sEnd - +",end=>" + end - ); - } + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Stack(sStart)=>" + sStart + ",Stack(sEnd)=>" + sEnd + ",end=>" + end); + } - for (int i = 0; i < diff - 2; i++) { - StackObject so = this.braceStack.get(firstIndex + 2 + i); - DataFlowNode node = so.getDataFlowNode(); + for (int i = 0; i < diff - 2; i++) { + StackObject so = this.braceStack.get(firstIndex + 2 + i); + DataFlowNode node = so.getDataFlowNode(); - if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.fine( "so(" + (firstIndex + 2 + i) + ")=>" + so - +" has dfn=>" + node - +" with first child =>" + node.getChildren().get(0) - ); - } - sStart.addPathToChild(node.getChildren().get(0)); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("so(" + (firstIndex + 2 + i) + ")=>" + so + " has dfn=>" + node + " with first child =>" + + node.getChildren().get(0)); + } + sStart.addPathToChild(node.getChildren().get(0)); - if (so.getType() == NodeType.SWITCH_LAST_DEFAULT_STATEMENT) { - defaultStatement = true; - } - } + if (so.getType() == NodeType.SWITCH_LAST_DEFAULT_STATEMENT) { + defaultStatement = true; + } + } - if (!defaultStatement) { - sStart.addPathToChild(end); - } - LOGGER.exiting(CLASS_NAME,"computeSwitch"); + if (!defaultStatement) { + sStart.addPathToChild(end); + } + LOGGER.exiting(CLASS_NAME, "computeSwitch"); } private void computeWhile(int first, int last) { - LOGGER.entering(CLASS_NAME,"computeWhile with first and last of" - + first + "," + last - ); - DataFlowNode wStart = this.braceStack.get(first).getDataFlowNode(); - DataFlowNode wEnd = this.braceStack.get(last).getDataFlowNode(); + LOGGER.entering(CLASS_NAME, "computeWhile with first and last of" + first + "," + last); + DataFlowNode wStart = this.braceStack.get(first).getDataFlowNode(); + DataFlowNode wEnd = this.braceStack.get(last).getDataFlowNode(); - DataFlowNode end = wEnd.getFlow().get(wEnd.getIndex() + 1); + DataFlowNode end = wEnd.getFlow().get(wEnd.getIndex() + 1); - if (wStart.getIndex() != wEnd.getIndex()) { - end.reverseParentPathsTo(wStart); - wStart.addPathToChild(end); - } - LOGGER.exiting(CLASS_NAME,"computeWhile"); + if (wStart.getIndex() != wEnd.getIndex()) { + end.reverseParentPathsTo(wStart); + wStart.addPathToChild(end); + } + LOGGER.exiting(CLASS_NAME, "computeWhile"); } private void computeIf(int first, int second, int last) { - LOGGER.entering(CLASS_NAME,"computeIf(3)",first+","+ second +","+ last); - DataFlowNode ifStart = this.braceStack.get(first).getDataFlowNode(); - DataFlowNode ifEnd = this.braceStack.get(second).getDataFlowNode(); - DataFlowNode elseEnd = this.braceStack.get(last).getDataFlowNode(); + LOGGER.entering(CLASS_NAME, "computeIf(3)", first + "," + second + "," + last); + DataFlowNode ifStart = this.braceStack.get(first).getDataFlowNode(); + DataFlowNode ifEnd = this.braceStack.get(second).getDataFlowNode(); + DataFlowNode elseEnd = this.braceStack.get(last).getDataFlowNode(); - DataFlowNode elseStart = ifEnd.getFlow().get(ifEnd.getIndex() + 1); - DataFlowNode end = elseEnd.getFlow().get(elseEnd.getIndex() + 1); + DataFlowNode elseStart = ifEnd.getFlow().get(ifEnd.getIndex() + 1); + DataFlowNode end = elseEnd.getFlow().get(elseEnd.getIndex() + 1); - LOGGER.log(Level.FINEST, "If ifstart={0}, ifEnd={1}, elseEnd={2}, elseStart={3}, end={4}" - , new Object[]{ifStart, ifEnd, elseEnd, elseStart, end} - ); + LOGGER.log(Level.FINEST, "If ifstart={0}, ifEnd={1}, elseEnd={2}, elseStart={3}, end={4}", new Object[] { + ifStart, ifEnd, elseEnd, elseStart, end }); - // if if-statement and else-statement contains statements or expressions - if (ifStart.getIndex() != ifEnd.getIndex() && ifEnd.getIndex() != elseEnd.getIndex()) { - elseStart.reverseParentPathsTo(end); - ifStart.addPathToChild(elseStart); - } - // if only if-statement contains no expressions - else if (ifStart.getIndex() == ifEnd.getIndex() && ifEnd.getIndex() != elseEnd.getIndex()) { - ifStart.addPathToChild(end); - } - // if only else-statement contains no expressions - else if (ifEnd.getIndex() == elseEnd.getIndex() && ifStart.getIndex() != ifEnd.getIndex()) { - ifStart.addPathToChild(end); - } - LOGGER.exiting(CLASS_NAME,"computeIf(3)"); + // if if-statement and else-statement contains statements or expressions + if (ifStart.getIndex() != ifEnd.getIndex() && ifEnd.getIndex() != elseEnd.getIndex()) { + elseStart.reverseParentPathsTo(end); + ifStart.addPathToChild(elseStart); + } + // if only if-statement contains no expressions + else if (ifStart.getIndex() == ifEnd.getIndex() && ifEnd.getIndex() != elseEnd.getIndex()) { + ifStart.addPathToChild(end); + } + // if only else-statement contains no expressions + else if (ifEnd.getIndex() == elseEnd.getIndex() && ifStart.getIndex() != ifEnd.getIndex()) { + ifStart.addPathToChild(end); + } + LOGGER.exiting(CLASS_NAME, "computeIf(3)"); } private void computeIf(int first, int last) { - LOGGER.entering(CLASS_NAME,"computeIf(2)"); - DataFlowNode ifStart = this.braceStack.get(first).getDataFlowNode(); - DataFlowNode ifEnd = this.braceStack.get(last).getDataFlowNode(); + LOGGER.entering(CLASS_NAME, "computeIf(2)"); + DataFlowNode ifStart = this.braceStack.get(first).getDataFlowNode(); + DataFlowNode ifEnd = this.braceStack.get(last).getDataFlowNode(); - // only if the if-statement contains another Statement or Expression - if (ifStart.getIndex() != ifEnd.getIndex()) { - DataFlowNode end = ifEnd.getFlow().get(ifEnd.getIndex() + 1); - ifStart.addPathToChild(end); - } - LOGGER.exiting(CLASS_NAME,"computeIf(2)"); + // only if the if-statement contains another Statement or Expression + if (ifStart.getIndex() != ifEnd.getIndex()) { + DataFlowNode end = ifEnd.getFlow().get(ifEnd.getIndex() + 1); + ifStart.addPathToChild(end); + } + LOGGER.exiting(CLASS_NAME, "computeIf(2)"); } + /** * * @return formatted dump of the StackList */ - private static String dump(String description, List stackList) { - StringBuilder stringDump = new StringBuilder("Stack List ("); - stringDump.append(description).append(") ListDump:\n"); - for (StackObject stackObject : stackList ) - { - stringDump.append ('\n').append(stackObject.toString()); - } - return stringDump.toString(); + private static String dump(String description, List stackList) { + StringBuilder stringDump = new StringBuilder("Stack List ("); + stringDump.append(description).append(") ListDump:\n"); + for (StackObject stackObject : stackList) { + stringDump.append('\n').append(stackObject.toString()); + } + return stringDump.toString(); } - } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/NodeType.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/NodeType.java index 3de99d107c..a142dd54d8 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/NodeType.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/NodeType.java @@ -44,43 +44,45 @@ public class NodeType { // TODO - throw statements? public static final int THROW_STATEMENT = 70; - //Poor Man's Enum until we convert the class to real enum + // Poor Man's Enum until we convert the class to real enum private static final Map TYPE_MAP = new HashMap(); static { - TYPE_MAP.put(NodeType.IF_EXPR, "IF_EXPR"); - TYPE_MAP.put(NodeType.IF_LAST_STATEMENT, "IF_LAST_STATEMENT"); - TYPE_MAP.put(NodeType.IF_LAST_STATEMENT_WITHOUT_ELSE, "IF_LAST_STATEMENT_WITHOUT_ELSE"); - TYPE_MAP.put(NodeType.ELSE_LAST_STATEMENT, "ELSE_LAST_STATEMENT"); - TYPE_MAP.put(NodeType.WHILE_LAST_STATEMENT, "WHILE_LAST_STATEMENT"); - TYPE_MAP.put(NodeType.WHILE_EXPR, "WHILE_EXPR"); - TYPE_MAP.put(NodeType.SWITCH_START, "SWITCH_START"); - TYPE_MAP.put(NodeType.CASE_LAST_STATEMENT, "CASE_LAST_STATEMENT"); - TYPE_MAP.put(NodeType.SWITCH_LAST_DEFAULT_STATEMENT, "SWITCH_LAST_DEFAULT_STATEMENT"); - TYPE_MAP.put(NodeType.SWITCH_END, "SWITCH_END"); - TYPE_MAP.put(NodeType.FOR_INIT, "FOR_INIT"); - TYPE_MAP.put(NodeType.FOR_EXPR, "FOR_EXPR"); - TYPE_MAP.put(NodeType.FOR_UPDATE, "FOR_UPDATE"); - TYPE_MAP.put(NodeType.FOR_BEFORE_FIRST_STATEMENT, "FOR_BEFORE_FIRST_STATEMENT"); - TYPE_MAP.put(NodeType.FOR_END, "FOR_END"); - TYPE_MAP.put(NodeType.DO_BEFORE_FIRST_STATEMENT, "DO_BEFORE_FIRST_STATEMENT"); - TYPE_MAP.put(NodeType.DO_EXPR, "DO_EXPR"); - TYPE_MAP.put(NodeType.RETURN_STATEMENT, "RETURN_STATEMENT"); - TYPE_MAP.put(NodeType.BREAK_STATEMENT, "BREAK_STATEMENT"); - TYPE_MAP.put(NodeType.CONTINUE_STATEMENT, "CONTINUE_STATEMENT"); - TYPE_MAP.put(NodeType.LABEL_STATEMENT, "LABEL_STATEMENT"); - TYPE_MAP.put(NodeType.LABEL_LAST_STATEMENT, "LABEL_END"); - TYPE_MAP.put(NodeType.THROW_STATEMENT, "THROW_STATEMENT"); + TYPE_MAP.put(NodeType.IF_EXPR, "IF_EXPR"); + TYPE_MAP.put(NodeType.IF_LAST_STATEMENT, "IF_LAST_STATEMENT"); + TYPE_MAP.put(NodeType.IF_LAST_STATEMENT_WITHOUT_ELSE, "IF_LAST_STATEMENT_WITHOUT_ELSE"); + TYPE_MAP.put(NodeType.ELSE_LAST_STATEMENT, "ELSE_LAST_STATEMENT"); + TYPE_MAP.put(NodeType.WHILE_LAST_STATEMENT, "WHILE_LAST_STATEMENT"); + TYPE_MAP.put(NodeType.WHILE_EXPR, "WHILE_EXPR"); + TYPE_MAP.put(NodeType.SWITCH_START, "SWITCH_START"); + TYPE_MAP.put(NodeType.CASE_LAST_STATEMENT, "CASE_LAST_STATEMENT"); + TYPE_MAP.put(NodeType.SWITCH_LAST_DEFAULT_STATEMENT, "SWITCH_LAST_DEFAULT_STATEMENT"); + TYPE_MAP.put(NodeType.SWITCH_END, "SWITCH_END"); + TYPE_MAP.put(NodeType.FOR_INIT, "FOR_INIT"); + TYPE_MAP.put(NodeType.FOR_EXPR, "FOR_EXPR"); + TYPE_MAP.put(NodeType.FOR_UPDATE, "FOR_UPDATE"); + TYPE_MAP.put(NodeType.FOR_BEFORE_FIRST_STATEMENT, "FOR_BEFORE_FIRST_STATEMENT"); + TYPE_MAP.put(NodeType.FOR_END, "FOR_END"); + TYPE_MAP.put(NodeType.DO_BEFORE_FIRST_STATEMENT, "DO_BEFORE_FIRST_STATEMENT"); + TYPE_MAP.put(NodeType.DO_EXPR, "DO_EXPR"); + TYPE_MAP.put(NodeType.RETURN_STATEMENT, "RETURN_STATEMENT"); + TYPE_MAP.put(NodeType.BREAK_STATEMENT, "BREAK_STATEMENT"); + TYPE_MAP.put(NodeType.CONTINUE_STATEMENT, "CONTINUE_STATEMENT"); + TYPE_MAP.put(NodeType.LABEL_STATEMENT, "LABEL_STATEMENT"); + TYPE_MAP.put(NodeType.LABEL_LAST_STATEMENT, "LABEL_END"); + TYPE_MAP.put(NodeType.THROW_STATEMENT, "THROW_STATEMENT"); } - public static Map getTypeMap() { - return TYPE_MAP; - } + return TYPE_MAP; + } + public static String stringFromType(int intype) { - if(-1 == intype) { return "" ; } - if (!TYPE_MAP.containsKey(intype) ) { - throw new RuntimeException("Couldn't find NodeType type id " + intype); - } - return TYPE_MAP.get(intype); - } + if (-1 == intype) { + return ""; + } + if (!TYPE_MAP.containsKey(intype)) { + throw new RuntimeException("Couldn't find NodeType type id " + intype); + } + return TYPE_MAP.get(intype); + } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/SequenceChecker.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/SequenceChecker.java index 01347fa1c5..b9a5289024 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/SequenceChecker.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/SequenceChecker.java @@ -183,7 +183,9 @@ public class SequenceChecker { * StackObjects, preventing infinite loops within the SequenceChecker. */ int maximumIterations = this.bracesList.size() * this.bracesList.size(); - for (int i = 0, l = 0; i < this.bracesList.size(); l++, i++) { + int l = -1; + for (int i = 0; i < this.bracesList.size(); i++) { + l++; StackObject so = bracesList.get(i); if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("Processing bracesList(l,i)=(" + l + "," + i + ") of Type " @@ -196,7 +198,9 @@ public class SequenceChecker { // Attempt to get to this StackObject's NodeType from the current // State aktStatus = this.aktStatus.step(so.getType()); - LOGGER.finest("Transition aktStatus=" + aktStatus); + if (LOGGER.isLoggable(Level.FINEST)) { + LOGGER.finest("Transition aktStatus=" + aktStatus); + } if (aktStatus == null) { // Not a valid Node from the current State if (lookAhead) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleReference.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleReference.java index 92608ff099..5b5a233eb1 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleReference.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleReference.java @@ -22,304 +22,312 @@ import net.sourceforge.pmd.util.StringUtil; * This class represents a Rule which is a reference to Rule defined in another * RuleSet. All details of the Rule are delegated to the underlying referenced * Rule, but those operations which modify overridden aspects of the rule are - * explicitly tracked. Modification operations which set a value to the - * current underlying value do not override. + * explicitly tracked. Modification operations which set a value to the current + * underlying value do not override. */ public class RuleReference extends AbstractDelegateRule { - private Language language; - private LanguageVersion minimumLanguageVersion; - private LanguageVersion maximumLanguageVersion; - private Boolean deprecated; - private String name; - private List> propertyDescriptors; - private Map, Object> propertyValues; - private String message; - private String description; - private List examples; - private String externalInfoUrl; - private RulePriority priority; - private RuleSetReference ruleSetReference; + private Language language; + private LanguageVersion minimumLanguageVersion; + private LanguageVersion maximumLanguageVersion; + private Boolean deprecated; + private String name; + private List> propertyDescriptors; + private Map, Object> propertyValues; + private String message; + private String description; + private List examples; + private String externalInfoUrl; + private RulePriority priority; + private RuleSetReference ruleSetReference; - private static final List> EMPTY_DESCRIPTORS = new ArrayList>(0); + private static final List> EMPTY_DESCRIPTORS = new ArrayList>(0); - public Language getOverriddenLanguage() { - return language; - } + public Language getOverriddenLanguage() { + return language; + } - public RuleReference() { - } + public RuleReference() { + } - public RuleReference(Rule theRule, RuleSetReference theRuleSetReference) { - setRule(theRule); - ruleSetReference = theRuleSetReference; - } + public RuleReference(Rule theRule, RuleSetReference theRuleSetReference) { + setRule(theRule); + ruleSetReference = theRuleSetReference; + } - @Override - public void setLanguage(Language language) { - // Only override if different than current value, or if already overridden. - if (!isSame(language, super.getLanguage()) || this.language != null) { - this.language = language; - super.setLanguage(language); - } - } + @Override + public void setLanguage(Language language) { + // Only override if different than current value, or if already + // overridden. + if (!isSame(language, super.getLanguage()) || this.language != null) { + this.language = language; + super.setLanguage(language); + } + } - public LanguageVersion getOverriddenMinimumLanguageVersion() { - return minimumLanguageVersion; - } + public LanguageVersion getOverriddenMinimumLanguageVersion() { + return minimumLanguageVersion; + } - @Override - public void setMinimumLanguageVersion(LanguageVersion minimumLanguageVersion) { - // Only override if different than current value, or if already overridden. - if (!isSame(minimumLanguageVersion, super.getMinimumLanguageVersion()) || this.minimumLanguageVersion != null) { - this.minimumLanguageVersion = minimumLanguageVersion; - super.setMinimumLanguageVersion(minimumLanguageVersion); - } - } + @Override + public void setMinimumLanguageVersion(LanguageVersion minimumLanguageVersion) { + // Only override if different than current value, or if already + // overridden. + if (!isSame(minimumLanguageVersion, super.getMinimumLanguageVersion()) || this.minimumLanguageVersion != null) { + this.minimumLanguageVersion = minimumLanguageVersion; + super.setMinimumLanguageVersion(minimumLanguageVersion); + } + } - public LanguageVersion getOverriddenMaximumLanguageVersion() { - return maximumLanguageVersion; - } + public LanguageVersion getOverriddenMaximumLanguageVersion() { + return maximumLanguageVersion; + } - @Override - public void setMaximumLanguageVersion(LanguageVersion maximumLanguageVersion) { - // Only override if different than current value, or if already overridden. - if (!isSame(maximumLanguageVersion, super.getMaximumLanguageVersion()) || this.maximumLanguageVersion != null) { - this.maximumLanguageVersion = maximumLanguageVersion; - super.setMaximumLanguageVersion(maximumLanguageVersion); - } - } + @Override + public void setMaximumLanguageVersion(LanguageVersion maximumLanguageVersion) { + // Only override if different than current value, or if already + // overridden. + if (!isSame(maximumLanguageVersion, super.getMaximumLanguageVersion()) || this.maximumLanguageVersion != null) { + this.maximumLanguageVersion = maximumLanguageVersion; + super.setMaximumLanguageVersion(maximumLanguageVersion); + } + } - public Boolean isOverriddenDeprecated() { - return deprecated; - } + public Boolean isOverriddenDeprecated() { + return deprecated; + } - @Override - public boolean isDeprecated() { - return deprecated != null && deprecated.booleanValue(); - } + @Override + public boolean isDeprecated() { + return deprecated != null && deprecated.booleanValue(); + } - @Override - public void setDeprecated(boolean deprecated) { - // Deprecation does not propagate to the underlying Rule. It is the - // Rule reference itself which is being deprecated. - this.deprecated = deprecated ? deprecated : null; - } + @Override + public void setDeprecated(boolean deprecated) { + // Deprecation does not propagate to the underlying Rule. It is the + // Rule reference itself which is being deprecated. + this.deprecated = deprecated ? deprecated : null; + } - public String getOverriddenName() { - return name; - } + public String getOverriddenName() { + return name; + } - public String getOriginalName() { - return super.getName(); - } + public String getOriginalName() { + return super.getName(); + } - @Override - public void setName(String name) { - // Only override if different than current value, or if already overridden. - if (!isSame(name, super.getName()) || this.name != null) { - this.name = name; - } - } + @Override + public void setName(String name) { + // Only override if different than current value, or if already + // overridden. + if (!isSame(name, super.getName()) || this.name != null) { + this.name = name; + } + } - @Override - public String getName() { - if (this.name != null) { - return this.name; - } - return super.getName(); - } + @Override + public String getName() { + if (this.name != null) { + return this.name; + } + return super.getName(); + } - public String getOverriddenMessage() { - return message; - } + public String getOverriddenMessage() { + return message; + } - @Override - public void setMessage(String message) { - // Only override if different than current value, or if already overridden. - if (!isSame(message, super.getMessage()) || this.message != null) { - this.message = message; - super.setMessage(message); - } - } + @Override + public void setMessage(String message) { + // Only override if different than current value, or if already + // overridden. + if (!isSame(message, super.getMessage()) || this.message != null) { + this.message = message; + super.setMessage(message); + } + } - public String getOverriddenDescription() { - return description; - } + public String getOverriddenDescription() { + return description; + } - @Override - public void setDescription(String description) { - // Only override if different than current value, or if already overridden. - if (!isSame(description, super.getDescription()) || this.description != null) { - this.description = description; - super.setDescription(description); - } - } + @Override + public void setDescription(String description) { + // Only override if different than current value, or if already + // overridden. + if (!isSame(description, super.getDescription()) || this.description != null) { + this.description = description; + super.setDescription(description); + } + } - public List getOverriddenExamples() { - return examples; - } + public List getOverriddenExamples() { + return examples; + } - @Override - public void addExample(String example) { - // TODO Meaningful override of examples is hard, because they are merely - // a list of strings. How does one indicate override of a particular - // value? Via index? Rule.setExample(int, String)? But the XML format - // does not provide a means of overriding by index, not unless you took - // the position in the XML file to indicate corresponding index to - // override. But that means you have to override starting from index 0. - // This would be so much easier if examples had to have names, like - // properties. + @Override + public void addExample(String example) { + // TODO Meaningful override of examples is hard, because they are merely + // a list of strings. How does one indicate override of a particular + // value? Via index? Rule.setExample(int, String)? But the XML format + // does not provide a means of overriding by index, not unless you took + // the position in the XML file to indicate corresponding index to + // override. But that means you have to override starting from index 0. + // This would be so much easier if examples had to have names, like + // properties. - // Only override if different than current values. - if (!contains(super.getExamples(), example)) { - if (examples == null) { - examples = new ArrayList(1); - } - // TODO Fix later. To keep example overrides from being unbounded, we're only going to keep track of the last one. - examples.clear(); - examples.add(example); - super.addExample(example); - } - } + // Only override if different than current values. + if (!contains(super.getExamples(), example)) { + if (examples == null) { + examples = new ArrayList(1); + } + // TODO Fix later. To keep example overrides from being unbounded, + // we're only going to keep track of the last one. + examples.clear(); + examples.add(example); + super.addExample(example); + } + } - public String getOverriddenExternalInfoUrl() { - return externalInfoUrl; - } + public String getOverriddenExternalInfoUrl() { + return externalInfoUrl; + } - @Override - public void setExternalInfoUrl(String externalInfoUrl) { - // Only override if different than current value, or if already overridden. - if (!isSame(externalInfoUrl, super.getExternalInfoUrl()) || this.externalInfoUrl != null) { - this.externalInfoUrl = externalInfoUrl; - super.setExternalInfoUrl(externalInfoUrl); - } - } + @Override + public void setExternalInfoUrl(String externalInfoUrl) { + // Only override if different than current value, or if already + // overridden. + if (!isSame(externalInfoUrl, super.getExternalInfoUrl()) || this.externalInfoUrl != null) { + this.externalInfoUrl = externalInfoUrl; + super.setExternalInfoUrl(externalInfoUrl); + } + } - public RulePriority getOverriddenPriority() { - return priority; - } + public RulePriority getOverriddenPriority() { + return priority; + } - @Override - public void setPriority(RulePriority priority) { - // Only override if different than current value, or if already overridden. - if (priority != super.getPriority() || this.priority != null) { - this.priority = priority; - super.setPriority(priority); - } - } + @Override + public void setPriority(RulePriority priority) { + // Only override if different than current value, or if already + // overridden. + if (priority != super.getPriority() || this.priority != null) { + this.priority = priority; + super.setPriority(priority); + } + } - public List> getOverriddenPropertyDescriptors() { + public List> getOverriddenPropertyDescriptors() { - return propertyDescriptors == null ? - EMPTY_DESCRIPTORS : - propertyDescriptors; - } + return propertyDescriptors == null ? EMPTY_DESCRIPTORS : propertyDescriptors; + } - @Override - public void definePropertyDescriptor(PropertyDescriptor propertyDescriptor) throws IllegalArgumentException { - // Define on the underlying Rule, where it is impossible to have two - // property descriptors with the same name. Therefore, there is no need - // to check if the property is already overridden at this level. - super.definePropertyDescriptor(propertyDescriptor); - if (propertyDescriptors == null) { - propertyDescriptors = new ArrayList>(); - } - propertyDescriptors.add(propertyDescriptor); - } + @Override + public void definePropertyDescriptor(PropertyDescriptor propertyDescriptor) throws IllegalArgumentException { + // Define on the underlying Rule, where it is impossible to have two + // property descriptors with the same name. Therefore, there is no need + // to check if the property is already overridden at this level. + super.definePropertyDescriptor(propertyDescriptor); + if (propertyDescriptors == null) { + propertyDescriptors = new ArrayList>(); + } + propertyDescriptors.add(propertyDescriptor); + } - public Map, Object> getOverriddenPropertiesByPropertyDescriptor() { - return propertyValues; - } + public Map, Object> getOverriddenPropertiesByPropertyDescriptor() { + return propertyValues; + } - @Override - public void setProperty(PropertyDescriptor propertyDescriptor, T value) { - // Only override if different than current value. - if (!isSame(super.getProperty(propertyDescriptor), value)) { - if (propertyValues == null) { - propertyValues = new HashMap, Object>(); - } - propertyValues.put(propertyDescriptor, value); - super.setProperty(propertyDescriptor, value); - } - } + @Override + public void setProperty(PropertyDescriptor propertyDescriptor, T value) { + // Only override if different than current value. + if (!isSame(super.getProperty(propertyDescriptor), value)) { + if (propertyValues == null) { + propertyValues = new HashMap, Object>(); + } + propertyValues.put(propertyDescriptor, value); + super.setProperty(propertyDescriptor, value); + } + } - public RuleSetReference getRuleSetReference() { - return ruleSetReference; - } + public RuleSetReference getRuleSetReference() { + return ruleSetReference; + } - public void setRuleSetReference(RuleSetReference ruleSetReference) { - this.ruleSetReference = ruleSetReference; - } + public void setRuleSetReference(RuleSetReference ruleSetReference) { + this.ruleSetReference = ruleSetReference; + } - private static boolean isSame(String s1, String s2) { - return StringUtil.isSame(s1, s2, true, false, true); - } + private static boolean isSame(String s1, String s2) { + return StringUtil.isSame(s1, s2, true, false, true); + } - @SuppressWarnings("PMD.CompareObjectsWithEquals") - private static boolean isSame(Object o1, Object o2) { - if (o1 instanceof Object[] && o2 instanceof Object[]) { - return isSame((Object[])o1, (Object[])o2); - } - return o1 == o2 || (o1 != null && o2 != null && o1.equals(o2)); - } - - @SuppressWarnings("PMD.UnusedNullCheckInEquals") //TODO: fix UnusedNullCheckInEquals rule for Arrays - private static boolean isSame(Object[] a1, Object[] a2) { - return a1 == a2 || (a1 != null && a2 != null && Arrays.equals(a1, a2)); - } + @SuppressWarnings("PMD.CompareObjectsWithEquals") + private static boolean isSame(Object o1, Object o2) { + if (o1 instanceof Object[] && o2 instanceof Object[]) { + return isSame((Object[]) o1, (Object[]) o2); + } + return o1 == o2 || o1 != null && o2 != null && o1.equals(o2); + } - private static boolean contains(Collection collection, String s1) { - for (String s2 : collection) { - if (isSame(s1, s2)) { - return true; - } - } - return false; - } + @SuppressWarnings("PMD.UnusedNullCheckInEquals") + // TODO: fix UnusedNullCheckInEquals rule for Arrays + private static boolean isSame(Object[] a1, Object[] a2) { + return a1 == a2 || a1 != null && a2 != null && Arrays.equals(a1, a2); + } - public boolean hasDescriptor(PropertyDescriptor descriptor) { - return (propertyDescriptors != null && propertyDescriptors.contains(descriptor)) || - super.hasDescriptor(descriptor); - } + private static boolean contains(Collection collection, String s1) { + for (String s2 : collection) { + if (isSame(s1, s2)) { + return true; + } + } + return false; + } - public boolean hasOverriddenProperty(PropertyDescriptor descriptor) { - return propertyValues != null && propertyValues.containsKey(descriptor); - } + public boolean hasDescriptor(PropertyDescriptor descriptor) { + return propertyDescriptors != null && propertyDescriptors.contains(descriptor) + || super.hasDescriptor(descriptor); + } - public boolean usesDefaultValues() { + public boolean hasOverriddenProperty(PropertyDescriptor descriptor) { + return propertyValues != null && propertyValues.containsKey(descriptor); + } - List> descriptors = getOverriddenPropertyDescriptors(); - if (!descriptors.isEmpty()) { - return false; - } + public boolean usesDefaultValues() { - for (PropertyDescriptor desc : descriptors) { - if (!isSame(desc.defaultValue(), getProperty(desc))) { - return false; - } - } + List> descriptors = getOverriddenPropertyDescriptors(); + if (!descriptors.isEmpty()) { + return false; + } - if (!getRule().usesDefaultValues()) { - return false; - } + for (PropertyDescriptor desc : descriptors) { + if (!isSame(desc.defaultValue(), getProperty(desc))) { + return false; + } + } - return true; - } + if (!getRule().usesDefaultValues()) { + return false; + } - public void useDefaultValueFor(PropertyDescriptor desc) { + return true; + } - // not sure if we should go all the way through to the real thing? - getRule().useDefaultValueFor(desc); + public void useDefaultValueFor(PropertyDescriptor desc) { - if (propertyValues == null) { - return; - } + // not sure if we should go all the way through to the real thing? + getRule().useDefaultValueFor(desc); - propertyValues.remove(desc); + if (propertyValues == null) { + return; + } - if (propertyDescriptors != null) { - propertyDescriptors.remove(desc); - } - } + propertyValues.remove(desc); + + if (propertyDescriptors != null) { + propertyDescriptors.remove(desc); + } + } }