@@ -371,6 +371,19 @@ class TypeIsBothConstructedAndUnbound extends TypeViolation {
371371 override string getMessage ( ) { result = "Type is both constructed and unbound" }
372372}
373373
374+ /**
375+ * The location of a constructed generic type should be the same
376+ * as the location of its unbound generic type.
377+ */
378+ class InconsistentTypeLocation extends TypeViolation {
379+ InconsistentTypeLocation ( ) {
380+ exists ( this .getType ( ) .getLocation ( ) ) and
381+ this .getType ( ) .getLocation ( ) != this .getType ( ) .getSourceDeclaration ( ) .getLocation ( )
382+ }
383+
384+ override string getMessage ( ) { result = "Inconsistent constructed type location" }
385+ }
386+
374387/**
375388 * A constructed type that does not match its unbound generic type.
376389 */
@@ -403,6 +416,19 @@ class MethodViolation extends ConsistencyViolation, DeclarationCheck {
403416 override string getMessage ( ) { none ( ) }
404417}
405418
419+ /**
420+ * The location of a constructed method should be equal to the
421+ * location of its unbound generic.
422+ */
423+ class InconsistentMethodLocation extends MethodViolation {
424+ InconsistentMethodLocation ( ) {
425+ exists ( this .getMethod ( ) .getLocation ( ) ) and
426+ this .getMethod ( ) .getLocation ( ) != this .getMethod ( ) .getSourceDeclaration ( ) .getLocation ( )
427+ }
428+
429+ override string getMessage ( ) { result = "Inconsistent constructed method location" }
430+ }
431+
406432/**
407433 * A constructed method that does not match its unbound method.
408434 */
@@ -431,7 +457,10 @@ abstract class MissingEntityViolation extends ConsistencyViolation, MissingEntit
431457 * The type `object` is missing from the database.
432458 */
433459class MissingObjectViolation extends MissingEntityViolation {
434- MissingObjectViolation ( ) { not exists ( ObjectType o ) }
460+ MissingObjectViolation ( ) {
461+ exists ( this ) and
462+ not exists ( ObjectType o )
463+ }
435464
436465 override string getMessage ( ) { result = "Object missing" }
437466}
@@ -480,6 +509,43 @@ class ArrayTypeInvalidRank extends TypeViolation {
480509 override string getMessage ( ) { result = "Invalid ArrayType.getRank()" }
481510}
482511
512+ /**
513+ * A type should have at most one kind, except for missing referenced types
514+ * where the interface/class is unknown.
515+ */
516+ class KindViolation extends TypeViolation {
517+ KindViolation ( ) {
518+ count ( typeKind ( this .getType ( ) ) ) != 1 and
519+ exists ( this .getType ( ) .getLocation ( ) )
520+ }
521+
522+ override string getMessage ( ) {
523+ result = "Incorrect class/interface on type: " + concat ( typeKind ( this .getType ( ) ) , " " )
524+ }
525+ }
526+
527+ /**
528+ * The type of a kind must be consistent between a constructed generic and its
529+ * unbound generic.
530+ */
531+ class InconsistentKind extends TypeViolation {
532+ InconsistentKind ( ) { typeKind ( this .getType ( ) ) != typeKind ( this .getType ( ) .getSourceDeclaration ( ) ) }
533+
534+ override string getMessage ( ) { result = "Inconsistent type kind of source declaration" }
535+ }
536+
537+ private string typeKind ( Type t ) {
538+ t instanceof Interface and result = "interface"
539+ or
540+ t instanceof Class and result = "class"
541+ or
542+ t instanceof TypeParameter and result = "type parameter"
543+ or
544+ t instanceof ArrayType and result = "array"
545+ or
546+ t instanceof PointerType and result = "pointer"
547+ }
548+
483549/**
484550 * A violation in a `Member`.
485551 */
0 commit comments