From e230027f9aa2e01819814e8ec79cb08aae5f68dd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 24 Dec 2019 11:17:59 +0100 Subject: [PATCH] [plsql] Support COMMENT statement Ref #2009 --- pmd-plsql/etc/grammar/PldocAST.jjt | 49 ++++++++++++------- .../plsql/ast/MultipleDDLStatementsTest.java | 3 ++ 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/pmd-plsql/etc/grammar/PldocAST.jjt b/pmd-plsql/etc/grammar/PldocAST.jjt index f01524dc45..f256faa56c 100644 --- a/pmd-plsql/etc/grammar/PldocAST.jjt +++ b/pmd-plsql/etc/grammar/PldocAST.jjt @@ -227,6 +227,9 @@ public class PLSQLParser { /** * Semantic lookahead to check if the next identifier is a * specific keyword. + * + *

+ * Usage: LOOKAHEAD({isKeyword("WAIT")}) KEYWORD("WAIT") */ private boolean isKeyword(String keyword) { return getToken(1).kind == IDENTIFIER && getToken(1).image.equalsIgnoreCase(keyword); @@ -259,12 +262,12 @@ ASTInput Input(String sourcecode) : {} | LOOKAHEAD(6) Directory() | LOOKAHEAD(6) DatabaseLink() | LOOKAHEAD(6) Global() - | LOOKAHEAD(6) DDLCommand() //Ignore any other DDL Event + | (LOOKAHEAD(6) DDLCommand())+ | LOOKAHEAD(2) SqlPlusCommand() | UpdateStatement() | DeleteStatement() | InsertStatement() - | SelectStatement() (";")? + | SelectStatement() [";"] |(|||||) SkipPastNextTokenOccurrence(SQLPLUS_TERMINATOR) //Ignore SQL statements in scripts ) ("/")* @@ -279,8 +282,15 @@ ASTDDLCommand DDLCommand() : } { ( - simpleNode = DDLEvent() - SkipPastNextTokenOccurrence(SQLPLUS_TERMINATOR) + ( + LOOKAHEAD({isKeyword("COMMENT")}) + simpleNode = Comment() + ) + | + ( + simpleNode = DDLEvent() + SkipPastNextTokenOccurrence(SQLPLUS_TERMINATOR) + ) ) { jjtThis.setImage(simpleNode.getImage()) ; return jjtThis ; } } @@ -315,7 +325,7 @@ ASTSqlPlusCommand SqlPlusCommand() : | | // DDL that might be encountered - | + | LOOKAHEAD({isKeyword("COMMENT")}) KEYWORD("COMMENT") | | | @@ -3904,19 +3914,22 @@ ASTViewColumn ViewColumn() : { return jjtThis ; } } +/** + * https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/COMMENT.html#GUID-65F447C4-6914-4823-9691-F15D52DB74D7 + */ ASTComment Comment() : { } { - ( + LOOKAHEAD({isKeyword("COMMENT")}) KEYWORD("COMMENT") + ( ((
| | ) [LOOKAHEAD(2) ID()"."] ID()) | ( [LOOKAHEAD(ID()"."ID()"."ID()) ID()"."] ID() "." ID()) ) - - [";"] - { return jjtThis ; } + StringLiteral() + ";" + { return jjtThis ; } } -// SRT * / @@ -4489,23 +4502,26 @@ ASTNonDMLTrigger NonDMLTrigger() : { return jjtThis ; } } - +/** + * https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/Types-of-SQL-Statements.html#GUID-FD9A8CB4-6B9A-44E5-B114-EFB8DA76FC88 + */ ASTDDLEvent DDLEvent(): {} { ( | | | - | + | LOOKAHEAD({isKeyword("COMMENT")}) KEYWORD("COMMENT") | | | + // | | | + // | | | | - | ) { jjtThis.setImage(token.toString()) ; jjtThis.value = token ; return jjtThis ; } } @@ -4741,7 +4757,6 @@ TOKEN [IGNORE_CASE]: | | | - | | | | @@ -4997,7 +5012,6 @@ TOKEN [IGNORE_CASE]: | //11G Trigger Syntax | //11G Trigger Syntax | //11G Trigger Syntax -| //11G Trigger Syntax | //11G Trigger Syntax | //11G Trigger Syntax | //11G Trigger Syntax @@ -5386,7 +5400,6 @@ ASTKEYWORD_UNRESERVED KEYWORD_UNRESERVED (): {} //| //| //| -| | //| //| @@ -5447,7 +5460,6 @@ ASTKEYWORD_UNRESERVED KEYWORD_UNRESERVED (): {} //| //| | -| //| //| | @@ -6352,7 +6364,7 @@ ASTID ID(): {} | KEYWORD_UNRESERVED() //SRT 2011-04-17 /*KEYWORDS_UNRESERVED | | | | | | | | | - | | | | + | | | */ //20120501 | | | @@ -6615,7 +6627,6 @@ ASTQualifiedID QualifiedID(): {} // //| //20120501 | - //| //| // // diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/MultipleDDLStatementsTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/MultipleDDLStatementsTest.java index 37bfe03804..91ac15b17e 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/MultipleDDLStatementsTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/MultipleDDLStatementsTest.java @@ -22,5 +22,8 @@ public class MultipleDDLStatementsTest extends AbstractPLSQLParserTst { ASTInput input = parsePLSQL(code); List ddlcommands = input.findDescendantsOfType(ASTDDLCommand.class); Assert.assertEquals(3, ddlcommands.size()); + List comments = input.findDescendantsOfType(ASTComment.class); + Assert.assertEquals(3, comments.size()); + Assert.assertEquals("'abbreviated job title'", comments.get(0).getFirstChildOfType(ASTStringLiteral.class).getImage()); } }