@@ -917,44 +917,113 @@ class Reach(
917
917
unsupported.getOrElseUpdate(global, details)
918
918
case _ =>
919
919
unreachable.getOrElseUpdate(
920
- global, {
921
- val (kind, symbol) = parseSymbol(global)
922
- UnreachableSymbol (
923
- name = global,
924
- kind = kind,
925
- symbol = symbol,
926
- backtrace = getBackTrace(global)
927
- )
928
- }
920
+ global,
921
+ UnreachableSymbol (
922
+ name = global,
923
+ symbol = parseSymbol(global),
924
+ backtrace = getBackTrace(global)
925
+ )
929
926
)
930
927
}
931
928
932
- private def parseSymbol (name : Global ): (String , String ) = {
933
- def parseSig (owner : String , sig : Sig ): (String , String ) =
929
+ private def parseSymbol (name : Global ): SymbolDescriptor = {
930
+ def renderType (tpe : nir.Type ): String = tpe match {
931
+ case arr : Type .Array => s " ${renderType(arr.ty)}[] "
932
+ case ref : Type .RefKind => ref.className.id
933
+ case ty => ty.show
934
+ }
935
+ def parseArgTypes (
936
+ types : Seq [nir.Type ],
937
+ isCtor : Boolean = false
938
+ ): Some [Seq [String ]] = Some {
939
+ val args = types match {
940
+ case _ if isCtor => types
941
+ case args :+ retty => args
942
+ case _ => Nil
943
+ }
944
+ args.map(renderType)
945
+ }
946
+
947
+ val Private = " private"
948
+ val Static = " static"
949
+
950
+ def parseResultType (types : Seq [nir.Type ]): Option [String ] =
951
+ types.lastOption.map(renderType)
952
+
953
+ def parseModifiers (scope : nir.Sig .Scope ): List [String ] = scope match {
954
+ case Sig .Scope .Public => Nil
955
+ case Sig .Scope .Private (_) => List (Private )
956
+ case Sig .Scope .PublicStatic => List (Static )
957
+ case Sig .Scope .PrivateStatic (_) => List (Static , Private )
958
+ }
959
+
960
+ def parseSig (owner : String , sig : Sig ): SymbolDescriptor =
934
961
sig.unmangled match {
935
- case Sig .Method (name, _, _) => " method" -> s " $owner. ${name}"
936
- case Sig .Ctor (tys) =>
937
- val ctorTys = tys
938
- .map {
939
- case ty : Type .RefKind => ty.className.id
940
- case ty => ty.show
941
- }
942
- .mkString(" ," )
943
- " constructor" -> s " $owner( $ctorTys) "
944
- case Sig .Clinit => " static constructor" -> owner
945
- case Sig .Field (name, _) => " field" -> s " $owner. $name"
962
+ case Sig .Method (name, types, scope) =>
963
+ SymbolDescriptor (
964
+ " method" ,
965
+ s " $owner. $name" ,
966
+ parseArgTypes(types),
967
+ parseResultType(types),
968
+ parseModifiers(scope)
969
+ )
970
+ case Sig .Ctor (types) =>
971
+ SymbolDescriptor (
972
+ " constructor" ,
973
+ owner,
974
+ parseArgTypes(types, isCtor = true )
975
+ )
976
+ case Sig .Clinit =>
977
+ SymbolDescriptor (
978
+ " constructor" ,
979
+ owner,
980
+ modifiers = List (Static )
981
+ )
982
+ case Sig .Field (name, scope) =>
983
+ SymbolDescriptor (
984
+ " field" ,
985
+ owner,
986
+ modifiers = parseModifiers(scope)
987
+ )
946
988
case Sig .Generated (name) =>
947
- " generated method" -> s " $owner. ${name}"
948
- case Sig .Proxy (name, _) => " proxy method" -> s " $owner. $name"
949
- case Sig .Duplicate (sig, _) =>
950
- val (kind, name) = parseSig(owner, sig)
951
- s " duplicate $kind" -> s " $owner.name "
952
- case Sig .Extern (name) => s " extern method " -> s " $owner. $name"
989
+ SymbolDescriptor (
990
+ " symbol" ,
991
+ s " $owner. $name" ,
992
+ modifiers = List (" generated" )
993
+ )
994
+ case Sig .Proxy (name, types) =>
995
+ SymbolDescriptor (
996
+ " method" ,
997
+ s " $owner. $name" ,
998
+ parseArgTypes(types),
999
+ parseResultType(types),
1000
+ modifiers = List (" proxy" )
1001
+ )
1002
+ case Sig .Duplicate (sig, types) =>
1003
+ val original = parseSig(owner, sig)
1004
+ original.copy(
1005
+ argTypes = parseArgTypes(types),
1006
+ resultType = parseResultType(types),
1007
+ modifiers = List (" duplicate" ) ++ original.modifiers
1008
+ )
1009
+ SymbolDescriptor (
1010
+ " method" ,
1011
+ s " $owner. $name" ,
1012
+ parseArgTypes(types),
1013
+ parseResultType(types),
1014
+ modifiers = List (" duplicate" )
1015
+ )
1016
+ case Sig .Extern (name) =>
1017
+ SymbolDescriptor (
1018
+ " symbol" ,
1019
+ s " $owner. $name" ,
1020
+ modifiers = List (" extern" )
1021
+ )
953
1022
}
954
1023
955
1024
name match {
956
1025
case Global .Member (owner, sig) => parseSig(owner.id, sig)
957
- case Global .Top (id) => " type" -> id
1026
+ case Global .Top (id) => SymbolDescriptor ( " type" , id)
958
1027
case _ => util.unreachable
959
1028
}
960
1029
}
@@ -969,11 +1038,9 @@ class Reach(
969
1038
else {
970
1039
val file = current.srcPosition.filename.getOrElse(" unknown" )
971
1040
val line = current.srcPosition.line
972
- val (kind, symbol) = parseSymbol(current.referencedBy)
973
1041
buf += BackTraceElement (
974
1042
name = current.referencedBy,
975
- kind = kind,
976
- symbol = symbol,
1043
+ symbol = parseSymbol(current.referencedBy),
977
1044
filename = file,
978
1045
line = line + 1
979
1046
)
@@ -1087,17 +1154,30 @@ object Reach {
1087
1154
object ReferencedFrom {
1088
1155
final val Root = ReferencedFrom (nir.Global .None , nir.Position .NoPosition )
1089
1156
}
1157
+ case class SymbolDescriptor (
1158
+ kind : String ,
1159
+ name : String ,
1160
+ argTypes : Option [Seq [String ]] = None ,
1161
+ resultType : Option [String ] = None ,
1162
+ modifiers : Seq [String ] = Nil
1163
+ ) {
1164
+ override def toString (): String = {
1165
+ val mods =
1166
+ if (modifiers.isEmpty) " " else modifiers.distinct.mkString(" " , " " , " " )
1167
+ val argsList = argTypes.fold(" " )(_.mkString(" (" , " , " , " )" ))
1168
+ val resType = resultType.fold(" " )(tpe => s " : $tpe" )
1169
+ s " $mods$kind $name$argsList$resType"
1170
+ }
1171
+ }
1090
1172
case class BackTraceElement (
1091
1173
name : Global ,
1092
- kind : String ,
1093
- symbol : String ,
1174
+ symbol : SymbolDescriptor ,
1094
1175
filename : String ,
1095
1176
line : Int
1096
1177
)
1097
1178
case class UnreachableSymbol (
1098
1179
name : Global ,
1099
- kind : String ,
1100
- symbol : String ,
1180
+ symbol : SymbolDescriptor ,
1101
1181
backtrace : List [BackTraceElement ]
1102
1182
)
1103
1183
0 commit comments