Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
60407d2
Moved DynamicKeyword to its own file. Wrote the metadata parser
rjmholt Feb 15, 2017
04854fa
Added 0-arg ctor check
rjmholt Feb 15, 2017
77a3cc3
Added remaining keyword attribute properties to metadata parser
rjmholt Feb 15, 2017
1e0e8c3
Added DynamicKeyword scoping
rjmholt Feb 15, 2017
ce86a2d
Removed internal command inheritance on Keyword. Moved GetModulesFrom…
rjmholt Feb 15, 2017
229e221
Removed GetUnderlyingEnumType -- not supported in dotnetCore
rjmholt Feb 15, 2017
13b9900
Moved the DynamicKeyword.cs file to where it should be
rjmholt Feb 15, 2017
89da080
Fixed tokenizer to highlight command keywords
rjmholt Feb 15, 2017
9d8a674
Fixed Command keyword rendering. Added error messages to keyword loader
rjmholt Feb 16, 2017
a90e8a2
Improved keyword loader failure. Added preliminary test files
rjmholt Feb 16, 2017
810b29c
Added error and semantic tests
rjmholt Feb 17, 2017
407ce53
Updated module paths. Added some Datastructure tests
rjmholt Feb 17, 2017
7b07d3a
Added data structure tests
rjmholt Feb 17, 2017
e80a1a6
Updated path string
rjmholt Feb 17, 2017
b5dc1a3
Updated module path string function
rjmholt Feb 17, 2017
a466f7f
updated path string
rjmholt Feb 17, 2017
48d82e7
Introduced AST tests
rjmholt Feb 18, 2017
c2fd533
Fixed FileNotFoundException regression in UsingAssembly test
rjmholt Feb 18, 2017
8e9eced
Cleaned up small code pieces. Removed app/packages.config
rjmholt Feb 18, 2017
50ce4b0
Changed PSModulePath to PSMODULEPATH to make tests work on Linux
rjmholt Feb 21, 2017
57df215
Fixed a format error message for required keywords
rjmholt Feb 21, 2017
fa18fbe
Fix scoped keyword references. Add parameters to command keywords. Gr…
rjmholt Feb 23, 2017
07130f6
Added completions for keywords, parameters and values
Feb 24, 2017
06e519e
Added keyword and keyword parameter completions
Feb 24, 2017
f7c164d
Generalized parameter completion for DynamicKeywords
Feb 25, 2017
cb6220f
Started Types DSL tests
Feb 25, 2017
c6e2eeb
Removed flag changes from PSReadline Render.cs
Feb 27, 2017
c90229a
Merge branch 'dynamic-keyword-completion' into dynamic-keyword-metada…
Feb 27, 2017
160183c
No longer set the command token flag for dynamic keywords
Feb 27, 2017
0011915
Stopped command-bodied dynamic keywords from being flagged as commands
Feb 27, 2017
63068b6
Changed ParseErrorContainer to suit better API
Feb 27, 2017
b435260
Updated namespaces. Revised keyword scopes. Updated tests
Feb 28, 2017
29dfe25
Added Types_ps1xml DSL tests
Mar 1, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,020 changes: 1,020 additions & 0 deletions .vs/config/applicationhost.config

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,10 @@ internal List<CompletionResult> GetResultHelper(CompletionContext completionCont
bool matched;
result = GetResultForIdentifierInConfiguration(completionContext, configAst, keywordAst, out matched);
}
else if (keywordAst != null)
{
result = GetInnerDynamicKeywordResult(completionContext, keywordAst);
}
}
}
else if (completionContext.TokenAtCursor == null)
Expand Down Expand Up @@ -689,8 +693,13 @@ internal List<CompletionResult> GetResultHelper(CompletionContext completionCont
result = GetResultForEnumPropertyValueOfDSCResource(completionContext, string.Empty,
ref replacementIndex, ref replacementLength, out unused);
}
break;
break;
default:
DynamicKeywordStatementAst keywordAst = Ast.GetAncestorAst<DynamicKeywordStatementAst>(lastAst);
if (keywordAst != null)
{
result = GetDynamicKeywordParameterResult(completionContext, keywordAst);
}
break;
}
}
Expand Down Expand Up @@ -989,6 +998,7 @@ private List<CompletionResult> GetResultForEnumPropertyValueOfDSCResource(
DynamicKeywordProperty property;
if (keywordAst.Keyword.Properties.TryGetValue(propertyNameAst.Value, out property))
{
result = new List<CompletionResult>();
List<String> existingValues = null;
WildcardPattern wildcardPattern = null;
bool isDependsOnProperty = String.Equals(property.Name, @"DependsOn", StringComparison.OrdinalIgnoreCase);
Expand Down Expand Up @@ -1037,7 +1047,6 @@ private List<CompletionResult> GetResultForEnumPropertyValueOfDSCResource(
completionContext.ReplacementIndex = replacementIndex;
string matchString = stringToComplete + "*";
wildcardPattern = WildcardPattern.Get(matchString, WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant);
result = new List<CompletionResult>();
}

Diagnostics.Assert(isCursorInString || (!hasNewLine), "hasNoQuote and hasNewLine cannot be true at the same time");
Expand Down Expand Up @@ -1114,6 +1123,13 @@ private List<CompletionResult> GetResultForEnumPropertyValueOfDSCResource(
}
}
}
else
{
foreach (var propertyValue in property.Values)
{
result.Add(new CompletionResult(propertyValue, propertyValue, CompletionResultType.Text, propertyValue));
}
}
}
}
}
Expand Down Expand Up @@ -1341,6 +1357,69 @@ private List<CompletionResult> GetResultForIdentifierInConfiguration(
return results;
}

internal static List<CompletionResult> GetInnerDynamicKeywordResult(CompletionContext context, DynamicKeywordStatementAst parentKeywordAst)
{
var results = new List<CompletionResult>();

if (String.IsNullOrEmpty(context.WordToComplete))
{
foreach (var keyword in parentKeywordAst.Keyword.InnerKeywords.Values)
{
results.Add(new CompletionResult(keyword.Keyword, keyword.Keyword, CompletionResultType.Keyword, keyword.Keyword));
}
}
else
{
foreach (var keyword in parentKeywordAst.Keyword.InnerKeywords.Values)
{
if (keyword.Keyword.StartsWith(context.WordToComplete))
{
results.Add(new CompletionResult(keyword.Keyword, keyword.Keyword, CompletionResultType.Keyword, keyword.Keyword));
}
}
}

return results;
}

internal static List<CompletionResult> GetDynamicKeywordParameterResult(CompletionContext context, DynamicKeywordStatementAst keywordAst)
{
var results = new List<CompletionResult>();

string toComplete;
if (context?.WordToComplete?.StartsWith("-") ?? false)
{
toComplete = context.WordToComplete.Substring(1);
}
else
{
toComplete = "";
}
foreach (var param in keywordAst.Keyword.Parameters.Values)
{
if (!param.Name.StartsWith(toComplete))
{
continue;
}

string typeConstraint = param.TypeConstraint;
Type paramType = Type.GetType(param.TypeConstraint);
if (paramType != null)
{
string acceleratedType = TypeAccelerators.FindBuiltinAccelerator(paramType);
if (!String.IsNullOrEmpty(acceleratedType))
{
typeConstraint = acceleratedType;
}
}

string tooltip = "[" + typeConstraint + "]" + param.Name;
results.Add(new CompletionResult("-" + param.Name, param.Name, CompletionResultType.ParameterName, tooltip));
}

return results;
}

private List<CompletionResult> GetResultForIdentifier(CompletionContext completionContext, ref int replacementIndex, ref int replacementLength, bool isQuotedString)
{
var tokenAtCursor = completionContext.TokenAtCursor;
Expand Down Expand Up @@ -1510,6 +1589,12 @@ private List<CompletionResult> GetResultForIdentifier(CompletionContext completi
// Current token is within ConfigurationDefinitionAst or DynamicKeywordStatementAst
keywordResult = GetResultForIdentifierInConfiguration(completionContext, configureAst, keywordAst, out matched);
}
else if (keywordAst != null)
{
// Lie so keywords appear when commands are also possible
matched = true;
keywordResult = GetInnerDynamicKeywordResult(completionContext, keywordAst);
}

// Handle the file completion before command name completion
result = CompleteFileNameAsCommand(completionContext);
Expand All @@ -1521,14 +1606,18 @@ private List<CompletionResult> GetResultForIdentifier(CompletionContext completi
result.AddRange(commandNameResult);
}

if (matched && keywordResult != null)
{
result.InsertRange(0, keywordResult);
}
else if (!matched && keywordResult != null && commandNameResult.Count == 0)
{
result.AddRange(keywordResult);
if (keywordResult != null)
{
if (matched)
{
result.InsertRange(0, keywordResult);
}
else if (commandNameResult.Count == 0)
{
result.AddRange(keywordResult);
}
}

return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -518,28 +518,35 @@ internal static List<CompletionResult> CompleteCommandParameter(CompletionContex
keywordAst = parameterAst.Parent as DynamicKeywordStatementAst;
}

// If parent is DynamicKeywordStatementAst - 'Import-DscResource',
// then customize the auto completion results
if (keywordAst != null && String.Equals(keywordAst.Keyword.Keyword, "Import-DscResource", StringComparison.OrdinalIgnoreCase)
&& !String.IsNullOrWhiteSpace(context.WordToComplete) && context.WordToComplete.StartsWith("-", StringComparison.OrdinalIgnoreCase))
{
var lastAst = context.RelatedAsts.Last();
var wordToMatch = context.WordToComplete.Substring(1) + "*";
var pattern = WildcardPattern.Get(wordToMatch, WildcardOptions.IgnoreCase);
var parameterNames = keywordAst.CommandElements.Where(ast => ast is CommandParameterAst).Select(ast => (ast as CommandParameterAst).ParameterName);
foreach (var parameterName in s_parameterNamesOfImportDSCResource)
{
if (pattern.IsMatch(parameterName) && !parameterNames.Contains(parameterName, StringComparer.OrdinalIgnoreCase))
{
string tooltip = "[String] " + parameterName;
result.Add(new CompletionResult("-" + parameterName, parameterName, CompletionResultType.ParameterName, tooltip));
}
}
if (result.Count > 0)
{
context.ReplacementLength = context.WordToComplete.Length;
context.ReplacementIndex = lastAst.Extent.StartOffset;
}
if (keywordAst != null && !String.IsNullOrWhiteSpace(context.WordToComplete) && context.WordToComplete.StartsWith("-", StringComparison.OrdinalIgnoreCase))
{
// If parent is DynamicKeywordStatementAst - 'Import-DscResource',
// then customize the auto completion results
if (String.Equals(keywordAst.Keyword.Keyword, "Import-DscResource", StringComparison.OrdinalIgnoreCase))
{
var lastAst = context.RelatedAsts.Last();
var wordToMatch = context.WordToComplete.Substring(1) + "*";
var pattern = WildcardPattern.Get(wordToMatch, WildcardOptions.IgnoreCase);
var parameterNames = keywordAst.CommandElements.Where(ast => ast is CommandParameterAst).Select(ast => (ast as CommandParameterAst).ParameterName);
foreach (var parameterName in s_parameterNamesOfImportDSCResource)
{
if (pattern.IsMatch(parameterName) && !parameterNames.Contains(parameterName, StringComparer.OrdinalIgnoreCase))
{
string tooltip = "[String] " + parameterName;
result.Add(new CompletionResult("-" + parameterName, parameterName, CompletionResultType.ParameterName, tooltip));
}
}
if (result.Count > 0)
{
context.ReplacementLength = context.WordToComplete.Length;
context.ReplacementIndex = lastAst.Extent.StartOffset;
}
}
else
{
result.AddRange(CompletionAnalysis.GetDynamicKeywordParameterResult(context, keywordAst));
}

return result;
}

Expand Down Expand Up @@ -1002,6 +1009,15 @@ internal static List<CompletionResult> CompleteCommandArgument(CompletionContext
if (paramAst != null)
{
commandAst = paramAst.Parent as CommandAst;

if (commandAst == null)
{
DynamicKeywordStatementAst keywordAst = paramAst.Parent as DynamicKeywordStatementAst;
if (keywordAst != null)
{
result = GetKeywordParameterValueResult(context, paramAst, keywordAst);
}
}
}
else
{
Expand Down Expand Up @@ -1379,6 +1395,23 @@ internal static string ConcatenateStringPathArguments(CommandElementAst stringAs
return null;
}

private static List<CompletionResult> GetKeywordParameterValueResult(CompletionContext context, CommandParameterAst paramAst, DynamicKeywordStatementAst keywordAst)
{
var results = new List<CompletionResult>();
DynamicKeywordParameter param;
if (!keywordAst.Keyword.Parameters.TryGetValue(paramAst.ParameterName, out param))
{
return results;
}

foreach (var paramVal in param.Values)
{
results.Add(new CompletionResult(paramVal, paramVal, CompletionResultType.ParameterValue, paramVal));
}

return results;
}

/// <summary>
/// Get the argument completion results when the pseudo binding was not successful
/// </summary>
Expand Down
Loading