示例#1
0
文件: parser_test.go 项目: kego/ke
func TestParse1(t *testing.T) {

	cb := tests.New().TempGopath(true)
	defer cb.Cleanup()

	path, dir := cb.TempPackage("a", map[string]string{
		"a.json": `{
			"description": "a",
			"type": "system:type",
			"id": "b",
			"fields": {
				"c": {
					"type": "system:@string"
				}
			}
		}`,
	})

	cb.Path(path).Dir(dir).Cmd().Sempty().Jsystem()

	_, err := Parse(cb.Ctx(), path)
	require.NoError(t, err)

	scache := sysctx.FromContext(cb.Ctx())
	i, ok := scache.GetType(path, "b")
	assert.True(t, ok)
	ty, ok := i.(*system.Type)
	assert.True(t, ok)
	assert.Equal(t, "a", ty.Description)

}
示例#2
0
文件: type.go 项目: kego/ke
func GetAllTypesThatImplementReflectInterface(ctx context.Context, reflectType reflect.Type) []*Type {

	if reflectType.Kind() != reflect.Interface {
		panic(kerr.New("JUCCMVNDLR", "%v is not an interface", reflectType).Error())
	}

	scache := sysctx.FromContext(ctx)

	out := []*Type{}

	for _, pkgName := range scache.Keys() {
		pkgInfo, ok := scache.Get(pkgName)
		if !ok {
			// ke: {"block": {"notest": true}}
			continue
		}
		for _, typName := range pkgInfo.Types.Keys() {
			typ, ok := pkgInfo.Types.Get(typName)
			if !ok {
				// ke: {"block": {"notest": true}}
				continue
			}
			t := typ.Type.(*Type)
			if t.Interface {
				continue
			}
			if t.Implements(ctx, reflectType) {
				out = append(out, t)
			}
		}
	}

	return out
}
示例#3
0
文件: validate.go 项目: kego/ke
func comparePackageHash(ctx context.Context, path string) (changes bool, err error) {

	scache := sysctx.FromContext(ctx)
	spi, ok := scache.Get(path)
	if !ok {
		return false, kerr.New("NHXWLPHCHL", "%s not found in sys ctx", path)
	}

	for _, aliasPath := range spi.Aliases {
		changes, err := comparePackageHash(ctx, aliasPath)
		if err != nil {
			return false, kerr.Wrap("DGJTLHQOCQ", err)
		}
		if changes {
			return true, nil
		}
	}

	jcache := jsonctx.FromContext(ctx)
	jpi, ok := jcache.Packages.Get(path)
	if !ok {
		return true, nil
	}

	// pcache.Environment.Hash is computed after parsing all the data files.
	// h.Hash is in generated.go (jsonctx.InitPackage), and correct when the types were generated.
	if jpi.Hash != spi.Hash {
		return true, nil
	}
	return false, nil
}
示例#4
0
文件: panel.go 项目: kego/ke
func addNewFile(ctx context.Context, app *stores.App, all bool) {

	var types []*system.Type
	if all {
		rt := reflect.TypeOf((*system.ObjectInterface)(nil)).Elem()
		typesAll := system.GetAllTypesThatImplementReflectInterface(ctx, rt)

		// TODO: Work out a more elegant way of doing this!
		rule := reflect.TypeOf((*system.RuleInterface)(nil)).Elem()
		for _, t := range typesAll {
			if t.Id.Package == "kego.io/system" {
				// none of the system types should be added as a global
				continue
			}
			if t.Implements(ctx, rule) {
				// rules should never be added as a global
				continue
			}
			types = append(types, t)
		}

	} else {
		syscache := sysctx.FromContext(ctx)
		t, ok := syscache.GetType("kego.io/system", "type")
		if !ok {
			panic(kerr.New("NNFSJEXNKF", "Can't find system:type in sys ctx").Error())
		}
		types = []*system.Type{t.(*system.Type)}
	}

	app.Dispatch(&actions.OpenAddPopup{
		Types: types,
	})

}
示例#5
0
文件: validate_test.go 项目: kego/ke
func TestComparePackageHash(t *testing.T) {
	cb := tests.New().TempGopath(true)
	path, _ := cb.TempPackage("a", map[string]string{
		"a.yaml": "type: system:package",
	})
	cb.Path(path).Jempty().Spkg(path)

	// "a.b/c" not found in scache.
	changes, err := comparePackageHash(cb.Ctx(), "a.b/c")
	assert.IsError(t, err, "NHXWLPHCHL")
	assert.False(t, changes)

	// path not found in jcache
	changes, err = comparePackageHash(cb.Ctx(), path)
	require.NoError(t, err)
	assert.True(t, changes)

	cb.Jsystem().Jpkg(path, 999).Sauto(parser.Parse)

	// hash changed
	changes, err = comparePackageHash(cb.Ctx(), path)
	require.NoError(t, err)
	assert.True(t, changes)

	scache := sysctx.FromContext(cb.Ctx())
	pi, _ := scache.Get(path)
	cb.Jpkg(path, pi.Hash)

	// hash correct
	changes, err = comparePackageHash(cb.Ctx(), path)
	require.NoError(t, err)
	assert.False(t, changes)

	pi.Aliases["c"] = "a.b/c"

	changes, err = comparePackageHash(cb.Ctx(), path)
	assert.IsError(t, err, "DGJTLHQOCQ")
	assert.False(t, changes)

	pi1 := scache.Set("a.b/c")

	changes, err = comparePackageHash(cb.Ctx(), path)
	require.NoError(t, err)
	assert.True(t, changes)

	cb.Jpkg("a.b/c", 1)
	pi1.Hash = 2

	changes, err = comparePackageHash(cb.Ctx(), path)
	require.NoError(t, err)
	assert.True(t, changes)

	pi1.Hash = 1

	changes, err = comparePackageHash(cb.Ctx(), path)
	require.NoError(t, err)
	assert.False(t, changes)

}
示例#6
0
文件: tests.go 项目: kego/ke
func (c *ContextBuilder) initSys() *sysctx.SysCache {
	scache := sysctx.FromContextOrNil(c.ctx)
	if scache == nil {
		c.ctx = sysctx.NewContext(c.ctx)
		scache = sysctx.FromContext(c.ctx)
	}
	return scache
}
示例#7
0
文件: type.go 项目: kego/ke
func GetTypeFromCache(ctx context.Context, path string, name string) (*Type, bool) {
	scache := sysctx.FromContext(ctx)
	pcache, ok := scache.Get(path)
	if !ok {
		return nil, false
	}
	t, ok := pcache.Types.Get(name)
	if !ok {
		return nil, false
	}
	return t.Type.(*Type), true
}
示例#8
0
文件: structfragment.go 项目: kego/ke
func NewStructFragmentView(ctx context.Context, node *node.Node, origin *system.Reference) *StructFragmentView {
	v := &StructFragmentView{}
	v.View = New(ctx, v)
	v.model = v.App.Editors.Get(node)
	v.origin = origin
	if ti, ok := sysctx.FromContext(ctx).GetType(origin.Package, origin.Name); ok {
		v.originType = ti.(*system.Type)
	} else {
		v.App.Fail <- kerr.New("DNMXCJXNVU", "Type %s not found in system context", origin.String())
		return nil
	}
	return v
}
示例#9
0
文件: rule_ext_test.go 项目: kego/ke
func checkReflectType(ctx context.Context, t *testing.T, path string, name string, field string, output string) {
	scache := sysctx.FromContext(ctx)
	p, ok := scache.Get(path)
	assert.True(t, ok)
	typ, ok := p.Types.Get(name)
	assert.True(t, ok)
	ty, ok := typ.Type.(*system.Type)
	assert.True(t, ok)
	r, ok := ty.Fields[field]
	assert.True(t, ok)
	rh := system.WrapRule(ctx, r)
	rt, err := rh.GetReflectType()
	require.NoError(t, err)
	assert.Equal(t, output, rt.String())
}
示例#10
0
文件: client.go 项目: kego/ke
func registerTypes(ctx context.Context, path string, imports map[string]shared.ImportInfo) (*sysctx.SysPackageInfo, error) {
	system.RegisterJsonTypes(ctx)
	scache := sysctx.FromContext(ctx)
	var current *sysctx.SysPackageInfo
	for _, info := range imports {
		env := &envctx.Env{Path: info.Path, Aliases: info.Aliases}
		pcache := scache.SetEnv(env)
		for _, ti := range info.Types {
			if err := parser.ProcessTypeFileBytes(ctx, env, ti.File, ti.Bytes, pcache, nil); err != nil {
				return nil, kerr.Wrap("UJLXYWCVUC", err)
			}
		}
		if path == info.Path {
			current = pcache
		}
	}
	return current, nil
}
示例#11
0
文件: client_test.go 项目: kego/ke
func TestRegisterTypes(t *testing.T) {
	cb := tests.New().Sempty().Jauto()

	imports := map[string]shared.ImportInfo{
		"a": {
			Path: "b",
			Types: map[string]shared.TypeInfo{
				"c": {Bytes: []byte(`{"type": "system:type", "id": "d"}`)},
			},
		},
		"g": {
			Path: "h",
			Types: map[string]shared.TypeInfo{
				"i": {Bytes: []byte(`{"type": "system:type", "id": "j"}`)},
			},
		},
	}
	pi, err := registerTypes(cb.Ctx(), "b", imports)
	require.NoError(t, err)

	ti, ok := pi.Types.Get("d")
	assert.True(t, ok)
	assert.Equal(t, "b:d", ti.Type.(*system.Type).Id.String())

	sc := sysctx.FromContext(cb.Ctx())

	pi, ok = sc.Get("b")
	assert.True(t, ok)

	ti, ok = pi.Types.Get("d")
	assert.True(t, ok)
	assert.Equal(t, "b:d", ti.Type.(*system.Type).Id.String())

	pi, ok = sc.Get("h")
	assert.True(t, ok)

	ti, ok = pi.Types.Get("j")
	assert.True(t, ok)
	assert.Equal(t, "h:j", ti.Type.(*system.Type).Id.String())

}
示例#12
0
文件: generate.go 项目: kego/ke
func GenerateAll(ctx context.Context, path string, done map[string]bool) error {

	if _, found := done[path]; found {
		return nil
	}

	scache := sysctx.FromContext(ctx)
	pi, ok := scache.Get(path)
	if !ok {
		return kerr.New("XMVXECGDOX", "%s not found in ctx", path)
	}
	if path != "kego.io/system" {
		if err := GenerateAll(ctx, "kego.io/system", done); err != nil {
			return kerr.Wrap("HBKXDVYWUP", err)
		}
	}
	for _, aliasPath := range pi.Aliases {
		if err := GenerateAll(ctx, aliasPath, done); err != nil {
			return kerr.Wrap("WVXTUBQYVT", err)
		}
	}

	info, found, err := getInfo(ctx, pi.Dir)
	if err != nil {
		return kerr.Wrap("SIMBVNBWOV", err)
	}

	if FORCE_GENERATE || !found || info.Hash != pi.Hash {
		if err := Generate(ctx, pi.Env); err != nil {
			return kerr.Wrap("TUFKDUPWMD", err)
		}
	}

	done[path] = true

	return nil

}
示例#13
0
文件: json.go 项目: kego/ke
func RegisterJsonTypes(ctx context.Context) {

	scache := sysctx.FromContext(ctx)
	pcache := scache.Set("kego.io/json")

	tr := NewReference("kego.io/system", "type")

	makeRule := func(name string) *Type {
		return &Type{
			Object: &Object{
				Id:   NewReference("kego.io/json", fmt.Sprint(jsonctx.RULE_PREFIX, name)),
				Type: tr},
			Interface: false,
			Embed:     []*Reference{NewReference("kego.io/system", "rule")},
			Native:    NewString("object"),
			Fields:    map[string]RuleInterface{},
			Rule:      (*Type)(nil)}
	}

	makeType := func(name string) *Type {
		return &Type{
			Object: &Object{
				Id:   NewReference("kego.io/json", name),
				Type: tr},
			Interface: false,
			Native:    NewString(name),
			Fields:    map[string]RuleInterface{},
			Rule:      makeRule(name)}
	}

	pcache.Types.Set("string", "", makeType("string"))
	pcache.Types.Set("number", "", makeType("number"))
	pcache.Types.Set("bool", "", makeType("bool"))
	pcache.Types.Set("@string", "", makeRule("string"))
	pcache.Types.Set("@number", "", makeRule("number"))
	pcache.Types.Set("@bool", "", makeRule("bool"))

}
示例#14
0
文件: server.go 项目: kego/ke
func root(ctx context.Context, w http.ResponseWriter, req *http.Request, auth auther.Auther) error {

	wgctx.Add(ctx, "root")
	defer wgctx.Done(ctx, "root")

	if b, err := static.Asset(req.URL.Path[1:]); err == nil {
		if strings.HasSuffix(req.URL.Path, ".css") {
			w.Header().Set("Content-Type", "text/css")
		}
		if err := writeWithTimeout(w, b); err != nil {
			return kerr.Wrap("PVPCXBIUJT", err)
		}
		return nil
	}

	path := req.URL.Path[1:]
	if strings.HasSuffix(path, "/") {
		path = path[0 : len(path)-1]
	}

	// use a new context with a blank sysctx for the duration of this function
	// to prevent caching
	ctx = sysctx.NewContext(ctx)

	scache := sysctx.FromContext(ctx)

	env, err := parser.ScanForEnv(ctx, path)
	if err != nil {
		if _, ok := kerr.Source(err).(gopackages.NotFoundError); ok {
			w.WriteHeader(404)
			return nil
		}
		return kerr.Wrap("ALINBMKDRP", err)
	}

	pcache, err := parser.Parse(ctx, path)
	if err != nil {
		return kerr.Wrap("HIHWJRPUKE", err)
	}

	if err := process.GenerateAll(ctx, env.Path, map[string]bool{}); err != nil {
		return kerr.Wrap("LVGHABDYNQ", err)
	}

	data := map[string]string{}
	for _, name := range pcache.Globals.Keys() {
		if g, ok := pcache.Globals.Get(name); ok {
			data[name] = g.File
		}
	}

	pkgBytes := pcache.PackageBytes
	pkgFilename := pcache.PackageFilename
	if pkgBytes == nil {
		b, err := system.Marshal(ctx, system.EmptyPackage())
		if err != nil {
			return kerr.Wrap("OUBOTYGPKU", err)
		}
		pkgBytes = b
		pkgFilename = "package.ke.json"
	}

	imports := map[string]shared.ImportInfo{}

	var scan func(string) error
	scan = func(path string) error {
		if _, ok := imports[path]; ok {
			return nil
		}
		syspi, ok := scache.Get(path)
		if !ok {
			return kerr.New("VIGKIUPNCF", "%s not found in sys ctx", path)
		}
		info := shared.ImportInfo{
			Path:    path,
			Aliases: syspi.Aliases,
			Types:   map[string]shared.TypeInfo{},
		}
		for _, name := range syspi.Files.Keys() {
			if b, ok := syspi.Files.Get(name); ok {
				info.Types[name] = shared.TypeInfo{
					File:  b.File,
					Bytes: b.Bytes,
				}
			}
		}
		imports[path] = info

		for _, child := range syspi.Aliases {
			if err := scan(child); err != nil {
				return kerr.Wrap("NCULMUUUOT", err)
			}
		}
		return nil
	}
	// First we always import system
	if err := scan("kego.io/system"); err != nil {
		return kerr.Wrap("KRXSLOJKWV", err)
	}
	if err := scan(env.Path); err != nil {
		return kerr.Wrap("EELKQDCJGN", err)
	}

	info := shared.Info{
		Path:            env.Path,
		Aliases:         env.Aliases,
		Data:            data,
		Package:         pkgBytes,
		PackageFilename: pkgFilename,
		Imports:         imports,
		Hash:            auth.Sign([]byte(env.Path)),
	}
	buf := bytes.NewBuffer([]byte{})
	err = gob.NewEncoder(buf).Encode(info)
	if err != nil {
		return kerr.Wrap("OHBYTULHUQ", err)
	}
	base64EncodedString := base64.StdEncoding.EncodeToString(buf.Bytes())
	attrib := base64EncodedString

	source := []byte(`
		<html>
			<head>
				<meta charset="utf-8">
				<link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css">
				<link rel="stylesheet" href="/bootstrap/css/bootstrap-theme.min.css">
				<link rel="stylesheet" href="/split.css">
				<link rel="stylesheet" href="/editors.css">
				<link rel="stylesheet" href="/tree.css">
				<script src="/jquery-2.2.4.min.js"></script>
				<script src="/jquery-ui/jquery-ui.min.js"></script>
				<script src="/split.min.js"></script>
				<script src="/bootstrap/js/bootstrap.min.js"></script>
				<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
			</head>
			<body id="body" info="` + attrib + `"></body>
			<script src="/` + env.Path + `/script.js"></script>
		</html>`)

	if err := writeWithTimeout(w, source); err != nil {
		return kerr.Wrap("ICJSAIMDRF", err)
	}

	return nil
}
示例#15
0
文件: parser.go 项目: kego/ke
func parse(ctx context.Context, path string, queue []string) (*sysctx.SysPackageInfo, error) {

	scache := sysctx.FromContext(ctx)
	cmd := cmdctx.FromContext(ctx)

	for _, q := range queue {
		if q == path {
			return nil, kerr.New("SCSCFJPPHD", "Circular import %v -> %v", queue, path)
		}
	}

	if _, found := scache.Get("kego.io/json"); !found {
		system.RegisterJsonTypes(ctx)
	}

	hash := &PackageHasher{Path: path, Aliases: map[string]string{}, Types: map[string]uint64{}, Exports: map[string]uint64{}}

	importPackage := func(importPath string, importAlias string) error {
		if _, found := scache.Get(importPath); !found {
			_, err := parse(ctx, importPath, append(queue, path))
			if err != nil {
				return kerr.Wrap("RIARRSCMVE", err)
			}
		}
		hash.Aliases[importAlias] = importPath
		return nil
	}

	packageDirectoryExists := true
	_, err := packages.GetDirFromPackage(ctx, path)
	if err != nil {
		_, ok := kerr.Source(err).(gopackages.NotFoundError)
		if ok {
			packageDirectoryExists = false
		}
	}
	if !packageDirectoryExists || cmd.Update {
		if err := GoGet(ctx, path); err != nil {
			return nil, kerr.Wrap("SBALWXUPKN", err)
		}
	}

	env, err := ScanForEnv(ctx, path)
	if err != nil {
		return nil, kerr.Wrap("GJRHNGGWFD", err)
	}

	// Always scan the system package first if we don't have it already
	if path != "kego.io/system" {
		if err := importPackage("kego.io/system", "system"); err != nil {
			return nil, kerr.Wrap("ORRCDNUPOX", err)
		}
	}

	for aliasName, aliasPath := range env.Aliases {
		if aliasPath == "kego.io/system" || aliasName == "system" {
			return nil, kerr.New("EWMLNJDXKC", "Illegal import %s", aliasName)
		}
		if err := importPackage(aliasPath, aliasName); err != nil {
			return nil, kerr.Wrap("NOVMGYKHHI", err)
		}
	}

	pcache := scache.SetEnv(env)

	cmd.Printf("Parsing %s...", path)

	if err := scanForTypesAndExports(ctx, env, pcache, hash); err != nil {
		return nil, kerr.Wrap("VFUNPHUFHD", err)
	}

	cmd.Println(" OK.")

	h, err := hash.Hash()
	if err != nil {
		return nil, kerr.Wrap("MIODRYNEJQ", err)
	}
	env.Hash = h

	return pcache, nil
}
示例#16
0
文件: structs.go 项目: kego/ke
func Structs(ctx context.Context, env *envctx.Env) (source []byte, err error) {

	scache := sysctx.FromContext(ctx)

	pcache, ok := scache.Get(env.Path)
	if !ok {
		return nil, kerr.New("DQVQWTKRSK", "%s not found in sys ctx", env.Path)
	}
	types := pcache.Types
	exports := pcache.Exports

	g := builder.New(env.Path)

	infoBytes, _ := json.Marshal(InfoStruct{Path: env.Path, Hash: env.Hash})

	g.SetPackageComment("info:" + string(infoBytes))
	g.SetIntroComment(`ke: {"file": {"notest": true}}`)

	for _, name := range types.Keys() {
		t, ok := types.Get(name)
		if !ok {
			// ke: {"block": {"notest": true}}
			continue
		}
		typ := t.Type.(*system.Type)

		isRule := typ.Id.IsRule()
		isNativeCollection := typ.IsNativeCollection() && typ.Alias == nil

		if !typ.Interface && !typ.Custom {
			if typ.Alias != nil {
				if err := printAliasDefinition(ctx, env, g, typ); err != nil {
					return nil, kerr.Wrap("TRERIECOEP", err)
				}
				if kind, _ := typ.Kind(ctx); kind == system.KindValue {
					if err := printValueMethod(ctx, env, g, typ); err != nil {
						return nil, kerr.Wrap("PGDUJQVQGR", err)
					}
				}
			} else {
				if err := printStructDefinition(ctx, env, g, typ); err != nil {
					return nil, kerr.Wrap("XKRYMXUIJD", err)
				}
			}
		}

		if !typ.Interface && !isRule && !isNativeCollection {
			printInterfaceDefinition(ctx, env, g, typ)
			printInterfaceImplementation(ctx, env, g, typ)
		}

		if !isRule && !isNativeCollection {
			printInterfaceUnpacker(ctx, env, g, typ)
		}

		if !typ.Custom && !typ.Interface && !isNativeCollection {
			if err := printUnpacker(ctx, env, g, typ); err != nil {
				return nil, kerr.Wrap("YJNWUAUKXI", err)
			}
			if err := printRepacker(ctx, env, g, typ); err != nil {
				return nil, kerr.Wrap("NCFFXUHYNY", err)
			}
		}

	}
	printInitFunction(ctx, env, g, types)

	for _, name := range exports.Keys() {
		export, ok := exports.Get(name)
		if !ok {
			// ke: {"block": {"notest": true}}
			continue
		}
		if err := printExportFunction(ctx, env, g, export); err != nil {
			return nil, kerr.Wrap("YJHRXIASNO", err)
		}
	}

	b, err := g.Build()
	if err != nil {
		return nil, kerr.Wrap("XKYHSDKBEP", err)
	}
	return b, nil
}