difftreelog
feat static analysis
in: master
45 files changed
crates/jrsonnet-evaluator/src/analysis_tests/array_comp.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/array_comp.jsonnet
@@ -0,0 +1 @@
+[x * 2 for x in [1, 2, 3] if x > 1]
crates/jrsonnet-evaluator/src/analysis_tests/dollar_deeply_nested.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/dollar_deeply_nested.jsonnet
@@ -0,0 +1,9 @@
+{
+ top: 'outer',
+ a: {
+ b: {
+ c: $.top,
+ d: self,
+ },
+ },
+}
crates/jrsonnet-evaluator/src/analysis_tests/dollar_outside_object.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/dollar_outside_object.jsonnet
@@ -0,0 +1 @@
+$.a
crates/jrsonnet-evaluator/src/analysis_tests/function_def.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/function_def.jsonnet
@@ -0,0 +1 @@
+local f(x, y) = x + y; f(1, 2)
crates/jrsonnet-evaluator/src/analysis_tests/hoistable_local.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/hoistable_local.jsonnet
@@ -0,0 +1 @@
+local outer = 1; local inner = 10 + 20; outer + inner
crates/jrsonnet-evaluator/src/analysis_tests/ifelse.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/ifelse.jsonnet
@@ -0,0 +1 @@
+if true then 1 else 2
crates/jrsonnet-evaluator/src/analysis_tests/literal.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/literal.jsonnet
@@ -0,0 +1 @@
+42
crates/jrsonnet-evaluator/src/analysis_tests/loop_invariant.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/loop_invariant.jsonnet
@@ -0,0 +1 @@
+[ i < j for i in std.range(1, 1000) for j in std.range(1, 1000)]
crates/jrsonnet-evaluator/src/analysis_tests/mutual_recursion.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/mutual_recursion.jsonnet
@@ -0,0 +1 @@
+local a = b, b = 1; a + 2
crates/jrsonnet-evaluator/src/analysis_tests/nested_object_independent.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/nested_object_independent.jsonnet
@@ -0,0 +1,6 @@
+{
+ a: 1,
+ b: {
+ c: 2, d: self.c
+ },
+}
crates/jrsonnet-evaluator/src/analysis_tests/object_comp.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/object_comp.jsonnet
@@ -0,0 +1 @@
+{ [k]: k for k in ['a', 'b'] }
crates/jrsonnet-evaluator/src/analysis_tests/object_dollar.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/object_dollar.jsonnet
@@ -0,0 +1 @@
+{ a: 1, b: { c: $.a } }
crates/jrsonnet-evaluator/src/analysis_tests/object_self.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/object_self.jsonnet
@@ -0,0 +1 @@
+{ a: 1, b: self.a }
crates/jrsonnet-evaluator/src/analysis_tests/object_with_locals.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/object_with_locals.jsonnet
@@ -0,0 +1,5 @@
+{
+ local helper = 10,
+ a: helper,
+ b: helper * 2,
+}
crates/jrsonnet-evaluator/src/analysis_tests/redeclared_local.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/redeclared_local.jsonnet
@@ -0,0 +1 @@
+local x = 1, x = 2; x
crates/jrsonnet-evaluator/src/analysis_tests/shadowing.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/shadowing.jsonnet
@@ -0,0 +1 @@
+local x = 1; local x = 2; x
crates/jrsonnet-evaluator/src/analysis_tests/simple_local.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/simple_local.jsonnet
@@ -0,0 +1 @@
+local x = 1; x + 2
crates/jrsonnet-evaluator/src/analysis_tests/slice.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/slice.jsonnet
@@ -0,0 +1 @@
+[1, 2, 3, 4, 5][1:3]
crates/jrsonnet-evaluator/src/analysis_tests/super_outside_object.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/super_outside_object.jsonnet
@@ -0,0 +1 @@
+super.a
crates/jrsonnet-evaluator/src/analysis_tests/super_usage.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/super_usage.jsonnet
@@ -0,0 +1 @@
+{ a: 1, b: 2 } + { a: super.a + 10, c: self.b }
crates/jrsonnet-evaluator/src/analysis_tests/undefined_var.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/undefined_var.jsonnet
@@ -0,0 +1 @@
+y + 1
crates/jrsonnet-evaluator/src/analysis_tests/unused_local.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/analysis_tests/unused_local.jsonnet
@@ -0,0 +1 @@
+local unused = 1; 2
crates/jrsonnet-evaluator/src/analyze.rsdiffbeforeafterbothno changes
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@array_comp.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@array_comp.jsonnet.snap
@@ -0,0 +1,64 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/array_comp.jsonnet
+---
+--- source ---
+[x * 2 for x in [1, 2, 3] if x > 1]
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: 0
+errored: false
+--- diagnostics ---
+--- lir ---
+ArrComp(
+ LArrComp {
+ value: BinaryOp {
+ lhs: Local(
+ LocalId(
+ 0,
+ ),
+ ),
+ op: Mul,
+ rhs: Num(
+ 2.0,
+ ),
+ },
+ compspecs: [
+ For {
+ destruct: Full(
+ LocalId(
+ 0,
+ ),
+ ),
+ over: Arr(
+ [
+ Num(
+ 1.0,
+ ),
+ Num(
+ 2.0,
+ ),
+ Num(
+ 3.0,
+ ),
+ ],
+ ),
+ loop_invariant: true,
+ },
+ If(
+ BinaryOp {
+ lhs: Local(
+ LocalId(
+ 0,
+ ),
+ ),
+ op: Gt,
+ rhs: Num(
+ 1.0,
+ ),
+ },
+ ),
+ ],
+ },
+)
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@dollar_deeply_nested.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@dollar_deeply_nested.jsonnet.snap
@@ -0,0 +1,126 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/dollar_deeply_nested.jsonnet
+---
+--- source ---
+{
+ top: 'outer',
+ a: {
+ b: {
+ c: $.top,
+ d: self,
+ },
+ },
+}
+--- root analysis ---
+object_dependent_depth: 0
+local_dependent_depth: 0
+errored: false
+--- diagnostics ---
+--- lir ---
+Obj(
+ MemberList(
+ LObjMembers {
+ this: Some(
+ LocalId(
+ 0,
+ ),
+ ),
+ set_dollar: true,
+ uses_super: false,
+ locals: [],
+ asserts: [],
+ fields: [
+ LFieldMember {
+ name: Fixed(
+ "top",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Str(
+ "outer",
+ ),
+ },
+ LFieldMember {
+ name: Fixed(
+ "a",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Obj(
+ MemberList(
+ LObjMembers {
+ this: None,
+ set_dollar: false,
+ uses_super: false,
+ locals: [],
+ asserts: [],
+ fields: [
+ LFieldMember {
+ name: Fixed(
+ "b",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Obj(
+ MemberList(
+ LObjMembers {
+ this: Some(
+ LocalId(
+ 2,
+ ),
+ ),
+ set_dollar: false,
+ uses_super: false,
+ locals: [],
+ asserts: [],
+ fields: [
+ LFieldMember {
+ name: Fixed(
+ "c",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Index {
+ indexable: Local(
+ LocalId(
+ 0,
+ ),
+ ),
+ parts: [
+ LIndexPart {
+ span: virtual:<test>:45-48,
+ value: Str(
+ "top",
+ ),
+ },
+ ],
+ },
+ },
+ LFieldMember {
+ name: Fixed(
+ "d",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Local(
+ LocalId(
+ 2,
+ ),
+ ),
+ },
+ ],
+ },
+ ),
+ ),
+ },
+ ],
+ },
+ ),
+ ),
+ },
+ ],
+ },
+ ),
+)
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@dollar_outside_object.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@dollar_outside_object.jsonnet.snap
@@ -0,0 +1,27 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/dollar_outside_object.jsonnet
+---
+--- source ---
+$.a
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: none
+errored: true
+--- diagnostics ---
+error: `$` used outside of object
+--- lir ---
+Index {
+ indexable: BadLocal(
+ "$",
+ ),
+ parts: [
+ LIndexPart {
+ span: virtual:<test>:2-3,
+ value: Str(
+ "a",
+ ),
+ },
+ ],
+}
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@function_def.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@function_def.jsonnet.snap
@@ -0,0 +1,104 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analysis_tests/function_def.jsonnet
+---
+--- source ---
+local f(x, y) = x + y; f(1, 2)
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: 0
+errored: false
+--- diagnostics ---
+--- lir ---
+LocalExpr {
+ binds: [
+ LBind {
+ destruct: Full(
+ LocalId(
+ 0,
+ ),
+ ),
+ value: Function(
+ LFunction {
+ name: Some(
+ "f",
+ ),
+ params: [
+ LParam {
+ name: Some(
+ "x",
+ ),
+ destruct: Full(
+ LocalId(
+ 1,
+ ),
+ ),
+ default: None,
+ },
+ LParam {
+ name: Some(
+ "y",
+ ),
+ destruct: Full(
+ LocalId(
+ 2,
+ ),
+ ),
+ default: None,
+ },
+ ],
+ signature: FunctionSignature(
+ [
+ ParamParse {
+ name: Named(
+ "x",
+ ),
+ default: None,
+ },
+ ParamParse {
+ name: Named(
+ "y",
+ ),
+ default: None,
+ },
+ ],
+ ),
+ body: BinaryOp {
+ lhs: Local(
+ LocalId(
+ 1,
+ ),
+ ),
+ op: Add,
+ rhs: Local(
+ LocalId(
+ 2,
+ ),
+ ),
+ },
+ },
+ ),
+ },
+ ],
+ body: Apply {
+ applicable: Local(
+ LocalId(
+ 0,
+ ),
+ ),
+ args: LArgsDesc {
+ unnamed: [
+ Num(
+ 1.0,
+ ),
+ Num(
+ 2.0,
+ ),
+ ],
+ names: [],
+ values: [],
+ } from virtual:<test>:24-30,
+ tailstrict: false,
+ },
+}
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@hoistable_local.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@hoistable_local.jsonnet.snap
@@ -0,0 +1,63 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/hoistable_local.jsonnet
+---
+--- source ---
+local outer = 1; local inner = 10 + 20; outer + inner
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: 0
+errored: false
+--- diagnostics ---
+ · ╭────── local could be hoisted to an outer scope: inner
+1 │ local outer = 1; local inner = 10 + 20; outer + inner
+2 │
+--- lir ---
+LocalExpr {
+ binds: [
+ LBind {
+ destruct: Full(
+ LocalId(
+ 0,
+ ),
+ ),
+ value: Num(
+ 1.0,
+ ),
+ },
+ ],
+ body: LocalExpr {
+ binds: [
+ LBind {
+ destruct: Full(
+ LocalId(
+ 1,
+ ),
+ ),
+ value: BinaryOp {
+ lhs: Num(
+ 10.0,
+ ),
+ op: Add,
+ rhs: Num(
+ 20.0,
+ ),
+ },
+ },
+ ],
+ body: BinaryOp {
+ lhs: Local(
+ LocalId(
+ 0,
+ ),
+ ),
+ op: Add,
+ rhs: Local(
+ LocalId(
+ 1,
+ ),
+ ),
+ },
+ },
+}
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@ifelse.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@ifelse.jsonnet.snap
@@ -0,0 +1,26 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/ifelse.jsonnet
+---
+--- source ---
+if true then 1 else 2
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: none
+errored: false
+--- diagnostics ---
+--- lir ---
+IfElse {
+ cond: Bool(
+ true,
+ ),
+ cond_then: Num(
+ 1.0,
+ ),
+ cond_else: Some(
+ Num(
+ 2.0,
+ ),
+ ),
+}
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@literal.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@literal.jsonnet.snap
@@ -0,0 +1,16 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/literal.jsonnet
+---
+--- source ---
+42
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: none
+errored: false
+--- diagnostics ---
+--- lir ---
+Num(
+ 42.0,
+)
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@loop_invariant.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@loop_invariant.jsonnet.snap
@@ -0,0 +1,109 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analysis_tests/loop_invariant.jsonnet
+---
+--- source ---
+[ i < j for i in std.range(1, 1000) for j in std.range(1, 1000)]
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: 0
+errored: true
+--- diagnostics ---
+ · ╭──────────────────────────────── undefined local: std
+ · │ ╭──── undefined local: std
+1 │ [ i < j for i in std.range(1, 1000) for j in std.range(1, 1000)]
+ · ╰── local could be hoisted to an outer scope: j
+2 │
+--- lir ---
+ArrComp(
+ LArrComp {
+ value: BinaryOp {
+ lhs: Local(
+ LocalId(
+ 0,
+ ),
+ ),
+ op: Lt,
+ rhs: Local(
+ LocalId(
+ 1,
+ ),
+ ),
+ },
+ compspecs: [
+ For {
+ destruct: Full(
+ LocalId(
+ 0,
+ ),
+ ),
+ over: Apply {
+ applicable: Index {
+ indexable: BadLocal(
+ "ref",
+ ),
+ parts: [
+ LIndexPart {
+ span: virtual:<test>:21-26,
+ value: Str(
+ "range",
+ ),
+ },
+ ],
+ },
+ args: LArgsDesc {
+ unnamed: [
+ Num(
+ 1.0,
+ ),
+ Num(
+ 1000.0,
+ ),
+ ],
+ names: [],
+ values: [],
+ } from virtual:<test>:26-35,
+ tailstrict: false,
+ },
+ loop_invariant: true,
+ },
+ For {
+ destruct: Full(
+ LocalId(
+ 1,
+ ),
+ ),
+ over: Apply {
+ applicable: Index {
+ indexable: BadLocal(
+ "ref",
+ ),
+ parts: [
+ LIndexPart {
+ span: virtual:<test>:49-54,
+ value: Str(
+ "range",
+ ),
+ },
+ ],
+ },
+ args: LArgsDesc {
+ unnamed: [
+ Num(
+ 1.0,
+ ),
+ Num(
+ 1000.0,
+ ),
+ ],
+ names: [],
+ values: [],
+ } from virtual:<test>:54-63,
+ tailstrict: false,
+ },
+ loop_invariant: true,
+ },
+ ],
+ },
+)
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@mutual_recursion.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@mutual_recursion.jsonnet.snap
@@ -0,0 +1,50 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/mutual_recursion.jsonnet
+---
+--- source ---
+local a = b, b = 1; a + 2
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: 0
+errored: false
+--- diagnostics ---
+--- lir ---
+LocalExpr {
+ binds: [
+ LBind {
+ destruct: Full(
+ LocalId(
+ 0,
+ ),
+ ),
+ value: Local(
+ LocalId(
+ 1,
+ ),
+ ),
+ },
+ LBind {
+ destruct: Full(
+ LocalId(
+ 1,
+ ),
+ ),
+ value: Num(
+ 1.0,
+ ),
+ },
+ ],
+ body: BinaryOp {
+ lhs: Local(
+ LocalId(
+ 0,
+ ),
+ ),
+ op: Add,
+ rhs: Num(
+ 2.0,
+ ),
+ },
+}
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@nested_object_independent.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@nested_object_independent.jsonnet.snap
@@ -0,0 +1,97 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analysis_golden/nested_object_independent.jsonnet
+---
+--- source ---
+{
+ a: 1,
+ b: {
+ c: 2, d: self.c
+ },
+}
+--- root analysis ---
+object_dependent_depth: 1
+local_dependent_depth: 1
+errored: false
+--- diagnostics ---
+--- lir ---
+Obj(
+ MemberList(
+ LObjMembers {
+ this: None,
+ set_dollar: false,
+ uses_super: false,
+ locals: [],
+ asserts: [],
+ fields: [
+ LFieldMember {
+ name: Fixed(
+ "a",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Num(
+ 1.0,
+ ),
+ },
+ LFieldMember {
+ name: Fixed(
+ "b",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Obj(
+ MemberList(
+ LObjMembers {
+ this: Some(
+ LocalId(
+ 1,
+ ),
+ ),
+ set_dollar: false,
+ uses_super: false,
+ locals: [],
+ asserts: [],
+ fields: [
+ LFieldMember {
+ name: Fixed(
+ "c",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Num(
+ 2.0,
+ ),
+ },
+ LFieldMember {
+ name: Fixed(
+ "d",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Index {
+ indexable: Local(
+ LocalId(
+ 1,
+ ),
+ ),
+ parts: [
+ LIndexPart {
+ span: virtual:<test>:35-36,
+ value: Str(
+ "c",
+ ),
+ },
+ ],
+ },
+ },
+ ],
+ },
+ ),
+ ),
+ },
+ ],
+ },
+ ),
+)
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_comp.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_comp.jsonnet.snap
@@ -0,0 +1,59 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/object_comp.jsonnet
+---
+--- source ---
+{ [k]: k for k in ['a', 'b'] }
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: 0
+errored: false
+--- diagnostics ---
+--- lir ---
+Obj(
+ ObjComp(
+ LObjComp {
+ this: None,
+ set_dollar: false,
+ uses_super: false,
+ locals: [],
+ field: LFieldMember {
+ name: Dyn(
+ Local(
+ LocalId(
+ 0,
+ ),
+ ),
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Local(
+ LocalId(
+ 0,
+ ),
+ ),
+ },
+ compspecs: [
+ For {
+ destruct: Full(
+ LocalId(
+ 0,
+ ),
+ ),
+ over: Arr(
+ [
+ Str(
+ "a",
+ ),
+ Str(
+ "b",
+ ),
+ ],
+ ),
+ loop_invariant: true,
+ },
+ ],
+ },
+ ),
+)
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_dollar.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_dollar.jsonnet.snap
@@ -0,0 +1,82 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/object_dollar.jsonnet
+---
+--- source ---
+{ a: 1, b: { c: $.a } }
+--- root analysis ---
+object_dependent_depth: 0
+local_dependent_depth: 0
+errored: false
+--- diagnostics ---
+--- lir ---
+Obj(
+ MemberList(
+ LObjMembers {
+ this: Some(
+ LocalId(
+ 0,
+ ),
+ ),
+ set_dollar: true,
+ uses_super: false,
+ locals: [],
+ asserts: [],
+ fields: [
+ LFieldMember {
+ name: Fixed(
+ "a",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Num(
+ 1.0,
+ ),
+ },
+ LFieldMember {
+ name: Fixed(
+ "b",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Obj(
+ MemberList(
+ LObjMembers {
+ this: None,
+ set_dollar: false,
+ uses_super: false,
+ locals: [],
+ asserts: [],
+ fields: [
+ LFieldMember {
+ name: Fixed(
+ "c",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Index {
+ indexable: Local(
+ LocalId(
+ 0,
+ ),
+ ),
+ parts: [
+ LIndexPart {
+ span: virtual:<test>:18-19,
+ value: Str(
+ "a",
+ ),
+ },
+ ],
+ },
+ },
+ ],
+ },
+ ),
+ ),
+ },
+ ],
+ },
+ ),
+)
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_self.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_self.jsonnet.snap
@@ -0,0 +1,62 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/object_self.jsonnet
+---
+--- source ---
+{ a: 1, b: self.a }
+--- root analysis ---
+object_dependent_depth: 0
+local_dependent_depth: 0
+errored: false
+--- diagnostics ---
+--- lir ---
+Obj(
+ MemberList(
+ LObjMembers {
+ this: Some(
+ LocalId(
+ 0,
+ ),
+ ),
+ set_dollar: false,
+ uses_super: false,
+ locals: [],
+ asserts: [],
+ fields: [
+ LFieldMember {
+ name: Fixed(
+ "a",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Num(
+ 1.0,
+ ),
+ },
+ LFieldMember {
+ name: Fixed(
+ "b",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Index {
+ indexable: Local(
+ LocalId(
+ 0,
+ ),
+ ),
+ parts: [
+ LIndexPart {
+ span: virtual:<test>:16-17,
+ value: Str(
+ "a",
+ ),
+ },
+ ],
+ },
+ },
+ ],
+ },
+ ),
+)
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_with_locals.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_with_locals.jsonnet.snap
@@ -0,0 +1,71 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/object_with_locals.jsonnet
+---
+--- source ---
+{
+ local helper = 10,
+ a: helper,
+ b: helper * 2,
+}
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: 0
+errored: false
+--- diagnostics ---
+--- lir ---
+Obj(
+ MemberList(
+ LObjMembers {
+ this: None,
+ set_dollar: false,
+ uses_super: false,
+ locals: [
+ LBind {
+ destruct: Full(
+ LocalId(
+ 1,
+ ),
+ ),
+ value: Num(
+ 10.0,
+ ),
+ },
+ ],
+ asserts: [],
+ fields: [
+ LFieldMember {
+ name: Fixed(
+ "a",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Local(
+ LocalId(
+ 1,
+ ),
+ ),
+ },
+ LFieldMember {
+ name: Fixed(
+ "b",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: BinaryOp {
+ lhs: Local(
+ LocalId(
+ 1,
+ ),
+ ),
+ op: Mul,
+ rhs: Num(
+ 2.0,
+ ),
+ },
+ },
+ ],
+ },
+ ),
+)
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@redeclared_local.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@redeclared_local.jsonnet.snap
@@ -0,0 +1,35 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/redeclared_local.jsonnet
+---
+--- source ---
+local x = 1, x = 2; x
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: 0
+errored: true
+--- diagnostics ---
+ · ╭── variable redeclared: x
+1 │ local x = 1, x = 2; x
+2 │
+--- lir ---
+LocalExpr {
+ binds: [
+ LBind {
+ destruct: Full(
+ LocalId(
+ 0,
+ ),
+ ),
+ value: Num(
+ 1.0,
+ ),
+ },
+ ],
+ body: Local(
+ LocalId(
+ 0,
+ ),
+ ),
+}
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@shadowing.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@shadowing.jsonnet.snap
@@ -0,0 +1,50 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/shadowing.jsonnet
+---
+--- source ---
+local x = 1; local x = 2; x
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: 1
+errored: false
+--- diagnostics ---
+ · ╭── local could be hoisted to an outer scope: x
+1 │ local x = 1; local x = 2; x
+ · ╰── unused local: x
+2 │
+--- lir ---
+LocalExpr {
+ binds: [
+ LBind {
+ destruct: Full(
+ LocalId(
+ 0,
+ ),
+ ),
+ value: Num(
+ 1.0,
+ ),
+ },
+ ],
+ body: LocalExpr {
+ binds: [
+ LBind {
+ destruct: Full(
+ LocalId(
+ 1,
+ ),
+ ),
+ value: Num(
+ 2.0,
+ ),
+ },
+ ],
+ body: Local(
+ LocalId(
+ 1,
+ ),
+ ),
+ },
+}
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@simple_local.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@simple_local.jsonnet.snap
@@ -0,0 +1,38 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/simple_local.jsonnet
+---
+--- source ---
+local x = 1; x + 2
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: 0
+errored: false
+--- diagnostics ---
+--- lir ---
+LocalExpr {
+ binds: [
+ LBind {
+ destruct: Full(
+ LocalId(
+ 0,
+ ),
+ ),
+ value: Num(
+ 1.0,
+ ),
+ },
+ ],
+ body: BinaryOp {
+ lhs: Local(
+ LocalId(
+ 0,
+ ),
+ ),
+ op: Add,
+ rhs: Num(
+ 2.0,
+ ),
+ },
+}
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@slice.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@slice.jsonnet.snap
@@ -0,0 +1,47 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/slice.jsonnet
+---
+--- source ---
+[1, 2, 3, 4, 5][1:3]
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: none
+errored: false
+--- diagnostics ---
+--- lir ---
+Slice(
+ LSliceExpr {
+ value: Arr(
+ [
+ Num(
+ 1.0,
+ ),
+ Num(
+ 2.0,
+ ),
+ Num(
+ 3.0,
+ ),
+ Num(
+ 4.0,
+ ),
+ Num(
+ 5.0,
+ ),
+ ],
+ ),
+ start: Some(
+ Num(
+ 1.0,
+ ),
+ ),
+ end: Some(
+ Num(
+ 3.0,
+ ),
+ ),
+ step: None,
+ },
+)
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@super_outside_object.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@super_outside_object.jsonnet.snap
@@ -0,0 +1,27 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/super_outside_object.jsonnet
+---
+--- source ---
+super.a
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: none
+errored: true
+--- diagnostics ---
+error: `super` used outside of object
+--- lir ---
+Index {
+ indexable: BadLocal(
+ "super",
+ ),
+ parts: [
+ LIndexPart {
+ span: virtual:<test>:6-7,
+ value: Str(
+ "a",
+ ),
+ },
+ ],
+}
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@super_usage.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@super_usage.jsonnet.snap
@@ -0,0 +1,112 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analysis_tests/super_usage.jsonnet
+---
+--- source ---
+{ a: 1, b: 2 } + { a: super.a + 10, c: self.b }
+--- root analysis ---
+object_dependent_depth: 0
+local_dependent_depth: 0
+errored: false
+--- diagnostics ---
+--- lir ---
+BinaryOp {
+ lhs: Obj(
+ MemberList(
+ LObjMembers {
+ this: None,
+ set_dollar: false,
+ uses_super: false,
+ locals: [],
+ asserts: [],
+ fields: [
+ LFieldMember {
+ name: Fixed(
+ "a",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Num(
+ 1.0,
+ ),
+ },
+ LFieldMember {
+ name: Fixed(
+ "b",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Num(
+ 2.0,
+ ),
+ },
+ ],
+ },
+ ),
+ ),
+ op: Add,
+ rhs: Obj(
+ MemberList(
+ LObjMembers {
+ this: Some(
+ LocalId(
+ 0,
+ ),
+ ),
+ set_dollar: false,
+ uses_super: true,
+ locals: [],
+ asserts: [],
+ fields: [
+ LFieldMember {
+ name: Fixed(
+ "a",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: BinaryOp {
+ lhs: Index {
+ indexable: Super,
+ parts: [
+ LIndexPart {
+ span: virtual:<test>:28-29,
+ value: Str(
+ "a",
+ ),
+ },
+ ],
+ },
+ op: Add,
+ rhs: Num(
+ 10.0,
+ ),
+ },
+ },
+ LFieldMember {
+ name: Fixed(
+ "c",
+ ),
+ plus: false,
+ visibility: Normal,
+ value: Index {
+ indexable: Local(
+ LocalId(
+ 0,
+ ),
+ ),
+ parts: [
+ LIndexPart {
+ span: virtual:<test>:44-45,
+ value: Str(
+ "b",
+ ),
+ },
+ ],
+ },
+ },
+ ],
+ },
+ ),
+ ),
+}
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@undefined_var.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@undefined_var.jsonnet.snap
@@ -0,0 +1,25 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analysis_tests/undefined_var.jsonnet
+---
+--- source ---
+y + 1
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: none
+errored: true
+--- diagnostics ---
+ · ╭── undefined local: y
+1 │ y + 1
+2 │
+--- lir ---
+BinaryOp {
+ lhs: BadLocal(
+ "ref",
+ ),
+ op: Add,
+ rhs: Num(
+ 1.0,
+ ),
+}
crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@unused_local.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@unused_local.jsonnet.snap
@@ -0,0 +1,33 @@
+---
+source: crates/jrsonnet-evaluator/src/analyze.rs
+expression: rendered
+input_file: crates/jrsonnet-evaluator/src/analyze_tests/unused_local.jsonnet
+---
+--- source ---
+local unused = 1; 2
+--- root analysis ---
+object_dependent_depth: none
+local_dependent_depth: none
+errored: false
+--- diagnostics ---
+ · ╭─────── unused local: unused
+1 │ local unused = 1; 2
+2 │
+--- lir ---
+LocalExpr {
+ binds: [
+ LBind {
+ destruct: Full(
+ LocalId(
+ 0,
+ ),
+ ),
+ value: Num(
+ 1.0,
+ ),
+ },
+ ],
+ body: Num(
+ 2.0,
+ ),
+}