View
@@ -13,7 +13,10 @@ import scala.collection.mutable.ListBuffer
import symtab.Flags._
/** Synthetic method implementations for case classes and case objects.
/** Synthetic method implementations.
*
* case classes and case objects
* -----------------------------
*
* Added to all case classes/objects:
* def productArity: Int
@@ -30,6 +33,13 @@ import symtab.Flags._
*
* Special handling:
* protected def readResolve(): AnyRef
*
* enums
* -----
*
* - <static> private[this] val $VALUES: Array[§EnumCass]
* - <static> def values: Array[§EnumCass]
* - <static> def valueOf(name: String): §EnumCass
*/
trait SyntheticMethods extends ast.TreeDSL {
self: Analyzer =>
@@ -60,8 +70,7 @@ trait SyntheticMethods extends ast.TreeDSL {
renamedCaseAccessors -= caseclazz
}
/** Add the synthetic methods to case classes.
*/
/** Add the synthetic methods to case classes. */
def addSyntheticMethods(templ: Template, clazz0: Symbol, context: Context): Template = {
val syntheticsOk = (phase.id <= currentRun.typerPhase.id) && {
symbolsToSynthesize(clazz0) filter (_ matchingSymbol clazz0.info isSynthetic) match {
@@ -400,4 +409,61 @@ trait SyntheticMethods extends ast.TreeDSL {
}
)
}
/** {{{
* <static> private[this] val $VALUES: Array[§EnumCass] = Array(§EnumClass.§EnumConstant1 ... §EnumClass.§EnumConstantN)
* }}}
*/
def enumValuesField(owner: Symbol, constants: List[TermName]): ValDef = {
val selectConstants = constants.map(const => Select(Ident(owner.name.toTermName), const))
ValDef(
mods = Modifiers(PRIVATE | STATIC | LOCAL),
name = TermName("$VALUES"),
tpt = AppliedTypeTree(Select(Ident(TermName("scala")), TypeName("Array")), List(Ident(owner.name))),
rhs =
Apply(
Apply(
TypeApply(
Select(Select(Ident(TermName("scala")), TermName("Array")), TermName("apply")),
List(Ident(owner.name))),
selectConstants),
List(Select(Ident(TermName("Predef")), TermName("implicitly")))))
}
/** {{{
* <static> def values: Array[§EnumCass] = $EnumCass.$VALUES.clone
* }}}
*/
def enumValuesMethod(owner: Symbol): DefDef =
DefDef(
mods = Modifiers(STATIC),
name = TermName("values"),
tparams = List(),
vparamss = List(),
tpt =
AppliedTypeTree(
tpt = Select(Ident(TermName("scala")), TypeName("Array")),
args = List(Ident(owner.name))),
rhs = Apply(Select(Ident(TermName("$VALUES")), TermName("clone")), List()))
/** {{{
* <static> def valueOf(name: String): §EnumCass = Enum.valueOf(classOf[§EnumCass], name)
* }}}
*/
def enumValueOfMethod(owner: Symbol): DefDef =
DefDef(
mods = Modifiers(STATIC),
name = TermName("valueOf"),
tparams = List(),
vparamss = List(
List(
ValDef(
mods = Modifiers(PARAM),
name = TermName("name"),
tpt = Ident(typeNames.String),
rhs = EmptyTree))),
tpt = Ident(owner.name),
rhs = Apply(
Select(Ident(JavaEnumClass.name.toTermName), TermName("valueOf")),
List(TypeApply(Ident(nme.classOf), List(Ident(owner.name))), Ident(TermName("name")))))
}
View
@@ -519,7 +519,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
/** Does the context of tree `tree` require a stable type?
*/
private def isStableContext(tree: Tree, mode: Mode, pt: Type) = {
private def isStableContext(tree: Tree, mode: Mode, pt: Type): Boolean = {
def ptSym = pt.typeSymbol
def expectsStable = (
pt.isStable
@@ -1160,7 +1160,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case atp @ AnnotatedType(_, _) if canAdaptAnnotations(tree, this, mode, pt) => // (-1)
adaptAnnotations(tree, this, mode, pt)
case ct @ ConstantType(value) if mode.inNone(TYPEmode | FUNmode) && (ct <:< pt) && canAdaptConstantTypeToLiteral => // (0)
adaptConstant(value)
if (value.tag == EnumTag) tree
else adaptConstant(value)
case OverloadedType(pre, alts) if !mode.inFunMode => // (1)
inferExprAlternative(tree, pt)
adaptAfterOverloadResolution(tree, mode, pt, original)
@@ -1792,12 +1793,14 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
def typedClassDef(cdef: ClassDef): Tree = {
val clazz = cdef.symbol
val templ = cdef.impl
val typedMods = typedModifiers(cdef.mods)
assert(clazz != NoSymbol, cdef)
reenterTypeParams(cdef.tparams)
val tparams1 = cdef.tparams mapConserve (typedTypeDef)
val impl1 = newTyper(context.make(cdef.impl, clazz, newScope)).typedTemplate(cdef.impl, typedParentTypes(cdef.impl))
val impl1 = newTyper(context.make(templ, clazz, newScope)).typedTemplate(templ, typedParentTypes(templ))
val impl2 = finishMethodSynthesis(impl1, clazz, context)
if (clazz.isTrait && clazz.info.parents.nonEmpty && clazz.info.firstParent.typeSymbol == AnyClass)
checkEphemeral(clazz, impl2.body)
@@ -2089,7 +2092,6 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case _ =>
(call, Nil)
}
// associate superclass paramaccessors with their aliases
val (superConstr, superArgs) = decompose(rhs)
if (superConstr.symbol.isPrimaryConstructor) {
@@ -3050,6 +3052,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
} else EmptyTree
// skip typechecking of statements in a sequence where some other statement includes the targetposition
case s if localTarget && !includesTargetPos(s) => s
case enumConstant if enumConstant.symbol != null && enumConstant.symbol.hasFlag(JAVA_ENUM) &&
enumConstant.attachments.get[EnumConstantOrdinalAttachment].isDefined =>
typedEnumConstant(enumConstant)
case _ =>
val localTyper = if (inBlock || (stat.isDef && !stat.isInstanceOf[LabelDef])) this
else newTyper(context.make(stat, exprOwner))
@@ -3195,6 +3200,47 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}
}
def typedEnumConstant(enumConstant: Tree) = {
def enumValDef(name: TermName, ordinal: Int, args: List[Tree], body: List[Tree]): ValDef =
ValDef(mods = Modifiers(JAVA_ENUM | STABLE | STATIC),
name = name,
tpt = Ident(context.owner.name),
rhs = enumNew(name, ordinal, args, body))
def enumNew(name: TermName, ordinal: Int, args: List[Tree], body: List[Tree]) = {
val allArgs = Literal(Constant(name.encoded)) :: Literal(Constant(ordinal)) :: args
if (body.nonEmpty)
context.owner.resetFlag(FINAL).setFlag(SEALED)
gen.mkNew(List(Apply(context.owner, allArgs: _*)), noSelfType, body.map(addOverrideModifier), NoPosition, context.owner.pos)
}
def addOverrideModifier(tree: Tree) = tree match {
case DefDef(mods, name, tparams, vparamss, tpt, rhs) => DefDef(Modifiers(mods.flags | OVERRIDE), name, tparams, vparamss, tpt, rhs)
case ValDef(mods, name, tpt, rhs) => ValDef(Modifiers(mods.flags | OVERRIDE), name, tpt, rhs)
case _ => tree
}
val ordinal = enumConstant.attachments.get[EnumConstantOrdinalAttachment].get.value
val enumField = enumConstant match {
// <ENUM>
case Ident(termName: TermName) => enumValDef(termName, ordinal, Nil, Nil)
// <ENUM> { <enumDef>, ... }
case Apply(Ident(termName: TermName),
List(Block(body, Literal(Constant(()))))) => enumValDef(termName, ordinal, Nil, body)
// <ENUM>(<enumParam>, ...)
case Apply(Ident(termName: TermName), args) => enumValDef(termName, ordinal, args, Nil)
// <ENUM>(<enumParam>, ...) { <enumDef>, ... }
case Apply(Apply(Ident(termName: TermName), args),
List(Block(body, Literal(Constant(()))))) => enumValDef(termName, ordinal, args, body)
}
namer.enterValDef(enumField)
val ds = context.owner.info.decls
ds.enter(enumField.symbol)
newTyper(context.make(enumField)).typedValDef(enumField)
}
def typedArg(arg: Tree, mode: Mode, newmode: Mode, pt: Type): Tree = {
val typedMode = mode.onlySticky | newmode
val t = withCondConstrTyper(mode.inSccMode)(_.typed(arg, typedMode, pt))
@@ -4776,11 +4822,13 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (isStableContext(tree, mode, pt)) tree setType clazz.thisType else tree
}
def isEligibleForJavaStatic(cls: Symbol): Boolean =
((context.unit.isJava && cls.isClass) || (cls != null && cls.companionClass.isJavaEnum && cls.isModule)) && !cls.isModuleClass
// For Java, instance and static members are in the same scope, but we put the static ones in the companion object
// so, when we can't find a member in the class scope, check the companion
def inCompanionForJavaStatic(pre: Type, cls: Symbol, name: Name): Symbol =
if (!(context.unit.isJava && cls.isClass && !cls.isModuleClass)) NoSymbol else {
if (!isEligibleForJavaStatic(cls)) NoSymbol else {
val companion = companionSymbolOf(cls, context)
if (!companion.exists) NoSymbol
else member(gen.mkAttributedRef(pre, companion), name) // assert(res.isStatic, s"inCompanionJavaStatic($pre, $cls, $name) = $res ${res.debugFlagString}")
@@ -4823,6 +4871,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}
NoSymbol
}
if (phase.erasedTypes && qual.isInstanceOf[Super] && tree.symbol != NoSymbol)
qual setType tree.symbol.owner.tpe
@@ -4985,7 +5034,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// actual call to the stubbed classOf method is generated, returning null.
typedClassOf(tree, TypeTree(pt.typeArgs.head).setPos(tree.pos.focus))
}
else {
else {
val pre1 = if (sym.isTopLevel) sym.owner.thisType else if (qual == EmptyTree) NoPrefix else qual.tpe
val tree1 = if (qual == EmptyTree) tree else atPos(tree.pos)(Select(atPos(tree.pos.focusStart)(qual), name))
val (tree2, pre2) = makeAccessible(tree1, sym, pre1, qual)
@@ -5549,12 +5598,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
def atOwner(tree: Tree, owner: Symbol): Typer =
newTyper(context.make(tree, owner))
/** Types expression or definition `tree`.
*/
def typed(tree: Tree): Tree = {
val ret = typed(tree, context.defaultModeForTyped, WildcardType)
ret
}
/** Types expression or definition `tree`. */
def typed(tree: Tree): Tree =
typed(tree, context.defaultModeForTyped, WildcardType)
def typedByValueExpr(tree: Tree, pt: Type = WildcardType): Tree = typed(tree, EXPRmode | BYVALmode, pt)
View
@@ -24,15 +24,7 @@ trait Unapplies extends ast.TreeDSL {
private def unapplyParamName = nme.x_0
private def caseMods = Modifiers(SYNTHETIC | CASE)
// 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.
class ClassForCaseCompanionAttachment(val caseClass: ClassDef)
/** Returns unapply or unapplySeq if available, without further checks.
*/
/** Returns unapply or unapplySeq if available, without further checks. */
def directUnapplyMember(tp: Type): Symbol = (tp member nme.unapply) orElse (tp member nme.unapplySeq)
/** Filters out unapplies with multiple (non-implicit) parameter lists,
View
@@ -50,6 +50,7 @@ import scala.util.matching.Regex
* identifies values at run-time.
* @author Matthias Zenger
*/
@deprecated("use @enum instead", "2.12.0")
@SerialVersionUID(8476000850333817230L)
abstract class Enumeration (initial: Int) extends Serializable {
thisenum =>
View
@@ -0,0 +1,11 @@
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2002-2016, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala
class enum extends scala.annotation.StaticAnnotation
View
@@ -970,7 +970,10 @@ trait Definitions extends api.StandardDefinitions {
// - .owner: the ModuleClassSymbol of the enumeration (object E)
// - .linkedClassOfClass: the ClassSymbol of the enumeration (class E)
// SI-6613 Subsequent runs of the resident compiler demand the phase discipline here.
enteringPhaseNotLaterThan(picklerPhase)(sym.owner.linkedClassOfClass).tpe
if (sym.isJavaDefined)
enteringPhaseNotLaterThan(picklerPhase)(sym.owner.linkedClassOfClass).tpe
else
enteringPhaseNotLaterThan(picklerPhase)(sym.owner).tpe
}
/** Given a class symbol C with type parameters T1, T2, ... Tn
@@ -1169,6 +1172,7 @@ trait Definitions extends api.StandardDefinitions {
lazy val DeprecatedNameAttr = requiredClass[scala.deprecatedName]
lazy val DeprecatedInheritanceAttr = requiredClass[scala.deprecatedInheritance]
lazy val DeprecatedOverridingAttr = requiredClass[scala.deprecatedOverriding]
lazy val EnumAttr = requiredClass[scala.enum]
lazy val NativeAttr = requiredClass[scala.native]
lazy val RemoteAttr = requiredClass[scala.remote]
lazy val ScalaInlineClass = requiredClass[scala.inline]
View
@@ -3598,8 +3598,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
creator(syms1, tpe.substSym(syms, syms1))
}
/** A deep map on a symbol's paramss.
*/
/** A deep map on a symbol's paramss. */
def mapParamss[T](sym: Symbol)(f: Symbol => T): List[List[T]] = mmap(sym.info.paramss)(f)
def existingSymbols(syms: List[Symbol]): List[Symbol] =
View
@@ -393,13 +393,30 @@ abstract class TreeGen {
}
val lvdefs = evdefs collect { case vdef: ValDef => copyValDef(vdef)(mods = vdef.mods | PRESUPER) }
var enumFieldDefs: List[ValDef] = Nil
val constr = {
if (constrMods.isTrait) {
if (body forall treeInfo.isInterfaceMember) None
else Some(
atPos(wrappingPos(superPos, lvdefs)) (
DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, Nil, ListOfNil, TypeTree(), Block(lvdefs, mkLiteralUnit))))
}
else if (constrMods.hasFlag(JAVA_ENUM)) {
val nameParam = ValDef(Modifiers(PRIVATE | LOCAL | PARAM | PARAMACCESSOR), "name", TypeTree(StringTpe), EmptyTree)
val ordinalParam = ValDef(Modifiers(PRIVATE | LOCAL | PARAM | PARAMACCESSOR), "ordinal", TypeTree(IntTpe), EmptyTree)
enumFieldDefs = List(nameParam, ordinalParam)
val enumConstructor =
DefDef(
mods = Modifiers(PRIVATE),
name = nme.CONSTRUCTOR.toTermName,
tparams = Nil,
vparamss = List(nameParam :: ordinalParam :: vparamss.flatten),
tpt = TypeTree(),
rhs = Block(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List(Ident("name"), Ident("ordinal"))), mkLiteralUnit))
Some(enumConstructor)
}
else {
// convert (implicit ... ) to ()(implicit ... ) if it's the only parameter section
if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit)
@@ -418,7 +435,7 @@ abstract class TreeGen {
constr foreach (ensureNonOverlapping(_, parents ::: gvdefs, focus = false))
// Field definitions for the class - remove defaults.
val fieldDefs = vparamss.flatten map (vd => {
val fieldDefs = (enumFieldDefs ::: vparamss.flatten) map (vd => {
val field = copyValDef(vd)(mods = vd.mods &~ DEFAULTPARAM, rhs = EmptyTree)
// Prevent overlapping of `field` end's position with default argument's start position.
// This is needed for `Positions.Locator(pos).traverse` to return the correct tree when
@@ -458,18 +475,18 @@ abstract class TreeGen {
val app = treeInfo.dissectApplied(parents.head)
atPos(npos union cpos) { New(app.callee, app.argss) }
} else {
val x = tpnme.ANON_CLASS_NAME
val anon = tpnme.ANON_CLASS_NAME
atPos(npos union cpos) {
Block(
List(
atPos(cpos) {
ClassDef(
Modifiers(FINAL), x, Nil,
Modifiers(FINAL), anon, Nil,
mkTemplate(parents, self, NoMods, ListOfNil, stats, cpos.focus))
}),
atPos(npos) {
New(
Ident(x) setPos npos.focus,
Ident(anon) setPos npos.focus,
Nil)
}
)
View
@@ -393,6 +393,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.DeprecatedNameAttr
definitions.DeprecatedInheritanceAttr
definitions.DeprecatedOverridingAttr
definitions.EnumAttr
definitions.NativeAttr
definitions.RemoteAttr
definitions.ScalaInlineClass
View
@@ -1,6 +1,6 @@
warning: there were two deprecation warnings (since 2.11.0)
warning: there were three deprecation warnings (since 2.12.0)
warning: there were 5 deprecation warnings in total; re-run with -deprecation for details
warning: there were four deprecation warnings (since 2.12.0)
warning: there were 6 deprecation warnings in total; re-run with -deprecation for details
a1 = Array[1,2,3]
_a1 = Array[1,2,3]
arrayEquals(a1, _a1): true
View
@@ -1,6 +1,6 @@
warning: there were two deprecation warnings (since 2.11.0)
warning: there was one deprecation warning (since 2.12.0)
warning: there were three deprecation warnings in total; re-run with -deprecation for details
warning: there were two deprecation warnings (since 2.12.0)
warning: there were four deprecation warnings in total; re-run with -deprecation for details
a1 = Array[1,2,3]
_a1 = Array[1,2,3]
arrayEquals(a1, _a1): true
View
@@ -1,3 +1,4 @@
warning: there was one deprecation warning (since 2.12.0); re-run with -deprecation for details
got DEBT
got FUTURE
got EQUITY
View
@@ -1,3 +1,4 @@
warning: there was one deprecation warning (since 2.12.0); re-run with -deprecation for details
Larry
Curly
Moe
View
@@ -1,6 +1,7 @@
virtpatmat_unreach_select.scala:10: warning: unreachable code
case WARNING.id => // unreachable
^
warning: there was one deprecation warning (since 2.12.0); re-run with -deprecation for details
error: No warnings can be incurred under -Xfatal-warnings.
one warning found
two warnings found
one error found
View
@@ -1,4 +1,5 @@
nsc>
nsc> warning: there was one deprecation warning (since 2.12.0); re-run with -deprecation for details
nsc>
nsc>
View
@@ -0,0 +1,16 @@
warning: there were 8 deprecation warnings (since 2.12.0); re-run with -deprecation for details
test Test1 was successful
test Test2 was successful
test Test3 was successful
test Test4 was successful
D1.ValueSet(North, East)
D2.ValueSet(North, East)
D1.ValueSet(North, East, West)
D2.ValueSet(North, East, West)
List(101)
List(101)
D1.ValueSet(North, East)
D2.ValueSet(North, East)
WeekDays.ValueSet(Tue, Wed, Thu, Fri)
View
@@ -0,0 +1,161 @@
//############################################################################
// Enumerations
//############################################################################
object Test1 {
object WeekDays extends Enumeration {
val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
def isWorkingDay(d: WeekDays.Value) =
! (d == WeekDays.Sat || d == WeekDays.Sun);
def run: Int = {
val it = WeekDays.values filter (isWorkingDay);
it.toList.length
}
}
object Test2 {
object ThreadState extends Enumeration {
val New = Value("NEW");
val Runnable = Value("RUNNABLE");
val Blocked = Value("BLOCKED");
val Waiting = Value("WAITING");
val TimedWaiting = Value("TIMED_WAITING");
val Terminated = Value("TERMINATED");
}
def run: Int = {
val it = for (s <- ThreadState.values; if s.id != 0) yield s;
it.toList.length
}
}
object Test3 {
object Direction extends Enumeration {
val North = Value("North")
val South = Value("South")
val East = Value("East")
val West = Value("West")
}
def run: Int = {
val it = for (d <- Direction.values; if d.toString() startsWith "N") yield d;
it.toList.length
}
}
object Test4 {
object Direction extends Enumeration {
val North = Value("North")
val South = Value("South")
val East = Value("East")
val West = Value("West")
}
def run: Int = {
val dir = Direction.withName("North")
assert(dir.toString == "North")
try {
Direction.withName("Nord")
assert(false)
} catch {
case e: Exception => /* do nothing */
}
0
}
}
object Test5 {
object D1 extends Enumeration(0) {
val North, South, East, West = Value;
}
object D2 extends Enumeration(-2) {
val North, South, East, West = Value;
}
object WeekDays extends Enumeration {
val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
def run {
val s1 = D1.ValueSet(D1.North, D1.East)
val s2 = D2.North + D2.East
println(s1)
println(s2)
println(s1 + D1.West)
println(s2 + D2.West)
println(s1.toBitMask.map(_.toBinaryString).toList)
println(s2.toBitMask.map(_.toBinaryString).toList)
println(D1.ValueSet.fromBitMask(s1.toBitMask))
println(D2.ValueSet.fromBitMask(s2.toBitMask))
println(WeekDays.values.range(WeekDays.Tue, WeekDays.Sat))
}
}
object SerializationTest {
object Types extends Enumeration { val X, Y = Value }
class A extends java.io.Serializable { val types = Types.values }
class B extends java.io.Serializable { val types = Set(Types.X, Types.Y) }
def serialize(obj: AnyRef) = {
val baos = new java.io.ByteArrayOutputStream()
val oos = new java.io.ObjectOutputStream(baos)
oos.writeObject(obj)
oos.close()
val bais = new java.io.ByteArrayInputStream(baos.toByteArray)
val ois = new java.io.ObjectInputStream(bais)
val prime = ois.readObject()
ois.close()
prime
}
def run {
serialize(new B())
serialize(new A())
}
}
//############################################################################
// Test code
object Test {
def check_success(name: String, closure: => Int, expected: Int): Unit = {
Console.print("test " + name);
try {
val actual: Int = closure;
if (actual == expected) {
Console.print(" was successful");
} else {
Console.print(" failed: expected "+ expected +", found "+ actual);
}
} catch {
case exception: Throwable => {
Console.print(" raised exception " + exception);
exception.printStackTrace();
}
}
Console.println;
}
def main(args: Array[String]): Unit = {
check_success("Test1", Test1.run, 5);
check_success("Test2", Test2.run, 5);
check_success("Test3", Test3.run, 1);
check_success("Test4", Test4.run, 0);
Console.println;
Test5.run;
Console.println;
SerializationTest.run;
}
}
//############################################################################
View
@@ -1,15 +1,124 @@
test Test1 was successful
test Test2 was successful
test Test3 was successful
test Test4 was successful
D1.ValueSet(North, East)
D2.ValueSet(North, East)
D1.ValueSet(North, East, West)
D2.ValueSet(North, East, West)
List(101)
List(101)
D1.ValueSet(North, East)
D2.ValueSet(North, East)
WeekDays.ValueSet(Tue, Wed, Thu, Fri)
enums.scala:23: warning: match may not be exhaustive.
It would fail on the following inputs: ConstructorWeek(), Friday, Monday, Thursday, Tuesday, Wednesday
def isWeekendMissing = this match {
^
enums.scala:45: warning: match may not be exhaustive.
It would fail on the following inputs: $anon(), $anon(), $anon(), Friday, MethodWeek(), Monday, Thursday, Tuesday, Wednesday
def isWeekendMissing = this match {
^
enums.scala:61: warning: match may not be exhaustive.
It would fail on the following inputs: $anon(), $anon(), $anon(), ArgNamedWeek(), Friday, Monday, Thursday, Tuesday, Wednesday
def isWeekendMissing = this match {
^
enums.scala:77: warning: match may not be exhaustive.
It would fail on the following inputs: $anon(), $anon(), $anon(), CaseWeek(_), Friday, Monday, Thursday, Tuesday, Wednesday
def isWeekendCase = this match {
^
enums.scala:81: warning: match may not be exhaustive.
It would fail on the following inputs: $anon(), $anon(), $anon(), CaseWeek(_), Friday, Monday, Thursday, Tuesday, Wednesday
def isWeekendMissing = this match {
^
enums.scala:163: warning: match may not be exhaustive.
It would fail on the following inputs: Friday, Monday, Thursday, Tuesday, Wednesday, Week()
def isWeekendMissing(week: Week) = week match {
^
==== enum Empty ====
true
16401
FINAL PUBLIC
class java.lang.Enum
List()
List(private Empty(java.lang.String,int))
List(public static Empty Empty.valueOf(java.lang.String), public static Empty[] Empty.values())
List(private static final Empty[] Empty.$VALUES)
List()
==== enum ReallyEmpty ====
true
16401
FINAL PUBLIC
class java.lang.Enum
List()
List(private ReallyEmpty(java.lang.String,int))
List(public static ReallyEmpty ReallyEmpty.valueOf(java.lang.String), public static ReallyEmpty[] ReallyEmpty.values())
List(private static final ReallyEmpty[] ReallyEmpty.$VALUES)
List()
==== enum Week ====
true
16401
FINAL PUBLIC
class java.lang.Enum
List()
List(private Week(java.lang.String,int))
List(public static Week Week.valueOf(java.lang.String), public static Week[] Week.values())
List(private static final Week[] Week.$VALUES, public static final Week Week.Friday, public static final Week Week.Monday, public static final Week Week.Saturday, public static final Week Week.Sunday, public static final Week Week.Thursday, public static final Week Week.Tuesday, public static final Week Week.Wednesday)
true
List(Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday)
true
true
true
true
==== enum ConstructorWeek ====
true
16401
FINAL PUBLIC
class java.lang.Enum
List()
List(private ConstructorWeek(java.lang.String,int,boolean))
List(public boolean ConstructorWeek.isWeekend(), public boolean ConstructorWeek.isWeekendMissing(), public static ConstructorWeek ConstructorWeek.valueOf(java.lang.String), public static ConstructorWeek[] ConstructorWeek.values())
List(private static final ConstructorWeek[] ConstructorWeek.$VALUES, public static final ConstructorWeek ConstructorWeek.Friday, public static final ConstructorWeek ConstructorWeek.Monday, public static final ConstructorWeek ConstructorWeek.Saturday, public static final ConstructorWeek ConstructorWeek.Sunday, public static final ConstructorWeek ConstructorWeek.Thursday, public static final ConstructorWeek ConstructorWeek.Tuesday, public static final ConstructorWeek ConstructorWeek.Wednesday, private final boolean ConstructorWeek.isWeekend)
true
List(Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday)
true
true
(List(Saturday, Sunday),List(Monday, Tuesday, Wednesday, Thursday, Friday))
==== enum MethodWeek ====
true
16385
PUBLIC
class java.lang.Enum
List()
List(public MethodWeek(java.lang.String,int))
List(public boolean MethodWeek.isGoodDay(), public boolean MethodWeek.isWeekend(), public boolean MethodWeek.isWeekendMissing(), public static MethodWeek MethodWeek.valueOf(java.lang.String), public static MethodWeek[] MethodWeek.values())
List(private static final MethodWeek[] MethodWeek.$VALUES, public static final MethodWeek MethodWeek.Friday, public static final MethodWeek MethodWeek.Monday, public static final MethodWeek MethodWeek.Saturday, public static final MethodWeek MethodWeek.Sunday, public static final MethodWeek MethodWeek.Thursday, public static final MethodWeek MethodWeek.Tuesday, public static final MethodWeek MethodWeek.Wednesday)
true
List(Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday)
true
true
(List(Saturday, Sunday),List(Monday, Tuesday, Wednesday, Thursday, Friday))
(List(Friday, Saturday, Sunday),List(Monday, Tuesday, Wednesday, Thursday))
==== enum ArgNamedWeek ====
true
16385
PUBLIC
class java.lang.Enum
List()
List(public ArgNamedWeek(java.lang.String,int,boolean))
List(public boolean ArgNamedWeek.isGoodDay(), public boolean ArgNamedWeek.isWeekend(), public boolean ArgNamedWeek.isWeekendMissing(), public static ArgNamedWeek ArgNamedWeek.valueOf(java.lang.String), public static ArgNamedWeek[] ArgNamedWeek.values())
List(private static final ArgNamedWeek[] ArgNamedWeek.$VALUES, public static final ArgNamedWeek ArgNamedWeek.Friday, public static final ArgNamedWeek ArgNamedWeek.Monday, public static final ArgNamedWeek ArgNamedWeek.Saturday, public static final ArgNamedWeek ArgNamedWeek.Sunday, public static final ArgNamedWeek ArgNamedWeek.Thursday, public static final ArgNamedWeek ArgNamedWeek.Tuesday, public static final ArgNamedWeek ArgNamedWeek.Wednesday, private final boolean ArgNamedWeek.isWeekend)
true
List(Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday)
true
true
(List(Saturday, Sunday),List(Monday, Tuesday, Wednesday, Thursday, Friday))
(List(Friday, Saturday, Sunday),List(Monday, Tuesday, Wednesday, Thursday))
==== enum CaseWeek ====
true
16385
PUBLIC
class java.lang.Enum
List(interface scala.Product, interface scala.Serializable)
List(public CaseWeek(java.lang.String,int,boolean))
List(public static CaseWeek CaseWeek.apply(java.lang.String,int,boolean), public boolean CaseWeek.canEqual(java.lang.Object), public CaseWeek CaseWeek.copy(java.lang.String,int,boolean), public java.lang.String CaseWeek.copy$default$1(), public int CaseWeek.copy$default$2(), public boolean CaseWeek.copy$default$3(), public boolean CaseWeek.isGoodDay(), public boolean CaseWeek.isWeekend(), public boolean CaseWeek.isWeekendCase(), public boolean CaseWeek.isWeekendMissing(), public int CaseWeek.productArity(), public java.lang.Object CaseWeek.productElement(int), public scala.collection.Iterator CaseWeek.productIterator(), public java.lang.String CaseWeek.productPrefix(), public static scala.Option CaseWeek.unapply(CaseWeek), public static CaseWeek CaseWeek.valueOf(java.lang.String), public static CaseWeek[] CaseWeek.values())
List(private static final CaseWeek[] CaseWeek.$VALUES, public static final CaseWeek CaseWeek.Friday, public static final CaseWeek CaseWeek.Monday, public static final CaseWeek CaseWeek.Saturday, public static final CaseWeek CaseWeek.Sunday, public static final CaseWeek CaseWeek.Thursday, public static final CaseWeek CaseWeek.Tuesday, public static final CaseWeek CaseWeek.Wednesday, private final boolean CaseWeek.isWeekend, private final java.lang.String CaseWeek.name, private final int CaseWeek.ordinal)
true
List(Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday)
true
true
(List(Saturday, Sunday),List(Monday, Tuesday, Wednesday, Thursday, Friday))
(List(Friday, Saturday, Sunday),List(Monday, Tuesday, Wednesday, Thursday))
View
@@ -1,161 +1,232 @@
//############################################################################
// Enumerations
//############################################################################
object Test1 {
object WeekDays extends Enumeration {
val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
@enum class Empty {}
@enum class ReallyEmpty
@enum class Week {
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
}
def isWorkingDay(d: WeekDays.Value) =
! (d == WeekDays.Sat || d == WeekDays.Sun);
@enum class ConstructorWeek(val isWeekend: Boolean) {
Monday(false)
Tuesday(false)
Wednesday(false)
Thursday(false)
Friday(false)
Saturday(true)
Sunday(true)
def run: Int = {
val it = WeekDays.values filter (isWorkingDay);
it.toList.length
def isWeekendMissing = this match {
case Saturday
| ConstructorWeek.Sunday => true
}
}
object Test2 {
@enum class MethodWeek {
Monday
Tuesday
Wednesday
Thursday
Friday { val isGoodDay = true }
Saturday { def isGoodDay = true }
Sunday { def isGoodDay = true }
object ThreadState extends Enumeration {
val New = Value("NEW");
val Runnable = Value("RUNNABLE");
val Blocked = Value("BLOCKED");
val Waiting = Value("WAITING");
val TimedWaiting = Value("TIMED_WAITING");
val Terminated = Value("TERMINATED");
}
def isGoodDay: Boolean = false
def run: Int = {
val it = for (s <- ThreadState.values; if s.id != 0) yield s;
it.toList.length
def isWeekend = this match {
case Saturday
| MethodWeek.Sunday => true
case _ => false
}
def isWeekendMissing = this match {
case Saturday
| MethodWeek.Sunday => true
}
}
object Test3 {
@enum class ArgNamedWeek(val isWeekend: Boolean) {
Monday(false)
Tuesday(false)
Wednesday(false)
Thursday(false)
Friday(false) { val isGoodDay = true }
Saturday(true) { def isGoodDay = true }
Sunday(isWeekend = true) { def isGoodDay = true }
object Direction extends Enumeration {
val North = Value("North")
val South = Value("South")
val East = Value("East")
val West = Value("West")
}
def run: Int = {
val it = for (d <- Direction.values; if d.toString() startsWith "N") yield d;
it.toList.length
def isGoodDay: Boolean = false
def isWeekendMissing = this match {
case Saturday
| ArgNamedWeek.Sunday => true
}
}
object Test4 {
@enum case class CaseWeek(isWeekend: Boolean) {
Monday(false)
Tuesday(false)
Wednesday(false)
Thursday(false)
Friday(false) { val isGoodDay = true }
Saturday(true) { def isGoodDay = true }
Sunday(isWeekend = true) { def isGoodDay = true }
object Direction extends Enumeration {
val North = Value("North")
val South = Value("South")
val East = Value("East")
val West = Value("West")
def isGoodDay: Boolean = false
def isWeekendCase = this match {
case Saturday //(true)
| CaseWeek.Sunday => true
}
def run: Int = {
val dir = Direction.withName("North")
assert(dir.toString == "North")
try {
Direction.withName("Nord")
assert(false)
} catch {
case e: Exception => /* do nothing */
}
0
def isWeekendMissing = this match {
case Saturday
| CaseWeek.Sunday => true
}
}
object Test5 {
/*
@enum class ArgDefaultWeek(isWeekend: Boolean = false) {
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday(true)
Sunday(true)
}
object D1 extends Enumeration(0) {
val North, South, East, West = Value;
object Nested {
@enum class Week {
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
}
}
object D2 extends Enumeration(-2) {
val North, South, East, West = Value;
class Nested {
@enum class Week {
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
}
}
*/
object WeekDays extends Enumeration {
val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
/*
@enum sealed abstract class EmptyADT
def run {
val s1 = D1.ValueSet(D1.North, D1.East)
val s2 = D2.North + D2.East
println(s1)
println(s2)
println(s1 + D1.West)
println(s2 + D2.West)
println(s1.toBitMask.map(_.toBinaryString).toList)
println(s2.toBitMask.map(_.toBinaryString).toList)
println(D1.ValueSet.fromBitMask(s1.toBitMask))
println(D2.ValueSet.fromBitMask(s2.toBitMask))
println(WeekDays.values.range(WeekDays.Tue, WeekDays.Sat))
}
}
@enum sealed abstract class ADT
object One extends ADT
object SerializationTest {
object Types extends Enumeration { val X, Y = Value }
class A extends java.io.Serializable { val types = Types.values }
class B extends java.io.Serializable { val types = Set(Types.X, Types.Y) }
def serialize(obj: AnyRef) = {
val baos = new java.io.ByteArrayOutputStream()
val oos = new java.io.ObjectOutputStream(baos)
oos.writeObject(obj)
oos.close()
val bais = new java.io.ByteArrayInputStream(baos.toByteArray)
val ois = new java.io.ObjectInputStream(bais)
val prime = ois.readObject()
ois.close()
prime
}
@enum sealed abstract class CaseADT
case object One
def run {
serialize(new B())
serialize(new A())
}
@enum sealed abstract class NestedADT
object NestedADT {
object One
}
//############################################################################
// Test code
object Test {
def check_success(name: String, closure: => Int, expected: Int): Unit = {
Console.print("test " + name);
try {
val actual: Int = closure;
if (actual == expected) {
Console.print(" was successful");
} else {
Console.print(" failed: expected "+ expected +", found "+ actual);
}
} catch {
case exception: Throwable => {
Console.print(" raised exception " + exception);
exception.printStackTrace();
}
}
Console.println;
}
def main(args: Array[String]): Unit = {
check_success("Test1", Test1.run, 5);
check_success("Test2", Test2.run, 5);
check_success("Test3", Test3.run, 1);
check_success("Test4", Test4.run, 0);
Console.println;
Test5.run;
Console.println;
SerializationTest.run;
@enum sealed abstract class NestedCaseADT
object NestedCaseADT {
case object One
}
*/
object Test extends App {
printEnumInfo(classOf[Empty])
println(Empty.values.toList)
println()
printEnumInfo(classOf[ReallyEmpty])
println(ReallyEmpty.values.toList)
println()
printEnumInfo(classOf[Week])
println(Week.Monday.getClass.isEnum)
println(Week.values.toList)
println(Week.valueOf("Friday") == Week.Friday)
println(Week.Saturday.compareTo(Week.Sunday) < 0)
println(isWeekendMissing(Week.Sunday))
println(!isWeekendComplete(Week.Thursday))
println()
// warning: match may not be exhaustive.
// It would fail on the following inputs: Friday, Monday, Tuesday, Wednesday, Week()
def isWeekendMissing(week: Week) = week match {
case Week.Saturday
| Week.Sunday => true
}
def isWeekendComplete(week: Week) = week match {
case Week.Saturday
| Week.Sunday => true
case _ => false
}
printEnumInfo(classOf[ConstructorWeek])
println(ConstructorWeek.Monday.getClass.isEnum)
println(ConstructorWeek.values.toList)
println(ConstructorWeek.valueOf("Friday") == ConstructorWeek.Friday)
println(ConstructorWeek.Saturday.compareTo(ConstructorWeek.Sunday) < 0)
println(ConstructorWeek.values.toList.partition(_.isWeekend))
println()
printEnumInfo(classOf[MethodWeek])
println(MethodWeek.Monday.getClass.isEnum)
println(MethodWeek.values.toList)
println(MethodWeek.valueOf("Friday") == MethodWeek.Friday)
println(MethodWeek.Saturday.compareTo(MethodWeek.Sunday) < 0)
println(MethodWeek.values.toList.partition(_.isWeekend))
println(MethodWeek.values.toList.partition(_.isGoodDay))
println()
printEnumInfo(classOf[ArgNamedWeek])
println(ArgNamedWeek.Monday.getClass.isEnum)
println(ArgNamedWeek.values.toList)
println(ArgNamedWeek.valueOf("Friday") == ArgNamedWeek.Friday)
println(ArgNamedWeek.Saturday.compareTo(ArgNamedWeek.Sunday) < 0)
println(ArgNamedWeek.values.toList.partition(_.isWeekend))
println(ArgNamedWeek.values.toList.partition(_.isGoodDay))
println()
printEnumInfo(classOf[CaseWeek])
println(CaseWeek.Monday.getClass.isEnum)
println(CaseWeek.values.toList)
println(CaseWeek.valueOf("Friday") == CaseWeek.Friday)
println(CaseWeek.Saturday.compareTo(CaseWeek.Sunday) < 0)
println(CaseWeek.values.toList.partition(_.isWeekend))
println(CaseWeek.values.toList.partition(_.isGoodDay))
def modifiersToString(flags: Int): String = {
import java.lang.reflect.Modifier
var buf = new StringBuilder
if (Modifier.isAbstract (flags)) buf ++= "ABSTRACT "
if (Modifier.isFinal (flags)) buf ++= "FINAL "
if (Modifier.isInterface(flags)) buf ++= "INTERFACE "
if (Modifier.isPrivate (flags)) buf ++= "PRIVATE "
if (Modifier.isProtected(flags)) buf ++= "PROTECTED "
if (Modifier.isPublic (flags)) buf ++= "PUBLIC "
if (Modifier.isStatic (flags)) buf ++= "STATIC "
buf = buf.init
buf.toString()
}
def printEnumInfo(clazz: Class[_ <: Enum[_]]): Unit = {
println(s"==== enum ${clazz.getSimpleName} ====")
println(clazz.isEnum)
println(clazz.getModifiers)
println(modifiersToString(clazz.getModifiers))
println(clazz.getSuperclass)
println(clazz.getInterfaces.toList)
println(clazz.getDeclaredConstructors.toList)
println(clazz.getDeclaredMethods.toList.sortBy(_.getName))
println(clazz.getDeclaredFields.toList.sortBy(_.getName))
}
}
//############################################################################
View
@@ -0,0 +1 @@
warning: there was one deprecation warning (since 2.12.0); re-run with -deprecation for details
View
@@ -0,0 +1 @@
warning: there were two deprecation warnings (since 2.12.0); re-run with -deprecation for details
View
@@ -0,0 +1 @@
warning: there were two deprecation warnings (since 2.12.0); re-run with -deprecation for details
View
@@ -1,3 +1,4 @@
warning: there were two deprecation warnings (since 2.12.0); re-run with -deprecation for details
Red
Green
Blue
View
@@ -1 +1,2 @@
warning: there were two deprecation warnings (since 2.12.0); re-run with -deprecation for details
false
View
@@ -1 +1,2 @@
warning: there were two deprecation warnings (since 2.12.0); re-run with -deprecation for details
Fruit.ValueSet(A, B, C)
View
@@ -1,2 +1,3 @@
warning: there was one deprecation warning (since 2.12.0); re-run with -deprecation for details
t.ValueSet(a, b)
t.ValueSet(a, b)
t.ValueSet(a, b)
View
@@ -1,4 +1,5 @@
warning: there was one deprecation warning (since 2.12.0); re-run with -deprecation for details
List(Mon, Tue, Wed, Thu, Fri, Sat, Sun)
Mon
Tue
Mon
Mon
View
@@ -1,3 +1,4 @@
warning: there was one deprecation warning (since 2.12.0); re-run with -deprecation for details
minus
zero
plus
plus
View
@@ -1 +1,2 @@
warning: there was one deprecation warning (since 2.12.0); re-run with -deprecation for details
foo
View
@@ -1,2 +1,3 @@
warning: there was one deprecation warning (since 2.12.0); re-run with -deprecation for details
true
true
View
@@ -1,3 +1,4 @@
warning: there was one deprecation warning (since 2.12.0); re-run with -deprecation for details
START for List(Two, Two, One, Three)
TWO
TWO
View
@@ -0,0 +1 @@
warning: there were two deprecation warnings (since 2.12.0); re-run with -deprecation for details
View

This file was deleted.

Oops, something went wrong.
View
@@ -0,0 +1 @@
warning: there was one deprecation warning (since 2.12.0); re-run with -deprecation for details