@@ -235,3 +235,58 @@ abstract class StructuralComparisonConfiguration extends string {
235235 toGvn ( x ) = toGvn ( y )
236236 }
237237}
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