Skip to content

Instantly share code, notes, and snippets.

@acsellers
Created September 30, 2013 21:45
Show Gist options
  • Save acsellers/6770765 to your computer and use it in GitHub Desktop.
Save acsellers/6770765 to your computer and use it in GitHub Desktop.
TypesThatResemble
// TypesThatResemble returns all types that (directly or indirectly) embed a
// type that has the same name as the t arget type, but have a different
// import path
// e.g. "github.com/acsellers/yield.Controller" vs "github.com/robfig/revel.Controller"
func (s *SourceInfo) TypesThatResemble(targetType string) (filtered []*TypeInfo) {
var (
nodeQueue = []string{}
processed []string
targetTypeName = targetType[strings.LastIndex(targetType, "."):]
)
// First, find resembling struct, so look through all known structs
for _, spec := range s.StructSpecs {
// Look through the embedded types to see if any of the types resemble
for _, embeddedType := range spec.embeddedTypes {
// If so, add this type's simple name to the nodeQueue, and its spec to
// the filtered list.
if embeddedType.String() == targetType ||
strings.HasSuffix(embeddedType.String(), targetTypeName) {
nodeQueue = append(nodeQueue, spec.String())
filtered = append(filtered, spec)
break
}
}
}
// Then, find all the types that embed the types that embed our resembling
// structs
for len(nodeQueue) > 0 {
controllerSimpleName := nodeQueue[0]
nodeQueue = nodeQueue[1:]
processed = append(processed, controllerSimpleName)
// Look through all known structs.
for _, spec := range s.StructSpecs {
// If this one has been processed or is already in nodeQueue, then skip it.
if revel.ContainsString(processed, spec.String()) ||
revel.ContainsString(nodeQueue, spec.String()) {
continue
}
// Look through the embedded types to see if the current type is among them.
for _, embeddedType := range spec.embeddedTypes {
// If so, add this type's simple name to the nodeQueue, and its spec to
// the filtered list.
if controllerSimpleName == embeddedType.String() {
nodeQueue = append(nodeQueue, spec.String())
filtered = append(filtered, spec)
break
}
}
}
}
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment