Skip to content

Commit 4499551

Browse files
committed
C#: Add a verbatim copy of the structural comparison for internal use only.
1 parent 16270cf commit 4499551

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

csharp/ql/lib/semmle/code/csharp/commons/StructuralComparison.qll

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)