Skip to content

Commit 2540480

Browse files
committed
Updates: abstract vs concrete
- Use the golang.py DATATYPES instead of the one in the jinja template. - Organized the macros. - Added checks for abstract vs concrete classes Signed-off-by: Nisha Kumar <nisha.kumar@oracle.com>
1 parent 40e99a1 commit 2540480

File tree

2 files changed

+99
-158
lines changed

2 files changed

+99
-158
lines changed

src/shacl2code/lang/golang.py

Lines changed: 30 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,42 +20,37 @@
2020
"http://www.w3.org/2001/XMLSchema#dateTimeStamp": "DateTimeStamp",
2121
}
2222

23-
RESERVED_WORDS = {
24-
"package"
25-
}
2623

27-
def export(name):
28-
# export converts the shacl name into an exportable go type name
29-
name_list = name.split('_')
30-
for i in range(0,len(name_list)):
31-
name_list[i] = name_list[i][0].upper() + name_list[i][1:]
32-
return ''.join(name_list)
24+
def upper_first(string):
25+
# upper_first will capitalize the string
26+
return string[0].upper() + string[1:]
27+
3328

29+
def lower_first(string):
30+
# lower_first sets the first character of a string to lower case
31+
return string[0].lower() + string[1:]
3432

35-
def type_name(name):
36-
parts = re.split(r'[^a-zA-Z0-9]', name)
37-
part = parts[len(parts)-1]
38-
return upper_first(part)
3933

34+
def type_name(clsname):
35+
# type_name converts the class name into an exportable go type name
36+
return upper_first(''.join(clsname).replace('_',''))
4037

41-
def struct_prop_name(prop):
42-
# prop:
43-
# class_id, comment, datatype, enum_values, max_count, min_count, path, pattern, varname
44-
return lower_first(type_name(prop.varname))
4538

39+
def interface_method(propname):
40+
# returns an interface method name
41+
# The interface method names are capitalized so they can be exported
42+
parts = propname.split('_')
43+
parts[0] = upper_first(parts[0])
44+
return ''.join(parts)
4645

47-
def prop_type(prop):
48-
# prop:
49-
# class_id, comment, datatype, enum_values, max_count, min_count, path, pattern, varname
50-
if prop.datatype in DATATYPES:
51-
typ = DATATYPES[prop.datatype]
52-
else:
53-
typ = type_name(prop.class_id)
46+
def struct_name(clsname):
47+
# Go structs are only used when a class is a concrete class
48+
return lower_first(type_name(clsname)) + "Impl"
5449

55-
if prop.max_count is None or prop.max_count > 1:
56-
typ = '[]' + typ
5750

58-
return typ
51+
def struct_prop_name(propname):
52+
# All properties in a Go struct are non-exportable
53+
return propname.replace('_','')
5954

6055

6156
def setter_prop_type(prop):
@@ -68,21 +63,21 @@ def struct_prop(prop):
6863

6964

7065
def interface_getter(prop):
71-
return upper_first(type_name(prop.varname)) + '() ' + prop_type(prop)
66+
return type_name(prop.varname) + '() ' + prop_type(prop)
7267

7368

7469
def interface_setter(prop):
75-
return "Set" + upper_first(type_name(prop.varname)) + '(' + setter_prop_type(prop) + ') error'
70+
return "Set" + type_name(prop.varname) + '(' + setter_prop_type(prop) + ') error'
7671

7772

7873
def struct_getter(cls, prop):
79-
return 'func (o *' + struct_name(cls) + ') ' + upper_first(type_name(prop.varname)) + '() ' + prop_type(prop) + '{\n' \
74+
return 'func (o *' + struct_name(cls) + ') ' + type_name(prop.varname) + '() ' + prop_type(prop) + '{\n' \
8075
+ ' return o.' + struct_prop_name(prop) + '\n' \
8176
+ '}'
8277

8378

8479
def struct_setter(cls, prop):
85-
return 'func (o *' + struct_name(cls) + ') Set' + upper_first(type_name(prop.varname)) + '(v ' + setter_prop_type(prop) + ') error{\n' \
80+
return 'func (o *' + struct_name(cls) + ') Set' + type_name(prop.varname) + '(v ' + setter_prop_type(prop) + ') error{\n' \
8681
+ ' o.' + struct_prop_name(prop) + ' = v\n' \
8782
+ ' return nil\n' \
8883
+ '}'
@@ -110,23 +105,12 @@ def include_prop(classes, cls, prop):
110105
return not parent_has_prop(classes, cls, prop)
111106

112107

113-
def lower_first(str):
114-
return str[0].lower() + str[1:]
115108

116109

117110
def interface_name(cls):
118-
return upper_first(type_name(cls.clsname))
119-
120-
121-
def struct_name(cls):
122-
name = lower_first(type_name(cls.clsname))
123-
if name in RESERVED_WORDS:
124-
return name + "Impl"
125-
return name
111+
return type_name(cls.clsname)
126112

127113

128-
def upper_first(str):
129-
return str[0].upper() + str[1:]
130114

131115

132116
def indent(indent_with, str):
@@ -151,9 +135,9 @@ def get_arguments(cls, parser):
151135

152136
def get_extra_env(self):
153137
return {
154-
"export": export,
155138
"type_name": type_name,
156-
"struct_prop": struct_prop,
139+
"interface_method": interface_method,
140+
"struct_prop_name": struct_prop_name,
157141
"struct_name": struct_name,
158142
"struct_getter": struct_getter,
159143
"struct_setter": struct_setter,
@@ -163,6 +147,7 @@ def get_extra_env(self):
163147
"include_prop": include_prop,
164148
"indent": indent,
165149
"comment": comment,
150+
"DATATYPES": DATATYPES,
166151
}
167152

168153
def get_additional_render_args(self):

src/shacl2code/lang/templates/golang.j2

Lines changed: 69 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -9,155 +9,111 @@
99
{%- macro array(prop) %}
1010
{%- if prop.max_count and prop.max_count >= 1 -%}
1111
[]
12-
{%- endif %}
12+
{%- endif -%}
1313
{%- endmacro %}
1414

15-
{%- macro struct_props(class) %}
16-
{%- for parent in class.parent_ids %}
17-
{{ struct_props(classes.get(parent)) }}
18-
{%- endfor %}
19-
20-
// ---------- {{ type_name(class.clsname) }} --------
21-
{%- for prop in class.properties %}
22-
{%- if include_prop(classes,class,prop) %}
23-
{{ struct_prop(prop) }}
24-
{%- endif %}
25-
{%- endfor %}
15+
{%- macro many(prop) %}
16+
{%- if prop.max_count and prop.max_count >= 1 -%}
17+
...
18+
{%- endif -%}
2619
{%- endmacro %}
2720

28-
{%- macro struct_funcs(base,class) %}
29-
{%- for parent in class.parent_ids %}
30-
{{ struct_funcs(base,classes.get(parent)) }}
31-
{%- endfor %}
32-
33-
// ---------- {{ type_name(class.clsname) }} --------
34-
{%- for prop in class.properties %}
35-
{%- if include_prop(classes,class,prop) %}
36-
37-
{{ struct_getter(base,prop) }}
38-
39-
{{ struct_setter(base,prop) }}
21+
{%- macro prop_type(prop) %}
22+
{%- if prop.class_id -%}
23+
{{ type_name(classes.get(prop.class_id).clsname) }}
24+
{%- else -%}
25+
{{ DATATYPES[prop.datatype] }}
4026
{%- endif %}
41-
{%- endfor %}
4227
{%- endmacro %}
4328

44-
{%- macro interface_props(class) -%}
45-
{%- for parent in class.parent_ids %}
46-
{{ interface_name(classes.get(parent)) }}
47-
{%- endfor %}
48-
49-
{%- for prop in class.properties %}
50-
{%- if include_prop(classes,class,prop) %}
51-
52-
{{ comment(" // ", struct_prop(prop), prop.comment) }}
53-
{{ interface_getter(prop) }}
29+
{%- macro namedind(class) %}
30+
type {{ type_name(class.clsname) }} struct {
31+
ObjRef {{ type_name(class.clsname) }}Ref
32+
}
33+
{%- endmacro %}
5434

55-
{{ interface_setter(prop) }}
56-
{%- endif %}
57-
{%- endfor %}
35+
{%- macro interface(class) %}
36+
type {{ type_name(class.clsname) }} interface {
37+
{% for parent in class.parent_ids %}
38+
{{ type_name(classes.get(parent).clsname) }}
39+
{% endfor %}
40+
{% for prop in class.properties %}
41+
{{ interface_method(prop.varname) }}() {{ array(prop) }}{{ prop_type(prop) }}
42+
Set{{ interface_method(prop.varname) }}(p {{ many(prop) }}{{ prop_type(prop) }}) error
43+
{% endfor %}
44+
}
5845
{%- endmacro %}
5946

60-
{%- macro interface_constructor(class) %}
61-
func New{{ interface_name(class) }}() {{ interface_name(class) }} {
62-
return &{{ struct_name(class) }}{}
47+
{%- macro struct(class) %}
48+
type {{ struct_name(class.clsname) }} struct {
49+
{% for parent in class.parent_ids %}
50+
//-----------{{ type_name(classes.get(parent).clsname) }}--------
51+
{% for prop in classes.get(parent).properties %}
52+
{{ struct_prop_name(prop.varname) }} {{ array(prop) }}{{ prop_type(prop) }}
53+
{% endfor %}
54+
{% endfor %}
55+
{% if not class.named_individuals %}
56+
{% for prop in class.properties %}
57+
{{ struct_prop_name(prop.varname) }} {{ array(prop) }}{{ prop_type(prop) }}
58+
{% endfor %}
59+
{% endif %}
6360
}
6461
{%- endmacro %}
6562

66-
{%- macro datatype(prop) %}
67-
{%- if prop.class_id -%}
68-
{{ export(classes.get(prop.class_id).clsname) }}
69-
{%- else -%}
70-
{{ DATATYPES[prop.datatype] }}
71-
{%- endif %}
63+
{%- macro constructor(class) %}
64+
func New{{ type_name(class.clsname) }}() {{ type_name(class.clsname) }} {
65+
return &{{ struct_name(class.clsname) }}{}
66+
}
7267
{%- endmacro %}
7368

74-
{%- macro interface(class) -%}
75-
type {{ export(class.clsname) }} interface {
69+
{%- macro func(class) %}
7670
{%- for prop in class.properties %}
77-
{{ export(prop.varname) }}() {{ array(prop) }}{{ datatype(prop) }}
78-
{%- endfor %}
71+
func (o * {{ type_name(class.clsname) }}) {{ interface_method(prop.varname) }}() {{ prop_type(prop) }}{
72+
return o.{{ struct_prop_name(prop.varname) }}
7973
}
80-
{% endmacro %}
8174

82-
{%- macro struct(class) -%}
83-
type {{ export(class.clsname) }} struct {
84-
{%- for prop in class.properties %}
75+
func (o *{{ type_name(class.clsname) }}) Set{{ interface_method(prop.varname) }}(v {{ prop_type(prop) }}) error {
76+
o.{{ struct_prop_name(prop.varname) }} = v
77+
return nil
8578
}
8679
{%- endfor %}
8780
{%- endmacro %}
8881

8982
{# go file content #}
9083
package spdx_v{{ module }}
9184

92-
// XSD types that don't have a Go equivalent
93-
type PInt uint
94-
95-
func (p PInt) Check() PInt {
96-
if p == 0 {
97-
panic("0 Assignment not allowed for PInt")
98-
}
99-
return p
100-
}
101-
102-
type DateTime string
103-
104-
type DateTimeStamp string
105-
106-
// Named Individuals handling
85+
// NAMED INDIVIDUALS
10786

10887
{%- for class in classes %}
10988
{%- if class.named_individuals %}
110-
111-
type {{ type_name(class.clsname) }} string
89+
type {{ type_name(class.clsname) }}Ref string
11290
var (
11391
{%- for ind in class.named_individuals %}
114-
{{ type_name(class.clsname) }}{{ type_name(ind.varname) }} {{ type_name(class.clsname) }} = "{{ ind._id }}"
92+
{{ type_name(class.clsname) }}{{ ind.varname }} {{ type_name(class.clsname) }}Ref = "{{ ind._id }}"
11593
{%- endfor %}
11694
)
11795
{%- endif %}
11896
{%- endfor %}
11997

120-
{% set
121-
DATATYPES = {
122-
"http://www.w3.org/2001/XMLSchema#string": "string",
123-
"http://www.w3.org/2001/XMLSchema#anyURI": "string",
124-
"http://www.w3.org/2001/XMLSchema#integer": "int",
125-
"http://www.w3.org/2001/XMLSchema#positiveInteger": "PInt",
126-
"http://www.w3.org/2001/XMLSchema#nonNegativeInteger": "uint",
127-
"http://www.w3.org/2001/XMLSchema#boolean": "bool",
128-
"http://www.w3.org/2001/XMLSchema#decimal": "float64",
129-
"http://www.w3.org/2001/XMLSchema#dateTime": "DateTime",
130-
"http://www.w3.org/2001/XMLSchema#dateTimeStamp": "DateTimeStamp",
131-
}
132-
%}
98+
// INTERFACES
13399

134-
{#var CONTEXT_URLS [{{ context.urls|length }}]string = [{{ context.urls|length }}]string{#}
135-
{# {%- for url in context.urls %}"{{ url }}"{{ ',' if not loop.last }}{%- endfor %}}#}
136-
{##}
137-
{#// CLASSES AND INTERFACES#}
100+
{% for class in classes %}
101+
{% if class.named_individuals %}
102+
{{ namedind(class) }}
103+
{% else %}
104+
{{ interface(class) }}
105+
{% endif %}
106+
{% endfor %}
138107

139-
{%- for class in classes %}
140-
{%- if not class.named_individuals %}
141-
type {{ interface_name(class) }} interface {
142-
{{ interface_props(class) }}
143-
}
144-
{%- if not class.is_abstract %}
145-
146-
type {{ struct_name(class) }} struct {
147-
{#- {%- if class.parent_ids %}#}
148-
{#- {%- for parent in class.parent_ids %}#}
149-
{#- {{ export(classes.get(parent).clsname) }}#}
150-
{#- {%- endfor %}#}
151-
{#- {%- endif %}#}
152-
{{ struct_props(class) }}
153-
{#- {%- if class.named_individuals %}#}
154-
{#- ObjectRef {{ export(class.clsname) }}Ref#}
155-
{#- {%- endif %}#}
156-
}
108+
// STRUCTS AND CONSTRUCTORS
157109

158-
{{ interface_constructor(class) }}
110+
{% for class in concrete_classes %}
111+
{{ struct(class) }}
112+
{{ constructor(class) }}
113+
{% endfor %}
159114

160-
{{ struct_funcs(class,class) }}
161-
{%- endif %}
162-
{%- endif %}
163-
{%- endfor %}
115+
// IMPLEMENTATIONS
116+
117+
{% for class in concrete_classes %}
118+
{{ func(class) }}
119+
{% endfor %}

0 commit comments

Comments
 (0)