mirror of
https://github.com/MontFerret/ferret.git
synced 2025-11-06 08:39:09 +02:00
Fixed access to a member property right after a function call (#368)
This commit is contained in:
@@ -1,19 +1,20 @@
|
||||
package compiler
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/MontFerret/ferret/pkg/parser"
|
||||
"github.com/MontFerret/ferret/pkg/runtime"
|
||||
"github.com/MontFerret/ferret/pkg/runtime/core"
|
||||
"github.com/MontFerret/ferret/pkg/stdlib"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type FqlCompiler struct {
|
||||
type Compiler struct {
|
||||
*NamespaceContainer
|
||||
}
|
||||
|
||||
func New(setters ...Option) *FqlCompiler {
|
||||
c := &FqlCompiler{}
|
||||
func New(setters ...Option) *Compiler {
|
||||
c := &Compiler{}
|
||||
c.NamespaceContainer = newRootNamespace()
|
||||
c.funcs = make(map[string]core.Function)
|
||||
|
||||
@@ -32,7 +33,7 @@ func New(setters ...Option) *FqlCompiler {
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *FqlCompiler) Compile(query string) (program *runtime.Program, err error) {
|
||||
func (c *Compiler) Compile(query string) (program *runtime.Program, err error) {
|
||||
if query == "" {
|
||||
return nil, ErrEmptyQuery
|
||||
}
|
||||
@@ -69,7 +70,7 @@ func (c *FqlCompiler) Compile(query string) (program *runtime.Program, err error
|
||||
return program, err
|
||||
}
|
||||
|
||||
func (c *FqlCompiler) MustCompile(query string) *runtime.Program {
|
||||
func (c *Compiler) MustCompile(query string) *runtime.Program {
|
||||
program, err := c.Compile(query)
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -119,6 +119,42 @@ func TestMember(t *testing.T) {
|
||||
|
||||
So(string(out), ShouldEqual, `"wsx"`)
|
||||
})
|
||||
|
||||
Convey("Prop after a func call", func() {
|
||||
c := compiler.New()
|
||||
|
||||
p, err := c.Compile(`
|
||||
LET arr = [{ name: "Bob" }]
|
||||
|
||||
RETURN FIRST(arr).name
|
||||
`)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
out, err := p.Run(context.Background())
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(string(out), ShouldEqual, `"Bob"`)
|
||||
})
|
||||
|
||||
Convey("Computed prop after a func call", func() {
|
||||
c := compiler.New()
|
||||
|
||||
p, err := c.Compile(`
|
||||
LET arr = [{ name: { first: "Bob" } }]
|
||||
|
||||
RETURN FIRST(arr)['name'].first
|
||||
`)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
out, err := p.Run(context.Background())
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(string(out), ShouldEqual, `"Bob"`)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -736,15 +736,39 @@ func (v *visitor) doVisitForExpressionStatement(ctx *fql.ForExpressionStatementC
|
||||
}
|
||||
|
||||
func (v *visitor) doVisitMemberExpression(ctx *fql.MemberExpressionContext, scope *scope) (core.Expression, error) {
|
||||
varName := ctx.Identifier().GetText()
|
||||
var source core.Expression
|
||||
var children []antlr.Tree
|
||||
|
||||
_, err := scope.GetVariable(varName)
|
||||
identifier := ctx.Identifier()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if identifier != nil {
|
||||
varName := ctx.Identifier().GetText()
|
||||
|
||||
_, err := scope.GetVariable(varName)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
varExp, err := expressions.NewVariableExpression(v.getSourceMap(ctx), varName)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
source = varExp
|
||||
children = ctx.GetChildren()
|
||||
} else {
|
||||
fcall, err := v.doVisitFunctionCallExpression(ctx.FunctionCallExpression().(*fql.FunctionCallExpressionContext), scope)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
source = fcall
|
||||
children = ctx.GetChildren()[1:]
|
||||
}
|
||||
|
||||
children := ctx.GetChildren()
|
||||
path := make([]core.Expression, 0, len(children))
|
||||
|
||||
for _, child := range children {
|
||||
@@ -786,7 +810,7 @@ func (v *visitor) doVisitMemberExpression(ctx *fql.MemberExpressionContext, scop
|
||||
|
||||
member, err := expressions.NewMemberExpression(
|
||||
v.getSourceMap(ctx),
|
||||
varName,
|
||||
source,
|
||||
path,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user