LEFT | RIGHT |
1 // Copyright 2012 The Go Authors. All rights reserved. | 1 // Copyright 2012 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // This file defines operands and associated operations. | 5 // This file defines operands and associated operations. |
6 | 6 |
7 package types | 7 package types |
8 | 8 |
9 import ( | 9 import ( |
10 "bytes" | 10 "bytes" |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 // Collect embedded struct fields for se
arching the next | 296 // Collect embedded struct fields for se
arching the next |
297 // lower level, but only if we have not
seen a match yet | 297 // lower level, but only if we have not
seen a match yet |
298 // (if we have a match it is either the
desired field or | 298 // (if we have a match it is either the
desired field or |
299 // we have a name collision on the same
level; in either | 299 // we have a name collision on the same
level; in either |
300 // case we don't need to look further). | 300 // case we don't need to look further). |
301 // Embedded fields are always of the for
m T or *T where | 301 // Embedded fields are always of the for
m T or *T where |
302 // T is a named type. If typ appeared mu
ltiple times at | 302 // T is a named type. If typ appeared mu
ltiple times at |
303 // this level, f.Type appears multiple t
imes at the next | 303 // this level, f.Type appears multiple t
imes at the next |
304 // level. | 304 // level. |
305 if f.IsAnonymous && res.mode == invalid
{ | 305 if f.IsAnonymous && res.mode == invalid
{ |
306 » » » » » » var index []int | 306 » » » » » » // Ignore embedded basic types -
only user-defined |
307 » » » » » » index = append(index, e.index...
) // copy e.index | 307 » » » » » » // named types can have methods
or have struct fields. |
308 » » » » » » index = append(index, i) | 308 » » » » » » if t, _ := deref(f.Type).(*Named
Type); t != nil { |
309 » » » » » » next = append(next, embeddedType
{deref(f.Type).(*NamedType), index, e.multiples}) | 309 » » » » » » » var index []int |
| 310 » » » » » » » index = append(index, e.
index...) // copy e.index |
| 311 » » » » » » » index = append(index, i) |
| 312 » » » » » » » next = append(next, embe
ddedType{t, index, e.multiples}) |
| 313 » » » » » » } |
310 } | 314 } |
311 } | 315 } |
312 | 316 |
313 case *Interface: | 317 case *Interface: |
314 // look for a matching method | 318 // look for a matching method |
315 for _, m := range t.Methods { | 319 for _, m := range t.Methods { |
316 if name.IsSame(m.QualifiedName) { | 320 if name.IsSame(m.QualifiedName) { |
317 assert(m.Type != nil) | 321 assert(m.Type != nil) |
318 if !potentialMatch(e.multiples,
value, m.Type) { | 322 if !potentialMatch(e.multiples,
value, m.Type) { |
319 return // name collision | 323 return // name collision |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 case *Struct: | 380 case *Struct: |
377 var next []embeddedType | 381 var next []embeddedType |
378 for i, f := range t.Fields { | 382 for i, f := range t.Fields { |
379 if name.IsSame(f.QualifiedName) { | 383 if name.IsSame(f.QualifiedName) { |
380 return lookupResult{variable, f.Type, []int{i}} | 384 return lookupResult{variable, f.Type, []int{i}} |
381 } | 385 } |
382 if f.IsAnonymous { | 386 if f.IsAnonymous { |
383 // Possible optimization: If the embedded type | 387 // Possible optimization: If the embedded type |
384 // is a pointer to the current type we could | 388 // is a pointer to the current type we could |
385 // ignore it. | 389 // ignore it. |
386 » » » » next = append(next, embeddedType{deref(f.Type).(
*NamedType), []int{i}, false}) | 390 » » » » // Ignore embedded basic types - only user-defin
ed |
| 391 » » » » // named types can have methods or have struct f
ields. |
| 392 » » » » if t, _ := deref(f.Type).(*NamedType); t != nil
{ |
| 393 » » » » » next = append(next, embeddedType{t, []in
t{i}, false}) |
| 394 » » » » } |
387 } | 395 } |
388 } | 396 } |
389 if len(next) > 0 { | 397 if len(next) > 0 { |
390 return lookupFieldBreadthFirst(next, name) | 398 return lookupFieldBreadthFirst(next, name) |
391 } | 399 } |
392 | 400 |
393 case *Interface: | 401 case *Interface: |
394 for _, m := range t.Methods { | 402 for _, m := range t.Methods { |
395 if name.IsSame(m.QualifiedName) { | 403 if name.IsSame(m.QualifiedName) { |
396 return lookupResult{value, m.Type, nil} | 404 return lookupResult{value, m.Type, nil} |
397 } | 405 } |
398 } | 406 } |
399 } | 407 } |
400 | 408 |
401 // not found | 409 // not found |
402 return lookupResult{mode: invalid} | 410 return lookupResult{mode: invalid} |
403 } | 411 } |
LEFT | RIGHT |