Beispiel #1
0
func (g *Go) complete_pkg(pkg string, cmp *content.CompletionResult) error {
	if g.imports == nil {
		g.imports = make(map[string]*types.Package)
	}

	if p, err := types.GcImport(g.imports, pkg); err != nil {
		return err
	} else {
		nn := p.Scope()
		for i := 0; i < nn.NumEntries(); i++ {
			t := nn.At(i)

			var flags content.Flags

			if n := t.Name(); n[0] != strings.ToUpper(n)[0] {
				flags = content.FLAG_ACC_PROTECTED
			} else {
				flags = content.FLAG_ACC_PUBLIC
			}
			switch t.(type) {
			case *types.Func:
				var m content.Method
				m.Flags |= flags
				m.Name.Relative = t.Name()
				sig := t.Type().Underlying().(*types.Signature)
				if sig.Recv() != nil {
					continue
				}
				par := sig.Params()
				for j := 0; j < par.Len(); j++ {
					m.Parameters = append(m.Parameters, g.pkg_var(par.At(j)))
				}
				ret := sig.Results()
				for j := 0; j < ret.Len(); j++ {
					m.Returns = append(m.Returns, g.pkg_var(ret.At(j)))
				}
				cmp.Methods = append(cmp.Methods, m)
			case *types.TypeName:
				var t2 content.Type
				t2.Flags |= flags
				t2.Name.Relative = t.Name()
				switch t.Type().Underlying().(type) {
				case *types.Interface:
					t2.Flags |= content.FLAG_TYPE_INTERFACE
				case *types.Struct:
					t2.Flags |= content.FLAG_TYPE_STRUCT
				}
				cmp.Types = append(cmp.Types, t2)
			case *types.Const, *types.Var:
				var f content.Field
				f.Name.Relative = t.Name()
				f.Type = g.pkg_type(t.Type())
				cmp.Fields = append(cmp.Fields, f)
			default:
				log4go.Warn("Unimplemented type in package completion: at: %+v, %v, %v", t, reflect.TypeOf(t), reflect.TypeOf(t.Type().Underlying()))
			}
		}
	}
	return nil
}
Beispiel #2
0
func (c *Cache) loaderthread() {
	for req := range c.load {
		loaded := false
		func() {
			c.mutex.Lock()
			defer c.mutex.Unlock()
			for i := range c.entries {
				if c.entries[i].name != req.name {
					continue
				}
				loaded = true
				if req.reload {
					if err := c.reload(&c.entries[i]); err != nil {
						log4go.Warn("Error reloading assembly \"%s\": %s", c.entries[i].name, err)
					}
				}
				break
			}
		}()
		if loaded {
			continue
		}
		exts := []string{".dll", ".exe"}
		_, err := c.Load(req.name)
		if err == nil {
			continue
		}
		for _, ext := range exts {
			if _, err := c.Load(req.name + ext); err == nil {
				break
			}
		}
	}
}
Beispiel #3
0
func eval(node *parser.Node) string {
	switch node.Name {
	case "Env":
		name := eval(node.Children[0])
		if ret := os.Getenv(name); ret == "" {
			return name + "_NOT_SET"
		} else {
			return ret
		}
	case "Folder":
		return filepath.Dir(eval(node.Children[0]))
	case "String", "NonOperation", "RecNonOp":
		return node.Data()
	case "Home":
		if u, err := user.Current(); err != nil {
			log4go.Warn("Couldn't lookup current user: %s", err)
		} else {
			return u.HomeDir
		}
	case "EXPAND_PATH", "RecOp":
		buf := bytes.NewBuffer(nil)
		for _, c := range node.Children {
			buf.WriteString(eval(c))
		}
		return buf.String()
	}
	return ""
}
Beispiel #4
0
func (c *Cache) watchthread() {
	for {
		select {
		case ev := <-c.watch.Events:
			if ev.Op == fsnotify.Remove {
				// File no longer exists so we wont get events for it anymore
				// with the old add. Thus need to re-add it like this so that
				// we get events for the new file once it is created.
				if err := c.watch.Add(ev.Name); err != nil {
					log4go.Warn("Failed to re-watch for removed file %s: %s", ev.Name, err)
				}
			}

			c.load <- loadreq{ev.Name, true}
		case err := <-c.watch.Errors:
			log4go.Error("error:", err)
		}
	}
}
func (t *TranslationUnitCache) GetTranslationUnit(filename string, options []string, options_script string, unsaved_files map[string]string) *LockedTranslationUnit {
	t.Lock()
	tu, ok := t.lut[filename]
	if !ok {
		t.Unlock()

		// TODO(q): SublimeClang executed opts_script here
		args := make([]string, len(options))
		for i := range options {
			args[i] = expand_path.ExpandPath(options[i])
		}

		log4go.Debug("Will compile file %s with the following options:\n%v", filename, options)
		if tu2 := t.index.Parse(filename, options, unsaved_files, index_parse_options); true || tu2.IsValid() {
			tu = &LockedTranslationUnit{}
			tu.TranslationUnit = tu2
			tu.opts = options
			tu.opts_script = options_script
			t.Lock()
			defer t.Unlock()
			t.lut[filename] = tu
		} else {
			log4go.Warn("Failed to compile %s, %v", filename, tu2)
		}
		return tu
	}
	recompile := !reflect.DeepEqual(tu.opts, options) || tu.opts_script != options_script
	if recompile {
		// TODO: need to dispose the tu.. Who's responsible for its disposal?
		delete(t.lut, filename)
	}
	t.Unlock()
	if recompile {
		log4go.Debug("Options change detected. Will recompile %s", filename)
		t.addEx(workunit{filename, options, options_script, nil})
	}
	return tu
}
Beispiel #6
0
func (t *Clang) CompleteAt(args *content.CompleteAtArgs, res *content.CompletionResult) error {
	origargs, _ := args.Settings().Get("compiler_flags").([]string)
	var unsaved map[string]string
	if args.Location.File.Contents != "" {
		unsaved = map[string]string{args.Location.File.Name: args.Location.File.Contents}
	}

	if tu := t.GetTranslationUnit(args.Location.File.Name, origargs, "", unsaved); tu == nil {
		return nil
	}
	cres := tu.CompleteAt(args.Location.File.Name, int(args.Location.Line), int(args.Location.Column), unsaved, 0)
	if !cres.IsValid() {
		return fmt.Errorf("CompleteResults is not valid")
	}
	defer cres.Dispose()
	for _, r := range cres.Results() {
		var (
			buf bytes.Buffer
		)
		switch r.CursorKind {
		case clang.CK_StructDecl, clang.CK_TypedefDecl:
			for _, c := range r.CompletionString.Chunks() {
				buf.WriteString(c.Text())
			}
			var tt content.Type
			tt.Flags = content.FLAG_TYPE_CLASS
			tt.Name.Absolute = buf.String()
			res.Types = append(res.Types, tt)
		case clang.CK_FunctionDecl:
			var (
				m            content.Method
				paramstarted bool
				argCount     int
			)
			for _, c := range r.CompletionString.Chunks() {
				switch k := c.Kind(); k {
				case clang.CompletionChunk_ResultType:
					var v content.Variable
					v.Name.Relative = c.Text()
					m.Returns = append(m.Returns, v)
				case clang.CompletionChunk_Placeholder:
					var v content.Variable
					v.Type.Name.Relative = c.Text()
					v.Name.Relative = fmt.Sprintf("arg%d", argCount)
					argCount++
					m.Parameters = append(m.Parameters, v)
				case clang.CompletionChunk_LeftParen:
					paramstarted = true
				case clang.CompletionChunk_RightParen, clang.CompletionChunk_Comma:
				case clang.CompletionChunk_TypedText:
					if !paramstarted {
						buf.WriteString(c.Text())
					}
				default:
					log4go.Warn("Unimplemented CompletionChunkKind: %s", k)
				}
			}
			m.Name.Relative = buf.String()
			res.Methods = append(res.Methods, m)
		default:
			log4go.Warn("Unimplemented CursorKind: %s", r.CursorKind)
		}
	}
	return nil
}