aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-08-02 16:51:55 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-08-02 16:57:32 +0200
commit394e6910d0eba8d9c4fcc4d10f66b68f3c097b3d (patch)
tree2cc379da69ef4df3cf4e5a87267e5f202a3863c5
parent1baf121c2fc6a3b92f01a48633d59290ff183476 (diff)
pkg/compiler: refactor checkType
checkType is too long and complex. Move basic type checks and args checks into separate functions. Update #538
-rw-r--r--pkg/compiler/check.go78
-rw-r--r--pkg/compiler/testdata/errors.txt2
2 files changed, 49 insertions, 31 deletions
diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go
index 195ca1245..5156bffc4 100644
--- a/pkg/compiler/check.go
+++ b/pkg/compiler/check.go
@@ -681,6 +681,36 @@ func (comp *compiler) checkType(ctx checkCtx, t *ast.Type, flags checkFlags) {
}
return
}
+ err0 := comp.errors
+ comp.checkTypeBasic(t, desc, flags)
+ if err0 != comp.errors {
+ return
+ }
+ args := comp.checkTypeArgs(t, desc, flags)
+ if err0 != comp.errors {
+ return
+ }
+ for i, arg := range args {
+ if desc.Args[i].Type == typeArgType {
+ var innerFlags checkFlags
+ if desc.Args[i].IsArg {
+ innerFlags |= checkIsArg
+ }
+ comp.checkType(ctx, arg, innerFlags)
+ } else {
+ comp.checkTypeArg(t, arg, desc.Args[i])
+ }
+ }
+ if err0 != comp.errors {
+ return
+ }
+ if desc.Check != nil {
+ _, args, base := comp.getArgsBase(t, "", prog.DirIn, flags&checkIsArg != 0)
+ desc.Check(comp, t, args, base)
+ }
+}
+
+func (comp *compiler) checkTypeBasic(t *ast.Type, desc *typeDesc, flags checkFlags) {
if t.HasColon {
if !desc.AllowColon {
comp.error(t.Pos2, "unexpected ':'")
@@ -699,6 +729,21 @@ func (comp *compiler) checkType(ctx checkCtx, t *ast.Type, flags checkFlags) {
comp.error(t.Pos, "%v can't be resource base (int types can)", t.Ident)
return
}
+ canBeArg, canBeRet := false, false
+ if desc.CanBeArgRet != nil {
+ canBeArg, canBeRet = desc.CanBeArgRet(comp, t)
+ }
+ if flags&checkIsRet != 0 && !canBeRet {
+ comp.error(t.Pos, "%v can't be syscall return", t.Ident)
+ return
+ }
+ if flags&checkIsArg != 0 && !canBeArg {
+ comp.error(t.Pos, "%v can't be syscall argument", t.Ident)
+ return
+ }
+}
+
+func (comp *compiler) checkTypeArgs(t *ast.Type, desc *typeDesc, flags checkFlags) []*ast.Type {
args, opt := removeOpt(t)
if opt != nil {
if len(opt.Args) != 0 {
@@ -710,7 +755,7 @@ func (comp *compiler) checkType(ctx checkCtx, t *ast.Type, flags checkFlags) {
what = t.Ident
}
comp.error(opt.Pos, "%v can't be marked as opt", what)
- return
+ return nil
}
}
addArgs := 0
@@ -721,41 +766,14 @@ func (comp *compiler) checkType(ctx checkCtx, t *ast.Type, flags checkFlags) {
if len(args) > len(desc.Args)+addArgs || len(args) < len(desc.Args)-desc.OptArgs+addArgs {
comp.error(t.Pos, "wrong number of arguments for type %v, expect %v",
t.Ident, expectedTypeArgs(desc, needBase))
- return
+ return nil
}
if needBase {
base := args[len(args)-1]
args = args[:len(args)-1]
comp.checkTypeArg(t, base, typeArgBase)
}
- err0 := comp.errors
- for i, arg := range args {
- if desc.Args[i].Type == typeArgType {
- var innerFlags checkFlags
- if desc.Args[i].IsArg {
- innerFlags |= checkIsArg
- }
- comp.checkType(ctx, arg, innerFlags)
- } else {
- comp.checkTypeArg(t, arg, desc.Args[i])
- }
- }
- canBeArg, canBeRet := false, false
- if desc.CanBeArgRet != nil {
- canBeArg, canBeRet = desc.CanBeArgRet(comp, t)
- }
- if flags&checkIsRet != 0 && !canBeRet {
- comp.error(t.Pos, "%v can't be syscall return", t.Ident)
- return
- }
- if flags&checkIsArg != 0 && !canBeArg {
- comp.error(t.Pos, "%v can't be syscall argument", t.Ident)
- return
- }
- if desc.Check != nil && err0 == comp.errors {
- _, args, base := comp.getArgsBase(t, "", prog.DirIn, flags&checkIsArg != 0)
- desc.Check(comp, t, args, base)
- }
+ return args
}
func (comp *compiler) replaceTypedef(ctx *checkCtx, t *ast.Type, flags checkFlags) {
diff --git a/pkg/compiler/testdata/errors.txt b/pkg/compiler/testdata/errors.txt
index 3c2cb57ae..b0e6ac834 100644
--- a/pkg/compiler/testdata/errors.txt
+++ b/pkg/compiler/testdata/errors.txt
@@ -321,7 +321,7 @@ foo$207(a ptr[in, templ_struct2[1]])
# fmt
-foo$fmt0(a fmt) ### wrong number of arguments for type fmt, expect format, value
+foo$fmt0(a ptr[in, fmt]) ### wrong number of arguments for type fmt, expect format, value
foo$fmt1(a fmt[dec, int8]) ### fmt can't be syscall argument
foo$fmt2(a ptr[in, fmt[dec, ptr[in, int8]]]) ### bad fmt value ptr, expect an integer
foo$fmt3(a ptr[in, fmt[foo, int8]]) ### unexpected value foo for format argument of fmt type, expect [dec hex oct]