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) }