func parseRow()

in internal/symbol/apigodoc.go [180:268]


func parseRow(s string) (vr versionedRow, ok bool) {
	if !strings.HasPrefix(s, "pkg ") {
		// Skip comments, blank lines, etc.
		return
	}
	rest := s[len("pkg "):]
	endPkg := strings.IndexFunc(rest, func(r rune) bool {
		return !(unicode.IsLetter(r) || r == '.' || r == '/' || r == '-' || unicode.IsDigit(r))
	})
	if endPkg == -1 {
		return
	}
	vr.pkg, rest = rest[:endPkg], rest[endPkg:]
	if !strings.HasPrefix(rest, ", ") {
		// If the part after the pkg name isn't ", ", then it's a OS/ARCH-dependent line of the form:
		//   pkg syscall (darwin-amd64), const ImplementsGetwd = false
		// We skip those for now.
		return
	}
	rest = rest[len(", "):]
	switch {
	case strings.HasPrefix(rest, "type "):
		rest = rest[len("type "):]
		sp := strings.IndexByte(rest, ' ')
		if sp == -1 {
			return
		}
		vr.name, rest = rest[:sp], rest[sp+1:]
		switch {
		case strings.HasPrefix(rest, "struct, "):
			rest = rest[len("struct, "):]
			if i := strings.IndexByte(rest, ' '); i != -1 {
				vr.kind = "field"
				vr.structName = vr.name
				vr.name = rest[:i]
				return vr, true
			}
		case strings.HasPrefix(rest, "interface, "):
			rest = rest[len("interface, "):]
			if i := strings.IndexByte(rest, '('); i != -1 {
				vr.kind = "method"
				vr.recv = vr.name
				vr.name = rest[:i]
				return vr, true
			}
		default:
			vr.kind = "type"
			return vr, true
		}
	case strings.HasPrefix(rest, "const "):
		vr.kind = "const"
		rest = rest[len("const "):]
		if i := strings.IndexByte(rest, ' '); i != -1 {
			vr.name = rest[:i]
			return vr, true
		}
	case strings.HasPrefix(rest, "var "):
		vr.kind = "var"
		rest = rest[len("var "):]
		if i := strings.IndexByte(rest, ' '); i != -1 {
			vr.name = rest[:i]
			return vr, true
		}
	case strings.HasPrefix(rest, "func "):
		vr.kind = "func"
		rest = rest[len("func "):]
		if i := strings.IndexByte(rest, '('); i != -1 {
			vr.name = rest[:i]
			return vr, true
		}
	case strings.HasPrefix(rest, "method "): // "method (*File) SetModTime(time.Time)"
		vr.kind = "method"
		rest = rest[len("method "):] // "(*File) SetModTime(time.Time)"
		sp := strings.IndexByte(rest, ' ')
		if sp == -1 {
			return
		}
		vr.recv = strings.Trim(rest[:sp], "()")    // "*File"
		vr.recv = strings.TrimPrefix(vr.recv, "*") // "File"
		rest = rest[sp+1:]                         // SetMode(os.FileMode)
		paren := strings.IndexByte(rest, '(')
		if paren == -1 {
			return
		}
		vr.name = rest[:paren]
		return vr, true
	}
	return // TODO: handle more cases
}