Skip to content

Add SubclassRelationCache and forbid isSubclassOf import #122

Description

@MessiasLima

Description

Create a SubclassRelationCache that stores the result of KClass.isSubclassOf lookups, expose a KClass<*>.isSubclassOfCached(base: KClass<*>) helper, and route every current kClass.isSubclassOf call site through it. Once no direct usages remain, forbid importing kotlin.reflect.full.isSubclassOf with detekt so future code must use the cached helper.

Scope and constraints

  • Cache the boolean result of isSubclassOf keyed by the subclass/superclass KClass pair.
  • Provide the helper fun KClass<*>.isSubclassOfCached(base: KClass<*>).
  • Preserve existing isSubclassOf semantics exactly, including self-relation and interface checks.
  • Replace every current kClass.isSubclassOf usage: ListResolver, SetResolver, MapResolver, OptionalResolver, and ClassResolver.
  • Add kotlin.reflect.full.isSubclassOf as a prohibited import in the shared detekt configuration.
  • Ensure correctness when resolver instances are shared across threads.
  • Leave existing isSubtypeOf checks (List/Set/Map mutability) out of scope.

References

Scope

Add SubclassRelationCache and isSubclassOfCached, migrate all current isSubclassOf usages, enable the prohibited-import rule, and add tests.

Out of scope: changing subclass rules, resolver ordering, caching isSubtypeOf, or the public Resolver API.

Acceptance criteria

  • SubclassRelationCache exposes a lookup that returns the same result as KClass.isSubclassOf.
  • KClass<*>.isSubclassOfCached(base: KClass<*>) is available and delegates to the cache.
  • Every current isSubclassOf usage in ListResolver, SetResolver, MapResolver, OptionalResolver, and ClassResolver goes through isSubclassOfCached.
  • Repeated checks for the same subclass/superclass pair reuse the cached result instead of recomputing it.
  • Distinct subclass/superclass pairs keep independent cached results.
  • Importing kotlin.reflect.full.isSubclassOf is flagged by detekt and ./gradlew detekt fails when it is used.
  • canResolve behavior is unchanged, including rejection of String, Number, Boolean, Char, and List/Set/Map subclasses in ClassResolver.
  • List, Set, Map, and Optional resolution behavior is unchanged.
  • Tests verify cache reuse and existing resolver behavior for the affected resolvers.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    • Status
      Ready

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions