Skip to content

Commit

Permalink
Removed some code smells
Browse files Browse the repository at this point in the history
See also: #25
  • Loading branch information
AnderssonPeter committed Dec 21, 2021
1 parent 6ba65ae commit 007d21c
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 136 deletions.
2 changes: 1 addition & 1 deletion PowerType/BackgroundProcessing/ExecutionEngineThread.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public void Dispose()

if (!backgroundThread.Join(200))
{
throw new Exception("Failed to shutdown background thread!");
//todo: log that we failed to shutdown background thread!
}
}
}
160 changes: 80 additions & 80 deletions PowerType/DictionarySuggestor.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
using PowerType.Model;
using PowerType.Parsing;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management.Automation.Language;
using System.Management.Automation.Subsystem.Prediction;
using System.Text;
using System.Threading.Tasks;

namespace PowerType;

Expand Down Expand Up @@ -57,9 +51,6 @@ public IEnumerable<PredictiveSuggestion> GetPredictions(DictionaryParsingContext

private IEnumerable<PredictiveSuggestion> Parse(IEnumerable<Parameter> parameters, DictionaryParsingContext context, IEnumerable<Parameter> additionalParameters)
{
var repeat = (Parameter perfectMatch) =>
Parse(parameters.Where(parameter => parameter != perfectMatch), context, additionalParameters);

var allParameters = parameters.Union(additionalParameters);
if (!context.HasValue)
{
Expand All @@ -70,103 +61,112 @@ private IEnumerable<PredictiveSuggestion> Parse(IEnumerable<Parameter> parameter
var perfectMatch = allParameters.FirstOrDefault(parameter => parameter.IsPerfectKeyMatch(currentArgument) && parameter.IsAvailable(context));
if (perfectMatch != null)
{
if (perfectMatch is CommandParameter commandParameter)
{
var recursiveParameters = parameters.Where(x => x.Recursive).ToList();
context.Parameters.Add(new ParameterWithValue(currentArgument, perfectMatch));
return Parse(commandParameter.Parameters, context, additionalParameters.Union(recursiveParameters));
}
else if (perfectMatch is ValueParameter valueParameter)
return GetPerfectMatches(parameters, context, additionalParameters, currentArgument, perfectMatch);
}
else if (context.IsLast)
{
//Check for partial matches
return GetPartialMatches(context, allParameters, currentArgument);
}
else
{
//Failed to find a match add empty to context and try again, skipping this value
context.Parameters.Add(new ParameterWithValue(currentArgument, null));
return Parse(parameters, context, additionalParameters);
}
}

private IEnumerable<PredictiveSuggestion> GetPerfectMatches(IEnumerable<Parameter> parameters, DictionaryParsingContext context, IEnumerable<Parameter> additionalParameters, PowerShellString currentArgument, Parameter perfectMatch)
{
var repeat = (Parameter perfectMatch) =>
Parse(parameters.Where(parameter => parameter != perfectMatch), context, additionalParameters);

if (perfectMatch is CommandParameter commandParameter)
{
var recursiveParameters = parameters.Where(x => x.Recursive).ToList();
context.Parameters.Add(new ParameterWithValue(currentArgument, perfectMatch));
return Parse(commandParameter.Parameters, context, additionalParameters.Union(recursiveParameters));
}
else if (perfectMatch is ValueParameter valueParameter)
{
if (valueParameter.TryGetKeyAndValue(currentArgument, out var key, out PowerShellString value))
{
if (valueParameter.TryGetKeyAndValue(currentArgument, out var key, out PowerShellString value))
var isDone = IsValueDone(context.IsLast, value);
context.Parameters.Add(new ParameterWithValue(key, perfectMatch)
{
var isDone = IsValueDone(context.IsLast, value);
context.Parameters.Add(new ParameterWithValue(key, perfectMatch)
{
Value = !isDone ? null : value,
UsedEqualSign = true
});
if (isDone)
{
return repeat(perfectMatch);
}
if (!context.HasValue)
{
if (valueParameter.Source != null)
{
return valueParameter.Source
.GetItems()
.Where(x => x.Name.Contains(value.RawValue, StringComparison.OrdinalIgnoreCase))
.Select(x => new PredictiveSuggestion(context.Reconstruct(GetFromRawWithPreferredType(value.Type, x.Name)), x.Description));
}
return Enumerable.Empty<PredictiveSuggestion>();
}
Value = !isDone ? null : value,
UsedEqualSign = true
});
if (isDone)
{
return repeat(perfectMatch);
}
else if (context.IsLast)
if (!context.HasValue)
{
context.Parameters.Add(new ParameterWithValue(currentArgument, perfectMatch));
if (valueParameter.Source != null)
{
return valueParameter.Source
.GetItems()
.Select(x => new PredictiveSuggestion(context.Reconstruct(GetFromRawWithPreferredType(currentArgument.Type, x.Name)), x.Description));
return GetPartialSourceMatches(context, valueParameter.Source, value);
}
return Enumerable.Empty<PredictiveSuggestion>();
}
else if (context.HasThreeOrMoreLeft)
}
else if (context.IsLast)
{
context.Parameters.Add(new ParameterWithValue(currentArgument, perfectMatch));
return GetAllSourceMatches(context, currentArgument, valueParameter);
}
else if (context.HasThreeOrMoreLeft)
{
context.Parameters.Add(new ParameterWithValue(currentArgument, perfectMatch)
{
context.Parameters.Add(new ParameterWithValue(currentArgument, perfectMatch)
{
Value = context.NextArgument
});
}
else if (context.IsSecondLast)
Value = context.NextArgument
});
}
else if (context.IsSecondLast)
{
var search = context.NextArgument;
var isDone = IsValueDone(true, search);
context.Parameters.Add(new ParameterWithValue(currentArgument, perfectMatch)
{
var search = context.NextArgument;
var isDone = IsValueDone(true, search);
context.Parameters.Add(new ParameterWithValue(currentArgument, perfectMatch)
{
Value = !isDone ? null : search
});
if (valueParameter.Source != null)
{
return valueParameter.Source
.GetItems()
.Where(x => x.Name.Contains(search.RawValue, StringComparison.OrdinalIgnoreCase))
.Select(x => new PredictiveSuggestion(context.Reconstruct(GetFromRawWithPreferredType(currentArgument.Type, x.Name)), x.Description));
}
}
else
Value = !isDone ? null : search
});
if (valueParameter.Source != null)
{
throw new InvalidOperationException();
//context.Parameters.Add(new ParameterWithValue(currentArgument, perfectMatch));
return GetPartialSourceMatches(context, valueParameter.Source, search);
}
}
else
{
context.Parameters.Add(new ParameterWithValue(currentArgument, perfectMatch));
throw new InvalidOperationException();
//context.Parameters.Add(new ParameterWithValue(currentArgument, perfectMatch));
}
//Check for more matches on same level
return repeat(perfectMatch);
}
else if (context.IsLast)
{
//Check for partial matches
return GetPartialMatches(context, allParameters, currentArgument);
}
else
{
//Failed to find a match add empty to context and try again, skipping this value
context.Parameters.Add(new ParameterWithValue(currentArgument, null));
return Parse(parameters, context, additionalParameters);
context.Parameters.Add(new ParameterWithValue(currentArgument, perfectMatch));
}
//Check for more matches on same level
return repeat(perfectMatch);
}

private bool IsValueDone(bool isLast, PowerShellString value)
private IEnumerable<PredictiveSuggestion> GetAllSourceMatches(DictionaryParsingContext context, PowerShellString currentArgument, ValueParameter valueParameter)
{
return !isLast || value.Type != StringConstantType.BareWord && value.IsEscapedOpened() && value.IsEscapedClosed();
if (valueParameter.Source != null)
{
return valueParameter.Source
.GetItems()
.Select(x => new PredictiveSuggestion(context.Reconstruct(GetFromRawWithPreferredType(currentArgument.Type, x.Name)), x.Description));
}
return Enumerable.Empty<PredictiveSuggestion>();
}

private IEnumerable<PredictiveSuggestion> GetPartialSourceMatches(DictionaryParsingContext context, Source source, PowerShellString value) => source
.GetItems()
.Where(x => x.Name.Contains(value.RawValue, StringComparison.OrdinalIgnoreCase))
.Select(x => new PredictiveSuggestion(context.Reconstruct(GetFromRawWithPreferredType(value.Type, x.Name)), x.Description));
private static bool IsValueDone(bool isLast, PowerShellString value) =>
!isLast || (value.Type != StringConstantType.BareWord && value.IsEscapedOpened() && value.IsEscapedClosed());

private IEnumerable<PredictiveSuggestion> GetPartialMatches(DictionaryParsingContext context, IEnumerable<Parameter> parameters, PowerShellString currentArgument)
{
foreach (var parameter in parameters)
Expand Down
54 changes: 0 additions & 54 deletions PowerType/ExecutionContext.cs

This file was deleted.

3 changes: 2 additions & 1 deletion PowerType/Model/Parameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace PowerType.Model;
public abstract class Parameter
{
public List<string> Keys { get; set; } = null!;
protected virtual bool AllowEmptyKeys => false;
public string Name { get; set; } = null!;
public string? Description { get; set; }
public bool Recursive { get; set; }
Expand All @@ -23,7 +24,7 @@ internal virtual void Initialize(ISystemTime systemTime)

internal virtual void Validate()
{
if (this is not ValueParameter && !HasKeys)
if (!AllowEmptyKeys && !HasKeys)
{
throw new Exception("Parameter must have at least one key");
}
Expand Down
1 change: 1 addition & 0 deletions PowerType/Model/ValueParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace PowerType.Model;

public class ValueParameter : Parameter
{
protected override bool AllowEmptyKeys => true;
public bool RequiresEqualSign { get; set; }
public ParameterType? Type { get; set; }
public Source? Source { get; set; }
Expand Down
4 changes: 4 additions & 0 deletions PowerType/PowerTypePredictor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,18 +143,22 @@ private IEnumerable<PredictiveSuggestion> GetDictrionaryPredictons(PowerShellStr

public void OnCommandLineAccepted(PredictionClient client, IReadOnlyList<string> history)
{
//This input is not needed
}

public void OnCommandLineExecuted(PredictionClient client, string commandLine, bool success)
{
//This input is not needed
}

public void OnSuggestionAccepted(PredictionClient client, uint session, string acceptedSuggestion)
{
//This input is not needed
}

public void OnSuggestionDisplayed(PredictionClient client, uint session, int countOrIndex)
{
//This input is not needed
}

public void Dispose()
Expand Down

0 comments on commit 007d21c

Please sign in to comment.