001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2009 SonarSource SA
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020 package org.sonar.squid.ast;
021
022 import java.util.ArrayList;
023 import java.util.Collection;
024 import java.util.List;
025 import java.util.SortedSet;
026 import java.util.TreeSet;
027
028 import org.slf4j.Logger;
029 import org.slf4j.LoggerFactory;
030 import org.sonar.squid.api.SquidConfiguration;
031 import org.sonar.squid.ast.visitor.AstVisitor;
032 import org.sonar.squid.recognizer.CodeRecognizer;
033 import org.sonar.squid.recognizer.JavaFootprint;
034 import org.sonar.squid.text.Source;
035
036 import com.puppycrawl.tools.checkstyle.api.Check;
037 import com.puppycrawl.tools.checkstyle.api.DetailAST;
038 import com.puppycrawl.tools.checkstyle.api.TextBlock;
039
040 public class CheckstyleSquidBridge extends Check {
041
042 private static Logger logger = LoggerFactory.getLogger(CheckstyleSquidBridge.class);
043 private static AstVisitor[] visitors;
044 private static int[] allTokens;
045 private static CodeRecognizer codeRecognizer;
046
047 static void setASTVisitors(List<AstVisitor> visitors) {
048 CheckstyleSquidBridge.visitors = visitors.toArray(new AstVisitor[0]);
049 SortedSet<Integer> sorter = new TreeSet<Integer>();
050 for (AstVisitor visitor : visitors) {
051 sorter.addAll(visitor.getWantedTokens());
052 allTokens = new int[sorter.size()];
053 int i = 0;
054 for (Integer itSorted : sorter) {
055 allTokens[i++] = itSorted;
056 }
057 }
058 }
059
060 static void setSquidConfiguration(SquidConfiguration conf) {
061 codeRecognizer = new CodeRecognizer(conf.getCommentedCodeThreshold(), new JavaFootprint());
062 }
063
064 @Override
065 public int[] getDefaultTokens() {
066 return allTokens;
067 }
068
069 @Override
070 public void beginTree(DetailAST ast) {
071 try {
072 Source source = createSource();
073 for (AstVisitor visitor : visitors) {
074 visitor.setFileContents(getFileContents());
075 visitor.setSource(source);
076 visitor.visitFile(ast);
077 }
078 } catch (RuntimeException e) {
079 // Exception are not propagated by Checkstyle engine
080 logger.error("Error occurs when analysing :" + getFileContents().getFilename(), e);
081 }
082 }
083
084 private Source createSource() {
085 List<TextBlock> comments = new ArrayList<TextBlock>();
086 for (List<TextBlock> listTextBlock : (Collection<List<TextBlock>>) getFileContents().getCComments().values()) {
087 comments.addAll(listTextBlock);
088 }
089
090 comments.addAll(getFileContents().getCppComments().values());
091 return new Source(getFileContents().getLines(), codeRecognizer, comments);
092 }
093
094 @Override
095 public void visitToken(DetailAST ast) {
096 try {
097 for (AstVisitor visitor : visitors) {
098 if (visitor.getWantedTokens().contains(ast.getType())) {
099 visitor.visitToken(ast);
100 }
101 }
102 } catch (RuntimeException e) {
103 // Exception are not propagated by Checkstyle engine
104 logger.error("Error occurs when analysing :" + getFileContents().getFilename(), e);
105 }
106 }
107
108 @Override
109 public void leaveToken(DetailAST ast) {
110 try {
111 for (int i = visitors.length - 1; i >= 0; i--) {
112 AstVisitor visitor = visitors[i];
113 if (visitor.getWantedTokens().contains(ast.getType())) {
114 visitor.leaveToken(ast);
115 }
116 }
117 } catch (RuntimeException e) {
118 // Exception are not propagated by Checkstyle engine
119 logger.error("Error occurs when analysing :" + getFileContents().getFilename(), e);
120 }
121 }
122
123 @Override
124 public void finishTree(DetailAST ast) {
125 try {
126 for (int i = visitors.length - 1; i >= 0; i--) {
127 AstVisitor visitor = visitors[i];
128 visitor.leaveFile(ast);
129 }
130 } catch (RuntimeException e) {
131 // Exception are not propagated by Checkstyle engine
132 logger.error("Error occurs when analysing :" + getFileContents().getFilename(), e);
133 }
134 }
135 }