Example #1
0
//ParsePackage parses package and filling info structure.
//It's filling info about all internal packages even if they
//are not imported in the root package.
func ParsePackage(pkgName string, info *types.Info) (*types.Package, *token.FileSet, error) {
	collectImporter := new(importer.CollectInfoImporter)
	collectImporter.Info = info

	var resultPkg *types.Package
	var resultFset *token.FileSet
	parsedPackages := make(map[string]bool)

	notParsedPackage := pkgName
	for len(notParsedPackage) > 0 {
		collectImporter.Pkg = notParsedPackage
		pkg, fset, err := collectImporter.Collect()
		if err != nil {
			return nil, nil, err
		}

		//Filling results only from first package
		//that was passed as argument to function
		if resultPkg == nil {
			resultPkg = pkg
			resultFset = fset
		}
		parsedPackages[notParsedPackage] = true

		//Searching for a new package that was not parsed before
		notParsedPackage = ""
		files, err := fs.GetUnusedSources(pkgName, fset)
		if err != nil {
			return nil, nil, err
		}
		for _, f := range files {
			newNotParsedPackage := fs.GetPackagePath(f)
			if !parsedPackages[newNotParsedPackage] {
				notParsedPackage = newNotParsedPackage
				break
			} else {
				util.Info("package %s has been already parsed, however %s file is still unused", newNotParsedPackage, f)
			}
		}
	}

	return resultPkg, resultFset, nil
}
Example #2
0
func isUsed(def *Definition) bool {
	used := true

	if len(def.Usages) == 0 {
		used = false
	} else {
		//Checking pathes of usages to not count internal
		hasExternalUsages := false
		util.Debug("checking [%s]", def.Name)
		for _, u := range def.Usages {
			pkgPath := ""
			if def.Pkg != nil {
				pkgPath = def.Pkg.Path()
			} else if dotIdx := strings.LastIndex(def.Name, "."); dotIdx >= 0 {
				pkgPath = def.Name[0:dotIdx]
			}
			util.Debug("checking [%v]", u.Pos)
			if u.Pos.IsValid() && fs.GetPackagePath(u.Pos.Filename) != pkgPath {
				hasExternalUsages = true
				break
			}
		}
		used = hasExternalUsages
	}

	if !used {
		//Check all interfaces
		for _, i := range def.Interfaces {
			if isUsed(i) {
				used = true
				break
			}
		}
	}
	return used
}