-
Notifications
You must be signed in to change notification settings - Fork 60
/
metainfo.go
247 lines (205 loc) · 6.19 KB
/
metainfo.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
package meta
import (
"strings"
"github.com/VKCOM/noverify/src/types"
)
type FuncFlags uint8
const (
FuncStatic FuncFlags = 1 << iota
FuncPure
FuncAbstract
FuncFinal
// FuncFromAnnotation is set if the function is described in the class annotation.
FuncFromAnnotation
)
type PropertyFlags uint8
const (
// PropFromAnnotation is set if the property is described in the class annotation.
PropFromAnnotation PropertyFlags = 1 << iota
)
type PackageInfo struct {
Name string
Internal bool
}
type DeprecationInfo struct {
Deprecated bool
Removed bool
Reason string
Replacement string
Since string
RemovedReason string
}
func (i *DeprecationInfo) Append(other DeprecationInfo) {
if !i.Deprecated {
i.Deprecated = other.Deprecated
}
if !i.Removed {
i.Removed = other.Removed
}
if i.Replacement == "" {
i.Replacement = other.Replacement
}
if i.Since == "" {
i.Since = other.Since
}
if i.RemovedReason == "" {
i.RemovedReason = other.RemovedReason
}
i.Reason = other.Reason
}
func (i DeprecationInfo) WithDeprecationNote() bool {
return i.Reason != "" || i.Replacement != "" || i.Since != "" || i.RemovedReason != ""
}
func (i DeprecationInfo) String() (res string) {
parts := make([]string, 0, 3)
if i.Since != "" {
parts = append(parts, "since: "+i.Since)
}
if i.Reason != "" {
reason := strings.TrimRight(i.Reason, ".!,")
parts = append(parts, "reason: "+reason)
}
if i.Replacement != "" {
parts = append(parts, "use "+i.Replacement+" instead")
}
if i.RemovedReason != "" {
parts = append(parts, "removed: "+i.RemovedReason)
}
return strings.Join(parts, ", ")
}
type AccessLevel int
const (
Public AccessLevel = iota
Protected
Private
)
func (l AccessLevel) String() string {
switch l {
case Public:
return "public"
case Protected:
return "protected"
case Private:
return "private"
}
panic("Invalid access level")
}
// PerFile contains all meta information about the specified file
type PerFile struct {
Traits ClassesMap
Classes ClassesMap
Functions FunctionsMap
Constants ConstantsMap
}
type FuncParam struct {
IsRef bool
Name string
Typ types.Map
}
type FuncInfo struct {
Pos ElementPosition
Name string
Params []FuncParam
MinParamsCnt int
Typ types.Map
AccessLevel AccessLevel
Flags FuncFlags
ExitFlags int // if function has exit/die/throw, then ExitFlags will be <> 0
Internal bool
DeprecationInfo
}
func (info *FuncInfo) IsStatic() bool { return info.Flags&FuncStatic != 0 }
func (info *FuncInfo) IsAbstract() bool { return info.Flags&FuncAbstract != 0 }
func (info *FuncInfo) IsPure() bool { return info.Flags&FuncPure != 0 }
func (info *FuncInfo) IsFromAnnotation() bool { return info.Flags&FuncFromAnnotation != 0 }
func (info *FuncInfo) IsFinal() bool { return info.Flags&FuncFinal != 0 }
func (info *FuncInfo) IsDeprecated() bool { return info.Deprecated }
type OverrideType int
const (
// OverrideArgType means that return type of a function is the same as the type of the argument
OverrideArgType OverrideType = iota
// OverrideElementType means that return type of a function is the same as the type of an element of the argument
OverrideElementType
// OverrideClassType means that return type of a function is the same as the type represented by the class name.
OverrideClassType
// OverrideNullableClassType means that return type of a function is the same as the type represented by the class name, and is also nullable.
OverrideNullableClassType
)
type OverrideProperties int
const (
// NotNull means that the null type will be removed from the resulting type.
NotNull OverrideProperties = 1 << iota
// NotFalse means that the false type will be removed from the resulting type.
NotFalse
// ArrayOf means that the type will be converted to an array of elements of that type.
ArrayOf
)
// FuncInfoOverride defines return type overrides based on their parameter types.
// For example, \array_slice($arr) returns type of element (OverrideElementType) of the ArgNum=0
type FuncInfoOverride struct {
OverrideType OverrideType
Properties OverrideProperties
ArgNum int
}
type PropertyInfo struct {
Pos ElementPosition
Typ types.Map
AccessLevel AccessLevel
Flags PropertyFlags
}
func (info *PropertyInfo) IsFromAnnotation() bool { return info.Flags&PropFromAnnotation != 0 }
type ConstInfo struct {
Pos ElementPosition
Typ types.Map
AccessLevel AccessLevel
Value ConstValue
}
type ClassFlags uint8
const (
ClassAbstract ClassFlags = 1 << iota
ClassFinal
ClassShape
ClassInterface
)
type ClassInfo struct {
Pos ElementPosition
Name string
Flags ClassFlags
Parent string
ParentInterfaces []string // interfaces allow multiple inheritance
Traits map[string]struct{}
Interfaces map[string]struct{}
Methods FunctionsMap
Properties PropertiesMap // both instance and static properties are inside. Static properties have "$" prefix
Constants ConstantsMap
Mixins []string
PackageInfo
}
func (info *ClassInfo) IsAbstract() bool { return info.Flags&ClassAbstract != 0 }
func (info *ClassInfo) IsFinal() bool { return info.Flags&ClassFinal != 0 }
func (info *ClassInfo) IsShape() bool { return info.Flags&ClassShape != 0 }
func (info *ClassInfo) IsInterface() bool { return info.Flags&ClassInterface != 0 }
// TODO: rename it; it's not only class-related.
type ClassParseState struct {
Info *Info
IsTrait bool
IsInterface bool
Namespace string
FunctionUses map[string]string
Uses map[string]string
CurrentFile string
CurrentClass string
CurrentParentClass string
CurrentParentInterfaces []string // interfaces allow for multiple inheritance...
CurrentFunction string // current method or function name
}
type FunctionsOverrideMap map[string]FuncInfoOverride
type PropertiesMap map[string]PropertyInfo
type ConstantsMap map[string]ConstInfo
type ElementPosition struct {
Filename string
Line int32
EndLine int32
Character int32
Length int32 // body length
}