resolver

package
v0.0.0-...-2e562ea Latest Latest
Warning

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

Go to latest
Published: Dec 18, 2023 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Example (NewScalaScope_String)
package main

import (
	"fmt"
	"log"

	sppb "github.com/stackb/scala-gazelle/build/stack/gazelle/scala/parse"
	"github.com/stackb/scala-gazelle/pkg/resolver"
)

func main() {
	scope := resolver.NewTrieScope()

	for _, symbol := range []*resolver.Symbol{
		{
			Type:     sppb.ImportType_PACKAGE,
			Name:     "java.lang",
			Provider: "java",
		},
		{
			Type:     sppb.ImportType_CLASS,
			Name:     "java.lang.String",
			Provider: "java",
		},
		{
			Type:     sppb.ImportType_PACKAGE,
			Name:     "scala",
			Provider: "java",
		},
		{
			Type:     sppb.ImportType_CLASS,
			Name:     "scala.Any",
			Provider: "java",
		},
	} {
		if err := scope.PutSymbol(symbol); err != nil {
			log.Fatal(err)
		}
	}

	scala, _ := resolver.NewScalaScope(scope)

	fmt.Println(scala)
}
Output:


--- layer 0 ---
java <nil>
└ lang (java.lang<PACKAGE> //:<java>)
  └ String (java.lang.String<CLASS> //:<java>)
scala (scala<PACKAGE> //:<java>)
└ Any (scala.Any<CLASS> //:<java>)

--- layer 1 ---
Any (scala.Any<CLASS> //:<java>)

--- layer 2 ---
String (java.lang.String<CLASS> //:<java>)

--- layer 3 ---
java <nil>
└ lang (java.lang<PACKAGE> //:<java>)
  └ String (java.lang.String<CLASS> //:<java>)
scala (scala<PACKAGE> //:<java>)
└ Any (scala.Any<CLASS> //:<java>)

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrSymbolNotFound = fmt.Errorf("symbol not found")

ErrSymbolNotFound is an error value assigned to an Import when the name could not be resolved.

Functions

func SymbolConfictMessage

func SymbolConfictMessage(symbol *Symbol, imp *Import, from label.Label) string

Types

type ChainScope

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

ChainScope implements Scope over a chain of registries.

func NewChainScope

func NewChainScope(chain ...Scope) *ChainScope

func (*ChainScope) GetScope

func (r *ChainScope) GetScope(imp string) (Scope, bool)

GetScope implements part of the resolver.Scope interface.

func (*ChainScope) GetSymbol

func (r *ChainScope) GetSymbol(imp string) (*Symbol, bool)

GetSymbol implements part of the Scope interface

func (*ChainScope) GetSymbols

func (r *ChainScope) GetSymbols(prefix string) []*Symbol

GetSymbols implements part of the Scope interface

func (*ChainScope) PutSymbol

func (r *ChainScope) PutSymbol(known *Symbol) error

PutSymbol is not supported and will panic.

func (*ChainScope) String

func (r *ChainScope) String() string

String implements the fmt.Stringer interface

type ChainSymbolResolver

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

ChainSymbolResolver implements SymbolResolver over a chain of resolvers.

func NewChainSymbolResolver

func NewChainSymbolResolver(chain ...SymbolResolver) *ChainSymbolResolver

func (*ChainSymbolResolver) ResolveSymbol

func (r *ChainSymbolResolver) ResolveSymbol(c *config.Config, ix *resolve.RuleIndex, from label.Label, lang string, imp string) (*Symbol, bool)

ResolveSymbol implements the SymbolResolver interface

type ConflictResolver

type ConflictResolver interface {
	// Name is the canonical name for the resolver
	Name() string
	// RegisterFlags configures the flags.  RegisterFlags is called for all
	// resolvers whether they are enabled or not.
	RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config)
	// CheckFlags asserts that the flags are correct.  CheckFlags is only called
	// if the resolver is enabled.
	CheckFlags(fs *flag.FlagSet, c *config.Config) error
	// ResolveConflict takes the context rule and imports, and the target symbol
	// with conflicts to resolve.
	ResolveConflict(universe Universe, r *rule.Rule, imports ImportMap, imp *Import, symbol *Symbol) (*Symbol, bool)
}

ConflictResolver implementations are capable of applying a conflict resolution strategy for conflicting resolved import symbols.

func GlobalConflictResolvers

func GlobalConflictResolvers() []ConflictResolver

GlobalConflictResolvers returns a sorted list of known conflict resolvers

type ConflictResolverRegistry

type ConflictResolverRegistry interface {
	// GetConflictResolver returns the named resolver.  If not known `(nil,
	// false)` is returned.
	GetConflictResolver(name string) (ConflictResolver, bool)

	// PutConflictResolver adds the given known rule to the registry.  It is an
	// error to attempt duplicate registration of the same rule twice.
	// Implementations should use the google.golang.org/grpc/status.Errorf for
	// error types.
	PutConflictResolver(name string, r ConflictResolver) error
}

ConflictResolverRegistry is an index of known conflict resolvers keyed by their name.

func GlobalConflictResolverRegistry

func GlobalConflictResolverRegistry() ConflictResolverRegistry

GlobalConflictResolverRegistry returns a default symbol provider registry. Third-party gazelle extensions can append to this list and configure their own implementations.

type CrossSymbolResolver

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

CrossSymbolResolver implements Resolver using the resolve.RuleIndex (which uses the gazelle cross resolver infrastructure).

func NewCrossSymbolResolver

func NewCrossSymbolResolver(lang string) *CrossSymbolResolver

func (*CrossSymbolResolver) ResolveSymbol

func (sr *CrossSymbolResolver) ResolveSymbol(c *config.Config, ix *resolve.RuleIndex, from label.Label, lang string, imp string) (*Symbol, bool)

ResolveSymbol implements the SymbolResolver interface

type Import

type Import struct {
	// Kind is the import type
	Kind sppb.ImportKind
	// Imp is the name of the import
	Imp string
	// File is the source file (when this is a direct import).
	Source *sppb.File
	// Src is the name of the parent import (when this is an implicit import)
	Src string
	// Symbol is the resolved symbol of the import, or nil if not resolved.
	Symbol *Symbol
	// Error is assiged if there is a resolution error.
	Error error
}

Import is used to trace import provenance.

func NewDirectImport

func NewDirectImport(imp string, source *sppb.File) *Import

NewDirectImport creates a new direct import from the given file.

func NewErrorImport

func NewErrorImport(imp string, source *sppb.File, src string, err error) *Import

NewError creates a new err import from the given file, name, and symbol.

func NewExtendsImport

func NewExtendsImport(imp string, source *sppb.File, src string, symbol *Symbol) *Import

NewExtendsImport creates a new extends import from the given requiring type.

func NewImplicitImport

func NewImplicitImport(imp, src string) *Import

NewImplicitImport creates a new implicit import from the given parent src.

func NewMainClassImport

func NewMainClassImport(imp string) *Import

NewMainClassImport creates a new main_class import.

func NewResolvedNameImport

func NewResolvedNameImport(imp string, source *sppb.File, name string, symbol *Symbol) *Import

NewResolvedNameImport creates a new resolved import from the given file, name, and symbol. The 'name' is the token that resolved in the file scope.

func NewTransitiveImport

func NewTransitiveImport(imp string, name string, symbol *Symbol) *Import

NewTransitiveImport creates a new resolved import from the given file, name, and symbol. The 'name' is the token that resolved in the file scope.

func (*Import) Comment

func (imp *Import) Comment() build.Comment

func (*Import) String

func (imp *Import) String() string

type ImportMap

type ImportMap map[string]*Import

ImportMap is a map if imports keyed by the import string.

func NewImportMap

func NewImportMap() ImportMap

func (ImportMap) Annotate

func (imports ImportMap) Annotate(comments *build.Comments, accept func(imp *Import) bool)

func (ImportMap) Deps

func (imports ImportMap) Deps(from label.Label) (deps []label.Label)

Deps returns a de-duplicated list of labels that represent the from-relative final deps. The list is not sorted under the expectation that sorting will be done elsewhere.

func (ImportMap) Keys

func (imports ImportMap) Keys() []string

Keys returns a sorted list of imports.

func (ImportMap) Put

func (imports ImportMap) Put(imp *Import)

Put the given import in the map.

func (ImportMap) Values

func (imports ImportMap) Values() []*Import

Values returns a sorted list of *Import.

type KnownRuleRegistry

type KnownRuleRegistry interface {
	// GetKnownRule does a lookup of the given label and returns the
	// known rule.  If not known `(nil, false)` is returned.
	GetKnownRule(from label.Label) (*rule.Rule, bool)

	// PutKnownRule adds the given known rule to the registry.  It is an
	// error to attempt duplicate registration of the same rule twice.
	// Implementations should use the google.golang.org/grpc/status.Errorf for
	// error types.
	PutKnownRule(from label.Label, r *rule.Rule) error
}

KnownRuleRegistry is an index of known rules keyed by their label.

type LabelNameRewriteSpec

type LabelNameRewriteSpec struct {
	// Src is the label name pattern to match
	Src string
	// Dst is the label name pattern to rewrite
	Dst string
}

LabelNameRewriteSpec is a specification to rewrite a label name. For example, a bazel macro like `custom_scala_library` might be implemented such that the macro instantiates a "real" scala_library rule as `name + "_lib"`. In this case, we don't want to resolve the actual macro name but rather the lib name. Given this example, it would be `LabelNameRewriteSpec{Src:"%{name}", Dst:"%{name}_lib"}`, where `%{name}` is a special token used as a placeholder for the label.Name.

func (*LabelNameRewriteSpec) Rewrite

func (m *LabelNameRewriteSpec) Rewrite(from label.Label) label.Label

type MemoSymbolResolver

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

MemoSymbolResolver implements SymbolResolver, memoizing results.

func NewMemoSymbolResolver

func NewMemoSymbolResolver(next SymbolResolver) *MemoSymbolResolver

func (*MemoSymbolResolver) ResolveSymbol

func (r *MemoSymbolResolver) ResolveSymbol(c *config.Config, ix *resolve.RuleIndex, from label.Label, lang string, imp string) (*Symbol, bool)

ResolveSymbol implements the SymbolResolver interface

type OverrideSymbolResolver

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

OverrideSymbolResolver implements Resolver for gazelle:resolve directives.

func NewOverrideSymbolResolver

func NewOverrideSymbolResolver(lang string) *OverrideSymbolResolver

func (*OverrideSymbolResolver) ResolveSymbol

func (sr *OverrideSymbolResolver) ResolveSymbol(c *config.Config, ix *resolve.RuleIndex, from label.Label, lang string, imp string) (*Symbol, bool)

ResolveSymbol implements the SymbolResolver interface

type PredefinedLabelConflictResolver

type PredefinedLabelConflictResolver struct {
}

PredefinedLabelConflictResolver implements a strategy where

func (*PredefinedLabelConflictResolver) CheckFlags

CheckFlags implements part of the resolver.ConflictResolver interface.

func (*PredefinedLabelConflictResolver) Name

RegisterFlags implements part of the resolver.ConflictResolver interface.

func (*PredefinedLabelConflictResolver) RegisterFlags

func (s *PredefinedLabelConflictResolver) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config)

RegisterFlags implements part of the resolver.ConflictResolver interface.

func (*PredefinedLabelConflictResolver) ResolveConflict

func (s *PredefinedLabelConflictResolver) ResolveConflict(universe Universe, r *rule.Rule, imports ImportMap, imp *Import, symbol *Symbol) (*Symbol, bool)

ResolveConflict implements part of the resolver.ConflictResolver interface. This implementation chooses symbols that have symbol.Label == label.NoLabel, which is the scenario when a symbol is provided by the platform / compiler, like "java.lang.String".

type ScalaScope

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

func NewScalaScope

func NewScalaScope(parent Scope) (*ScalaScope, error)

func (*ScalaScope) GetScope

func (r *ScalaScope) GetScope(imp string) (Scope, bool)

GetScope implements part of the resolver.Scope interface.

func (*ScalaScope) GetSymbol

func (r *ScalaScope) GetSymbol(imp string) (*Symbol, bool)

GetSymbol implements part of the Scope interface

func (*ScalaScope) GetSymbols

func (r *ScalaScope) GetSymbols(prefix string) []*Symbol

GetSymbols implements part of the Scope interface

func (*ScalaScope) PutSymbol

func (r *ScalaScope) PutSymbol(known *Symbol) error

PutSymbol is not supported and will panic.

func (*ScalaScope) String

func (r *ScalaScope) String() string

String implements the fmt.Stringer interface

type ScalaSymbolResolver

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

ScalaSymbolResolver implements SymbolResolver for scala imports. Patterns like '_root_.' or "._" are stripped.

func NewScalaSymbolResolver

func NewScalaSymbolResolver(next SymbolResolver) *ScalaSymbolResolver

NewScalaSymbolResolver constructs a new resolver that chains to the given resolver.

func (*ScalaSymbolResolver) ResolveSymbol

func (sr *ScalaSymbolResolver) ResolveSymbol(c *config.Config, ix *resolve.RuleIndex, from label.Label, lang string, imp string) (*Symbol, bool)

ResolveSymbol implements the SymbolResolver interface

type Scope

type Scope interface {
	fmt.Stringer

	// GetScope returns a scope for th symbol under the given prefix.
	GetScope(name string) (Scope, bool)

	// GetSymbol does a lookup of the given import symbol and returns the
	// known import.  If not known `(nil, false)` is returned.
	GetSymbol(name string) (*Symbol, bool)

	// GetSymbols does a lookup of the given prefix and returns the
	// symbols.
	GetSymbols(prefix string) []*Symbol

	// PutSymbol adds the given known import to the registry.  It is an
	// error to attempt duplicate registration of the same import twice.
	PutSymbol(known *Symbol) error
}

Scope is an index of known symbols.

type ScopeSymbolResolver

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

ScopeSymbolResolver implements Resolver for symbols.

func NewScopeSymbolResolver

func NewScopeSymbolResolver(scope Scope) *ScopeSymbolResolver

func (*ScopeSymbolResolver) ResolveSymbol

func (sr *ScopeSymbolResolver) ResolveSymbol(c *config.Config, ix *resolve.RuleIndex, from label.Label, lang string, symbol string) (*Symbol, bool)

ResolveSymbol implements the ImportResolver interface

type Symbol

type Symbol struct {
	// Type is the kind of symbol this is.
	Type sppb.ImportType
	// Name is the fully-qualified import name.
	Name string
	// Label is the bazel label where the symbol is provided from.
	Label label.Label
	// Provider is the name of the provider that supplied the symbol.
	Provider string
	// Conflicts is a list of symbols provided by another provider or label.
	Conflicts []*Symbol
	// Requires is a list of other symbols that are required by this one.
	Requires []*Symbol
}

Symbol associates a name with the label that provides it, along with a type classifier that says what kind of symbol it is.

func NewSymbol

func NewSymbol(impType sppb.ImportType, name, provider string, from label.Label) *Symbol

NewSymbol constructs a new symbol pointer with the given arguments.

func (*Symbol) Conflict

func (s *Symbol) Conflict(sym *Symbol)

Conflict adds a symbol to the conflicts list.

func (*Symbol) Require

func (s *Symbol) Require(sym *Symbol)

Require adds a symbol to the requires list.

func (*Symbol) String

func (s *Symbol) String() string

String implements fmt.Stringer

type SymbolMap

type SymbolMap map[string]*Symbol

SymbolMap is a map of symbols that are in a scope. For the import 'com.foo.Bar', the map key is 'Bar' and the map value is the known import for it.

func (SymbolMap) Add

func (s SymbolMap) Add(known *Symbol) bool

Add tries to put the given import into the scope. If the import does not have a valid base name, returns false.

func (SymbolMap) Get

func (s SymbolMap) Get(basename string) (*Symbol, bool)

Get returns a symbol in scope.

type SymbolProvider

type SymbolProvider interface {
	// Providers have canonical names
	Name() string
	// RegisterFlags configures the flags.  RegisterFlags is called for all
	// providers whether they are enabled or not.
	RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config)
	// CheckFlags asserts that the flags are correct and provides a scope to
	// provide symbols to.  CheckFlags is only called if the provider is
	// enabled.
	CheckFlags(fs *flag.FlagSet, c *config.Config, scope Scope) error
	// OnResolve is a lifecycle hook that gets called when the resolve phase has
	// started.
	OnResolve() error
	// OnEnd is a lifecycle hook that gets called when the resolve phase has
	// ended.
	OnEnd() error
	// Providers typically manage a particular sub-space of labels.  For
	// example, the maven resolver may return true for labels like
	// "@maven//:junit_junit". The rule Index can be used to consult what type
	// of label from is, based on the rule characteristics.
	CanProvide(dep label.Label, knownRule func(from label.Label) (*rule.Rule, bool)) bool
}

SymbolProvider is a flag-configurable entity that supplies symbols to a registry.

func GetNamedSymbolProviders

func GetNamedSymbolProviders(names []string) (want []SymbolProvider, err error)

type SymbolProviderRegistry

type SymbolProviderRegistry interface {
	// SymbolProviders returns a list of all known providers.
	SymbolProviders() []SymbolProvider

	// AddSymbolProvider adds the given known import provider to the
	// registry.  It is an error to add the same namedprovider twice.
	AddSymbolProvider(provider SymbolProvider) error
}

SymbolProviderRegistry is an index of import providers.

func GlobalSymbolProviderRegistry

func GlobalSymbolProviderRegistry() SymbolProviderRegistry

GlobalSymbolProviderRegistry returns a default symbol provider registry. Third-party gazelle extensions can append to this list and configure their own implementations.

type SymbolResolver

type SymbolResolver interface {
	// ResolveSymbol takes the given config, gazelle rule index, and an
	// import to resolve.
	ResolveSymbol(c *config.Config, ix *resolve.RuleIndex, from label.Label, lang string, sym string) (*Symbol, bool)
}

SymbolResolver knows how to resolve imports.

type TrieScope

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

TrieScope implements Scope using a trie.

func NewTrieScope

func NewTrieScope() *TrieScope

TrieScope constructs a new TrieScope.

func (*TrieScope) GetScope

func (r *TrieScope) GetScope(name string) (Scope, bool)

GetScope implements part of the resolver.Scope interface.

func (*TrieScope) GetSymbol

func (r *TrieScope) GetSymbol(imp string) (*Symbol, bool)

GetSymbol implements part of the resolver.Scope interface.

func (*TrieScope) GetSymbols

func (r *TrieScope) GetSymbols(prefix string) (symbols []*Symbol)

GetSymbols implements part of the resolver.Scope interface.

func (*TrieScope) Lines

func (r *TrieScope) Lines() string

func (*TrieScope) Put

func (r *TrieScope) Put(name string, symbol *Symbol) error

Put gives the user control over the name of the symbol to be added to the trie.

func (*TrieScope) PutSymbol

func (r *TrieScope) PutSymbol(symbol *Symbol) error

PutSymbol implements part of the Scope interface.

func (*TrieScope) String

func (r *TrieScope) String() string

String implements the fmt.Stringer interface.

Example
scope := NewTrieScope()

for _, symbol := range []*Symbol{
	{
		Type:     sppb.ImportType_PACKAGE,
		Name:     "java.lang",
		Provider: "java",
	},
	{
		Type:     sppb.ImportType_CLASS,
		Name:     "java.lang.String",
		Provider: "java",
	},
	{
		Type:     sppb.ImportType_PACKAGE,
		Name:     "scala",
		Provider: "java",
	},
	{
		Type:     sppb.ImportType_CLASS,
		Name:     "scala.Any",
		Provider: "java",
	},
} {
	if err := scope.PutSymbol(symbol); err != nil {
		log.Fatal(err)
	}
}

fmt.Println(scope)
Output:


java <nil>
└ lang (java.lang<PACKAGE> //:<java>)
  └ String (java.lang.String<CLASS> //:<java>)
scala (scala<PACKAGE> //:<java>)
└ Any (scala.Any<CLASS> //:<java>)
Example (Empty)
scope := NewTrieScope()
fmt.Println(scope)
Output:

func (*TrieScope) Symbols

func (r *TrieScope) Symbols() (symbols []*Symbol)

Symbols returns a sorted list of all symbols in the scope.

type TrimPrefixScope

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

TrimPrefixScope implements Scope that trims a prefix from the lookup name.

func NewTrimPrefixScope

func NewTrimPrefixScope(prefix string, next Scope) *TrimPrefixScope

func (*TrimPrefixScope) GetScope

func (r *TrimPrefixScope) GetScope(name string) (Scope, bool)

GetScope implements part of the resolver.Scope interface.

func (*TrimPrefixScope) GetSymbol

func (r *TrimPrefixScope) GetSymbol(name string) (*Symbol, bool)

GetSymbol implements part of the Scope interface

func (*TrimPrefixScope) GetSymbols

func (r *TrimPrefixScope) GetSymbols(name string) []*Symbol

GetSymbols implements part of the Scope interface

func (*TrimPrefixScope) PutSymbol

func (r *TrimPrefixScope) PutSymbol(known *Symbol) error

PutSymbol is not supported and will panic.

func (*TrimPrefixScope) String

func (r *TrimPrefixScope) String() string

String implements the fmt.Stringer interface

type Universe

Universe is a mashup of interfaces that represents all known symbols, rules, etc.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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