Skip to content

Fix #2760: Support defaults in Java annotations parsed from sources #3865

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

Merged
merged 3 commits into from
Mar 26, 2018

Conversation

smarter
Copy link
Member

@smarter smarter commented Jan 18, 2018

No description provided.

@smarter smarter force-pushed the fix/java-default-annot branch 2 times, most recently from 56ec914 to d00f754 Compare January 18, 2018 14:29
@smarter smarter requested a review from odersky January 18, 2018 15:42
@@ -0,0 +1 @@
@Fork(value = 16) class Test
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we know we get the right default in the backend? Can we make this a run test?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, done :).

@smarter
Copy link
Member Author

smarter commented Feb 1, 2018

Hmm, the run test revealed another issue:

Exception in thread "main" java.lang.NoSuchFieldError: value
        at Test$.main(Test.scala:6)
        at Test.main(Test.scala)

Calling fork.value fails because Fork has a method value, not a field value, but the Java parser outputs a val:

  abstract class Fork(val value: Int = _root_.scala.Predef.???, 
    val warmups: Int = _root_.scala.Predef.???
  ) extends _root_.scala.annotation.Annotation with _root_.java.lang.annotation.
    Annotation
   with _root_.scala.annotation.ClassfileAnnotation {}

and the Getters mini-phase wil not transform JavaDefined symbols. I think the simplest thing to do here is to use defs instead of vals and create default getters by hand like ClassfileParser does: https://github.com/lampepfl/dotty/blob/7058f69fe1852b7776e703692555a0b4e4dcf37f/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala#L640-L645

smarter added 3 commits March 23, 2018 20:54
It's defined in scala.annotation.internal, not scala.runtime
This commit is enough to get the added testcase to compile but not to
run (it crashes with a NoSuchFieldError), this is fixed in the next
commit.
Previously, for tests/run/i2760/Fork.java, the parser output was:

    abstract class Fork(val value: Int = ???,  val warmups: Int = ???)
    extends ...

Since Fork is JavaDefined, calls to `value` were translated into
field calls, but `value` is a method, not a field, so i2760 crashed at
runtime with NoSuchFieldError. We now generate instead:

    abstract class Fork private[this](x$1: _root_.scala.Unit)
    extends ... {
       def <init>(value: Int = ???, warmups: Int = ???)

       def value(): Int = 1
       def warmups(): Int = 1
    }

This way we get both named parameters for the constructor and real
method calls.
@smarter smarter force-pushed the fix/java-default-annot branch from fb316ee to a1a1a4b Compare March 23, 2018 20:25
@smarter smarter removed the stat:wip label Mar 23, 2018
@smarter
Copy link
Member Author

smarter commented Mar 23, 2018

Fixed by tweaking the parser output, see last commit.

@smarter smarter assigned odersky and unassigned smarter Mar 23, 2018
Copy link
Contributor

@odersky odersky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@odersky odersky merged commit b74b492 into scala:master Mar 26, 2018
@allanrenucci allanrenucci deleted the fix/java-default-annot branch March 26, 2018 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants