Skip to content

Commit

Permalink
Initial Java 1.5 support
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Studman committed Sep 27, 2004
1 parent 624f82b commit 6125bef
Show file tree
Hide file tree
Showing 77 changed files with 2,857 additions and 387 deletions.
6 changes: 3 additions & 3 deletions build.xml
Expand Up @@ -85,7 +85,7 @@
<fileset dir="src/checkstyle">
<include name="**/Generated*.java"/>
<include name="**/Generated*.txt"/>
<include name="**/expandedjava14.g"/>
<include name="**/expandedjava*.g"/>
</fileset>
</delete>
<delete dir="target" />
Expand All @@ -104,7 +104,7 @@
description="Checks whether the grammar file is newer that the generated code">
<uptodate property="uptodate.antlr"
targetfile="${checkstyle.grammar.dir}/GeneratedJava14Lexer.java" >
<srcfiles dir= "${checkstyle.grammar.dir}" includes="java_new.g,java14_new.g,java.g,java14.g"/>
<srcfiles dir= "${checkstyle.grammar.dir}" includes="java_new.g,java14_new.g,java.g,java14.g,java15.g"/>
</uptodate>
</target>

Expand All @@ -127,7 +127,7 @@
dir="${checkstyle.grammar.dir}">
<arg value="-glib" />
<arg value="java.g" />
<arg value="java14.g" />
<arg value="java15.g" />
</java>
</target>

Expand Down
131 changes: 93 additions & 38 deletions src/checkstyle/com/puppycrawl/tools/checkstyle/TreeWalker.java
Expand Up @@ -29,10 +29,13 @@
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.lang.reflect.InvocationTargetException;

import antlr.RecognitionException;
import antlr.TokenStreamException;
import antlr.TokenStreamRecognitionException;
import antlr.TokenStream;
import antlr.LLkParser;

import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
import com.puppycrawl.tools.checkstyle.api.Check;
Expand All @@ -45,9 +48,10 @@
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.api.Utils;
import com.puppycrawl.tools.checkstyle.grammars.GeneratedJavaRecognizer;
import com.puppycrawl.tools.checkstyle.grammars.GeneratedJava14Recognizer;
import com.puppycrawl.tools.checkstyle.grammars.GeneratedJava15Recognizer;
import com.puppycrawl.tools.checkstyle.grammars.GeneratedJavaLexer;
import com.puppycrawl.tools.checkstyle.grammars.GeneratedJava14Lexer;
import com.puppycrawl.tools.checkstyle.grammars.GeneratedJava15Lexer;
import com.puppycrawl.tools.checkstyle.grammars.CommentListener;

/**
* Responsible for walking an abstract syntax tree and notifying interested
Expand All @@ -67,15 +71,15 @@ public final class TreeWalker
* parsing fails because with the next grammar it might succeed
* and the user will be confused.
*/
private static final class SilentJava14Recognizer
extends GeneratedJava14Recognizer
private static final class SilentJava15Recognizer
extends GeneratedJava15Recognizer
{
/**
* Creates a new <code>SilentJava14Recognizer</code> instance.
*
* @param aLexer the tokenstream the recognizer operates on.
*/
private SilentJava14Recognizer(GeneratedJava14Lexer aLexer)
public SilentJava15Recognizer(TokenStream aLexer)
{
super(aLexer);
}
Expand Down Expand Up @@ -217,7 +221,8 @@ private void process(File aFile)
getMessageDispatcher().fireFileStarted(fileName);
final String[] lines = Utils.getLines(fileName, getCharset());
final FileContents contents = new FileContents(fileName, lines);
final DetailAST rootAST = TreeWalker.parse(contents);
final DetailAST rootAST =
TreeWalker.parse(contents);
walk(rootAST, contents);
}
catch (FileNotFoundException fnfe) {
Expand Down Expand Up @@ -487,49 +492,99 @@ private void notifyLeave(DetailAST aAST)
/**
* Static helper method to parses a Java source file.
* @param aContents contains the contents of the file
* @throws RecognitionException if parsing failed
* @throws TokenStreamException if lexing failed
* @throws RecognitionException if parsing failed
* @return the root of the AST
*/
public static DetailAST parse(FileContents aContents)
public static DetailAST parse(
FileContents aContents)
throws RecognitionException, TokenStreamException
{
DetailAST rootAST;
try {
// try the 1.4 grammar first, this will succeed for
// all code that compiles without any warnings in JDK 1.4,
// that should cover most cases
final Reader sar = new StringArrayReader(aContents.getLines());
final GeneratedJava14Lexer jl = new GeneratedJava14Lexer(sar);
jl.setFilename(aContents.getFilename());
jl.setCommentListener(aContents);

final GeneratedJava14Recognizer jr =
new SilentJava14Recognizer(jl);
jr.setFilename(aContents.getFilename());
jr.setASTNodeClass(DetailAST.class.getName());
jr.compilationUnit();
rootAST = (DetailAST) jr.getAST();
try {
rootAST = parse(
GeneratedJava15Lexer.class, SilentJava15Recognizer.class,
aContents);
}
catch (RecognitionException re) {
// Parsing might have failed because the checked
// file contains "assert" as an identifier. Retry with a
// grammar that treats "assert" as an identifier
// and not as a keyword
catch (RecognitionException exception) {
rootAST = parse(
GeneratedJavaLexer.class, GeneratedJavaRecognizer.class,
aContents);
}
return rootAST;
}

// Arghh - the pain - duplicate code!
/**
* Static helper method to parses a Java source file with a given
* lexer class and parser class.
* @param aLexerClass class to use for lexing
* @param aParserClass class to use for parsing
* @param aContents contains the contents of the file
* @throws TokenStreamException if lexing failed
* @throws RecognitionException if parsing failed
* @return the root of the AST
*/
private static DetailAST parse(
Class aLexerClass,
Class aParserClass,
FileContents aContents)
throws RecognitionException, TokenStreamException
{
try {
final Reader sar = new StringArrayReader(aContents.getLines());
final GeneratedJavaLexer jl = new GeneratedJavaLexer(sar);
jl.setFilename(aContents.getFilename());
jl.setCommentListener(aContents);

final GeneratedJavaRecognizer jr = new GeneratedJavaRecognizer(jl);
jr.setFilename(aContents.getFilename());
jr.setASTNodeClass(DetailAST.class.getName());
jr.compilationUnit();
rootAST = (DetailAST) jr.getAST();
final TokenStream lexer = (TokenStream)
aLexerClass.getConstructor(new Class[] {Reader.class})
.newInstance(new Object[] {sar});
aLexerClass.getMethod(
"setFilename",
new Class[] {String.class}).invoke(
lexer, new Object[] {aContents.getFilename()});
aLexerClass.getMethod(
"setCommentListener", new Class[] {CommentListener.class})
.invoke(lexer, new Object[] {aContents});

final LLkParser parser = (LLkParser)
aParserClass.getConstructor(new Class[] {TokenStream.class})
.newInstance(new Object[] {lexer});

parser.setFilename(aContents.getFilename());
parser.setASTNodeClass(DetailAST.class.getName());
aParserClass.getMethod(
"compilationUnit", new Class[] {}).invoke(
parser, new Object[] {});
return (DetailAST) parser.getAST();
}
catch (InvocationTargetException exception) {
//Re-throw antlr exceptions, pass on runtime exceptions
//and convert any other exception to a runtime exception
if (RecognitionException.class.isAssignableFrom(
exception.getCause().getClass()))
{
throw (RecognitionException) exception.getCause();
}
else if (TokenStreamException.class.isAssignableFrom(
exception.getCause().getClass()))
{
throw (TokenStreamException) exception.getCause();
}
else if (RuntimeException.class.isAssignableFrom(
exception.getCause().getClass()))
{
throw (RuntimeException) exception.getCause();
}
else {
throw new RuntimeException(exception.getCause());
}
}
catch (RuntimeException exception) {
//Pass on runtime exceptions
throw exception;
}
catch (Exception exception) {
//Convert any reflection exceptions to runtime exceptions
throw new RuntimeException(exception);
}
return rootAST;
}

/** @see com.puppycrawl.tools.checkstyle.api.FileSetCheck */
Expand Down
91 changes: 88 additions & 3 deletions src/checkstyle/com/puppycrawl/tools/checkstyle/api/ScopeUtils.java
Expand Up @@ -78,7 +78,9 @@ public static Scope getSurroundingScope(DetailAST aAST)
{
final int type = token.getType();
if ((type == TokenTypes.CLASS_DEF)
|| (type == TokenTypes.INTERFACE_DEF))
|| (type == TokenTypes.INTERFACE_DEF)
|| (type == TokenTypes.ANNOTATION_DEF)
|| (type == TokenTypes.ENUM_DEF))
{
final DetailAST mods =
token.findFirstToken(TokenTypes.MODIFIERS);
Expand Down Expand Up @@ -128,6 +130,86 @@ else if (type == TokenTypes.INTERFACE_DEF) {
return retVal;
}

/**
* Returns whether a node is directly contained within an annotation block.
*
* @param aAST the node to check if directly contained within an annotation
* block
* @return a <code>boolean</code> value
*/
public static boolean inAnnotationBlock(DetailAST aAST)
{
boolean retVal = false;

// Loop up looking for a containing interface block
for (DetailAST token = aAST.getParent();
token != null;
token = token.getParent())
{
final int type = token.getType();
if (type == TokenTypes.CLASS_DEF) {
break; // in a class
}
else if (type == TokenTypes.LITERAL_NEW) {
break; // inner implementation
}
else if (type == TokenTypes.ANNOTATION_DEF) {
retVal = true;
break;
}
}

return retVal;
}

/**
* Returns whether a node is directly contained within an interface or
* annotation block.
*
* @param aAST the node to check if directly contained within an interface
* or annotation block
* @return a <code>boolean</code> value
*/
public static boolean inInterfaceOrAnnotationBlock(DetailAST aAST)
{
return inInterfaceBlock(aAST) || inAnnotationBlock(aAST);
}

/**
* Returns whether a node is directly contained within an enum block.
*
* @param aAST the node to check if directly contained within an enum
* block
* @return a <code>boolean</code> value
*/
public static boolean inEnumBlock(DetailAST aAST)
{
boolean retVal = false;

// Loop up looking for a containing interface block
for (DetailAST token = aAST.getParent();
token != null;
token = token.getParent())
{
final int type = token.getType();
if (type == TokenTypes.INTERFACE_DEF
|| type == TokenTypes.ANNOTATION_DEF
|| type == TokenTypes.CLASS_DEF)
{
break; // in an interface, annotation or class
}
else if (type == TokenTypes.LITERAL_NEW) {
break; // inner implementation, enums can't be inner classes
}
else if (type == TokenTypes.ENUM_DEF) {
retVal = true;
break;
}
}

return retVal;
}

/**
* Returns whether the scope of a node is restricted to a code block.
* A code block is a method or constructor body, or a initialiser block.
Expand Down Expand Up @@ -172,7 +254,9 @@ public static boolean isOuterMostType(DetailAST aAST)
parent = parent.getParent())
{
if ((parent.getType() == TokenTypes.CLASS_DEF)
|| (parent.getType() == TokenTypes.INTERFACE_DEF))
|| (parent.getType() == TokenTypes.INTERFACE_DEF)
|| (parent.getType() == TokenTypes.ANNOTATION_DEF)
|| (parent.getType() == TokenTypes.ENUM_DEF))
{
retVal = false;
break;
Expand All @@ -197,7 +281,8 @@ public static boolean isLocalVariableDef(DetailAST aAST)
if (parent != null) {
final int type = parent.getType();
return (type == TokenTypes.SLIST)
|| (type == TokenTypes.FOR_INIT);
|| (type == TokenTypes.FOR_INIT)
|| (type == TokenTypes.FOR_EACH_CLAUSE);
}
}
// catch parameter?
Expand Down

0 comments on commit 6125bef

Please sign in to comment.