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 }