@@ -509,7 +509,7 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
509
509
* classfile attribute.
510
510
*/
511
511
private def buildInlineInfo (classSym : Symbol , internalName : InternalName ): InlineInfo = {
512
- def buildFromSymbol = buildInlineInfoFromClassSymbol(classSym, classBTypeFromSymbol(_).internalName, methodBTypeFromSymbol(_).descriptor )
512
+ def buildFromSymbol = buildInlineInfoFromClassSymbol(classSym)
513
513
514
514
// phase travel required, see implementation of `compiles`. for nested classes, it checks if the
515
515
// enclosingTopLevelClass is being compiled. after flatten, all classes are considered top-level,
@@ -530,6 +530,73 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
530
530
}
531
531
}
532
532
533
+ /**
534
+ * Build the [[InlineInfo ]] for a class symbol.
535
+ */
536
+ def buildInlineInfoFromClassSymbol (classSym : Symbol ): InlineInfo = {
537
+ val isEffectivelyFinal = classSym.isEffectivelyFinal
538
+
539
+ val sam = {
540
+ if (classSym.isEffectivelyFinal) None
541
+ else {
542
+ // Phase travel necessary. For example, nullary methods (getter of an abstract val) get an
543
+ // empty parameter list in later phases and would therefore be picked as SAM.
544
+ val samSym = exitingPickler(definitions.samOf(classSym.tpe))
545
+ if (samSym == NoSymbol ) None
546
+ else Some (samSym.javaSimpleName.toString + methodBTypeFromSymbol(samSym).descriptor)
547
+ }
548
+ }
549
+
550
+ var warning = Option .empty[ClassSymbolInfoFailureSI9111 ]
551
+
552
+ // Primitive methods cannot be inlined, so there's no point in building a MethodInlineInfo. Also, some
553
+ // primitive methods (e.g., `isInstanceOf`) have non-erased types, which confuses [[typeToBType]].
554
+ val methodInlineInfos = classSym.info.decls.iterator.filter(m => m.isMethod && ! scalaPrimitives.isPrimitive(m)).flatMap({
555
+ case methodSym =>
556
+ if (completeSilentlyAndCheckErroneous(methodSym)) {
557
+ // Happens due to SI-9111. Just don't provide any MethodInlineInfo for that method, we don't need fail the compiler.
558
+ if (! classSym.isJavaDefined) devWarning(" SI-9111 should only be possible for Java classes" )
559
+ warning = Some (ClassSymbolInfoFailureSI9111 (classSym.fullName))
560
+ Nil
561
+ } else {
562
+ val name = methodSym.javaSimpleName.toString // same as in genDefDef
563
+ val signature = name + methodBTypeFromSymbol(methodSym).descriptor
564
+
565
+ // In `trait T { object O }`, `oSym.isEffectivelyFinalOrNotOverridden` is true, but the
566
+ // method is abstract in bytecode, `defDef.rhs.isEmpty`. Abstract methods are excluded
567
+ // so they are not marked final in the InlineInfo attribute.
568
+ //
569
+ // However, due to https://github.com/scala/scala-dev/issues/126, this currently does not
570
+ // work, the abstract accessor for O will be marked effectivelyFinal.
571
+ val effectivelyFinal = methodSym.isEffectivelyFinalOrNotOverridden && ! methodSym.isDeferred
572
+
573
+ val info = MethodInlineInfo (
574
+ effectivelyFinal = effectivelyFinal,
575
+ annotatedInline = methodSym.hasAnnotation(ScalaInlineClass ),
576
+ annotatedNoInline = methodSym.hasAnnotation(ScalaNoInlineClass ))
577
+
578
+ if (isTraitMethodRequiringStaticImpl(methodSym)) {
579
+ val selfParam = methodSym.newSyntheticValueParam(methodSym.owner.typeConstructor, nme.SELF )
580
+ val staticMethodType = methodSym.info match {
581
+ case mt @ MethodType (params, res) => copyMethodType(mt, selfParam :: params, res)
582
+ }
583
+ val staticMethodSignature = name + methodBTypeFromMethodType(staticMethodType, isConstructor = false )
584
+ val staticMethodInfo = MethodInlineInfo (
585
+ effectivelyFinal = true ,
586
+ annotatedInline = info.annotatedInline,
587
+ annotatedNoInline = info.annotatedNoInline)
588
+ if (methodSym.isMixinConstructor)
589
+ List ((staticMethodSignature, staticMethodInfo))
590
+ else
591
+ List ((signature, info), (staticMethodSignature, staticMethodInfo))
592
+ } else
593
+ List ((signature, info))
594
+ }
595
+ }).toMap
596
+
597
+ InlineInfo (isEffectivelyFinal, sam, methodInlineInfos, warning)
598
+ }
599
+
533
600
/**
534
601
* For top-level objects without a companion class, the compiler generates a mirror class with
535
602
* static forwarders (Java compat). There's no symbol for the mirror class, but we still need a
0 commit comments