(ctx *parser.FunctionDeclarationContext)
| 30 | } |
| 31 | |
| 32 | func (s *SemanticResolver) ExitFunctionDeclaration(ctx *parser.FunctionDeclarationContext) { |
| 33 | function := s.at.GetNode2Scope()[ctx] |
| 34 | if ctx.TypeTypeOrVoid() != nil { |
| 35 | switch function.(type) { |
| 36 | case *symbol.Func: |
| 37 | f := function.(*symbol.Func) |
| 38 | if GetInternalFunction(f.GetName()) != nil { |
| 39 | // skip internal function |
| 40 | return |
| 41 | } |
| 42 | returnType := f.GetReturnType() |
| 43 | _, isDeclareFunction := returnType.(*symbol.DeclareFunctionType) |
| 44 | r := s.checkReturn(ctx) |
| 45 | if returnType != nil && r == false && isDeclareFunction == false { |
| 46 | // 函数声明了返回值,但却没有返回返回值时,同时这个函数声明的返回值是"函数类型"时,则不需要校验 |
| 47 | s.at.Log(ctx, fmt.Sprintf("miss return at end of function: %s", f.GetName())) |
| 48 | } |
| 49 | } |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | // 递归查询下级是否包含 return statement |
| 54 | func (s *SemanticResolver) checkReturn(ctx antlr.Tree) bool { |
nothing calls this directly
no test coverage detected