Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
Choose a Base Repository
scala/scala
4e6/scala
Acidburn0zzz/scala
AesirMachina/scala
AndreVanDelft/scala
AndreaCrotti/scala
Blaisorblade/scala
DavidBiesack/scala
EdSimonoff/scala
IntotheCode01/scala
JamesIry/scala
Jesus-loves-you/scala
Jiwei0/scala
Johnlon/scala
JunSuzukiJapan/scala
LannyRipple/scala
MarcusChang/scala
Omeqagear/scala
Open-Source-Learn/scala
ScionM1009/scala
TheByteKnight/scala
TiarkRompf/scala
Zealsathish/scala
ZeusbaseWeb/scala
acruise/scala
adamalix/scala
adriaanm/scala
agiledon/scala
alexclare/scala
alireza-naghizadeh/scala
amumuisbest/scala
andry-k/scala
anshul-cached/scala
arnfred/scala
axel22/scala-github
aztek/scala
benhutchison/scala-1
bhuber/scala
blair/scala
bocchino/ScalaLE-Compiler
chris-twiner/scala
chrislewis/scala
chuvoks/scala
colder/scala
colladoc/scala
commonlisp/scala
ctalau/scala
cvogt/scala
davidandrzej/scala
dcsobral/scala
densh/scala
dgruntz/scala
dineshk22/scala
dlwh/scala
dojotech/scala
dongjoon-hyun/scala
doubleotoo/scala
dragos/scala
dvigal/scala
dyx/scala
edmundnoble/scala
eed3si9n/scala
erikrozendaal/scala
espadrine/scala
etaty/scala
fdalmaso/scala
fmlrt/scala
free-books/scala
fridayIT/scala
gakuzzzz/scala
geokollias/scala
gkossakowski/scala
greedy/scala
guersam/scala
gustavonalle/scala
haraldme/scala
haroldoramirez/scala
harrah/scala
havocp/scala
hcchen/scala
headinthebox/scala
heathermiller/scala
hoanguyen81190/scala
huangbqsky/scala
hubertp/scala-dev
iainmcgin/scala
igor-petruk/scala
ihji/scala
ijuma/scala
ikuraj/scala
ingoem/scala
jamesward/scala
jdanbrown/scala
jeffsang/scala
jmurzy/scala
joshmarcus/scala
jrudolph/scala
jsuereth/scala
julienrf/scala
julio/scala
juneyoung/scala
khernyo/scala
klaperman/scala
ktoso/scala
kzys/scala
l0rdn1kk0n/scala
lalithsuresh/scala
lampepfl/scala
ldpadelin/scala
leifwickland/scala
lexspoon/scala
liyapingXY/scala
lossyrob/scala
magarciaEPFL/scala
mandubian/scala
manojo/scala
manuelbernhardt/scala
marcinidasiak/scala
melezov/scala
miandreu/scala
michelou/scala-parlib
migue/scala
milessabin/scala
milliondreams/scala
mingjin/scala
mlbileschi/scala
mt2309/scala
mwiacek/scala
nadezhin/scala
namin/scala
nbronson/scala
netroby/scala
nicholassm/scala
non/scala
notnoop/scala
ochafik/scala-loops
odersky/scala
ozzie00/scala-1
pandabucks/scala
parambirs/scala
patrickxia/scala
paulbutcher/scala
pavelpavlov/scala
pbzdyl/scala
pchapin/scala
phaller/scala
pniederw/scala
postbird/scala
pranjal5215/scala
rahul1719/scala
rcoh/scala
retronym/scala
rjmac/scala
rklaehn/scala
rkuhn/scala
robinst/scala
rodzyn0688/scala
rorygraves/scalac_perf
rssh/scala
rtyley/scala
rubenbaer/scala
ryanbw/scala
samskivert/scala
sanjeevonline/scala
sassembla/scala
scala-ide/scala
scala-virtualized/scala
scalacenter/scala
scalamacros/kepler
sergz72/scala
sgolodetz/scala
sjrd/scala
soc/scala
som-snytt/scala
sreeteja999/scala
srp/scala
ssvastav/scala
stegenish/scala
stephenjudkins/scala
symsec/scala
syokucyo/scala
szeiger/scala
taolee/scala
tekverkp/scala
tlockney/scala
tslominski/scala
twitter-forks/scala
typelevel/scala
vinayshivanna/scala
vjovanov/scala
walidcafe/scala
westhood/scala
xcarpentier/scala
xjdx/scala
xuwei-k/scala-1
yadavjpr/scala
yajxh/scala
ybr/scala
zeloran571/scala
zengxi2014/scala
Nothing to show
Choose a Head Repository
scala/scala
4e6/scala
Acidburn0zzz/scala
AesirMachina/scala
AndreVanDelft/scala
AndreaCrotti/scala
Blaisorblade/scala
DavidBiesack/scala
EdSimonoff/scala
IntotheCode01/scala
JamesIry/scala
Jesus-loves-you/scala
Jiwei0/scala
Johnlon/scala
JunSuzukiJapan/scala
LannyRipple/scala
MarcusChang/scala
Omeqagear/scala
Open-Source-Learn/scala
ScionM1009/scala
TheByteKnight/scala
TiarkRompf/scala
Zealsathish/scala
ZeusbaseWeb/scala
acruise/scala
adamalix/scala
adriaanm/scala
agiledon/scala
alexclare/scala
alireza-naghizadeh/scala
amumuisbest/scala
andry-k/scala
anshul-cached/scala
arnfred/scala
axel22/scala-github
aztek/scala
benhutchison/scala-1
bhuber/scala
blair/scala
bocchino/ScalaLE-Compiler
chris-twiner/scala
chrislewis/scala
chuvoks/scala
colder/scala
colladoc/scala
commonlisp/scala
ctalau/scala
cvogt/scala
davidandrzej/scala
dcsobral/scala
densh/scala
dgruntz/scala
dineshk22/scala
dlwh/scala
dojotech/scala
dongjoon-hyun/scala
doubleotoo/scala
dragos/scala
dvigal/scala
dyx/scala
edmundnoble/scala
eed3si9n/scala
erikrozendaal/scala
espadrine/scala
etaty/scala
fdalmaso/scala
fmlrt/scala
free-books/scala
fridayIT/scala
gakuzzzz/scala
geokollias/scala
gkossakowski/scala
greedy/scala
guersam/scala
gustavonalle/scala
haraldme/scala
haroldoramirez/scala
harrah/scala
havocp/scala
hcchen/scala
headinthebox/scala
heathermiller/scala
hoanguyen81190/scala
huangbqsky/scala
hubertp/scala-dev
iainmcgin/scala
igor-petruk/scala
ihji/scala
ijuma/scala
ikuraj/scala
ingoem/scala
jamesward/scala
jdanbrown/scala
jeffsang/scala
jmurzy/scala
joshmarcus/scala
jrudolph/scala
jsuereth/scala
julienrf/scala
julio/scala
juneyoung/scala
khernyo/scala
klaperman/scala
ktoso/scala
kzys/scala
l0rdn1kk0n/scala
lalithsuresh/scala
lampepfl/scala
ldpadelin/scala
leifwickland/scala
lexspoon/scala
liyapingXY/scala
lossyrob/scala
magarciaEPFL/scala
mandubian/scala
manojo/scala
manuelbernhardt/scala
marcinidasiak/scala
melezov/scala
miandreu/scala
michelou/scala-parlib
migue/scala
milessabin/scala
milliondreams/scala
mingjin/scala
mlbileschi/scala
mt2309/scala
mwiacek/scala
nadezhin/scala
namin/scala
nbronson/scala
netroby/scala
nicholassm/scala
non/scala
notnoop/scala
ochafik/scala-loops
odersky/scala
ozzie00/scala-1
pandabucks/scala
parambirs/scala
patrickxia/scala
paulbutcher/scala
pavelpavlov/scala
pbzdyl/scala
pchapin/scala
phaller/scala
pniederw/scala
postbird/scala
pranjal5215/scala
rahul1719/scala
rcoh/scala
retronym/scala
rjmac/scala
rklaehn/scala
rkuhn/scala
robinst/scala
rodzyn0688/scala
rorygraves/scalac_perf
rssh/scala
rtyley/scala
rubenbaer/scala
ryanbw/scala
samskivert/scala
sanjeevonline/scala
sassembla/scala
scala-ide/scala
scala-virtualized/scala
scalacenter/scala
scalamacros/kepler
sergz72/scala
sgolodetz/scala
sjrd/scala
soc/scala
som-snytt/scala
sreeteja999/scala
srp/scala
ssvastav/scala
stegenish/scala
stephenjudkins/scala
symsec/scala
syokucyo/scala
szeiger/scala
taolee/scala
tekverkp/scala
tlockney/scala
tslominski/scala
twitter-forks/scala
typelevel/scala
vinayshivanna/scala
vjovanov/scala
walidcafe/scala
westhood/scala
xcarpentier/scala
xjdx/scala
xuwei-k/scala-1
yadavjpr/scala
yajxh/scala
ybr/scala
zeloran571/scala
zengxi2014/scala
Nothing to show
Choose a head branch
2.8.x
2.9.x
2.10.x
2.11.x
2.12.x
SI-2034
SI-2080
SI-2818-reduceRight
SI-2856
SI-3235-deprecation
SI-3235
SI-3481
SI-3556
SI-4023
SI-4478
SI-4619
SI-4627
SI-4658-numericrange
SI-4658-range
SI-4788-new
SI-4788
SI-4950
SI-4990
SI-4990#2
SI-5034
SI-5353
SI-5394
SI-5666
SI-5722-2.11
SI-5722
SI-6064
SI-6162-public
SI-6167a
SI-6167
SI-6345
SI-6380-fixup+SI-6626
SI-6380
SI-6388-app-predef
SI-6388-application-predef
SI-6388-compiler
SI-6388-misc
SI-6388-without-predef
SI-6388
SI-6407
SI-6449
SI-6503
SI-6626
SI-6632+SI-6633
SI-6632
SI-6634-for-2.11
SI-6634
SI-6746
SI-6747
SI-6809
SI-6811-automata
SI-6811-cloneable-definition
SI-6811-json
SI-6811-moves
SI-6811-parsing-old
SI-6811-parsing
SI-6811-removals
SI-6811-text
SI-6811-xinclude
SI-6918
SI-6969-2.9.x
SI-6991
SI-6998
SI-7017
SI-7155
SI-7174
SI-7236
SI-7237-2.9
SI-7237-2.10
SI-7237
SI-7258
SI-7265-temporary-fix
SI-7265
SI-7281-workaround
SI-7292-fix
SI-7292
SI-7303-remove-name-mangling
SI-7391-2.9
SI-7391-2.10
SI-7391
SI-7402
SI-7403
SI-7408
SI-7462-no-unqualified-java-lang
SI-7462-specific-java-lang-imports
SI-7469-ast
SI-7469-combinator
SI-7469-concurrent
SI-7469-hashing
SI-7469-java-collections
SI-7469-logging
SI-7469-repl
SI-7469
SI-7474
SI-7476
SI-7479
SI-7480
SI-7484
SI-7492-redux
SI-7492
SI-7497-2.9
SI-7497
SI-7511
SI-7523
SI-7546
SI-7564-redux
SI-7564
SI-7566-actor-leftovers
SI-7566-actors
SI-7566-collection-parallel
SI-7566-manifests
SI-7566-predef
SI-7566-text
SI-7566
SI-7590
SI-7591
SI-7592-defaultmapmodel
SI-7592-multihashmap
SI-7592
SI-7599
SI-7600
SI-7605-deprecate-procedures
SI-7618
SI-7620
SI-7624-2
SI-7624
SI-7629-deprecate-view-bounds
SI-7630
SI-7633
SI-7658
SI-7679-remove-standardscalasettings-make
SI-7680
SI-7681-dead-code-changes
SI-7681-dead-code-daemonthreadfactory
SI-7681-dead-code-phases
SI-7681-dead-code-settinggroup
SI-7704-redux
SI-7704
SI-7880
SI-7961
SI-7971
SI-7974
SI-7999
SI-8035
SI-8050
SI-8052
SI-8058-enums
SI-8059
SI-8226
SI-8700
SI-8778
SI-8916
SI-8927
SI-8928-better-annotations
SI-8928
SI-9080
SI-9081
SI-9173-either-product-serializable
SI-9174
SI-9315-less-boxing
SI-9315
SI-9437
SI-9539
SI-9560-scaladoc-json-dep
SI-9607
SI-9709
SI-9892-list-tails
SI-10033
master
no-bridges
partest-formatting
patch-1
patch-2
patch-3
paulp/orphaned
poc/no-constant-inlining
scaladoc-anyval
scaladoc-controlthrowable
scaladoc-hashsetmap
scaladoc-links
scaladoc-spacing
topic/annotations-throws
topic/annotations
topic/avian-test-fixes
topic/avian-tests
topic/backend-cleanup
topic/better-enum-tree-support
topic/biased-either-fixup
topic/biased-either
topic/broken-symbol-cleanup
topic/case-syntax
topic/classOf-macro-2.11
topic/classOf-macro
topic/collection-get
topic/deprecation-fixes-2.12
topic/deprecations-2.12
topic/deprecations-since-everything
topic/deprecations-since
topic/drop-genasm
topic/drop-icode-genasm
topic/drop-icode
topic/drop-threadpool-fallback
topic/enums
topic/int-long-bitops
topic/interfaces-any
topic/io-to-interactive
topic/java-annotations
topic/java-rawtype-cleanup
topic/java-runtime-warnings-cleanup
topic/less-warnings-for-2.12
topic/macro-constructors
topic/marco-constructors
topic/misc-warning-fixes
topic/module-to-object
topic/no-bridges-for-covariant-overrides
topic/no-implicit-widening-conversions-between-intergral-and-floating-point-types
topic/no-new-in-annotation-printing
topic/no-procedures
topic/no-useless-curly-braces
topic/osgi-feature-warnings
topic/osgi
topic/osgi2
topic/paulp-package-objects
topic/paulp-record-symbol-arity
topic/paulp-typer-crash-output
topic/paulp-typer-debug-output
topic/remove-deprecation-warnings
topic/remove-fsc
topic/replace-treeset
topic/scala-partest-1.0.3
topic/scalacheck-1.12.1
topic/serialversionuid-spam
topic/spec-default-args
topic/spec-history
topic/spec
topic/std-in
topic/stream-lazylist
topic/throws-clause-as-annotation
topic/unused-imports
topic/virtual-classes
topic/virtual-new
typelevel/2.11.x
wip/annotation-target
wip/binary-literals
wip/function1-flatMap
wip/tagged-collection
Nothing to show
Checking mergeability… Don’t worry, you can still create the pull request.
  • 1 commit
  • 46 files changed
  • 0 commit comments
  • 1 contributor
Commits on Oct 01, 2016
soc
Deprecate scala.Enumeration, add @enum annotation
Rough draft, some things are necessarily ugly, others temporarily.

The syntax

    @enum
    class Week(val isWeekend: Boolean = false) {
      Monday  (false)
      ...
      ...
      Friday  (false)            { def isGoodDay = true }
      Saturday(true)             { val isGoodDay = true }
      Sunday  (isWeekend = true) { def isGoodDay = true }

      def isGoodDay = false
    }

is a possible implementation example, intention is to also support ADTs
that conform to certain restrictions (no nesting, recursion or
varying constructor parameters), e. g.:

    @enum
    sealed trait Toggle
    case object ON  extends Toggle
    case object OFF extends Toggle

Deprecates the unmitigated disaster that is scala.Enumeration.
Advantages of @enum over scala.Enumeration:
 - Actually works
 - Java interop
 - No erasure issues
 - No confusing mini-DSL to learn when defining enumerations

Disadvantages: None.

This addresses the issue of not being able to have one codebase that
supports Scala-JVM, Scala.js and Scala-Native (Java source code
not supported on Scala.js/Scala-Native, Scala source code not able to
define enums that are accepted by existing APIs on Scala-JVM).
Showing with 837 additions and 236 deletions.
  1. +23 −7 src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
  2. +6 −2 src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
  3. +2 −4 src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
  4. +6 −4 src/compiler/scala/tools/nsc/transform/Constructors.scala
  5. +3 −3 src/compiler/scala/tools/nsc/transform/Fields.scala
  6. +1 −2 src/compiler/scala/tools/nsc/transform/Flatten.scala
  7. +1 −0 src/compiler/scala/tools/nsc/transform/InfoTransform.scala
  8. +1 −2 src/compiler/scala/tools/nsc/transform/Statics.scala
  9. +1 −1 src/compiler/scala/tools/nsc/typechecker/Contexts.scala
  10. +1 −4 src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
  11. +63 −4 src/compiler/scala/tools/nsc/typechecker/Namers.scala
  12. +33 −18 src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
  13. +69 −3 src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
  14. +58 −12 src/compiler/scala/tools/nsc/typechecker/Typers.scala
  15. +1 −9 src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
  16. +1 −0 src/library/scala/Enumeration.scala
  17. +11 −0 src/library/scala/enum.scala
  18. +5 −1 src/reflect/scala/reflect/internal/Definitions.scala
  19. +1 −2 src/reflect/scala/reflect/internal/Symbols.scala
  20. +21 −4 src/reflect/scala/reflect/internal/TreeGen.scala
  21. +1 −0 src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
  22. +2 −2 test/files/jvm/serialization-new.check
  23. +2 −2 test/files/jvm/serialization.check
  24. +1 −0 test/files/jvm/t2214.check
  25. +1 −0 test/files/jvm/t2827.check
  26. +2 −1 test/files/neg/virtpatmat_unreach_select.check
  27. +2 −1 test/files/res/t831.check
  28. +16 −0 test/files/run/enumerations.check
  29. +161 −0 test/files/run/enumerations.scala
  30. +123 −14 test/files/run/enums.check
  31. +201 −130 test/files/run/enums.scala
  32. +1 −0 test/files/run/iterator-from.check
  33. +1 −0 test/files/run/manifests-new.check
  34. +1 −0 test/files/run/t1505.check
  35. +1 −0 test/files/run/t2111.check
  36. +1 −0 test/files/run/t3186.check
  37. +1 −0 test/files/run/t3616.check
  38. +2 −1 test/files/run/t3687.check
  39. +2 −1 test/files/run/t3719.check
  40. +2 −1 test/files/run/t3950.check
  41. +1 −0 test/files/run/t4570.check
  42. +1 −0 test/files/run/t5588.check
  43. +1 −0 test/files/run/t5612.check
  44. +1 −0 test/files/run/t8611b.check
  45. +0 −1 test/files/run/t8611b.flags
  46. +1 −0 test/files/run/t949.check
@@ -2773,7 +2773,15 @@ self =>
val annots = annotations(skipNewLines = true)
val pos = caseAwareTokenOffset
val mods = modifiers() withAnnotations annots
tmplDef(pos, mods)
// We need to come up with a more principled way to communicate the ability for
// exhaustiveness checks to the pattern matcher instead of abusing various flag
// combinations that need to be undone again in a later phase.
// It should be possible to address both Java-defined and Scala-defined enums with a simple
// check for the JAVA_ENUM flag.
val mods1 =
if (mods.hasAnnotationNamed("enum")) mods | Flags.JAVA_ENUM | Flags.SEALED | Flags.FINAL
else mods
tmplDef(pos, mods1)
}
/** {{{
@@ -2828,9 +2836,8 @@ self =>
val (constrMods, vparamss) =
if (mods.isTrait) (Modifiers(Flags.TRAIT), List())
else (accessModifierOpt(), paramClauses(name, classContextBounds, ofCaseClass = mods.isCase))
var mods1 = mods
val template = templateOpt(mods1, name, constrMods withAnnotations constrAnnots, vparamss, tstart)
val result = gen.mkClassDef(mods1, name, tparams, template)
val template = templateOpt(mods, name, constrMods withAnnotations constrAnnots, vparamss, tstart)
val result = gen.mkClassDef(mods, name, tparams, template)
// Context bounds generate implicit parameters (part of the template) with types
// from tparams: we need to ensure these don't overlap
if (!classContextBounds.isEmpty)
@@ -2970,21 +2977,30 @@ self =>
(List(), self, body)
}
)
val newParents =
if (mods.hasFlag(Flags.JAVA_ENUM)) {
val enumParent = AppliedTypeTree(Ident(definitions.JavaEnumClass.name), List(Ident(name)))
enumParent :: parents
} else {
parents
}
def anyvalConstructor() = (
// Not a well-formed constructor, has to be finished later - see note
// regarding AnyVal constructor in AddInterfaces.
DefDef(NoMods, nme.CONSTRUCTOR, Nil, ListOfNil, TypeTree(), Block(Nil, literalUnit))
)
val parentPos = o2p(in.offset)
val tstart1 = if (body.isEmpty && in.lastOffset < tstart) in.lastOffset else tstart
val newConstrMods = constrMods | (mods & Flags.JAVA_ENUM).flags
atPos(tstart1) {
// Exclude only the 9 primitives plus AnyVal.
if (inScalaRootPackage && ScalaValueClassNames.contains(name))
Template(parents, self, anyvalConstructor :: body)
else
gen.mkTemplate(gen.mkParents(mods, parents, parentPos),
self, constrMods, vparamss, body, o2p(tstart))
gen.mkTemplate(gen.mkParents(mods, newParents, parentPos),
self, newConstrMods, vparamss, body, o2p(tstart))
}
}
@@ -337,8 +337,12 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
genLoadQualUnlessElidable()
genLoadModule(tree)
} else if (sym.isStaticMember) {
genLoadQualUnlessElidable()
fieldLoad(sym, receiverClass)
if (sym.isJavaEnum) {
fieldLoad(sym, receiverClass.companionClass)
} else {
genLoadQualUnlessElidable()
fieldLoad(sym, receiverClass)
}
} else {
genLoadQualifier(tree)
fieldLoad(sym, receiverClass)
@@ -385,18 +385,16 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
/*
* must-single-thread
*/
def fieldSymbols(cls: Symbol): List[Symbol] = {
def fieldSymbols(cls: Symbol): List[Symbol] =
for (f <- cls.info.decls.toList ;
if !f.isMethod && f.isTerm && !f.isModule
) yield f
}
/*
* can-multi-thread
*/
def methodSymbols(cd: ClassDef): List[Symbol] = {
def methodSymbols(cd: ClassDef): List[Symbol] =
cd.impl.body collect { case dd: DefDef => dd.symbol }
}
/*
* must-single-thread
@@ -555,7 +555,9 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
// Assign `rhs` to class field / trait setter `assignSym`
def mkAssign(assignSym: Symbol, rhs: Tree): Tree =
localTyper.typedPos(assignSym.pos) {
val qual = Select(This(clazz), assignSym)
val qual =
if (assignSym.isStaticMember) Select(Ident(clazz), assignSym)
else Select(This(clazz), assignSym)
if (assignSym.isSetter) Apply(qual, List(rhs))
else Assign(qual, rhs)
}
@@ -598,7 +600,7 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
private def triage() = {
// Constant typed vals are not memoized.
def memoizeValue(sym: Symbol) = !sym.info.resultType.isInstanceOf[ConstantType]
def memoizeValue(sym: Symbol) = !sym.info.resultType.isInstanceOf[ConstantType] || sym.hasFlag(JAVA_ENUM)
// The early initialized field definitions of the class (these are the class members)
val presupers = treeInfo.preSuperFields(stats)
@@ -700,8 +702,8 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
// TODO: this should omit fields for non-memoized (constant-typed, unit-typed vals need no storage --
// all the action is in the getter)
def omittableSym(sym: Symbol) = omittableAccessor(sym)
def omittableStat(stat: Tree) = omittableSym(stat.symbol)
def omittableSym(sym: Symbol): Boolean = omittableAccessor(sym)
def omittableStat(stat: Tree): Boolean = omittableSym(stat.symbol)
// The parameter accessor fields which are members of the class
val paramAccessors =
@@ -84,7 +84,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
else synthFieldsAndAccessors(tp)
// TODO: drop PRESUPER support when we implement trait parameters in 2.13
private def excludedAccessorOrFieldByFlags(statSym: Symbol): Boolean = statSym hasFlag PRESUPER
private def excludedAccessorOrFieldByFlags(statSym: Symbol): Boolean = statSym hasFlag PRESUPER | JAVA_ENUM
// used for internal communication between info and tree transform of this phase -- not pickled, not in initialflags
// TODO: reuse MIXEDIN for NEEDS_TREES?
@@ -158,7 +158,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
// Note that a strict unit-typed val does receive a field, because we cannot omit the write to the field
// (well, we could emit it for non-@volatile ones, if I understand the memory model correctly,
// but that seems pretty edge-casey)
val constantTyped = tp.isInstanceOf[ConstantType]
val constantTyped = tp.isInstanceOf[ConstantType] && tp.asInstanceOf[ConstantType].value.tag != EnumTag
}
private def fieldTypeForGetterIn(getter: Symbol, pre: Type): Type = getter.info.finalResultType.asSeenFrom(pre, getter.owner)
@@ -351,7 +351,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
}
}
if (newDecls nonEmpty) {
if (newDecls.nonEmpty) {
val allDecls = newScope
origDecls foreach allDecls.enter
newDecls foreach allDecls.enter
@@ -17,8 +17,7 @@ abstract class Flatten extends InfoTransform {
/** the following two members override abstract members in Transform */
val phaseName: String = "flatten"
/** Updates the owning scope with the given symbol, unlinking any others.
*/
/** Updates the owning scope with the given symbol, unlinking any others. */
private def replaceSymbolInCurrentScope(sym: Symbol): Unit = exitingFlatten {
removeSymbolInCurrentScope(sym)
sym.owner.info.decls enter sym
@@ -33,6 +33,7 @@ trait InfoTransform extends Transform {
if (infoTransformers.nextFrom(id).pid != id) {
// this phase is not yet in the infoTransformers
val infoTransformer = new InfoTransformer {
override def toString = InfoTransform.this.getClass.toString
val pid = id
val changesBaseClasses = InfoTransform.this.changesBaseClasses
def transform(sym: Symbol, tpe: Type): Type = transformInfo(sym, tpe)
@@ -5,8 +5,7 @@ abstract class Statics extends Transform with ast.TreeDSL {
import global._
trait StaticsTransformer extends Transformer {
/** generate a static constructor with symbol fields inits, or an augmented existing static ctor
*/
/** generate a static constructor with symbol fields inits, or an augmented existing static ctor */
def staticConstructor(body: List[Tree], localTyper: analyzer.Typer, pos: Position)(newStaticInits: List[Tree]): Tree =
body.collectFirst {
// If there already was a static ctor - augment existing one
@@ -436,7 +436,7 @@ trait Contexts { self: Analyzer =>
* Construct a child context. The parent and child will share the report buffer.
* Compare with `makeSilent`, in which the child has a fresh report buffer.
*
* If `tree` is an `Import`, that import will be avaiable at the head of
* If `tree` is an `Import`, that import will be available at the head of
* `Context#imports`.
*/
def make(tree: Tree = tree, owner: Symbol = owner,
@@ -10,17 +10,14 @@ import symtab.Flags._
import scala.reflect.internal.util.StringOps.ojoin
import scala.reflect.internal.util.ListOfNil
/** Logic related to method synthesis which involves cooperation between
* Namer and Typer.
*/
/** Logic related to method synthesis which involves cooperation between Namer and Typer. */
trait MethodSynthesis {
self: Analyzer =>
import global._
import definitions._
import CODE._
class ClassMethodSynthesis(val clazz: Symbol, localTyper: Typer) {
def mkThis = This(clazz) setPos clazz.pos.focus
def mkThisSelect(sym: Symbol) = atPos(clazz.pos.focus)(
@@ -665,9 +665,14 @@ trait Namers extends MethodSynthesis {
if (isScala && deriveAccessors(tree)) enterGetterSetter(tree)
else assignAndEnterFinishedSymbol(tree)
val sym = tree.symbol
if (isEnumConstant(tree)) {
tree.symbol setInfo ConstantType(Constant(tree.symbol))
tree.symbol.owner.linkedClassOfClass addChild tree.symbol
sym setInfo ConstantType(Constant(sym))
if (sym.isJavaDefined)
sym.owner.linkedClassOfClass addChild sym
else
sym.owner addChild sym
}
}
@@ -698,6 +703,38 @@ trait Namers extends MethodSynthesis {
tree.symbol = enterClassSymbol(tree)
tree.symbol setInfo completerOf(tree)
if (mods.hasAnnotationNamed(TypeName("enum"))) {
var ordinal = 0
def newEnumItemOrdinalAttachment() = {
val att = new EnumConstantOrdinalAttachment(ordinal)
ordinal += 1
att
}
def isPossibleEnumConstantTree(tree: Tree): Boolean = { val result = tree.isInstanceOf[Ident] || tree.isInstanceOf[Apply]; println(s"$tree is enum? $result"); result }
def enumConstantName(enumConstant: Tree): TermName = enumConstant match {
case Ident(termName: TermName) => termName
case Apply(Ident(termName: TermName), _) => termName
case Apply(Apply(Ident(termName: TermName), _), _) => termName
}
val enumConstants: List[TermName] =
tree.impl.body.iterator
.dropWhile(tree => !isPossibleEnumConstantTree(tree))
.takeWhile(isPossibleEnumConstantTree)
.map(const => {
const.updateAttachment(newEnumItemOrdinalAttachment())
const.symbol.setFlag(JAVA_ENUM)
enumConstantName(const)})
.toList
tree.symbol.setFlag(JAVA_ENUM)
tree.symbol.updateAttachment(EnumConstantsAttachment(enumConstants))
// We keep this for the moment, otherwise the compiler doesn't see the members.
ensureCompanionObject(tree)
}
if (mods.isCase) {
val m = ensureCompanionObject(tree, caseModuleDef)
m.moduleClass.updateAttachment(new ClassForCaseCompanionAttachment(tree))
@@ -718,7 +755,7 @@ trait Namers extends MethodSynthesis {
// Suggested location only.
if (mods.isImplicit) {
if (primaryConstructorArity == 1) {
log("enter implicit wrapper "+tree+", owner = "+owner)
log(s"enter implicit wrapper $tree, owner = $owner")
enterImplicitWrapper(tree)
}
else reporter.error(tree.pos, "implicit classes must accept exactly one primary constructor parameter")
@@ -1028,6 +1065,7 @@ trait Namers extends MethodSynthesis {
private def templateSig(templ: Template): Type = {
val clazz = context.owner
def checkParent(tpt: Tree): Type = {
if (tpt.tpe.isError) AnyRefTpe
else tpt.tpe
@@ -1041,6 +1079,10 @@ trait Namers extends MethodSynthesis {
val templateNamer = newNamer(context.make(templ, clazz, decls))
templateNamer enterSyms templ.body
if (clazz.hasJavaEnumFlag)
clazz.attachments.get[EnumConstantsAttachment]
.map(att => addEnumMembers(att.constants, templateNamer))
// add apply and unapply methods to companion objects of case classes,
// unless they exist already; here, "clazz" is the module class
if (clazz.isModuleClass) {
@@ -1617,7 +1659,6 @@ trait Namers extends MethodSynthesis {
}
}
/** Given a case class
* case class C[Ts] (ps: Us)
* Add the following methods to toScope:
@@ -1643,6 +1684,24 @@ trait Namers extends MethodSynthesis {
caseClassCopyMeth(cdef) foreach namer.enterSyntheticSym
}
/** Given an enum class §EnumClass with enum constants §EnumConstant1 ... §EnumConstantN,
* add the following members to scope:
* - a private static field $VALUES containing the enum constants
* `<static> private[this] val $VALUES: Array[§EnumCass]`
* - a public static method that returns a copy of $VALUES
* `<static> def values: Array[§EnumCass]`
* a public static method that returns the enum constant denoted by the string if such an enum constant exists
* - `<static> def valueOf(name: String): §EnumCass`
*
* @param constants a list of the enum constants defined by this enum
* @param namer the namer of this class
*/
def addEnumMembers(constants: List[TermName], namer: Namer) = {
namer.enterSyntheticSym(enumValuesField(owner, constants))
namer.enterSyntheticSym(enumValuesMethod(owner))
namer.enterSyntheticSym(enumValueOfMethod(owner))
}
/**
* TypeSig is invoked by monoTypeCompleters. It returns the type of a definition which
* is then assigned to the corresponding symbol (typeSig itself does not need to assign
@@ -107,24 +107,6 @@ trait StdAttachments {
})
)
/** After being synthesized by the parser, primary constructors aren't fully baked yet.
* A call to super in such constructors is just a fill-me-in-later dummy resolved later
* by `parentTypes`. This attachment coordinates `parentTypes` and `typedTemplate` and
* allows them to complete the synthesis.
*/
case class SuperArgsAttachment(argss: List[List[Tree]])
/** Convenience method for `SuperArgsAttachment`.
* Compared with `MacroRuntimeAttachment` this attachment has different a usage pattern,
* so it really benefits from a dedicated extractor.
*/
def superArgs(tree: Tree): Option[List[List[Tree]]] =
tree.attachments.get[SuperArgsAttachment] collect { case SuperArgsAttachment(argss) => argss }
/** Determines whether the given tree has an associated SuperArgsAttachment.
*/
def hasSuperArgs(tree: Tree): Boolean = superArgs(tree).nonEmpty
/** @see markMacroImplRef
*/
case object MacroImplRefAttachment
@@ -152,6 +134,39 @@ trait StdAttachments {
*/
def isMacroImplRef(tree: Tree): Boolean = tree.hasAttachment[MacroImplRefAttachment.type]
/** After being synthesized by the parser, primary constructors aren't fully baked yet.
* A call to super in such constructors is just a fill-me-in-later dummy resolved later
* by `parentTypes`. This attachment coordinates `parentTypes` and `typedTemplate` and
* allows them to complete the synthesis.
*/
case class SuperArgsAttachment(argss: List[List[Tree]])
/** Convenience method for `SuperArgsAttachment`.
* Compared with `MacroRuntimeAttachment` this attachment has different a usage pattern,
* so it really benefits from a dedicated extractor.
*/
def superArgs(tree: Tree): Option[List[List[Tree]]] =
tree.attachments.get[SuperArgsAttachment] collect { case SuperArgsAttachment(argss) => argss }
/** Determines whether the given tree has an associated SuperArgsAttachment.
*/
def hasSuperArgs(tree: Tree): Boolean = superArgs(tree).nonEmpty
/** In the typeCompleter (templateSig) of a case class (resp it's module),
* synthetic `copy` (reps `apply`, `unapply`) methods are added. To compute
* their signatures, the corresponding ClassDef is needed. During naming (in
* `enterClassDef`), the case class ClassDef is added as an attachment to the
* moduleClass symbol of the companion module.
*/
case class ClassForCaseCompanionAttachment(caseClass: ClassDef)
/** We need to pass the tree of the class to the companion object as the methods there need to know which methods where defined. */
case class EnumConstantsAttachment(constants: List[TermName])
/** We use this to keep track of the right ordinal value in typedStat as we read one enum constant after another. */
case class EnumConstantOrdinalAttachment(value: Int)
/** Since mkInvoke, the applyDynamic/selectDynamic/etc desugarer, is disconnected
* from typedNamedApply, the applyDynamicNamed argument rewriter, the latter
* doesn’t know whether it needs to apply the rewriting because the application
Oops, something went wrong.

No commit comments for this range