Skip to content

Commit c8e90f3

Browse files
committed
Java 21: Pattern Matching + StringTemplate JEP-430 + Unnamed JEP-445
1 parent 8627fd2 commit c8e90f3

File tree

54 files changed

+2698
-21
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2698
-21
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,5 @@ generated/
5656
# Blueprint theme
5757
__init__.pyc
5858

59-
node_modules/
59+
node_modules/
60+
target

build.gradle

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
buildscript {
22
repositories {
3+
mavenLocal() { metadataSources { mavenPom(); ignoreGradleMetadataRedirection() } }
34
mavenCentral() { metadataSources { mavenPom(); ignoreGradleMetadataRedirection() } }
45
gradlePluginPortal() { metadataSources { mavenPom(); ignoreGradleMetadataRedirection() } }
56
}
67

78
dependencies {
89
classpath 'com.palantir.jakartapackagealignment:jakarta-package-alignment:0.5.0'
910
classpath 'com.gradle.publish:plugin-publish-plugin:1.2.1'
10-
classpath 'com.palantir.baseline:gradle-baseline-java:5.20.0'
11+
classpath 'com.palantir.baseline:gradle-baseline-java:5.21.0'
1112
classpath 'com.palantir.gradle.consistentversions:gradle-consistent-versions:2.15.0'
1213
classpath 'com.palantir.gradle.externalpublish:gradle-external-publish-plugin:1.12.0'
1314
classpath 'com.palantir.gradle.gitversion:gradle-git-version:3.0.0'
@@ -37,6 +38,7 @@ allprojects {
3738
version = rootProject.version
3839

3940
repositories {
41+
mavenLocal() { metadataSources { mavenPom(); ignoreGradleMetadataRedirection() } }
4042
mavenCentral() { metadataSources { mavenPom(); ignoreGradleMetadataRedirection() } }
4143
}
4244
}
@@ -45,8 +47,7 @@ subprojects {
4547
apply plugin: 'java-library'
4648
apply plugin: 'org.inferred.processors'
4749

48-
sourceCompatibility = 11
49-
targetCompatibility = 11
50+
5051

5152
tasks.withType(Checkstyle) {
5253
enabled = false

gradle-palantir-java-format/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ configurations {
88
implicitDependencies
99
pluginClasspath
1010
}
11+
java{
12+
sourceCompatibility = 11
13+
targetCompatibility = 11
14+
}
1115

1216
dependencies {
1317
implementation gradleApi()

idea-plugin/build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ configurations {
5151
}
5252
}
5353

54+
java{
55+
sourceCompatibility = 11
56+
targetCompatibility = 11
57+
}
58+
5459
dependencies {
5560
implementation project(':palantir-java-format-jdk-bootstrap')
5661
implementation 'com.github.ben-manes.caffeine:caffeine'

palantir-java-format-jdk-bootstrap/build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ apply plugin: 'java-library'
22
apply plugin: 'com.palantir.external-publish-jar'
33
apply plugin: 'com.palantir.revapi'
44

5+
java{
6+
sourceCompatibility = 11
7+
targetCompatibility = 11
8+
}
9+
510
dependencies {
611
annotationProcessor "org.immutables:value"
712

palantir-java-format-jdk-bootstrap/src/main/java/com/palantir/javaformat/bootstrap/BootstrappingFormatterService.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,17 @@ final class Builder extends ImmutableFormatterCliArgs.Builder {
153153
Builder withJvmArgsForVersion(Integer majorJvmVersion) {
154154
if (majorJvmVersion >= 16) {
155155
addJvmArgs(
156-
"--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
157-
"--add-exports", "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
158-
"--add-exports", "jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED",
159-
"--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
160-
"--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED");
156+
"--enable-preview",
157+
"--add-exports",
158+
"jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
159+
"--add-exports",
160+
"jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
161+
"--add-exports",
162+
"jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED",
163+
"--add-exports",
164+
"jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
165+
"--add-exports",
166+
"jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED");
161167
}
162168
return this;
163169
}

palantir-java-format-spi/build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ apply plugin: 'java-library'
22
apply plugin: 'com.palantir.external-publish-jar'
33
apply plugin: 'com.palantir.revapi'
44

5+
java{
6+
sourceCompatibility = 11
7+
targetCompatibility = 11
8+
}
9+
510
dependencies {
611
api 'com.google.guava:guava'
712
api 'com.fasterxml.jackson.core:jackson-annotations'

palantir-java-format/build.gradle

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ def exports = [
4343
'jdk.compiler/com.sun.tools.javac.api'
4444
]
4545

46+
java{
47+
sourceCompatibility = 11
48+
targetCompatibility = 11
49+
}
50+
4651
def jvmArgList = exports.stream().map(new Function<String, String>() {
4752
@Override
4853
String apply(String value) {
@@ -57,12 +62,14 @@ tasks.withType(JavaCompile).configureEach {
5762
options.compilerArgs += jvmArgList
5863

5964
if (JavaVersion.current() < JavaVersion.VERSION_14) {
60-
excludes = ['**/Java14InputAstVisitor.java']
65+
exclude '**/Java14InputAstVisitor.java'
6166
}
67+
6268
}
6369

6470
tasks.withType(Test).configureEach {
6571
jvmArgs = jvmArgList
72+
maxParallelForks = 1
6673
}
6774

6875
tasks.withType(Javadoc).configureEach {
@@ -72,6 +79,7 @@ tasks.withType(Javadoc).configureEach {
7279
if (JavaVersion.current() < JavaVersion.VERSION_14) {
7380
exclude '**/Java14InputAstVisitor.java'
7481
}
82+
7583
}
7684

7785
// false positives due to org.junit.runners.* in the test cases
@@ -85,7 +93,7 @@ tasks.test {
8593

8694
// necessary to compile Java14InputAstVisitor
8795
idea {
88-
module.languageLevel = new org.gradle.plugins.ide.idea.model.IdeaLanguageLevel(14)
96+
module.languageLevel = new org.gradle.plugins.ide.idea.model.IdeaLanguageLevel(17)
8997
}
9098

9199
// This block may be replaced by BaselineExportsExtension exports
@@ -95,3 +103,11 @@ jar {
95103
attributes('Add-Exports': exports.stream().collect(Collectors.joining(' ')))
96104
}
97105
}
106+
107+
tasks.named('jar', Jar){
108+
// hack to get java21 Class ...
109+
// the build script should be completely review to handle java 21
110+
from ('build/classes/java/main', '../palantir-java-format21/build/classes/java/main')
111+
112+
include('**/*')
113+
}

palantir-java-format/src/main/java/com/palantir/javaformat/java/Formatter.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,17 @@ static JavaOutput format(
131131
OpsBuilder opsBuilder = new OpsBuilder(javaInput);
132132

133133
JavaInputAstVisitor visitor;
134-
if (getRuntimeVersion() >= 14) {
134+
135+
if (getRuntimeVersion() >= 21) {
136+
try {
137+
visitor = Class.forName("com.palantir.javaformat.java.java21.Java21InputAstVisitor")
138+
.asSubclass(JavaInputAstVisitor.class)
139+
.getConstructor(OpsBuilder.class, int.class)
140+
.newInstance(opsBuilder, options.indentationMultiplier());
141+
} catch (ReflectiveOperationException e) {
142+
throw new RuntimeException(e.getMessage(), e);
143+
}
144+
} else if (getRuntimeVersion() >= 14) {
135145
try {
136146
visitor = Class.forName("com.palantir.javaformat.java.java14.Java14InputAstVisitor")
137147
.asSubclass(JavaInputAstVisitor.class)

palantir-java-format/src/main/java/com/palantir/javaformat/java/JavaInput.java

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,22 +370,60 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept
370370
List<Tok> toks = new ArrayList<>();
371371
int charI = 0;
372372
int columnI = 0;
373+
int stringFragmentEndPos = -1;
374+
373375
for (RawTok t : rawToks) {
374376
if (stopTokens.contains(t.kind())) {
375377
break;
376378
}
377379
int charI0 = t.pos();
380+
381+
/**
382+
* String Templates : https://openjdk.org/jeps/430
383+
* "String Template" tokenize like that : {STRINGFRAGMENT}{literal}{STRINGFRAGMENT} and after list of parameters
384+
* for exemple:
385+
* `String s = STR."\{fruit[0]} is nice";`
386+
* will give this token (STRINGFRAGMENT)""" , (literal)fruit[0] ,(STRINGFRAGMENT)" is nice" and after "fruit[0]" again with a potion of fruit[0] on file
387+
*
388+
* for this reason we comme back after the position of the last STRINGFRAGMENT
389+
*/
390+
if (t.pos() < stringFragmentEndPos && stringFragmentEndPos < t.endPos()) {
391+
// case System.out.println(STR." \{o} ---" );
392+
// on this case tokTex == " ---\" " but we already add the token " ---\""
393+
// it is why we recreate a new token with only " " (after \" )
394+
395+
charI0 = stringFragmentEndPos;
396+
t = new RawTok("", t.kind(), stringFragmentEndPos, t.endPos());
397+
}
398+
399+
if (t.pos() == stringFragmentEndPos) {
400+
// reset when it come back exactly to the same position: System.out.println(STR." \{o}");
401+
stringFragmentEndPos = -1;
402+
}
403+
404+
// drop token when after STRINGFRAGMENT when it comme back
405+
if (t.pos() < stringFragmentEndPos) {
406+
continue;
407+
}
408+
boolean stringFragmentKind =
409+
(t.kind() != null && "STRINGFRAGMENT".equals(t.kind().name()));
410+
411+
// end String Templates
412+
378413
// Get string, possibly with Unicode escapes.
379414
String originalTokText = text.substring(charI0, t.endPos());
380-
String tokText = t.kind() == TokenKind.STRINGLITERAL
415+
416+
String tokText = (t.kind() == TokenKind.STRINGLITERAL)
381417
? t.stringVal() // Unicode escapes removed.
382418
: originalTokText;
419+
383420
char tokText0 = tokText.charAt(0); // The token's first character.
384421
final boolean isToken; // Is this tok a token?
385422
final boolean isNumbered; // Is this tok numbered? (tokens and comments)
386423
String extraNewline = null; // Extra newline at end?
387424
List<String> strings = new ArrayList<>();
388-
if (Character.isWhitespace(tokText0)) {
425+
426+
if (Character.isWhitespace(tokText0) && !stringFragmentKind) {
389427
isToken = false;
390428
isNumbered = false;
391429
Iterator<String> it = Newlines.lineIterator(originalTokText);
@@ -402,10 +440,14 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept
402440
strings.add(line);
403441
}
404442
}
405-
} else if (tokText.startsWith("'") || tokText.startsWith("\"")) {
443+
} else if (tokText.startsWith("'") || tokText.startsWith("\"") || stringFragmentKind) {
406444
isToken = true;
407445
isNumbered = true;
408446
strings.add(originalTokText);
447+
if (stringFragmentKind) {
448+
stringFragmentEndPos = t.endPos();
449+
}
450+
409451
} else if (tokText.startsWith("//") || tokText.startsWith("/*")) {
410452
// For compatibility with an earlier lexer, the newline after a // comment is its own tok.
411453
if (tokText.startsWith("//") && (originalTokText.endsWith("\n") || originalTokText.endsWith("\r"))) {

0 commit comments

Comments
 (0)