-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgen_options.go
More file actions
111 lines (103 loc) · 3.85 KB
/
gen_options.go
File metadata and controls
111 lines (103 loc) · 3.85 KB
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
package codegen
import (
"github.com/AndroidGoLab/binder/tools/pkg/parser"
"github.com/AndroidGoLab/binder/tools/pkg/resolver"
)
// GenOptions holds optional parameters for code generation functions.
type GenOptions struct {
Registry *resolver.TypeRegistry
CurrentPkg string // AIDL package of the type being generated
CurrentDef string // fully qualified name of the definition being generated (for nested type resolution)
ImportGraph *ImportGraph
// CycleTypeCallback is called when a type is redirected to a "types"
// sub-package to break an import cycle. The callback receives the
// qualified AIDL name and the types sub-package AIDL name.
CycleTypeCallback func(qualifiedName, typesPkg string)
}
// marshalForType returns the MarshalInfo for a type, using the registry
// from options if available.
func marshalForType(
ts *parser.TypeSpecifier,
opts GenOptions,
) MarshalInfo {
return MarshalForTypeWithRegistry(ts, opts.Registry, opts.CurrentPkg, opts.CurrentDef)
}
// marshalForTypeWithCycleCheck returns the MarshalInfo for a type,
// checking if the type is unresolvable or resolved to any.
// Such types cannot be marshaled/unmarshaled, so the expressions are empty.
//
// Cycle-broken parcelables that were redirected to a "types" sub-package
// are NOT treated as opaque — they have full marshal/unmarshal
// capabilities via the sub-package. Cycle-broken interfaces remain
// opaque because their proxy constructors only exist in the original
// package, not the types sub-package.
func marshalForTypeWithCycleCheck(
ts *parser.TypeSpecifier,
opts GenOptions,
typeRef *TypeRefResolver,
) MarshalInfo {
if typeRef != nil {
if typeRef.IsCycleBroken(ts.Name) {
// Cycle-broken interfaces must stay opaque: their proxy
// constructor (NewXxxProxy) lives in the original package,
// not the types sub-package. Cycle-broken parcelables are
// fine — MarshalParcel/UnmarshalParcel exist in the types
// sub-package.
if typeRef.isInterfaceType(ts.Name) {
return opaqueTypeMarshalInfo
}
}
// If the type would resolve to any (unknown, forward-declared,
// or cycle-broken without a types sub-package), it cannot be
// marshaled/unmarshaled.
if typeRef.isUnresolvableType(ts.Name) {
return opaqueTypeMarshalInfo
}
// Check what the type actually resolves to in Go.
// If it resolves to any, skip marshaling regardless of why.
resolved := typeRef.GoTypeRef(ts)
if isOpaqueGoType(resolved) {
return opaqueTypeMarshalInfo
}
}
return marshalForType(ts, opts)
}
// isOpaqueGoType returns true if the Go type string indicates an opaque
// type that cannot be marshaled (e.g. any, *any).
func isOpaqueGoType(goType string) bool {
// Strip pointer and slice prefixes.
t := goType
for len(t) > 0 && (t[0] == '*' || t[0] == '[') {
if t[0] == '[' {
t = t[1:]
if len(t) > 0 && t[0] == ']' {
t = t[1:]
}
continue
}
t = t[1:]
}
return t == "any"
}
// opaqueTypeMarshalInfo is the marshal info for types that were resolved
// to any due to import cycles. These types cannot be marshaled/
// unmarshaled directly, so the expressions are empty (causing the
// generators to skip these fields).
var opaqueTypeMarshalInfo = MarshalInfo{}
// recursiveFields returns the set of struct fields that need pointer types
// to break recursive type definitions within the same package.
func (opts GenOptions) recursiveFields() *recursiveFieldSet {
return detectRecursiveTypes(opts.Registry, opts.CurrentPkg)
}
// newTypeRefResolver creates a TypeRefResolver from the options and a GoFile.
// If no registry is available, returns nil.
func (opts GenOptions) newTypeRefResolver(goFile *GoFile) *TypeRefResolver {
if opts.Registry == nil {
return nil
}
r := NewTypeRefResolver(opts.Registry, opts.CurrentPkg, goFile)
r.CurrentDef = opts.CurrentDef
r.ImportGraph = opts.ImportGraph
r.CycleTypeCallback = opts.CycleTypeCallback
return r
}