mirror of
https://github.com/github/codeql.git
synced 2025-12-17 09:13:20 +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
|
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 {
|
fun useSimpleType(s: IrSimpleType, canReturnPrimitiveTypes: Boolean): TypeResults {
|
||||||
// We use this when we don't actually have an IrClass for a class
|
// We use this when we don't actually have an IrClass for a class
|
||||||
// we want to refer to
|
// we want to refer to
|
||||||
@@ -514,28 +539,7 @@ class X {
|
|||||||
val classifier: IrClassifierSymbol = s.classifier
|
val classifier: IrClassifierSymbol = s.classifier
|
||||||
val cls: IrClass = classifier.owner as IrClass
|
val cls: IrClass = classifier.owner as IrClass
|
||||||
|
|
||||||
val classInstanceResult = useClassInstance(cls, s.arguments)
|
return useSimpleTypeClass(cls, s.arguments, s.hasQuestionMark)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
s.classifier.owner is IrTypeParameter -> {
|
s.classifier.owner is IrTypeParameter -> {
|
||||||
val javaId = useTypeParameter(s.classifier.owner as IrTypeParameter)
|
val javaId = useTypeParameter(s.classifier.owner as IrTypeParameter)
|
||||||
@@ -1006,8 +1010,8 @@ open class KotlinFileExtractor(
|
|||||||
} else {
|
} else {
|
||||||
val id = useProperty(p)
|
val id = useProperty(p)
|
||||||
val locId = tw.getLocation(p)
|
val locId = tw.getLocation(p)
|
||||||
val typeId = useTypeOld(bf.type)
|
val type = useType(bf.type)
|
||||||
tw.writeFields(id, p.name.asString(), typeId, parentId, id)
|
tw.writeFields(id, p.name.asString(), type.javaResult.id, type.kotlinResult.id, parentId, id)
|
||||||
tw.writeHasLocation(id, locId)
|
tw.writeHasLocation(id, locId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1015,9 +1019,17 @@ open class KotlinFileExtractor(
|
|||||||
fun extractEnumEntry(ee: IrEnumEntry, parentId: Label<out DbReftype>) {
|
fun extractEnumEntry(ee: IrEnumEntry, parentId: Label<out DbReftype>) {
|
||||||
val id = useEnumEntry(ee)
|
val id = useEnumEntry(ee)
|
||||||
val locId = tw.getLocation(ee)
|
val locId = tw.getLocation(ee)
|
||||||
tw.writeFields(id, ee.name.asString(), parentId, parentId, id)
|
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)
|
tw.writeHasLocation(id, locId)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun extractBody(b: IrBody, callable: Label<out DbCallable>) {
|
fun extractBody(b: IrBody, callable: Label<out DbCallable>) {
|
||||||
when(b) {
|
when(b) {
|
||||||
|
|||||||
@@ -353,6 +353,7 @@ fields(
|
|||||||
unique int id: @field,
|
unique int id: @field,
|
||||||
string nodeName: string ref,
|
string nodeName: string ref,
|
||||||
int typeid: @type ref,
|
int typeid: @type ref,
|
||||||
|
int kttypeid: @kt_type ref,
|
||||||
int parentid: @reftype ref,
|
int parentid: @reftype ref,
|
||||||
int sourceid: @field ref
|
int sourceid: @field ref
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ predicate hasName(Element e, string name) {
|
|||||||
or
|
or
|
||||||
methods(e, name, _, _, _, _)
|
methods(e, name, _, _, _, _)
|
||||||
or
|
or
|
||||||
fields(e, name, _, _, _)
|
fields(e, name, _, _, _, _)
|
||||||
or
|
or
|
||||||
packages(e, name)
|
packages(e, name)
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ private predicate hasChildElement(Element parent, Element e) {
|
|||||||
or
|
or
|
||||||
params(e, _, _, parent, _)
|
params(e, _, _, parent, _)
|
||||||
or
|
or
|
||||||
fields(e, _, _, parent, _)
|
fields(e, _, _, _, parent, _)
|
||||||
or
|
or
|
||||||
typeVars(e, _, _, _, parent)
|
typeVars(e, _, _, _, parent)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -598,10 +598,13 @@ class FieldDeclaration extends ExprParent, @fielddecl, Annotatable {
|
|||||||
/** A class or instance field. */
|
/** A class or instance field. */
|
||||||
class Field extends Member, ExprParent, @field, Variable {
|
class Field extends Member, ExprParent, @field, Variable {
|
||||||
/** Gets the declared type of this field. */
|
/** 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. */
|
/** 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.
|
* 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.
|
* 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. */
|
/** Holds if this field is the same as its source declaration. */
|
||||||
predicate isSourceDeclaration() { this.getSourceDeclaration() = this }
|
predicate isSourceDeclaration() { this.getSourceDeclaration() = this }
|
||||||
|
|||||||
@@ -319,7 +319,7 @@ predicate declaresMember(Type t, @member m) {
|
|||||||
or
|
or
|
||||||
constrs(m, _, _, _, t, _)
|
constrs(m, _, _, _, t, _)
|
||||||
or
|
or
|
||||||
fields(m, _, _, t, _)
|
fields(m, _, _, _, t, _)
|
||||||
or
|
or
|
||||||
enclInReftype(m, t) and
|
enclInReftype(m, t) and
|
||||||
// Since the type `@member` in the dbscheme includes all `@reftype`s,
|
// 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. */
|
/** Gets the enum constant with the specified name. */
|
||||||
EnumConstant getEnumConstant(string 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. */
|
/** Gets an enum constant declared in this enum type. */
|
||||||
EnumConstant getAnEnumConstant() { fields(result, _, _, this, _) }
|
EnumConstant getAnEnumConstant() { fields(result, _, _, _, this, _) }
|
||||||
|
|
||||||
override predicate isFinal() {
|
override predicate isFinal() {
|
||||||
// JLS 8.9: An enum declaration is implicitly `final` unless it contains
|
// JLS 8.9: An enum declaration is implicitly `final` unless it contains
|
||||||
|
|||||||
Reference in New Issue
Block a user