Beispiel #1
0
func findPackageSym(
	b *builder, sub *lex8.Token, pkg *types.Pkg,
) *sym8.Symbol {
	sym := pkg.Syms.Query(sub.Lit)
	if sym == nil {
		b.Errorf(sub.Pos, "%s has no symbol named %s",
			pkg, sub.Lit,
		)
		return nil
	}
	name := sym.Name()
	if !sym8.IsPublic(name) && sym.Pkg() != b.path {
		b.Errorf(sub.Pos, "symbol %s is not public", name)
		return nil
	}

	return sym
}
Beispiel #2
0
func linkSymbol(b *builder, s *funcStmt, f *link8.Func) {
	t := s.symTok
	if b.curPkg == nil {
		b.Errorf(t.Pos, "no context for resolving %q", t.Lit)
		return // this may happen for bare function
	}

	typ, pkg, name := resolveSymbol(b, s)
	if typ == SymNone {
		return
	}

	if s.fill == fillLink && typ != SymFunc {
		b.Errorf(t.Pos, "%s %q is not a function", SymStr(typ), t.Lit)
		return
	} else if pkg != b.curPkg.Path() && !sym8.IsPublic(s.sym) {
		// for imported package, check if it is public
		b.Errorf(t.Pos, "%q is not public", t.Lit)
		return
	}

	// save the link
	f.AddLink(s.fill, &link8.PkgSym{pkg, name})
}
Beispiel #3
0
func buildMember(b *builder, m *ast.MemberExpr) tast.Expr {
	obj := b.buildExpr(m.Expr)
	if obj == nil {
		return nil
	}

	ref := obj.R()
	if !ref.IsSingle() {
		b.Errorf(m.Dot.Pos, "%s does not have any member", ref)
		return nil
	}

	t := ref.T
	if pkg, ok := t.(*types.Pkg); ok {
		r, sym := buildPkgSym(b, m, pkg)
		if r == nil {
			return nil
		}
		// TODO: this can be further optimized
		return &tast.MemberExpr{obj, m.Sub, r, sym}
	}

	pt := types.PointerOf(t)
	var tstruct *types.Struct
	var ok bool
	if pt != nil {
		if tstruct, ok = pt.(*types.Struct); !ok {
			b.Errorf(m.Dot.Pos, "*%s is not a pointer of struct", t)
			return nil
		}
	} else {
		if tstruct, ok = t.(*types.Struct); !ok {
			b.Errorf(m.Dot.Pos, "%s is not a struct", t)
			return nil
		}
	}

	symTable := tstruct.Syms
	name := m.Sub.Lit
	sym := symTable.Query(name)
	if sym == nil {
		b.Errorf(m.Sub.Pos, "struct %s has no member named %s",
			tstruct, name,
		)
		return nil
	} else if !sym8.IsPublic(name) && sym.Pkg() != b.path {
		b.Errorf(m.Sub.Pos, "symbol %s is not public", name)
		return nil
	}

	b.refSym(sym, m.Sub.Pos)

	if sym.Type == tast.SymField {
		t := sym.ObjType.(types.T)
		r := tast.NewAddressableRef(t)
		return &tast.MemberExpr{obj, m.Sub, r, sym}
	} else if sym.Type == tast.SymFunc {
		ft := sym.ObjType.(*types.Func)
		r := tast.NewRef(ft.MethodFunc)
		r.Recv = ref
		return &tast.MemberExpr{obj, m.Sub, r, sym}
	}

	b.Errorf(m.Sub.Pos, "invalid sym type: %s", tast.SymStr(sym.Type))
	return nil
}
Beispiel #4
0
func buildType(b *builder, expr ast.Expr) types.T {
	if expr == nil {
		panic("bug")
	}

	switch expr := expr.(type) {
	case *ast.Operand:
		ret := buildOperand(b, expr)
		if ret == nil {
			return nil
		}
		ref := ret.R()
		t, ok := ref.T.(*types.Type)
		if !ok {
			b.Errorf(ast.ExprPos(expr), "expect a type, got %s", ref.T)
			return nil
		}
		return t.T
	case *ast.StarExpr:
		t := buildType(b, expr.Expr)
		if t == nil {
			return nil
		}
		return &types.Pointer{t}
	case *ast.ArrayTypeExpr:
		return buildArrayType(b, expr)
	case *ast.ParenExpr:
		return buildType(b, expr.Expr)
	case *ast.FuncTypeExpr:
		return buildFuncType(b, nil, expr.FuncSig)
	case *ast.MemberExpr:
		op, ok := expr.Expr.(*ast.Operand)
		if !ok {
			b.Errorf(ast.ExprPos(expr.Expr), "expect a package")
			return nil
		}
		pkg := buildPkgRef(b, op.Token)
		if pkg == nil {
			return nil
		}
		name := expr.Sub.Lit
		s := pkg.Syms.Query(name)
		if s == nil {
			b.Errorf(expr.Sub.Pos, "symbol %s not found", name)
			return nil
		}
		if !sym8.IsPublic(name) && s.Pkg() != b.path {
			b.Errorf(expr.Sub.Pos, "symbol %s is not public", name)
			return nil
		}

		if s.Type != tast.SymStruct {
			b.Errorf(expr.Sub.Pos, "symbol %s is a %s, not a struct",
				name, tast.SymStr(s.Type),
			)
			return nil
		}

		return s.ObjType.(*types.Type).T
	}

	b.Errorf(ast.ExprPos(expr), "expect a type")
	return nil
}