diff --git a/project/buildSrc/build.gradle.kts b/project/buildSrc/build.gradle.kts index a91f4a672f..ac48c47e56 100644 --- a/project/buildSrc/build.gradle.kts +++ b/project/buildSrc/build.gradle.kts @@ -3,6 +3,6 @@ plugins { } dependencies { - api("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10") + api("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0") api("org.jetbrains.dokka:dokka-gradle-plugin:1.6.10") } diff --git a/project/gradle/libs.versions.toml b/project/gradle/libs.versions.toml index b5f6eaa32f..2bc371906e 100644 --- a/project/gradle/libs.versions.toml +++ b/project/gradle/libs.versions.toml @@ -15,7 +15,7 @@ jetbrainsAnnotations = "24.0.0" jupiter = "5.10.2" kafka = "0.10.0.0" kotlinpoet = "1.14.2" -ksp = "1.7.10-1.0.6" +ksp = "2.1.0-1.0.29" lombok = "1.18.30" mapstruct = "1.5.3.Final" mysql = "8.0.29" diff --git a/project/jimmer-apt/src/main/java/org/babyfish/jimmer/apt/client/ClientProcessor.java b/project/jimmer-apt/src/main/java/org/babyfish/jimmer/apt/client/ClientProcessor.java index f99a0e0133..f70eb6e098 100644 --- a/project/jimmer-apt/src/main/java/org/babyfish/jimmer/apt/client/ClientProcessor.java +++ b/project/jimmer-apt/src/main/java/org/babyfish/jimmer/apt/client/ClientProcessor.java @@ -664,9 +664,13 @@ private void fillDefinition(TypeElement typeElement, boolean immutable) { if (!immutable || typeElement.getKind() == ElementKind.INTERFACE) { boolean isClientException = typeElement.getAnnotation(ClientException.class) != null; for (Element element : typeElement.getEnclosedElements()) { + if (element.getKind().toString().equals("RECORD_COMPONENT")) { + element = ((RecordComponentElement) element).getAccessor(); + } if (!(element instanceof ExecutableElement)) { continue; } + ExecutableElement executableElement = (ExecutableElement) element; if (!executableElement.getParameters().isEmpty() || executableElement.getModifiers().contains(Modifier.STATIC) || @@ -688,10 +692,13 @@ private void fillDefinition(TypeElement typeElement, boolean immutable) { !Character.isLowerCase(name.charAt(3))) { name = StringUtil.identifier(name.substring(3)); } else { - if (!immutable) { + if (!immutable && !typeElement.getKind().toString().equals("RECORD")) { continue; } } + if (Arrays.asList("toString","hashCode").stream().anyMatch(name::equals)) { + continue; + } if (isClientException && (name.equals("code") || name.equals("fields"))) { continue; } diff --git a/project/jimmer-client/build.gradle.kts b/project/jimmer-client/build.gradle.kts index 7226647fbf..49ef2bfaf7 100644 --- a/project/jimmer-client/build.gradle.kts +++ b/project/jimmer-client/build.gradle.kts @@ -21,6 +21,10 @@ tasks.withType().configureEach { options.compilerArgs.add("-Ajimmer.client.checkedException=true") } +tasks.compileTestJava { + options.release.set(21) +} + ksp { arg("jimmer.source.includes", "org.babyfish.jimmer.client.kotlin.") arg("jimmer.dto.testDirs", "src/test/dto2") diff --git a/project/jimmer-client/src/test/java/org/babyfish/jimmer/client/java/service/PageQuery.java b/project/jimmer-client/src/test/java/org/babyfish/jimmer/client/java/service/PageQuery.java new file mode 100644 index 0000000000..ff21ecadcb --- /dev/null +++ b/project/jimmer-client/src/test/java/org/babyfish/jimmer/client/java/service/PageQuery.java @@ -0,0 +1,9 @@ +package org.babyfish.jimmer.client.java.service; + +public record PageQuery( + Integer pageIndex, + Integer pageSize, + T spec +) { + +} \ No newline at end of file diff --git a/project/jimmer-client/src/test/java/org/babyfish/jimmer/client/java/service/RecordService.java b/project/jimmer-client/src/test/java/org/babyfish/jimmer/client/java/service/RecordService.java new file mode 100644 index 0000000000..f9d299e82a --- /dev/null +++ b/project/jimmer-client/src/test/java/org/babyfish/jimmer/client/java/service/RecordService.java @@ -0,0 +1,13 @@ +package org.babyfish.jimmer.client.java.service; + +import org.babyfish.jimmer.client.common.PostMapping; +import org.babyfish.jimmer.client.meta.Api; + +@Api("recordService") +public class RecordService { + @Api + @PostMapping("/page/query") + public PageQuery pageQuery(PageQuery pageQuery) { + return pageQuery; + } +} diff --git a/project/jimmer-client/src/test/java/org/babyfish/jimmer/client/java/ts/RecordServiceTest.java b/project/jimmer-client/src/test/java/org/babyfish/jimmer/client/java/ts/RecordServiceTest.java new file mode 100644 index 0000000000..09c840b513 --- /dev/null +++ b/project/jimmer-client/src/test/java/org/babyfish/jimmer/client/java/ts/RecordServiceTest.java @@ -0,0 +1,89 @@ +package org.babyfish.jimmer.client.java.ts; + +import org.babyfish.jimmer.client.common.OperationParserImpl; +import org.babyfish.jimmer.client.common.ParameterParserImpl; +import org.babyfish.jimmer.client.generator.Context; +import org.babyfish.jimmer.client.generator.ts.TypeScriptContext; +import org.babyfish.jimmer.client.java.service.RecordService; +import org.babyfish.jimmer.client.runtime.Metadata; +import org.babyfish.jimmer.client.source.Source; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.StringWriter; +import java.util.Collections; + +public class RecordServiceTest { + + private static final Metadata METADATA = + Metadata + .newBuilder() + .setOperationParser(new OperationParserImpl()) + .setParameterParser(new ParameterParserImpl()) + .setGroups(Collections.singleton("recordService")) + .setGenericSupported(true) + .build(); + + @Test + public void testService() { + Context ctx = new TypeScriptContext(METADATA); + Source source = ctx.getRootSource("services/" + RecordService.class.getSimpleName()); + StringWriter writer = new StringWriter(); + ctx.render(source, writer); + Assertions.assertEquals("import type {Executor} from '../';\n" + + "import type {PageQuery} from '../model/static/';\n" + + "\n" + + "export class RecordService {\n" + + " \n" + + " constructor(private executor: Executor) {}\n" + + " \n" + + " readonly pageQuery: (options: RecordServiceOptions['pageQuery']) => Promise<\n" + + " PageQuery\n" + + " > = async(options) => {\n" + + " let _uri = '/page/query';\n" + + " let _separator = _uri.indexOf('?') === -1 ? '?' : '&';\n" + + " let _value: any = undefined;\n" + + " _value = options.pageQuery.pageIndex;\n" + + " if (_value !== undefined && _value !== null) {\n" + + " _uri += _separator\n" + + " _uri += 'pageIndex='\n" + + " _uri += encodeURIComponent(_value);\n" + + " _separator = '&';\n" + + " }\n" + + " _value = options.pageQuery.pageSize;\n" + + " if (_value !== undefined && _value !== null) {\n" + + " _uri += _separator\n" + + " _uri += 'pageSize='\n" + + " _uri += encodeURIComponent(_value);\n" + + " _separator = '&';\n" + + " }\n" + + " return (await this.executor({uri: _uri, method: 'POST'})) as Promise>;\n" + + " }\n" + + "}\n" + + "\n" + + "export type RecordServiceOptions = {\n" + + " 'pageQuery': {\n" + + " readonly pageQuery: PageQuery\n" + + " }\n" + + "}\n", + writer.toString() + ); + } + + + @Test + public void testPageQuery() { + Context ctx = new TypeScriptContext(METADATA); + Source source = ctx.getRootSource("model/static/PageQuery"); + StringWriter writer = new StringWriter(); + ctx.render(source, writer); + Assertions.assertEquals( + "export interface PageQuery {\n" + + " readonly pageIndex?: number | undefined;\n" + + " readonly pageSize?: number | undefined;\n" + + " readonly spec: T;\n" + + "}\n", + writer.toString() + ); + } +}