Skip to content

Commit

Permalink
Initial changes to fix issue #804
Browse files Browse the repository at this point in the history
  • Loading branch information
bhsubra committed Apr 17, 2021
1 parent 81fa2c2 commit 860e77d
Show file tree
Hide file tree
Showing 11 changed files with 116 additions and 258 deletions.
18 changes: 18 additions & 0 deletions src/Bicep.Core.Samples/Files/Completions/declarations.json
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,24 @@
"newText": "resource automationAccount 'Microsoft.Automation/automationAccounts@2019-06-01' = {\n name: ${1:'automationAccount'}\n location: resourceGroup().location\n properties: {\n sku: {\n name: '${2|Free,Basic|}'\n }\n }\n}\n"
}
},
{
"label": "res-automation-module",
"kind": "snippet",
"detail": "Automation Module",
"documentation": {
"kind": "markdown",
"value": "```bicep\nresource automationAccount_automationVariable 'Microsoft.Automation/automationAccounts/modules@2015-10-31' = {\n name: '${automationAccount.name}/automationVariable'\n properties: {\n contentLink: {\n uri: 'https://content-url.nupkg'\n }\n }\n}\n\nresource automationAccount 'Microsoft.Automation/automationAccounts@2015-10-31' = {\n name: 'automationAccount'\n}\n```"
},
"deprecated": false,
"preselect": false,
"sortText": "2_res-automation-module",
"insertTextFormat": "snippet",
"insertTextMode": "adjustIndentation",
"textEdit": {
"range": {},
"newText": "resource automationAccount_automationVariable 'Microsoft.Automation/automationAccounts/modules@2015-10-31' = {\n name: '${automationAccount.name}/${2:automationVariable}'\n properties: {\n contentLink: {\n uri: '${3:https://content-url.nupkg}'\n }\n }\n}\n\nresource automationAccount 'Microsoft.Automation/automationAccounts@2015-10-31' = {\n name: '${1:automationAccount}'\n}"
}
},
{
"label": "res-availability-set",
"kind": "snippet",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,21 @@
}
},
{
"label": "{}",
"kind": "value",
"detail": "{}",
"label": "res-dns-zone",
"kind": "snippet",
"detail": "DNS Zone",
"documentation": {
"kind": "markdown",
"value": "```bicep\n{\n name: 'dnsZone'\n location: 'global'\n}\n```"
},
"deprecated": false,
"preselect": true,
"sortText": "1_{}",
"sortText": "2_res-dns-zone",
"insertTextFormat": "snippet",
"insertTextMode": "adjustIndentation",
"textEdit": {
"range": {},
"newText": "{\n\t$0\n}"
"newText": "{\n name: '${1:dnsZone}'\n location: 'global'\n}"
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// $1 = testAutomationModule
// $2 = testAutomationVariable
// $3 = https://test-content-url.nupkg

// Insert snippet here
19 changes: 19 additions & 0 deletions src/Bicep.LangServer.UnitTests/Snippets/SnippetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,25 @@ public void SinglePropertySnippetShouldParseCorrectly()
snippet.FormatDocumentation().Should().Be("name: ''");
}

[TestMethod]
public void SnippetPlaceholderTextWithUrlShouldParseCorrectly()
{
string text = @"var testIdentifier = '${1:http://test-content-url.nupkg}'";

var snippet = new Snippet(text);
snippet.Text.Should().Be(text);

snippet.Placeholders.Should().SatisfyRespectively(
x =>
{
x.Index.Should().Be(1);
x.Name.Should().Be("http://test-content-url.nupkg");
x.Span.ToString().Should().Be("[22:56]");
});

snippet.FormatDocumentation().Should().Be("var testIdentifier = 'http://test-content-url.nupkg'");
}

[TestMethod]
public void SnippetPlaceholderTextWithMultipleChoicesShouldReturnFirstOneByDefault()
{
Expand Down
145 changes: 0 additions & 145 deletions src/Bicep.LangServer.UnitTests/Snippets/SnippetsProviderTests.cs

This file was deleted.

58 changes: 51 additions & 7 deletions src/Bicep.LangServer/Completions/BicepCompletionProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ public IEnumerable<CompletionItem> GetFilteredCompletions(Compilation compilatio
.Concat(GetResourceTypeCompletions(model, context))
.Concat(GetResourceTypeFollowerCompletions(context))
.Concat(GetModulePathCompletions(model, context))
.Concat(GetResourceOrModuleBodyCompletions(context))
.Concat(GetModuleBodyCompletions(context))
.Concat(GetResourceBodyCompletions(context))
.Concat(GetParameterDefaultValueCompletions(model, context))
.Concat(GetVariableValueCompletions(context))
.Concat(GetOutputValueCompletions(model, context))
Expand Down Expand Up @@ -326,7 +327,7 @@ private IEnumerable<CompletionItem> GetParameterDefaultValueCompletions(Semantic

private IEnumerable<CompletionItem> GetVariableValueCompletions(BicepCompletionContext context)
{
if(!context.Kind.HasFlag(BicepCompletionContextKind.VariableValue))
if (!context.Kind.HasFlag(BicepCompletionContextKind.VariableValue))
{
return Enumerable.Empty<CompletionItem>();
}
Expand All @@ -347,9 +348,51 @@ private IEnumerable<CompletionItem> GetOutputValueCompletions(SemanticModel mode
return GetValueCompletionsForType(declaredType, context.ReplacementRange, model, context, loopsAllowed: true);
}

private IEnumerable<CompletionItem> GetResourceOrModuleBodyCompletions(BicepCompletionContext context)
private IEnumerable<CompletionItem> GetResourceBodyCompletions(BicepCompletionContext context)
{
if (context.Kind.HasFlag(BicepCompletionContextKind.ResourceBody) || context.Kind.HasFlag(BicepCompletionContextKind.ModuleBody))
if (context.Kind.HasFlag(BicepCompletionContextKind.ResourceBody))
{
StringSyntax? stringSyntax = (context.EnclosingDeclaration as ResourceDeclarationSyntax)?.TypeString;

if (stringSyntax is not null)
{
string type = stringSyntax.StringTokens[0].Text;

Snippet? snippet = SnippetsProvider.GetResourceCompletionSnippet(type);

if (snippet is null)
{
yield return CompletionItemBuilder.Create(CompletionItemKind.Value)
.WithLabel("{}")
.WithSnippetEdit(context.ReplacementRange, "{\n\t$0\n}")
.WithDetail("{}")
.Preselect()
.WithSortText(GetSortText("{}", CompletionPriority.High));
}
else
{
yield return CreateContextualSnippetCompletion(snippet.Prefix,
snippet.Detail,
snippet.Text,
context.ReplacementRange,
snippet.CompletionPriority,
preselect: true);
}
}

yield return CreateResourceOrModuleConditionCompletion(context.ReplacementRange);

// loops are always allowed in a resource/module
foreach (var completion in CreateLoopCompletions(context.ReplacementRange, LanguageConstants.Object, filtersAllowed: true))
{
yield return completion;
}
}
}

private IEnumerable<CompletionItem> GetModuleBodyCompletions(BicepCompletionContext context)
{
if (context.Kind.HasFlag(BicepCompletionContextKind.ModuleBody))
{
yield return CreateObjectBodyCompletion(context.ReplacementRange);

Expand Down Expand Up @@ -742,7 +785,7 @@ private static IEnumerable<CompletionItem> CreateLoopCompletions(Range replaceme
yield return CreateContextualSnippetCompletion(loopLabel, loopLabel, itemSnippet, replacementRange, CompletionPriority.High);
yield return CreateContextualSnippetCompletion(indexedLabel, indexedLabel, indexedSnippet, replacementRange, CompletionPriority.High);

if(filtersAllowed && assignableToObject && !assignableToArray)
if (filtersAllowed && assignableToObject && !assignableToArray)
{
yield return CreateContextualSnippetCompletion(filteredLabel, filteredLabel, "[for (${2:item}, ${3:index}) in ${1:list}: if (${4:condition}) {\n\t$0\n}]", replacementRange, CompletionPriority.High);
}
Expand Down Expand Up @@ -864,13 +907,14 @@ private static CompletionItem CreateModulePathCompletion(string name, string pat
/// <summary>
/// Creates a completion with a contextual snippet. This will look like a snippet to the user.
/// </summary>
private static CompletionItem CreateContextualSnippetCompletion(string label, string detail, string snippet, Range replacementRange, CompletionPriority priority = CompletionPriority.Medium) =>
private static CompletionItem CreateContextualSnippetCompletion(string label, string detail, string snippet, Range replacementRange, CompletionPriority priority = CompletionPriority.Medium, bool preselect = false) =>
CompletionItemBuilder.Create(CompletionItemKind.Snippet)
.WithLabel(label)
.WithSnippetEdit(replacementRange, snippet)
.WithDetail(detail)
.WithDocumentation($"```bicep\n{new Snippet(snippet).FormatDocumentation()}\n```")
.WithSortText(GetSortText(label, priority));
.WithSortText(GetSortText(label, priority))
.Preselect(preselect);

/// <summary>
/// Creates a completion with a contextual snippet. This will look like a snippet to the user.
Expand Down
4 changes: 0 additions & 4 deletions src/Bicep.LangServer/Completions/CompletionItemBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,6 @@ public static CompletionItem WithSnippetEdit(this CompletionItem item, Range ran
return item;
}




public static CompletionItem WithSortText(this CompletionItem item, string sortText)
{
item.SortText = sortText;
Expand All @@ -103,7 +100,6 @@ public static CompletionItem Preselect(this CompletionItem item, bool preselect)
return item;
}


public static CompletionItem WithCommand(this CompletionItem item, Command command)
{
item.Command = command;
Expand Down
12 changes: 0 additions & 12 deletions src/Bicep.LangServer/Snippets/ISnippetsProvider.cs

This file was deleted.

Loading

0 comments on commit 860e77d

Please sign in to comment.