88 "go/token"
99 "strings"
1010 "path/filepath"
11+ "github.com/revel/cmd/logger"
1112)
1213
1314type (
@@ -31,14 +32,21 @@ func (s *SourceInfoProcessor) processPackage(p *packages.Package) (sourceInfo *m
3132 strings .Contains (p .PkgPath , "/tests/" )
3233 methodMap = map [string ][]* model.MethodSpec {}
3334 )
35+ localImportMap := map [string ]string {}
36+ log := s .sourceProcessor .log .New ("package" , p .PkgPath )
37+ log .Info ("Processing package" )
3438 for _ , tree := range p .Syntax {
3539 for _ , decl := range tree .Decls {
40+
3641 s .sourceProcessor .packageMap [p .PkgPath ] = filepath .Dir (p .Fset .Position (decl .Pos ()).Filename )
37- //println("*** checking", p.Fset.Position(decl.Pos()).Filename)
42+ if ! s .addImport (decl , p , localImportMap , log ) {
43+ continue
44+ }
3845 spec , found := s .getStructTypeDecl (decl , p .Fset )
46+ //log.Info("Checking file","filename", p.Fset.Position(decl.Pos()).Filename,"found",found)
3947 if found {
4048 if isController || isTest {
41- controllerSpec := s .getControllerSpec (spec , p )
49+ controllerSpec := s .getControllerSpec (spec , p , localImportMap )
4250 sourceInfo .StructSpecs = append (sourceInfo .StructSpecs , controllerSpec )
4351 }
4452 } else {
@@ -56,7 +64,7 @@ func (s *SourceInfoProcessor) processPackage(p *packages.Package) (sourceInfo *m
5664 // return one result
5765 if m , receiver := s .getControllerFunc (funcDecl , p ); m != nil {
5866 methodMap [receiver ] = append (methodMap [receiver ], m )
59- s . sourceProcessor . log .Info ("Added method map to " , "receiver" , receiver , "method" , m .Name )
67+ log .Info ("Added method map to " , "receiver" , receiver , "method" , m .Name )
6068 }
6169 }
6270 // Check for validation
@@ -271,7 +279,7 @@ func (s *SourceInfoProcessor) getControllerFunc(funcDecl *ast.FuncDecl, p *packa
271279 }
272280 return
273281}
274- func (s * SourceInfoProcessor ) getControllerSpec (spec * ast.TypeSpec , p * packages.Package ) (controllerSpec * model.TypeInfo ) {
282+ func (s * SourceInfoProcessor ) getControllerSpec (spec * ast.TypeSpec , p * packages.Package , localImportMap map [ string ] string ) (controllerSpec * model.TypeInfo ) {
275283 structType := spec .Type .(* ast.StructType )
276284
277285 // At this point we know it's a type declaration for a struct.
@@ -282,6 +290,7 @@ func (s *SourceInfoProcessor) getControllerSpec(spec *ast.TypeSpec, p *packages.
282290 ImportPath : p .PkgPath ,
283291 PackageName : p .Name ,
284292 }
293+ log := s .sourceProcessor .log .New ("file" , p .Fset .Position (spec .Pos ()).Filename , "position" , p .Fset .Position (spec .Pos ()).Line )
285294 for _ , field := range structType .Fields .List {
286295 // If field.Names is set, it's not an embedded type.
287296 if field .Names != nil {
@@ -329,9 +338,12 @@ func (s *SourceInfoProcessor) getControllerSpec(spec *ast.TypeSpec, p *packages.
329338 importPath = p .PkgPath
330339 } else {
331340 var ok bool
332- if importPath , ok = s .sourceProcessor .importMap [pkgName ]; ! ok {
333- s .sourceProcessor .log .Error ("Error: Failed to find import path for " , "package" , pkgName , "type" , typeName , "map" , s .sourceProcessor .importMap )
334- continue
341+ if importPath , ok = localImportMap [pkgName ]; ! ok {
342+ log .Debug ("Debug: Unusual, failed to find package locally " , "package" , pkgName , "type" , typeName , "map" , s .sourceProcessor .importMap , "usedin" , )
343+ if importPath , ok = s .sourceProcessor .importMap [pkgName ]; ! ok {
344+ log .Error ("Error: Failed to find import path for " , "package" , pkgName , "type" , typeName , "map" , s .sourceProcessor .importMap , "usedin" , )
345+ continue
346+ }
335347 }
336348 }
337349
@@ -376,4 +388,37 @@ func (s *SourceInfoProcessor) getFuncName(funcDecl *ast.FuncDecl) string {
376388 prefix += "."
377389 }
378390 return prefix + funcDecl .Name .Name
391+ }
392+ func (s * SourceInfoProcessor ) addImport (decl ast.Decl , p * packages.Package , localImportMap map [string ]string , log logger.MultiLogger ) (shouldContinue bool ) {
393+ shouldContinue = true
394+ genDecl , ok := decl .(* ast.GenDecl )
395+ if ! ok {
396+ return
397+ }
398+
399+ if genDecl .Tok == token .IMPORT {
400+ shouldContinue = false
401+ for _ , spec := range genDecl .Specs {
402+ importSpec := spec .(* ast.ImportSpec )
403+ //fmt.Printf("*** import specification %#v\n", importSpec)
404+ var pkgAlias string
405+ if importSpec .Name != nil {
406+ pkgAlias = importSpec .Name .Name
407+ if pkgAlias == "_" {
408+ continue
409+ }
410+ }
411+ quotedPath := importSpec .Path .Value // e.g. "\"sample/app/models\""
412+ fullPath := quotedPath [1 : len (quotedPath ) - 1 ] // Remove the quotes
413+ if pkgAlias == "" {
414+ pkgAlias = fullPath
415+ if index := strings .LastIndex (pkgAlias , "/" ); index > 0 {
416+ pkgAlias = pkgAlias [index + 1 :]
417+ }
418+ }
419+ localImportMap [pkgAlias ] = fullPath
420+ }
421+
422+ }
423+ return
379424}
0 commit comments