Preserve Gotlin semantics across packages

This commit is contained in:
pavel 2026-08-27 22:18:45 +02:00
commit acb42a5702
10 changed files with 525 additions and 34 deletions

View file

@ -43,6 +43,14 @@ type ClassType struct{ Class *ClassSymbol }
func (ClassType) typeNode() {}
func (t ClassType) String() string { return t.Class.Name }
type ImportedClassType struct {
Package string
Class *ClassSymbol
}
func (ImportedClassType) typeNode() {}
func (t ImportedClassType) String() string { return t.Package + "." + t.Class.Name }
type NullableType struct{ Element Type }
func (NullableType) typeNode() {}
@ -185,6 +193,39 @@ func resolveClassTypes(typ Type, classes map[string]*ClassSymbol) Type {
}
}
func resolveImportedTypes(typ Type, packages map[string]*PackageSymbol) Type {
switch value := typ.(type) {
case NamedType:
parts := strings.Split(value.Name, ".")
if len(parts) == 2 {
if pack := packages[parts[0]]; pack != nil {
if class := pack.Classes[parts[1]]; class != nil {
return ImportedClassType{Package: parts[0], Class: class}
}
}
}
return value
case NullableType:
return NullableType{Element: resolveImportedTypes(value.Element, packages)}
case GoPointerType:
return GoPointerType{Element: resolveImportedTypes(value.Element, packages)}
case GenericType:
args := make([]Type, len(value.Args))
for index, arg := range value.Args {
args[index] = resolveImportedTypes(arg, packages)
}
return GenericType{Base: resolveImportedTypes(value.Base, packages), Args: args}
case FunctionType:
params := make([]Type, len(value.Params))
for index, param := range value.Params {
params[index] = resolveImportedTypes(param, packages)
}
return FunctionType{TypeParams: value.TypeParams, Params: params, Result: resolveImportedTypes(value.Result, packages), Effects: value.Effects}
default:
return typ
}
}
func resolveTypeParameters(typ Type, params map[string]bool) Type {
switch value := typ.(type) {
case NamedType:
@ -221,6 +262,19 @@ func resolveTypeParameters(typ Type, params map[string]bool) Type {
func typeEqual(left, right Type) bool { return left.String() == right.String() }
func isImportedClassType(typ Type) bool {
switch value := typ.(type) {
case ImportedClassType:
return true
case NullableType:
return isImportedClassType(value.Element)
case GenericType:
_, ok := value.Base.(ImportedClassType)
return ok
}
return false
}
func substituteType(typ Type, bindings map[string]Type) Type {
switch value := typ.(type) {
case TypeParameterType:
@ -284,10 +338,12 @@ func renderGoType(typ Type) string {
return ""
case ClassType:
return "*" + value.Class.Name
case ImportedClassType:
return "*" + value.Package + "." + value.Class.Name
case NullableType:
element := renderGoType(value.Element)
switch value.Element.(type) {
case ClassType, GoPointerType:
case ClassType, ImportedClassType, GoPointerType:
return element
}
if element == "error" || element == "any" {
@ -334,6 +390,9 @@ func renderGoType(typ Type) string {
if class, ok := value.Base.(ClassType); ok {
return "*" + class.Class.Name + "[" + strings.Join(args, ", ") + "]"
}
if class, ok := value.Base.(ImportedClassType); ok {
return "*" + class.Package + "." + class.Class.Name + "[" + strings.Join(args, ", ") + "]"
}
return base + "[" + strings.Join(args, ", ") + "]"
case TypeParameterType:
return value.Name