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

Streamline logic related to accessor derivation in MethodSynthesis & Namers #4709

Merged
merged 3 commits into from Sep 8, 2015

Conversation

adriaanm
Copy link
Contributor

Distinguish abstract ValDef from ValDef that needs a setter.
(Later, all trait vals will also need a setter -- right now, it's only mutable ones.)

Similarly, make explicit whether a field is needed. (Later, fields will not be emitted for traits.)

Simplify decision whether to derive accessors. Comments in the original code below (modulo renaming & reduction of double negation in previous commit) explain why I believe my changes make sense:

def deriveAccessors(vd: ValDef) = vd.mods.isLazy || !(
     !owner.isClass
  || (vd.mods.isPrivateLocal && !vd.mods.isCaseAccessor) // this is an error -- now checking first
  || (vd.name startsWith nme.OUTER)
  || (context.unit.isJava) // pulled out to caller
  || isEnumConstant(vd)
)

def deriveAccessorTrees(vd: ValDef) = !(
     (vd.mods.isPrivateLocal && !vd.mods.isLazy) // lazy was pulled out to outer disjunction
  || vd.symbol.isModuleVar // pulled out to caller
  || isEnumConstant(vd))

These conditions are now captured by one method.

Review by @lrytz, @retronym & @SethTisue. I'll check bytecode diffs (should be empty) later tonight.

@scala-jenkins scala-jenkins added this to the 2.12.0-M3 milestone Aug 25, 2015
@adriaanm
Copy link
Contributor Author

This is in preparation of https://github.com/adriaanm/scala/tree/traits-late-fields, which will ultimately enable the interfaces-with-default-methods encoding of traits.

tree.symbol = (
if (mods.isLazy) {
// TODO: why is all this symbol creation disconnected from addDerivedTrees,
// which creates another list of Field/Getter/Setter factories???
Copy link
Member

Choose a reason for hiding this comment

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

Looks like this part enters the symbols (which needs to be done before typechecking), and addDerivedTrees is called to create the corresponding trees during typechecking.

I agree it would be cleaner to keep track of the factories we create here (maybe as a attachment on the ValDef's symbol?) and avoid the duplicated logic in allValDefDerived.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • I'll include your comment to improve on my snarky rhetoric.

@adriaanm
Copy link
Contributor Author

Progress? EDIT: nope, bug in my refactoring (in doNotDeriveField).

Testcase: testDefWithLazyVal2 took 0.096 sec
    FAILED
using toolbox typechecker
 expected:<... {
  lazy val test: []Unit = {
    scala.P...> but was:<... {
  lazy val test: [scala.]Unit = {
    scala.P...>
junit.framework.AssertionFailedError: using toolbox typechecker
 expected:<... {
  lazy val test: []Unit = {
    scala.P...> but was:<... {
  lazy val test: [scala.]Unit = {
    scala.P...>
    at scala.reflect.internal.PrinterHelper$.assertResultCode(PrintersTest.scala:53)
    at scala.reflect.internal.PrinterHelper$.assertPrintedCode(PrintersTest.scala:67)
    at scala.reflect.internal.ValAndDefPrintTests$class.testDefWithLazyVal2(PrintersTest.scala:1013)
    at scala.reflect.internal.PrintersTest.testDefWithLazyVal2(PrintersTest.scala:12)

@adriaanm
Copy link
Contributor Author

adriaanm commented Sep 2, 2015

I rebased, addressing some feedback in earlier commits, adding the assert last for easy reversal.

Give Getter control over whether a setter is needed. For now,
only mutable ValDefs entail setters. In the new trait encoding,
a trait val will also receive a setter from the start.

Similarly, distinguish whether to derive a field from deferredness of the val.
(Later, fields will not be emitted for traits, deferred or not.)
Originally (modulo renaming & reduction of double negation in previous commit):

```
def deriveAccessors(vd: ValDef) = vd.mods.isLazy || !(
     !owner.isClass
  || (vd.mods.isPrivateLocal && !vd.mods.isCaseAccessor) // this is an error -- now checking first
  || (vd.name startsWith nme.OUTER)
  || (context.unit.isJava) // pulled out to caller
  || isEnumConstant(vd)
)

def deriveAccessorTrees(vd: ValDef) = !(
     (vd.mods.isPrivateLocal && !vd.mods.isLazy) // lazy was pulled out to outer disjunction
  || vd.symbol.isModuleVar // pulled out to caller
  || isEnumConstant(vd))
```

With changes in comments above, these conditions are now captured by one method.
@adriaanm
Copy link
Contributor Author

adriaanm commented Sep 2, 2015

@retronym
Copy link
Member

retronym commented Sep 8, 2015

LGTM

retronym added a commit that referenced this pull request Sep 8, 2015
Streamline logic related to accessor derivation in MethodSynthesis & Namers
@retronym retronym merged commit 468abc4 into scala:2.12.x Sep 8, 2015
@adriaanm adriaanm deleted the namers-accessors branch April 27, 2016 20:08
@adriaanm adriaanm added 2.12 and removed 2.12 labels Oct 29, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants