mirror of
https://github.com/github/codeql.git
synced 2026-07-20 18:58:36 +02:00
Merge pull request #12111 from smowton/smowton/feature/java-merge-classes-and-interfaces
Java: merge the @class and @interface database types and tables
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
class ClassOrInterface extends @classorinterface {
|
||||
string toString() { result = "class-or-interface" }
|
||||
}
|
||||
|
||||
class Package extends @package {
|
||||
string toString() { result = "package" }
|
||||
}
|
||||
|
||||
from ClassOrInterface id, string nodeName, Package parentId, ClassOrInterface sourceId
|
||||
where classes_or_interfaces(id, nodeName, parentId, sourceId) and not isInterface(id)
|
||||
select id, nodeName, parentId, sourceId
|
||||
@@ -0,0 +1,11 @@
|
||||
class ClassOrInterface extends @classorinterface {
|
||||
string toString() { result = "class-or-interface" }
|
||||
}
|
||||
|
||||
class Package extends @package {
|
||||
string toString() { result = "package" }
|
||||
}
|
||||
|
||||
from ClassOrInterface id, string nodeName, Package parentId, ClassOrInterface sourceId
|
||||
where classes_or_interfaces(id, nodeName, parentId, sourceId) and isInterface(id)
|
||||
select id, nodeName, parentId, sourceId
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
description: Seperate class and interface tables
|
||||
compatibility: full
|
||||
classes.rel: run classes.qlo
|
||||
interfaces.rel: run interfaces.qlo
|
||||
isInterface.rel: delete
|
||||
classes_or_interfaces.rel: delete
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -346,26 +346,26 @@ error_type(
|
||||
unique int id: @errortype
|
||||
);
|
||||
|
||||
classes(
|
||||
unique int id: @class,
|
||||
classes_or_interfaces(
|
||||
unique int id: @classorinterface,
|
||||
string nodeName: string ref,
|
||||
int parentid: @package ref,
|
||||
int sourceid: @class ref
|
||||
int sourceid: @classorinterface ref
|
||||
);
|
||||
|
||||
file_class(
|
||||
int id: @class ref
|
||||
int id: @classorinterface ref
|
||||
);
|
||||
|
||||
class_object(
|
||||
unique int id: @class ref,
|
||||
unique int id: @classorinterface ref,
|
||||
unique int instance: @field ref
|
||||
);
|
||||
|
||||
type_companion_object(
|
||||
unique int id: @classorinterface ref,
|
||||
unique int instance: @field ref,
|
||||
unique int companion_object: @class ref
|
||||
unique int companion_object: @classorinterface ref
|
||||
);
|
||||
|
||||
kt_nullable_types(
|
||||
@@ -386,15 +386,12 @@ kt_type_alias(
|
||||
|
||||
@kt_type = @kt_nullable_type | @kt_notnull_type
|
||||
|
||||
isRecord(
|
||||
unique int id: @class ref
|
||||
isInterface(
|
||||
unique int id: @classorinterface ref
|
||||
);
|
||||
|
||||
interfaces(
|
||||
unique int id: @interface,
|
||||
string nodeName: string ref,
|
||||
int parentid: @package ref,
|
||||
int sourceid: @interface ref
|
||||
isRecord(
|
||||
unique int id: @classorinterface ref
|
||||
);
|
||||
|
||||
fielddecls(
|
||||
@@ -480,7 +477,7 @@ exceptions(
|
||||
);
|
||||
|
||||
isAnnotType(
|
||||
int interfaceid: @interface ref
|
||||
int interfaceid: @classorinterface ref
|
||||
);
|
||||
|
||||
isAnnotElem(
|
||||
@@ -494,7 +491,7 @@ annotValue(
|
||||
);
|
||||
|
||||
isEnumType(
|
||||
int classid: @class ref
|
||||
int classid: @classorinterface ref
|
||||
);
|
||||
|
||||
isEnumConst(
|
||||
@@ -546,7 +543,7 @@ erasure(
|
||||
|
||||
#keyset[classid] #keyset[parent]
|
||||
isAnonymClass(
|
||||
int classid: @class ref,
|
||||
int classid: @classorinterface ref,
|
||||
int parent: @classinstancexpr ref
|
||||
);
|
||||
|
||||
@@ -586,7 +583,7 @@ extendsReftype(
|
||||
|
||||
implInterface(
|
||||
int id1: @classorarray ref,
|
||||
int id2: @interface ref
|
||||
int id2: @classorinterface ref
|
||||
);
|
||||
|
||||
permits(
|
||||
@@ -868,7 +865,7 @@ propertyRefSetBinding(
|
||||
int setter: @callable ref
|
||||
);
|
||||
|
||||
@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable;
|
||||
@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable;
|
||||
|
||||
variableBinding(
|
||||
unique int expr: @varaccess ref,
|
||||
@@ -1022,12 +1019,11 @@ javadocText(
|
||||
@javadocParent = @javadoc | @javadocTag;
|
||||
@javadocElement = @javadocTag | @javadocText;
|
||||
|
||||
@classorinterface = @interface | @class;
|
||||
@classorinterfaceorpackage = @classorinterface | @package;
|
||||
@classorinterfaceorcallable = @classorinterface | @callable;
|
||||
@boundedtype = @typevariable | @wildcard;
|
||||
@reftype = @classorinterface | @array | @boundedtype | @errortype;
|
||||
@classorarray = @class | @array;
|
||||
@classorarray = @classorinterface | @array;
|
||||
@type = @primitive | @reftype;
|
||||
@callable = @method | @constructor;
|
||||
|
||||
@@ -1035,13 +1031,13 @@ javadocText(
|
||||
@element = @package | @modifier | @annotation | @errortype |
|
||||
@locatableElement;
|
||||
|
||||
@locatableElement = @file | @primitive | @class | @interface | @method | @constructor | @param | @exception | @field |
|
||||
@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field |
|
||||
@boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias |
|
||||
@kt_property;
|
||||
|
||||
@modifiable = @member_modifiable| @param | @localvar | @typevariable;
|
||||
|
||||
@member_modifiable = @class | @interface | @method | @constructor | @field | @kt_property;
|
||||
@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property;
|
||||
|
||||
@member = @method | @constructor | @field | @reftype ;
|
||||
|
||||
@@ -1242,5 +1238,5 @@ ktFunctionOriginalNames(
|
||||
)
|
||||
|
||||
ktDataClasses(
|
||||
unique int id: @class ref
|
||||
unique int id: @classorinterface ref
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,9 +10,7 @@ private import semmle.code.SMAP
|
||||
|
||||
/** Holds if element `e` has name `name`. */
|
||||
predicate hasName(Element e, string name) {
|
||||
classes(e, name, _, _)
|
||||
or
|
||||
interfaces(e, name, _, _)
|
||||
classes_or_interfaces(e, name, _, _)
|
||||
or
|
||||
primitives(e, name)
|
||||
or
|
||||
|
||||
@@ -397,14 +397,21 @@ private predicate potentialInterfaceImplementationWithSignature(string sig, RefT
|
||||
not t.isAbstract()
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate implementsInterfaceMethod(SrcMethod impl, SrcMethod m) {
|
||||
exists(RefType t, Interface i, Method minst, Method implinst |
|
||||
m = minst.getSourceDeclaration() and
|
||||
pragma[noinline]
|
||||
private predicate isInterfaceSourceImplementation(Method minst, RefType t) {
|
||||
exists(Interface i |
|
||||
i = minst.getDeclaringType() and
|
||||
t.extendsOrImplements+(i) and
|
||||
t.isSourceDeclaration() and
|
||||
t.isSourceDeclaration()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate implementsInterfaceMethod(SrcMethod impl, SrcMethod m) {
|
||||
exists(RefType t, Method minst, Method implinst |
|
||||
isInterfaceSourceImplementation(minst, t) and
|
||||
potentialInterfaceImplementationWithSignature(minst.getSignature(), t, implinst) and
|
||||
m = minst.getSourceDeclaration() and
|
||||
impl = implinst.getSourceDeclaration()
|
||||
)
|
||||
}
|
||||
@@ -542,7 +549,7 @@ class Method extends Callable, @method {
|
||||
|
||||
/** A method that is the same as its source declaration. */
|
||||
class SrcMethod extends Method {
|
||||
SrcMethod() { methods(_, _, _, _, _, this) }
|
||||
SrcMethod() { methods(this, _, _, _, _, this) }
|
||||
|
||||
/**
|
||||
* All the methods that could possibly be called when this method
|
||||
|
||||
@@ -385,10 +385,7 @@ class Array extends RefType, @array {
|
||||
*/
|
||||
class RefType extends Type, Annotatable, Modifiable, @reftype {
|
||||
/** Gets the package in which this type is declared. */
|
||||
Package getPackage() {
|
||||
classes(this, _, result, _) or
|
||||
interfaces(this, _, result, _)
|
||||
}
|
||||
Package getPackage() { classes_or_interfaces(this, _, result, _) }
|
||||
|
||||
/** Gets the type in which this reference type is enclosed, if any. */
|
||||
RefType getEnclosingType() { enclInReftype(this, result) }
|
||||
@@ -685,12 +682,12 @@ class SrcRefType extends RefType {
|
||||
}
|
||||
|
||||
/** A class declaration. */
|
||||
class Class extends ClassOrInterface, @class {
|
||||
class Class extends ClassOrInterface {
|
||||
Class() { not isInterface(this) }
|
||||
|
||||
/** Holds if this class is an anonymous class. */
|
||||
predicate isAnonymous() { isAnonymClass(this.getSourceDeclaration(), _) }
|
||||
|
||||
override RefType getSourceDeclaration() { classes(this, _, _, result) }
|
||||
|
||||
/**
|
||||
* Gets an annotation that applies to this class.
|
||||
*
|
||||
@@ -742,10 +739,10 @@ class Record extends Class {
|
||||
}
|
||||
|
||||
/** An intersection type. */
|
||||
class IntersectionType extends RefType, @class {
|
||||
class IntersectionType extends RefType, @classorinterface {
|
||||
IntersectionType() {
|
||||
exists(string shortname |
|
||||
classes(this, shortname, _, _) and
|
||||
classes_or_interfaces(this, shortname, _, _) and
|
||||
shortname.matches("% & ...")
|
||||
)
|
||||
}
|
||||
@@ -842,7 +839,7 @@ class LocalClass extends LocalClassOrInterface, NestedClass {
|
||||
class TopLevelType extends RefType {
|
||||
TopLevelType() {
|
||||
not enclInReftype(this, _) and
|
||||
(this instanceof Class or this instanceof Interface)
|
||||
this instanceof ClassOrInterface
|
||||
}
|
||||
}
|
||||
|
||||
@@ -940,8 +937,8 @@ class InnerClass extends NestedClass {
|
||||
}
|
||||
|
||||
/** An interface. */
|
||||
class Interface extends ClassOrInterface, @interface {
|
||||
override RefType getSourceDeclaration() { interfaces(this, _, _, result) }
|
||||
class Interface extends ClassOrInterface {
|
||||
Interface() { isInterface(this) }
|
||||
|
||||
override predicate isAbstract() {
|
||||
// JLS 9.1.1.1: "Every interface is implicitly abstract"
|
||||
@@ -953,6 +950,8 @@ class Interface extends ClassOrInterface, @interface {
|
||||
|
||||
/** A class or interface. */
|
||||
class ClassOrInterface extends RefType, @classorinterface {
|
||||
override RefType getSourceDeclaration() { classes_or_interfaces(this, _, _, result) }
|
||||
|
||||
/** Holds if this class or interface is local. */
|
||||
predicate isLocal() { isLocalClassOrInterface(this.getSourceDeclaration(), _) }
|
||||
|
||||
|
||||
@@ -681,9 +681,14 @@ private predicate unionTypeFlow0(TypeFlowNode n, RefType t, boolean exact) {
|
||||
private predicate unionTypeFlow(TypeFlowNode n, RefType t, boolean exact) {
|
||||
unionTypeFlow0(n, t, exact) and
|
||||
// filter impossible union parts:
|
||||
if exact = true
|
||||
then t.getErasure().(RefType).getASourceSupertype*() = getTypeBound(n).getErasure()
|
||||
else haveIntersection(getTypeBound(n), t)
|
||||
exists(RefType tErased, RefType boundErased |
|
||||
pragma[only_bind_into](tErased) = t.getErasure() and
|
||||
pragma[only_bind_into](boundErased) = getTypeBound(n).getErasure()
|
||||
|
|
||||
if exact = true
|
||||
then tErased.getASourceSupertype*() = boundErased
|
||||
else erasedHaveIntersection(tErased, boundErased)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,6 +22,17 @@ module MkUnification<unificationTarget/1 targetLeft, unificationTarget/1 targetR
|
||||
targetRight(t2) and t2.getGenericType() = g
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate unificationTargetsWithCommonSourceDecl(
|
||||
ParameterizedType pt1, ParameterizedType pt2
|
||||
) {
|
||||
exists(RefType commonSourceDecl |
|
||||
unificationTargets(pt1, pt2) and
|
||||
pragma[only_bind_out](pt1).getSourceDeclaration() = pragma[only_bind_out](commonSourceDecl) and
|
||||
pragma[only_bind_out](pt2).getSourceDeclaration() = commonSourceDecl
|
||||
)
|
||||
}
|
||||
|
||||
private predicate unificationTargets(Type t1, Type t2) {
|
||||
exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g))
|
||||
or
|
||||
@@ -32,10 +43,9 @@ module MkUnification<unificationTarget/1 targetLeft, unificationTarget/1 targetR
|
||||
)
|
||||
or
|
||||
exists(ParameterizedType pt1, ParameterizedType pt2, int pos |
|
||||
unificationTargets(pt1, pt2) and
|
||||
not pt1.getSourceDeclaration() != pt2.getSourceDeclaration() and
|
||||
t1 = pt1.getTypeArgument(pos) and
|
||||
t2 = pt2.getTypeArgument(pos)
|
||||
unificationTargetsWithCommonSourceDecl(pt1, pt2) and
|
||||
t1 = pt1.getTypeArgument(pragma[only_bind_into](pos)) and
|
||||
t2 = pt2.getTypeArgument(pragma[only_bind_into](pos))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -44,8 +54,8 @@ module MkUnification<unificationTarget/1 targetLeft, unificationTarget/1 targetR
|
||||
ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2
|
||||
) {
|
||||
unificationTargets(t1, t2) and
|
||||
arg1 = t1.getTypeArgument(pos) and
|
||||
arg2 = t2.getTypeArgument(pos)
|
||||
arg1 = t1.getTypeArgument(pragma[only_bind_into](pos)) and
|
||||
arg2 = t2.getTypeArgument(pragma[only_bind_into](pos))
|
||||
}
|
||||
|
||||
private RefType getUpperBound(RefType t) {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
class ClassOrInterface extends @classorinterface {
|
||||
string toString() { result = "class-or-interface" }
|
||||
}
|
||||
|
||||
class Package extends @package {
|
||||
string toString() { result = "package" }
|
||||
}
|
||||
|
||||
from ClassOrInterface id, string nodeName, Package parentId, ClassOrInterface sourceId
|
||||
where classes(id, nodeName, parentId, sourceId) or interfaces(id, nodeName, parentId, sourceId)
|
||||
select id, nodeName, parentId, sourceId
|
||||
@@ -0,0 +1,6 @@
|
||||
class Interface extends @interface {
|
||||
string toString() { result = "interface" }
|
||||
}
|
||||
|
||||
from Interface i
|
||||
select i
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
description: Merge class and interface tables
|
||||
compatibility: full
|
||||
classes_or_interfaces.rel: run classes_or_interfaces.qlo
|
||||
isInterface.rel: run isInterface.qlo
|
||||
classes.rel: delete
|
||||
interfaces.rel: delete
|
||||
@@ -515,7 +515,7 @@ private RefType getAReferencedType(RefType t) {
|
||||
|
||||
/** A top level type whose file should be stubbed */
|
||||
class GeneratedTopLevel extends TopLevelType instanceof GeneratedType {
|
||||
GeneratedTopLevel() { this = this.getSourceDeclaration() }
|
||||
GeneratedTopLevel() { this = this.(ClassOrInterface).getSourceDeclaration() }
|
||||
|
||||
private TopLevelType getAnImportedType() {
|
||||
result = getAReferencedType(this).getSourceDeclaration() and
|
||||
@@ -523,9 +523,8 @@ class GeneratedTopLevel extends TopLevelType instanceof GeneratedType {
|
||||
}
|
||||
|
||||
private string stubAnImport() {
|
||||
exists(RefType t, string pkg, string name |
|
||||
exists(ClassOrInterface t, string pkg, string name |
|
||||
t = this.getAnImportedType() and
|
||||
(t instanceof Class or t instanceof Interface) and
|
||||
t.hasQualifiedName(pkg, name) and
|
||||
t != this and
|
||||
pkg != "java.lang"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import java
|
||||
|
||||
@class clasz() { any() }
|
||||
@classorinterface clasz() { any() }
|
||||
|
||||
select clasz()
|
||||
|
||||
Reference in New Issue
Block a user