Documentation
¶
Overview ¶
Package typeinfer provides lightweight type inference for Kotlin source code. It builds a partial type system from AST analysis — no JVM, no classpath, no compilation required. Runs at tree-sitter speed.
What it resolves:
- Import-based type resolution (java.util.Random → knows Random is java.util.Random)
- Declaration-site types (val x: String = ... → knows x is String)
- Nullable vs non-null tracking (String vs String?)
- Partial class hierarchy from source (class Foo : Bar → knows Foo extends Bar)
- Sealed class/enum variants (sealed class Result → knows Success, Failure)
- Annotation arguments (@RequiresApi(26) → knows value is 26)
What it does NOT resolve:
- Types from compiled dependencies (JARs)
- Generic type argument inference
- Complex expression type inference (result of chained calls)
- Overload resolution
Index ¶
- Variables
- func ClearTypeIndexCache(dir string) error
- func ImplementsInterface(typeFQN, interfaceFQN string) bool
- func IsKnownCloseable(typeName string) bool
- func IsKnownSubtype(typeFQN, supertypeFQN string) bool
- func IsKnownValueType(rt *ResolvedType) bool
- func IsSubtypeOfException(a, b string) bool
- func MapJavaToKotlin(javaFQN string) string
- func NewResolver() *defaultResolver
- func TypeIndexCacheDir(repoDir string) string
- type ClassInfo
- type ExtensionFuncInfo
- type FakeResolver
- func (f *FakeResolver) AnnotationValueFlat(_ uint32, _ *scanner.File, annotationName, argName string) string
- func (f *FakeResolver) ClassHierarchy(typeName string) *ClassInfo
- func (f *FakeResolver) EnumEntries(enumTypeName string) []string
- func (f *FakeResolver) IsExceptionSubtype(a, b string) bool
- func (f *FakeResolver) IsNullableFlat(idx uint32, file *scanner.File) *bool
- func (f *FakeResolver) ResolveByNameFlat(name string, _ uint32, _ *scanner.File) *ResolvedType
- func (f *FakeResolver) ResolveFlatNode(idx uint32, file *scanner.File) *ResolvedType
- func (f *FakeResolver) ResolveImport(simpleName string, _ *scanner.File) string
- func (f *FakeResolver) SealedVariants(sealedTypeName string) []string
- type FileTypeInfo
- type ImportTable
- type MemberInfo
- type ParamInfo
- type ResolvedType
- type ScopeTable
- func (s *ScopeTable) Declare(name string, typ *ResolvedType)
- func (s *ScopeTable) FindScopeAtOffset(offset uint32) *ScopeTable
- func (s *ScopeTable) IsSmartCastNonNull(name string) bool
- func (s *ScopeTable) Lookup(name string) *ResolvedType
- func (s *ScopeTable) NewScope() *ScopeTable
- func (s *ScopeTable) NewScopeForNode(node interface{ ... }) *ScopeTable
- type StdlibMethod
- type TypeKind
- type TypeResolver
Constants ¶
This section is empty.
Variables ¶
var ExceptionAncestors = map[string][]string{
"Throwable": {},
"Exception": {"Throwable"},
"RuntimeException": {"Exception", "Throwable"},
"Error": {"Throwable"},
"IOException": {"Exception", "Throwable"},
"FileNotFoundException": {"IOException", "Exception", "Throwable"},
"InterruptedException": {"Exception", "Throwable"},
"TimeoutException": {"Exception", "Throwable"},
"ParseException": {"Exception", "Throwable"},
"CloneNotSupportedException": {"Exception", "Throwable"},
"ReflectiveOperationException": {"Exception", "Throwable"},
"ClassNotFoundException": {"ReflectiveOperationException", "Exception", "Throwable"},
"NoSuchMethodException": {"ReflectiveOperationException", "Exception", "Throwable"},
"NoSuchFieldException": {"ReflectiveOperationException", "Exception", "Throwable"},
"URISyntaxException": {"Exception", "Throwable"},
"GeneralSecurityException": {"Exception", "Throwable"},
"NoSuchAlgorithmException": {"GeneralSecurityException", "Exception", "Throwable"},
"InvalidKeyException": {"GeneralSecurityException", "Exception", "Throwable"},
"CertificateException": {"GeneralSecurityException", "Exception", "Throwable"},
"SocketException": {"IOException", "Exception", "Throwable"},
"ConnectException": {"SocketException", "IOException", "Exception", "Throwable"},
"SocketTimeoutException": {"SocketException", "IOException", "Exception", "Throwable"},
"MalformedURLException": {"IOException", "Exception", "Throwable"},
"UnknownHostException": {"IOException", "Exception", "Throwable"},
"EOFException": {"IOException", "Exception", "Throwable"},
"SSLException": {"IOException", "Exception", "Throwable"},
"SSLHandshakeException": {"SSLException", "IOException", "Exception", "Throwable"},
"NullPointerException": {"RuntimeException", "Exception", "Throwable"},
"IllegalArgumentException": {"RuntimeException", "Exception", "Throwable"},
"IllegalStateException": {"RuntimeException", "Exception", "Throwable"},
"CancellationException": {"IllegalStateException", "RuntimeException", "Exception", "Throwable"},
"NumberFormatException": {"IllegalArgumentException", "RuntimeException", "Exception", "Throwable"},
"IndexOutOfBoundsException": {"RuntimeException", "Exception", "Throwable"},
"ArrayIndexOutOfBoundsException": {"IndexOutOfBoundsException", "RuntimeException", "Exception", "Throwable"},
"StringIndexOutOfBoundsException": {"IndexOutOfBoundsException", "RuntimeException", "Exception", "Throwable"},
"ClassCastException": {"RuntimeException", "Exception", "Throwable"},
"TypeCastException": {"ClassCastException", "RuntimeException", "Exception", "Throwable"},
"UnsupportedOperationException": {"RuntimeException", "Exception", "Throwable"},
"ConcurrentModificationException": {"RuntimeException", "Exception", "Throwable"},
"NoSuchElementException": {"RuntimeException", "Exception", "Throwable"},
"ArithmeticException": {"RuntimeException", "Exception", "Throwable"},
"SecurityException": {"RuntimeException", "Exception", "Throwable"},
"NegativeArraySizeException": {"RuntimeException", "Exception", "Throwable"},
"KotlinNullPointerException": {"NullPointerException", "RuntimeException", "Exception", "Throwable"},
"UninitializedPropertyAccessException": {"RuntimeException", "Exception", "Throwable"},
"VirtualMachineError": {"Error", "Throwable"},
"OutOfMemoryError": {"VirtualMachineError", "Error", "Throwable"},
"StackOverflowError": {"VirtualMachineError", "Error", "Throwable"},
"LinkageError": {"Error", "Throwable"},
"ExceptionInInitializerError": {"LinkageError", "Error", "Throwable"},
"NoClassDefFoundError": {"LinkageError", "Error", "Throwable"},
"NotImplementedError": {"Error", "Throwable"},
"AssertionError": {"Error", "Throwable"},
"TimeoutCancellationException": {"CancellationException", "IllegalStateException", "RuntimeException", "Exception", "Throwable"},
"AndroidException": {"Exception", "Throwable"},
"ActivityNotFoundException": {"RuntimeException", "Exception", "Throwable"},
"RemoteException": {"AndroidException", "Exception", "Throwable"},
"DeadObjectException": {"RemoteException", "AndroidException", "Exception", "Throwable"},
"JSONException": {"Exception", "Throwable"},
"SQLiteException": {"RuntimeException", "Exception", "Throwable"},
"SQLiteConstraintException": {"SQLiteException", "RuntimeException", "Exception", "Throwable"},
"BadParcelableException": {"RuntimeException", "Exception", "Throwable"},
}
ExceptionAncestors maps exception class name -> ordered list of supertypes.
var JavaToKotlinTypes = map[string]string{
"java.lang.String": "kotlin.String",
"java.lang.Integer": "kotlin.Int",
"java.lang.Long": "kotlin.Long",
"java.lang.Short": "kotlin.Short",
"java.lang.Byte": "kotlin.Byte",
"java.lang.Float": "kotlin.Float",
"java.lang.Double": "kotlin.Double",
"java.lang.Boolean": "kotlin.Boolean",
"java.lang.Character": "kotlin.Char",
"java.lang.Object": "kotlin.Any",
"java.lang.Void": "kotlin.Unit",
"java.lang.Number": "kotlin.Number",
"java.util.List": "kotlin.collections.List",
"java.util.ArrayList": "kotlin.collections.ArrayList",
"java.util.Set": "kotlin.collections.Set",
"java.util.HashSet": "kotlin.collections.HashSet",
"java.util.LinkedHashSet": "kotlin.collections.LinkedHashSet",
"java.util.TreeSet": "kotlin.collections.TreeSet",
"java.util.Map": "kotlin.collections.Map",
"java.util.HashMap": "kotlin.collections.HashMap",
"java.util.LinkedHashMap": "kotlin.collections.LinkedHashMap",
"java.util.TreeMap": "kotlin.collections.TreeMap",
"java.util.Collection": "kotlin.collections.Collection",
"java.util.Iterator": "kotlin.collections.Iterator",
"java.lang.Iterable": "kotlin.collections.Iterable",
"java.lang.Comparable": "kotlin.Comparable",
"java.lang.Enum": "kotlin.Enum",
"java.lang.Annotation": "kotlin.Annotation",
"java.lang.Cloneable": "kotlin.Cloneable",
"java.lang.Throwable": "kotlin.Throwable",
"java.lang.Exception": "kotlin.Exception",
"java.lang.RuntimeException": "kotlin.RuntimeException",
"java.lang.Error": "kotlin.Error",
"java.lang.Runnable": "kotlin.Runnable",
}
JavaToKotlinTypes maps Java FQNs to their Kotlin equivalents.
var KnownClassHierarchy = map[string][]string{
"android.app.Activity": {"android.content.ContextWrapper", "android.content.Context"},
"androidx.fragment.app.FragmentActivity": {"android.app.Activity", "android.content.ContextWrapper", "android.content.Context"},
"androidx.appcompat.app.AppCompatActivity": {"androidx.fragment.app.FragmentActivity", "android.app.Activity"},
"android.app.Application": {"android.content.ContextWrapper", "android.content.Context"},
"android.app.Service": {"android.content.ContextWrapper", "android.content.Context"},
"android.content.BroadcastReceiver": {},
"android.content.ContentProvider": {},
"android.view.ViewGroup": {"android.view.View"},
"android.widget.LinearLayout": {"android.view.ViewGroup", "android.view.View"},
"android.widget.FrameLayout": {"android.view.ViewGroup", "android.view.View"},
"android.widget.RelativeLayout": {"android.view.ViewGroup", "android.view.View"},
"android.widget.TextView": {"android.view.View"},
"android.widget.ImageView": {"android.view.View"},
"android.widget.Button": {"android.widget.TextView", "android.view.View"},
"java.lang.Exception": {"java.lang.Throwable"},
"java.lang.RuntimeException": {"java.lang.Exception", "java.lang.Throwable"},
}
KnownClassHierarchy maps FQN -> ordered list of supertypes (nearest first).
var KnownCloseableTypes = map[string]bool{ "InputStream": true, "OutputStream": true, "Reader": true, "Writer": true, "BufferedReader": true, "BufferedWriter": true, "FileInputStream": true, "FileOutputStream": true, "FileReader": true, "FileWriter": true, "InputStreamReader": true, "OutputStreamWriter": true, "PrintWriter": true, "PrintStream": true, "Socket": true, "ServerSocket": true, "Connection": true, "Statement": true, "PreparedStatement": true, "ResultSet": true, "Cursor": true, "TypedArray": true, "ParcelFileDescriptor": true, "HttpURLConnection": true, "ZipFile": true, "JarFile": true, "RandomAccessFile": true, "Channel": true, "AssetFileDescriptor": true, "Scanner": true, "ByteArrayInputStream": true, "ByteArrayOutputStream": true, "DataInputStream": true, "DataOutputStream": true, "ObjectInputStream": true, "ObjectOutputStream": true, "BufferedInputStream": true, "BufferedOutputStream": true, }
KnownCloseableTypes lists types known to implement Closeable/AutoCloseable.
var KnownInterfaces = map[string][]string{
"java.io.Serializable": {
"java.lang.Number", "java.lang.String", "java.lang.Enum",
"java.util.ArrayList", "java.util.HashMap", "java.util.HashSet",
"java.util.LinkedList", "java.util.TreeMap", "java.util.TreeSet",
"kotlin.Pair", "kotlin.Triple",
"java.util.Date", "java.util.Calendar",
"java.math.BigDecimal", "java.math.BigInteger",
"java.io.File", "java.net.URL", "java.net.URI",
},
"java.io.Closeable": {
"java.io.InputStream", "java.io.OutputStream",
"java.io.FileInputStream", "java.io.FileOutputStream",
"java.io.BufferedReader", "java.io.BufferedWriter",
"java.io.InputStreamReader", "java.io.OutputStreamWriter",
"java.io.PrintWriter", "java.io.PrintStream",
"java.net.Socket", "java.net.ServerSocket",
"java.sql.Connection", "java.sql.Statement", "java.sql.ResultSet",
"java.util.Scanner",
},
"android.os.Parcelable": {
"android.os.Bundle", "android.content.Intent",
"android.net.Uri", "android.graphics.Bitmap",
},
}
KnownInterfaces maps interface FQN -> known implementors.
var KnownValueTypes = map[string]bool{ "String": true, "kotlin.String": true, "Int": true, "kotlin.Int": true, "Long": true, "kotlin.Long": true, "Double": true, "kotlin.Double": true, "Float": true, "kotlin.Float": true, "Boolean": true, "kotlin.Boolean": true, "Byte": true, "kotlin.Byte": true, "Short": true, "kotlin.Short": true, "Char": true, "kotlin.Char": true, "UInt": true, "kotlin.UInt": true, "ULong": true, "kotlin.ULong": true, "UByte": true, "kotlin.UByte": true, "UShort": true, "kotlin.UShort": true, "Pair": true, "kotlin.Pair": true, "Triple": true, "kotlin.Triple": true, "java.lang.String": true, "java.lang.Integer": true, "java.lang.Long": true, "java.lang.Double": true, "java.lang.Float": true, "java.lang.Boolean": true, "java.lang.Byte": true, "java.lang.Short": true, "java.lang.Character": true, "BigDecimal": true, "java.math.BigDecimal": true, "BigInteger": true, "java.math.BigInteger": true, }
KnownValueTypes lists types where referential equality (===) is almost certainly wrong and structural equality (==) should be used instead. Both Kotlin and Java FQNs are included so the lookup works regardless of whether the resolver produced a simple name or a fully-qualified name.
var KotlinAutoImports = map[string]string{
"Runtime": "java.lang.Runtime",
"ProcessBuilder": "java.lang.ProcessBuilder",
"Process": "java.lang.Process",
"Thread": "java.lang.Thread",
"ThreadLocal": "java.lang.ThreadLocal",
"ThreadGroup": "java.lang.ThreadGroup",
"Throwable": "java.lang.Throwable",
"Exception": "java.lang.Exception",
"RuntimeException": "java.lang.RuntimeException",
"Error": "java.lang.Error",
"System": "java.lang.System",
"Math": "java.lang.Math",
"StrictMath": "java.lang.StrictMath",
"Class": "java.lang.Class",
"ClassLoader": "java.lang.ClassLoader",
"Object": "java.lang.Object",
"Number": "java.lang.Number",
"Void": "java.lang.Void",
"Package": "java.lang.Package",
"StackTraceElement": "java.lang.StackTraceElement",
"Enum": "java.lang.Enum",
}
KotlinAutoImports maps simple names of types Kotlin auto-imports from java.lang.* (which is implicitly visible in every Kotlin file even without an explicit import statement) to their Java FQNs.
These names are only used when no explicit import, alias, primitive, or stdlib mapping wins first. Several java.lang.* types are remapped by Kotlin to kotlin.* counterparts (String, Throwable, Exception, Object, ...) — those live in PrimitiveTypes / KotlinStdlibTypes and are not duplicated here. The entries below are types Kotlin uses by their java.lang.* FQN.
var KotlinStdlibTypes = map[string]string{
"List": "kotlin.collections.List",
"MutableList": "kotlin.collections.MutableList",
"Set": "kotlin.collections.Set",
"MutableSet": "kotlin.collections.MutableSet",
"Map": "kotlin.collections.Map",
"MutableMap": "kotlin.collections.MutableMap",
"Sequence": "kotlin.sequences.Sequence",
"Flow": "kotlinx.coroutines.flow.Flow",
"StateFlow": "kotlinx.coroutines.flow.StateFlow",
"SharedFlow": "kotlinx.coroutines.flow.SharedFlow",
"MutableStateFlow": "kotlinx.coroutines.flow.MutableStateFlow",
"MutableSharedFlow": "kotlinx.coroutines.flow.MutableSharedFlow",
"Job": "kotlinx.coroutines.Job",
"Deferred": "kotlinx.coroutines.Deferred",
"Pair": "kotlin.Pair",
"Triple": "kotlin.Triple",
"Result": "kotlin.Result",
"Lazy": "kotlin.Lazy",
"Comparable": "kotlin.Comparable",
"Iterable": "kotlin.collections.Iterable",
"Iterator": "kotlin.collections.Iterator",
"Collection": "kotlin.collections.Collection",
"Array": "kotlin.Array",
"IntArray": "kotlin.IntArray",
"LongArray": "kotlin.LongArray",
"ByteArray": "kotlin.ByteArray",
"CharArray": "kotlin.CharArray",
"BooleanArray": "kotlin.BooleanArray",
"FloatArray": "kotlin.FloatArray",
"DoubleArray": "kotlin.DoubleArray",
"ShortArray": "kotlin.ShortArray",
}
KotlinStdlibTypes maps common stdlib type simple names to FQNs.
var PrimitiveTypes = map[string]string{
"Int": "kotlin.Int", "Long": "kotlin.Long", "Short": "kotlin.Short",
"Byte": "kotlin.Byte", "Float": "kotlin.Float", "Double": "kotlin.Double",
"Boolean": "kotlin.Boolean", "Char": "kotlin.Char", "String": "kotlin.String",
"Unit": "kotlin.Unit", "Nothing": "kotlin.Nothing", "Any": "kotlin.Any",
}
PrimitiveTypes maps Kotlin primitive type names to their FQNs.
var StdlibMethods map[string]*StdlibMethod
StdlibMethods maps "ReceiverType.methodName" -> return type info. The receiver type uses simple names (String, List, Map, etc.). For collection types, List/Collection/Iterable/MutableList share entries.
Functions ¶
func ClearTypeIndexCache ¶
func ImplementsInterface ¶
ImplementsInterface checks whether a given FQN is a known implementor of the specified interface FQN.
func IsKnownCloseable ¶
IsKnownCloseable returns true if the type name (simple name) is known to implement Closeable.
func IsKnownSubtype ¶
IsKnownSubtype checks whether typeFQN is a known subtype of supertypeFQN using KnownClassHierarchy (transitive) and KnownInterfaces.
func IsKnownValueType ¶
func IsKnownValueType(rt *ResolvedType) bool
IsKnownValueType returns true if the resolved type (by Name or FQN) is a known value type where structural equality should be preferred.
func IsSubtypeOfException ¶
IsSubtypeOfException checks if exceptionA is a subtype of exceptionB.
func MapJavaToKotlin ¶
MapJavaToKotlin returns the Kotlin equivalent FQN for a Java FQN. Returns "" if no mapping exists.
func NewResolver ¶
func NewResolver() *defaultResolver
NewResolver creates a new resolver backed by source-level analysis.
func TypeIndexCacheDir ¶
TypeIndexCacheDir returns the per-file source type-index cache directory.
Types ¶
type ClassInfo ¶
type ClassInfo struct {
Name string // Simple name
FQN string // Fully qualified name
Kind string // "class", "interface", "object", "enum", "sealed class", "sealed interface"
Supertypes []string // FQNs of direct supertypes
IsSealed bool
IsData bool
IsInner bool
IsAbstract bool
IsOpen bool
Members []MemberInfo
File string // Source file path
Line int
}
ClassInfo holds information about a class resolved from source.
type ExtensionFuncInfo ¶
type ExtensionFuncInfo struct {
ReceiverType string // Simple name of the receiver type (e.g., "String")
Name string // Function name
ReturnType *ResolvedType // Return type
}
ExtensionFuncInfo describes an extension function from source.
type FakeResolver ¶
type FakeResolver struct {
NodeTypes map[string]*ResolvedType // node text → type
NameTypes map[string]*ResolvedType // variable name → type
Imports map[string]string // simple name → FQN
Nullability map[string]*bool // node text → nullable
Classes map[string]*ClassInfo // type name → class info
SealedMap map[string][]string // sealed class → variants
EnumMap map[string][]string // enum class → entries
Annotations map[string]string // "AnnotationName.argName" → value
}
FakeResolver is a configurable test double for TypeResolver. Set up responses before using in tests.
func NewFakeResolver ¶
func NewFakeResolver() *FakeResolver
NewFakeResolver creates a FakeResolver with all maps initialized.
func (*FakeResolver) AnnotationValueFlat ¶
func (*FakeResolver) ClassHierarchy ¶
func (f *FakeResolver) ClassHierarchy(typeName string) *ClassInfo
ClassHierarchy returns the configured ClassInfo for the type name, or nil.
func (*FakeResolver) EnumEntries ¶
func (f *FakeResolver) EnumEntries(enumTypeName string) []string
EnumEntries returns the configured entries for the enum class, or nil.
func (*FakeResolver) IsExceptionSubtype ¶
func (f *FakeResolver) IsExceptionSubtype(a, b string) bool
IsExceptionSubtype delegates to the global ExceptionAncestors table.
func (*FakeResolver) IsNullableFlat ¶
func (f *FakeResolver) IsNullableFlat(idx uint32, file *scanner.File) *bool
func (*FakeResolver) ResolveByNameFlat ¶
func (f *FakeResolver) ResolveByNameFlat(name string, _ uint32, _ *scanner.File) *ResolvedType
func (*FakeResolver) ResolveFlatNode ¶
func (f *FakeResolver) ResolveFlatNode(idx uint32, file *scanner.File) *ResolvedType
func (*FakeResolver) ResolveImport ¶
func (f *FakeResolver) ResolveImport(simpleName string, _ *scanner.File) string
ResolveImport returns the configured FQN for the simple name, or "".
func (*FakeResolver) SealedVariants ¶
func (f *FakeResolver) SealedVariants(sealedTypeName string) []string
SealedVariants returns the configured variants for the sealed class, or nil.
type FileTypeInfo ¶
type FileTypeInfo struct {
Path string
ImportTable *ImportTable
RootScope *ScopeTable
Classes []*ClassInfo
SealedSubs map[string][]string // supertype name → subclass names
EnumEntries map[string][]string // enum class name → entry names
TypeAliases map[string]*ResolvedType // alias name or FQN → target type
Functions map[string]*ResolvedType // function name → return type
Extensions []*ExtensionFuncInfo // extension functions
}
FileTypeInfo holds all type information extracted from a single file. It is produced independently per file with no shared state, enabling embarrassingly parallel indexing.
func IndexFileParallel ¶
func IndexFileParallel(file *scanner.File) *FileTypeInfo
IndexFileParallel extracts type info from a single file without touching any shared state. Returns a FileTypeInfo that can be merged later.
type ImportTable ¶
type ImportTable struct {
Explicit map[string]string // import com.foo.Bar → "Bar" → "com.foo.Bar"
Wildcard []string // import com.foo.* → ["com.foo"]
Aliases map[string]string // import com.foo.Bar as Baz → "Baz" → "com.foo.Bar"
}
ImportTable maps simple names to FQNs for a single file.
func (*ImportTable) Resolve ¶
func (it *ImportTable) Resolve(simpleName string) string
Resolve returns the FQN for a simple name, checking explicit imports, Kotlin stdlib, and primitives.
type MemberInfo ¶
type MemberInfo struct {
Name string
Kind string // "function", "property"
Type *ResolvedType // function: return type; property: declared type
Visibility string // "public", "private", "internal", "protected"
IsOverride bool
IsAbstract bool
// Params is the parameter list for function members. Nil for
// properties or for functions where parameters could not be
// extracted. The order matches the source declaration. Each
// ParamInfo records the parameter's simple name and best-effort
// resolved type — types from same-workspace declarations populate
// fully; library-typed parameters carry only the simple name with
// a TypeUnknown ResolvedType until classpath-aware resolution lands.
Params []ParamInfo
// TypeParameters is the simple list of generic type parameter names
// declared on the function (e.g. ["T", "R"] for `fun <T, R> f()`).
// Populated for function members; nil for properties.
TypeParameters []string
}
MemberInfo holds information about a class member.
type ParamInfo ¶ added in v0.2.0
type ParamInfo struct {
Name string
Type *ResolvedType
HasDefault bool
}
ParamInfo describes a function parameter as recorded in MemberInfo.
type ResolvedType ¶
type ResolvedType struct {
Name string // Simple name: "String", "MutableList"
FQN string // Fully qualified: "kotlin.String", "kotlin.collections.MutableList"
Kind TypeKind // What category of type
Nullable bool // Is this T?
TypeArgs []ResolvedType // Generic type arguments
Supertypes []string // Known supertypes from source (FQN)
}
ResolvedType represents a type resolved from source analysis.
func (*ResolvedType) IsMutable ¶
func (t *ResolvedType) IsMutable() bool
IsMutable returns whether this is a known mutable collection type.
func (*ResolvedType) IsNullable ¶
func (t *ResolvedType) IsNullable() bool
IsNullable returns whether this type allows null values.
func (*ResolvedType) IsPrimitive ¶
func (t *ResolvedType) IsPrimitive() bool
IsPrimitive returns whether this is a Kotlin primitive type.
func (*ResolvedType) IsSubtypeOf ¶
func (t *ResolvedType) IsSubtypeOf(typeName string) bool
IsSubtypeOf checks if this type is a known subtype of the given type name.
type ScopeTable ¶
type ScopeTable struct {
Parent *ScopeTable
Children []*ScopeTable
Entries map[string]*ResolvedType // name → type
SmartCasts map[string]bool // variable names known to be non-null in this scope
SmartCastTypes map[string]*ResolvedType // variable names narrowed by is-checks
StartByte uint32 // byte offset where this scope begins
EndByte uint32 // byte offset where this scope ends
}
ScopeTable tracks variable declarations and their types within a scope.
func (*ScopeTable) Declare ¶
func (s *ScopeTable) Declare(name string, typ *ResolvedType)
Declare adds a variable to the current scope.
func (*ScopeTable) FindScopeAtOffset ¶
func (s *ScopeTable) FindScopeAtOffset(offset uint32) *ScopeTable
FindScopeAtOffset finds the most specific (deepest) scope containing the given byte offset.
func (*ScopeTable) IsSmartCastNonNull ¶
func (s *ScopeTable) IsSmartCastNonNull(name string) bool
IsSmartCastNonNull checks if a name is smart-cast to non-null in this scope or any parent.
func (*ScopeTable) Lookup ¶
func (s *ScopeTable) Lookup(name string) *ResolvedType
Lookup finds a variable in the current scope or any parent. If the variable is smart-cast to non-null in the current scope chain, the returned type will have Nullable set to false. If the variable has been narrowed by an is-check, the narrowed type is returned.
func (*ScopeTable) NewScope ¶
func (s *ScopeTable) NewScope() *ScopeTable
NewScope creates a child scope.
func (*ScopeTable) NewScopeForNode ¶
func (s *ScopeTable) NewScopeForNode(node interface { StartByte() uint32 EndByte() uint32 }) *ScopeTable
NewScopeForNode creates a child scope with byte range from the given node.
type StdlibMethod ¶
type StdlibMethod struct {
ReturnType *ResolvedType
Nullable bool
ReturnTypeArgIndex int // -1 = use fixed ReturnType; 0+ = use receiver's TypeArgs[i]
}
StdlibMethod describes a known stdlib method's return type.
func LookupStdlibMethod ¶
func LookupStdlibMethod(receiverType, methodName string) *StdlibMethod
LookupStdlibMethod looks up a stdlib method by receiver type name and method name. It tries the exact receiver first, then falls back to common supertype aliases.
type TypeKind ¶
type TypeKind int
TypeKind represents the category of a resolved type.
const ( TypeUnknown TypeKind = iota TypeClass // class, interface, object, enum TypePrimitive // Int, Long, Boolean, etc. TypeNullable // T? wrapper TypeFunction // (A, B) -> C TypeGeneric // T, with bounds TypeArray // Array<T>, IntArray, etc. TypeUnit // Unit (void equivalent) TypeNothing // Nothing (bottom type) )
type TypeResolver ¶
type TypeResolver interface {
// ResolveFlatNode returns the inferred type at a flat-tree index.
// This is the preferred production API.
// Returns UnknownType if the type cannot be determined.
ResolveFlatNode(idx uint32, file *scanner.File) *ResolvedType
// ResolveByName looks up a variable/property name in the current scope.
ResolveByNameFlat(name string, idx uint32, file *scanner.File) *ResolvedType
// ResolveImport returns the FQN for an imported simple name.
// Returns "" if not imported.
ResolveImport(simpleName string, file *scanner.File) string
IsNullableFlat(idx uint32, file *scanner.File) *bool
// ClassHierarchy returns the known class hierarchy for a type.
ClassHierarchy(typeName string) *ClassInfo
// SealedVariants returns known variants of a sealed class/interface.
SealedVariants(sealedTypeName string) []string
// EnumEntries returns known entries of an enum class.
EnumEntries(enumTypeName string) []string
AnnotationValueFlat(idx uint32, file *scanner.File, annotationName, argName string) string
// IsExceptionSubtype checks if exceptionA is a known subtype of exceptionB.
IsExceptionSubtype(a, b string) bool
}
TypeResolver resolves types from Kotlin source ASTs. It is the main interface rules use to query type information.