diff --git a/go/ql/lib/upgrades/5ff5325d274ae4f86defa195577bc7c1370b72fa/upgrade.properties b/go/ql/lib/upgrades/5ff5325d274ae4f86defa195577bc7c1370b72fa/upgrade.properties index 768d62bb215d..1a8bbabd727f 100644 --- a/go/ql/lib/upgrades/5ff5325d274ae4f86defa195577bc7c1370b72fa/upgrade.properties +++ b/go/ql/lib/upgrades/5ff5325d274ae4f86defa195577bc7c1370b72fa/upgrade.properties @@ -1,2 +1,5 @@ description: Add @rangeelementexpr, grouping the loop variables of a range statement -compatibility: partial +compatibility: full + +exprs.rel: run upgrade.qlo new_exprs +has_location.rel: run upgrade.qlo new_has_location diff --git a/go/ql/lib/upgrades/5ff5325d274ae4f86defa195577bc7c1370b72fa/upgrade.ql b/go/ql/lib/upgrades/5ff5325d274ae4f86defa195577bc7c1370b72fa/upgrade.ql new file mode 100644 index 000000000000..cbf128324d8a --- /dev/null +++ b/go/ql/lib/upgrades/5ff5325d274ae4f86defa195577bc7c1370b72fa/upgrade.ql @@ -0,0 +1,69 @@ +class Expr extends @expr { + string toString() { none() } +} + +class ExprParent extends @exprparent { + string toString() { none() } +} + +class RangeStmt extends @rangestmt { + string toString() { none() } +} + +class Location extends @location { + string toString() { none() } +} + +newtype TAddedExpr = TRangeElement(RangeStmt stmt) + +module Fresh = QlBuiltins::NewEntity; + +class TNewExpr = @expr or Fresh::EntityId; + +class NewExpr extends TNewExpr { + string toString() { none() } +} + +class TNewExprParent = @exprparent or Fresh::EntityId; + +class NewExprParent extends TNewExprParent { + string toString() { none() } +} + +class TNewLocatable = @locatable or Fresh::EntityId; + +class NewLocatable extends TNewLocatable { + string toString() { none() } +} + +predicate isRangeElementChild(ExprParent parent, int idx, RangeStmt range) { + parent = range and + idx in [0 .. 1] +} + +query predicate new_exprs(NewExpr id, int kind, NewExprParent parent, int idx) { + exists(RangeStmt range | + id = Fresh::map(TRangeElement(range)) and + kind = 55 and + parent = range and + idx = 0 + ) + or + exists(ExprParent oldParent | exprs(id, kind, oldParent, idx) | + exists(RangeStmt range | isRangeElementChild(oldParent, idx, range) | + parent = Fresh::map(TRangeElement(range)) + ) + or + not isRangeElementChild(oldParent, idx, _) and + parent = oldParent + ) +} + +query predicate new_has_location(NewLocatable locatable, Location location) { + has_location(locatable, location) + or + exists(RangeStmt range | + locatable = Fresh::map(TRangeElement(range)) and + has_location(range, location) + ) +}