Skip to content

Commit c0c2f2b

Browse files
jvelillawing328
andauthored
[Eiffel] various enhancements (#8076)
* Updated Eiffel code generator. Added missing language reserved words. Updated mustache templates to use the latest Eiffel rules to avoid obsolte feature calls and Cat-Calls. Updated Eiffel configuration files (ecf's) Updated comments styles. Updated Travis CI file to use the latest Eiffel compiler. Updated EIffel sample to use https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml * Added missing mapping decimal to REAL_64 Added Eiffel Kernel classes to importMapping to avoid generate models for them. Fixed issue with Eiffel feature name generation, updated toOperationId(String) method. Simplified toInstantiationType method implementaetion. Improved model.mustache to generate Eiffel models. * Updated Eiffel sample. * Removed unneeded tabs. * Added AnyType mapping to ANY Removed unneeded tab Updated model name, remane models that starts with _. * update doc Co-authored-by: William Cheng <[email protected]>
1 parent 3195338 commit c0c2f2b

File tree

135 files changed

+3195
-968
lines changed

Some content is hidden

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

135 files changed

+3195
-968
lines changed

docs/generators/eiffel.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ These options may be applied as additional-properties (cli) or configOptions (pl
1515

1616
| Type/Alias | Imports |
1717
| ---------- | ------- |
18+
|File|FILE|
19+
|List|LIST|
20+
|Map|STRING_TABLE|
21+
|Set|SET|
22+
|file|FILE|
1823

1924

2025
## INSTANTIATION TYPES
@@ -52,6 +57,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
5257
<li>and</li>
5358
<li>as</li>
5459
<li>assign</li>
60+
<li>attached</li>
5561
<li>attribute</li>
5662
<li>check</li>
5763
<li>class</li>
@@ -60,6 +66,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
6066
<li>current</li>
6167
<li>debug</li>
6268
<li>deferred</li>
69+
<li>detachable</li>
6370
<li>do</li>
6471
<li>else</li>
6572
<li>elseif</li>

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractEiffelCodegen.java

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ public AbstractEiffelCodegen() {
4848

4949
setReservedWordsLowerCase(Arrays.asList(
5050
// language reserved words
51-
"across", "agent", "alias", "all", "and", "as", "assign", "attribute", "check", "class", "convert",
52-
"create", "Current", "debug", "deferred", "do", "else", "elseif", "end", "ensure", "expanded", "export",
51+
"across", "agent", "alias", "all", "and", "as", "assign", "attached", "attribute", "check", "class", "convert",
52+
"create", "Current", "debug", "deferred", "detachable", "do", "else", "elseif", "end", "ensure", "expanded", "export",
5353
"external", "False", "feature", "from", "frozen", "if", "implies", "inherit", "inspect", "invariant",
5454
"like", "local", "loop", "not", "note", "obsolete", "old", "once", "only", "or", "Precursor",
5555
"redefine", "rename", "require", "rescue", "Result", "retry", "select", "separate", "then", "True",
@@ -68,6 +68,7 @@ public AbstractEiffelCodegen() {
6868
typeMapping.put("long", "INTEGER_64");
6969
typeMapping.put("number", "REAL_32");
7070
typeMapping.put("float", "REAL_32");
71+
typeMapping.put("decimal", "REAL_64");
7172
typeMapping.put("double", "REAL_64");
7273
typeMapping.put("boolean", "BOOLEAN");
7374
typeMapping.put("string", "STRING_32");
@@ -85,10 +86,17 @@ public AbstractEiffelCodegen() {
8586
typeMapping.put("map", "STRING_TABLE");
8687
typeMapping.put("array", "LIST");
8788
typeMapping.put("list", "LIST");
89+
typeMapping.put("AnyType", "ANY");
8890

8991
instantiationTypes.put("array", "ARRAYED_LIST");
9092
instantiationTypes.put("list", "ARRAYED_LIST");
9193
instantiationTypes.put("map", "STRING_TABLE");
94+
95+
importMapping.put("List", "LIST");
96+
importMapping.put("Set", "SET");
97+
importMapping.put("file", "FILE");
98+
importMapping.put("File", "FILE");
99+
importMapping.put("Map", "STRING_TABLE");
92100

93101

94102
cliOptions.clear();
@@ -167,6 +175,12 @@ public String toModelName(String name) {
167175

168176
@Override
169177
public String toModelFilename(String name) {
178+
// We need to check if import-mapping has a different model for this class, so we use it
179+
// instead of the auto-generated one.
180+
if (importMapping.containsKey(name)) {
181+
return importMapping.get(name);
182+
}
183+
170184
if (!StringUtils.isEmpty(modelNamePrefix)) {
171185
name = modelNamePrefix + "_" + name;
172186
}
@@ -191,6 +205,13 @@ public String toModelFilename(String name) {
191205
name = "model_" + name; // e.g. 200Response => Model200Response
192206
// (after camelize)
193207
}
208+
// model name starts with _
209+
if (name.startsWith("_")) {
210+
LOGGER.warn(name + " (model name starts with _) cannot be used as model name. Renamed to "
211+
+ ("model" + name));
212+
name = "model" + name; // e.g. 200Response => Model200Response
213+
// (after camelize)
214+
}
194215

195216
return underscore(name);
196217
}
@@ -278,7 +299,7 @@ public String getTypeDeclaration(Schema p) {
278299
} else if (ModelUtils.isMapSchema(p)) {
279300
Schema inner = getAdditionalProperties(p);
280301

281-
return getSchemaType(p) + "[" + getTypeDeclaration(inner) + "]";
302+
return getSchemaType(p) + " [" + getTypeDeclaration(inner) + "]";
282303
}
283304
// return super.getTypeDeclaration(p);
284305

@@ -315,14 +336,26 @@ public String getSchemaType(Schema p) {
315336

316337
@Override
317338
public String toOperationId(String operationId) {
318-
String sanitizedOperationId = sanitizeName(operationId);
339+
// throw exception if method name is empty
340+
if (StringUtils.isEmpty(operationId)) {
341+
throw new RuntimeException("Empty method/operation name (operationId) not allowed");
342+
}
343+
344+
String sanitizedOperationId = camelize(sanitizeName(operationId), true);
319345

320346
// method name cannot use reserved keyword, e.g. return
321347
if (isReservedWord(sanitizedOperationId)) {
322348
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to "
323349
+ camelize("call_" + operationId));
324350
sanitizedOperationId = "call_" + sanitizedOperationId;
325351
}
352+
353+
// operationId starts with a number
354+
if (operationId.matches("^\\d.*")) {
355+
LOGGER.warn(operationId + " (starting with a number) cannot be used as method sname. Renamed to " + camelize("call_" + operationId), true);
356+
sanitizedOperationId = camelize("call_" + sanitizedOperationId, true);
357+
}
358+
326359
// method name from updateSomething to update_Something.
327360
sanitizedOperationId = unCamelize(sanitizedOperationId);
328361

@@ -537,22 +570,23 @@ public Map<String, String> createMapping(String key, String value) {
537570

538571
@Override
539572
public String toInstantiationType(Schema p) {
540-
if (ModelUtils.isMapSchema(p)) {
541-
Schema additionalProperties2 = getAdditionalProperties(p);
542-
String type = additionalProperties2.getType();
543-
if (null == type) {
544-
LOGGER.error("No Type defined for Additional Schema " + additionalProperties2 + "\n" //
545-
+ "\tIn Schema: " + p);
546-
}
547-
String inner = toModelName(getSchemaType(additionalProperties2));
548-
return instantiationTypes.get("map") + " [" + inner + "]";
549-
} else if (ModelUtils.isArraySchema(p)) {
550-
ArraySchema ap = (ArraySchema) p;
551-
String inner = toModelName(getSchemaType(ap.getItems()));
552-
return instantiationTypes.get("array") + " [" + inner + "]";
553-
} else {
554-
return null;
555-
}
573+
return getTypeDeclaration(p);
574+
// if (ModelUtils.isMapSchema(p)) {
575+
// Schema additionalProperties2 = getAdditionalProperties(p);
576+
// String type = additionalProperties2.getType();
577+
// if (null == type) {
578+
// LOGGER.error("No Type defined for Additional Schema " + additionalProperties2 + "\n" //
579+
// + "\tIn Schema: " + p);
580+
// }
581+
// String inner = toModelName(getSchemaType(additionalProperties2));
582+
// return instantiationTypes.get("map") + " [" + inner + "]";
583+
// } else if (ModelUtils.isArraySchema(p)) {
584+
// ArraySchema ap = (ArraySchema) p;
585+
// String inner = toModelName(getSchemaType(ap.getItems()));
586+
// return instantiationTypes.get("array") + " [" + inner + "]";
587+
// } else {
588+
// return null;
589+
// }
556590
}
557591

558592
public String unCamelize(String name) {

modules/openapi-generator/src/main/resources/Eiffel/api.mustache

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ feature -- API Access
5959
end
6060
{{/formParams}}
6161

62-
if attached {STRING} api_client.select_header_accept (<<{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}>>) as l_accept then
62+
if attached {STRING} api_client.select_header_accept ({ARRAY [STRING]}<<{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}>>) as l_accept then
6363
l_request.add_header(l_accept,"Accept");
6464
end
65-
l_request.add_header(api_client.select_header_content_type (<<{{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}>>),"Content-Type")
66-
l_request.set_auth_names (<<{{#authMethods}}"{{name}}"{{^-last}}, {{/-last}}{{/authMethods}}>>)
65+
l_request.add_header(api_client.select_header_content_type ({ARRAY [STRING]}<<{{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}>>),"Content-Type")
66+
l_request.set_auth_names ({ARRAY [STRING]}<<{{#authMethods}}"{{name}}"{{^-last}}, {{/-last}}{{/authMethods}}>>)
6767
l_response := api_client.call_api (l_path, "{{httpMethod}}", l_request, {{#returnType}}Void{{/returnType}}{{^returnType}}agent serializer{{/returnType}}, {{#returnType}}agent deserializer{{/returnType}}{{^returnType}}Void{{/returnType}})
6868
{{#returnType}}
6969
if l_response.has_error then

modules/openapi-generator/src/main/resources/Eiffel/api_client.mustache

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,8 @@ feature -- Query Parameter Helpers
233233
-- dateTime string date-time As defined by date-time - RFC3339
234234
Result := date_time.date.debug_output
235235
elseif attached {STRING_32} a_param as str_32 then
236-
Result := str_32
236+
-- TODO check if this is a good convertion.
237+
Result := str_32.to_string_8
237238
elseif attached {STRING_8} a_param as str_8 then
238239
Result := str_8
239240
else
@@ -420,18 +421,18 @@ feature -- HTTP client: call api
420421
end
421422
end
422423

423-
add_header_params (a_content_executor:HTTP_CLIENT_REQUEST_CONTEXT; a_header_params: STRING_TABLE [STRING])
424+
add_header_params (a_content_executor:HTTP_CLIENT_REQUEST_CONTEXT; a_header_params: STRING_TABLE [READABLE_STRING_8])
424425
-- Set header parameters `a_header_params' to the request context executor `a_content_executor', including default headers.
425426
do
426427
-- headers
427428
across a_header_params as ic loop
428-
a_content_executor.add_header (ic.key.as_string_8, ic.item)
429+
a_content_executor.add_header (ic.key.to_string_8, ic.item)
429430
end
430431

431432
-- default headers
432433
across default_header_map as ic loop
433434
if not a_header_params.has (ic.key) then
434-
a_content_executor.add_header (ic.key.as_string_8, ic.item)
435+
a_content_executor.add_header (ic.key.to_string_8, ic.item)
435436
end
436437
end
437438
end
@@ -484,7 +485,7 @@ feature -- HTTP client: Change Element
484485

485486
feature {NONE} -- Implementation
486487

487-
default_header_map: STRING_TABLE [STRING]
488+
default_header_map: STRING_TABLE [READABLE_STRING_8]
488489
-- default header map.
489490

490491
http_session: detachable HTTP_CLIENT_SESSION

modules/openapi-generator/src/main/resources/Eiffel/ecf.mustache

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="ISO-8859-1"?>
2-
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="{{libraryTarget}}" uuid="{{uuid}}" library_target="{{libraryTarget}}">
2+
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-21-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-21-0 http://www.eiffel.com/developers/xml/configuration-1-21-0.xsd" name="{{libraryTarget}}" uuid="{{uuid}}" library_target="{{libraryTarget}}">
33
<target name="{{libraryTarget}}">
44
<root all_classes="true"/>
55
<file_rule>
@@ -8,17 +8,17 @@
88
<exclude>/CVS$</exclude>
99
<exclude>/EIFGENs$</exclude>
1010
</file_rule>
11-
<option warning="true">
11+
<option warning="warning" manifest_array_type="mismatch_warning">
1212
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
13-
</option>
13+
</option>
1414
<setting name="console_application" value="true"/>
1515
<library name="base" location="$ISE_LIBRARY/library/base/base.ecf"/>
16-
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
17-
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
18-
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
19-
<library name="http_client" location="$ISE_LIBRARY\contrib\library\network\http_client\http_client-safe.ecf"/>
20-
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
21-
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri-safe.ecf"/>
16+
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/>
17+
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
18+
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
19+
<library name="http_client" location="$ISE_LIBRARY\contrib\library\network\http_client\http_client.ecf"/>
20+
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
21+
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/>
2222
<library name="uuid" location="$ISE_LIBRARY\library\uuid\uuid.ecf"/>
2323
<cluster name="client" location=".\src" recursive="true"/>
2424
</target>

modules/openapi-generator/src/main/resources/Eiffel/framework/api_client_response.mustache

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ create
77

88
feature {NONE} -- Initialization
99

10-
make (a_response: detachable HTTP_CLIENT_RESPONSE; a_error: detachable API_ERROR; a_custom_deserializer: detachable FUNCTION [TUPLE [STRING, STRING, TYPE [detachable ANY]], detachable ANY])
10+
make (a_response: detachable HTTP_CLIENT_RESPONSE; a_error: detachable API_ERROR; a_custom_deserializer: detachable FUNCTION [TUPLE [READABLE_STRING_8, READABLE_STRING_8, TYPE [detachable ANY]], detachable ANY])
1111
do
1212
response := a_response
1313
error := a_error
@@ -23,6 +23,7 @@ feature -- Access
2323
end
2424

2525
status: INTEGER
26+
-- Status code of the response.
2627
do
2728
if attached response as l_response then
2829
Result := l_response.status
@@ -32,7 +33,7 @@ feature -- Access
3233
feature -- Data
3334

3435
data (a_type: TYPE [detachable ANY]): detachable ANY
35-
-- Data representation of the HTTP Response
36+
-- Data representation of the HTTP Response.
3637
do
3738
if
3839
attached response as l_response and then
@@ -54,8 +55,7 @@ feature {NONE} -- Implementation
5455
response: detachable HTTP_CLIENT_RESPONSE
5556
-- Low level response returned by the API call.
5657

57-
deserializer: detachable FUNCTION [TUPLE [STRING, STRING, TYPE [detachable ANY]], detachable ANY]
58-
-- function to map a response body with a given content type to the target
59-
-- in the domain model.
58+
deserializer: detachable FUNCTION [TUPLE [READABLE_STRING_8, READABLE_STRING_8, TYPE [detachable ANY]], detachable ANY]
59+
-- Function to map a response body with a given content type to the target in the domain model.
6060

6161
end

modules/openapi-generator/src/main/resources/Eiffel/framework/api_i.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ feature {NONE} -- Initialization
2424
feature -- Status Report
2525

2626
last_error: detachable API_ERROR
27-
-- last error if any from the API call.
27+
-- Last error if any from the API call.
2828

2929
feature -- Error
3030

3131
reset_error
32-
-- reset `last_error' to void.
32+
-- Reset `last_error' to void.
3333
do
3434
last_error := Void
3535
end

modules/openapi-generator/src/main/resources/Eiffel/framework/auth/api_key_auth.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ feature -- Change Element
4545

4646
feature -- Access
4747

48-
apply_to_params(a_query_params: LIST [TUPLE [name:STRING; value:STRING]]; a_header_params: STRING_TABLE [STRING])
48+
apply_to_params(a_query_params: LIST [TUPLE [name:READABLE_STRING_8; value:READABLE_STRING_8]]; a_header_params: STRING_TABLE [READABLE_STRING_8])
4949
-- <Precursor>.
5050
local
5151
l_value: STRING_32

modules/openapi-generator/src/main/resources/Eiffel/framework/auth/authentication.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ deferred class
55

66
feature -- Access
77

8-
apply_to_params(a_query_params: LIST [TUPLE [name:STRING; value:STRING]]; a_header_params: STRING_TABLE [STRING])
8+
apply_to_params(a_query_params: LIST [TUPLE [name:READABLE_STRING_8; value:READABLE_STRING_8]]; a_header_params: STRING_TABLE [READABLE_STRING_8])
99
-- Apply authentication settings to header and query params.
1010
-- `a_query_params' List of query parameters.
1111
-- `a_header_params' Map of header parameters.

modules/openapi-generator/src/main/resources/Eiffel/framework/auth/http_basic_auth.mustache

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ inherit
1010
feature -- Access
1111

1212
user_name: detachable STRING_32
13-
-- user name.
13+
-- User name.
1414

1515
password: detachable STRING_32
16-
-- password.
16+
-- Password.
1717

1818
feature -- Element Change
1919

@@ -35,14 +35,15 @@ feature -- Element Change
3535

3636
feature -- Access
3737

38-
apply_to_params(a_query_params: LIST [TUPLE [name:STRING; value:STRING]]; a_header_params: STRING_TABLE [STRING])
38+
apply_to_params(a_query_params: LIST [TUPLE [name:READABLE_STRING_8; value:READABLE_STRING_8]]; a_header_params: STRING_TABLE [READABLE_STRING_8])
3939
-- <Precursor>.
4040
do
4141
if
4242
attached user_name as l_username and then
4343
attached password as l_password
4444
then
45-
a_header_params.force ("Basic " + (create {BASE64}).encoded_string (l_username + ":" + l_password) , "Authorization")
45+
-- TODO check if this convertion it's ok.
46+
a_header_params.force ("Basic " + (create {BASE64}).encoded_string (l_username.to_string_8 + ":" + l_password.to_string_8) , "Authorization")
4647
end
4748
end
4849

0 commit comments

Comments
 (0)