diff options
author | Evgeny Mandrikov <mandrikov@gmail.com> | 2011-09-26 22:16:29 +0400 |
---|---|---|
committer | Evgeny Mandrikov <mandrikov@gmail.com> | 2011-09-27 02:07:56 +0400 |
commit | c7c56a4d5ff5e0721f56c245ef11df52d2cc945c (patch) | |
tree | 4bfda245083a70b758ce141b9314c069472bee45 /sonar-duplications/src/main/java/org/sonar | |
parent | e01749f160a9bead858e17b37c2b1dc0be93b7bc (diff) | |
download | sonarqube-c7c56a4d5ff5e0721f56c245ef11df52d2cc945c.tar.gz sonarqube-c7c56a4d5ff5e0721f56c245ef11df52d2cc945c.zip |
SONAR-2837 Fix detection of false-positive duplication in case of initialization of multidimensional array
Diffstat (limited to 'sonar-duplications/src/main/java/org/sonar')
3 files changed, 75 insertions, 4 deletions
diff --git a/sonar-duplications/src/main/java/org/sonar/duplications/java/BridgeWithExceptionTokenMatcher.java b/sonar-duplications/src/main/java/org/sonar/duplications/java/BridgeWithExceptionTokenMatcher.java new file mode 100644 index 00000000000..27c4e3d9800 --- /dev/null +++ b/sonar-duplications/src/main/java/org/sonar/duplications/java/BridgeWithExceptionTokenMatcher.java @@ -0,0 +1,66 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.duplications.java; + +import java.util.List; + +import org.sonar.duplications.statement.matcher.TokenMatcher; +import org.sonar.duplications.token.Token; +import org.sonar.duplications.token.TokenQueue; + +public class BridgeWithExceptionTokenMatcher extends TokenMatcher { + + private final String lToken; + private final String rToken; + private final String except; + + public BridgeWithExceptionTokenMatcher(String lToken, String rToken, String except) { + if (lToken == null || rToken == null || except == null) { + throw new IllegalArgumentException(); + } + this.lToken = lToken; + this.rToken = rToken; + this.except = except; + } + + @Override + public boolean matchToken(TokenQueue tokenQueue, List<Token> matchedTokenList) { + if (!tokenQueue.isNextTokenValue(lToken)) { + return false; + } + int stack = 0; + while (tokenQueue.peek() != null) { + Token token = tokenQueue.poll(); + matchedTokenList.add(token); + if (lToken.equals(token.getValue())) { + stack++; + } else if (rToken.equals(token.getValue())) { + stack--; + } else if (except.equals(token.getValue())) { + return false; + } + if (stack == 0) { + return true; + } + } + return false; + } + +} diff --git a/sonar-duplications/src/main/java/org/sonar/duplications/java/JavaStatementBuilder.java b/sonar-duplications/src/main/java/org/sonar/duplications/java/JavaStatementBuilder.java index 99a74d26927..e783cd3c758 100644 --- a/sonar-duplications/src/main/java/org/sonar/duplications/java/JavaStatementBuilder.java +++ b/sonar-duplications/src/main/java/org/sonar/duplications/java/JavaStatementBuilder.java @@ -19,10 +19,10 @@ */ package org.sonar.duplications.java; -import org.sonar.duplications.statement.StatementChunker; - import static org.sonar.duplications.statement.TokenMatcherFactory.*; +import org.sonar.duplications.statement.StatementChunker; + public final class JavaStatementBuilder { private JavaStatementBuilder() { @@ -32,8 +32,10 @@ public final class JavaStatementBuilder { return StatementChunker.builder() .ignore(from("import"), to(";")) .ignore(from("package"), to(";")) + .statement(new BridgeWithExceptionTokenMatcher("{", "}", ";")) .ignore(token("}")) .ignore(token("{")) + .ignore(token(";")) .statement(from("@"), anyToken(), opt(bridge("(", ")"))) .statement(from("do")) .statement(from("if"), bridge("(", ")")) diff --git a/sonar-duplications/src/main/java/org/sonar/duplications/statement/matcher/ForgetLastTokenMatcher.java b/sonar-duplications/src/main/java/org/sonar/duplications/statement/matcher/ForgetLastTokenMatcher.java index 06a8e7d801e..6a36087bb4e 100644 --- a/sonar-duplications/src/main/java/org/sonar/duplications/statement/matcher/ForgetLastTokenMatcher.java +++ b/sonar-duplications/src/main/java/org/sonar/duplications/statement/matcher/ForgetLastTokenMatcher.java @@ -19,13 +19,14 @@ */ package org.sonar.duplications.statement.matcher; +import java.util.Collections; import java.util.List; import org.sonar.duplications.token.Token; import org.sonar.duplications.token.TokenQueue; /** - * Forgets token, which was consumed last. + * Last token would be returned to the queue. */ public class ForgetLastTokenMatcher extends TokenMatcher { @@ -34,7 +35,9 @@ public class ForgetLastTokenMatcher extends TokenMatcher { */ @Override public boolean matchToken(TokenQueue tokenQueue, List<Token> matchedTokenList) { - matchedTokenList.remove(matchedTokenList.size() - 1); + int last = matchedTokenList.size() - 1; + tokenQueue.pushForward(Collections.singletonList(matchedTokenList.get(last))); + matchedTokenList.remove(last); return true; } |