예제 #1
0
// evalCtxPathExpression evaluates a context path expression
func (v *evalVisitor) evalCtxPathExpression(node *ast.PathExpression, exprRoot bool) interface{} {
	v.at(node)

	if node.IsDataRoot() {
		// `@root` - remove the first part
		parts := node.Parts[1:len(node.Parts)]

		result, _ := v.evalCtxPath(v.rootCtx(), parts, exprRoot)
		return result
	}

	return v.evalDepthPath(node.Depth, node.Parts, exprRoot)
}
예제 #2
0
// evalPathExpression evaluates a path expression
func (v *evalVisitor) evalPathExpression(node *ast.PathExpression, exprRoot bool) interface{} {
	var result interface{}

	if name, value := v.findBlockParam(node); value != nil {
		// block parameter value

		// We push a new context so we can evaluate the path expression (note: this may be a bad idea).
		//
		// Example:
		//   {{#foo as |bar|}}
		//     {{bar.baz}}
		//   {{/foo}}
		//
		// With data:
		//   {"foo": {"baz": "bat"}}
		newCtx := map[string]interface{}{name: value}

		v.pushCtx(reflect.ValueOf(newCtx))
		result = v.evalCtxPathExpression(node, exprRoot)
		v.popCtx()
	} else {
		ctxTried := false

		if node.IsDataRoot() {
			// context path
			result = v.evalCtxPathExpression(node, exprRoot)

			ctxTried = true
		}

		if (result == nil) && node.Data {
			// if it is @root, then we tried to evaluate with root context but nothing was found
			// so let's try with private data

			// private data
			result = v.evalDataPathExpression(node, exprRoot)
		}

		if (result == nil) && !ctxTried {
			// context path
			result = v.evalCtxPathExpression(node, exprRoot)
		}
	}

	return result
}