github.com/blp1526/goa@v1.4.0/goagen/codegen/import_spec.go (about)

     1  package codegen
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/goadesign/goa/design"
     7  )
     8  
     9  // ImportSpec defines a generated import statement.
    10  type ImportSpec struct {
    11  	Name string
    12  	Path string
    13  }
    14  
    15  // NewImport creates an import spec.
    16  func NewImport(name, path string) *ImportSpec {
    17  	return &ImportSpec{Name: name, Path: path}
    18  }
    19  
    20  // SimpleImport creates an import with no explicit path component.
    21  func SimpleImport(path string) *ImportSpec {
    22  	return &ImportSpec{Path: path}
    23  }
    24  
    25  // Code returns the Go import statement for the ImportSpec.
    26  func (s *ImportSpec) Code() string {
    27  	if len(s.Name) > 0 {
    28  		return fmt.Sprintf(`%s "%s"`, s.Name, s.Path)
    29  	}
    30  	return fmt.Sprintf(`"%s"`, s.Path)
    31  }
    32  
    33  // AttributeImports constructs a new ImportsSpec slice from an existing slice and adds in imports specified in
    34  // struct:field:type Metadata tags.
    35  func AttributeImports(att *design.AttributeDefinition, imports []*ImportSpec, seen []*design.AttributeDefinition) []*ImportSpec {
    36  
    37  	for _, a := range seen {
    38  		if att == a {
    39  			return imports
    40  		}
    41  	}
    42  	seen = append(seen, att)
    43  
    44  	if tname, ok := att.Metadata["struct:field:type"]; ok {
    45  		if len(tname) > 1 {
    46  			tagImp := SimpleImport(tname[1])
    47  			impSlice := []*ImportSpec{tagImp}
    48  			imports = appendImports(imports, impSlice)
    49  		}
    50  	}
    51  
    52  	switch t := att.Type.(type) {
    53  	case *design.UserTypeDefinition:
    54  		return appendImports(imports, AttributeImports(t.AttributeDefinition, imports, seen))
    55  	case *design.MediaTypeDefinition:
    56  		return appendImports(imports, AttributeImports(t.AttributeDefinition, imports, seen))
    57  	case design.Object:
    58  		t.IterateAttributes(func(n string, t *design.AttributeDefinition) error {
    59  			imports = appendImports(imports, AttributeImports(t, imports, seen))
    60  			return nil
    61  		})
    62  		return imports
    63  	case *design.Array:
    64  		return appendImports(imports, AttributeImports(t.ElemType, imports, seen))
    65  	case *design.Hash:
    66  		imports = appendImports(imports, AttributeImports(t.KeyType, imports, seen))
    67  		return appendImports(imports, AttributeImports(t.ElemType, imports, seen))
    68  	}
    69  
    70  	return imports
    71  }
    72  
    73  // appendImports appends two ImportSpec slices and preserves uniqueness
    74  func appendImports(i, a []*ImportSpec) []*ImportSpec {
    75  	for _, v := range a {
    76  		contains := false
    77  		for _, att := range i {
    78  			if att.Path == v.Path {
    79  				contains = true
    80  				break
    81  			}
    82  		}
    83  		if contains != true {
    84  			i = append(i, v)
    85  		}
    86  	}
    87  	return i
    88  }