From c3ff3d2ff7a9068a567f456d5340d7923f250e29 Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Wed, 1 Nov 2023 11:49:27 +0100 Subject: [PATCH 1/4] Update package, version 34 --- .run/Enhance.run.xml | 18 ----------- CHANGELOG.md | 15 +++++++++ build.gradle | 32 ++++++++++++------- .../{ru => io}/noties/enhance/ApiInfo.java | 2 +- .../noties/enhance/ApiInfoStore.java | 2 +- .../noties/enhance/ApiInfoStoreImpl.java | 2 +- .../{ru => io}/noties/enhance/ApiVersion.java | 3 +- .../noties/enhance/ApiVersionFormatter.java | 2 +- .../noties/enhance/ByteCodeSignature.java | 2 +- .../{ru => io}/noties/enhance/Enhance.java | 8 ++--- .../noties/enhance/EnhanceWriter.java | 4 +-- .../noties/enhance/EnhanceWriterImpl.java | 6 ++-- .../java/{ru => io}/noties/enhance/Log.java | 2 +- .../{ru => io}/noties/enhance/SdkHelper.java | 4 +-- .../java/{ru => io}/noties/enhance/Stats.java | 2 +- .../enhance/options/EnhanceOptions.java | 2 +- .../enhance/options/EnhanceOptionsImpl.java | 2 +- .../noties/enhance/options/SourceFormat.java | 2 +- .../noties/enhance/ApiInfoStoreImplTest.java | 4 +-- 19 files changed, 61 insertions(+), 53 deletions(-) delete mode 100644 .run/Enhance.run.xml rename src/main/java/{ru => io}/noties/enhance/ApiInfo.java (94%) rename src/main/java/{ru => io}/noties/enhance/ApiInfoStore.java (97%) rename src/main/java/{ru => io}/noties/enhance/ApiInfoStoreImpl.java (99%) rename src/main/java/{ru => io}/noties/enhance/ApiVersion.java (97%) rename src/main/java/{ru => io}/noties/enhance/ApiVersionFormatter.java (95%) rename src/main/java/{ru => io}/noties/enhance/ByteCodeSignature.java (99%) rename src/main/java/{ru => io}/noties/enhance/Enhance.java (96%) rename src/main/java/{ru => io}/noties/enhance/EnhanceWriter.java (86%) rename src/main/java/{ru => io}/noties/enhance/EnhanceWriterImpl.java (98%) rename src/main/java/{ru => io}/noties/enhance/Log.java (89%) rename src/main/java/{ru => io}/noties/enhance/SdkHelper.java (96%) rename src/main/java/{ru => io}/noties/enhance/Stats.java (99%) rename src/main/java/{ru => io}/noties/enhance/options/EnhanceOptions.java (91%) rename src/main/java/{ru => io}/noties/enhance/options/EnhanceOptionsImpl.java (98%) rename src/main/java/{ru => io}/noties/enhance/options/SourceFormat.java (63%) rename src/test/java/{ru => io}/noties/enhance/ApiInfoStoreImplTest.java (93%) diff --git a/.run/Enhance.run.xml b/.run/Enhance.run.xml deleted file mode 100644 index cfedf3b..0000000 --- a/.run/Enhance.run.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f126797..d0c528f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # CHANGELOG +# 34 +Applied new version-name strategy - now version equals latest supported Android SDK platform +### Added +* Upside Down Cake (34) + +### Changed +* Updated code structure, moved to `io.noties` package (no change for clients) + + +# 1.3.0 +### Added +* Android S_V2 (32) +* Tiramisu (33) + + # 1.2.0 ### Added * Android 12, SDK 31 API version diff --git a/build.gradle b/build.gradle index 23391e5..762a1ae 100644 --- a/build.gradle +++ b/build.gradle @@ -4,13 +4,13 @@ plugins { id 'application' } -group 'ru.noties' -version '1.3.0' +group 'io.noties' +version '34' -sourceCompatibility = JavaVersion.VERSION_1_8 -targetCompatibility = JavaVersion.VERSION_1_8 +sourceCompatibility = JavaVersion.VERSION_17 +targetCompatibility = JavaVersion.VERSION_17 -mainClassName = 'ru.noties.enhance.Enhance' +mainClassName = 'io.noties.enhance.Enhance' repositories { jcenter() @@ -21,14 +21,15 @@ dependencies { implementation 'com.google.code.findbugs:jsr305:3.0.2' // https://github.com/javaparser/javaparser - implementation 'com.github.javaparser:javaparser-core:3.24.8' + implementation 'com.github.javaparser:javaparser-core:3.25.4' // https://github.com/google/google-java-format - implementation 'com.google.googlejavaformat:google-java-format:1.5' + implementation 'com.google.googlejavaformat:google-java-format:1.17.0' implementation 'commons-cli:commons-cli:1.4' - implementation 'commons-io:commons-io:2.6' - testImplementation 'junit:junit:4.12' + implementation 'commons-io:commons-io:2.7' + + testImplementation 'junit:junit:4.13.1' } wrapper { @@ -37,13 +38,13 @@ wrapper { } afterEvaluate { - final def folder = new File(rootDir, '/gen/ru/noties/enhance') + final def folder = new File(rootDir, '/gen/io/noties/enhance') if (!folder.exists()) { folder.mkdirs() } final def file = new File(folder, 'EnhanceVersion.java') file.write(""" -package ru.noties.enhance; +package io.noties.enhance; class EnhanceVersion { static final String NAME = \"${version}\"; } """) } @@ -51,3 +52,12 @@ class EnhanceVersion { static final String NAME = \"${version}\"; } sourceSets { main.java.srcDirs += new File(rootDir, 'gen') } + +compileJava { + options.compilerArgs += '--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED' + options.compilerArgs += '--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED' + options.compilerArgs += '--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED' + options.compilerArgs += '--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED' + options.compilerArgs += '--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED' + options.compilerArgs += '--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED' +} diff --git a/src/main/java/ru/noties/enhance/ApiInfo.java b/src/main/java/io/noties/enhance/ApiInfo.java similarity index 94% rename from src/main/java/ru/noties/enhance/ApiInfo.java rename to src/main/java/io/noties/enhance/ApiInfo.java index 530ed15..ce8416e 100644 --- a/src/main/java/ru/noties/enhance/ApiInfo.java +++ b/src/main/java/io/noties/enhance/ApiInfo.java @@ -1,4 +1,4 @@ -package ru.noties.enhance; +package io.noties.enhance; public class ApiInfo { diff --git a/src/main/java/ru/noties/enhance/ApiInfoStore.java b/src/main/java/io/noties/enhance/ApiInfoStore.java similarity index 97% rename from src/main/java/ru/noties/enhance/ApiInfoStore.java rename to src/main/java/io/noties/enhance/ApiInfoStore.java index 8df6c82..a1f8e3d 100644 --- a/src/main/java/ru/noties/enhance/ApiInfoStore.java +++ b/src/main/java/io/noties/enhance/ApiInfoStore.java @@ -1,4 +1,4 @@ -package ru.noties.enhance; +package io.noties.enhance; import javax.annotation.Nonnull; import javax.annotation.Nullable; diff --git a/src/main/java/ru/noties/enhance/ApiInfoStoreImpl.java b/src/main/java/io/noties/enhance/ApiInfoStoreImpl.java similarity index 99% rename from src/main/java/ru/noties/enhance/ApiInfoStoreImpl.java rename to src/main/java/io/noties/enhance/ApiInfoStoreImpl.java index 2f334b9..2f77297 100644 --- a/src/main/java/ru/noties/enhance/ApiInfoStoreImpl.java +++ b/src/main/java/io/noties/enhance/ApiInfoStoreImpl.java @@ -1,4 +1,4 @@ -package ru.noties.enhance; +package io.noties.enhance; import org.w3c.dom.Document; import org.w3c.dom.Element; diff --git a/src/main/java/ru/noties/enhance/ApiVersion.java b/src/main/java/io/noties/enhance/ApiVersion.java similarity index 97% rename from src/main/java/ru/noties/enhance/ApiVersion.java rename to src/main/java/io/noties/enhance/ApiVersion.java index c4923db..20875f3 100644 --- a/src/main/java/ru/noties/enhance/ApiVersion.java +++ b/src/main/java/io/noties/enhance/ApiVersion.java @@ -1,4 +1,4 @@ -package ru.noties.enhance; +package io.noties.enhance; import javax.annotation.Nonnull; @@ -99,6 +99,7 @@ public String toString() { new ApiVersion(31, "12", "Android S"), new ApiVersion(32, "12", "Android S_V2"), new ApiVersion(33, "13", "Tiramisu"), + new ApiVersion(34, "14", "Upside Down Cake") }; private static final int LENGTH = VERSIONS.length; diff --git a/src/main/java/ru/noties/enhance/ApiVersionFormatter.java b/src/main/java/io/noties/enhance/ApiVersionFormatter.java similarity index 95% rename from src/main/java/ru/noties/enhance/ApiVersionFormatter.java rename to src/main/java/io/noties/enhance/ApiVersionFormatter.java index b89fef5..2811da1 100644 --- a/src/main/java/ru/noties/enhance/ApiVersionFormatter.java +++ b/src/main/java/io/noties/enhance/ApiVersionFormatter.java @@ -1,4 +1,4 @@ -package ru.noties.enhance; +package io.noties.enhance; import javax.annotation.Nonnull; diff --git a/src/main/java/ru/noties/enhance/ByteCodeSignature.java b/src/main/java/io/noties/enhance/ByteCodeSignature.java similarity index 99% rename from src/main/java/ru/noties/enhance/ByteCodeSignature.java rename to src/main/java/io/noties/enhance/ByteCodeSignature.java index e7278b5..d2434d8 100644 --- a/src/main/java/ru/noties/enhance/ByteCodeSignature.java +++ b/src/main/java/io/noties/enhance/ByteCodeSignature.java @@ -1,4 +1,4 @@ -package ru.noties.enhance; +package io.noties.enhance; import com.github.javaparser.ast.body.CallableDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; diff --git a/src/main/java/ru/noties/enhance/Enhance.java b/src/main/java/io/noties/enhance/Enhance.java similarity index 96% rename from src/main/java/ru/noties/enhance/Enhance.java rename to src/main/java/io/noties/enhance/Enhance.java index 49dbdd1..0b8276e 100644 --- a/src/main/java/ru/noties/enhance/Enhance.java +++ b/src/main/java/io/noties/enhance/Enhance.java @@ -1,7 +1,7 @@ -package ru.noties.enhance; +package io.noties.enhance; import org.apache.commons.io.FileUtils; -import ru.noties.enhance.options.EnhanceOptions; +import io.noties.enhance.options.EnhanceOptions; import javax.annotation.Nonnull; import java.io.BufferedReader; @@ -10,8 +10,8 @@ import java.io.InputStreamReader; import java.util.Locale; -import static ru.noties.enhance.Log.log; -import static ru.noties.enhance.Stats.printStatsFor; +import static io.noties.enhance.Log.log; +import static io.noties.enhance.Stats.printStatsFor; public class Enhance { diff --git a/src/main/java/ru/noties/enhance/EnhanceWriter.java b/src/main/java/io/noties/enhance/EnhanceWriter.java similarity index 86% rename from src/main/java/ru/noties/enhance/EnhanceWriter.java rename to src/main/java/io/noties/enhance/EnhanceWriter.java index e9819e6..0fdc46e 100644 --- a/src/main/java/ru/noties/enhance/EnhanceWriter.java +++ b/src/main/java/io/noties/enhance/EnhanceWriter.java @@ -1,6 +1,6 @@ -package ru.noties.enhance; +package io.noties.enhance; -import ru.noties.enhance.options.SourceFormat; +import io.noties.enhance.options.SourceFormat; import javax.annotation.Nonnull; import java.io.File; diff --git a/src/main/java/ru/noties/enhance/EnhanceWriterImpl.java b/src/main/java/io/noties/enhance/EnhanceWriterImpl.java similarity index 98% rename from src/main/java/ru/noties/enhance/EnhanceWriterImpl.java rename to src/main/java/io/noties/enhance/EnhanceWriterImpl.java index be302c1..955573e 100644 --- a/src/main/java/ru/noties/enhance/EnhanceWriterImpl.java +++ b/src/main/java/io/noties/enhance/EnhanceWriterImpl.java @@ -1,4 +1,4 @@ -package ru.noties.enhance; +package io.noties.enhance; import com.github.javaparser.JavaParser; import com.github.javaparser.ParseResult; @@ -13,8 +13,8 @@ import com.google.googlejavaformat.java.Formatter; import com.google.googlejavaformat.java.FormatterException; import com.google.googlejavaformat.java.JavaFormatterOptions; +import io.noties.enhance.options.SourceFormat; import org.apache.commons.io.FileUtils; -import ru.noties.enhance.options.SourceFormat; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -25,7 +25,7 @@ import java.util.ArrayList; import java.util.List; -import static ru.noties.enhance.Log.log; +import static io.noties.enhance.Log.log; class EnhanceWriterImpl extends EnhanceWriter { diff --git a/src/main/java/ru/noties/enhance/Log.java b/src/main/java/io/noties/enhance/Log.java similarity index 89% rename from src/main/java/ru/noties/enhance/Log.java rename to src/main/java/io/noties/enhance/Log.java index 25be5b8..f93f2fe 100644 --- a/src/main/java/ru/noties/enhance/Log.java +++ b/src/main/java/io/noties/enhance/Log.java @@ -1,4 +1,4 @@ -package ru.noties.enhance; +package io.noties.enhance; import javax.annotation.Nonnull; diff --git a/src/main/java/ru/noties/enhance/SdkHelper.java b/src/main/java/io/noties/enhance/SdkHelper.java similarity index 96% rename from src/main/java/ru/noties/enhance/SdkHelper.java rename to src/main/java/io/noties/enhance/SdkHelper.java index ca85563..a6c53fa 100644 --- a/src/main/java/ru/noties/enhance/SdkHelper.java +++ b/src/main/java/io/noties/enhance/SdkHelper.java @@ -1,6 +1,6 @@ -package ru.noties.enhance; +package io.noties.enhance; -import ru.noties.enhance.options.EnhanceOptions; +import io.noties.enhance.options.EnhanceOptions; import javax.annotation.Nonnull; import java.io.File; diff --git a/src/main/java/ru/noties/enhance/Stats.java b/src/main/java/io/noties/enhance/Stats.java similarity index 99% rename from src/main/java/ru/noties/enhance/Stats.java rename to src/main/java/io/noties/enhance/Stats.java index ad5b2d6..9f2b50d 100644 --- a/src/main/java/ru/noties/enhance/Stats.java +++ b/src/main/java/io/noties/enhance/Stats.java @@ -1,4 +1,4 @@ -package ru.noties.enhance; +package io.noties.enhance; import javax.annotation.Nonnull; import java.util.*; diff --git a/src/main/java/ru/noties/enhance/options/EnhanceOptions.java b/src/main/java/io/noties/enhance/options/EnhanceOptions.java similarity index 91% rename from src/main/java/ru/noties/enhance/options/EnhanceOptions.java rename to src/main/java/io/noties/enhance/options/EnhanceOptions.java index 56aac64..a2fa9e6 100644 --- a/src/main/java/ru/noties/enhance/options/EnhanceOptions.java +++ b/src/main/java/io/noties/enhance/options/EnhanceOptions.java @@ -1,4 +1,4 @@ -package ru.noties.enhance.options; +package io.noties.enhance.options; import javax.annotation.Nonnull; diff --git a/src/main/java/ru/noties/enhance/options/EnhanceOptionsImpl.java b/src/main/java/io/noties/enhance/options/EnhanceOptionsImpl.java similarity index 98% rename from src/main/java/ru/noties/enhance/options/EnhanceOptionsImpl.java rename to src/main/java/io/noties/enhance/options/EnhanceOptionsImpl.java index 2beabbd..ae23a3b 100644 --- a/src/main/java/ru/noties/enhance/options/EnhanceOptionsImpl.java +++ b/src/main/java/io/noties/enhance/options/EnhanceOptionsImpl.java @@ -1,4 +1,4 @@ -package ru.noties.enhance.options; +package io.noties.enhance.options; import org.apache.commons.cli.*; diff --git a/src/main/java/ru/noties/enhance/options/SourceFormat.java b/src/main/java/io/noties/enhance/options/SourceFormat.java similarity index 63% rename from src/main/java/ru/noties/enhance/options/SourceFormat.java rename to src/main/java/io/noties/enhance/options/SourceFormat.java index b20f152..2f601fb 100644 --- a/src/main/java/ru/noties/enhance/options/SourceFormat.java +++ b/src/main/java/io/noties/enhance/options/SourceFormat.java @@ -1,4 +1,4 @@ -package ru.noties.enhance.options; +package io.noties.enhance.options; public enum SourceFormat { NONE, diff --git a/src/test/java/ru/noties/enhance/ApiInfoStoreImplTest.java b/src/test/java/io/noties/enhance/ApiInfoStoreImplTest.java similarity index 93% rename from src/test/java/ru/noties/enhance/ApiInfoStoreImplTest.java rename to src/test/java/io/noties/enhance/ApiInfoStoreImplTest.java index 4bed200..ac346a8 100644 --- a/src/test/java/ru/noties/enhance/ApiInfoStoreImplTest.java +++ b/src/test/java/io/noties/enhance/ApiInfoStoreImplTest.java @@ -1,4 +1,4 @@ -package ru.noties.enhance; +package io.noties.enhance; import org.junit.Test; @@ -6,7 +6,7 @@ import java.util.Map; import static org.junit.Assert.assertEquals; -import static ru.noties.enhance.ApiInfoStoreImpl.Parser.normalizeMethodSignature; +import static io.noties.enhance.ApiInfoStoreImpl.Parser.normalizeMethodSignature; public class ApiInfoStoreImplTest { From ee470538e330cb30c6c843462e1a99e6806469bd Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Wed, 1 Nov 2023 14:45:23 +0100 Subject: [PATCH 2/4] Update writer for android-34 --- build.gradle | 8 +- src/main/java/io/noties/enhance/Api.java | 78 ++++++++++ .../java/io/noties/enhance/ApiVersion.java | 102 ++++++------- src/main/java/io/noties/enhance/Enhance.java | 11 +- .../java/io/noties/enhance/EnhanceWriter.java | 3 +- .../io/noties/enhance/EnhanceWriterImpl.java | 135 +++++++++++++++--- 6 files changed, 252 insertions(+), 85 deletions(-) create mode 100644 src/main/java/io/noties/enhance/Api.java diff --git a/build.gradle b/build.gradle index 762a1ae..8ea8e04 100644 --- a/build.gradle +++ b/build.gradle @@ -7,8 +7,8 @@ plugins { group 'io.noties' version '34' -sourceCompatibility = JavaVersion.VERSION_17 -targetCompatibility = JavaVersion.VERSION_17 +sourceCompatibility = JavaVersion.VERSION_11 +targetCompatibility = JavaVersion.VERSION_11 mainClassName = 'io.noties.enhance.Enhance' @@ -21,10 +21,10 @@ dependencies { implementation 'com.google.code.findbugs:jsr305:3.0.2' // https://github.com/javaparser/javaparser - implementation 'com.github.javaparser:javaparser-core:3.25.4' + implementation 'com.github.javaparser:javaparser-core:3.25.5' // https://github.com/google/google-java-format - implementation 'com.google.googlejavaformat:google-java-format:1.17.0' + implementation 'com.google.googlejavaformat:google-java-format:1.18.1' implementation 'commons-cli:commons-cli:1.4' implementation 'commons-io:commons-io:2.7' diff --git a/src/main/java/io/noties/enhance/Api.java b/src/main/java/io/noties/enhance/Api.java new file mode 100644 index 0000000..7c0c9b9 --- /dev/null +++ b/src/main/java/io/noties/enhance/Api.java @@ -0,0 +1,78 @@ +package io.noties.enhance; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +public enum Api { + SDK_1(1, "1.0", "(initial)"), + SDK_2(2, "1.1", "(initial)"), + SDK_3(3, "1.5", "Cupcake"), + SDK_4(4, "1.6", "Donut"), + SDK_5(5, "2.0", "Eclair"), + SDK_6(6, "2.0.1", "Eclair"), + SDK_7(7, "2.1", "Eclair"), + SDK_8(8, "2.2", "Froyo"), + SDK_9(9, "2.3", "Gingerbread"), + SDK_10(10, "2.3.3", "Gingerbread"), + SDK_11(11, "3.0", "Honeycomb"), + SDK_12(12, "3.1", "Honeycomb"), + SDK_13(13, "3.2", "Honeycomb"), + SDK_14(14, "4.0", "Ice Scream Sandwich"), + SDK_15(15, "4.0.3", "Ice Scream Sandwich"), + SDK_16(16, "4.1", "Jelly Bean"), + SDK_17(17, "4.2", "Jelly Bean"), + SDK_18(18, "4.3", "Jelly Bean"), + SDK_19(19, "4.4", "Kitkat"), + SDK_20(20, "4.4W", "Kitkat"), + SDK_21(21, "5.0", "Lollipop"), + SDK_22(22, "5.1", "Lollipop"), + SDK_23(23, "6.0", "Marshmallow"), + SDK_24(24, "7.0", "Nougat"), + SDK_25(25, "7.1", "Nougat"), + SDK_26(26, "8.0", "Oreo"), + SDK_27(27, "8.1", "Oreo"), + SDK_28(28, "9.0", "Pie"), + SDK_29(29, "10", "Android Q"), + SDK_30(30, "11", "Android R"), + SDK_31(31, "12", "Android S"), + SDK_32(32, "12", "Android S_V2"), + SDK_33(33, "13", "Tiramisu"), + SDK_34(34, "14", "Upside Down Cake"); + + public final int sdkInt; + public final String versionName; + public final String codeName; + + Api(int sdkInt, @Nonnull String versionName, @Nonnull String codeName) { + this.sdkInt = sdkInt; + this.versionName = versionName; + this.codeName = codeName; + } + + @Override + public String toString() { + return "Api.SDK{" + + "sdkInt=" + sdkInt + + ", versionName='" + versionName + '\'' + + ", codeName='" + codeName + '\'' + + '}'; + } + + private static final List VALUES = List.of(values()); + + @Nonnull + public static Api latest() { + return VALUES.get(VALUES.size() - 1); + } + + @Nullable + public static Api of(int sdkInt) { + for (Api api : VALUES) { + if (sdkInt == api.sdkInt) { + return api; + } + } + return null; + } +} diff --git a/src/main/java/io/noties/enhance/ApiVersion.java b/src/main/java/io/noties/enhance/ApiVersion.java index 20875f3..5473769 100644 --- a/src/main/java/io/noties/enhance/ApiVersion.java +++ b/src/main/java/io/noties/enhance/ApiVersion.java @@ -1,40 +1,51 @@ package io.noties.enhance; import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Objects; public class ApiVersion { @Nonnull public static ApiVersion latest() { - return VERSIONS[VERSIONS.length - 1]; + return new ApiVersion(Api.latest()); } @Nonnull public static ApiVersion of(int sdkInt) { - final ApiVersion version; - if (sdkInt < 0 - || (sdkInt - 1) >= LENGTH) { - version = new ApiVersion(sdkInt, "unknown", "unknown", true); + final Api api = Api.of(sdkInt); + final ApiVersion apiVersion; + if (api == null) { + apiVersion = new ApiVersion(sdkInt, "unknown", "unknown"); } else { - version = VERSIONS[sdkInt - 1]; + apiVersion = new ApiVersion(api); } - return version; + return apiVersion; } + @Nullable + private final Api api; private final int sdkInt; private final String versionName; private final String codeName; - private final boolean unknown; - private ApiVersion(int sdkInt, @Nonnull String versionName, @Nonnull String codeName) { - this(sdkInt, versionName, codeName, false); + private ApiVersion(@Nonnull Api api) { + this.api = api; + this.sdkInt = api.sdkInt; + this.versionName = api.versionName; + this.codeName = api.codeName; } - private ApiVersion(int sdkInt, @Nonnull String versionName, @Nonnull String codeName, boolean unknown) { + private ApiVersion(int sdkInt, @Nonnull String versionName, @Nonnull String codeName) { + this.api = null; this.sdkInt = sdkInt; this.versionName = versionName; this.codeName = codeName; - this.unknown = unknown; + } + + @Nullable + public Api api() { + return api; } public int getSdkInt() { @@ -52,55 +63,34 @@ public String getCodeName() { } public boolean isUnknown() { - return unknown; + return api == null; } @Override public String toString() { - return "ApiVersion{" + - "sdkInt=" + sdkInt + - ", versionName='" + versionName + '\'' + - ", codeName='" + codeName + '\'' + - ", unknown=" + unknown + - '}'; + if (api == null) { + return "ApiVersion{" + + "sdkInt=" + sdkInt + + ", versionName='" + versionName + '\'' + + ", codeName='" + codeName + '\'' + + '}'; + } else { + return "ApiVersion{" + + "api=" + api + + '}'; + } } - private static final ApiVersion[] VERSIONS = { - new ApiVersion(1, "1.0", "(initial)"), - new ApiVersion(2, "1.1", "(initial)"), - new ApiVersion(3, "1.5", "Cupcake"), - new ApiVersion(4, "1.6", "Donut"), - new ApiVersion(5, "2.0", "Eclair"), - new ApiVersion(6, "2.0.1", "Eclair"), - new ApiVersion(7, "2.1", "Eclair"), - new ApiVersion(8, "2.2", "Froyo"), - new ApiVersion(9, "2.3", "Gingerbread"), - new ApiVersion(10, "2.3.3", "Gingerbread"), - new ApiVersion(11, "3.0", "Honeycomb"), - new ApiVersion(12, "3.1", "Honeycomb"), - new ApiVersion(13, "3.2", "Honeycomb"), - new ApiVersion(14, "4.0", "Ice Scream Sandwich"), - new ApiVersion(15, "4.0.3", "Ice Scream Sandwich"), - new ApiVersion(16, "4.1", "Jelly Bean"), - new ApiVersion(17, "4.2", "Jelly Bean"), - new ApiVersion(18, "4.3", "Jelly Bean"), - new ApiVersion(19, "4.4", "Kitkat"), - new ApiVersion(20, "4.4W", "Kitkat"), - new ApiVersion(21, "5.0", "Lollipop"), - new ApiVersion(22, "5.1", "Lollipop"), - new ApiVersion(23, "6.0", "Marshmallow"), - new ApiVersion(24, "7.0", "Nougat"), - new ApiVersion(25, "7.1", "Nougat"), - new ApiVersion(26, "8.0", "Oreo"), - new ApiVersion(27, "8.1", "Oreo"), - new ApiVersion(28, "9.0", "Pie"), - new ApiVersion(29, "10", "Android Q"), - new ApiVersion(30, "11", "Android R"), - new ApiVersion(31, "12", "Android S"), - new ApiVersion(32, "12", "Android S_V2"), - new ApiVersion(33, "13", "Tiramisu"), - new ApiVersion(34, "14", "Upside Down Cake") - }; + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ApiVersion that = (ApiVersion) o; + return sdkInt == that.sdkInt; + } - private static final int LENGTH = VERSIONS.length; + @Override + public int hashCode() { + return Objects.hash(sdkInt); + } } diff --git a/src/main/java/io/noties/enhance/Enhance.java b/src/main/java/io/noties/enhance/Enhance.java index 0b8276e..8dd98bf 100644 --- a/src/main/java/io/noties/enhance/Enhance.java +++ b/src/main/java/io/noties/enhance/Enhance.java @@ -1,7 +1,7 @@ package io.noties.enhance; -import org.apache.commons.io.FileUtils; import io.noties.enhance.options.EnhanceOptions; +import org.apache.commons.io.FileUtils; import javax.annotation.Nonnull; import java.io.BufferedReader; @@ -22,7 +22,7 @@ public static void main(String[] args) { final ApiVersionFormatter apiVersionFormatter = ApiVersionFormatter.create(); log("[Enhance] version: %s", EnhanceVersion.NAME); - log("[Enhance] latest SDK version: %s", apiVersionFormatter.format(ApiVersion.latest())); + log("[Enhance] latest Android SDK version: %s", apiVersionFormatter.format(ApiVersion.latest())); log("[Enhance] https://github.com/noties/Enhance"); final EnhanceOptions options = EnhanceOptions.create(args); @@ -128,7 +128,12 @@ public static void main(String[] args) { log("[Enhance] processing source files"); - final EnhanceWriter writer = EnhanceWriter.create(options.sourceFormat(), store, apiVersionFormatter); + final EnhanceWriter writer = EnhanceWriter.create( + apiVersion, + options.sourceFormat(), + store, + apiVersionFormatter + ); writer.write(source, sdkSources); final long took = System.currentTimeMillis() - start; diff --git a/src/main/java/io/noties/enhance/EnhanceWriter.java b/src/main/java/io/noties/enhance/EnhanceWriter.java index 0fdc46e..e5b8a7e 100644 --- a/src/main/java/io/noties/enhance/EnhanceWriter.java +++ b/src/main/java/io/noties/enhance/EnhanceWriter.java @@ -9,11 +9,12 @@ public abstract class EnhanceWriter { @Nonnull public static EnhanceWriter create( + @Nonnull ApiVersion apiVersion, @Nonnull SourceFormat format, @Nonnull ApiInfoStore apiInfoStore, @Nonnull ApiVersionFormatter apiVersionFormatter ) { - return new EnhanceWriterImpl(format, apiInfoStore, apiVersionFormatter); + return new EnhanceWriterImpl(apiVersion, format, apiInfoStore, apiVersionFormatter); } public abstract void write(@Nonnull File source, @Nonnull File destination); diff --git a/src/main/java/io/noties/enhance/EnhanceWriterImpl.java b/src/main/java/io/noties/enhance/EnhanceWriterImpl.java index 955573e..5f5b5aa 100644 --- a/src/main/java/io/noties/enhance/EnhanceWriterImpl.java +++ b/src/main/java/io/noties/enhance/EnhanceWriterImpl.java @@ -2,6 +2,7 @@ import com.github.javaparser.JavaParser; import com.github.javaparser.ParseResult; +import com.github.javaparser.ParserConfiguration; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.PackageDeclaration; @@ -34,22 +35,54 @@ private interface SourceFormatter { String format(@Nonnull String source); } + @Nullable private final SourceFormatter sourceFormatter; + + @Nonnull private final ApiInfoStore apiInfoStore; + + @Nonnull private final ApiVersionFormatter apiVersionFormatter; - private final JavaParser javaParser = new JavaParser(); + // Android 34 should have been compiled with Java-17, but some sources + // contain java-17 keywords: `sealed` and `permits` as variable names + @Nonnull + private final JavaParser javaParser17; + + @Nonnull + private final JavaParser javaParser11; + + private final boolean isJava17; - EnhanceWriterImpl(@Nonnull SourceFormat format, @Nonnull ApiInfoStore apiInfoStore, @Nonnull ApiVersionFormatter apiVersionFormatter) { + EnhanceWriterImpl( + @Nonnull ApiVersion apiVersion, + @Nonnull SourceFormat format, + @Nonnull ApiInfoStore apiInfoStore, + @Nonnull ApiVersionFormatter apiVersionFormatter + ) { this.sourceFormatter = sourceFormatter(format); this.apiInfoStore = apiInfoStore; this.apiVersionFormatter = apiVersionFormatter; + + this.javaParser17 = new JavaParser(new ParserConfiguration().setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_17)); + this.javaParser11 = new JavaParser(new ParserConfiguration().setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_11)); + + final int sdk = apiVersion.getSdkInt(); + this.isJava17 = sdk >= Api.SDK_34.sdkInt; } @Override public void write(@Nonnull File source, @Nonnull File destination) { + write("", source, destination); + } + private void write( + @Nonnull String path, + @Nonnull File source, + @Nonnull File destination + ) { final File[] files = source.listFiles(); + //noinspection RedundantLengthCheck if (files == null || files.length == 0) { return; @@ -64,51 +97,77 @@ public void write(@Nonnull File source, @Nonnull File destination) { throw new RuntimeException("Cannot create folder: " + folder.getPath()); } - write(file, folder); + write( + path + "/" + file.getName(), + file, + folder + ); } else { final String name = file.getName(); final File f = new File(destination, name); - // @since 1.0.3 there are also `*.annotated.java` files, ignore them - if (name.endsWith(".java") - && !name.endsWith(".annotated.java")) { + log("[Enhance] path:'%s' name:'%s'", path, name); + if (isJavaFileToProcess(path, name)) { final String java = processJavaFile(file); try { FileUtils.write(f, java, StandardCharsets.UTF_8); } catch (IOException e) { - throw new RuntimeException(e); + throw new RuntimeException( + "Error writing file:'" + name + "' at path:'" + path + "'", + e + ); } - } else { + log("[Enhance] copy file: %s", file.getPath()); try { FileUtils.copyFile(file, f); } catch (IOException e) { - throw new RuntimeException(e); + throw new RuntimeException( + "Error copying file:'" + name + "' at path:'" + path + "'", + e + ); } } } } } + private boolean isJavaFileToProcess(@Nonnull String path, @Nonnull String name) { + // @since 1.0.3 there are also `*.annotated.java` files, ignore them + return name.endsWith(".java") && !name.endsWith(".annotated.java"); + } + @Nonnull private String processJavaFile(@Nonnull File file) { log("[Enhance] processing java source file: %s", file.getPath()); final CompilationUnit unit; - try { - final ParseResult result = javaParser.parse(file); - if (result.isSuccessful()) { - //noinspection OptionalGetWithoutIsPresent - unit = result.getResult().get(); - } else { - throw new RuntimeException(result.toString()); + if (isJava17) { + + // first try parsing with java-17 and then fallback to java-11 + // this is done because, even though android-34 should be compiled with java-17 + // there are classes that contain illegal variable names: `sealed` and `permits` + CompilationUnit compilationUnit = null; + try { + compilationUnit = compile(javaParser17, file); + } catch (Throwable t) { + log("[Enhance] Exception parsing with java-17"); + //noinspection CallToPrintStackTrace + t.printStackTrace(); } - } catch (FileNotFoundException e) { - throw new RuntimeException(e); + + if (compilationUnit == null) { + compilationUnit = compile(javaParser11, file); + } + + unit = compilationUnit; + + } else { + unit = compile(javaParser11, file); } unit.accept(new ApiInfoVisitor(apiVersionFormatter), apiInfoStore); @@ -135,6 +194,23 @@ private String processJavaFile(@Nonnull File file) { return out; } + @Nonnull + private static CompilationUnit compile(@Nonnull JavaParser javaParser, @Nonnull File file) { + final CompilationUnit unit; + try { + final ParseResult result = javaParser.parse(file); + if (result.isSuccessful()) { + //noinspection OptionalGetWithoutIsPresent + unit = result.getResult().get(); + } else { + throw new RuntimeException(result.toString()); + } + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + return unit; + } + private static class ApiInfoVisitor extends VoidVisitorAdapter { private final ApiVersionFormatter formatter; @@ -245,7 +321,7 @@ private String typeName(@Nonnull TypeDeclaration typeDeclaration) { } else { final StringBuilder builder = new StringBuilder(); builder.append(typeDeclaration.getNameAsString()); - TypeDeclaration parent = parentTypeDeclaration(typeDeclaration); + TypeDeclaration parent = parentTypeDeclaration(typeDeclaration); while (parent != null) { builder.insert(0, '$'); builder.insert(0, parent.getNameAsString()); @@ -258,13 +334,30 @@ private String typeName(@Nonnull TypeDeclaration typeDeclaration) { } @Nullable - private static TypeDeclaration parentTypeDeclaration(@Nonnull TypeDeclaration typeDeclaration) { - return (TypeDeclaration) typeDeclaration.getParentNode() + private static TypeDeclaration parentTypeDeclaration(@Nonnull TypeDeclaration typeDeclaration) { + return (TypeDeclaration) typeDeclaration.getParentNode() .filter(node -> node instanceof TypeDeclaration) .orElse(null); } } + // Unfortunately java-parser printer is a little weird and does not give enough options + // to format the code +// @Nonnull +// private static Printer createDefaultPrinter(int indent) { +// final PrinterConfiguration configuration = new DefaultPrinterConfiguration() +// .addOption(new DefaultConfigurationOption(DefaultPrinterConfiguration.ConfigOption.INDENTATION, new Indentation(Indentation.IndentType.SPACES, indent))) +// .addOption(new DefaultConfigurationOption(DefaultPrinterConfiguration.ConfigOption.ORDER_IMPORTS, Boolean.TRUE)) +// .addOption(new DefaultConfigurationOption(DefaultPrinterConfiguration.ConfigOption.SORT_IMPORTS_STRATEGY, new IntelliJImportOrderingStrategy())) +// .addOption(new DefaultConfigurationOption(DefaultPrinterConfiguration.ConfigOption.PRINT_COMMENTS, Boolean.TRUE)) +// .addOption(new DefaultConfigurationOption(DefaultPrinterConfiguration.ConfigOption.PRINT_JAVADOC, Boolean.TRUE)) +// .addOption(new DefaultConfigurationOption(DefaultPrinterConfiguration.ConfigOption.COLUMN_ALIGN_PARAMETERS, Boolean.FALSE)) +// .addOption(new DefaultConfigurationOption(DefaultPrinterConfiguration.ConfigOption.COLUMN_ALIGN_FIRST_METHOD_CHAIN, Boolean.FALSE)) +// .addOption(new DefaultConfigurationOption(DefaultPrinterConfiguration.ConfigOption.INDENT_CASE_IN_SWITCH, Boolean.FALSE)) +// .addOption(new DefaultConfigurationOption(DefaultPrinterConfiguration.ConfigOption.MAX_ENUM_CONSTANTS_TO_ALIGN_HORIZONTALLY, 1)); +// return new DefaultPrettyPrinter(configuration); +// } + @Nullable private static SourceFormatter sourceFormatter(@Nonnull SourceFormat format) { From eaac75422361cd2d1eaa0b6d4e2b5252902895e0 Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Wed, 1 Nov 2023 16:28:01 +0100 Subject: [PATCH 3/4] Update api sdk version handling --- .run/Enhance.run.xml | 17 +++ README.md | 16 +++ build.gradle | 10 +- src/main/java/io/noties/enhance/Api.java | 15 ++- src/main/java/io/noties/enhance/ApiInfo.java | 9 +- .../java/io/noties/enhance/ApiInfoStore.java | 4 +- .../io/noties/enhance/ApiInfoStoreImpl.java | 34 +++--- .../java/io/noties/enhance/ApiVersion.java | 96 --------------- .../noties/enhance/ApiVersionFormatter.java | 15 ++- src/main/java/io/noties/enhance/Enhance.java | 22 ++-- .../java/io/noties/enhance/EnhanceWriter.java | 4 +- .../io/noties/enhance/EnhanceWriterImpl.java | 111 +++++++++++------- src/main/java/io/noties/enhance/Stats.java | 14 +-- src/test/java/io/noties/enhance/ApiTest.java | 57 +++++++++ 14 files changed, 221 insertions(+), 203 deletions(-) create mode 100644 .run/Enhance.run.xml delete mode 100644 src/main/java/io/noties/enhance/ApiVersion.java create mode 100644 src/test/java/io/noties/enhance/ApiTest.java diff --git a/.run/Enhance.run.xml b/.run/Enhance.run.xml new file mode 100644 index 0000000..4980299 --- /dev/null +++ b/.run/Enhance.run.xml @@ -0,0 +1,17 @@ + + + + \ No newline at end of file diff --git a/README.md b/README.md index 92fd5aa..0f89da4 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,22 @@ java -jar enhance.jar -sdk 26 -sp "/Users/not_me/android/sdk" If you would like to restore unmodified copy of source code you can find it: `{your-home-directory}/.enhance-backup/android-{sdk}` +## Formatting on JDK 17 +Formatting is done with the [google-java-format](https://github.com/google/google-java-format) library +which requires access to the internals of the JDK. This is why on JDK-17 in order to format +the sources additional commandline arguments are required: + +```bash +java \ + --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ + --add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \ + --add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \ + --add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ + --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ + --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ + -jar enhance-34-all.jar -sdk 34 -format google +``` + ## Thanks Big kudos to the maintainers of amazing [javaparser](https://github.com/javaparser/javaparser)! diff --git a/build.gradle b/build.gradle index 8ea8e04..008377c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,5 @@ plugins { + // https://github.com/johnrengelman/shadow id 'com.github.johnrengelman.shadow' version '7.1.2' id 'java' id 'application' @@ -52,12 +53,3 @@ class EnhanceVersion { static final String NAME = \"${version}\"; } sourceSets { main.java.srcDirs += new File(rootDir, 'gen') } - -compileJava { - options.compilerArgs += '--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED' - options.compilerArgs += '--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED' - options.compilerArgs += '--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED' - options.compilerArgs += '--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED' - options.compilerArgs += '--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED' - options.compilerArgs += '--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED' -} diff --git a/src/main/java/io/noties/enhance/Api.java b/src/main/java/io/noties/enhance/Api.java index 7c0c9b9..f9e037c 100644 --- a/src/main/java/io/noties/enhance/Api.java +++ b/src/main/java/io/noties/enhance/Api.java @@ -2,6 +2,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.EnumMap; import java.util.List; public enum Api { @@ -38,7 +39,8 @@ public enum Api { SDK_31(31, "12", "Android S"), SDK_32(32, "12", "Android S_V2"), SDK_33(33, "13", "Tiramisu"), - SDK_34(34, "14", "Upside Down Cake"); + SDK_34(34, "14", "Upside Down Cake") + ; public final int sdkInt; public final String versionName; @@ -68,11 +70,12 @@ public static Api latest() { @Nullable public static Api of(int sdkInt) { - for (Api api : VALUES) { - if (sdkInt == api.sdkInt) { - return api; - } + // NB! we assume that it starts at 1 + // so, SDK_1 is at 0, SDK_2 at 1, etc + final int ordinal = sdkInt - 1; + if (ordinal < 0 || ordinal >= VALUES.size()) { + return null; } - return null; + return VALUES.get(ordinal); } } diff --git a/src/main/java/io/noties/enhance/ApiInfo.java b/src/main/java/io/noties/enhance/ApiInfo.java index ce8416e..b41bea5 100644 --- a/src/main/java/io/noties/enhance/ApiInfo.java +++ b/src/main/java/io/noties/enhance/ApiInfo.java @@ -1,11 +1,14 @@ package io.noties.enhance; +import javax.annotation.Nullable; + public class ApiInfo { - public final ApiVersion since; - public final ApiVersion deprecated; + @Nullable + public final Integer since; + @Nullable public final Integer deprecated; - public ApiInfo(ApiVersion since, ApiVersion deprecated) { + public ApiInfo(@Nullable Integer since, @Nullable Integer deprecated) { this.since = since; this.deprecated = deprecated; } diff --git a/src/main/java/io/noties/enhance/ApiInfoStore.java b/src/main/java/io/noties/enhance/ApiInfoStore.java index a1f8e3d..43540bb 100644 --- a/src/main/java/io/noties/enhance/ApiInfoStore.java +++ b/src/main/java/io/noties/enhance/ApiInfoStore.java @@ -13,12 +13,12 @@ public static ApiInfoStore create(@Nonnull File apiVersions) { return new ApiInfoStoreImpl(apiVersions); } - static class TypeVersion extends ApiInfo { + public static class TypeVersion extends ApiInfo { final Map fields = new HashMap<>(3); final Map methods = new HashMap<>(3); - TypeVersion(ApiVersion since, ApiVersion deprecated) { + TypeVersion(@Nullable Integer since, @Nullable Integer deprecated) { super(since, deprecated); } } diff --git a/src/main/java/io/noties/enhance/ApiInfoStoreImpl.java b/src/main/java/io/noties/enhance/ApiInfoStoreImpl.java index 2f77297..b7474c8 100644 --- a/src/main/java/io/noties/enhance/ApiInfoStoreImpl.java +++ b/src/main/java/io/noties/enhance/ApiInfoStoreImpl.java @@ -156,8 +156,8 @@ private static void methods(@Nonnull TypeVersion version, @Nonnull Element paren private static boolean isEmpty(@Nonnull TypeVersion version) { return version.since == null && version.deprecated == null - && version.fields.size() == 0 - && version.methods.size() == 0; + && version.fields.isEmpty() + && version.methods.isEmpty(); } @Nullable @@ -165,8 +165,8 @@ private static ApiInfo apiInfo(@Nonnull Element element) { final ApiInfo apiInfo; - final ApiVersion since = apiVersion(element.getAttribute(SINCE)); - final ApiVersion deprecated = apiVersion(element.getAttribute(DEPRECATED)); + final Integer since = apiVersion(element.getAttribute(SINCE)); + final Integer deprecated = apiVersion(element.getAttribute(DEPRECATED)); if (since == null && deprecated == null) { @@ -179,21 +179,19 @@ private static ApiInfo apiInfo(@Nonnull Element element) { } @Nullable - private static ApiVersion apiVersion(@Nullable String value) { - final ApiVersion version; - if (value == null - || value.length() == 0) { - version = null; - } else { - int sdk; - try { - sdk = Integer.parseInt(value); - } catch (NumberFormatException e) { - sdk = 0; - } - version = ApiVersion.of(sdk); + private static Integer apiVersion(@Nullable String value) { + if (value == null || value.isEmpty()) { + return null; + } + + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + //noinspection CallToPrintStackTrace + e.printStackTrace(); } - return version; + + return null; } private static final Pattern RE = Pattern.compile("L\\w+[/\\w]+[/$](\\w+);"); diff --git a/src/main/java/io/noties/enhance/ApiVersion.java b/src/main/java/io/noties/enhance/ApiVersion.java deleted file mode 100644 index 5473769..0000000 --- a/src/main/java/io/noties/enhance/ApiVersion.java +++ /dev/null @@ -1,96 +0,0 @@ -package io.noties.enhance; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.Objects; - -public class ApiVersion { - - @Nonnull - public static ApiVersion latest() { - return new ApiVersion(Api.latest()); - } - - @Nonnull - public static ApiVersion of(int sdkInt) { - final Api api = Api.of(sdkInt); - final ApiVersion apiVersion; - if (api == null) { - apiVersion = new ApiVersion(sdkInt, "unknown", "unknown"); - } else { - apiVersion = new ApiVersion(api); - } - return apiVersion; - } - - @Nullable - private final Api api; - private final int sdkInt; - private final String versionName; - private final String codeName; - - private ApiVersion(@Nonnull Api api) { - this.api = api; - this.sdkInt = api.sdkInt; - this.versionName = api.versionName; - this.codeName = api.codeName; - } - - private ApiVersion(int sdkInt, @Nonnull String versionName, @Nonnull String codeName) { - this.api = null; - this.sdkInt = sdkInt; - this.versionName = versionName; - this.codeName = codeName; - } - - @Nullable - public Api api() { - return api; - } - - public int getSdkInt() { - return sdkInt; - } - - @Nonnull - public String getVersionName() { - return versionName; - } - - @Nonnull - public String getCodeName() { - return codeName; - } - - public boolean isUnknown() { - return api == null; - } - - @Override - public String toString() { - if (api == null) { - return "ApiVersion{" + - "sdkInt=" + sdkInt + - ", versionName='" + versionName + '\'' + - ", codeName='" + codeName + '\'' + - '}'; - } else { - return "ApiVersion{" + - "api=" + api + - '}'; - } - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ApiVersion that = (ApiVersion) o; - return sdkInt == that.sdkInt; - } - - @Override - public int hashCode() { - return Objects.hash(sdkInt); - } -} diff --git a/src/main/java/io/noties/enhance/ApiVersionFormatter.java b/src/main/java/io/noties/enhance/ApiVersionFormatter.java index 2811da1..a1d0dda 100644 --- a/src/main/java/io/noties/enhance/ApiVersionFormatter.java +++ b/src/main/java/io/noties/enhance/ApiVersionFormatter.java @@ -9,16 +9,21 @@ public static ApiVersionFormatter create() { return new Impl(); } - - public abstract String format(@Nonnull ApiVersion apiVersion); + @Nonnull + public abstract String format(int version); private static class Impl extends ApiVersionFormatter { + @Nonnull @Override - public String format(@Nonnull ApiVersion apiVersion) { - // for example - @since 5.1 Lollipop (22) - return apiVersion.getVersionName() + " " + apiVersion.getCodeName() + " (" + apiVersion.getSdkInt() + ")"; + public String format(int version) { + final Api api = Api.of(version); + if (api != null) { + // for example - @since 5.1 Lollipop (22) + return api.versionName + " " + api.codeName + " (" + api.sdkInt + ")"; + } + return "unknown (" + version + ")"; } } } diff --git a/src/main/java/io/noties/enhance/Enhance.java b/src/main/java/io/noties/enhance/Enhance.java index 8dd98bf..7a1942b 100644 --- a/src/main/java/io/noties/enhance/Enhance.java +++ b/src/main/java/io/noties/enhance/Enhance.java @@ -22,7 +22,7 @@ public static void main(String[] args) { final ApiVersionFormatter apiVersionFormatter = ApiVersionFormatter.create(); log("[Enhance] version: %s", EnhanceVersion.NAME); - log("[Enhance] latest Android SDK version: %s", apiVersionFormatter.format(ApiVersion.latest())); + log("[Enhance] latest Android SDK version: %s", apiVersionFormatter.format(Api.latest().sdkInt)); log("[Enhance] https://github.com/noties/Enhance"); final EnhanceOptions options = EnhanceOptions.create(args); @@ -30,12 +30,13 @@ public static void main(String[] args) { // @since 1.0.2 // check if we have this version info included and ask user if he/she want to proceed if // supplied sdk is not known to this library version - final ApiVersion apiVersion = ApiVersion.of(options.sdk()); - if (apiVersion.isUnknown()) { + final int sdk = options.sdk(); + final Api api = Api.of(sdk); - System.err.printf(Locale.US, "[Enhance] WARNING: specified SDK version %d (`%s`) is unknown to this " + - "library version, do you wish to proceed anyway? (Y|N)%n", options.sdk(), - apiVersionFormatter.format(apiVersion)); + if (api == null) { + + System.err.printf(Locale.US, "[Enhance] WARNING: specified SDK version %d is unknown to this " + + "library version, do you wish to proceed anyway? (Y|N)%n", sdk); try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { final String line = reader.readLine(); @@ -66,11 +67,8 @@ public static void main(String[] args) { final ApiInfoStore store = ApiInfoStore.create(sdkHelper.apiVersions()); if (options.emitDiff()) { - log("[Enhance] emit diff for %d SDK level (%s %s)", - apiVersion.getSdkInt(), - apiVersion.getCodeName(), - apiVersion.getVersionName()); - printStatsFor(apiVersion, store.info()); + log("[Enhance] emit diff for api:%s", api != null ? api : sdk); + printStatsFor(sdk, store.info()); return; } @@ -129,7 +127,7 @@ public static void main(String[] args) { log("[Enhance] processing source files"); final EnhanceWriter writer = EnhanceWriter.create( - apiVersion, + sdk, options.sourceFormat(), store, apiVersionFormatter diff --git a/src/main/java/io/noties/enhance/EnhanceWriter.java b/src/main/java/io/noties/enhance/EnhanceWriter.java index e5b8a7e..3dee42e 100644 --- a/src/main/java/io/noties/enhance/EnhanceWriter.java +++ b/src/main/java/io/noties/enhance/EnhanceWriter.java @@ -9,12 +9,12 @@ public abstract class EnhanceWriter { @Nonnull public static EnhanceWriter create( - @Nonnull ApiVersion apiVersion, + int sdk, @Nonnull SourceFormat format, @Nonnull ApiInfoStore apiInfoStore, @Nonnull ApiVersionFormatter apiVersionFormatter ) { - return new EnhanceWriterImpl(apiVersion, format, apiInfoStore, apiVersionFormatter); + return new EnhanceWriterImpl(sdk, format, apiInfoStore, apiVersionFormatter); } public abstract void write(@Nonnull File source, @Nonnull File destination); diff --git a/src/main/java/io/noties/enhance/EnhanceWriterImpl.java b/src/main/java/io/noties/enhance/EnhanceWriterImpl.java index 5f5b5aa..7b6f888 100644 --- a/src/main/java/io/noties/enhance/EnhanceWriterImpl.java +++ b/src/main/java/io/noties/enhance/EnhanceWriterImpl.java @@ -30,11 +30,19 @@ class EnhanceWriterImpl extends EnhanceWriter { + private interface Parser { + @Nonnull + CompilationUnit parse(@Nonnull File file); + } + private interface SourceFormatter { @Nonnull String format(@Nonnull String source); } + @Nonnull + private final Parser parser; + @Nullable private final SourceFormatter sourceFormatter; @@ -44,31 +52,17 @@ private interface SourceFormatter { @Nonnull private final ApiVersionFormatter apiVersionFormatter; - // Android 34 should have been compiled with Java-17, but some sources - // contain java-17 keywords: `sealed` and `permits` as variable names - @Nonnull - private final JavaParser javaParser17; - - @Nonnull - private final JavaParser javaParser11; - - private final boolean isJava17; - EnhanceWriterImpl( - @Nonnull ApiVersion apiVersion, + int sdk, @Nonnull SourceFormat format, @Nonnull ApiInfoStore apiInfoStore, @Nonnull ApiVersionFormatter apiVersionFormatter ) { + this.parser = sdk >= Api.SDK_34.sdkInt ? new Parser17() : new Parser11(); + this.sourceFormatter = sourceFormatter(format); this.apiInfoStore = apiInfoStore; this.apiVersionFormatter = apiVersionFormatter; - - this.javaParser17 = new JavaParser(new ParserConfiguration().setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_17)); - this.javaParser11 = new JavaParser(new ParserConfiguration().setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_11)); - - final int sdk = apiVersion.getSdkInt(); - this.isJava17 = sdk >= Api.SDK_34.sdkInt; } @Override @@ -76,6 +70,7 @@ public void write(@Nonnull File source, @Nonnull File destination) { write("", source, destination); } + // `path` could be used in future if some files would be processed differently private void write( @Nonnull String path, @Nonnull File source, @@ -110,7 +105,7 @@ private void write( log("[Enhance] path:'%s' name:'%s'", path, name); - if (isJavaFileToProcess(path, name)) { + if (isJavaFileToProcess(name)) { final String java = processJavaFile(file); try { FileUtils.write(f, java, StandardCharsets.UTF_8); @@ -135,7 +130,7 @@ private void write( } } - private boolean isJavaFileToProcess(@Nonnull String path, @Nonnull String name) { + private boolean isJavaFileToProcess(@Nonnull String name) { // @since 1.0.3 there are also `*.annotated.java` files, ignore them return name.endsWith(".java") && !name.endsWith(".annotated.java"); } @@ -145,30 +140,7 @@ private String processJavaFile(@Nonnull File file) { log("[Enhance] processing java source file: %s", file.getPath()); - final CompilationUnit unit; - if (isJava17) { - - // first try parsing with java-17 and then fallback to java-11 - // this is done because, even though android-34 should be compiled with java-17 - // there are classes that contain illegal variable names: `sealed` and `permits` - CompilationUnit compilationUnit = null; - try { - compilationUnit = compile(javaParser17, file); - } catch (Throwable t) { - log("[Enhance] Exception parsing with java-17"); - //noinspection CallToPrintStackTrace - t.printStackTrace(); - } - - if (compilationUnit == null) { - compilationUnit = compile(javaParser11, file); - } - - unit = compilationUnit; - - } else { - unit = compile(javaParser11, file); - } + final CompilationUnit unit = parser.parse(file); unit.accept(new ApiInfoVisitor(apiVersionFormatter), apiInfoStore); @@ -358,6 +330,59 @@ private static TypeDeclaration parentTypeDeclaration(@Nonnull TypeDeclaration // return new DefaultPrettyPrinter(configuration); // } + private static class Parser11 implements Parser { + + private final JavaParser javaParser11 = new JavaParser(new ParserConfiguration().setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_11)); + + @Nonnull + @Override + public CompilationUnit parse(@Nonnull File file) { + final CompilationUnit unit; + try { + final ParseResult result = javaParser11.parse(file); + if (result.isSuccessful()) { + //noinspection OptionalGetWithoutIsPresent + unit = result.getResult().get(); + } else { + throw new RuntimeException(result.toString()); + } + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + return unit; + } + } + + // Android 34 should have been compiled with Java-17, but some sources + // contain java-17 keywords: `sealed` and `permits` as variable names + private static class Parser17 extends Parser11 { + + private final JavaParser javaParser17 = new JavaParser(new ParserConfiguration().setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_17)); + + @Nonnull + @Override + public CompilationUnit parse(@Nonnull File file) { + + // first try parsing with java-17 and then fallback to java-11 + // this is done because, even though android-34 should be compiled with java-17 + // there are classes that contain illegal variable names: `sealed` and `permits` + CompilationUnit compilationUnit = null; + try { + compilationUnit = compile(javaParser17, file); + } catch (Throwable t) { + log("[Enhance] Exception parsing with java-17"); + //noinspection CallToPrintStackTrace + t.printStackTrace(); + } + + if (compilationUnit == null) { + compilationUnit = super.parse(file); + } + + return compilationUnit; + } + } + @Nullable private static SourceFormatter sourceFormatter(@Nonnull SourceFormat format) { diff --git a/src/main/java/io/noties/enhance/Stats.java b/src/main/java/io/noties/enhance/Stats.java index 9f2b50d..b4d767c 100644 --- a/src/main/java/io/noties/enhance/Stats.java +++ b/src/main/java/io/noties/enhance/Stats.java @@ -5,7 +5,7 @@ abstract class Stats { - static void printStatsFor(@Nonnull ApiVersion version, @Nonnull Map info) { + static void printStatsFor(@Nonnull Integer version, @Nonnull Map info) { // filter final Map filtered = new HashMap<>(); @@ -28,7 +28,7 @@ static void printStatsFor(@Nonnull ApiVersion version, @Nonnull Map 0 || typeVersion.methods.size() > 0)) { + || (!typeVersion.fields.isEmpty() || !typeVersion.methods.isEmpty())) { filtered.put(types.getKey(), typeVersion); } } @@ -69,8 +69,8 @@ static void printStatsFor(@Nonnull ApiVersion version, @Nonnull Map sorted(@Nonnull Collection collection) { @@ -81,19 +81,19 @@ private static List sorted(@Nonnull Collection collection) { private static boolean appendDiffed( @Nonnull StringBuilder builder, - @Nonnull ApiVersion version, + @Nonnull Integer version, @Nonnull ApiInfo info) { // priority for deprecated (some nodes are both added and deprecated in the same version) boolean result = false; - if (version == info.deprecated) { + if (version.equals(info.deprecated)) { builder.append('-'); result = true; } - if (version == info.since) { + if (version.equals(info.since)) { builder.append('+'); result = true; } diff --git a/src/test/java/io/noties/enhance/ApiTest.java b/src/test/java/io/noties/enhance/ApiTest.java new file mode 100644 index 0000000..ff79396 --- /dev/null +++ b/src/test/java/io/noties/enhance/ApiTest.java @@ -0,0 +1,57 @@ +package io.noties.enhance; + +import org.checkerframework.checker.units.qual.A; +import org.junit.Assert; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class ApiTest { + + @Test + public void testOf() { + final int length = Api.values().length; + // index starts at 0, but values start at 1 + for (int i = 1, max = length + 1; i < max; i++) { + final Api api = Api.of(i); + assertNotNull(String.valueOf(i), api); + assertEquals(String.valueOf(i), i, api.sdkInt); + } + } + + @Test + public void testUnknown() { + final Api[] values = Api.values(); + final int max = values[values.length - 1].sdkInt; + + final int[] inputs = { + Integer.MIN_VALUE, + -1, + 0, + max + 1, + max + 2, + Integer.MAX_VALUE + }; + + for (int input: inputs) { + assertNull(String.valueOf(input), Api.of(input)); + } + } + + @Test + public void testSequential() { + final Api[] values = Api.values(); + + // verify all go without interruption from 1 to max + assertEquals(1, values[0].sdkInt); + + for (int i = 1, length = values.length; i < length; i++) { + final Api api = values[i]; + assertEquals( + "i:" + i + ", api:" + api, + values[i - 1].sdkInt + 1, + api.sdkInt + ); + } + } +} \ No newline at end of file From 24f76bf190a4b606bd0474e995e424f73d32f7c3 Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Wed, 1 Nov 2023 16:34:42 +0100 Subject: [PATCH 4/4] Update writer --- .../io/noties/enhance/EnhanceWriterImpl.java | 26 +++++-------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/src/main/java/io/noties/enhance/EnhanceWriterImpl.java b/src/main/java/io/noties/enhance/EnhanceWriterImpl.java index 7b6f888..5ff78a7 100644 --- a/src/main/java/io/noties/enhance/EnhanceWriterImpl.java +++ b/src/main/java/io/noties/enhance/EnhanceWriterImpl.java @@ -166,23 +166,6 @@ private String processJavaFile(@Nonnull File file) { return out; } - @Nonnull - private static CompilationUnit compile(@Nonnull JavaParser javaParser, @Nonnull File file) { - final CompilationUnit unit; - try { - final ParseResult result = javaParser.parse(file); - if (result.isSuccessful()) { - //noinspection OptionalGetWithoutIsPresent - unit = result.getResult().get(); - } else { - throw new RuntimeException(result.toString()); - } - } catch (FileNotFoundException e) { - throw new RuntimeException(e); - } - return unit; - } - private static class ApiInfoVisitor extends VoidVisitorAdapter { private final ApiVersionFormatter formatter; @@ -337,9 +320,14 @@ private static class Parser11 implements Parser { @Nonnull @Override public CompilationUnit parse(@Nonnull File file) { + return parse(javaParser11, file); + } + + @Nonnull + protected static CompilationUnit parse(@Nonnull JavaParser javaParser, @Nonnull File file) { final CompilationUnit unit; try { - final ParseResult result = javaParser11.parse(file); + final ParseResult result = javaParser.parse(file); if (result.isSuccessful()) { //noinspection OptionalGetWithoutIsPresent unit = result.getResult().get(); @@ -368,7 +356,7 @@ public CompilationUnit parse(@Nonnull File file) { // there are classes that contain illegal variable names: `sealed` and `permits` CompilationUnit compilationUnit = null; try { - compilationUnit = compile(javaParser17, file); + compilationUnit = parse(javaParser17, file); } catch (Throwable t) { log("[Enhance] Exception parsing with java-17"); //noinspection CallToPrintStackTrace