66
77package viper .silver .ast .utility .rewriter
88
9- import viper .silver .parser .{PDomain , PDomainFunction , PFields , PFunction , PMethod , PPredicate }
10- import viper .silver .parser .Transformer .ParseTreeDuplicationError
9+ import viper .silver .parser .PNode
1110import viper .silver .ast .{AtomicType , BackendFuncApp , DomainFuncApp , ErrorTrafo , FuncApp , Info , Node , Position }
1211
1312import scala .reflect .runtime .{universe => reflection }
1413
14+ trait HasExtraValList {
15+ def getExtraVals : Seq [Any ]
16+ }
17+ trait HasExtraVars {
18+ def copyExtraVars (from : Any ): Unit
19+ }
20+
1521/**
1622 * Trait Rewritable provides an interface that specifies which methods are required for the rewriter to work with.
1723 * For classes that implement product (especially case classes) everything is already implemented here and one only has to extend this base class
@@ -37,27 +43,26 @@ trait Rewritable extends Product {
3743 val constructorMirror = classMirror.reflectConstructor(constructorSymbol)
3844
3945 // Add additional arguments to constructor call, besides children
40- var firstArgList = children
46+ val firstArgList = children
4147 var secondArgList = Seq .empty[Any ]
4248 import viper .silver .ast .{DomainType , DomainAxiom , FuncApp , DomainFunc , DomainFuncApp }
43- import viper .silver .parser .{PAxiom , PMagicWandExp , PNode , PDomainType }
4449 this match {
50+ // TODO: remove the following cases by implementing `HasExtraValList` on the respective classes
4551 case dt : DomainType => secondArgList = Seq (dt.typeParameters)
4652 case da : DomainAxiom => secondArgList = Seq (da.pos, da.info, da.domainName, da.errT)
4753 case fa : FuncApp => secondArgList = Seq (fa.pos, fa.info, fa.typ, fa.errT)
4854 case df : DomainFunc => secondArgList = Seq (df.pos, df.info, df.domainName, df.errT)
4955 case df : DomainFuncApp => secondArgList = Seq (df.pos, df.info, df.typ, df.domainName, df.errT)
5056 case ba : BackendFuncApp => secondArgList = Seq (ba.pos, ba.info, ba.typ, ba.interpretation, ba.errT)
5157 case no : Node => secondArgList = no.getMetadata
52- case pa : PAxiom => secondArgList = Seq (pa.domainName) ++ Seq (pos.getOrElse(pa.pos), pa.annotations)
53- case pm : PMagicWandExp => firstArgList = Seq (children.head) ++ children.drop(2 ) ++ Seq (pos.getOrElse(pm.pos))
54- case pd : PDomainFunction => secondArgList = Seq (pd.domainName) ++ Seq (pos.getOrElse(pd.pos), pd.annotations)
55- case pd : PDomain => secondArgList = Seq (pos.getOrElse(pd.pos), pd.annotations)
56- case pm : PMethod => secondArgList = Seq (pos.getOrElse(pm.pos), pm.annotations)
57- case pp : PPredicate => secondArgList = Seq (pos.getOrElse(pp.pos), pp.annotations)
58- case pf : PFunction => secondArgList = Seq (pos.getOrElse(pf.pos), pf.annotations)
59- case pf : PFields => secondArgList = Seq (pos.getOrElse(pf.pos), pf.annotations)
60- case pn : PNode => secondArgList = Seq (pos.getOrElse(pn.pos))
58+
59+ case evl : HasExtraValList => {
60+ secondArgList = evl.getExtraVals.map(ev => {
61+ // Replace positions with the new one
62+ val replace = pos.isDefined && ev.isInstanceOf [(_, _)] && ev.asInstanceOf [(_, _)]._1.isInstanceOf [Position ] && ev.asInstanceOf [(_, _)]._2.isInstanceOf [Position ]
63+ if (replace) pos.get else ev
64+ })
65+ }
6166 case _ =>
6267 }
6368
@@ -69,9 +74,9 @@ trait Rewritable extends Product {
6974 }
7075
7176 // Copy member values, as they aren't in the parameters' list.
72- this match {
73- case dt : PDomainType =>
74- newNode. asInstanceOf [ PDomainType ].kind = dt.kind
77+ newNode match {
78+ case ev : HasExtraVars =>
79+ ev.copyExtraVars( this )
7580 case _ =>
7681 }
7782
@@ -116,4 +121,9 @@ trait Rewritable extends Product {
116121 newNode.asInstanceOf [this .type ]
117122 }
118123 }
124+
125+ def initProperties (): Unit = ()
119126}
127+
128+ case class ParseTreeDuplicationError (original : PNode , newChildren : Seq [Any ])
129+ extends RuntimeException (s " Cannot duplicate $original with new children $newChildren" )
0 commit comments