-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Removes generating a separate class/struct for nested sequence and scalar type #111
Conversation
* Adds changes to `Field` to store `AbstractDataType` information of the field value * Modified to `map_constraint_to_abstract_data_type` to consider nested sequence/scalar type and change `AsbtractDataType` and `tera_fields` accordingly * Modified template to call `util_macros` for reading or writing a field as sequence
* Modified Rust templates to consider `util_macros` when reading or writing a nested sequence type
@@ -56,70 +58,36 @@ public class {{ target_kind_name }} { | |||
null | |||
{% endif %}; | |||
{% endfor %} | |||
{% if abstract_data_type == "Value"%} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(🗺️ PR tour) This template used to contain all abstract data types templates but now it separated into 3 templates.
- class.templ (For struct type)
- scalar.templ
- sequence.templ
{% if field.value_type is containing("ArrayList") %} | ||
{{ util_macros::read_as_sequence(field=field) }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(🗺️ PR tour) This statement is modified to read fields that are of type ArrayList
using util_macros write_as_sequence
. Previously it was not possible for a field in struct to be of sequence type(e.g. It would be inside some nested type NestedtypeX
). But with this change it is possible to have fields with sequence type (e.g. ArrayList<Integer>
).
{% if field.value_type | is_built_in_type == false %} | ||
{% if field.value_type is containing("ArrayList") %} | ||
{{ util_macros::write_as_sequence(field=field) }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(🗺️ PR tour) This statement is modified to write fields that are of type ArrayList
using util_macros write_as_sequence
. Previously it was not possible for a field in struct to be of sequence type(e.g. It would be inside some nested type NestedtypeX
). But with this change it is possible to have fields with sequence type (e.g. ArrayList<Inetger>
).
@@ -0,0 +1,69 @@ | |||
package {{ namespace }}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(🗺️ PR tour) Contents of files java/scalar.templ
, java/sequence.templ
, rust/scalar.templ
, rust/sequence.templ
are copied from java/class.templ
and rust/struct.templ
respectively.
@@ -29,106 +31,52 @@ pub mod {{ target_kind_name | snake }} { | |||
|
|||
pub fn read_from(reader: &mut Reader) -> SerdeResult<Self> { | |||
let mut abstract_data_type = {{ target_kind_name }}::default(); | |||
{% if abstract_data_type == "Value"%} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(🗺️ PR tour) This template used to contain all abstract data types templates but now it separated into 3 templates.
- struct.templ (For struct type)
- scalar.templ
- sequence.templ
{% if field.value_type | is_built_in_type == false %} | ||
{% if field.value_type is containing("Vec") %} | ||
"{{ field.name }}" => { {{ util_macros::read_as_sequence(field=field) }} } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗺️ PR tour) This statement is modified to read fields that are of type Vec
using util_macros write_as_sequence
. Previously it was not possible for a field in struct to be of sequence type(e.g. It would be inside some nested type NestedtypeX
). But with this change it is possible to have fields with sequence type (e.g. Vec<i64>
).
{% if field.value_type | is_built_in_type == false %} | ||
{% if field.value_type is containing("Vec") %} | ||
{{ util_macros::write_as_sequence(field=field) }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(🗺️ PR tour) This statement is modified to write fields that are of type Vec
using util_macros write_as_sequence
. Previously it was not possible for a field in struct to be of sequence type(e.g. It would be inside some nested type NestedtypeX
). But with this change it is possible to have fields with sequence type (e.g. Vec<i64>
).
Struct, // Represents a template for a Rust struct or Java class with Ion struct value | ||
Sequence, // Represents a template for a Rust struct or Java class with Ion sequence value | ||
Scalar, // Represents a template for a Rust struct or Java class with Ion scalar value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(🗺️ PR tour) Add new templates names here to use template based on abstract data type.
tests/cli.rs
Outdated
@@ -279,8 +279,8 @@ fn test_write_all_values(#[case] number: i32, #[case] expected_output: &str) -> | |||
} | |||
} | |||
"#, | |||
&["nested_type: NestedType1"], | |||
&["pub fn nested_type(&self) -> &NestedType1 {"] | |||
&["nested_type: i64"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(🗺️ PR tour) This file contains changes for having nested sequence type/scalar type in the same struct/class without generating separate structure.
code-gen-projects/java/code-gen-demo/src/test/java/org/example/CodeGenTest.java
Outdated
Show resolved
Hide resolved
let mut isl_type_name = value.type_reference().name(); | ||
|
||
if let Some(type_reference_name) = &type_name { | ||
if type_reference_name.contains("NestedType") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is a short-term hack, it's okay. It's a problem if this is here long term because there's nothing stopping a user from creating a type named NestedType
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, with the model change(Likely next PR) I think we can add a field in the model suggesting whether this is an inline type or not. And that should help with these kind of checks.
/// A target-language-agnostic data type that determines which template(s) to use for code generation. | ||
#[allow(dead_code)] | ||
#[derive(Debug, Clone, PartialEq, Serialize)] | ||
pub enum CodeGenType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion—if you create types for each of the variants, then you can require specific types in the signatures of various functions.
pub enum CodeGenType {
Value(Value),
Sequence(Sequence),
// etc.
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea! Will change that.
// value: i64 | ||
// } | ||
// ``` | ||
Value { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion—Scalar
?
// } | ||
// ``` | ||
Value { | ||
isl_type_name: String, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is actually the name from ISL, then it should probably be Option<String>
. If this is guaranteed to always have a name, then perhaps it should just be type_name
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! I will update this to be Option<String>
instead.
@@ -74,7 +76,11 @@ | |||
reader.{{ field.value_type | camel }}Value(); | |||
{% endif %} | |||
{% else %} | |||
{{ field.value_type }}.readFrom(reader); | |||
{% if field.value_type is containing("ArrayList") %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this break if someone creates an ISL type like MyArrayListener
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will. I will be changing the data model defined as per the current PR in model.rs
. That has a reference to CodeGenType
and based on this enum variant these checks can be defined properly.
src/bin/ion/commands/beta/generate/templates/java/util_macros.templ
Outdated
Show resolved
Hide resolved
src/bin/ion/commands/beta/generate/templates/java/util_macros.templ
Outdated
Show resolved
Hide resolved
src/bin/ion/commands/beta/generate/templates/java/util_macros.templ
Outdated
Show resolved
Hide resolved
{% endif %} | ||
{% endfor %} | ||
{% elif abstract_data_type is object and abstract_data_type is containing("Structure") %} | ||
writer.step_in(IonType::Struct)?; | ||
{% for field in fields %} | ||
writer.set_field_name("{{ field.name }}"); | ||
{% if field.value_type | is_built_in_type == false %} | ||
self.{{ field.name | snake }}.write_to(writer)?; | ||
{% if field.value_type is containing("Vec") %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I define an ISL type such as FeatureVector
or FlowVector
, this is probably going to do surprising things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. which is why with the new model we can just check the data model type.
As per offline discussion, I am removing |
8e98264
to
1802ff6
Compare
Issue #110:
Description of changes:
This PR works on generating nested sequence and scalar types in the same class/struct.
What is the change?
Previously, code generator would generate nested sequence or scalar types as a separate nested class or struct in a nested module. But this new change does not create a new class rather maps these nested sequence or scalar type in the same class/struct that uses it.
e.g. For a schema as below:
Previously generated code:
Code generated with this PR changes:
(Note: For example purpose I have only used java code but same is the case with Rust. Also, top level sequence/scalar top would still generate a separate class/struct. For more information on complete newly generated code see here)
Note for reviewer:
This PR also adds a new data model that can be used by code generator to render templates. The current approach can not generate nested sequence types like
{type: list, element: {type: sexp, element: int} }
. This will be resolved with the new data model as well as the new data model makes it easier to store all the information used by templates in a single place. This Pr just introduces the model but doesn't use it in implementation yet. The change for usage will be added in a separate PR.Generated code:
Generated code for Java can be found here.
Generated code for Rust can be found here.
(You can find corresponding ISL files and Ion files in code-gen-projects directory)
List of changes:
Field
to storeAbstractDataType
information of thefield value
map_constraint_to_abstract_data_type
to consider nestedsequence/scalar type and change
AsbtractDataType
andtera_fields
accordingly
util_macros
for reading or writing a fieldas sequence
util_macros
when reading orwriting a nested sequence type
Test:
Added new test schema and input files for this change.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.