118 lines
4.2 KiB
Go
118 lines
4.2 KiB
Go
|
package hcl
|
||
|
|
||
|
// -----------------------------------------------------------------------------
|
||
|
// The methods in this file all have the general pattern of making a best-effort
|
||
|
// to find one or more constructs that contain a given source position.
|
||
|
//
|
||
|
// These all operate by delegating to an optional method of the same name and
|
||
|
// signature on the file's root body, allowing each syntax to potentially
|
||
|
// provide its own implementations of these. For syntaxes that don't implement
|
||
|
// them, the result is always nil.
|
||
|
// -----------------------------------------------------------------------------
|
||
|
|
||
|
// BlocksAtPos attempts to find all of the blocks that contain the given
|
||
|
// position, ordered so that the outermost block is first and the innermost
|
||
|
// block is last. This is a best-effort method that may not be able to produce
|
||
|
// a complete result for all positions or for all HCL syntaxes.
|
||
|
//
|
||
|
// If the returned slice is non-empty, the first element is guaranteed to
|
||
|
// represent the same block as would be the result of OutermostBlockAtPos and
|
||
|
// the last element the result of InnermostBlockAtPos. However, the
|
||
|
// implementation may return two different objects describing the same block,
|
||
|
// so comparison by pointer identity is not possible.
|
||
|
//
|
||
|
// The result is nil if no blocks at all contain the given position.
|
||
|
func (f *File) BlocksAtPos(pos Pos) []*Block {
|
||
|
// The root body of the file must implement this interface in order
|
||
|
// to support BlocksAtPos.
|
||
|
type Interface interface {
|
||
|
BlocksAtPos(pos Pos) []*Block
|
||
|
}
|
||
|
|
||
|
impl, ok := f.Body.(Interface)
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return impl.BlocksAtPos(pos)
|
||
|
}
|
||
|
|
||
|
// OutermostBlockAtPos attempts to find a top-level block in the receiving file
|
||
|
// that contains the given position. This is a best-effort method that may not
|
||
|
// be able to produce a result for all positions or for all HCL syntaxes.
|
||
|
//
|
||
|
// The result is nil if no single block could be selected for any reason.
|
||
|
func (f *File) OutermostBlockAtPos(pos Pos) *Block {
|
||
|
// The root body of the file must implement this interface in order
|
||
|
// to support OutermostBlockAtPos.
|
||
|
type Interface interface {
|
||
|
OutermostBlockAtPos(pos Pos) *Block
|
||
|
}
|
||
|
|
||
|
impl, ok := f.Body.(Interface)
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return impl.OutermostBlockAtPos(pos)
|
||
|
}
|
||
|
|
||
|
// InnermostBlockAtPos attempts to find the most deeply-nested block in the
|
||
|
// receiving file that contains the given position. This is a best-effort
|
||
|
// method that may not be able to produce a result for all positions or for
|
||
|
// all HCL syntaxes.
|
||
|
//
|
||
|
// The result is nil if no single block could be selected for any reason.
|
||
|
func (f *File) InnermostBlockAtPos(pos Pos) *Block {
|
||
|
// The root body of the file must implement this interface in order
|
||
|
// to support InnermostBlockAtPos.
|
||
|
type Interface interface {
|
||
|
InnermostBlockAtPos(pos Pos) *Block
|
||
|
}
|
||
|
|
||
|
impl, ok := f.Body.(Interface)
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return impl.InnermostBlockAtPos(pos)
|
||
|
}
|
||
|
|
||
|
// OutermostExprAtPos attempts to find an expression in the receiving file
|
||
|
// that contains the given position. This is a best-effort method that may not
|
||
|
// be able to produce a result for all positions or for all HCL syntaxes.
|
||
|
//
|
||
|
// Since expressions are often nested inside one another, this method returns
|
||
|
// the outermost "root" expression that is not contained by any other.
|
||
|
//
|
||
|
// The result is nil if no single expression could be selected for any reason.
|
||
|
func (f *File) OutermostExprAtPos(pos Pos) Expression {
|
||
|
// The root body of the file must implement this interface in order
|
||
|
// to support OutermostExprAtPos.
|
||
|
type Interface interface {
|
||
|
OutermostExprAtPos(pos Pos) Expression
|
||
|
}
|
||
|
|
||
|
impl, ok := f.Body.(Interface)
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return impl.OutermostExprAtPos(pos)
|
||
|
}
|
||
|
|
||
|
// AttributeAtPos attempts to find an attribute definition in the receiving
|
||
|
// file that contains the given position. This is a best-effort method that may
|
||
|
// not be able to produce a result for all positions or for all HCL syntaxes.
|
||
|
//
|
||
|
// The result is nil if no single attribute could be selected for any reason.
|
||
|
func (f *File) AttributeAtPos(pos Pos) *Attribute {
|
||
|
// The root body of the file must implement this interface in order
|
||
|
// to support OutermostExprAtPos.
|
||
|
type Interface interface {
|
||
|
AttributeAtPos(pos Pos) *Attribute
|
||
|
}
|
||
|
|
||
|
impl, ok := f.Body.(Interface)
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return impl.AttributeAtPos(pos)
|
||
|
}
|