Ejemplo n.º 1
0
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)
}
Ejemplo n.º 2
0
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
}