1
0
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:
Tim Voronov
2019-09-01 16:01:03 -04:00
committed by GitHub
parent 4dbfe85b97
commit 2a8135657d
12 changed files with 805 additions and 582 deletions

View File

@@ -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 {

View File

@@ -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"`)
})
})
}

View File

@@ -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,
)