Skip to content

Commit aac05a6

Browse files
committed
type conditional stash
1 parent d607e5d commit aac05a6

File tree

7 files changed

+409
-6
lines changed

7 files changed

+409
-6
lines changed

crates/emmylua_parser/src/grammar/doc/tag.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,16 +135,21 @@ fn parse_generic_decl_list(p: &mut LuaDocParser, allow_angle_brackets: bool) ->
135135
}
136136

137137
// A : type
138+
// A extends type
138139
// A
139140
// A ...
140141
// A ... : type
142+
// A ... extends type
141143
fn parse_generic_param(p: &mut LuaDocParser) -> DocParseResult {
142144
let m = p.mark(LuaSyntaxKind::DocGenericParameter);
143145
expect_token(p, LuaTokenKind::TkName)?;
144146
if p.current_token() == LuaTokenKind::TkDots {
145147
p.bump();
146148
}
147-
if p.current_token() == LuaTokenKind::TkColon {
149+
if matches!(
150+
p.current_token(),
151+
LuaTokenKind::TkColon | LuaTokenKind::TkDocExtends
152+
) {
148153
p.bump();
149154
parse_type(p)?;
150155
}

crates/emmylua_parser/src/grammar/doc/test.rs

Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2867,4 +2867,318 @@ Syntax(Chunk)@0..137
28672867

28682868
assert_ast_eq!(code, result);
28692869
}
2870+
2871+
#[test]
2872+
fn test_alias_infer_identifier() {
2873+
let code = r#"
2874+
---@alias Foo infer
2875+
"#;
2876+
let result = r#"
2877+
Syntax(Chunk)@0..37
2878+
Syntax(Block)@0..37
2879+
Token(TkEndOfLine)@0..1 "\n"
2880+
Token(TkWhitespace)@1..9 " "
2881+
Syntax(Comment)@9..28
2882+
Token(TkDocStart)@9..13 "---@"
2883+
Syntax(DocTagAlias)@13..28
2884+
Token(TkTagAlias)@13..18 "alias"
2885+
Token(TkWhitespace)@18..19 " "
2886+
Token(TkName)@19..22 "Foo"
2887+
Token(TkWhitespace)@22..23 " "
2888+
Syntax(TypeName)@23..28
2889+
Token(TkName)@23..28 "infer"
2890+
Token(TkEndOfLine)@28..29 "\n"
2891+
Token(TkWhitespace)@29..37 " "
2892+
"#;
2893+
2894+
assert_ast_eq!(code, result);
2895+
}
2896+
2897+
#[test]
2898+
fn test_alias_conditional_infer_param() {
2899+
let code = r#"
2900+
---@alias ConstructorParameters<T> T extends (fun(infer: infer P): any) and P or unknown
2901+
"#;
2902+
2903+
let result = r#"
2904+
Syntax(Chunk)@0..106
2905+
Syntax(Block)@0..106
2906+
Token(TkEndOfLine)@0..1 "\n"
2907+
Token(TkWhitespace)@1..9 " "
2908+
Syntax(Comment)@9..97
2909+
Token(TkDocStart)@9..13 "---@"
2910+
Syntax(DocTagAlias)@13..97
2911+
Token(TkTagAlias)@13..18 "alias"
2912+
Token(TkWhitespace)@18..19 " "
2913+
Token(TkName)@19..40 "ConstructorParameters"
2914+
Syntax(DocGenericDeclareList)@40..43
2915+
Token(TkLt)@40..41 "<"
2916+
Syntax(DocGenericParameter)@41..42
2917+
Token(TkName)@41..42 "T"
2918+
Token(TkGt)@42..43 ">"
2919+
Token(TkWhitespace)@43..44 " "
2920+
Syntax(TypeConditional)@44..97
2921+
Syntax(TypeBinary)@44..80
2922+
Syntax(TypeName)@44..45
2923+
Token(TkName)@44..45 "T"
2924+
Token(TkWhitespace)@45..46 " "
2925+
Token(TkDocExtends)@46..53 "extends"
2926+
Token(TkWhitespace)@53..54 " "
2927+
Token(TkLeftParen)@54..55 "("
2928+
Syntax(TypeFun)@55..79
2929+
Token(TkName)@55..58 "fun"
2930+
Token(TkLeftParen)@58..59 "("
2931+
Syntax(DocTypedParameter)@59..73
2932+
Token(TkName)@59..64 "infer"
2933+
Token(TkColon)@64..65 ":"
2934+
Token(TkWhitespace)@65..66 " "
2935+
Syntax(TypeInfer)@66..73
2936+
Token(TkName)@66..71 "infer"
2937+
Token(TkWhitespace)@71..72 " "
2938+
Syntax(DocGenericParameter)@72..73
2939+
Token(TkName)@72..73 "P"
2940+
Token(TkRightParen)@73..74 ")"
2941+
Token(TkColon)@74..75 ":"
2942+
Token(TkWhitespace)@75..76 " "
2943+
Syntax(DocTypeList)@76..79
2944+
Syntax(DocNamedReturnType)@76..79
2945+
Syntax(TypeName)@76..79
2946+
Token(TkName)@76..79 "any"
2947+
Token(TkRightParen)@79..80 ")"
2948+
Token(TkWhitespace)@80..81 " "
2949+
Token(TkAnd)@81..84 "and"
2950+
Token(TkWhitespace)@84..85 " "
2951+
Syntax(TypeName)@85..86
2952+
Token(TkName)@85..86 "P"
2953+
Token(TkWhitespace)@86..87 " "
2954+
Token(TkOr)@87..89 "or"
2955+
Token(TkWhitespace)@89..90 " "
2956+
Syntax(TypeName)@90..97
2957+
Token(TkName)@90..97 "unknown"
2958+
Token(TkEndOfLine)@97..98 "\n"
2959+
Token(TkWhitespace)@98..106 " "
2960+
"#;
2961+
2962+
assert_ast_eq!(code, result);
2963+
}
2964+
2965+
#[test]
2966+
fn test_alias_conditional_infer() {
2967+
let code = r#"
2968+
---@alias ConstructorParameters<T extends fun(...: any): any> T extends (fun(...: infer P): any) and P or unknown
2969+
"#;
2970+
2971+
let result = r#"
2972+
Syntax(Chunk)@0..131
2973+
Syntax(Block)@0..131
2974+
Token(TkEndOfLine)@0..1 "\n"
2975+
Token(TkWhitespace)@1..9 " "
2976+
Syntax(Comment)@9..122
2977+
Token(TkDocStart)@9..13 "---@"
2978+
Syntax(DocTagAlias)@13..122
2979+
Token(TkTagAlias)@13..18 "alias"
2980+
Token(TkWhitespace)@18..19 " "
2981+
Token(TkName)@19..40 "ConstructorParameters"
2982+
Syntax(DocGenericDeclareList)@40..70
2983+
Token(TkLt)@40..41 "<"
2984+
Syntax(DocGenericParameter)@41..69
2985+
Token(TkName)@41..42 "T"
2986+
Token(TkWhitespace)@42..43 " "
2987+
Token(TkDocExtends)@43..50 "extends"
2988+
Token(TkWhitespace)@50..51 " "
2989+
Syntax(TypeFun)@51..69
2990+
Token(TkName)@51..54 "fun"
2991+
Token(TkLeftParen)@54..55 "("
2992+
Syntax(DocTypedParameter)@55..63
2993+
Token(TkDots)@55..58 "..."
2994+
Token(TkColon)@58..59 ":"
2995+
Token(TkWhitespace)@59..60 " "
2996+
Syntax(TypeName)@60..63
2997+
Token(TkName)@60..63 "any"
2998+
Token(TkRightParen)@63..64 ")"
2999+
Token(TkColon)@64..65 ":"
3000+
Token(TkWhitespace)@65..66 " "
3001+
Syntax(DocTypeList)@66..69
3002+
Syntax(DocNamedReturnType)@66..69
3003+
Syntax(TypeName)@66..69
3004+
Token(TkName)@66..69 "any"
3005+
Token(TkGt)@69..70 ">"
3006+
Token(TkWhitespace)@70..71 " "
3007+
Syntax(TypeConditional)@71..122
3008+
Syntax(TypeBinary)@71..105
3009+
Syntax(TypeName)@71..72
3010+
Token(TkName)@71..72 "T"
3011+
Token(TkWhitespace)@72..73 " "
3012+
Token(TkDocExtends)@73..80 "extends"
3013+
Token(TkWhitespace)@80..81 " "
3014+
Token(TkLeftParen)@81..82 "("
3015+
Syntax(TypeFun)@82..104
3016+
Token(TkName)@82..85 "fun"
3017+
Token(TkLeftParen)@85..86 "("
3018+
Syntax(DocTypedParameter)@86..98
3019+
Token(TkDots)@86..89 "..."
3020+
Token(TkColon)@89..90 ":"
3021+
Token(TkWhitespace)@90..91 " "
3022+
Syntax(TypeInfer)@91..98
3023+
Token(TkName)@91..96 "infer"
3024+
Token(TkWhitespace)@96..97 " "
3025+
Syntax(DocGenericParameter)@97..98
3026+
Token(TkName)@97..98 "P"
3027+
Token(TkRightParen)@98..99 ")"
3028+
Token(TkColon)@99..100 ":"
3029+
Token(TkWhitespace)@100..101 " "
3030+
Syntax(DocTypeList)@101..104
3031+
Syntax(DocNamedReturnType)@101..104
3032+
Syntax(TypeName)@101..104
3033+
Token(TkName)@101..104 "any"
3034+
Token(TkRightParen)@104..105 ")"
3035+
Token(TkWhitespace)@105..106 " "
3036+
Token(TkAnd)@106..109 "and"
3037+
Token(TkWhitespace)@109..110 " "
3038+
Syntax(TypeName)@110..111
3039+
Token(TkName)@110..111 "P"
3040+
Token(TkWhitespace)@111..112 " "
3041+
Token(TkOr)@112..114 "or"
3042+
Token(TkWhitespace)@114..115 " "
3043+
Syntax(TypeName)@115..122
3044+
Token(TkName)@115..122 "unknown"
3045+
Token(TkEndOfLine)@122..123 "\n"
3046+
Token(TkWhitespace)@123..131 " "
3047+
"#;
3048+
3049+
assert_ast_eq!(code, result);
3050+
}
3051+
3052+
#[test]
3053+
fn test_alias_nested_conditional_no_paren() {
3054+
let code = r#"
3055+
---@alias IsFortyTwo<T> T extends number and T extends 42 and true or false or false
3056+
"#;
3057+
3058+
let result = r#"
3059+
Syntax(Chunk)@0..102
3060+
Syntax(Block)@0..102
3061+
Token(TkEndOfLine)@0..1 "\n"
3062+
Token(TkWhitespace)@1..9 " "
3063+
Syntax(Comment)@9..93
3064+
Token(TkDocStart)@9..13 "---@"
3065+
Syntax(DocTagAlias)@13..93
3066+
Token(TkTagAlias)@13..18 "alias"
3067+
Token(TkWhitespace)@18..19 " "
3068+
Token(TkName)@19..29 "IsFortyTwo"
3069+
Syntax(DocGenericDeclareList)@29..32
3070+
Token(TkLt)@29..30 "<"
3071+
Syntax(DocGenericParameter)@30..31
3072+
Token(TkName)@30..31 "T"
3073+
Token(TkGt)@31..32 ">"
3074+
Token(TkWhitespace)@32..33 " "
3075+
Syntax(TypeConditional)@33..93
3076+
Syntax(TypeBinary)@33..49
3077+
Syntax(TypeName)@33..34
3078+
Token(TkName)@33..34 "T"
3079+
Token(TkWhitespace)@34..35 " "
3080+
Token(TkDocExtends)@35..42 "extends"
3081+
Token(TkWhitespace)@42..43 " "
3082+
Syntax(TypeName)@43..49
3083+
Token(TkName)@43..49 "number"
3084+
Token(TkWhitespace)@49..50 " "
3085+
Token(TkAnd)@50..53 "and"
3086+
Token(TkWhitespace)@53..54 " "
3087+
Syntax(TypeConditional)@54..84
3088+
Syntax(TypeBinary)@54..66
3089+
Syntax(TypeName)@54..55
3090+
Token(TkName)@54..55 "T"
3091+
Token(TkWhitespace)@55..56 " "
3092+
Token(TkDocExtends)@56..63 "extends"
3093+
Token(TkWhitespace)@63..64 " "
3094+
Syntax(TypeLiteral)@64..66
3095+
Token(TkInt)@64..66 "42"
3096+
Token(TkWhitespace)@66..67 " "
3097+
Token(TkAnd)@67..70 "and"
3098+
Token(TkWhitespace)@70..71 " "
3099+
Syntax(TypeLiteral)@71..75
3100+
Token(TkTrue)@71..75 "true"
3101+
Token(TkWhitespace)@75..76 " "
3102+
Token(TkOr)@76..78 "or"
3103+
Token(TkWhitespace)@78..79 " "
3104+
Syntax(TypeLiteral)@79..84
3105+
Token(TkFalse)@79..84 "false"
3106+
Token(TkWhitespace)@84..85 " "
3107+
Token(TkOr)@85..87 "or"
3108+
Token(TkWhitespace)@87..88 " "
3109+
Syntax(TypeLiteral)@88..93
3110+
Token(TkFalse)@88..93 "false"
3111+
Token(TkEndOfLine)@93..94 "\n"
3112+
Token(TkWhitespace)@94..102 " "
3113+
"#;
3114+
3115+
assert_ast_eq!(code, result);
3116+
}
3117+
3118+
#[test]
3119+
fn test_alias_nested_conditional() {
3120+
let code = r#"
3121+
---@alias IsFortyTwo<T> T extends number and (T extends 42 and true or false) or false
3122+
"#;
3123+
3124+
let result = r#"
3125+
Syntax(Chunk)@0..104
3126+
Syntax(Block)@0..104
3127+
Token(TkEndOfLine)@0..1 "\n"
3128+
Token(TkWhitespace)@1..9 " "
3129+
Syntax(Comment)@9..95
3130+
Token(TkDocStart)@9..13 "---@"
3131+
Syntax(DocTagAlias)@13..95
3132+
Token(TkTagAlias)@13..18 "alias"
3133+
Token(TkWhitespace)@18..19 " "
3134+
Token(TkName)@19..29 "IsFortyTwo"
3135+
Syntax(DocGenericDeclareList)@29..32
3136+
Token(TkLt)@29..30 "<"
3137+
Syntax(DocGenericParameter)@30..31
3138+
Token(TkName)@30..31 "T"
3139+
Token(TkGt)@31..32 ">"
3140+
Token(TkWhitespace)@32..33 " "
3141+
Syntax(TypeConditional)@33..95
3142+
Syntax(TypeBinary)@33..49
3143+
Syntax(TypeName)@33..34
3144+
Token(TkName)@33..34 "T"
3145+
Token(TkWhitespace)@34..35 " "
3146+
Token(TkDocExtends)@35..42 "extends"
3147+
Token(TkWhitespace)@42..43 " "
3148+
Syntax(TypeName)@43..49
3149+
Token(TkName)@43..49 "number"
3150+
Token(TkWhitespace)@49..50 " "
3151+
Token(TkAnd)@50..53 "and"
3152+
Token(TkWhitespace)@53..54 " "
3153+
Token(TkLeftParen)@54..55 "("
3154+
Syntax(TypeConditional)@55..85
3155+
Syntax(TypeBinary)@55..67
3156+
Syntax(TypeName)@55..56
3157+
Token(TkName)@55..56 "T"
3158+
Token(TkWhitespace)@56..57 " "
3159+
Token(TkDocExtends)@57..64 "extends"
3160+
Token(TkWhitespace)@64..65 " "
3161+
Syntax(TypeLiteral)@65..67
3162+
Token(TkInt)@65..67 "42"
3163+
Token(TkWhitespace)@67..68 " "
3164+
Token(TkAnd)@68..71 "and"
3165+
Token(TkWhitespace)@71..72 " "
3166+
Syntax(TypeLiteral)@72..76
3167+
Token(TkTrue)@72..76 "true"
3168+
Token(TkWhitespace)@76..77 " "
3169+
Token(TkOr)@77..79 "or"
3170+
Token(TkWhitespace)@79..80 " "
3171+
Syntax(TypeLiteral)@80..85
3172+
Token(TkFalse)@80..85 "false"
3173+
Token(TkRightParen)@85..86 ")"
3174+
Token(TkWhitespace)@86..87 " "
3175+
Token(TkOr)@87..89 "or"
3176+
Token(TkWhitespace)@89..90 " "
3177+
Syntax(TypeLiteral)@90..95
3178+
Token(TkFalse)@90..95 "false"
3179+
Token(TkEndOfLine)@95..96 "\n"
3180+
Token(TkWhitespace)@96..104 " "
3181+
"#;
3182+
assert_ast_eq!(code, result);
3183+
}
28703184
}

0 commit comments

Comments
 (0)