Skip to content

Commit ee92ee6

Browse files
pmderodatRoldak
authored andcommitted
Update code generation to account for null syntax fields
TN: R925-010
1 parent ef1acb1 commit ee92ee6

12 files changed

+63
-35
lines changed

langkit/compiled_types.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2275,8 +2275,9 @@ def set_types(self, types):
22752275
22762276
:type types: list[CompiledType]
22772277
"""
2278-
fields = self.get_parse_fields(predicate=lambda f: not f.abstract,
2279-
concrete_order=True)
2278+
fields = self.get_parse_fields(
2279+
predicate=lambda f: not f.abstract and not f.null,
2280+
concrete_order=True)
22802281

22812282
check_source_language(
22822283
len(fields) == len(types), '{} has {} fields ({} types given). You'

langkit/expressions/structs.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -321,9 +321,16 @@ def error_if_not_empty(name_set, message):
321321
# Create a dict of field names to fields in the struct type
322322

323323
def is_required(f):
324-
return (self.struct_type.is_struct_type
325-
if isinstance(f, BuiltinField) else
326-
isinstance(f, (Field, UserField)))
324+
if isinstance(f, BuiltinField):
325+
# BuiltinFields are actually stored fields only for structure
326+
# types (not for nodes).
327+
return self.struct_type.is_struct_type
328+
329+
elif isinstance(f, Field):
330+
return not f.null
331+
332+
else:
333+
return isinstance(f, UserField)
327334

328335
required_fields = {
329336
f._name.lower: f

langkit/parsers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1579,7 +1579,7 @@ def compute_fields_types(self):
15791579
# fields in the destination node are the same.
15801580
nb_transform_values = len(fields_types)
15811581
nb_fields = len(typ.get_parse_fields(
1582-
predicate=lambda f: not f.abstract))
1582+
predicate=lambda f: not f.abstract and not f.null))
15831583
check_source_language(
15841584
nb_transform_values == nb_fields,
15851585
'Transform parser generates {} values, but {} has {} fields'

langkit/templates/astnode_types_ada.mako

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,18 @@
8686
% if field.abstract:
8787
case ${field.struct.ada_kind_name} (Node.Kind) is
8888
% for cf in field.concrete_fields:
89-
when ${cf.struct.ada_kind_name} =>
90-
declare
91-
N : constant ${cf.struct.name} :=
92-
${cf.struct.name} (Node);
93-
begin
94-
${return_value('N')}
95-
end;
89+
when ${' | '.join(n.ada_kind_name
90+
for n in cf.struct.concrete_subclasses)} =>
91+
% if cf.null:
92+
return ${cf.type.nullexpr};
93+
% else:
94+
declare
95+
N : constant ${cf.struct.name} :=
96+
${cf.struct.name} (Node);
97+
begin
98+
${return_value('N')}
99+
end;
100+
% endif
96101
% endfor
97102
end case;
98103
% else:
@@ -173,7 +178,9 @@
173178
<%
174179
fields = cls.get_fields(
175180
include_inherited=False,
176-
predicate=lambda f: f.should_emit and not f.abstract)
181+
predicate=lambda f: (f.should_emit and
182+
not f.abstract and
183+
not f.null))
177184
ext = ctx.ext('nodes', cls.raw_name, 'components')
178185
%>
179186
% if fields:

langkit/templates/parsers/transform_code_ada.mako

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ if ${parser.pos_var} /= No_Token_Index then
3838
else ${parser.pos_var} - 1);
3939
<% fields_n_args = zip(
4040
parser.get_type().get_parse_fields(
41-
predicate=lambda f: not f.abstract,
41+
predicate=lambda f: not f.abstract and not f.null,
4242
concrete_order=True),
4343
args) %>
4444

langkit/templates/pkg_analysis_body_ada.mako

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ package body ${ada_lib_name}.Analysis is
718718

719719
% for f in e.element_type.get_parse_fields( \
720720
include_inherited=False, \
721-
predicate=lambda f: f.is_public \
721+
predicate=lambda f: f.is_public and not f.overriding \
722722
):
723723
${astnode_types.field_body(f)}
724724
% endfor

langkit/templates/pkg_implementation_body_ada.mako

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2290,7 +2290,7 @@ package body ${ada_lib_name}.Implementation is
22902290
22912291
def get_actions(astnode, node_expr):
22922292
specific_fields = astnode.get_parse_fields(
2293-
lambda f: not f.abstract,
2293+
lambda f: not f.abstract and not f.null,
22942294
include_inherited=False
22952295
)
22962296
@@ -2315,7 +2315,7 @@ package body ${ada_lib_name}.Implementation is
23152315
elif specific_fields:
23162316
# Compute the index of the first AST node field we handle here
23172317
all_fields = astnode.get_parse_fields(
2318-
lambda f: not f.abstract,
2318+
lambda f: not f.abstract and not f.null,
23192319
include_inherited=True
23202320
)
23212321
first_field_index = len(all_fields) - len(specific_fields) + 1

langkit/templates/pkg_implementation_spec_ada.mako

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ private package ${ada_lib_name}.Implementation is
381381
(${', \n'.join(
382382
'{} => {}'.format(
383383
cls.ada_kind_name,
384-
(len(cls.get_parse_fields(lambda f: f.type.is_ast_node))
384+
(len(cls.get_parse_fields(lambda f: not f.null))
385385
if not cls.is_list_type else -1)
386386
)
387387
for cls in ctx.astnode_types if not cls.abstract)});

langkit/templates/pkg_introspection_body_ada.mako

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ package body ${ada_lib_name}.Introspection is
4545
% for n in concrete_astnodes:
4646
when ${n.ada_kind_name} =>
4747
return (case Field is
48-
% for f in n.get_parse_fields(concrete_order=True):
48+
% for f in n.get_parse_fields( \
49+
predicate=lambda f: not f.null, \
50+
concrete_order=True \
51+
):
4952
when ${enum_literal(f)} => ${f.index + 1},
5053
% endfor
5154
when others => raise Constraint_Error);
@@ -68,7 +71,7 @@ package body ${ada_lib_name}.Introspection is
6871
<%
6972
def get_actions(astnode, node_expr):
7073
fields = astnode.get_parse_fields(
71-
predicate=lambda f: not f.abstract,
74+
predicate=lambda f: not f.abstract and not f.null,
7275
include_inherited=False
7376
)
7477
result = []

langkit/templates/pkg_iterators_body_ada.mako

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -449,23 +449,29 @@ package body ${ada_lib_name}.Iterators is
449449
--------------
450450

451451
overriding function Evaluate
452-
(P : in out Child_With_Predicate; N : ${node}) return Boolean
453-
is
454-
Field_Index : Positive;
452+
(P : in out Child_With_Predicate; N : ${node}) return Boolean is
455453
begin
456454
if N.Is_Null then
457455
return False;
458456
end if;
459457

460-
-- First check that N has the requested field
461-
begin
462-
Field_Index := Index (N.Kind, P.Field);
463-
exception
464-
when Invalid_Field =>
465-
return False;
466-
end;
467-
468-
return P.Predicate.Unchecked_Get.Evaluate (N.Child (Field_Index));
458+
% if ctx.sorted_parse_fields:
459+
declare
460+
Field_Index : Positive;
461+
begin
462+
-- First check that N has the requested field
463+
begin
464+
Field_Index := Index (N.Kind, P.Field);
465+
exception
466+
when Invalid_Field =>
467+
return False;
468+
end;
469+
470+
return P.Predicate.Unchecked_Get.Evaluate (N.Child (Field_Index));
471+
end;
472+
% else:
473+
return False;
474+
% endif
469475
end Evaluate;
470476

471477
--------------

0 commit comments

Comments
 (0)