code cleanup: generics, eclipse warnings, ...
git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@6122 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
1 parent
91a4499754
commit
4bd104698f
59 files changed
+4831
-4719
No files matched your search
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -12,23 +12,23 @@ import net.sourceforge.pmd.lang.rule.AbstractRule;
|
||||
*/
|
||||
public class MockRule extends AbstractRule {
|
||||
|
||||
public MockRule() {
|
||||
super();
|
||||
}
|
||||
public MockRule() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MockRule(String name, String description, String message, String ruleSetName, int priority) {
|
||||
this(name, description, message, ruleSetName);
|
||||
setPriority(priority);
|
||||
}
|
||||
public MockRule(String name, String description, String message, String ruleSetName, int priority) {
|
||||
this(name, description, message, ruleSetName);
|
||||
setPriority(priority);
|
||||
}
|
||||
|
||||
public MockRule(String name, String description, String message, String ruleSetName) {
|
||||
super();
|
||||
setName(name);
|
||||
setDescription(description);
|
||||
setMessage(message);
|
||||
setRuleSetName(ruleSetName);
|
||||
}
|
||||
public MockRule(String name, String description, String message, String ruleSetName) {
|
||||
super();
|
||||
setName(name);
|
||||
setDescription(description);
|
||||
setMessage(message);
|
||||
setRuleSetName(ruleSetName);
|
||||
}
|
||||
|
||||
public void apply(List<Node> nodes, RuleContext ctx) {
|
||||
}
|
||||
public void apply(List<? extends Node> nodes, RuleContext ctx) {
|
||||
}
|
||||
}
|
||||
@@ -539,6 +539,7 @@ public class PMD {
|
||||
return rulesets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PmdThread " + id;
|
||||
}
|
||||
@@ -595,7 +596,7 @@ public class PMD {
|
||||
* ExecutorService can also be disabled if threadCount is not positive, e.g. using the
|
||||
* "-cpus 0" command line option.
|
||||
*/
|
||||
boolean useMT = mtSupported && (threadCount > 0);
|
||||
boolean useMT = mtSupported && threadCount > 0;
|
||||
|
||||
if (stressTestEnabled) {
|
||||
// randomize processing order
|
||||
@@ -830,9 +831,9 @@ public class PMD {
|
||||
ZipFile zipFile;
|
||||
try {
|
||||
zipFile = new ZipFile(inputFile);
|
||||
Enumeration e = zipFile.entries();
|
||||
Enumeration<? extends ZipEntry> e = zipFile.entries();
|
||||
while (e.hasMoreElements()) {
|
||||
ZipEntry zipEntry = (ZipEntry) e.nextElement();
|
||||
ZipEntry zipEntry = e.nextElement();
|
||||
if (fileSelector.isWantedFile(zipEntry.getName())) {
|
||||
dataSources.add(new ZipDataSource(zipFile, zipEntry));
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -39,8 +39,8 @@ public class RuleSets {
|
||||
* @param ruleSet the RuleSet
|
||||
*/
|
||||
public RuleSets(RuleSet ruleSet) {
|
||||
this();
|
||||
addRuleSet(ruleSet);
|
||||
this();
|
||||
addRuleSet(ruleSet);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,8 +51,8 @@ public class RuleSets {
|
||||
* @param ruleSet the RuleSet
|
||||
*/
|
||||
public void addRuleSet(RuleSet ruleSet) {
|
||||
ruleSets.add(ruleSet);
|
||||
ruleChain.add(ruleSet);
|
||||
ruleSets.add(ruleSet);
|
||||
ruleChain.add(ruleSet);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,11 +61,11 @@ public class RuleSets {
|
||||
* @return RuleSet[]
|
||||
*/
|
||||
public RuleSet[] getAllRuleSets() {
|
||||
return ruleSets.toArray(new RuleSet[ruleSets.size()]);
|
||||
return ruleSets.toArray(new RuleSet[ruleSets.size()]);
|
||||
}
|
||||
|
||||
public Iterator<RuleSet> getRuleSetsIterator() {
|
||||
return ruleSets.iterator();
|
||||
return ruleSets.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,13 +74,13 @@ public class RuleSets {
|
||||
* @return Set
|
||||
*/
|
||||
public Set<Rule> getAllRules() {
|
||||
HashSet<Rule> result = new HashSet<Rule>();
|
||||
for (RuleSet r: ruleSets) {
|
||||
result.addAll(r.getRules());
|
||||
}
|
||||
return result;
|
||||
HashSet<Rule> result = new HashSet<Rule>();
|
||||
for (RuleSet r : ruleSets) {
|
||||
result.addAll(r.getRules());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a given source file should be checked by rules in this RuleSets.
|
||||
*
|
||||
@@ -88,12 +88,12 @@ public class RuleSets {
|
||||
* @return <code>true</code> if the file should be checked, <code>false</code> otherwise
|
||||
*/
|
||||
public boolean applies(File file) {
|
||||
for (Iterator i = ruleSets.iterator(); i.hasNext();) {
|
||||
if (((RuleSet)i.next()).applies(file)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
for (RuleSet ruleSet : ruleSets) {
|
||||
if ((ruleSet).applies(file)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,17 +107,17 @@ public class RuleSets {
|
||||
* @return boolean true if the rule applies, else false
|
||||
*/
|
||||
public boolean applies(Language languageOfSource, Language languageOfRule) {
|
||||
return (languageOfSource.equals(languageOfRule) || (languageOfSource
|
||||
.equals(Language.JAVA) && (null == languageOfRule)));
|
||||
return languageOfSource.equals(languageOfRule) || languageOfSource.equals(Language.JAVA)
|
||||
&& null == languageOfRule;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notify all rules of the start of processing.
|
||||
*/
|
||||
public void start(RuleContext ctx) {
|
||||
for (RuleSet ruleSet: ruleSets) {
|
||||
ruleSet.start(ctx);
|
||||
}
|
||||
for (RuleSet ruleSet : ruleSets) {
|
||||
ruleSet.start(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,21 +131,21 @@ public class RuleSets {
|
||||
* @param language the Language of the source
|
||||
*/
|
||||
public void apply(List<Node> acuList, RuleContext ctx, Language language) {
|
||||
ruleChain.apply(acuList, ctx, language);
|
||||
for (RuleSet ruleSet: ruleSets) {
|
||||
if (applies(language, ruleSet.getLanguage())) {
|
||||
ruleSet.apply(acuList, ctx);
|
||||
}
|
||||
}
|
||||
ruleChain.apply(acuList, ctx, language);
|
||||
for (RuleSet ruleSet : ruleSets) {
|
||||
if (applies(language, ruleSet.getLanguage())) {
|
||||
ruleSet.apply(acuList, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notify all rules of the end of processing.
|
||||
*/
|
||||
public void end(RuleContext ctx) {
|
||||
for (RuleSet ruleSet: ruleSets) {
|
||||
ruleSet.end(ctx);
|
||||
}
|
||||
for (RuleSet ruleSet : ruleSets) {
|
||||
ruleSet.end(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,12 +156,12 @@ public class RuleSets {
|
||||
* @return true if any rule in the RuleSet needs the DFA layer
|
||||
*/
|
||||
public boolean usesDFA(Language language) {
|
||||
for (RuleSet ruleSet: ruleSets) {
|
||||
if (applies(language, ruleSet.getLanguage()) && ruleSet.usesDFA()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
for (RuleSet ruleSet : ruleSets) {
|
||||
if (applies(language, ruleSet.getLanguage()) && ruleSet.usesDFA()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,20 +171,20 @@ public class RuleSets {
|
||||
* @return the rule or null if not found
|
||||
*/
|
||||
public Rule getRuleByName(String ruleName) {
|
||||
Rule rule = null;
|
||||
for (Iterator<RuleSet> i = ruleSets.iterator(); i.hasNext() && (rule == null);) {
|
||||
RuleSet ruleSet = i.next();
|
||||
rule = ruleSet.getRuleByName(ruleName);
|
||||
}
|
||||
return rule;
|
||||
Rule rule = null;
|
||||
for (Iterator<RuleSet> i = ruleSets.iterator(); i.hasNext() && rule == null;) {
|
||||
RuleSet ruleSet = i.next();
|
||||
rule = ruleSet.getRuleByName(ruleName);
|
||||
}
|
||||
return rule;
|
||||
}
|
||||
|
||||
public boolean usesTypeResolution(Language language) {
|
||||
for (RuleSet ruleSet: ruleSets) {
|
||||
if (applies(language, ruleSet.getLanguage()) && ruleSet.usesTypeResolution()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
public boolean usesTypeResolution(Language language) {
|
||||
for (RuleSet ruleSet : ruleSets) {
|
||||
if (applies(language, ruleSet.getLanguage()) && ruleSet.usesTypeResolution()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -85,7 +85,7 @@ public class MatchCollector {
|
||||
continue;
|
||||
}
|
||||
//prune the mark set
|
||||
Set pruned = match1.getMarkSet();
|
||||
Set<TokenEntry> pruned = match1.getMarkSet();
|
||||
boolean done = false;
|
||||
ArrayList<TokenEntry> a1 = new ArrayList<TokenEntry>(match1.getMarkSet());
|
||||
Collections.sort(a1);
|
||||
|
||||
@@ -8,19 +8,16 @@ import java.util.List;
|
||||
public class PHPTokenizer implements Tokenizer {
|
||||
|
||||
public void tokenize(SourceCode tokens, Tokens tokenEntries) {
|
||||
List code = tokens.getCode();
|
||||
for (int i = 0; i < code.size(); i++) {
|
||||
String currentLine = (String) code.get(i);
|
||||
for (int j = 0; j < currentLine.length(); j++) {
|
||||
char tok = currentLine.charAt(j);
|
||||
if (!Character.isWhitespace(tok) &&
|
||||
tok != '{' &&
|
||||
tok != '}' &&
|
||||
tok != ';') {
|
||||
tokenEntries.add(new TokenEntry(String.valueOf(tok), tokens.getFileName(), i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
tokenEntries.add(TokenEntry.getEOF());
|
||||
List<String> code = tokens.getCode();
|
||||
for (int i = 0; i < code.size(); i++) {
|
||||
String currentLine = code.get(i);
|
||||
for (int j = 0; j < currentLine.length(); j++) {
|
||||
char tok = currentLine.charAt(j);
|
||||
if (!Character.isWhitespace(tok) && tok != '{' && tok != '}' && tok != ';') {
|
||||
tokenEntries.add(new TokenEntry(String.valueOf(tok), tokens.getFileName(), i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
tokenEntries.add(TokenEntry.getEOF());
|
||||
}
|
||||
}
|
||||
@@ -3,139 +3,144 @@
|
||||
*/
|
||||
package net.sourceforge.pmd.cpd;
|
||||
|
||||
import net.sourceforge.pmd.PMD;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.PMD;
|
||||
|
||||
public class SourceCode {
|
||||
|
||||
public static abstract class CodeLoader {
|
||||
private SoftReference<List<String>> code;
|
||||
private SoftReference<List<String>> code;
|
||||
|
||||
public List<String> getCode() {
|
||||
List<String> c = null;
|
||||
if (code != null) {
|
||||
c = code.get();
|
||||
}
|
||||
if (c != null) {
|
||||
return c;
|
||||
}
|
||||
this.code = new SoftReference<List<String>>(load());
|
||||
return code.get();
|
||||
}
|
||||
public List<String> getCode() {
|
||||
List<String> c = null;
|
||||
if (code != null) {
|
||||
c = code.get();
|
||||
}
|
||||
if (c != null) {
|
||||
return c;
|
||||
}
|
||||
this.code = new SoftReference<List<String>>(load());
|
||||
return code.get();
|
||||
}
|
||||
|
||||
public abstract String getFileName();
|
||||
public abstract String getFileName();
|
||||
|
||||
protected abstract Reader getReader() throws Exception;
|
||||
protected abstract Reader getReader() throws Exception;
|
||||
|
||||
protected List<String> load() {
|
||||
LineNumberReader lnr = null;
|
||||
try {
|
||||
lnr = new LineNumberReader(getReader());
|
||||
List<String> lines = new ArrayList<String>();
|
||||
String currentLine;
|
||||
while ((currentLine = lnr.readLine()) != null) {
|
||||
lines.add(currentLine);
|
||||
}
|
||||
return lines;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
if (lnr != null)
|
||||
lnr.close();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
protected List<String> load() {
|
||||
LineNumberReader lnr = null;
|
||||
try {
|
||||
lnr = new LineNumberReader(getReader());
|
||||
List<String> lines = new ArrayList<String>();
|
||||
String currentLine;
|
||||
while ((currentLine = lnr.readLine()) != null) {
|
||||
lines.add(currentLine);
|
||||
}
|
||||
return lines;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
if (lnr != null) {
|
||||
lnr.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class FileCodeLoader extends CodeLoader {
|
||||
private File file;
|
||||
private String encoding;
|
||||
private File file;
|
||||
private String encoding;
|
||||
|
||||
public FileCodeLoader(File file, String encoding) {
|
||||
this.file = file;
|
||||
this.encoding = encoding;
|
||||
}
|
||||
public FileCodeLoader(File file, String encoding) {
|
||||
this.file = file;
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
public Reader getReader() throws Exception {
|
||||
return new InputStreamReader(new FileInputStream(file), encoding);
|
||||
}
|
||||
@Override
|
||||
public Reader getReader() throws Exception {
|
||||
return new InputStreamReader(new FileInputStream(file), encoding);
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return this.file.getAbsolutePath();
|
||||
}
|
||||
@Override
|
||||
public String getFileName() {
|
||||
return this.file.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
public static class StringCodeLoader extends CodeLoader {
|
||||
public static final String DEFAULT_NAME = "CODE_LOADED_FROM_STRING";
|
||||
public static final String DEFAULT_NAME = "CODE_LOADED_FROM_STRING";
|
||||
|
||||
private String source_code;
|
||||
private String source_code;
|
||||
|
||||
private String name;
|
||||
private String name;
|
||||
|
||||
public StringCodeLoader(String code) {
|
||||
this(code, DEFAULT_NAME);
|
||||
}
|
||||
public StringCodeLoader(String code) {
|
||||
this(code, DEFAULT_NAME);
|
||||
}
|
||||
|
||||
public StringCodeLoader(String code, String name) {
|
||||
this.source_code = code;
|
||||
this.name = name;
|
||||
}
|
||||
public StringCodeLoader(String code, String name) {
|
||||
this.source_code = code;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Reader getReader() {
|
||||
return new StringReader(source_code);
|
||||
}
|
||||
@Override
|
||||
public Reader getReader() {
|
||||
return new StringReader(source_code);
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return name;
|
||||
}
|
||||
@Override
|
||||
public String getFileName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
private CodeLoader cl;
|
||||
|
||||
public SourceCode(CodeLoader cl) {
|
||||
this.cl = cl;
|
||||
this.cl = cl;
|
||||
}
|
||||
|
||||
public List<String> getCode() {
|
||||
return cl.getCode();
|
||||
return cl.getCode();
|
||||
}
|
||||
|
||||
public StringBuffer getCodeBuffer() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
List<String> lines = cl.getCode();
|
||||
for ( String line : lines ) {
|
||||
sb.append(line);
|
||||
sb.append(PMD.EOL);
|
||||
}
|
||||
return sb;
|
||||
StringBuffer sb = new StringBuffer();
|
||||
List<String> lines = cl.getCode();
|
||||
for (String line : lines) {
|
||||
sb.append(line);
|
||||
sb.append(PMD.EOL);
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
public String getSlice(int startLine, int endLine) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
List lines = cl.getCode();
|
||||
for (int i = startLine - 1; i < endLine && i < lines.size(); i++) {
|
||||
if (sb.length() != 0) {
|
||||
sb.append(PMD.EOL);
|
||||
}
|
||||
sb.append((String) lines.get(i));
|
||||
}
|
||||
return sb.toString();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
List<String> lines = cl.getCode();
|
||||
for (int i = startLine - 1; i < endLine && i < lines.size(); i++) {
|
||||
if (sb.length() != 0) {
|
||||
sb.append(PMD.EOL);
|
||||
}
|
||||
sb.append(lines.get(i));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return cl.getFileName();
|
||||
return cl.getFileName();
|
||||
}
|
||||
}
|
||||
@@ -13,157 +13,158 @@ import java.lang.reflect.Method;
|
||||
*/
|
||||
public class ClassLoaderUtil {
|
||||
|
||||
public static final String CLINIT = "<clinit>";
|
||||
public static final String CLINIT = "<clinit>";
|
||||
|
||||
public static final String INIT = "<init>";
|
||||
public static final String INIT = "<init>";
|
||||
|
||||
public static String fromInternalForm(String internalForm) {
|
||||
return internalForm.replace('/', '.');
|
||||
public static String fromInternalForm(String internalForm) {
|
||||
return internalForm.replace('/', '.');
|
||||
}
|
||||
|
||||
public static String toInternalForm(String internalForm) {
|
||||
return internalForm.replace('.', '/');
|
||||
}
|
||||
|
||||
public static Class<?> getClass(String name) {
|
||||
try {
|
||||
return ClassLoaderUtil.class.getClassLoader().loadClass(name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String toInternalForm(String internalForm) {
|
||||
return internalForm.replace('.', '/');
|
||||
public static Field getField(Class<?> type, String name) {
|
||||
try {
|
||||
return myGetField(type, name);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Class getClass(String name) {
|
||||
private static Field myGetField(Class<?> type, String name) throws NoSuchFieldException {
|
||||
// Scan the type hierarchy just like Class.getField(String) using
|
||||
// Class.getDeclaredField(String)
|
||||
try {
|
||||
return type.getDeclaredField(name);
|
||||
} catch (NoSuchFieldException e) {
|
||||
// Try the super interfaces
|
||||
for (Class<?> superInterface : type.getInterfaces()) {
|
||||
try {
|
||||
return ClassLoaderUtil.class.getClassLoader().loadClass(name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
return myGetField(superInterface, name);
|
||||
} catch (NoSuchFieldException e2) {
|
||||
// Okay
|
||||
}
|
||||
}
|
||||
// Try the super classes
|
||||
if (type.getSuperclass() != null) {
|
||||
return myGetField(type.getSuperclass(), name);
|
||||
} else {
|
||||
throw new NoSuchFieldException(type.getName() + "." + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Field getField(Class type, String name) {
|
||||
public static Method getMethod(Class<?> type, String name, Class<?>... parameterTypes) {
|
||||
try {
|
||||
return myGetMethod(type, name, parameterTypes);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Method myGetMethod(Class<?> type, String name, Class<?>... parameterTypes)
|
||||
throws NoSuchMethodException {
|
||||
// Scan the type hierarchy just like Class.getMethod(String, Class[])
|
||||
// using Class.getDeclaredMethod(String, Class[])
|
||||
// System.out.println("type: " + type);
|
||||
// System.out.println("name: " + name);
|
||||
// System.out
|
||||
// .println("parameterTypes: " + Arrays.toString(parameterTypes));
|
||||
try {
|
||||
// System.out.println("Checking getDeclaredMethod");
|
||||
// for (Method m : type.getDeclaredMethods()) {
|
||||
// System.out.println("\t" + m);
|
||||
// }
|
||||
return type.getDeclaredMethod(name, parameterTypes);
|
||||
} catch (NoSuchMethodException e) {
|
||||
try {
|
||||
// Try the super classes
|
||||
if (type.getSuperclass() != null) {
|
||||
// System.out.println("Checking super: "
|
||||
// + type.getSuperclass());
|
||||
return myGetMethod(type.getSuperclass(), name, parameterTypes);
|
||||
}
|
||||
} catch (NoSuchMethodException e2) {
|
||||
// Okay
|
||||
}
|
||||
// Try the super interfaces
|
||||
for (Class<?> superInterface : type.getInterfaces()) {
|
||||
try {
|
||||
return myGetField(type, name);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
// System.out.println("Checking super interface: "
|
||||
// + superInterface);
|
||||
return myGetMethod(superInterface, name, parameterTypes);
|
||||
} catch (NoSuchMethodException e3) {
|
||||
// Okay
|
||||
}
|
||||
}
|
||||
throw new NoSuchMethodException(type.getName() + "." + getMethodSignature(name, parameterTypes));
|
||||
}
|
||||
}
|
||||
|
||||
private static Field myGetField(Class type, String name) throws NoSuchFieldException {
|
||||
// Scan the type hierarchy just like Class.getField(String) using
|
||||
// Class.getDeclaredField(String)
|
||||
try {
|
||||
return type.getDeclaredField(name);
|
||||
} catch (NoSuchFieldException e) {
|
||||
// Try the super interfaces
|
||||
for (Class superInterface : type.getInterfaces()) {
|
||||
try {
|
||||
return myGetField(superInterface, name);
|
||||
} catch (NoSuchFieldException e2) {
|
||||
// Okay
|
||||
}
|
||||
}
|
||||
// Try the super classes
|
||||
if (type.getSuperclass() != null) {
|
||||
return myGetField(type.getSuperclass(), name);
|
||||
} else {
|
||||
throw new NoSuchFieldException(type.getName() + "." + name);
|
||||
}
|
||||
}
|
||||
public static Constructor<?> getConstructor(Class<?> type, String name, Class<?>... parameterTypes) {
|
||||
try {
|
||||
return type.getDeclaredConstructor(parameterTypes);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Method getMethod(Class type, String name, Class... parameterTypes) {
|
||||
try {
|
||||
return myGetMethod(type, name, parameterTypes);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
public static String getMethodSignature(String name, Class<?>... parameterTypes) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(name);
|
||||
if (!(name.equals(CLINIT) || name.equals(INIT))) {
|
||||
builder.append("(");
|
||||
if (parameterTypes != null) {
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
if (i > 0) {
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append(parameterTypes[i].getName());
|
||||
}
|
||||
}
|
||||
builder.append(")");
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static Method myGetMethod(Class type, String name, Class... parameterTypes) throws NoSuchMethodException {
|
||||
// Scan the type hierarchy just like Class.getMethod(String, Class[])
|
||||
// using Class.getDeclaredMethod(String, Class[])
|
||||
// System.out.println("type: " + type);
|
||||
// System.out.println("name: " + name);
|
||||
// System.out
|
||||
// .println("parameterTypes: " + Arrays.toString(parameterTypes));
|
||||
try {
|
||||
// System.out.println("Checking getDeclaredMethod");
|
||||
// for (Method m : type.getDeclaredMethods()) {
|
||||
// System.out.println("\t" + m);
|
||||
// }
|
||||
return type.getDeclaredMethod(name, parameterTypes);
|
||||
} catch (NoSuchMethodException e) {
|
||||
try {
|
||||
// Try the super classes
|
||||
if (type.getSuperclass() != null) {
|
||||
// System.out.println("Checking super: "
|
||||
// + type.getSuperclass());
|
||||
return myGetMethod(type.getSuperclass(), name, parameterTypes);
|
||||
}
|
||||
} catch (NoSuchMethodException e2) {
|
||||
// Okay
|
||||
}
|
||||
// Try the super interfaces
|
||||
for (Class superInterface : type.getInterfaces()) {
|
||||
try {
|
||||
// System.out.println("Checking super interface: "
|
||||
// + superInterface);
|
||||
return myGetMethod(superInterface, name, parameterTypes);
|
||||
} catch (NoSuchMethodException e3) {
|
||||
// Okay
|
||||
}
|
||||
}
|
||||
throw new NoSuchMethodException(type.getName() + "." + getMethodSignature(name, parameterTypes));
|
||||
}
|
||||
public static Class<?>[] getParameterTypes(String... parameterTypeNames) {
|
||||
Class<?>[] parameterTypes = new Class[parameterTypeNames.length];
|
||||
for (int i = 0; i < parameterTypeNames.length; i++) {
|
||||
parameterTypes[i] = getClass(parameterTypeNames[i]);
|
||||
}
|
||||
return parameterTypes;
|
||||
}
|
||||
|
||||
public static Constructor getConstructor(Class type, String name, Class... parameterTypes) {
|
||||
try {
|
||||
return type.getDeclaredConstructor(parameterTypes);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
public static boolean isOverridenMethod(Class<?> clazz, Method method, boolean checkThisClass) {
|
||||
try {
|
||||
if (checkThisClass) {
|
||||
clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
|
||||
return true;
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
}
|
||||
|
||||
public static String getMethodSignature(String name, Class... parameterTypes) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(name);
|
||||
if (!(name.equals(CLINIT) || name.equals(INIT))) {
|
||||
builder.append("(");
|
||||
if (parameterTypes != null) {
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
if (i > 0) {
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append(parameterTypes[i].getName());
|
||||
}
|
||||
}
|
||||
builder.append(")");
|
||||
}
|
||||
return builder.toString();
|
||||
// Check super class
|
||||
if (clazz.getSuperclass() != null) {
|
||||
if (isOverridenMethod(clazz.getSuperclass(), method, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static Class[] getParameterTypes(String... parameterTypeNames) {
|
||||
Class[] parameterTypes = new Class[parameterTypeNames.length];
|
||||
for (int i = 0; i < parameterTypeNames.length; i++) {
|
||||
parameterTypes[i] = getClass(parameterTypeNames[i]);
|
||||
}
|
||||
return parameterTypes;
|
||||
}
|
||||
|
||||
public static boolean isOverridenMethod(Class clazz, Method method, boolean checkThisClass) {
|
||||
try {
|
||||
if (checkThisClass) {
|
||||
clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
|
||||
return true;
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
}
|
||||
// Check super class
|
||||
if (clazz.getSuperclass() != null) {
|
||||
if (isOverridenMethod(clazz.getSuperclass(), method, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Check interfaces
|
||||
for (Class anInterface : clazz.getInterfaces()) {
|
||||
if (isOverridenMethod(anInterface, method, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
// Check interfaces
|
||||
for (Class<?> anInterface : clazz.getInterfaces()) {
|
||||
if (isOverridenMethod(anInterface, method, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -32,142 +32,143 @@ public abstract class AbstractDataFlowNode implements DataFlowNode {
|
||||
protected int line;
|
||||
|
||||
public AbstractDataFlowNode(LinkedList<DataFlowNode> dataFlow) {
|
||||
this.dataFlow = dataFlow;
|
||||
if (!this.dataFlow.isEmpty()) {
|
||||
DataFlowNode parent = this.dataFlow.getLast();
|
||||
parent.addPathToChild(this);
|
||||
}
|
||||
this.dataFlow.addLast(this);
|
||||
this.dataFlow = dataFlow;
|
||||
if (!this.dataFlow.isEmpty()) {
|
||||
DataFlowNode parent = this.dataFlow.getLast();
|
||||
parent.addPathToChild(this);
|
||||
}
|
||||
this.dataFlow.addLast(this);
|
||||
}
|
||||
|
||||
public AbstractDataFlowNode(LinkedList<DataFlowNode> dataFlow, Node node) {
|
||||
this(dataFlow);
|
||||
|
||||
this.node = node;
|
||||
node.setDataFlowNode(this);
|
||||
this.line = node.getBeginLine();
|
||||
node.setDataFlowNode(this);
|
||||
this.line = node.getBeginLine();
|
||||
}
|
||||
|
||||
public void addPathToChild(DataFlowNode child) {
|
||||
DataFlowNode thisChild = (DataFlowNode) child;
|
||||
// TODO - throw an exception if already contained in children list?
|
||||
if (!this.children.contains(thisChild) || this.equals(thisChild)) {
|
||||
this.children.add(thisChild);
|
||||
thisChild.getParents().add(this);
|
||||
}
|
||||
DataFlowNode thisChild = child;
|
||||
// TODO - throw an exception if already contained in children list?
|
||||
if (!this.children.contains(thisChild) || this.equals(thisChild)) {
|
||||
this.children.add(thisChild);
|
||||
thisChild.getParents().add(this);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean removePathToChild(DataFlowNode child) {
|
||||
DataFlowNode thisChild = (DataFlowNode) child;
|
||||
thisChild.getParents().remove(this);
|
||||
return this.children.remove(thisChild);
|
||||
DataFlowNode thisChild = child;
|
||||
thisChild.getParents().remove(this);
|
||||
return this.children.remove(thisChild);
|
||||
}
|
||||
|
||||
public void reverseParentPathsTo(DataFlowNode destination) {
|
||||
while (!parents.isEmpty()) {
|
||||
DataFlowNode parent = parents.get(0);
|
||||
parent.removePathToChild(this);
|
||||
parent.addPathToChild(destination);
|
||||
}
|
||||
while (!parents.isEmpty()) {
|
||||
DataFlowNode parent = parents.get(0);
|
||||
parent.removePathToChild(this);
|
||||
parent.addPathToChild(destination);
|
||||
}
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return this.line;
|
||||
return this.line;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type.set(type);
|
||||
this.type.set(type);
|
||||
}
|
||||
|
||||
public boolean isType(int intype) {
|
||||
try {
|
||||
return type.get(intype);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
try {
|
||||
return type.get(intype);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Node getNode() {
|
||||
return this.node;
|
||||
return this.node;
|
||||
}
|
||||
|
||||
public List<DataFlowNode> getChildren() {
|
||||
return this.children;
|
||||
return this.children;
|
||||
}
|
||||
|
||||
public List<DataFlowNode> getParents() {
|
||||
return this.parents;
|
||||
return this.parents;
|
||||
}
|
||||
|
||||
public List<DataFlowNode> getFlow() {
|
||||
return this.dataFlow;
|
||||
return this.dataFlow;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return this.dataFlow.indexOf(this);
|
||||
return this.dataFlow.indexOf(this);
|
||||
}
|
||||
|
||||
public void setVariableAccess(List<VariableAccess> variableAccess) {
|
||||
if (this.variableAccess.isEmpty()) {
|
||||
this.variableAccess = variableAccess;
|
||||
} else {
|
||||
this.variableAccess.addAll(variableAccess);
|
||||
}
|
||||
if (this.variableAccess.isEmpty()) {
|
||||
this.variableAccess = variableAccess;
|
||||
} else {
|
||||
this.variableAccess.addAll(variableAccess);
|
||||
}
|
||||
}
|
||||
|
||||
public List<VariableAccess> getVariableAccess() {
|
||||
return this.variableAccess;
|
||||
return this.variableAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String res = "DataFlowNode: line " + this.getLine() + ", ";
|
||||
String tmp = type.toString();
|
||||
String newTmp = "";
|
||||
for (char c : tmp.toCharArray()) {
|
||||
if (c != '{' && c != '}' && c != ' ') {
|
||||
newTmp += c;
|
||||
}
|
||||
}
|
||||
for (StringTokenizer st = new StringTokenizer(newTmp, ","); st.hasMoreTokens();) {
|
||||
int newTmpInt = Integer.parseInt(st.nextToken());
|
||||
res += "(" + stringFromType(newTmpInt) + ")";
|
||||
}
|
||||
res += ", " + this.node.getClass().getName().substring(node.getClass().getName().lastIndexOf('.') + 1);
|
||||
res += (node.getImage() == null ? "" : "(" + this.node.getImage() + ")");
|
||||
return res;
|
||||
String res = "DataFlowNode: line " + this.getLine() + ", ";
|
||||
String tmp = type.toString();
|
||||
String newTmp = "";
|
||||
for (char c : tmp.toCharArray()) {
|
||||
if (c != '{' && c != '}' && c != ' ') {
|
||||
newTmp += c;
|
||||
}
|
||||
}
|
||||
for (StringTokenizer st = new StringTokenizer(newTmp, ","); st.hasMoreTokens();) {
|
||||
int newTmpInt = Integer.parseInt(st.nextToken());
|
||||
res += "(" + stringFromType(newTmpInt) + ")";
|
||||
}
|
||||
res += ", " + this.node.getClass().getName().substring(node.getClass().getName().lastIndexOf('.') + 1);
|
||||
res += node.getImage() == null ? "" : "(" + this.node.getImage() + ")";
|
||||
return res;
|
||||
}
|
||||
|
||||
private String stringFromType(int intype) {
|
||||
if (typeMap.isEmpty()) {
|
||||
typeMap.put(NodeType.IF_EXPR, "IF_EXPR");
|
||||
typeMap.put(NodeType.IF_LAST_STATEMENT, "IF_LAST_STATEMENT");
|
||||
typeMap.put(NodeType.IF_LAST_STATEMENT_WITHOUT_ELSE, "IF_LAST_STATEMENT_WITHOUT_ELSE");
|
||||
typeMap.put(NodeType.ELSE_LAST_STATEMENT, "ELSE_LAST_STATEMENT");
|
||||
typeMap.put(NodeType.WHILE_LAST_STATEMENT, "WHILE_LAST_STATEMENT");
|
||||
typeMap.put(NodeType.WHILE_EXPR, "WHILE_EXPR");
|
||||
typeMap.put(NodeType.SWITCH_START, "SWITCH_START");
|
||||
typeMap.put(NodeType.CASE_LAST_STATEMENT, "CASE_LAST_STATEMENT");
|
||||
typeMap.put(NodeType.SWITCH_LAST_DEFAULT_STATEMENT, "SWITCH_LAST_DEFAULT_STATEMENT");
|
||||
typeMap.put(NodeType.SWITCH_END, "SWITCH_END");
|
||||
typeMap.put(NodeType.FOR_INIT, "FOR_INIT");
|
||||
typeMap.put(NodeType.FOR_EXPR, "FOR_EXPR");
|
||||
typeMap.put(NodeType.FOR_UPDATE, "FOR_UPDATE");
|
||||
typeMap.put(NodeType.FOR_BEFORE_FIRST_STATEMENT, "FOR_BEFORE_FIRST_STATEMENT");
|
||||
typeMap.put(NodeType.FOR_END, "FOR_END");
|
||||
typeMap.put(NodeType.DO_BEFORE_FIRST_STATEMENT, "DO_BEFORE_FIRST_STATEMENT");
|
||||
typeMap.put(NodeType.DO_EXPR, "DO_EXPR");
|
||||
typeMap.put(NodeType.RETURN_STATEMENT, "RETURN_STATEMENT");
|
||||
typeMap.put(NodeType.BREAK_STATEMENT, "BREAK_STATEMENT");
|
||||
typeMap.put(NodeType.CONTINUE_STATEMENT, "CONTINUE_STATEMENT");
|
||||
typeMap.put(NodeType.LABEL_STATEMENT, "LABEL_STATEMENT");
|
||||
typeMap.put(NodeType.LABEL_LAST_STATEMENT, "LABEL_END");
|
||||
typeMap.put(NodeType.THROW_STATEMENT, "THROW_STATEMENT");
|
||||
}
|
||||
if (!typeMap.containsKey(intype)) {
|
||||
throw new RuntimeException("Couldn't find type id " + intype);
|
||||
}
|
||||
return typeMap.get(intype);
|
||||
if (typeMap.isEmpty()) {
|
||||
typeMap.put(NodeType.IF_EXPR, "IF_EXPR");
|
||||
typeMap.put(NodeType.IF_LAST_STATEMENT, "IF_LAST_STATEMENT");
|
||||
typeMap.put(NodeType.IF_LAST_STATEMENT_WITHOUT_ELSE, "IF_LAST_STATEMENT_WITHOUT_ELSE");
|
||||
typeMap.put(NodeType.ELSE_LAST_STATEMENT, "ELSE_LAST_STATEMENT");
|
||||
typeMap.put(NodeType.WHILE_LAST_STATEMENT, "WHILE_LAST_STATEMENT");
|
||||
typeMap.put(NodeType.WHILE_EXPR, "WHILE_EXPR");
|
||||
typeMap.put(NodeType.SWITCH_START, "SWITCH_START");
|
||||
typeMap.put(NodeType.CASE_LAST_STATEMENT, "CASE_LAST_STATEMENT");
|
||||
typeMap.put(NodeType.SWITCH_LAST_DEFAULT_STATEMENT, "SWITCH_LAST_DEFAULT_STATEMENT");
|
||||
typeMap.put(NodeType.SWITCH_END, "SWITCH_END");
|
||||
typeMap.put(NodeType.FOR_INIT, "FOR_INIT");
|
||||
typeMap.put(NodeType.FOR_EXPR, "FOR_EXPR");
|
||||
typeMap.put(NodeType.FOR_UPDATE, "FOR_UPDATE");
|
||||
typeMap.put(NodeType.FOR_BEFORE_FIRST_STATEMENT, "FOR_BEFORE_FIRST_STATEMENT");
|
||||
typeMap.put(NodeType.FOR_END, "FOR_END");
|
||||
typeMap.put(NodeType.DO_BEFORE_FIRST_STATEMENT, "DO_BEFORE_FIRST_STATEMENT");
|
||||
typeMap.put(NodeType.DO_EXPR, "DO_EXPR");
|
||||
typeMap.put(NodeType.RETURN_STATEMENT, "RETURN_STATEMENT");
|
||||
typeMap.put(NodeType.BREAK_STATEMENT, "BREAK_STATEMENT");
|
||||
typeMap.put(NodeType.CONTINUE_STATEMENT, "CONTINUE_STATEMENT");
|
||||
typeMap.put(NodeType.LABEL_STATEMENT, "LABEL_STATEMENT");
|
||||
typeMap.put(NodeType.LABEL_LAST_STATEMENT, "LABEL_END");
|
||||
typeMap.put(NodeType.THROW_STATEMENT, "THROW_STATEMENT");
|
||||
}
|
||||
if (!typeMap.containsKey(intype)) {
|
||||
throw new RuntimeException("Couldn't find type id " + intype);
|
||||
}
|
||||
return typeMap.get(intype);
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -26,118 +26,117 @@ public class SequenceChecker {
|
||||
* Element of logical structure of brace nodes.
|
||||
* */
|
||||
private static class Status {
|
||||
public static final int ROOT = -1;
|
||||
public static final int ROOT = -1;
|
||||
|
||||
private List<Status> nextSteps = new ArrayList<Status>();
|
||||
private int type;
|
||||
private boolean lastStep;
|
||||
private List<Status> nextSteps = new ArrayList<Status>();
|
||||
private int type;
|
||||
private boolean lastStep;
|
||||
|
||||
public Status(int type) {
|
||||
this(type, false);
|
||||
}
|
||||
|
||||
public Status(int type) {
|
||||
this(type, false);
|
||||
}
|
||||
public Status(int type, boolean lastStep) {
|
||||
this.type = type;
|
||||
this.lastStep = lastStep;
|
||||
}
|
||||
|
||||
public Status(int type, boolean lastStep) {
|
||||
this.type = type;
|
||||
this.lastStep = lastStep;
|
||||
}
|
||||
public void addStep(Status type) {
|
||||
nextSteps.add(type);
|
||||
}
|
||||
|
||||
public void addStep(Status type) {
|
||||
nextSteps.add(type);
|
||||
}
|
||||
public Status step(int type) {
|
||||
for (int i = 0; i < this.nextSteps.size(); i++) {
|
||||
if (type == nextSteps.get(i).type) {
|
||||
return nextSteps.get(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Status step(int type) {
|
||||
for (int i = 0; i < this.nextSteps.size(); i++) {
|
||||
if (type == nextSteps.get(i).type) {
|
||||
return nextSteps.get(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public boolean isLastStep() {
|
||||
return this.lastStep;
|
||||
}
|
||||
|
||||
public boolean isLastStep() {
|
||||
return this.lastStep;
|
||||
}
|
||||
|
||||
public boolean hasMoreSteps() {
|
||||
return this.nextSteps.size() > 1;
|
||||
}
|
||||
public boolean hasMoreSteps() {
|
||||
return this.nextSteps.size() > 1;
|
||||
}
|
||||
}
|
||||
|
||||
private static Status root;
|
||||
|
||||
static {
|
||||
root = new Status(Status.ROOT);
|
||||
Status ifNode = new Status(NodeType.IF_EXPR);
|
||||
Status ifSt = new Status(NodeType.IF_LAST_STATEMENT);
|
||||
Status ifStWithoutElse = new Status(NodeType.IF_LAST_STATEMENT_WITHOUT_ELSE, true);
|
||||
Status elseSt = new Status(NodeType.ELSE_LAST_STATEMENT, true);
|
||||
Status whileNode = new Status(NodeType.WHILE_EXPR);
|
||||
Status whileSt = new Status(NodeType.WHILE_LAST_STATEMENT, true);
|
||||
Status switchNode = new Status(NodeType.SWITCH_START);
|
||||
Status caseSt = new Status(NodeType.CASE_LAST_STATEMENT);
|
||||
Status switchDefault = new Status(NodeType.SWITCH_LAST_DEFAULT_STATEMENT);
|
||||
Status switchEnd = new Status(NodeType.SWITCH_END, true);
|
||||
root = new Status(Status.ROOT);
|
||||
Status ifNode = new Status(NodeType.IF_EXPR);
|
||||
Status ifSt = new Status(NodeType.IF_LAST_STATEMENT);
|
||||
Status ifStWithoutElse = new Status(NodeType.IF_LAST_STATEMENT_WITHOUT_ELSE, true);
|
||||
Status elseSt = new Status(NodeType.ELSE_LAST_STATEMENT, true);
|
||||
Status whileNode = new Status(NodeType.WHILE_EXPR);
|
||||
Status whileSt = new Status(NodeType.WHILE_LAST_STATEMENT, true);
|
||||
Status switchNode = new Status(NodeType.SWITCH_START);
|
||||
Status caseSt = new Status(NodeType.CASE_LAST_STATEMENT);
|
||||
Status switchDefault = new Status(NodeType.SWITCH_LAST_DEFAULT_STATEMENT);
|
||||
Status switchEnd = new Status(NodeType.SWITCH_END, true);
|
||||
|
||||
Status forInit = new Status(NodeType.FOR_INIT);
|
||||
Status forExpr = new Status(NodeType.FOR_EXPR);
|
||||
Status forUpdate = new Status(NodeType.FOR_UPDATE);
|
||||
Status forSt = new Status(NodeType.FOR_BEFORE_FIRST_STATEMENT);
|
||||
Status forEnd = new Status(NodeType.FOR_END, true);
|
||||
Status forInit = new Status(NodeType.FOR_INIT);
|
||||
Status forExpr = new Status(NodeType.FOR_EXPR);
|
||||
Status forUpdate = new Status(NodeType.FOR_UPDATE);
|
||||
Status forSt = new Status(NodeType.FOR_BEFORE_FIRST_STATEMENT);
|
||||
Status forEnd = new Status(NodeType.FOR_END, true);
|
||||
|
||||
Status doSt = new Status(NodeType.DO_BEFORE_FIRST_STATEMENT);
|
||||
Status doExpr = new Status(NodeType.DO_EXPR, true);
|
||||
Status doSt = new Status(NodeType.DO_BEFORE_FIRST_STATEMENT);
|
||||
Status doExpr = new Status(NodeType.DO_EXPR, true);
|
||||
|
||||
Status labelNode = new Status(NodeType.LABEL_STATEMENT);
|
||||
Status labelEnd = new Status(NodeType.LABEL_LAST_STATEMENT, true);
|
||||
Status labelNode = new Status(NodeType.LABEL_STATEMENT);
|
||||
Status labelEnd = new Status(NodeType.LABEL_LAST_STATEMENT, true);
|
||||
|
||||
root.addStep(ifNode);
|
||||
root.addStep(whileNode);
|
||||
root.addStep(switchNode);
|
||||
root.addStep(forInit);
|
||||
root.addStep(forExpr);
|
||||
root.addStep(forUpdate);
|
||||
root.addStep(forSt);
|
||||
root.addStep(doSt);
|
||||
root.addStep(labelNode);
|
||||
root.addStep(ifNode);
|
||||
root.addStep(whileNode);
|
||||
root.addStep(switchNode);
|
||||
root.addStep(forInit);
|
||||
root.addStep(forExpr);
|
||||
root.addStep(forUpdate);
|
||||
root.addStep(forSt);
|
||||
root.addStep(doSt);
|
||||
root.addStep(labelNode);
|
||||
|
||||
ifNode.addStep(ifSt);
|
||||
ifNode.addStep(ifStWithoutElse);
|
||||
ifSt.addStep(elseSt);
|
||||
ifStWithoutElse.addStep(root);
|
||||
elseSt.addStep(root);
|
||||
ifNode.addStep(ifSt);
|
||||
ifNode.addStep(ifStWithoutElse);
|
||||
ifSt.addStep(elseSt);
|
||||
ifStWithoutElse.addStep(root);
|
||||
elseSt.addStep(root);
|
||||
|
||||
labelNode.addStep(labelEnd);
|
||||
labelEnd.addStep(root);
|
||||
labelNode.addStep(labelEnd);
|
||||
labelEnd.addStep(root);
|
||||
|
||||
whileNode.addStep(whileSt);
|
||||
whileSt.addStep(root);
|
||||
whileNode.addStep(whileSt);
|
||||
whileSt.addStep(root);
|
||||
|
||||
switchNode.addStep(caseSt);
|
||||
switchNode.addStep(switchDefault);
|
||||
switchNode.addStep(switchEnd);
|
||||
caseSt.addStep(caseSt);
|
||||
caseSt.addStep(switchDefault);
|
||||
caseSt.addStep(switchEnd);
|
||||
switchDefault.addStep(switchEnd);
|
||||
switchDefault.addStep(caseSt);
|
||||
switchEnd.addStep(root);
|
||||
switchNode.addStep(caseSt);
|
||||
switchNode.addStep(switchDefault);
|
||||
switchNode.addStep(switchEnd);
|
||||
caseSt.addStep(caseSt);
|
||||
caseSt.addStep(switchDefault);
|
||||
caseSt.addStep(switchEnd);
|
||||
switchDefault.addStep(switchEnd);
|
||||
switchDefault.addStep(caseSt);
|
||||
switchEnd.addStep(root);
|
||||
|
||||
forInit.addStep(forExpr);
|
||||
forInit.addStep(forUpdate);
|
||||
forInit.addStep(forSt);
|
||||
forExpr.addStep(forUpdate);
|
||||
forExpr.addStep(forSt);
|
||||
forUpdate.addStep(forSt);
|
||||
forSt.addStep(forEnd);
|
||||
forEnd.addStep(root);
|
||||
forInit.addStep(forExpr);
|
||||
forInit.addStep(forUpdate);
|
||||
forInit.addStep(forSt);
|
||||
forExpr.addStep(forUpdate);
|
||||
forExpr.addStep(forSt);
|
||||
forUpdate.addStep(forSt);
|
||||
forSt.addStep(forEnd);
|
||||
forEnd.addStep(root);
|
||||
|
||||
doSt.addStep(doExpr);
|
||||
doExpr.addStep(root);
|
||||
doSt.addStep(doExpr);
|
||||
doExpr.addStep(root);
|
||||
}
|
||||
|
||||
private Status aktStatus;
|
||||
private List bracesList;
|
||||
private List<StackObject> bracesList;
|
||||
|
||||
private int firstIndex = -1;
|
||||
private int lastIndex = -1;
|
||||
@@ -145,9 +144,9 @@ public class SequenceChecker {
|
||||
/*
|
||||
* Defines the logical structure.
|
||||
* */
|
||||
public SequenceChecker(List bracesList) {
|
||||
this.aktStatus = root;
|
||||
this.bracesList = bracesList;
|
||||
public SequenceChecker(List<StackObject> bracesList) {
|
||||
this.aktStatus = root;
|
||||
this.bracesList = bracesList;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,43 +154,43 @@ public class SequenceChecker {
|
||||
* is found or the list is empty the method returns false.
|
||||
*/
|
||||
public boolean run() {
|
||||
this.aktStatus = root;
|
||||
this.firstIndex = 0;
|
||||
this.lastIndex = 0;
|
||||
boolean lookAhead = false;
|
||||
this.aktStatus = root;
|
||||
this.firstIndex = 0;
|
||||
this.lastIndex = 0;
|
||||
boolean lookAhead = false;
|
||||
|
||||
for (int i = 0; i < this.bracesList.size(); i++) {
|
||||
StackObject so = (StackObject) bracesList.get(i);
|
||||
aktStatus = this.aktStatus.step(so.getType());
|
||||
for (int i = 0; i < this.bracesList.size(); i++) {
|
||||
StackObject so = bracesList.get(i);
|
||||
aktStatus = this.aktStatus.step(so.getType());
|
||||
|
||||
if (aktStatus == null) {
|
||||
if (lookAhead) {
|
||||
this.lastIndex = i - 1;
|
||||
return false;
|
||||
}
|
||||
this.aktStatus = root;
|
||||
this.firstIndex = i;
|
||||
i--;
|
||||
continue;
|
||||
} else {
|
||||
if (aktStatus.isLastStep() && !aktStatus.hasMoreSteps()) {
|
||||
this.lastIndex = i;
|
||||
return false;
|
||||
} else if (aktStatus.isLastStep() && aktStatus.hasMoreSteps()) {
|
||||
lookAhead = true;
|
||||
this.lastIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.firstIndex == this.lastIndex;
|
||||
if (aktStatus == null) {
|
||||
if (lookAhead) {
|
||||
this.lastIndex = i - 1;
|
||||
return false;
|
||||
}
|
||||
this.aktStatus = root;
|
||||
this.firstIndex = i;
|
||||
i--;
|
||||
continue;
|
||||
} else {
|
||||
if (aktStatus.isLastStep() && !aktStatus.hasMoreSteps()) {
|
||||
this.lastIndex = i;
|
||||
return false;
|
||||
} else if (aktStatus.isLastStep() && aktStatus.hasMoreSteps()) {
|
||||
lookAhead = true;
|
||||
this.lastIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.firstIndex == this.lastIndex;
|
||||
}
|
||||
|
||||
public int getFirstIndex() {
|
||||
return this.firstIndex;
|
||||
return this.firstIndex;
|
||||
}
|
||||
|
||||
public int getLastIndex() {
|
||||
return this.lastIndex;
|
||||
return this.lastIndex;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import java.util.Stack;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.java.ast.JavaDataFlowNode;
|
||||
|
||||
|
||||
/**
|
||||
* @author raik
|
||||
* <p/>
|
||||
@@ -31,27 +30,27 @@ public class Structure {
|
||||
*/
|
||||
public DataFlowNode createNewNode(Node node) {
|
||||
// FUTURE Keep working on generalizing beyond just Java support
|
||||
return new JavaDataFlowNode(this.dataFlow, node);
|
||||
return new JavaDataFlowNode(this.dataFlow, node);
|
||||
}
|
||||
|
||||
public DataFlowNode createStartNode(int line) {
|
||||
return new StartOrEndDataFlowNode(this.dataFlow, line, true);
|
||||
return new StartOrEndDataFlowNode(this.dataFlow, line, true);
|
||||
}
|
||||
|
||||
public DataFlowNode createEndNode(int line) {
|
||||
return new StartOrEndDataFlowNode(this.dataFlow, line, false);
|
||||
return new StartOrEndDataFlowNode(this.dataFlow, line, false);
|
||||
}
|
||||
|
||||
public DataFlowNode getLast() {
|
||||
return this.dataFlow.getLast();
|
||||
return this.dataFlow.getLast();
|
||||
}
|
||||
|
||||
public DataFlowNode getFirst() {
|
||||
return this.dataFlow.getFirst();
|
||||
return this.dataFlow.getFirst();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// STACK FUNCTIONS
|
||||
// ----------------------------------------------------------------------------
|
||||
// STACK FUNCTIONS
|
||||
|
||||
/**
|
||||
* The braceStack contains all nodes which are important to link the data
|
||||
@@ -59,25 +58,23 @@ public class Structure {
|
||||
* There are 2 Stacks because the have to process differently.
|
||||
*/
|
||||
protected void pushOnStack(int type, DataFlowNode node) {
|
||||
StackObject obj = new StackObject(type, node);
|
||||
if (type == NodeType.RETURN_STATEMENT
|
||||
|| type == NodeType.BREAK_STATEMENT
|
||||
|| type == NodeType.CONTINUE_STATEMENT
|
||||
|| type == NodeType.THROW_STATEMENT) {
|
||||
// ugly solution - stores the type information in two ways
|
||||
continueBreakReturnStack.push(obj);
|
||||
} else {
|
||||
braceStack.push(obj);
|
||||
}
|
||||
((DataFlowNode) node).setType(type);
|
||||
StackObject obj = new StackObject(type, node);
|
||||
if (type == NodeType.RETURN_STATEMENT || type == NodeType.BREAK_STATEMENT
|
||||
|| type == NodeType.CONTINUE_STATEMENT || type == NodeType.THROW_STATEMENT) {
|
||||
// ugly solution - stores the type information in two ways
|
||||
continueBreakReturnStack.push(obj);
|
||||
} else {
|
||||
braceStack.push(obj);
|
||||
}
|
||||
node.setType(type);
|
||||
}
|
||||
|
||||
public List getBraceStack() {
|
||||
return braceStack;
|
||||
public List<StackObject> getBraceStack() {
|
||||
return braceStack;
|
||||
}
|
||||
|
||||
public List getContinueBreakReturnStack() {
|
||||
return continueBreakReturnStack;
|
||||
public List<StackObject> getContinueBreakReturnStack() {
|
||||
return continueBreakReturnStack;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,79 +30,79 @@ import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
|
||||
public class VariableAccessVisitor extends JavaParserVisitorAdapter {
|
||||
|
||||
public void compute(ASTMethodDeclaration node) {
|
||||
if (node.jjtGetParent() instanceof ASTClassOrInterfaceBodyDeclaration) {
|
||||
this.computeNow(node);
|
||||
}
|
||||
if (node.jjtGetParent() instanceof ASTClassOrInterfaceBodyDeclaration) {
|
||||
this.computeNow(node);
|
||||
}
|
||||
}
|
||||
|
||||
public void compute(ASTConstructorDeclaration node) {
|
||||
this.computeNow(node);
|
||||
this.computeNow(node);
|
||||
}
|
||||
|
||||
private void computeNow(Node node) {
|
||||
DataFlowNode inode = node.getDataFlowNode();
|
||||
|
||||
List<VariableAccess> undefinitions = markUsages(inode);
|
||||
List<VariableAccess> undefinitions = markUsages(inode);
|
||||
|
||||
// all variables are first in state undefinition
|
||||
DataFlowNode firstINode = inode.getFlow().get(0);
|
||||
firstINode.setVariableAccess(undefinitions);
|
||||
// all variables are first in state undefinition
|
||||
DataFlowNode firstINode = inode.getFlow().get(0);
|
||||
firstINode.setVariableAccess(undefinitions);
|
||||
|
||||
// all variables are getting undefined when leaving scope
|
||||
DataFlowNode lastINode = inode.getFlow().get(inode.getFlow().size() - 1);
|
||||
lastINode.setVariableAccess(undefinitions);
|
||||
// all variables are getting undefined when leaving scope
|
||||
DataFlowNode lastINode = inode.getFlow().get(inode.getFlow().size() - 1);
|
||||
lastINode.setVariableAccess(undefinitions);
|
||||
}
|
||||
|
||||
private List<VariableAccess> markUsages(DataFlowNode inode) {
|
||||
// undefinitions was once a field... seems like it works fine as a local
|
||||
List<VariableAccess> undefinitions = new ArrayList<VariableAccess>();
|
||||
Set<Map<VariableNameDeclaration, List<NameOccurrence>>> variableDeclarations = collectDeclarations(inode);
|
||||
for (Map<VariableNameDeclaration, List<NameOccurrence>> declarations: variableDeclarations) {
|
||||
for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry: declarations.entrySet()) {
|
||||
VariableNameDeclaration vnd = entry.getKey();
|
||||
// undefinitions was once a field... seems like it works fine as a local
|
||||
List<VariableAccess> undefinitions = new ArrayList<VariableAccess>();
|
||||
Set<Map<VariableNameDeclaration, List<NameOccurrence>>> variableDeclarations = collectDeclarations(inode);
|
||||
for (Map<VariableNameDeclaration, List<NameOccurrence>> declarations : variableDeclarations) {
|
||||
for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : declarations.entrySet()) {
|
||||
VariableNameDeclaration vnd = entry.getKey();
|
||||
|
||||
if (vnd.getAccessNodeParent() instanceof ASTFormalParameter) {
|
||||
// no definition/undefinition/references for parameters
|
||||
continue;
|
||||
} else if (((Node)vnd.getAccessNodeParent()).getFirstChildOfType(ASTVariableInitializer.class) != null) {
|
||||
// add definition for initialized variables
|
||||
addVariableAccess(
|
||||
vnd.getNode(),
|
||||
new VariableAccess(VariableAccess.DEFINITION, vnd.getImage()),
|
||||
inode.getFlow());
|
||||
}
|
||||
undefinitions.add(new VariableAccess(VariableAccess.UNDEFINITION, vnd.getImage()));
|
||||
if (vnd.getAccessNodeParent() instanceof ASTFormalParameter) {
|
||||
// no definition/undefinition/references for parameters
|
||||
continue;
|
||||
} else if (((Node) vnd.getAccessNodeParent()).getFirstChildOfType(ASTVariableInitializer.class) != null) {
|
||||
// add definition for initialized variables
|
||||
addVariableAccess(vnd.getNode(), new VariableAccess(VariableAccess.DEFINITION, vnd.getImage()),
|
||||
inode.getFlow());
|
||||
}
|
||||
undefinitions.add(new VariableAccess(VariableAccess.UNDEFINITION, vnd.getImage()));
|
||||
|
||||
for (NameOccurrence occurrence: entry.getValue()) {
|
||||
addAccess(occurrence, inode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefinitions;
|
||||
for (NameOccurrence occurrence : entry.getValue()) {
|
||||
addAccess(occurrence, inode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefinitions;
|
||||
}
|
||||
|
||||
private Set<Map<VariableNameDeclaration, List<NameOccurrence>>> collectDeclarations(DataFlowNode inode) {
|
||||
Set<Map<VariableNameDeclaration, List<NameOccurrence>>> decls = new HashSet<Map<VariableNameDeclaration, List<NameOccurrence>>>();
|
||||
Map<VariableNameDeclaration, List<NameOccurrence>> varDecls;
|
||||
for (int i = 0; i < inode.getFlow().size(); i++) {
|
||||
DataFlowNode n = inode.getFlow().get(i);
|
||||
if (n instanceof StartOrEndDataFlowNode) {
|
||||
continue;
|
||||
}
|
||||
varDecls = n.getNode().getScope().getVariableDeclarations();
|
||||
if (!decls.contains(varDecls)) {
|
||||
decls.add(varDecls);
|
||||
}
|
||||
}
|
||||
return decls;
|
||||
Set<Map<VariableNameDeclaration, List<NameOccurrence>>> decls = new HashSet<Map<VariableNameDeclaration, List<NameOccurrence>>>();
|
||||
Map<VariableNameDeclaration, List<NameOccurrence>> varDecls;
|
||||
for (int i = 0; i < inode.getFlow().size(); i++) {
|
||||
DataFlowNode n = inode.getFlow().get(i);
|
||||
if (n instanceof StartOrEndDataFlowNode) {
|
||||
continue;
|
||||
}
|
||||
varDecls = n.getNode().getScope().getVariableDeclarations();
|
||||
if (!decls.contains(varDecls)) {
|
||||
decls.add(varDecls);
|
||||
}
|
||||
}
|
||||
return decls;
|
||||
}
|
||||
|
||||
private void addAccess(NameOccurrence occurrence, DataFlowNode inode) {
|
||||
if (occurrence.isOnLeftHandSide()) {
|
||||
this.addVariableAccess(occurrence.getLocation(), new VariableAccess(VariableAccess.DEFINITION, occurrence.getImage()), inode.getFlow());
|
||||
} else if (occurrence.isOnRightHandSide() || (!occurrence.isOnLeftHandSide() && !occurrence.isOnRightHandSide())) {
|
||||
this.addVariableAccess(occurrence.getLocation(), new VariableAccess(VariableAccess.REFERENCING, occurrence.getImage()), inode.getFlow());
|
||||
}
|
||||
if (occurrence.isOnLeftHandSide()) {
|
||||
this.addVariableAccess(occurrence.getLocation(), new VariableAccess(VariableAccess.DEFINITION, occurrence
|
||||
.getImage()), inode.getFlow());
|
||||
} else if (occurrence.isOnRightHandSide() || !occurrence.isOnLeftHandSide() && !occurrence.isOnRightHandSide()) {
|
||||
this.addVariableAccess(occurrence.getLocation(), new VariableAccess(VariableAccess.REFERENCING, occurrence
|
||||
.getImage()), inode.getFlow());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,24 +111,24 @@ public class VariableAccessVisitor extends JavaParserVisitorAdapter {
|
||||
* @param va variable access to add
|
||||
* @param flow dataflownodes that can contain the node.
|
||||
*/
|
||||
private void addVariableAccess(Node node, VariableAccess va, List flow) {
|
||||
// backwards to find the right inode (not a method declaration)
|
||||
for (int i = flow.size()-1; i > 0; i--) {
|
||||
DataFlowNode inode = (DataFlowNode) flow.get(i);
|
||||
if (inode.getNode() == null) {
|
||||
continue;
|
||||
}
|
||||
private void addVariableAccess(Node node, VariableAccess va, List<DataFlowNode> flow) {
|
||||
// backwards to find the right inode (not a method declaration)
|
||||
for (int i = flow.size() - 1; i > 0; i--) {
|
||||
DataFlowNode inode = flow.get(i);
|
||||
if (inode.getNode() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<? extends Node> children = inode.getNode().findChildrenOfType(node.getClass());
|
||||
for (Node n: children) {
|
||||
if (node.equals(n)) {
|
||||
List<VariableAccess> v = new ArrayList<VariableAccess>();
|
||||
v.add(va);
|
||||
inode.setVariableAccess(v);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
List<? extends Node> children = inode.getNode().findChildrenOfType(node.getClass());
|
||||
for (Node n : children) {
|
||||
if (node.equals(n)) {
|
||||
List<VariableAccess> v = new ArrayList<VariableAccess>();
|
||||
v.add(va);
|
||||
inode.setVariableAccess(v);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -66,7 +66,7 @@ public abstract class AbstractNode implements Node {
|
||||
}
|
||||
|
||||
public int jjtGetNumChildren() {
|
||||
return (children == null) ? 0 : children.length;
|
||||
return children == null ? 0 : children.length;
|
||||
}
|
||||
|
||||
public int jjtGetId() {
|
||||
@@ -77,6 +77,7 @@ public abstract class AbstractNode implements Node {
|
||||
* Subclasses should implement this method to return a name usable with
|
||||
* XPathRule for evaluating Element Names.
|
||||
*/
|
||||
@Override
|
||||
public abstract String toString();
|
||||
|
||||
public String getImage() {
|
||||
@@ -103,7 +104,7 @@ public abstract class AbstractNode implements Node {
|
||||
if (beginColumn != -1) {
|
||||
return beginColumn;
|
||||
} else {
|
||||
if ((children != null) && (children.length > 0)) {
|
||||
if (children != null && children.length > 0) {
|
||||
return children[0].getBeginColumn();
|
||||
} else {
|
||||
throw new RuntimeException("Unable to determine begining line of Node.");
|
||||
@@ -265,7 +266,7 @@ public abstract class AbstractNode implements Node {
|
||||
Attribute attr = iter.next();
|
||||
element.setAttribute(attr.getName(), attr.getValue());
|
||||
}
|
||||
for (Iterator iter = docNav.getChildAxisIterator(this); iter.hasNext();) {
|
||||
for (Iterator<Node> iter = docNav.getChildAxisIterator(this); iter.hasNext();) {
|
||||
AbstractNode child = (AbstractNode) iter.next();
|
||||
child.appendElement(element);
|
||||
}
|
||||
@@ -285,11 +286,13 @@ public abstract class AbstractNode implements Node {
|
||||
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
|
||||
Node n = node.jjtGetChild(i);
|
||||
if (n != null) {
|
||||
if (n.getClass().equals(childType))
|
||||
if (n.getClass().equals(childType)) {
|
||||
return (T) n;
|
||||
}
|
||||
T n2 = getFirstChildOfType(childType, n);
|
||||
if (n2 != null)
|
||||
if (n2 != null) {
|
||||
return n2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -15,23 +15,31 @@ import net.sourceforge.pmd.lang.ast.Node;
|
||||
public class AttributeAxisIterator implements Iterator<Attribute> {
|
||||
|
||||
private static class MethodWrapper {
|
||||
public Method method;
|
||||
public String name;
|
||||
|
||||
public MethodWrapper(Method m) {
|
||||
this.method = m;
|
||||
this.name = truncateMethodName(m.getName());
|
||||
}
|
||||
public Method method;
|
||||
public String name;
|
||||
|
||||
private String truncateMethodName(String n) {
|
||||
// about 70% of the methods start with 'get', so this case goes first
|
||||
if (n.startsWith("get")) return n.substring("get".length());
|
||||
if (n.startsWith("is")) return n.substring("is".length());
|
||||
if (n.startsWith("has")) return n.substring("has".length());
|
||||
if (n.startsWith("uses")) return n.substring("uses".length());
|
||||
|
||||
return n;
|
||||
}
|
||||
public MethodWrapper(Method m) {
|
||||
this.method = m;
|
||||
this.name = truncateMethodName(m.getName());
|
||||
}
|
||||
|
||||
private String truncateMethodName(String n) {
|
||||
// about 70% of the methods start with 'get', so this case goes first
|
||||
if (n.startsWith("get")) {
|
||||
return n.substring("get".length());
|
||||
}
|
||||
if (n.startsWith("is")) {
|
||||
return n.substring("is".length());
|
||||
}
|
||||
if (n.startsWith("has")) {
|
||||
return n.substring("has".length());
|
||||
}
|
||||
if (n.startsWith("uses")) {
|
||||
return n.substring("uses".length());
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
private Attribute currObj;
|
||||
@@ -39,64 +47,64 @@ public class AttributeAxisIterator implements Iterator<Attribute> {
|
||||
private int position;
|
||||
private Node node;
|
||||
|
||||
private static Map<Class, MethodWrapper[]> methodCache = new HashMap<Class, MethodWrapper[]>();
|
||||
private static Map<Class<?>, MethodWrapper[]> methodCache = new HashMap<Class<?>, MethodWrapper[]>();
|
||||
|
||||
public AttributeAxisIterator(Node contextNode) {
|
||||
this.node = contextNode;
|
||||
if (!methodCache.containsKey(contextNode.getClass())) {
|
||||
Method[] preFilter = contextNode.getClass().getMethods();
|
||||
List<MethodWrapper> postFilter = new ArrayList<MethodWrapper>();
|
||||
for (int i = 0; i < preFilter.length; i++) {
|
||||
if (isAttributeAccessor(preFilter[i])) {
|
||||
postFilter.add(new MethodWrapper(preFilter[i]));
|
||||
}
|
||||
}
|
||||
methodCache.put(contextNode.getClass(), postFilter.toArray(new MethodWrapper[postFilter.size()]));
|
||||
}
|
||||
this.methodWrappers = methodCache.get(contextNode.getClass());
|
||||
this.node = contextNode;
|
||||
if (!methodCache.containsKey(contextNode.getClass())) {
|
||||
Method[] preFilter = contextNode.getClass().getMethods();
|
||||
List<MethodWrapper> postFilter = new ArrayList<MethodWrapper>();
|
||||
for (Method element : preFilter) {
|
||||
if (isAttributeAccessor(element)) {
|
||||
postFilter.add(new MethodWrapper(element));
|
||||
}
|
||||
}
|
||||
methodCache.put(contextNode.getClass(), postFilter.toArray(new MethodWrapper[postFilter.size()]));
|
||||
}
|
||||
this.methodWrappers = methodCache.get(contextNode.getClass());
|
||||
|
||||
this.position = 0;
|
||||
this.currObj = getNextAttribute();
|
||||
this.position = 0;
|
||||
this.currObj = getNextAttribute();
|
||||
}
|
||||
|
||||
public Attribute next() {
|
||||
if (currObj == null) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
Attribute ret = currObj;
|
||||
currObj = getNextAttribute();
|
||||
return ret;
|
||||
if (currObj == null) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
Attribute ret = currObj;
|
||||
currObj = getNextAttribute();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return currObj != null;
|
||||
return currObj != null;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private Attribute getNextAttribute() {
|
||||
if (position == methodWrappers.length) {
|
||||
return null;
|
||||
}
|
||||
MethodWrapper m = methodWrappers[position++];
|
||||
return new Attribute(node, m.name, m.method);
|
||||
if (position == methodWrappers.length) {
|
||||
return null;
|
||||
}
|
||||
MethodWrapper m = methodWrappers[position++];
|
||||
return new Attribute(node, m.name, m.method);
|
||||
}
|
||||
|
||||
protected boolean isAttributeAccessor(Method method) {
|
||||
|
||||
String methodName = method.getName();
|
||||
|
||||
return (Integer.TYPE == method.getReturnType() || Boolean.TYPE == method.getReturnType() || String.class == method.getReturnType())
|
||||
&& (method.getParameterTypes().length == 0)
|
||||
&& (Void.TYPE != method.getReturnType())
|
||||
&& !methodName.startsWith("jjt")
|
||||
&& !methodName.equals("toString")
|
||||
&& !methodName.equals("getScope")
|
||||
&& !methodName.equals("getClass")
|
||||
&& !methodName.equals("getTypeNameNode")
|
||||
&& !methodName.equals("getImportedNameNode")
|
||||
&& !methodName.equals("hashCode");
|
||||
|
||||
String methodName = method.getName();
|
||||
|
||||
return (Integer.TYPE == method.getReturnType() || Boolean.TYPE == method.getReturnType() || String.class == method
|
||||
.getReturnType())
|
||||
&& method.getParameterTypes().length == 0
|
||||
&& Void.TYPE != method.getReturnType()
|
||||
&& !methodName.startsWith("jjt")
|
||||
&& !methodName.equals("toString")
|
||||
&& !methodName.equals("getScope")
|
||||
&& !methodName.equals("getClass")
|
||||
&& !methodName.equals("getTypeNameNode")
|
||||
&& !methodName.equals("getImportedNameNode") && !methodName.equals("hashCode");
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -2,53 +2,54 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import net.sourceforge.pmd.Rule;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.Rule;
|
||||
|
||||
public class ASTAnnotation extends AbstractJavaNode {
|
||||
|
||||
private static List unusedRules = Arrays.asList(new String[]{"UnusedPrivateField","UnusedLocalVariable","UnusedPrivateMethod","UnusedFormalParameter"});
|
||||
private static List<String> unusedRules = Arrays.asList(new String[] { "UnusedPrivateField", "UnusedLocalVariable",
|
||||
"UnusedPrivateMethod", "UnusedFormalParameter" });
|
||||
|
||||
public ASTAnnotation(int id) {
|
||||
super(id);
|
||||
super(id);
|
||||
}
|
||||
|
||||
public ASTAnnotation(JavaParser p, int id) {
|
||||
super(p, id);
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
public boolean suppresses(Rule rule) {
|
||||
final String ruleAnno = "\"PMD." + rule.getName() + "\"";
|
||||
final String ruleAnno = "\"PMD." + rule.getName() + "\"";
|
||||
|
||||
if (jjtGetChild(0) instanceof ASTSingleMemberAnnotation) {
|
||||
ASTSingleMemberAnnotation n = (ASTSingleMemberAnnotation) jjtGetChild(0);
|
||||
if (jjtGetChild(0) instanceof ASTSingleMemberAnnotation) {
|
||||
ASTSingleMemberAnnotation n = (ASTSingleMemberAnnotation) jjtGetChild(0);
|
||||
|
||||
if (n.jjtGetChild(0) instanceof ASTName) {
|
||||
ASTName annName = ((ASTName) n.jjtGetChild(0));
|
||||
if (n.jjtGetChild(0) instanceof ASTName) {
|
||||
ASTName annName = (ASTName) n.jjtGetChild(0);
|
||||
|
||||
if (annName.getImage().equals("SuppressWarnings")) {
|
||||
List<ASTLiteral> nodes = n.findChildrenOfType(ASTLiteral.class);
|
||||
for (ASTLiteral element: nodes) {
|
||||
if (element.hasImageEqualTo("\"PMD\"")
|
||||
|| element.hasImageEqualTo(ruleAnno)
|
||||
// the SuppressWarnings("unused") annotation allows unused code
|
||||
// to be igored and is a Java standard annotation
|
||||
|| (element.hasImageEqualTo("\"unused\"") && unusedRules.contains(rule.getName()))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if (annName.getImage().equals("SuppressWarnings")) {
|
||||
List<ASTLiteral> nodes = n.findChildrenOfType(ASTLiteral.class);
|
||||
for (ASTLiteral element : nodes) {
|
||||
if (element.hasImageEqualTo("\"PMD\"") || element.hasImageEqualTo(ruleAnno)
|
||||
// the SuppressWarnings("unused") annotation allows unused code
|
||||
// to be ignored and is a Java standard annotation
|
||||
|| element.hasImageEqualTo("\"unused\"") && unusedRules.contains(rule.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept the visitor.
|
||||
*/
|
||||
@Override
|
||||
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
}
|
||||
@@ -8,21 +8,21 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
*/
|
||||
public abstract class AbstractJavaTypeNode extends AbstractJavaNode implements TypeNode {
|
||||
|
||||
public AbstractJavaTypeNode(int i) {
|
||||
super(i);
|
||||
}
|
||||
public AbstractJavaTypeNode(int i) {
|
||||
super(i);
|
||||
}
|
||||
|
||||
public AbstractJavaTypeNode(JavaParser p, int i) {
|
||||
super(p, i);
|
||||
}
|
||||
public AbstractJavaTypeNode(JavaParser p, int i) {
|
||||
super(p, i);
|
||||
}
|
||||
|
||||
private Class type;
|
||||
private Class<?> type;
|
||||
|
||||
public Class getType() {
|
||||
return type;
|
||||
}
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Class type) {
|
||||
this.type = type;
|
||||
}
|
||||
public void setType(Class<?> type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -22,14 +22,13 @@ import net.sourceforge.pmd.symboltable.NameOccurrence;
|
||||
* @version $Revision$
|
||||
*/
|
||||
public abstract class AbstractPoorMethodCall extends AbstractJavaRule {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The name of the type the method will be invoked against.
|
||||
* @return String
|
||||
*/
|
||||
protected abstract String targetTypename();
|
||||
|
||||
|
||||
/**
|
||||
* Return the names of all the methods we are scanning for, no brackets or
|
||||
* argument types.
|
||||
@@ -37,7 +36,7 @@ public abstract class AbstractPoorMethodCall extends AbstractJavaRule {
|
||||
* @return String[]
|
||||
*/
|
||||
protected abstract String[] methodNames();
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the string argument at the stated position being sent to
|
||||
* the method is ok or not. Return true if you want to record the method call
|
||||
@@ -48,7 +47,7 @@ public abstract class AbstractPoorMethodCall extends AbstractJavaRule {
|
||||
* @return boolean
|
||||
*/
|
||||
protected abstract boolean isViolationArgument(int argIndex, String arg);
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the name occurrence is one of the method calls
|
||||
* we are interested in.
|
||||
@@ -57,18 +56,22 @@ public abstract class AbstractPoorMethodCall extends AbstractJavaRule {
|
||||
* @return boolean
|
||||
*/
|
||||
private boolean isNotedMethod(NameOccurrence occurrence) {
|
||||
|
||||
if (occurrence == null) return false;
|
||||
|
||||
String methodCall = occurrence.getImage();
|
||||
String[] methodNames = methodNames();
|
||||
|
||||
for (int i=0; i<methodNames.length; i++) {
|
||||
if (methodCall.indexOf(methodNames[i]) != -1) return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
if (occurrence == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String methodCall = occurrence.getImage();
|
||||
String[] methodNames = methodNames();
|
||||
|
||||
for (String element : methodNames) {
|
||||
if (methodCall.indexOf(element) != -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the value argument is a single character string.
|
||||
*
|
||||
@@ -76,9 +79,9 @@ public abstract class AbstractPoorMethodCall extends AbstractJavaRule {
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isSingleCharAsString(String value) {
|
||||
return value.length() == 3 && value.charAt(0) == '\"';
|
||||
return value.length() == 3 && value.charAt(0) == '\"';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method visit.
|
||||
* @param node ASTVariableDeclaratorId
|
||||
@@ -86,32 +89,32 @@ public abstract class AbstractPoorMethodCall extends AbstractJavaRule {
|
||||
* @return Object
|
||||
* @see net.sourceforge.pmd.lang.java.ast.JavaParserVisitor#visit(ASTVariableDeclaratorId, Object)
|
||||
*/
|
||||
@Override
|
||||
public Object visit(ASTVariableDeclaratorId node, Object data) {
|
||||
|
||||
if (!node.getNameDeclaration().getTypeImage().equals(targetTypename())) {
|
||||
return data;
|
||||
}
|
||||
|
||||
for (NameOccurrence occ: node.getUsages()) {
|
||||
if (isNotedMethod(occ.getNameForWhichThisIsAQualifier())) {
|
||||
Node parent = occ.getLocation().jjtGetParent().jjtGetParent();
|
||||
if (parent instanceof ASTPrimaryExpression) {
|
||||
// bail out if it's something like indexOf("a" + "b")
|
||||
List additives = parent.findChildrenOfType(ASTAdditiveExpression.class);
|
||||
if (!additives.isEmpty()) {
|
||||
return data;
|
||||
}
|
||||
List literals = parent.findChildrenOfType(ASTLiteral.class);
|
||||
for (int l=0; l<literals.size(); l++) {
|
||||
ASTLiteral literal = (ASTLiteral)literals.get(l);
|
||||
if (isViolationArgument(l, literal.getImage())) {
|
||||
addViolation(data, occ.getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
|
||||
if (!node.getNameDeclaration().getTypeImage().equals(targetTypename())) {
|
||||
return data;
|
||||
}
|
||||
|
||||
for (NameOccurrence occ : node.getUsages()) {
|
||||
if (isNotedMethod(occ.getNameForWhichThisIsAQualifier())) {
|
||||
Node parent = occ.getLocation().jjtGetParent().jjtGetParent();
|
||||
if (parent instanceof ASTPrimaryExpression) {
|
||||
// bail out if it's something like indexOf("a" + "b")
|
||||
List<ASTAdditiveExpression> additives = parent.findChildrenOfType(ASTAdditiveExpression.class);
|
||||
if (!additives.isEmpty()) {
|
||||
return data;
|
||||
}
|
||||
List<ASTLiteral> literals = parent.findChildrenOfType(ASTLiteral.class);
|
||||
for (int l = 0; l < literals.size(); l++) {
|
||||
ASTLiteral literal = literals.get(l);
|
||||
if (isViolationArgument(l, literal.getImage())) {
|
||||
addViolation(data, occ.getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public abstract class AbstractStatisticalJavaRule extends AbstractJavaRule imple
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(List<Node> nodes, RuleContext ctx) {
|
||||
public void apply(List<? extends Node> nodes, RuleContext ctx) {
|
||||
super.apply(nodes, ctx);
|
||||
helper.apply(ctx);
|
||||
}
|
||||
|
||||
+56
-51
@@ -18,68 +18,73 @@ public class OverrideBothEqualsAndHashcodeRule extends AbstractJavaRule {
|
||||
private boolean containsEquals = false;
|
||||
|
||||
private boolean containsHashCode = false;
|
||||
|
||||
|
||||
private Node nodeFound = null;
|
||||
|
||||
@Override
|
||||
public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
|
||||
if (node.isInterface()) {
|
||||
return data;
|
||||
}
|
||||
super.visit(node, data);
|
||||
if (!implementsComparable && (containsEquals ^ containsHashCode)) {
|
||||
if(nodeFound == null){
|
||||
nodeFound = node;
|
||||
}
|
||||
addViolation(data, nodeFound);
|
||||
}
|
||||
implementsComparable = containsEquals = containsHashCode = false;
|
||||
nodeFound = null;
|
||||
return data;
|
||||
if (node.isInterface()) {
|
||||
return data;
|
||||
}
|
||||
super.visit(node, data);
|
||||
if (!implementsComparable && containsEquals ^ containsHashCode) {
|
||||
if (nodeFound == null) {
|
||||
nodeFound = node;
|
||||
}
|
||||
addViolation(data, nodeFound);
|
||||
}
|
||||
implementsComparable = containsEquals = containsHashCode = false;
|
||||
nodeFound = null;
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTImplementsList node, Object data) {
|
||||
for (int ix = 0; ix < node.jjtGetNumChildren(); ix++) {
|
||||
if (node.jjtGetChild(ix).getClass().equals(ASTClassOrInterfaceType.class)) {
|
||||
ASTClassOrInterfaceType cit = (ASTClassOrInterfaceType)node.jjtGetChild(ix);
|
||||
Class clazz = cit.getType();
|
||||
if (clazz != null || node.jjtGetChild(ix).hasImageEqualTo("Comparable")) {
|
||||
implementsComparable = true;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.visit(node, data);
|
||||
for (int ix = 0; ix < node.jjtGetNumChildren(); ix++) {
|
||||
if (node.jjtGetChild(ix).getClass().equals(ASTClassOrInterfaceType.class)) {
|
||||
ASTClassOrInterfaceType cit = (ASTClassOrInterfaceType) node.jjtGetChild(ix);
|
||||
Class<?> clazz = cit.getType();
|
||||
if (clazz != null || node.jjtGetChild(ix).hasImageEqualTo("Comparable")) {
|
||||
implementsComparable = true;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTMethodDeclarator node, Object data) {
|
||||
if (implementsComparable) {
|
||||
return data;
|
||||
}
|
||||
if (implementsComparable) {
|
||||
return data;
|
||||
}
|
||||
|
||||
int iFormalParams = 0;
|
||||
String paramName = null;
|
||||
for (int ix = 0; ix < node.jjtGetNumChildren(); ix++) {
|
||||
Node sn = node.jjtGetChild(ix);
|
||||
if (sn.getClass().equals(ASTFormalParameters.class)) {
|
||||
List<ASTFormalParameter> allParams = ((ASTFormalParameters) sn).findChildrenOfType(ASTFormalParameter.class);
|
||||
for (ASTFormalParameter formalParam: allParams) {
|
||||
iFormalParams++;
|
||||
ASTClassOrInterfaceType param = formalParam.getFirstChildOfType(ASTClassOrInterfaceType.class);
|
||||
if (param != null) {
|
||||
paramName = param.getImage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int iFormalParams = 0;
|
||||
String paramName = null;
|
||||
for (int ix = 0; ix < node.jjtGetNumChildren(); ix++) {
|
||||
Node sn = node.jjtGetChild(ix);
|
||||
if (sn.getClass().equals(ASTFormalParameters.class)) {
|
||||
List<ASTFormalParameter> allParams = ((ASTFormalParameters) sn)
|
||||
.findChildrenOfType(ASTFormalParameter.class);
|
||||
for (ASTFormalParameter formalParam : allParams) {
|
||||
iFormalParams++;
|
||||
ASTClassOrInterfaceType param = formalParam.getFirstChildOfType(ASTClassOrInterfaceType.class);
|
||||
if (param != null) {
|
||||
paramName = param.getImage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (iFormalParams == 0 && node.hasImageEqualTo("hashCode")) {
|
||||
containsHashCode = true;
|
||||
nodeFound = node;
|
||||
} else if (iFormalParams == 1 && node.hasImageEqualTo("equals") && ("Object".equals(paramName) || "java.lang.Object".equals(paramName))) {
|
||||
containsEquals = true;
|
||||
nodeFound = node;
|
||||
}
|
||||
return super.visit(node, data);
|
||||
if (iFormalParams == 0 && node.hasImageEqualTo("hashCode")) {
|
||||
containsHashCode = true;
|
||||
nodeFound = node;
|
||||
} else if (iFormalParams == 1 && node.hasImageEqualTo("equals")
|
||||
&& ("Object".equals(paramName) || "java.lang.Object".equals(paramName))) {
|
||||
containsEquals = true;
|
||||
nodeFound = node;
|
||||
}
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
}
|
||||
+164
-157
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,9 +1,5 @@
|
||||
package net.sourceforge.pmd.lang.java.rule.codesize;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import net.sourceforge.pmd.RuleContext;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
||||
import net.sourceforge.pmd.stat.DataPoint;
|
||||
|
||||
@@ -14,21 +10,21 @@ import net.sourceforge.pmd.stat.DataPoint;
|
||||
*/
|
||||
public class NcssMethodCountRule extends AbstractNcssCountRule {
|
||||
|
||||
/**
|
||||
* Count the size of all non-constructor methods.
|
||||
*/
|
||||
public NcssMethodCountRule() {
|
||||
super( ASTMethodDeclaration.class );
|
||||
}
|
||||
/**
|
||||
* Count the size of all non-constructor methods.
|
||||
*/
|
||||
public NcssMethodCountRule() {
|
||||
super(ASTMethodDeclaration.class);
|
||||
}
|
||||
|
||||
public Object visit(ASTMethodDeclaration node, Object data) {
|
||||
return super.visit( node, data );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getViolationParameters(DataPoint point) {
|
||||
return new String[] {
|
||||
( (ASTMethodDeclaration) point.getNode() ).getMethodName(),
|
||||
String.valueOf( (int) point.getScore() ) };
|
||||
}
|
||||
@Override
|
||||
public Object visit(ASTMethodDeclaration node, Object data) {
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getViolationParameters(DataPoint point) {
|
||||
return new String[] { ((ASTMethodDeclaration) point.getNode()).getMethodName(),
|
||||
String.valueOf((int) point.getScore()) };
|
||||
}
|
||||
}
|
||||
Loaded 30 of 59 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user