Skip to content

Commit 600ae86

Browse files
authored
Merge pull request #96 from SokaDance/accessors
[gen][ts] property / method accessors and async methods
2 parents 52ded8d + 63fada5 commit 600ae86

17 files changed

+837
-562
lines changed

Dockerfile-ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ INCLUDE+ Dockerfile-base
66
FROM openjdk:16-alpine AS jvm
77
COPY --from=build /home/soft.gen/out/soft.generator.ts/*.jar /soft.generator.ts/
88
WORKDIR /soft.generator.ts
9-
RUN jdeps --print-module-deps --multi-release 16 --ignore-missing-deps --class-path '*' -recursive soft.generator.ts-1.3.0.jar > java.modules \
9+
RUN jdeps --print-module-deps --multi-release 16 --ignore-missing-deps --class-path '*' -recursive soft.generator.ts-1.4.0.jar > java.modules \
1010
&& jlink --strip-java-debug-attributes --add-modules $(cat java.modules) --output /java-generator
1111

1212
# Build result stage
1313
FROM alpine
1414
COPY --from=build /home/soft.gen/out/soft.generator.ts/*.jar /usr/share/soft.generator.ts/
1515
COPY --from=jvm /java-generator /usr/lib/jvm/java-generator
1616

17-
ENTRYPOINT ["/usr/lib/jvm/java-generator/bin/java","-jar","/usr/share/soft.generator.ts/soft.generator.ts-1.3.0.jar"]
17+
ENTRYPOINT ["/usr/lib/jvm/java-generator/bin/java","-jar","/usr/share/soft.generator.ts/soft.generator.ts-1.4.0.jar"]

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ soft.generators.version := 1.6.0
44
soft.generator.common.version := 1.4.1
55
soft.generator.cpp.version := 1.2.4
66
soft.generator.go.version := 1.9.1
7-
soft.generator.ts.version := 1.3.0
7+
soft.generator.ts.version := 1.4.0
88

99
export DOCKER_BUILDKIT=1
1010

soft.generators/soft.generator.go/src/soft/generator/go/generateCommon.mtl

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ methodName.toUpperFirst()
177177
/]
178178

179179
[** Accessors Names **/]
180-
[query public getterPrefix(feature : EStructuralFeature) : String = if feature.eType.name = 'EBoolean' then 'Is' else 'Get' endif/]
180+
[query private getterPrefix(feature : EStructuralFeature) : String = if feature.eType.name = 'EBoolean' then 'Is' else 'Get' endif/]
181181
[query private getAccessorName(feature : EStructuralFeature) : String =
182182
if feature.eContainingClass.isMapEntry() then
183183
'Typed' + name.toUpperFirst()

soft.generators/soft.generator.ts/META-INF/MANIFEST.MF

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Created-By: 13.0.2+8 (Oracle Corporation)
44
Bundle-ManifestVersion: 2
55
Bundle-Name: Soft Generator TypeScript
66
Bundle-SymbolicName: soft.generator.ts
7-
Bundle-Version: 1.3.0
7+
Bundle-Version: 1.4.0
88
Export-Package: soft.generator.ts,
99
soft.generator.ts.lib,
1010
soft.generator.ts.lib.factory,

soft.generators/soft.generator.ts/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<version>1.6.0</version>
99
</parent>
1010
<artifactId>soft.generator.ts</artifactId>
11-
<version>1.3.0</version>
11+
<version>1.4.0</version>
1212
<dependencies>
1313
<dependency>
1414
<groupId>soft.generators</groupId>

soft.generators/soft.generator.ts/src/soft/generator/ts/generateCommon.mtl

+118-3
Original file line numberDiff line numberDiff line change
@@ -39,27 +39,46 @@
3939
/]
4040

4141

42+
[**
43+
* return the package output directory.
44+
* property: packageDir
45+
* default : .
46+
*/]
4247
[query public getPackageDirectory( anPackage : EPackage ) : String =
4348
let replacement : String = if anPackage.hasPackageProperty('packageDir')
4449
then anPackage.getPackageProperty('packageDir')
4550
else '$1' endif in
4651
anPackage.name.replaceFirst('(.*)', replacement)
4752
/]
4853

54+
[**
55+
* return the package module resolution.
56+
* property: moduleResolution
57+
* default : nodenext
58+
*/]
4959
[query public getModuleResolution(anPackage : EPackage) : String =
5060
if anPackage.hasPackageProperty('moduleResolution')
5161
then anPackage.getPackageProperty('moduleResolution').toLower()
5262
else 'nodenext'
5363
endif
5464
/]
5565

66+
[**
67+
* return the package test framework.
68+
* property: testFramework
69+
* default : jest
70+
*/]
5671
[query public getTestFramework(anPackage : EPackage) : String =
5772
if anPackage.hasPackageProperty('testFramework')
5873
then anPackage.getPackageProperty('testFramework').toLower()
5974
else 'jest'
6075
endif
6176
/]
6277

78+
79+
[**
80+
* return true if the package test framework is vitest
81+
*/]
6382
[query public isVitest(anPackage : EPackage) : Boolean =
6483
anPackage.getTestFramework() = 'vitest'
6584
/]
@@ -75,6 +94,70 @@
7594
else false
7695
endif
7796
/]
97+
98+
[**
99+
* return the package accessors type for features.
100+
* property: accessors
101+
* default : method
102+
*/]
103+
[query public getAccessorsType(aPackage : EPackage) : Sequence(String) =
104+
if aPackage.hasPackageProperty('accessors') then
105+
aPackage.getPackageProperty('accessors').tokenize(',')
106+
else
107+
Sequence{'method'}
108+
endif
109+
/]
110+
111+
[**
112+
* return the accessors type for a feature.
113+
* property: accessors
114+
* default : method
115+
*/]
116+
[query public getAccessorsType(aFeature : EStructuralFeature) : Sequence(String) =
117+
if aFeature.hasKey('accessors') then
118+
aFeature.valueKey('accessors').tokenize(',')
119+
else
120+
aFeature.getEPackage().getAccessorsType()
121+
endif
122+
/]
123+
124+
[**
125+
* return true if feature accessors are defined as property
126+
*/]
127+
[query public isPropertyAccessors(aFeature : EStructuralFeature) : Boolean =
128+
aFeature.getAccessorsType()->includes('property')
129+
/]
130+
131+
[**
132+
* return true if feature accessors are defined as property
133+
*/]
134+
[query public isMethodAccessors(aFeature : EStructuralFeature) : Boolean =
135+
aFeature.getAccessorsType()->includes('method')
136+
/]
137+
138+
[**
139+
* return true if feature accessors are defined as async
140+
*/]
141+
[query public isAsync(aPackage : EPackage) : Boolean =
142+
if aPackage.hasPackageProperty('async') then
143+
aPackage.getPackageProperty('async') = 'true'
144+
else
145+
false
146+
endif
147+
/]
148+
149+
[**
150+
* return true if element accessors are defined as async
151+
*/]
152+
[query public isAsync(aTypedElement : ETypedElement) : Boolean =
153+
if aTypedElement.hasKey('async') then
154+
aTypedElement.valueKey('async') = 'true'
155+
else
156+
aTypedElement.getEPackage().isAsync()
157+
endif
158+
/]
159+
160+
78161
[**
79162
* File Comments
80163
*/]
@@ -85,6 +168,7 @@
85168
[/template]
86169

87170
[query public hasExtension( aModelElement : EModelElement ) : Boolean = hasKey('extension') and valueKey('extension' )='true'/]
171+
88172
[query public isExported( aNamedElement : ENamedElement ) : Boolean = if ( hasKey('exported') ) then valueKey('exported') = 'true' else false endif/]
89173

90174
[**
@@ -183,10 +267,25 @@ endif endif endif endif
183267
/]
184268

185269
[** Accessors Names **/]
186-
[query public getterPrefix(feature : EStructuralFeature) : String = if feature.eType.name = 'EBoolean' then 'Is' else 'Get' endif/]
270+
[query private getterPrefix(feature : EStructuralFeature) : String =
271+
if feature.eType.name = 'EBoolean' then
272+
if feature.isPropertyAccessors() then
273+
'get'
274+
else
275+
'is'
276+
endif
277+
else
278+
'get'
279+
endif
280+
/]
281+
282+
[query public getSetterName(feature : EStructuralFeature) : String = feature.getElementName( feature.name.toUpperFirst(), 'setterName', 'set$1')/]
283+
284+
[query public getGetterName(feature : EStructuralFeature) : String = feature.getElementName( feature.name.toUpperFirst(), 'getterName', feature.getterPrefix() + '$1')/]
187285

188-
[query public getUnSetterName(feature : EStructuralFeature) : String = feature.getElementName( name.toUpperFirst() , 'unSetterName', 'unSet$1')/]
189-
[query public getIsSetName(feature : EStructuralFeature) : String = feature.getElementName( name.toUpperFirst() , 'isSetName', 'isSet$1')/]
286+
[query public getUnSetterName(feature : EStructuralFeature) : String = feature.getElementName( feature.name.toUpperFirst(), 'unSetterName', 'unSet$1')/]
287+
288+
[query public getIsSetName(feature : EStructuralFeature) : String = feature.getElementName( feature.name.toUpperFirst(), 'isSetName', 'isSet$1')/]
190289

191290
[query public getOperationName(aOperation : EOperation ) : String = aOperation.getElementName( aOperation.name , 'operationName' )/]
192291

@@ -197,6 +296,22 @@ endif endif endif endif
197296
endif
198297
/]
199298

299+
[query public getPropertyName( aFeature : EStructuralFeature ) : String =
300+
if aFeature.eType.name = 'EBoolean' then
301+
'is' + aFeature.name.toUpperFirst()
302+
else if getReservedKeywords()->exists(s | s = aFeature.name) then
303+
aFeature.name + '_'
304+
else
305+
aFeature.name
306+
endif endif/]
307+
308+
[query public getVariableName( aFeature : EStructuralFeature ) : String =
309+
'_' + (if aFeature.eType.name = 'EBoolean' then
310+
'is' + aFeature.name.toUpperFirst()
311+
else aFeature.name endif
312+
)
313+
/]
314+
200315
[query public getReflectiveGetterName(anENamedElement : ENamedElement) : String =
201316
let getterName : String = 'get' + anENamedElement.getElementAccessorName() in
202317
let ecorePackageClass : EClass = anENamedElement.eClass().ePackage.eClass() in

soft.generators/soft.generator.ts/src/soft/generator/ts/lib/factory/generateFactoryImplementation.mtl

+20-15
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
[import soft::generator::ts::generateCommon/]
1818
[import soft::generator::ts::generateType/]
1919
[import soft::generator::ts::lib::generateCommon/]
20+
[import soft::generator::ts::lib::generateStructuralFeature/]
2021

2122
[query private getPackageEnumTypes(aPackage : EPackage) : Set(String) =
2223
aPackage.eAllContents(EEnum)->iterate( aEnum : EEnum ; res : Set(String) = Set{} | (
@@ -61,13 +62,13 @@ export class [className/] extends [if not aPackage.isEcorePackage()]ecore.[/if]E
6162
}
6263

6364
create(eClass: [if not aPackage.isEcorePackage()]ecore.[/if]EClass): [if not aPackage.isEcorePackage()]ecore.[/if]EObject {
64-
switch(eClass.classifierID){
65+
switch (eClass.getClassifierID()){
6566
[for (aClass : EClass | classes)]
66-
case [aClass.getImportedIDName(modules)/]:
67-
return this.create[aClass.name/]()
67+
case [aClass.getImportedIDName(modules)/]:
68+
return this.create[aClass.name/]()
6869
[/for]
69-
default:
70-
throw new Error("create: " + eClass.classifierID + " not found")
70+
default:
71+
throw new Error(`create: ${eClass.getClassifierID()} not found`)
7172
}
7273
}
7374
[for (aClass : EClass | classes)]
@@ -93,24 +94,24 @@ export class [className/] extends [if not aPackage.isEcorePackage()]ecore.[/if]E
9394
[let dataTypes : Sequence(EDataType) = aPackage.eAllContents(EDataType)->select( serializable )->sortedBy(name)]
9495

9596
createFromString(eDataType: [if not aPackage.isEcorePackage()]ecore.[/if]EDataType,literalValue: string): any {
96-
switch (eDataType.classifierID) {
97+
switch (eDataType.getClassifierID()) {
9798
[for (aDataType : EDataType | dataTypes)]
9899
case [aDataType.getImportedIDName(modules)/]:
99100
return this.create[aDataType.name/]FromString(eDataType, literalValue)
100101
[/for]
101102
default:
102-
throw new Error("The datatype '" + eDataType.name + "' is not a valid classifier")
103+
throw new Error(`The datatype '${eDataType.getName()}' is not a valid classifier`)
103104
}
104105
}
105106

106107
convertToString(eDataType: [if not aPackage.isEcorePackage()]ecore.[/if]EDataType, instanceValue: any): string {
107-
switch (eDataType.classifierID) {
108+
switch (eDataType.getClassifierID()) {
108109
[for (aDataType : EDataType | dataTypes)]
109-
case [aDataType.getImportedIDName(modules)/]:
110-
return this.convert[aDataType.name/]ToString(eDataType, instanceValue)
110+
case [aDataType.getImportedIDName(modules)/]:
111+
return this.convert[aDataType.name/]ToString(eDataType, instanceValue)
111112
[/for]
112-
default:
113-
throw new Error("The datatype '" + eDataType.name + "' is not a valid classifier")
113+
default:
114+
throw new Error(`The datatype '${eDataType.getName()}' is not a valid classifier`)
114115
}
115116
}
116117
[for (aDataType : EDataType | dataTypes)]
@@ -234,16 +235,20 @@ convert[aDataType.name/]ToString(eDataType: [if not aPackage.isEcorePackage()]ec
234235
[/template]
235236

236237
[template public generateCreateFunctionContent(aClass : EClass, aReference : EReference, addID : Boolean)]
237-
let element = new [if aClass.hasExtension()][aClass.getExtensionName()/][else][aClass.getImplementationName()/][/if]();
238+
const element = new [if aClass.hasExtension()][aClass.getExtensionName()/][else][aClass.getImplementationName()/][/if]();
238239
[if(addID)]
240+
[if aReference.isMethodAccessors()]
241+
element.set[aClass.getElementIDAccessorName()/]ID(classID)
242+
[elseif aReference.isPropertyAccessors()]
239243
element.[aClass.getElementIDAccessorName().toLowerFirst()/]ID = classID
240244
[/if]
245+
[/if]
241246
[if(not aReference.eOpposite.name.oclIsUndefined())]
242247
if (eContainer != null) {
243248
[if(aReference.eOpposite.upperBound <> 1)]
244-
eContainer.[aReference.eOpposite.name/].add(element)
249+
eContainer.[aReference.eOpposite.generateGetCall()/].add(element)
245250
[else]
246-
eContainer.[aReference.eOpposite.name/] = element
251+
eContainer.[aReference.eOpposite.generateSetCall('element')/]
247252
[/if]
248253
}
249254
[/if]

soft.generators/soft.generator.ts/src/soft/generator/ts/lib/generateCommon.mtl

-10
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,5 @@
6666
/]
6767

6868

69-
[query public getPropertyName( aFeature : EStructuralFeature ) : String =
70-
if aFeature.eType.name = 'EBoolean' then
71-
'is' + aFeature.name.toUpperFirst()
72-
else if getReservedKeywords()->exists(s | s = aFeature.name) then
73-
aFeature.name + '_'
74-
else
75-
aFeature.name
76-
endif endif/]
7769

78-
[query public getVariableName( aFeature : EStructuralFeature ) : String =
79-
'_' + aFeature.getPropertyName()/]
8070

soft.generators/soft.generator.ts/src/soft/generator/ts/lib/generateImplementation.mtl

+5-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ export class [className/] extends [getImportedIdentifier(classExtend, modules)/]
7676
return get[aPackage.getInterfaceName()/]().[aClass.getReflectiveGetterName()/]()
7777
}
7878

79-
[features.generateImplementation(aClass,modules)/]
79+
[let properties : OrderedSet(EStructuralFeature) = features->select( isPropertyAccessors() and (isGet() or isSet()))]
80+
[properties.generatePropertyImplementation(aClass,modules)/]
81+
[/let]
82+
83+
[features.generateMethodsImplementation(aClass,modules)/]
8084

8185
[operations.generateImplementation(aClass,modules)/]
8286

soft.generators/soft.generator.ts/src/soft/generator/ts/lib/generateInterface.mtl

+5-11
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,15 @@
6464
[aClass.generateImports('interface', types, modules)/]
6565

6666
export interface [interfaceName/][for ( qualifiedIdentifier : String | interfaceExtends ) before (' extends ') separator (', ')][getImportedIdentifier( qualifiedIdentifier , modules)/][/for] {
67-
[let attributes : OrderedSet(EAttribute) = aClass.eAttributes->asOrderedSet()->select( isGet() or isSet() )]
68-
[if attributes->notEmpty()]
69-
// Attributes
70-
[attributes->asOrderedSet().generateDeclaration(modules)/]
71-
[/if]
67+
[let properties : OrderedSet(EStructuralFeature) = aClass.eStructuralFeatures->asOrderedSet()->select( isPropertyAccessors() and (isGet() or isSet()))]
68+
[properties.generatePropertyDeclaration(modules)/]
7269
[/let]
73-
[let references : OrderedSet(EReference) = aClass.eReferences->asOrderedSet()->select( isGet() or isSet() )]
74-
[if references->notEmpty()]
75-
// References
76-
[references.generateDeclaration(modules)/]
77-
[/if]
70+
[let methods : OrderedSet(EStructuralFeature) = aClass.eStructuralFeatures->asOrderedSet()->select( isMethodAccessors() and (isGet() or isSet()))]
71+
[methods.generateMethodsDeclaration(modules)/]
7872
[/let]
7973
[let operations : OrderedSet(EOperation) = aClass.eOperations->asOrderedSet()]
8074
[if operations->notEmpty()]
81-
// Operations
75+
// operations
8276
[operations.generateDeclaration(modules)/]
8377
[/if]
8478
[/let]

soft.generators/soft.generator.ts/src/soft/generator/ts/lib/generateOperation.mtl

+9-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818

1919
[template public generateDeclaration(aOperation : EOperation, modules : OclAny)]
2020
[aOperation.getOperationName()/]([aOperation.generateParameterList(modules)/]): [aOperation.generateType(modules)/]
21-
21+
[if aOperation.isAsync()]
22+
[aOperation.getOperationName()/]Async([aOperation.generateParameterList(modules)/]): Promise<[aOperation.generateType(modules)/]>
23+
[/if]
2224
[/template]
2325

2426
[query public isDefault(anEOperation : EOperation ) : Boolean = not anEOperation.hasKey('default') or ( anEOperation.hasKey('default') and anEOperation.valueKey('default') = 'true' )/]
@@ -32,5 +34,10 @@
3234
throw new Error("[anEOperation.getOperationName()/] not implemented")
3335
}
3436

35-
37+
[if anEOperation.isAsync()]
38+
// [anEOperation.getOperationName()/] default implementation
39+
[anEOperation.getOperationName()/]Async([anEOperation.generateParameterList(modules)/]): Promise<[anEOperation.generateType(modules)/]> {
40+
throw new Error("[anEOperation.getOperationName()/]Async not implemented")
41+
}
42+
[/if]
3643
[/template]

0 commit comments

Comments
 (0)