func goFileInfo()

in language/go/fileinfo.go [291:384]


func goFileInfo(path, rel string) fileInfo {
	info := fileNameInfo(path)
	fset := token.NewFileSet()
	pf, err := parser.ParseFile(fset, info.path, nil, parser.ImportsOnly|parser.ParseComments)
	if err != nil {
		log.Printf("%s: error reading go file: %v", info.path, err)
		return info
	}

	info.packageName = pf.Name.Name
	if info.isTest && strings.HasSuffix(info.packageName, "_test") {
		info.packageName = info.packageName[:len(info.packageName)-len("_test")]
		info.isExternalTest = true
	}

	importsEmbed := false
	for _, decl := range pf.Decls {
		d, ok := decl.(*ast.GenDecl)
		if !ok {
			continue
		}
		for _, dspec := range d.Specs {
			spec, ok := dspec.(*ast.ImportSpec)
			if !ok {
				continue
			}
			quoted := spec.Path.Value
			path, err := strconv.Unquote(quoted)
			if err != nil {
				log.Printf("%s: error reading go file: %v", info.path, err)
				continue
			}

			if path == "C" {
				if info.isTest {
					log.Printf("%s: warning: use of cgo in test not supported", info.path)
				}
				info.isCgo = true
				cg := spec.Doc
				if cg == nil && len(d.Specs) == 1 {
					cg = d.Doc
				}
				if cg != nil {
					if err := saveCgo(&info, rel, cg); err != nil {
						log.Printf("%s: error reading go file: %v", info.path, err)
					}
				}
				continue
			}
			if path == "embed" {
				importsEmbed = true
			}
			info.imports = append(info.imports, path)
		}
	}

	tags, err := readTags(info.path)
	if err != nil {
		log.Printf("%s: error reading go file: %v", info.path, err)
		return info
	}
	info.tags = tags

	if importsEmbed {
		pf, err = parser.ParseFile(fset, info.path, nil, parser.ParseComments)
		if err != nil {
			log.Printf("%s: error reading go file: %v", info.path, err)
			return info
		}
		for _, cg := range pf.Comments {
			for _, c := range cg.List {
				if !strings.HasPrefix(c.Text, "//go:embed") {
					continue
				}
				args := c.Text[len("//go:embed"):]
				p := c.Pos()
				for len(args) > 0 && (args[0] == ' ' || args[0] == '\t') {
					args = args[1:]
					p++
				}
				args = strings.TrimSpace(args) // trim right side
				pos := fset.Position(p)
				embeds, err := parseGoEmbed(args, pos)
				if err != nil {
					log.Printf("%v: parsing //go:embed directive: %v", pos, err)
					continue
				}
				info.embeds = append(info.embeds, embeds...)
			}
		}
	}

	return info
}