Use TypeTableStack

This commit is contained in:
Konstantin Anisimov
2017-06-20 10:01:30 +07:00
committed by KonstantinAnisimov
parent f70835fc29
commit f1542f7007
@@ -38,21 +38,25 @@ class PrettyPrinter(val library: Base64, val packageLoader: (String) -> Base64)
get() = moduleHeader.packageFragmentNameList get() = moduleHeader.packageFragmentNameList
fun printPackageFragment(fqname: String) { fun printPackageFragment(fqname: String) {
if (fqname.isNotEmpty()) println("\nPackage $fqname" ) if (fqname == "konan") {
val fragment = packageFragment(fqname) if (fqname.isNotEmpty()) println("\nPackage $fqname")
PackageFragmentPrinter(fragment, out).print() val fragment = packageFragment(fqname)
PackageFragmentPrinter(fragment, out).print()
}
} }
} }
class PackageFragmentPrinter(val packageFragment: KonanLinkData.PackageFragment, out: Appendable) { class PackageFragmentPrinter(val packageFragment: KonanLinkData.PackageFragment, out: Appendable) {
val printer = Printer(out, " ") val printer = Printer(out, " ")
val stringTable = packageFragment.stringTable!! val stringTable = packageFragment.stringTable!!
val qualifiedNameTable = packageFragment.nameTable!! val qualifiedNameTable = packageFragment.nameTable!!
var typeTable: ProtoBuf.TypeTable? = packageFragment.`package`.typeTable var typeTableStack = mutableListOf<ProtoBuf.TypeTable>() //? =
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
fun print() { fun print() {
typeTableStack.add(packageFragment.`package`.typeTable)
val protoTypeAliases = packageFragment.`package`.typeAliasList val protoTypeAliases = packageFragment.`package`.typeAliasList
protoTypeAliases.forEach { protoTypeAlias -> protoTypeAliases.forEach { protoTypeAlias ->
printTypeAlias(protoTypeAlias) printTypeAlias(protoTypeAlias)
@@ -61,7 +65,6 @@ class PackageFragmentPrinter(val packageFragment: KonanLinkData.PackageFragment,
val protoClasses = packageFragment.classes.classesList // ProtoBuf classes val protoClasses = packageFragment.classes.classesList // ProtoBuf classes
protoClasses.forEach { protoClass -> protoClasses.forEach { protoClass ->
val classKind = Flags.CLASS_KIND.get(protoClass.flags) val classKind = Flags.CLASS_KIND.get(protoClass.flags)
if (protoClass.hasTypeTable()) typeTable = protoClass.typeTable
when (classKind) { when (classKind) {
ProtoBuf.Class.Kind.CLASS -> printClass(protoClass) ProtoBuf.Class.Kind.CLASS -> printClass(protoClass)
ProtoBuf.Class.Kind.ENUM_CLASS -> printEnum(protoClass) ProtoBuf.Class.Kind.ENUM_CLASS -> printEnum(protoClass)
@@ -75,8 +78,6 @@ class PackageFragmentPrinter(val packageFragment: KonanLinkData.PackageFragment,
val protoFunctions = packageFragment.`package`.functionList val protoFunctions = packageFragment.`package`.functionList
protoFunctions.forEach { protoFunction -> protoFunctions.forEach { protoFunction ->
if (protoFunction.hasTypeTable()) typeTable = protoFunction.typeTable
else typeTable = packageFragment.`package`.typeTable
printFunction(protoFunction) printFunction(protoFunction)
} }
@@ -97,6 +98,8 @@ class PackageFragmentPrinter(val packageFragment: KonanLinkData.PackageFragment,
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
fun printClass(protoClass: ProtoBuf.Class) { fun printClass(protoClass: ProtoBuf.Class) {
val hasTypeTable = protoClass.hasTypeTable()
if (hasTypeTable) typeTableStack.add(protoClass.typeTable)
val className = getShortName(protoClass.fqName) val className = getShortName(protoClass.fqName)
val annotations = protoClass.getExtension(KonanSerializerProtocol.classAnnotation) val annotations = protoClass.getExtension(KonanSerializerProtocol.classAnnotation)
val keyword = classOrInterface(protoClass) val keyword = classOrInterface(protoClass)
@@ -120,11 +123,14 @@ class PackageFragmentPrinter(val packageFragment: KonanLinkData.PackageFragment,
nestedClasses.forEach { printNestedClass(it) } nestedClasses.forEach { printNestedClass(it) }
printer.popIndent() printer.popIndent()
printer.println("}\n") printer.println("}\n")
if (hasTypeTable) typeTableStack.removeAt(typeTableStack.lastIndex)
} }
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
fun printFunction(protoFunction: ProtoBuf.Function) { fun printFunction(protoFunction: ProtoBuf.Function) {
val hasTypeTable = protoFunction.hasTypeTable()
if (hasTypeTable) typeTableStack.add(protoFunction.typeTable)
val flags = protoFunction.flags val flags = protoFunction.flags
val name = stringTable.getString(protoFunction.name) val name = stringTable.getString(protoFunction.name)
val visibility = visibilityToString(Flags.VISIBILITY.get(flags)) val visibility = visibilityToString(Flags.VISIBILITY.get(flags))
@@ -133,10 +139,11 @@ class PackageFragmentPrinter(val packageFragment: KonanLinkData.PackageFragment,
val annotations = protoFunction.getExtension(KonanSerializerProtocol.functionAnnotation) val annotations = protoFunction.getExtension(KonanSerializerProtocol.functionAnnotation)
val typeParameters = typeParametersToString(protoFunction.typeParameterList) val typeParameters = typeParametersToString(protoFunction.typeParameterList)
val valueParameters = valueParametersToString(protoFunction.valueParameterList) val valueParameters = valueParametersToString(protoFunction.valueParameterList)
val returnType = typeToString(protoFunction.returnTypeId) val returnType = returnTypeToString(protoFunction)
printAnnotations(annotations) printAnnotations(annotations)
printer.println("$visibility${isInline}fun $typeParameters$receiverType$name$valueParameters: $returnType") printer.println("$visibility${isInline}fun $typeParameters$receiverType$name$valueParameters$returnType")
if (hasTypeTable) typeTableStack.removeAt(typeTableStack.lastIndex)
} }
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
@@ -157,6 +164,8 @@ class PackageFragmentPrinter(val packageFragment: KonanLinkData.PackageFragment,
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
fun printEnum(protoEnum: ProtoBuf.Class) { fun printEnum(protoEnum: ProtoBuf.Class) {
val hasTypeTable = protoEnum.hasTypeTable()
if (hasTypeTable) typeTableStack.add(protoEnum.typeTable)
val flags = protoEnum.flags val flags = protoEnum.flags
val enumName = getShortName(protoEnum.fqName) val enumName = getShortName(protoEnum.fqName)
val modality = modalityToString(Flags.MODALITY.get(flags)) val modality = modalityToString(Flags.MODALITY.get(flags))
@@ -171,6 +180,7 @@ class PackageFragmentPrinter(val packageFragment: KonanLinkData.PackageFragment,
enumEntries.dropLast(1).forEach { printer.print(" ${enumEntryToString(it)},\n") } enumEntries.dropLast(1).forEach { printer.print(" ${enumEntryToString(it)},\n") }
enumEntries.lastOrNull()?.let { printer.print(" ${enumEntryToString(it)} \n") } enumEntries.lastOrNull()?.let { printer.print(" ${enumEntryToString(it)} \n") }
printer.println("}\n") printer.println("}\n")
if (hasTypeTable) typeTableStack.removeAt(typeTableStack.lastIndex)
} }
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
@@ -350,7 +360,10 @@ class PackageFragmentPrinter(val packageFragment: KonanLinkData.PackageFragment,
fun valueParameterToString(protoValueParameter: ProtoBuf.ValueParameter): String { fun valueParameterToString(protoValueParameter: ProtoBuf.ValueParameter): String {
val parameterName = stringTable.getString(protoValueParameter.name) val parameterName = stringTable.getString(protoValueParameter.name)
val type = typeToString(protoValueParameter.typeId) val typeId = protoValueParameter.typeId
val type = if (isCallableType(typeId)) callableTypeToString(typeId)
else typeToString(typeId)
val flags = protoValueParameter.flags val flags = protoValueParameter.flags
val isCrossInline = crossInlineToString(Flags.IS_CROSSINLINE.get(flags)) val isCrossInline = crossInlineToString(Flags.IS_CROSSINLINE.get(flags))
val visibility = visibilityToString(Flags.VISIBILITY.get(flags)) val visibility = visibilityToString(Flags.VISIBILITY.get(flags))
@@ -434,10 +447,9 @@ class PackageFragmentPrinter(val packageFragment: KonanLinkData.PackageFragment,
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
fun typeToString(typeId: Int): String { fun typeToString(typeId: Int): String {
val type = typeTable!!.getType(typeId) val type = typeTableStack.last().getType(typeId)
if (isCallableType(type)) return callableTypeToString(type)
val buff = StringBuilder(typeName(type)) val buff = StringBuilder(typeName(type))
val argumentList = type.argumentList val argumentList = type.argumentList
if (argumentList.isNotEmpty()) { if (argumentList.isNotEmpty()) {
buff.append("<") buff.append("<")
@@ -454,11 +466,15 @@ class PackageFragmentPrinter(val packageFragment: KonanLinkData.PackageFragment,
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
fun isCallableType(type: ProtoBuf.Type) = typeName(type).contains("Function") fun isCallableType(typeId: Int): Boolean {
val type = typeTableStack.last().getType(typeId)
return typeName(type).contains("Function")
}
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
fun callableTypeToString(callableType: ProtoBuf.Type): String { fun callableTypeToString(typeId: Int): String {
val callableType = typeTableStack.last().getType(typeId)
val buff = StringBuilder("(") val buff = StringBuilder("(")
val argumentTypes = callableType.argumentList.dropLast(1) val argumentTypes = callableType.argumentList.dropLast(1)
val returnType = callableType.argumentList.lastOrNull() val returnType = callableType.argumentList.lastOrNull()
@@ -536,6 +552,14 @@ class PackageFragmentPrinter(val packageFragment: KonanLinkData.PackageFragment,
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
fun returnTypeToString(protoFunction: ProtoBuf.Function): String {
val returnType = typeToString(protoFunction.returnTypeId)
if (returnType == "Unit") return ""
return ": " + returnType
}
//-------------------------------------------------------------------------//
fun classOrInterface(protoClass: ProtoBuf.Class): String { fun classOrInterface(protoClass: ProtoBuf.Class): String {
val flags = protoClass.flags val flags = protoClass.flags
val classKind = Flags.CLASS_KIND.get(flags) val classKind = Flags.CLASS_KIND.get(flags)