Back to godoc.org
github.com/godoctor/godoctor/refactoring

package refactoring

v0.0.0 (362e1ca)
Latest Go to latest
Published: Oct 29, 2019 | License: BSD-3-Clause | Module: github.com/godoctor/godoctor

Overview

Package refactoring contains all of the refactorings supported by the Go Doctor, as well as types (such as refactoring.Log) used to interface with those refactorings.

Index

func InterpretArgs

func InterpretArgs(args []string, r Refactoring) []interface{}

func SortVars

func SortVars(vars []*types.Var)

type AddGoDoc

type AddGoDoc struct {
	RefactoringBase
}

The AddGoDoc refactoring adds GoDoc comments to all exported top-level declarations in a File.

func (*AddGoDoc) Description

func (r *AddGoDoc) Description() *Description

func (*AddGoDoc) Run

func (r *AddGoDoc) Run(config *Config) *Result

type Config

type Config struct {
	// The File system on which the refactoring will operate.
	FileSystem filesystem.FileSystem
	// A set of initial packages to load.  This extents will be passed as-is
	// to the Config.FromArgs method of go.tools/go/loader.  Typically, the
	// scope will consist of a package name or a File containing the
	// Program entrypoint (main function), which may be different from the
	// File containing the text selection.
	Scope []string
	// The range of text on which to invoke the refactoring.
	Selection text.Selection
	// Refactoring-specific arguments.  To determine what arguments are
	// required for each refactoring, see Refactoring.Description().Params.
	// For example, for the Rename refactoring, you must specify a new name
	// for the entity being renamed.  If the refactoring does not require
	// any arguments, this may be nil.
	Args []interface{}
	// Level of verbosity, i.e., how many types of informational items to
	// include in the log.  If Verbosity ≥ 0, only essential log messages
	// (usually errors and warnings) are included.  If ≥ 1, a list of files
	// modified by the refactoring are added to the log.  If ≥ 2, an
	// exhaustive list of edits made by the refactoring is appended to
	// the log.
	Verbosity int
	// The GOPATH.  If this is set to the empty string, the GOPATH is
	// determined from the environment.
	GoPath string
	// The GOROOT.  If this is set to the empty string, the GOROOT is
	// determined from the environment.
	GoRoot string
}

A Config provides the initial configuration for a refactoring, including the File system and Program on which it will operate, the initial text selection, and any refactoring-specific arguments.

At a minimum, the FileSystem, Scope, and Selection arguments must be set.

type Debug

type Debug struct {
	RefactoringBase
}

func (*Debug) Description

func (r *Debug) Description() *Description

func (*Debug) Run

func (r *Debug) Run(config *Config) *Result

type Description

type Description struct {
	// A human-readable name for this refactoring, properly capitalized
	// (e.g., "Rename" or "Extract Function") as it would appear in a user
	// interface.  Every refactoring should have a unique name.
	Name string
	// A brief phrase (≤50 characters) describing this refactoring, with
	// the first letter capitalized.  For example:
	//     ----+----1----+----2----+----3----+----4----+----5
	//     Changes the name of an identifier
	Synopsis string
	// A one-line synopsis of this refactoring's arguments (≤50 characters)
	// with angle brackets surrounding argument names (question marks
	// denoting Boolean arguments) and square brackets surrounding optional
	// arguments.  For example:
	//     ----+----1----+----2----+----3----+----4----+----5
	//     <new_name> [<rename_in_comments?>]
	Usage string
	// HTML doumentation for this refactoring, which can be embedded into
	// the User's Guide.
	HTMLDoc string
	// Multifile is set to true only if this refactoring may change files
	// other than the File containing the selection.  For example, renaming
	// an exported identifier may cause references to be updated in several
	// files, so for the Rename refactoring, Multifile=true.  However,
	// extracting a local variable will only change the File containing the
	// selection, so Extract Local Variable has Multifile=false.
	Multifile bool
	// Required inputs for this refactoring (e.g., if a variable is being
	// renamed, a new name for that variable).  See Parameter.
	Params []Parameter
	// Optional inputs following the required inputs.  See Parameter.
	OptionalParams []Parameter
	// False if this refactoring is not intended for production use.
	Hidden bool
}

Description provides information about a refactoring suitable for display in a user interface.

type Entry

type Entry struct {
	Severity Severity
	Message  string
	Pos      token.Pos
	End      token.Pos
	// contains filtered or unexported fields
}

A Entry constitutes a single entry in a Log. Every Entry has a severity and a message. If the filename is a nonempty string, the Entry is associated with a particular position in the given file. Some log entries are marked as "initial." These indicate semantic errors that were present in the input file (e.g., unresolved identifiers, unnecessary imports, etc.) before the refactoring was started.

func (*Entry) String

func (entry *Entry) String() string

type ErrInvalidArgs

type ErrInvalidArgs error

type ErrInvalidSelection

type ErrInvalidSelection error

type ExtractFunc

type ExtractFunc struct {
	RefactoringBase
	// contains filtered or unexported fields
}

The ExtractFunc refactoring is used to break down larger functions into smaller functions such that the logic of the code remains unchanged. The user is expected to extract recvTypeExpr part of code from the function and enter recvTypeExpr valid name

func (*ExtractFunc) Description

func (r *ExtractFunc) Description() *Description

func (*ExtractFunc) Run

func (r *ExtractFunc) Run(config *Config) *Result

type ExtractLocal

type ExtractLocal struct {
	RefactoringBase
	// contains filtered or unexported fields
}

func (*ExtractLocal) Description

func (r *ExtractLocal) Description() *Description

func (*ExtractLocal) Run

func (r *ExtractLocal) Run(config *Config) *Result

type Log

type Log struct {
	// FileSet to map log entries' Pos and End fields to file positions
	Fset *token.FileSet
	// Informational messages, warnings, and errors, in the (temporal)
	// order they were added to the log
	Entries []*Entry
}

A Log is used to store informational messages, warnings, and errors that will be presented to the user before a refactoring's changes are applied.

func NewLog

func NewLog() *Log

NewLog creates an empty Log. The Log will be unable to associate errors with filenames and line/column/offset information until its Fset field is set non-nil.

func (*Log) Append

func (log *Log) Append(entries []*Entry)

Append adds the given entries to the end of this log, preserving their order.

func (*Log) AssociateNode

func (log *Log) AssociateNode(node ast.Node)

AssociateNode associates the most recently-logged entry with the region of source code corresponding to the given AST Node.

func (*Log) AssociatePos

func (log *Log) AssociatePos(start, end token.Pos)

// Associate associates the most recently-logged entry with the given filename. func (log *Log) Associate(filename string) {

if len(log.Entries) == 0 {
	return
}
entry := log.Entries[len(log.Entries)-1]
entry.Filename = displayablePath(filename)

}

AssociatePos associates the most recently-logged entry with the file and offset denoted by the given Pos.

func (*Log) ChangeInitialErrorsToWarnings

func (log *Log) ChangeInitialErrorsToWarnings()

ChangeInitialErrorsToWarnings changes the severity of any initial errors to Warning severity.

func (*Log) Clear

func (log *Log) Clear()

Clear removes all Entries from the error log.

func (*Log) ContainsErrors

func (log *Log) ContainsErrors() bool

ContainsErrors returns true if the log contains at least one error. The error may be an initial entry, or it may not.

func (*Log) ContainsInitialErrors

func (log *Log) ContainsInitialErrors() bool

ContainsInitialErrors returns true if the log contains at least one initial entry with Error severity.

func (*Log) ContainsPositions

func (log *Log) ContainsPositions() bool

ContainsPositions returns true if the log contains at least one entry that has position information associated with it.

func (*Log) Error

func (log *Log) Error(entry interface{})

Error adds an entry with Error severity to a log.

func (*Log) Errorf

func (log *Log) Errorf(format string, v ...interface{})

Errorf adds an entry with Error severity to a log.

func (*Log) Info

func (log *Log) Info(entry interface{})

Info adds an informational message (an entry with Info severity) to a log.

func (*Log) Infof

func (log *Log) Infof(format string, v ...interface{})

Infof adds an informational message (an entry with Info severity) to a log.

func (*Log) MarkInitial

func (log *Log) MarkInitial()

MarkInitial marks all entries that have been logged so far as initial entries. Subsequent entries will not be marked as initial unless this method is called again at a later point in time.

func (*Log) RemoveInitialEntries

func (log *Log) RemoveInitialEntries()

RemoveInitialEntries removes all initial entries from the log. Entries that are not marked as initial are retained.

func (*Log) String

func (log *Log) String() string

func (*Log) Warn

func (log *Log) Warn(entry interface{})

Warn adds an entry with Warning severity to a log.

func (*Log) Warnf

func (log *Log) Warnf(format string, v ...interface{})

Warnf adds an entry with Warning severity to a log.

func (*Log) Write

func (log *Log) Write(out io.Writer, cwd string)

Write outputs this log in a GNU-style 'file:line:col: message' format. Filenames are displayed relative to the given directory, if possible.

type Null

type Null struct {
	RefactoringBase
}

A Null refactoring makes no changes to a program.

func (*Null) Description

func (r *Null) Description() *Description

func (*Null) Run

func (r *Null) Run(config *Config) *Result

type Parameter

type Parameter struct {
	// A brief label suitable for display next to an input field (e.g., a
	// text box or check box in a dialog box), e.g., "Name:" or "Replace
	// occurrences"
	Label string
	// A longer (typically one sentence) description of the input
	// requested, suitable for display in a tooltip/hover tip.
	Prompt string
	// The default value for this parameter.  The type of the parameter
	// (string or boolean) can be determined from the type of its default
	// value.
	DefaultValue interface{}
}

Description of a parameter for a refactoring.

Some refactorings require additional input from the user besides a text selection. For example, in a Rename refactoring, the user may select an identifier to rename, but the refactoring tool must also elicit (1) a new name for the identifier and (2) whether or not occurrences of the name should be replaced in comments. These two inputs are parameters to the refactoring.

func (*Parameter) IsBoolean

func (p *Parameter) IsBoolean() bool

IsBoolean returns true iff this Parameter must be either true or false.

type Refactoring

type Refactoring interface {
	Description() *Description
	Run(*Config) *Result
}

The Refactoring interface identifies methods common to all refactorings.

The protocol for invoking a refactoring is:

1. If necessary, invoke the Description() method to obtain the name of
   the refactoring and a list of arguments that must be provided to it.
2. Create a Config.  Refactorings are typically invoked from a text
   editor; the Config provides the refactoring with the File that was
   open in the text editor and the selected region/caret position.
3. Invoke Run, which returns a Result.
4. If Result.Log is not empty, display the log to the user.
5. If Result.Edits is non-nil, the edits may be applied to complete the
   transformation.

type RefactoringBase

type RefactoringBase struct {
	// The Program to be refactored, including all dependent files
	Program *loader.Program
	// The AST of the File containing the user's selection
	File *ast.File
	// The Filename containing the user's selection
	Filename string
	// The complete contents of the File containing the user's selection
	FileContents []byte
	// The position of the first character of the user's selection
	SelectionStart token.Pos
	// The position immediately following the user's selection
	SelectionEnd token.Pos
	// AST nodes from SelectedNode to the root (from PathEnclosingInterval)
	PathEnclosingSelection []ast.Node
	// Whether the user's selection exactly encloses the SelectedNode (from
	// PathEnclosingInterval)
	SelectionIsExact bool
	// The deepest ast.Node enclosing the user's selection
	SelectedNode ast.Node
	// The package containing the SelectedNode
	SelectedNodePkg *loader.PackageInfo
	// The Result of this refactoring, returned to the client invoking it
	Result
}

func (*RefactoringBase) Extent

func (r *RefactoringBase) Extent(node ast.Node) *text.Extent

func (*RefactoringBase) FormatFileInEditor

func (r *RefactoringBase) FormatFileInEditor()

func (*RefactoringBase) Init

func (r *RefactoringBase) Init(config *Config, desc *Description) *Result

Setup code for a Run method. Most refactorings should invoke this method before performing refactoring-specific work. This method initializes the refactoring, clears the log, and configures all of the fields in the RefactoringBase struct.

func (*RefactoringBase) OffsetLength

func (r *RefactoringBase) OffsetLength(node ast.Node) (int, int)

func (*RefactoringBase) OffsetOfPos

func (r *RefactoringBase) OffsetOfPos(pos token.Pos) int

func (*RefactoringBase) Text

func (r *RefactoringBase) Text(node ast.Node) string

func (*RefactoringBase) TextFromPosRange

func (r *RefactoringBase) TextFromPosRange(start, end token.Pos) string

func (*RefactoringBase) UpdateLog

func (r *RefactoringBase) UpdateLog(config *Config, checkForErrors bool)

UpdateLog applies the edits in r.Edits and updates existing error messages in r.Log to reflect their locations in the resulting Program. If checkForErrors is true, and if the log does not contain any initial errors, the resulting Program will be type checked, and any new errors introduced by the refactoring will be logged.

type Rename

type Rename struct {
	RefactoringBase
	// contains filtered or unexported fields
}

Rename is a refactoring that changes the names of variables, functions, methods, types, interfaces, and packages in Go programs. It attempts to prevent name changes that will introduce syntactic or semantic errors into the Program.

func (*Rename) Description

func (r *Rename) Description() *Description

func (*Rename) Run

func (r *Rename) Run(config *Config) *Result

type Result

type Result struct {
	// A list of informational messages, errors, and warnings to display to
	// the user.  If the Log.ContainsErrors() is true, the Edits may be
	// empty or incomplete, since it may not be possible to perform the
	// refactoring.
	Log *Log
	// Maps filenames to the text edits that should be applied to those
	// files.
	Edits map[string]*text.EditSet
	// DebugOutput is used by the debug refactoring to output additional
	// information (e.g., the description of the AST or control flow graph)
	// that doesn't belong in the log or the output file
	DebugOutput bytes.Buffer
}

type Severity

type Severity int

A Severity indicates whether a log entry describes an informational message, a warning, or an error.

const (
	Info    Severity = iota // informational message
	Warning                 // warning, something to be cautious of
	Error                   // the refactoring transformation is, or might be, invalid
)

type ToggleVar

type ToggleVar struct {
	RefactoringBase
}

A ToggleVar refactoring converts between explicitly-typed variable declarations (var n int = 5) and short assignment statements (n := 5).

func (*ToggleVar) Description

func (r *ToggleVar) Description() *Description

func (*ToggleVar) Run

func (r *ToggleVar) Run(config *Config) *Result
Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
f or F : Jump to identifier