Skip to content
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

hide private classes and methods #47

Closed
wants to merge 4 commits into from

Conversation

mengxr
Copy link

@mengxr mengxr commented Feb 5, 2015

I'm not sure whether this is the correct way to hide private classes and methods from generated Java docs. It seems to work on Apache Spark.

CC: @rxin

@viktorklang
Copy link

Ping @rkuhn

@rkuhn
Copy link
Contributor

rkuhn commented Mar 13, 2015

Oh, thanks Viktor, it seems that I don’t get notifications anymore. Will have to defer deeper look until after my ScalaDays presentation is at least somewhat in shape.

@dragos
Copy link

dragos commented Mar 13, 2015

I think this is a good improvement, but it currently fails tests, for example:

[error] /Users/dragos/workspace/git/genjavadoc/tests/target/java/akka/rk/buh/is/it/PTrait.java:5: error: modifier private not allowed here
[error] private  interface PTrait {
[error]          ^
[error] 5 errors

It would be good to also add some tests to illustrate how this is supposed to work. On top of my head, private[qualifier] does not translate to private members on the JVM (unless qualifier == this), so what is the correct thing to do for genjavadoc? Should it follow the scalac encoding (what it does right now), or it should follow the Scala semantics (and discourage usage from Java). I believe this PR wants to implement the second behavior, but it should probably have a flag to turn it on explicitly.

@rkuhn
Copy link
Contributor

rkuhn commented Mar 13, 2015

Without having looked at the details yet the intention is to follow Scala semantics: there should not be any docs for methods that should actually not be accessible (but are due to lack of byte-code expressiveness).

@2m
Copy link
Contributor

2m commented Mar 14, 2015

Closing and reopening for PR validation to kick in.

@2m 2m closed this Mar 14, 2015
@2m 2m reopened this Mar 14, 2015
@mengxr
Copy link
Author

mengxr commented Mar 14, 2015

I didn't update the tests because we may want to discuss the semantics first. If the target here is to generate the JavaDoc, I think we should hide all package private classes/methods. Those are not supposed to be called by Scala users. Java users should not see them either. If we agree on this, I'll go and update the tests.

@mengxr
Copy link
Author

mengxr commented Mar 14, 2015

I mapped Scala's package private to Java's empty modifier, so Java compiler won't complain on private class or private interface.

@@ -97,14 +97,16 @@ trait AST { this: TransformCake ⇒
if (m.isPublic) "public"
else if (m.isProtected && !topLevel) "protected"
else if (m.isPrivate && !topLevel) "private"
else "public" // this is the case for “private[xy]” and top level classes
else if (m.privateWithin != tpnme.EMPTY) ""
Copy link

Choose a reason for hiding this comment

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

privateWithin may point to any enclosing definition (this, enclosing class or package, and packages nest). I think you'd need to consider the following mappings:

package org.example

class Outer {
  class Inner {
     private[this] val x
     private[Inner] val y
     private[Outer] val z
     private[example] val t
     private[org] val u
  }
}
  • private[this] --> private
  • private[Inner] --> private
  • private[Outer] --> ?? (I guess private again)
  • private[org|example] --> ""

What do you think?

Copy link
Author

Choose a reason for hiding this comment

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

private[org] val u under org.example has to be public in Java. Otherwise, if there exists references to u under org, the Java code won't compile. Is it correct?

Copy link

Choose a reason for hiding this comment

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

I'm not very sure about how java doc works. Does it expect everything to type-check according to Java rules? If that's the case, I think this comment would apply everywhere Scala makes something public in classfiles that was private in source. So probably none of the changes here would be safe to do. AFAIK the compiler does not make anything public just for tha sake of it.

@rkuhn
Copy link
Contributor

rkuhn commented Mar 17, 2015

Sorry for keeping you waiting so long, but I’ll have to defer really looking into this until after ScalaDays.

@dragos
Copy link

dragos commented Jun 15, 2015

@rkuhn could you have a look at this one now that ScalaDays is behind us?

@rkuhn
Copy link
Contributor

rkuhn commented Jun 18, 2015

Currently a bit difficult, how urgent is it?

@rkuhn
Copy link
Contributor

rkuhn commented Jun 25, 2015

Hmm, trying this out I find that Scalac’s behavior does not match my previous understanding: I thought that protected[<package>] should result in package protected Java byte-code, but that is not the case. Having the emitted Java code be stricter than the real byte-code will result in javadoc failures, especially with the extremely picky updates in JDK8, so I’m wary to tighten things up here.

Is this really needed?

@dragos
Copy link

dragos commented Jul 3, 2015

Could we put this behind a flag? It seems to be useful at least for projects that don't use the fact that Scala packages nest (so no private[org] or the like). @mengxr what do you think? Would this remove the need for the Spark fork?

@mengxr
Copy link
Author

mengxr commented Jul 5, 2015

@rkuhn @dragos Yes, based on the discussion I think using flags would be a reasonable solution. Then we can remove our fork for Spark. What flags do you recommend? For Spark use cases, we only need to hide package private traits/classes and methods from the generated JavaDoc. So maybe we can start with making these configurable first. If people ask for more, we could add others in the future. Does it sound good to you? I'm not familiar with the code base. It would be really helpful if you can show me an existing flag implementation in genjavadoc.

@dragos
Copy link

dragos commented Jul 6, 2015

@mengxr I think this would be the first instance of a flag, and your suggestion makes sense to me. I'll let @rkuhn comment, this was only my take, but I'm not the author/maintainer.

@rkuhn
Copy link
Contributor

rkuhn commented Jul 6, 2015

Yes, providing this capability behind a flag would be a good compromise. There is one challenge, though, and that is how to test this feature then. I guess it needs another subproject next to tests because it needs to compile some files with the feature flag and then verify that the right Java sources drop out—we don’t need to check for classfile equivalence because that would be (intentionally) violated anyway.

@mengxr would you mind changing this PR towards such a scheme? Thanks a lot for contributing and for bearing with my slowness.

Concerning a release: my plan was to push out 1.0 last week but I discovered some more bugs that need fixing first :-( This week I’m at CurryOn so I might not get around to this.

@dragos
Copy link

dragos commented Jul 7, 2015

Sorry to hijack this thread, but @mengxr can you please publish a 2.11.7 version of your fork? See my PR stalled for more than a week now: apache/spark#6903

@mengxr
Copy link
Author

mengxr commented Aug 5, 2015

Sorry that I didn't have time to work on this. I will try to take a look next week.

@mengxr
Copy link
Author

mengxr commented Mar 17, 2016

cc: @jodersky

@jodersky
Copy link
Contributor

@mengxr I'm in the process of rebasing your changes and solving conflicts. Was the only issue stopping a merge the missing flag (and tests)?

@mengxr
Copy link
Author

mengxr commented Mar 23, 2016

Yes, I guess so. We could make it more general, e.g., allow customizing scope mapping. But for Spark releases, we only need a boolean feature flag for hiding package private classes/members in the generated Java API doc.

@jodersky
Copy link
Contributor

@dragos, what would be the best way to implement a flag for the features discussed in this PR?
I guess it's more of a general question, what's the convention for passing flags to compiler plugins?

@jodersky
Copy link
Contributor

never mind, it was right under my nose

@mengxr mengxr closed this Mar 25, 2016
2m added a commit that referenced this pull request Apr 15, 2016
Private access visibility (follow-up to #47)
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.

6 participants