@@ -235,3 +235,58 @@ abstract class StructuralComparisonConfiguration extends string {
235
235
toGvn ( x ) = toGvn ( y )
236
236
}
237
237
}
238
+
239
+ /**
240
+ * INTERNAL: Do not use.
241
+ *
242
+ * A verbatim copy of the class `StructuralComparisonConfiguration` for internal
243
+ * use.
244
+ *
245
+ * A copy is needed in order to use structural comparison within the standard
246
+ * library without running into caching issues.
247
+ */
248
+ module Internal {
249
+ // Import all uses of the internal library to make sure caching works
250
+ private import semmle.code.csharp.controlflow.Guards as G
251
+
252
+ /**
253
+ * A configuration for performing structural comparisons of program elements
254
+ * (expressions and statements).
255
+ *
256
+ * The predicate `candidate()` must be overridden, in order to identify the
257
+ * elements for which to perform structural comparison.
258
+ *
259
+ * Each use of the library is identified by a unique string value.
260
+ */
261
+ abstract class InternalStructuralComparisonConfiguration extends string {
262
+ bindingset [ this ]
263
+ InternalStructuralComparisonConfiguration ( ) { any ( ) }
264
+
265
+ /**
266
+ * Holds if elements `x` and `y` are candidates for testing structural
267
+ * equality.
268
+ *
269
+ * Subclasses are expected to override this predicate to identify the
270
+ * top-level elements which they want to compare. Care should be
271
+ * taken to avoid identifying too many pairs of elements, as in general
272
+ * there are very many structurally equal subtrees in a program, and
273
+ * in order to keep the computation feasible we must focus attention.
274
+ *
275
+ * Note that this relation is not expected to be symmetric -- it's
276
+ * fine to include a pair `(x, y)` but not `(y, x)`.
277
+ * In fact, not including the symmetrically implied fact will save
278
+ * half the computation time on the structural comparison.
279
+ */
280
+ abstract predicate candidate ( ControlFlowElement x , ControlFlowElement y ) ;
281
+
282
+ /**
283
+ * Holds if elements `x` and `y` structurally equal. `x` and `y` must be
284
+ * flagged as candidates for structural equality, that is,
285
+ * `candidate(x, y)` must hold.
286
+ */
287
+ predicate same ( ControlFlowElement x , ControlFlowElement y ) {
288
+ candidate ( x , y ) and
289
+ toGvn ( x ) = toGvn ( y )
290
+ }
291
+ }
292
+ }
0 commit comments