diff --git a/Engine/Settings/CodeFormatting.psd1 b/Engine/Settings/CodeFormatting.psd1
index c6c94129c..02a07a1da 100644
--- a/Engine/Settings/CodeFormatting.psd1
+++ b/Engine/Settings/CodeFormatting.psd1
@@ -24,6 +24,7 @@
PSUseConsistentIndentation = @{
Enable = $true
+ Kind = 'space'
IndentationSize = 4
}
diff --git a/Engine/Settings/CodeFormattingAllman.psd1 b/Engine/Settings/CodeFormattingAllman.psd1
index bf10dffd8..15b0ecfbd 100644
--- a/Engine/Settings/CodeFormattingAllman.psd1
+++ b/Engine/Settings/CodeFormattingAllman.psd1
@@ -24,6 +24,7 @@
PSUseConsistentIndentation = @{
Enable = $true
+ Kind = 'space'
IndentationSize = 4
}
diff --git a/Engine/Settings/CodeFormattingOTBS.psd1 b/Engine/Settings/CodeFormattingOTBS.psd1
index 2bd6d69d4..589487235 100644
--- a/Engine/Settings/CodeFormattingOTBS.psd1
+++ b/Engine/Settings/CodeFormattingOTBS.psd1
@@ -24,6 +24,7 @@
PSUseConsistentIndentation = @{
Enable = $true
+ Kind = 'space'
IndentationSize = 4
}
diff --git a/Engine/Settings/CodeFormattingStroustrup.psd1 b/Engine/Settings/CodeFormattingStroustrup.psd1
index 8640f6761..51cbb540a 100644
--- a/Engine/Settings/CodeFormattingStroustrup.psd1
+++ b/Engine/Settings/CodeFormattingStroustrup.psd1
@@ -25,6 +25,7 @@
PSUseConsistentIndentation = @{
Enable = $true
+ Kind = 'space'
IndentationSize = 4
}
diff --git a/RuleDocumentation/UseConsistentIndentation.md b/RuleDocumentation/UseConsistentIndentation.md
index f89f7324a..51c32ba18 100644
--- a/RuleDocumentation/UseConsistentIndentation.md
+++ b/RuleDocumentation/UseConsistentIndentation.md
@@ -28,3 +28,10 @@ Enable or disable the rule during ScriptAnalyzer invocation.
#### IndentationSize: bool (Default value is `4`)
Indentation size in the number of space characters.
+
+#### Kind: string (Default value is `space`)
+
+Represents the kind of indentation to be used. Possible values are: `space`, `tab`. If any invalid value is given, the property defaults to `space`.
+
+`space` means `IndentationSize` number of `space` characters are used to provide one level of indentation.
+`tab` means a tab character, `\t`.
diff --git a/Rules/UseConsistentIndentation.cs b/Rules/UseConsistentIndentation.cs
index b7da9c629..58880d021 100644
--- a/Rules/UseConsistentIndentation.cs
+++ b/Rules/UseConsistentIndentation.cs
@@ -36,10 +36,48 @@ public class UseConsistentIndentation : ConfigurableRule
[ConfigurableRuleProperty(defaultValue: 4)]
public int IndentationSize { get; protected set; }
- private enum IndentationKind { Space, Tab };
+
+ // Cannot name to IndentationKind due to the enum type of the same name.
+ ///
+ /// Represents the kind of indentation to be used.
+ ///
+ /// Possible values are: `space`, `tab`. If any invalid value is given, the
+ /// property defaults to `space`.
+ ///
+ /// `space` means `IndentationSize` number of `space` characters are used to provide one level of indentation.
+ /// `tab` means a tab character, `\t`.
+ ///
+ [ConfigurableRuleProperty(defaultValue: "space")]
+ public string Kind
+ {
+ get
+ {
+ return indentationKind.ToString();
+ }
+ set
+ {
+ if (String.IsNullOrWhiteSpace(value) ||
+ !Enum.TryParse(value, true, out indentationKind))
+ {
+ indentationKind = IndentationKind.Space;
+ }
+ }
+ }
+
+ private bool insertSpaces;
+ private char indentationChar;
+ private int indentationLevelMultiplier;
+
+ // TODO Enable auto when the rule is able to detect indentation
+ private enum IndentationKind {
+ Space,
+ Tab,
+ // Auto
+ };
// TODO make this configurable
- private readonly IndentationKind indentationKind = IndentationKind.Space;
+ private IndentationKind indentationKind = IndentationKind.Space;
+
///
/// Analyzes the given ast to find violations.
@@ -61,6 +99,14 @@ public override IEnumerable AnalyzeScript(Ast ast, string file
return Enumerable.Empty();
}
+ // It is more efficient to initialize these fields in ConfigurRule method
+ // but when the rule will enable `Auto` IndentationKind, we will anyways need to move
+ // the setting of these variables back here after the rule detects the indentation kind for
+ // each invocation.
+ insertSpaces = indentationKind == IndentationKind.Space;
+ indentationChar = insertSpaces ? ' ' : '\t';
+ indentationLevelMultiplier = insertSpaces ? IndentationSize : 1;
+
var tokens = Helper.Instance.Tokens;
var diagnosticRecords = new List();
var indentationLevel = 0;
@@ -262,17 +308,13 @@ private int GetIndentationColumnNumber(int indentationLevel)
private int GetIndentation(int indentationLevel)
{
- return indentationLevel * this.IndentationSize;
- }
-
- private char GetIndentationChar()
- {
- return indentationKind == IndentationKind.Space ? ' ' : '\t';
+ // todo if condition can be evaluated during rule configuration
+ return indentationLevel * indentationLevelMultiplier;
}
private string GetIndentationString(int indentationLevel)
{
- return new string(GetIndentationChar(), GetIndentation(indentationLevel));
+ return new string(indentationChar, GetIndentation(indentationLevel));
}
}
}
diff --git a/Tests/Rules/UseConsistentIndentation.tests.ps1 b/Tests/Rules/UseConsistentIndentation.tests.ps1
index 3dd083712..89bb6d3f1 100644
--- a/Tests/Rules/UseConsistentIndentation.tests.ps1
+++ b/Tests/Rules/UseConsistentIndentation.tests.ps1
@@ -6,17 +6,19 @@ Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1")
$indentationUnit = ' '
$indentationSize = 4
+$ruleConfiguration = @{
+ Enable = $true
+ IndentationSize = 4
+ Kind = 'space'
+}
+
$settings = @{
IncludeRules = @("PSUseConsistentIndentation")
- Rules = @{
- PSUseConsistentIndentation = @{
- Enable = $true
- IndentationSize = 4
- }
+ Rules = @{
+ PSUseConsistentIndentation = $ruleConfiguration
}
}
-
Describe "UseConsistentIndentation" {
Context "When top level indentation is not consistent" {
BeforeAll {
@@ -127,8 +129,8 @@ function foo {
get-process |
where-object {$_.Name -match 'powershell'}
'@
- $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings
- $violations.Count | Should Be 1
+ $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings
+ $violations.Count | Should Be 1
}
It "Should not find a violation if a pipleline element is indented correctly" {
@@ -136,8 +138,8 @@ where-object {$_.Name -match 'powershell'}
get-process |
where-object {$_.Name -match 'powershell'}
'@
- $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings
- $violations.Count | Should Be 0
+ $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings
+ $violations.Count | Should Be 0
}
It "Should ignore comment in the pipleline" {
@@ -147,8 +149,8 @@ get-process |
select Name,Id |
format-list
'@
- $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings
- $violations.Count | Should Be 3
+ $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings
+ $violations.Count | Should Be 3
}
It "Should indent properly after line continuation (backtick) character" {
@@ -159,13 +161,46 @@ $x = "this " + `
$violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings
$violations.Count | Should Be 1
$params = @{
- RawContent = $def
+ RawContent = $def
DiagnosticRecord = $violations[0]
CorrectionsCount = 1
- ViolationText = "`"Should be indented properly`""
- CorrectionText = (New-Object -TypeName String -ArgumentList $indentationUnit,$indentationSize) + "`"Should be indented properly`""
+ ViolationText = "`"Should be indented properly`""
+ CorrectionText = (New-Object -TypeName String -ArgumentList $indentationUnit, $indentationSize) + "`"Should be indented properly`""
}
Test-CorrectionExtentFromContent @params
}
}
+
+ Context "When tabs instead of spaces are used for indentation" {
+ BeforeAll {
+ $ruleConfiguration.'Kind' = 'tab'
+ }
+
+ It "Should indent using tabs" {
+ $def = @'
+function foo
+{
+get-childitem
+$x=1+2
+$hashtable = @{
+property1 = "value"
+ anotherProperty = "another value"
+}
+}
+'@
+ ${t} = "`t"
+ $expected = @"
+function foo
+{
+${t}get-childitem
+${t}`$x=1+2
+${t}`$hashtable = @{
+${t}${t}property1 = "value"
+${t}${t}anotherProperty = "another value"
+${t}}
+}
+"@
+ Invoke-Formatter -ScriptDefinition $def -Settings $settings | Should Be $expected
+ }
+ }
}