示例#1
0
func (s *Styler) Ident(id *ast.Ident) (text []byte, tag printer.HTMLTag) {
	text = strings.Bytes(id.Name())
	if s.highlight == id.Name() {
		tag = printer.HTMLTag{"<span class=highlight>", "</span>"}
	}
	return
}
示例#2
0
func (a *typeCompiler) compileIdent(x *ast.Ident, allowRec bool) Type {
	_, _, def := a.block.Lookup(x.Name())
	if def == nil {
		a.diagAt(x, "%s: undefined", x.Name())
		return nil
	}
	switch def := def.(type) {
	case *Constant:
		a.diagAt(x, "constant %v used as type", x.Name())
		return nil
	case *Variable:
		a.diagAt(x, "variable %v used as type", x.Name())
		return nil
	case *NamedType:
		if !allowRec && def.incomplete {
			a.diagAt(x, "illegal recursive type")
			return nil
		}
		if !def.incomplete && def.Def == nil {
			// Placeholder type from an earlier error
			return nil
		}
		return def
	case Type:
		return def
	}
	log.Crashf("name %s has unknown type %T", x.Name(), def)
	return nil
}
示例#3
0
func (s *snippetStyler) Ident(id *ast.Ident) (text []byte, tag printer.HTMLTag) {
	text = []byte(id.Name())
	if s.highlight == id {
		tag = printer.HTMLTag{"<span class=highlight>", "</span>"}
	}
	return
}
示例#4
0
func (a *stmtCompiler) findLexicalLabel(name *ast.Ident, pred func(*label) bool, errOp, errCtx string) *label {
	bc := a.blockCompiler
	for ; bc != nil; bc = bc.parent {
		if bc.label == nil {
			continue
		}
		l := bc.label
		if name == nil && pred(l) {
			return l
		}
		if name != nil && l.name == name.Name() {
			if !pred(l) {
				a.diag("cannot %s to %s %s", errOp, l.desc, l.name)
				return nil
			}
			return l
		}
	}
	if name == nil {
		a.diag("%s outside %s", errOp, errCtx)
	} else {
		a.diag("%s label %s not defined", errOp, name.Name())
	}
	return nil
}
示例#5
0
func (p *parser) declIdent(scope *ast.Scope, id *ast.Ident) {
	decl := scope.Declare(id.Obj)
	if p.checkDecl && decl != id.Obj {
		if decl.Kind == ast.Err {
			// declared object is a forward declaration - update it
			*decl = *id.Obj
			id.Obj = decl
			return
		}
		p.Error(id.Pos(), "'"+id.Name()+"' declared already at "+decl.Pos.String())
	}
}
示例#6
0
// NewSnippet creates a text snippet from a declaration decl containing an
// identifier id. Parts of the declaration not containing the identifier
// may be removed for a more compact snippet.
//
func NewSnippet(decl ast.Decl, id *ast.Ident) (s *Snippet) {
	switch d := decl.(type) {
	case *ast.GenDecl:
		s = genSnippet(d, id)
	case *ast.FuncDecl:
		s = funcSnippet(d, id)
	}

	// handle failure gracefully
	if s == nil {
		s = &Snippet{
			id.Pos().Line,
			fmt.Sprintf(`could not generate a snippet for <span class="highlight">%s</span>`, id.Name()),
		}
	}
	return
}
示例#7
0
文件: decl.go 项目: kij/gocode
func checkForBuiltinFuncs(typ *ast.Ident, c *ast.CallExpr) ast.Expr {
	if strings.HasPrefix(typ.Name(), "func(") {
		if t, ok := c.Fun.(*ast.Ident); ok {
			switch t.Name() {
			case "new":
				e := new(ast.StarExpr)
				e.X = c.Args[0]
				return e
			case "make":
				return c.Args[0]
			case "cmplx":
				return ast.NewIdent("complex")
			case "closed":
				return ast.NewIdent("bool")
			}
		}
	}
	return nil
}
示例#8
0
func (a *stmtCompiler) defineVar(ident *ast.Ident, t Type) *Variable {
	v, prev := a.block.DefineVar(ident.Name(), ident.Pos(), t)
	if prev != nil {
		// TODO(austin) It's silly that we have to capture
		// Pos() in a variable.
		pos := prev.Pos()
		if pos.IsValid() {
			a.diagAt(ident, "variable %s redeclared in this block\n\tprevious declaration at %s", ident.Name(), &pos)
		} else {
			a.diagAt(ident, "variable %s redeclared in this block", ident.Name())
		}
		return nil
	}

	// Initialize the variable
	index := v.Index
	if v.Index >= 0 {
		a.push(func(v *Thread) { v.f.Vars[index] = t.Zero() })
	}
	return v
}
示例#9
0
文件: makers.go 项目: 8l/gsp
func makeFunDeclFromFuncLit(name *ast.Ident, f *ast.FuncLit) *ast.FuncDecl {
	if name.Name != "main" {
		numArgs := strconv.Itoa(len(f.Type.Params.List[0].Names))
		name.Name = name.Name + numArgs
	}

	return &ast.FuncDecl{
		Name: name,
		Type: f.Type,
		Body: f.Body,
	}
}
示例#10
0
func (x *Indexer) visitIdent(kind SpotKind, id *ast.Ident) {
	if id != nil {
		lists, found := x.words[id.Name()]
		if !found {
			lists = new(IndexResult)
			x.words[id.Name()] = lists
		}

		if kind == Use || x.decl == nil {
			// not a declaration or no snippet required
			info := makeSpotInfo(kind, id.Pos().Line, false)
			lists.Others.Push(Spot{x.file, info})
		} else {
			// a declaration with snippet
			index := x.addSnippet(NewSnippet(x.decl, id))
			info := makeSpotInfo(kind, index, true)
			lists.Decls.Push(Spot{x.file, info})
		}

		x.nspots++
	}
}
示例#11
0
func (a *stmtCompiler) doAssign(lhs []ast.Expr, rhs []ast.Expr, tok token.Token, declTypeExpr ast.Expr) {
	nerr := a.numError()

	// Compile right side first so we have the types when
	// compiling the left side and so we don't see definitions
	// made on the left side.
	rs := make([]*expr, len(rhs))
	for i, re := range rhs {
		rs[i] = a.compileExpr(a.block, false, re)
	}

	errOp := "assignment"
	if tok == token.DEFINE || tok == token.VAR {
		errOp = "declaration"
	}
	ac, ok := a.checkAssign(a.pos, rs, errOp, "value")
	ac.allowMapForms(len(lhs))

	// If this is a definition and the LHS is too big, we won't be
	// able to produce the usual error message because we can't
	// begin to infer the types of the LHS.
	if (tok == token.DEFINE || tok == token.VAR) && len(lhs) > len(ac.rmt.Elems) {
		a.diag("not enough values for definition")
	}

	// Compile left type if there is one
	var declType Type
	if declTypeExpr != nil {
		declType = a.compileType(a.block, declTypeExpr)
	}

	// Compile left side
	ls := make([]*expr, len(lhs))
	nDefs := 0
	for i, le := range lhs {
		// If this is a definition, get the identifier and its type
		var ident *ast.Ident
		var lt Type
		switch tok {
		case token.DEFINE:
			// Check that it's an identifier
			ident, ok = le.(*ast.Ident)
			if !ok {
				a.diagAt(le, "left side of := must be a name")
				// Suppress new defitions errors
				nDefs++
				continue
			}

			// Is this simply an assignment?
			if _, ok := a.block.defs[ident.Name()]; ok {
				ident = nil
				break
			}
			nDefs++

		case token.VAR:
			ident = le.(*ast.Ident)
		}

		// If it's a definition, get or infer its type.
		if ident != nil {
			// Compute the identifier's type from the RHS
			// type.  We use the computed MultiType so we
			// don't have to worry about unpacking.
			switch {
			case declTypeExpr != nil:
				// We have a declaration type, use it.
				// If declType is nil, we gave an
				// error when we compiled it.
				lt = declType

			case i >= len(ac.rmt.Elems):
				// Define a placeholder.  We already
				// gave the "not enough" error above.
				lt = nil

			case ac.rmt.Elems[i] == nil:
				// We gave the error when we compiled
				// the RHS.
				lt = nil

			case ac.rmt.Elems[i].isIdeal():
				// If the type is absent and the
				// corresponding expression is a
				// constant expression of ideal
				// integer or ideal float type, the
				// type of the declared variable is
				// int or float respectively.
				switch {
				case ac.rmt.Elems[i].isInteger():
					lt = IntType
				case ac.rmt.Elems[i].isFloat():
					lt = FloatType
				default:
					log.Crashf("unexpected ideal type %v", rs[i].t)
				}

			default:
				lt = ac.rmt.Elems[i]
			}
		}

		// If it's a definition, define the identifier
		if ident != nil {
			if a.defineVar(ident, lt) == nil {
				continue
			}
		}

		// Compile LHS
		ls[i] = a.compileExpr(a.block, false, le)
		if ls[i] == nil {
			continue
		}

		if ls[i].evalMapValue != nil {
			// Map indexes are not generally addressable,
			// but they are assignable.
			//
			// TODO(austin) Now that the expression
			// compiler uses semantic values, this might
			// be easier to implement as a function call.
			sub := ls[i]
			ls[i] = ls[i].newExpr(sub.t, sub.desc)
			ls[i].evalMapValue = sub.evalMapValue
			mvf := sub.evalMapValue
			et := sub.t
			ls[i].evalAddr = func(t *Thread) Value {
				m, k := mvf(t)
				e := m.Elem(t, k)
				if e == nil {
					e = et.Zero()
					m.SetElem(t, k, e)
				}
				return e
			}
		} else if ls[i].evalAddr == nil {
			ls[i].diag("cannot assign to %s", ls[i].desc)
			continue
		}
	}

	// A short variable declaration may redeclare variables
	// provided they were originally declared in the same block
	// with the same type, and at least one of the variables is
	// new.
	if tok == token.DEFINE && nDefs == 0 {
		a.diag("at least one new variable must be declared")
		return
	}

	// If there have been errors, our arrays are full of nil's so
	// get out of here now.
	if nerr != a.numError() {
		return
	}

	// Check for 'a[x] = r, ok'
	if len(ls) == 1 && len(rs) == 2 && ls[0].evalMapValue != nil {
		a.diag("a[x] = r, ok form not implemented")
		return
	}

	// Create assigner
	var lt Type
	n := len(lhs)
	if n == 1 {
		lt = ls[0].t
	} else {
		lts := make([]Type, len(ls))
		for i, l := range ls {
			if l != nil {
				lts[i] = l.t
			}
		}
		lt = NewMultiType(lts)
	}
	bc := a.enterChild()
	defer bc.exit()
	assign := ac.compile(bc.block, lt)
	if assign == nil {
		return
	}

	// Compile
	if n == 1 {
		// Don't need temporaries and can avoid []Value.
		lf := ls[0].evalAddr
		a.push(func(t *Thread) { assign(lf(t), t) })
	} else if tok == token.VAR || (tok == token.DEFINE && nDefs == n) {
		// Don't need temporaries
		lfs := make([]func(*Thread) Value, n)
		for i, l := range ls {
			lfs[i] = l.evalAddr
		}
		a.push(func(t *Thread) {
			dest := make([]Value, n)
			for i, lf := range lfs {
				dest[i] = lf(t)
			}
			assign(multiV(dest), t)
		})
	} else {
		// Need temporaries
		lmt := lt.(*MultiType)
		lfs := make([]func(*Thread) Value, n)
		for i, l := range ls {
			lfs[i] = l.evalAddr
		}
		a.push(func(t *Thread) {
			temp := lmt.Zero().(multiV)
			assign(temp, t)
			// Copy to destination
			for i := 0; i < n; i++ {
				// TODO(austin) Need to evaluate LHS
				// before RHS
				lfs[i](t).Assign(t, temp[i])
			}
		})
	}
}
示例#12
0
func OmitFunctionCalls(node ast.Node, f *ast.File, writeMutation func()) {
	if ce, ok := node.(*ast.CallExpr); ok {
		var ident *ast.Ident

		if se, ok := ce.Fun.(*ast.SelectorExpr); ok {
			ident = se.Sel
		} else if ident, ok = ce.Fun.(*ast.Ident); ok {
		}

		if ident != nil && ident.Obj != nil {
			if ident.Obj.Decl != nil {
				if fun_decl, ok := ident.Obj.Decl.(*ast.FuncDecl); ok {
					original_func_name := ident.Name

					fmt.Println(ident.Name)

					fake_func_name := original_func_name + "FakeMugoFunction"
					ident.Name = fake_func_name

					fake_func_ident := ast.NewIdent(fake_func_name)

					var numReturnValues uint
					var returnTypes []ast.Expr

					if fun_decl.Type.Results.NumFields() > 0 {
						for _, field := range fun_decl.Type.Results.List {
							if len(field.Names) == 0 {
								numReturnValues++
								returnTypes = append(returnTypes, field.Type)
							} else {
								for _, _ = range field.Names {
									numReturnValues++
									returnTypes = append(returnTypes, field.Type)
								}
							}
						}
					}

					// Anropa originalmetoden i fakemetoden och returnera alla utom ett som ersätts med default value (?)
					var stmt_list []ast.Stmt
					var returnVariables []string

					for i, rt := range returnTypes {
						var returnVariable string

						returnVariable = fmt.Sprintf("rv%d", i+1)
						ident := ast.NewIdent(returnVariable)

						if se, ok := rt.(*ast.StarExpr); ok {
							// Make it a non-star expression
							rt = se.X
							// Return the address of the variable
							returnVariable = fmt.Sprintf("&rv%d", i+1)
						}

						returnVariables = append(returnVariables, returnVariable)

						vs := ast.ValueSpec{Names: []*ast.Ident{ident}, Type: rt}
						gd := ast.GenDecl{Tok: token.VAR, Specs: []ast.Spec{&vs}}

						ds := ast.DeclStmt{Decl: &gd}

						stmt_list = append(stmt_list, &ds)
					}

					var returnExpressions []ast.Expr

					for _, rv := range returnVariables {
						expr, _ := parser.ParseExpr(rv)
						returnExpressions = append(returnExpressions, expr)
					}

					rs := ast.ReturnStmt{Results: returnExpressions}

					stmt_list = append(stmt_list, &rs)

					//stmt_list = append(stmt_list, &params_to_blank_asgn_stmt)
					// Body is a list of statements
					body := ast.BlockStmt{List: stmt_list}

					fake_func_decl := ast.FuncDecl{Name: fake_func_ident, Type: fun_decl.Type, Body: &body, Recv: fun_decl.Recv}

					f.Decls = append(f.Decls, &fake_func_decl)

					defer func() {
						// Return function name of call expression
						ident.Name = original_func_name
						// Remove the inserted function
						d := len(f.Decls) - 1
						f.Decls = append(f.Decls[:d], f.Decls[d+1:]...)
					}()

					writeMutation()
				}
			}
		}
	}
}