@@ -2671,33 +2671,82 @@ pub fn lookupSymbolContainer(
26712671pub fn lookupSymbolEnumLiteral (
26722672 analyser : * Analyser ,
26732673 handle : * const DocumentStore.Handle ,
2674+ source_index : usize ,
26742675 nodes : []Ast.Node.Index ,
26752676) error {OutOfMemory }! ? DeclWithHandle {
26762677 if (nodes .len == 0 ) return null ;
26772678
26782679 const tree = handle .tree ;
26792680 const node_tags = tree .nodes .items (.tag );
2680- if (node_tags [nodes [0 ]] != .enum_literal ) return null ;
2681+ const main_tokens = tree .nodes .items (.main_token );
2682+
2683+ var struct_init_buf : [2 ]Ast.Node.Index = undefined ;
2684+ if (tree .fullStructInit (& struct_init_buf , nodes [0 ])) | struct_init | {
2685+ for (struct_init .ast .fields ) | field_init | {
2686+ const field_token = handle .tree .firstToken (field_init ) - 2 ;
2687+ const field_loc = offsets .tokenToLoc (handle .tree , field_token );
2688+ if (field_loc .start <= source_index and source_index <= field_loc .end ) {
2689+ const field_name = tree .tokenSlice (field_token );
2690+ return analyser .lookupSymbolFieldInit (handle , field_name , nodes );
2691+ }
2692+ }
2693+ } else if (node_tags [nodes [0 ]] == .enum_literal ) {
2694+ const field_name = tree .tokenSlice (main_tokens [nodes [0 ]]);
2695+ return analyser .lookupSymbolFieldInit (handle , field_name , nodes );
2696+ }
2697+
2698+ return null ;
2699+ }
26812700
2682- const container_type = (try analyser .resolveEnumLiteralType (
2701+ pub fn lookupSymbolFieldInit (
2702+ analyser : * Analyser ,
2703+ handle : * const DocumentStore.Handle ,
2704+ field_name : []const u8 ,
2705+ nodes : []Ast.Node.Index ,
2706+ ) error {OutOfMemory }! ? DeclWithHandle {
2707+ if (nodes .len == 0 ) return null ;
2708+
2709+ var container_type = (try analyser .resolveExpressionType (
26832710 handle ,
26842711 nodes [0 ],
26852712 nodes [1.. ],
26862713 )) orelse return null ;
26872714
2715+ if (try analyser .resolveUnwrapErrorUnionType (container_type , .right )) | unwrapped |
2716+ container_type = unwrapped ;
2717+
2718+ if (try analyser .resolveUnwrapOptionalType (container_type )) | unwrapped |
2719+ container_type = unwrapped ;
2720+
26882721 const container_node = switch (container_type .type .data ) {
26892722 .other = > | n | n ,
26902723 else = > return null ,
26912724 };
26922725
26932726 return analyser .lookupSymbolContainer (
26942727 .{ .node = container_node , .handle = container_type .handle },
2695- tree . tokenSlice ( tree . nodes . items ( .main_token )[ nodes [ 0 ]]) ,
2728+ field_name ,
26962729 ! container_type .isEnumType (),
26972730 );
26982731}
26992732
2700- pub fn resolveEnumLiteralType (
2733+ pub fn resolveExpressionType (
2734+ analyser : * Analyser ,
2735+ handle : * const DocumentStore.Handle ,
2736+ node : Ast.Node.Index ,
2737+ ancestors : []Ast.Node.Index ,
2738+ ) error {OutOfMemory }! ? TypeWithHandle {
2739+ return (try analyser .resolveExpressionTypeFromAncestors (
2740+ handle ,
2741+ node ,
2742+ ancestors ,
2743+ )) orelse (try analyser .resolveTypeOfNode (.{
2744+ .node = node ,
2745+ .handle = handle ,
2746+ }));
2747+ }
2748+
2749+ pub fn resolveExpressionTypeFromAncestors (
27012750 analyser : * Analyser ,
27022751 handle : * const DocumentStore.Handle ,
27032752 node : Ast.Node.Index ,
@@ -2711,8 +2760,16 @@ pub fn resolveEnumLiteralType(
27112760 const token_tags : []std.zig.Token.Tag = tree .tokens .items (.tag );
27122761
27132762 var call_buf : [1 ]Ast.Node.Index = undefined ;
2763+ var struct_init_buf : [2 ]Ast.Node.Index = undefined ;
27142764
2715- if (tree .fullVarDecl (ancestors [0 ])) | var_decl | {
2765+ if (tree .fullStructInit (& struct_init_buf , ancestors [0 ])) | struct_init | {
2766+ if (std .mem .indexOfScalar (Ast .Node .Index , struct_init .ast .fields , node ) != null ) {
2767+ const field_name = tree .tokenSlice (tree .firstToken (node ) - 2 );
2768+ if (try analyser .lookupSymbolFieldInit (handle , field_name , ancestors )) | field_decl | {
2769+ return try field_decl .resolveType (analyser );
2770+ }
2771+ }
2772+ } else if (tree .fullVarDecl (ancestors [0 ])) | var_decl | {
27162773 if (node == var_decl .ast .init_node ) {
27172774 return try analyser .resolveTypeOfNode (.{
27182775 .node = ancestors [0 ],
@@ -2721,36 +2778,27 @@ pub fn resolveEnumLiteralType(
27212778 }
27222779 } else if (tree .fullIf (ancestors [0 ])) | if_node | {
27232780 if (node == if_node .ast .then_expr or node == if_node .ast .else_expr ) {
2724- return (try analyser .resolveTypeOfNode (.{
2725- .node = ancestors [0 ],
2726- .handle = handle ,
2727- })) orelse (try analyser .resolveEnumLiteralType (
2781+ return try analyser .resolveExpressionType (
27282782 handle ,
27292783 ancestors [0 ],
27302784 ancestors [1.. ],
2731- )) ;
2785+ );
27322786 }
27332787 } else if (tree .fullFor (ancestors [0 ])) | for_node | {
27342788 if (node == for_node .ast .else_expr ) {
2735- return (try analyser .resolveTypeOfNode (.{
2736- .node = ancestors [0 ],
2737- .handle = handle ,
2738- })) orelse (try analyser .resolveEnumLiteralType (
2789+ return try analyser .resolveExpressionType (
27392790 handle ,
27402791 ancestors [0 ],
27412792 ancestors [1.. ],
2742- )) ;
2793+ );
27432794 }
27442795 } else if (tree .fullWhile (ancestors [0 ])) | while_node | {
27452796 if (node == while_node .ast .else_expr ) {
2746- return (try analyser .resolveTypeOfNode (.{
2747- .node = ancestors [0 ],
2748- .handle = handle ,
2749- })) orelse (try analyser .resolveEnumLiteralType (
2797+ return try analyser .resolveExpressionType (
27502798 handle ,
27512799 ancestors [0 ],
27522800 ancestors [1.. ],
2753- )) ;
2801+ );
27542802 }
27552803 } else if (tree .fullSwitchCase (ancestors [0 ])) | switch_case | {
27562804 if (ancestors .len == 1 ) return null ;
@@ -2761,14 +2809,11 @@ pub fn resolveEnumLiteralType(
27612809 }
27622810
27632811 if (node == switch_case .ast .target_expr ) {
2764- return (try analyser .resolveTypeOfNode (.{
2765- .node = ancestors [1 ],
2766- .handle = handle ,
2767- })) orelse (try analyser .resolveEnumLiteralType (
2812+ return try analyser .resolveExpressionType (
27682813 handle ,
27692814 ancestors [1 ],
27702815 ancestors [2.. ],
2771- )) ;
2816+ );
27722817 }
27732818
27742819 for (switch_case .ast .values ) | value | {
@@ -2833,6 +2878,19 @@ pub fn resolveEnumLiteralType(
28332878 }));
28342879 },
28352880
2881+ .@"return" = > {
2882+ if (node != datas [ancestors [0 ]].lhs ) return null ;
2883+
2884+ var func_buf : [1 ]Ast.Node.Index = undefined ;
2885+ for (1.. ancestors .len ) | index | {
2886+ const func = tree .fullFnProto (& func_buf , ancestors [index ]) orelse continue ;
2887+ return try analyser .resolveTypeOfNode (.{
2888+ .node = func .ast .return_type ,
2889+ .handle = handle ,
2890+ });
2891+ }
2892+ },
2893+
28362894 .@"break" = > {
28372895 if (node != datas [ancestors [0 ]].rhs ) return null ;
28382896
@@ -2869,17 +2927,14 @@ pub fn resolveEnumLiteralType(
28692927 }
28702928 } else return null ;
28712929
2872- return (try analyser .resolveTypeOfNode (.{
2873- .node = ancestors [index ],
2874- .handle = handle ,
2875- })) orelse (try analyser .resolveEnumLiteralType (
2930+ return try analyser .resolveExpressionType (
28762931 handle ,
28772932 ancestors [index ],
28782933 ancestors [index + 1 .. ],
2879- )) ;
2934+ );
28802935 },
28812936
2882- else = > {}, // TODO: Implement more expressions that may contain enum literals ; better safe than sorry
2937+ else = > {}, // TODO: Implement more expressions; better safe than sorry
28832938 }
28842939
28852940 return null ;
0 commit comments