1// Copyright 2012 Aaron Jacobs. All Rights Reserved.
2// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16package srcutil
17
18import (
19	"fmt"
20	"reflect"
21	"runtime"
22	"sort"
23)
24
25func getLine(m reflect.Method) int {
26	pc := m.Func.Pointer()
27
28	f := runtime.FuncForPC(pc)
29	if f == nil {
30		panic(fmt.Sprintf("Couldn't get runtime func for method (pc=%d): %v", pc, m))
31	}
32
33	_, line := f.FileLine(pc)
34	return line
35}
36
37type sortableMethodSet []reflect.Method
38
39func (s sortableMethodSet) Len() int {
40	return len(s)
41}
42
43func (s sortableMethodSet) Less(i, j int) bool {
44	return getLine(s[i]) < getLine(s[j])
45}
46
47func (s sortableMethodSet) Swap(i, j int) {
48	s[i], s[j] = s[j], s[i]
49}
50
51// Given a type t, return all of the methods of t sorted such that source file
52// order is preserved. Order across files is undefined. Order within lines is
53// undefined.
54func GetMethodsInSourceOrder(t reflect.Type) []reflect.Method {
55	// Build the list of methods.
56	methods := sortableMethodSet{}
57	for i := 0; i < t.NumMethod(); i++ {
58		methods = append(methods, t.Method(i))
59	}
60
61	// Sort it.
62	sort.Sort(methods)
63
64	return methods
65}
66