RETURNS: - type expression which represents a full name of a type - bool whether a type expression is actually a type (used internally) - scope in which type makes sense
(v ast.Expr, scope *scope, index int)
| 753 | // - bool whether a type expression is actually a type (used internally) |
| 754 | // - scope in which type makes sense |
| 755 | func infer_type(v ast.Expr, scope *scope, index int) (ast.Expr, *scope, bool) { |
| 756 | switch t := v.(type) { |
| 757 | case *ast.CompositeLit: |
| 758 | return t.Type, scope, true |
| 759 | case *ast.Ident: |
| 760 | if d := scope.lookup(t.Name); d != nil { |
| 761 | if d.class == decl_package { |
| 762 | return ast.NewIdent(t.Name), scope, false |
| 763 | } |
| 764 | typ, scope := d.infer_type() |
| 765 | return typ, scope, d.class == decl_type |
| 766 | } |
| 767 | case *ast.UnaryExpr: |
| 768 | switch t.Op { |
| 769 | case token.AND: |
| 770 | // &a makes sense only with values, don't even check for type |
| 771 | it, s, _ := infer_type(t.X, scope, -1) |
| 772 | if it == nil { |
| 773 | break |
| 774 | } |
| 775 | |
| 776 | e := new(ast.StarExpr) |
| 777 | e.X = it |
| 778 | return e, s, false |
| 779 | case token.ARROW: |
| 780 | // <-a makes sense only with values |
| 781 | it, s, _ := infer_type(t.X, scope, -1) |
| 782 | if it == nil { |
| 783 | break |
| 784 | } |
| 785 | switch index { |
| 786 | case -1, 0: |
| 787 | it, s = advance_to_type(chan_predicate, it, s) |
| 788 | return it.(*ast.ChanType).Value, s, false |
| 789 | case 1: |
| 790 | // technically it's a value, but in case of index == 1 |
| 791 | // it is always the last infer operation |
| 792 | return ast.NewIdent("bool"), g_universe_scope, false |
| 793 | } |
| 794 | case token.ADD, token.NOT, token.SUB, token.XOR: |
| 795 | it, s, _ := infer_type(t.X, scope, -1) |
| 796 | if it == nil { |
| 797 | break |
| 798 | } |
| 799 | return it, s, false |
| 800 | } |
| 801 | case *ast.BinaryExpr: |
| 802 | switch t.Op { |
| 803 | case token.EQL, token.NEQ, token.LSS, token.LEQ, |
| 804 | token.GTR, token.GEQ, token.LOR, token.LAND: |
| 805 | // logic operations, the result is a bool, always |
| 806 | return ast.NewIdent("bool"), g_universe_scope, false |
| 807 | case token.ADD, token.SUB, token.MUL, token.QUO, token.OR, |
| 808 | token.XOR, token.REM, token.AND, token.AND_NOT: |
| 809 | // try X, then Y, they should be the same anyway |
| 810 | it, s, _ := infer_type(t.X, scope, -1) |
| 811 | if it == nil { |
| 812 | it, s, _ = infer_type(t.Y, scope, -1) |
no test coverage detected