diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 2 | ||||
-rw-r--r-- | src/partest/scala/tools/partest/AsmNode.scala | 60 | ||||
-rw-r--r-- | src/partest/scala/tools/partest/BytecodeTest.scala | 33 |
3 files changed, 91 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 |