linter

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jan 15, 2021 License: MIT Imports: 45 Imported by: 9

Documentation

Index

Constants

View Source
const (
	// FlagReturn shows whether or not block has "return"
	FlagReturn = 1 << iota
	FlagBreak
	FlagContinue
	FlagThrow
	FlagDie
)
View Source
const (
	LevelError       = lintapi.LevelError
	LevelWarning     = lintapi.LevelWarning
	LevelInformation = lintapi.LevelInformation
	LevelHint        = lintapi.LevelHint
	LevelUnused      = lintapi.LevelUnused
	LevelDoNotReject = lintapi.LevelMaybe
	LevelSyntax      = lintapi.LevelSyntax
	LevelSecurity    = lintapi.LevelSecurity // Like warning, but reported without a context line
)
View Source
const (
	// IgnoreLinterMessage is a commit message that you specify if you want to cancel linter checks for this changeset
	IgnoreLinterMessage = "@linter disable"
)

Variables

View Source
var (
	// LangServer represents whether or not we run in a language server mode.
	LangServer bool

	// BaselineProfile is a suppression database for warnings.
	// Nil profile is an empty suppression profile.
	BaselineProfile      *baseline.Profile
	ConservativeBaseline bool

	ApplyQuickFixes bool

	// KPHP tells whether we're working in KPHP-compatible mode.
	KPHP bool

	CacheDir string

	// TypoFixer is a rule set for English typos correction.
	// If nil, no misspell checking is performed.
	// See github.com/client9/misspell for details.
	TypoFixer *misspell.Replacer

	// AnalysisFiles is a list of files that are being analyzed (in non-git mode)
	AnalysisFiles []string

	// SrcInput implements source code reading from files and buffers.
	//
	// TODO(quasilyte): avoid having it as a global variable?
	SrcInput = inputs.NewDefaultSourceInput()

	// Rules is a set of dynamically loaded linter diagnostics.
	Rules = &rules.Set{}

	StubsDir       string
	Debug          bool
	MaxConcurrency = runtime.NumCPU()
	MaxFileSize    int

	// DebugParseDuration specifies the minimum parse duration for it to be printed to debug output.
	DebugParseDuration time.Duration

	CheckAutoGenerated bool

	IsDiscardVar = isUnderscore

	ExcludeRegex *regexp.Regexp
)

Functions

func AnalyzeFileRootLevel

func AnalyzeFileRootLevel(rootNode ir.Node, d *RootWalker)

AnalyzeFileRootLevel does analyze file top-level code. This method is exposed for language server use, you usually do not need to call it yourself.

func DebugMessage

func DebugMessage(msg string, args ...interface{})

DebugMessage is used to actually print debug messages.

func DeclareCheck

func DeclareCheck(info CheckInfo)

DeclareCheck declares a check described by an info. It's a good practice to declare *all* provided checks.

If check is not declared, for example, there is no way to make it enabled by default.

func DeclareRules added in v0.3.0

func DeclareRules(rset *rules.Set)

func FlagsToString

func FlagsToString(f int) string

FlagsToString is designed for debugging flags.

func IndexFile

func IndexFile(filename string, contents []byte) error

IndexFile is a legacy way of indexing files. Deprecated: use Worker.IndexFile instead.

func InitStubs

func InitStubs(readFileNamesFunc workspace.ReadCallback)

func InitStubsFromDir added in v0.3.0

func InitStubsFromDir(dir string)

InitStubsFromDir parses directory with PHPStorm stubs which has all internal PHP classes and functions declared.

func MemoryLimiterThread

func MemoryLimiterThread()

MemoryLimiterThread starts memory limiter goroutine that disallows to use parse files more than MaxFileSize total bytes.

func MergeTypeMaps added in v0.3.0

func MergeTypeMaps(left meta.TypesMap, right meta.TypesMap) meta.TypesMap

MergeTypeMaps merges two typesmaps without losing information. So merging int[] and array will give int[], and Foo and object will give Foo.

func RegisterBlockChecker

func RegisterBlockChecker(c BlockCheckerCreateFunc)

RegisterBlockChecker registers a custom block linter that will be used on block level.

func RegisterRootChecker

func RegisterRootChecker(c RootCheckerCreateFunc)

RegisterRootChecker registers a custom root linter that will be used on root level.

Root checker indexing phase is expected to be stateless. If indexing results need to be saved (and cached), use RegisterRootCheckerWithCacher.

func RegisterRootCheckerWithCacher

func RegisterRootCheckerWithCacher(cacher MetaCacher, c RootCheckerCreateFunc)

RegisterRootCheckerWithCacher registers a custom root linter that will be used on root level. Specified cacher is used to save (and load) indexing phase results.

Types

type BlockChecker

type BlockChecker interface {
	BeforeEnterNode(ir.Node)
	AfterEnterNode(ir.Node)
	BeforeLeaveNode(ir.Node)
	AfterLeaveNode(ir.Node)
}

BlockChecker is a custom linter that is called on block level

type BlockCheckerCreateFunc

type BlockCheckerCreateFunc func(*BlockContext) BlockChecker

BlockCheckerCreateFunc is a factory function for BlockChecker

type BlockCheckerDefaults

type BlockCheckerDefaults struct{}

BlockCheckerDefaults is a type for embedding into checkers to get default (empty) BlockChecker implementations.

You can "override" any required methods while ignoring the others.

The benefit is higher backwards-compatibility. If new methods are added to BlockChecker, you wouldn't need to change your code right away (especially if you don't need a new hook).

func (BlockCheckerDefaults) AfterEnterNode

func (BlockCheckerDefaults) AfterEnterNode(ir.Node)

func (BlockCheckerDefaults) AfterLeaveNode

func (BlockCheckerDefaults) AfterLeaveNode(ir.Node)

func (BlockCheckerDefaults) BeforeEnterNode

func (BlockCheckerDefaults) BeforeEnterNode(ir.Node)

func (BlockCheckerDefaults) BeforeLeaveNode

func (BlockCheckerDefaults) BeforeLeaveNode(ir.Node)

type BlockContext

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

BlockContext is the context for block checker.

func (*BlockContext) AddQuickfix added in v0.3.0

func (ctx *BlockContext) AddQuickfix(fix quickfix.TextEdit)

AddQuickfix adds a new quick fix.

func (*BlockContext) ClassParseState

func (ctx *BlockContext) ClassParseState() *meta.ClassParseState

ClassParseState returns class parse state (namespace, class, etc).

func (*BlockContext) ExprType added in v0.3.0

func (ctx *BlockContext) ExprType(e ir.Node) meta.TypesMap

ExprType resolves the type of e expression node.

func (*BlockContext) File added in v0.3.0

func (ctx *BlockContext) File() *workspace.File

File returns the file being analyzed.

func (*BlockContext) Filename

func (ctx *BlockContext) Filename() string

Filename returns the file name of the file being analyzed.

func (*BlockContext) IsRootLevel

func (ctx *BlockContext) IsRootLevel() bool

IsRootLevel reports whether we are analysing root-level code currently.

func (*BlockContext) IsStatement

func (ctx *BlockContext) IsStatement(n ir.Node) bool

IsStatement reports whether or not specified node is a statement.

func (*BlockContext) NodePath added in v0.3.0

func (ctx *BlockContext) NodePath() NodePath

NodePath returns a node path up to the current traversal position. The path includes the node that is being traversed as well.

func (*BlockContext) PrematureExitFlags

func (ctx *BlockContext) PrematureExitFlags() int

func (*BlockContext) Report

func (ctx *BlockContext) Report(n ir.Node, level int, checkName, msg string, args ...interface{})

Report records linter warning of specified level. chechName is a key that identifies the "checker" (diagnostic name) that found issue being reported.

func (*BlockContext) ReportByLine added in v0.3.0

func (ctx *BlockContext) ReportByLine(lineNumber, level int, checkName, msg string, args ...interface{})

func (*BlockContext) RootState

func (ctx *BlockContext) RootState() map[string]interface{}

RootState returns state from root context.

func (*BlockContext) Scope

func (ctx *BlockContext) Scope() *meta.Scope

Scope returns variables declared in this block.

type BlockWalker

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

BlockWalker is used to process function/method contents.

func (*BlockWalker) EnterNode

func (b *BlockWalker) EnterNode(n ir.Node) (res bool)

EnterNode is called before walking to inner nodes.

func (*BlockWalker) LeaveNode

func (b *BlockWalker) LeaveNode(w ir.Node)

LeaveNode is called after all children have been visited.

type CheckInfo

type CheckInfo struct {
	// Name is a diagnostic short name.
	// If several words are needed, prefer camelCase.
	Name string

	// Default controls whether diagnostic is
	// enabled by default or it should be included by allow-checks explicitly.
	Default bool

	// Quickfix tells whether this checker can automatically fix the reported
	// issues when linter works in -fix mode.
	Quickfix bool

	// Comment is a short summary of what this diagnostic does.
	// A single descriptive sentence is a perfect format for it.
	Comment string

	// Before is a non-compliant code example (before the fix).
	// Optional, but if present, After should also be non-empty.
	Before string

	// After is a compliant code example (after the fix).
	// Optional, but if present, Before should also be non-empty.
	After string
}

CheckInfo provides a single check (diagnostic) metadata.

This structure may change with different revisions of noverify and get new fields that may be used by the linter.

func GetDeclaredChecks

func GetDeclaredChecks() []CheckInfo

GetDeclaredChecks returns a list of all checks that were declared. Slice is sorted by check names.

type MetaCacher

type MetaCacher interface {
	// Version returns a unique cache version identifier.
	// When underlying cache structure is updated, version
	// should return different value.
	//
	// Preferably something unique, prefixed with a vendor
	// name, like `mylints-1.0.0` or `extension-abc4`.
	//
	// Returned value is written before Encode() is called to
	// the same writer. It's also read from the reader before
	// Decode() is invoked.
	Version() string

	// Encode stores custom meta cache part data into provided writer.
	// RootChecker is expected to carry the necessary indexing phase results.
	Encode(io.Writer, RootChecker) error

	// Decode loads custom meta cache part data from provided reader.
	// Those results are used insted of running the associated indexer.
	Decode(r io.Reader, filename string) error
}

MetaCacher is an interface for integrating checker-specific indexing results into NoVerify cache.

Usually, every vendor contains a global meta object that can implement MetaCacher and be associated with a relevant root checker.

type NodePath added in v0.3.0

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

func (NodePath) Conditional added in v0.3.0

func (p NodePath) Conditional() bool

func (NodePath) ConditionalUntil added in v0.3.0

func (p NodePath) ConditionalUntil(end ir.Node) bool

func (NodePath) Current added in v0.3.0

func (p NodePath) Current() ir.Node

func (NodePath) NthParent added in v0.3.0

func (p NodePath) NthParent(n int) ir.Node

func (NodePath) Parent added in v0.3.0

func (p NodePath) Parent() ir.Node

func (NodePath) String added in v0.3.0

func (p NodePath) String() string

type ParseWaiter

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

ParseWaiter waits to allow parsing of a file.

func BeforeParse

func BeforeParse(size int, filename string) *ParseWaiter

BeforeParse must be called before parsing file, so that soft memory limit can be applied. Do not forget to call Finish()!

func (*ParseWaiter) Finish

func (p *ParseWaiter) Finish()

Finish must be called after parsing is finished (e.g. using defer p.Finish()) to allow other goroutines to parse files.

type Report

type Report struct {
	CheckName string `json:"check_name"`
	Level     int    `json:"level"`
	Context   string `json:"context"`
	Message   string `json:"message"`
	Filename  string `json:"filename"`
	Line      int    `json:"line"`
	StartChar int    `json:"start_char"`
	EndChar   int    `json:"end_char"`
	Hash      uint64 `json:"hash"`
}

Report is a linter report message.

func DiffReports

func DiffReports(gitRepo string, diffArgs []string, changesList []git.Change, changeLog []git.Commit, oldList, newList []*Report, maxConcurrency int) (res []*Report, err error)

DiffReports returns only reports that are new. Pass diffArgs=nil if we are called from diff in working copy.

func ParseFilenames

func ParseFilenames(readFileNamesFunc workspace.ReadCallback, allowDisabled *regexp.Regexp) []*Report

ParseFilenames is used to do initial parsing of files.

func (*Report) IsCritical

func (r *Report) IsCritical() bool

IsCritical returns whether or not we need to reject whole commit when found this kind of report.

func (*Report) Severity added in v0.3.0

func (r *Report) Severity() string

type RootChecker

type RootChecker interface {
	BeforeEnterFile()
	AfterLeaveFile()
	BeforeEnterNode(ir.Node)
	AfterEnterNode(ir.Node)
	BeforeLeaveNode(ir.Node)
	AfterLeaveNode(ir.Node)
}

RootChecker is a custom linter that should operator only at root level. Block level analysis (function and method bodies and all if/else/for/etc blocks) must be performed in BlockChecker.

type RootCheckerCreateFunc

type RootCheckerCreateFunc func(*RootContext) RootChecker

RootCheckerCreateFunc is a factory function for RootChecker

type RootCheckerDefaults

type RootCheckerDefaults struct{}

RootCheckerDefaults is a type for embedding into checkers to get default (empty) RootChecker implementations.

You can "override" any required methods while ignoring the others.

The benefit is higher backwards-compatibility. If new methods are added to RootChecker, you wouldn't need to change your code right away (especially if you don't need a new hook).

func (RootCheckerDefaults) AfterEnterNode

func (RootCheckerDefaults) AfterEnterNode(ir.Node)

func (RootCheckerDefaults) AfterLeaveFile

func (RootCheckerDefaults) AfterLeaveFile()

func (RootCheckerDefaults) AfterLeaveNode

func (RootCheckerDefaults) AfterLeaveNode(ir.Node)

func (RootCheckerDefaults) BeforeEnterFile added in v0.3.0

func (RootCheckerDefaults) BeforeEnterFile()

func (RootCheckerDefaults) BeforeEnterNode

func (RootCheckerDefaults) BeforeEnterNode(ir.Node)

func (RootCheckerDefaults) BeforeLeaveNode

func (RootCheckerDefaults) BeforeLeaveNode(ir.Node)

type RootContext

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

RootContext is the context for root checker to run on.

func (*RootContext) ClassParseState

func (ctx *RootContext) ClassParseState() *meta.ClassParseState

ClassParseState returns class parse state (namespace, class, etc).

func (*RootContext) File added in v0.3.0

func (ctx *RootContext) File() *workspace.File

File returns analyzed file.

Experimental API.

func (*RootContext) Filename

func (ctx *RootContext) Filename() string

Filename returns the file name of the file being analyzed.

func (*RootContext) ParsePHPDoc added in v0.3.0

func (ctx *RootContext) ParsePHPDoc(doc string) []phpdoc.CommentPart

ParsePHPDoc returns parsed phpdoc comment parts.

func (*RootContext) Report

func (ctx *RootContext) Report(n ir.Node, level int, checkName, msg string, args ...interface{})

Report records linter warning of specified level. chechName is a key that identifies the "checker" (diagnostic name) that found issue being reported.

func (*RootContext) ReportByLine added in v0.3.0

func (ctx *RootContext) ReportByLine(lineNumber, level int, checkName, msg string, args ...interface{})

func (*RootContext) Scope

func (ctx *RootContext) Scope() *meta.Scope

Scope returns variables declared at root level.

func (*RootContext) State

func (ctx *RootContext) State() map[string]interface{}

State returns state that can be modified and passed into block context

type RootWalker

type RootWalker struct {

	// exposed meta-information for language server to use
	Scopes      map[ir.Node]*meta.Scope
	Diagnostics []vscode.Diagnostic
	// contains filtered or unexported fields
}

RootWalker is used to analyze root scope. Mostly defines, function and class definitions are analyzed.

func NewWalkerForLangServer

func NewWalkerForLangServer(workerCtx *WorkerContext, prev *RootWalker) *RootWalker

NewWalkerForLangServer creates a copy of RootWalker to make full analysis of a file

func NewWalkerForReferencesSearcher

func NewWalkerForReferencesSearcher(workerCtx *WorkerContext, filename string, block BlockCheckerCreateFunc) *RootWalker

NewWalkerForReferencesSearcher allows to access full context of a parser so that we can perform complex searches if needed.

func ParseContents

func ParseContents(filename string, contents []byte, lineRanges []git.LineRange, allowDisabled *regexp.Regexp) (root *ir.Root, walker *RootWalker, err error)

ParseContents is a legacy way of linting files. Deprecated: use Worker.ParseContents instead.

func (*RootWalker) EnterNode

func (d *RootWalker) EnterNode(n ir.Node) (res bool)

EnterNode is invoked at every node in hierarchy

func (*RootWalker) File added in v0.3.0

func (d *RootWalker) File() *workspace.File

File returns file for current root walker.

func (*RootWalker) GetReports

func (d *RootWalker) GetReports() []*Report

GetReports returns collected reports for this file.

func (*RootWalker) InitCustom

func (d *RootWalker) InitCustom()

InitCustom is needed to initialize walker state

func (*RootWalker) InitCustomFileData added in v0.3.0

func (d *RootWalker) InitCustomFileData(filename string, contents []byte)

InitCustomFileData initializes file that are needed for RootWalker work for language server

func (*RootWalker) LeaveNode

func (d *RootWalker) LeaveNode(n ir.Node)

LeaveNode is invoked after node process

func (*RootWalker) Report

func (d *RootWalker) Report(n ir.Node, level int, checkName, msg string, args ...interface{})

Report registers a single report message about some found problem.

func (*RootWalker) ReportByLine added in v0.3.0

func (d *RootWalker) ReportByLine(lineNumber int, level int, checkName, msg string, args ...interface{})

ReportByLine registers a single report message about some found problem in lineNumber code line.

func (*RootWalker) UpdateMetaInfo

func (d *RootWalker) UpdateMetaInfo()

UpdateMetaInfo is intended to be used in tests. Do not use it directly!

type Worker added in v0.3.0

type Worker struct {
	AllowDisable *regexp.Regexp
	// contains filtered or unexported fields
}

Worker is a linter handle that is expected to be executed in a single goroutine context.

It's not thread-safe and contains the state that will be re-used between the linter API calls.

See NewLintingWorker and NewIndexingWorker.

func NewIndexingWorker added in v0.3.0

func NewIndexingWorker(id int) *Worker

func NewLintingWorker added in v0.3.0

func NewLintingWorker(id int) *Worker

func (*Worker) ID added in v0.3.0

func (w *Worker) ID() int

func (*Worker) IndexFile added in v0.3.0

func (w *Worker) IndexFile(file workspace.FileInfo) error

IndexFile parses the file and fills in the meta info. Can use cache.

func (*Worker) ParseContents added in v0.3.0

func (w *Worker) ParseContents(fileInfo workspace.FileInfo) (root *ir.Root, walker *RootWalker, err error)

ParseContents parses specified contents (or file) and returns *RootWalker. Function does not update global meta.

type WorkerContext added in v0.3.0

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

WorkerContext is a state that is shared between all worker-owned RootWalker's and BlockWalker's.

A worker is a separate goroutine that processed the incoming files.

Since workerContext is worker-bound, that state is never accessed from different threads, so we can re-use it without synchronization.

func NewWorkerContext added in v0.3.0

func NewWorkerContext() *WorkerContext

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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