blob: 3393a486702c7839dae93340e3739d6acad1fd65 [file] [log] [blame]
// Copyright 2013 The Go Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd.
package database
import (
"path"
"regexp"
"strings"
"unicode"
"github.com/garyburd/gddo/doc"
"github.com/garyburd/gosrc"
)
func isStandardPackage(path string) bool {
return strings.Index(path, ".") < 0
}
func isTermSep(r rune) bool {
return unicode.IsSpace(r) || unicode.IsPunct(r) || unicode.IsSymbol(r)
}
func normalizeProjectRoot(projectRoot string) string {
if projectRoot == "" {
return "go"
}
return projectRoot
}
var httpPat = regexp.MustCompile(`https?://\S+`)
func documentTerms(pdoc *doc.Package, score float64) []string {
terms := make(map[string]bool)
// Project root
projectRoot := normalizeProjectRoot(pdoc.ProjectRoot)
terms["project:"+projectRoot] = true
if strings.HasPrefix(pdoc.ImportPath, "code.google.com/p/go.") {
terms["project:subrepo"] = true
}
// Imports
for _, path := range pdoc.Imports {
if gosrc.IsValidPath(path) {
terms["import:"+path] = true
}
}
if score > 0 {
if isStandardPackage(pdoc.ImportPath) {
for _, term := range parseQuery(pdoc.ImportPath) {
terms[term] = true
}
} else {
terms["all:"] = true
for _, term := range parseQuery(pdoc.ProjectName) {
terms[term] = true
}
for _, term := range parseQuery(pdoc.Name) {
terms[term] = true
}
}
// Synopsis
synopsis := httpPat.ReplaceAllLiteralString(pdoc.Synopsis, "")
for i, s := range strings.FieldsFunc(synopsis, isTermSep) {
s = strings.ToLower(s)
if !stopWord[s] && (i > 3 || s != "package") {
terms[stem(s)] = true
}
}
}
result := make([]string, 0, len(terms))
for term := range terms {
result = append(result, term)
}
return result
}
func documentScore(pdoc *doc.Package) float64 {
if pdoc.Name == "" ||
pdoc.IsCmd ||
len(pdoc.Errors) > 0 ||
strings.HasSuffix(pdoc.ImportPath, ".go") ||
strings.HasPrefix(pdoc.ImportPath, "gist.github.com/") {
return 0
}
for _, p := range pdoc.Imports {
if strings.HasSuffix(p, ".go") {
return 0
}
}
if !pdoc.Truncated &&
len(pdoc.Consts) == 0 &&
len(pdoc.Vars) == 0 &&
len(pdoc.Funcs) == 0 &&
len(pdoc.Types) == 0 &&
len(pdoc.Examples) == 0 {
return 0
}
var r float64
switch {
case isStandardPackage(pdoc.ImportPath):
r = 1000
case strings.HasPrefix(pdoc.ImportPath, "code.google.com/p/go."):
r = 500
case pdoc.Doc == "":
// Chekc Doc before Synopsis to handle case where the synopsis is
// derived from the repository description on the version control
// service.
r = 1
case strings.HasPrefix(pdoc.Synopsis, "Package "+pdoc.Name+" "):
r = 100
case len(pdoc.Synopsis) > 0:
r = 10
default:
r = 1
}
for i := 0; i < strings.Count(pdoc.ImportPath[len(pdoc.ProjectRoot):], "/"); i++ {
r *= 0.99
}
if strings.Index(pdoc.ImportPath[len(pdoc.ProjectRoot):], "/src/") > 0 {
r *= 0.85
}
if path.Base(pdoc.ImportPath) != pdoc.Name {
r *= 0.9
}
return r
}
func parseQuery(q string) []string {
var terms []string
q = strings.ToLower(q)
for _, s := range strings.FieldsFunc(q, isTermSep) {
if !stopWord[s] {
terms = append(terms, stem(s))
}
}
return terms
}