google / jsinterop-generator

Generates Java annotated with JsInterop from JavaScript extern sources
Apache License 2.0
78 stars 24 forks source link

@typedef on a property fails to build #45

Open niloc132 opened 4 years ago

niloc132 commented 4 years ago

Example JS, as put in the externs/modules/modules.js file:

/**
 * @typedef {(string|number|boolean)}
 */
baz.structural;

Results in this stack trace:

Exception in thread "main" java.lang.UnsupportedOperationException
        at com.google.javascript.rhino.jstype.Property.getScope(Property.java:185)
        at jsinterop.generator.closure.visitor.AbstractClosureVisitor.acceptTypedef(AbstractClosureVisitor.java:175)
        at jsinterop.generator.closure.visitor.AbstractClosureVisitor.accept(AbstractClosureVisitor.java:86)
        at jsinterop.generator.closure.visitor.AbstractClosureVisitor.lambda$acceptProperties$1(AbstractClosureVisitor.java:247)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
        at java.base/java.util.TreeMap$KeySpliterator.forEachRemaining(TreeMap.java:2739)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
        at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
        at jsinterop.generator.closure.visitor.AbstractClosureVisitor.acceptProperties(AbstractClosureVisitor.java:244)
        at jsinterop.generator.closure.visitor.AbstractClosureVisitor.acceptModule(AbstractClosureVisitor.java:195)
        at jsinterop.generator.closure.visitor.AbstractClosureVisitor.accept(AbstractClosureVisitor.java:84)
        at jsinterop.generator.closure.visitor.AbstractClosureVisitor.accept(AbstractClosureVisitor.java:64)
        at jsinterop.generator.closure.visitor.TypeCollector.accept(TypeCollector.java:41)
        at jsinterop.generator.closure.ClosureJsInteropGenerator.generateJavaProgram(ClosureJsInteropGenerator.java:170)
        at jsinterop.generator.closure.ClosureJsInteropGenerator.convert(ClosureJsInteropGenerator.java:68)

This is because the StaticTypedSlot instance passed here to AbstractClosureVisitor.acceptTypedef(...) is a closure Property, which throws when it is asked for its scope: https://github.com/google/closure-compiler/blob/00ad3658b30221987fbbfe4a59db7e298d68cd72/src/com/google/javascript/rhino/jstype/Property.java#L183-L186

  @Override
  public StaticTypedScope getScope() {
    throw new UnsupportedOperationException();
  }

My workaround for now is to just remove these typedefs and hope they don't matter to the eventual compilation, but they are hard to avoid:

I explored options for a fix briefly, but I'm struggling to find examples in closure-compiler which show how to read a Property to see its type, without either just asking Property.getType() or having a valid "scope" for it.

niloc132 commented 1 year ago

Note that this is preventing proposing an elemental2-webcrypto addition to https://github.com/google/elemental2, since the closure provided externs make extensive use of @typedef:

https://github.com/google/closure-compiler/blob/2dd00e617a6990202032669270807ef222a4cc3c/externs/browser/w3c_webcrypto.js#L45