Welcome! Please see the About page for a little more info on how this works.

0 votes
ago in ClojureScript by
retagged ago by

ClojureScript does not seem to infer an extern or emit an inference warning for a JavaScript method call after an intermediate some-> step.

Advanced compilation then renames the call across an npm boundary and causes a runtime error.

I reproduced this with ClojureScript 1.12.145 and with an uberjar built from master at b45dff9f

Reproduction

deps.edn:

{:deps {org.clojure/clojure {:mvn/version "1.12.4"}
        org.clojure/clojurescript {:mvn/version "1.12.145"}}
 :paths ["src"]}

package.json:

{"dependencies":{"formatter-lib":"file:formatter-lib"},"private":true}

formatter-lib/package.json:

{"main":"index.js","name":"formatter-lib","version":"1.0.0"}

formatter-lib/index.js:

class Formatter {
  constructor(value) {
    this.value = value;
  }

  toPattern(pattern) {
    return `${this.value}:${pattern}`;
  }
}

module.exports = (value) => new Formatter(value);

src/repro/core.cljs:

(ns repro.core
  (:require ["formatter-lib" :as formatter]))

(set! *warn-on-infer* true)

(defn -main []
  (println (some-> (formatter 42) identity (.toPattern "yyyy"))))

(set! *main-cli-fn* -main)

build.edn:

{:infer-externs true
 :install-deps false
 :main repro.core
 :npm-deps {"formatter-lib" "1.0.0"}
 :optimizations :advanced
 :output-dir "target/out"
 :output-to "target/main.js"
 :target :nodejs}

Run:

npm install
clojure -M -m cljs.main -co build.edn -c repro.core
node target/main.js

The compile emits no extern inference warning. The generated call is renamed and Node fails:

TypeError: a.Yb is not a function

The same result occurs with the uberjar built from master:

java -cp /path/to/clojurescript/target/cljs.jar:src \
  clojure.main -m cljs.main -co build.edn -c repro.core
node target/main.js

Control

Removing the intermediate identity step:

(println (some-> (formatter 42) (.toPattern "yyyy")))

causes the compiler to infer the extern:

WARNING: Adding extern to Object for property toPattern due to ambiguous expression

The generated method remains toPattern, and Node prints:

42:yyyy

I expected the version with the intermediate step to infer the same extern, or at least emit a warning that the target type could not be inferred.

Please log in or register to answer this question.

...