-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
package.go
152 lines (119 loc) · 3.4 KB
/
package.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package parser
import (
"go/ast"
"strings"
"github.com/leaanthony/slicer"
"golang.org/x/tools/go/packages"
)
// Package is a wrapper around the go parsed package
type Package struct {
// A unique Name for this package.
// This is calculated and may not be the same as the one
// defined in Go - but that's ok!
Name string
// the package we are wrapping
Gopackage *packages.Package
// a list of struct names that are bound in this package
boundStructs slicer.StringSlicer
// Structs used in this package
parsedStructs map[string]*Struct
// A list of external packages we reference from this package
externalReferences slicer.InterfaceSlicer
}
func newPackage(pkg *packages.Package) *Package {
return &Package{
Gopackage: pkg,
parsedStructs: make(map[string]*Struct),
}
}
func (p *Package) getWailsImportName(file *ast.File) string {
// Scan the imports for the wails v2 import
for _, details := range file.Imports {
if details.Path.Value == `"github.com/wailsapp/wails/v2"` {
if details.Name != nil {
return details.Name.Name
}
// Get the import name from the package
imp := p.getImportByPath("github.com/wailsapp/wails/v2")
if imp != nil {
return imp.Name
}
}
}
return ""
}
func (p *Package) getImportByName(importName string, file *ast.File) *packages.Package {
// Check if the file has aliased the import
for _, imp := range file.Imports {
if imp.Name != nil {
if imp.Name.Name == importName {
// Yes it has. Get the import by path
return p.getImportByPath(imp.Path.Value)
}
}
}
// We need to find which package import has this name
for _, imp := range p.Gopackage.Imports {
if imp.Name == importName {
return imp
}
}
// Looks like this package is outside the project...
return nil
}
func (p *Package) getImportByPath(packagePath string) *packages.Package {
packagePath = strings.Trim(packagePath, "\"")
return p.Gopackage.Imports[packagePath]
}
func (p *Package) getStruct(structName string) *Struct {
return p.parsedStructs[structName]
}
func (p *Package) addStruct(strct *Struct) {
p.parsedStructs[strct.Name] = strct
}
// HasBoundStructs returns true if any of its structs
// are bound
func (p *Package) HasBoundStructs() bool {
for _, strct := range p.parsedStructs {
if strct.IsBound {
return true
}
}
return false
}
// HasDataStructs returns true if any of its structs
// are used as data
func (p *Package) HasDataStructs() bool {
for _, strct := range p.parsedStructs {
if strct.IsUsedAsData {
return true
}
}
return false
}
// ShouldGenerate returns true when this package should be generated
func (p *Package) ShouldGenerate() bool {
return p.HasBoundStructs() || p.HasDataStructs()
}
// DeclarationReferences returns a list of external packages
// we reference from this package
func (p *Package) DeclarationReferences() []string {
var referenceNames slicer.StringSlicer
// Generics can't come soon enough!
p.externalReferences.Each(func(p interface{}) {
referenceNames.Add(p.(*Package).Name)
})
return referenceNames.AsSlice()
}
// addExternalReference saves the given package as an external reference
func (p *Package) addExternalReference(pkg *Package) {
p.externalReferences.AddUnique(pkg)
}
// Structs returns the structs that we want to generate
func (p *Package) Structs() []*Struct {
var result []*Struct
for _, elem := range p.parsedStructs {
result = append(result, elem)
}
return result
}