From ad2ec2e8175eff3e680fdbd00e17bfcc060e8bc0 Mon Sep 17 00:00:00 2001 From: 3timeslazy Date: Tue, 15 Oct 2019 21:06:48 +0300 Subject: [PATCH] build core.Functions with map --- e2e/runner/lib.go | 16 +++-- pkg/compiler/namespace.go | 6 +- pkg/runtime/core/function.go | 23 +++++-- pkg/stdlib/arrays/lib.go | 49 +++++++------- pkg/stdlib/collections/lib.go | 9 +-- pkg/stdlib/datetime/lib.go | 4 +- pkg/stdlib/html/lib.go | 117 +++++++++++++++++----------------- pkg/stdlib/math/lib.go | 71 +++++++++++---------- pkg/stdlib/objects/lib.go | 19 +++--- pkg/stdlib/strings/lib.go | 71 +++++++++++---------- pkg/stdlib/types/lib.go | 43 +++++++------ pkg/stdlib/utils/lib.go | 10 +-- 12 files changed, 231 insertions(+), 207 deletions(-) diff --git a/e2e/runner/lib.go b/e2e/runner/lib.go index a2c64ac9..a3f0d17a 100644 --- a/e2e/runner/lib.go +++ b/e2e/runner/lib.go @@ -11,15 +11,19 @@ import ( ) func HTTPHelpers(ns core.Namespace) error { - return ns.RegisterFunctions(core.FunctionsMap{ - "GET": httpGet, - }) + return ns.RegisterFunctions( + core.NewFunctionsFromMap(map[string]core.Function{ + "GET": httpGet, + }), + ) } func Assertions(ns core.Namespace) error { - return ns.RegisterFunctions(core.FunctionsMap{ - "EXPECT": expect, - }) + return ns.RegisterFunctions( + core.NewFunctionsFromMap(map[string]core.Function{ + "EXPECT": expect, + }), + ) } func expect(_ context.Context, args ...core.Value) (core.Value, error) { diff --git a/pkg/compiler/namespace.go b/pkg/compiler/namespace.go index c705aecb..c5b0e7c6 100644 --- a/pkg/compiler/namespace.go +++ b/pkg/compiler/namespace.go @@ -60,8 +60,10 @@ func (nc *NamespaceContainer) RemoveFunction(name string) { nc.funcs.Unset(nc.makeFullName(name)) } -func (nc *NamespaceContainer) RegisterFunctions(funcs core.FunctionsMap) error { - for name, fun := range funcs { +func (nc *NamespaceContainer) RegisterFunctions(funcs *core.Functions) error { + for _, name := range funcs.Names() { + fun, _ := funcs.Get(name) + if err := nc.RegisterFunction(name, fun); err != nil { return err } diff --git a/pkg/runtime/core/function.go b/pkg/runtime/core/function.go index 0d377183..ea723648 100644 --- a/pkg/runtime/core/function.go +++ b/pkg/runtime/core/function.go @@ -12,7 +12,7 @@ type ( Namespace interface { Namespace(name string) Namespace RegisterFunction(name string, fun Function) error - RegisterFunctions(funs FunctionsMap) error + RegisterFunctions(funs *Functions) error RegisteredFunctions() []string RemoveFunction(name string) } @@ -37,12 +37,9 @@ func ValidateArgs(args []Value, minimum, maximum int) error { type ( // Functions is a container for functions. Functions struct { - functions FunctionsMap + functions map[string]Function } - // FunctionsMap is a map of functions and their names. - FunctionsMap map[string]Function - // Function is a common interface for all functions of FQL. Function = func(ctx context.Context, args ...Value) (Value, error) ) @@ -50,10 +47,22 @@ type ( // NewFunctions returns new empty Functions. func NewFunctions() *Functions { return &Functions{ - functions: make(FunctionsMap), + functions: make(map[string]Function), } } +// NewFunctionsFromMap creates new Functions from map, where +// key is the name of the function and value is the function. +func NewFunctionsFromMap(funcs map[string]Function) *Functions { + fns := NewFunctions() + + for name, fn := range funcs { + fns.Set(name, fn) + } + + return fns +} + // Get returns the function with the given name. If the function // does not exist it returns nil, false. func (fns *Functions) Get(name string) (Function, bool) { @@ -67,7 +76,7 @@ func (fns *Functions) Set(name string, fn Function) { // the preferred way to create Functions is NewFunctions. // But just in case, if someone creates differently if fns.functions == nil { - fns.functions = make(FunctionsMap, 1) + fns.functions = make(map[string]Function, 1) } fns.functions[strings.ToUpper(name)] = fn diff --git a/pkg/stdlib/arrays/lib.go b/pkg/stdlib/arrays/lib.go index fda27e37..d56f57e1 100644 --- a/pkg/stdlib/arrays/lib.go +++ b/pkg/stdlib/arrays/lib.go @@ -6,30 +6,31 @@ import ( ) func RegisterLib(ns core.Namespace) error { - return ns.RegisterFunctions(core.FunctionsMap{ - "APPEND": Append, - "FIRST": First, - "FLATTEN": Flatten, - "INTERSECTION": Intersection, - "LAST": Last, - "MINUS": Minus, - "NTH": Nth, - "OUTERSECTION": Outersection, - "POP": Pop, - "POSITION": Position, - "PUSH": Push, - "REMOVE_NTH": RemoveNth, - "REMOVE_VALUE": RemoveValue, - "REMOVE_VALUES": RemoveValues, - "SHIFT": Shift, - "SLICE": Slice, - "SORTED": Sorted, - "SORTED_UNIQUE": SortedUnique, - "UNION": Union, - "UNION_DISTINCT": UnionDistinct, - "UNIQUE": Unique, - "UNSHIFT": Unshift, - }) + return ns.RegisterFunctions( + core.NewFunctionsFromMap(map[string]core.Function{ + "APPEND": Append, + "FIRST": First, + "FLATTEN": Flatten, + "INTERSECTION": Intersection, + "LAST": Last, + "MINUS": Minus, + "NTH": Nth, + "OUTERSECTION": Outersection, + "POP": Pop, + "POSITION": Position, + "PUSH": Push, + "REMOVE_NTH": RemoveNth, + "REMOVE_VALUE": RemoveValue, + "REMOVE_VALUES": RemoveValues, + "SHIFT": Shift, + "SLICE": Slice, + "SORTED": Sorted, + "SORTED_UNIQUE": SortedUnique, + "UNION": Union, + "UNION_DISTINCT": UnionDistinct, + "UNIQUE": Unique, + "UNSHIFT": Unshift, + })) } func ToUniqueArray(arr *values.Array) *values.Array { diff --git a/pkg/stdlib/collections/lib.go b/pkg/stdlib/collections/lib.go index 09007e69..7df673d5 100644 --- a/pkg/stdlib/collections/lib.go +++ b/pkg/stdlib/collections/lib.go @@ -3,8 +3,9 @@ package collections import "github.com/MontFerret/ferret/pkg/runtime/core" func RegisterLib(ns core.Namespace) error { - return ns.RegisterFunctions(core.FunctionsMap{ - "LENGTH": Length, - "REVERSE": Reverse, - }) + return ns.RegisterFunctions( + core.NewFunctionsFromMap(map[string]core.Function{ + "LENGTH": Length, + "REVERSE": Reverse, + })) } diff --git a/pkg/stdlib/datetime/lib.go b/pkg/stdlib/datetime/lib.go index 6168f1fd..3daa77b2 100644 --- a/pkg/stdlib/datetime/lib.go +++ b/pkg/stdlib/datetime/lib.go @@ -2,8 +2,8 @@ package datetime import "github.com/MontFerret/ferret/pkg/runtime/core" -func NewLib() core.FunctionsMap { - return core.FunctionsMap{ +func NewLib() map[string]core.Function { + return map[string]core.Function{ "NOW": Now, "DATE": Date, "DATE_DAYOFWEEK": DateDayOfWeek, diff --git a/pkg/stdlib/html/lib.go b/pkg/stdlib/html/lib.go index 5fcde2e4..09e95992 100644 --- a/pkg/stdlib/html/lib.go +++ b/pkg/stdlib/html/lib.go @@ -11,64 +11,65 @@ import ( ) func RegisterLib(ns core.Namespace) error { - return ns.RegisterFunctions(core.FunctionsMap{ - "ATTR_GET": AttributeGet, - "ATTR_REMOVE": AttributeRemove, - "ATTR_SET": AttributeSet, - "BLUR": Blur, - "COOKIE_DEL": CookieDel, - "COOKIE_GET": CookieGet, - "COOKIE_SET": CookieSet, - "CLICK": Click, - "CLICK_ALL": ClickAll, - "DOCUMENT": Open, - "DOWNLOAD": Download, - "ELEMENT": Element, - "ELEMENT_EXISTS": ElementExists, - "ELEMENTS": Elements, - "ELEMENTS_COUNT": ElementsCount, - "FOCUS": Focus, - "HOVER": Hover, - "INNER_HTML": GetInnerHTML, - "INNER_HTML_SET": SetInnerHTML, - "INNER_HTML_ALL": GetInnerHTMLAll, - "INNER_TEXT": GetInnerText, - "INNER_TEXT_SET": SetInnerText, - "INNER_TEXT_ALL": GetInnerTextAll, - "INPUT": Input, - "INPUT_CLEAR": InputClear, - "MOUSE": MouseMoveXY, - "NAVIGATE": Navigate, - "NAVIGATE_BACK": NavigateBack, - "NAVIGATE_FORWARD": NavigateForward, - "PAGINATION": Pagination, - "PDF": PDF, - "SCREENSHOT": Screenshot, - "SCROLL": ScrollXY, - "SCROLL_BOTTOM": ScrollBottom, - "SCROLL_ELEMENT": ScrollInto, - "SCROLL_TOP": ScrollTop, - "SELECT": Select, - "STYLE_GET": StyleGet, - "STYLE_REMOVE": StyleRemove, - "STYLE_SET": StyleSet, - "WAIT_ATTR": WaitAttribute, - "WAIT_NO_ATTR": WaitNoAttribute, - "WAIT_ATTR_ALL": WaitAttributeAll, - "WAIT_NO_ATTR_ALL": WaitNoAttributeAll, - "WAIT_ELEMENT": WaitElement, - "WAIT_NO_ELEMENT": WaitNoElement, - "WAIT_CLASS": WaitClass, - "WAIT_NO_CLASS": WaitNoClass, - "WAIT_CLASS_ALL": WaitClassAll, - "WAIT_NO_CLASS_ALL": WaitNoClassAll, - "WAIT_STYLE": WaitStyle, - "WAIT_NO_STYLE": WaitNoStyle, - "WAIT_STYLE_ALL": WaitStyleAll, - "WAIT_NO_STYLE_ALL": WaitNoStyleAll, - "WAIT_NAVIGATION": WaitNavigation, - "XPATH": XPath, - }) + return ns.RegisterFunctions( + core.NewFunctionsFromMap(map[string]core.Function{ + "ATTR_GET": AttributeGet, + "ATTR_REMOVE": AttributeRemove, + "ATTR_SET": AttributeSet, + "BLUR": Blur, + "COOKIE_DEL": CookieDel, + "COOKIE_GET": CookieGet, + "COOKIE_SET": CookieSet, + "CLICK": Click, + "CLICK_ALL": ClickAll, + "DOCUMENT": Open, + "DOWNLOAD": Download, + "ELEMENT": Element, + "ELEMENT_EXISTS": ElementExists, + "ELEMENTS": Elements, + "ELEMENTS_COUNT": ElementsCount, + "FOCUS": Focus, + "HOVER": Hover, + "INNER_HTML": GetInnerHTML, + "INNER_HTML_SET": SetInnerHTML, + "INNER_HTML_ALL": GetInnerHTMLAll, + "INNER_TEXT": GetInnerText, + "INNER_TEXT_SET": SetInnerText, + "INNER_TEXT_ALL": GetInnerTextAll, + "INPUT": Input, + "INPUT_CLEAR": InputClear, + "MOUSE": MouseMoveXY, + "NAVIGATE": Navigate, + "NAVIGATE_BACK": NavigateBack, + "NAVIGATE_FORWARD": NavigateForward, + "PAGINATION": Pagination, + "PDF": PDF, + "SCREENSHOT": Screenshot, + "SCROLL": ScrollXY, + "SCROLL_BOTTOM": ScrollBottom, + "SCROLL_ELEMENT": ScrollInto, + "SCROLL_TOP": ScrollTop, + "SELECT": Select, + "STYLE_GET": StyleGet, + "STYLE_REMOVE": StyleRemove, + "STYLE_SET": StyleSet, + "WAIT_ATTR": WaitAttribute, + "WAIT_NO_ATTR": WaitNoAttribute, + "WAIT_ATTR_ALL": WaitAttributeAll, + "WAIT_NO_ATTR_ALL": WaitNoAttributeAll, + "WAIT_ELEMENT": WaitElement, + "WAIT_NO_ELEMENT": WaitNoElement, + "WAIT_CLASS": WaitClass, + "WAIT_NO_CLASS": WaitNoClass, + "WAIT_CLASS_ALL": WaitClassAll, + "WAIT_NO_CLASS_ALL": WaitNoClassAll, + "WAIT_STYLE": WaitStyle, + "WAIT_NO_STYLE": WaitNoStyle, + "WAIT_STYLE_ALL": WaitStyleAll, + "WAIT_NO_STYLE_ALL": WaitNoStyleAll, + "WAIT_NAVIGATION": WaitNavigation, + "XPATH": XPath, + })) } func OpenOrCastPage(ctx context.Context, value core.Value) (drivers.HTMLPage, bool, error) { diff --git a/pkg/stdlib/math/lib.go b/pkg/stdlib/math/lib.go index e40e9416..41d76e0a 100644 --- a/pkg/stdlib/math/lib.go +++ b/pkg/stdlib/math/lib.go @@ -16,41 +16,42 @@ const ( ) func RegisterLib(ns core.Namespace) error { - return ns.RegisterFunctions(core.FunctionsMap{ - "ABS": Abs, - "ACOS": Acos, - "ASIN": Asin, - "ATAN": Atan, - "ATAN2": Atan2, - "AVERAGE": Average, - "CEIL": Ceil, - "COS": Cos, - "DEGREES": Degrees, - "EXP": Exp, - "EXP2": Exp2, - "FLOOR": Floor, - "LOG": Log, - "LOG2": Log2, - "LOG10": Log10, - "MAX": Max, - "MEDIAN": Median, - "MIN": Min, - "PERCENTILE": Percentile, - "PI": Pi, - "POW": Pow, - "RADIANS": Radians, - "RAND": Rand, - "RANGE": Range, - "ROUND": Round, - "SIN": Sin, - "SQRT": Sqrt, - "STDDEV_POPULATION": StandardDeviationPopulation, - "STDDEV_SAMPLE": StandardDeviationSample, - "SUM": Sum, - "TAN": Tan, - "VARIANCE_POPULATION": PopulationVariance, - "VARIANCE_SAMPLE": SampleVariance, - }) + return ns.RegisterFunctions( + core.NewFunctionsFromMap(map[string]core.Function{ + "ABS": Abs, + "ACOS": Acos, + "ASIN": Asin, + "ATAN": Atan, + "ATAN2": Atan2, + "AVERAGE": Average, + "CEIL": Ceil, + "COS": Cos, + "DEGREES": Degrees, + "EXP": Exp, + "EXP2": Exp2, + "FLOOR": Floor, + "LOG": Log, + "LOG2": Log2, + "LOG10": Log10, + "MAX": Max, + "MEDIAN": Median, + "MIN": Min, + "PERCENTILE": Percentile, + "PI": Pi, + "POW": Pow, + "RADIANS": Radians, + "RAND": Rand, + "RANGE": Range, + "ROUND": Round, + "SIN": Sin, + "SQRT": Sqrt, + "STDDEV_POPULATION": StandardDeviationPopulation, + "STDDEV_SAMPLE": StandardDeviationSample, + "SUM": Sum, + "TAN": Tan, + "VARIANCE_POPULATION": PopulationVariance, + "VARIANCE_SAMPLE": SampleVariance, + })) } func toFloat(arg core.Value) float64 { diff --git a/pkg/stdlib/objects/lib.go b/pkg/stdlib/objects/lib.go index f67fc2e3..65351f7b 100644 --- a/pkg/stdlib/objects/lib.go +++ b/pkg/stdlib/objects/lib.go @@ -3,13 +3,14 @@ package objects import "github.com/MontFerret/ferret/pkg/runtime/core" func RegisterLib(ns core.Namespace) error { - return ns.RegisterFunctions(core.FunctionsMap{ - "HAS": Has, - "KEYS": Keys, - "KEEP_KEYS": KeepKeys, - "MERGE": Merge, - "ZIP": Zip, - "VALUES": Values, - "MERGE_RECURSIVE": MergeRecursive, - }) + return ns.RegisterFunctions( + core.NewFunctionsFromMap(map[string]core.Function{ + "HAS": Has, + "KEYS": Keys, + "KEEP_KEYS": KeepKeys, + "MERGE": Merge, + "ZIP": Zip, + "VALUES": Values, + "MERGE_RECURSIVE": MergeRecursive, + })) } diff --git a/pkg/stdlib/strings/lib.go b/pkg/stdlib/strings/lib.go index 8baed88a..267dff41 100644 --- a/pkg/stdlib/strings/lib.go +++ b/pkg/stdlib/strings/lib.go @@ -3,39 +3,40 @@ package strings import "github.com/MontFerret/ferret/pkg/runtime/core" func RegisterLib(ns core.Namespace) error { - return ns.RegisterFunctions(core.FunctionsMap{ - "CONCAT": Concat, - "CONCAT_SEPARATOR": ConcatWithSeparator, - "CONTAINS": Contains, - "ESCAPE_HTML": EscapeHTML, - "DECODE_URI_COMPONENT": DecodeURIComponent, - "ENCODE_URI_COMPONENT": EncodeURIComponent, - "FIND_FIRST": FindFirst, - "FIND_LAST": FindLast, - "JSON_PARSE": JSONParse, - "JSON_STRINGIFY": JSONStringify, - "LEFT": Left, - "LIKE": Like, - "LOWER": Lower, - "LTRIM": LTrim, - "RANDOM_TOKEN": RandomToken, - "MD5": Md5, - "REGEXP_MATCH": RegexMatch, - "REGEXP_SPLIT": RegexSplit, - "REGEXP_TEST": RegexTest, - "REGEXP_REPLACE": RegexReplace, - "RIGHT": Right, - "RTRIM": RTrim, - "SHA1": Sha1, - "SHA512": Sha512, - "SPLIT": Split, - "SUBSTITUTE": Substitute, - "SUBSTRING": Substring, - "TO_BASE64": ToBase64, - "FROM_BASE64": FromBase64, - "TRIM": Trim, - "UPPER": Upper, - "FMT": Fmt, - "UNESCAPE_HTML": UnescapeHTML, - }) + return ns.RegisterFunctions( + core.NewFunctionsFromMap(map[string]core.Function{ + "CONCAT": Concat, + "CONCAT_SEPARATOR": ConcatWithSeparator, + "CONTAINS": Contains, + "ESCAPE_HTML": EscapeHTML, + "DECODE_URI_COMPONENT": DecodeURIComponent, + "ENCODE_URI_COMPONENT": EncodeURIComponent, + "FIND_FIRST": FindFirst, + "FIND_LAST": FindLast, + "JSON_PARSE": JSONParse, + "JSON_STRINGIFY": JSONStringify, + "LEFT": Left, + "LIKE": Like, + "LOWER": Lower, + "LTRIM": LTrim, + "RANDOM_TOKEN": RandomToken, + "MD5": Md5, + "REGEXP_MATCH": RegexMatch, + "REGEXP_SPLIT": RegexSplit, + "REGEXP_TEST": RegexTest, + "REGEXP_REPLACE": RegexReplace, + "RIGHT": Right, + "RTRIM": RTrim, + "SHA1": Sha1, + "SHA512": Sha512, + "SPLIT": Split, + "SUBSTITUTE": Substitute, + "SUBSTRING": Substring, + "TO_BASE64": ToBase64, + "FROM_BASE64": FromBase64, + "TRIM": Trim, + "UPPER": Upper, + "FMT": Fmt, + "UNESCAPE_HTML": UnescapeHTML, + })) } diff --git a/pkg/stdlib/types/lib.go b/pkg/stdlib/types/lib.go index 5b78096f..38e4decc 100644 --- a/pkg/stdlib/types/lib.go +++ b/pkg/stdlib/types/lib.go @@ -6,27 +6,28 @@ import ( ) func RegisterLib(ns core.Namespace) error { - return ns.RegisterFunctions(core.FunctionsMap{ - "TO_BOOL": ToBool, - "TO_INT": ToInt, - "TO_FLOAT": ToFloat, - "TO_STRING": ToString, - "TO_DATETIME": ToDateTime, - "TO_ARRAY": ToArray, - "IS_NONE": IsNone, - "IS_BOOL": IsBool, - "IS_INT": IsInt, - "IS_FLOAT": IsFloat, - "IS_STRING": IsString, - "IS_DATETIME": IsDateTime, - "IS_ARRAY": IsArray, - "IS_OBJECT": IsObject, - "IS_HTML_ELEMENT": IsHTMLElement, - "IS_HTML_DOCUMENT": IsHTMLDocument, - "IS_BINARY": IsBinary, - "IS_NAN": IsNaN, - "TYPENAME": TypeName, - }) + return ns.RegisterFunctions( + core.NewFunctionsFromMap(map[string]core.Function{ + "TO_BOOL": ToBool, + "TO_INT": ToInt, + "TO_FLOAT": ToFloat, + "TO_STRING": ToString, + "TO_DATETIME": ToDateTime, + "TO_ARRAY": ToArray, + "IS_NONE": IsNone, + "IS_BOOL": IsBool, + "IS_INT": IsInt, + "IS_FLOAT": IsFloat, + "IS_STRING": IsString, + "IS_DATETIME": IsDateTime, + "IS_ARRAY": IsArray, + "IS_OBJECT": IsObject, + "IS_HTML_ELEMENT": IsHTMLElement, + "IS_HTML_DOCUMENT": IsHTMLDocument, + "IS_BINARY": IsBinary, + "IS_NAN": IsNaN, + "TYPENAME": TypeName, + })) } func isTypeof(value core.Value, ctype core.Type) core.Value { diff --git a/pkg/stdlib/utils/lib.go b/pkg/stdlib/utils/lib.go index 87ff4c66..ff87cc56 100644 --- a/pkg/stdlib/utils/lib.go +++ b/pkg/stdlib/utils/lib.go @@ -3,8 +3,10 @@ package utils import "github.com/MontFerret/ferret/pkg/runtime/core" func RegisterLib(ns core.Namespace) error { - return ns.RegisterFunctions(core.FunctionsMap{ - "WAIT": Wait, - "PRINT": Print, - }) + return ns.RegisterFunctions( + core.NewFunctionsFromMap(map[string]core.Function{ + "WAIT": Wait, + "PRINT": Print, + }), + ) }