@@ -32,7 +32,7 @@ private string getSyntheticFieldToken(SyntheticFieldContent fc) {
3232/**
3333 * Returns a token suitable for incorporation into a Java method name describing content `c`.
3434 */
35- string contentToken ( Content c ) {
35+ private string contentToken ( Content c ) {
3636 c instanceof ArrayContent and result = "ArrayElement"
3737 or
3838 c instanceof CollectionContent and result = "Element"
@@ -49,4 +49,304 @@ string contentToken(Content c) {
4949/**
5050 * Returns the `content` wrapped by `component`, if any.
5151 */
52- Content getContent ( SummaryComponent component ) { component = SummaryComponent:: content ( result ) }
52+ private Content getContent ( SummaryComponent component ) {
53+ component = SummaryComponent:: content ( result )
54+ }
55+
56+ module SupportMethod {
57+ GenMethod genMethodForContent ( SummaryComponentStack c ) {
58+ result = min ( GenMethod g | g .appliesTo ( any ( VoidType v ) , getContent ( c .head ( ) ) ) )
59+ }
60+
61+ GenMethod genMethodFor ( Type t , SummaryComponentStack c ) {
62+ result = min ( GenMethod g | g .appliesTo ( t , getContent ( c .head ( ) ) ) )
63+ }
64+
65+ GetMethod getMethodForContent ( SummaryComponentStack c ) {
66+ result = min ( GetMethod g | g .appliesTo ( any ( VoidType v ) , getContent ( c .head ( ) ) ) )
67+ }
68+
69+ GetMethod getMethodFor ( Type t , SummaryComponentStack c ) {
70+ result = min ( GetMethod g | g .appliesTo ( t , getContent ( c .head ( ) ) ) )
71+ }
72+ }
73+
74+ bindingset [ this ]
75+ abstract class SupportMethod extends string {
76+ abstract predicate appliesTo ( Type t , Content c ) ;
77+
78+ string getARequiredImport ( ) { none ( ) }
79+
80+ string getDefinition ( ) { none ( ) }
81+
82+ bindingset [ this , arg]
83+ abstract string getCall ( string arg ) ;
84+
85+ /**
86+ * Gets the CSV row describing this support method if it is needed to set up the output for this test.
87+ *
88+ * For example, `newWithMapValue` will propagate a value from `Argument[0]` to `MapValue of ReturnValue`, and `getMapValue`
89+ * will do the opposite.
90+ */
91+ string getCsvModel ( ) { none ( ) }
92+ }
93+
94+ class SourceMethod extends SupportMethod {
95+ SourceMethod ( ) { this = "source" }
96+
97+ override predicate appliesTo ( Type t , Content c ) { none ( ) }
98+
99+ bindingset [ arg]
100+ override string getCall ( string arg ) {
101+ result = "source()" and
102+ // suppress unused variable warning
103+ arg = arg
104+ }
105+
106+ override string getDefinition ( ) { result = "Object source() { return null; }" }
107+ }
108+
109+ class SinkMethod extends SupportMethod {
110+ SinkMethod ( ) { this = "sink" }
111+
112+ override predicate appliesTo ( Type t , Content c ) { none ( ) }
113+
114+ bindingset [ arg]
115+ override string getCall ( string arg ) { result = "sink(" + arg + ")" }
116+
117+ override string getDefinition ( ) { result = "void sink(Object o) { }" }
118+ }
119+
120+ bindingset [ this ]
121+ abstract class GetMethod extends SupportMethod { }
122+
123+ private class DefaultGetMethod extends GetMethod {
124+ Content c ;
125+
126+ // prefix with zzz so the default getter is always last
127+ DefaultGetMethod ( ) { this = "zzzDefaultGet" + contentToken ( c ) }
128+
129+ string getName ( ) { result = "get" + contentToken ( c ) }
130+
131+ override predicate appliesTo ( Type t , Content c1 ) {
132+ c = c1 and
133+ // suppress unused variable warning
134+ t = t
135+ }
136+
137+ bindingset [ arg]
138+ override string getCall ( string arg ) { result = this .getName ( ) + "(" + arg + ")" }
139+
140+ override string getDefinition ( ) {
141+ result = "Object get" + contentToken ( c ) + "(Object container) { return null; }"
142+ }
143+
144+ override string getCsvModel ( ) {
145+ result =
146+ "generatedtest;Test;false;" + this .getName ( ) + ";;;" +
147+ getComponentSpec ( SummaryComponent:: content ( c ) ) + " of Argument[0];ReturnValue;value"
148+ }
149+ }
150+
151+ private class ListGetMethod extends GetMethod {
152+ ListGetMethod ( ) { this = "listgetmethod" }
153+
154+ override predicate appliesTo ( Type t , Content c ) {
155+ t .( RefType ) .getASourceSupertype * ( ) .hasQualifiedName ( "java.lang" , "Iterable" ) and
156+ c instanceof CollectionContent
157+ }
158+
159+ override string getDefinition ( ) {
160+ result = "<T> T getElement(Iterable<T> it) { return it.iterator().next(); }"
161+ }
162+
163+ bindingset [ arg]
164+ override string getCall ( string arg ) { result = "getElement(" + arg + ")" }
165+ }
166+
167+ private class IteratorGetMethod extends GetMethod {
168+ IteratorGetMethod ( ) { this = "iteratorgetmethod" }
169+
170+ override predicate appliesTo ( Type t , Content c ) {
171+ t .( RefType ) .getASourceSupertype * ( ) .hasQualifiedName ( "java.util" , "Iterator" ) and
172+ c instanceof CollectionContent
173+ }
174+
175+ override string getDefinition ( ) {
176+ result = "<T> T getElement(Iterator<T> it) { return it.next(); }"
177+ }
178+
179+ bindingset [ arg]
180+ override string getCall ( string arg ) { result = "getElement(" + arg + ")" }
181+ }
182+
183+ private class OptionalGetMethod extends GetMethod {
184+ OptionalGetMethod ( ) { this = "optionalgetmethod" }
185+
186+ override predicate appliesTo ( Type t , Content c ) {
187+ t .( RefType ) .getSourceDeclaration ( ) .hasQualifiedName ( "java.util" , "Optional" ) and
188+ c instanceof CollectionContent
189+ }
190+
191+ override string getDefinition ( ) { result = "<T> T getElement(Optional<T> o) { return o.get(); }" }
192+
193+ bindingset [ arg]
194+ override string getCall ( string arg ) { result = "getElement(" + arg + ")" }
195+ }
196+
197+ private class MapGetKeyMethod extends GetMethod {
198+ MapGetKeyMethod ( ) { this = "mapgetkeymethod" }
199+
200+ override predicate appliesTo ( Type t , Content c ) {
201+ t .( RefType ) .getASourceSupertype * ( ) .hasQualifiedName ( "java.util" , "Map" ) and
202+ c instanceof MapKeyContent
203+ }
204+
205+ override string getDefinition ( ) {
206+ result = "<K> K getMapKey(Map<K,?> map) { return map.keySet().iterator().next(); }"
207+ }
208+
209+ bindingset [ arg]
210+ override string getCall ( string arg ) { result = "getMapKey(" + arg + ")" }
211+ }
212+
213+ private class MapValueGetMethod extends GetMethod {
214+ MapValueGetMethod ( ) { this = "MapValueGetMethod" }
215+
216+ override predicate appliesTo ( Type t , Content c ) {
217+ t .( RefType ) .getASourceSupertype * ( ) .hasQualifiedName ( "java.util" , "Map" ) and
218+ c instanceof MapValueContent
219+ }
220+
221+ override string getDefinition ( ) {
222+ result = "<V> V getMapValue(Map<?,V> map) { return map.get(null); }"
223+ }
224+
225+ bindingset [ arg]
226+ override string getCall ( string arg ) { result = "getMapValue(" + arg + ")" }
227+ }
228+
229+ private class ArrayGetMethod extends GetMethod {
230+ ArrayGetMethod ( ) { this = "arraygetmethod" }
231+
232+ override predicate appliesTo ( Type t , Content c ) {
233+ t instanceof Array and
234+ c instanceof ArrayContent
235+ }
236+
237+ override string getDefinition ( ) {
238+ result = "<T> T getArrayElement(T[] array) { return array[0]; }"
239+ }
240+
241+ bindingset [ arg]
242+ override string getCall ( string arg ) { result = "getArrayElement(" + arg + ")" }
243+ }
244+
245+ bindingset [ this ]
246+ abstract class GenMethod extends SupportMethod { }
247+
248+ private class DefaultGenMethod extends GenMethod {
249+ Content c ;
250+
251+ // prefix with zzz so the default generator is always last
252+ DefaultGenMethod ( ) { this = "zzzDefaultGen" + contentToken ( c ) }
253+
254+ string getName ( ) { result = "newWith" + contentToken ( c ) }
255+
256+ override predicate appliesTo ( Type t , Content c1 ) {
257+ c = c1 and
258+ // suppress unused variable warning
259+ t = t
260+ }
261+
262+ bindingset [ arg]
263+ override string getCall ( string arg ) { result = this .getName ( ) + "(" + arg + ")" }
264+
265+ override string getDefinition ( ) {
266+ result = "Object newWith" + contentToken ( c ) + "(Object element) { return null; }"
267+ }
268+
269+ override string getCsvModel ( ) {
270+ result =
271+ "generatedtest;Test;false;" + this .getName ( ) + ";;;Argument[0];" +
272+ getComponentSpec ( SummaryComponent:: content ( c ) ) + " of ReturnValue;value"
273+ }
274+ }
275+
276+ private class ListGenMethod extends GenMethod {
277+ ListGenMethod ( ) { this = "listgenmethod" }
278+
279+ override predicate appliesTo ( Type t , Content c ) {
280+ exists ( GenericType list | list .hasQualifiedName ( "java.util" , "List" ) |
281+ t = list or list .getAParameterizedType ( ) .getASupertype * ( ) = t
282+ ) and
283+ c instanceof CollectionContent
284+ }
285+
286+ bindingset [ arg]
287+ override string getCall ( string arg ) { result = "List.of(" + arg + ")" }
288+ }
289+
290+ private class OptionalGenMethod extends GenMethod {
291+ OptionalGenMethod ( ) { this = "optionalgenmethod" }
292+
293+ override predicate appliesTo ( Type t , Content c ) {
294+ exists ( GenericType list | list .hasQualifiedName ( "java.util" , "List" ) |
295+ list .getAParameterizedType ( ) .getASupertype * ( ) = t
296+ ) and
297+ c instanceof CollectionContent
298+ }
299+
300+ bindingset [ arg]
301+ override string getCall ( string arg ) { result = "Optional.of(" + arg + ")" }
302+ }
303+
304+ private class MapGenKeyMethod extends GenMethod {
305+ MapGenKeyMethod ( ) { this = "mapkeygenmethod" }
306+
307+ override predicate appliesTo ( Type t , Content c ) {
308+ exists ( GenericType map | map .hasQualifiedName ( "java.util" , "Map" ) |
309+ map .getAParameterizedType ( ) .getASupertype * ( ) = t
310+ ) and
311+ c instanceof MapKeyContent
312+ }
313+
314+ bindingset [ arg]
315+ override string getCall ( string arg ) { result = "Map.of(" + arg + ", null)" }
316+ }
317+
318+ private class MapGenValueMethod extends GenMethod {
319+ MapGenValueMethod ( ) { this = "mapvaluegenmethod" }
320+
321+ override predicate appliesTo ( Type t , Content c ) {
322+ exists ( GenericType map | map .hasQualifiedName ( "java.util" , "Map" ) |
323+ map .getAParameterizedType ( ) .getASupertype * ( ) = t
324+ ) and
325+ c instanceof MapValueContent
326+ }
327+
328+ bindingset [ arg]
329+ override string getCall ( string arg ) { result = "Map.of(null, " + arg + ")" }
330+ }
331+
332+ string getConvertExprIfNotObject ( RefType t ) {
333+ if t .hasQualifiedName ( "java.lang" , "Object" )
334+ then result = ""
335+ else result = "(" + getShortNameIfPossible ( t ) + ")"
336+ }
337+
338+ private class ArrayGenMethod extends GenMethod {
339+ Array type ;
340+
341+ ArrayGenMethod ( ) { this = type .getName ( ) + "genmethod" }
342+
343+ override predicate appliesTo ( Type t , Content c ) {
344+ t = type and
345+ c instanceof ArrayContent
346+ }
347+
348+ bindingset [ arg]
349+ override string getCall ( string arg ) {
350+ result = "{" + getConvertExprIfNotObject ( type .getElementType ( ) ) + arg + "}"
351+ }
352+ }
0 commit comments