diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-08-02 16:51:55 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-08-02 16:57:32 +0200 |
| commit | 394e6910d0eba8d9c4fcc4d10f66b68f3c097b3d (patch) | |
| tree | 2cc379da69ef4df3cf4e5a87267e5f202a3863c5 | |
| parent | 1baf121c2fc6a3b92f01a48633d59290ff183476 (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.go | 78 | ||||
| -rw-r--r-- | pkg/compiler/testdata/errors.txt | 2 |
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] |
