processFilterNode builds query for the XPath filter predicate.
(root *filterNode, flags flag, props *builderProp)
| 172 | |
| 173 | // processFilterNode builds query for the XPath filter predicate. |
| 174 | func (b *builder) processFilter(root *filterNode, flags flag, props *builderProp) (query, error) { |
| 175 | first := (flags & flagsEnum.Filter) == 0 |
| 176 | |
| 177 | qyInput, err := b.processNode(root.Input, (flags | flagsEnum.Filter), props) |
| 178 | if err != nil { |
| 179 | return nil, err |
| 180 | } |
| 181 | firstInput := b.firstInput |
| 182 | |
| 183 | var propsCond builderProp |
| 184 | cond, err := b.processNode(root.Condition, flags, &propsCond) |
| 185 | if err != nil { |
| 186 | return nil, err |
| 187 | } |
| 188 | |
| 189 | // Checking whether is number |
| 190 | if canBeNumber(cond) || ((propsCond & (builderProps.HasPosition | builderProps.HasLast)) != 0) { |
| 191 | propsCond |= builderProps.HasPosition |
| 192 | flags |= flagsEnum.PosFilter |
| 193 | } |
| 194 | |
| 195 | if root.Input.Type() != nodeFilter { |
| 196 | *props &= ^builderProps.PosFilter |
| 197 | } |
| 198 | |
| 199 | if (propsCond & builderProps.HasPosition) != 0 { |
| 200 | *props |= builderProps.PosFilter |
| 201 | } |
| 202 | |
| 203 | if (propsCond & builderProps.HasPosition) != builderProps.None { |
| 204 | if (propsCond & builderProps.HasLast) != 0 { |
| 205 | // https://github.com/antchfx/xpath/issues/76 |
| 206 | // https://github.com/antchfx/xpath/issues/78 |
| 207 | if qyFunc, ok := cond.(*functionQuery); ok { |
| 208 | switch qyFunc.Input.(type) { |
| 209 | case *filterQuery: |
| 210 | cond = &lastFuncQuery{Input: qyFunc.Input} |
| 211 | case *groupQuery: |
| 212 | cond = &lastFuncQuery{Input: qyFunc.Input} |
| 213 | } |
| 214 | } |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | merge := (qyInput.Properties() & queryProps.Merge) != 0 |
| 219 | if first && firstInput != nil { |
| 220 | if merge && ((*props & builderProps.PosFilter) != 0) { |
| 221 | var ( |
| 222 | rootQuery = &contextQuery{} |
| 223 | parent query |
| 224 | ) |
| 225 | switch axisQuery := firstInput.(type) { |
| 226 | case *ancestorQuery: |
| 227 | if _, ok := axisQuery.Input.(*contextQuery); !ok { |
| 228 | parent = axisQuery.Input |
| 229 | axisQuery.Input = rootQuery |
| 230 | } |
| 231 | case *attributeQuery: |
no test coverage detected