blob: 40a5dc28de54826c7c5455274c4922a1bd684bc9 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package java
import (
"bytes"
"fmt"
"sort"
"v.io/x/ref/lib/vdl/compile"
)
func isStreamingMethod(method *compile.Method) bool {
return method.InStream != nil || method.OutStream != nil
}
// methodAndOrigin is simply a pair of a method and its origin (the interface from which it came from)
// The usefulness of this pair of data is that methods can be defined on multiple interfaces and embeds can clash for the same method.
// Therefore, we need to keep track of the originating interface.
type methodAndOrigin struct {
Method *compile.Method
Origin *compile.Interface
}
// allMethodsAndOrigins constructs a list of all methods in an interface (including embeded interfaces) along with their corresponding origin interface.
func allMethodsAndOrigin(iface *compile.Interface) []methodAndOrigin {
result := make([]methodAndOrigin, len(iface.Methods))
for i, method := range iface.Methods {
result[i] = methodAndOrigin{
Method: method,
Origin: iface,
}
}
for _, embed := range iface.Embeds {
result = append(result, allMethodsAndOrigin(embed)...)
}
return result
}
// dedupedEmbeddedMethodAndOrigins returns the set of methods only defined in embedded interfaces and dedupes methods with the same name.
// This is used to generate a set of methods for a given service that are not (re)defined in the interface body (and instead only in embeddings).
func dedupedEmbeddedMethodAndOrigins(iface *compile.Interface) []methodAndOrigin {
ifaceMethods := map[string]bool{}
for _, method := range iface.Methods {
ifaceMethods[method.Name] = true
}
embeddedMao := map[string]methodAndOrigin{}
for _, mao := range allMethodsAndOrigin(iface) {
if _, found := ifaceMethods[mao.Method.Name]; found {
continue
}
if _, found := embeddedMao[mao.Method.Name]; found {
continue
}
embeddedMao[mao.Method.Name] = mao
}
ret := []methodAndOrigin{}
for _, mao := range embeddedMao {
ret = append(ret, mao)
}
sort.Sort(bySignature(ret))
return ret
}
// bySignature implements sort.Interface
type bySignature []methodAndOrigin
func (b bySignature) Len() int {
return len(b)
}
func (b bySignature) Less(i, j int) bool {
return b.signature(i) < b.signature(j)
}
func (b bySignature) signature(i int) string {
var buf bytes.Buffer
buf.WriteString(fmt.Sprintf("%s|%s|%s",
b[i].Origin.File.Package.GenPath,
b[i].Origin.Name,
b[i].Method.Name,
))
for _, arg := range b[i].Method.InArgs {
buf.WriteString(fmt.Sprintf("|%s", arg.Type.Name()))
}
return buf.String()
}
func (b bySignature) Swap(i, j int) {
b[i], b[j] = b[j], b[i]
}