mirror of
https://github.com/golang/go
synced 2024-11-19 02:44:44 -07:00
63859f3815
Now the "type" of a *ast.PkgName is the package it points to. Of course, a package is not a real types.Type, but we can still jump you there. We have to pick one of the package's files, so we choose the longest one, hoping it is the most interesting. Similarly, the "definition" of an *ast.ImportSpec is the package being imported. I also added a nil check for the package in SignatureHelp. This panics for me occasionally. Change-Id: Ide4640530a28bcec9da6de36723eb7f0e4cc941c GitHub-Last-Rev: 8190baa0b908065db5b53f236de03d2f3bff39b5 GitHub-Pull-Request: golang/tools#92 Reviewed-on: https://go-review.googlesource.com/c/tools/+/174081 Run-TryBot: Rebecca Stambler <rstambler@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
117 lines
3.4 KiB
Go
117 lines
3.4 KiB
Go
// Copyright 2018 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.
|
|
|
|
package source
|
|
|
|
import (
|
|
"context"
|
|
"go/ast"
|
|
"go/token"
|
|
"go/types"
|
|
"strings"
|
|
|
|
"golang.org/x/tools/go/analysis"
|
|
"golang.org/x/tools/go/packages"
|
|
"golang.org/x/tools/internal/lsp/diff"
|
|
"golang.org/x/tools/internal/lsp/xlog"
|
|
"golang.org/x/tools/internal/span"
|
|
)
|
|
|
|
// View abstracts the underlying architecture of the package using the source
|
|
// package. The view provides access to files and their contents, so the source
|
|
// package does not directly access the file system.
|
|
type View interface {
|
|
Logger() xlog.Logger
|
|
FileSet() *token.FileSet
|
|
BuiltinPackage() *ast.Package
|
|
GetFile(ctx context.Context, uri span.URI) (File, error)
|
|
SetContent(ctx context.Context, uri span.URI, content []byte) error
|
|
}
|
|
|
|
// File represents a Go source file that has been type-checked. It is the input
|
|
// to most of the exported functions in this package, as it wraps up the
|
|
// building blocks for most queries. Users of the source package can abstract
|
|
// the loading of packages into their own caching systems.
|
|
type File interface {
|
|
URI() span.URI
|
|
View() View
|
|
GetAST(ctx context.Context) *ast.File
|
|
GetFileSet(ctx context.Context) *token.FileSet
|
|
GetPackage(ctx context.Context) Package
|
|
GetToken(ctx context.Context) *token.File
|
|
GetContent(ctx context.Context) []byte
|
|
|
|
// GetActiveReverseDeps returns the active files belonging to the reverse
|
|
// dependencies of this file's package.
|
|
GetActiveReverseDeps(ctx context.Context) []File
|
|
}
|
|
|
|
// Package represents a Go package that has been type-checked. It maintains
|
|
// only the relevant fields of a *go/packages.Package.
|
|
type Package interface {
|
|
PkgPath() string
|
|
GetFilenames() []string
|
|
GetSyntax() []*ast.File
|
|
GetErrors() []packages.Error
|
|
GetTypes() *types.Package
|
|
GetTypesInfo() *types.Info
|
|
GetTypesSizes() types.Sizes
|
|
IsIllTyped() bool
|
|
GetActionGraph(ctx context.Context, a *analysis.Analyzer) (*Action, error)
|
|
GetImport(pkgPath string) Package
|
|
}
|
|
|
|
// TextEdit represents a change to a section of a document.
|
|
// The text within the specified span should be replaced by the supplied new text.
|
|
type TextEdit struct {
|
|
Span span.Span
|
|
NewText string
|
|
}
|
|
|
|
// DiffToEdits converts from a sequence of diff operations to a sequence of
|
|
// source.TextEdit
|
|
func DiffToEdits(uri span.URI, ops []*diff.Op) []TextEdit {
|
|
edits := make([]TextEdit, 0, len(ops))
|
|
for _, op := range ops {
|
|
s := span.New(uri, span.NewPoint(op.I1+1, 1, 0), span.NewPoint(op.I2+1, 1, 0))
|
|
switch op.Kind {
|
|
case diff.Delete:
|
|
// Delete: unformatted[i1:i2] is deleted.
|
|
edits = append(edits, TextEdit{Span: s})
|
|
case diff.Insert:
|
|
// Insert: formatted[j1:j2] is inserted at unformatted[i1:i1].
|
|
if content := strings.Join(op.Content, ""); content != "" {
|
|
edits = append(edits, TextEdit{Span: s, NewText: content})
|
|
}
|
|
}
|
|
}
|
|
return edits
|
|
}
|
|
|
|
func EditsToDiff(edits []TextEdit) []*diff.Op {
|
|
iToJ := 0
|
|
ops := make([]*diff.Op, len(edits))
|
|
for i, edit := range edits {
|
|
i1 := edit.Span.Start().Line() - 1
|
|
i2 := edit.Span.End().Line() - 1
|
|
kind := diff.Insert
|
|
if edit.NewText == "" {
|
|
kind = diff.Delete
|
|
}
|
|
ops[i] = &diff.Op{
|
|
Kind: kind,
|
|
Content: diff.SplitLines(edit.NewText),
|
|
I1: i1,
|
|
I2: i2,
|
|
J1: i1 + iToJ,
|
|
}
|
|
if kind == diff.Insert {
|
|
iToJ += len(ops[i].Content)
|
|
} else {
|
|
iToJ -= i2 - i1
|
|
}
|
|
}
|
|
return ops
|
|
}
|