aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Julian2015-09-12 19:00:56 -0400
committerEduardo Julian2015-09-12 19:00:56 -0400
commit45a102bae3707d1a5220d7e124221ed46882f22d (patch)
tree057b24eac5513803bc3b0c0c84af00ec0ad37a4c
parent1e5f1afbd0f8b54350e552c110dead87b4b5dca0 (diff)
- Added exhaustiveness testing for class definition.
-rw-r--r--src/lux/analyser/host.clj29
-rw-r--r--src/lux/host.clj5
2 files changed, 32 insertions, 2 deletions
diff --git a/src/lux/analyser/host.clj b/src/lux/analyser/host.clj
index 69e1ff47a..0eb89b251 100644
--- a/src/lux/analyser/host.clj
+++ b/src/lux/analyser/host.clj
@@ -315,7 +315,9 @@
modifiers))
(defn analyse-jvm-class [analyse compile-token ?name ?super-class ?interfaces ?fields ?methods]
- (|do [=fields (&/map% (fn [?field]
+ (|do [class-loader &/loader
+ abstract-methods (&/flat-map% (partial &host/abstract-methods class-loader) (&/Cons$ ?super-class ?interfaces))
+ =fields (&/map% (fn [?field]
(|case ?field
[_ (&/$FormS (&/$Cons [_ (&/$TextS ?field-name)]
(&/$Cons [_ (&/$TextS ?field-type)]
@@ -369,8 +371,31 @@
_
(fail "[Analyser Error] Wrong syntax for method.")))
(&/enumerate ?methods))
+ ;; Test for method completion
+ :let [methods-map (&/fold (fn [mmap mentry]
+ (assoc mmap (:name mentry) mentry))
+ {}
+ =methods)
+ missing-method (&/fold (fn [missing abs-meth]
+ (|let [[am-name am-inputs] abs-meth]
+ (or missing
+ (if-let [meth-struct (get methods-map am-name)]
+ (let [meth-inputs (:inputs meth-struct)]
+ (if (and (= (&/|length meth-inputs) (&/|length am-inputs))
+ (&/fold2 (fn [prev mi ai] (and prev (= mi ai)))
+ true
+ meth-inputs am-inputs))
+ nil
+ am-name))
+ am-name))))
+ nil
+ abstract-methods)]
+ _ (if (nil? missing-method)
+ (return nil)
+ (fail (str "[Analyser Error] Missing method: " missing-method)))
_ (compile-token (&/V &&/$jvm-class (&/T ?name ?super-class ?interfaces =fields =methods)))
- :let [_ (prn 'analyse-jvm-class ?name ?super-class)]]
+ ;; :let [_ (prn 'analyse-jvm-class ?name ?super-class)]
+ ]
(return (&/|list))))
(defn analyse-jvm-interface [analyse compile-token name supers methods]
diff --git a/src/lux/host.clj b/src/lux/host.clj
index 81323b1d8..8d6135d64 100644
--- a/src/lux/host.clj
+++ b/src/lux/host.clj
@@ -134,5 +134,10 @@
(return &type/Unit)
(fail (str "[Host Error] Constructor does not exist: " target))))
+(defn abstract-methods [class-loader class]
+ (return (&/->list (for [^Method =method (.getDeclaredMethods (Class/forName (&type/as-obj class) true class-loader))
+ :when (.equals true (Modifier/isAbstract (.getModifiers =method)))]
+ (&/T (.getName =method) (&/|map #(.getName ^Class %) (&/->list (seq (.getParameterTypes =method)))))))))
+
(defn location [scope]
(->> scope (&/|map &/normalize-name) (&/|interpose "$") (&/fold str "")))