Preserve Gotlin semantics across packages
This commit is contained in:
parent
5b30e49486
commit
acb42a5702
10 changed files with 525 additions and 34 deletions
|
|
@ -56,6 +56,14 @@ type ClassSymbol struct {
|
|||
Methods map[string]*Symbol
|
||||
}
|
||||
|
||||
type PackageSymbol struct {
|
||||
Alias string
|
||||
Metadata *PackageMetadata
|
||||
Classes map[string]*ClassSymbol
|
||||
Functions map[string]*Symbol
|
||||
Enums map[string]EnumDecl
|
||||
}
|
||||
|
||||
type SemanticProgram struct {
|
||||
Syntax *Program
|
||||
Global *Scope
|
||||
|
|
@ -69,6 +77,7 @@ type SemanticProgram struct {
|
|||
Mappings *mappingState
|
||||
Diagnostics []SemanticDiagnostic
|
||||
FunctionEffects map[string]Effect
|
||||
Packages map[string]*PackageSymbol
|
||||
}
|
||||
|
||||
func Analyze(program *Program) (*SemanticProgram, error) {
|
||||
|
|
@ -80,7 +89,19 @@ func Analyze(program *Program) (*SemanticProgram, error) {
|
|||
}
|
||||
|
||||
func AnalyzeWithContext(program *Program, additional []*Program) (*SemanticProgram, []SemanticDiagnostic) {
|
||||
semantic, err := analyzeProgram(program, additional)
|
||||
return analyzeWithMetadata(program, additional, nil)
|
||||
}
|
||||
|
||||
func AnalyzeWithContextAndMetadata(program *Program, additional []*Program, metadata []*PackageMetadata) (*SemanticProgram, []SemanticDiagnostic) {
|
||||
return analyzeWithMetadata(program, additional, metadata)
|
||||
}
|
||||
|
||||
func AnalyzeWithMetadata(program *Program, metadata []*PackageMetadata) (*SemanticProgram, []SemanticDiagnostic) {
|
||||
return analyzeWithMetadata(program, nil, metadata)
|
||||
}
|
||||
|
||||
func analyzeWithMetadata(program *Program, additional []*Program, metadata []*PackageMetadata) (*SemanticProgram, []SemanticDiagnostic) {
|
||||
semantic, err := analyzeProgram(program, additional, metadata)
|
||||
if err != nil {
|
||||
return semantic, []SemanticDiagnostic{diagnosticForError("semantic-error", err)}
|
||||
}
|
||||
|
|
@ -91,7 +112,7 @@ func AnalyzeWithContext(program *Program, additional []*Program) (*SemanticProgr
|
|||
return semantic, nil
|
||||
}
|
||||
|
||||
func analyzeProgram(program *Program, additional []*Program) (*SemanticProgram, error) {
|
||||
func analyzeProgram(program *Program, additional []*Program, metadata []*PackageMetadata) (*SemanticProgram, error) {
|
||||
semantic := &SemanticProgram{
|
||||
Syntax: program,
|
||||
Global: NewScope(nil),
|
||||
|
|
@ -103,6 +124,7 @@ func analyzeProgram(program *Program, additional []*Program) (*SemanticProgram,
|
|||
GoPackages: map[string]*gotypes.Package{},
|
||||
Mappings: &mappingState{functions: map[string]string{}},
|
||||
FunctionEffects: map[string]Effect{},
|
||||
Packages: map[string]*PackageSymbol{},
|
||||
}
|
||||
programs := append([]*Program{program}, additional...)
|
||||
for _, source := range programs {
|
||||
|
|
@ -132,6 +154,9 @@ func analyzeProgram(program *Program, additional []*Program) (*SemanticProgram,
|
|||
name = defaultImportAlias(imported)
|
||||
}
|
||||
semantic.Imports[name] = true
|
||||
if packageMetadata := metadataForImport(imported, metadata); packageMetadata != nil {
|
||||
semantic.Packages[name] = packageSymbolFromMetadata(name, packageMetadata)
|
||||
}
|
||||
if importedPackage, err := importGoPackage(imported); err == nil {
|
||||
semantic.GoPackages[name] = importedPackage
|
||||
}
|
||||
|
|
@ -210,7 +235,7 @@ func (semantic *SemanticProgram) ResolveType(text string) (Type, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resolved := resolveClassTypes(typ, semantic.ClassInfo)
|
||||
resolved := resolveImportedTypes(resolveClassTypes(typ, semantic.ClassInfo), semantic.Packages)
|
||||
if err := validateNoClassPointer(resolved); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -234,7 +259,7 @@ func (semantic *SemanticProgram) ResolveTypeRefWithParams(ref TypeRef, params []
|
|||
for _, param := range params {
|
||||
paramSet[param] = true
|
||||
}
|
||||
resolved := resolveClassTypes(resolveTypeParameters(typ, paramSet), semantic.ClassInfo)
|
||||
resolved := resolveImportedTypes(resolveClassTypes(resolveTypeParameters(typ, paramSet), semantic.ClassInfo), semantic.Packages)
|
||||
if err := validateNoClassPointer(resolved); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -244,8 +269,11 @@ func (semantic *SemanticProgram) ResolveTypeRefWithParams(ref TypeRef, params []
|
|||
func validateNoClassPointer(typ Type) error {
|
||||
switch value := typ.(type) {
|
||||
case GoPointerType:
|
||||
if class, ok := value.Element.(ClassType); ok {
|
||||
switch class := value.Element.(type) {
|
||||
case ClassType:
|
||||
return fmt.Errorf("Gotlin class %s is already reference-valued; remove '*'", class.Class.Name)
|
||||
case ImportedClassType:
|
||||
return fmt.Errorf("Gotlin class %s is already reference-valued; remove '*'", class.String())
|
||||
}
|
||||
return validateNoClassPointer(value.Element)
|
||||
case NullableType:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue