From 88ce27406e8d3c2c737868fb638c2c12b0829929 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Wed, 21 Nov 2018 20:47:14 +0100 Subject: [PATCH 01/34] Add basic enum basetype tests --- .../Language/Classes/scripting.enums.tests.ps1 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/powershell/Language/Classes/scripting.enums.tests.ps1 b/test/powershell/Language/Classes/scripting.enums.tests.ps1 index 02bb420e1e3..6eff9e80606 100644 --- a/test/powershell/Language/Classes/scripting.enums.tests.ps1 +++ b/test/powershell/Language/Classes/scripting.enums.tests.ps1 @@ -70,6 +70,20 @@ Describe 'enums' -Tags "CI" { It 'E5 has correct value' { [E5]::e0 | Should -Be ([E5]40) } It 'E6 has correct value' { [E6]::e0 | Should -Be ([E6]38) } } + + Context 'Enum with non-default underlying type' { + enum EX0 : byte + { + } + + enum EX1 : System.Int64 + { + } + + It 'EX0 has the specified underlying type' { [Enum]::GetUnderlyingType([EX0]) | Should -Be ([byte]) } + + It 'EX0 has the specified underlying type' { [Enum]::GetUnderlyingType([EX0]) | Should -Be ([long]) } + } } Describe 'Basic enum errors' -Tags "CI" { From 06ff8a3d1e9aa66c65532f4bd3cb5acbc12f6792 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Wed, 21 Nov 2018 20:48:41 +0100 Subject: [PATCH 02/34] Add optional base type to enum parsing rule --- .../engine/parser/Parser.cs | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index a31f64fa0da..bffd1a75f4e 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -4543,6 +4543,29 @@ private StatementAst EnumDefinitionRule(List customAttributes, return new ErrorStatementAst(enumToken.Extent); } + TypeConstraintAst underlyingTypeConstraint = null; + + SetTokenizerMode(TokenizerMode.Signature); + Token colonToken = PeekToken(); + if (colonToken.Kind == TokenKind.Colon) + { + this.SkipToken(); + SkipNewlines(); + ITypeName underlyingType; + Token unused; + underlyingType = this.TypeNameRule(allowAssemblyQualifiedNames: false, firstTypeNameToken: out unused); + if (underlyingType == null) + { + ReportIncompleteInput(After(colonToken), + nameof(ParserStrings.TypeNameExpected), + ParserStrings.TypeNameExpected); + } + else + { + underlyingTypeConstraint = new TypeConstraintAst(underlyingType.Extent, underlyingType); + } + } + SkipNewlines(); Token lCurly = NextToken(); if (lCurly.Kind != TokenKind.LCurly) @@ -4580,7 +4603,7 @@ private StatementAst EnumDefinitionRule(List customAttributes, ? customAttributes[0].Extent : enumToken.Extent; var extent = ExtentOf(startExtent, rCurly); - var enumDefn = new TypeDefinitionAst(extent, name.Value, customAttributes == null ? null : customAttributes.OfType(), members, TypeAttributes.Enum, null); + var enumDefn = new TypeDefinitionAst(extent, name.Value, customAttributes == null ? null : customAttributes.OfType(), members, TypeAttributes.Enum, underlyingTypeConstraint == null ? null : new[] { underlyingTypeConstraint }); if (customAttributes != null && customAttributes.OfType().Any()) { //no need to report error since there is error reported in method StatementRule From e12015800d28a946a57f758b514a54902758668a Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Wed, 21 Nov 2018 20:56:37 +0100 Subject: [PATCH 03/34] WIP: Variable underlying types for enum definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit changes the behavior of the DefineEnumHelper, specifically the way the underlying type of the Enum type is specified. 06ff8a3d makes the parser recognize a base type token, this changes the underlying type of the generated EnumBuilder if the base type token corresponds to a builtin CLS value type as specified in ECMA-335 §I.8.5.2 (CLS Rule 7), otherwise it defaults to [int] TODO: - re-introduce range validation - better parsing errors for invalid underlying types --- .../engine/parser/PSType.cs | 58 +++++++++---------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index 475f0cebbc4..ab057ba1b38 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -950,6 +950,7 @@ private class DefineEnumHelper private readonly TypeDefinitionAst _enumDefinitionAst; private readonly ModuleBuilder _moduleBuilder; private readonly string _typeName; + private readonly Type[] _validBaseTypes = new[] { typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong) }; internal DefineEnumHelper(Parser parser, ModuleBuilder module, TypeDefinitionAst enumDefinitionAst, string typeName) { @@ -1091,10 +1092,20 @@ internal static List Sort(List defineEnumHel internal void DefineEnum() { + var underlyingType = typeof(int); + foreach (var type in _enumDefinitionAst.BaseTypes) + { + underlyingType = type.TypeName.GetReflectionType() ?? typeof(int); + if (!_validBaseTypes.Contains(underlyingType)) + { + throw new TypeInitializationException(underlyingType.FullName, null); + } + } + var definedEnumerators = new HashSet(StringComparer.OrdinalIgnoreCase); - var enumBuilder = _moduleBuilder.DefineEnum(_typeName, Reflection.TypeAttributes.Public, typeof(int)); + var enumBuilder = _moduleBuilder.DefineEnum(_typeName, Reflection.TypeAttributes.Public, underlyingType); DefineCustomAttributes(enumBuilder, _enumDefinitionAst.Attributes, _parser, AttributeTargets.Enum); - int value = 0; + dynamic value = 0; bool valueTooBig = false; foreach (var member in _enumDefinitionAst.Members) { @@ -1104,28 +1115,21 @@ internal void DefineEnum() object constValue; if (IsConstantValueVisitor.IsConstant(enumerator.InitialValue, out constValue, false, false)) { - if (constValue is int) + if (!LanguagePrimitives.TryConvertTo(constValue, underlyingType, out value)) { - value = (int)constValue; - } - else - { - if (!LanguagePrimitives.TryConvertTo(constValue, out value)) + if (constValue != null && + LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constValue.GetType()))) { - if (constValue != null && - LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constValue.GetType()))) - { - _parser.ReportError(enumerator.InitialValue.Extent, - nameof(ParserStrings.EnumeratorValueTooLarge), - ParserStrings.EnumeratorValueTooLarge); - } - else - { - _parser.ReportError(enumerator.InitialValue.Extent, - nameof(ParserStrings.CannotConvertValue), - ParserStrings.CannotConvertValue, - ToStringCodeMethods.Type(typeof(int))); - } + _parser.ReportError(enumerator.InitialValue.Extent, + nameof(ParserStrings.EnumeratorValueTooLarge), + ParserStrings.EnumeratorValueTooLarge); + } + else + { + _parser.ReportError(enumerator.InitialValue.Extent, + nameof(ParserStrings.CannotConvertValue), + ParserStrings.CannotConvertValue, + ToStringCodeMethods.Type(typeof(int))); } } } @@ -1152,17 +1156,9 @@ internal void DefineEnum() } else { + value = Convert.ChangeType(value, underlyingType); definedEnumerators.Add(enumerator.Name); enumBuilder.DefineLiteral(enumerator.Name, value); - if (value < int.MaxValue) - { - value += 1; - valueTooBig = false; - } - else - { - valueTooBig = true; - } } } _enumDefinitionAst.Type = enumBuilder.CreateTypeInfo().AsType(); From f58eba81d585a74cdef8e22807e9f39710e406ea Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Wed, 21 Nov 2018 21:48:15 +0100 Subject: [PATCH 04/34] Add support for Flags() and fix implied member literal values --- src/System.Management.Automation/engine/parser/PSType.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index ab057ba1b38..787e59d462d 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -1160,6 +1160,15 @@ internal void DefineEnum() definedEnumerators.Add(enumerator.Name); enumBuilder.DefineLiteral(enumerator.Name, value); } + + if (_enumDefinitionAst.Attributes.Any(attr => attr.TypeName.GetReflectionType() == typeof(FlagsAttribute)) && value != 0) + { + value *= 2; + } + else + { + value += 1; + } } _enumDefinitionAst.Type = enumBuilder.CreateTypeInfo().AsType(); } From c1bc80d5bbe3e5341638e6d139373e8b68b3f07b Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Wed, 21 Nov 2018 21:52:39 +0100 Subject: [PATCH 05/34] Fix CodeFactor issue (SA1116) --- src/System.Management.Automation/engine/parser/Parser.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index bffd1a75f4e..611c1fcac44 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -4593,7 +4593,8 @@ private StatementAst EnumDefinitionRule(List customAttributes, if (rCurly.Kind != TokenKind.RCurly) { UngetToken(rCurly); - ReportIncompleteInput(After(lCurly), + ReportIncompleteInput( + After(lCurly), rCurly.Extent, nameof(ParserStrings.MissingEndCurlyBrace), ParserStrings.MissingEndCurlyBrace); From f417453b99636bdb1fd10b25d3ea554304d72315 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Wed, 21 Nov 2018 23:00:02 +0100 Subject: [PATCH 06/34] Add type-aware range check for enum member values I'm thinking there must be an easier way of abstracting this away, but I can't think of anything --- .../engine/parser/PSType.cs | 56 ++++++++++++++++++- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index 787e59d462d..f929b02546c 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -1106,6 +1106,8 @@ internal void DefineEnum() var enumBuilder = _moduleBuilder.DefineEnum(_typeName, Reflection.TypeAttributes.Public, underlyingType); DefineCustomAttributes(enumBuilder, _enumDefinitionAst.Attributes, _parser, AttributeTargets.Enum); dynamic value = 0; + ulong maxValue; + GetMaxValue(underlyingType, out maxValue); bool valueTooBig = false; foreach (var member in _enumDefinitionAst.Members) { @@ -1163,15 +1165,65 @@ internal void DefineEnum() if (_enumDefinitionAst.Attributes.Any(attr => attr.TypeName.GetReflectionType() == typeof(FlagsAttribute)) && value != 0) { - value *= 2; + if (Convert.ToUInt64(value) < maxValue / 2) + { + value *= 2; + } + else + { + valueTooBig = true; + } } else { - value += 1; + if (Convert.ToUInt64(value) < maxValue) + { + value += 1; + } + else + { + valueTooBig = true; + } } } _enumDefinitionAst.Type = enumBuilder.CreateTypeInfo().AsType(); } + + private void GetMaxValue(Type underlyingType, out ulong maxValue) + { + if (underlyingType == typeof(byte)) + { + maxValue = Convert .ToUInt64(byte.MaxValue); + } + else if (underlyingType == typeof(sbyte)) + { + maxValue = Convert.ToUInt64(sbyte.MaxValue); + } + else if (underlyingType == typeof(short)) + { + maxValue = Convert.ToUInt64(short.MaxValue); + } + else if (underlyingType == typeof(ushort)) + { + maxValue = Convert.ToUInt64(ushort.MaxValue); + } + else if (underlyingType == typeof(int)) + { + maxValue = Convert.ToUInt64(int.MaxValue); + } + else if (underlyingType == typeof(uint)) + { + maxValue = Convert.ToUInt64(uint.MaxValue); + } + else if (underlyingType == typeof(long)) + { + maxValue = Convert.ToUInt64(long.MaxValue); + } + else + { + maxValue = Convert.ToUInt64(ulong.MaxValue); + } + } } private static IEnumerable GetAssemblyAttributeBuilders(string scriptFile) From 5d1ff8a53066a0ee124edd673b3628055b2b410e Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Wed, 21 Nov 2018 23:41:14 +0100 Subject: [PATCH 07/34] Reset tokenizer mode in EnumDefinitionRule Forgot to reset the tokenizer in a previous commit, causing parsing errors. --- .../engine/parser/Parser.cs | 124 ++++++++++-------- 1 file changed, 66 insertions(+), 58 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 611c1fcac44..1eb903196d0 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -4544,76 +4544,84 @@ private StatementAst EnumDefinitionRule(List customAttributes, } TypeConstraintAst underlyingTypeConstraint = null; - - SetTokenizerMode(TokenizerMode.Signature); - Token colonToken = PeekToken(); - if (colonToken.Kind == TokenKind.Colon) + var oldTokenizerMode = _tokenizer.Mode; + try { - this.SkipToken(); + SetTokenizerMode(TokenizerMode.Signature); + Token colonToken = PeekToken(); + if (colonToken.Kind == TokenKind.Colon) + { + this.SkipToken(); + SkipNewlines(); + ITypeName underlyingType; + Token unused; + underlyingType = this.TypeNameRule(allowAssemblyQualifiedNames: false, firstTypeNameToken: out unused); + if (underlyingType == null) + { + ReportIncompleteInput(After(colonToken), + nameof(ParserStrings.TypeNameExpected), + ParserStrings.TypeNameExpected); + } + else + { + underlyingTypeConstraint = new TypeConstraintAst(underlyingType.Extent, underlyingType); + } + } + SkipNewlines(); - ITypeName underlyingType; - Token unused; - underlyingType = this.TypeNameRule(allowAssemblyQualifiedNames: false, firstTypeNameToken: out unused); - if (underlyingType == null) + Token lCurly = NextToken(); + if (lCurly.Kind != TokenKind.LCurly) { - ReportIncompleteInput(After(colonToken), - nameof(ParserStrings.TypeNameExpected), - ParserStrings.TypeNameExpected); + // ErrorRecovery: If there is no opening curly, assume it hasn't been entered yet and don't consume anything. + + UngetToken(lCurly); + ReportIncompleteInput(After(name), + nameof(ParserStrings.MissingTypeBody), + ParserStrings.MissingTypeBody, + enumToken.Kind.Text()); + return new ErrorStatementAst(ExtentOf(enumToken, name)); } - else + + IScriptExtent lastExtent = lCurly.Extent; + MemberAst member; + List members = new List(); + while ((member = EnumMemberRule()) != null) { - underlyingTypeConstraint = new TypeConstraintAst(underlyingType.Extent, underlyingType); + members.Add(member); + lastExtent = member.Extent; } - } - SkipNewlines(); - Token lCurly = NextToken(); - if (lCurly.Kind != TokenKind.LCurly) - { - // ErrorRecovery: If there is no opening curly, assume it hasn't been entered yet and don't consume anything. + var rCurly = NextToken(); + if (rCurly.Kind != TokenKind.RCurly) + { + UngetToken(rCurly); + ReportIncompleteInput( + After(lCurly), + rCurly.Extent, + nameof(ParserStrings.MissingEndCurlyBrace), + ParserStrings.MissingEndCurlyBrace); + } - UngetToken(lCurly); - ReportIncompleteInput(After(name), - nameof(ParserStrings.MissingTypeBody), - ParserStrings.MissingTypeBody, - enumToken.Kind.Text()); - return new ErrorStatementAst(ExtentOf(enumToken, name)); - } + var startExtent = customAttributes != null && customAttributes.Count > 0 + ? customAttributes[0].Extent + : enumToken.Extent; + var extent = ExtentOf(startExtent, rCurly); + var enumDefn = new TypeDefinitionAst(extent, name.Value, customAttributes == null ? null : customAttributes.OfType(), members, TypeAttributes.Enum, underlyingTypeConstraint == null ? null : new[] { underlyingTypeConstraint }); + if (customAttributes != null && customAttributes.OfType().Any()) + { + //no need to report error since there is error reported in method StatementRule + List nestedAsts = new List(); + nestedAsts.AddRange(customAttributes.OfType()); + nestedAsts.Add(enumDefn); + return new ErrorStatementAst(startExtent, nestedAsts); + } - IScriptExtent lastExtent = lCurly.Extent; - MemberAst member; - List members = new List(); - while ((member = EnumMemberRule()) != null) - { - members.Add(member); - lastExtent = member.Extent; + return enumDefn; } - - var rCurly = NextToken(); - if (rCurly.Kind != TokenKind.RCurly) + finally { - UngetToken(rCurly); - ReportIncompleteInput( - After(lCurly), - rCurly.Extent, - nameof(ParserStrings.MissingEndCurlyBrace), - ParserStrings.MissingEndCurlyBrace); + SetTokenizerMode(oldTokenizerMode); } - - var startExtent = customAttributes != null && customAttributes.Count > 0 - ? customAttributes[0].Extent - : enumToken.Extent; - var extent = ExtentOf(startExtent, rCurly); - var enumDefn = new TypeDefinitionAst(extent, name.Value, customAttributes == null ? null : customAttributes.OfType(), members, TypeAttributes.Enum, underlyingTypeConstraint == null ? null : new[] { underlyingTypeConstraint }); - if (customAttributes != null && customAttributes.OfType().Any()) - { - //no need to report error since there is error reported in method StatementRule - List nestedAsts = new List(); - nestedAsts.AddRange(customAttributes.OfType()); - nestedAsts.Add(enumDefn); - return new ErrorStatementAst(startExtent, nestedAsts); - } - return enumDefn; } private MemberAst EnumMemberRule() From fc5a608f3483941f82d1a817cbde1eead3c18a77 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Wed, 21 Nov 2018 23:42:43 +0100 Subject: [PATCH 08/34] Update error strings, add null check for Enum member values --- .../engine/parser/PSType.cs | 15 ++++++++++----- .../resources/ParserStrings.resx | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index f929b02546c..a2257e4de62 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -1124,14 +1124,15 @@ internal void DefineEnum() { _parser.ReportError(enumerator.InitialValue.Extent, nameof(ParserStrings.EnumeratorValueTooLarge), - ParserStrings.EnumeratorValueTooLarge); + ParserStrings.EnumeratorValueTooLarge, + ToStringCodeMethods.Type(underlyingType)); } else { _parser.ReportError(enumerator.InitialValue.Extent, nameof(ParserStrings.CannotConvertValue), ParserStrings.CannotConvertValue, - ToStringCodeMethods.Type(typeof(int))); + ToStringCodeMethods.Type(underlyingType)); } } } @@ -1141,12 +1142,16 @@ internal void DefineEnum() nameof(ParserStrings.EnumeratorValueMustBeConstant), ParserStrings.EnumeratorValueMustBeConstant); } + + valueTooBig = Convert.ToUInt64(value) >= maxValue; } - else if (valueTooBig) + + if (valueTooBig) { _parser.ReportError(enumerator.Extent, nameof(ParserStrings.EnumeratorValueTooLarge), - ParserStrings.EnumeratorValueTooLarge); + ParserStrings.EnumeratorValueTooLarge, + ToStringCodeMethods.Type(underlyingType)); } if (definedEnumerators.Contains(enumerator.Name)) @@ -1156,7 +1161,7 @@ internal void DefineEnum() ParserStrings.MemberAlreadyDefined, enumerator.Name); } - else + else if(value != null) { value = Convert.ChangeType(value, underlyingType); definedEnumerators.Add(enumerator.Name); diff --git a/src/System.Management.Automation/resources/ParserStrings.resx b/src/System.Management.Automation/resources/ParserStrings.resx index 6cd368daffd..7ef9911550e 100644 --- a/src/System.Management.Automation/resources/ParserStrings.resx +++ b/src/System.Management.Automation/resources/ParserStrings.resx @@ -1290,7 +1290,7 @@ ModuleVersion : Version of module to import. If used, ModuleName must represent Cannot define enum because of a cycle in the initialization expressions. - Enumerator value is too large for a System.Int. + Enumerator value is too large for {0}. Enumerator value must be a constant value. From 48ac5b3b873304dbf984e218bcb849a90ec029c0 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Wed, 21 Nov 2018 23:49:48 +0100 Subject: [PATCH 09/34] Fix CodeFactor issue (SA1000, SA1019) --- src/System.Management.Automation/engine/parser/PSType.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index a2257e4de62..1681cd936a4 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -1161,7 +1161,7 @@ internal void DefineEnum() ParserStrings.MemberAlreadyDefined, enumerator.Name); } - else if(value != null) + else if (value != null) { value = Convert.ChangeType(value, underlyingType); definedEnumerators.Add(enumerator.Name); @@ -1198,7 +1198,7 @@ private void GetMaxValue(Type underlyingType, out ulong maxValue) { if (underlyingType == typeof(byte)) { - maxValue = Convert .ToUInt64(byte.MaxValue); + maxValue = Convert.ToUInt64(byte.MaxValue); } else if (underlyingType == typeof(sbyte)) { From 55ee223672ac1673bc7005377a5ef6d229d3bfdf Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Thu, 22 Nov 2018 00:20:21 +0100 Subject: [PATCH 10/34] Fix valueTooBig test (off-by-one) in DefineEnum() --- src/System.Management.Automation/engine/parser/PSType.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index 1681cd936a4..3e901470483 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -1143,7 +1143,7 @@ internal void DefineEnum() ParserStrings.EnumeratorValueMustBeConstant); } - valueTooBig = Convert.ToUInt64(value) >= maxValue; + valueTooBig = Convert.ToUInt64(value) > maxValue; } if (valueTooBig) From 661e7c7c8bb588ce49c982577ec3eca013b0564f Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Thu, 22 Nov 2018 00:26:47 +0100 Subject: [PATCH 11/34] Fix type names in enum test --- test/powershell/Language/Classes/scripting.enums.tests.ps1 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/powershell/Language/Classes/scripting.enums.tests.ps1 b/test/powershell/Language/Classes/scripting.enums.tests.ps1 index 6eff9e80606..7a3bccda3a3 100644 --- a/test/powershell/Language/Classes/scripting.enums.tests.ps1 +++ b/test/powershell/Language/Classes/scripting.enums.tests.ps1 @@ -81,8 +81,7 @@ Describe 'enums' -Tags "CI" { } It 'EX0 has the specified underlying type' { [Enum]::GetUnderlyingType([EX0]) | Should -Be ([byte]) } - - It 'EX0 has the specified underlying type' { [Enum]::GetUnderlyingType([EX0]) | Should -Be ([long]) } + It 'EX1 has the specified underlying type' { [Enum]::GetUnderlyingType([EX1]) | Should -Be ([long]) } } } From 84edbf9a505500a2586e6cab2bca4328fb14eea9 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Thu, 22 Nov 2018 01:13:35 +0100 Subject: [PATCH 12/34] Add more enum tests Added new context for testing behavior when Flags() is applied. Increased test coverage for all underlying types, added type constraint test --- .../Classes/scripting.enums.tests.ps1 | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/test/powershell/Language/Classes/scripting.enums.tests.ps1 b/test/powershell/Language/Classes/scripting.enums.tests.ps1 index 7a3bccda3a3..3f2e1aedd7b 100644 --- a/test/powershell/Language/Classes/scripting.enums.tests.ps1 +++ b/test/powershell/Language/Classes/scripting.enums.tests.ps1 @@ -72,16 +72,35 @@ Describe 'enums' -Tags "CI" { } Context 'Enum with non-default underlying type' { - enum EX0 : byte - { - } + enum EX1 : byte { A;B;C;D } + enum EX2 : sbyte { A;B;C;D } + enum EX3 : short { A;B;C;D } + enum EX4 : ushort { A;B;C;D } + enum EX5 : int { A;B;C;D } + enum EX6 : uint { A;B;C;D } + enum EX7 : long { A;B;C;D } + enum EX8 : ulong { A;B;C;D } - enum EX1 : System.Int64 - { - } + It 'EX1 has the specified underlying type' { [Enum]::GetUnderlyingType([EX1]) | Should -Be ([byte]) } + It 'EX2 has the specified underlying type' { [Enum]::GetUnderlyingType([EX2]) | Should -Be ([sbyte]) } + It 'EX3 has the specified underlying type' { [Enum]::GetUnderlyingType([EX3]) | Should -Be ([short]) } + It 'EX4 has the specified underlying type' { [Enum]::GetUnderlyingType([EX4]) | Should -Be ([ushort]) } + It 'EX5 has the specified underlying type' { [Enum]::GetUnderlyingType([EX5]) | Should -Be ([int]) } + It 'EX6 has the specified underlying type' { [Enum]::GetUnderlyingType([EX6]) | Should -Be ([uint]) } + It 'EX7 has the specified underlying type' { [Enum]::GetUnderlyingType([EX7]) | Should -Be ([long]) } + It 'EX8 has the specified underlying type' { [Enum]::GetUnderlyingType([EX8]) | Should -Be ([ulong]) } + } + + Context 'Enum with FlagsAttribute' { + [Flags()] + enum BitMask { A;B;C;D } - It 'EX0 has the specified underlying type' { [Enum]::GetUnderlyingType([EX0]) | Should -Be ([byte]) } - It 'EX1 has the specified underlying type' { [Enum]::GetUnderlyingType([EX1]) | Should -Be ([long]) } + It 'Consecutive member values double when FlagsAttribute is present' { + [BitMask]::A.value__ | Should -Be 0 + [BitMask]::B.value__ | Should -Be 1 + [BitMask]::C.value__ | Should -Be 2 + [BitMask]::D.value__ | Should -Be 4 + } } } @@ -100,4 +119,5 @@ Describe 'Basic enum errors' -Tags "CI" { ShouldBeParseError 'enum foo { e = $foo }' EnumeratorValueMustBeConstant 15 -SkipAndCheckRuntimeError ShouldBeParseError 'enum foo { e = "hello" }' CannotConvertValue 15 -SkipAndCheckRuntimeError ShouldBeParseError 'enum foo { a;b;c;' MissingEndCurlyBrace 10 + ShouldBeParseError 'enum foo : string { a }' IntegralTypeExpected 11 -SkipAndCheckRuntimeError } From d4486d8fc1d0ef49294a3972ad966bd97b485787 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Thu, 22 Nov 2018 01:16:21 +0100 Subject: [PATCH 13/34] Better error handling + parser errors for invalid enum underlying type enums can only be based off builtin integral types, parser should report an error if any other kind of type name is passed in --- .../engine/parser/PSType.cs | 13 ++++++++++--- .../resources/ParserStrings.resx | 3 +++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index 3e901470483..38458673051 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -1095,10 +1095,17 @@ internal void DefineEnum() var underlyingType = typeof(int); foreach (var type in _enumDefinitionAst.BaseTypes) { - underlyingType = type.TypeName.GetReflectionType() ?? typeof(int); - if (!_validBaseTypes.Contains(underlyingType)) + var resolvedType = type.TypeName.GetReflectionType(); + if (resolvedType == null || !_validBaseTypes.Contains(resolvedType)) { - throw new TypeInitializationException(underlyingType.FullName, null); + _parser.ReportError(type.Extent, + nameof(ParserStrings.IntegralTypeExpected), + ParserStrings.IntegralTypeExpected, + ToStringCodeMethods.Type(resolvedType)); + } + else + { + underlyingType = resolvedType; } } diff --git a/src/System.Management.Automation/resources/ParserStrings.resx b/src/System.Management.Automation/resources/ParserStrings.resx index 7ef9911550e..d1caef119cc 100644 --- a/src/System.Management.Automation/resources/ParserStrings.resx +++ b/src/System.Management.Automation/resources/ParserStrings.resx @@ -1316,6 +1316,9 @@ ModuleVersion : Version of module to import. If used, ModuleName must represent Type name expected. + + '{0}' is not a valid integral type (one of byte, sbyte, short, ushort, int, uint, long or ulong) + '{0}': Interface name expected. From b0371baacf0ae19ac7d7a9de6a7ddbdfe901e67f Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 22 Nov 2018 13:29:53 +0100 Subject: [PATCH 14/34] Optimize counter branch when defining enum member values Co-Authored-By: IISResetMe --- src/System.Management.Automation/engine/parser/PSType.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index 38458673051..fcc68ce866b 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -1175,7 +1175,7 @@ internal void DefineEnum() enumBuilder.DefineLiteral(enumerator.Name, value); } - if (_enumDefinitionAst.Attributes.Any(attr => attr.TypeName.GetReflectionType() == typeof(FlagsAttribute)) && value != 0) + if (value != 0 && _enumDefinitionAst.Attributes.Any(attr => attr.TypeName.GetReflectionType() == typeof(FlagsAttribute))) { if (Convert.ToUInt64(value) < maxValue / 2) { From dd6eee9e9b27bae3317ee31abae4c1cc4630cac8 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Thu, 22 Nov 2018 13:49:21 +0100 Subject: [PATCH 15/34] Add enum type constraint check to parser Given that valid enum underlying types are all resolvable at parse-time (and unlikely to change), we might as well have the Parser error when an invalid underlying type is passed in as a type constraint. --- .../engine/parser/PSType.cs | 8 ++++---- .../engine/parser/Parser.cs | 10 ++++++++++ .../resources/ParserStrings.resx | 4 ++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index 38458673051..1db30cbb263 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -950,7 +950,7 @@ private class DefineEnumHelper private readonly TypeDefinitionAst _enumDefinitionAst; private readonly ModuleBuilder _moduleBuilder; private readonly string _typeName; - private readonly Type[] _validBaseTypes = new[] { typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong) }; + private static readonly Type[] s_validBaseTypes = new[] { typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong) }; internal DefineEnumHelper(Parser parser, ModuleBuilder module, TypeDefinitionAst enumDefinitionAst, string typeName) { @@ -1096,11 +1096,11 @@ internal void DefineEnum() foreach (var type in _enumDefinitionAst.BaseTypes) { var resolvedType = type.TypeName.GetReflectionType(); - if (resolvedType == null || !_validBaseTypes.Contains(resolvedType)) + if (resolvedType == null || !s_validBaseTypes.Contains(resolvedType)) { _parser.ReportError(type.Extent, - nameof(ParserStrings.IntegralTypeExpected), - ParserStrings.IntegralTypeExpected, + nameof(ParserStrings.InvalidUnderlyingType), + ParserStrings.InvalidUnderlyingType, ToStringCodeMethods.Type(resolvedType)); } else diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 1eb903196d0..40760a54b36 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -4532,6 +4532,8 @@ private StatementAst EnumDefinitionRule(List customAttributes, //G enum-member new-lines:opt //G enum-member-list enum-member + Type[] validBaseTypes = new[] { typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong) }; + SkipNewlines(); var name = SimpleNameRule(); if (name == null) @@ -4564,6 +4566,14 @@ private StatementAst EnumDefinitionRule(List customAttributes, } else { + var resolvedType = underlyingType.GetReflectionType(); + if (resolvedType == null || !validBaseTypes.Contains(resolvedType)) + { + ReportError(underlyingType.Extent, + nameof(ParserStrings.InvalidUnderlyingType), + ParserStrings.InvalidUnderlyingType, + underlyingType.Name); + } underlyingTypeConstraint = new TypeConstraintAst(underlyingType.Extent, underlyingType); } } diff --git a/src/System.Management.Automation/resources/ParserStrings.resx b/src/System.Management.Automation/resources/ParserStrings.resx index d1caef119cc..2d47a0f1514 100644 --- a/src/System.Management.Automation/resources/ParserStrings.resx +++ b/src/System.Management.Automation/resources/ParserStrings.resx @@ -1316,8 +1316,8 @@ ModuleVersion : Version of module to import. If used, ModuleName must represent Type name expected. - - '{0}' is not a valid integral type (one of byte, sbyte, short, ushort, int, uint, long or ulong) + + '{0}' is not a valid underlying type for enums. Expected a builtin integral type (one of byte, sbyte, short, ushort, int, uint, long or ulong) '{0}': Interface name expected. From 1c767a9ce7a2398ab2fb7ec1dfd825f8d3c4e81f Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Thu, 22 Nov 2018 13:57:13 +0100 Subject: [PATCH 16/34] Update enum type constraint test ErrorId updated in @548b6cd3 --- test/powershell/Language/Classes/scripting.enums.tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/powershell/Language/Classes/scripting.enums.tests.ps1 b/test/powershell/Language/Classes/scripting.enums.tests.ps1 index 3f2e1aedd7b..8f9d238b80e 100644 --- a/test/powershell/Language/Classes/scripting.enums.tests.ps1 +++ b/test/powershell/Language/Classes/scripting.enums.tests.ps1 @@ -119,5 +119,5 @@ Describe 'Basic enum errors' -Tags "CI" { ShouldBeParseError 'enum foo { e = $foo }' EnumeratorValueMustBeConstant 15 -SkipAndCheckRuntimeError ShouldBeParseError 'enum foo { e = "hello" }' CannotConvertValue 15 -SkipAndCheckRuntimeError ShouldBeParseError 'enum foo { a;b;c;' MissingEndCurlyBrace 10 - ShouldBeParseError 'enum foo : string { a }' IntegralTypeExpected 11 -SkipAndCheckRuntimeError + ShouldBeParseError 'enum foo : string { a }' InvalidUnderlyingType 11 -SkipAndCheckRuntimeError } From c43da74aea81caee0e2df4d0cfc4e02d347ae2ec Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Thu, 22 Nov 2018 14:45:27 +0100 Subject: [PATCH 17/34] Remove redundant enum type check from PSType --- .../engine/parser/PSType.cs | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index 10bc9c223d7..fb2f232352f 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -950,7 +950,6 @@ private class DefineEnumHelper private readonly TypeDefinitionAst _enumDefinitionAst; private readonly ModuleBuilder _moduleBuilder; private readonly string _typeName; - private static readonly Type[] s_validBaseTypes = new[] { typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong) }; internal DefineEnumHelper(Parser parser, ModuleBuilder module, TypeDefinitionAst enumDefinitionAst, string typeName) { @@ -1092,22 +1091,7 @@ internal static List Sort(List defineEnumHel internal void DefineEnum() { - var underlyingType = typeof(int); - foreach (var type in _enumDefinitionAst.BaseTypes) - { - var resolvedType = type.TypeName.GetReflectionType(); - if (resolvedType == null || !s_validBaseTypes.Contains(resolvedType)) - { - _parser.ReportError(type.Extent, - nameof(ParserStrings.InvalidUnderlyingType), - ParserStrings.InvalidUnderlyingType, - ToStringCodeMethods.Type(resolvedType)); - } - else - { - underlyingType = resolvedType; - } - } + var underlyingType = _enumDefinitionAst.BaseTypes.Count() == 0 ? typeof(int) : _enumDefinitionAst.BaseTypes[0].TypeName.GetReflectionType(); var definedEnumerators = new HashSet(StringComparer.OrdinalIgnoreCase); var enumBuilder = _moduleBuilder.DefineEnum(_typeName, Reflection.TypeAttributes.Public, underlyingType); From 19b277054a16139678b64f277e5dd95530638add Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Thu, 22 Nov 2018 22:47:47 +0100 Subject: [PATCH 18/34] Clean up DefineEnum() Since (any valid) input value and maxValue are bound to be of the same type, we may as well mark maxValue dynamic as well - they will be comparable at runtime, and this avoids incorrectly erring when the user specifies a negative integer value for a member --- .../engine/parser/PSType.cs | 47 +++---------------- 1 file changed, 6 insertions(+), 41 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index fb2f232352f..fb265659607 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -1096,10 +1096,11 @@ internal void DefineEnum() var definedEnumerators = new HashSet(StringComparer.OrdinalIgnoreCase); var enumBuilder = _moduleBuilder.DefineEnum(_typeName, Reflection.TypeAttributes.Public, underlyingType); DefineCustomAttributes(enumBuilder, _enumDefinitionAst.Attributes, _parser, AttributeTargets.Enum); + dynamic value = 0; - ulong maxValue; - GetMaxValue(underlyingType, out maxValue); + dynamic maxValue = underlyingType.GetField("MaxValue",BindingFlags.Public | BindingFlags.Static | BindingFlags.GetField).GetValue(null); bool valueTooBig = false; + foreach (var member in _enumDefinitionAst.Members) { var enumerator = (PropertyMemberAst)member; @@ -1134,7 +1135,7 @@ internal void DefineEnum() ParserStrings.EnumeratorValueMustBeConstant); } - valueTooBig = Convert.ToUInt64(value) > maxValue; + valueTooBig = value > maxValue; } if (valueTooBig) @@ -1161,7 +1162,7 @@ internal void DefineEnum() if (value != 0 && _enumDefinitionAst.Attributes.Any(attr => attr.TypeName.GetReflectionType() == typeof(FlagsAttribute))) { - if (Convert.ToUInt64(value) < maxValue / 2) + if (value < maxValue / 2) { value *= 2; } @@ -1172,7 +1173,7 @@ internal void DefineEnum() } else { - if (Convert.ToUInt64(value) < maxValue) + if (value < maxValue) { value += 1; } @@ -1184,42 +1185,6 @@ internal void DefineEnum() } _enumDefinitionAst.Type = enumBuilder.CreateTypeInfo().AsType(); } - - private void GetMaxValue(Type underlyingType, out ulong maxValue) - { - if (underlyingType == typeof(byte)) - { - maxValue = Convert.ToUInt64(byte.MaxValue); - } - else if (underlyingType == typeof(sbyte)) - { - maxValue = Convert.ToUInt64(sbyte.MaxValue); - } - else if (underlyingType == typeof(short)) - { - maxValue = Convert.ToUInt64(short.MaxValue); - } - else if (underlyingType == typeof(ushort)) - { - maxValue = Convert.ToUInt64(ushort.MaxValue); - } - else if (underlyingType == typeof(int)) - { - maxValue = Convert.ToUInt64(int.MaxValue); - } - else if (underlyingType == typeof(uint)) - { - maxValue = Convert.ToUInt64(uint.MaxValue); - } - else if (underlyingType == typeof(long)) - { - maxValue = Convert.ToUInt64(long.MaxValue); - } - else - { - maxValue = Convert.ToUInt64(ulong.MaxValue); - } - } } private static IEnumerable GetAssemblyAttributeBuilders(string scriptFile) From d7a90a2959c1a1abfd205dd271fc41e5f3d8eaf1 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Thu, 22 Nov 2018 22:53:00 +0100 Subject: [PATCH 19/34] Fix CodeFactor issues (SA1116, SA1001) --- src/System.Management.Automation/engine/parser/PSType.cs | 2 +- src/System.Management.Automation/engine/parser/Parser.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index fb265659607..ebc9f7b6b19 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -1098,7 +1098,7 @@ internal void DefineEnum() DefineCustomAttributes(enumBuilder, _enumDefinitionAst.Attributes, _parser, AttributeTargets.Enum); dynamic value = 0; - dynamic maxValue = underlyingType.GetField("MaxValue",BindingFlags.Public | BindingFlags.Static | BindingFlags.GetField).GetValue(null); + dynamic maxValue = underlyingType.GetField("MaxValue", BindingFlags.Public | BindingFlags.Static | BindingFlags.GetField).GetValue(null); bool valueTooBig = false; foreach (var member in _enumDefinitionAst.Members) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 40760a54b36..1f9f5837fe0 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -4585,7 +4585,8 @@ private StatementAst EnumDefinitionRule(List customAttributes, // ErrorRecovery: If there is no opening curly, assume it hasn't been entered yet and don't consume anything. UngetToken(lCurly); - ReportIncompleteInput(After(name), + ReportIncompleteInput( + After(name), nameof(ParserStrings.MissingTypeBody), ParserStrings.MissingTypeBody, enumToken.Kind.Text()); From ba4ccacbbb6ad2b3a51b4c86858a0efb60e25645 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Fri, 23 Nov 2018 23:10:45 +0100 Subject: [PATCH 20/34] Add enum negative value tests --- .../Language/Classes/scripting.enums.tests.ps1 | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/powershell/Language/Classes/scripting.enums.tests.ps1 b/test/powershell/Language/Classes/scripting.enums.tests.ps1 index 8f9d238b80e..940af0bed5c 100644 --- a/test/powershell/Language/Classes/scripting.enums.tests.ps1 +++ b/test/powershell/Language/Classes/scripting.enums.tests.ps1 @@ -102,6 +102,18 @@ Describe 'enums' -Tags "CI" { [BitMask]::D.value__ | Should -Be 4 } } + + Context 'Enum with negative user-specified values' { + enum V1 { + A = -4 + B + } + + It 'Negative values are correctly assigned to members' { + [V1]::A.value__ | Should -Be -4 + [V1]::B.value__ | Should -Be -3 + } + } } Describe 'Basic enum errors' -Tags "CI" { From 46c654af81cfc6a694f88afe3004f577a2170147 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Fri, 23 Nov 2018 23:12:22 +0100 Subject: [PATCH 21/34] Refactor enum underlying type check --- .../engine/parser/PSType.cs | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index ebc9f7b6b19..5773467349d 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -1091,14 +1091,50 @@ internal static List Sort(List defineEnumHel internal void DefineEnum() { - var underlyingType = _enumDefinitionAst.BaseTypes.Count() == 0 ? typeof(int) : _enumDefinitionAst.BaseTypes[0].TypeName.GetReflectionType(); + var typeConstraintAst = _enumDefinitionAst.BaseTypes.FirstOrDefault(); + var underlyingType = typeConstraintAst == null ? typeof(int) : typeConstraintAst.TypeName.GetReflectionType(); var definedEnumerators = new HashSet(StringComparer.OrdinalIgnoreCase); var enumBuilder = _moduleBuilder.DefineEnum(_typeName, Reflection.TypeAttributes.Public, underlyingType); DefineCustomAttributes(enumBuilder, _enumDefinitionAst.Attributes, _parser, AttributeTargets.Enum); dynamic value = 0; - dynamic maxValue = underlyingType.GetField("MaxValue", BindingFlags.Public | BindingFlags.Static | BindingFlags.GetField).GetValue(null); + dynamic maxValue = 0; + switch (Type.GetTypeCode(underlyingType)) + { + case TypeCode.Byte: + maxValue = byte.MaxValue; + break; + case TypeCode.Int16: + maxValue = short.MaxValue; + break; + case TypeCode.Int32: + maxValue = int.MaxValue; + break; + case TypeCode.Int64: + maxValue = long.MaxValue; + break; + case TypeCode.SByte: + maxValue = sbyte.MaxValue; + break; + case TypeCode.UInt16: + maxValue = UInt16.MaxValue; + break; + case TypeCode.UInt32: + maxValue = UInt32.MaxValue; + break; + case TypeCode.UInt64: + maxValue = ulong.MaxValue; + break; + default: + _parser.ReportError( + typeConstraintAst.Extent, + nameof(ParserStrings.InvalidUnderlyingType), + ParserStrings.InvalidUnderlyingType, + underlyingType); + break; + } + bool valueTooBig = false; foreach (var member in _enumDefinitionAst.Members) From c6b29518cb72e92110c74b32a477aa6398b309e2 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Fri, 23 Nov 2018 23:25:59 +0100 Subject: [PATCH 22/34] Change enum type parser check to TypeCode --- src/System.Management.Automation/engine/parser/Parser.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 1f9f5837fe0..c1dd570387a 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -4532,7 +4532,7 @@ private StatementAst EnumDefinitionRule(List customAttributes, //G enum-member new-lines:opt //G enum-member-list enum-member - Type[] validBaseTypes = new[] { typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong) }; + TypeCode validUnderlyingTypeCodes = TypeCode.Byte | TypeCode.Int16 | TypeCode.Int32 | TypeCode.Int64 | TypeCode.SByte | TypeCode.UInt16 | TypeCode.UInt32 | TypeCode.UInt64; SkipNewlines(); var name = SimpleNameRule(); @@ -4567,7 +4567,7 @@ private StatementAst EnumDefinitionRule(List customAttributes, else { var resolvedType = underlyingType.GetReflectionType(); - if (resolvedType == null || !validBaseTypes.Contains(resolvedType)) + if (resolvedType == null || !validUnderlyingTypeCodes.HasFlag(resolvedType.GetTypeCode())) { ReportError(underlyingType.Extent, nameof(ParserStrings.InvalidUnderlyingType), From 434bbab6bef1862ea125aad97f3eeeba37000657 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Fri, 23 Nov 2018 23:45:20 +0100 Subject: [PATCH 23/34] Fix ReportError()/ReportIncompleteInput() argument alignment in Parser --- .../engine/parser/Parser.cs | 561 ++++++++++++------ 1 file changed, 368 insertions(+), 193 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index c1dd570387a..0a6a72e7180 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -212,7 +212,8 @@ private ScriptBlockAst ParseTask(string fileName, string input, List toke } else { - ReportError(_tokenizer.CurrentExtent(), + ReportError( + _tokenizer.CurrentExtent(), nameof(ParserStrings.ScriptTooComplicated), ParserStrings.ScriptTooComplicated); } @@ -561,7 +562,8 @@ internal void RequireStatementTerminator() } else if (terminatorToken.Kind != TokenKind.EndOfInput) { - ReportIncompleteInput(terminatorToken.Extent, + ReportIncompleteInput( + terminatorToken.Extent, nameof(ParserStrings.MissingStatementTerminator), ParserStrings.MissingStatementTerminator); } @@ -867,7 +869,8 @@ private ParamBlockAst ParamBlockRule() UngetToken(rParen); endExtent = Before(rParen); - ReportIncompleteInput(After(parameters != null && parameters.Any() ? parameters.Last().Extent : lparen.Extent), + ReportIncompleteInput( + After(parameters != null && parameters.Any() ? parameters.Last().Extent : lparen.Extent), nameof(ParserStrings.MissingEndParenthesisInFunctionParameterList), ParserStrings.MissingEndParenthesisInFunctionParameterList); } @@ -887,7 +890,8 @@ private ParamBlockAst ParamBlockRule() // ErrorRecovery: nothing to do, this is a semantic error that is caught in the parser // because the ast only allows attributes, no type constraints. - ReportError(attr.Extent, + ReportError( + attr.Extent, nameof(ParserStrings.TypeNotAllowedBeforeParam), ParserStrings.TypeNotAllowedBeforeParam, attr.TypeName.FullName); @@ -915,7 +919,8 @@ private List ParameterListRule() { // ErrorRecovery: ?? - ReportIncompleteInput(After(commaToken), + ReportIncompleteInput( + After(commaToken), nameof(ParserStrings.MissingExpressionAfterToken), ParserStrings.MissingExpressionAfterToken, commaToken.Kind.Text()); @@ -964,7 +969,8 @@ private ParameterAst ParameterRule() { // ErrorRecovery: skip to closing paren because returning null signals the last parameter. - ReportIncompleteInput(After(attributes.Last()), + ReportIncompleteInput( + After(attributes.Last()), nameof(ParserStrings.InvalidFunctionParameter), ParserStrings.InvalidFunctionParameter); SyncOnError(true, TokenKind.RParen); @@ -988,7 +994,8 @@ private ParameterAst ParameterRule() defaultValue = ExpressionRule(); if (defaultValue == null) { - ReportIncompleteInput(After(equalsToken), + ReportIncompleteInput( + After(equalsToken), nameof(ParserStrings.MissingExpressionAfterToken), ParserStrings.MissingExpressionAfterToken, equalsToken.Kind.Text()); @@ -1055,7 +1062,8 @@ private AttributeBaseAst AttributeRule() // ErrorRecovery: Return null so we stop looking for attributes. Resync(lBracket); // TypeNameRule might have consumed some tokens - ReportIncompleteInput(After(lBracket), + ReportIncompleteInput( + After(lBracket), nameof(ParserStrings.MissingTypename), ParserStrings.MissingTypename); return null; @@ -1089,7 +1097,8 @@ private AttributeBaseAst AttributeRule() UngetToken(rParen); rParen = null; - ReportIncompleteInput(After(lastItemExtent), + ReportIncompleteInput( + After(lastItemExtent), nameof(ParserStrings.MissingEndParenthesisInExpression), ParserStrings.MissingEndParenthesisInExpression); } @@ -1104,7 +1113,8 @@ private AttributeBaseAst AttributeRule() // Don't bother reporting a missing ']' if we reported a missing ')'. if (rParen != null) { - ReportIncompleteInput(After(rParen), + ReportIncompleteInput( + After(rParen), nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); } @@ -1124,7 +1134,8 @@ private AttributeBaseAst AttributeRule() if (lParenOrRBracket.Kind != TokenKind.RBracket) { UngetToken(lParenOrRBracket); - ReportError(Before(lParenOrRBracket), + ReportError( + Before(lParenOrRBracket), nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); lParenOrRBracket = null; @@ -1173,7 +1184,8 @@ private void AttributeArgumentsRule(ICollection positionalArgumen // ErrorRecovery: ? IScriptExtent errorPosition = After(token); - ReportIncompleteInput(errorPosition, + ReportIncompleteInput( + errorPosition, nameof(ParserStrings.MissingExpressionInNamedArgument), ParserStrings.MissingExpressionInNamedArgument); expr = new ErrorExpressionAst(errorPosition); @@ -1201,7 +1213,8 @@ private void AttributeArgumentsRule(ICollection positionalArgumen { // ErrorRecovery: this is a semantic error, so just keep parsing. - ReportError(name.Extent, + ReportError( + name.Extent, nameof(ParserStrings.DuplicateNamedArgument), ParserStrings.DuplicateNamedArgument, name.Value); @@ -1222,7 +1235,8 @@ private void AttributeArgumentsRule(ICollection positionalArgumen // ErrorRecovery: Pretend we saw the argument and keep going. IScriptExtent errorExtent = After(commaToken); - ReportIncompleteInput(errorExtent, + ReportIncompleteInput( + errorExtent, nameof(ParserStrings.MissingExpressionAfterToken), ParserStrings.MissingExpressionAfterToken, commaToken.Kind.Text()); @@ -1337,7 +1351,8 @@ private ITypeName FinishTypeNameRule(Token typeName, bool unBracketedGenericArg if (token.Kind != TokenKind.EndOfInput) { - ReportError(token.Extent, + ReportError( + token.Extent, nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, token.Text); @@ -1346,7 +1361,8 @@ private ITypeName FinishTypeNameRule(Token typeName, bool unBracketedGenericArg else { UngetToken(token); - ReportIncompleteInput(After(lbracket), + ReportIncompleteInput( + After(lbracket), nameof(ParserStrings.MissingTypename), ParserStrings.MissingTypename); } @@ -1360,7 +1376,8 @@ private ITypeName FinishTypeNameRule(Token typeName, bool unBracketedGenericArg string assemblyNameSpec = _tokenizer.GetAssemblyNameSpec(); if (string.IsNullOrWhiteSpace(assemblyNameSpec)) { - ReportError(After(token), + ReportError( + After(token), nameof(ParserStrings.MissingAssemblyNameSpecification), ParserStrings.MissingAssemblyNameSpecification); return new TypeName(typeName.Extent, typeName.Text); @@ -1384,7 +1401,8 @@ private ITypeName GetSingleGenericArgument(Token firstToken) if (token.Kind != TokenKind.Identifier) { UngetToken(token); - ReportIncompleteInput(After(token), + ReportIncompleteInput( + After(token), nameof(ParserStrings.MissingTypename), ParserStrings.MissingTypename); return new TypeName(firstToken.Extent, ":ErrorTypeName:"); @@ -1399,7 +1417,8 @@ private ITypeName GetSingleGenericArgument(Token firstToken) // ErrorRecovery: pretend we saw the closing bracket. UngetToken(rBracket); - ReportIncompleteInput(Before(rBracket), + ReportIncompleteInput( + Before(rBracket), nameof(ParserStrings.EndSquareBracketExpectedAtEndOfType), ParserStrings.EndSquareBracketExpectedAtEndOfType); } @@ -1437,7 +1456,8 @@ private ITypeName GenericTypeArgumentsRule(Token genericTypeName, Token firstTok } else { - ReportIncompleteInput(After(commaOrRBracketToken), + ReportIncompleteInput( + After(commaOrRBracketToken), nameof(ParserStrings.MissingTypename), ParserStrings.MissingTypename); typeName = new TypeName(commaOrRBracketToken.Extent, ":ErrorTypeName:"); @@ -1450,7 +1470,8 @@ private ITypeName GenericTypeArgumentsRule(Token genericTypeName, Token firstTok // ErrorRecovery: pretend we had the closing bracket and just continue on. UngetToken(commaOrRBracketToken); - ReportIncompleteInput(Before(commaOrRBracketToken), + ReportIncompleteInput( + Before(commaOrRBracketToken), nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); commaOrRBracketToken = null; @@ -1471,7 +1492,8 @@ private ITypeName GenericTypeArgumentsRule(Token genericTypeName, Token firstTok string assemblyNameSpec = _tokenizer.GetAssemblyNameSpec(); if (string.IsNullOrEmpty(assemblyNameSpec)) { - ReportError(After(token), + ReportError( + After(token), nameof(ParserStrings.MissingAssemblyNameSpecification), ParserStrings.MissingAssemblyNameSpecification); } @@ -1506,7 +1528,8 @@ private ITypeName CompleteArrayTypeName(ITypeName elementType, TypeName typeForA // ErrorRecovery: just pretend we saw a ']'. UngetToken(token); - ReportError(After(lastComma), + ReportError( + After(lastComma), nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); } @@ -1520,7 +1543,8 @@ private ITypeName CompleteArrayTypeName(ITypeName elementType, TypeName typeForA case TokenKind.EndOfInput: UngetToken(firstTokenAfterLBracket); - ReportError(Before(firstTokenAfterLBracket), + ReportError( + Before(firstTokenAfterLBracket), nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); break; @@ -1528,7 +1552,8 @@ private ITypeName CompleteArrayTypeName(ITypeName elementType, TypeName typeForA default: // ErrorRecovery: sync to ']', and return null to avoid cascading errors. - ReportError(firstTokenAfterLBracket.Extent, + ReportError( + firstTokenAfterLBracket.Extent, nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, firstTokenAfterLBracket.Text); @@ -1543,7 +1568,8 @@ private ITypeName CompleteArrayTypeName(ITypeName elementType, TypeName typeForA var assemblyName = _tokenizer.GetAssemblyNameSpec(); if (string.IsNullOrEmpty(assemblyName)) { - ReportError(After(token), + ReportError( + After(token), nameof(ParserStrings.MissingAssemblyNameSpecification), ParserStrings.MissingAssemblyNameSpecification); } @@ -1581,7 +1607,8 @@ private bool CompleteScriptBlockBody(Token lCurly, ref IScriptExtent bodyExtent, UngetToken(rCurly); endScriptBlock = bodyExtent ?? lCurly.Extent; - ReportIncompleteInput(lCurly.Extent, + ReportIncompleteInput( + lCurly.Extent, rCurly.Extent, nameof(ParserStrings.MissingEndCurlyBrace), ParserStrings.MissingEndCurlyBrace); @@ -1608,7 +1635,8 @@ private bool CompleteScriptBlockBody(Token lCurly, ref IScriptExtent bodyExtent, // ErrorRecovery: eat the unexpected token, and continue parsing to find more // of the script. - ReportError(token.Extent, + ReportError( + token.Extent, nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, token.Text); @@ -1704,7 +1732,8 @@ private ScriptBlockAst NamedBlockListRule(Token lCurly, List } // Report error about the unexpected token. - ReportError(blockNameToken.Extent, + ReportError( + blockNameToken.Extent, nameof(ParserStrings.MissingNamedBlocks), ParserStrings.MissingNamedBlocks, blockNameToken.Text); @@ -1736,7 +1765,8 @@ private ScriptBlockAst NamedBlockListRule(Token lCurly, List { // ErrorRecovery: Eat the block name and keep going, there might be a valid block next. - ReportIncompleteInput(After(blockNameToken.Extent), + ReportIncompleteInput( + After(blockNameToken.Extent), nameof(ParserStrings.MissingNamedStatementBlock), ParserStrings.MissingNamedStatementBlock, blockNameToken.Kind.Text()); @@ -1768,7 +1798,8 @@ private ScriptBlockAst NamedBlockListRule(Token lCurly, List { // ErrorRecovery: this is a semantic error, we can keep parsing w/o trouble. - ReportError(extent, + ReportError( + extent, nameof(ParserStrings.DuplicateScriptCommandClause), ParserStrings.DuplicateScriptCommandClause, blockNameToken.Kind.Text()); @@ -1809,7 +1840,8 @@ private StatementBlockAst StatementBlockRule() UngetToken(rCurly); endBlock = statementListExtent ?? lCurly.Extent; - ReportIncompleteInput(lCurly.Extent, + ReportIncompleteInput( + lCurly.Extent, rCurly.Extent, nameof(ParserStrings.MissingEndCurlyBrace), ParserStrings.MissingEndCurlyBrace); @@ -1932,7 +1964,8 @@ private StatementAst StatementRule() } else { - ReportError(attributes[0].Extent, + ReportError( + attributes[0].Extent, nameof(ParserStrings.UnexpectedAttribute), ParserStrings.UnexpectedAttribute, attributes[0].TypeName.FullName); @@ -1942,7 +1975,8 @@ private StatementAst StatementRule() { foreach (var attr in attributes.Where(attr => !(attr is AttributeAst))) { - ReportError(attr.Extent, + ReportError( + attr.Extent, nameof(ParserStrings.TypeNotAllowedBeforeStatement), ParserStrings.TypeNotAllowedBeforeStatement, attr.TypeName.FullName); @@ -2016,7 +2050,8 @@ private StatementAst StatementRule() case TokenKind.From: case TokenKind.Define: case TokenKind.Var: - ReportError(token.Extent, + ReportError( + token.Extent, nameof(ParserStrings.ReservedKeywordNotAllowed), ParserStrings.ReservedKeywordNotAllowed, token.Kind.Text()); @@ -2064,7 +2099,8 @@ private StatementAst StatementRule() case TokenKind.Using: statement = UsingStatementRule(token); // Report an error - usings must appear before anything else in the script, but parse it anyway - ReportError(statement.Extent, + ReportError( + statement.Extent, nameof(ParserStrings.UsingMustBeAtStartOfScript), ParserStrings.UsingMustBeAtStartOfScript); break; @@ -2272,7 +2308,8 @@ private StatementAst BlockStatementRule(Token kindToken) // ErrorRecovery: nothing more to look for, so just return the error statement. if (body == null) { - ReportIncompleteInput(After(kindToken.Extent), + ReportIncompleteInput( + After(kindToken.Extent), nameof(ParserStrings.MissingStatementAfterKeyword), ParserStrings.MissingStatementAfterKeyword, kindToken.Text); @@ -2309,7 +2346,8 @@ private bool InlineScriptRule(Token inlineScriptToken, List e // ErrorRecovery: If there is no opening curly, assume it hasn't been entered yet and don't consume anything. UngetToken(lCurly); - ReportIncompleteInput(After(inlineScriptToken), + ReportIncompleteInput( + After(inlineScriptToken), nameof(ParserStrings.MissingStatementAfterKeyword), ParserStrings.MissingStatementAfterKeyword, inlineScriptToken.Text); @@ -2348,7 +2386,8 @@ private StatementAst IfStatementRule(Token ifToken) // else yet. Next token is likely a newline, so just put it back and keep parsing. UngetToken(lParen); - ReportIncompleteInput(After(keyword), + ReportIncompleteInput( + After(keyword), nameof(ParserStrings.MissingOpenParenthesisInIfStatement), ParserStrings.MissingOpenParenthesisInIfStatement, keyword.Text); @@ -2363,7 +2402,8 @@ private StatementAst IfStatementRule(Token ifToken) // to find a close paren and statement block. IScriptExtent errorPosition = After(lParen); - ReportIncompleteInput(errorPosition, + ReportIncompleteInput( + errorPosition, nameof(ParserStrings.IfStatementMissingCondition), ParserStrings.IfStatementMissingCondition, keyword.Text); @@ -2385,7 +2425,8 @@ private StatementAst IfStatementRule(Token ifToken) // Don't bother reporting this error if we already reported an empty condition error. if (!(condition is ErrorStatementAst)) { - ReportIncompleteInput(rParen.Extent, + ReportIncompleteInput( + rParen.Extent, nameof(ParserStrings.MissingEndParenthesisAfterStatement), ParserStrings.MissingEndParenthesisAfterStatement, keyword.Text); @@ -2400,7 +2441,8 @@ private StatementAst IfStatementRule(Token ifToken) // ErrorRecovery: assume the next token is a newline or part of something else, // so stop parsing the statement and try parsing something else. - ReportIncompleteInput(rParen.Extent, + ReportIncompleteInput( + rParen.Extent, nameof(ParserStrings.MissingStatementBlock), ParserStrings.MissingStatementBlock, keyword.Text); @@ -2439,7 +2481,8 @@ private StatementAst IfStatementRule(Token ifToken) // ErrorRecovery: assume the next token is a newline or part of something else, // so stop parsing the statement and try parsing something else. - ReportIncompleteInput(After(keyword), + ReportIncompleteInput( + After(keyword), nameof(ParserStrings.MissingStatementBlockAfterElse), ParserStrings.MissingStatementBlockAfterElse); return new ErrorStatementAst(ExtentOf(ifToken, keyword), componentAsts); @@ -2567,7 +2610,8 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: pretend we saw the filename and continue. isError = true; - isIncompleteError = ReportIncompleteInput(After(switchParameterToken), + isIncompleteError = ReportIncompleteInput( + After(switchParameterToken), nameof(ParserStrings.MissingFilenameOption), ParserStrings.MissingFilenameOption); @@ -2593,7 +2637,8 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: just ignore the token, continue parsing. isError = true; - ReportError(switchParameterToken.Extent, + ReportError( + switchParameterToken.Extent, nameof(ParserStrings.InvalidSwitchFlag), ParserStrings.InvalidSwitchFlag, ((ParameterToken)switchParameterToken).ParameterName); @@ -2619,7 +2664,8 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: nothing special this is a semantic error. isError = true; - ReportError(lParen.Extent, + ReportError( + lParen.Extent, nameof(ParserStrings.PipelineValueRequired), ParserStrings.PipelineValueRequired); } @@ -2632,7 +2678,8 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: pretend we saw the condition and keep parsing. isError = true; - isIncompleteError = ReportIncompleteInput(After(lParen), + isIncompleteError = ReportIncompleteInput( + After(lParen), nameof(ParserStrings.PipelineValueRequired), ParserStrings.PipelineValueRequired); } @@ -2652,9 +2699,10 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke { isError = true; isIncompleteError = - ReportIncompleteInput(After(endErrorStatement), - nameof(ParserStrings.MissingEndParenthesisInSwitchStatement), - ParserStrings.MissingEndParenthesisInSwitchStatement); + ReportIncompleteInput( + After(endErrorStatement), + nameof(ParserStrings.MissingEndParenthesisInSwitchStatement), + ParserStrings.MissingEndParenthesisInSwitchStatement); } } else @@ -2667,9 +2715,11 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke if ((flags & SwitchFlags.File) == 0) { isError = true; - isIncompleteError = ReportIncompleteInput(After(endErrorStatement), - nameof(ParserStrings.PipelineValueRequired), - ParserStrings.PipelineValueRequired); + isIncompleteError = + ReportIncompleteInput( + After(endErrorStatement), + nameof(ParserStrings.PipelineValueRequired), + ParserStrings.PipelineValueRequired); } else { @@ -2691,7 +2741,8 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke if (!isIncompleteError) { isError = true; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingCurlyBraceInSwitchStatement), ParserStrings.MissingCurlyBraceInSwitchStatement); } @@ -2711,7 +2762,8 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // So don't look for a body, hope we find the '}' next. isError = true; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingSwitchConditionExpression), ParserStrings.MissingSwitchConditionExpression); // Consume a closing curly, if there is one, to avoid an extra error @@ -2729,9 +2781,11 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: We might find another condition/body pair, so keep going. isError = true; - isIncompleteError = ReportIncompleteInput(After(endErrorStatement), - nameof(ParserStrings.MissingSwitchStatementClause), - ParserStrings.MissingSwitchStatementClause); + isIncompleteError = + ReportIncompleteInput( + After(endErrorStatement), + nameof(ParserStrings.MissingSwitchStatementClause), + ParserStrings.MissingSwitchStatementClause); } else { @@ -2749,7 +2803,8 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: just report the error and continue, forget the previous default clause. isError = true; - ReportError(clauseCondition.Extent, + ReportError( + clauseCondition.Extent, nameof(ParserStrings.MultipleSwitchDefaultClauses), ParserStrings.MultipleSwitchDefaultClauses); } @@ -2774,7 +2829,8 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke if (!isIncompleteError) { isError = true; - ReportIncompleteInput(lCurly.Extent, + ReportIncompleteInput( + lCurly.Extent, token.Extent, nameof(ParserStrings.MissingEndCurlyBrace), ParserStrings.MissingEndCurlyBrace); @@ -2817,7 +2873,8 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom if (configurationNameToken.Kind == TokenKind.LCurly) { - ReportError(After(startExtent), + ReportError( + After(startExtent), nameof(ParserStrings.MissingConfigurationName), ParserStrings.MissingConfigurationName); @@ -2830,9 +2887,10 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom { UngetToken(configurationNameToken); - ReportIncompleteInput(After(configurationNameToken.Extent), - nameof(ParserStrings.MissingConfigurationName), - ParserStrings.MissingConfigurationName); + ReportIncompleteInput( + After(configurationNameToken.Extent), + nameof(ParserStrings.MissingConfigurationName), + ParserStrings.MissingConfigurationName); return null; } @@ -2844,7 +2902,8 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom if (configurationName == null) { isError = true; - ReportIncompleteInput(configurationNameToken.Extent, + ReportIncompleteInput( + configurationNameToken.Extent, nameof(ParserStrings.MissingConfigurationName), ParserStrings.MissingConfigurationName); } @@ -2860,7 +2919,8 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom // This is actually a semantics check, the syntax is fine at this point. // Continue parsing to get as much information as possible isError = true; - ReportError(configurationName.Extent, + ReportError( + configurationName.Extent, nameof(ParserStrings.InvalidConfigurationName), ParserStrings.InvalidConfigurationName, simpleConfigurationNameValue ?? string.Empty); @@ -2891,20 +2951,22 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom // Configuration is not supported on ARM or in ConstrainedLanguage if (PsUtils.IsRunningOnProcessorArchitectureARM() || Runspace.DefaultRunspace.ExecutionContext.LanguageMode == PSLanguageMode.ConstrainedLanguage) { - ReportError(configurationToken.Extent, - nameof(ParserStrings.ConfigurationNotAllowedInConstrainedLanguage), - ParserStrings.ConfigurationNotAllowedInConstrainedLanguage, - configurationToken.Kind.Text()); + ReportError( + configurationToken.Extent, + nameof(ParserStrings.ConfigurationNotAllowedInConstrainedLanguage), + ParserStrings.ConfigurationNotAllowedInConstrainedLanguage, + configurationToken.Kind.Text()); return null; } // Configuration is not supported on WinPE if (Utils.IsWinPEHost()) { - ReportError(configurationToken.Extent, - nameof(ParserStrings.ConfigurationNotAllowedOnWinPE), - ParserStrings.ConfigurationNotAllowedOnWinPE, - configurationToken.Kind.Text()); + ReportError( + configurationToken.Extent, + nameof(ParserStrings.ConfigurationNotAllowedOnWinPE), + ParserStrings.ConfigurationNotAllowedOnWinPE, + configurationToken.Kind.Text()); return null; } @@ -2965,7 +3027,8 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom { // This shouldn't happen - the system classes should always be good, but just in case, // we'll catch the exception and report it as an error. - ReportError(configurationKeywordToken.Extent, + ReportError( + configurationKeywordToken.Extent, nameof(ParserStrings.ParserError), ParserStrings.ParserError, e.ToString()); @@ -2988,7 +3051,8 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom Token lCurly = NextToken(); if (lCurly.Kind != TokenKind.LCurly) { - ReportIncompleteInput(After(lCurly.Extent), + ReportIncompleteInput( + After(lCurly.Extent), nameof(ParserStrings.MissingCurlyInConfigurationStatement), ParserStrings.MissingCurlyInConfigurationStatement); isError = true; @@ -3008,7 +3072,8 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom } if (configurationBodyScriptBlock == null) { - ReportError(After(lCurly.Extent), + ReportError( + After(lCurly.Extent), nameof(ParserStrings.ConfigurationBodyEmpty), ParserStrings.ConfigurationBodyEmpty); return null; @@ -3154,7 +3219,8 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom catch (Exception e) { // In theory this should never happen so if it does, we'll report the actual exception rather than introducing a new message - ReportError(configurationKeywordToken.Extent, + ReportError( + configurationKeywordToken.Extent, nameof(ParserStrings.ParserError), ParserStrings.ParserError, "ConfigurationStatementToken: " + e); @@ -3202,7 +3268,8 @@ private ExpressionAst GetWordOrExpression(Token keywordToken) { // ErrorRecovery: report incomplete statement and return UngetToken(nameToken); - ReportIncompleteInput(After(keywordToken), + ReportIncompleteInput( + After(keywordToken), nameof(ParserStrings.RequiredNameOrExpressionMissing), ParserStrings.RequiredNameOrExpressionMissing); return null; @@ -3212,7 +3279,8 @@ private ExpressionAst GetWordOrExpression(Token keywordToken) if (argument == null) { var extent = keywordToken.Extent; - ReportError(After(extent), + ReportError( + After(extent), nameof(ParserStrings.ParameterRequiresArgument), ParserStrings.ParameterRequiresArgument, keywordToken.Text); @@ -3262,7 +3330,8 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo { // ErrorRecovery: pretend we saw the throttle limit and continue. - ReportIncompleteInput(After(foreachParameterToken), + ReportIncompleteInput( + After(foreachParameterToken), nameof(ParserStrings.MissingThrottleLimit), ParserStrings.MissingThrottleLimit); } @@ -3272,7 +3341,8 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo // ErrorRecovery: just ignore the token, continue parsing. endErrorStatement = foreachParameterToken.Extent; - ReportError(foreachParameterToken.Extent, + ReportError( + foreachParameterToken.Extent, nameof(ParserStrings.InvalidForeachFlag), ParserStrings.InvalidForeachFlag, ((ParameterToken)foreachParameterToken).ParameterName); @@ -3289,7 +3359,8 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo UngetToken(lParen); endErrorStatement = forEachToken.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingOpenParenthesisAfterKeyword), ParserStrings.MissingOpenParenthesisAfterKeyword, forEachToken.Kind.Text()); @@ -3304,7 +3375,8 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo UngetToken(token); endErrorStatement = lParen.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingVariableNameAfterForeach), ParserStrings.MissingVariableNameAfterForeach); return new ErrorStatementAst(ExtentOf(startOfStatement, endErrorStatement)); @@ -3322,7 +3394,8 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo UngetToken(inToken); endErrorStatement = variableAst.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingInInForeach), ParserStrings.MissingInInForeach); } @@ -3335,7 +3408,8 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo // ErrorRecovery: assume the rest of the statement is missing. endErrorStatement = inToken.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingForeachExpression), ParserStrings.MissingForeachExpression); } @@ -3349,7 +3423,8 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo UngetToken(rParen); endErrorStatement = pipeline.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingEndParenthesisAfterForeach), ParserStrings.MissingEndParenthesisAfterForeach); } @@ -3361,7 +3436,8 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo // ErrorRecovery: nothing more to look for, so just return the error statement. endErrorStatement = rParen.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingForeachStatement), ParserStrings.MissingForeachStatement); } @@ -3412,7 +3488,8 @@ private StatementAst ForStatementRule(LabelToken labelToken, Token forToken) UngetToken(lParen); endErrorStatement = forToken.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingOpenParenthesisAfterKeyword), ParserStrings.MissingOpenParenthesisAfterKeyword, forToken.Kind.Text()); @@ -3456,7 +3533,8 @@ private StatementAst ForStatementRule(LabelToken labelToken, Token forToken) { endErrorStatement = lParen.Extent; } - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingEndParenthesisAfterStatement), ParserStrings.MissingEndParenthesisAfterStatement, forToken.Kind.Text()); @@ -3468,10 +3546,11 @@ private StatementAst ForStatementRule(LabelToken labelToken, Token forToken) { // ErrorRecovery: return an error statement. endErrorStatement = rParen.Extent; - ReportIncompleteInput(After(endErrorStatement), - nameof(ParserStrings.MissingLoopStatement), - ParserStrings.MissingLoopStatement, - forToken.Kind.Text()); + ReportIncompleteInput( + After(endErrorStatement), + nameof(ParserStrings.MissingLoopStatement), + ParserStrings.MissingLoopStatement, + forToken.Kind.Text()); } } @@ -3499,7 +3578,8 @@ private StatementAst WhileStatementRule(LabelToken labelToken, Token whileToken) // else yet. Next token is likely a newline, so just put it back and keep parsing. UngetToken(lParen); - ReportIncompleteInput(After(whileToken), + ReportIncompleteInput( + After(whileToken), nameof(ParserStrings.MissingOpenParenthesisAfterKeyword), ParserStrings.MissingOpenParenthesisAfterKeyword, whileToken.Text); @@ -3515,7 +3595,8 @@ private StatementAst WhileStatementRule(LabelToken labelToken, Token whileToken) // to find a close paren and statement block. IScriptExtent errorPosition = After(lParen); - ReportIncompleteInput(errorPosition, + ReportIncompleteInput( + errorPosition, nameof(ParserStrings.MissingExpressionAfterKeyword), ParserStrings.MissingExpressionAfterKeyword, whileToken.Kind.Text()); @@ -3537,7 +3618,8 @@ private StatementAst WhileStatementRule(LabelToken labelToken, Token whileToken) UngetToken(rParen); if (!(condition is ErrorStatementAst)) { - ReportIncompleteInput(After(condition), + ReportIncompleteInput( + After(condition), nameof(ParserStrings.MissingEndParenthesisAfterStatement), ParserStrings.MissingEndParenthesisAfterStatement, whileToken.Kind.Text()); @@ -3551,7 +3633,8 @@ private StatementAst WhileStatementRule(LabelToken labelToken, Token whileToken) { // ErrorRecovery: assume the next token is a newline or part of something else. - ReportIncompleteInput(After(rParen), + ReportIncompleteInput( + After(rParen), nameof(ParserStrings.MissingLoopStatement), ParserStrings.MissingLoopStatement, whileToken.Kind.Text()); @@ -3596,7 +3679,8 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw } catch (Exception e) { - ReportError(functionName.Extent, + ReportError( + functionName.Extent, nameof(ParserStrings.DynamicKeywordPreParseException), ParserStrings.DynamicKeywordPreParseException, keywordData.ResourceName, e.ToString()); @@ -3607,7 +3691,8 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw if (keywordData.IsReservedKeyword) { // ErrorRecovery: eat the token - ReportError(functionName.Extent, + ReportError( + functionName.Extent, nameof(ParserStrings.UnsupportedReservedKeyword), ParserStrings.UnsupportedReservedKeyword, keywordData.Keyword); @@ -3617,7 +3702,8 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw if (keywordData.HasReservedProperties) { // ErrorRecovery: eat the token - ReportError(functionName.Extent, + ReportError( + functionName.Extent, nameof(ParserStrings.UnsupportedReservedProperty), ParserStrings.UnsupportedReservedProperty, "'Require', 'Trigger', 'Notify', 'Before', 'After' and 'Subscribe'"); @@ -3648,14 +3734,16 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw if (keywordData.NameMode == DynamicKeywordNameMode.NameRequired || keywordData.NameMode == DynamicKeywordNameMode.SimpleNameRequired) { - ReportIncompleteInput(After(functionName), + ReportIncompleteInput( + After(functionName), nameof(ParserStrings.RequiredNameOrExpressionMissing), ParserStrings.RequiredNameOrExpressionMissing); } else { // Name not required so report missing brace - ReportIncompleteInput(After(functionName.Extent), + ReportIncompleteInput( + After(functionName.Extent), nameof(ParserStrings.MissingBraceInObjectDefinition), ParserStrings.MissingBraceInObjectDefinition); } @@ -3669,7 +3757,8 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw lCurly = nameToken; if (keywordData.NameMode == DynamicKeywordNameMode.NameRequired || keywordData.NameMode == DynamicKeywordNameMode.SimpleNameRequired) { - ReportError(After(functionName), + ReportError( + After(functionName), nameof(ParserStrings.RequiredNameOrExpressionMissing), ParserStrings.RequiredNameOrExpressionMissing); UngetToken(nameToken); @@ -3680,7 +3769,8 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw { if (keywordData.NameMode == DynamicKeywordNameMode.NoName) { - ReportError(After(functionName), + ReportError( + After(functionName), nameof(ParserStrings.UnexpectedNameForType), ParserStrings.UnexpectedNameForType, functionName.Text, @@ -3695,7 +3785,8 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw // If only a simple name is allowed, then the string must be non-null. if ((keywordData.NameMode == DynamicKeywordNameMode.SimpleNameRequired || keywordData.NameMode == DynamicKeywordNameMode.SimpleOptionalName) && string.IsNullOrEmpty(elementName)) { - ReportIncompleteInput(After(functionName), + ReportIncompleteInput( + After(functionName), nameof(ParserStrings.RequiredNameOrExpressionMissing), ParserStrings.RequiredNameOrExpressionMissing); UngetToken(nameToken); @@ -3712,14 +3803,16 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw { if (keywordData.NameMode == DynamicKeywordNameMode.SimpleNameRequired || keywordData.NameMode == DynamicKeywordNameMode.SimpleOptionalName) { - ReportError(After(functionName), + ReportError( + After(functionName), nameof(ParserStrings.RequiredNameOrExpressionMissing), ParserStrings.RequiredNameOrExpressionMissing); } else { // It wasn't an '{' and it wasn't a name expression so it's a unexpected token. - ReportError(After(functionName), + ReportError( + After(functionName), nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, nameToken.Text); @@ -3730,7 +3823,8 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw // Ok, we got a name expression, but we're expecting no name, so it's and error. if (keywordData.NameMode == DynamicKeywordNameMode.NoName) { - ReportError(After(functionName), + ReportError( + After(functionName), nameof(ParserStrings.UnexpectedNameForType), ParserStrings.UnexpectedNameForType, functionName.Text, @@ -3742,7 +3836,8 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw if (keywordData.NameMode == DynamicKeywordNameMode.SimpleNameRequired || keywordData.NameMode == DynamicKeywordNameMode.SimpleOptionalName) { // If no match, then this is an incomplete token BUGBUG fix message - ReportError(nameToken.Extent, + ReportError( + nameToken.Extent, nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, nameToken.Text); @@ -3773,7 +3868,8 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw if (lCurly.Kind == TokenKind.EndOfInput) { UngetToken(lCurly); - ReportIncompleteInput(After(functionName.Extent), + ReportIncompleteInput( + After(functionName.Extent), nameof(ParserStrings.MissingBraceInObjectDefinition), ParserStrings.MissingBraceInObjectDefinition); @@ -3802,14 +3898,16 @@ instanceInvokeMemberExpressionAst.Arguments[0] is ScriptBlockExpressionAst && // the last condition checks that there is no space between "method" name and '{' instanceInvokeMemberExpressionAst.Member.Extent.EndOffset == instanceInvokeMemberExpressionAst.Arguments[0].Extent.StartOffset) { - ReportError(LastCharacterOf(instanceInvokeMemberExpressionAst.Member.Extent), + ReportError( + LastCharacterOf(instanceInvokeMemberExpressionAst.Member.Extent), nameof(ParserStrings.UnexpectedTokenInDynamicKeyword), ParserStrings.UnexpectedTokenInDynamicKeyword, functionName.Text); } else { - ReportError(lCurly.Extent, + ReportError( + lCurly.Extent, nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, lCurly.Text); @@ -3875,7 +3973,8 @@ instanceInvokeMemberExpressionAst.Arguments[0] is ScriptBlockExpressionAst && if (body == null) { // Failed to read the statement body - ReportIncompleteInput(After(lCurly), + ReportIncompleteInput( + After(lCurly), nameof(ParserStrings.MissingStatementAfterKeyword), ParserStrings.MissingStatementAfterKeyword, keywordData.Keyword); @@ -3933,7 +4032,8 @@ instanceInvokeMemberExpressionAst.Arguments[0] is ScriptBlockExpressionAst && } catch (Exception e) { - ReportError(functionName.Extent, + ReportError( + functionName.Extent, nameof(ParserStrings.DynamicKeywordPostParseException), ParserStrings.DynamicKeywordPostParseException, keywordData.Keyword, @@ -3975,7 +4075,8 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) // comes next. endErrorStatement = doToken.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingLoopStatement), ParserStrings.MissingLoopStatement, TokenKind.Do.Text()); @@ -3990,7 +4091,8 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) UngetToken(whileOrUntilToken); endErrorStatement = body.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingWhileOrUntilInDoWhile), ParserStrings.MissingWhileOrUntilInDoWhile); } @@ -4004,7 +4106,8 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) UngetToken(lParen); endErrorStatement = whileOrUntilToken.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingOpenParenthesisAfterKeyword), ParserStrings.MissingOpenParenthesisAfterKeyword, whileOrUntilToken.Kind.Text()); @@ -4018,7 +4121,8 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) // ErrorRecovery: try to get the matching close paren, then return an error statement. endErrorStatement = lParen.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingExpressionAfterKeyword), ParserStrings.MissingExpressionAfterKeyword, whileOrUntilToken.Kind.Text()); @@ -4035,7 +4139,8 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) if (condition != null) { endErrorStatement = condition.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingEndParenthesisAfterStatement), ParserStrings.MissingEndParenthesisAfterStatement, whileOrUntilToken.Kind.Text()); @@ -4081,7 +4186,8 @@ private StatementAst ClassDefinitionRule(List customAttributes var name = SimpleNameRule(out classNameToken); if (name == null) { - ReportIncompleteInput(After(classToken), + ReportIncompleteInput( + After(classToken), nameof(ParserStrings.MissingNameAfterKeyword), ParserStrings.MissingNameAfterKeyword, classToken.Text); @@ -4113,7 +4219,8 @@ private StatementAst ClassDefinitionRule(List customAttributes superClass = this.TypeNameRule(allowAssemblyQualifiedNames: false, firstTypeNameToken: out unused); if (superClass == null) { - ReportIncompleteInput(After(ExtentFromFirstOf(commaToken, colonToken)), + ReportIncompleteInput( + After(ExtentFromFirstOf(commaToken, colonToken)), nameof(ParserStrings.TypeNameExpected), ParserStrings.TypeNameExpected); break; @@ -4141,7 +4248,8 @@ private StatementAst ClassDefinitionRule(List customAttributes UngetToken(lCurly); var lastElement = (superClassesList.Count > 0) ? (Ast)superClassesList[superClassesList.Count - 1] : name; - ReportIncompleteInput(After(lastElement), + ReportIncompleteInput( + After(lastElement), nameof(ParserStrings.MissingTypeBody), ParserStrings.MissingTypeBody, classToken.Kind.Text()); @@ -4176,7 +4284,8 @@ private StatementAst ClassDefinitionRule(List customAttributes if (rCurly.Kind != TokenKind.RCurly) { UngetToken(rCurly); - ReportIncompleteInput(After(lCurly), + ReportIncompleteInput( + After(lCurly), rCurly.Extent, nameof(ParserStrings.MissingEndCurlyBrace), ParserStrings.MissingEndCurlyBrace); @@ -4293,14 +4402,16 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) case TokenKind.Public: if (publicToken != null) { - ReportError(token.Extent, + ReportError( + token.Extent, nameof(ParserStrings.DuplicateQualifier), ParserStrings.DuplicateQualifier, token.Text); } if (privateToken != null) { - ReportError(token.Extent, + ReportError( + token.Extent, nameof(ParserStrings.ModifiersCannotBeCombined), ParserStrings.ModifiersCannotBeCombined, privateToken.Text, @@ -4313,14 +4424,16 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) case TokenKind.Private: if (privateToken != null) { - ReportError(token.Extent, + ReportError( + token.Extent, nameof(ParserStrings.DuplicateQualifier), ParserStrings.DuplicateQualifier, token.Text); } if (publicToken != null) { - ReportError(token.Extent, + ReportError( + token.Extent, nameof(ParserStrings.ModifiersCannotBeCombined), ParserStrings.ModifiersCannotBeCombined, publicToken.Text, @@ -4334,7 +4447,8 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) case TokenKind.Hidden: if (hiddenToken != null) { - ReportError(token.Extent, + ReportError( + token.Extent, nameof(ParserStrings.DuplicateQualifier), ParserStrings.DuplicateQualifier, token.Text); @@ -4347,7 +4461,8 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) case TokenKind.Static: if (staticToken != null) { - ReportError(token.Extent, + ReportError( + token.Extent, nameof(ParserStrings.DuplicateQualifier), ParserStrings.DuplicateQualifier, token.Text); @@ -4396,7 +4511,8 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) Token terminatorToken = PeekToken(); if (terminatorToken.Kind != TokenKind.NewLine && terminatorToken.Kind != TokenKind.Semi && terminatorToken.Kind != TokenKind.RCurly) { - ReportIncompleteInput(After(endExtent), + ReportIncompleteInput( + After(endExtent), nameof(ParserStrings.MissingPropertyTerminator), ParserStrings.MissingPropertyTerminator); } @@ -4460,7 +4576,8 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) if (lastAttribute != null) { // We have the start of a member, but didn't see a variable or 'def'. - ReportIncompleteInput(After(ExtentFromFirstOf(lastAttribute)), + ReportIncompleteInput( + After(ExtentFromFirstOf(lastAttribute)), nameof(ParserStrings.IncompleteMemberDefinition), ParserStrings.IncompleteMemberDefinition); RecordErrorAsts(attributeList, ref astsOnError); @@ -4538,7 +4655,8 @@ private StatementAst EnumDefinitionRule(List customAttributes, var name = SimpleNameRule(); if (name == null) { - ReportIncompleteInput(After(enumToken), + ReportIncompleteInput( + After(enumToken), nameof(ParserStrings.MissingNameAfterKeyword), ParserStrings.MissingNameAfterKeyword, enumToken.Text); @@ -4560,7 +4678,8 @@ private StatementAst EnumDefinitionRule(List customAttributes, underlyingType = this.TypeNameRule(allowAssemblyQualifiedNames: false, firstTypeNameToken: out unused); if (underlyingType == null) { - ReportIncompleteInput(After(colonToken), + ReportIncompleteInput( + After(colonToken), nameof(ParserStrings.TypeNameExpected), ParserStrings.TypeNameExpected); } @@ -4569,7 +4688,8 @@ private StatementAst EnumDefinitionRule(List customAttributes, var resolvedType = underlyingType.GetReflectionType(); if (resolvedType == null || !validUnderlyingTypeCodes.HasFlag(resolvedType.GetTypeCode())) { - ReportError(underlyingType.Extent, + ReportError( + underlyingType.Extent, nameof(ParserStrings.InvalidUnderlyingType), ParserStrings.InvalidUnderlyingType, underlyingType.Name); @@ -4669,7 +4789,8 @@ private MemberAst EnumMemberRule() initialValueAst = ExpressionRule(); if (initialValueAst == null) { - ReportError(After(assignToken), + ReportError( + After(assignToken), nameof(ParserStrings.ExpectedValueExpression), ParserStrings.ExpectedValueExpression, assignToken.Kind.Text()); @@ -4693,7 +4814,8 @@ private MemberAst EnumMemberRule() // If the initializer is missing, no sense in reporting another error about a missing terminator if (!missingInitializer) { - ReportIncompleteInput(After(endExtent), + ReportIncompleteInput( + After(endExtent), nameof(ParserStrings.MissingPropertyTerminator), ParserStrings.MissingPropertyTerminator); } @@ -4757,7 +4879,8 @@ private StatementAst UsingStatementRule(Token usingToken) default: UngetToken(directiveToken); - ReportIncompleteInput(After(usingToken), + ReportIncompleteInput( + After(usingToken), nameof(ParserStrings.MissingUsingStatementDirective), ParserStrings.MissingUsingStatementDirective); return new ErrorStatementAst(usingToken.Extent); @@ -4774,7 +4897,8 @@ private StatementAst UsingStatementRule(Token usingToken) case TokenKind.Comma: case TokenKind.Semi: { - ReportIncompleteInput(After(directiveToken), + ReportIncompleteInput( + After(directiveToken), nameof(ParserStrings.MissingUsingItemName), ParserStrings.MissingUsingItemName); return new ErrorStatementAst(ExtentOf(usingToken, directiveToken)); @@ -4784,7 +4908,8 @@ private StatementAst UsingStatementRule(Token usingToken) var itemAst = GetCommandArgument(CommandArgumentContext.CommandArgument, itemToken); if (itemAst == null) { - ReportError(itemToken.Extent, + ReportError( + itemToken.Extent, nameof(ParserStrings.InvalidValueForUsingItemName), ParserStrings.InvalidValueForUsingItemName, itemToken.Text); @@ -4795,7 +4920,8 @@ private StatementAst UsingStatementRule(Token usingToken) if (!(itemAst is StringConstantExpressionAst) && (kind != UsingStatementKind.Module || !(itemAst is HashtableAst))) { - ReportError(ExtentFromFirstOf(itemAst, itemToken), + ReportError( + ExtentFromFirstOf(itemAst, itemToken), nameof(ParserStrings.InvalidValueForUsingItemName), ParserStrings.InvalidValueForUsingItemName, itemAst.Extent.Text); @@ -4825,7 +4951,8 @@ private StatementAst UsingStatementRule(Token usingToken) if (aliasToken.Kind == TokenKind.EndOfInput) { UngetToken(aliasToken); - ReportIncompleteInput(After(equalsToken), + ReportIncompleteInput( + After(equalsToken), nameof(ParserStrings.MissingNamespaceAlias), ParserStrings.MissingNamespaceAlias); return new ErrorStatementAst(ExtentOf(usingToken, equalsToken)); @@ -4862,7 +4989,8 @@ private StatementAst UsingStatementRule(Token usingToken) if (aliasRequired) { - ReportIncompleteInput(After(itemToken), + ReportIncompleteInput( + After(itemToken), nameof(ParserStrings.MissingEqualsInUsingAlias), ParserStrings.MissingEqualsInUsingAlias); return new ErrorStatementAst(ExtentOf(usingToken, itemAst), new Ast[] { itemAst }); @@ -4891,7 +5019,8 @@ private StringConstantExpressionAst ResolveUsingAssembly(StringConstantExpressio { if (uri.IsUnc) { - ReportError(name.Extent, + ReportError( + name.Extent, nameof(ParserStrings.CannotLoadAssemblyFromUncPath), ParserStrings.CannotLoadAssemblyFromUncPath, assemblyName); @@ -4900,7 +5029,8 @@ private StringConstantExpressionAst ResolveUsingAssembly(StringConstantExpressio // don't allow things like 'using assembly http://microsoft.com' if (uri.Scheme != "file") { - ReportError(name.Extent, + ReportError( + name.Extent, nameof(ParserStrings.CannotLoadAssemblyWithUriSchema), ParserStrings.CannotLoadAssemblyWithUriSchema, uri.Scheme); @@ -4955,7 +5085,8 @@ private StringConstantExpressionAst ResolveUsingAssembly(StringConstantExpressio if (assemblyFileName == null || !File.Exists(assemblyFileName)) { - ReportError(name.Extent, + ReportError( + name.Extent, nameof(ParserStrings.ErrorLoadingAssembly), ParserStrings.ErrorLoadingAssembly, assemblyName); @@ -4993,7 +5124,8 @@ private StatementAst MethodDeclarationRule(Token functionNameToken, string class } else { - this.ReportIncompleteInput(After(functionNameToken), + this.ReportIncompleteInput( + After(functionNameToken), nameof(ParserStrings.MissingMethodParameterList), ParserStrings.MissingMethodParameterList); parameters = new List(); @@ -5035,7 +5167,8 @@ private StatementAst MethodDeclarationRule(Token functionNameToken, string class else { endErrorStatement = baseToken.Extent; - ReportIncompleteInput(After(baseToken), + ReportIncompleteInput( + After(baseToken), nameof(ParserStrings.MissingMethodParameterList), ParserStrings.MissingMethodParameterList); } @@ -5043,7 +5176,8 @@ private StatementAst MethodDeclarationRule(Token functionNameToken, string class else { endErrorStatement = colonToken.Extent; - ReportIncompleteInput(After(colonToken), + ReportIncompleteInput( + After(colonToken), nameof(ParserStrings.MissingBaseCtorCall), ParserStrings.MissingBaseCtorCall); } @@ -5070,7 +5204,8 @@ private StatementAst MethodDeclarationRule(Token functionNameToken, string class if (endErrorStatement == null) { endErrorStatement = ExtentFromFirstOf(rParen, functionNameToken); - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingFunctionBody), ParserStrings.MissingFunctionBody); } @@ -5158,7 +5293,8 @@ private StatementAst FunctionDeclarationRule(Token functionToken) // ErrorRecovery: Don't continue, assume the function isn't there yet. UngetToken(functionNameToken); - ReportIncompleteInput(After(functionToken), + ReportIncompleteInput( + After(functionToken), nameof(ParserStrings.MissingNameAfterKeyword), ParserStrings.MissingNameAfterKeyword, functionToken.Text); @@ -5181,7 +5317,8 @@ private StatementAst FunctionDeclarationRule(Token functionToken) if (endErrorStatement == null) { endErrorStatement = ExtentFromFirstOf(rParen, functionNameToken); - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingFunctionBody), ParserStrings.MissingFunctionBody); } @@ -5238,7 +5375,8 @@ private List FunctionParameterDeclarationRule(out IScriptExtent en UngetToken(rParen); endErrorStatement = parameters.Any() ? parameters.Last().Extent : lParen.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingEndParenthesisInFunctionParameterList), ParserStrings.MissingEndParenthesisInFunctionParameterList); } @@ -5272,7 +5410,8 @@ private StatementAst TrapStatementRule(Token trapToken) // ErrorRecovery: just return an error statement. IScriptExtent endErrorStatement = ExtentFromFirstOf(typeConstraintAst, trapToken); - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingTrapStatement), ParserStrings.MissingTrapStatement); return new ErrorStatementAst(ExtentOf(trapToken, endErrorStatement), GetNestedErrorAsts(typeConstraintAst)); @@ -5323,7 +5462,8 @@ private CatchClauseAst CatchBlockRule(ref IScriptExtent endErrorStatement, ref L // ErrorRecovery: Just consume the comma, pretend it wasn't there and look for the handler block. endErrorStatement = commaToken.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingTypeLiteralToken), ParserStrings.MissingTypeLiteralToken); } @@ -5368,7 +5508,8 @@ private CatchClauseAst CatchBlockRule(ref IScriptExtent endErrorStatement, ref L // ErrorRecovery: just use the "missing" block in the result ast. endErrorStatement = exceptionTypes != null ? exceptionTypes.Last().Extent : catchToken.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingCatchHandlerBlock), ParserStrings.MissingCatchHandlerBlock); } @@ -5413,7 +5554,8 @@ private StatementAst TryStatementRule(Token tryToken) { // ErrorRecovery: don't parse more, return an error statement. - ReportIncompleteInput(After(tryToken), + ReportIncompleteInput( + After(tryToken), nameof(ParserStrings.MissingTryStatementBlock), ParserStrings.MissingTryStatementBlock); return new ErrorStatementAst(tryToken.Extent); @@ -5442,10 +5584,11 @@ private StatementAst TryStatementRule(Token tryToken) // marking the resulting ast as having an error.) endErrorStatement = finallyToken.Extent; - ReportIncompleteInput(After(endErrorStatement), - nameof(ParserStrings.MissingFinallyStatementBlock), - ParserStrings.MissingFinallyStatementBlock, - finallyToken.Kind.Text()); + ReportIncompleteInput( + After(endErrorStatement), + nameof(ParserStrings.MissingFinallyStatementBlock), + ParserStrings.MissingFinallyStatementBlock, + finallyToken.Kind.Text()); } } @@ -5454,7 +5597,8 @@ private StatementAst TryStatementRule(Token tryToken) // ErrorRecovery: don't parse more, return an error statement. endErrorStatement = body.Extent; - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingCatchOrFinally), ParserStrings.MissingCatchOrFinally); } @@ -5499,7 +5643,8 @@ private StatementAst DataStatementRule(Token dataToken) // ErrorRecovery: Assume the parameter is just misspelled, look for command names next endErrorStatement = supportedCommandToken.Extent; - ReportError(endErrorStatement, + ReportError( + endErrorStatement, nameof(ParserStrings.InvalidParameterForDataSectionStatement), ParserStrings.InvalidParameterForDataSectionStatement, ((ParameterToken)supportedCommandToken).ParameterName); @@ -5518,7 +5663,8 @@ private StatementAst DataStatementRule(Token dataToken) // Only report an error if an error hasn't already been issued. if (endErrorStatement == null) { - ReportIncompleteInput(After(commaToken ?? supportedCommandToken), + ReportIncompleteInput( + After(commaToken ?? supportedCommandToken), nameof(ParserStrings.MissingValueForSupportedCommandInDataSectionStatement), ParserStrings.MissingValueForSupportedCommandInDataSectionStatement); } @@ -5550,7 +5696,8 @@ private StatementAst DataStatementRule(Token dataToken) endErrorStatement = commands != null ? commands.Last().Extent : ExtentFromFirstOf(dataVariableNameAst, dataToken); - ReportIncompleteInput(After(endErrorStatement), + ReportIncompleteInput( + After(endErrorStatement), nameof(ParserStrings.MissingStatementBlockForDataSection), ParserStrings.MissingStatementBlockForDataSection); } @@ -5622,7 +5769,8 @@ private PipelineBaseAst PipelineRule() { // ErrorRecovery: this is a semantic error, so just keep parsing. - ReportError(expr.Extent, + ReportError( + expr.Extent, nameof(ParserStrings.ExpressionsMustBeFirstInPipeline), ParserStrings.ExpressionsMustBeFirstInPipeline); } @@ -5638,7 +5786,8 @@ private PipelineBaseAst PipelineRule() // pipeline, so just keep parsing. IScriptExtent errorExtent = After(assignToken); - ReportIncompleteInput(errorExtent, + ReportIncompleteInput( + errorExtent, nameof(ParserStrings.ExpectedValueExpression), ParserStrings.ExpectedValueExpression, assignToken.Kind.Text()); @@ -5690,7 +5839,8 @@ private PipelineBaseAst PipelineRule() // point before, but the pipe could be the first character), otherwise the empty element // is after the pipe character. IScriptExtent errorPosition = pipeToken != null ? After(pipeToken) : PeekToken().Extent; - ReportIncompleteInput(errorPosition, + ReportIncompleteInput( + errorPosition, nameof(ParserStrings.EmptyPipeElement), ParserStrings.EmptyPipeElement); } @@ -5717,7 +5867,8 @@ private PipelineBaseAst PipelineRule() if (PeekToken().Kind == TokenKind.EndOfInput) { scanning = false; - ReportIncompleteInput(After(pipeToken), + ReportIncompleteInput( + After(pipeToken), nameof(ParserStrings.EmptyPipeElement), ParserStrings.EmptyPipeElement); } @@ -5727,7 +5878,8 @@ private PipelineBaseAst PipelineRule() // Parse in a manner similar to a pipe, but issue an error (for now, but should implement this for V3.) SkipToken(); SkipNewlines(); - ReportError(pipeToken.Extent, + ReportError( + pipeToken.Extent, nameof(ParserStrings.InvalidEndOfLine), ParserStrings.InvalidEndOfLine, pipeToken.Text); @@ -5740,7 +5892,8 @@ private PipelineBaseAst PipelineRule() default: // ErrorRecovery: don't eat the token, assume it belongs to something else. - ReportError(pipeToken.Extent, + ReportError( + pipeToken.Extent, nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, pipeToken.Text); @@ -5780,7 +5933,8 @@ private RedirectionAst RedirectionRule(RedirectionToken redirectionToken, Redire { // ErrorRecovery: Just pretend we have a filename and continue parsing. - ReportError(After(redirectionToken), + ReportError( + After(redirectionToken), nameof(ParserStrings.MissingFileSpecification), ParserStrings.MissingFileSpecification); filename = new ErrorExpressionAst(redirectionToken.Extent); @@ -5789,7 +5943,8 @@ private RedirectionAst RedirectionRule(RedirectionToken redirectionToken, Redire if (fileRedirectionToken == null) { // Must be an input redirection - ReportError(redirectionToken.Extent, + ReportError( + redirectionToken.Extent, nameof(ParserStrings.RedirectionNotSupported), ParserStrings.RedirectionNotSupported, redirectionToken.Text); @@ -5811,7 +5966,8 @@ private RedirectionAst RedirectionRule(RedirectionToken redirectionToken, Redire // Have we seen something like 1>&2 or 2>&3 // ErrorRecovery: This is just a semantic error, so no special recovery. - ReportError(redirectionToken.Extent, + ReportError( + redirectionToken.Extent, nameof(ParserStrings.RedirectionNotSupported), ParserStrings.RedirectionNotSupported, mergingRedirectionToken.Text); @@ -5822,7 +5978,8 @@ private RedirectionAst RedirectionRule(RedirectionToken redirectionToken, Redire // Make sure 1>&1, 2>&2, etc. is an error. // ErrorRecovery: This is just a semantic error, so no special recovery. - ReportError(redirectionToken.Extent, + ReportError( + redirectionToken.Extent, nameof(ParserStrings.RedirectionNotSupported), ParserStrings.RedirectionNotSupported, mergingRedirectionToken.Text); @@ -5850,7 +6007,8 @@ private RedirectionAst RedirectionRule(RedirectionToken redirectionToken, Redire default: throw PSTraceSource.NewArgumentOutOfRangeException("result.FromStream", result.FromStream); } - ReportError(result.Extent, + ReportError( + result.Extent, nameof(ParserStrings.StreamAlreadyRedirected), ParserStrings.StreamAlreadyRedirected, errorStream); @@ -5926,7 +6084,8 @@ private ExpressionAst GetCommandArgument(CommandArgumentContext context, Token t // ErrorRecovery: stop looking for additional arguments, exclude the trailing comma - ReportIncompleteInput(After(commaToken), + ReportIncompleteInput( + After(commaToken), nameof(ParserStrings.MissingExpression), ParserStrings.MissingExpression, ","); @@ -6132,7 +6291,8 @@ internal Ast CommandRule(bool forDynamicKeyword) case TokenKind.Comma: endExtent = token.Extent; - ReportError(token.Extent, + ReportError( + token.Extent, nameof(ParserStrings.MissingArgument), ParserStrings.MissingArgument); SkipNewlines(); @@ -6158,7 +6318,8 @@ internal Ast CommandRule(bool forDynamicKeyword) if (parameterArgs == null) { extent = parameterToken.Extent; - ReportError(After(extent), + ReportError( + After(extent), nameof(ParserStrings.ParameterRequiresArgument), ParserStrings.ParameterRequiresArgument, parameterToken.Text); @@ -6258,7 +6419,8 @@ internal Ast CommandRule(bool forDynamicKeyword) if (dotSource || ampersand) { IScriptExtent extent = firstToken.Extent; - ReportError(extent, + ReportError( + extent, nameof(ParserStrings.MissingExpression), ParserStrings.MissingExpression, firstToken.Text); @@ -6367,7 +6529,8 @@ private ExpressionAst ExpressionRule() IScriptExtent extent = After(token); // Use token.Text, not token.Kind.Text() b/c the kind might not match the actual operator used // when a case insensitive operator is used. - ReportIncompleteInput(extent, + ReportIncompleteInput( + extent, nameof(ParserStrings.ExpectedValueExpression), ParserStrings.ExpectedValueExpression, token.Text); @@ -6427,7 +6590,8 @@ private ExpressionAst ErrorRecoveryParameterInExpression(ParameterToken paramTok // that it's an incomplete operator. This simplifies analysis later, e.g. trying to autocomplete // operators. - ReportError(paramToken.Extent, + ReportError( + paramToken.Extent, nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, paramToken.Text); @@ -6465,7 +6629,8 @@ private ExpressionAst ArrayLiteralRule() { // ErrorRecovery: create an error expression for the ast and break. - ReportIncompleteInput(After(commaToken), + ReportIncompleteInput( + After(commaToken), nameof(ParserStrings.MissingExpressionAfterToken), ParserStrings.MissingExpressionAfterToken, commaToken.Text); @@ -6556,7 +6721,8 @@ private ExpressionAst UnaryExpressionRule() // Use token.Text, not token.Kind.Text() b/c the kind might not match the actual operator used // when a case insensitive operator is used. - ReportIncompleteInput(After(token), + ReportIncompleteInput( + After(token), nameof(ParserStrings.MissingExpressionAfterOperator), ParserStrings.MissingExpressionAfterOperator, token.Text); @@ -6582,7 +6748,8 @@ private ExpressionAst UnaryExpressionRule() // ErrorRecovery: We have a list of attributes, and we know it's not before a param statement, // so we know we must have some sort of expression. Return an error expression then. - ReportIncompleteInput(lastAttribute.Extent, + ReportIncompleteInput( + lastAttribute.Extent, nameof(ParserStrings.UnexpectedAttribute), ParserStrings.UnexpectedAttribute, lastAttribute.TypeName.FullName); @@ -6970,7 +7137,8 @@ private ExpressionAst SubExpressionRule(Token firstToken) // ErrorRecovery: Assume only the closing paren is missing, continue as though it was present. UngetToken(rParen); - ReportIncompleteInput(rParen.Extent, + ReportIncompleteInput( + rParen.Extent, nameof(ParserStrings.MissingEndParenthesisInSubexpression), ParserStrings.MissingEndParenthesisInSubexpression); } @@ -7015,7 +7183,8 @@ private ExpressionAst ParenthesizedExpressionRule(Token lParen) if (pipelineAst == null) { IScriptExtent errorPosition = After(lParen); - ReportIncompleteInput(errorPosition, + ReportIncompleteInput( + errorPosition, nameof(ParserStrings.ExpectedExpression), ParserStrings.ExpectedExpression); pipelineAst = new ErrorStatementAst(errorPosition); @@ -7027,7 +7196,8 @@ private ExpressionAst ParenthesizedExpressionRule(Token lParen) // ErrorRecovery: Assume only the closing paren is missing, continue as though it was present. UngetToken(rParen); - ReportIncompleteInput(After(pipelineAst), + ReportIncompleteInput( + After(pipelineAst), nameof(ParserStrings.MissingEndParenthesisInExpression), ParserStrings.MissingEndParenthesisInExpression); rParen = null; @@ -7151,7 +7321,8 @@ private ExpressionAst MemberAccessRule(ExpressionAst targetExpr, Token operatorT // ErrorRecovery: pretend we saw a property name, don't bother looking for an invocation, // and keep parsing. - ReportIncompleteInput(After(operatorToken), + ReportIncompleteInput( + After(operatorToken), nameof(ParserStrings.MissingPropertyName), ParserStrings.MissingPropertyName); member = GetSingleCommandArgument(CommandArgumentContext.CommandArgument) ?? @@ -7234,7 +7405,8 @@ private List InvokeParamParenListRule(Token lParen, out IScriptEx { // ErrorRecovery: sync at closing paren or newline. - ReportIncompleteInput(After(comma), + ReportIncompleteInput( + After(comma), nameof(ParserStrings.MissingExpressionAfterToken), ParserStrings.MissingExpressionAfterToken, TokenKind.Comma.Text()); @@ -7262,7 +7434,8 @@ private List InvokeParamParenListRule(Token lParen, out IScriptEx UngetToken(rParen); if (!reportedError) { - ReportIncompleteInput(arguments.Any() ? After(arguments.Last()) : After(lParen), + ReportIncompleteInput( + arguments.Any() ? After(arguments.Last()) : After(lParen), nameof(ParserStrings.MissingEndParenthesisInMethodCall), ParserStrings.MissingEndParenthesisInMethodCall); } @@ -7290,7 +7463,8 @@ private ExpressionAst ElementAccessRule(ExpressionAst primaryExpression, Token l // the closing bracket, but build an expression that can't compile. var errorExtent = After(lBracket); - ReportIncompleteInput(errorExtent, + ReportIncompleteInput( + errorExtent, nameof(ParserStrings.MissingArrayIndexExpression), ParserStrings.MissingArrayIndexExpression); indexExpr = new ErrorExpressionAst(lBracket.Extent); @@ -7306,7 +7480,8 @@ private ExpressionAst ElementAccessRule(ExpressionAst primaryExpression, Token l // Skip reporting the error if we've already reported a missing index. if (!(indexExpr is ErrorExpressionAst)) { - ReportIncompleteInput(After(indexExpr), + ReportIncompleteInput( + After(indexExpr), nameof(ParserStrings.MissingEndSquareBracket), ParserStrings.MissingEndSquareBracket); } From 61234b9113227068f067ffc38134fb6946fe5d0f Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Sat, 24 Nov 2018 18:48:44 +0100 Subject: [PATCH 24/34] Revert "Fix ReportError()/ReportIncompleteInput() argument alignment in Parser" This reverts commit 434bbab6bef1862ea125aad97f3eeeba37000657. Will re-add in a separate PR --- .../engine/parser/Parser.cs | 561 ++++++------------ 1 file changed, 193 insertions(+), 368 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 0a6a72e7180..c1dd570387a 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -212,8 +212,7 @@ private ScriptBlockAst ParseTask(string fileName, string input, List toke } else { - ReportError( - _tokenizer.CurrentExtent(), + ReportError(_tokenizer.CurrentExtent(), nameof(ParserStrings.ScriptTooComplicated), ParserStrings.ScriptTooComplicated); } @@ -562,8 +561,7 @@ internal void RequireStatementTerminator() } else if (terminatorToken.Kind != TokenKind.EndOfInput) { - ReportIncompleteInput( - terminatorToken.Extent, + ReportIncompleteInput(terminatorToken.Extent, nameof(ParserStrings.MissingStatementTerminator), ParserStrings.MissingStatementTerminator); } @@ -869,8 +867,7 @@ private ParamBlockAst ParamBlockRule() UngetToken(rParen); endExtent = Before(rParen); - ReportIncompleteInput( - After(parameters != null && parameters.Any() ? parameters.Last().Extent : lparen.Extent), + ReportIncompleteInput(After(parameters != null && parameters.Any() ? parameters.Last().Extent : lparen.Extent), nameof(ParserStrings.MissingEndParenthesisInFunctionParameterList), ParserStrings.MissingEndParenthesisInFunctionParameterList); } @@ -890,8 +887,7 @@ private ParamBlockAst ParamBlockRule() // ErrorRecovery: nothing to do, this is a semantic error that is caught in the parser // because the ast only allows attributes, no type constraints. - ReportError( - attr.Extent, + ReportError(attr.Extent, nameof(ParserStrings.TypeNotAllowedBeforeParam), ParserStrings.TypeNotAllowedBeforeParam, attr.TypeName.FullName); @@ -919,8 +915,7 @@ private List ParameterListRule() { // ErrorRecovery: ?? - ReportIncompleteInput( - After(commaToken), + ReportIncompleteInput(After(commaToken), nameof(ParserStrings.MissingExpressionAfterToken), ParserStrings.MissingExpressionAfterToken, commaToken.Kind.Text()); @@ -969,8 +964,7 @@ private ParameterAst ParameterRule() { // ErrorRecovery: skip to closing paren because returning null signals the last parameter. - ReportIncompleteInput( - After(attributes.Last()), + ReportIncompleteInput(After(attributes.Last()), nameof(ParserStrings.InvalidFunctionParameter), ParserStrings.InvalidFunctionParameter); SyncOnError(true, TokenKind.RParen); @@ -994,8 +988,7 @@ private ParameterAst ParameterRule() defaultValue = ExpressionRule(); if (defaultValue == null) { - ReportIncompleteInput( - After(equalsToken), + ReportIncompleteInput(After(equalsToken), nameof(ParserStrings.MissingExpressionAfterToken), ParserStrings.MissingExpressionAfterToken, equalsToken.Kind.Text()); @@ -1062,8 +1055,7 @@ private AttributeBaseAst AttributeRule() // ErrorRecovery: Return null so we stop looking for attributes. Resync(lBracket); // TypeNameRule might have consumed some tokens - ReportIncompleteInput( - After(lBracket), + ReportIncompleteInput(After(lBracket), nameof(ParserStrings.MissingTypename), ParserStrings.MissingTypename); return null; @@ -1097,8 +1089,7 @@ private AttributeBaseAst AttributeRule() UngetToken(rParen); rParen = null; - ReportIncompleteInput( - After(lastItemExtent), + ReportIncompleteInput(After(lastItemExtent), nameof(ParserStrings.MissingEndParenthesisInExpression), ParserStrings.MissingEndParenthesisInExpression); } @@ -1113,8 +1104,7 @@ private AttributeBaseAst AttributeRule() // Don't bother reporting a missing ']' if we reported a missing ')'. if (rParen != null) { - ReportIncompleteInput( - After(rParen), + ReportIncompleteInput(After(rParen), nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); } @@ -1134,8 +1124,7 @@ private AttributeBaseAst AttributeRule() if (lParenOrRBracket.Kind != TokenKind.RBracket) { UngetToken(lParenOrRBracket); - ReportError( - Before(lParenOrRBracket), + ReportError(Before(lParenOrRBracket), nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); lParenOrRBracket = null; @@ -1184,8 +1173,7 @@ private void AttributeArgumentsRule(ICollection positionalArgumen // ErrorRecovery: ? IScriptExtent errorPosition = After(token); - ReportIncompleteInput( - errorPosition, + ReportIncompleteInput(errorPosition, nameof(ParserStrings.MissingExpressionInNamedArgument), ParserStrings.MissingExpressionInNamedArgument); expr = new ErrorExpressionAst(errorPosition); @@ -1213,8 +1201,7 @@ private void AttributeArgumentsRule(ICollection positionalArgumen { // ErrorRecovery: this is a semantic error, so just keep parsing. - ReportError( - name.Extent, + ReportError(name.Extent, nameof(ParserStrings.DuplicateNamedArgument), ParserStrings.DuplicateNamedArgument, name.Value); @@ -1235,8 +1222,7 @@ private void AttributeArgumentsRule(ICollection positionalArgumen // ErrorRecovery: Pretend we saw the argument and keep going. IScriptExtent errorExtent = After(commaToken); - ReportIncompleteInput( - errorExtent, + ReportIncompleteInput(errorExtent, nameof(ParserStrings.MissingExpressionAfterToken), ParserStrings.MissingExpressionAfterToken, commaToken.Kind.Text()); @@ -1351,8 +1337,7 @@ private ITypeName FinishTypeNameRule(Token typeName, bool unBracketedGenericArg if (token.Kind != TokenKind.EndOfInput) { - ReportError( - token.Extent, + ReportError(token.Extent, nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, token.Text); @@ -1361,8 +1346,7 @@ private ITypeName FinishTypeNameRule(Token typeName, bool unBracketedGenericArg else { UngetToken(token); - ReportIncompleteInput( - After(lbracket), + ReportIncompleteInput(After(lbracket), nameof(ParserStrings.MissingTypename), ParserStrings.MissingTypename); } @@ -1376,8 +1360,7 @@ private ITypeName FinishTypeNameRule(Token typeName, bool unBracketedGenericArg string assemblyNameSpec = _tokenizer.GetAssemblyNameSpec(); if (string.IsNullOrWhiteSpace(assemblyNameSpec)) { - ReportError( - After(token), + ReportError(After(token), nameof(ParserStrings.MissingAssemblyNameSpecification), ParserStrings.MissingAssemblyNameSpecification); return new TypeName(typeName.Extent, typeName.Text); @@ -1401,8 +1384,7 @@ private ITypeName GetSingleGenericArgument(Token firstToken) if (token.Kind != TokenKind.Identifier) { UngetToken(token); - ReportIncompleteInput( - After(token), + ReportIncompleteInput(After(token), nameof(ParserStrings.MissingTypename), ParserStrings.MissingTypename); return new TypeName(firstToken.Extent, ":ErrorTypeName:"); @@ -1417,8 +1399,7 @@ private ITypeName GetSingleGenericArgument(Token firstToken) // ErrorRecovery: pretend we saw the closing bracket. UngetToken(rBracket); - ReportIncompleteInput( - Before(rBracket), + ReportIncompleteInput(Before(rBracket), nameof(ParserStrings.EndSquareBracketExpectedAtEndOfType), ParserStrings.EndSquareBracketExpectedAtEndOfType); } @@ -1456,8 +1437,7 @@ private ITypeName GenericTypeArgumentsRule(Token genericTypeName, Token firstTok } else { - ReportIncompleteInput( - After(commaOrRBracketToken), + ReportIncompleteInput(After(commaOrRBracketToken), nameof(ParserStrings.MissingTypename), ParserStrings.MissingTypename); typeName = new TypeName(commaOrRBracketToken.Extent, ":ErrorTypeName:"); @@ -1470,8 +1450,7 @@ private ITypeName GenericTypeArgumentsRule(Token genericTypeName, Token firstTok // ErrorRecovery: pretend we had the closing bracket and just continue on. UngetToken(commaOrRBracketToken); - ReportIncompleteInput( - Before(commaOrRBracketToken), + ReportIncompleteInput(Before(commaOrRBracketToken), nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); commaOrRBracketToken = null; @@ -1492,8 +1471,7 @@ private ITypeName GenericTypeArgumentsRule(Token genericTypeName, Token firstTok string assemblyNameSpec = _tokenizer.GetAssemblyNameSpec(); if (string.IsNullOrEmpty(assemblyNameSpec)) { - ReportError( - After(token), + ReportError(After(token), nameof(ParserStrings.MissingAssemblyNameSpecification), ParserStrings.MissingAssemblyNameSpecification); } @@ -1528,8 +1506,7 @@ private ITypeName CompleteArrayTypeName(ITypeName elementType, TypeName typeForA // ErrorRecovery: just pretend we saw a ']'. UngetToken(token); - ReportError( - After(lastComma), + ReportError(After(lastComma), nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); } @@ -1543,8 +1520,7 @@ private ITypeName CompleteArrayTypeName(ITypeName elementType, TypeName typeForA case TokenKind.EndOfInput: UngetToken(firstTokenAfterLBracket); - ReportError( - Before(firstTokenAfterLBracket), + ReportError(Before(firstTokenAfterLBracket), nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); break; @@ -1552,8 +1528,7 @@ private ITypeName CompleteArrayTypeName(ITypeName elementType, TypeName typeForA default: // ErrorRecovery: sync to ']', and return null to avoid cascading errors. - ReportError( - firstTokenAfterLBracket.Extent, + ReportError(firstTokenAfterLBracket.Extent, nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, firstTokenAfterLBracket.Text); @@ -1568,8 +1543,7 @@ private ITypeName CompleteArrayTypeName(ITypeName elementType, TypeName typeForA var assemblyName = _tokenizer.GetAssemblyNameSpec(); if (string.IsNullOrEmpty(assemblyName)) { - ReportError( - After(token), + ReportError(After(token), nameof(ParserStrings.MissingAssemblyNameSpecification), ParserStrings.MissingAssemblyNameSpecification); } @@ -1607,8 +1581,7 @@ private bool CompleteScriptBlockBody(Token lCurly, ref IScriptExtent bodyExtent, UngetToken(rCurly); endScriptBlock = bodyExtent ?? lCurly.Extent; - ReportIncompleteInput( - lCurly.Extent, + ReportIncompleteInput(lCurly.Extent, rCurly.Extent, nameof(ParserStrings.MissingEndCurlyBrace), ParserStrings.MissingEndCurlyBrace); @@ -1635,8 +1608,7 @@ private bool CompleteScriptBlockBody(Token lCurly, ref IScriptExtent bodyExtent, // ErrorRecovery: eat the unexpected token, and continue parsing to find more // of the script. - ReportError( - token.Extent, + ReportError(token.Extent, nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, token.Text); @@ -1732,8 +1704,7 @@ private ScriptBlockAst NamedBlockListRule(Token lCurly, List } // Report error about the unexpected token. - ReportError( - blockNameToken.Extent, + ReportError(blockNameToken.Extent, nameof(ParserStrings.MissingNamedBlocks), ParserStrings.MissingNamedBlocks, blockNameToken.Text); @@ -1765,8 +1736,7 @@ private ScriptBlockAst NamedBlockListRule(Token lCurly, List { // ErrorRecovery: Eat the block name and keep going, there might be a valid block next. - ReportIncompleteInput( - After(blockNameToken.Extent), + ReportIncompleteInput(After(blockNameToken.Extent), nameof(ParserStrings.MissingNamedStatementBlock), ParserStrings.MissingNamedStatementBlock, blockNameToken.Kind.Text()); @@ -1798,8 +1768,7 @@ private ScriptBlockAst NamedBlockListRule(Token lCurly, List { // ErrorRecovery: this is a semantic error, we can keep parsing w/o trouble. - ReportError( - extent, + ReportError(extent, nameof(ParserStrings.DuplicateScriptCommandClause), ParserStrings.DuplicateScriptCommandClause, blockNameToken.Kind.Text()); @@ -1840,8 +1809,7 @@ private StatementBlockAst StatementBlockRule() UngetToken(rCurly); endBlock = statementListExtent ?? lCurly.Extent; - ReportIncompleteInput( - lCurly.Extent, + ReportIncompleteInput(lCurly.Extent, rCurly.Extent, nameof(ParserStrings.MissingEndCurlyBrace), ParserStrings.MissingEndCurlyBrace); @@ -1964,8 +1932,7 @@ private StatementAst StatementRule() } else { - ReportError( - attributes[0].Extent, + ReportError(attributes[0].Extent, nameof(ParserStrings.UnexpectedAttribute), ParserStrings.UnexpectedAttribute, attributes[0].TypeName.FullName); @@ -1975,8 +1942,7 @@ private StatementAst StatementRule() { foreach (var attr in attributes.Where(attr => !(attr is AttributeAst))) { - ReportError( - attr.Extent, + ReportError(attr.Extent, nameof(ParserStrings.TypeNotAllowedBeforeStatement), ParserStrings.TypeNotAllowedBeforeStatement, attr.TypeName.FullName); @@ -2050,8 +2016,7 @@ private StatementAst StatementRule() case TokenKind.From: case TokenKind.Define: case TokenKind.Var: - ReportError( - token.Extent, + ReportError(token.Extent, nameof(ParserStrings.ReservedKeywordNotAllowed), ParserStrings.ReservedKeywordNotAllowed, token.Kind.Text()); @@ -2099,8 +2064,7 @@ private StatementAst StatementRule() case TokenKind.Using: statement = UsingStatementRule(token); // Report an error - usings must appear before anything else in the script, but parse it anyway - ReportError( - statement.Extent, + ReportError(statement.Extent, nameof(ParserStrings.UsingMustBeAtStartOfScript), ParserStrings.UsingMustBeAtStartOfScript); break; @@ -2308,8 +2272,7 @@ private StatementAst BlockStatementRule(Token kindToken) // ErrorRecovery: nothing more to look for, so just return the error statement. if (body == null) { - ReportIncompleteInput( - After(kindToken.Extent), + ReportIncompleteInput(After(kindToken.Extent), nameof(ParserStrings.MissingStatementAfterKeyword), ParserStrings.MissingStatementAfterKeyword, kindToken.Text); @@ -2346,8 +2309,7 @@ private bool InlineScriptRule(Token inlineScriptToken, List e // ErrorRecovery: If there is no opening curly, assume it hasn't been entered yet and don't consume anything. UngetToken(lCurly); - ReportIncompleteInput( - After(inlineScriptToken), + ReportIncompleteInput(After(inlineScriptToken), nameof(ParserStrings.MissingStatementAfterKeyword), ParserStrings.MissingStatementAfterKeyword, inlineScriptToken.Text); @@ -2386,8 +2348,7 @@ private StatementAst IfStatementRule(Token ifToken) // else yet. Next token is likely a newline, so just put it back and keep parsing. UngetToken(lParen); - ReportIncompleteInput( - After(keyword), + ReportIncompleteInput(After(keyword), nameof(ParserStrings.MissingOpenParenthesisInIfStatement), ParserStrings.MissingOpenParenthesisInIfStatement, keyword.Text); @@ -2402,8 +2363,7 @@ private StatementAst IfStatementRule(Token ifToken) // to find a close paren and statement block. IScriptExtent errorPosition = After(lParen); - ReportIncompleteInput( - errorPosition, + ReportIncompleteInput(errorPosition, nameof(ParserStrings.IfStatementMissingCondition), ParserStrings.IfStatementMissingCondition, keyword.Text); @@ -2425,8 +2385,7 @@ private StatementAst IfStatementRule(Token ifToken) // Don't bother reporting this error if we already reported an empty condition error. if (!(condition is ErrorStatementAst)) { - ReportIncompleteInput( - rParen.Extent, + ReportIncompleteInput(rParen.Extent, nameof(ParserStrings.MissingEndParenthesisAfterStatement), ParserStrings.MissingEndParenthesisAfterStatement, keyword.Text); @@ -2441,8 +2400,7 @@ private StatementAst IfStatementRule(Token ifToken) // ErrorRecovery: assume the next token is a newline or part of something else, // so stop parsing the statement and try parsing something else. - ReportIncompleteInput( - rParen.Extent, + ReportIncompleteInput(rParen.Extent, nameof(ParserStrings.MissingStatementBlock), ParserStrings.MissingStatementBlock, keyword.Text); @@ -2481,8 +2439,7 @@ private StatementAst IfStatementRule(Token ifToken) // ErrorRecovery: assume the next token is a newline or part of something else, // so stop parsing the statement and try parsing something else. - ReportIncompleteInput( - After(keyword), + ReportIncompleteInput(After(keyword), nameof(ParserStrings.MissingStatementBlockAfterElse), ParserStrings.MissingStatementBlockAfterElse); return new ErrorStatementAst(ExtentOf(ifToken, keyword), componentAsts); @@ -2610,8 +2567,7 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: pretend we saw the filename and continue. isError = true; - isIncompleteError = ReportIncompleteInput( - After(switchParameterToken), + isIncompleteError = ReportIncompleteInput(After(switchParameterToken), nameof(ParserStrings.MissingFilenameOption), ParserStrings.MissingFilenameOption); @@ -2637,8 +2593,7 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: just ignore the token, continue parsing. isError = true; - ReportError( - switchParameterToken.Extent, + ReportError(switchParameterToken.Extent, nameof(ParserStrings.InvalidSwitchFlag), ParserStrings.InvalidSwitchFlag, ((ParameterToken)switchParameterToken).ParameterName); @@ -2664,8 +2619,7 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: nothing special this is a semantic error. isError = true; - ReportError( - lParen.Extent, + ReportError(lParen.Extent, nameof(ParserStrings.PipelineValueRequired), ParserStrings.PipelineValueRequired); } @@ -2678,8 +2632,7 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: pretend we saw the condition and keep parsing. isError = true; - isIncompleteError = ReportIncompleteInput( - After(lParen), + isIncompleteError = ReportIncompleteInput(After(lParen), nameof(ParserStrings.PipelineValueRequired), ParserStrings.PipelineValueRequired); } @@ -2699,10 +2652,9 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke { isError = true; isIncompleteError = - ReportIncompleteInput( - After(endErrorStatement), - nameof(ParserStrings.MissingEndParenthesisInSwitchStatement), - ParserStrings.MissingEndParenthesisInSwitchStatement); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingEndParenthesisInSwitchStatement), + ParserStrings.MissingEndParenthesisInSwitchStatement); } } else @@ -2715,11 +2667,9 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke if ((flags & SwitchFlags.File) == 0) { isError = true; - isIncompleteError = - ReportIncompleteInput( - After(endErrorStatement), - nameof(ParserStrings.PipelineValueRequired), - ParserStrings.PipelineValueRequired); + isIncompleteError = ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.PipelineValueRequired), + ParserStrings.PipelineValueRequired); } else { @@ -2741,8 +2691,7 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke if (!isIncompleteError) { isError = true; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingCurlyBraceInSwitchStatement), ParserStrings.MissingCurlyBraceInSwitchStatement); } @@ -2762,8 +2711,7 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // So don't look for a body, hope we find the '}' next. isError = true; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingSwitchConditionExpression), ParserStrings.MissingSwitchConditionExpression); // Consume a closing curly, if there is one, to avoid an extra error @@ -2781,11 +2729,9 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: We might find another condition/body pair, so keep going. isError = true; - isIncompleteError = - ReportIncompleteInput( - After(endErrorStatement), - nameof(ParserStrings.MissingSwitchStatementClause), - ParserStrings.MissingSwitchStatementClause); + isIncompleteError = ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingSwitchStatementClause), + ParserStrings.MissingSwitchStatementClause); } else { @@ -2803,8 +2749,7 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: just report the error and continue, forget the previous default clause. isError = true; - ReportError( - clauseCondition.Extent, + ReportError(clauseCondition.Extent, nameof(ParserStrings.MultipleSwitchDefaultClauses), ParserStrings.MultipleSwitchDefaultClauses); } @@ -2829,8 +2774,7 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke if (!isIncompleteError) { isError = true; - ReportIncompleteInput( - lCurly.Extent, + ReportIncompleteInput(lCurly.Extent, token.Extent, nameof(ParserStrings.MissingEndCurlyBrace), ParserStrings.MissingEndCurlyBrace); @@ -2873,8 +2817,7 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom if (configurationNameToken.Kind == TokenKind.LCurly) { - ReportError( - After(startExtent), + ReportError(After(startExtent), nameof(ParserStrings.MissingConfigurationName), ParserStrings.MissingConfigurationName); @@ -2887,10 +2830,9 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom { UngetToken(configurationNameToken); - ReportIncompleteInput( - After(configurationNameToken.Extent), - nameof(ParserStrings.MissingConfigurationName), - ParserStrings.MissingConfigurationName); + ReportIncompleteInput(After(configurationNameToken.Extent), + nameof(ParserStrings.MissingConfigurationName), + ParserStrings.MissingConfigurationName); return null; } @@ -2902,8 +2844,7 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom if (configurationName == null) { isError = true; - ReportIncompleteInput( - configurationNameToken.Extent, + ReportIncompleteInput(configurationNameToken.Extent, nameof(ParserStrings.MissingConfigurationName), ParserStrings.MissingConfigurationName); } @@ -2919,8 +2860,7 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom // This is actually a semantics check, the syntax is fine at this point. // Continue parsing to get as much information as possible isError = true; - ReportError( - configurationName.Extent, + ReportError(configurationName.Extent, nameof(ParserStrings.InvalidConfigurationName), ParserStrings.InvalidConfigurationName, simpleConfigurationNameValue ?? string.Empty); @@ -2951,22 +2891,20 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom // Configuration is not supported on ARM or in ConstrainedLanguage if (PsUtils.IsRunningOnProcessorArchitectureARM() || Runspace.DefaultRunspace.ExecutionContext.LanguageMode == PSLanguageMode.ConstrainedLanguage) { - ReportError( - configurationToken.Extent, - nameof(ParserStrings.ConfigurationNotAllowedInConstrainedLanguage), - ParserStrings.ConfigurationNotAllowedInConstrainedLanguage, - configurationToken.Kind.Text()); + ReportError(configurationToken.Extent, + nameof(ParserStrings.ConfigurationNotAllowedInConstrainedLanguage), + ParserStrings.ConfigurationNotAllowedInConstrainedLanguage, + configurationToken.Kind.Text()); return null; } // Configuration is not supported on WinPE if (Utils.IsWinPEHost()) { - ReportError( - configurationToken.Extent, - nameof(ParserStrings.ConfigurationNotAllowedOnWinPE), - ParserStrings.ConfigurationNotAllowedOnWinPE, - configurationToken.Kind.Text()); + ReportError(configurationToken.Extent, + nameof(ParserStrings.ConfigurationNotAllowedOnWinPE), + ParserStrings.ConfigurationNotAllowedOnWinPE, + configurationToken.Kind.Text()); return null; } @@ -3027,8 +2965,7 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom { // This shouldn't happen - the system classes should always be good, but just in case, // we'll catch the exception and report it as an error. - ReportError( - configurationKeywordToken.Extent, + ReportError(configurationKeywordToken.Extent, nameof(ParserStrings.ParserError), ParserStrings.ParserError, e.ToString()); @@ -3051,8 +2988,7 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom Token lCurly = NextToken(); if (lCurly.Kind != TokenKind.LCurly) { - ReportIncompleteInput( - After(lCurly.Extent), + ReportIncompleteInput(After(lCurly.Extent), nameof(ParserStrings.MissingCurlyInConfigurationStatement), ParserStrings.MissingCurlyInConfigurationStatement); isError = true; @@ -3072,8 +3008,7 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom } if (configurationBodyScriptBlock == null) { - ReportError( - After(lCurly.Extent), + ReportError(After(lCurly.Extent), nameof(ParserStrings.ConfigurationBodyEmpty), ParserStrings.ConfigurationBodyEmpty); return null; @@ -3219,8 +3154,7 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom catch (Exception e) { // In theory this should never happen so if it does, we'll report the actual exception rather than introducing a new message - ReportError( - configurationKeywordToken.Extent, + ReportError(configurationKeywordToken.Extent, nameof(ParserStrings.ParserError), ParserStrings.ParserError, "ConfigurationStatementToken: " + e); @@ -3268,8 +3202,7 @@ private ExpressionAst GetWordOrExpression(Token keywordToken) { // ErrorRecovery: report incomplete statement and return UngetToken(nameToken); - ReportIncompleteInput( - After(keywordToken), + ReportIncompleteInput(After(keywordToken), nameof(ParserStrings.RequiredNameOrExpressionMissing), ParserStrings.RequiredNameOrExpressionMissing); return null; @@ -3279,8 +3212,7 @@ private ExpressionAst GetWordOrExpression(Token keywordToken) if (argument == null) { var extent = keywordToken.Extent; - ReportError( - After(extent), + ReportError(After(extent), nameof(ParserStrings.ParameterRequiresArgument), ParserStrings.ParameterRequiresArgument, keywordToken.Text); @@ -3330,8 +3262,7 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo { // ErrorRecovery: pretend we saw the throttle limit and continue. - ReportIncompleteInput( - After(foreachParameterToken), + ReportIncompleteInput(After(foreachParameterToken), nameof(ParserStrings.MissingThrottleLimit), ParserStrings.MissingThrottleLimit); } @@ -3341,8 +3272,7 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo // ErrorRecovery: just ignore the token, continue parsing. endErrorStatement = foreachParameterToken.Extent; - ReportError( - foreachParameterToken.Extent, + ReportError(foreachParameterToken.Extent, nameof(ParserStrings.InvalidForeachFlag), ParserStrings.InvalidForeachFlag, ((ParameterToken)foreachParameterToken).ParameterName); @@ -3359,8 +3289,7 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo UngetToken(lParen); endErrorStatement = forEachToken.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingOpenParenthesisAfterKeyword), ParserStrings.MissingOpenParenthesisAfterKeyword, forEachToken.Kind.Text()); @@ -3375,8 +3304,7 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo UngetToken(token); endErrorStatement = lParen.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingVariableNameAfterForeach), ParserStrings.MissingVariableNameAfterForeach); return new ErrorStatementAst(ExtentOf(startOfStatement, endErrorStatement)); @@ -3394,8 +3322,7 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo UngetToken(inToken); endErrorStatement = variableAst.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingInInForeach), ParserStrings.MissingInInForeach); } @@ -3408,8 +3335,7 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo // ErrorRecovery: assume the rest of the statement is missing. endErrorStatement = inToken.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingForeachExpression), ParserStrings.MissingForeachExpression); } @@ -3423,8 +3349,7 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo UngetToken(rParen); endErrorStatement = pipeline.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingEndParenthesisAfterForeach), ParserStrings.MissingEndParenthesisAfterForeach); } @@ -3436,8 +3361,7 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo // ErrorRecovery: nothing more to look for, so just return the error statement. endErrorStatement = rParen.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingForeachStatement), ParserStrings.MissingForeachStatement); } @@ -3488,8 +3412,7 @@ private StatementAst ForStatementRule(LabelToken labelToken, Token forToken) UngetToken(lParen); endErrorStatement = forToken.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingOpenParenthesisAfterKeyword), ParserStrings.MissingOpenParenthesisAfterKeyword, forToken.Kind.Text()); @@ -3533,8 +3456,7 @@ private StatementAst ForStatementRule(LabelToken labelToken, Token forToken) { endErrorStatement = lParen.Extent; } - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingEndParenthesisAfterStatement), ParserStrings.MissingEndParenthesisAfterStatement, forToken.Kind.Text()); @@ -3546,11 +3468,10 @@ private StatementAst ForStatementRule(LabelToken labelToken, Token forToken) { // ErrorRecovery: return an error statement. endErrorStatement = rParen.Extent; - ReportIncompleteInput( - After(endErrorStatement), - nameof(ParserStrings.MissingLoopStatement), - ParserStrings.MissingLoopStatement, - forToken.Kind.Text()); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingLoopStatement), + ParserStrings.MissingLoopStatement, + forToken.Kind.Text()); } } @@ -3578,8 +3499,7 @@ private StatementAst WhileStatementRule(LabelToken labelToken, Token whileToken) // else yet. Next token is likely a newline, so just put it back and keep parsing. UngetToken(lParen); - ReportIncompleteInput( - After(whileToken), + ReportIncompleteInput(After(whileToken), nameof(ParserStrings.MissingOpenParenthesisAfterKeyword), ParserStrings.MissingOpenParenthesisAfterKeyword, whileToken.Text); @@ -3595,8 +3515,7 @@ private StatementAst WhileStatementRule(LabelToken labelToken, Token whileToken) // to find a close paren and statement block. IScriptExtent errorPosition = After(lParen); - ReportIncompleteInput( - errorPosition, + ReportIncompleteInput(errorPosition, nameof(ParserStrings.MissingExpressionAfterKeyword), ParserStrings.MissingExpressionAfterKeyword, whileToken.Kind.Text()); @@ -3618,8 +3537,7 @@ private StatementAst WhileStatementRule(LabelToken labelToken, Token whileToken) UngetToken(rParen); if (!(condition is ErrorStatementAst)) { - ReportIncompleteInput( - After(condition), + ReportIncompleteInput(After(condition), nameof(ParserStrings.MissingEndParenthesisAfterStatement), ParserStrings.MissingEndParenthesisAfterStatement, whileToken.Kind.Text()); @@ -3633,8 +3551,7 @@ private StatementAst WhileStatementRule(LabelToken labelToken, Token whileToken) { // ErrorRecovery: assume the next token is a newline or part of something else. - ReportIncompleteInput( - After(rParen), + ReportIncompleteInput(After(rParen), nameof(ParserStrings.MissingLoopStatement), ParserStrings.MissingLoopStatement, whileToken.Kind.Text()); @@ -3679,8 +3596,7 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw } catch (Exception e) { - ReportError( - functionName.Extent, + ReportError(functionName.Extent, nameof(ParserStrings.DynamicKeywordPreParseException), ParserStrings.DynamicKeywordPreParseException, keywordData.ResourceName, e.ToString()); @@ -3691,8 +3607,7 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw if (keywordData.IsReservedKeyword) { // ErrorRecovery: eat the token - ReportError( - functionName.Extent, + ReportError(functionName.Extent, nameof(ParserStrings.UnsupportedReservedKeyword), ParserStrings.UnsupportedReservedKeyword, keywordData.Keyword); @@ -3702,8 +3617,7 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw if (keywordData.HasReservedProperties) { // ErrorRecovery: eat the token - ReportError( - functionName.Extent, + ReportError(functionName.Extent, nameof(ParserStrings.UnsupportedReservedProperty), ParserStrings.UnsupportedReservedProperty, "'Require', 'Trigger', 'Notify', 'Before', 'After' and 'Subscribe'"); @@ -3734,16 +3648,14 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw if (keywordData.NameMode == DynamicKeywordNameMode.NameRequired || keywordData.NameMode == DynamicKeywordNameMode.SimpleNameRequired) { - ReportIncompleteInput( - After(functionName), + ReportIncompleteInput(After(functionName), nameof(ParserStrings.RequiredNameOrExpressionMissing), ParserStrings.RequiredNameOrExpressionMissing); } else { // Name not required so report missing brace - ReportIncompleteInput( - After(functionName.Extent), + ReportIncompleteInput(After(functionName.Extent), nameof(ParserStrings.MissingBraceInObjectDefinition), ParserStrings.MissingBraceInObjectDefinition); } @@ -3757,8 +3669,7 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw lCurly = nameToken; if (keywordData.NameMode == DynamicKeywordNameMode.NameRequired || keywordData.NameMode == DynamicKeywordNameMode.SimpleNameRequired) { - ReportError( - After(functionName), + ReportError(After(functionName), nameof(ParserStrings.RequiredNameOrExpressionMissing), ParserStrings.RequiredNameOrExpressionMissing); UngetToken(nameToken); @@ -3769,8 +3680,7 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw { if (keywordData.NameMode == DynamicKeywordNameMode.NoName) { - ReportError( - After(functionName), + ReportError(After(functionName), nameof(ParserStrings.UnexpectedNameForType), ParserStrings.UnexpectedNameForType, functionName.Text, @@ -3785,8 +3695,7 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw // If only a simple name is allowed, then the string must be non-null. if ((keywordData.NameMode == DynamicKeywordNameMode.SimpleNameRequired || keywordData.NameMode == DynamicKeywordNameMode.SimpleOptionalName) && string.IsNullOrEmpty(elementName)) { - ReportIncompleteInput( - After(functionName), + ReportIncompleteInput(After(functionName), nameof(ParserStrings.RequiredNameOrExpressionMissing), ParserStrings.RequiredNameOrExpressionMissing); UngetToken(nameToken); @@ -3803,16 +3712,14 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw { if (keywordData.NameMode == DynamicKeywordNameMode.SimpleNameRequired || keywordData.NameMode == DynamicKeywordNameMode.SimpleOptionalName) { - ReportError( - After(functionName), + ReportError(After(functionName), nameof(ParserStrings.RequiredNameOrExpressionMissing), ParserStrings.RequiredNameOrExpressionMissing); } else { // It wasn't an '{' and it wasn't a name expression so it's a unexpected token. - ReportError( - After(functionName), + ReportError(After(functionName), nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, nameToken.Text); @@ -3823,8 +3730,7 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw // Ok, we got a name expression, but we're expecting no name, so it's and error. if (keywordData.NameMode == DynamicKeywordNameMode.NoName) { - ReportError( - After(functionName), + ReportError(After(functionName), nameof(ParserStrings.UnexpectedNameForType), ParserStrings.UnexpectedNameForType, functionName.Text, @@ -3836,8 +3742,7 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw if (keywordData.NameMode == DynamicKeywordNameMode.SimpleNameRequired || keywordData.NameMode == DynamicKeywordNameMode.SimpleOptionalName) { // If no match, then this is an incomplete token BUGBUG fix message - ReportError( - nameToken.Extent, + ReportError(nameToken.Extent, nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, nameToken.Text); @@ -3868,8 +3773,7 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw if (lCurly.Kind == TokenKind.EndOfInput) { UngetToken(lCurly); - ReportIncompleteInput( - After(functionName.Extent), + ReportIncompleteInput(After(functionName.Extent), nameof(ParserStrings.MissingBraceInObjectDefinition), ParserStrings.MissingBraceInObjectDefinition); @@ -3898,16 +3802,14 @@ instanceInvokeMemberExpressionAst.Arguments[0] is ScriptBlockExpressionAst && // the last condition checks that there is no space between "method" name and '{' instanceInvokeMemberExpressionAst.Member.Extent.EndOffset == instanceInvokeMemberExpressionAst.Arguments[0].Extent.StartOffset) { - ReportError( - LastCharacterOf(instanceInvokeMemberExpressionAst.Member.Extent), + ReportError(LastCharacterOf(instanceInvokeMemberExpressionAst.Member.Extent), nameof(ParserStrings.UnexpectedTokenInDynamicKeyword), ParserStrings.UnexpectedTokenInDynamicKeyword, functionName.Text); } else { - ReportError( - lCurly.Extent, + ReportError(lCurly.Extent, nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, lCurly.Text); @@ -3973,8 +3875,7 @@ instanceInvokeMemberExpressionAst.Arguments[0] is ScriptBlockExpressionAst && if (body == null) { // Failed to read the statement body - ReportIncompleteInput( - After(lCurly), + ReportIncompleteInput(After(lCurly), nameof(ParserStrings.MissingStatementAfterKeyword), ParserStrings.MissingStatementAfterKeyword, keywordData.Keyword); @@ -4032,8 +3933,7 @@ instanceInvokeMemberExpressionAst.Arguments[0] is ScriptBlockExpressionAst && } catch (Exception e) { - ReportError( - functionName.Extent, + ReportError(functionName.Extent, nameof(ParserStrings.DynamicKeywordPostParseException), ParserStrings.DynamicKeywordPostParseException, keywordData.Keyword, @@ -4075,8 +3975,7 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) // comes next. endErrorStatement = doToken.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingLoopStatement), ParserStrings.MissingLoopStatement, TokenKind.Do.Text()); @@ -4091,8 +3990,7 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) UngetToken(whileOrUntilToken); endErrorStatement = body.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingWhileOrUntilInDoWhile), ParserStrings.MissingWhileOrUntilInDoWhile); } @@ -4106,8 +4004,7 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) UngetToken(lParen); endErrorStatement = whileOrUntilToken.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingOpenParenthesisAfterKeyword), ParserStrings.MissingOpenParenthesisAfterKeyword, whileOrUntilToken.Kind.Text()); @@ -4121,8 +4018,7 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) // ErrorRecovery: try to get the matching close paren, then return an error statement. endErrorStatement = lParen.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingExpressionAfterKeyword), ParserStrings.MissingExpressionAfterKeyword, whileOrUntilToken.Kind.Text()); @@ -4139,8 +4035,7 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) if (condition != null) { endErrorStatement = condition.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingEndParenthesisAfterStatement), ParserStrings.MissingEndParenthesisAfterStatement, whileOrUntilToken.Kind.Text()); @@ -4186,8 +4081,7 @@ private StatementAst ClassDefinitionRule(List customAttributes var name = SimpleNameRule(out classNameToken); if (name == null) { - ReportIncompleteInput( - After(classToken), + ReportIncompleteInput(After(classToken), nameof(ParserStrings.MissingNameAfterKeyword), ParserStrings.MissingNameAfterKeyword, classToken.Text); @@ -4219,8 +4113,7 @@ private StatementAst ClassDefinitionRule(List customAttributes superClass = this.TypeNameRule(allowAssemblyQualifiedNames: false, firstTypeNameToken: out unused); if (superClass == null) { - ReportIncompleteInput( - After(ExtentFromFirstOf(commaToken, colonToken)), + ReportIncompleteInput(After(ExtentFromFirstOf(commaToken, colonToken)), nameof(ParserStrings.TypeNameExpected), ParserStrings.TypeNameExpected); break; @@ -4248,8 +4141,7 @@ private StatementAst ClassDefinitionRule(List customAttributes UngetToken(lCurly); var lastElement = (superClassesList.Count > 0) ? (Ast)superClassesList[superClassesList.Count - 1] : name; - ReportIncompleteInput( - After(lastElement), + ReportIncompleteInput(After(lastElement), nameof(ParserStrings.MissingTypeBody), ParserStrings.MissingTypeBody, classToken.Kind.Text()); @@ -4284,8 +4176,7 @@ private StatementAst ClassDefinitionRule(List customAttributes if (rCurly.Kind != TokenKind.RCurly) { UngetToken(rCurly); - ReportIncompleteInput( - After(lCurly), + ReportIncompleteInput(After(lCurly), rCurly.Extent, nameof(ParserStrings.MissingEndCurlyBrace), ParserStrings.MissingEndCurlyBrace); @@ -4402,16 +4293,14 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) case TokenKind.Public: if (publicToken != null) { - ReportError( - token.Extent, + ReportError(token.Extent, nameof(ParserStrings.DuplicateQualifier), ParserStrings.DuplicateQualifier, token.Text); } if (privateToken != null) { - ReportError( - token.Extent, + ReportError(token.Extent, nameof(ParserStrings.ModifiersCannotBeCombined), ParserStrings.ModifiersCannotBeCombined, privateToken.Text, @@ -4424,16 +4313,14 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) case TokenKind.Private: if (privateToken != null) { - ReportError( - token.Extent, + ReportError(token.Extent, nameof(ParserStrings.DuplicateQualifier), ParserStrings.DuplicateQualifier, token.Text); } if (publicToken != null) { - ReportError( - token.Extent, + ReportError(token.Extent, nameof(ParserStrings.ModifiersCannotBeCombined), ParserStrings.ModifiersCannotBeCombined, publicToken.Text, @@ -4447,8 +4334,7 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) case TokenKind.Hidden: if (hiddenToken != null) { - ReportError( - token.Extent, + ReportError(token.Extent, nameof(ParserStrings.DuplicateQualifier), ParserStrings.DuplicateQualifier, token.Text); @@ -4461,8 +4347,7 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) case TokenKind.Static: if (staticToken != null) { - ReportError( - token.Extent, + ReportError(token.Extent, nameof(ParserStrings.DuplicateQualifier), ParserStrings.DuplicateQualifier, token.Text); @@ -4511,8 +4396,7 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) Token terminatorToken = PeekToken(); if (terminatorToken.Kind != TokenKind.NewLine && terminatorToken.Kind != TokenKind.Semi && terminatorToken.Kind != TokenKind.RCurly) { - ReportIncompleteInput( - After(endExtent), + ReportIncompleteInput(After(endExtent), nameof(ParserStrings.MissingPropertyTerminator), ParserStrings.MissingPropertyTerminator); } @@ -4576,8 +4460,7 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) if (lastAttribute != null) { // We have the start of a member, but didn't see a variable or 'def'. - ReportIncompleteInput( - After(ExtentFromFirstOf(lastAttribute)), + ReportIncompleteInput(After(ExtentFromFirstOf(lastAttribute)), nameof(ParserStrings.IncompleteMemberDefinition), ParserStrings.IncompleteMemberDefinition); RecordErrorAsts(attributeList, ref astsOnError); @@ -4655,8 +4538,7 @@ private StatementAst EnumDefinitionRule(List customAttributes, var name = SimpleNameRule(); if (name == null) { - ReportIncompleteInput( - After(enumToken), + ReportIncompleteInput(After(enumToken), nameof(ParserStrings.MissingNameAfterKeyword), ParserStrings.MissingNameAfterKeyword, enumToken.Text); @@ -4678,8 +4560,7 @@ private StatementAst EnumDefinitionRule(List customAttributes, underlyingType = this.TypeNameRule(allowAssemblyQualifiedNames: false, firstTypeNameToken: out unused); if (underlyingType == null) { - ReportIncompleteInput( - After(colonToken), + ReportIncompleteInput(After(colonToken), nameof(ParserStrings.TypeNameExpected), ParserStrings.TypeNameExpected); } @@ -4688,8 +4569,7 @@ private StatementAst EnumDefinitionRule(List customAttributes, var resolvedType = underlyingType.GetReflectionType(); if (resolvedType == null || !validUnderlyingTypeCodes.HasFlag(resolvedType.GetTypeCode())) { - ReportError( - underlyingType.Extent, + ReportError(underlyingType.Extent, nameof(ParserStrings.InvalidUnderlyingType), ParserStrings.InvalidUnderlyingType, underlyingType.Name); @@ -4789,8 +4669,7 @@ private MemberAst EnumMemberRule() initialValueAst = ExpressionRule(); if (initialValueAst == null) { - ReportError( - After(assignToken), + ReportError(After(assignToken), nameof(ParserStrings.ExpectedValueExpression), ParserStrings.ExpectedValueExpression, assignToken.Kind.Text()); @@ -4814,8 +4693,7 @@ private MemberAst EnumMemberRule() // If the initializer is missing, no sense in reporting another error about a missing terminator if (!missingInitializer) { - ReportIncompleteInput( - After(endExtent), + ReportIncompleteInput(After(endExtent), nameof(ParserStrings.MissingPropertyTerminator), ParserStrings.MissingPropertyTerminator); } @@ -4879,8 +4757,7 @@ private StatementAst UsingStatementRule(Token usingToken) default: UngetToken(directiveToken); - ReportIncompleteInput( - After(usingToken), + ReportIncompleteInput(After(usingToken), nameof(ParserStrings.MissingUsingStatementDirective), ParserStrings.MissingUsingStatementDirective); return new ErrorStatementAst(usingToken.Extent); @@ -4897,8 +4774,7 @@ private StatementAst UsingStatementRule(Token usingToken) case TokenKind.Comma: case TokenKind.Semi: { - ReportIncompleteInput( - After(directiveToken), + ReportIncompleteInput(After(directiveToken), nameof(ParserStrings.MissingUsingItemName), ParserStrings.MissingUsingItemName); return new ErrorStatementAst(ExtentOf(usingToken, directiveToken)); @@ -4908,8 +4784,7 @@ private StatementAst UsingStatementRule(Token usingToken) var itemAst = GetCommandArgument(CommandArgumentContext.CommandArgument, itemToken); if (itemAst == null) { - ReportError( - itemToken.Extent, + ReportError(itemToken.Extent, nameof(ParserStrings.InvalidValueForUsingItemName), ParserStrings.InvalidValueForUsingItemName, itemToken.Text); @@ -4920,8 +4795,7 @@ private StatementAst UsingStatementRule(Token usingToken) if (!(itemAst is StringConstantExpressionAst) && (kind != UsingStatementKind.Module || !(itemAst is HashtableAst))) { - ReportError( - ExtentFromFirstOf(itemAst, itemToken), + ReportError(ExtentFromFirstOf(itemAst, itemToken), nameof(ParserStrings.InvalidValueForUsingItemName), ParserStrings.InvalidValueForUsingItemName, itemAst.Extent.Text); @@ -4951,8 +4825,7 @@ private StatementAst UsingStatementRule(Token usingToken) if (aliasToken.Kind == TokenKind.EndOfInput) { UngetToken(aliasToken); - ReportIncompleteInput( - After(equalsToken), + ReportIncompleteInput(After(equalsToken), nameof(ParserStrings.MissingNamespaceAlias), ParserStrings.MissingNamespaceAlias); return new ErrorStatementAst(ExtentOf(usingToken, equalsToken)); @@ -4989,8 +4862,7 @@ private StatementAst UsingStatementRule(Token usingToken) if (aliasRequired) { - ReportIncompleteInput( - After(itemToken), + ReportIncompleteInput(After(itemToken), nameof(ParserStrings.MissingEqualsInUsingAlias), ParserStrings.MissingEqualsInUsingAlias); return new ErrorStatementAst(ExtentOf(usingToken, itemAst), new Ast[] { itemAst }); @@ -5019,8 +4891,7 @@ private StringConstantExpressionAst ResolveUsingAssembly(StringConstantExpressio { if (uri.IsUnc) { - ReportError( - name.Extent, + ReportError(name.Extent, nameof(ParserStrings.CannotLoadAssemblyFromUncPath), ParserStrings.CannotLoadAssemblyFromUncPath, assemblyName); @@ -5029,8 +4900,7 @@ private StringConstantExpressionAst ResolveUsingAssembly(StringConstantExpressio // don't allow things like 'using assembly http://microsoft.com' if (uri.Scheme != "file") { - ReportError( - name.Extent, + ReportError(name.Extent, nameof(ParserStrings.CannotLoadAssemblyWithUriSchema), ParserStrings.CannotLoadAssemblyWithUriSchema, uri.Scheme); @@ -5085,8 +4955,7 @@ private StringConstantExpressionAst ResolveUsingAssembly(StringConstantExpressio if (assemblyFileName == null || !File.Exists(assemblyFileName)) { - ReportError( - name.Extent, + ReportError(name.Extent, nameof(ParserStrings.ErrorLoadingAssembly), ParserStrings.ErrorLoadingAssembly, assemblyName); @@ -5124,8 +4993,7 @@ private StatementAst MethodDeclarationRule(Token functionNameToken, string class } else { - this.ReportIncompleteInput( - After(functionNameToken), + this.ReportIncompleteInput(After(functionNameToken), nameof(ParserStrings.MissingMethodParameterList), ParserStrings.MissingMethodParameterList); parameters = new List(); @@ -5167,8 +5035,7 @@ private StatementAst MethodDeclarationRule(Token functionNameToken, string class else { endErrorStatement = baseToken.Extent; - ReportIncompleteInput( - After(baseToken), + ReportIncompleteInput(After(baseToken), nameof(ParserStrings.MissingMethodParameterList), ParserStrings.MissingMethodParameterList); } @@ -5176,8 +5043,7 @@ private StatementAst MethodDeclarationRule(Token functionNameToken, string class else { endErrorStatement = colonToken.Extent; - ReportIncompleteInput( - After(colonToken), + ReportIncompleteInput(After(colonToken), nameof(ParserStrings.MissingBaseCtorCall), ParserStrings.MissingBaseCtorCall); } @@ -5204,8 +5070,7 @@ private StatementAst MethodDeclarationRule(Token functionNameToken, string class if (endErrorStatement == null) { endErrorStatement = ExtentFromFirstOf(rParen, functionNameToken); - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingFunctionBody), ParserStrings.MissingFunctionBody); } @@ -5293,8 +5158,7 @@ private StatementAst FunctionDeclarationRule(Token functionToken) // ErrorRecovery: Don't continue, assume the function isn't there yet. UngetToken(functionNameToken); - ReportIncompleteInput( - After(functionToken), + ReportIncompleteInput(After(functionToken), nameof(ParserStrings.MissingNameAfterKeyword), ParserStrings.MissingNameAfterKeyword, functionToken.Text); @@ -5317,8 +5181,7 @@ private StatementAst FunctionDeclarationRule(Token functionToken) if (endErrorStatement == null) { endErrorStatement = ExtentFromFirstOf(rParen, functionNameToken); - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingFunctionBody), ParserStrings.MissingFunctionBody); } @@ -5375,8 +5238,7 @@ private List FunctionParameterDeclarationRule(out IScriptExtent en UngetToken(rParen); endErrorStatement = parameters.Any() ? parameters.Last().Extent : lParen.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingEndParenthesisInFunctionParameterList), ParserStrings.MissingEndParenthesisInFunctionParameterList); } @@ -5410,8 +5272,7 @@ private StatementAst TrapStatementRule(Token trapToken) // ErrorRecovery: just return an error statement. IScriptExtent endErrorStatement = ExtentFromFirstOf(typeConstraintAst, trapToken); - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingTrapStatement), ParserStrings.MissingTrapStatement); return new ErrorStatementAst(ExtentOf(trapToken, endErrorStatement), GetNestedErrorAsts(typeConstraintAst)); @@ -5462,8 +5323,7 @@ private CatchClauseAst CatchBlockRule(ref IScriptExtent endErrorStatement, ref L // ErrorRecovery: Just consume the comma, pretend it wasn't there and look for the handler block. endErrorStatement = commaToken.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingTypeLiteralToken), ParserStrings.MissingTypeLiteralToken); } @@ -5508,8 +5368,7 @@ private CatchClauseAst CatchBlockRule(ref IScriptExtent endErrorStatement, ref L // ErrorRecovery: just use the "missing" block in the result ast. endErrorStatement = exceptionTypes != null ? exceptionTypes.Last().Extent : catchToken.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingCatchHandlerBlock), ParserStrings.MissingCatchHandlerBlock); } @@ -5554,8 +5413,7 @@ private StatementAst TryStatementRule(Token tryToken) { // ErrorRecovery: don't parse more, return an error statement. - ReportIncompleteInput( - After(tryToken), + ReportIncompleteInput(After(tryToken), nameof(ParserStrings.MissingTryStatementBlock), ParserStrings.MissingTryStatementBlock); return new ErrorStatementAst(tryToken.Extent); @@ -5584,11 +5442,10 @@ private StatementAst TryStatementRule(Token tryToken) // marking the resulting ast as having an error.) endErrorStatement = finallyToken.Extent; - ReportIncompleteInput( - After(endErrorStatement), - nameof(ParserStrings.MissingFinallyStatementBlock), - ParserStrings.MissingFinallyStatementBlock, - finallyToken.Kind.Text()); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingFinallyStatementBlock), + ParserStrings.MissingFinallyStatementBlock, + finallyToken.Kind.Text()); } } @@ -5597,8 +5454,7 @@ private StatementAst TryStatementRule(Token tryToken) // ErrorRecovery: don't parse more, return an error statement. endErrorStatement = body.Extent; - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingCatchOrFinally), ParserStrings.MissingCatchOrFinally); } @@ -5643,8 +5499,7 @@ private StatementAst DataStatementRule(Token dataToken) // ErrorRecovery: Assume the parameter is just misspelled, look for command names next endErrorStatement = supportedCommandToken.Extent; - ReportError( - endErrorStatement, + ReportError(endErrorStatement, nameof(ParserStrings.InvalidParameterForDataSectionStatement), ParserStrings.InvalidParameterForDataSectionStatement, ((ParameterToken)supportedCommandToken).ParameterName); @@ -5663,8 +5518,7 @@ private StatementAst DataStatementRule(Token dataToken) // Only report an error if an error hasn't already been issued. if (endErrorStatement == null) { - ReportIncompleteInput( - After(commaToken ?? supportedCommandToken), + ReportIncompleteInput(After(commaToken ?? supportedCommandToken), nameof(ParserStrings.MissingValueForSupportedCommandInDataSectionStatement), ParserStrings.MissingValueForSupportedCommandInDataSectionStatement); } @@ -5696,8 +5550,7 @@ private StatementAst DataStatementRule(Token dataToken) endErrorStatement = commands != null ? commands.Last().Extent : ExtentFromFirstOf(dataVariableNameAst, dataToken); - ReportIncompleteInput( - After(endErrorStatement), + ReportIncompleteInput(After(endErrorStatement), nameof(ParserStrings.MissingStatementBlockForDataSection), ParserStrings.MissingStatementBlockForDataSection); } @@ -5769,8 +5622,7 @@ private PipelineBaseAst PipelineRule() { // ErrorRecovery: this is a semantic error, so just keep parsing. - ReportError( - expr.Extent, + ReportError(expr.Extent, nameof(ParserStrings.ExpressionsMustBeFirstInPipeline), ParserStrings.ExpressionsMustBeFirstInPipeline); } @@ -5786,8 +5638,7 @@ private PipelineBaseAst PipelineRule() // pipeline, so just keep parsing. IScriptExtent errorExtent = After(assignToken); - ReportIncompleteInput( - errorExtent, + ReportIncompleteInput(errorExtent, nameof(ParserStrings.ExpectedValueExpression), ParserStrings.ExpectedValueExpression, assignToken.Kind.Text()); @@ -5839,8 +5690,7 @@ private PipelineBaseAst PipelineRule() // point before, but the pipe could be the first character), otherwise the empty element // is after the pipe character. IScriptExtent errorPosition = pipeToken != null ? After(pipeToken) : PeekToken().Extent; - ReportIncompleteInput( - errorPosition, + ReportIncompleteInput(errorPosition, nameof(ParserStrings.EmptyPipeElement), ParserStrings.EmptyPipeElement); } @@ -5867,8 +5717,7 @@ private PipelineBaseAst PipelineRule() if (PeekToken().Kind == TokenKind.EndOfInput) { scanning = false; - ReportIncompleteInput( - After(pipeToken), + ReportIncompleteInput(After(pipeToken), nameof(ParserStrings.EmptyPipeElement), ParserStrings.EmptyPipeElement); } @@ -5878,8 +5727,7 @@ private PipelineBaseAst PipelineRule() // Parse in a manner similar to a pipe, but issue an error (for now, but should implement this for V3.) SkipToken(); SkipNewlines(); - ReportError( - pipeToken.Extent, + ReportError(pipeToken.Extent, nameof(ParserStrings.InvalidEndOfLine), ParserStrings.InvalidEndOfLine, pipeToken.Text); @@ -5892,8 +5740,7 @@ private PipelineBaseAst PipelineRule() default: // ErrorRecovery: don't eat the token, assume it belongs to something else. - ReportError( - pipeToken.Extent, + ReportError(pipeToken.Extent, nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, pipeToken.Text); @@ -5933,8 +5780,7 @@ private RedirectionAst RedirectionRule(RedirectionToken redirectionToken, Redire { // ErrorRecovery: Just pretend we have a filename and continue parsing. - ReportError( - After(redirectionToken), + ReportError(After(redirectionToken), nameof(ParserStrings.MissingFileSpecification), ParserStrings.MissingFileSpecification); filename = new ErrorExpressionAst(redirectionToken.Extent); @@ -5943,8 +5789,7 @@ private RedirectionAst RedirectionRule(RedirectionToken redirectionToken, Redire if (fileRedirectionToken == null) { // Must be an input redirection - ReportError( - redirectionToken.Extent, + ReportError(redirectionToken.Extent, nameof(ParserStrings.RedirectionNotSupported), ParserStrings.RedirectionNotSupported, redirectionToken.Text); @@ -5966,8 +5811,7 @@ private RedirectionAst RedirectionRule(RedirectionToken redirectionToken, Redire // Have we seen something like 1>&2 or 2>&3 // ErrorRecovery: This is just a semantic error, so no special recovery. - ReportError( - redirectionToken.Extent, + ReportError(redirectionToken.Extent, nameof(ParserStrings.RedirectionNotSupported), ParserStrings.RedirectionNotSupported, mergingRedirectionToken.Text); @@ -5978,8 +5822,7 @@ private RedirectionAst RedirectionRule(RedirectionToken redirectionToken, Redire // Make sure 1>&1, 2>&2, etc. is an error. // ErrorRecovery: This is just a semantic error, so no special recovery. - ReportError( - redirectionToken.Extent, + ReportError(redirectionToken.Extent, nameof(ParserStrings.RedirectionNotSupported), ParserStrings.RedirectionNotSupported, mergingRedirectionToken.Text); @@ -6007,8 +5850,7 @@ private RedirectionAst RedirectionRule(RedirectionToken redirectionToken, Redire default: throw PSTraceSource.NewArgumentOutOfRangeException("result.FromStream", result.FromStream); } - ReportError( - result.Extent, + ReportError(result.Extent, nameof(ParserStrings.StreamAlreadyRedirected), ParserStrings.StreamAlreadyRedirected, errorStream); @@ -6084,8 +5926,7 @@ private ExpressionAst GetCommandArgument(CommandArgumentContext context, Token t // ErrorRecovery: stop looking for additional arguments, exclude the trailing comma - ReportIncompleteInput( - After(commaToken), + ReportIncompleteInput(After(commaToken), nameof(ParserStrings.MissingExpression), ParserStrings.MissingExpression, ","); @@ -6291,8 +6132,7 @@ internal Ast CommandRule(bool forDynamicKeyword) case TokenKind.Comma: endExtent = token.Extent; - ReportError( - token.Extent, + ReportError(token.Extent, nameof(ParserStrings.MissingArgument), ParserStrings.MissingArgument); SkipNewlines(); @@ -6318,8 +6158,7 @@ internal Ast CommandRule(bool forDynamicKeyword) if (parameterArgs == null) { extent = parameterToken.Extent; - ReportError( - After(extent), + ReportError(After(extent), nameof(ParserStrings.ParameterRequiresArgument), ParserStrings.ParameterRequiresArgument, parameterToken.Text); @@ -6419,8 +6258,7 @@ internal Ast CommandRule(bool forDynamicKeyword) if (dotSource || ampersand) { IScriptExtent extent = firstToken.Extent; - ReportError( - extent, + ReportError(extent, nameof(ParserStrings.MissingExpression), ParserStrings.MissingExpression, firstToken.Text); @@ -6529,8 +6367,7 @@ private ExpressionAst ExpressionRule() IScriptExtent extent = After(token); // Use token.Text, not token.Kind.Text() b/c the kind might not match the actual operator used // when a case insensitive operator is used. - ReportIncompleteInput( - extent, + ReportIncompleteInput(extent, nameof(ParserStrings.ExpectedValueExpression), ParserStrings.ExpectedValueExpression, token.Text); @@ -6590,8 +6427,7 @@ private ExpressionAst ErrorRecoveryParameterInExpression(ParameterToken paramTok // that it's an incomplete operator. This simplifies analysis later, e.g. trying to autocomplete // operators. - ReportError( - paramToken.Extent, + ReportError(paramToken.Extent, nameof(ParserStrings.UnexpectedToken), ParserStrings.UnexpectedToken, paramToken.Text); @@ -6629,8 +6465,7 @@ private ExpressionAst ArrayLiteralRule() { // ErrorRecovery: create an error expression for the ast and break. - ReportIncompleteInput( - After(commaToken), + ReportIncompleteInput(After(commaToken), nameof(ParserStrings.MissingExpressionAfterToken), ParserStrings.MissingExpressionAfterToken, commaToken.Text); @@ -6721,8 +6556,7 @@ private ExpressionAst UnaryExpressionRule() // Use token.Text, not token.Kind.Text() b/c the kind might not match the actual operator used // when a case insensitive operator is used. - ReportIncompleteInput( - After(token), + ReportIncompleteInput(After(token), nameof(ParserStrings.MissingExpressionAfterOperator), ParserStrings.MissingExpressionAfterOperator, token.Text); @@ -6748,8 +6582,7 @@ private ExpressionAst UnaryExpressionRule() // ErrorRecovery: We have a list of attributes, and we know it's not before a param statement, // so we know we must have some sort of expression. Return an error expression then. - ReportIncompleteInput( - lastAttribute.Extent, + ReportIncompleteInput(lastAttribute.Extent, nameof(ParserStrings.UnexpectedAttribute), ParserStrings.UnexpectedAttribute, lastAttribute.TypeName.FullName); @@ -7137,8 +6970,7 @@ private ExpressionAst SubExpressionRule(Token firstToken) // ErrorRecovery: Assume only the closing paren is missing, continue as though it was present. UngetToken(rParen); - ReportIncompleteInput( - rParen.Extent, + ReportIncompleteInput(rParen.Extent, nameof(ParserStrings.MissingEndParenthesisInSubexpression), ParserStrings.MissingEndParenthesisInSubexpression); } @@ -7183,8 +7015,7 @@ private ExpressionAst ParenthesizedExpressionRule(Token lParen) if (pipelineAst == null) { IScriptExtent errorPosition = After(lParen); - ReportIncompleteInput( - errorPosition, + ReportIncompleteInput(errorPosition, nameof(ParserStrings.ExpectedExpression), ParserStrings.ExpectedExpression); pipelineAst = new ErrorStatementAst(errorPosition); @@ -7196,8 +7027,7 @@ private ExpressionAst ParenthesizedExpressionRule(Token lParen) // ErrorRecovery: Assume only the closing paren is missing, continue as though it was present. UngetToken(rParen); - ReportIncompleteInput( - After(pipelineAst), + ReportIncompleteInput(After(pipelineAst), nameof(ParserStrings.MissingEndParenthesisInExpression), ParserStrings.MissingEndParenthesisInExpression); rParen = null; @@ -7321,8 +7151,7 @@ private ExpressionAst MemberAccessRule(ExpressionAst targetExpr, Token operatorT // ErrorRecovery: pretend we saw a property name, don't bother looking for an invocation, // and keep parsing. - ReportIncompleteInput( - After(operatorToken), + ReportIncompleteInput(After(operatorToken), nameof(ParserStrings.MissingPropertyName), ParserStrings.MissingPropertyName); member = GetSingleCommandArgument(CommandArgumentContext.CommandArgument) ?? @@ -7405,8 +7234,7 @@ private List InvokeParamParenListRule(Token lParen, out IScriptEx { // ErrorRecovery: sync at closing paren or newline. - ReportIncompleteInput( - After(comma), + ReportIncompleteInput(After(comma), nameof(ParserStrings.MissingExpressionAfterToken), ParserStrings.MissingExpressionAfterToken, TokenKind.Comma.Text()); @@ -7434,8 +7262,7 @@ private List InvokeParamParenListRule(Token lParen, out IScriptEx UngetToken(rParen); if (!reportedError) { - ReportIncompleteInput( - arguments.Any() ? After(arguments.Last()) : After(lParen), + ReportIncompleteInput(arguments.Any() ? After(arguments.Last()) : After(lParen), nameof(ParserStrings.MissingEndParenthesisInMethodCall), ParserStrings.MissingEndParenthesisInMethodCall); } @@ -7463,8 +7290,7 @@ private ExpressionAst ElementAccessRule(ExpressionAst primaryExpression, Token l // the closing bracket, but build an expression that can't compile. var errorExtent = After(lBracket); - ReportIncompleteInput( - errorExtent, + ReportIncompleteInput(errorExtent, nameof(ParserStrings.MissingArrayIndexExpression), ParserStrings.MissingArrayIndexExpression); indexExpr = new ErrorExpressionAst(lBracket.Extent); @@ -7480,8 +7306,7 @@ private ExpressionAst ElementAccessRule(ExpressionAst primaryExpression, Token l // Skip reporting the error if we've already reported a missing index. if (!(indexExpr is ErrorExpressionAst)) { - ReportIncompleteInput( - After(indexExpr), + ReportIncompleteInput(After(indexExpr), nameof(ParserStrings.MissingEndSquareBracket), ParserStrings.MissingEndSquareBracket); } From dbb4d18874da2dcf1b4e232e94ba2eb2bd806e40 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Sat, 24 Nov 2018 18:57:25 +0100 Subject: [PATCH 25/34] Simplify type names --- src/System.Management.Automation/engine/parser/PSType.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index 5773467349d..e4f04f9d3f6 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -1118,10 +1118,10 @@ internal void DefineEnum() maxValue = sbyte.MaxValue; break; case TypeCode.UInt16: - maxValue = UInt16.MaxValue; + maxValue = ushort.MaxValue; break; case TypeCode.UInt32: - maxValue = UInt32.MaxValue; + maxValue = uint.MaxValue; break; case TypeCode.UInt64: maxValue = ulong.MaxValue; From 23f26227628a6f0bd567cef08fbee3dff9e7352d Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Tue, 27 Nov 2018 19:44:34 +0100 Subject: [PATCH 26/34] Update EnumDefinitionRule syntax description Updated syntax description to reflect changes made. Additionally marked `validUnderlyingTypeCodes` const. --- src/System.Management.Automation/engine/parser/Parser.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index c1dd570387a..6c5325b77cf 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -4524,15 +4524,19 @@ private StatementAst EnumDefinitionRule(List customAttributes, { //G enum-statement: //G 'enum' new-lines:opt enum-name '{' enum-member-list '}' + //G 'enum' new-lines:opt enum-name ':' enum-underlying-type '{' enum-member-list '}' //G //G enum-name: //G simple-name //G + //G enum-underlying-type: + //G new-lines:opt valid-type-name new-lines:opt + //G //G enum-member-list: //G enum-member new-lines:opt //G enum-member-list enum-member - TypeCode validUnderlyingTypeCodes = TypeCode.Byte | TypeCode.Int16 | TypeCode.Int32 | TypeCode.Int64 | TypeCode.SByte | TypeCode.UInt16 | TypeCode.UInt32 | TypeCode.UInt64; + const TypeCode validUnderlyingTypeCodes = TypeCode.Byte | TypeCode.Int16 | TypeCode.Int32 | TypeCode.Int64 | TypeCode.SByte | TypeCode.UInt16 | TypeCode.UInt32 | TypeCode.UInt64; SkipNewlines(); var name = SimpleNameRule(); From b18213ee79c63a30f4e3583ce1332dfdb047f08c Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Tue, 27 Nov 2018 19:57:31 +0100 Subject: [PATCH 27/34] Fix argument indentation Aligned arguments passed to ReportError() and ReportIncompleteInput() in a single column in the code paths modified --- .../engine/parser/PSType.cs | 15 ++++++++++----- .../engine/parser/Parser.cs | 9 ++++++--- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index e4f04f9d3f6..cd6de75ef43 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -1150,14 +1150,16 @@ internal void DefineEnum() if (constValue != null && LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constValue.GetType()))) { - _parser.ReportError(enumerator.InitialValue.Extent, + _parser.ReportError( + enumerator.InitialValue.Extent, nameof(ParserStrings.EnumeratorValueTooLarge), ParserStrings.EnumeratorValueTooLarge, ToStringCodeMethods.Type(underlyingType)); } else { - _parser.ReportError(enumerator.InitialValue.Extent, + _parser.ReportError( + enumerator.InitialValue.Extent, nameof(ParserStrings.CannotConvertValue), ParserStrings.CannotConvertValue, ToStringCodeMethods.Type(underlyingType)); @@ -1166,7 +1168,8 @@ internal void DefineEnum() } else { - _parser.ReportError(enumerator.InitialValue.Extent, + _parser.ReportError( + enumerator.InitialValue.Extent, nameof(ParserStrings.EnumeratorValueMustBeConstant), ParserStrings.EnumeratorValueMustBeConstant); } @@ -1176,7 +1179,8 @@ internal void DefineEnum() if (valueTooBig) { - _parser.ReportError(enumerator.Extent, + _parser.ReportError( + enumerator.Extent, nameof(ParserStrings.EnumeratorValueTooLarge), ParserStrings.EnumeratorValueTooLarge, ToStringCodeMethods.Type(underlyingType)); @@ -1184,7 +1188,8 @@ internal void DefineEnum() if (definedEnumerators.Contains(enumerator.Name)) { - _parser.ReportError(enumerator.Extent, + _parser.ReportError( + enumerator.Extent, nameof(ParserStrings.MemberAlreadyDefined), ParserStrings.MemberAlreadyDefined, enumerator.Name); diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 6c5325b77cf..433d57d49ec 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -4542,7 +4542,8 @@ private StatementAst EnumDefinitionRule(List customAttributes, var name = SimpleNameRule(); if (name == null) { - ReportIncompleteInput(After(enumToken), + ReportIncompleteInput( + After(enumToken), nameof(ParserStrings.MissingNameAfterKeyword), ParserStrings.MissingNameAfterKeyword, enumToken.Text); @@ -4564,7 +4565,8 @@ private StatementAst EnumDefinitionRule(List customAttributes, underlyingType = this.TypeNameRule(allowAssemblyQualifiedNames: false, firstTypeNameToken: out unused); if (underlyingType == null) { - ReportIncompleteInput(After(colonToken), + ReportIncompleteInput( + After(colonToken), nameof(ParserStrings.TypeNameExpected), ParserStrings.TypeNameExpected); } @@ -4573,7 +4575,8 @@ private StatementAst EnumDefinitionRule(List customAttributes, var resolvedType = underlyingType.GetReflectionType(); if (resolvedType == null || !validUnderlyingTypeCodes.HasFlag(resolvedType.GetTypeCode())) { - ReportError(underlyingType.Extent, + ReportError( + underlyingType.Extent, nameof(ParserStrings.InvalidUnderlyingType), ParserStrings.InvalidUnderlyingType, underlyingType.Name); From 052c0937fd0d3eef3d3a4dd0a3e6d3c16f14e0af Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Tue, 27 Nov 2018 20:11:51 +0100 Subject: [PATCH 28/34] Expand test for enum with negative initial value --- test/powershell/Language/Classes/scripting.enums.tests.ps1 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/powershell/Language/Classes/scripting.enums.tests.ps1 b/test/powershell/Language/Classes/scripting.enums.tests.ps1 index 940af0bed5c..caa227d86f8 100644 --- a/test/powershell/Language/Classes/scripting.enums.tests.ps1 +++ b/test/powershell/Language/Classes/scripting.enums.tests.ps1 @@ -106,12 +106,14 @@ Describe 'enums' -Tags "CI" { Context 'Enum with negative user-specified values' { enum V1 { A = -4 - B + B = [int]::MinValue + C } It 'Negative values are correctly assigned to members' { [V1]::A.value__ | Should -Be -4 - [V1]::B.value__ | Should -Be -3 + [V1]::B.value__ | Should -Be -2147483648 + [V1]::C.value__ | Should -Be -2147483647 } } } From 1c8c5ad9c6d4fd61772b633b8210b53b96729c8a Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Tue, 27 Nov 2018 20:33:24 +0100 Subject: [PATCH 29/34] Remove binary enum value incrementations when Flags() is present --- .../engine/parser/PSType.cs | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index cd6de75ef43..b78d14d3537 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -1201,27 +1201,14 @@ internal void DefineEnum() enumBuilder.DefineLiteral(enumerator.Name, value); } - if (value != 0 && _enumDefinitionAst.Attributes.Any(attr => attr.TypeName.GetReflectionType() == typeof(FlagsAttribute))) + if (value < maxValue) { - if (value < maxValue / 2) - { - value *= 2; - } - else - { - valueTooBig = true; - } + value += 1; + valueTooBig = false; } else { - if (value < maxValue) - { - value += 1; - } - else - { - valueTooBig = true; - } + valueTooBig = true; } } _enumDefinitionAst.Type = enumBuilder.CreateTypeInfo().AsType(); From 4c882f472a291e160dae0de5b957f36d1493aaad Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Tue, 27 Nov 2018 20:54:23 +0100 Subject: [PATCH 30/34] Remove test for binary enum value incrementations when Flags() is present --- .../Language/Classes/scripting.enums.tests.ps1 | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test/powershell/Language/Classes/scripting.enums.tests.ps1 b/test/powershell/Language/Classes/scripting.enums.tests.ps1 index caa227d86f8..0e623b17e31 100644 --- a/test/powershell/Language/Classes/scripting.enums.tests.ps1 +++ b/test/powershell/Language/Classes/scripting.enums.tests.ps1 @@ -91,18 +91,6 @@ Describe 'enums' -Tags "CI" { It 'EX8 has the specified underlying type' { [Enum]::GetUnderlyingType([EX8]) | Should -Be ([ulong]) } } - Context 'Enum with FlagsAttribute' { - [Flags()] - enum BitMask { A;B;C;D } - - It 'Consecutive member values double when FlagsAttribute is present' { - [BitMask]::A.value__ | Should -Be 0 - [BitMask]::B.value__ | Should -Be 1 - [BitMask]::C.value__ | Should -Be 2 - [BitMask]::D.value__ | Should -Be 4 - } - } - Context 'Enum with negative user-specified values' { enum V1 { A = -4 From 6d283d30e641fbc9a7f308b912c7ee7408f9bc19 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Sun, 13 Jan 2019 00:07:17 +0100 Subject: [PATCH 31/34] Rename ParserStrings.EnumeratorValueTooLarge The contexts in which this error string is used covers not only literals that are too large, but also sometimes too small Renamed to EnumeratorValueOutOfBounds --- src/System.Management.Automation/engine/parser/PSType.cs | 8 ++++---- .../resources/ParserStrings.resx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index b78d14d3537..a9d6bc1f818 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -1152,8 +1152,8 @@ internal void DefineEnum() { _parser.ReportError( enumerator.InitialValue.Extent, - nameof(ParserStrings.EnumeratorValueTooLarge), - ParserStrings.EnumeratorValueTooLarge, + nameof(ParserStrings.EnumeratorValueOutOfBounds), + ParserStrings.EnumeratorValueOutOfBounds, ToStringCodeMethods.Type(underlyingType)); } else @@ -1181,8 +1181,8 @@ internal void DefineEnum() { _parser.ReportError( enumerator.Extent, - nameof(ParserStrings.EnumeratorValueTooLarge), - ParserStrings.EnumeratorValueTooLarge, + nameof(ParserStrings.EnumeratorValueOutOfBounds), + ParserStrings.EnumeratorValueOutOfBounds, ToStringCodeMethods.Type(underlyingType)); } diff --git a/src/System.Management.Automation/resources/ParserStrings.resx b/src/System.Management.Automation/resources/ParserStrings.resx index 2d47a0f1514..20d462d9bed 100644 --- a/src/System.Management.Automation/resources/ParserStrings.resx +++ b/src/System.Management.Automation/resources/ParserStrings.resx @@ -1289,8 +1289,8 @@ ModuleVersion : Version of module to import. If used, ModuleName must represent Cannot define enum because of a cycle in the initialization expressions. - - Enumerator value is too large for {0}. + + Enumerator value is either too large or too small for {0}. Enumerator value must be a constant value. From 80e119cd9f61e246de54edcdcfba4820fe2d3f68 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Sun, 13 Jan 2019 00:22:27 +0100 Subject: [PATCH 32/34] Add test for enum literal value too small --- test/powershell/Language/Classes/scripting.enums.tests.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/powershell/Language/Classes/scripting.enums.tests.ps1 b/test/powershell/Language/Classes/scripting.enums.tests.ps1 index 0e623b17e31..a3a86863a0a 100644 --- a/test/powershell/Language/Classes/scripting.enums.tests.ps1 +++ b/test/powershell/Language/Classes/scripting.enums.tests.ps1 @@ -116,8 +116,9 @@ Describe 'Basic enum errors' -Tags "CI" { ShouldBeParseError 'enum foo { x; x }' MemberAlreadyDefined 14 -SkipAndCheckRuntimeError ShouldBeParseError 'enum foo { X; x }' MemberAlreadyDefined 14 -SkipAndCheckRuntimeError ShouldBeParseError 'enum foo1 { x = [foo2]::x } enum foo2 { x = [foo1]::x }' CycleInEnumInitializers,CycleInEnumInitializers 0,28 -SkipAndCheckRuntimeError - ShouldBeParseError 'enum foo { e = [int]::MaxValue; e2 }' EnumeratorValueTooLarge 33 -SkipAndCheckRuntimeError - ShouldBeParseError 'enum foo { e = [int]::MaxValue + 1 }' EnumeratorValueTooLarge 15 -SkipAndCheckRuntimeError + ShouldBeParseError 'enum foo { e = [int]::MaxValue; e2 }' EnumeratorValueOutOfBounds 33 -SkipAndCheckRuntimeError + ShouldBeParseError 'enum foo { e = [int]::MaxValue + 1 }' EnumeratorValueOutOfBounds 15 -SkipAndCheckRuntimeError + ShouldBeParseError 'enum foo : byte { e = -1 }' EnumeratorValueOutOfBounds 22 -SkipAndCheckRuntimeError ShouldBeParseError 'enum foo { e = $foo }' EnumeratorValueMustBeConstant 15 -SkipAndCheckRuntimeError ShouldBeParseError 'enum foo { e = "hello" }' CannotConvertValue 15 -SkipAndCheckRuntimeError ShouldBeParseError 'enum foo { a;b;c;' MissingEndCurlyBrace 10 From 065e151b2ead98e59dd17ffc3e21f4aec7dca95a Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Sun, 13 Jan 2019 12:29:09 +0100 Subject: [PATCH 33/34] Fix comment + variable casing --- src/System.Management.Automation/engine/parser/Parser.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 433d57d49ec..17bde6c6170 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -4536,7 +4536,7 @@ private StatementAst EnumDefinitionRule(List customAttributes, //G enum-member new-lines:opt //G enum-member-list enum-member - const TypeCode validUnderlyingTypeCodes = TypeCode.Byte | TypeCode.Int16 | TypeCode.Int32 | TypeCode.Int64 | TypeCode.SByte | TypeCode.UInt16 | TypeCode.UInt32 | TypeCode.UInt64; + const TypeCode ValidUnderlyingTypeCodes = TypeCode.Byte | TypeCode.Int16 | TypeCode.Int32 | TypeCode.Int64 | TypeCode.SByte | TypeCode.UInt16 | TypeCode.UInt32 | TypeCode.UInt64; SkipNewlines(); var name = SimpleNameRule(); @@ -4627,7 +4627,7 @@ private StatementAst EnumDefinitionRule(List customAttributes, var enumDefn = new TypeDefinitionAst(extent, name.Value, customAttributes == null ? null : customAttributes.OfType(), members, TypeAttributes.Enum, underlyingTypeConstraint == null ? null : new[] { underlyingTypeConstraint }); if (customAttributes != null && customAttributes.OfType().Any()) { - //no need to report error since there is error reported in method StatementRule + // No need to report error since there is error reported in method StatementRule List nestedAsts = new List(); nestedAsts.AddRange(customAttributes.OfType()); nestedAsts.Add(enumDefn); From 85c36a81a4c7790160647e2ce5e10dc46a1789cc Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Sun, 13 Jan 2019 12:49:57 +0100 Subject: [PATCH 34/34] Fix variable casing for ValidUnderlyingTypeCodes --- src/System.Management.Automation/engine/parser/Parser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index c707491aee9..7af775f56c5 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -4668,7 +4668,7 @@ private StatementAst EnumDefinitionRule(List customAttributes, else { var resolvedType = underlyingType.GetReflectionType(); - if (resolvedType == null || !validUnderlyingTypeCodes.HasFlag(resolvedType.GetTypeCode())) + if (resolvedType == null || !ValidUnderlyingTypeCodes.HasFlag(resolvedType.GetTypeCode())) { ReportError( underlyingType.Extent,