Example #1
0
func (f *File) methodSet(set *types.MethodSet) {
	// Build the set of things we're looking for.
	methods := make([]method, 0, set.Len())
	docs := make([]string, set.Len())
	for i := 0; i < set.Len(); i++ {
		if ast.IsExported(set.At(i).Obj().Name()) {
			m := method{
				i,
				set.At(i),
			}
			methods = append(methods, m)
		}
	}
	if len(methods) == 0 {
		return
	}
	// Collect the docs.
	for _, file := range f.allFiles {
		visitor := &methodVisitor{
			File:    file,
			methods: methods,
			docs:    docs,
		}
		ast.Walk(visitor, file.file)
		methods = visitor.methods
	}
	// Print them in order. The incoming method set is sorted by name.
	for _, doc := range docs {
		if doc != "" {
			fmt.Print(doc)
		}
	}
}
Example #2
0
// containsAllIdsOf reports whether the method identifiers of T are a
// superset of those in U.  If U belongs to an interface type, the
// result is equal to types.Assignable(T, U), but is cheaper to compute.
//
// TODO(gri): make this a method of *types.MethodSet.
//
func containsAllIdsOf(T, U *types.MethodSet) bool {
	t, tlen := 0, T.Len()
	u, ulen := 0, U.Len()
	for t < tlen && u < ulen {
		tMeth := T.At(t).Obj()
		uMeth := U.At(u).Obj()
		tId := tMeth.Id()
		uId := uMeth.Id()
		if tId > uId {
			// U has a method T lacks: fail.
			return false
		}
		if tId < uId {
			// T has a method U lacks: ignore it.
			t++
			continue
		}
		// U and T both have a method of this Id.  Check types.
		if !types.Identical(tMeth.Type(), uMeth.Type()) {
			return false // type mismatch
		}
		u++
		t++
	}
	return u == ulen
}
Example #3
0
func (l langType) uncommonBuild(i int, sizes types.Sizes, name string, t types.Type) string {
	pkgPath := ""
	tt := t
	switch tt.(type) {
	case *types.Pointer:
		el, ok := tt.(*types.Pointer).Elem().(*types.Named)
		if ok {
			tt = el
		}
	}
	switch tt.(type) {
	case *types.Named:
		obj := tt.(*types.Named).Obj()
		if obj != nil {
			pkg := obj.Pkg()
			if pkg != nil {
				pkgPath = pkg.Path()
			}
		}
	}

	var methods *types.MethodSet
	numMethods := 0
	methods = l.PogoComp().MethodSetFor(t)
	numMethods = methods.Len()
	if name != "" || numMethods > 0 {
		ret := "Go_haxegoruntime_newPPtrTToUUncommonTType.callFromRT(0,\n"
		ret += "\t\t/*name:*/ \"" + name + "\",\n"
		ret += "\t\t/*pkgPath:*/ \"" + pkgPath + "\",\n"
		ret += "\t\t/*methods:*/ "
		meths := "Go_haxegoruntime_newMMethodSSlice.callFromRT(0)"
		//_, isIF := t.Underlying().(*types.Interface)
		//if !isIF {
		for m := 0; m < numMethods; m++ {
			sel := methods.At(m)
			ssaFn := l.PogoComp().RootProgram().Method(sel)
			if l.PogoComp().FnIsCalled(ssaFn) {
				fn := "null"
				fnToCall := "null"
				var name, str, path string
				fid, haveFn := l.hc.pte.At(sel.Obj().Type()).(int)
				if haveFn {
					fn = fmt.Sprintf("type%d()", fid)
				}
				name = sel.Obj().Name()
				str = sel.String()
				funcObj, ok := sel.Obj().(*types.Func)
				if ok {
					pn := "unknown"
					if funcObj.Pkg() != nil {
						pn = sel.Obj().Pkg().Name()
						path = sel.Obj().Pkg().Path()
					}
					fnToCall = `Go_` + l.LangName(
						pn+":"+sel.Recv().String(),
						funcObj.Name())
				}

				// now write out the method information
				meths = "Go_haxegoruntime_addMMethod.callFromRT(0," + meths + ",\n"
				meths += fmt.Sprintf("\n\t\t\t/*name:*/ \"%s\", // %s\n", name, str)
				rune1, _ := utf8.DecodeRune([]byte(name))
				if unicode.IsUpper(rune1) {
					path = ""
				}

				meths += fmt.Sprintf("\t\t\t/*pkgPath:*/ \"%s\",\n", path)
				// TODO should the two lines below be different?
				meths += fmt.Sprintf("\t\t\t/*mtyp:*/ %s,\n", fn)
				meths += fmt.Sprintf("\t\t\t/*typ:*/ %s,\n", fn)
				// add links to the functions ...

				if l.hc.funcNamesUsed[fnToCall] {
					fnToCall += ".call"
				} else {
					//println("DEBUG uncommonBuild function name not found: ", fnToCall)
					fnToCall = "null /* " + fnToCall + " */ "
				}
				meths += "\t\t\t" + fnToCall + "," + fnToCall + ")"
			}
		}
		//}
		ret += meths
		return ret + "\t)"
	}
	return "null"
}