graph

package
v0.0.31 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 8, 2015 License: BSD-3-Clause, MIT Imports: 12 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// An Unqualified name is just the def's name.
	//
	// Examples:
	//
	//   Go method         `MyMethod`
	//   Python method     `my_method`
	//   JavaScript method `myMethod`
	Unqualified Qualification = ""

	// A ScopeQualified name is the language-specific description of the
	// def's defining scope plus the def's unqualified name. It should
	// uniquely describe the def among all other defs defined in the same
	// logical package (but this is not strictly defined or enforced).
	//
	// Examples:
	//
	//   Go method         `(*MyType).MyMethod`
	//   Python method     `MyClass.my_method`
	//   JavaScript method `MyConstructor.prototype.myMethod`
	ScopeQualified = "scope"

	// A DepQualified name is the package/module name (as seen by an external
	// library that imports/depends on the def's package/module) plus the
	// def's scope-qualified name. If there are nested packages, it should
	// describe enough of the package hierarchy to distinguish it from other
	// similarly named defs (but this is not strictly defined or enforced).
	//
	// Examples:
	//
	//   Go method       `(*mypkg.MyType).MyMethod`
	//   Python method   `mypkg.MyClass.my_method`
	//   CommonJS method `mymodule.MyConstructor.prototype.myMethod`
	DepQualified = "dep"

	// A RepositoryWideQualified name is the full package/module name(s) plus
	// the def's scope-qualified name. It should describe enough of the
	// package hierarchy so that it is unique in its repository.
	// RepositoryWideQualified differs from DepQualified in that the former
	// includes the full nested package/module path from the repository root
	// (e.g., 'a/b.C' for a Go func C in the repository 'github.com/user/a'
	// subdirectory 'b'), while DepQualified would only be the last directory
	// component (e.g., 'b.C' in that example).
	//
	// Examples:
	//
	//   Go method       `(*mypkg/subpkg.MyType).MyMethod`
	//   Python method   `mypkg.subpkg.MyClass.my_method` (unless mypkg =~ subpkg)
	//   CommonJS method `mypkg.mymodule.MyConstructor.prototype.myMethod` (unless mypkg =~ mymodule)
	RepositoryWideQualified = "repo-wide"

	// A LanguageWideQualified name is the library/repository name plus the
	// package-qualified def name. It should describe the def so that it
	// is logically unique among all defs that could reasonably exist for the
	// language that the def is written in (but this is not strictly defined
	// or enforced).
	//
	// Examples:
	//
	//   Go method       `(*github.com/user/repo/mypkg.MyType).MyMethod`
	//   Python method   `mylib.MyClass.my_method` (if mylib =~ mypkg, as for Django, etc.)
	//   CommonJS method `mylib.MyConstructor.prototype.myMethod` (if mylib =~ mymod, as for caolan/async, etc.)
	LanguageWideQualified = "lang-wide"
)
View Source
const (
	// StatXRefs is the number of external references to a def (i.e.,
	// references from other repositories). It is only computed for abstract
	// defs (see the docs for DefKey) because it is not easy to determine
	// which specific commit a ref references (for external refs).
	StatXRefs = "xrefs"

	// StatRRefs is the number of references to a def from the same
	// repository in which the def is defined. It is inclusive of the
	// StatURefs count. It is only computed for concrete defs (see the docs
	// for DefKey) because otherwise it would count 1 rref for each unique
	// revision of the repository that we have processed. (It is easy to
	// determine which specific commit an internal ref references; we just
	// assume it references a def in the same commit.)
	StatRRefs = "rrefs"

	// StatURefs is the number of references to a def from the same source
	// unit in which the def is defined. It is included in the StatRRefs
	// count. It is only computed for concrete defs (see the docs for
	// DefKey) because otherwise it would count 1 uref for each revision of
	// the repository that we have processed.
	StatURefs = "urefs"

	// StatAuthors is the number of distinct resolved people who contributed
	// code to a def's definition (according to a VCS "blame" of the
	// version). It is only computed for concrete defs (see the docs for
	// DefKey).
	StatAuthors = "authors"

	// StatClients is the number of distinct resolved people who have committed
	// refs that reference a def. It is only computed for abstract defs
	// (see the docs for DefKey) because it is not easy to determine which
	// specific commit a ref references.
	StatClients = "clients"

	// StatDependents is the number of distinct repositories that contain refs
	// that reference a def. It is only computed for abstract defs (see
	// the docs for DefKey) because it is not easy to determine which
	// specific commit a ref references.
	StatDependents = "dependents"

	// StatExportedElements is the number of exported defs whose path is a
	// descendant of this def's path (and that is in the same repository and
	// source unit). It is only computed for concrete defs (see the docs for
	// DefKey) because otherwise it would count 1 exported element for each
	// revision of the repository that we have processed.
	StatExportedElements = "exported_elements"
)

Variables

View Source
var ErrDefNotExist = errors.New("def does not exist")
View Source
var MakeDefFormatters = make(map[string]MakeDefFormatter)

MakeDefFormatter holds MakeDefFormatters that toolchains have registered with RegisterMakeDefFormatter.

Functions

func IsNotExist

func IsNotExist(err error) bool

func MakeURI added in v0.0.27

func MakeURI(cloneURL string) string

MakeURI converts a repository clone URL, such as "git://github.com/user/repo.git", to a normalized URI string, such as "github.com/user/repo".

func RegisterMakeDefFormatter added in v0.0.9

func RegisterMakeDefFormatter(unitType string, f MakeDefFormatter)

RegisterMakeDefFormatter makes a DefFormatter constructor function (MakeDefFormatter) available for defs with the specified unitType. If Register is called twice with the same unitType or if sf is nil, it panics

func TryMakeURI added in v0.0.27

func TryMakeURI(cloneURL string) (string, error)

func URIEqual added in v0.0.27

func URIEqual(a, b string) bool

URIEqual returns true if a and b are equal, based on a case insensitive comparison (strings.EqualFold).

func UniqueRefDefs added in v0.0.9

func UniqueRefDefs(refs []*Ref, m map[RefDefKey]int) map[RefDefKey]int

UniqueRefDefs groups refs by the RefDefKey field and returns a map of how often each RefDefKey appears. If m is non-nil, counts are incremented and a new map is not created.

Types

type Def added in v0.0.9

type Def struct {
	// DefKey is the natural unique key for a def. It is stable
	// (subsequent runs of a grapher will emit the same defs with the same
	// DefKeys).
	DefKey

	// TreePath is a structurally significant path descriptor for a def. For
	// many languages, it may be identical or similar to DefKey.Path.
	// However, it has the following constraints, which allow it to define a
	// def tree.
	//
	// A tree-path is a chain of '/'-delimited components. A component is either a
	// def name or a ghost component.
	// - A def name satifies the regex [^/-][^/]*
	// - A ghost component satisfies the regex -[^/]*
	// Any prefix of a tree-path that terminates in a def name must be a valid
	// tree-path for some def.
	// The following regex captures the children of a tree-path X: X(/-[^/]*)*(/[^/-][^/]*)
	TreePath TreePath `db:"treepath" json:",omitempty"`

	// Name of the definition. This need not be unique.
	Name string

	// Kind is the kind of thing this definition is. This is
	// language-specific. Possible values include "type", "func",
	// "var", etc.
	Kind string

	File string

	DefStart int `db:"def_start"`
	DefEnd   int `db:"def_end"`

	// Exported is whether this def is part of a source unit's
	// public API. For example, in Java a "public" field is
	// Exported.
	Exported bool

	// Local is whether this def is local to a function or some
	// other inner scope. Local defs do *not* have module,
	// package, or file scope. For example, in Java a function's
	// args are Local, but fields with "private" scope are not
	// Local.
	Local sdf.Bool

	// Test is whether this def is defined in test code (as opposed to main
	// code). For example, definitions in Go *_test.go files have Test = true.
	Test bool `json:",omitempty"`

	// Private is whether this definition is private, i.e., if it came from a private repository.
	Private nnz.Bool `json:",omitempty"`

	// Data contains additional language- and toolchain-specific information
	// about the def. Data is used to construct function signatures,
	// import/require statements, language-specific type descriptions, etc.
	Data sqltypes.JSON `json:",omitempty"`
}

START Def OMIT

func (*Def) Fmt added in v0.0.9

func (s *Def) Fmt() DefPrintFormatter

func (Def) String added in v0.0.9

func (x Def) String() string

type DefFormatter added in v0.0.9

type DefFormatter interface {
	// Name formats the def's name with the specified level of qualification.
	Name(qual Qualification) string

	// Type is the type of the def s, if s is not itself a type. If s is
	// itself a type, then Type returns its underlying type.
	//
	// Outputs:
	//
	//   TYPE OF s          RESULT
	//   ------------   -----------------------------------------------------------------
	//   named type     the named type's name
	//   primitive      the primitive's name
	//   function       `(arg1, arg2, ..., argN)` with language-specific type annotations
	//   package        empty
	//   anon. type     the leading keyword (or similar) of the anonymous type definition
	//
	// These rules are not strictly defined or enforced. Language toolchains
	// should freely bend the rules (after noting important exceptions here) to
	// produce sensible output.
	Type(qual Qualification) string

	// NameAndTypeSeparator is the string that should be inserted between the
	// def's name and type. This is typically empty for functions (so that
	// they are formatted with the left paren immediately following the name,
	// like `F(a)`) and a single space for other defs (e.g., `MyVar string`).
	NameAndTypeSeparator() string

	// Language is the name of the programming language that s is in; e.g.,
	// "Python" or "Go".
	Language() string

	// DefKeyword is the language keyword used to define the def (e.g.,
	// 'class', 'type', 'func').
	DefKeyword() string

	// Kind is the language-specific kind of this def (e.g., 'package', 'field', 'CommonJS module').
	Kind() string
}

DefFormatter formats a def.

type DefKey added in v0.0.9

type DefKey struct {
	// Repo is the VCS repository that defines this definition. Its Elasticsearch mapping is defined
	// separately.
	Repo string `json:",omitempty"`

	// CommitID is the ID of the VCS commit that this definition was defined in. The
	// CommitID is always a full commit ID (40 hexadecimal characters for git
	// and hg), never a branch or tag name.
	CommitID string `db:"commit_id" json:",omitempty"`

	// UnitType is the type name of the source unit (obtained from unit.Type(u))
	// that this definition was defined in.
	UnitType string `db:"unit_type" json:",omitempty"`

	// Unit is the name of the source unit (obtained from u.Name()) that this
	// definition was defined in.
	Unit string `json:",omitempty"`

	// Path is a unique identifier for the def, relative to the source unit.
	// It should remain stable across commits as long as the def is the
	// "same" def. Its Elasticsearch mapping is defined separately (because
	// it is a multi_field, which the struct tag can't currently represent).
	//
	// Path encodes no structural semantics. Its only meaning is to be a stable
	// unique identifier within a given source unit. In many languages, it is
	// convenient to use the namespace hierarchy (with some modifications) as
	// the Path, but this may not always be the case. I.e., don't rely on Path
	// to find parents or children or any other structural propreties of the
	// def hierarchy). See Def.TreePath instead.
	Path DefPath
}

START DefKey OMIT DefKey specifies a definition, either concretely or abstractly. A concrete definition key has a non-empty CommitID and refers to a definition defined in a specific commit. An abstract definition key has an empty CommitID and is considered to refer to definitions from any number of commits (so long as the Repo, UnitType, Unit, and Path match).

You can think of CommitID as the time dimension. With an empty CommitID, you are referring to a definition that may or may not exist at various times. With a non-empty CommitID, you are referring to a specific definition of a definition at the time specified by the CommitID.

func (DefKey) String added in v0.0.9

func (s DefKey) String() string

type DefPath added in v0.0.9

type DefPath string

func (*DefPath) Scan added in v0.0.9

func (x *DefPath) Scan(v interface{}) error

func (DefPath) Value added in v0.0.9

func (x DefPath) Value() (driver.Value, error)

type DefPrintFormatter added in v0.0.9

type DefPrintFormatter interface {
	DefFormatter
	fmt.Formatter
}

func PrintFormatter

func PrintFormatter(s *Def) DefPrintFormatter

Formatter creates a string formatter for a def.

The verbs:

%n     qualified name
%w     language keyword used to define the def (e.g., 'class', 'type', 'func')
%k     language-specific kind of this def (e.g., 'package', 'field', 'CommonJS module')
%t     type

The flags:

' '    (in `% t`) prepend the language-specific delimiter between a def's name and type

See DefFormatter for more information.

type Defs added in v0.0.9

type Defs []*Def

func (Defs) KeySet added in v0.0.12

func (defs Defs) KeySet() (keys map[DefKey]struct{}, err error)

func (Defs) Keys added in v0.0.9

func (defs Defs) Keys() (keys []DefKey)

func (Defs) Len added in v0.0.9

func (vs Defs) Len() int

func (Defs) Less added in v0.0.9

func (vs Defs) Less(i, j int) bool

func (Defs) Swap added in v0.0.9

func (vs Defs) Swap(i, j int)

type Doc

type Doc struct {
	// A link to the definition that this docstring describes
	DefKey

	// The MIME-type that the documentation is stored in. Valid formats include 'text/html', 'text/plain', 'text/x-markdown', text/x-rst'
	Format string

	// The actual documentation text
	Data string

	// Location where the docstring was extracted from. Leave blank for undefined location
	File  string
	Start int
	End   int
}

START Doc OMIT Docstring

type Docs

type Docs []*Doc

func (Docs) Len

func (vs Docs) Len() int

func (Docs) Less

func (vs Docs) Less(i, j int) bool

func (Docs) Swap

func (vs Docs) Swap(i, j int)

type MakeDefFormatter added in v0.0.9

type MakeDefFormatter func(*Def) DefFormatter

A MakeDefFormatter is a function, typically implemented by toolchains, that creates a DefFormatter for a def.

type Propagate

type Propagate struct {
	// Src is the def whose type/value is being propagated to the dst def.
	SrcRepo     string
	SrcPath     DefPath
	SrcUnit     string
	SrcUnitType string

	// Dst is the def that is receiving a propagated type/value from the src def.
	DstRepo     string
	DstPath     DefPath
	DstUnit     string
	DstUnitType string
}

Propagate describes type/value propagation in code. A Propagate entry from A (src) to B (dst) indicates that the type/value of A propagates to B. In Tern, this is indicated by A having a "fwd" property whose value is an array that includes B.

## Motivation & example

For example, consider the following JavaScript code:

var a = Foo;
var b = a;

Foo, a, and b are each their own def. We could resolve all of them to the def of their original type (perhaps Foo), but there are occasions when you do want to see only the definition of a or b and examples thereof. Therefore, we need to represent them as distinct defs.

Even though Foo, a, and b are distinct defs, there are propagation relationships between them that are important to represent. The type of Foo propagates to both a and b, and the type of a propagates to b. In this case, we would have 3 Propagates: Propagate{Src: "Foo", Dst: "a"}, Propagate{Src: "Foo", Dst: "b"}, and Propagate{Src: "a", Dst: "b"}. (The propagation relationships could be described by just the first and last Propagates, but we explicitly include all paths as a denormalization optimization to avoid requiring an unbounded number of DB queries to determine which defs a type propagates to or from.)

## Directionality

Propagation is unidirectional, in the general case. In the example above, if Foo referred to a JavaScript object and if the code were evaluated, any *runtime* type changes (e.g., setting a property) on Foo, a, and b would be reflected on all of the others. But this doesn't hold for static analysis; it's not always true that if a property "a.x" or "b.x" exists, then "Foo.x" exists. The simplest example is when Foo is an external definition. Perhaps this example file (which uses Foo as a library) modifies Foo to add a new property, but other libraries that use Foo would never see that property because they wouldn't be executed in the same context as this example file. So, in general, we cannot say that Foo receives all types applied to defs that Foo propagates to.

## Hypothetical Python example

Consider the following 2 Python files:

"""file1.py"""
class Foo(object): end

"""file2.py"""
from .file1 import Foo
Foo2 = Foo

In this example, there would be one Propagate: Propagate{Src: "file1/Foo", Dst: "file2/Foo2}.

type Qualification

type Qualification string

A Qualification specifies how much to qualify names when formatting defs and their type information.

type Ref

type Ref struct {
	// The definition that this reference points to
	DefRepo     string  `db:"def_repo"`
	DefUnitType string  `db:"def_unit_type"`
	DefUnit     string  `db:"def_unit"`
	DefPath     DefPath `db:"def_path"`

	// Def is true if this ref is the original definition or a redefinition
	Def bool

	Repo string

	// CommitID is the immutable commit ID (not the branch name) of the VCS
	// revision that this ref was found in.
	CommitID string `db:"commit_id" json:",omitempty"`

	UnitType string `db:"unit_type" json:",omitempty"`
	Unit     string `json:",omitempty"`

	// Private is whether this reference is private, i.e., if it came from a private repository. Note that this means
	// the the repository that contains the reference is private, NOT the repository to which the reference points.
	Private nnz.Bool `json:",omitempty"`

	File  string
	Start int
	End   int
}

START Ref OMIT Ref represents a reference from source code to a def.

func (*Ref) DefKey added in v0.0.9

func (r *Ref) DefKey() DefKey

func (*Ref) RefDefKey added in v0.0.9

func (r *Ref) RefDefKey() RefDefKey

func (*Ref) RefKey

func (r *Ref) RefKey() RefKey

func (*Ref) SetFromDefKey added in v0.0.9

func (r *Ref) SetFromDefKey(k DefKey)

type RefDefKey added in v0.0.9

type RefDefKey struct {
	DefRepo     string  `db:"def_repo" json:",omitempty"`
	DefUnitType string  `db:"def_unit_type" json:",omitempty"`
	DefUnit     string  `db:"def_unit" json:",omitempty"`
	DefPath     DefPath `db:"def_path" json:",omitempty"`
}

type RefKey

type RefKey struct {
	DefRepo     string  `db:"def_repo" json:",omitempty"`
	DefUnitType string  `db:"def_unit_type" json:",omitempty"`
	DefUnit     string  `db:"def_unit" json:",omitempty"`
	DefPath     DefPath `db:"def_path" json:",omitempty"`
	Def         bool    `json:",omitempty"`
	Repo        string  `json:",omitempty"`
	UnitType    string  `db:"unit_type" json:",omitempty"`
	Unit        string  `json:",omitempty"`
	File        string  `json:",omitempty"`
	CommitID    string  `db:"commit_id" json:",omitempty"`
	Start       int     `json:",omitempty"`
	End         int     `json:",omitempty"`
}

func (*RefKey) RefDefKey added in v0.0.9

func (r *RefKey) RefDefKey() RefDefKey

type RefSet

type RefSet struct {
	// contains filtered or unexported fields
}

RefSet is a set of Refs. It can used to determine whether a grapher emits duplicate refs.

func NewRefSet

func NewRefSet() *RefSet

func (*RefSet) AddAndCheckUnique

func (c *RefSet) AddAndCheckUnique(ref Ref) (duplicate bool)

AddAndCheckUnique adds ref to the set of seen refs, and returns whether the ref already existed in the set.

type Refs

type Refs []*Ref

func (Refs) Len

func (vs Refs) Len() int

func (Refs) Less

func (vs Refs) Less(i, j int) bool

func (Refs) Swap

func (vs Refs) Swap(i, j int)

type RepositoryListingDef added in v0.0.9

type RepositoryListingDef struct {
	// Name is the full name shown on the page.
	Name string

	// NameLabel is a label displayed next to the Name, such as "(main package)"
	// to denote that a package is a Go main package.
	NameLabel string

	// Language is the source language of the def, with any additional
	// specifiers, such as "JavaScript (node.js)".
	Language string

	// SortKey is the key used to lexicographically sort all of the defs on
	// the page.
	SortKey string
}

RepositoryListingDef holds rendered display text to show on the "package" listing page of a repository.

type StatType

type StatType string

StatType is the name of a def statistic (see below for a listing).

func (StatType) IsAbstract

func (x StatType) IsAbstract() bool

func (*StatType) Scan

func (x *StatType) Scan(v interface{}) error

Scan implements database/sql.Scanner.

func (StatType) Value

func (x StatType) Value() (driver.Value, error)

Value implements database/sql/driver.Valuer.

type Stats

type Stats map[StatType]int

Stats holds statistics for a def.

type TreePath

type TreePath string

func (TreePath) IsValid

func (p TreePath) IsValid() bool

func (*TreePath) Scan

func (x *TreePath) Scan(v interface{}) error

func (TreePath) Value

func (x TreePath) Value() (driver.Value, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL