diff options
author | Simon Ochsenreither <simon@ochsenreither.de> | 2015-08-31 05:03:29 +0200 |
---|---|---|
committer | Simon Ochsenreither <simon@ochsenreither.de> | 2016-01-25 19:21:43 +0100 |
commit | c78d771e6f025e767801f7fe118acc2ea7540acd (patch) | |
tree | e2e4faa4bcc60e7b5fd0d9a59d5586ed5522b900 /src | |
parent | 94a228f90e7d0cb997c866a8b9a7663c67e2df3d (diff) | |
download | scala-c78d771e6f025e767801f7fe118acc2ea7540acd.tar.gz scala-c78d771e6f025e767801f7fe118acc2ea7540acd.tar.bz2 scala-c78d771e6f025e767801f7fe118acc2ea7540acd.zip |
SI-9437 Emit and support parameter names in class files
JEP 118 added a MethodParameters attribute to the class file spec which
holds the parameter names of methods when compiling Java code with
`javac -parameters`.
We emit parameter names by default now.
Diffstat (limited to 'src')
4 files changed, 33 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala index 1ec9ba8a95..1b5ece772c 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala @@ -841,6 +841,17 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { } } + /* + * must-single-thread + */ + def emitParamNames(jmethod: asm.MethodVisitor, params: List[Symbol]) = { + for (param <- params) { + var access = asm.Opcodes.ACC_FINAL + if (param.isArtifact) + access |= asm.Opcodes.ACC_SYNTHETIC + jmethod.visitParameter(param.name.decoded, access) + } + } } // end of trait BCAnnotGen trait BCJGenSigGen { diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala index 7180c25d25..9dea21154f 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala @@ -512,7 +512,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { /* * must-single-thread */ - def initJMethod(flags: Int, paramAnnotations: List[List[AnnotationInfo]]) { + def initJMethod(flags: Int, params: List[Symbol]) { val jgensig = getGenericSignature(methSymbol, claszSymbol) addRemoteExceptionAnnot(isCZRemote, hasPublicBitSet(flags), methSymbol) @@ -532,10 +532,9 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { mkArray(thrownExceptions) ).asInstanceOf[asm.tree.MethodNode] - // TODO param names: (m.params map (p => javaName(p.sym))) - + emitParamNames(mnode, params) emitAnnotations(mnode, others) - emitParamAnnotations(mnode, paramAnnotations) + emitParamAnnotations(mnode, params.map(_.annotations)) } // end of method initJMethod @@ -574,8 +573,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { if (isNative) asm.Opcodes.ACC_NATIVE else 0 // native methods of objects are generated in mirror classes ) - // TODO needed? for(ann <- m.symbol.annotations) { ann.symbol.initialize } - initJMethod(flags, params.map(p => p.symbol.annotations)) + initJMethod(flags, params.map(_.symbol)) /* Add method-local vars for LabelDef-params. * diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 406411f21f..fffd48d145 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -816,6 +816,23 @@ abstract class ClassfileParser { val c1 = convertTo(c, symtype) if (c1 ne null) sym.setInfo(ConstantType(c1)) else devWarning(s"failure to convert $c to $symtype") + case tpnme.MethodParametersATTR => + def readParamNames(): Unit = { + import tools.asm.Opcodes.ACC_SYNTHETIC + val paramCount = u1 + var i = 0 + while (i < paramCount) { + val name = pool.getName(u2) + val access = u2 + if ((access & ACC_SYNTHETIC) != ACC_SYNTHETIC) { // name not synthetic + val params = sym.paramss.head // Java only has exactly one parameter list + params(i).name = name.encode + params(i).resetFlag(SYNTHETIC) + } + i += 1 + } + } + readParamNames() case tpnme.ScalaSignatureATTR => if (!isScalaAnnot) { devWarning(s"symbol ${sym.fullName} has pickled signature in attribute") diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index d16d431f6e..80ed597fb7 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -291,6 +291,7 @@ trait StdNames { final val DeprecatedATTR: NameType = "Deprecated" final val ExceptionsATTR: NameType = "Exceptions" final val InnerClassesATTR: NameType = "InnerClasses" + final val MethodParametersATTR: NameType = "MethodParameters" final val RuntimeAnnotationATTR: NameType = "RuntimeVisibleAnnotations" // RetentionPolicy.RUNTIME final val ScalaATTR: NameType = "Scala" final val ScalaSignatureATTR: NameType = "ScalaSig" |