diff options
-rw-r--r-- | src/reflect/scala/reflect/internal/Trees.scala | 10 | ||||
-rw-r--r-- | test/junit/scala/tools/nsc/symtab/CannotHaveAttrsTest.scala | 70 |
2 files changed, 76 insertions, 4 deletions
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index df1ba1e2ea..02bee5e369 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -1017,14 +1017,16 @@ trait Trees extends api.Trees { self: SymbolTable => trait CannotHaveAttrs extends Tree { override def canHaveAttrs = false - private def unsupported(what: String, args: Any*) = - throw new UnsupportedOperationException(s"$what($args) inapplicable for "+self.toString) + private def requireLegal(value: Any, allowed: Any, what: String) = + require(value == allowed, s"can't set $what for $self to value other than $allowed") super.setPos(NoPosition) - override def setPos(pos: Position) = unsupported("setPos", pos) + override def setPos(pos: Position) = { requireLegal(pos, NoPosition, "pos"); this } + override def pos_=(pos: Position) = setPos(pos) super.setType(NoType) - override def tpe_=(t: Type) = if (t != NoType) unsupported("tpe_=", t) + override def setType(t: Type) = { requireLegal(t, NoType, "tpe"); this } + override def tpe_=(t: Type) = setType(t) } case object EmptyTree extends TermTree with CannotHaveAttrs { override def isEmpty = true; val asList = List(this) } diff --git a/test/junit/scala/tools/nsc/symtab/CannotHaveAttrsTest.scala b/test/junit/scala/tools/nsc/symtab/CannotHaveAttrsTest.scala new file mode 100644 index 0000000000..5867a9030b --- /dev/null +++ b/test/junit/scala/tools/nsc/symtab/CannotHaveAttrsTest.scala @@ -0,0 +1,70 @@ +package scala.tools.nsc +package symtab + +import org.junit.Assert._ +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +import scala.tools.testing.AssertUtil.assertThrows +import scala.reflect.internal.util.OffsetPosition + +@RunWith(classOf[JUnit4]) +class CannotHaveAttrsTest { + class CustomSymbolTable extends SymbolTableForUnitTesting { + object CHA extends CannotHaveAttrs { + def canEqual(that: Any): Boolean = ??? + def productArity: Int = ??? + def productElement(n: Int): Any = ??? + } + val attrlessTrees = List(CHA, EmptyTree, emptyValDef, pendingSuperCall) + } + def withCtx(body: CustomSymbolTable => Unit) = body(new CustomSymbolTable) + + @Test + def canHaveAttrsIsFalse = withCtx { st => import st._ + attrlessTrees.foreach { t => + assertFalse(t.canHaveAttrs) + } + } + + @Test + def defaultPosAssignment = withCtx { st => import st._ + attrlessTrees.foreach { t => + assertEquals(t.pos, NoPosition) + t.pos = NoPosition + assertEquals(t.pos, NoPosition) + t.setPos(NoPosition) + assertEquals(t.pos, NoPosition) + } + } + + @Test + def defaultTpeAssignment = withCtx { st => import st._ + attrlessTrees.foreach { t => + assertEquals(t.tpe, NoType) + t.tpe = NoType + assertEquals(t.tpe, NoType) + t.setType(NoType) + assertEquals(t.tpe, NoType) + } + } + + @Test + def nonDefaultPosAssignmentFails = withCtx { st => import st._ + val pos = new OffsetPosition(null, 0) + attrlessTrees.foreach { t => + assertThrows[IllegalArgumentException] { t.pos = pos } + assertThrows[IllegalArgumentException] { t.setPos(pos) } + } + } + + @Test + def nonDefaultTpeAssignmentFails = withCtx { st => import st._ + val tpe = typeOf[Int] + attrlessTrees.foreach { t => + assertThrows[IllegalArgumentException] { t.tpe = tpe } + assertThrows[IllegalArgumentException] { t.setType(tpe) } + } + } +} |