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 (ross.judson@soletta.com) |
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 |
| - |
628 | 514 | trait JAndroidBuilder {
|
629 | 515 | self: BCInnerClassGen =>
|
630 | 516 |
|
|
0 commit comments