github.com/hashicorp/hcl/v2@v2.20.0/structure_at_pos.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package hcl 5 6 // ----------------------------------------------------------------------------- 7 // The methods in this file all have the general pattern of making a best-effort 8 // to find one or more constructs that contain a given source position. 9 // 10 // These all operate by delegating to an optional method of the same name and 11 // signature on the file's root body, allowing each syntax to potentially 12 // provide its own implementations of these. For syntaxes that don't implement 13 // them, the result is always nil. 14 // ----------------------------------------------------------------------------- 15 16 // BlocksAtPos attempts to find all of the blocks that contain the given 17 // position, ordered so that the outermost block is first and the innermost 18 // block is last. This is a best-effort method that may not be able to produce 19 // a complete result for all positions or for all HCL syntaxes. 20 // 21 // If the returned slice is non-empty, the first element is guaranteed to 22 // represent the same block as would be the result of OutermostBlockAtPos and 23 // the last element the result of InnermostBlockAtPos. However, the 24 // implementation may return two different objects describing the same block, 25 // so comparison by pointer identity is not possible. 26 // 27 // The result is nil if no blocks at all contain the given position. 28 func (f *File) BlocksAtPos(pos Pos) []*Block { 29 // The root body of the file must implement this interface in order 30 // to support BlocksAtPos. 31 type Interface interface { 32 BlocksAtPos(pos Pos) []*Block 33 } 34 35 impl, ok := f.Body.(Interface) 36 if !ok { 37 return nil 38 } 39 return impl.BlocksAtPos(pos) 40 } 41 42 // OutermostBlockAtPos attempts to find a top-level block in the receiving file 43 // that contains the given position. This is a best-effort method that may not 44 // be able to produce a result for all positions or for all HCL syntaxes. 45 // 46 // The result is nil if no single block could be selected for any reason. 47 func (f *File) OutermostBlockAtPos(pos Pos) *Block { 48 // The root body of the file must implement this interface in order 49 // to support OutermostBlockAtPos. 50 type Interface interface { 51 OutermostBlockAtPos(pos Pos) *Block 52 } 53 54 impl, ok := f.Body.(Interface) 55 if !ok { 56 return nil 57 } 58 return impl.OutermostBlockAtPos(pos) 59 } 60 61 // InnermostBlockAtPos attempts to find the most deeply-nested block in the 62 // receiving file that contains the given position. This is a best-effort 63 // method that may not be able to produce a result for all positions or for 64 // all HCL syntaxes. 65 // 66 // The result is nil if no single block could be selected for any reason. 67 func (f *File) InnermostBlockAtPos(pos Pos) *Block { 68 // The root body of the file must implement this interface in order 69 // to support InnermostBlockAtPos. 70 type Interface interface { 71 InnermostBlockAtPos(pos Pos) *Block 72 } 73 74 impl, ok := f.Body.(Interface) 75 if !ok { 76 return nil 77 } 78 return impl.InnermostBlockAtPos(pos) 79 } 80 81 // OutermostExprAtPos attempts to find an expression in the receiving file 82 // that contains the given position. This is a best-effort method that may not 83 // be able to produce a result for all positions or for all HCL syntaxes. 84 // 85 // Since expressions are often nested inside one another, this method returns 86 // the outermost "root" expression that is not contained by any other. 87 // 88 // The result is nil if no single expression could be selected for any reason. 89 func (f *File) OutermostExprAtPos(pos Pos) Expression { 90 // The root body of the file must implement this interface in order 91 // to support OutermostExprAtPos. 92 type Interface interface { 93 OutermostExprAtPos(pos Pos) Expression 94 } 95 96 impl, ok := f.Body.(Interface) 97 if !ok { 98 return nil 99 } 100 return impl.OutermostExprAtPos(pos) 101 } 102 103 // AttributeAtPos attempts to find an attribute definition in the receiving 104 // file that contains the given position. This is a best-effort method that may 105 // not be able to produce a result for all positions or for all HCL syntaxes. 106 // 107 // The result is nil if no single attribute could be selected for any reason. 108 func (f *File) AttributeAtPos(pos Pos) *Attribute { 109 // The root body of the file must implement this interface in order 110 // to support OutermostExprAtPos. 111 type Interface interface { 112 AttributeAtPos(pos Pos) *Attribute 113 } 114 115 impl, ok := f.Body.(Interface) 116 if !ok { 117 return nil 118 } 119 return impl.AttributeAtPos(pos) 120 }