scalameta / mdoc

Typechecked markdown documentation for Scala
https://scalameta.org/mdoc/
Apache License 2.0
394 stars 80 forks source link

Snippets which include @main #879

Open adamw opened 1 month ago

adamw commented 1 month ago

Currently, such snippets cause the following error:

error: x.md:51:1:
method xyz cannot be a main method since it cannot be accessed statically
@main def xyz(): Unit =
^^^^^

maybe it would make sense to include an option to filter out @main from the snippets text, so that example code could still be verified, but also copy-pasteable for anybody wanting to try on their own?

tgodzik commented 1 month ago

You should be able to use https://scalameta.org/mdoc/docs/modifiers.html#reset-object so that the code is inside an object. I don't think we should filter anything as it might become a complex heuristic easily

adamw commented 1 month ago

Awesome! This works - thanks :)

adamw commented 1 month ago

Well, almost ;) If I have multiple mdoc:reset-object:silent clauses, I get:

error: 01_hello_world.md:80:1:
helloWorldTapir is already defined as class helloWorldTapir in 01_hello_world.md
@main def helloWorldTapir(): Unit =
^^^^^

It works with a single snippet.

tgodzik commented 1 month ago

Does it work with reset also? I think ideally resetObject should always be a different scope. If that doesn't work the only other workaround for now would be changing the main's name.

adamw commented 1 month ago

no, reset fails with the original error message. Shouldn't resetObject generate a new "fresh" name every time?

tgodzik commented 1 month ago

no, reset fails with the original error message. Shouldn't resetObject generate a new "fresh" name every time?

I think so, though I wonder if that doesn't play nice with @main annotation

adamw commented 1 month ago

ah, might be ... the compiler might be generating the top-level method then

tgodzik commented 1 month ago

Looks like it:

image

It can't even be in the same package, so would need to be separate compilation unit altogether. I don't think we want to work around that problem. Filtering @main might work, but on the other hand we should not modify the code, this can be misleading

tgodzik commented 1 month ago

Or we would need a resetPackage option:

image

adamw commented 1 month ago

ah yes, a :resetPackage:resetObject:silent could work :)

tgodzik commented 1 month ago

For now my recommendation would be to just name it differently. If anyone want to take a look I did a quick stab at it (https://github.com/tgodzik/mdoc/tree/reset-package) , but then forgot I need more than just a package, so we would need to make sure packages are sensibly handled if defined and even if not defined.