Browse Source

Create some function to reorganize the code

content-update
Augusto 4 years ago committed by xpetit
parent
commit
35b5cca101
  1. 234
      rc/rc.go

234
rc/rc.go

@ -80,6 +80,57 @@ func (i *illegal) String() string {
return i.T + " " + i.Name + " " + i.Pos return i.T + " " + i.Name + " " + i.Pos
} }
func init() {
flag.Var(&noTheseArrays, "no-these-arrays", "Disallowes the array types passed in the flag as a list separeted by comma with out spaces\nLike so: -no-these-arrays=int,string,bool")
flag.Var(&noLit, "no-lit",
`The use of basic literals (strings or characters) matching the pattern -no-lit="{PATTERN}"
passed to the program would not be allowed`,
)
flag.BoolVar(&noRelativeImports, "no-relative-imports", false, `Disallowes the use of relative imports`)
flag.BoolVar(&noFor, "no-for", false, `The "for" instruction is not allowed`)
flag.BoolVar(&casting, "cast", false, "Allowes casting")
flag.BoolVar(&noArrays, "no-arrays", false, "Disallowes all array types")
flag.BoolVar(&allowBuiltin, "allow-builtin", false, "Allowes all builtin functions and casting")
}
func main() {
flag.Parse()
if flag.NArg() < 1 {
fmt.Println("Not enough arguments: missing file")
os.Exit(1)
}
fmt.Println("Parsing:")
err := parseArgs(flag.Args()[1:], allowBuiltin, casting)
if err != nil {
panic(err)
}
filename := flag.Arg(0)
load := make(loadedSource)
currentPath := filepath.Dir(flag.Arg(0))
err = loadProgram(currentPath, load)
if err != nil {
panic(err)
}
fmt.Println("\tOk")
fmt.Println("Cheating:")
info := analyseProgram(filename, currentPath, load)
if info.illegals != nil {
printIllegals(info.illegals)
os.Exit(1)
}
fmt.Println("\tOk")
}
// Returns the smallest block containing the position pos. It can // Returns the smallest block containing the position pos. It can
// return nil if `pos` is not inside any ast.BlockStmt // return nil if `pos` is not inside any ast.BlockStmt
func smallestBlock(pos token.Pos, blocks []*ast.BlockStmt) *ast.BlockStmt { func smallestBlock(pos token.Pos, blocks []*ast.BlockStmt) *ast.BlockStmt {
@ -227,6 +278,7 @@ func loadProgram(path string, load loadedSource) error {
fillScope(defs, scope, l.scopes) fillScope(defs, scope, l.scopes)
} }
load[path] = l load[path] = l
l.files = pkg.Files
} }
for _, v := range l.relImports { for _, v := range l.relImports {
@ -251,7 +303,7 @@ func smallestScopeContaining(pos token.Pos, path string, load loadedSource) *ast
return pack.scopes[sm] return pack.scopes[sm]
} }
func lookupDefinitionObj(el element, path string, load loadedSource) *ast.Object { func lookupDefinitionObj(el *element, path string, load loadedSource) *ast.Object {
scope := smallestScopeContaining(el.pos, path, load) scope := smallestScopeContaining(el.pos, path, load)
for scope != nil { for scope != nil {
obj := scope.Lookup(el.name) obj := scope.Lookup(el.name)
@ -265,7 +317,7 @@ func lookupDefinitionObj(el element, path string, load loadedSource) *ast.Object
type visitor struct { type visitor struct {
fset *token.FileSet fset *token.FileSet
uses []element uses []*element
selections map[string][]*element selections map[string][]*element
arrays []*occurrence arrays []*occurrence
lits []*occurrence lits []*occurrence
@ -312,7 +364,7 @@ func (v *visitor) Visit(n ast.Node) ast.Visitor {
}) })
case *ast.CallExpr: case *ast.CallExpr:
if fun, ok := t.Fun.(*ast.Ident); ok { if fun, ok := t.Fun.(*ast.Ident); ok {
v.uses = append(v.uses, element{ v.uses = append(v.uses, &element{
name: fun.Name, name: fun.Name,
pos: fun.Pos(), pos: fun.Pos(),
}) })
@ -333,7 +385,7 @@ func (v *visitor) Visit(n ast.Node) ast.Visitor {
// Returns the info structure with all the ocurrences of the element // Returns the info structure with all the ocurrences of the element
// of the analised in the project // of the analised in the project
func isAllowed(function element, path string, load loadedSource, walked map[ast.Node]bool, info *info) bool { func isAllowed(function *element, path string, load loadedSource, walked map[ast.Node]bool, info *info) bool {
if walked == nil { if walked == nil {
walked = make(map[ast.Node]bool) walked = make(map[ast.Node]bool)
} }
@ -408,10 +460,7 @@ func isAllowed(function element, path string, load loadedSource, walked map[ast.
if err != nil { if err != nil {
panic(err) panic(err)
} }
newEl := element{ newEl := newElement(fun.name)
name: fun.name,
pos: token.Pos(0),
}
allowedSel := isAllowed(newEl, newPath, load, walked, info) allowedSel := isAllowed(newEl, newPath, load, walked, info)
if !allowedSel { if !allowedSel {
info.illegals = append(info.illegals, &illegal{ info.illegals = append(info.illegals, &illegal{
@ -459,22 +508,36 @@ type info struct {
illegals []*illegal // functions, selections that are not allowed illegals []*illegal // functions, selections that are not allowed
} }
func analyseProgram(functions []*fDefInfo, path string, load loadedSource) *info { func newElement(name string) *element {
return &element{
name: name,
pos: token.Pos(0),
}
}
func analyseProgram(filename, path string, load loadedSource) *info {
fset := load[path].fset
file := load[path].files[filename]
// Functions defined in the file
functions := defs(file)
info := &info{ info := &info{
callRep: make(map[string]int), callRep: make(map[string]int),
} }
info.illegals = append(info.illegals, analyseImports(file, fset, noRelativeImports)...)
walked := make(map[ast.Node]bool) walked := make(map[ast.Node]bool)
for _, v := range functions { for _, v := range functions {
f := element{ f := newElement(v.obj.Name)
name: v.obj.Name,
pos: token.Pos(0),
}
isAllowed(f, path, load, walked, info) isAllowed(f, path, load, walked, info)
} }
info.illegals = removeRepetitions(info.illegals) info.illegals = append(info.illegals, analyseLoops(info.fors, noFor)...)
info.illegals = append(info.illegals, analyseArrayTypes(info.arrays, noArrays, noTheseArrays)...)
info.illegals = append(info.illegals, analyseLits(info.lits, noLit)...)
info.illegals = append(info.illegals, analyseRepetition(info.callRep, allowedRep)...)
return info return info
} }
@ -511,19 +574,6 @@ func createChildScope(
scopes[block] = ast.NewScope(scopes[parentBlock]) scopes[block] = ast.NewScope(scopes[parentBlock])
} }
func init() {
flag.Var(&noTheseArrays, "no-these-arrays", "Disallowes the array types passed in the flag as a list separeted by comma with out spaces\nLike so: -no-these-arrays=int,string,bool")
flag.Var(&noLit, "no-lit",
`The use of basic literals (strings or characters) matching the pattern -no-lit="{PATTERN}"
passed to the program would not be allowed`,
)
flag.BoolVar(&noRelativeImports, "no-relative-imports", false, `Disallowes the use of relative imports`)
flag.BoolVar(&noFor, "no-for", false, `The "for" instruction is not allowed`)
flag.BoolVar(&casting, "cast", false, "Allowes casting")
flag.BoolVar(&noArrays, "no-arrays", false, "Disallowes all array types")
flag.BoolVar(&allowBuiltin, "allow-builtin", false, "Allowes all builtin functions and casting")
}
func parseArgs(toAllow []string, builtins bool, casting bool) error { func parseArgs(toAllow []string, builtins bool, casting bool) error {
allowedFun["builtin"] = make(map[string]bool) allowedFun["builtin"] = make(map[string]bool)
predeclaredTypes := []string{"bool", "byte", "complex64", "complex128", predeclaredTypes := []string{"bool", "byte", "complex64", "complex128",
@ -580,104 +630,83 @@ func parseArgs(toAllow []string, builtins bool, casting bool) error {
return nil return nil
} }
func main() { func printIllegals(illegals []*illegal) {
flag.Parse() tbl, err := table.NewTable([]table.Column{
if flag.NArg() < 1 { {Header: "\tTYPE:"},
fmt.Println("Not enough arguments: missing file") {Header: "NAME:", MinWidth: 7},
os.Exit(1) {Header: "LOCATION:"},
} }...)
fmt.Println("Parsing:")
err := parseArgs(flag.Args()[1:], allowBuiltin, casting)
if err != nil {
panic(err)
}
FileSet := token.NewFileSet()
file, err := parser.ParseFile(FileSet, flag.Arg(0), nil, parser.AllErrors)
if err != nil { if err != nil {
panic(err) panic(err)
} }
tbl.Separator = "\t"
load := make(loadedSource) for _, v := range illegals {
tbl.AddRow("\t"+v.T, v.Name, v.Pos)
currentPath := filepath.Dir(flag.Arg(0))
err = loadProgram(currentPath, load)
if err != nil {
panic(err)
} }
fmt.Println("\tOk") tbl.Print()
}
fmt.Println("Cheating:") func analyseRepetition(callRep map[string]int, allowRep map[string]int) []*illegal {
// Functions defined in the file var illegals []*illegal
fileFunc := defs(file) for name, rep := range allowedRep {
info := analyseProgram(fileFunc, currentPath, load) if callRep[name] > rep {
info.illegals = append(analyseImports(file, FileSet, noRelativeImports), info.illegals...) diff := callRep[name] - rep
if noFor {
for _, v := range info.fors {
il := &illegal{
T: "illegal-loop",
Name: v.name,
Pos: v.pos,
}
info.illegals = append(info.illegals, il)
}
}
for _, v := range info.arrays {
if noArrays || noTheseArrays[v.name] {
il := &illegal{ il := &illegal{
T: "illegal-array", T: "illegal-amount",
Name: v.name, Name: name + " exeding max repetitions by " + strconv.Itoa(diff),
Pos: v.pos, Pos: "all the project",
} }
info.illegals = append(info.illegals, il) illegals = append(illegals, il)
} }
} }
return illegals
}
func analyseLits(litOccu []*occurrence, noLit regexpFlag) []*illegal {
var illegals []*illegal
if noLit.active { if noLit.active {
for _, v := range info.lits { for _, v := range litOccu {
if noLit.reg.Match([]byte(v.name)) { if noLit.reg.Match([]byte(v.name)) {
il := &illegal{ il := &illegal{
T: "illegal-lit", T: "illegal-lit",
Name: v.name, Name: v.name,
Pos: v.pos, Pos: v.pos,
} }
info.illegals = append(info.illegals, il) illegals = append(illegals, il)
} }
} }
} }
for name, rep := range allowedRep { return illegals
if info.callRep[name] > rep { }
diff := info.callRep[name] - rep
func analyseArrayTypes(arrays []*occurrence, noArrays bool, noTheseArrays map[string]bool) []*illegal {
var illegals []*illegal
for _, v := range arrays {
if noArrays || noTheseArrays[v.name] {
il := &illegal{ il := &illegal{
T: "illegal-amount", T: "illegal-array",
Name: name + " exeding max repetitions by " + strconv.Itoa(diff), Name: v.name,
Pos: "all the project", Pos: v.pos,
} }
info.illegals = append(info.illegals, il) illegals = append(illegals, il)
} }
} }
info.illegals = removeRepetitions(info.illegals) return illegals
if info.illegals != nil { }
tbl, err := table.NewTable([]table.Column{ func analyseLoops(fors []*occurrence, noFor bool) []*illegal {
{Header: "\tTYPE:"}, var illegals []*illegal
{Header: "NAME:", MinWidth: 7}, if noFor {
{Header: "LOCATION:"}, for _, v := range fors {
}...) il := &illegal{
if err != nil { T: "illegal-loop",
panic(err) Name: v.name,
} Pos: v.pos,
tbl.Separator = "\t" }
for _, v := range info.illegals { illegals = append(illegals, il)
tbl.AddRow("\t"+v.T, v.Name, v.Pos) }
}
tbl.Print()
os.Exit(1)
} }
fmt.Println("\tOk") return illegals
} }
type importVisitor struct { type importVisitor struct {
@ -702,12 +731,12 @@ func (i *importVisitor) Visit(n ast.Node) ast.Visitor {
return i return i
} }
func analyseImports(n ast.Node, fset *token.FileSet, noRelImp bool) []*illegal { func analyseImports(file ast.Node, fset *token.FileSet, noRelImp bool) []*illegal {
var il []*illegal var il []*illegal
i := &importVisitor{ i := &importVisitor{
imports: make(map[string]*element), imports: make(map[string]*element),
} }
ast.Walk(i, n) ast.Walk(i, file)
for _, path := range i.imports { for _, path := range i.imports {
isRelativeImport := isRelativeImport(path.name) isRelativeImport := isRelativeImport(path.name)
if (noRelativeImports && isRelativeImport) || (allowedFun[path.name] == nil && !isRelativeImport) { if (noRelativeImports && isRelativeImport) || (allowedFun[path.name] == nil && !isRelativeImport) {
@ -736,6 +765,7 @@ type loadVisitor struct {
scopes map[*ast.BlockStmt]*ast.Scope // nil after the visit scopes map[*ast.BlockStmt]*ast.Scope // nil after the visit
// used to keep the result of the createScope function // used to keep the result of the createScope function
pkgScope *ast.Scope pkgScope *ast.Scope
files map[string]*ast.File
} }
// Returns all the parameter of a function that identify a function // Returns all the parameter of a function that identify a function

Loading…
Cancel
Save