func mLintCheckTypes(kind string, m *mLint) { files := []*ast.File{m.af} if m.v.dir != "" { pkg, pkgs, _ := parsePkg(m.fset, m.v.dir, parser.ParseComments) if pkg == nil { for _, p := range pkgs { if f := p.Files[m.v.fn]; f != nil { pkg = p break } } if pkg == nil { return } } for fn, f := range pkg.Files { if fn != m.v.fn { files = append(files, f) } } } ctx := types.Config{ Error: func(err error) { s := mLintErrPat.FindStringSubmatch(err.Error()) if len(s) == 5 { line, _ := strconv.Atoi(s[2]) column, _ := strconv.Atoi(s[3]) m.report(mLintReport{ Fn: s[1], Row: line - 1, Col: column - 1, Message: s[4], Kind: kind, }) } }, } ctx.Check(m.v.dir, m.fset, files, nil) }
func (w *PkgWalker) Import(parentDir string, name string, conf *PkgConfig) (pkg *types.Package, err error) { /*defer func() { err := recover() if err != nil && typeVerbose { log.Println(err) } }()*/ if strings.HasPrefix(name, ".") && parentDir != "" { name = filepath.Join(parentDir, name) } pkg = w.imported[name] if pkg != nil { if pkg == &w.importing { return nil, fmt.Errorf("cycle importing package %q", name) } return pkg, nil } if typeVerbose { log.Println("parser pkg", name) } var bp *build.Package if filepath.IsAbs(name) { bp, err = w.context.ImportDir(name, 0) } else { bp, err = w.context.Import(name, "", 0) } checkName := name if bp.ImportPath == "." { checkName = bp.Name } else { checkName = bp.ImportPath } if err != nil { return nil, err //if _, nogo := err.(*build.NoGoError); nogo { // return //} //return //log.Fatalf("pkg %q, dir %q: ScanDir: %v", name, info.Dir, err) } filenames := append(append([]string{}, bp.GoFiles...), bp.CgoFiles...) if conf.WithTestFiles { filenames = append(filenames, bp.TestGoFiles...) } if name == "runtime" { n := fmt.Sprintf("zgoos_%s.go", w.context.GOOS) if !contains(filenames, n) { filenames = append(filenames, n) } n = fmt.Sprintf("zgoarch_%s.go", w.context.GOARCH) if !contains(filenames, n) { filenames = append(filenames, n) } } parserFiles := func(filenames []string, cursor *FileCursor, includeDefault bool) (files []*ast.File) { foundCursor := false for _, file := range filenames { var f *ast.File if cursor != nil && cursor.fileName == file { f, err = w.parseFile(bp.Dir, file, cursor.src) cursor.pos = token.Pos(w.fset.File(f.Pos()).Base()) + token.Pos(cursor.cursorPos) cursor.fileDir = bp.Dir foundCursor = true } else { f, err = w.parseFile(bp.Dir, file, nil) } if err != nil && typeVerbose { log.Printf("error parsing package %s: %s\n", name, err) } files = append(files, f) } if cursor != nil && includeDefault && !foundCursor { f, err := w.parseFile(bp.Dir, cursor.fileName, cursor.src) if err != nil && typeVerbose { log.Printf("error parsing cursor package %s: %s\n", cursor.fileName, err) } else { cursor.pos = token.Pos(w.fset.File(f.Pos()).Base()) + token.Pos(cursor.cursorPos) cursor.fileDir = bp.Dir } } return } files := parserFiles(filenames, conf.Cursor, true) xfiles := parserFiles(bp.XTestGoFiles, conf.Cursor, false) typesConf := types.Config{ IgnoreFuncBodies: conf.IgnoreFuncBodies, FakeImportC: true, Packages: w.gcimporter, Import: func(imports map[string]*types.Package, name string) (pkg *types.Package, err error) { if pkg != nil { return pkg, nil } if conf.AllowBinary && w.isBinaryPkg(name) { pkg = w.gcimporter[name] if pkg != nil && pkg.Complete() { return } pkg, err = gcimporter.Import(imports, name) if pkg != nil && pkg.Complete() { w.gcimporter[name] = pkg return } } return w.Import(bp.Dir, name, &PkgConfig{IgnoreFuncBodies: true, AllowBinary: true, WithTestFiles: false}) }, Error: func(err error) { if typeVerbose { log.Println(err) } }, } if pkg == nil { pkg, err = typesConf.Check(checkName, w.fset, files, conf.Info) } w.imported[name] = pkg if len(xfiles) > 0 { xpkg, _ := typesConf.Check(checkName+"_test", w.fset, xfiles, conf.Info) w.imported[checkName+"_test"] = xpkg } return }