Preserve Gotlin semantics across packages
This commit is contained in:
parent
5b30e49486
commit
acb42a5702
10 changed files with 525 additions and 34 deletions
|
|
@ -11,17 +11,25 @@ import (
|
|||
)
|
||||
|
||||
func GenerateGo(program *Program) ([]byte, error) {
|
||||
return generateGo(program, "")
|
||||
return generateGo(program, "", nil)
|
||||
}
|
||||
|
||||
func GenerateGoMain(program *Program) ([]byte, error) {
|
||||
return generateGo(program, "main")
|
||||
return generateGo(program, "main", nil)
|
||||
}
|
||||
|
||||
func generateGo(program *Program, packageOverride string) ([]byte, error) {
|
||||
semantic, err := Analyze(program)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func GenerateGoWithMetadata(program *Program, metadata []*PackageMetadata) ([]byte, error) {
|
||||
return generateGo(program, "", metadata)
|
||||
}
|
||||
|
||||
func GenerateGoMainWithMetadata(program *Program, metadata []*PackageMetadata) ([]byte, error) {
|
||||
return generateGo(program, "main", metadata)
|
||||
}
|
||||
|
||||
func generateGo(program *Program, packageOverride string, metadata []*PackageMetadata) ([]byte, error) {
|
||||
semantic, diagnostics := AnalyzeWithMetadata(program, metadata)
|
||||
if len(diagnostics) > 0 {
|
||||
return nil, diagnostics[0]
|
||||
}
|
||||
g := goGenerator{semantic: semantic}
|
||||
if err := g.program(program, packageOverride); err != nil {
|
||||
|
|
@ -1260,10 +1268,15 @@ func (g *goGenerator) expr(expr Expr, expectedType string) (string, error) {
|
|||
if ident, ok := e.Receiver.(IdentExpr); ok && g.semantic.Imports[ident.Name] {
|
||||
name = exportedGoName(name)
|
||||
} else if class, ok := g.classForType(g.exprType(e.Receiver)); ok {
|
||||
for _, field := range class.Fields {
|
||||
if field.Name == name && class.Data && !field.Private {
|
||||
name = exportedGoName(name)
|
||||
break
|
||||
resolvedType, _ := g.semantic.ResolveType(g.exprType(e.Receiver))
|
||||
if isImportedClassType(resolvedType) {
|
||||
name = exportedGoName(name)
|
||||
} else {
|
||||
for _, field := range class.Fields {
|
||||
if field.Name == name && class.Data && !field.Private {
|
||||
name = exportedGoName(name)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ident, ok := e.Receiver.(IdentExpr); ok && (ident.Name == "this" || ident.Name == "self") && g.currentClass != nil {
|
||||
|
|
@ -2445,10 +2458,15 @@ func (g *goGenerator) isExternalGoCall(callee Expr) bool {
|
|||
}
|
||||
|
||||
func (g *goGenerator) classForType(typ string) (ClassDecl, bool) {
|
||||
typ = strings.TrimPrefix(typ, "*")
|
||||
typ = strings.TrimSuffix(typ, "?")
|
||||
class, ok := g.semantic.Classes[typ]
|
||||
return class, ok
|
||||
resolved, err := g.semantic.ResolveType(typ)
|
||||
if err != nil {
|
||||
return ClassDecl{}, false
|
||||
}
|
||||
class, _ := classInstance(resolved)
|
||||
if class == nil || class.Decl == nil {
|
||||
return ClassDecl{}, false
|
||||
}
|
||||
return *class.Decl, true
|
||||
}
|
||||
|
||||
func (g *goGenerator) isDefined(name string) bool {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue