summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Iry <jamesiry@gmail.com>2013-02-09 06:46:59 -0800
committerJames Iry <jamesiry@gmail.com>2013-02-09 06:46:59 -0800
commitdb5919a7d3b18be94e79899c2f7e33c535e15a27 (patch)
tree7165c6450b5506874e9f69708c6240c34b2a0512
parent23b69c1e05474dc6b504d63c074629132264deaf (diff)
parent13caa498fb856ac1de3b851ddc413e36d728c3a6 (diff)
downloadscala-db5919a7d3b18be94e79899c2f7e33c535e15a27.tar.gz
scala-db5919a7d3b18be94e79899c2f7e33c535e15a27.tar.bz2
scala-db5919a7d3b18be94e79899c2f7e33c535e15a27.zip
Merge pull request #2100 from paulp/pr/fix-super-varargs-saved
Fixing binary compat for $super regression
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--src/partest/scala/tools/partest/AsmNode.scala60
-rw-r--r--src/partest/scala/tools/partest/BytecodeTest.scala33
-rw-r--r--test/files/run/t7106.check6
-rw-r--r--test/files/run/t7106/Analyzed_1.scala14
-rw-r--r--test/files/run/t7106/test.scala10
6 files changed, 121 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index dc5491a509..478312116a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2037,7 +2037,7 @@ trait Typers extends Modes with Adaptations with Tags {
val alias = (
superAcc.initialize.alias
orElse (superAcc getter superAcc.owner)
- filter (alias => superClazz.info.nonPrivateMember(alias.name) != alias)
+ filter (alias => superClazz.info.nonPrivateMember(alias.name) == alias)
)
if (alias.exists && !alias.accessed.isVariable) {
val ownAcc = clazz.info decl name suchThat (_.isParamAccessor) match {
diff --git a/src/partest/scala/tools/partest/AsmNode.scala b/src/partest/scala/tools/partest/AsmNode.scala
new file mode 100644
index 0000000000..d181436676
--- /dev/null
+++ b/src/partest/scala/tools/partest/AsmNode.scala
@@ -0,0 +1,60 @@
+package scala.tools.partest
+
+import scala.collection.JavaConverters._
+import scala.tools.asm
+import asm._
+import asm.tree._
+import java.lang.reflect.Modifier
+
+sealed trait AsmNode[+T] {
+ def node: T
+ def access: Int
+ def desc: String
+ def name: String
+ def signature: String
+ def attrs: List[Attribute]
+ def visibleAnnotations: List[AnnotationNode]
+ def invisibleAnnotations: List[AnnotationNode]
+ def characteristics = f"$name%15s $desc%-30s$accessString$sigString"
+
+ private def accessString = if (access == 0) "" else " " + Modifier.toString(access)
+ private def sigString = if (signature == null) "" else " " + signature
+ override def toString = characteristics
+}
+
+object AsmNode {
+ type AsmMethod = AsmNode[MethodNode]
+ type AsmField = AsmNode[FieldNode]
+ type AsmMember = AsmNode[_]
+
+ implicit class ClassNodeOps(val node: ClassNode) {
+ def fieldsAndMethods: List[AsmMember] = {
+ val xs: List[AsmMember] = (
+ node.methods.asScala.toList.map(x => (x: AsmMethod))
+ ++ node.fields.asScala.toList.map(x => (x: AsmField))
+ )
+ xs sortBy (_.characteristics)
+ }
+ }
+ implicit class AsmMethodNode(val node: MethodNode) extends AsmNode[MethodNode] {
+ def access: Int = node.access
+ def desc: String = node.desc
+ def name: String = node.name
+ def signature: String = node.signature
+ def attrs: List[Attribute] = node.attrs.asScala.toList
+ def visibleAnnotations: List[AnnotationNode] = node.visibleAnnotations.asScala.toList
+ def invisibleAnnotations: List[AnnotationNode] = node.invisibleAnnotations.asScala.toList
+ }
+ implicit class AsmFieldNode(val node: FieldNode) extends AsmNode[FieldNode] {
+ def access: Int = node.access
+ def desc: String = node.desc
+ def name: String = node.name
+ def signature: String = node.signature
+ def attrs: List[Attribute] = node.attrs.asScala.toList
+ def visibleAnnotations: List[AnnotationNode] = node.visibleAnnotations.asScala.toList
+ def invisibleAnnotations: List[AnnotationNode] = node.invisibleAnnotations.asScala.toList
+ }
+
+ def apply(node: MethodNode): AsmMethodNode = new AsmMethodNode(node)
+ def apply(node: FieldNode): AsmFieldNode = new AsmFieldNode(node)
+}
diff --git a/src/partest/scala/tools/partest/BytecodeTest.scala b/src/partest/scala/tools/partest/BytecodeTest.scala
index 41329a8264..2699083069 100644
--- a/src/partest/scala/tools/partest/BytecodeTest.scala
+++ b/src/partest/scala/tools/partest/BytecodeTest.scala
@@ -3,9 +3,10 @@ package scala.tools.partest
import scala.tools.nsc.util.JavaClassPath
import scala.collection.JavaConverters._
import scala.tools.asm
-import asm.ClassReader
+import asm.{ ClassReader }
import asm.tree.{ClassNode, MethodNode, InsnList}
import java.io.InputStream
+import AsmNode._
/**
* Provides utilities for inspecting bytecode using ASM library.
@@ -29,13 +30,14 @@ import java.io.InputStream
*
*/
abstract class BytecodeTest extends ASMConverters {
+ import instructions._
/** produce the output to be compared against a checkfile */
protected def show(): Unit
def main(args: Array[String]): Unit = show
-// asserts
+ // asserts
def sameBytecode(methA: MethodNode, methB: MethodNode) = {
val isa = instructions.fromMethod(methA)
val isb = instructions.fromMethod(methB)
@@ -43,7 +45,32 @@ abstract class BytecodeTest extends ASMConverters {
else diffInstructions(isa, isb)
}
- import instructions._
+ // Do these classes have all the same methods, with the same names, access,
+ // descriptors and generic signatures? Method bodies are not considered, and
+ // the names of the classes containing the methods are substituted so they do
+ // not appear as differences.
+ def sameMethodAndFieldSignatures(clazzA: ClassNode, clazzB: ClassNode): Boolean = {
+ val ms1 = clazzA.fieldsAndMethods.toIndexedSeq
+ val ms2 = clazzB.fieldsAndMethods.toIndexedSeq
+ val name1 = clazzA.name
+ val name2 = clazzB.name
+
+ if (ms1.length != ms2.length) {
+ println("Different member counts in $name1 and $name2")
+ false
+ }
+ else (ms1, ms2).zipped forall { (m1, m2) =>
+ val c1 = m1.characteristics
+ val c2 = m2.characteristics.replaceAllLiterally(name2, name1)
+ if (c1 == c2)
+ println(s"[ok] $m1")
+ else
+ println(s"[fail]\n in $name1: $c1\n in $name2: $c2")
+
+ c1 == c2
+ }
+ }
+
// bytecode is equal modulo local variable numbering
def equalsModuloVar(a: Instruction, b: Instruction) = (a, b) match {
case _ if a == b => true
diff --git a/test/files/run/t7106.check b/test/files/run/t7106.check
new file mode 100644
index 0000000000..9a4bb430fd
--- /dev/null
+++ b/test/files/run/t7106.check
@@ -0,0 +1,6 @@
+[ok] q1 I private final
+[ok] q3 I private final
+[ok] <init> (III)V public
+[ok] bippy1 ()I public
+[ok] bippy2 ()I public
+[ok] bippy3 ()I public
diff --git a/test/files/run/t7106/Analyzed_1.scala b/test/files/run/t7106/Analyzed_1.scala
new file mode 100644
index 0000000000..a2ddebceed
--- /dev/null
+++ b/test/files/run/t7106/Analyzed_1.scala
@@ -0,0 +1,14 @@
+
+abstract class Base0 { def p2: Int }
+class Base(p1: Int, override val p2: Int) extends Base0
+
+abstract class Sub1(q1: Int, q2: Int, q3: Int) extends Base(q1, q2) {
+ def bippy1 = q1
+ def bippy2 = q2
+ def bippy3 = q3
+}
+abstract class Sub2(q1: Int, q2: Int, q3: Int) extends Base(q1, q2) {
+ def bippy1 = q1
+ def bippy2 = p2
+ def bippy3 = q3
+}
diff --git a/test/files/run/t7106/test.scala b/test/files/run/t7106/test.scala
new file mode 100644
index 0000000000..3584a272db
--- /dev/null
+++ b/test/files/run/t7106/test.scala
@@ -0,0 +1,10 @@
+import scala.tools.partest.BytecodeTest
+
+object Test extends BytecodeTest {
+ def show {
+ val node1 = loadClassNode("Sub1")
+ val node2 = loadClassNode("Sub2")
+
+ sameMethodAndFieldSignatures(node1, node2)
+ }
+}