Skip to content

Commit cf3c2ce

Browse files
committed
Fix infer by alias
1 parent 743dc64 commit cf3c2ce

File tree

8 files changed

+163
-29
lines changed

8 files changed

+163
-29
lines changed

EmmyLua.LanguageServer/Completion/CompleteProvider/MemberProvider.cs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,38 @@ private void AddCompletionNormal(CompleteContext context)
6363
var colon = indexExpr.IsColonIndex;
6464
foreach (var member in context.SemanticModel.Context.GetMembers(prefixType))
6565
{
66-
context.CreateCompletion(member.Name, member.Type)
67-
.WithColon(colon)
68-
.WithData(member.RelationInformation)
69-
.WithDotCheckBracketLabel(indexExpr)
70-
.WithCheckDeclaration(member)
71-
.WithCheckVisible(indexExpr, member)
72-
.AddToContext();
66+
if (member.Name.StartsWith("["))
67+
{
68+
var label = member.Name[1..^1];
69+
var parent = context.TriggerToken.Parent;
70+
var dotToken = parent.FirstChildToken(LuaTokenKind.TkDot);
71+
if (dotToken is not null)
72+
{
73+
var additionalTextEdit = new AnnotatedTextEdit()
74+
{
75+
NewText = string.Empty,
76+
Range = dotToken.Range.ToLspRange(context.SemanticModel.Document)
77+
};
78+
79+
context.CreateCompletion(label, member.Type)
80+
.WithInsertText(member.Name)
81+
.WithData(member.RelationInformation)
82+
.WithAdditionalTextEdit(additionalTextEdit)
83+
.WithCheckDeclaration(member)
84+
.WithCheckVisible(indexExpr, member)
85+
.AddToContext();
86+
}
87+
}
88+
else
89+
{
90+
context.CreateCompletion(member.Name, member.Type)
91+
.WithColon(colon)
92+
.WithData(member.RelationInformation)
93+
.WithDotCheckBracketLabel(indexExpr)
94+
.WithCheckDeclaration(member)
95+
.WithCheckVisible(indexExpr, member)
96+
.AddToContext();
97+
}
7398
}
7499
}
75100

EmmyLua.LanguageServer/Completion/CompletionItemBuilder.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using EmmyLua.LanguageServer.Framework.Protocol.Message.Completion;
77
using EmmyLua.LanguageServer.Framework.Protocol.Model;
88
using EmmyLua.LanguageServer.Framework.Protocol.Model.Kind;
9+
using EmmyLua.LanguageServer.Framework.Protocol.Model.TextEdit;
910
using EmmyLua.LanguageServer.Framework.Protocol.Model.Union;
1011

1112
namespace EmmyLua.LanguageServer.Completion;
@@ -26,6 +27,8 @@ public class CompletionItemBuilder(string label, LuaType type, CompleteContext c
2627

2728
private TextEditOrInsertReplaceEdit? TextOrReplaceEdit { get; set; }
2829

30+
private List<AnnotatedTextEdit>? AdditionalTextEdit { get; set; }
31+
2932
private bool Colon { get; set; } = false;
3033

3134
private bool Disable { get; set; } = false;
@@ -132,6 +135,12 @@ public CompletionItemBuilder WithCommand(Command command)
132135
return this;
133136
}
134137

138+
public CompletionItemBuilder WithAdditionalTextEdit(AnnotatedTextEdit textEdit)
139+
{
140+
AdditionalTextEdit = [textEdit];
141+
return this;
142+
}
143+
135144
public CompletionItemBuilder WithTextEditOrReplaceEdit(TextEditOrInsertReplaceEdit textOrReplaceEdit)
136145
{
137146
TextOrReplaceEdit = textOrReplaceEdit;
@@ -178,7 +187,8 @@ public void AddToContext()
178187
InsertText = InsertText,
179188
Data = Data!,
180189
Command = Command,
181-
TextEdit = TextOrReplaceEdit
190+
TextEdit = TextOrReplaceEdit,
191+
AdditionalTextEdits = AdditionalTextEdit,
182192
};
183193
if (IsDeprecated)
184194
{
@@ -292,6 +302,7 @@ private CompletionItem GetSignatureCompletionItem(string label, LuaSignature sig
292302
InsertText = InsertText,
293303
Data = Data!,
294304
Command = Command,
305+
AdditionalTextEdits = AdditionalTextEdit,
295306
TextEdit = TextOrReplaceEdit
296307
};
297308

EmmyLua/CodeAnalysis/Compilation/Search/IndexMembers.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,21 @@ public class IndexMembers(SearchContext context)
112112
}
113113
}
114114

115-
var op = context.GetBestMatchedIndexOperator(namedType, Builtin.String);
116-
if (op is not null)
115+
if (name.StartsWith('['))
117116
{
118-
return new LuaSymbol(name, op.Ret, new VirtualInfo());
117+
var op = context.GetBestMatchedIndexOperator(namedType, Builtin.Integer);
118+
if (op is not null)
119+
{
120+
return new LuaSymbol(name, op.Ret, new VirtualInfo());
121+
}
122+
}
123+
else
124+
{
125+
var op = context.GetBestMatchedIndexOperator(namedType, Builtin.String);
126+
if (op is not null)
127+
{
128+
return new LuaSymbol(name, op.Ret, new VirtualInfo());
129+
}
119130
}
120131

121132
return null;

EmmyLua/CodeAnalysis/Compilation/Search/SameTypeInfer.cs

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
using EmmyLua.CodeAnalysis.Type;
22
using EmmyLua.CodeAnalysis.Type.Manager;
3+
using EmmyLua.CodeAnalysis.Type.Manager.TypeInfo;
34

45
namespace EmmyLua.CodeAnalysis.Compilation.Search;
56

67
public class SameTypeInfer(SearchContext context)
78
{
89
private LuaTypeManager TypeManager => context.Compilation.TypeManager;
910

11+
private Dictionary<SameTypeKey, SameTypeResult> SameTypeCaches { get; } = new();
12+
13+
enum SameTypeResult
14+
{
15+
NoAnswer,
16+
True,
17+
False,
18+
}
19+
20+
private record struct SameTypeKey(TypeInfo Left, TypeInfo Right);
21+
1022
public bool IsSameType(LuaType? left, LuaType? right)
1123
{
1224
if (left is null || right is null)
@@ -21,6 +33,8 @@ private bool InnerSameTypeOf(LuaType left, LuaType right)
2133
{
2234
switch ((left, right))
2335
{
36+
case (LuaGenericType leftGenericType, LuaGenericType rightGenericType):
37+
return IsSameTypeOfGenericType(leftGenericType, rightGenericType);
2438
case (LuaNamedType leftNamedType, LuaNamedType rightNamedType):
2539
return IsSameTypeOfNamedType(leftNamedType, rightNamedType);
2640
case (LuaArrayType leftArrayType, LuaArrayType rightArrayType):
@@ -32,8 +46,72 @@ private bool InnerSameTypeOf(LuaType left, LuaType right)
3246
return false;
3347
}
3448

49+
private bool IsSameTypeOfGenericType(LuaGenericType left, LuaGenericType right)
50+
{
51+
if (!IsSameTypeOfNamedType(left, right))
52+
{
53+
return false;
54+
}
55+
56+
if (left.GenericArgs.Count != right.GenericArgs.Count)
57+
{
58+
return false;
59+
}
60+
61+
for (var i = 0; i < left.GenericArgs.Count; i++)
62+
{
63+
if (!IsSameType(left.GenericArgs[i], right.GenericArgs[i]))
64+
{
65+
return false;
66+
}
67+
}
68+
69+
return true;
70+
}
71+
3572
private bool IsSameTypeOfNamedType(LuaNamedType left, LuaNamedType right)
3673
{
37-
return context.Compilation.TypeManager.IsSameType(left, right);
74+
if (left.DocumentId == right.DocumentId && left.Name == right.Name)
75+
{
76+
return true;
77+
}
78+
79+
var leftTypeInfo = TypeManager.FindTypeInfo(left);
80+
if (leftTypeInfo is null)
81+
{
82+
return false;
83+
}
84+
85+
var rightTypeInfo = TypeManager.FindTypeInfo(right);
86+
if (rightTypeInfo is null)
87+
{
88+
return false;
89+
}
90+
91+
if (leftTypeInfo == rightTypeInfo)
92+
{
93+
return true;
94+
}
95+
96+
var key = new SameTypeKey(leftTypeInfo, rightTypeInfo);
97+
if (SameTypeCaches.TryGetValue(key, out var result))
98+
{
99+
return result == SameTypeResult.True;
100+
}
101+
102+
SameTypeCaches[key] = SameTypeResult.NoAnswer;
103+
104+
var sameType = false;
105+
if (leftTypeInfo.Kind == NamedTypeKind.Alias)
106+
{
107+
sameType = IsSameType(leftTypeInfo.BaseType, right);
108+
}
109+
else if (rightTypeInfo.Kind == NamedTypeKind.Alias)
110+
{
111+
sameType = IsSameType(left, rightTypeInfo.BaseType);
112+
}
113+
114+
SameTypeCaches[key] = sameType ? SameTypeResult.True : SameTypeResult.False;
115+
return sameType;
38116
}
39117
}

EmmyLua/CodeAnalysis/Compile/Grammar/Doc/Fields.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,21 @@ public static CompleteMarker Field(LuaDocParser p, bool inBody)
1818
p.Accept(LuaTokenKind.TkDocVisibility);
1919
p.SetState(LuaDocLexerState.Normal);
2020
}
21+
2122
switch (p.Current)
2223
{
2324
case LuaTokenKind.TkLeftBracket:
2425
{
2526
p.Bump();
26-
TypesParser.Type(p);
27+
if (p.Current is LuaTokenKind.TkString or LuaTokenKind.TkInt)
28+
{
29+
p.Bump();
30+
}
31+
else
32+
{
33+
TypesParser.Type(p);
34+
}
35+
2736
p.Expect(LuaTokenKind.TkRightBracket);
2837
break;
2938
}

EmmyLua/CodeAnalysis/Type/Manager/LuaTypeManager.cs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ public void AddMemberImplementation(LuaNamedType type, LuaSymbol member)
293293
return;
294294
}
295295

296-
if (IsSameType(type, Builtin.Global))
296+
if (type.Name == "global")
297297
{
298298
AddGlobal(member.Name, member);
299299
return;
@@ -580,21 +580,6 @@ public IEnumerable<NamespaceOrType> GetNamespaceOrTypeInfos(string prefixNamespa
580580
return null;
581581
}
582582

583-
public bool IsSameType(LuaNamedType left, LuaNamedType right)
584-
{
585-
if (left.DocumentId == right.DocumentId)
586-
{
587-
return left.Name == right.Name;
588-
}
589-
else if (!NamespaceIndices.ContainsKey(left.DocumentId) &&
590-
!NamespaceIndices.ContainsKey(right.DocumentId))
591-
{
592-
return left.Name == right.Name;
593-
}
594-
595-
return FindTypeInfo(left) == FindTypeInfo(right);
596-
}
597-
598583
public bool HasNamespace(LuaDocumentId documentId)
599584
{
600585
return NamespaceIndices.ContainsKey(documentId);

EmmyLua/Resources/schema.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,17 @@
327327
}
328328
}
329329
},
330+
"SemanticTokens": {
331+
"type": [
332+
"object",
333+
"null"
334+
],
335+
"properties": {
336+
"enable": {
337+
"type": "boolean"
338+
}
339+
}
340+
},
330341
"Signature": {
331342
"type": [
332343
"object",
@@ -452,6 +463,9 @@
452463
},
453464
"strict": {
454465
"$ref": "#/definitions/Strict"
466+
},
467+
"semanticTokens": {
468+
"$ref": "#/definitions/SemanticTokens"
455469
}
456470
}
457471
}

EmmyLuaAnalyzer.sln.DotSettings.user

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInlineValueResponse_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F711ad90a91044e319e8113d478f367f0185400_003F4f_003F96f5c525_003FInlineValueResponse_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
1313
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInlineValueResponseJsonConverter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F711ad90a91044e319e8113d478f367f0185400_003F44_003Fc441625b_003FInlineValueResponseJsonConverter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
1414
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ALanguageServer_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fe108d28480f84c0581fb7bde75f4047e16ca00_003F4a_003F0a460284_003FLanguageServer_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
15+
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AList_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fbbd9fa7e8a144347ab86a6809b8a3a35d888b0_003Fb8_003F27298dba_003FList_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
1516
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ALocation_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fffaa84ff0ee24797965086335219d4ea16d800_003Fe0_003F904fa90b_003FLocation_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
1617
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASemanticTokensBuilder_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fffaa84ff0ee24797965086335219d4ea16d800_003Fbc_003Fae50f606_003FSemanticTokensBuilder_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
1718
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AServerCapabilities_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fffaa84ff0ee24797965086335219d4ea16d800_003F5f_003F4fdebbcf_003FServerCapabilities_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>

0 commit comments

Comments
 (0)