@@ -192,11 +192,13 @@ public
192192 array< InstNode > classes;
193193 array< InstNode > components;
194194 array< InstNode > imports;
195+ DuplicateTree . Tree duplicates;
195196 end FLAT_TREE ;
196197
197198 function fromSCode
198199 "Creates a new class tree from a list of SCode elements."
199200 input list< SCode . Element > elements;
201+ input Boolean isClassExtends;
200202 input InstNode parent;
201203 output ClassTree tree;
202204 protected
@@ -210,16 +212,32 @@ public
210212 algorithm
211213 ltree := LookupTree . new();
212214
213- // Count the elements and create arrays for them. We can't do this for
214- // imports though, since an import clause might import multiple elements.
215+ // Count the different types of elements.
215216 (clsc, compc, extc) := countElements(elements);
217+
218+ // If the class is a class extends, reserve space for the extends.
219+ if isClassExtends then
220+ extc := extc + 1 ;
221+ end if ;
222+
223+ // Preallocate arrays for the elements. We can't do this for imports
224+ // though, since an import clause might import multiple elements.
216225 clss := arrayCreateNoInit(clsc, InstNode . EMPTY_NODE ());
217226 comps := arrayCreateNoInit(compc + extc, InstNode . EMPTY_NODE ());
218227 exts := arrayCreateNoInit(extc, InstNode . EMPTY_NODE ());
219228 dups := DuplicateTree . new();
220229 // Make a temporary class tree so we can do lookup for error reporting.
221230 tree := PARTIAL_TREE (ltree, clss, comps, exts, listArray({}), dups);
222231
232+ // If the class is a class extends, fill in the first extends with an
233+ // empty node so we don't have unassigned memory after this step.
234+ if isClassExtends then
235+ exts[1 ] := InstNode . EMPTY_NODE ();
236+ comps[1 ] := InstNode . REF_NODE (1 );
237+ ext_idx := ext_idx + 1 ;
238+ comp_idx := comp_idx + 1 ;
239+ end if ;
240+
223241 for e in elements loop
224242 () := match e
225243 // A class, add it to the class array and add an entry in the lookup tree.
@@ -232,7 +250,7 @@ public
232250
233251 // If the class is an element redeclare, add an entry in the duplicate
234252 // tree so we can check later that it actually redeclares something.
235- if SCode . isElementRedeclare(e) then
253+ if SCode . isElementRedeclare(e) or SCode . isClassExtends(e) then
236254 dups := DuplicateTree . add(dups, e. name, DuplicateTree . newRedeclare(lentry));
237255 end if ;
238256 then
@@ -324,7 +342,7 @@ public
324342 end for ;
325343
326344 // Enumerations can't contain extends, so we can go directly to a flat tree here.
327- tree := FLAT_TREE (ltree, listArray({}), comps, listArray({}));
345+ tree := FLAT_TREE (ltree, listArray({}), comps, listArray({}), DuplicateTree . EMPTY () );
328346 end fromEnumeration;
329347
330348 function expand
@@ -577,7 +595,7 @@ public
577595 flatten2(tree. classes, clss, dup_cls);
578596 flatten2(tree. components, comps, dup_comp);
579597 then
580- FLAT_TREE (tree. tree, clss, comps, tree. imports);
598+ FLAT_TREE (tree. tree, clss, comps, tree. imports, tree . duplicates );
581599
582600 else tree;
583601 end match;
@@ -810,8 +828,13 @@ public
810828 // A redeclare element without an element to replace.
811829 case DuplicateTree . EntryType . REDECLARE guard listEmpty(entry. children)
812830 algorithm
813- Error . addSourceMessage(Error . REDECLARE_NONEXISTING_ELEMENT ,
814- {name}, InstNode . info(kept));
831+ if SCode . isClassExtends(InstNode . definition(kept)) then
832+ Error . addSourceMessage(Error . CLASS_EXTENDS_TARGET_NOT_FOUND ,
833+ {name}, InstNode . info(kept));
834+ else
835+ Error . addSourceMessage(Error . REDECLARE_NONEXISTING_ELEMENT ,
836+ {name}, InstNode . info(kept));
837+ end if ;
815838 then
816839 fail();
817840
@@ -839,6 +862,35 @@ public
839862 algorithm
840863 identical := true ;
841864 end isIdentical;
865+
866+ function getRedeclaredNode
867+ input String name;
868+ input ClassTree tree;
869+ output InstNode node;
870+ protected
871+ DuplicateTree . Entry entry;
872+ algorithm
873+ try
874+ entry := DuplicateTree . get(getDuplicates(tree), name);
875+ entry := listHead(entry. children);
876+
877+ if isSome(entry. node) then
878+ SOME (node) := entry. node;
879+ else
880+ node := resolveEntry(entry. entry, tree);
881+ end if ;
882+ else
883+ assert (false , getInstanceName() + " failed on " + name);
884+ end try ;
885+ end getRedeclaredNode;
886+
887+ function setClassExtends
888+ input InstNode extNode;
889+ input output ClassTree tree;
890+ algorithm
891+ arrayUpdate(getExtends(tree), 1 , extNode);
892+ end setClassExtends;
893+
842894 protected
843895
844896 function instExtendsComps
@@ -869,6 +921,18 @@ public
869921 end match;
870922 end getExtends;
871923
924+ function getDuplicates
925+ input ClassTree tree;
926+ output DuplicateTree . Tree duplicates;
927+ algorithm
928+ duplicates := match tree
929+ case PARTIAL_TREE () then tree. duplicates;
930+ case EXPANDED_TREE () then tree. duplicates;
931+ case INSTANTIATED_TREE () then tree. duplicates;
932+ case FLAT_TREE () then tree. duplicates;
933+ end match;
934+ end getDuplicates;
935+
872936 function lookupTree
873937 input ClassTree ctree;
874938 output LookupTree . Tree ltree;
0 commit comments