99 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
// Copyright 2019 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 (
 | 
						|
	"fmt"
 | 
						|
	"go/ast"
 | 
						|
 | 
						|
	"golang.org/x/tools/internal/lsp/snippet"
 | 
						|
)
 | 
						|
 | 
						|
// structFieldSnippets calculates the plain and placeholder snippets for struct literal field names.
 | 
						|
func (c *completer) structFieldSnippets(label, detail string) (*snippet.Builder, *snippet.Builder) {
 | 
						|
	if !c.inCompositeLiteralField {
 | 
						|
		return nil, nil
 | 
						|
	}
 | 
						|
 | 
						|
	lit := c.enclosingCompositeLiteral
 | 
						|
	kv := c.enclosingKeyValue
 | 
						|
 | 
						|
	// If we aren't in a composite literal or are already in a key-value expression,
 | 
						|
	// we don't want a snippet.
 | 
						|
	if lit == nil || kv != nil {
 | 
						|
		return nil, nil
 | 
						|
	}
 | 
						|
	// First, confirm that we are actually completing a struct field.
 | 
						|
	if len(lit.Elts) > 0 {
 | 
						|
		i := indexExprAtPos(c.pos, lit.Elts)
 | 
						|
		if i >= len(lit.Elts) {
 | 
						|
			return nil, nil
 | 
						|
		}
 | 
						|
		// If the expression is not an identifer, it is not a struct field name.
 | 
						|
		if _, ok := lit.Elts[i].(*ast.Ident); !ok {
 | 
						|
			return nil, nil
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	plain, placeholder := &snippet.Builder{}, &snippet.Builder{}
 | 
						|
	label = fmt.Sprintf("%s: ", label)
 | 
						|
 | 
						|
	// A plain snippet turns "Foo{Ba<>" into "Foo{Bar: <>".
 | 
						|
	plain.WriteText(label)
 | 
						|
	plain.WritePlaceholder(nil)
 | 
						|
 | 
						|
	// A placeholder snippet turns "Foo{Ba<>" into "Foo{Bar: <*int*>".
 | 
						|
	placeholder.WriteText(label)
 | 
						|
	placeholder.WritePlaceholder(func(b *snippet.Builder) {
 | 
						|
		b.WriteText(detail)
 | 
						|
	})
 | 
						|
 | 
						|
	// If the cursor position is on a different line from the literal's opening brace,
 | 
						|
	// we are in a multiline literal.
 | 
						|
	if c.view.FileSet().Position(c.pos).Line != c.view.FileSet().Position(lit.Lbrace).Line {
 | 
						|
		plain.WriteText(",")
 | 
						|
		placeholder.WriteText(",")
 | 
						|
	}
 | 
						|
 | 
						|
	return plain, placeholder
 | 
						|
}
 | 
						|
 | 
						|
// functionCallSnippets calculates the plain and placeholder snippets for function calls.
 | 
						|
func (c *completer) functionCallSnippets(name string, params []string) (*snippet.Builder, *snippet.Builder) {
 | 
						|
	for i := 1; i <= 2 && i < len(c.path); i++ {
 | 
						|
		call, ok := c.path[i].(*ast.CallExpr)
 | 
						|
 | 
						|
		// If we are the left side (i.e. "Fun") part of a call expression,
 | 
						|
		// we don't want a snippet since there are already parens present.
 | 
						|
		if ok && call.Fun == c.path[i-1] {
 | 
						|
			return nil, nil
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	plain, placeholder := &snippet.Builder{}, &snippet.Builder{}
 | 
						|
	label := fmt.Sprintf("%s(", name)
 | 
						|
 | 
						|
	// A plain snippet turns "someFun<>" into "someFunc(<>)".
 | 
						|
	plain.WriteText(label)
 | 
						|
	if len(params) > 0 {
 | 
						|
		plain.WritePlaceholder(nil)
 | 
						|
	}
 | 
						|
	plain.WriteText(")")
 | 
						|
 | 
						|
	// A placeholder snippet turns "someFun<>" into "someFunc(<*i int*>, *s string*)".
 | 
						|
	placeholder.WriteText(label)
 | 
						|
	for i, p := range params {
 | 
						|
		if i > 0 {
 | 
						|
			placeholder.WriteText(", ")
 | 
						|
		}
 | 
						|
		placeholder.WritePlaceholder(func(b *snippet.Builder) {
 | 
						|
			b.WriteText(p)
 | 
						|
		})
 | 
						|
	}
 | 
						|
	placeholder.WriteText(")")
 | 
						|
 | 
						|
	return plain, placeholder
 | 
						|
}
 |