Add Variable support in Intellisense (#460)

This commit is contained in:
Luc Genetier 2022-07-19 22:50:07 +02:00 коммит произвёл GitHub
Родитель ecf4679a73
Коммит 6416143a11
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 81 добавлений и 10 удалений

Просмотреть файл

@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System.Collections.Generic;
using Microsoft.PowerFx.Core.Binding.BindInfo;
namespace Microsoft.PowerFx.Core.Binding
{
// Allows Name resolvers to support global symbols, used for identifying
// variables in intellisense
internal interface IGlobalSymbolNameResolver : INameResolver
{
IReadOnlyDictionary<string, NameLookupInfo> GlobalSymbols { get; }
}
}

Просмотреть файл

@ -714,6 +714,14 @@ namespace Microsoft.PowerFx.Intellisense
AddSuggestion(intellisenseData, funcNamespace.Name, SuggestionKind.Global, SuggestionIconKind.Other, DType.Unknown, requiresSuggestionEscaping: true);
}
if (intellisenseData.Binding.NameResolver is IGlobalSymbolNameResolver nr2 && nr2.GlobalSymbols != null)
{
foreach (var symbol in nr2.GlobalSymbols.Where(symbol => IsMatch(symbol.Key, intellisenseData.MatchingStr)))
{
CheckAndAddSuggestion(new IntellisenseSuggestion(new UIString(symbol.Key), SuggestionKind.Global, SuggestionIconKind.Other, symbol.Value.Type, -1, symbol.Value.DisplayName, null, null), intellisenseData.Suggestions);
}
}
}
public static void AddSuggestionsForUnaryOperatorKeyWords(IntellisenseData.IntellisenseData intellisenseData)

Просмотреть файл

@ -1,6 +1,9 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.PowerFx.Core.Binding;
using Microsoft.PowerFx.Core.Binding.BindInfo;
using Microsoft.PowerFx.Core.Glue;
@ -11,11 +14,18 @@ namespace Microsoft.PowerFx
/// <summary>
/// <see cref="INameResolver"/> implementation for <see cref="RecalcEngine"/>.
/// </summary>
internal class RecalcEngineResolver : SimpleResolver
internal class RecalcEngineResolver : SimpleResolver, IGlobalSymbolNameResolver
{
private readonly RecalcEngine _parent;
private readonly PowerFxConfig _powerFxConfig;
public IReadOnlyDictionary<string, NameLookupInfo> GlobalSymbols => _parent.Formulas.ToDictionary(kvp => kvp.Key, kvp => Create(kvp.Key, kvp.Value));
private NameLookupInfo Create(string name, RecalcFormulaInfo recalcFormulaInfo)
{
return new NameLookupInfo(BindKind.PowerFxResolvedObject, recalcFormulaInfo.Value.Type._type, DPath.Root, 0, recalcFormulaInfo);
}
public RecalcEngineResolver(RecalcEngine parent, PowerFxConfig powerFxConfig)
: base(powerFxConfig)
{
@ -34,15 +44,7 @@ namespace Microsoft.PowerFx
if (_parent.Formulas.TryGetValue(str, out var fi))
{
var data = fi;
var type = fi._type._type;
nameInfo = new NameLookupInfo(
BindKind.PowerFxResolvedObject,
type,
DPath.Root,
0,
data);
nameInfo = Create(str, fi);
return true;
}

Просмотреть файл

@ -4,8 +4,13 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.PowerFx.Core;
using Microsoft.PowerFx.Core.Binding;
using Microsoft.PowerFx.Core.Binding.BindInfo;
using Microsoft.PowerFx.Core.Functions;
using Microsoft.PowerFx.Core.Types;
using Microsoft.PowerFx.Core.Types.Enums;
using Microsoft.PowerFx.Core.Utils;
using Microsoft.PowerFx.Intellisense;
using Microsoft.PowerFx.Tests.IntellisenseTests;
using Microsoft.PowerFx.Types;
using Xunit;
@ -71,5 +76,46 @@ namespace Microsoft.PowerFx.Interpreter.Tests
var actualSuggestions = SuggestStrings(expression, config, null);
Assert.Equal(expectedSuggestions, actualSuggestions);
}
[Theory]
[InlineData("Fi")]
[InlineData("fi")]
[InlineData("fileIndex")]
[InlineData("FILEINDEX")]
public void TestSuggestVariableName(string suggestion)
{
const string varName = "fileIndex";
var pfxConfig = new PowerFxConfig();
var recalcEngine = new RecalcEngine(pfxConfig);
recalcEngine.UpdateVariable(varName, FormulaValue.New(12));
var suggestions = recalcEngine.Suggest(suggestion, null, 2);
var s1 = suggestions.Suggestions.OfType<IntellisenseSuggestion>();
Assert.NotNull(s1);
Assert.Equal(8, s1.Count());
var s = s1.FirstOrDefault(su => su.Text == varName);
Assert.NotNull(s);
Assert.Equal("fileIndex", s.DisplayText.Text);
Assert.Null(s.FunctionName);
Assert.Equal(SuggestionIconKind.Other, s.IconKind);
Assert.Equal(SuggestionKind.Global, s.Kind);
Assert.Equal(DType.Number, s.Type);
var resolver = new RecalcEngineResolver(recalcEngine, pfxConfig);
Assert.True(resolver.GlobalSymbols.ContainsKey(varName));
Assert.Equal(BindKind.PowerFxResolvedObject, resolver.GlobalSymbols[varName].Kind);
Assert.IsType<RecalcFormulaInfo>(resolver.GlobalSymbols[varName].Data);
var b = resolver.Lookup(new DName(varName), out var nameInfo, NameLookupPreferences.GlobalsOnly);
Assert.True(b);
Assert.Equal(BindKind.PowerFxResolvedObject, nameInfo.Kind);
Assert.IsType<RecalcFormulaInfo>(nameInfo.Data);
}
}
}