From 612364a06d94258ce9e9c4c831c9d2c8b85159a3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 30 Sep 2014 19:51:42 +0200 Subject: [PATCH] Create a first sub-module for java * almost empty, just compiling the java grammar * no code moved yet --- pmd-java/etc/grammar/Java.jjt | 2258 +++++++++++++++++++++++++++ pmd-java/pom.xml | 434 +++++ pmd-java/src/main/ant/alljavacc.xml | 91 ++ pom.xml | 1 + 4 files changed, 2784 insertions(+) create mode 100644 pmd-java/etc/grammar/Java.jjt create mode 100644 pmd-java/pom.xml create mode 100644 pmd-java/src/main/ant/alljavacc.xml diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt new file mode 100644 index 0000000000..7d9435c504 --- /dev/null +++ b/pmd-java/etc/grammar/Java.jjt @@ -0,0 +1,2258 @@ +/** + * Fix for Lambda expressions with two or three variables. + * + * Andreas Dangel 07/2014 + *==================================================================== + * Added support for Java 8 language constructs. + * + * Andreas Dangel 01/2014 + * =================================================================== + * Fix ForStatement to allow Annotations within the initializer. + * + * Andreas Dangel 01/2013 + * =================================================================== + * Fix wrong consumption of modifiers (e.g. "final") in a for-each loop. + * Check for wrong java usage when catching multiple exceptions. + * + * Andreas Dangel 12/2012 + * =================================================================== + * Enhance grammar to use LocalVariableDeclaration in a for-each loop. + * This enhances the symbol table to recognize variables declared in such + * a for-each loop. + * + * Andreas Dangel 10/2012 + * =================================================================== + * Fix parser problem #3530124 with generics + * + * Modified the grammar, so that the different usages of generics work. + * Adjusted the rules, that use "super", as super is no longer a PrimarySuffix. + * It's now either a ExplicitConstructorInvocation or a PrimaryPrefix. + * See also test case ParserCornersTest/testParsersCases + * + * Andreas Dangel 05/2012 + * =================================================================== + * Added support for Java 7 language constructs + * + * Dinesh Bolkensteyn (SonarSource), 10/2011 + * =================================================================== + * Changed the CastLookahead production to use 3 lookaheads for primitive types as suggested by Andreas Dangel + * + * Brian Remedios 07/2011 + * =================================================================== + * Added in support for assert as a name using lookaheads + * + * Tom Copeland, 09/03 + * =================================================================== + * Copied over the changes made by Andrea Gini and Marco Savard to + * support JDK 1.4 language constructs, i.e., asserts. + * See the java1_4c.jj distributed in the javacc2.1/examples/JavaGrammers directory. + * Made numerous other modifications to support PMD. + * + * Tom Copeland, 6/02 + * =================================================================== + * This file is a modified version of one originally found in the + * VTransformer Examples directory of JavaCC1_1. It has been + * modified to accept Java source code for Java 1.2. Basically, + * this means a new key word was added, 'strictfp', and that keyword + * added to the appropriate productions and LOOKAHEADs (where other, + * similar keywords are listed as possible choices). This involved + * changing 11 lines. + * + * Some other minor changes were made, which can be found by doing + * a search on 'DW, 7/99'. + * + * The goal of this effort was for the grammar to be able to parse + * any legal Java 1.2 source code. It does not reject all illegal + * cases, but neither did the original. Plus, when it comes to + * the new 'strictfp' keyword, the Java Compiler from Sun (JDK1.2.1) + * also does not reject all illegal cases, as defined by the + * "Updates" document found at + * http://java.sun.com/docs/books/jls/strictfp-changes.pdf + * (see the testcases.txt file for details). + * + * David Williams, 7/99 + * =================================================================== + * + * + * Copyright (C) 1996, 1997 Sun Microsystems Inc. + * + * Use of this file and the system it is part of is constrained by the + * file COPYRIGHT in the root directory of this system. You may, however, + * make any modifications you wish to this file. + * + * Java files generated by running JavaCC on this file (or modified versions + * of this file) may be used in exactly the same manner as Java files + * generated from any grammar developed by you. + * + * Author: Sriram Sankar + * Date: 3/5/97 + * + * This file contains a Java grammar and actions that implement a front-end. + */ + +options { + JAVA_UNICODE_ESCAPE = true; + CACHE_TOKENS = true; + STATIC = false; + USER_CHAR_STREAM = true; + JDK_VERSION = "1.5"; + + MULTI = true; + VISITOR = true; + NODE_USES_PARSER = true; + NODE_PACKAGE="net.sourceforge.pmd.lang.java.ast"; + + //DEBUG_PARSER = true; + //DEBUG_LOOKAHEAD = true; +} + +PARSER_BEGIN(JavaParser) +package net.sourceforge.pmd.lang.java.ast; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import net.sourceforge.pmd.lang.ast.CharStream; +import net.sourceforge.pmd.lang.ast.TokenMgrError; +public class JavaParser { + + private int jdkVersion = 0; + + public void setJdkVersion(int jdkVersion) { + this.jdkVersion = jdkVersion; + } + + private void throwParseException(String message) { + int line = -1; + int col = -1; + if (jj_lastpos != null) { + line = jj_lastpos.beginLine; + col = jj_lastpos.beginColumn; + } + throw new ParseException("Line " + line + ", Column " + col + ": " + message); + } + + private void checkForBadAssertUsage(String in, String usage) { + if (jdkVersion > 3 && in.equals("assert")) { + throwParseException("Can't use 'assert' as " + usage + " when running in JDK 1.4 mode!"); + } + } + + private void checkForBadStaticImportUsage() { + if (jdkVersion < 5) { + throwParseException("Can't use static imports when running in JDK 1.4 mode!"); + } + } + + private void checkForBadAnnotationUsage() { + if (jdkVersion < 5) { + throwParseException("Can't use annotations when running in JDK 1.4 mode!"); + } + } + + private void checkForBadGenericsUsage() { + if (jdkVersion < 5) { + throwParseException("Can't use generics unless running in JDK 1.5 mode!"); + } + } + + private void checkForBadVariableArgumentsUsage() { + if (jdkVersion < 5) { + throwParseException("Can't use variable arguments (varargs) when running in JDK 1.4 mode!"); + } + } + + private void checkForBadJDK15ForLoopSyntaxArgumentsUsage() { + if (jdkVersion < 5) { + throwParseException("Can't use JDK 1.5 for loop syntax when running in JDK 1.4 mode!"); + } + } + + private void checkForBadEnumUsage(String in, String usage) { + if (jdkVersion >= 5 && in.equals("enum")) { + throwParseException("Can't use 'enum' as " + usage + " when running in JDK 1.5 mode!"); + } + } + + private void checkForBadHexFloatingPointLiteral() { + if (jdkVersion < 5) { + throwParseException("Can't use hexadecimal floating point literals in pre-JDK 1.5 target"); + } + } + + private void checkForBadNumericalLiteralslUsage(Token token) { + if (jdkVersion < 7) { + if (token.image.contains("_")) { + throwParseException("Can't use underscores in numerical literals when running in JDK inferior to 1.7 mode!"); + } + + if (token.image.startsWith("0b") || token.image.startsWith("0B")) { + throwParseException("Can't use binary numerical literals when running in JDK inferior to 1.7 mode!"); + } + } + } + + private void checkForBadDiamondUsage() { + if (jdkVersion < 7) { + throwParseException("Cannot use the diamond generic notation when running in JDK inferior to 1.7 mode!"); + } + } + + private void checkForBadTryWithResourcesUsage() { + if (jdkVersion < 7) { + throwParseException("Cannot use the try-with-resources notation when running in JDK inferior to 1.7 mode!"); + } + } + + private void checkForBadMultipleExceptionsCatching() { + if (jdkVersion < 7) { + throwParseException("Cannot catch multiple exceptions when running in JDK inferior to 1.7 mode!"); + } + } + + private void checkForBadLambdaUsage() { + if (jdkVersion < 8) { + throwParseException("Cannot use lambda expressions when running in JDK inferior to 1.8 mode!"); + } + } + private void checkForBadMethodReferenceUsage() { + if (jdkVersion < 8) { + throwParseException("Cannot use method references when running in JDK inferior to 1.8 mode!"); + } + } + private void checkForBadDefaultImplementationUsage() { + if (jdkVersion < 8) { + throwParseException("Cannot use default implementations in interfaces when running in JDK inferior to 1.8 mode!"); + } + } + private void checkForBadIntersectionTypesInCasts() { + if (jdkVersion < 8) { + throwParseException("Cannot use intersection types in casts when running in JDK inferior to 1.8 mode!"); + } + } + private void checkForBadTypeAnnotations() { + if (jdkVersion < 8) { + throwParseException("Cannot use type annotations when running in JDK inferior to 1.8 mode!"); + } + } + + // This is a semantic LOOKAHEAD to determine if we're dealing with an assert + // Note that this can't be replaced with a syntactic lookahead + // since "assert" isn't a string literal token + private boolean isNextTokenAnAssert() { + boolean res = getToken(1).image.equals("assert"); + if (res && jdkVersion <= 3 && getToken(2).image.equals("(")) { + res = false; + } + return res; + } + + private boolean isPrecededByComment(Token tok) { + boolean res = false; + while (!res && tok.specialToken != null) { + tok = tok.specialToken; + res = tok.kind == SINGLE_LINE_COMMENT || + tok.kind == FORMAL_COMMENT || + tok.kind == MULTI_LINE_COMMENT; + } + return res; + } + + public Map getSuppressMap() { + return token_source.getSuppressMap(); + } + + public void setSuppressMarker(String marker) { + token_source.setSuppressMarker(marker); + } + + +} +PARSER_END(JavaParser) + +TOKEN_MGR_DECLS : +{ + protected List comments = new ArrayList(); +} + +/* WHITE SPACE */ + +SPECIAL_TOKEN : +{ + " " | "\t" | "\n" | "\r" | "\f" +} + +SPECIAL_TOKEN : +{ +< SINGLE_LINE_COMMENT: "//"(~["\n","\r"])* ("\n"|"\r"|"\r\n")? > + { + int startOfNOPMD = matchedToken.image.indexOf(suppressMarker); + if (startOfNOPMD != -1) { + suppressMap.put(matchedToken.beginLine, matchedToken.image.substring(startOfNOPMD + suppressMarker.length())); + } + comments.add(new SingleLineComment(matchedToken)); + } +} + +/* COMMENTS */ + +MORE : +{ + <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT +| + "/*" : IN_MULTI_LINE_COMMENT +} + + +SPECIAL_TOKEN : +{ + { comments.add(new FormalComment(matchedToken)); } : DEFAULT +} + + +SPECIAL_TOKEN : +{ + { comments.add(new MultiLineComment(matchedToken)); } : DEFAULT +} + + +MORE : +{ + < ~[] > +} + +/* RESERVED WORDS AND LITERALS */ + +TOKEN : +{ + < ABSTRACT: "abstract" > +| < BOOLEAN: "boolean" > +| < BREAK: "break" > +| < BYTE: "byte" > +| < CASE: "case" > +| < CATCH: "catch" > +| < CHAR: "char" > +| < CLASS: "class" > +| < CONST: "const" > +| < CONTINUE: "continue" > +| < _DEFAULT: "default" > +| < DO: "do" > +| < DOUBLE: "double" > +| < ELSE: "else" > +| < EXTENDS: "extends" > +| < FALSE: "false" > +| < FINAL: "final" > +| < FINALLY: "finally" > +| < FLOAT: "float" > +| < FOR: "for" > +| < GOTO: "goto" > +| < IF: "if" > +| < IMPLEMENTS: "implements" > +| < IMPORT: "import" > +| < INSTANCEOF: "instanceof" > +| < INT: "int" > +| < INTERFACE: "interface" > +| < LONG: "long" > +| < NATIVE: "native" > +| < NEW: "new" > +| < NULL: "null" > +| < PACKAGE: "package"> +| < PRIVATE: "private" > +| < PROTECTED: "protected" > +| < PUBLIC: "public" > +| < RETURN: "return" > +| < SHORT: "short" > +| < STATIC: "static" > +| < SUPER: "super" > +| < SWITCH: "switch" > +| < SYNCHRONIZED: "synchronized" > +| < THIS: "this" > +| < THROW: "throw" > +| < THROWS: "throws" > +| < TRANSIENT: "transient" > +| < TRUE: "true" > +| < TRY: "try" > +| < VOID: "void" > +| < VOLATILE: "volatile" > +| < WHILE: "while" > +| < STRICTFP: "strictfp" > +} + +/* LITERALS */ + +TOKEN : +{ + < INTEGER_LITERAL: + (["l","L"])? + | (["l","L"])? + | (["l","L"])? + | (["l","L"])? + > +| + < #DECIMAL_LITERAL: (["0"-"9"]((["0"-"9","_"])*["0"-"9"])?) > +| + < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"]((["0"-"9","a"-"f","A"-"F","_"])*["0"-"9","a"-"f","A"-"F"])?) > +| + < #BINARY_LITERAL: "0" ["b","B"] (["0","1"]((["0","1","_"])*["0","1"])?) > +| + < #OCTAL_LITERAL: "0" (["0"-"7"]((["0"-"7","_"])*["0"-"7"])?) > +| + < FLOATING_POINT_LITERAL: + (["0"-"9"]((["0"-"9","_"])*["0"-"9"])?) "." (["0"-"9"]((["0"-"9","_"])*["0"-"9"])?)? ()? (["f","F","d","D"])? + | "." (["0"-"9"]((["0"-"9","_"])*["0"-"9"])?) ()? (["f","F","d","D"])? + | (["0"-"9"]((["0"-"9","_"])*["0"-"9"])?) (["f","F","d","D"])? + | (["0"-"9"]((["0"-"9","_"])*["0"-"9"])?) ()? ["f","F","d","D"] + > +| + < HEX_FLOATING_POINT_LITERAL: + ( (".")? | "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"]((["0"-"9","a"-"f","A"-"F","_"])*["0"-"9","a"-"f","A"-"F"])?)? "." (["0"-"9","a"-"f","A"-"F"]((["0"-"9","a"-"f","A"-"F","_"])*["0"-"9","a"-"f","A"-"F"])?)) ["p","P"] (["+","-"])? (["0"-"9"]((["0"-"9","_"])*["0"-"9"])?) (["f","F","d","D"])? + > +| + < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"]((["0"-"9","_"])*["0"-"9"])?) > +| + < CHARACTER_LITERAL: + "'" + ( (~["'","\\","\n","\r"]) + | ("\\" + ( ["n","t","b","r","f","\\","'","\""] + | ["0"-"7"] ( ["0"-"7"] )? + | ["0"-"3"] ["0"-"7"] ["0"-"7"] + ) + ) + ) + "'" + > +| + < STRING_LITERAL: + "\"" + ( (~["\"","\\","\n","\r"]) + | ("\\" + ( ["n","t","b","r","f","\\","'","\""] + | ["0"-"7"] ( ["0"-"7"] )? + | ["0"-"3"] ["0"-"7"] ["0"-"7"] + ) + ) + )* + "\"" + > +} + +/* IDENTIFIERS */ + +TOKEN : +{ + < IDENTIFIER: ()* > +| + < #LETTER: + [ // all chars for which Character.isIdentifierStart is true + "$", + "A"-"Z", + "_", + "a"-"z", + "\u00a2"-"\u00a5", + "\u00aa", + "\u00b5", + "\u00ba", + "\u00c0"-"\u00d6", + "\u00d8"-"\u00f6", + "\u00f8"-"\u021f", + "\u0222"-"\u0233", + "\u0250"-"\u02ad", + "\u02b0"-"\u02b8", + "\u02bb"-"\u02c1", + "\u02d0"-"\u02d1", + "\u02e0"-"\u02e4", + "\u02ee", + "\u037a", + "\u0386", + "\u0388"-"\u038a", + "\u038c", + "\u038e"-"\u03a1", + "\u03a3"-"\u03ce", + "\u03d0"-"\u03d7", + "\u03da"-"\u03f3", + "\u0400"-"\u0481", + "\u048c"-"\u04c4", + "\u04c7"-"\u04c8", + "\u04cb"-"\u04cc", + "\u04d0"-"\u04f5", + "\u04f8"-"\u04f9", + "\u0531"-"\u0556", + "\u0559", + "\u0561"-"\u0587", + "\u05d0"-"\u05ea", + "\u05f0"-"\u05f2", + "\u0621"-"\u063a", + "\u0640"-"\u064a", + "\u0671"-"\u06d3", + "\u06d5", + "\u06e5"-"\u06e6", + "\u06fa"-"\u06fc", + "\u0710", + "\u0712"-"\u072c", + "\u0780"-"\u07a5", + "\u0905"-"\u0939", + "\u093d", + "\u0950", + "\u0958"-"\u0961", + "\u0985"-"\u098c", + "\u098f"-"\u0990", + "\u0993"-"\u09a8", + "\u09aa"-"\u09b0", + "\u09b2", + "\u09b6"-"\u09b9", + "\u09dc"-"\u09dd", + "\u09df"-"\u09e1", + "\u09f0"-"\u09f3", + "\u0a05"-"\u0a0a", + "\u0a0f"-"\u0a10", + "\u0a13"-"\u0a28", + "\u0a2a"-"\u0a30", + "\u0a32"-"\u0a33", + "\u0a35"-"\u0a36", + "\u0a38"-"\u0a39", + "\u0a59"-"\u0a5c", + "\u0a5e", + "\u0a72"-"\u0a74", + "\u0a85"-"\u0a8b", + "\u0a8d", + "\u0a8f"-"\u0a91", + "\u0a93"-"\u0aa8", + "\u0aaa"-"\u0ab0", + "\u0ab2"-"\u0ab3", + "\u0ab5"-"\u0ab9", + "\u0abd", + "\u0ad0", + "\u0ae0", + "\u0b05"-"\u0b0c", + "\u0b0f"-"\u0b10", + "\u0b13"-"\u0b28", + "\u0b2a"-"\u0b30", + "\u0b32"-"\u0b33", + "\u0b36"-"\u0b39", + "\u0b3d", + "\u0b5c"-"\u0b5d", + "\u0b5f"-"\u0b61", + "\u0b85"-"\u0b8a", + "\u0b8e"-"\u0b90", + "\u0b92"-"\u0b95", + "\u0b99"-"\u0b9a", + "\u0b9c", + "\u0b9e"-"\u0b9f", + "\u0ba3"-"\u0ba4", + "\u0ba8"-"\u0baa", + "\u0bae"-"\u0bb5", + "\u0bb7"-"\u0bb9", + "\u0c05"-"\u0c0c", + "\u0c0e"-"\u0c10", + "\u0c12"-"\u0c28", + "\u0c2a"-"\u0c33", + "\u0c35"-"\u0c39", + "\u0c60"-"\u0c61", + "\u0c85"-"\u0c8c", + "\u0c8e"-"\u0c90", + "\u0c92"-"\u0ca8", + "\u0caa"-"\u0cb3", + "\u0cb5"-"\u0cb9", + "\u0cde", + "\u0ce0"-"\u0ce1", + "\u0d05"-"\u0d0c", + "\u0d0e"-"\u0d10", + "\u0d12"-"\u0d28", + "\u0d2a"-"\u0d39", + "\u0d60"-"\u0d61", + "\u0d85"-"\u0d96", + "\u0d9a"-"\u0db1", + "\u0db3"-"\u0dbb", + "\u0dbd", + "\u0dc0"-"\u0dc6", + "\u0e01"-"\u0e30", + "\u0e32"-"\u0e33", + "\u0e3f"-"\u0e46", + "\u0e81"-"\u0e82", + "\u0e84", + "\u0e87"-"\u0e88", + "\u0e8a", + "\u0e8d", + "\u0e94"-"\u0e97", + "\u0e99"-"\u0e9f", + "\u0ea1"-"\u0ea3", + "\u0ea5", + "\u0ea7", + "\u0eaa"-"\u0eab", + "\u0ead"-"\u0eb0", + "\u0eb2"-"\u0eb3", + "\u0ebd", + "\u0ec0"-"\u0ec4", + "\u0ec6", + "\u0edc"-"\u0edd", + "\u0f00", + "\u0f40"-"\u0f47", + "\u0f49"-"\u0f6a", + "\u0f88"-"\u0f8b", + "\u1000"-"\u1021", + "\u1023"-"\u1027", + "\u1029"-"\u102a", + "\u1050"-"\u1055", + "\u10a0"-"\u10c5", + "\u10d0"-"\u10f6", + "\u1100"-"\u1159", + "\u115f"-"\u11a2", + "\u11a8"-"\u11f9", + "\u1200"-"\u1206", + "\u1208"-"\u1246", + "\u1248", + "\u124a"-"\u124d", + "\u1250"-"\u1256", + "\u1258", + "\u125a"-"\u125d", + "\u1260"-"\u1286", + "\u1288", + "\u128a"-"\u128d", + "\u1290"-"\u12ae", + "\u12b0", + "\u12b2"-"\u12b5", + "\u12b8"-"\u12be", + "\u12c0", + "\u12c2"-"\u12c5", + "\u12c8"-"\u12ce", + "\u12d0"-"\u12d6", + "\u12d8"-"\u12ee", + "\u12f0"-"\u130e", + "\u1310", + "\u1312"-"\u1315", + "\u1318"-"\u131e", + "\u1320"-"\u1346", + "\u1348"-"\u135a", + "\u13a0"-"\u13f4", + "\u1401"-"\u166c", + "\u166f"-"\u1676", + "\u1681"-"\u169a", + "\u16a0"-"\u16ea", + "\u1780"-"\u17b3", + "\u17db", + "\u1820"-"\u1877", + "\u1880"-"\u18a8", + "\u1e00"-"\u1e9b", + "\u1ea0"-"\u1ef9", + "\u1f00"-"\u1f15", + "\u1f18"-"\u1f1d", + "\u1f20"-"\u1f45", + "\u1f48"-"\u1f4d", + "\u1f50"-"\u1f57", + "\u1f59", + "\u1f5b", + "\u1f5d", + "\u1f5f"-"\u1f7d", + "\u1f80"-"\u1fb4", + "\u1fb6"-"\u1fbc", + "\u1fbe", + "\u1fc2"-"\u1fc4", + "\u1fc6"-"\u1fcc", + "\u1fd0"-"\u1fd3", + "\u1fd6"-"\u1fdb", + "\u1fe0"-"\u1fec", + "\u1ff2"-"\u1ff4", + "\u1ff6"-"\u1ffc", + "\u203f"-"\u2040", + "\u207f", + "\u20a0"-"\u20af", + "\u2102", + "\u2107", + "\u210a"-"\u2113", + "\u2115", + "\u2119"-"\u211d", + "\u2124", + "\u2126", + "\u2128", + "\u212a"-"\u212d", + "\u212f"-"\u2131", + "\u2133"-"\u2139", + "\u2160"-"\u2183", + "\u3005"-"\u3007", + "\u3021"-"\u3029", + "\u3031"-"\u3035", + "\u3038"-"\u303a", + "\u3041"-"\u3094", + "\u309d"-"\u309e", + "\u30a1"-"\u30fe", + "\u3105"-"\u312c", + "\u3131"-"\u318e", + "\u31a0"-"\u31b7", + "\u3400"-"\u4db5", + "\u4e00"-"\u9fa5", + "\ua000"-"\ua48c", + "\uac00"-"\ud7a3", + "\uf900"-"\ufa2d", + "\ufb00"-"\ufb06", + "\ufb13"-"\ufb17", + "\ufb1d", + "\ufb1f"-"\ufb28", + "\ufb2a"-"\ufb36", + "\ufb38"-"\ufb3c", + "\ufb3e", + "\ufb40"-"\ufb41", + "\ufb43"-"\ufb44", + "\ufb46"-"\ufbb1", + "\ufbd3"-"\ufd3d", + "\ufd50"-"\ufd8f", + "\ufd92"-"\ufdc7", + "\ufdf0"-"\ufdfb", + "\ufe33"-"\ufe34", + "\ufe4d"-"\ufe4f", + "\ufe69", + "\ufe70"-"\ufe72", + "\ufe74", + "\ufe76"-"\ufefc", + "\uff04", + "\uff21"-"\uff3a", + "\uff3f", + "\uff41"-"\uff5a", + "\uff65"-"\uffbe", + "\uffc2"-"\uffc7", + "\uffca"-"\uffcf", + "\uffd2"-"\uffd7", + "\uffda"-"\uffdc", + "\uffe0"-"\uffe1", + "\uffe5"-"\uffe6" + ] + > +| + < #PART_LETTER: + [ // all chars for which Character.isIdentifierPart is true + "\u0000"-"\u0008", + "\u000e"-"\u001b", + "$", + "0"-"9", + "A"-"Z", + "_", + "a"-"z", + "\u007f"-"\u009f", + "\u00a2"-"\u00a5", + "\u00aa", + "\u00b5", + "\u00ba", + "\u00c0"-"\u00d6", + "\u00d8"-"\u00f6", + "\u00f8"-"\u021f", + "\u0222"-"\u0233", + "\u0250"-"\u02ad", + "\u02b0"-"\u02b8", + "\u02bb"-"\u02c1", + "\u02d0"-"\u02d1", + "\u02e0"-"\u02e4", + "\u02ee", + "\u0300"-"\u034e", + "\u0360"-"\u0362", + "\u037a", + "\u0386", + "\u0388"-"\u038a", + "\u038c", + "\u038e"-"\u03a1", + "\u03a3"-"\u03ce", + "\u03d0"-"\u03d7", + "\u03da"-"\u03f3", + "\u0400"-"\u0481", + "\u0483"-"\u0486", + "\u048c"-"\u04c4", + "\u04c7"-"\u04c8", + "\u04cb"-"\u04cc", + "\u04d0"-"\u04f5", + "\u04f8"-"\u04f9", + "\u0531"-"\u0556", + "\u0559", + "\u0561"-"\u0587", + "\u0591"-"\u05a1", + "\u05a3"-"\u05b9", + "\u05bb"-"\u05bd", + "\u05bf", + "\u05c1"-"\u05c2", + "\u05c4", + "\u05d0"-"\u05ea", + "\u05f0"-"\u05f2", + "\u0621"-"\u063a", + "\u0640"-"\u0655", + "\u0660"-"\u0669", + "\u0670"-"\u06d3", + "\u06d5"-"\u06dc", + "\u06df"-"\u06e8", + "\u06ea"-"\u06ed", + "\u06f0"-"\u06fc", + "\u070f"-"\u072c", + "\u0730"-"\u074a", + "\u0780"-"\u07b0", + "\u0901"-"\u0903", + "\u0905"-"\u0939", + "\u093c"-"\u094d", + "\u0950"-"\u0954", + "\u0958"-"\u0963", + "\u0966"-"\u096f", + "\u0981"-"\u0983", + "\u0985"-"\u098c", + "\u098f"-"\u0990", + "\u0993"-"\u09a8", + "\u09aa"-"\u09b0", + "\u09b2", + "\u09b6"-"\u09b9", + "\u09bc", + "\u09be"-"\u09c4", + "\u09c7"-"\u09c8", + "\u09cb"-"\u09cd", + "\u09d7", + "\u09dc"-"\u09dd", + "\u09df"-"\u09e3", + "\u09e6"-"\u09f3", + "\u0a02", + "\u0a05"-"\u0a0a", + "\u0a0f"-"\u0a10", + "\u0a13"-"\u0a28", + "\u0a2a"-"\u0a30", + "\u0a32"-"\u0a33", + "\u0a35"-"\u0a36", + "\u0a38"-"\u0a39", + "\u0a3c", + "\u0a3e"-"\u0a42", + "\u0a47"-"\u0a48", + "\u0a4b"-"\u0a4d", + "\u0a59"-"\u0a5c", + "\u0a5e", + "\u0a66"-"\u0a74", + "\u0a81"-"\u0a83", + "\u0a85"-"\u0a8b", + "\u0a8d", + "\u0a8f"-"\u0a91", + "\u0a93"-"\u0aa8", + "\u0aaa"-"\u0ab0", + "\u0ab2"-"\u0ab3", + "\u0ab5"-"\u0ab9", + "\u0abc"-"\u0ac5", + "\u0ac7"-"\u0ac9", + "\u0acb"-"\u0acd", + "\u0ad0", + "\u0ae0", + "\u0ae6"-"\u0aef", + "\u0b01"-"\u0b03", + "\u0b05"-"\u0b0c", + "\u0b0f"-"\u0b10", + "\u0b13"-"\u0b28", + "\u0b2a"-"\u0b30", + "\u0b32"-"\u0b33", + "\u0b36"-"\u0b39", + "\u0b3c"-"\u0b43", + "\u0b47"-"\u0b48", + "\u0b4b"-"\u0b4d", + "\u0b56"-"\u0b57", + "\u0b5c"-"\u0b5d", + "\u0b5f"-"\u0b61", + "\u0b66"-"\u0b6f", + "\u0b82"-"\u0b83", + "\u0b85"-"\u0b8a", + "\u0b8e"-"\u0b90", + "\u0b92"-"\u0b95", + "\u0b99"-"\u0b9a", + "\u0b9c", + "\u0b9e"-"\u0b9f", + "\u0ba3"-"\u0ba4", + "\u0ba8"-"\u0baa", + "\u0bae"-"\u0bb5", + "\u0bb7"-"\u0bb9", + "\u0bbe"-"\u0bc2", + "\u0bc6"-"\u0bc8", + "\u0bca"-"\u0bcd", + "\u0bd7", + "\u0be7"-"\u0bef", + "\u0c01"-"\u0c03", + "\u0c05"-"\u0c0c", + "\u0c0e"-"\u0c10", + "\u0c12"-"\u0c28", + "\u0c2a"-"\u0c33", + "\u0c35"-"\u0c39", + "\u0c3e"-"\u0c44", + "\u0c46"-"\u0c48", + "\u0c4a"-"\u0c4d", + "\u0c55"-"\u0c56", + "\u0c60"-"\u0c61", + "\u0c66"-"\u0c6f", + "\u0c82"-"\u0c83", + "\u0c85"-"\u0c8c", + "\u0c8e"-"\u0c90", + "\u0c92"-"\u0ca8", + "\u0caa"-"\u0cb3", + "\u0cb5"-"\u0cb9", + "\u0cbe"-"\u0cc4", + "\u0cc6"-"\u0cc8", + "\u0cca"-"\u0ccd", + "\u0cd5"-"\u0cd6", + "\u0cde", + "\u0ce0"-"\u0ce1", + "\u0ce6"-"\u0cef", + "\u0d02"-"\u0d03", + "\u0d05"-"\u0d0c", + "\u0d0e"-"\u0d10", + "\u0d12"-"\u0d28", + "\u0d2a"-"\u0d39", + "\u0d3e"-"\u0d43", + "\u0d46"-"\u0d48", + "\u0d4a"-"\u0d4d", + "\u0d57", + "\u0d60"-"\u0d61", + "\u0d66"-"\u0d6f", + "\u0d82"-"\u0d83", + "\u0d85"-"\u0d96", + "\u0d9a"-"\u0db1", + "\u0db3"-"\u0dbb", + "\u0dbd", + "\u0dc0"-"\u0dc6", + "\u0dca", + "\u0dcf"-"\u0dd4", + "\u0dd6", + "\u0dd8"-"\u0ddf", + "\u0df2"-"\u0df3", + "\u0e01"-"\u0e3a", + "\u0e3f"-"\u0e4e", + "\u0e50"-"\u0e59", + "\u0e81"-"\u0e82", + "\u0e84", + "\u0e87"-"\u0e88", + "\u0e8a", + "\u0e8d", + "\u0e94"-"\u0e97", + "\u0e99"-"\u0e9f", + "\u0ea1"-"\u0ea3", + "\u0ea5", + "\u0ea7", + "\u0eaa"-"\u0eab", + "\u0ead"-"\u0eb9", + "\u0ebb"-"\u0ebd", + "\u0ec0"-"\u0ec4", + "\u0ec6", + "\u0ec8"-"\u0ecd", + "\u0ed0"-"\u0ed9", + "\u0edc"-"\u0edd", + "\u0f00", + "\u0f18"-"\u0f19", + "\u0f20"-"\u0f29", + "\u0f35", + "\u0f37", + "\u0f39", + "\u0f3e"-"\u0f47", + "\u0f49"-"\u0f6a", + "\u0f71"-"\u0f84", + "\u0f86"-"\u0f8b", + "\u0f90"-"\u0f97", + "\u0f99"-"\u0fbc", + "\u0fc6", + "\u1000"-"\u1021", + "\u1023"-"\u1027", + "\u1029"-"\u102a", + "\u102c"-"\u1032", + "\u1036"-"\u1039", + "\u1040"-"\u1049", + "\u1050"-"\u1059", + "\u10a0"-"\u10c5", + "\u10d0"-"\u10f6", + "\u1100"-"\u1159", + "\u115f"-"\u11a2", + "\u11a8"-"\u11f9", + "\u1200"-"\u1206", + "\u1208"-"\u1246", + "\u1248", + "\u124a"-"\u124d", + "\u1250"-"\u1256", + "\u1258", + "\u125a"-"\u125d", + "\u1260"-"\u1286", + "\u1288", + "\u128a"-"\u128d", + "\u1290"-"\u12ae", + "\u12b0", + "\u12b2"-"\u12b5", + "\u12b8"-"\u12be", + "\u12c0", + "\u12c2"-"\u12c5", + "\u12c8"-"\u12ce", + "\u12d0"-"\u12d6", + "\u12d8"-"\u12ee", + "\u12f0"-"\u130e", + "\u1310", + "\u1312"-"\u1315", + "\u1318"-"\u131e", + "\u1320"-"\u1346", + "\u1348"-"\u135a", + "\u1369"-"\u1371", + "\u13a0"-"\u13f4", + "\u1401"-"\u166c", + "\u166f"-"\u1676", + "\u1681"-"\u169a", + "\u16a0"-"\u16ea", + "\u1780"-"\u17d3", + "\u17db", + "\u17e0"-"\u17e9", + "\u180b"-"\u180e", + "\u1810"-"\u1819", + "\u1820"-"\u1877", + "\u1880"-"\u18a9", + "\u1e00"-"\u1e9b", + "\u1ea0"-"\u1ef9", + "\u1f00"-"\u1f15", + "\u1f18"-"\u1f1d", + "\u1f20"-"\u1f45", + "\u1f48"-"\u1f4d", + "\u1f50"-"\u1f57", + "\u1f59", + "\u1f5b", + "\u1f5d", + "\u1f5f"-"\u1f7d", + "\u1f80"-"\u1fb4", + "\u1fb6"-"\u1fbc", + "\u1fbe", + "\u1fc2"-"\u1fc4", + "\u1fc6"-"\u1fcc", + "\u1fd0"-"\u1fd3", + "\u1fd6"-"\u1fdb", + "\u1fe0"-"\u1fec", + "\u1ff2"-"\u1ff4", + "\u1ff6"-"\u1ffc", + "\u200c"-"\u200f", + "\u202a"-"\u202e", + "\u203f"-"\u2040", + "\u206a"-"\u206f", + "\u207f", + "\u20a0"-"\u20af", + "\u20d0"-"\u20dc", + "\u20e1", + "\u2102", + "\u2107", + "\u210a"-"\u2113", + "\u2115", + "\u2119"-"\u211d", + "\u2124", + "\u2126", + "\u2128", + "\u212a"-"\u212d", + "\u212f"-"\u2131", + "\u2133"-"\u2139", + "\u2160"-"\u2183", + "\u3005"-"\u3007", + "\u3021"-"\u302f", + "\u3031"-"\u3035", + "\u3038"-"\u303a", + "\u3041"-"\u3094", + "\u3099"-"\u309a", + "\u309d"-"\u309e", + "\u30a1"-"\u30fe", + "\u3105"-"\u312c", + "\u3131"-"\u318e", + "\u31a0"-"\u31b7", + "\u3400"-"\u4db5", + "\u4e00"-"\u9fa5", + "\ua000"-"\ua48c", + "\uac00"-"\ud7a3", + "\uf900"-"\ufa2d", + "\ufb00"-"\ufb06", + "\ufb13"-"\ufb17", + "\ufb1d"-"\ufb28", + "\ufb2a"-"\ufb36", + "\ufb38"-"\ufb3c", + "\ufb3e", + "\ufb40"-"\ufb41", + "\ufb43"-"\ufb44", + "\ufb46"-"\ufbb1", + "\ufbd3"-"\ufd3d", + "\ufd50"-"\ufd8f", + "\ufd92"-"\ufdc7", + "\ufdf0"-"\ufdfb", + "\ufe20"-"\ufe23", + "\ufe33"-"\ufe34", + "\ufe4d"-"\ufe4f", + "\ufe69", + "\ufe70"-"\ufe72", + "\ufe74", + "\ufe76"-"\ufefc", + "\ufeff", + "\uff04", + "\uff10"-"\uff19", + "\uff21"-"\uff3a", + "\uff3f", + "\uff41"-"\uff5a", + "\uff65"-"\uffbe", + "\uffc2"-"\uffc7", + "\uffca"-"\uffcf", + "\uffd2"-"\uffd7", + "\uffda"-"\uffdc", + "\uffe0"-"\uffe1", + "\uffe5"-"\uffe6", + "\ufff9"-"\ufffb" + ] + > +} + +/* SEPARATORS */ + +TOKEN : +{ + < LPAREN: "(" > +| < RPAREN: ")" > +| < LBRACE: "{" > +| < RBRACE: "}" > +| < LBRACKET: "[" > +| < RBRACKET: "]" > +| < SEMICOLON: ";" > +| < COMMA: "," > +| < DOT: "." > +| < AT: "@" > +} + +/* OPERATORS */ + +TOKEN : +{ + < ASSIGN: "=" > +| < LT: "<" > +| < BANG: "!" > +| < TILDE: "~" > +| < HOOK: "?" > +| < COLON: ":" > +| < EQ: "==" > +| < LE: "<=" > +| < GE: ">=" > +| < NE: "!=" > +| < SC_OR: "||" > +| < SC_AND: "&&" > +| < INCR: "++" > +| < DECR: "--" > +| < PLUS: "+" > +| < MINUS: "-" > +| < STAR: "*" > +| < SLASH: "/" > +| < BIT_AND: "&" > +| < BIT_OR: "|" > +| < XOR: "^" > +| < REM: "%" > +| < LSHIFT: "<<" > +| < PLUSASSIGN: "+=" > +| < MINUSASSIGN: "-=" > +| < STARASSIGN: "*=" > +| < SLASHASSIGN: "/=" > +| < ANDASSIGN: "&=" > +| < ORASSIGN: "|=" > +| < XORASSIGN: "^=" > +| < REMASSIGN: "%=" > +| < LSHIFTASSIGN: "<<=" > +| < RSIGNEDSHIFTASSIGN: ">>=" > +| < RUNSIGNEDSHIFTASSIGN: ">>>=" > +| < ELLIPSIS: "..." > +| < LAMBDA: "->" > +| < METHOD_REF: "::" > +} + +/* >'s need special attention due to generics syntax. */ +TOKEN : +{ + < RUNSIGNEDSHIFT: ">>>" > + { + matchedToken.kind = GT; + ((Token.GTToken)matchedToken).realKind = RUNSIGNEDSHIFT; + input_stream.backup(2); + matchedToken.image = ">"; + } +| < RSIGNEDSHIFT: ">>" > + { + matchedToken.kind = GT; + ((Token.GTToken)matchedToken).realKind = RSIGNEDSHIFT; + input_stream.backup(1); + matchedToken.image = ">"; + } +| < GT: ">" > +} + +/***************************************** + * THE JAVA LANGUAGE GRAMMAR STARTS HERE * + *****************************************/ + +/* + * Program structuring syntax follows. + */ + +ASTCompilationUnit CompilationUnit() : +{} +{ + [ LOOKAHEAD( ( Annotation() )* "package" ) PackageDeclaration() ] + ( ImportDeclaration() )* + ( TypeDeclaration() )* + ( < "\u001a" > )? + ( < "~[]" > )? + +{ + jjtThis.setComments(token_source.comments); + return jjtThis; +} +} + +void PackageDeclaration() : +{} +{ + ( Annotation() )* "package" Name() ";" +} + +void ImportDeclaration() : +{} +{ + "import" [ "static" {checkForBadStaticImportUsage();jjtThis.setStatic();} ] Name() [ "." "*" {jjtThis.setImportOnDemand();} ] ";" +} + +/* + * Modifiers. We match all modifiers in a single rule to reduce the chances of + * syntax errors for simple modifier mistakes. It will also enable us to give + * better error messages. + */ +int Modifiers() #void: +{ + int modifiers = 0; +} +{ + ( + LOOKAHEAD(2) + ( + "public" { modifiers |= AccessNode.PUBLIC; } + | "static" { modifiers |= AccessNode.STATIC; } + | "protected" { modifiers |= AccessNode.PROTECTED; } + | "private" { modifiers |= AccessNode.PRIVATE; } + | "final" { modifiers |= AccessNode.FINAL; } + | "abstract" { modifiers |= AccessNode.ABSTRACT; } + | "synchronized" { modifiers |= AccessNode.SYNCHRONIZED; } + | "native" { modifiers |= AccessNode.NATIVE; } + | "transient" { modifiers |= AccessNode.TRANSIENT; } + | "volatile" { modifiers |= AccessNode.VOLATILE; } + | "strictfp" { modifiers |= AccessNode.STRICTFP; } + | "default" { modifiers |= AccessNode.DEFAULT; checkForBadDefaultImplementationUsage(); } + | Annotation() + ) + )* + { + return modifiers; + } +} + +/* + * Declaration syntax follows. + */ +void TypeDeclaration(): +{ + int modifiers; +} +{ + ";" +| + modifiers = Modifiers() + ( + ClassOrInterfaceDeclaration(modifiers) + | + EnumDeclaration(modifiers) + | + AnnotationTypeDeclaration(modifiers) + ) +} + +void ClassOrInterfaceDeclaration(int modifiers): +{ +Token t = null; +jjtThis.setModifiers(modifiers); +} +{ + + ( /* See note about this optional final modifier in BlockStatement */ ["final"|"abstract"] "class" | "interface" { jjtThis.setInterface(); } ) + t= { jjtThis.setImage(t.image); } + [ TypeParameters() ] + [ ExtendsList() ] + [ ImplementsList() ] + ClassOrInterfaceBody() +} + +void ExtendsList(): +{ + boolean extendsMoreThanOne = false; +} +{ + "extends" (Annotation() {checkForBadTypeAnnotations();})* ClassOrInterfaceType() + ( "," (Annotation() {checkForBadTypeAnnotations();})* ClassOrInterfaceType() { extendsMoreThanOne = true; } )* +} + +void ImplementsList(): +{} +{ + "implements" (Annotation() {checkForBadTypeAnnotations();})* ClassOrInterfaceType() + ( "," (Annotation() {checkForBadTypeAnnotations();})* ClassOrInterfaceType() )* +} + +void EnumDeclaration(int modifiers): +{ + +Token t; +jjtThis.setModifiers(modifiers); +} +{ + t = { + if (!t.image.equals("enum")) { + throw new ParseException("ERROR: expecting enum"); + } + + if (jdkVersion < 5) { + throw new ParseException("ERROR: Can't use enum as a keyword in pre-JDK 1.5 target"); + } + } + t= {jjtThis.setImage(t.image);} + [ ImplementsList() ] + EnumBody() +} + +void EnumBody(): +{} +{ + "{" + [( Annotation() )* EnumConstant() ( LOOKAHEAD(2) "," ( Annotation() )* EnumConstant() )* ] + [ "," ] + [ ";" ( ClassOrInterfaceBodyDeclaration() )* ] + "}" +} + +void EnumConstant(): +{Token t;} +{ + t= {jjtThis.setImage(t.image);} [ Arguments() ] [ ClassOrInterfaceBody() ] +} + +void TypeParameters(): +{} +{ + "<" {checkForBadGenericsUsage();} TypeParameter() ( "," TypeParameter() )* ">" +} + +void TypeParameter(): +{Token t;} +{ + (Annotation() {checkForBadTypeAnnotations();})* + t= {jjtThis.setImage(t.image);} [ TypeBound() ] +} + +void TypeBound(): +{} +{ + "extends" ClassOrInterfaceType() ( "&" ClassOrInterfaceType() )* +} + +void ClassOrInterfaceBody(): +{} +{ + "{" ( ClassOrInterfaceBodyDeclaration() )* "}" +} + +void ClassOrInterfaceBodyDeclaration(): +{ + int modifiers; +} +{ LOOKAHEAD(["static"] "{" ) Initializer() +| modifiers = Modifiers() + ( LOOKAHEAD(3) ClassOrInterfaceDeclaration(modifiers) + | LOOKAHEAD(3) EnumDeclaration(modifiers) + | LOOKAHEAD( [ TypeParameters() ] "(" ) ConstructorDeclaration(modifiers) + | LOOKAHEAD( Type() ( "[" "]" )* ( "," | "=" | ";" ) ) FieldDeclaration(modifiers) + | MethodDeclaration(modifiers) + | AnnotationTypeDeclaration(modifiers) + ) +| + ";" +} + +void FieldDeclaration(int modifiers) : +{jjtThis.setModifiers(modifiers);} +{ + Type() VariableDeclarator() ( "," VariableDeclarator() )* ";" +} + +void VariableDeclarator() : +{} +{ + VariableDeclaratorId() [ "=" VariableInitializer() ] +} + +void VariableDeclaratorId() : +{Token t;} +{ + t= + ( "[" "]" { jjtThis.bumpArrayDepth(); })* + { + checkForBadAssertUsage(t.image, "a variable name"); + checkForBadEnumUsage(t.image, "a variable name"); + jjtThis.setImage( t.image ); + } +} + +void VariableInitializer() : +{} +{ + ArrayInitializer() +| Expression() +} + +void ArrayInitializer() : +{} +{ + "{" [ VariableInitializer() ( LOOKAHEAD(2) "," VariableInitializer() )* ] [ "," ] "}" +} + +void MethodDeclaration(int modifiers) : +{jjtThis.setModifiers(modifiers);} +{ + [ TypeParameters() ] + ResultType() MethodDeclarator() [ "throws" NameList() ] + ( Block() | ";" ) +} + +void MethodDeclarator() : +{Token t;} +{ + t= + { + checkForBadAssertUsage(t.image, "a method name"); + checkForBadEnumUsage(t.image, "a method name"); + jjtThis.setImage( t.image ); + } + FormalParameters() ( "[" "]" )* +} + + +void FormalParameters() : +{} +{ + "(" [ FormalParameter() ( "," FormalParameter() )* ] ")" +} + +void FormalParameter() : +{ +} +{ + ( "final" {jjtThis.setFinal(true);} | Annotation() )* + Type() ("|" {checkForBadMultipleExceptionsCatching();} Type())* + [ "..." {checkForBadVariableArgumentsUsage();} {jjtThis.setVarargs();} ] + VariableDeclaratorId() +} + +void ConstructorDeclaration(int modifiers) : +{jjtThis.setModifiers(modifiers); +Token t;} +{ + [ TypeParameters() ] + FormalParameters() [ "throws" NameList() ] + "{" + [ LOOKAHEAD(ExplicitConstructorInvocation()) ExplicitConstructorInvocation() ] + ( BlockStatement() )* + t = "}" { if (isPrecededByComment(t)) { jjtThis.setContainsComment(); } } +} + +void ExplicitConstructorInvocation() : +{} +{ + LOOKAHEAD("this" Arguments() ";") "this" {jjtThis.setIsThis();} Arguments() ";" +| + LOOKAHEAD(TypeArguments() "this" Arguments() ";") TypeArguments() "this" {jjtThis.setIsThis();} Arguments() ";" +| + [ LOOKAHEAD(PrimaryExpression() ".") PrimaryExpression() "." ] [ TypeArguments() ] "super" {jjtThis.setIsSuper();} Arguments() ";" +} + +void Initializer() : +{} +{ + [ "static" {jjtThis.setStatic();} ] Block() +} + + +/* + * Type, name and expression syntax follows. + */ +void Type(): +{} +{ + LOOKAHEAD(2) ReferenceType() + | + PrimitiveType() +} + +void ReferenceType(): +{} +{ + PrimitiveType() ( LOOKAHEAD(2) "[" "]" { jjtThis.bumpArrayDepth(); })+ + | + ( ClassOrInterfaceType() ) ( LOOKAHEAD(2) "[" "]" { jjtThis.bumpArrayDepth(); })* +} + +void ClassOrInterfaceType(): +{ + StringBuffer s = new StringBuffer(); + Token t; +} +{ + t= {s.append(t.image);} + [ LOOKAHEAD(2) TypeArguments() ] + ( LOOKAHEAD(2) "." t= {s.append('.').append(t.image);} [ LOOKAHEAD(2) TypeArguments() ] )* + {jjtThis.setImage(s.toString());} +} + +void TypeArguments(): +{} +{ + LOOKAHEAD(2) + "<" {checkForBadGenericsUsage();} TypeArgument() ( "," TypeArgument() )* ">" + | + "<" {checkForBadDiamondUsage();} ">" +} + +void TypeArgument(): +{} +{ + (Annotation() {checkForBadTypeAnnotations();})* ReferenceType() + | + "?" [ WildcardBounds() ] +} + +void WildcardBounds(): +{} +{ + "extends" (Annotation() {checkForBadTypeAnnotations();})* ReferenceType() + | + "super" (Annotation() {checkForBadTypeAnnotations();})* ReferenceType() +} + +void PrimitiveType() : +{} +{ + "boolean" {jjtThis.setImage("boolean");} +| "char" {jjtThis.setImage("char");} +| "byte" {jjtThis.setImage("byte");} +| "short" {jjtThis.setImage("short");} +| "int" {jjtThis.setImage("int");} +| "long" {jjtThis.setImage("long");} +| "float" {jjtThis.setImage("float");} +| "double" {jjtThis.setImage("double");} +} + + +void ResultType() : +{} +{ + "void" | Type() +} + +void Name() : +/* + * A lookahead of 2 is required below since "Name" can be followed + * by a ".*" when used in the context of an "ImportDeclaration". + */ +{ + StringBuffer s = new StringBuffer(); + Token t; +} +{ + t= + { + jjtThis.testingOnly__setBeginLine( t.beginLine); + jjtThis.testingOnly__setBeginColumn( t.beginColumn); + s.append(t.image); + } + ( LOOKAHEAD(2) "." t= + {s.append('.').append(t.image);} + )* + {jjtThis.setImage(s.toString());} +} + +void NameList() : +{} +{ + (Annotation() {checkForBadTypeAnnotations();})* Name() + ( "," (Annotation() {checkForBadTypeAnnotations();})* Name() + )* +} + + +/* + * Expression syntax follows. + */ + +void Expression() : +/* + * This expansion has been written this way instead of: + * Assignment() | ConditionalExpression() + * for performance reasons. + * However, it is a weakening of the grammar for it allows the LHS of + * assignments to be any conditional expression whereas it can only be + * a primary expression. Consider adding a semantic predicate to work + * around this. + */ +{} +{ + ConditionalExpression() + [ + LOOKAHEAD(2) AssignmentOperator() Expression() + ] +} + +void AssignmentOperator() : +{} +{ + "=" {jjtThis.setImage("=");} + | "*=" {jjtThis.setImage("*="); jjtThis.setCompound();} + | "/=" {jjtThis.setImage("/="); jjtThis.setCompound();} + | "%=" {jjtThis.setImage("%="); jjtThis.setCompound();} + | "+=" {jjtThis.setImage("+="); jjtThis.setCompound();} + | "-=" {jjtThis.setImage("-="); jjtThis.setCompound();} + | "<<=" {jjtThis.setImage("<<="); jjtThis.setCompound();} + | ">>=" {jjtThis.setImage(">>="); jjtThis.setCompound();} + | ">>>=" {jjtThis.setImage(">>>="); jjtThis.setCompound();} + | "&=" {jjtThis.setImage("&="); jjtThis.setCompound();} + | "^=" {jjtThis.setImage("^="); jjtThis.setCompound();} + | "|=" {jjtThis.setImage("|="); jjtThis.setCompound();} +} + +void ConditionalExpression() #ConditionalExpression(>1) : +{} +{ + ConditionalOrExpression() [ LOOKAHEAD(2) "?" {jjtThis.setTernary();} Expression() ":" ConditionalExpression() ] +} + +void ConditionalOrExpression() #ConditionalOrExpression(>1): +{} +{ + ConditionalAndExpression() ( LOOKAHEAD(2) "||" ConditionalAndExpression() )* +} + +void ConditionalAndExpression() #ConditionalAndExpression(>1): +{} +{ + InclusiveOrExpression() ( LOOKAHEAD(2) "&&" InclusiveOrExpression() )* +} + +void InclusiveOrExpression() #InclusiveOrExpression(>1) : +{} +{ + ExclusiveOrExpression() ( LOOKAHEAD(2) "|" ExclusiveOrExpression() )* +} + +void ExclusiveOrExpression() #ExclusiveOrExpression(>1) : +{} +{ + AndExpression() ( LOOKAHEAD(2) "^" AndExpression() )* +} + +void AndExpression() #AndExpression(>1): +{} +{ + EqualityExpression() ( LOOKAHEAD(2) "&" EqualityExpression() )* +} + +void EqualityExpression() #EqualityExpression(>1): +{} +{ + InstanceOfExpression() ( LOOKAHEAD(2) ( "==" {jjtThis.setImage("==");} | "!=" {jjtThis.setImage("!=");} ) InstanceOfExpression() )* +} + +void InstanceOfExpression() #InstanceOfExpression(>1): +{} +{ + RelationalExpression() [ LOOKAHEAD(2) "instanceof" Type() ] +} + +void RelationalExpression() #RelationalExpression(>1): +{} +{ + ShiftExpression() + ( LOOKAHEAD(2) + ( "<" {jjtThis.setImage("<");} + | ">" {jjtThis.setImage(">");} + | "<=" {jjtThis.setImage("<=");} + | ">=" {jjtThis.setImage(">=");} + ) ShiftExpression() )* +} + +void ShiftExpression() #ShiftExpression(>1): +{} +{ + AdditiveExpression() + ( LOOKAHEAD(2) + ( "<<" { jjtThis.setImage("<<");} + | RSIGNEDSHIFT() + | RUNSIGNEDSHIFT() + ) AdditiveExpression() )* +} + +void AdditiveExpression() #AdditiveExpression(>1): +{} +{ + MultiplicativeExpression() ( LOOKAHEAD(2) ( "+" {jjtThis.setImage("+");} | "-" {jjtThis.setImage("-");} ) MultiplicativeExpression() )* +} + +void MultiplicativeExpression() #MultiplicativeExpression(>1): +{} +{ + UnaryExpression() ( LOOKAHEAD(2) ( "*" {jjtThis.setImage("*");} | "/" {jjtThis.setImage("/");} | "%" {jjtThis.setImage("%");}) UnaryExpression() )* +} + +void UnaryExpression() #UnaryExpression((jjtn000.getImage() != null)): +{} +{ + ("+" {jjtThis.setImage("+");} | "-" {jjtThis.setImage("-");}) UnaryExpression() + | PreIncrementExpression() + | PreDecrementExpression() + | UnaryExpressionNotPlusMinus() +} + +void PreIncrementExpression() : +{} +{ + "++" PrimaryExpression() +} + +void PreDecrementExpression() : +{} +{ + "--" PrimaryExpression() +} + +void UnaryExpressionNotPlusMinus() #UnaryExpressionNotPlusMinus((jjtn000.getImage() != null)): +{} +{ + ( "~" {jjtThis.setImage("~");} | "!" {jjtThis.setImage("!");} ) UnaryExpression() +| LOOKAHEAD( CastExpression() ) CastExpression() +| PostfixExpression() +} + +void PostfixExpression() #PostfixExpression((jjtn000.getImage() != null)): +{} +{ + PrimaryExpression() [ "++" {jjtThis.setImage("++");} | "--" {jjtThis.setImage("--");} ] +} + +void CastExpression() #CastExpression(>1): +{} +{ + LOOKAHEAD("(" (Annotation())* Type() ")") "(" (Annotation() {checkForBadTypeAnnotations();})* Type() ")" UnaryExpression() +| LOOKAHEAD("(" (Annotation())* Type() "&") "(" (Annotation() {checkForBadTypeAnnotations();})* Type() ( "&" {checkForBadIntersectionTypesInCasts(); jjtThis.setIntersectionTypes(true);} ReferenceType() )+ ")" UnaryExpressionNotPlusMinus() +| "(" (Annotation() {checkForBadTypeAnnotations();})* Type() ")" UnaryExpressionNotPlusMinus() +} + +void PrimaryExpression() : +{} +{ + PrimaryPrefix() ( LOOKAHEAD(2) PrimarySuffix() )* +} + +void MemberSelector(): +{ +Token t; +} +{ + "." TypeArguments() t= {jjtThis.setImage(t.image);} +| MethodReference() +} + +void MethodReference() : +{Token t; checkForBadMethodReferenceUsage();} +{ + "::" ("new" {jjtThis.setImage("new");} | t= {jjtThis.setImage(t.image);} ) +} + +void PrimaryPrefix() : +{Token t;} +{ + Literal() +| "this" {jjtThis.setUsesThisModifier();} +| "super" {jjtThis.setUsesSuperModifier();} +| LOOKAHEAD( "->" ) LambdaExpression() +| LOOKAHEAD( "(" VariableDeclaratorId() "," VariableDeclaratorId() ["," VariableDeclaratorId()] ")" "->" ) LambdaExpression() +| LOOKAHEAD( "(" FormalParameter() "," FormalParameter() ["," FormalParameter() ] ")" "->" ) LambdaExpression() +| LOOKAHEAD( LambdaExpression() ) LambdaExpression() +| LOOKAHEAD(3) "(" Expression() ")" +| AllocationExpression() +| LOOKAHEAD( ResultType() "." "class" ) ResultType() "." "class" +| LOOKAHEAD( Name() "::" ) Name() +| LOOKAHEAD( ReferenceType() MethodReference() ) ReferenceType() MethodReference() +| Name() +} + +void LambdaExpression() : +{ checkForBadLambdaUsage(); } +{ + VariableDeclaratorId() "->" ( Expression() | Block() ) +| LOOKAHEAD(3) FormalParameters() "->" ( Expression() | Block() ) +| LOOKAHEAD(3) "(" VariableDeclaratorId() ( "," VariableDeclaratorId() )* ")" "->" ( Expression() | Block() ) +} + +void PrimarySuffix() : +{Token t;} +{ LOOKAHEAD(2) "." "this" +| LOOKAHEAD(2) "." "super" +| LOOKAHEAD(2) "." AllocationExpression() +| LOOKAHEAD(3) MemberSelector() +| "[" Expression() "]" {jjtThis.setIsArrayDereference();} +| "." t= {jjtThis.setImage(t.image);} +| Arguments() {jjtThis.setIsArguments();} +} + +void Literal() : +{} +{ +{ Token t;} + t= { checkForBadNumericalLiteralslUsage(t); jjtThis.setImage(t.image); jjtThis.setIntLiteral();} +| t= { checkForBadNumericalLiteralslUsage(t); jjtThis.setImage(t.image); jjtThis.setFloatLiteral();} +| t= { checkForBadHexFloatingPointLiteral(); checkForBadNumericalLiteralslUsage(t); jjtThis.setImage(t.image); jjtThis.setFloatLiteral();} +| t= {jjtThis.setImage(t.image); jjtThis.setCharLiteral();} +| t= {jjtThis.setImage(t.image); jjtThis.setStringLiteral();} +| BooleanLiteral() +| NullLiteral() +} + +void BooleanLiteral() : +{} +{ + "true" { jjtThis.setTrue(); } | "false" +} + +void NullLiteral() : +{} +{ "null" } + +void Arguments() : +{} +{ + "(" [ ArgumentList() ] ")" +} + +void ArgumentList() : +{} +{ + Expression() ( "," Expression() )* +} + +void AllocationExpression(): +{} +{ + "new" (Annotation() {checkForBadTypeAnnotations();})* + (LOOKAHEAD(2) + PrimitiveType() ArrayDimsAndInits() + | + ClassOrInterfaceType() [ TypeArguments() ] + ( + ArrayDimsAndInits() + | + Arguments() [ ClassOrInterfaceBody() ] + ) + ) +} + +/* + * The second LOOKAHEAD specification below is to parse to PrimarySuffix + * if there is an expression between the "[...]". + */ +void ArrayDimsAndInits() : +{} +{ + LOOKAHEAD(2) + ( LOOKAHEAD(2) "[" Expression() "]" )+ ( LOOKAHEAD(2) "[" "]" )* +| + ( "[" "]" )+ ArrayInitializer() +} + + +/* + * Statement syntax follows. + */ + +void Statement() : +{} +{ + LOOKAHEAD( { isNextTokenAnAssert() } ) AssertStatement() +| LOOKAHEAD(2) LabeledStatement() +| Block() +| EmptyStatement() +| StatementExpression() ";" +| SwitchStatement() +| IfStatement() +| WhileStatement() +| DoStatement() +| ForStatement() +| BreakStatement() +| ContinueStatement() +| ReturnStatement() +| ThrowStatement() +| SynchronizedStatement() +| TryStatement() +} + +void LabeledStatement() : +{Token t;} +{ + t= {jjtThis.setImage(t.image);} ":" Statement() +} + +void Block() : +{Token t;} +{ + "{" + + ( BlockStatement() )* t = "}" { if (isPrecededByComment(t)) { jjtThis.setContainsComment(); } } +} + +void BlockStatement(): +{} +{ + LOOKAHEAD( { isNextTokenAnAssert() } ) AssertStatement() +| + LOOKAHEAD(( "final" | Annotation() )* Type() ) + LocalVariableDeclaration() ";" +| + Statement() +| + /* + TODO: Seems like we should be discarding the "final" + after using it in the lookahead; I added a ["final|abstract"] inside + ClassOrInterfaceDeclaration, but that seems like a hack that + could break other things... + */ + LOOKAHEAD( [Annotation()] ["final"|"abstract"] "class") [Annotation()] ClassOrInterfaceDeclaration(0) +} + +void LocalVariableDeclaration() : +{} +{ + ( "final" {jjtThis.setFinal(true);} | Annotation() )* + Type() + VariableDeclarator() + ( "," VariableDeclarator() )* +} + +void EmptyStatement() : +{} +{ + ";" +} + +void StatementExpression() : +{} +{ + PreIncrementExpression() +| + PreDecrementExpression() +| + LOOKAHEAD( PrimaryExpression() ("++" | "--") ) PostfixExpression() +| + PrimaryExpression() + [ + AssignmentOperator() Expression() + ] +} + +void SwitchStatement() : +{} +{ + "switch" "(" Expression() ")" "{" + ( SwitchLabel() ( BlockStatement() )* )* + "}" +} + +void SwitchLabel() : +{} +{ + "case" Expression() ":" +| + "default" {jjtThis.setDefault();} ":" +} + +void IfStatement() : +/* + * The disambiguating algorithm of JavaCC automatically binds dangling + * else's to the innermost if statement. The LOOKAHEAD specification + * is to tell JavaCC that we know what we are doing. + */ +{} +{ + "if" "(" Expression() ")" Statement() [ LOOKAHEAD(1) "else" {jjtThis.setHasElse();} Statement() ] +{} +} + +void WhileStatement() : +{} +{ + "while" "(" Expression() ")" Statement() +} + +void DoStatement() : +{} +{ + "do" Statement() "while" "(" Expression() ")" ";" +} + +void ForStatement() : +{} +{ + "for" "(" +( + LOOKAHEAD(LocalVariableDeclaration() ":") + {checkForBadJDK15ForLoopSyntaxArgumentsUsage();} + LocalVariableDeclaration() ":" Expression() +| + [ ForInit() ] ";" + [ Expression() ] ";" + [ ForUpdate() ] +) + ")" Statement() +} + +void ForInit() : +{} +{ + LOOKAHEAD( LocalVariableDeclaration() ) + LocalVariableDeclaration() +| + StatementExpressionList() +} + +void StatementExpressionList() : +{} +{ + StatementExpression() ( "," StatementExpression() )* +} + +void ForUpdate() : +{} +{ + StatementExpressionList() +} + +void BreakStatement() : +{Token t;} +{ + "break" [ t= {jjtThis.setImage(t.image);} ] ";" +} + +void ContinueStatement() : +{Token t;} +{ + "continue" [ t= {jjtThis.setImage(t.image);} ] ";" +} + +void ReturnStatement() : +{} +{ + "return" [ Expression() ] ";" +} + +void ThrowStatement() : +{} +{ + "throw" Expression() ";" +} + +void SynchronizedStatement() : +{} +{ + "synchronized" "(" Expression() ")" Block() +} + +void TryStatement() : +/* + * Semantic check required here to make sure that at least one + * resource/finally/catch is present. + */ +{} +{ + "try" (ResourceSpecification())? Block() + ( CatchStatement() )* + [ FinallyStatement() ] +} + +void ResourceSpecification() : +{} +{ + {checkForBadTryWithResourcesUsage();} + "(" + Resources() + (LOOKAHEAD(2) ";")? + ")" +} + +void Resources() : +{} +{ + Resource() (LOOKAHEAD(2) ";" Resource())* +} + +void Resource() : +{} +{ + ( "final" | Annotation() )* + Type() + VariableDeclaratorId() + "=" + Expression() +} + +void CatchStatement() : +{} +{ + "catch" + "(" FormalParameter() ")" + Block() +} + +void FinallyStatement() : +{} +{ + "finally" Block() +} + +void AssertStatement() : +{ + if (jdkVersion <= 3) { + throw new ParseException("Can't use 'assert' as a keyword when running in JDK 1.3 mode!"); + } +} +{ + Expression() [ ":" Expression() ] ";" +} + +/* We use productions to match >>>, >> and > so that we can keep the + * type declaration syntax with generics clean + */ + +void RUNSIGNEDSHIFT(): +{} +{ + ( LOOKAHEAD({ getToken(1).kind == GT && + ((Token.GTToken)getToken(1)).realKind == RUNSIGNEDSHIFT} ) + ">" ">" ">" + ) +} + +void RSIGNEDSHIFT(): +{} +{ + ( LOOKAHEAD({ getToken(1).kind == GT && + ((Token.GTToken)getToken(1)).realKind == RSIGNEDSHIFT} ) + ">" ">" + ) +} + +/* Annotation syntax follows. */ + +void Annotation(): +{} +{ + LOOKAHEAD( "@" Name() "(" ( "=" | ")" )) + NormalAnnotation() + | + LOOKAHEAD( "@" Name() "(" ) + SingleMemberAnnotation() + | + MarkerAnnotation() +} + +void NormalAnnotation(): +{} +{ + "@" Name() "(" [ MemberValuePairs() ] ")" {checkForBadAnnotationUsage();} +} + +void MarkerAnnotation(): +{} +{ + "@" Name() {checkForBadAnnotationUsage();} +} + +void SingleMemberAnnotation(): +{} +{ + "@" Name() "(" MemberValue() ")" {checkForBadAnnotationUsage();} +} + +void MemberValuePairs(): +{} +{ + MemberValuePair() ( "," MemberValuePair() )* +} + +void MemberValuePair(): +{Token t;} +{ + t= { jjtThis.setImage(t.image); } "=" MemberValue() +} + +void MemberValue(): +{} +{ + Annotation() + | + MemberValueArrayInitializer() + | + ConditionalExpression() +} + +void MemberValueArrayInitializer(): +{} +{ + "{" (MemberValue() ( LOOKAHEAD(2) "," MemberValue() )* [ "," ])? "}" +} + + +/* Annotation Types. */ + +void AnnotationTypeDeclaration(int modifiers): +{ +Token t; +jjtThis.setModifiers(modifiers); +} +{ + "@" "interface" t= {checkForBadAnnotationUsage();jjtThis.setImage(t.image);} AnnotationTypeBody() +} + +void AnnotationTypeBody(): +{} +{ + "{" ( AnnotationTypeMemberDeclaration() )* "}" +} + +void AnnotationTypeMemberDeclaration(): +{ + int modifiers; +} +{ + modifiers = Modifiers() + ( + LOOKAHEAD(3) AnnotationMethodDeclaration(modifiers) + | + ClassOrInterfaceDeclaration(modifiers) + | + LOOKAHEAD(3) EnumDeclaration(modifiers) + | + AnnotationTypeDeclaration(modifiers) + | + FieldDeclaration(modifiers) + ) + | + ( ";" ) +} + +void AnnotationMethodDeclaration(int modifiers): +{ + Token t; + jjtThis.setModifiers(modifiers); +} +{ + Type() t= "(" ")" [ DefaultValue() ] ";" + { + jjtThis.setImage(t.image); + } +} + +void DefaultValue(): +{} +{ + "default" MemberValue() +} diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml new file mode 100644 index 0000000000..a93abfc797 --- /dev/null +++ b/pmd-java/pom.xml @@ -0,0 +1,434 @@ + + + 4.0.0 + net.sourceforge.pmd + pmd-java + PMD Java + 5.1.4-SNAPSHOT + + + org.sonatype.oss + oss-parent + 7 + + + + + 5.0 + 2.17 + 2.12.1 + 3.2 + 1.6 + + UTF-8 + + + + + + ${basedir}/src/test/resources + + + ${basedir}/src/test/java + + **/testdata/*.java + + + + + + ${basedir}/src/main/resources + true + + + + + org.apache.maven.wagon + wagon-ssh + 2.6 + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.7 + + + org.apache.maven.plugins + maven-assembly-plugin + 2.4.1 + + + org.apache.maven.plugins + maven-dependency-plugin + 2.8 + + + org.apache.maven.plugins + maven-release-plugin + 2.3.2 + + + org.apache.maven.plugins + maven-clean-plugin + 2.5 + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + + org.apache.maven.plugins + maven-deploy-plugin + 2.8.1 + + + org.apache.maven.plugins + maven-install-plugin + 2.5.1 + + + org.apache.maven.plugins + maven-jar-plugin + 2.5 + + + org.apache.maven.plugins + maven-resources-plugin + 2.6 + + + org.apache.maven.plugins + maven-site-plugin + 3.4 + + + org.apache.maven.plugins + maven-surefire-plugin + ${surefire.version} + + + org.codehaus.mojo + build-helper-maven-plugin + 1.8 + + + com.atlassian.maven.plugins + maven-clover2-plugin + 2.5.1 + + + net.sourceforge.pmd + pmd-build + 0.8 + + + org.apache.maven.plugins + maven-source-plugin + 2.3 + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle.version} + + + org.apache.maven.plugins + maven-enforcer-plugin + 1.3.1 + + + org.apache.maven.plugins + maven-pmd-plugin + ${pmd.plugin.version} + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.apache.maven.plugins + maven-antrun-plugin + [1.7,) + + run + + + + + false + true + + + + + + + + + + + + maven-resources-plugin + + false + + ${*} + + + + + maven-surefire-plugin + + once + -Xmx512m -Dfile.encoding=${project.build.sourceEncoding} + alphabetical + + + + maven-compiler-plugin + + ${java.version} + ${java.version} + + + + + org.apache.maven.plugins + maven-antrun-plugin + true + + + generate-sources + generate-sources + + + + + + + + + + run + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-javacc-generated-sources + + add-source + + + + ${project.build.directory}/generated-sources/javacc + + + + + + + + + com.atlassian.maven.plugins + maven-clover2-plugin + + ${java.version} + ${basedir}/../pmd/licences/clover2.license + + + + pre-site + + instrument + + + + + + org.apache.maven.plugins + maven-site-plugin + + + org.apache.maven.doxia + doxia-module-markdown + 1.6 + + + + ${project.build.directory}/generated-xdocs + + + + + + + net.sourceforge.pmd + pmd + ${project.version} + + + org.apache.ant + ant + 1.8.1 + provided + + + org.apache.ant + ant-testutil + 1.7.1 + test + + + jaxen + jaxen + 1.1.1 + + + xercesImpl + xerces + + + xalan + xalan + + + icu4j + com.ibm.icu + + + + + com.beust + jcommander + 1.27 + + + org.ow2.asm + asm + 5.0.2 + + + net.sourceforge.saxon + saxon + 9.1.0.8 + + + net.sourceforge.saxon + saxon + 9.1.0.8 + dom + runtime + + + org.mozilla + rhino + 1.7R3 + + + junit + junit + 4.11 + test + + + xerces + xercesImpl + 2.9.1 + jar + compile + + + net.java.dev.javacc + javacc + ${javacc.version} + + + commons-io + commons-io + 2.2 + + + org.mockito + mockito-all + 1.9.5 + test + + + org.apache.commons + commons-lang3 + 3.1 + + + org.slf4j + slf4j-api + 1.7.7 + test + + + + + + reports + + true + + + + + org.apache.maven.plugins + maven-pmd-plugin + + + verify + + pmd + + + + + 100 + ${java.version} + + ${basedir}/../pmd/src/main/resources/rulesets/internal/dogfood.xml + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + verify + + checkstyle + + + + + ${basedir}/../pmd/etc/checkstyle-config.xml + ${basedir}/../pmd/etc/checkstyle-suppressions.xml + + + + + + + diff --git a/pmd-java/src/main/ant/alljavacc.xml b/pmd-java/src/main/ant/alljavacc.xml new file mode 100644 index 0000000000..5534549057 --- /dev/null +++ b/pmd-java/src/main/ant/alljavacc.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + public class + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index fd08f60f0f..3b79a71bbb 100644 --- a/pom.xml +++ b/pom.xml @@ -14,5 +14,6 @@ pmd + pmd-java