Skip to content

Commit

Permalink
improve generation
Browse files Browse the repository at this point in the history
  • Loading branch information
tomsontom committed Dec 11, 2024
1 parent 1b733c8 commit f3c08f4
Show file tree
Hide file tree
Showing 11 changed files with 262 additions and 32 deletions.
1 change: 1 addition & 0 deletions dsl/src/cli/java-client-api/base-dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export function generateBaseDTOContent() {
const node = new CompositeGeneratorNode()
node.append(`public interface BaseDTO {`,NL)
node.indent( child => {
child.append('public static record Nillable<T>(T value) {}',NL,NL)
child.append(`public interface Builder {`, NL)
child.indent( body => {
body.append('public BaseDTO build();',NL)
Expand Down
48 changes: 46 additions & 2 deletions dsl/src/cli/java-client-api/record.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CompositeGeneratorNode, NL, toString } from "langium/generate";
import { Artifact } from "../artifact-generator.js";
import { JavaImportsCollector, JavaClientAPIGeneratorConfig, generateCompilationUnit, toPath } from "../java-gen-utils.js";
import { MResolvedRecordType, allRecordProperties, isMInlineEnumType, isMProperty } from "../model.js";
import { JavaImportsCollector, JavaClientAPIGeneratorConfig, generateCompilationUnit, toPath, resolveObjectType } from "../java-gen-utils.js";
import { MResolvedRecordType, allRecordProperties, isMInlineEnumType, isMKeyProperty, isMProperty, isMRevisionProperty } from "../model.js";
import { generateInlineEnum } from "./enum.js";
import { toFirstUpper } from "../util.js";
import { generateBuilderProperty, generateProperty } from "./shared.js";
Expand Down Expand Up @@ -68,6 +68,50 @@ export function generateRecordContent(t: MResolvedRecordType, artifactConfig: Ja
builderChild.append(`public ${t.name}DTO build();`, NL)
} )
child.append('}', NL)
if( t.patchable ) {
child.append('public interface Patch {',NL)
child.indent( patchBody => {
if( allProps.find( p => !isMKeyProperty(p) && !isMRevisionProperty(p) ) ) {
patchBody.append('public enum Props {',NL)
patchBody.indent(enumBody => {
allProps.filter( p => !isMKeyProperty(p) && !isMRevisionProperty(p) ).forEach( (p, idx) => {
enumBody.append(`${p.name.toUpperCase()},`,NL)
})
})

patchBody.append('}',NL,NL)

patchBody.append('public boolean isSet(Props prop);', NL,NL)
}

allProps.forEach( p => {
if( isMKeyProperty(p) || isMRevisionProperty(p) ) {
generateProperty(patchBody, p, artifactConfig, fqn)
} else if( p.nullable === false && p.array === false ) {
generateProperty(patchBody, p, artifactConfig, fqn)
}
} )
allProps.forEach( p => {
if( ! isMKeyProperty(p) && ! isMRevisionProperty(p) && p.nullable === false && p.array === false ) {
const Consumer = fqn('java.util.function.Consumer');
if( p.variant === 'union' || p.variant === 'record' ) {

} else if( typeof p.type === 'string' ) {
patchBody.append(`public static void if${toFirstUpper(p.name)}(Patch dto, ${Consumer}<${resolveObjectType(p.type, artifactConfig.nativeTypeSubstitues, fqn)}> consumer) {`,NL)
patchBody.indent( mBody => {
mBody.append(`if( dto.isSet(Props.${p.name.toUpperCase()}) ) {`,NL)
mBody.indent( block => {
block.append(`consumer.accept(dto.${p.name}());`,NL)
})
mBody.append('}',NL)
} )
patchBody.append('}',NL)
}
}
})
})
child.append('}',NL)
}
});
node.append('}',NL)
return node
Expand Down
4 changes: 2 additions & 2 deletions dsl/src/cli/java-client-api/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ function toMethod(
}

function toParameter(parameter: MParameter, artifactConfig: JavaClientAPIGeneratorConfig, fqn: (type: string) => string) {
return `${toType(parameter, artifactConfig, fqn)} ${parameter.name}`;
return `${toType(parameter, artifactConfig, fqn, parameter.nullable)} ${parameter.name}`;
}

function toResultType(type: MReturnType | undefined, artifactConfig: JavaClientAPIGeneratorConfig, fqn: (type: string) => string) {
Expand All @@ -88,7 +88,7 @@ function toResultType(type: MReturnType | undefined, artifactConfig: JavaClientA
if( type.array ) {
return `${fqn('java.util.List')}<${resolveObjectType(type.type, artifactConfig.nativeTypeSubstitues, fqn)}>`
} else {
return `${resolveType(type.type, artifactConfig.nativeTypeSubstitues, fqn)}`;
return `${resolveType(type.type, artifactConfig.nativeTypeSubstitues, fqn, false)}`;
}
}
return type.type;
Expand Down
19 changes: 14 additions & 5 deletions dsl/src/cli/java-client-api/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function generateBuilderProperty(node: IndentNode, property: MKeyProperty
if( property.array ) {
node.append(`public Builder ${property.name}(${fqn('java.util.List')}<${resolveObjectType(property.type, artifactConfig.nativeTypeSubstitues, fqn)}> ${property.name});`,NL)
} else {
node.append(`public Builder ${property.name}(${resolveType(property.type, artifactConfig.nativeTypeSubstitues, fqn)} ${property.name});`,NL)
node.append(`public Builder ${property.name}(${resolveType(property.type, artifactConfig.nativeTypeSubstitues, fqn, property.nullable)} ${property.name});`,NL)
}
} else {
node.append(`public Builder ${property.name}(${toFirstUpper(property.name)} ${property.name});`,NL)
Expand All @@ -29,7 +29,12 @@ export function generateBuilderProperty(node: IndentNode, property: MKeyProperty
}
}

export function generateProperty(node: IndentNode, property: MKeyProperty | MRevisionProperty | MProperty, artifactConfig: JavaClientAPIGeneratorConfig, fqn: (type: string) => string) {
export function generateProperty(
node: IndentNode,
property: MKeyProperty | MRevisionProperty | MProperty,
artifactConfig: JavaClientAPIGeneratorConfig,
fqn: (type: string) => string
) {
if( property.doc ) {
node.append('/**', NL)
node.append(' * ', property.doc, NL)
Expand All @@ -50,7 +55,7 @@ export function generateProperty(node: IndentNode, property: MKeyProperty | MRev
if( property.array ) {
node.append(`public ${fqn('java.util.List')}<${resolveObjectType(property.type, artifactConfig.nativeTypeSubstitues, fqn)}> ${property.name}();`,NL)
} else {
node.append(`public ${resolveType(property.type, artifactConfig.nativeTypeSubstitues, fqn)} ${property.name}();`,NL)
node.append(`public ${resolveType(property.type, artifactConfig.nativeTypeSubstitues, fqn, property.nullable)} ${property.name}();`,NL)
}
} else {
node.append(`public ${toFirstUpper(property.name)} ${property.name}();`,NL)
Expand All @@ -59,7 +64,11 @@ export function generateProperty(node: IndentNode, property: MKeyProperty | MRev
}
}

export function toType(typeOwner: Pick<MProperty, 'variant'|'array'|'type'|'name'>, artifactConfig: Pick<JavaClientAPIGeneratorConfig, 'rootPackageName'|'nativeTypeSubstitues'>, fqn: (type: string) => string) {
export function toType(
typeOwner: Pick<MProperty, 'variant'|'array'|'type'|'name'>,
artifactConfig: Pick<JavaClientAPIGeneratorConfig, 'rootPackageName'|'nativeTypeSubstitues'>,
fqn: (type: string) => string,
useBuiltinObject: boolean) {
if( typeOwner.variant === 'union' || typeOwner.variant === 'record' ) {
const dtoType = fqn(`${artifactConfig.rootPackageName}.dto.${typeOwner.type}DTO`)
if( typeOwner.array ) {
Expand All @@ -71,7 +80,7 @@ export function toType(typeOwner: Pick<MProperty, 'variant'|'array'|'type'|'name
if( typeOwner.array ) {
return `${fqn('java.util.List')}<${resolveObjectType(typeOwner.type, artifactConfig.nativeTypeSubstitues, fqn)}>`;
} else {
return `${resolveType(typeOwner.type, artifactConfig.nativeTypeSubstitues, fqn)}`;
return `${resolveType(typeOwner.type, artifactConfig.nativeTypeSubstitues, fqn, useBuiltinObject)}`;
}
}
return `${toFirstUpper(typeOwner.name)}`
Expand Down
5 changes: 4 additions & 1 deletion dsl/src/cli/java-gen-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ export function builtinToJavaObjectType(type: MBuiltinType, fqn: (type: string)
}
}

export function resolveType(type: string, nativeSubstitutes: Record<string,string> | undefined, fqn: (type: string) => string) {
export function resolveType(type: string, nativeSubstitutes: Record<string,string> | undefined, fqn: (type: string) => string, useBuiltinObject: boolean) {
if( isMBuiltinType(type) ) {
if( useBuiltinObject ) {
return builtinToJavaObjectType(type, fqn);
}
return builtinToJavaType(type, fqn);
} else if( nativeSubstitutes !== undefined && type in nativeSubstitutes ) {
return fqn(nativeSubstitutes[type]);
Expand Down
4 changes: 2 additions & 2 deletions dsl/src/cli/java-rest-client-jdk/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ function computePath(orignalPath: string): { path: string, variables: string[] }
}

function toParameter(parameter: MParameter, artifactConfig: JavaRestClientJDKGeneratorConfig, fqn: (type: string) => string) {
return `${toType(parameter, artifactConfig, fqn)} ${parameter.name}`;
return `${toType(parameter, artifactConfig, fqn, parameter.nullable)} ${parameter.name}`;
}

function toResultType(type: MReturnType | undefined, artifactConfig: JavaRestClientJDKGeneratorConfig, fqn: (type: string) => string) {
Expand All @@ -381,7 +381,7 @@ function toResultType(type: MReturnType | undefined, artifactConfig: JavaRestCli
if( type.array ) {
return `${fqn('java.util.List')}<${resolveObjectType(type.type, artifactConfig.nativeTypeSubstitues, fqn)}>`
} else {
return `${resolveType(type.type, artifactConfig.nativeTypeSubstitues, fqn)}`;
return `${resolveType(type.type, artifactConfig.nativeTypeSubstitues, fqn, false)}`;
}
}
return type.type;
Expand Down
20 changes: 10 additions & 10 deletions dsl/src/cli/java-rest-client-jdk/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@ export function generateProperty(node: IndentNode, property: MKeyProperty | MRev
node.append('}', NL)
} else {
node.append('@Override', NL)
node.append(`public ${toType(property, artifactConfig, fqn)} ${property.name}() {`, NL)
node.append(`public ${toType(property, artifactConfig, fqn, property.nullable)} ${property.name}() {`, NL)
node.indent( methodBody => {
if( property.array ) {
if( property.variant === 'builtin' && isMBuiltinType(property.type) ) {
methodBody.append(`return ${builtinArrayJSONAccess( { type: property.type, name: property.name }, fqn )};`,NL)
} else if( property.variant === 'enum' || property.variant === 'inline-enum' || property.variant === 'scalar' ) {
if( property.variant === 'enum' || property.variant === 'inline-enum') {
const type = typeof property.type === 'string' ? property.type : toFirstUpper(property.name);
methodBody.append(`return DTOUtils.mapLiterals(data, "${property.name}", ${resolveType(type, artifactConfig.nativeTypeSubstitues, fqn)}::valueOf);`, NL);
methodBody.append(`return DTOUtils.mapLiterals(data, "${property.name}", ${resolveType(type, artifactConfig.nativeTypeSubstitues, fqn, property.nullable)}::valueOf);`, NL);
} else if( typeof property.type === 'string' ) {
methodBody.append(`return DTOUtils.mapLiterals(data, "${property.name}", ${resolveType(property.type, artifactConfig.nativeTypeSubstitues, fqn)}::of);`, NL);
methodBody.append(`return DTOUtils.mapLiterals(data, "${property.name}", ${resolveType(property.type, artifactConfig.nativeTypeSubstitues, fqn, property.nullable)}::of);`, NL);
}
} else {
methodBody.append(`DTOUtils.mapObjects(data, "${property.name}", ${toType(property, artifactConfig, fqn)}::of)`, NL);
methodBody.append(`DTOUtils.mapObjects(data, "${property.name}", ${toType(property, artifactConfig, fqn, property.nullable)}::of)`, NL);
}

} else {
Expand All @@ -41,19 +41,19 @@ export function generateProperty(node: IndentNode, property: MKeyProperty | MRev
if( property.nullable || property.optional ) {
if( property.variant === 'enum' || property.variant === 'inline-enum' || property.variant === 'scalar' ) {
if( property.variant === 'enum' || property.variant === 'inline-enum') {
methodBody.append(`return DTOUtils.mapLiteral(data, "${property.name}", ${toType(property, artifactConfig, fqn)}::valueOf, ${toType(property, artifactConfig, fqn)}.values()[0]);`, NL);
methodBody.append(`return DTOUtils.mapLiteral(data, "${property.name}", ${toType(property, artifactConfig, fqn, property.nullable)}::valueOf, ${toType(property, artifactConfig, fqn, property.nullable)}.values()[0]);`, NL);
} else {
methodBody.append(`return DTOUtils.mapLiteral(data, "${property.name}", ${toType(property, artifactConfig, fqn)}::of, null);`, NL);
methodBody.append(`return DTOUtils.mapLiteral(data, "${property.name}", ${toType(property, artifactConfig, fqn, property.nullable)}::of, null);`, NL);
}
} else {
methodBody.append(`return DTOUtils.mapObject(data, "${property.name}", ${property.type}DTOImpl::of, null);`, NL);
}
} else {
if( property.variant === 'enum' || property.variant === 'inline-enum' || property.variant === 'scalar' ) {
if( property.variant === 'enum' || property.variant === 'inline-enum') {
methodBody.append(`return DTOUtils.mapLiteral(data, "${property.name}", ${toType(property, artifactConfig, fqn)}::valueOf);`, NL);
methodBody.append(`return DTOUtils.mapLiteral(data, "${property.name}", ${toType(property, artifactConfig, fqn, property.nullable)}::valueOf);`, NL);
} else {
methodBody.append(`return DTOUtils.mapLiteral(data, "${property.name}", ${toType(property, artifactConfig, fqn)}::of);`, NL);
methodBody.append(`return DTOUtils.mapLiteral(data, "${property.name}", ${toType(property, artifactConfig, fqn, property.nullable)}::of);`, NL);
}
} else {
methodBody.append(`return DTOUtils.mapObject(data, "${property.name}", ${property.type}DTOImpl::of);`, NL);
Expand Down Expand Up @@ -123,7 +123,7 @@ export function generateBuilderProperty(node: IndentNode, property: MKeyProperty
node.append('}', NL)
} else {
node.append('@Override', NL)
node.append(`public ${typePrefix ? `${typePrefix}.`: ''}Builder ${property.name}(${toType(property, artifactConfig, fqn)} ${property.name}) {`, NL)
node.append(`public ${typePrefix ? `${typePrefix}.`: ''}Builder ${property.name}(${toType(property, artifactConfig, fqn, property.nullable)} ${property.name}) {`, NL)
node.indent( methodBody => {
if( property.optional && ! property.nullable && !( isMBuiltinType(property.type) && isJavaPrimitive(property.type) ) ) {
methodBody.append(`if( ${property.name} == null ) {`, NL);
Expand All @@ -133,7 +133,7 @@ export function generateBuilderProperty(node: IndentNode, property: MKeyProperty
if( property.nullable && !( isMBuiltinType(property.type) && isJavaPrimitive(property.type) ) ) {
methodBody.append(`if( ${property.name} == null ) {`, NL);
methodBody.indent( block => {
block.append(`$builder.addNull("${property.name}");`);
block.append(`$builder.addNull("${property.name}");`,NL);
block.append('return this;', NL);
})
methodBody.append('}',NL);
Expand Down
2 changes: 1 addition & 1 deletion dsl/src/cli/java-rest-client-jdk/union.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ function generateUnionContent(t: MResolvedUnionType, artifactConfig: JavaRestCli
subtypeBuilderBody.append('}', NL)
} else {
subtypeBuilderBody.append('@Override', NL)
subtypeBuilderBody.append(`public ${subtype.name}DTO.Builder ${property.name}(${toType(property, artifactConfig, fqn)} ${property.name}) {`, NL)
subtypeBuilderBody.append(`public ${subtype.name}DTO.Builder ${property.name}(${toType(property, artifactConfig, fqn, property.nullable)} ${property.name}) {`, NL)
subtypeBuilderBody.indent( methodBody => {
methodBody.append(`return (${subtype.name}DTO.Builder) super.${property.name}(${property.name});`, NL)
})
Expand Down
4 changes: 2 additions & 2 deletions dsl/src/cli/java-server-jakarta-ws/record.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ export function addBuilderMethod(param: IndentNode, property: MBaseProperty, art
})
param.append('}', NL)
} else {
param.append(`public ${typePrefix}Builder ${property.name}(${resolveType(property.type, artifactConfig.nativeTypeSubstitues, fqn)} ${property.name}) {`, NL)
param.append(`public ${typePrefix}Builder ${property.name}(${resolveType(property.type, artifactConfig.nativeTypeSubstitues, fqn, property.nullable)} ${property.name}) {`, NL)
param.indent( body => {
body.append(`this.${property.name} = ${property.name};`,NL)
body.append('return this;',NL)
Expand Down Expand Up @@ -220,7 +220,7 @@ function addProperty(param: IndentNode, property: MBaseProperty, end: string, ar
if( property.array ) {
param.append(`${fqn('java.util.List')}<${resolveObjectType(property.type, artifactConfig.nativeTypeSubstitues, fqn)}> ${property.name}`, end, NL)
} else {
param.append(`${resolveType(property.type, artifactConfig.nativeTypeSubstitues, fqn)} ${property.name}`, end, NL)
param.append(`${resolveType(property.type, artifactConfig.nativeTypeSubstitues, fqn, property.nullable)} ${property.name}`, end, NL)
}
} else {
param.append(`${toFirstUpper(property.name)} ${property.name}`, end, NL)
Expand Down
Loading

0 comments on commit f3c08f4

Please sign in to comment.