diff --git a/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsLanguage.java b/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsLanguage.java index f6a1bd145f..2bf957a1ad 100644 --- a/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsLanguage.java +++ b/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsLanguage.java @@ -1,6 +1,7 @@ /** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ + package net.sourceforge.pmd.cpd; import java.util.Properties; @@ -20,7 +21,7 @@ public class CsLanguage extends AbstractLanguage { } public final void setProperties(Properties properties) { - CsTokenizer tokenizer = (CsTokenizer)getTokenizer(); + CsTokenizer tokenizer = (CsTokenizer) getTokenizer(); tokenizer.setProperties(properties); } } diff --git a/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java b/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java index c9dcce4a4e..1f595003f3 100644 --- a/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java +++ b/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java @@ -1,6 +1,7 @@ /** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ + package net.sourceforge.pmd.cpd; import java.io.BufferedReader; @@ -30,30 +31,30 @@ public class CsTokenizer implements Tokenizer { @Override public void tokenize(SourceCode sourceCode, Tokens tokenEntries) { - Tokenizer tokenizer = - new Tokenizer(sourceCode.getCodeBuffer().toString()); + Tokenizer tokenizer = new Tokenizer(sourceCode.getCodeBuffer().toString()); Token token = tokenizer.getNextToken(); while (!token.equals(Token.EOF)) { Token lookAhead = tokenizer.getNextToken(); // Ignore using directives - // Only using directives should be ignored, because these are used to import namespaces + // Only using directives should be ignored, because these are used + // to import namespaces // // Using directive: 'using System.Math;' // Using statement: 'using (Font font1 = new Font(..)) { .. }' - if (ignoreUsings && - "using".equals(token.image) && - !"(".equals(lookAhead.image) - ) { - // We replace the 'using' token by a random token, because it should not be part of - // any duplication block. When we omit it from the token stream, there is a change that - // we get a duplication block that starts before the 'using' directives and ends afterwards. - String randomTokenText = - RandomStringUtils.randomAlphanumeric(20); + if (ignoreUsings && "using".equals(token.image) && !"(".equals(lookAhead.image)) { + // We replace the 'using' token by a random token, because it + // should not be part of + // any duplication block. When we omit it from the token stream, + // there is a change that + // we get a duplication block that starts before the 'using' + // directives and ends afterwards. + String randomTokenText = RandomStringUtils.randomAlphanumeric(20); token = new Token(randomTokenText, token.lineNumber); - //Skip all other tokens of the using directive to prevent a partial matching + // Skip all other tokens of the using directive to prevent a + // partial matching while (!";".equals(lookAhead.image) && !lookAhead.equals(Token.EOF)) { lookAhead = tokenizer.getNextToken(); } @@ -71,13 +72,12 @@ public class CsTokenizer implements Tokenizer { this.ignoreUsings = ignoreUsings; } - private static class Tokenizer implements Closeable { private boolean endOfFile; private int line; private final PushbackReader reader; - public Tokenizer(String sourceCode) { + Tokenizer(String sourceCode) { endOfFile = false; line = 1; reader = new PushbackReader(new BufferedReader(new CharArrayReader(sourceCode.toCharArray()))); @@ -120,7 +120,7 @@ public class CsTokenizer implements Tokenizer { } else if (ic == c) { ic = reader.read(); if (ic == '=') { - return new Token(c + c + "=", line); + return new Token(c + c + "=", line); } else { reader.unread(ic); return new Token(String.valueOf(c) + c, line); @@ -130,7 +130,7 @@ public class CsTokenizer implements Tokenizer { return new Token(String.valueOf(c), line); } - // = == & &= && | |= || + += ++ - -= -- + // = == & &= && | |= || + += ++ - -= -- case '=': case '&': case '|': @@ -144,7 +144,7 @@ public class CsTokenizer implements Tokenizer { return new Token(String.valueOf(c), line); } - // ! != * *= % %= ^ ^= ~ ~= + // ! != * *= % %= ^ ^= ~ ~= case '!': case '*': case '%': @@ -158,7 +158,7 @@ public class CsTokenizer implements Tokenizer { return new Token(String.valueOf(c), line); } - // strings & chars + // strings & chars case '"': case '\'': int beginLine = line; @@ -189,9 +189,11 @@ public class CsTokenizer implements Tokenizer { // / /= /*...*/ //... case '/': - switch (c = (char) (ic = reader.read())) { + ic = reader.read(); + c = (char) ic; + switch (c) { case '*': - //int beginLine = line; + // int beginLine = line; int state = 1; b = new StringBuilder(); b.append("/*"); @@ -251,30 +253,31 @@ public class CsTokenizer implements Tokenizer { b = new StringBuilder(); do { b.append(c); - c = (char) (ic = reader.read()); + ic = reader.read(); + c = (char) ic; } while (Character.isJavaIdentifierPart(c)); reader.unread(ic); return new Token(b.toString(), line); - } - // numbers - else if (Character.isDigit(c) || c == '.') { + } else if (Character.isDigit(c) || c == '.') { + // numbers b = new StringBuilder(); do { b.append(c); if (c == 'e' || c == 'E') { - c = (char) (ic = reader.read()); + ic = reader.read(); + c = (char) ic; if ("1234567890-".indexOf(c) == -1) { break; } b.append(c); } - c = (char) (ic = reader.read()); + ic = reader.read(); + c = (char) ic; } while ("1234567890.iIlLfFdDsSuUeExX".indexOf(c) != -1); reader.unread(ic); return new Token(b.toString(), line); - } - // anything else - else { + } else { + // anything else return new Token(String.valueOf(c), line); } } @@ -298,7 +301,7 @@ public class CsTokenizer implements Tokenizer { public final String image; public final int lineNumber; - public Token(String image, int lineNumber) { + Token(String image, int lineNumber) { this.image = image; this.lineNumber = lineNumber; } diff --git a/pmd-cs/src/main/java/net/sourceforge/pmd/lang/cs/CsLanguageModule.java b/pmd-cs/src/main/java/net/sourceforge/pmd/lang/cs/CsLanguageModule.java index c24e2ffdbd..238014b832 100644 --- a/pmd-cs/src/main/java/net/sourceforge/pmd/lang/cs/CsLanguageModule.java +++ b/pmd-cs/src/main/java/net/sourceforge/pmd/lang/cs/CsLanguageModule.java @@ -1,6 +1,7 @@ /** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ + package net.sourceforge.pmd.lang.cs; import net.sourceforge.pmd.lang.BaseLanguageModule; diff --git a/pmd-cs/src/test/java/net/sourceforge/pmd/cpd/CsTokenizerTest.java b/pmd-cs/src/test/java/net/sourceforge/pmd/cpd/CsTokenizerTest.java index 9c1a9a9014..20aefc8194 100644 --- a/pmd-cs/src/test/java/net/sourceforge/pmd/cpd/CsTokenizerTest.java +++ b/pmd-cs/src/test/java/net/sourceforge/pmd/cpd/CsTokenizerTest.java @@ -44,13 +44,8 @@ public class CsTokenizerTest { @Test public void testSimpleClassMethodMultipleLines() { - tokenizer.tokenize(toSourceCode( - "class Foo {\n" - + " public String foo(int a) {\n" - + " int i = a;\n" - + " return \"x\" + a;\n" - + " }\n" - + "}"), tokens); + tokenizer.tokenize(toSourceCode("class Foo {\n" + " public String foo(int a) {\n" + " int i = a;\n" + + " return \"x\" + a;\n" + " }\n" + "}"), tokens); assertEquals(22, tokens.size()); List tokenList = tokens.getTokens(); assertEquals(1, tokenList.get(0).getBeginLine()); @@ -70,7 +65,6 @@ public class CsTokenizerTest { assertEquals(5, tokens.size()); } - @Test public void testCommentsIgnored1() { tokenizer.tokenize(toSourceCode("class Foo { /* class * ** X */ }"), tokens); @@ -91,35 +85,22 @@ public class CsTokenizerTest { @Test public void testMoreTokens() { - tokenizer.tokenize(toSourceCode( - "class Foo {\n" - + " void bar() {\n" - + " int a = 1 >> 2; \n" - + " a += 1; \n" - + " a++; \n" - + " a /= 3e2; \n" - + " float f = -3.1; \n" - + " f *= 2; \n" - + " bool b = ! (f == 2.0 || f >= 1.0 && f <= 2.0) \n" - + " }\n" - + "}" - ), tokens); + tokenizer + .tokenize( + toSourceCode("class Foo {\n" + " void bar() {\n" + " int a = 1 >> 2; \n" + " a += 1; \n" + + " a++; \n" + " a /= 3e2; \n" + " float f = -3.1; \n" + " f *= 2; \n" + + " bool b = ! (f == 2.0 || f >= 1.0 && f <= 2.0) \n" + " }\n" + "}"), + tokens); assertEquals(50, tokens.size()); } @Test public void testLineNumberAfterMultilineComment() { - tokenizer.tokenize(toSourceCode( - "/* This is a multiline comment \n" - + " * \n" - + " * Lorem ipsum dolor sit amet, \n" - + " * consectetur adipiscing elit \n" - + " */\n" - + "\n" - + "class Foo {\n" - + "\n" - + "}" - ), tokens); + tokenizer + .tokenize( + toSourceCode("/* This is a multiline comment \n" + " * \n" + " * Lorem ipsum dolor sit amet, \n" + + " * consectetur adipiscing elit \n" + " */\n" + "\n" + "class Foo {\n" + "\n" + "}"), + tokens); assertEquals(5, tokens.size()); assertEquals(7, tokens.getTokens().get(0).getBeginLine()); } @@ -127,15 +108,9 @@ public class CsTokenizerTest { @Test public void testLineNumberAfterMultilineString() { tokenizer.tokenize(toSourceCode( - "class Foo {\n" - + " void bar() {\n" - + " String query = \n" - + " @\"SELECT foo, bar\n" - + " FROM table \n" - + " WHERE id = 42\"; \n" - + " }\n" - + "}" - ), tokens); + "class Foo {\n" + " void bar() {\n" + " String query = \n" + " @\"SELECT foo, bar\n" + + " FROM table \n" + " WHERE id = 42\"; \n" + " }\n" + "}"), + tokens); assertEquals(16, tokens.size()); assertEquals(8, tokens.getTokens().get(14).getBeginLine()); } @@ -152,10 +127,8 @@ public class CsTokenizerTest { public void testUsingStatementsAreNotIgnored() { tokenizer.setIgnoreUsings(true); tokenizer.tokenize(toSourceCode( - "using (Font font1 = new Font(\"Arial\", 10.0f)) {\n" - + " byte charset = font1.GdiCharSet;\n" - + "}\n" - ), tokens); + "using (Font font1 = new Font(\"Arial\", 10.0f)) {\n" + " byte charset = font1.GdiCharSet;\n" + "}\n"), + tokens); assertEquals("using", tokens.getTokens().get(0).toString()); }