mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Kotlin: Give fields a Kotlin type
This meant refactoring the EnumEntry extraction a bit. The IR doesn't give us a type for fields, so we have to make it up based on the parent.
This commit is contained in:
@@ -389,6 +389,31 @@ open class KotlinUsesExtractor(
|
||||
return id
|
||||
}
|
||||
|
||||
fun useSimpleTypeClass(c: IrClass, args: List<IrTypeArgument>, hasQuestionMark: Boolean): TypeResults {
|
||||
val classInstanceResult = useClassInstance(c, args)
|
||||
val javaClassId = classInstanceResult.classLabel
|
||||
val kotlinQualClassName = getUnquotedClassLabel(c, args)
|
||||
val javaQualClassName = classInstanceResult.javaClass.fqNameForIrSerialization.asString()
|
||||
val javaSignature = javaQualClassName // TODO: Is this right?
|
||||
val javaResult = TypeResult(javaClassId, javaSignature)
|
||||
val kotlinResult = if (hasQuestionMark) {
|
||||
val kotlinSignature = "$kotlinQualClassName?" // TODO: Is this right?
|
||||
val kotlinLabel = "@\"kt_type;nullable;$kotlinQualClassName\""
|
||||
val kotlinId: Label<DbKt_nullable_type> = tw.getLabelFor(kotlinLabel, {
|
||||
tw.writeKt_nullable_types(it, javaClassId)
|
||||
})
|
||||
TypeResult(kotlinId, kotlinSignature)
|
||||
} else {
|
||||
val kotlinSignature = kotlinQualClassName // TODO: Is this right?
|
||||
val kotlinLabel = "@\"kt_type;notnull;$kotlinQualClassName\""
|
||||
val kotlinId: Label<DbKt_notnull_type> = tw.getLabelFor(kotlinLabel, {
|
||||
tw.writeKt_notnull_types(it, javaClassId)
|
||||
})
|
||||
TypeResult(kotlinId, kotlinSignature)
|
||||
}
|
||||
return TypeResults(javaResult, kotlinResult)
|
||||
}
|
||||
|
||||
fun useSimpleType(s: IrSimpleType, canReturnPrimitiveTypes: Boolean): TypeResults {
|
||||
// We use this when we don't actually have an IrClass for a class
|
||||
// we want to refer to
|
||||
@@ -514,28 +539,7 @@ class X {
|
||||
val classifier: IrClassifierSymbol = s.classifier
|
||||
val cls: IrClass = classifier.owner as IrClass
|
||||
|
||||
val classInstanceResult = useClassInstance(cls, s.arguments)
|
||||
val javaClassId = classInstanceResult.classLabel
|
||||
val kotlinQualClassName = getUnquotedClassLabel(cls, s.arguments)
|
||||
val javaQualClassName = classInstanceResult.javaClass.fqNameForIrSerialization.asString()
|
||||
val javaSignature = javaQualClassName // TODO: Is this right?
|
||||
val javaResult = TypeResult(javaClassId, javaSignature)
|
||||
val kotlinResult = if (s.hasQuestionMark) {
|
||||
val kotlinSignature = "$kotlinQualClassName?" // TODO: Is this right?
|
||||
val kotlinLabel = "@\"kt_type;nullable;$kotlinQualClassName\""
|
||||
val kotlinId: Label<DbKt_nullable_type> = tw.getLabelFor(kotlinLabel, {
|
||||
tw.writeKt_nullable_types(it, javaClassId)
|
||||
})
|
||||
TypeResult(kotlinId, kotlinSignature)
|
||||
} else {
|
||||
val kotlinSignature = kotlinQualClassName // TODO: Is this right?
|
||||
val kotlinLabel = "@\"kt_type;notnull;$kotlinQualClassName\""
|
||||
val kotlinId: Label<DbKt_notnull_type> = tw.getLabelFor(kotlinLabel, {
|
||||
tw.writeKt_notnull_types(it, javaClassId)
|
||||
})
|
||||
TypeResult(kotlinId, kotlinSignature)
|
||||
}
|
||||
return TypeResults(javaResult, kotlinResult)
|
||||
return useSimpleTypeClass(cls, s.arguments, s.hasQuestionMark)
|
||||
}
|
||||
s.classifier.owner is IrTypeParameter -> {
|
||||
val javaId = useTypeParameter(s.classifier.owner as IrTypeParameter)
|
||||
@@ -1006,8 +1010,8 @@ open class KotlinFileExtractor(
|
||||
} else {
|
||||
val id = useProperty(p)
|
||||
val locId = tw.getLocation(p)
|
||||
val typeId = useTypeOld(bf.type)
|
||||
tw.writeFields(id, p.name.asString(), typeId, parentId, id)
|
||||
val type = useType(bf.type)
|
||||
tw.writeFields(id, p.name.asString(), type.javaResult.id, type.kotlinResult.id, parentId, id)
|
||||
tw.writeHasLocation(id, locId)
|
||||
}
|
||||
}
|
||||
@@ -1015,8 +1019,16 @@ open class KotlinFileExtractor(
|
||||
fun extractEnumEntry(ee: IrEnumEntry, parentId: Label<out DbReftype>) {
|
||||
val id = useEnumEntry(ee)
|
||||
val locId = tw.getLocation(ee)
|
||||
tw.writeFields(id, ee.name.asString(), parentId, parentId, id)
|
||||
tw.writeHasLocation(id, locId)
|
||||
val parent = ee.parent
|
||||
if(parent !is IrClass) {
|
||||
logger.warnElement(Severity.ErrorSevere, "Enum entry with unexpected parent: " + parent.javaClass, ee)
|
||||
} else if (!parent.typeParameters.isEmpty()) {
|
||||
logger.warnElement(Severity.ErrorSevere, "Enum entry parent class has type parameters: " + parent.name, ee)
|
||||
} else {
|
||||
val type = useSimpleTypeClass(parent, emptyList(), false)
|
||||
tw.writeFields(id, ee.name.asString(), type.javaResult.id, type.kotlinResult.id, parentId, id)
|
||||
tw.writeHasLocation(id, locId)
|
||||
}
|
||||
}
|
||||
|
||||
fun extractBody(b: IrBody, callable: Label<out DbCallable>) {
|
||||
|
||||
@@ -353,6 +353,7 @@ fields(
|
||||
unique int id: @field,
|
||||
string nodeName: string ref,
|
||||
int typeid: @type ref,
|
||||
int kttypeid: @kt_type ref,
|
||||
int parentid: @reftype ref,
|
||||
int sourceid: @field ref
|
||||
);
|
||||
|
||||
@@ -20,7 +20,7 @@ predicate hasName(Element e, string name) {
|
||||
or
|
||||
methods(e, name, _, _, _, _)
|
||||
or
|
||||
fields(e, name, _, _, _)
|
||||
fields(e, name, _, _, _, _)
|
||||
or
|
||||
packages(e, name)
|
||||
or
|
||||
|
||||
@@ -63,7 +63,7 @@ private predicate hasChildElement(Element parent, Element e) {
|
||||
or
|
||||
params(e, _, _, parent, _)
|
||||
or
|
||||
fields(e, _, _, parent, _)
|
||||
fields(e, _, _, _, parent, _)
|
||||
or
|
||||
typeVars(e, _, _, _, parent)
|
||||
}
|
||||
|
||||
@@ -598,10 +598,13 @@ class FieldDeclaration extends ExprParent, @fielddecl, Annotatable {
|
||||
/** A class or instance field. */
|
||||
class Field extends Member, ExprParent, @field, Variable {
|
||||
/** Gets the declared type of this field. */
|
||||
override Type getType() { fields(this, _, result, _, _) }
|
||||
override Type getType() { fields(this, _, result, _, _, _) }
|
||||
|
||||
/** Gets the Kotlin type of this field. */
|
||||
KotlinType getKotlinType() { fields(this, _, _, result, _, _) }
|
||||
|
||||
/** Gets the type in which this field is declared. */
|
||||
override RefType getDeclaringType() { fields(this, _, _, result, _) }
|
||||
override RefType getDeclaringType() { fields(this, _, _, _, result, _) }
|
||||
|
||||
/**
|
||||
* Gets the field declaration in which this field is declared.
|
||||
@@ -631,7 +634,7 @@ class Field extends Member, ExprParent, @field, Variable {
|
||||
*
|
||||
* For all other fields, the source declaration is the field itself.
|
||||
*/
|
||||
Field getSourceDeclaration() { fields(this, _, _, _, result) }
|
||||
Field getSourceDeclaration() { fields(this, _, _, _, _, result) }
|
||||
|
||||
/** Holds if this field is the same as its source declaration. */
|
||||
predicate isSourceDeclaration() { this.getSourceDeclaration() = this }
|
||||
|
||||
@@ -319,7 +319,7 @@ predicate declaresMember(Type t, @member m) {
|
||||
or
|
||||
constrs(m, _, _, _, t, _)
|
||||
or
|
||||
fields(m, _, _, t, _)
|
||||
fields(m, _, _, _, t, _)
|
||||
or
|
||||
enclInReftype(m, t) and
|
||||
// Since the type `@member` in the dbscheme includes all `@reftype`s,
|
||||
@@ -1109,11 +1109,11 @@ class EnumType extends Class {
|
||||
|
||||
/** Gets the enum constant with the specified name. */
|
||||
EnumConstant getEnumConstant(string name) {
|
||||
fields(result, _, _, this, _) and result.hasName(name)
|
||||
fields(result, _, _, _, this, _) and result.hasName(name)
|
||||
}
|
||||
|
||||
/** Gets an enum constant declared in this enum type. */
|
||||
EnumConstant getAnEnumConstant() { fields(result, _, _, this, _) }
|
||||
EnumConstant getAnEnumConstant() { fields(result, _, _, _, this, _) }
|
||||
|
||||
override predicate isFinal() {
|
||||
// JLS 8.9: An enum declaration is implicitly `final` unless it contains
|
||||
|
||||
Reference in New Issue
Block a user