func argsFromType(t *types.Type) generator.Args {
	return generator.Args{
		"type":               t,
		"OpenAPIDefinitions": types.Ref(openAPICommonPackagePath, "OpenAPIDefinitions"),
		"OpenAPIDefinition":  types.Ref(openAPICommonPackagePath, "OpenAPIDefinition"),
		"SpecSchemaType":     types.Ref(specPackagePath, "Schema"),
	}
}
Exemple #2
0
// Returns all manually-defined conversion functions in the package.
func getManualConversionFunctions(context *generator.Context, pkg *types.Package, manualMap conversionFuncMap) {
	scopeName := types.Ref(conversionPackagePath, "Scope").Name
	errorName := types.Ref("", "error").Name
	buffer := &bytes.Buffer{}
	sw := generator.NewSnippetWriter(buffer, context, "$", "$")

	for _, f := range pkg.Functions {
		if f.Underlying == nil || f.Underlying.Kind != types.Func {
			glog.Errorf("Malformed function: %#v", f)
			continue
		}
		if f.Underlying.Signature == nil {
			glog.Errorf("Function without signature: %#v", f)
			continue
		}
		signature := f.Underlying.Signature
		// Check whether the function is conversion function.
		// Note that all of them have signature:
		// func Convert_inType_To_outType(inType, outType, conversion.Scope) error
		if signature.Receiver != nil {
			continue
		}
		if len(signature.Parameters) != 3 || signature.Parameters[2].Name != scopeName {
			continue
		}
		if len(signature.Results) != 1 || signature.Results[0].Name != errorName {
			continue
		}
		inType := signature.Parameters[0]
		outType := signature.Parameters[1]
		if inType.Kind != types.Pointer || outType.Kind != types.Pointer {
			continue
		}
		// Now check if the name satisfies the convention.
		// TODO: This should call the Namer directly.
		args := argsFromType(inType.Elem, outType.Elem)
		sw.Do("Convert_$.inType|public$_To_$.outType|public$", args)
		if f.Name.Name == buffer.String() {
			key := conversionPair{inType.Elem, outType.Elem}
			// We might scan the same package twice, and that's OK.
			if v, ok := manualMap[key]; ok && v != nil && v.Name.Package != pkg.Path {
				panic(fmt.Sprintf("duplicate static conversion defined: %#v", key))
			}
			manualMap[key] = f
		}
		buffer.Reset()
	}
}
Exemple #3
0
func (g *genConversion) generateConversion(inType, outType *types.Type, sw *generator.SnippetWriter) {
	args := argsFromType(inType, outType).
		With("Scope", types.Ref(conversionPackagePath, "Scope"))

	sw.Do("func auto"+nameTmpl+"(in *$.inType|raw$, out *$.outType|raw$, s $.Scope|raw$) error {\n", args)
	// if no defaulter of form SetDefaults_XXX is defined, do not inline a check for defaulting.
	if function, ok := g.manualDefaulters[inType]; ok {
		sw.Do("$.|raw$(in)\n", function)
	}
	g.generateFor(inType, outType, sw)
	sw.Do("return nil\n", nil)
	sw.Do("}\n\n", nil)

	if _, found := g.preexists(inType, outType); found {
		// There is a public manual Conversion method: use it.
	} else if skipped := g.skippedFields[inType]; len(skipped) != 0 {
		// The inType had some fields we could not generate.
		glog.Errorf("Warning: could not find nor generate a final Conversion function for %v -> %v", inType, outType)
		glog.Errorf("  the following fields need manual conversion:")
		for _, f := range skipped {
			glog.Errorf("      - %v", f)
		}
	} else {
		// Emit a public conversion function.
		sw.Do("func "+nameTmpl+"(in *$.inType|raw$, out *$.outType|raw$, s $.Scope|raw$) error {\n", args)
		sw.Do("return auto"+nameTmpl+"(in, out, s)\n", args)
		sw.Do("}\n\n", nil)
	}
}
Exemple #4
0
func (g *genDeepCopy) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	if !g.needsGeneration(t) {
		return nil
	}
	glog.V(5).Infof("generating for type %v", t)

	sw := generator.NewSnippetWriter(w, c, "$", "$")
	args := argsFromType(t).
		With("clonerType", types.Ref(conversionPackagePath, "Cloner"))
	sw.Do("func $.type|dcFnName$(in interface{}, out interface{}, c *$.clonerType|raw$) error {{\n", args)
	sw.Do("in := in.(*$.type|raw$)\nout := out.(*$.type|raw$)\n", argsFromType(t))
	g.generateFor(t, sw)
	sw.Do("return nil\n", nil)
	sw.Do("}}\n\n", nil)
	return sw.Error()
}