-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Scaladoc generation fails when extending some Java-defined or Scala-2-defined classes #15927
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
How would we reproduce the problem on our own computers? What is the minimum code |
@SethTisue Could you look into it please? I can even push a repo with this the simplified code. |
It's not my area of expertise, but perhaps one of the Scaladoc maintainers will have a look. |
You've improved the report greatly by supplying code, but presumably most of that code presumably isn't actually necessary for reproducing the bug. The report would be even higher quality, and much likelier to be acted upon, if you reduced it to the absolute minimum necessary code to demonstrate the problem. (And that's why Paweł added the "needs minimization" label.) |
@SethTisue |
A slightly simpler minimization: trait Foo extends Numeric[Any] It crashes with just |
@SethTisue @prolativ |
Currently I have other priorities so I cannot give you any guarantee about when this would be fixed. For now this looks like a very strange corner case. I played with this example a bit and didn't manage to make this crash when |
you can find that out for yourself by trying it in the latest nightly build |
There are a lot of other types that can cause this too. For instance, import javax.swing.JPanel
class bug2 extends JPanel:
end bug2
and with scala-3.2.0-RC4/api...
Problem parsing src/main/scala/Bug2.scala:<0..65>, documentation may not be generated.
java.lang.AssertionError: assertion failed
| => rat scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:11)
at dotty.tools.dotc.util.Spans$Span$.start$extension(Spans.scala:45)
at dotty.tools.dotc.util.SourcePosition.start(SourcePosition.scala:52)
at scala.quoted.runtime.impl.QuotesImpl$reflect$PositionMethods$.start(QuotesImpl.scala:2813)
at scala.quoted.runtime.impl.QuotesImpl$reflect$PositionMethods$.start(QuotesImpl.scala:2813)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.getParentsAsTreeSymbolTuples$$anonfun$1(ClassLikeSupport.scala:260)
at scala.collection.Iterator$$anon$6.hasNext(Iterator.scala:472)
at scala.collection.Iterator$$anon$9.hasNext(Iterator.scala:576)
at scala.collection.immutable.List.prependedAll(List.scala:152)
at scala.collection.immutable.List$.from(List.scala:684)
at scala.collection.immutable.List$.from(List.scala:681)
at scala.collection.IterableOps$WithFilter.map(Iterable.scala:891)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.getParentsAsTreeSymbolTuples(ClassLikeSupport.scala:264)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.getParentsAsTreeSymbolTuples$(ClassLikeSupport.scala:15)
at dotty.tools.scaladoc.tasty.TastyParser.getParentsAsTreeSymbolTuples(TastyParser.scala:169)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.getParentsAsLinkToTypes(ClassLikeSupport.scala:253)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.getParentsAsLinkToTypes$(ClassLikeSupport.scala:15)
at dotty.tools.scaladoc.tasty.TastyParser.getParentsAsLinkToTypes(TastyParser.scala:169)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.mkClass(ClassLikeSupport.scala:106)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.mkClass$(ClassLikeSupport.scala:15)
at dotty.tools.scaladoc.tasty.TastyParser.mkClass(TastyParser.scala:169)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.parseClasslike(ClassLikeSupport.scala:290)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.parseClasslike$(ClassLikeSupport.scala:15)
at dotty.tools.scaladoc.tasty.TastyParser.parseClasslike(TastyParser.scala:169)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.parseInheritedMember$$anonfun$1(ClassLikeSupport.scala:190)
at dotty.tools.scaladoc.tasty.TastyParser.processTreeOpt(TastyParser.scala:204)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.parseInheritedMember(ClassLikeSupport.scala:202)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.extractMembers$$anonfun$2(ClassLikeSupport.scala:221)
at scala.collection.immutable.List.flatMap(List.scala:293)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.extractMembers(ClassLikeSupport.scala:221)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.extractMembers$(ClassLikeSupport.scala:15)
at dotty.tools.scaladoc.tasty.TastyParser.extractMembers(TastyParser.scala:169)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.extractPatchedMembers(ClassLikeSupport.scala:226)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.extractPatchedMembers$(ClassLikeSupport.scala:15)
at dotty.tools.scaladoc.tasty.TastyParser.extractPatchedMembers(TastyParser.scala:169)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.mkClass(ClassLikeSupport.scala:113)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.mkClass$(ClassLikeSupport.scala:15)
at dotty.tools.scaladoc.tasty.TastyParser.mkClass(TastyParser.scala:169)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.parseClasslike(ClassLikeSupport.scala:290)
at dotty.tools.scaladoc.tasty.ClassLikeSupport.parseClasslike$(ClassLikeSupport.scala:15)
at dotty.tools.scaladoc.tasty.TastyParser.parseClasslike(TastyParser.scala:169)
at dotty.tools.scaladoc.tasty.TastyParser$Traverser$2$.traverseTree(TastyParser.scala:223)
at scala.quoted.Quotes$reflectModule$TreeTraverser.foldTree(Quotes.scala:4666)
at scala.quoted.Quotes$reflectModule$TreeTraverser.foldTree$(Quotes.scala:4662)
at dotty.tools.scaladoc.tasty.TastyParser$Traverser$2$.foldTree(TastyParser.scala:211)
at dotty.tools.scaladoc.tasty.TastyParser$Traverser$2$.foldTree(TastyParser.scala:211)
at scala.quoted.Quotes$reflectModule$TreeAccumulator.foldTrees$$anonfun$1(Quotes.scala:4554)
at scala.collection.LinearSeqOps.foldLeft(LinearSeq.scala:169)
at scala.collection.LinearSeqOps.foldLeft$(LinearSeq.scala:165)
at scala.collection.immutable.List.foldLeft(List.scala:79)
at scala.quoted.Quotes$reflectModule$TreeAccumulator.foldTrees(Quotes.scala:4554)
at scala.quoted.Quotes$reflectModule$TreeAccumulator.foldTrees$(Quotes.scala:4549)
at dotty.tools.scaladoc.tasty.TastyParser$Traverser$2$.foldTrees(TastyParser.scala:211)
at scala.quoted.Quotes$reflectModule$TreeAccumulator.foldOverTree(Quotes.scala:4617)
at scala.quoted.Quotes$reflectModule$TreeAccumulator.foldOverTree$(Quotes.scala:4549)
at dotty.tools.scaladoc.tasty.TastyParser$Traverser$2$.foldOverTree(TastyParser.scala:211)
at scala.quoted.Quotes$reflectModule$TreeTraverser.traverseTreeChildren(Quotes.scala:4668)
at scala.quoted.Quotes$reflectModule$TreeTraverser.traverseTreeChildren$(Quotes.scala:4662)
at dotty.tools.scaladoc.tasty.TastyParser$Traverser$2$.traverseTreeChildren(TastyParser.scala:211)
at scala.quoted.Quotes$reflectModule$TreeTraverser.traverseTree(Quotes.scala:4664)
at scala.quoted.Quotes$reflectModule$TreeTraverser.traverseTree$(Quotes.scala:4662)
at dotty.tools.scaladoc.tasty.TastyParser$Traverser$2$.traverseTree(TastyParser.scala:219)
at dotty.tools.scaladoc.tasty.TastyParser.parseRootTree(TastyParser.scala:228)
at dotty.tools.scaladoc.tasty.ScaladocTastyInspector.$anonfun$4(TastyParser.scala:123)
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
at dotty.tools.scaladoc.tasty.ScaladocTastyInspector.postProcess$$anonfun$2(TastyParser.scala:42)
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
at scala.collection.immutable.List.foreach(List.scala:333)
at dotty.tools.scaladoc.tasty.ScaladocTastyInspector.postProcess(TastyParser.scala:42)
at scala.tasty.inspector.OldTastyInspector$TastyInspectorFinishPhase$1.runOn(OldTastyInspector.scala:91)
at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:234)
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1328)
at dotty.tools.dotc.Run.runPhases$1(Run.scala:245)
at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:253)
at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:262)
at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:68)
at dotty.tools.dotc.Run.compileUnits(Run.scala:262)
at dotty.tools.dotc.Run.compileUnits(Run.scala:192)
at dotty.tools.dotc.fromtasty.TASTYRun.compile(TASTYRun.scala:14)
at dotty.tools.dotc.Driver.doCompile(Driver.scala:35)
at dotty.tools.dotc.Driver.process(Driver.scala:195)
at scala.tasty.inspector.OldTastyInspector.inspectFilesInContext(OldTastyInspector.scala:72)
at scala.tasty.inspector.OldTastyInspector.inspectFilesInContext$(OldTastyInspector.scala:22)
at scala.tasty.inspector.DocTastyInspector.inspectFilesInContext(DocTastyInspector.scala:5)
at dotty.tools.scaladoc.tasty.ScaladocTastyInspector.result(TastyParser.scala:147)
at dotty.tools.scaladoc.ScalaModuleProvider$.mkModule(ScalaModuleProvider.scala:11)
at dotty.tools.scaladoc.Scaladoc$.run(Scaladoc.scala:230)
at dotty.tools.scaladoc.Scaladoc$.run$$anonfun$1(Scaladoc.scala:72)
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
at scala.Option.map(Option.scala:242)
at dotty.tools.scaladoc.Scaladoc$.run(Scaladoc.scala:76)
at dotty.tools.dottydoc.Main$.process(Main.scala:25)
at dotty.tools.dottydoc.Main.process(Main.scala)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at xsbt.DottydocRunner.run(DottydocRunner.java:61)
at xsbt.ScaladocInterface.run(ScaladocInterface.java:11)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at sbt.internal.inc.AnalyzingCompiler.invoke(AnalyzingCompiler.scala:329)
at sbt.internal.inc.AnalyzingCompiler.doc(AnalyzingCompiler.scala:175)
at sbt.internal.inc.AnalyzingCompiler.doc(AnalyzingCompiler.scala:133)
at sbt.Doc$.$anonfun$scaladoc$1(Doc.scala:52)
at sbt.Doc$.$anonfun$scaladoc$1$adapted(Doc.scala:40)
at sbt.RawCompileLike$.$anonfun$prepare$1(RawCompileLike.scala:79)
at sbt.RawCompileLike$.$anonfun$prepare$1$adapted(RawCompileLike.scala:72)
at sbt.RawCompileLike$.$anonfun$cached$4(RawCompileLike.scala:63)
at sbt.RawCompileLike$.$anonfun$cached$4$adapted(RawCompileLike.scala:61)
at sbt.util.Tracked$.$anonfun$inputChangedW$1(Tracked.scala:219)
at sbt.RawCompileLike$.$anonfun$cached$1(RawCompileLike.scala:68)
at sbt.RawCompileLike$.$anonfun$cached$1$adapted(RawCompileLike.scala:52)
at sbt.Defaults$.$anonfun$docTaskSettings$4(Defaults.scala:2157)
at scala.Function1.$anonfun$compose$1(Function1.scala:49)
at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
at sbt.std.Transform$$anon$4.work(Transform.scala:68)
at sbt.Execute.$anonfun$submit$2(Execute.scala:282)
at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23)
at sbt.Execute.work(Execute.scala:291)
at sbt.Execute.$anonfun$submit$1(Execute.scala:282)
at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
at sbt.CompletionService$$anon$2.call(CompletionService.scala:64)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
[info] Main Scala API documentation successful. Yeah there are more.. |
One thing I wonder is if the parent must be Java-defined to trigger the bug. Not every Java-defined parent triggers it, though (for example, the problem goes away if you change @anatoliykmetyuk might be a good spree ticket? |
reported again at #16290 (on |
I'm seeing this as well, with traits/abstract classes extending Same stacktrace as above: Scala 3.2.2-RC1 |
This issue was picked for the Issue Spree No. 25 of 24 January 2023 which takes place in a week from now. @SethTisue, @jan-pieter, @yzia2000 will be working on it. If you have any insight into the issue or guidance on how to fix it, please leave it here. |
When preparing for a spree, one tries to strike a balance between being unprepared, and over-preparing in the sense that you figure out what's going on before the spree has even started :-) I wasn't sure how the Scaladoc tool was tested, and there didn't seem to be a relevant directory under so I searched recently merged PRs for "Scaladoc": https://github.com/lampepfl/dotty/pulls?q=is%3Apr+sort%3Aupdated-desc+is%3Amerged+scaladoc since presumably these PRs would touch test cases and indeed, that led me to discover the then I wondered how they were run, and after further poking around I found
wow, cool! but still not clear to me how to run the tests? as a guess, maybe so I tried creating another thing that perhaps I'm expected to somehow tell the testing stuff that I added a file, maybe files in but it's not clear to me in this case where the right place to add my new file would be. maybe to so at the end of that file I added:
and I ran and it said "The test name is incorrect or scaladoc-testcases were not recompiled" I looked at another test file in the same directory and I noticed it started with a package declaration, so I tried changing package tests
package numeric
trait Foo extends Numeric[Any] and lo and behold, now when I run and I also verified that if I changed the test file to something harmless like so, I think at this point we know one way to add a test for this — maybe not the best way, but enough to proceed with attempting a fix at the spree @jan-pieter it looks like you have one previous contribution here, and @yzia2000 it looks like it's your first time? though I might be mistaken? if I'm right, we should let @yzia2000 drive to make sure he gets up to speed on basics of contributing |
Fixes scala#15927 Check for whether the java parent exists before checking the start and end of the span to confirm whether the span exists in getParentsAsTreeSymbolTuples.
We believe the problem is in parentTree <- c.parents if parentTree.pos.start != parentTree.pos.end // We assume here that order is correct if What we want is to call In the long run, we should add probably add |
Caveat: not crashing isn't enough, we also need to verify that the parent still shows up in the generated Scaladoc. |
No, because for example |
in the sbt build, |
Fixes scala#15927 Check for whether the java parent exists before checking the start and end of the span to confirm whether the span exists in getParentsAsTreeSymbolTuples.
Fixes scala#15927 Check for whether the non-scala3 parent exists before checking the start and end of the span to confirm whether the span exists in getParentsAsTreeSymbolTuples.
…hods are not safe to call on non-existing Spans. Fixes scala#15927
…hods are not safe to call on non-existing Spans. Fixes scala#15927
Minor comment about wording: would |
good comment/question, but: |
I lived through the same, so this seems to indicate some documentation is missing I had actually isolated a commit to make it only about setting up the test: 5671d26 Something that pointed in the right direction was the old behaviour of running
I don't know why the behavior was changed I do not have time at the moment, do you think you could investigate what makes it hard to start the scaladoc tests, and address it ? (Probably through creating some documentation in the readme or in https://docs.scala-lang.org/scala3/guides/contribution/procedures-intro.html, in particular https://docs.scala-lang.org/scala3/guides/contribution/procedures-testing.html does not mention the commands to test other things like scaladoc) |
The tree that has a non-existent position should have a position. |
The way to debug this is to set |
It seems that the problematic trees are generated here: We should probably set the span of those trees to |
(working on it over at #16769) |
Thanks @nicolasstucki for digging into the underlying cause. I'll get back to it (but not right away). |
Fixes scala#15927 Check for whether the non-scala3 parent exists before checking the start and end of the span to confirm whether the span exists in getParentsAsTreeSymbolTuples.
Compiler version
3.2.0.rc4 and sbt 1.7.1,
If you're not sure what version you're using, run
print scalaVersion
from sbt(if you're running scalac manually, use
scalac -version
instead).Minimized code
Output (click arrow to expand)
The text was updated successfully, but these errors were encountered: