aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/compiler/default/phase/analysis/reference.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/test/lux/compiler/default/phase/analysis/reference.lux')
-rw-r--r--stdlib/source/test/lux/compiler/default/phase/analysis/reference.lux107
1 files changed, 107 insertions, 0 deletions
diff --git a/stdlib/source/test/lux/compiler/default/phase/analysis/reference.lux b/stdlib/source/test/lux/compiler/default/phase/analysis/reference.lux
new file mode 100644
index 000000000..18ab58fa9
--- /dev/null
+++ b/stdlib/source/test/lux/compiler/default/phase/analysis/reference.lux
@@ -0,0 +1,107 @@
+(.module:
+ [lux #*
+ [control
+ [monad (#+ do)]
+ pipe]
+ [data
+ ["." error (#+ Error)]
+ [name ("name/." equivalence)]
+ [text ("text/." equivalence)]]
+ [math
+ ["r" random]]
+ [type ("type/." equivalence)]
+ [macro
+ ["." code]]
+ [compiler
+ [default
+ ["." reference]
+ ["." init]
+ ["." phase
+ ["." analysis
+ ["." scope]
+ ["." module]
+ [".A" type]
+ ["." expression]]
+ [extension
+ [".E" analysis]]]]]
+ test]
+ [//
+ ["_." primitive]])
+
+(type: Check (-> (Error Any) Bit))
+
+(do-template [<name> <on-success> <on-failure>]
+ [(def: <name>
+ Check
+ (|>> (case> (#error.Success _)
+ <on-success>
+
+ (#error.Failure _)
+ <on-failure>)))]
+
+ [success? #1 #0]
+ [failure? #0 #1]
+ )
+
+(def: (reach-test var-name [export? def-module] [import? dependent-module] check!)
+ (-> Text [Bit Text] [Bit Text] Check Bit)
+ (|> (do phase.monad
+ [_ (module.with-module 0 def-module
+ (module.define var-name [Any
+ (if export?
+ (' {#.export? #1})
+ (' {}))
+ []]))]
+ (module.with-module 0 dependent-module
+ (do @
+ [_ (if import?
+ (module.import def-module)
+ (wrap []))]
+ (typeA.with-inference
+ (_primitive.phase (code.identifier [def-module var-name]))))))
+ (phase.run _primitive.state)
+ check!))
+
+(context: "References"
+ (<| (times 100)
+ (do @
+ [[expectedT _] _primitive.primitive
+ def-module (r.unicode 5)
+ scope-name (r.unicode 5)
+ var-name (r.unicode 5)
+ dependent-module (|> (r.unicode 5)
+ (r.filter (|>> (text/= def-module) not)))]
+ ($_ seq
+ (test "Can analyse variable."
+ (|> (scope.with-scope scope-name
+ (scope.with-local [var-name expectedT]
+ (typeA.with-inference
+ (_primitive.phase (code.local-identifier var-name)))))
+ (phase.run _primitive.state)
+ (case> (^ (#error.Success [inferredT (#analysis.Reference (reference.local var))]))
+ (and (type/= expectedT inferredT)
+ (n/= 0 var))
+
+ _
+ #0)))
+ (test "Can analyse definition (in the same module)."
+ (let [def-name [def-module var-name]]
+ (|> (do phase.monad
+ [_ (module.define var-name [expectedT (' {}) []])]
+ (typeA.with-inference
+ (_primitive.phase (code.identifier def-name))))
+ (module.with-module 0 def-module)
+ (phase.run _primitive.state)
+ (case> (^ (#error.Success [_ inferredT (#analysis.Reference (reference.constant constant-name))]))
+ (and (type/= expectedT inferredT)
+ (name/= def-name constant-name))
+
+ _
+ #0))))
+ (test "Can analyse definition (if exported from imported module)."
+ (reach-test var-name [#1 def-module] [#1 dependent-module] success?))
+ (test "Cannot analyse definition (if not exported from imported module)."
+ (reach-test var-name [#0 def-module] [#1 dependent-module] failure?))
+ (test "Cannot analyse definition (if exported from non-imported module)."
+ (reach-test var-name [#1 def-module] [#0 dependent-module] failure?))
+ ))))