@@ -82,19 +82,42 @@ func (r *Repository) SetNode(id Identity, typ NodeType) *Node {
8282
8383func calOffset (ref , dep FileLine ) int {
8484 refLine := dep .Line - ref .Line
85- if refLine < 0 {
86- return - 1
85+ if refLine <= 0 {
86+ return 0
8787 }
8888 return refLine
8989}
9090
91- func (r * Repository ) AddRelation (node * Node , dep Identity , depFl FileLine ) {
91+ func (r * Repository ) AddRelation (node * Node , dep Identity , depFl FileLine , kinds ... RelationKind ) {
9292 line := calOffset (node .FileLine (), depFl )
93- node .Dependencies = InsertRelation (node .Dependencies , Relation {
94- Identity : dep ,
95- Kind : DEPENDENCY ,
96- Line : line ,
97- })
93+ for _ , kind := range kinds {
94+ if kind == DEPENDENCY {
95+ node .Dependencies = InsertRelation (node .Dependencies , Relation {
96+ Identity : dep ,
97+ Kind : DEPENDENCY ,
98+ Line : line ,
99+ })
100+ } else if kind == IMPLEMENT {
101+ node .Implements = InsertRelation (node .Implements , Relation {
102+ Identity : dep ,
103+ Kind : IMPLEMENT ,
104+ Line : line ,
105+ })
106+ } else if kind == INHERIT {
107+ node .Inherits = InsertRelation (node .Inherits , Relation {
108+ Identity : dep ,
109+ Kind : INHERIT ,
110+ Line : line ,
111+ })
112+ } else if kind == GROUP {
113+ node .Groups = InsertRelation (node .Groups , Relation {
114+ Identity : dep ,
115+ Kind : GROUP ,
116+ Line : line ,
117+ })
118+ }
119+ }
120+
98121 key := dep .Full ()
99122 nd , ok := r .Graph [key ]
100123 if ! ok {
@@ -104,11 +127,16 @@ func (r *Repository) AddRelation(node *Node, dep Identity, depFl FileLine) {
104127 }
105128 r .Graph [key ] = nd
106129 }
107- nd .References = InsertRelation (nd .References , Relation {
108- Identity : node .Identity ,
109- Kind : REFERENCE ,
110- Line : line ,
111- })
130+ for _ , kind := range kinds {
131+ if kind == DEPENDENCY {
132+ nd .References = InsertRelation (nd .References , Relation {
133+ Identity : node .Identity ,
134+ Kind : DEPENDENCY ,
135+ Line : line ,
136+ })
137+ }
138+ }
139+
112140 if f := r .GetFunction (dep ); f != nil {
113141 nd .Type = FUNC
114142 } else if t := r .GetType (dep ); t != nil {
@@ -137,36 +165,46 @@ func (r *Repository) BuildGraph() error {
137165 for _ , f := range pkg .Functions {
138166 n := r .SetNode (f .Identity , FUNC )
139167 for _ , dep := range f .FunctionCalls {
140- r .AddRelation (n , dep .Identity , dep .FileLine )
168+ r .AddRelation (n , dep .Identity , dep .FileLine , DEPENDENCY )
141169 }
142170 for _ , dep := range f .MethodCalls {
143- r .AddRelation (n , dep .Identity , dep .FileLine )
171+ r .AddRelation (n , dep .Identity , dep .FileLine , DEPENDENCY )
144172 }
145173 for _ , dep := range f .Types {
146- r .AddRelation (n , dep .Identity , dep .FileLine )
174+ r .AddRelation (n , dep .Identity , dep .FileLine , DEPENDENCY )
147175 }
176+ // NOTICE: We regard the receiver of a method as a dependency of the method
148177 if f .Receiver != nil {
149- r .AddRelation (n , f .Receiver .Type , n .FileLine ())
178+ r .AddRelation (n , f .Receiver .Type , n .FileLine (), DEPENDENCY )
150179 }
151180 for _ , dep := range f .GlobalVars {
152- r .AddRelation (n , dep .Identity , dep .FileLine )
181+ r .AddRelation (n , dep .Identity , dep .FileLine , DEPENDENCY )
153182 }
154183 }
155184
156185 for _ , t := range pkg .Types {
157186 n := r .SetNode (t .Identity , TYPE )
158187 for _ , dep := range t .SubStruct {
159- r .AddRelation (n , dep .Identity , dep .FileLine )
188+ r .AddRelation (n , dep .Identity , dep .FileLine , DEPENDENCY )
160189 }
161190 for _ , dep := range t .InlineStruct {
162- r .AddRelation (n , dep .Identity , dep .FileLine )
191+ r .AddRelation (n , dep .Identity , dep .FileLine , INHERIT )
192+ }
193+ for _ , dep := range t .Implements {
194+ r .AddRelation (n , dep , n .FileLine (), IMPLEMENT )
163195 }
164196 }
165197
166198 for _ , v := range pkg .Vars {
167199 n := r .SetNode (v .Identity , VAR )
168200 if v .Type != nil {
169- r .AddRelation (n , * v .Type , v .FileLine )
201+ r .AddRelation (n , * v .Type , v .FileLine , DEPENDENCY )
202+ }
203+ for _ , dep := range v .Dependencies {
204+ r .AddRelation (n , dep .Identity , dep .FileLine , DEPENDENCY )
205+ }
206+ for _ , dep := range v .Groups {
207+ r .AddRelation (n , dep , n .FileLine (), GROUP )
170208 }
171209 }
172210 }
@@ -180,8 +218,12 @@ type RelationKind string
180218const (
181219 // DEPENDENCY: the target node is a dependency of the current node
182220 DEPENDENCY RelationKind = "Dependency"
183- // REFERENCE: the target node is a reference of the current node
184- REFERENCE RelationKind = "Reference"
221+ // IMPLEMENT: the target node is implemented by the current node
222+ IMPLEMENT RelationKind = "Implement"
223+ // INHERIT: the target node is inherited by the current node
224+ INHERIT RelationKind = "Inherit"
225+ // GROUPT: the target is in same definition group of nodes, like `const(a=1,b=2)`
226+ GROUP RelationKind = "Group"
185227)
186228
187229// Relation between two nodes
@@ -191,7 +233,7 @@ type Relation struct {
191233 // target node
192234 Identity
193235 // start line-offset of the target token related to the current node's codes
194- Line int
236+ Line int `json:",omitempty"`
195237 // information about this relation
196238 Desc * string `json:",omitempty"`
197239 // related codes representing this relation, comming from current node's codes
@@ -273,9 +315,15 @@ type Node struct {
273315 // Node Type, must be one of FUNC, TYPE, VAR
274316 Type NodeType
275317 // other nodes that depends on this node
276- Dependencies []Relation
277- // other nodes that reference this node
278- References []Relation
318+ Dependencies []Relation `json:",omitempty"`
319+ // other nodes that references this node
320+ References []Relation `json:",omitempty"`
321+ // other nodes this node implements
322+ Implements []Relation `json:",omitempty"`
323+ // other nodes this node inherits
324+ Inherits []Relation `json:",omitempty"`
325+ // other nodes in the same definition group
326+ Groups []Relation `json:",omitempty"`
279327 // the repo that this node belongs to
280328 Repo * Repository `json:"-"`
281329}
0 commit comments