Skip to content

Commit d3111e3

Browse files
committed
Remove compiler dependency on @BeanInfo
This mirror similar changes done by Adriaan Moors in scala#6164
1 parent b4f9188 commit d3111e3

File tree

6 files changed

+10
-278
lines changed

6 files changed

+10
-278
lines changed

src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala

Lines changed: 0 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -511,120 +511,6 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
511511

512512
} // end of class JMirrorBuilder
513513

514-
/* builder of bean info classes */
515-
class JBeanInfoBuilder extends BCInnerClassGen {
516-
517-
/*
518-
* Generate a bean info class that describes the given class.
519-
*
520-
* @author Ross Judson ([email protected])
521-
*
522-
* must-single-thread
523-
*/
524-
def genBeanInfoClass(cls: Symbol, cunit: CompilationUnit, fieldSymbols: List[Symbol], methodSymbols: List[Symbol]): asm.tree.ClassNode = {
525-
526-
def javaSimpleName(s: Symbol): String = { s.javaSimpleName.toString }
527-
528-
innerClassBufferASM.clear()
529-
530-
val flags = javaFlags(cls)
531-
532-
val beanInfoName = (internalName(cls) + "BeanInfo")
533-
val beanInfoClass = new asm.tree.ClassNode
534-
beanInfoClass.visit(
535-
classfileVersion,
536-
flags,
537-
beanInfoName,
538-
null, // no java-generic-signature
539-
"scala/beans/ScalaBeanInfo",
540-
EMPTY_STRING_ARRAY
541-
)
542-
543-
beanInfoClass.visitSource(
544-
sourceFileFor(cunit).toString,
545-
null /* SourceDebugExtension */
546-
)
547-
548-
var fieldList = List[String]()
549-
550-
for (f <- fieldSymbols if f.hasGetter;
551-
g = f.getter(cls);
552-
s = f.setter(cls);
553-
if g.isPublic && !(f.name startsWith "$")
554-
) {
555-
// inserting $outer breaks the bean
556-
fieldList = javaSimpleName(f) :: javaSimpleName(g) :: (if (s != NoSymbol) javaSimpleName(s) else null) :: fieldList
557-
}
558-
559-
val methodList: List[String] =
560-
for (m <- methodSymbols
561-
if !m.isConstructor &&
562-
m.isPublic &&
563-
!(m.name startsWith "$") &&
564-
!m.isGetter &&
565-
!m.isSetter)
566-
yield javaSimpleName(m)
567-
568-
val constructor = beanInfoClass.visitMethod(
569-
asm.Opcodes.ACC_PUBLIC,
570-
INSTANCE_CONSTRUCTOR_NAME,
571-
"()V",
572-
null, // no java-generic-signature
573-
EMPTY_STRING_ARRAY // no throwable exceptions
574-
)
575-
576-
val stringArrayJType: BType = ArrayBType(StringRef)
577-
val conJType: BType = MethodBType(
578-
classBTypeFromSymbol(ClassClass) :: stringArrayJType :: stringArrayJType :: Nil,
579-
UNIT
580-
)
581-
582-
def push(lst: List[String]): Unit = {
583-
var fi = 0
584-
for (f <- lst) {
585-
constructor.visitInsn(asm.Opcodes.DUP)
586-
constructor.visitLdcInsn(new java.lang.Integer(fi))
587-
if (f == null) { constructor.visitInsn(asm.Opcodes.ACONST_NULL) }
588-
else { constructor.visitLdcInsn(f) }
589-
constructor.visitInsn(StringRef.typedOpcode(asm.Opcodes.IASTORE))
590-
fi += 1
591-
}
592-
}
593-
594-
constructor.visitCode()
595-
596-
constructor.visitVarInsn(asm.Opcodes.ALOAD, 0)
597-
// push the class
598-
constructor.visitLdcInsn(classBTypeFromSymbol(cls).toASMType)
599-
600-
// push the string array of field information
601-
constructor.visitLdcInsn(new java.lang.Integer(fieldList.length))
602-
constructor.visitTypeInsn(asm.Opcodes.ANEWARRAY, StringRef.internalName)
603-
push(fieldList)
604-
605-
// push the string array of method information
606-
constructor.visitLdcInsn(new java.lang.Integer(methodList.length))
607-
constructor.visitTypeInsn(asm.Opcodes.ANEWARRAY, StringRef.internalName)
608-
push(methodList)
609-
610-
// invoke the superclass constructor, which will do the
611-
// necessary java reflection and create Method objects.
612-
constructor.visitMethodInsn(asm.Opcodes.INVOKESPECIAL, "scala/beans/ScalaBeanInfo", INSTANCE_CONSTRUCTOR_NAME, conJType.descriptor, false)
613-
constructor.visitInsn(asm.Opcodes.RETURN)
614-
615-
constructor.visitMaxs(0, 0) // just to follow protocol, dummy arguments
616-
constructor.visitEnd()
617-
618-
innerClassBufferASM ++= classBTypeFromSymbol(cls).info.memberClasses
619-
addInnerClassesASM(beanInfoClass, innerClassBufferASM.toList)
620-
621-
beanInfoClass.visitEnd()
622-
623-
beanInfoClass
624-
}
625-
626-
} // end of class JBeanInfoBuilder
627-
628514
trait JAndroidBuilder {
629515
self: BCInnerClassGen =>
630516

src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ abstract class BTypes {
559559
* Mirror Classes
560560
* --------------
561561
*
562-
* TODO: innerclass attributes on mirror class, bean info class
562+
* TODO: innerclass attributes on mirror class
563563
*/
564564

565565
/**

src/compiler/scala/tools/nsc/backend/jvm/BackendInterface.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions {
457457
def hasPackageFlag: Boolean
458458
def isImplClass: Boolean
459459
def isInterface: Boolean
460-
def hasGetter: Boolean
461460
def isGetter: Boolean
462461
def isSetter: Boolean
463462
def isGetClass: Boolean

src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala

Lines changed: 1 addition & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
7878
binarynme.RuntimeNull.toString() -> RuntimeNullClass
7979
)
8080

81-
// Lazy val; can't have eager vals in Phase constructors which may
82-
// cause cycles before Global has finished initialization.
83-
lazy val BeanInfoAttr = rootMirror.getRequiredClass("scala.beans.BeanInfo")
84-
8581
private def initBytecodeWriter(entryPoints: List[IClass]): BytecodeWriter = {
8682
settings.outputDirs.getSingleOutput match {
8783
case Some(f) if f hasExtension "jar" =>
@@ -192,7 +188,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
192188
val needsOutfile = bytecodeWriter.isInstanceOf[ClassBytecodeWriter]
193189
val plainCodeGen = new JPlainBuilder( bytecodeWriter, needsOutfile)
194190
val mirrorCodeGen = new JMirrorBuilder( bytecodeWriter, needsOutfile)
195-
val beanInfoCodeGen = new JBeanInfoBuilder(bytecodeWriter, needsOutfile)
196191

197192
def emitFor(c: IClass) {
198193
if (isStaticModule(c.symbol) && isTopLevelModule(c.symbol)) {
@@ -202,7 +197,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
202197
log(s"No mirror class for module with linked class: ${c.symbol.fullName}")
203198
}
204199
plainCodeGen genClass c
205-
if (c.symbol hasAnnotation BeanInfoAttr) beanInfoCodeGen genBeanInfoClass c
206200
}
207201

208202
while (!sortedClasses.isEmpty) {
@@ -528,7 +522,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
528522
}
529523

530524
// -----------------------------------------------------------------------------------------
531-
// utilities useful when emitting plain, mirror, and beaninfo classes.
525+
// utilities useful when emitting plain and mirror classes.
532526
// -----------------------------------------------------------------------------------------
533527

534528
def writeIfNotTooBig(label: String, jclassName: String, jclass: asm.ClassWriter, sym: Symbol) {
@@ -2807,134 +2801,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
28072801
}
28082802
} // end of class JMirrorBuilder
28092803

2810-
2811-
/** builder of bean info classes */
2812-
class JBeanInfoBuilder(bytecodeWriter: BytecodeWriter, needsOutfile: Boolean) extends JBuilder(bytecodeWriter, needsOutfile) {
2813-
2814-
/**
2815-
* Generate a bean info class that describes the given class.
2816-
*
2817-
* @author Ross Judson ([email protected])
2818-
*/
2819-
def genBeanInfoClass(clasz: IClass) {
2820-
2821-
// val BeanInfoSkipAttr = definitions.getRequiredClass("scala.beans.BeanInfoSkip")
2822-
// val BeanDisplayNameAttr = definitions.getRequiredClass("scala.beans.BeanDisplayName")
2823-
// val BeanDescriptionAttr = definitions.getRequiredClass("scala.beans.BeanDescription")
2824-
// val description = c.symbol getAnnotation BeanDescriptionAttr
2825-
// informProgress(description.toString)
2826-
innerClassBuffer.clear()
2827-
2828-
val flags = mkFlags(
2829-
javaFlags(clasz.symbol),
2830-
if(isDeprecated(clasz.symbol)) asm.Opcodes.ACC_DEPRECATED else 0 // ASM pseudo access flag
2831-
)
2832-
2833-
val beanInfoName = (javaName(clasz.symbol) + "BeanInfo")
2834-
val beanInfoClass = createJClass(
2835-
flags,
2836-
beanInfoName,
2837-
null, // no java-generic-signature
2838-
"scala/beans/ScalaBeanInfo",
2839-
EMPTY_STRING_ARRAY
2840-
)
2841-
2842-
// beanInfoClass typestate: entering mode with valid call sequences:
2843-
// [ visitSource ] [ visitOuterClass ] ( visitAnnotation | visitAttribute )*
2844-
2845-
beanInfoClass.visitSource(
2846-
clasz.cunit.source.toString,
2847-
null /* SourceDebugExtension */
2848-
)
2849-
2850-
var fieldList = List[String]()
2851-
2852-
for (f <- clasz.fields if f.symbol.hasGetter;
2853-
g = f.symbol.getter(clasz.symbol);
2854-
s = f.symbol.setter(clasz.symbol)
2855-
if g.isPublic && !(f.symbol.name startsWith "$")
2856-
) {
2857-
// inserting $outer breaks the bean
2858-
fieldList = javaName(f.symbol) :: javaName(g) :: (if (s != NoSymbol) javaName(s) else null) :: fieldList
2859-
}
2860-
2861-
val methodList: List[String] =
2862-
for (m <- clasz.methods
2863-
if !m.symbol.isConstructor &&
2864-
m.symbol.isPublic &&
2865-
!(m.symbol.name startsWith "$") &&
2866-
!m.symbol.isGetter &&
2867-
!m.symbol.isSetter)
2868-
yield javaName(m.symbol)
2869-
2870-
// beanInfoClass typestate: entering mode with valid call sequences:
2871-
// ( visitInnerClass | visitField | visitMethod )* visitEnd
2872-
2873-
val constructor = beanInfoClass.visitMethod(
2874-
asm.Opcodes.ACC_PUBLIC,
2875-
INSTANCE_CONSTRUCTOR_NAME,
2876-
mdesc_arglessvoid,
2877-
null, // no java-generic-signature
2878-
EMPTY_STRING_ARRAY // no throwable exceptions
2879-
)
2880-
2881-
// constructor typestate: entering mode with valid call sequences:
2882-
// [ visitAnnotationDefault ] ( visitAnnotation | visitParameterAnnotation | visitAttribute )*
2883-
2884-
val stringArrayJType: asm.Type = javaArrayType(JAVA_LANG_STRING)
2885-
val conJType: asm.Type =
2886-
asm.Type.getMethodType(
2887-
asm.Type.VOID_TYPE,
2888-
Array(javaType(ClassClass), stringArrayJType, stringArrayJType): _*
2889-
)
2890-
2891-
def push(lst: List[String]) {
2892-
var fi = 0
2893-
for (f <- lst) {
2894-
constructor.visitInsn(asm.Opcodes.DUP)
2895-
constructor.visitLdcInsn(new java.lang.Integer(fi))
2896-
if (f == null) { constructor.visitInsn(asm.Opcodes.ACONST_NULL) }
2897-
else { constructor.visitLdcInsn(f) }
2898-
constructor.visitInsn(JAVA_LANG_STRING.getOpcode(asm.Opcodes.IASTORE))
2899-
fi += 1
2900-
}
2901-
}
2902-
2903-
// constructor typestate: entering mode with valid call sequences:
2904-
// [ visitCode ( visitFrame | visitXInsn | visitLabel | visitTryCatchBlock | visitLocalVariable | visitLineNumber )* visitMaxs ] visitEnd
2905-
2906-
constructor.visitCode()
2907-
2908-
constructor.visitVarInsn(asm.Opcodes.ALOAD, 0)
2909-
// push the class
2910-
constructor.visitLdcInsn(javaType(clasz.symbol))
2911-
2912-
// push the string array of field information
2913-
constructor.visitLdcInsn(new java.lang.Integer(fieldList.length))
2914-
constructor.visitTypeInsn(asm.Opcodes.ANEWARRAY, JAVA_LANG_STRING.getInternalName)
2915-
push(fieldList)
2916-
2917-
// push the string array of method information
2918-
constructor.visitLdcInsn(new java.lang.Integer(methodList.length))
2919-
constructor.visitTypeInsn(asm.Opcodes.ANEWARRAY, JAVA_LANG_STRING.getInternalName)
2920-
push(methodList)
2921-
2922-
// invoke the superclass constructor, which will do the
2923-
// necessary java reflection and create Method objects.
2924-
constructor.visitMethodInsn(asm.Opcodes.INVOKESPECIAL, "scala/beans/ScalaBeanInfo", INSTANCE_CONSTRUCTOR_NAME, conJType.getDescriptor, false)
2925-
constructor.visitInsn(asm.Opcodes.RETURN)
2926-
2927-
constructor.visitMaxs(0, 0) // just to follow protocol, dummy arguments
2928-
constructor.visitEnd()
2929-
2930-
addInnerClasses(clasz.symbol, beanInfoClass)
2931-
beanInfoClass.visitEnd()
2932-
2933-
writeIfNotTooBig("BeanInfo ", beanInfoName, beanInfoClass, clasz.symbol)
2934-
}
2935-
2936-
} // end of class JBeanInfoBuilder
2937-
29382804
/** A namespace for utilities to normalize the code of an IMethod, over and beyond what IMethod.normalize() strives for.
29392805
* In particualr, IMethod.normalize() doesn't collapseJumpChains().
29402806
*

0 commit comments

Comments
 (0)