Beispiel #1
0
func getCompletions(vm *otto.Otto, line string) (results []string) {
	parts := strings.Split(line, ".")
	objRef := "this"
	prefix := line
	if len(parts) > 1 {
		objRef = strings.Join(parts[0:len(parts)-1], ".")
		prefix = parts[len(parts)-1]
	}

	obj, _ := vm.Object(objRef)
	if obj == nil {
		return nil
	}
	iterOwnAndConstructorKeys(vm, obj, func(k string) {
		if strings.HasPrefix(k, prefix) {
			if objRef == "this" {
				results = append(results, k)
			} else {
				results = append(results, strings.Join(parts[:len(parts)-1], ".")+"."+k)
			}
		}
	})
	// e.g. web3<tab><tab> append dot since its an object
	if obj, _ = vm.Object(line); obj != nil {
		results = append(results, line+".")
	}

	sort.Strings(results)
	return results
}
Beispiel #2
0
func reverseGremlinChainTo(env *otto.Otto, prevObj *otto.Object, tag string) (*otto.Object, *otto.Object) {
	env.Run("var _base_object = {}")
	base, err := env.Object("_base_object")
	if err != nil {
		glog.Error(err)
		return otto.NullValue().Object(), otto.NullValue().Object()
	}
	if isVertexChain(prevObj) {
		base.Set("_gremlin_type", "vertex")
	} else {
		base.Set("_gremlin_type", "morphism")
	}
	return reverseGremlinChainHelper(env, prevObj, base, tag)
}
Beispiel #3
0
func iterOwnKeys(vm *otto.Otto, obj *otto.Object, f func(string)) {
	Object, _ := vm.Object("Object")
	rv, _ := Object.Call("getOwnPropertyNames", obj.Value())
	gv, _ := rv.Export()
	switch gv := gv.(type) {
	case []interface{}:
		for _, v := range gv {
			f(v.(string))
		}
	case []string:
		for _, v := range gv {
			f(v)
		}
	default:
		panic(fmt.Errorf("Object.getOwnPropertyNames returned unexpected type %T", gv))
	}
}
Beispiel #4
0
func OttoNewFunction(o *otto.Otto, f string) (otto.Value, error) {
	fn, err := o.Object("(" + f + ")")
	if err != nil {
		return otto.UndefinedValue(),
			fmt.Errorf("could not eval function, err: %v", err)
	}
	if fn.Class() != "Function" {
		return otto.UndefinedValue(),
			fmt.Errorf("fn not a function, was: %v", fn.Class())
	}
	fnv := fn.Value()
	if fnv.Class() != "Function" {
		return otto.UndefinedValue(),
			fmt.Errorf("fnv not a function, was: %v", fnv.Class())
	}
	return fnv, nil
}
Beispiel #5
0
func OttoFromGo(o *otto.Otto, v interface{}) (otto.Value, error) {
	jv, err := json.Marshal(v)
	if err != nil {
		return otto.UndefinedValue(),
			fmt.Errorf("could not jsonify v, err: %v", err)
	}
	obj, err := o.Object("({v:" + string(jv) + "})")
	if err != nil {
		return otto.UndefinedValue(),
			fmt.Errorf("could not convert jv, err: %v", err)
	}
	objv, err := obj.Get("v")
	if err != nil {
		return otto.UndefinedValue(),
			fmt.Errorf("could not convert obj, err: %v", err)
	}
	return objv, nil
}
Beispiel #6
0
func reverseGremlinChainHelper(env *otto.Otto, chain *otto.Object, newBase *otto.Object, tag string) (*otto.Object, *otto.Object) {
	kindVal, _ := chain.Get("_gremlin_type")
	kind, _ := kindVal.ToString()

	if tag != "" {
		if kind == "tag" {
			tags := getStringArgs(chain)
			for _, t := range tags {
				if t == tag {
					return newBase, chain
				}
			}
		}
	}

	if kind == "morphism" || kind == "vertex" {
		return newBase, chain
	}
	var newKind string
	switch kind {
	case "in":
		newKind = "out"
	case "out":
		newKind = "in"
	default:
		newKind = kind
	}
	prev, _ := chain.Get("_gremlin_prev")
	env.Run("var out = {}")
	out, _ := env.Object("out")
	out.Set("_gremlin_type", newKind)
	values, _ := chain.Get("_gremlin_values")
	out.Set("_gremlin_values", values)
	back, _ := chain.Get("_gremlin_back_chain")
	out.Set("_gremlin_back_chain", back)
	out.Set("_gremlin_prev", newBase)
	strings, _ := chain.Get("string_args")
	out.Set("string_args", strings)
	return reverseGremlinChainHelper(env, prev.Object(), out, tag)
}
Beispiel #7
0
func getCompletions(vm *otto.Otto, line string) (results []string) {
	parts := strings.Split(line, ".")
	objRef := "this"
	prefix := line
	if len(parts) > 1 {
		objRef = strings.Join(parts[0:len(parts)-1], ".")
		prefix = parts[len(parts)-1]
	}

	obj, _ := vm.Object(objRef)
	if obj == nil {
		return nil
	}
	iterOwnAndConstructorKeys(vm, obj, func(k string) {
		if strings.HasPrefix(k, prefix) {
			if objRef == "this" {
				results = append(results, k)
			} else {
				results = append(results, strings.Join(parts[:len(parts)-1], ".")+"."+k)
			}
		}
	})

	// Append opening parenthesis (for functions) or dot (for objects)
	// if the line itself is the only completion.
	if len(results) == 1 && results[0] == line {
		obj, _ := vm.Object(line)
		if obj != nil {
			if obj.Class() == "Function" {
				results[0] += "("
			} else {
				results[0] += "."
			}
		}
	}

	sort.Strings(results)
	return results
}
Beispiel #8
0
func setupGremlin(env *otto.Otto, ses *Session) {
	graph, _ := env.Object("graph = {}")
	graph.Set("Vertex", func(call otto.FunctionCall) otto.Value {
		call.Otto.Run("var out = {}")
		out, err := call.Otto.Object("out")
		if err != nil {
			glog.Error(err.Error())
			return otto.TrueValue()
		}
		out.Set("_gremlin_type", "vertex")
		outStrings := concatStringArgs(call)
		if len(*outStrings) > 0 {
			out.Set("string_args", *outStrings)
		}
		embedTraversals(env, ses, out)
		embedFinals(env, ses, out)
		return out.Value()
	})

	graph.Set("Morphism", func(call otto.FunctionCall) otto.Value {
		call.Otto.Run("var out = {}")
		out, _ := call.Otto.Object("out")
		out.Set("_gremlin_type", "morphism")
		embedTraversals(env, ses, out)
		return out.Value()
	})
	graph.Set("Emit", func(call otto.FunctionCall) otto.Value {
		value := call.Argument(0)
		if value.IsDefined() {
			ses.SendResult(&GremlinResult{metaresult: false, err: "", val: &value, actualResults: nil})
		}
		return otto.NullValue()
	})
	env.Run("graph.V = graph.Vertex")
	env.Run("graph.M = graph.Morphism")
	env.Run("g = graph")

}
Beispiel #9
0
func setValueAtPath(context *otto.Otto, path string, value interface{}) {
	parts := strings.Split(path, ".")
	parentCount := len(parts) - 1
	if parentCount > 0 {
		parentPath := strings.Join(parts[0:parentCount], ".")
		parent, err := context.Object("(" + parentPath + ")")
		if err != nil {
			emptyObject, _ := context.Object(`({})`)
			setValueAtPath(context, parentPath, emptyObject)
		}
		parent, _ = context.Object("(" + parentPath + ")")
		parent.Set(parts[parentCount], value)
	} else {
		context.Set(path, value)
	}
}