Java: merge the @class and @interface database types and tables

This will allow the extractor to emit class(id, ...) when all it knows about a class is its name, due to not having it available on the classpath. Previously it would have had to guess whether it belonged to @class or @interface, possibly introducing an inconsistency.
This commit is contained in:
Chris Smowton
2023-02-06 21:08:27 +00:00
parent 029e1d47fe
commit 3514dd1e4d
17 changed files with 31939 additions and 78 deletions

View File

@@ -351,18 +351,14 @@ open class KotlinFileExtractor(
val pkgId = extractPackage(pkg)
// TODO: There's lots of duplication between this and extractClassSource.
// Can we share it?
val sourceId = useClassSource(c)
tw.writeClasses_or_interfaces(id, cls, pkgId, sourceId)
if (c.isInterfaceLike) {
val interfaceId = id.cast<DbInterface>()
val sourceInterfaceId = useClassSource(c).cast<DbInterface>()
tw.writeInterfaces(interfaceId, cls, pkgId, sourceInterfaceId)
tw.writeIsInterface(id)
} else {
val classId = id.cast<DbClass>()
val sourceClassId = useClassSource(c).cast<DbClass>()
tw.writeClasses(classId, cls, pkgId, sourceClassId)
val kind = c.kind
if (kind == ClassKind.ENUM_CLASS) {
tw.writeIsEnumType(classId)
tw.writeIsEnumType(id)
} else if (kind != ClassKind.CLASS && kind != ClassKind.OBJECT && kind != ClassKind.ENUM_ENTRY) {
logger.errorElement("Unrecognised class kind $kind", c)
}
@@ -459,11 +455,11 @@ open class KotlinFileExtractor(
}
private fun extractLocalTypeDeclStmt(c: IrClass, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
val id = extractClassSource(c, extractDeclarations = true, extractStaticInitializer = true, extractPrivateMembers = true, extractFunctionBodies = true).cast<DbClass>()
val id = extractClassSource(c, extractDeclarations = true, extractStaticInitializer = true, extractPrivateMembers = true, extractFunctionBodies = true)
extractLocalTypeDeclStmt(id, c, callable, parent, idx)
}
private fun extractLocalTypeDeclStmt(id: Label<out DbClass>, locElement: IrElement, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
private fun extractLocalTypeDeclStmt(id: Label<out DbClassorinterface>, locElement: IrElement, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
val stmtId = tw.getFreshIdLabel<DbLocaltypedeclstmt>()
tw.writeStmts_localtypedeclstmt(stmtId, parent, idx, callable)
tw.writeIsLocalClassOrInterface(id, stmtId)
@@ -630,26 +626,22 @@ open class KotlinFileExtractor(
val pkg = c.packageFqName?.asString() ?: ""
val cls = if (c.isAnonymousObject) "" else c.name.asString()
val pkgId = extractPackage(pkg)
tw.writeClasses_or_interfaces(id, cls, pkgId, id)
if (c.isInterfaceLike) {
val interfaceId = id.cast<DbInterface>()
tw.writeInterfaces(interfaceId, cls, pkgId, interfaceId)
tw.writeIsInterface(id)
if (c.kind == ClassKind.ANNOTATION_CLASS) {
tw.writeIsAnnotType(interfaceId)
tw.writeIsAnnotType(id)
}
} else {
val classId = id.cast<DbClass>()
tw.writeClasses(classId, cls, pkgId, classId)
val kind = c.kind
if (kind == ClassKind.ENUM_CLASS) {
tw.writeIsEnumType(classId)
tw.writeIsEnumType(id)
} else if (kind != ClassKind.CLASS && kind != ClassKind.OBJECT && kind != ClassKind.ENUM_ENTRY) {
logger.warnElement("Unrecognised class kind $kind", c)
}
if (c.isData) {
tw.writeKtDataClasses(classId)
tw.writeKtDataClasses(id)
}
}
@@ -694,7 +686,7 @@ open class KotlinFileExtractor(
tw.writeFieldsKotlinType(instance.id, type.kotlinResult.id)
tw.writeHasLocation(instance.id, locId)
addModifiers(instance.id, "public", "static", "final")
tw.writeClass_object(id.cast<DbClass>(), instance.id)
tw.writeClass_object(id, instance.id)
}
if (c.isObject) {
addModifiers(id, "static")
@@ -830,7 +822,7 @@ open class KotlinFileExtractor(
tw.writeFieldsKotlinType(instance.id, type.kotlinResult.id)
tw.writeHasLocation(instance.id, innerLocId)
addModifiers(instance.id, "public", "static", "final")
tw.writeType_companion_object(parentId, instance.id, innerId.cast<DbClass>())
tw.writeType_companion_object(parentId, instance.id, innerId)
}
}
@@ -4448,7 +4440,7 @@ open class KotlinFileExtractor(
}
private open inner class GeneratedClassHelper(protected val locId: Label<DbLocation>, protected val ids: GeneratedClassLabels) {
protected val classId = ids.type.javaResult.id.cast<DbClass>()
protected val classId = ids.type.javaResult.id.cast<DbClassorinterface>()
/**
* Extract a parameter to field assignment, such as `this.field = paramName` below:
@@ -4788,7 +4780,7 @@ open class KotlinFileExtractor(
val locId = tw.getLocation(propertyReferenceExpr)
val javaResult = TypeResult(tw.getFreshIdLabel<DbClass>(), "", "")
val javaResult = TypeResult(tw.getFreshIdLabel<DbClassorinterface>(), "", "")
val kotlinResult = TypeResult(tw.getFreshIdLabel<DbKt_notnull_type>(), "", "")
tw.writeKt_notnull_types(kotlinResult.id, javaResult.id)
val ids = GeneratedClassLabels(
@@ -4980,7 +4972,7 @@ open class KotlinFileExtractor(
val locId = tw.getLocation(functionReferenceExpr)
val javaResult = TypeResult(tw.getFreshIdLabel<DbClass>(), "", "")
val javaResult = TypeResult(tw.getFreshIdLabel<DbClassorinterface>(), "", "")
val kotlinResult = TypeResult(tw.getFreshIdLabel<DbKt_notnull_type>(), "", "")
tw.writeKt_notnull_types(kotlinResult.id, javaResult.id)
val ids = LocallyVisibleFunctionLabels(
@@ -5550,7 +5542,7 @@ open class KotlinFileExtractor(
return
}
val javaResult = TypeResult(tw.getFreshIdLabel<DbClass>(), "", "")
val javaResult = TypeResult(tw.getFreshIdLabel<DbClassorinterface>(), "", "")
val kotlinResult = TypeResult(tw.getFreshIdLabel<DbKt_notnull_type>(), "", "")
tw.writeKt_notnull_types(kotlinResult.id, javaResult.id)
val ids = LocallyVisibleFunctionLabels(
@@ -5659,7 +5651,7 @@ open class KotlinFileExtractor(
val idNewexpr = extractNewExpr(ids.constructor, ids.type, locId, id, 1, callable, enclosingStmt)
tw.writeIsAnonymClass(ids.type.javaResult.id.cast<DbClass>(), idNewexpr)
tw.writeIsAnonymClass(ids.type.javaResult.id.cast<DbClassorinterface>(), idNewexpr)
extractTypeAccessRecursive(e.typeOperand, locId, idNewexpr, -3, callable, enclosingStmt)
@@ -5705,11 +5697,11 @@ open class KotlinFileExtractor(
compilerGeneratedKindOverride: CompilerGeneratedKinds? = null,
superConstructorSelector: (IrFunction) -> Boolean = { it.valueParameters.isEmpty() },
extractSuperconstructorArgs: (Label<DbSuperconstructorinvocationstmt>) -> Unit = {},
): Label<out DbClass> {
): Label<out DbClassorinterface> {
// Write class
val id = ids.type.javaResult.id.cast<DbClass>()
val id = ids.type.javaResult.id.cast<DbClassorinterface>()
val pkgId = extractPackage("")
tw.writeClasses(id, "", pkgId, id)
tw.writeClasses_or_interfaces(id, "", pkgId, id)
tw.writeCompiler_generated(id, (compilerGeneratedKindOverride ?: CompilerGeneratedKinds.CALLABLE_CLASS).kind)
tw.writeHasLocation(id, locId)
@@ -5761,7 +5753,7 @@ open class KotlinFileExtractor(
localFunction: IrFunction,
superTypes: List<IrType>,
compilerGeneratedKindOverride: CompilerGeneratedKinds? = null
) : Label<out DbClass> {
) : Label<out DbClassorinterface> {
with("generated class", localFunction) {
val ids = getLocallyVisibleFunctionLabels(localFunction)

View File

@@ -71,16 +71,16 @@ open class KotlinUsesExtractor(
TypeResult(fakeKotlinType(), "", "")
)
fun extractFileClass(f: IrFile): Label<out DbClass> {
fun extractFileClass(f: IrFile): Label<out DbClassorinterface> {
val pkg = f.fqName.asString()
val jvmName = getFileClassName(f)
val qualClassName = if (pkg.isEmpty()) jvmName else "$pkg.$jvmName"
val label = "@\"class;$qualClassName\""
val id: Label<DbClass> = tw.getLabelFor(label) {
val id: Label<DbClassorinterface> = tw.getLabelFor(label) {
val fileId = tw.mkFileId(f.path, false)
val locId = tw.getWholeFileLocation(fileId)
val pkgId = extractPackage(pkg)
tw.writeClasses(it, jvmName, pkgId, it)
tw.writeClasses_or_interfaces(it, jvmName, pkgId, it)
tw.writeFile_class(it)
tw.writeHasLocation(it, locId)
@@ -478,7 +478,7 @@ open class KotlinUsesExtractor(
private fun useAnonymousClass(c: IrClass) =
tw.lm.anonymousTypeMapping.getOrPut(c) {
TypeResults(
TypeResult(tw.getFreshIdLabel<DbClass>(), "", ""),
TypeResult(tw.getFreshIdLabel<DbClassorinterface>(), "", ""),
TypeResult(fakeKotlinType(), "TODO", "TODO")
)
}
@@ -487,8 +487,8 @@ open class KotlinUsesExtractor(
val fakeKotlinPackageId: Label<DbPackage> = tw.getLabelFor("@\"FakeKotlinPackage\"", {
tw.writePackages(it, "fake.kotlin")
})
val fakeKotlinClassId: Label<DbClass> = tw.getLabelFor("@\"FakeKotlinClass\"", {
tw.writeClasses(it, "FakeKotlinClass", fakeKotlinPackageId, it)
val fakeKotlinClassId: Label<DbClassorinterface> = tw.getLabelFor("@\"FakeKotlinClass\"", {
tw.writeClasses_or_interfaces(it, "FakeKotlinClass", fakeKotlinPackageId, it)
})
val fakeKotlinTypeId: Label<DbKt_nullable_type> = tw.getLabelFor("@\"FakeKotlinType\"", {
tw.writeKt_nullable_types(it, fakeKotlinClassId)
@@ -650,11 +650,11 @@ open class KotlinUsesExtractor(
// We use this when we don't actually have an IrClass for a class
// we want to refer to
// TODO: Eliminate the need for this if possible
fun makeClass(pkgName: String, className: String): Label<DbClass> {
fun makeClass(pkgName: String, className: String): Label<DbClassorinterface> {
val pkgId = extractPackage(pkgName)
val label = "@\"class;$pkgName.$className\""
val classId: Label<DbClass> = tw.getLabelFor(label, {
tw.writeClasses(it, className, pkgId, it)
val classId: Label<DbClassorinterface> = tw.getLabelFor(label, {
tw.writeClasses_or_interfaces(it, className, pkgId, it)
})
return classId
}
@@ -1237,7 +1237,7 @@ open class KotlinUsesExtractor(
var res = tw.lm.locallyVisibleFunctionLabelMapping[f]
if (res == null) {
val javaResult = TypeResult(tw.getFreshIdLabel<DbClass>(), "", "")
val javaResult = TypeResult(tw.getFreshIdLabel<DbClassorinterface>(), "", "")
val kotlinResult = TypeResult(tw.getFreshIdLabel<DbKt_notnull_type>(), "", "")
tw.writeKt_notnull_types(kotlinResult.id, javaResult.id)
res = LocallyVisibleFunctionLabels(