func()

in internal/importers/java/java.go [193:312]


func (j *Importer) Import(refs *importers.References) ([]*Class, error) {
	if j.clsMap == nil {
		j.clsMap = make(map[string]*Class)
	}
	clsSet := make(map[string]struct{})
	var names []string
	for _, ref := range refs.Refs {
		// The reference could be to some/pkg.Class or some/pkg/Class.Identifier. Include both.
		pkg := strings.Replace(ref.Pkg, "/", ".", -1)
		for _, cls := range []string{pkg, pkg + "." + ref.Name} {
			if _, exists := clsSet[cls]; !exists {
				clsSet[cls] = struct{}{}
				names = append(names, cls)
			}
		}
	}
	// Make sure toString() is included; it is called when wrapping Java exception types to Go
	// errors.
	refs.Names["ToString"] = struct{}{}
	funcRefs := make(map[funcRef]struct{})
	for _, ref := range refs.Refs {
		pkgName := strings.Replace(ref.Pkg, "/", ".", -1)
		funcRefs[funcRef{pkgName, ref.Name}] = struct{}{}
	}
	classes, err := j.importClasses(names, true)
	if err != nil {
		return nil, err
	}
	j.filterReferences(classes, refs, funcRefs)
	supers, err := j.importReferencedClasses(classes)
	if err != nil {
		return nil, err
	}
	j.filterReferences(supers, refs, funcRefs)
	// Embedders refer to every exported Go struct that will have its class
	// generated. Allow Go code to reverse bind to those classes by synthesizing
	// their class descriptors.
	for _, emb := range refs.Embedders {
		n := emb.Pkg + "." + emb.Name
		if j.JavaPkg != "" {
			n = j.JavaPkg + "." + n
		}
		if _, exists := j.clsMap[n]; exists {
			continue
		}
		clsSet[n] = struct{}{}
		cls := &Class{
			Name:        n,
			FindName:    n,
			JNIName:     JNIMangle(n),
			PkgName:     emb.Name,
			HasNoArgCon: true,
		}
		for _, ref := range emb.Refs {
			jpkg := strings.Replace(ref.Pkg, "/", ".", -1)
			super := jpkg + "." + ref.Name
			if _, exists := j.clsMap[super]; !exists {
				return nil, fmt.Errorf("failed to find Java class %s, embedded by %s", super, n)
			}
			cls.Supers = append(cls.Supers, super)
		}
		classes = append(classes, cls)
		j.clsMap[cls.Name] = cls
	}
	// Include implicit classes that are used in parameter or return values.
	for _, cls := range classes {
		for _, fsets := range [][]*FuncSet{cls.Funcs, cls.Methods} {
			for _, fs := range fsets {
				for _, f := range fs.Funcs {
					names := j.implicitFuncTypes(f)
					for _, name := range names {
						if _, exists := clsSet[name]; exists {
							continue
						}
						clsSet[name] = struct{}{}
						classes = append(classes, j.clsMap[name])
					}
				}
			}
		}
	}
	for _, cls := range j.clsMap {
		j.fillFuncSigs(cls.Funcs)
		j.fillFuncSigs(cls.Methods)
		for _, m := range cls.Methods {
			j.fillSuperSigs(cls, m)
		}
	}
	for _, cls := range j.clsMap {
		j.fillAllMethods(cls)
	}
	// Include classes that appear as ancestor types for overloaded signatures.
	for _, cls := range classes {
		for _, funcs := range [][]*FuncSet{cls.Funcs, cls.AllMethods} {
			for _, f := range funcs {
				for _, p := range f.Params {
					if p == nil || p.Kind != Object {
						continue
					}
					if _, exists := clsSet[p.Class]; !exists {
						clsSet[p.Class] = struct{}{}
						classes = append(classes, j.clsMap[p.Class])
					}
				}
				if t := f.Ret; t != nil && t.Kind == Object {
					if _, exists := clsSet[t.Class]; !exists {
						clsSet[t.Class] = struct{}{}
						classes = append(classes, j.clsMap[t.Class])
					}
				}
			}
		}
	}
	for _, cls := range classes {
		j.fillJNINames(cls.Funcs)
		j.fillJNINames(cls.AllMethods)
	}
	j.fillThrowables(classes)
	return classes, nil
}