diff --git a/build.gradle b/build.gradle index 319cbdcbb..dffc267ea 100644 --- a/build.gradle +++ b/build.gradle @@ -73,7 +73,7 @@ def getVersion = { boolean considerSnapshot -> // for publishing a release, call Gradle with Environment Variable RELEASE: // RELEASE=true gradle JSQLParser:publish version = getVersion( !System.getenv("RELEASE") ) -group = 'com.github.jsqlparser' +group = 'com.manticore-projects.jsqlformatter' description = 'JSQLParser library' tasks.register('generateBuildInfo') { @@ -591,81 +591,56 @@ publish { dependsOn(check, gitChangelogTask, renderRR, xslt, xmldoc) } -publishing { - publications { - mavenJava(MavenPublication) { - artifactId = 'jsqlparser' +mavenPublishing { + publishToMavenCentral(true) + signAllPublications() - from components.java + coordinates(group, "jsqlparser", version) - versionMapping { - usage('java-api') { - fromResolutionOf('runtimeClasspath') - } - usage('java-runtime') { - fromResolutionResult() - } - } - - pom { - name.set('JSQLParser library') - description.set('Parse SQL Statements into Abstract Syntax Trees (AST)') - url.set('https://github.com/JSQLParser/JSqlParser') - - licenses { - license { - name.set('GNU Library or Lesser General Public License (LGPL) V2.1') - url.set('http://www.gnu.org/licenses/lgpl-2.1.html') - } - license { - name.set('The Apache Software License, Version 2.0') - url.set('http://www.apache.org/licenses/LICENSE-2.0.txt') - } - } - - developers { - developer { - id.set('twa') - name.set('Tobias Warneke') - email.set('t.warneke@gmx.net') - } - developer { - id.set('are') - name.set('Andreas Reichel') - email.set('andreas@manticore-projects.com') - } - } + pom { + name.set('JSQLParser library') + description.set('Parse SQL Statements into Abstract Syntax Trees (AST)') + url.set('https://github.com/JSQLParser/JSqlParser') - scm { - connection.set('scm:git:https://github.com/JSQLParser/JSqlParser.git') - developerConnection.set('scm:git:ssh://git@github.com:JSQLParser/JSqlParser.git') - url.set('https://github.com/JSQLParser/JSqlParser.git') - } + licenses { + license { + name.set('GNU Library or Lesser General Public License (LGPL) V2.1') + url.set('http://www.gnu.org/licenses/lgpl-2.1.html') + } + license { + name.set('The Apache Software License, Version 2.0') + url.set('http://www.apache.org/licenses/LICENSE-2.0.txt') } } - } - repositories { - maven { - name = "ossrh" - def releasesRepoUrl = "https://central.sonatype.com/repository/maven-releases" - def snapshotsRepoUrl = "https://central.sonatype.com/repository/maven-snapshots/" - url(version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl) - - credentials { - username = providers.environmentVariable("ossrhUsername").orNull - password = providers.environmentVariable("ossrhPassword").orNull + developers { + developer { + id.set('twa') + name.set('Tobias Warneke') + email.set('t.warneke@gmx.net') + } + developer { + id.set('are') + name.set('Andreas Reichel') + email.set('andreas@manticore-projects.com') } } + + scm { + connection.set('scm:git:https://github.com/JSQLParser/JSqlParser.git') + developerConnection.set('scm:git:ssh://git@github.com:JSQLParser/JSqlParser.git') + url.set('https://github.com/JSQLParser/JSqlParser.git') + } } } +// Fix signing task dependencies +tasks.withType(AbstractPublishToMaven).configureEach { + dependsOn(tasks.withType(Sign)) +} signing { - // don't sign SNAPSHOTS - if (!version.endsWith('SNAPSHOT')) { - sign publishing.publications.mavenJava - } + required { !version.endsWith("SNAPSHOT") && gradle.taskGraph.hasTask("publish") } } tasks.withType(JavaCompile).configureEach { diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 5883319e7..fdfba2d10 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -914,10 +914,6 @@ PARSER_END(CCJSqlParser) TOKEN_MGR_DECLS : { public FeatureConfiguration configuration = new FeatureConfiguration(); - // Nesting depth for block comments: /* /* ... */ */ - int commentNesting = 0; - // Stores the comment image up to and including the outermost */ - String storedCommentImage = null; // Identify the index of the quoting/escaping tokens public int charLiteralIndex = -1; @@ -1005,6 +1001,35 @@ TOKEN_MGR_DECLS : { reportError(Math.max(closingQuote.length(), input_stream.GetImage().length())); } } + + /** + * Consumes the body of a block comment after the opening delimiter has been matched, + * honouring nesting, up to and including the outermost closing delimiter. Then backs + * up 2 characters so the MULTI_LINE_COMMENT rule matches the closing delimiter and + * terminates the MORE chain. + */ + void consumeBlockCommentBody() { + int nesting = 1; + char prev = 0; + try { + while (nesting > 0) { + char c = input_stream.readChar(); + if (prev == '/' && c == '*') { + nesting++; + prev = 0; + } else if (prev == '*' && c == '/') { + nesting--; + prev = 0; + } else { + prev = c; + } + } + input_stream.backup(2); + } catch (java.io.IOException e) { + // Unterminated comment: leave the stream at EOF and let the token + // manager raise the lexical error from IN_BLOCK_COMMENT. + } + } } SKIP: @@ -1612,41 +1637,23 @@ SPECIAL_TOKEN: // Nested block comments: /* ... /* ... */ ... */ // -// Uses a nesting counter (commentNesting in TOKEN_MGR_DECLS) and -// lexer states DEFAULT -> IN_BLOCK_COMMENT -> BLOCK_COMMENT_END. -// -// The */ rule has NO `: STATE` suffix — this is critical because -// JavaCC's `: STATE` always overrides SwitchTo(). Without it, -// SwitchTo(BLOCK_COMMENT_END) only fires when nesting reaches 0. +// The body is consumed manually in the MORE action below because JavaCC 8 +// discards actions attached to SPECIAL_TOKEN and SKIP rules: it emits +// SkipLexicalActions() with an empty switch. Only TOKEN and MORE actions +// survive code generation. Do not move this action onto the rule below. // -// In BLOCK_COMMENT_END, we match one real char with ~[], then -// backup(1) to put it back. This avoids the empty-string-at-EOF -// problem while cleanly emitting the accumulated comment image. +// consumeBlockCommentBody() scans past the whole comment, honouring nesting, +// then backs up 2 chars so re-matches the outermost "*/" +// and closes the MORE chain. No character past the comment is ever consumed, +// so there is nothing to push back and no dependency on what follows. MORE: { - "/*" { commentNesting = 0; } : IN_BLOCK_COMMENT -} - - MORE: -{ - "/*" { commentNesting++; } -| "*/" { - if (commentNesting > 0) { - commentNesting--; - } else { - storedCommentImage = image.toString(); - SwitchTo(BLOCK_COMMENT_END); - } - } -| < ~[] > + "/*" { consumeBlockCommentBody(); } : IN_BLOCK_COMMENT } - SPECIAL_TOKEN: + SPECIAL_TOKEN: { - { - input_stream.backup(1); - matchedToken.image = storedCommentImage; - } : DEFAULT + : DEFAULT } TOKEN: diff --git a/src/test/java/net/sf/jsqlparser/statement/select/SelectASTTest.java b/src/test/java/net/sf/jsqlparser/statement/select/SelectASTTest.java index 8c2a36261..ddc578d26 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/SelectASTTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/SelectASTTest.java @@ -199,7 +199,7 @@ public Object visit(Node node, Object data) { } }, null); - assertThat(comments).extracting(token -> token.image).containsExactly("/* testcomment */ ", + assertThat(comments).extracting(token -> token.image).containsExactly("/* testcomment */", "-- testcomment2 "); } @@ -210,6 +210,6 @@ public void testSelectASTExtractWithCommentsIssue1580_2() throws JSQLParserExcep Node root = (Node) CCJSqlParserUtil.parseAST(sql); assertThat(root.jjtGetFirstToken().specialToken.image) - .isEqualTo("/* I want this comment */\n"); + .isEqualTo("/* I want this comment */"); } }