summaryrefslogtreecommitdiff
path: root/experiments/windowsconstgen.go
blob: bfbeac466793456d982185919e9411545dc7007a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// 24 may 2014
package main

import (
	"fmt"
	"os"
	"strings"
	"go/token"
	"go/ast"
	"go/parser"
)

func main() {
	var pkg *ast.Package

	importpath := os.Args[1]

	fileset := token.NewFileSet()

	filter := func(i os.FileInfo) bool {
		return strings.HasSuffix(i.Name(), "_windows.go")
	}
	pkgs, err := parser.ParseDir(fileset, importpath,
		filter, parser.AllErrors)
	if err != nil {
		panic(err)
	}
	if len(pkgs) != 1 {
		panic("more than one package found")
	}
	for k, _ := range pkgs {		// get the sole key
		pkg = pkgs[k]
	}

	var run func(...ast.Decl)
	var runstmt func(ast.Stmt)
	var runblock func(*ast.BlockStmt)

	desired := func(name string) bool {
		return strings.HasPrefix(name, "_")
	}
	run = func(decls ...ast.Decl) {
		for _, d := range decls {
			switch dd := d.(type) {
			case *ast.FuncDecl:
				runblock(dd.Body)
			case *ast.GenDecl:
				if desired(d.Name.String()) {
					fmt.Println(d.Name.String())
				}
			default:
				panic(fmt.Errorf("unknown decl type %T: %v", dd, dd))
			}
		}
	}
	runstmt = func(s ast.Stmt) {
		switch ss := s.(type) {
		case *ast.DeclStmt:
			run(ss.Decl)
		case *ast.LabeledStmt:
			runstmt(ss.Stmt)
		case *ast.AssignStmt:
			// TODO go through Lhs if ss.Tok type == DEFINE
		case *ast.GoStmt:
		// these don't have decls
		case *ast.EmptyStmt:
		case *ast.ExprStmt:
		case *ast.SendStmt:
		case *ast.IncDecStmt:
			// all do nothing
		default:
			panic(fmt.Errorf("unknown stmt type %T: %v", dd, dd))
		}
	}
	runblock = func(block *ast.BlockStmt) {
		for _, s := range block.Stmt {
			runstmt(s)
		}
	}
	for _, f := range pkg.Files {
		run(f.Decls...)
	}
}