@@ -11,18 +11,7 @@ public class ZserioAstTypeResolver extends ZserioAstWalker
11
11
@ Override
12
12
public void visitSubtype (Subtype subtype )
13
13
{
14
- if (!subtypesOnStack .isEmpty () && subtypesOnStack .get (0 ).equals (subtype ))
15
- {
16
- final ParserStackedException stackedException = new ParserStackedException (subtype .getLocation (),
17
- "Cyclic dependency detected in subtype '" + subtype .getName () + "' definition!" );
18
- for (int i = 1 ; i < subtypesOnStack .size (); ++i )
19
- {
20
- final Subtype subtypeOnStack = subtypesOnStack .get (i );
21
- stackedException .pushMessage (subtypeOnStack .getLocation (),
22
- " Through subtype '" + subtypeOnStack .getName () + "' here" );
23
- }
24
- throw stackedException ;
25
- }
14
+ checkCycle (subtypesOnStack , subtype , "subtype" );
26
15
27
16
subtypesOnStack .add (subtype );
28
17
@@ -63,6 +52,7 @@ public void visitTypeReference(TypeReference typeReference)
63
52
typeReference .resolve (templateParameters );
64
53
65
54
// make sure that typeReference.getBaseTypeReference() can be called after this resolve
55
+ // note: this can cause cycles which are guarded by subtypesOnStack and instantiateTypesOnStack
66
56
final ZserioType type = typeReference .getType ();
67
57
if (type instanceof Subtype || type instanceof InstantiateType )
68
58
type .accept (this );
@@ -78,8 +68,15 @@ public void visitTypeInstantiation(TypeInstantiation typeInstantiation)
78
68
@ Override
79
69
public void visitInstantiateType (InstantiateType instantiateType )
80
70
{
71
+ // cannot be checked in resolve since the cycle happens via visitChildren
72
+ checkCycle (instantiateTypesOnStack , instantiateType , "template instantiation" );
73
+
74
+ instantiateTypesOnStack .add (instantiateType );
75
+
81
76
instantiateType .visitChildren (this );
82
77
instantiateType .resolve ();
78
+
79
+ instantiateTypesOnStack .remove (instantiateTypesOnStack .size () - 1 );
83
80
}
84
81
85
82
private void visitType (TemplatableType templatableType )
@@ -91,6 +88,23 @@ private void visitType(TemplatableType templatableType)
91
88
templateParameters = null ;
92
89
}
93
90
91
+ private <T extends ZserioType > void checkCycle (List <T > typesOnStack , T type , String typeName )
92
+ {
93
+ if (!typesOnStack .isEmpty () && typesOnStack .get (0 ) == type )
94
+ {
95
+ final ParserStackedException stackedException = new ParserStackedException (type .getLocation (),
96
+ "Cyclic dependency detected in " + typeName + " '" + type .getName () + "'!" );
97
+ for (int i = 1 ; i < typesOnStack .size (); ++i )
98
+ {
99
+ final T typeOnStack = typesOnStack .get (i );
100
+ stackedException .pushMessage (typeOnStack .getLocation (),
101
+ " Through " + typeName + " '" + typeOnStack .getName () + "' here" );
102
+ }
103
+ throw stackedException ;
104
+ }
105
+ }
106
+
94
107
private final List <Subtype > subtypesOnStack = new ArrayList <Subtype >();
108
+ private final List <InstantiateType > instantiateTypesOnStack = new ArrayList <InstantiateType >();
95
109
private List <TemplateParameter > templateParameters = null ;
96
110
}
0 commit comments