@@ -28,7 +28,7 @@ private predicate shouldPrint(Locatable e) { any(PrintAstConfiguration config).s
2828/**
2929 * An AST node that should be printed.
3030 */
31- private newtype TPrintAstNode = TLocatable ( Locatable ast )
31+ private newtype TPrintAstNode = TPrintLocatable ( Locatable ast )
3232
3333/**
3434 * A node in the output tree.
@@ -60,6 +60,11 @@ class PrintAstNode extends TPrintAstNode {
6060 * the property is `key`.
6161 */
6262 string getProperty ( string key ) { none ( ) }
63+
64+ /**
65+ * Gets the underlying AST node, if any.
66+ */
67+ abstract Locatable getAstNode ( ) ;
6368}
6469
6570private string prettyPrint ( Locatable e ) {
@@ -73,10 +78,10 @@ private class Unresolved extends Locatable {
7378/**
7479 * A graph node representing a real Locatable node.
7580 */
76- class PrintLocatable extends PrintAstNode , TLocatable {
81+ class PrintLocatable extends PrintAstNode , TPrintLocatable {
7782 Locatable ast ;
7883
79- PrintLocatable ( ) { this = TLocatable ( ast ) }
84+ PrintLocatable ( ) { this = TPrintLocatable ( ast ) }
8085
8186 override string toString ( ) { result = prettyPrint ( ast ) }
8287
@@ -87,9 +92,9 @@ class PrintLocatable extends PrintAstNode, TLocatable {
8792 c = getChildAndAccessor ( ast , i , accessor ) and
8893 (
8994 // use even indexes for normal children, leaving odd slots for conversions if any
90- child = TLocatable ( c ) and index = 2 * i and label = accessor
95+ child = TPrintLocatable ( c ) and index = 2 * i and label = accessor
9196 or
92- child = TLocatable ( c .getFullyUnresolved ( ) .( Unresolved ) ) and
97+ child = TPrintLocatable ( c .getFullyUnresolved ( ) .( Unresolved ) ) and
9398 index = 2 * i + 1 and
9499 (
95100 if c instanceof Expr
@@ -100,6 +105,8 @@ class PrintLocatable extends PrintAstNode, TLocatable {
100105 )
101106 }
102107
108+ final override Locatable getAstNode ( ) { result = ast }
109+
103110 final override Location getLocation ( ) { result = ast .getLocation ( ) }
104111}
105112
@@ -112,17 +119,38 @@ class PrintUnresolved extends PrintLocatable {
112119
113120 override predicate hasChild ( PrintAstNode child , int index , string label ) {
114121 // only print immediate unresolved children from the "parallel" AST
115- child = TLocatable ( getImmediateChildAndAccessor ( ast , index , label ) .( Unresolved ) )
122+ child = TPrintLocatable ( getImmediateChildAndAccessor ( ast , index , label ) .( Unresolved ) )
116123 }
117124}
118125
126+ private predicate hasPropertyWrapperElement ( VarDecl d , Locatable a ) {
127+ a = [ d .getPropertyWrapperBackingVar ( ) , d .getPropertyWrapperProjectionVar ( ) ] or
128+ a = [ d .getPropertyWrapperBackingVarBinding ( ) , d .getPropertyWrapperProjectionVarBinding ( ) ]
129+ }
130+
119131/**
120- * A specialization of graph node for `VarDecl`, to add typing information.
132+ * A specialization of graph node for `VarDecl`, to add typing information and deal with ambiguity
133+ * over property wrapper children.
121134 */
122135class PrintVarDecl extends PrintLocatable {
123136 override VarDecl ast ;
124137
125138 override string getProperty ( string key ) { key = "Type" and result = ast .getType ( ) .toString ( ) }
139+
140+ override predicate hasChild ( PrintAstNode child , int index , string label ) {
141+ PrintLocatable .super .hasChild ( child , index , label ) and
142+ // exclude property wrapper related children when they are already listed in the enclosing
143+ // nominal type declaration or for a wrapped parameter for which this is a virtual local variable copy
144+ not exists ( Locatable childAst |
145+ childAst = child .getAstNode ( ) and
146+ hasPropertyWrapperElement ( ast , childAst ) and
147+ (
148+ childAst = ast .getDeclaringDecl ( ) .getAMember ( )
149+ or
150+ ast instanceof ConcreteVarDecl and hasPropertyWrapperElement ( any ( ParamDecl p ) , childAst )
151+ )
152+ )
153+ }
126154}
127155
128156/**
@@ -135,3 +163,23 @@ class PrintFunction extends PrintLocatable {
135163 key = "InterfaceType" and result = ast .getInterfaceType ( ) .toString ( )
136164 }
137165}
166+
167+ /**
168+ * A specialization of graph node for `PatternBindingDecl`, to solve ambiguity on `getInit`.
169+ * When a property wrapper is involved, `getInit` may become shared between the explicit binding and
170+ * the implicit compiler synthesized one.
171+ */
172+ class PrintPatternBindingDecl extends PrintLocatable {
173+ override PatternBindingDecl ast ;
174+
175+ override predicate hasChild ( PrintAstNode child , int index , string label ) {
176+ PrintLocatable .super .hasChild ( child , index , label ) and
177+ // exclude `getInit` that are already the initializer of a variable that has this as a property wrapper backer
178+ not exists ( Expr init , VarDecl var |
179+ init = child .getAstNode ( ) and
180+ init = ast .getAnInit ( ) and
181+ var .getPropertyWrapperBackingVarBinding ( ) = ast and
182+ var .getParentInitializer ( ) = init
183+ )
184+ }
185+ }
0 commit comments