summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-11-12 00:07:37 +0000
committerPaul Phillips <paulp@improving.org>2010-11-12 00:07:37 +0000
commit91eff8e6d903a9eab2bc83c120774d623df5ad7d (patch)
tree23b15f42d230452d5f0ac0b7ff6ee9f96766a3d5
parent46a921df8152d2535cca577132a2fe323a57ca88 (diff)
downloadscala-91eff8e6d903a9eab2bc83c120774d623df5ad7d.tar.gz
scala-91eff8e6d903a9eab2bc83c120774d623df5ad7d.tar.bz2
scala-91eff8e6d903a9eab2bc83c120774d623df5ad7d.zip
Half of an implementation of sealedness for jav...
Half of an implementation of sealedness for java enums. Since it's only half it's behind -Xexperimental, but it works like a charm for the half where it works (that being compiling against bytecode.) Need input on how to approach the source half. References ticket #2442. Review by moors.
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala24
-rw-r--r--test/files/neg/sealed-java-enums.check8
-rw-r--r--test/files/neg/sealed-java-enums.flags1
-rw-r--r--test/files/neg/sealed-java-enums.scala10
5 files changed, 39 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index c2136edbb6..0f05a7fcce 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -222,6 +222,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
def debug = settings.debug.value
def deprecation = settings.deprecation.value
+ def experimental = settings.Xexperimental.value
def fatalWarnings = settings.Xwarnfatal.value
def logClasspath = settings.Ylogcp.value
def printLate = settings.printLate.value
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 2c47239a92..a051177a87 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -603,14 +603,28 @@ abstract class ClassfileParser {
if ((sflags & PRIVATE) != 0L && !global.settings.XO.value) {
in.skip(4); skipAttributes()
} else {
- val name = pool.getName(in.nextChar)
- val info = pool.getType(in.nextChar)
- val sym = getOwner(jflags)
- .newValue(NoPosition, name).setFlag(sflags)
- sym.setInfo(if ((jflags & JAVA_ACC_ENUM) == 0) info else ConstantType(Constant(sym)))
+ val name = pool.getName(in.nextChar)
+ val info = pool.getType(in.nextChar)
+ val sym = getOwner(jflags).newValue(NoPosition, name).setFlag(sflags)
+ val isEnum = (jflags & JAVA_ACC_ENUM) != 0
+
+ sym setInfo {
+ if (isEnum) ConstantType(Constant(sym))
+ else info
+ }
setPrivateWithin(sym, jflags)
parseAttributes(sym, info)
getScope(jflags).enter(sym)
+
+ // sealed java enums (experimental)
+ if (isEnum && opt.experimental) {
+ // need to give singleton type
+ sym setInfo info.narrow
+ if (!sym.superClass.isSealed)
+ sym.superClass setFlag (SEALED | ABSTRACT)
+
+ sym.superClass addChild sym
+ }
}
}
diff --git a/test/files/neg/sealed-java-enums.check b/test/files/neg/sealed-java-enums.check
new file mode 100644
index 0000000000..9a4bd4241e
--- /dev/null
+++ b/test/files/neg/sealed-java-enums.check
@@ -0,0 +1,8 @@
+sealed-java-enums.scala:5: error: match is not exhaustive!
+missing combination BLOCKED
+missing combination TERMINATED
+missing combination TIMED_WAITING
+
+ def f(state: State) = state match {
+ ^
+one error found
diff --git a/test/files/neg/sealed-java-enums.flags b/test/files/neg/sealed-java-enums.flags
new file mode 100644
index 0000000000..e709c65918
--- /dev/null
+++ b/test/files/neg/sealed-java-enums.flags
@@ -0,0 +1 @@
+-Xexperimental -Xfatal-warnings
diff --git a/test/files/neg/sealed-java-enums.scala b/test/files/neg/sealed-java-enums.scala
new file mode 100644
index 0000000000..2daf93f308
--- /dev/null
+++ b/test/files/neg/sealed-java-enums.scala
@@ -0,0 +1,10 @@
+import java.lang.Thread.State
+import java.lang.Thread.State._
+
+object Test {
+ def f(state: State) = state match {
+ case NEW | WAITING => true
+ case RUNNABLE => false
+ // and I forget the rest
+ }
+}