From 2b416ccd94e52aa08b39c95085bebec5a577fefe Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Fri, 23 Mar 2018 18:38:03 -0700 Subject: [PATCH 01/15] Change parser ReportError to use nameof instead of LINQ expression --- .../engine/parser/PSType.cs | 109 ++- .../engine/parser/Parser.cs | 836 +++++++++++++----- .../engine/parser/tokenizer.cs | 52 +- 3 files changed, 736 insertions(+), 261 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index 8cfd53815ba..769218bc7e1 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -36,7 +36,10 @@ private static bool TryConvertArg(object arg, Type type, out object result, Pars } if (!LanguagePrimitives.TryConvertTo(arg, type, out result)) { - parser.ReportError(errorExtent, () => ParserStrings.CannotConvertValue, ToStringCodeMethods.Type(type)); + parser.ReportError(errorExtent, + nameof(ParserStrings.CannotConvertValue), + ParserStrings.CannotConvertValue, + ToStringCodeMethods.Type(type)); return false; } return true; @@ -307,7 +310,10 @@ private Type GetBaseTypes(Parser parser, TypeDefinitionAst typeDefinitionAst, ou if (firstBaseTypeAst.TypeName.IsArray) { - parser.ReportError(firstBaseTypeAst.Extent, () => ParserStrings.SubtypeArray, firstBaseTypeAst.TypeName.FullName); + parser.ReportError(firstBaseTypeAst.Extent, + nameof(ParserStrings.SubtypeArray), + ParserStrings.SubtypeArray, + firstBaseTypeAst.TypeName.FullName); // fall to the default base type } else @@ -315,7 +321,10 @@ private Type GetBaseTypes(Parser parser, TypeDefinitionAst typeDefinitionAst, ou baseClass = firstBaseTypeAst.TypeName.GetReflectionType(); if (baseClass == null) { - parser.ReportError(firstBaseTypeAst.Extent, () => ParserStrings.TypeNotFound, firstBaseTypeAst.TypeName.FullName); + parser.ReportError(firstBaseTypeAst.Extent, + nameof(ParserStrings.TypeNotFound), + ParserStrings.TypeNotFound, + firstBaseTypeAst.TypeName.FullName); // fall to the default base type } else @@ -323,13 +332,19 @@ private Type GetBaseTypes(Parser parser, TypeDefinitionAst typeDefinitionAst, ou { if (baseClass.GetTypeInfo().IsSealed) { - parser.ReportError(firstBaseTypeAst.Extent, () => ParserStrings.SealedBaseClass, baseClass.Name); + parser.ReportError(firstBaseTypeAst.Extent, + nameof(ParserStrings.SealedBaseClass), + ParserStrings.SealedBaseClass, + baseClass.Name); // ignore base type if it's sealed. baseClass = null; } else if (baseClass.GetTypeInfo().IsGenericType && !baseClass.IsConstructedGenericType) { - parser.ReportError(firstBaseTypeAst.Extent, () => ParserStrings.SubtypeUnclosedGeneric, baseClass.Name); + parser.ReportError(firstBaseTypeAst.Extent, + nameof(ParserStrings.SubtypeUnclosedGeneric), + ParserStrings.SubtypeUnclosedGeneric, + baseClass.Name); // ignore base type, we cannot inherit from unclosed generic. baseClass = null; } @@ -361,7 +376,10 @@ private Type GetBaseTypes(Parser parser, TypeDefinitionAst typeDefinitionAst, ou { if (baseTypeAsts[i].TypeName.IsArray) { - parser.ReportError(baseTypeAsts[i].Extent, () => ParserStrings.SubtypeArray, baseTypeAsts[i].TypeName.FullName); + parser.ReportError(baseTypeAsts[i].Extent, + nameof(ParserStrings.SubtypeArray), + ParserStrings.SubtypeArray, + baseTypeAsts[i].TypeName.FullName); this.HasFatalErrors = true; } } @@ -370,14 +388,20 @@ private Type GetBaseTypes(Parser parser, TypeDefinitionAst typeDefinitionAst, ou { if (baseTypeAsts[i].TypeName.IsArray) { - parser.ReportError(baseTypeAsts[i].Extent, () => ParserStrings.SubtypeArray, baseTypeAsts[i].TypeName.FullName); + parser.ReportError(baseTypeAsts[i].Extent, + nameof(ParserStrings.SubtypeArray), + ParserStrings.SubtypeArray, + baseTypeAsts[i].TypeName.FullName); } else { Type interfaceType = baseTypeAsts[i].TypeName.GetReflectionType(); if (interfaceType == null) { - parser.ReportError(baseTypeAsts[i].Extent, () => ParserStrings.TypeNotFound, baseTypeAsts[i].TypeName.FullName); + parser.ReportError(baseTypeAsts[i].Extent, + nameof(ParserStrings.TypeNotFound), + ParserStrings.TypeNotFound, + baseTypeAsts[i].TypeName.FullName); } else { @@ -387,7 +411,10 @@ private Type GetBaseTypes(Parser parser, TypeDefinitionAst typeDefinitionAst, ou } else { - parser.ReportError(baseTypeAsts[i].Extent, () => ParserStrings.InterfaceNameExpected, interfaceType.Name); + parser.ReportError(baseTypeAsts[i].Extent, + nameof(ParserStrings.InterfaceNameExpected), + ParserStrings.InterfaceNameExpected, + interfaceType.Name); } } } @@ -494,7 +521,10 @@ public void DefineMembers() { if (!instanceCtors.Any()) { - _parser.ReportError(_typeDefinitionAst.Extent, () => ParserStrings.BaseClassNoDefaultCtor, _typeBuilder.BaseType.Name); + _parser.ReportError(_typeDefinitionAst.Extent, + nameof(ParserStrings.BaseClassNoDefaultCtor), + ParserStrings.BaseClassNoDefaultCtor, + _typeBuilder.BaseType.Name); this.HasFatalErrors = true; } } @@ -504,7 +534,10 @@ private void DefineProperty(PropertyMemberAst propertyMemberAst) { if (_definedProperties.ContainsKey(propertyMemberAst.Name)) { - _parser.ReportError(propertyMemberAst.Extent, () => ParserStrings.MemberAlreadyDefined, propertyMemberAst.Name); + _parser.ReportError(propertyMemberAst.Extent, + nameof(ParserStrings.MemberAlreadyDefined), + ParserStrings.MemberAlreadyDefined, + propertyMemberAst.Name); return; } @@ -658,7 +691,9 @@ private bool CheckForDuplicateOverload(FunctionMemberAst functionMemberAst, Type !functionMemberAst.IsConstructor) { _parser.ReportError(functionMemberAst.NameExtent ?? functionMemberAst.Extent, - () => ParserStrings.MemberAlreadyDefined, functionMemberAst.Name); + nameof(ParserStrings.MemberAlreadyDefined), + ParserStrings.MemberAlreadyDefined, + functionMemberAst.Name); return true; } } @@ -687,12 +722,17 @@ private Type[] GetParameterTypes(FunctionMemberAst functionMemberAst) : typeof(object); if (paramType == null) { - _parser.ReportError(typeConstraint.Extent, () => ParserStrings.TypeNotFound, typeConstraint.TypeName.FullName); + _parser.ReportError(typeConstraint.Extent, + nameof(ParserStrings.TypeNotFound), + ParserStrings.TypeNotFound, + typeConstraint.TypeName.FullName); anyErrors = true; } else if (paramType == typeof(void) || paramType.GetTypeInfo().IsGenericTypeDefinition) { - _parser.ReportError(typeConstraint.Extent, () => ParserStrings.TypeNotAllowedForParameter, + _parser.ReportError(typeConstraint.Extent, + nameof(ParserStrings.TypeNotAllowedForParameter), + ParserStrings.TypeNotAllowedForParameter, typeConstraint.TypeName.FullName); anyErrors = true; } @@ -735,7 +775,9 @@ private void DefineMethod(FunctionMemberAst functionMemberAst) var parameters = functionMemberAst.Parameters; if (parameters.Count > 0) { - _parser.ReportError(Parser.ExtentOf(parameters.First(), parameters.Last()), () => ParserStrings.StaticConstructorCantHaveParameters); + _parser.ReportError(Parser.ExtentOf(parameters.First(), parameters.Last()), + nameof(ParserStrings.StaticConstructorCantHaveParameters), + ParserStrings.StaticConstructorCantHaveParameters); return; } methodAttributes |= Reflection.MethodAttributes.Static; @@ -763,7 +805,10 @@ private void DefineMethod(FunctionMemberAst functionMemberAst) var returnType = functionMemberAst.GetReturnType(); if (returnType == null) { - _parser.ReportError(functionMemberAst.ReturnType.Extent, () => ParserStrings.TypeNotFound, functionMemberAst.ReturnType.TypeName.FullName); + _parser.ReportError(functionMemberAst.ReturnType.Extent, + nameof(ParserStrings.TypeNotFound), + ParserStrings.TypeNotFound, + functionMemberAst.ReturnType.TypeName.FullName); return; } var method = _typeBuilder.DefineMethod(functionMemberAst.Name, attributes, returnType, parameterTypes); @@ -1019,7 +1064,9 @@ internal static List Sort(List defineEnumHel { if (!result.Contains(helper)) { - parser.ReportError(helper._enumDefinitionAst.Extent, () => ParserStrings.CycleInEnumInitializers); + parser.ReportError(helper._enumDefinitionAst.Extent, + nameof(ParserStrings.CycleInEnumInitializers), + ParserStrings.CycleInEnumInitializers); } } } @@ -1057,11 +1104,15 @@ internal void DefineEnum() if (constValue != null && LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constValue.GetType()))) { - _parser.ReportError(enumerator.InitialValue.Extent, () => ParserStrings.EnumeratorValueTooLarge); + _parser.ReportError(enumerator.InitialValue.Extent, + nameof(ParserStrings.EnumeratorValueTooLarge), + ParserStrings.EnumeratorValueTooLarge); } else { - _parser.ReportError(enumerator.InitialValue.Extent, () => ParserStrings.CannotConvertValue, + _parser.ReportError(enumerator.InitialValue.Extent, + nameof(ParserStrings.CannotConvertValue), + ParserStrings.CannotConvertValue, ToStringCodeMethods.Type(typeof(int))); } } @@ -1069,17 +1120,24 @@ internal void DefineEnum() } else { - _parser.ReportError(enumerator.InitialValue.Extent, () => ParserStrings.EnumeratorValueMustBeConstant); + _parser.ReportError(enumerator.InitialValue.Extent, + nameof(ParserStrings.EnumeratorValueMustBeConstant), + ParserStrings.EnumeratorValueMustBeConstant); } } else if (valueTooBig) { - _parser.ReportError(enumerator.Extent, () => ParserStrings.EnumeratorValueTooLarge); + _parser.ReportError(enumerator.Extent, + nameof(ParserStrings.EnumeratorValueTooLarge), + ParserStrings.EnumeratorValueTooLarge); } if (definedEnumerators.Contains(enumerator.Name)) { - _parser.ReportError(enumerator.Extent, () => ParserStrings.MemberAlreadyDefined, enumerator.Name); + _parser.ReportError(enumerator.Extent, + nameof(ParserStrings.MemberAlreadyDefined), + ParserStrings.MemberAlreadyDefined, + enumerator.Name); } else { @@ -1204,8 +1262,11 @@ internal static Assembly DefineTypes(Parser parser, Ast rootAst, TypeDefinitionA // // Presumably this catch could go away when we will not create Type at parse time. // Error checking should be moved/added to semantic checks. - parser.ReportError(helper._typeDefinitionAst.Extent, () => ParserStrings.TypeCreationError, - helper._typeBuilder.Name, e.Message); + parser.ReportError(helper._typeDefinitionAst.Extent, + nameof(ParserStrings.TypeCreationError), + ParserStrings.TypeCreationError, + helper._typeBuilder.Name, + e.Message); } } diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 971e4be4808..490487628e3 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -212,7 +212,9 @@ private ScriptBlockAst ParseTask(string fileName, string input, List toke } else { - ReportError(_tokenizer.CurrentExtent(), () => ParserStrings.ScriptTooComplicated); + ReportError(_tokenizer.CurrentExtent(), + nameof(ParserStrings.ScriptTooComplicated), + ParserStrings.ScriptTooComplicated); } } @@ -559,7 +561,9 @@ internal void RequireStatementTerminator() } else if (terminatorToken.Kind != TokenKind.EndOfInput) { - ReportIncompleteInput(terminatorToken.Extent, () => ParserStrings.MissingStatementTerminator); + ReportIncompleteInput(terminatorToken.Extent, + nameof(ParserStrings.MissingStatementTerminator), + ParserStrings.MissingStatementTerminator); } } @@ -864,7 +868,8 @@ private ParamBlockAst ParamBlockRule() UngetToken(rParen); endExtent = Before(rParen); ReportIncompleteInput(After(parameters != null && parameters.Any() ? parameters.Last().Extent : lparen.Extent), - () => ParserStrings.MissingEndParenthesisInFunctionParameterList); + nameof(ParserStrings.MissingEndParenthesisInFunctionParameterList), + ParserStrings.MissingEndParenthesisInFunctionParameterList); } List attributes = new List(); @@ -882,7 +887,10 @@ 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, () => ParserStrings.TypeNotAllowedBeforeParam, attr.TypeName.FullName); + ReportError(attr.Extent, + nameof(ParserStrings.TypeNotAllowedBeforeParam), + ParserStrings.TypeNotAllowedBeforeParam, + attr.TypeName.FullName); } } } @@ -907,8 +915,10 @@ private List ParameterListRule() { // ErrorRecovery: ?? - ReportIncompleteInput(After(commaToken), () => ParserStrings.MissingExpressionAfterToken, - commaToken.Kind.Text()); + ReportIncompleteInput(After(commaToken), + nameof(ParserStrings.MissingExpressionAfterToken), + ParserStrings.MissingExpressionAfterToken, + commaToken.Kind.Text()); } break; } @@ -954,7 +964,9 @@ private ParameterAst ParameterRule() { // ErrorRecovery: skip to closing paren because returning null signals the last parameter. - ReportIncompleteInput(After(attributes.Last()), () => ParserStrings.InvalidFunctionParameter); + ReportIncompleteInput(After(attributes.Last()), + nameof(ParserStrings.InvalidFunctionParameter), + ParserStrings.InvalidFunctionParameter); SyncOnError(true, TokenKind.RParen); // Even though we don't have a complete parameter, we do have attributes. Intellisense @@ -976,7 +988,10 @@ private ParameterAst ParameterRule() defaultValue = ExpressionRule(); if (defaultValue == null) { - ReportIncompleteInput(After(equalsToken), () => ParserStrings.MissingExpressionAfterToken, equalsToken.Kind.Text()); + ReportIncompleteInput(After(equalsToken), + nameof(ParserStrings.MissingExpressionAfterToken), + ParserStrings.MissingExpressionAfterToken, + equalsToken.Kind.Text()); } } } @@ -1040,7 +1055,9 @@ private AttributeBaseAst AttributeRule() // ErrorRecovery: Return null so we stop looking for attributes. Resync(lBracket); // TypeNameRule might have consumed some tokens - ReportIncompleteInput(After(lBracket), () => ParserStrings.MissingTypename); + ReportIncompleteInput(After(lBracket), + nameof(ParserStrings.MissingTypename), + ParserStrings.MissingTypename); return null; } @@ -1072,7 +1089,9 @@ private AttributeBaseAst AttributeRule() UngetToken(rParen); rParen = null; - ReportIncompleteInput(After(lastItemExtent), () => ParserStrings.MissingEndParenthesisInExpression); + ReportIncompleteInput(After(lastItemExtent), + nameof(ParserStrings.MissingEndParenthesisInExpression), + ParserStrings.MissingEndParenthesisInExpression); } SkipNewlines(); Token rBracket = NextToken(); @@ -1085,7 +1104,9 @@ private AttributeBaseAst AttributeRule() // Don't bother reporting a missing ']' if we reported a missing ')'. if (rParen != null) { - ReportIncompleteInput(After(rParen), () => ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); + ReportIncompleteInput(After(rParen), + nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), + ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); } } @@ -1103,7 +1124,9 @@ private AttributeBaseAst AttributeRule() if (lParenOrRBracket.Kind != TokenKind.RBracket) { UngetToken(lParenOrRBracket); - ReportError(Before(lParenOrRBracket), () => ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); + ReportError(Before(lParenOrRBracket), + nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), + ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); lParenOrRBracket = null; } @@ -1150,7 +1173,9 @@ private void AttributeArgumentsRule(ICollection positionalArgumen // ErrorRecovery: ? IScriptExtent errorPosition = After(token); - ReportIncompleteInput(errorPosition, () => ParserStrings.MissingExpressionInNamedArgument); + ReportIncompleteInput(errorPosition, + nameof(ParserStrings.MissingExpressionInNamedArgument), + ParserStrings.MissingExpressionInNamedArgument); expr = new ErrorExpressionAst(errorPosition); SyncOnError(true, TokenKind.Comma, TokenKind.RParen, TokenKind.RBracket, TokenKind.NewLine); } @@ -1176,7 +1201,10 @@ private void AttributeArgumentsRule(ICollection positionalArgumen { // ErrorRecovery: this is a semantic error, so just keep parsing. - ReportError(name.Extent, () => ParserStrings.DuplicateNamedArgument, name.Value); + ReportError(name.Extent, + nameof(ParserStrings.DuplicateNamedArgument), + ParserStrings.DuplicateNamedArgument, + name.Value); } else { @@ -1194,7 +1222,9 @@ private void AttributeArgumentsRule(ICollection positionalArgumen // ErrorRecovery: Pretend we saw the argument and keep going. IScriptExtent errorExtent = After(commaToken); - ReportIncompleteInput(errorExtent, () => ParserStrings.MissingExpressionAfterToken, + ReportIncompleteInput(errorExtent, + nameof(ParserStrings.MissingExpressionAfterToken), + ParserStrings.MissingExpressionAfterToken, commaToken.Kind.Text()); positionalArguments.Add(new ErrorExpressionAst(errorExtent)); lastItemExtent = errorExtent; @@ -1307,13 +1337,18 @@ private ITypeName FinishTypeNameRule(Token typeName, bool unBracketedGenericArg if (token.Kind != TokenKind.EndOfInput) { - ReportError(token.Extent, () => ParserStrings.UnexpectedToken, token.Text); + ReportError(token.Extent, + nameof(ParserStrings.UnexpectedToken), + ParserStrings.UnexpectedToken, + token.Text); SyncOnError(true, TokenKind.RBracket); } else { UngetToken(token); - ReportIncompleteInput(After(lbracket), () => ParserStrings.MissingTypename); + ReportIncompleteInput(After(lbracket), + nameof(ParserStrings.MissingTypename), + ParserStrings.MissingTypename); } return new TypeName(typeName.Extent, typeName.Text); } @@ -1325,7 +1360,9 @@ private ITypeName FinishTypeNameRule(Token typeName, bool unBracketedGenericArg string assemblyNameSpec = _tokenizer.GetAssemblyNameSpec(); if (string.IsNullOrWhiteSpace(assemblyNameSpec)) { - ReportError(After(token), () => ParserStrings.MissingAssemblyNameSpecification); + ReportError(After(token), + nameof(ParserStrings.MissingAssemblyNameSpecification), + ParserStrings.MissingAssemblyNameSpecification); return new TypeName(typeName.Extent, typeName.Text); } return new TypeName(ExtentOf(typeName.Extent, _tokenizer.CurrentExtent()), typeName.Text, assemblyNameSpec); @@ -1347,7 +1384,9 @@ private ITypeName GetSingleGenericArgument(Token firstToken) if (token.Kind != TokenKind.Identifier) { UngetToken(token); - ReportIncompleteInput(After(token), () => ParserStrings.MissingTypename); + ReportIncompleteInput(After(token), + nameof(ParserStrings.MissingTypename), + ParserStrings.MissingTypename); return new TypeName(firstToken.Extent, ":ErrorTypeName:"); } @@ -1360,7 +1399,9 @@ private ITypeName GetSingleGenericArgument(Token firstToken) // ErrorRecovery: pretend we saw the closing bracket. UngetToken(rBracket); - ReportIncompleteInput(Before(rBracket), () => ParserStrings.EndSquareBracketExpectedAtEndOfType); + ReportIncompleteInput(Before(rBracket), + nameof(ParserStrings.EndSquareBracketExpectedAtEndOfType), + ParserStrings.EndSquareBracketExpectedAtEndOfType); } } @@ -1396,7 +1437,9 @@ private ITypeName GenericTypeArgumentsRule(Token genericTypeName, Token firstTok } else { - ReportIncompleteInput(After(commaOrRBracketToken), () => ParserStrings.MissingTypename); + ReportIncompleteInput(After(commaOrRBracketToken), + nameof(ParserStrings.MissingTypename), + ParserStrings.MissingTypename); typeName = new TypeName(commaOrRBracketToken.Extent, ":ErrorTypeName:"); } genericArguments.Add(typeName); @@ -1408,7 +1451,8 @@ private ITypeName GenericTypeArgumentsRule(Token genericTypeName, Token firstTok UngetToken(commaOrRBracketToken); ReportIncompleteInput(Before(commaOrRBracketToken), - () => ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); + nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), + ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); commaOrRBracketToken = null; } @@ -1427,7 +1471,9 @@ private ITypeName GenericTypeArgumentsRule(Token genericTypeName, Token firstTok string assemblyNameSpec = _tokenizer.GetAssemblyNameSpec(); if (string.IsNullOrEmpty(assemblyNameSpec)) { - ReportError(After(token), () => ParserStrings.MissingAssemblyNameSpecification); + ReportError(After(token), + nameof(ParserStrings.MissingAssemblyNameSpecification), + ParserStrings.MissingAssemblyNameSpecification); } else { @@ -1460,7 +1506,9 @@ private ITypeName CompleteArrayTypeName(ITypeName elementType, TypeName typeForA // ErrorRecovery: just pretend we saw a ']'. UngetToken(token); - ReportError(After(lastComma), () => ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); + ReportError(After(lastComma), + nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), + ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); } elementType = new ArrayTypeName(ExtentOf(elementType.Extent, token.Extent), elementType, dim); @@ -1472,13 +1520,18 @@ private ITypeName CompleteArrayTypeName(ITypeName elementType, TypeName typeForA case TokenKind.EndOfInput: UngetToken(firstTokenAfterLBracket); - ReportError(Before(firstTokenAfterLBracket), () => ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); + ReportError(Before(firstTokenAfterLBracket), + nameof(ParserStrings.EndSquareBracketExpectedAtEndOfAttribute), + ParserStrings.EndSquareBracketExpectedAtEndOfAttribute); break; default: // ErrorRecovery: sync to ']', and return null to avoid cascading errors. - ReportError(firstTokenAfterLBracket.Extent, () => ParserStrings.UnexpectedToken, firstTokenAfterLBracket.Text); + ReportError(firstTokenAfterLBracket.Extent, + nameof(ParserStrings.UnexpectedToken), + ParserStrings.UnexpectedToken, + firstTokenAfterLBracket.Text); SyncOnError(true, TokenKind.RBracket); break; } @@ -1490,7 +1543,9 @@ private ITypeName CompleteArrayTypeName(ITypeName elementType, TypeName typeForA var assemblyName = _tokenizer.GetAssemblyNameSpec(); if (string.IsNullOrEmpty(assemblyName)) { - ReportError(After(token), () => ParserStrings.MissingAssemblyNameSpecification); + ReportError(After(token), + nameof(ParserStrings.MissingAssemblyNameSpecification), + ParserStrings.MissingAssemblyNameSpecification); } else { @@ -1526,7 +1581,10 @@ private bool CompleteScriptBlockBody(Token lCurly, ref IScriptExtent bodyExtent, UngetToken(rCurly); endScriptBlock = bodyExtent ?? lCurly.Extent; - ReportIncompleteInput(lCurly.Extent, rCurly.Extent, () => ParserStrings.MissingEndCurlyBrace); + ReportIncompleteInput(lCurly.Extent, + rCurly.Extent, + nameof(ParserStrings.MissingEndCurlyBrace), + ParserStrings.MissingEndCurlyBrace); } else { @@ -1550,7 +1608,10 @@ 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, () => ParserStrings.UnexpectedToken, token.Text); + ReportError(token.Extent, + nameof(ParserStrings.UnexpectedToken), + ParserStrings.UnexpectedToken, + token.Text); return false; } } @@ -1643,7 +1704,10 @@ private ScriptBlockAst NamedBlockListRule(Token lCurly, List } // Report error about the unexpected token. - ReportError(blockNameToken.Extent, () => ParserStrings.MissingNamedBlocks, blockNameToken.Text); + ReportError(blockNameToken.Extent, + nameof(ParserStrings.MissingNamedBlocks), + ParserStrings.MissingNamedBlocks, + blockNameToken.Text); goto return_script_block_ast; case TokenKind.RCurly: @@ -1673,7 +1737,9 @@ 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), - () => ParserStrings.MissingNamedStatementBlock, blockNameToken.Kind.Text()); + nameof(ParserStrings.MissingNamedStatementBlock), + ParserStrings.MissingNamedStatementBlock, + blockNameToken.Kind.Text()); statementBlock = new StatementBlockAst(blockNameToken.Extent, Utils.EmptyArray(), null); } else @@ -1703,7 +1769,9 @@ private ScriptBlockAst NamedBlockListRule(Token lCurly, List // ErrorRecovery: this is a semantic error, we can keep parsing w/o trouble. ReportError(extent, - () => ParserStrings.DuplicateScriptCommandClause, blockNameToken.Kind.Text()); + nameof(ParserStrings.DuplicateScriptCommandClause), + ParserStrings.DuplicateScriptCommandClause, + blockNameToken.Kind.Text()); } SkipNewlinesAndSemicolons(); @@ -1741,7 +1809,10 @@ private StatementBlockAst StatementBlockRule() UngetToken(rCurly); endBlock = statementListExtent ?? lCurly.Extent; - ReportIncompleteInput(lCurly.Extent, rCurly.Extent, () => ParserStrings.MissingEndCurlyBrace); + ReportIncompleteInput(lCurly.Extent, + rCurly.Extent, + nameof(ParserStrings.MissingEndCurlyBrace), + ParserStrings.MissingEndCurlyBrace); } else { @@ -1861,7 +1932,9 @@ private StatementAst StatementRule() } else { - ReportError(attributes[0].Extent, () => ParserStrings.UnexpectedAttribute, + ReportError(attributes[0].Extent, + nameof(ParserStrings.UnexpectedAttribute), + ParserStrings.UnexpectedAttribute, attributes[0].TypeName.FullName); } } @@ -1869,7 +1942,9 @@ private StatementAst StatementRule() { foreach (var attr in attributes.Where(attr => !(attr is AttributeAst))) { - ReportError(attr.Extent, () => ParserStrings.TypeNotAllowedBeforeStatement, + ReportError(attr.Extent, + nameof(ParserStrings.TypeNotAllowedBeforeStatement), + ParserStrings.TypeNotAllowedBeforeStatement, attr.TypeName.FullName); break; } @@ -1941,7 +2016,10 @@ private StatementAst StatementRule() case TokenKind.From: case TokenKind.Define: case TokenKind.Var: - ReportError(token.Extent, () => ParserStrings.ReservedKeywordNotAllowed, token.Kind.Text()); + ReportError(token.Extent, + nameof(ParserStrings.ReservedKeywordNotAllowed), + ParserStrings.ReservedKeywordNotAllowed, + token.Kind.Text()); statement = new ErrorStatementAst(token.Extent); break; case TokenKind.Label: @@ -1986,7 +2064,9 @@ 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, () => ParserStrings.UsingMustBeAtStartOfScript); + ReportError(statement.Extent, + nameof(ParserStrings.UsingMustBeAtStartOfScript), + ParserStrings.UsingMustBeAtStartOfScript); break; default: @@ -2192,7 +2272,10 @@ private StatementAst BlockStatementRule(Token kindToken) // ErrorRecovery: nothing more to look for, so just return the error statement. if (body == null) { - ReportIncompleteInput(After(kindToken.Extent), () => ParserStrings.MissingStatementAfterKeyword, kindToken.Text); + ReportIncompleteInput(After(kindToken.Extent), + nameof(ParserStrings.MissingStatementAfterKeyword), + ParserStrings.MissingStatementAfterKeyword, + kindToken.Text); return new ErrorStatementAst(ExtentOf(kindToken, kindToken)); } @@ -2226,7 +2309,10 @@ 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), () => ParserStrings.MissingStatementAfterKeyword, inlineScriptToken.Text); + ReportIncompleteInput(After(inlineScriptToken), + nameof(ParserStrings.MissingStatementAfterKeyword), + ParserStrings.MissingStatementAfterKeyword, + inlineScriptToken.Text); return false; } @@ -2263,7 +2349,9 @@ private StatementAst IfStatementRule(Token ifToken) UngetToken(lParen); ReportIncompleteInput(After(keyword), - () => ParserStrings.MissingOpenParenthesisInIfStatement, keyword.Text); + nameof(ParserStrings.MissingOpenParenthesisInIfStatement), + ParserStrings.MissingOpenParenthesisInIfStatement, + keyword.Text); return new ErrorStatementAst(ExtentOf(ifToken, keyword), componentAsts); } @@ -2276,7 +2364,9 @@ private StatementAst IfStatementRule(Token ifToken) IScriptExtent errorPosition = After(lParen); ReportIncompleteInput(errorPosition, - () => ParserStrings.IfStatementMissingCondition, keyword.Text); + nameof(ParserStrings.IfStatementMissingCondition), + ParserStrings.IfStatementMissingCondition, + keyword.Text); condition = new ErrorStatementAst(errorPosition); } else @@ -2296,7 +2386,9 @@ private StatementAst IfStatementRule(Token ifToken) if (!(condition is ErrorStatementAst)) { ReportIncompleteInput(rParen.Extent, - () => ParserStrings.MissingEndParenthesisAfterStatement, keyword.Text); + nameof(ParserStrings.MissingEndParenthesisAfterStatement), + ParserStrings.MissingEndParenthesisAfterStatement, + keyword.Text); } return new ErrorStatementAst(ExtentOf(ifToken, Before(rParen)), componentAsts); } @@ -2308,7 +2400,9 @@ 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, () => ParserStrings.MissingStatementBlock, keyword.Text); + ReportIncompleteInput(rParen.Extent, + nameof(ParserStrings.MissingStatementBlock), + keyword.Text); return new ErrorStatementAst(ExtentOf(ifToken, rParen), componentAsts); } @@ -2335,7 +2429,9 @@ 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), () => ParserStrings.MissingStatementBlockAfterElse); + ReportIncompleteInput(After(keyword), + nameof(ParserStrings.MissingStatementBlockAfterElse), + ParserStrings.MissingStatementBlockAfterElse); return new ErrorStatementAst(ExtentOf(ifToken, keyword), componentAsts); } } @@ -2456,7 +2552,9 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: pretend we saw the filename and continue. isError = true; - isIncompleteError = ReportIncompleteInput(After(switchParameterToken), () => ParserStrings.MissingFilenameOption); + isIncompleteError = ReportIncompleteInput(After(switchParameterToken), + nameof(ParserStrings.MissingFilenameOption), + ParserStrings.MissingFilenameOption); if (!specifiedFlags.ContainsKey("file")) { @@ -2480,7 +2578,9 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: just ignore the token, continue parsing. isError = true; - ReportError(switchParameterToken.Extent, () => ParserStrings.InvalidSwitchFlag, + ReportError(switchParameterToken.Extent, + nameof(ParserStrings.InvalidSwitchFlag), + ParserStrings.InvalidSwitchFlag, ((ParameterToken)switchParameterToken).ParameterName); } @@ -2504,7 +2604,9 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: nothing special this is a semantic error. isError = true; - ReportError(lParen.Extent, () => ParserStrings.PipelineValueRequired); + ReportError(lParen.Extent, + nameof(ParserStrings.PipelineValueRequired), + ParserStrings.PipelineValueRequired); } needErrorCondition = true; // need to add condition ast to the error statement if the parsing fails @@ -2515,7 +2617,9 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: pretend we saw the condition and keep parsing. isError = true; - isIncompleteError = ReportIncompleteInput(After(lParen), () => ParserStrings.PipelineValueRequired); + isIncompleteError = ReportIncompleteInput(After(lParen), + nameof(ParserStrings.PipelineValueRequired), + ParserStrings.PipelineValueRequired); } else { @@ -2534,7 +2638,8 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke isError = true; isIncompleteError = ReportIncompleteInput(After(endErrorStatement), - () => ParserStrings.MissingEndParenthesisInSwitchStatement); + nameof(ParserStrings.MissingEndParenthesisInSwitchStatement), + ParserStrings.MissingEndParenthesisInSwitchStatement); } } else @@ -2548,7 +2653,8 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke { isError = true; isIncompleteError = ReportIncompleteInput(After(endErrorStatement), - () => ParserStrings.PipelineValueRequired); + nameof(ParserStrings.PipelineValueRequired), + ParserStrings.PipelineValueRequired); } else { @@ -2570,7 +2676,9 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke if (!isIncompleteError) { isError = true; - ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingCurlyBraceInSwitchStatement); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingCurlyBraceInSwitchStatement), + ParserStrings.MissingCurlyBraceInSwitchStatement); } } else @@ -2588,7 +2696,9 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // So don't look for a body, hope we find the '}' next. isError = true; - ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingSwitchConditionExpression); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingSwitchConditionExpression), + ParserStrings.MissingSwitchConditionExpression); // Consume a closing curly, if there is one, to avoid an extra error if (PeekToken().Kind == TokenKind.RCurly) { @@ -2605,7 +2715,8 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke isError = true; isIncompleteError = ReportIncompleteInput(After(endErrorStatement), - () => ParserStrings.MissingSwitchStatementClause); + nameof(ParserStrings.MissingSwitchStatementClause), + ParserStrings.MissingSwitchStatementClause); } else { @@ -2623,7 +2734,9 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke // ErrorRecovery: just report the error and continue, forget the previous default clause. isError = true; - ReportError(clauseCondition.Extent, () => ParserStrings.MultipleSwitchDefaultClauses); + ReportError(clauseCondition.Extent, + nameof(ParserStrings.MultipleSwitchDefaultClauses), + ParserStrings.MultipleSwitchDefaultClauses); } @default = clauseBody; } @@ -2646,7 +2759,10 @@ private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToke if (!isIncompleteError) { isError = true; - ReportIncompleteInput(lCurly.Extent, token.Extent, () => ParserStrings.MissingEndCurlyBrace); + ReportIncompleteInput(lCurly.Extent, + token.Extent, + nameof(ParserStrings.MissingEndCurlyBrace), + ParserStrings.MissingEndCurlyBrace); } break; } @@ -2686,7 +2802,9 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom if (configurationNameToken.Kind == TokenKind.LCurly) { - ReportError(After(startExtent), () => ParserStrings.MissingConfigurationName); + ReportError(After(startExtent), + nameof(ParserStrings.MissingConfigurationName), + ParserStrings.MissingConfigurationName); // Try reading the configuration body - this should keep the parse in sync - but we won't return it ScriptBlockExpressionRule(configurationNameToken); @@ -2698,7 +2816,8 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom UngetToken(configurationNameToken); ReportIncompleteInput(After(configurationNameToken.Extent), - () => ParserStrings.MissingConfigurationName); + nameof(ParserStrings.MissingConfigurationName), + ParserStrings.MissingConfigurationName); return null; } @@ -2710,7 +2829,9 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom if (configurationName == null) { isError = true; - ReportIncompleteInput(configurationNameToken.Extent, () => ParserStrings.MissingConfigurationName); + ReportIncompleteInput(configurationNameToken.Extent, + nameof(ParserStrings.MissingConfigurationName), + ParserStrings.MissingConfigurationName); } else { @@ -2724,7 +2845,10 @@ 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, () => ParserStrings.InvalidConfigurationName, simpleConfigurationNameValue ?? string.Empty); + ReportError(configurationName.Extent, + nameof(ParserStrings.InvalidConfigurationName), + ParserStrings.InvalidConfigurationName, + simpleConfigurationNameValue ?? string.Empty); } } } @@ -2753,7 +2877,8 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom if (PsUtils.IsRunningOnProcessorArchitectureARM() || Runspace.DefaultRunspace.ExecutionContext.LanguageMode == PSLanguageMode.ConstrainedLanguage) { ReportError(configurationToken.Extent, - () => ParserStrings.ConfigurationNotAllowedInConstrainedLanguage, + nameof(ParserStrings.ConfigurationNotAllowedInConstrainedLanguage), + ParserStrings.ConfigurationNotAllowedInConstrainedLanguage, configurationToken.Kind.Text()); return null; } @@ -2762,7 +2887,8 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom if (Utils.IsWinPEHost()) { ReportError(configurationToken.Extent, - () => ParserStrings.ConfigurationNotAllowedOnWinPE, + nameof(ParserStrings.ConfigurationNotAllowedOnWinPE), + ParserStrings.ConfigurationNotAllowedOnWinPE, configurationToken.Kind.Text()); return null; } @@ -2824,7 +2950,9 @@ 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, () => e.ToString()); + ReportError(configurationKeywordToken.Extent, + "ParserError", + e.ToString()); return null; } } @@ -2844,7 +2972,9 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom Token lCurly = NextToken(); if (lCurly.Kind != TokenKind.LCurly) { - ReportIncompleteInput(After(lCurly.Extent), () => ParserStrings.MissingCurlyInConfigurationStatement); + ReportIncompleteInput(After(lCurly.Extent), + nameof(ParserStrings.MissingCurlyInConfigurationStatement), + ParserStrings.MissingCurlyInConfigurationStatement); isError = true; UngetToken(lCurly); } @@ -2862,7 +2992,9 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom } if (configurationBodyScriptBlock == null) { - ReportError(After(lCurly.Extent), () => ParserStrings.ConfigurationBodyEmpty); + ReportError(After(lCurly.Extent), + nameof(ParserStrings.ConfigurationBodyEmpty), + ParserStrings.ConfigurationBodyEmpty); return null; } } @@ -3006,7 +3138,9 @@ 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, () => "ConfigurationStatementToken: " + e); + ReportError(configurationKeywordToken.Extent, + "ParserError", + "ConfigurationStatementToken: " + e); return null; } finally @@ -3051,7 +3185,9 @@ private ExpressionAst GetWordOrExpression(Token keywordToken) { // ErrorRecovery: report incomplete statement and return UngetToken(nameToken); - ReportIncompleteInput(After(keywordToken), () => ParserStrings.RequiredNameOrExpressionMissing); + ReportIncompleteInput(After(keywordToken), + nameof(ParserStrings.RequiredNameOrExpressionMissing), + ParserStrings.RequiredNameOrExpressionMissing); return null; } @@ -3059,7 +3195,10 @@ private ExpressionAst GetWordOrExpression(Token keywordToken) if (argument == null) { var extent = keywordToken.Extent; - ReportError(After(extent), () => ParserStrings.ParameterRequiresArgument, keywordToken.Text); + ReportError(After(extent), + nameof(ParserStrings.ParameterRequiresArgument), + ParserStrings.ParameterRequiresArgument, + keywordToken.Text); } return argument; } @@ -3106,7 +3245,9 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo { // ErrorRecovery: pretend we saw the throttle limit and continue. - ReportIncompleteInput(After(foreachParameterToken), () => ParserStrings.MissingThrottleLimit); + ReportIncompleteInput(After(foreachParameterToken), + nameof(ParserStrings.MissingThrottleLimit), + ParserStrings.MissingThrottleLimit); } } else @@ -3114,7 +3255,9 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo // ErrorRecovery: just ignore the token, continue parsing. endErrorStatement = foreachParameterToken.Extent; - ReportError(foreachParameterToken.Extent, () => ParserStrings.InvalidForeachFlag, + ReportError(foreachParameterToken.Extent, + nameof(ParserStrings.InvalidForeachFlag), + ParserStrings.InvalidForeachFlag, ((ParameterToken)foreachParameterToken).ParameterName); } @@ -3130,7 +3273,9 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo UngetToken(lParen); endErrorStatement = forEachToken.Extent; ReportIncompleteInput(After(endErrorStatement), - () => ParserStrings.MissingOpenParenthesisAfterKeyword, forEachToken.Kind.Text()); + nameof(ParserStrings.MissingOpenParenthesisAfterKeyword), + ParserStrings.MissingOpenParenthesisAfterKeyword, + forEachToken.Kind.Text()); return new ErrorStatementAst(ExtentOf(startOfStatement, endErrorStatement)); } SkipNewlines(); @@ -3142,7 +3287,9 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo UngetToken(token); endErrorStatement = lParen.Extent; - ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingVariableNameAfterForeach); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingVariableNameAfterForeach), + ParserStrings.MissingVariableNameAfterForeach); return new ErrorStatementAst(ExtentOf(startOfStatement, endErrorStatement)); } @@ -3158,7 +3305,9 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo UngetToken(inToken); endErrorStatement = variableAst.Extent; - ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingInInForeach); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingInInForeach), + ParserStrings.MissingInInForeach); } else { @@ -3169,7 +3318,9 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo // ErrorRecovery: assume the rest of the statement is missing. endErrorStatement = inToken.Extent; - ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingForeachExpression); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingForeachExpression), + ParserStrings.MissingForeachExpression); } else { @@ -3181,7 +3332,9 @@ private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachTo UngetToken(rParen); endErrorStatement = pipeline.Extent; - ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingEndParenthesisAfterForeach); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingEndParenthesisAfterForeach), + ParserStrings.MissingEndParenthesisAfterForeach); } else { @@ -3191,7 +3344,9 @@ 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), () => ParserStrings.MissingForeachStatement); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingForeachStatement), + ParserStrings.MissingForeachStatement); } } } @@ -3241,7 +3396,9 @@ private StatementAst ForStatementRule(LabelToken labelToken, Token forToken) UngetToken(lParen); endErrorStatement = forToken.Extent; ReportIncompleteInput(After(endErrorStatement), - () => ParserStrings.MissingOpenParenthesisAfterKeyword, forToken.Kind.Text()); + nameof(ParserStrings.MissingOpenParenthesisAfterKeyword), + ParserStrings.MissingOpenParenthesisAfterKeyword, + forToken.Kind.Text()); return new ErrorStatementAst(ExtentOf(labelToken ?? forToken, endErrorStatement)); } SkipNewlines(); @@ -3283,7 +3440,9 @@ private StatementAst ForStatementRule(LabelToken labelToken, Token forToken) endErrorStatement = lParen.Extent; } ReportIncompleteInput(After(endErrorStatement), - () => ParserStrings.MissingEndParenthesisAfterStatement, forToken.Kind.Text()); + nameof(ParserStrings.MissingEndParenthesisAfterStatement), + ParserStrings.MissingEndParenthesisAfterStatement, + forToken.Kind.Text()); } else { @@ -3293,7 +3452,9 @@ private StatementAst ForStatementRule(LabelToken labelToken, Token forToken) // ErrorRecovery: return an error statement. endErrorStatement = rParen.Extent; ReportIncompleteInput(After(endErrorStatement), - () => ParserStrings.MissingLoopStatement, forToken.Kind.Text()); + nameof(ParserStrings.MissingLoopStatement), + ParserStrings.MissingLoopStatement, + forToken.Kind.Text()); } } @@ -3322,7 +3483,9 @@ private StatementAst WhileStatementRule(LabelToken labelToken, Token whileToken) UngetToken(lParen); ReportIncompleteInput(After(whileToken), - () => ParserStrings.MissingOpenParenthesisAfterKeyword, whileToken.Text); + nameof(ParserStrings.MissingOpenParenthesisAfterKeyword), + ParserStrings.MissingOpenParenthesisAfterKeyword, + whileToken.Text); return new ErrorStatementAst(ExtentOf(labelToken ?? whileToken, whileToken)); } @@ -3336,7 +3499,9 @@ private StatementAst WhileStatementRule(LabelToken labelToken, Token whileToken) IScriptExtent errorPosition = After(lParen); ReportIncompleteInput(errorPosition, - () => ParserStrings.MissingExpressionAfterKeyword, whileToken.Kind.Text()); + nameof(ParserStrings.MissingExpressionAfterKeyword), + ParserStrings.MissingExpressionAfterKeyword, + whileToken.Kind.Text()); condition = new ErrorStatementAst(errorPosition); } else @@ -3356,7 +3521,9 @@ private StatementAst WhileStatementRule(LabelToken labelToken, Token whileToken) if (!(condition is ErrorStatementAst)) { ReportIncompleteInput(After(condition), - () => ParserStrings.MissingEndParenthesisAfterStatement, whileToken.Kind.Text()); + nameof(ParserStrings.MissingEndParenthesisAfterStatement), + ParserStrings.MissingEndParenthesisAfterStatement, + whileToken.Kind.Text()); } return new ErrorStatementAst(ExtentOf(labelToken ?? whileToken, condition), GetNestedErrorAsts(errorCondition)); } @@ -3368,7 +3535,9 @@ private StatementAst WhileStatementRule(LabelToken labelToken, Token whileToken) // ErrorRecovery: assume the next token is a newline or part of something else. ReportIncompleteInput(After(rParen), - () => ParserStrings.MissingLoopStatement, whileToken.Kind.Text()); + nameof(ParserStrings.MissingLoopStatement), + ParserStrings.MissingLoopStatement, + whileToken.Kind.Text()); return new ErrorStatementAst(ExtentOf(labelToken ?? whileToken, rParen), GetNestedErrorAsts(errorCondition)); } @@ -3410,7 +3579,10 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw } catch (Exception e) { - ReportError(functionName.Extent, () => ParserStrings.DynamicKeywordPreParseException, keywordData.ResourceName, e.ToString()); + ReportError(functionName.Extent, + nameof(ParserStrings.DynamicKeywordPreParseException), + ParserStrings.DynamicKeywordPreParseException, + keywordData.ResourceName, e.ToString()); return null; } } @@ -3418,14 +3590,20 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw if (keywordData.IsReservedKeyword) { // ErrorRecovery: eat the token - ReportError(functionName.Extent, () => ParserStrings.UnsupportedReservedKeyword, keywordData.Keyword); + ReportError(functionName.Extent, + nameof(ParserStrings.UnsupportedReservedKeyword), + ParserStrings.UnsupportedReservedKeyword, + keywordData.Keyword); return null; } if (keywordData.HasReservedProperties) { // ErrorRecovery: eat the token - ReportError(functionName.Extent, () => ParserStrings.UnsupportedReservedProperty, "'Require', 'Trigger', 'Notify', 'Before', 'After' and 'Subscribe'"); + ReportError(functionName.Extent, + nameof(ParserStrings.UnsupportedReservedProperty), + ParserStrings.UnsupportedReservedProperty, + "'Require', 'Trigger', 'Notify', 'Before', 'After' and 'Subscribe'"); return null; } @@ -3453,12 +3631,16 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw if (keywordData.NameMode == DynamicKeywordNameMode.NameRequired || keywordData.NameMode == DynamicKeywordNameMode.SimpleNameRequired) { - ReportIncompleteInput(After(functionName), () => ParserStrings.RequiredNameOrExpressionMissing); + ReportIncompleteInput(After(functionName), + nameof(ParserStrings.RequiredNameOrExpressionMissing), + ParserStrings.RequiredNameOrExpressionMissing); } else { // Name not required so report missing brace - ReportIncompleteInput(After(functionName.Extent), () => ParserStrings.MissingBraceInObjectDefinition); + ReportIncompleteInput(After(functionName.Extent), + nameof(ParserStrings.MissingBraceInObjectDefinition), + ParserStrings.MissingBraceInObjectDefinition); } return null; } @@ -3470,7 +3652,9 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw lCurly = nameToken; if (keywordData.NameMode == DynamicKeywordNameMode.NameRequired || keywordData.NameMode == DynamicKeywordNameMode.SimpleNameRequired) { - ReportError(After(functionName), () => ParserStrings.RequiredNameOrExpressionMissing); + ReportError(After(functionName), + nameof(ParserStrings.RequiredNameOrExpressionMissing), + ParserStrings.RequiredNameOrExpressionMissing); UngetToken(nameToken); return null; } @@ -3479,7 +3663,11 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw { if (keywordData.NameMode == DynamicKeywordNameMode.NoName) { - ReportError(After(functionName), () => ParserStrings.UnexpectedNameForType, functionName.Text, nameToken.Text); + ReportError(After(functionName), + nameof(ParserStrings.UnexpectedNameForType), + ParserStrings.UnexpectedNameForType, + functionName.Text, + nameToken.Text); UngetToken(nameToken); return null; } @@ -3490,7 +3678,9 @@ 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), () => ParserStrings.RequiredNameOrExpressionMissing); + ReportIncompleteInput(After(functionName), + nameof(ParserStrings.RequiredNameOrExpressionMissing), + ParserStrings.RequiredNameOrExpressionMissing); UngetToken(nameToken); return null; } @@ -3505,12 +3695,17 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw { if (keywordData.NameMode == DynamicKeywordNameMode.SimpleNameRequired || keywordData.NameMode == DynamicKeywordNameMode.SimpleOptionalName) { - ReportError(After(functionName), () => ParserStrings.RequiredNameOrExpressionMissing); + 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), () => ParserStrings.UnexpectedToken, nameToken.Text); + ReportError(After(functionName), + nameof(ParserStrings.UnexpectedToken), + ParserStrings.UnexpectedToken, + nameToken.Text); } return null; } @@ -3518,7 +3713,11 @@ 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), () => ParserStrings.UnexpectedNameForType, functionName.Text, instanceName.ToString()); + ReportError(After(functionName), + nameof(ParserStrings.UnexpectedNameForType), + ParserStrings.UnexpectedNameForType, + functionName.Text, + instanceName.ToString()); return null; } @@ -3526,7 +3725,10 @@ 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, () => ParserStrings.UnexpectedToken, nameToken.Text); + ReportError(nameToken.Extent, + nameof(ParserStrings.UnexpectedToken), + ParserStrings.UnexpectedToken, + nameToken.Text); return null; } } @@ -3554,7 +3756,9 @@ private StatementAst DynamicKeywordStatementRule(Token functionName, DynamicKeyw if (lCurly.Kind == TokenKind.EndOfInput) { UngetToken(lCurly); - ReportIncompleteInput(After(functionName.Extent), () => ParserStrings.MissingBraceInObjectDefinition); + ReportIncompleteInput(After(functionName.Extent), + nameof(ParserStrings.MissingBraceInObjectDefinition), + ParserStrings.MissingBraceInObjectDefinition); // Preserve the name expression for tab completion return originalInstanceName == null @@ -3581,11 +3785,17 @@ 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), () => ParserStrings.UnexpectedTokenInDynamicKeyword, functionName.Text); + ReportError(LastCharacterOf(instanceInvokeMemberExpressionAst.Member.Extent), + nameof(ParserStrings.UnexpectedTokenInDynamicKeyword), + ParserStrings.UnexpectedTokenInDynamicKeyword, + functionName.Text); } else { - ReportError(lCurly.Extent, () => ParserStrings.UnexpectedToken, lCurly.Text); + ReportError(lCurly.Extent, + nameof(ParserStrings.UnexpectedToken), + ParserStrings.UnexpectedToken, + lCurly.Text); } if (lCurly.Kind == TokenKind.Dot && originalInstanceName != null && lCurly.Extent.StartOffset == originalInstanceName.Extent.EndOffset) @@ -3648,7 +3858,10 @@ instanceInvokeMemberExpressionAst.Arguments[0] is ScriptBlockExpressionAst && if (body == null) { // Failed to read the statement body - ReportIncompleteInput(After(lCurly), () => ParserStrings.MissingStatementAfterKeyword, keywordData.Keyword); + ReportIncompleteInput(After(lCurly), + nameof(ParserStrings.MissingStatementAfterKeyword), + ParserStrings.MissingStatementAfterKeyword, + keywordData.Keyword); // Preserve the name expression for tab completion return originalInstanceName == null @@ -3703,7 +3916,11 @@ instanceInvokeMemberExpressionAst.Arguments[0] is ScriptBlockExpressionAst && } catch (Exception e) { - ReportError(functionName.Extent, () => ParserStrings.DynamicKeywordPostParseException, keywordData.Keyword, e.ToString()); + ReportError(functionName.Extent, + nameof(ParserStrings.DynamicKeywordPostParseException), + ParserStrings.DynamicKeywordPostParseException, + keywordData.Keyword, + e.ToString()); return null; } } @@ -3741,7 +3958,10 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) // comes next. endErrorStatement = doToken.Extent; - ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingLoopStatement, TokenKind.Do.Text()); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingLoopStatement), + ParserStrings.MissingLoopStatement, + TokenKind.Do.Text()); } else { @@ -3753,7 +3973,9 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) UngetToken(whileOrUntilToken); endErrorStatement = body.Extent; - ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingWhileOrUntilInDoWhile); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingWhileOrUntilInDoWhile), + ParserStrings.MissingWhileOrUntilInDoWhile); } else { @@ -3766,7 +3988,9 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) UngetToken(lParen); endErrorStatement = whileOrUntilToken.Extent; ReportIncompleteInput(After(endErrorStatement), - () => ParserStrings.MissingOpenParenthesisAfterKeyword, whileOrUntilToken.Kind.Text()); + nameof(ParserStrings.MissingOpenParenthesisAfterKeyword), + ParserStrings.MissingOpenParenthesisAfterKeyword, + whileOrUntilToken.Kind.Text()); } else { @@ -3778,7 +4002,9 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) endErrorStatement = lParen.Extent; ReportIncompleteInput(After(endErrorStatement), - () => ParserStrings.MissingExpressionAfterKeyword, whileOrUntilToken.Kind.Text()); + nameof(ParserStrings.MissingExpressionAfterKeyword), + ParserStrings.MissingExpressionAfterKeyword, + whileOrUntilToken.Kind.Text()); } SkipNewlines(); rParen = NextToken(); @@ -3793,7 +4019,9 @@ private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) { endErrorStatement = condition.Extent; ReportIncompleteInput(After(endErrorStatement), - () => ParserStrings.MissingEndParenthesisAfterStatement, whileOrUntilToken.Kind.Text()); + nameof(ParserStrings.MissingEndParenthesisAfterStatement), + ParserStrings.MissingEndParenthesisAfterStatement, + whileOrUntilToken.Kind.Text()); } } } @@ -3836,7 +4064,10 @@ private StatementAst ClassDefinitionRule(List customAttributes var name = SimpleNameRule(out classNameToken); if (name == null) { - ReportIncompleteInput(After(classToken), () => ParserStrings.MissingNameAfterKeyword, classToken.Text); + ReportIncompleteInput(After(classToken), + nameof(ParserStrings.MissingNameAfterKeyword), + ParserStrings.MissingNameAfterKeyword, + classToken.Text); return new ErrorStatementAst(classToken.Extent); } @@ -3865,7 +4096,9 @@ private StatementAst ClassDefinitionRule(List customAttributes superClass = this.TypeNameRule(allowAssemblyQualifiedNames: false, firstTypeNameToken: out unused); if (superClass == null) { - ReportIncompleteInput(After(ExtentFromFirstOf(commaToken, colonToken)), () => ParserStrings.TypeNameExpected); + ReportIncompleteInput(After(ExtentFromFirstOf(commaToken, colonToken)), + nameof(ParserStrings.TypeNameExpected), + ParserStrings.TypeNameExpected); break; } @@ -3891,7 +4124,10 @@ private StatementAst ClassDefinitionRule(List customAttributes UngetToken(lCurly); var lastElement = (superClassesList.Count > 0) ? (Ast)superClassesList[superClassesList.Count - 1] : name; - ReportIncompleteInput(After(lastElement), () => ParserStrings.MissingTypeBody, classToken.Kind.Text()); + ReportIncompleteInput(After(lastElement), + nameof(ParserStrings.MissingTypeBody), + ParserStrings.MissingTypeBody, + classToken.Kind.Text()); return new ErrorStatementAst(ExtentOf(classToken, lastElement), superClassesList); } @@ -3923,7 +4159,10 @@ private StatementAst ClassDefinitionRule(List customAttributes if (rCurly.Kind != TokenKind.RCurly) { UngetToken(rCurly); - ReportIncompleteInput(After(lCurly), rCurly.Extent, () => ParserStrings.MissingEndCurlyBrace); + ReportIncompleteInput(After(lCurly), + rCurly.Extent, + nameof(ParserStrings.MissingEndCurlyBrace), + ParserStrings.MissingEndCurlyBrace); } else { @@ -4020,7 +4259,7 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) } else { - ReportError(attribute.Extent, () => ParserStrings.TooManyTypes); + ReportError(attribute.Extent, nameof(ParserStrings.TooManyTypes), ParserStrings.TooManyTypes); } continue; } @@ -4064,7 +4303,10 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) case TokenKind.Hidden: if (hiddenToken != null) { - ReportError(token.Extent, () => ParserStrings.DuplicateQualifier, token.Text); + ReportError(token.Extent, + nameof(ParserStrings.DuplicateQualifier), + ParserStrings.DuplicateQualifier, + token.Text); } hiddenToken = token; lastAttribute = token; @@ -4074,7 +4316,10 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) case TokenKind.Static: if (staticToken != null) { - ReportError(token.Extent, () => ParserStrings.DuplicateQualifier, token.Text); + ReportError(token.Extent, + nameof(ParserStrings.DuplicateQualifier), + ParserStrings.DuplicateQualifier, + token.Text); } staticToken = token; lastAttribute = token; @@ -4120,7 +4365,9 @@ 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), () => ParserStrings.MissingPropertyTerminator); + ReportIncompleteInput(After(endExtent), + nameof(ParserStrings.MissingPropertyTerminator), + ParserStrings.MissingPropertyTerminator); } SkipNewlinesAndSemicolons(); @@ -4182,7 +4429,9 @@ 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)), () => ParserStrings.IncompleteMemberDefinition); + ReportIncompleteInput(After(ExtentFromFirstOf(lastAttribute)), + nameof(ParserStrings.IncompleteMemberDefinition), + ParserStrings.IncompleteMemberDefinition); RecordErrorAsts(attributeList, ref astsOnError); RecordErrorAsts(typeConstraint, ref astsOnError); } @@ -4256,7 +4505,10 @@ private StatementAst EnumDefinitionRule(List customAttributes, var name = SimpleNameRule(); if (name == null) { - ReportIncompleteInput(After(enumToken), () => ParserStrings.MissingNameAfterKeyword, enumToken.Text); + ReportIncompleteInput(After(enumToken), + nameof(ParserStrings.MissingNameAfterKeyword), + ParserStrings.MissingNameAfterKeyword, + enumToken.Text); return new ErrorStatementAst(enumToken.Extent); } @@ -4267,7 +4519,10 @@ 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), () => ParserStrings.MissingTypeBody, enumToken.Kind.Text()); + ReportIncompleteInput(After(name), + nameof(ParserStrings.MissingTypeBody), + ParserStrings.MissingTypeBody, + enumToken.Kind.Text()); return new ErrorStatementAst(ExtentOf(enumToken, name)); } @@ -4284,7 +4539,10 @@ private StatementAst EnumDefinitionRule(List customAttributes, if (rCurly.Kind != TokenKind.RCurly) { UngetToken(rCurly); - ReportIncompleteInput(After(lCurly), rCurly.Extent, () => ParserStrings.MissingEndCurlyBrace); + ReportIncompleteInput(After(lCurly), + rCurly.Extent, + nameof(ParserStrings.MissingEndCurlyBrace), + ParserStrings.MissingEndCurlyBrace); } var startExtent = customAttributes != null && customAttributes.Count > 0 @@ -4337,7 +4595,10 @@ private MemberAst EnumMemberRule() initialValueAst = ExpressionRule(); if (initialValueAst == null) { - ReportError(After(assignToken), () => ParserStrings.ExpectedValueExpression, assignToken.Kind.Text()); + ReportError(After(assignToken), + nameof(ParserStrings.ExpectedValueExpression), + ParserStrings.ExpectedValueExpression, + assignToken.Kind.Text()); endExtent = assignToken.Extent; missingInitializer = true; } @@ -4358,7 +4619,9 @@ private MemberAst EnumMemberRule() // If the initializer is missing, no sense in reporting another error about a missing terminator if (!missingInitializer) { - ReportIncompleteInput(After(endExtent), () => ParserStrings.MissingPropertyTerminator); + ReportIncompleteInput(After(endExtent), + nameof(ParserStrings.MissingPropertyTerminator), + ParserStrings.MissingPropertyTerminator); } } SkipNewlinesAndSemicolons(); @@ -4420,7 +4683,9 @@ private StatementAst UsingStatementRule(Token usingToken) default: UngetToken(directiveToken); - ReportIncompleteInput(After(usingToken), () => ParserStrings.MissingUsingStatementDirective); + ReportIncompleteInput(After(usingToken), + nameof(ParserStrings.MissingUsingStatementDirective), + ParserStrings.MissingUsingStatementDirective); return new ErrorStatementAst(usingToken.Extent); } @@ -4435,7 +4700,9 @@ private StatementAst UsingStatementRule(Token usingToken) case TokenKind.Comma: case TokenKind.Semi: { - ReportIncompleteInput(After(directiveToken), () => ParserStrings.MissingUsingItemName); + ReportIncompleteInput(After(directiveToken), + nameof(ParserStrings.MissingUsingItemName), + ParserStrings.MissingUsingItemName); return new ErrorStatementAst(ExtentOf(usingToken, directiveToken)); } } @@ -4443,7 +4710,10 @@ private StatementAst UsingStatementRule(Token usingToken) var itemAst = GetCommandArgument(CommandArgumentContext.CommandArgument, itemToken); if (itemAst == null) { - ReportError(itemToken.Extent, () => ParserStrings.InvalidValueForUsingItemName, itemToken.Text); + ReportError(itemToken.Extent, + nameof(ParserStrings.InvalidValueForUsingItemName), + ParserStrings.InvalidValueForUsingItemName, + itemToken.Text); // ErrorRecovery: If there is no identifier, skip whole 'using' line SyncOnError(true, TokenKind.Semi, TokenKind.NewLine); return new ErrorStatementAst(ExtentOf(usingToken, itemToken.Extent)); @@ -4451,7 +4721,10 @@ private StatementAst UsingStatementRule(Token usingToken) if (!(itemAst is StringConstantExpressionAst) && (kind != UsingStatementKind.Module || !(itemAst is HashtableAst))) { - ReportError(ExtentFromFirstOf(itemAst, itemToken), () => ParserStrings.InvalidValueForUsingItemName, itemAst.Extent.Text); + ReportError(ExtentFromFirstOf(itemAst, itemToken), + nameof(ParserStrings.InvalidValueForUsingItemName), + ParserStrings.InvalidValueForUsingItemName, + itemAst.Extent.Text); return new ErrorStatementAst(ExtentOf(usingToken, ExtentFromFirstOf(itemAst, itemToken))); } @@ -4478,7 +4751,9 @@ private StatementAst UsingStatementRule(Token usingToken) if (aliasToken.Kind == TokenKind.EndOfInput) { UngetToken(aliasToken); - ReportIncompleteInput(After(equalsToken), () => ParserStrings.MissingNamespaceAlias); + ReportIncompleteInput(After(equalsToken), + nameof(ParserStrings.MissingNamespaceAlias), + ParserStrings.MissingNamespaceAlias); return new ErrorStatementAst(ExtentOf(usingToken, equalsToken)); } @@ -4513,7 +4788,9 @@ private StatementAst UsingStatementRule(Token usingToken) if (aliasRequired) { - ReportIncompleteInput(After(itemToken), () => ParserStrings.MissingEqualsInUsingAlias); + ReportIncompleteInput(After(itemToken), + nameof(ParserStrings.MissingEqualsInUsingAlias), + ParserStrings.MissingEqualsInUsingAlias); return new ErrorStatementAst(ExtentOf(usingToken, itemAst), new Ast[] { itemAst }); } } @@ -4540,13 +4817,19 @@ private StringConstantExpressionAst ResolveUsingAssembly(StringConstantExpressio { if (uri.IsUnc) { - ReportError(name.Extent, () => ParserStrings.CannotLoadAssemblyFromUncPath, assemblyName); + ReportError(name.Extent, + nameof(ParserStrings.CannotLoadAssemblyFromUncPath), + ParserStrings.CannotLoadAssemblyFromUncPath, + assemblyName); } // don't allow things like 'using assembly http://microsoft.com' if (uri.Scheme != "file") { - ReportError(name.Extent, () => ParserStrings.CannotLoadAssemblyWithUriSchema, uri.Scheme); + ReportError(name.Extent, + nameof(ParserStrings.CannotLoadAssemblyWithUriSchema), + ParserStrings.CannotLoadAssemblyWithUriSchema, + uri.Scheme); } } else @@ -4598,7 +4881,10 @@ private StringConstantExpressionAst ResolveUsingAssembly(StringConstantExpressio if (assemblyFileName == null || !File.Exists(assemblyFileName)) { - ReportError(name.Extent, () => ParserStrings.ErrorLoadingAssembly, assemblyName); + ReportError(name.Extent, + nameof(ParserStrings.ErrorLoadingAssembly), + ParserStrings.ErrorLoadingAssembly, + assemblyName); } else { @@ -4633,7 +4919,9 @@ private StatementAst MethodDeclarationRule(Token functionNameToken, string class } else { - this.ReportIncompleteInput(After(functionNameToken), () => ParserStrings.MissingMethodParameterList); + this.ReportIncompleteInput(After(functionNameToken), + nameof(ParserStrings.MissingMethodParameterList), + ParserStrings.MissingMethodParameterList); parameters = new List(); } @@ -4673,13 +4961,17 @@ private StatementAst MethodDeclarationRule(Token functionNameToken, string class else { endErrorStatement = baseToken.Extent; - ReportIncompleteInput(After(baseToken), () => ParserStrings.MissingMethodParameterList); + ReportIncompleteInput(After(baseToken), + nameof(ParserStrings.MissingMethodParameterList), + ParserStrings.MissingMethodParameterList); } } else { endErrorStatement = colonToken.Extent; - ReportIncompleteInput(After(colonToken), () => ParserStrings.MissingBaseCtorCall); + ReportIncompleteInput(After(colonToken), + nameof(ParserStrings.MissingBaseCtorCall), + ParserStrings.MissingBaseCtorCall); } } } @@ -4704,7 +4996,9 @@ private StatementAst MethodDeclarationRule(Token functionNameToken, string class if (endErrorStatement == null) { endErrorStatement = ExtentFromFirstOf(rParen, functionNameToken); - ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingFunctionBody); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingFunctionBody), + ParserStrings.MissingFunctionBody); } } @@ -4790,7 +5084,10 @@ private StatementAst FunctionDeclarationRule(Token functionToken) // ErrorRecovery: Don't continue, assume the function isn't there yet. UngetToken(functionNameToken); - ReportIncompleteInput(After(functionToken), () => ParserStrings.MissingNameAfterKeyword, functionToken.Text); + ReportIncompleteInput(After(functionToken), + nameof(ParserStrings.MissingNameAfterKeyword), + ParserStrings.MissingNameAfterKeyword, + functionToken.Text); return new ErrorStatementAst(functionToken.Extent); } @@ -4810,7 +5107,9 @@ private StatementAst FunctionDeclarationRule(Token functionToken) if (endErrorStatement == null) { endErrorStatement = ExtentFromFirstOf(rParen, functionNameToken); - ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingFunctionBody); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingFunctionBody), + ParserStrings.MissingFunctionBody); } } @@ -4865,7 +5164,9 @@ private List FunctionParameterDeclarationRule(out IScriptExtent en UngetToken(rParen); endErrorStatement = parameters.Any() ? parameters.Last().Extent : lParen.Extent; - ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingEndParenthesisInFunctionParameterList); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingEndParenthesisInFunctionParameterList), + ParserStrings.MissingEndParenthesisInFunctionParameterList); } SkipNewlines(); } @@ -4897,7 +5198,9 @@ private StatementAst TrapStatementRule(Token trapToken) // ErrorRecovery: just return an error statement. IScriptExtent endErrorStatement = ExtentFromFirstOf(typeConstraintAst, trapToken); - ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingTrapStatement); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingTrapStatement), + ParserStrings.MissingTrapStatement); return new ErrorStatementAst(ExtentOf(trapToken, endErrorStatement), GetNestedErrorAsts(typeConstraintAst)); } @@ -4946,7 +5249,9 @@ 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), () => ParserStrings.MissingTypeLiteralToken); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingTypeLiteralToken), + ParserStrings.MissingTypeLiteralToken); } break; } @@ -4989,7 +5294,9 @@ 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), () => ParserStrings.MissingCatchHandlerBlock); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingCatchHandlerBlock), + ParserStrings.MissingCatchHandlerBlock); } if (exceptionTypes != null) { @@ -5032,7 +5339,9 @@ private StatementAst TryStatementRule(Token tryToken) { // ErrorRecovery: don't parse more, return an error statement. - ReportIncompleteInput(After(tryToken), () => ParserStrings.MissingTryStatementBlock); + ReportIncompleteInput(After(tryToken), + nameof(ParserStrings.MissingTryStatementBlock), + ParserStrings.MissingTryStatementBlock); return new ErrorStatementAst(tryToken.Extent); } @@ -5060,7 +5369,9 @@ private StatementAst TryStatementRule(Token tryToken) endErrorStatement = finallyToken.Extent; ReportIncompleteInput(After(endErrorStatement), - () => ParserStrings.MissingFinallyStatementBlock, finallyToken.Kind.Text()); + nameof(ParserStrings.MissingFinallyStatementBlock), + ParserStrings.MissingFinallyStatementBlock, + finallyToken.Kind.Text()); } } @@ -5069,7 +5380,9 @@ private StatementAst TryStatementRule(Token tryToken) // ErrorRecovery: don't parse more, return an error statement. endErrorStatement = body.Extent; - ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingCatchOrFinally); + ReportIncompleteInput(After(endErrorStatement), + nameof(ParserStrings.MissingCatchOrFinally), + ParserStrings.MissingCatchOrFinally); } if (endErrorStatement != null) @@ -5112,7 +5425,9 @@ private StatementAst DataStatementRule(Token dataToken) // ErrorRecovery: Assume the parameter is just misspelled, look for command names next endErrorStatement = supportedCommandToken.Extent; - ReportError(endErrorStatement, () => ParserStrings.InvalidParameterForDataSectionStatement, + ReportError(endErrorStatement, + nameof(ParserStrings.InvalidParameterForDataSectionStatement), + ParserStrings.InvalidParameterForDataSectionStatement, ((ParameterToken)supportedCommandToken).ParameterName); } @@ -5130,7 +5445,8 @@ private StatementAst DataStatementRule(Token dataToken) if (endErrorStatement == null) { ReportIncompleteInput(After(commaToken ?? supportedCommandToken), - () => ParserStrings.MissingValueForSupportedCommandInDataSectionStatement); + nameof(ParserStrings.MissingValueForSupportedCommandInDataSectionStatement), + ParserStrings.MissingValueForSupportedCommandInDataSectionStatement); } endErrorStatement = commaToken != null ? commaToken.Extent : supportedCommandToken.Extent; break; @@ -5161,7 +5477,8 @@ private StatementAst DataStatementRule(Token dataToken) ? commands.Last().Extent : ExtentFromFirstOf(dataVariableNameAst, dataToken); ReportIncompleteInput(After(endErrorStatement), - () => ParserStrings.MissingStatementBlockForDataSection); + nameof(ParserStrings.MissingStatementBlockForDataSection), + ParserStrings.MissingStatementBlockForDataSection); } } @@ -5231,7 +5548,9 @@ private PipelineBaseAst PipelineRule() { // ErrorRecovery: this is a semantic error, so just keep parsing. - ReportError(expr.Extent, () => ParserStrings.ExpressionsMustBeFirstInPipeline); + ReportError(expr.Extent, + nameof(ParserStrings.ExpressionsMustBeFirstInPipeline), + ParserStrings.ExpressionsMustBeFirstInPipeline); } if (assignToken != null) @@ -5245,7 +5564,10 @@ private PipelineBaseAst PipelineRule() // pipeline, so just keep parsing. IScriptExtent errorExtent = After(assignToken); - ReportIncompleteInput(errorExtent, () => ParserStrings.ExpectedValueExpression, assignToken.Kind.Text()); + ReportIncompleteInput(errorExtent, + nameof(ParserStrings.ExpectedValueExpression), + ParserStrings.ExpectedValueExpression, + assignToken.Kind.Text()); statement = new ErrorStatementAst(errorExtent); } @@ -5294,7 +5616,9 @@ 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, () => ParserStrings.EmptyPipeElement); + ReportIncompleteInput(errorPosition, + nameof(ParserStrings.EmptyPipeElement), + ParserStrings.EmptyPipeElement); } pipeToken = PeekToken(); @@ -5319,7 +5643,9 @@ private PipelineBaseAst PipelineRule() if (PeekToken().Kind == TokenKind.EndOfInput) { scanning = false; - ReportIncompleteInput(After(pipeToken), () => ParserStrings.EmptyPipeElement); + ReportIncompleteInput(After(pipeToken), + nameof(ParserStrings.EmptyPipeElement), + ParserStrings.EmptyPipeElement); } break; case TokenKind.AndAnd: @@ -5327,7 +5653,10 @@ 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, () => ParserStrings.InvalidEndOfLine, pipeToken.Text); + ReportError(pipeToken.Extent, + nameof(ParserStrings.InvalidEndOfLine), + ParserStrings.InvalidEndOfLine, + pipeToken.Text); if (PeekToken().Kind == TokenKind.EndOfInput) { scanning = false; @@ -5337,7 +5666,10 @@ private PipelineBaseAst PipelineRule() default: // ErrorRecovery: don't eat the token, assume it belongs to something else. - ReportError(pipeToken.Extent, () => ParserStrings.UnexpectedToken, pipeToken.Text); + ReportError(pipeToken.Extent, + nameof(ParserStrings.UnexpectedToken), + ParserStrings.UnexpectedToken, + pipeToken.Text); scanning = false; break; } @@ -5374,14 +5706,19 @@ private RedirectionAst RedirectionRule(RedirectionToken redirectionToken, Redire { // ErrorRecovery: Just pretend we have a filename and continue parsing. - ReportError(After(redirectionToken), () => ParserStrings.MissingFileSpecification); + ReportError(After(redirectionToken), + nameof(ParserStrings.MissingFileSpecification), + ParserStrings.MissingFileSpecification); filename = new ErrorExpressionAst(redirectionToken.Extent); } if (fileRedirectionToken == null) { // Must be an input redirection - ReportError(redirectionToken.Extent, () => ParserStrings.RedirectionNotSupported, redirectionToken.Text); + ReportError(redirectionToken.Extent, + nameof(ParserStrings.RedirectionNotSupported), + ParserStrings.RedirectionNotSupported, + redirectionToken.Text); extent = ExtentOf(redirectionToken, filename); return null; } @@ -5400,7 +5737,10 @@ 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, () => ParserStrings.RedirectionNotSupported, mergingRedirectionToken.Text); + ReportError(redirectionToken.Extent, + nameof(ParserStrings.RedirectionNotSupported), + ParserStrings.RedirectionNotSupported, + mergingRedirectionToken.Text); toStream = RedirectionStream.Output; } else if (fromStream == toStream) @@ -5408,7 +5748,10 @@ 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, () => ParserStrings.RedirectionNotSupported, mergingRedirectionToken.Text); + ReportError(redirectionToken.Extent, + nameof(ParserStrings.RedirectionNotSupported), + ParserStrings.RedirectionNotSupported, + mergingRedirectionToken.Text); } result = new MergingRedirectionAst(mergingRedirectionToken.Extent, mergingRedirectionToken.FromStream, toStream); @@ -5433,7 +5776,10 @@ private RedirectionAst RedirectionRule(RedirectionToken redirectionToken, Redire default: throw PSTraceSource.NewArgumentOutOfRangeException("result.FromStream", result.FromStream); } - ReportError(result.Extent, () => ParserStrings.StreamAlreadyRedirected, errorStream); + ReportError(result.Extent, + nameof(ParserStrings.StreamAlreadyRedirected), + ParserStrings.StreamAlreadyRedirected, + errorStream); } extent = result.Extent; @@ -5506,7 +5852,10 @@ private ExpressionAst GetCommandArgument(CommandArgumentContext context, Token t // ErrorRecovery: stop looking for additional arguments, exclude the trailing comma - ReportIncompleteInput(After(commaToken), () => ParserStrings.MissingExpression, ","); + ReportIncompleteInput(After(commaToken), + nameof(ParserStrings.MissingExpression), + ParserStrings.MissingExpression, + ","); return new ErrorExpressionAst(ExtentOf(commandArgs.First(), commaToken), commandArgs); case TokenKind.SplattedVariable: @@ -5709,7 +6058,9 @@ internal Ast CommandRule(bool forDynamicKeyword) case TokenKind.Comma: endExtent = token.Extent; - ReportError(token.Extent, () => ParserStrings.MissingArgument); + ReportError(token.Extent, + nameof(ParserStrings.MissingArgument), + ParserStrings.MissingArgument); SkipNewlines(); break; @@ -5733,7 +6084,10 @@ internal Ast CommandRule(bool forDynamicKeyword) if (parameterArgs == null) { extent = parameterToken.Extent; - ReportError(After(extent), () => ParserStrings.ParameterRequiresArgument, parameterToken.Text); + ReportError(After(extent), + nameof(ParserStrings.ParameterRequiresArgument), + ParserStrings.ParameterRequiresArgument, + parameterToken.Text); } else { @@ -5830,7 +6184,10 @@ internal Ast CommandRule(bool forDynamicKeyword) if (dotSource || ampersand) { IScriptExtent extent = firstToken.Extent; - ReportError(extent, () => ParserStrings.MissingExpression, firstToken.Text); + ReportError(extent, + nameof(ParserStrings.MissingExpression), + ParserStrings.MissingExpression, + firstToken.Text); } return null; } @@ -5936,7 +6293,10 @@ 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, () => ParserStrings.ExpectedValueExpression, token.Text); + ReportIncompleteInput(extent, + nameof(ParserStrings.ExpectedValueExpression), + ParserStrings.ExpectedValueExpression, + token.Text); expr = new ErrorExpressionAst(extent); } operandStack.Push(expr); @@ -5993,7 +6353,10 @@ private ExpressionAst ErrorRecoveryParameterInExpression(ParameterToken paramTok // that it's an incomplete operator. This simplifies analysis later, e.g. trying to autocomplete // operators. - ReportError(paramToken.Extent, () => ParserStrings.UnexpectedToken, paramToken.Text); + ReportError(paramToken.Extent, + nameof(ParserStrings.UnexpectedToken), + ParserStrings.UnexpectedToken, + paramToken.Text); SkipToken(); return new ErrorExpressionAst(ExtentOf(expr, paramToken), new Ast[] { @@ -6028,7 +6391,10 @@ private ExpressionAst ArrayLiteralRule() { // ErrorRecovery: create an error expression for the ast and break. - ReportIncompleteInput(After(commaToken), () => ParserStrings.MissingExpressionAfterToken, commaToken.Text); + ReportIncompleteInput(After(commaToken), + nameof(ParserStrings.MissingExpressionAfterToken), + ParserStrings.MissingExpressionAfterToken, + commaToken.Text); lastExpr = new ErrorExpressionAst(commaToken.Extent); arrayValues.Add(lastExpr); break; @@ -6116,7 +6482,10 @@ 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), () => ParserStrings.MissingExpressionAfterOperator, token.Text); + ReportIncompleteInput(After(token), + nameof(ParserStrings.MissingExpressionAfterOperator), + ParserStrings.MissingExpressionAfterOperator, + token.Text); return new ErrorExpressionAst(token.Extent); } } @@ -6140,7 +6509,9 @@ private ExpressionAst UnaryExpressionRule() // so we know we must have some sort of expression. Return an error expression then. ReportIncompleteInput(lastAttribute.Extent, - () => ParserStrings.UnexpectedAttribute, lastAttribute.TypeName.FullName); + nameof(ParserStrings.UnexpectedAttribute), + ParserStrings.UnexpectedAttribute, + lastAttribute.TypeName.FullName); return new ErrorExpressionAst(ExtentOf(token, lastAttribute)); } expr = new AttributedExpressionAst(ExtentOf(lastAttribute, child), lastAttribute, child); @@ -6358,10 +6729,20 @@ private ExpressionAst HashExpressionRule(Token atCurlyToken, bool parsingSchemaE { UngetToken(rCurly); // Note - the error handling function inspects the error message body to extra the ParserStrings property name. It uses this value as the errorid. - var errorMessageExpression = parsingSchemaElement ? - (Expression>)(() => ParserStrings.IncompletePropertyAssignmentBlock) - : (Expression>)(() => ParserStrings.MissingEndCurlyBrace); - ReportIncompleteInput(After(atCurlyToken), rCurly.Extent, errorMessageExpression); + string errorId; + string errorMsg; + if (parsingSchemaElement) + { + errorId = nameof(ParserStrings.IncompletePropertyAssignmentBlock); + errorMsg = ParserStrings.IncompletePropertyAssignmentBlock; + } + else + { + errorId = nameof(ParserStrings.MissingEndCurlyBrace); + errorMsg = ParserStrings.MissingEndCurlyBrace; + } + + ReportIncompleteInput(After(atCurlyToken), rCurly.Extent, errorId, errorMsg); endExtent = Before(rCurly); } else @@ -6405,11 +6786,21 @@ private KeyValuePair GetKeyValuePair(bool parsingSchemaElement) UngetToken(equals); IScriptExtent errorExtent = After(key); - // Note - the error handling function inspects the error message body to extra the ParserStrings property name. It uses this value as the errorid. - var errorMessageExpression = parsingSchemaElement - ? (() => (ParserStrings.MissingEqualsInPropertyAssignmentBlock)) - : (Expression>)(() => ParserStrings.MissingEqualsInHashLiteral); - ReportError(errorExtent, errorMessageExpression); + + string errorId; + string errorMsg; + if (parsingSchemaElement) + { + errorId = nameof(ParserStrings.MissingEqualsInPropertyAssignmentBlock); + errorMsg = ParserStrings.MissingEqualsInPropertyAssignmentBlock; + } + else + { + errorId = nameof(ParserStrings.MissingEqualsInHashLiteral); + errorMsg = ParserStrings.MissingEqualsInHashLiteral; + } + + ReportError(errorExtent, errorId, errorMsg); SyncOnError(false, TokenKind.RCurly, TokenKind.Semi, TokenKind.NewLine); return new KeyValuePair(key, new ErrorStatementAst(errorExtent)); } @@ -6426,11 +6817,21 @@ private KeyValuePair GetKeyValuePair(bool parsingSchemaElement) // ErrorRecovery: pretend we saw a statement and keep parsing. IScriptExtent errorExtent = After(equals); - // Note - the error handling function inspects the error message body to extra the ParserStrings property name. It uses this value as the errorid. - var errorMessageExpression = parsingSchemaElement ? - (Expression>)(() => ParserStrings.MissingEqualsInPropertyAssignmentBlock) - : (Expression>)(() => ParserStrings.MissingStatementInHashLiteral); - ReportIncompleteInput(errorExtent, errorMessageExpression); + + string errorId; + string errorMsg; + if (parsingSchemaElement) + { + errorId = nameof(ParserStrings.MissingEqualsInPropertyAssignmentBlock); + errorMsg = ParserStrings.MissingEqualsInPropertyAssignmentBlock; + } + else + { + errorId = nameof(ParserStrings.MissingStatementInHashLiteral); + errorMsg = ParserStrings.MissingStatementInHashLiteral; + } + + ReportIncompleteInput(errorExtent, errorId, errorMsg); statement = new ErrorStatementAst(errorExtent); } } @@ -6496,7 +6897,9 @@ private ExpressionAst SubExpressionRule(Token firstToken) // ErrorRecovery: Assume only the closing paren is missing, continue as though it was present. UngetToken(rParen); - ReportIncompleteInput(rParen.Extent, () => ParserStrings.MissingEndParenthesisInSubexpression); + ReportIncompleteInput(rParen.Extent, + nameof(ParserStrings.MissingEndParenthesisInSubexpression), + ParserStrings.MissingEndParenthesisInSubexpression); } } finally @@ -6539,7 +6942,9 @@ private ExpressionAst ParenthesizedExpressionRule(Token lParen) if (pipelineAst == null) { IScriptExtent errorPosition = After(lParen); - ReportIncompleteInput(errorPosition, () => ParserStrings.ExpectedExpression); + ReportIncompleteInput(errorPosition, + nameof(ParserStrings.ExpectedExpression), + ParserStrings.ExpectedExpression); pipelineAst = new ErrorStatementAst(errorPosition); } SkipNewlines(); @@ -6549,7 +6954,9 @@ private ExpressionAst ParenthesizedExpressionRule(Token lParen) // ErrorRecovery: Assume only the closing paren is missing, continue as though it was present. UngetToken(rParen); - ReportIncompleteInput(After(pipelineAst), () => ParserStrings.MissingEndParenthesisInExpression); + ReportIncompleteInput(After(pipelineAst), + nameof(ParserStrings.MissingEndParenthesisInExpression), + ParserStrings.MissingEndParenthesisInExpression); rParen = null; } } @@ -6671,7 +7078,9 @@ 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), () => ParserStrings.MissingPropertyName); + ReportIncompleteInput(After(operatorToken), + nameof(ParserStrings.MissingPropertyName), + ParserStrings.MissingPropertyName); member = GetSingleCommandArgument(CommandArgumentContext.CommandArgument) ?? new ErrorExpressionAst(ExtentOf(targetExpr, operatorToken)); } @@ -6753,7 +7162,9 @@ private List InvokeParamParenListRule(Token lParen, out IScriptEx // ErrorRecovery: sync at closing paren or newline. ReportIncompleteInput(After(comma), - () => ParserStrings.MissingExpressionAfterToken, TokenKind.Comma.Text()); + nameof(ParserStrings.MissingExpressionAfterToken), + ParserStrings.MissingExpressionAfterToken, + TokenKind.Comma.Text()); reportedError = true; } break; @@ -6779,7 +7190,8 @@ private List InvokeParamParenListRule(Token lParen, out IScriptEx if (!reportedError) { ReportIncompleteInput(arguments.Any() ? After(arguments.Last()) : After(lParen), - () => ParserStrings.MissingEndParenthesisInMethodCall); + nameof(ParserStrings.MissingEndParenthesisInMethodCall), + ParserStrings.MissingEndParenthesisInMethodCall); } rParen = null; } @@ -6805,7 +7217,9 @@ private ExpressionAst ElementAccessRule(ExpressionAst primaryExpression, Token l // the closing bracket, but build an expression that can't compile. var errorExtent = After(lBracket); - ReportIncompleteInput(errorExtent, () => ParserStrings.MissingArrayIndexExpression); + ReportIncompleteInput(errorExtent, + nameof(ParserStrings.MissingArrayIndexExpression), + ParserStrings.MissingArrayIndexExpression); indexExpr = new ErrorExpressionAst(lBracket.Extent); } @@ -6819,7 +7233,9 @@ 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), () => ParserStrings.MissingEndSquareBracket); + ReportIncompleteInput(After(indexExpr), + nameof(ParserStrings.MissingEndSquareBracket), + ParserStrings.MissingEndSquareBracket); } rBracket = null; } @@ -6849,27 +7265,10 @@ private void SaveError(ParseError error) ErrorList.Add(error); } - private void SaveError(IScriptExtent extent, Expression> errorExpr, bool incompleteInput, params object[] args) + private void SaveError(IScriptExtent extent, string errorId, string errorMsg, bool incompleteInput, params object[] args) { - string errorMsg = null; - string errorId = null; - var memberExpression = errorExpr.Body as MemberExpression; - if (memberExpression != null) - { - var propertyInfo = memberExpression.Member as PropertyInfo; - if (propertyInfo != null) - { - var getter = propertyInfo.GetMethod; - if (getter != null && getter.IsStatic && getter.ReturnType == typeof(string)) - { - errorMsg = (string)getter.Invoke(null, null); - errorId = propertyInfo.Name; - } - } - } - if (errorMsg == null) + if (String.IsNullOrEmpty(errorId)) { - errorMsg = errorExpr.Compile().Invoke(); errorId = "ParserError"; } @@ -6896,58 +7295,59 @@ private static object[] arrayOfTwoArgs [ThreadStatic] private static object[] t_arrayOfTwoArgs; - internal bool ReportIncompleteInput(IScriptExtent extent, Expression> errorExpr) + internal bool ReportIncompleteInput(IScriptExtent extent, string errorId, string errorMsg) { // If the error position isn't at the end of the input, then we don't want to mark the error // as incomplete input. bool incompleteInput = _tokenizer.IsAtEndOfScript(extent, checkCommentsAndWhitespace: true); - SaveError(extent, errorExpr, incompleteInput, null); + SaveError(extent, errorId, errorMsg, incompleteInput, null); return incompleteInput; } - internal bool ReportIncompleteInput(IScriptExtent extent, Expression> errorExpr, object arg) + internal bool ReportIncompleteInput(IScriptExtent extent, string errorId, string errorMsg, object arg) { // If the error position isn't at the end of the input, then we don't want to mark the error // as incomplete input. bool incompleteInput = _tokenizer.IsAtEndOfScript(extent, checkCommentsAndWhitespace: true); arrayOfOneArg[0] = arg; - SaveError(extent, errorExpr, incompleteInput, arrayOfOneArg); + SaveError(extent, errorId, errorMsg, incompleteInput, arrayOfOneArg); return incompleteInput; } internal bool ReportIncompleteInput(IScriptExtent errorPosition, IScriptExtent errorDetectedPosition, - Expression> errorExpr, + string errorId, + string errorMsg, params object[] args) { // If the error position isn't at the end of the input, then we don't want to mark the error // as incomplete input. bool incompleteInput = _tokenizer.IsAtEndOfScript(errorDetectedPosition, checkCommentsAndWhitespace: true); - SaveError(errorPosition, errorExpr, incompleteInput, args); + SaveError(errorPosition, errorId, errorMsg, incompleteInput, args); return incompleteInput; } - internal void ReportError(IScriptExtent extent, Expression> errorExpr) + internal void ReportError(IScriptExtent extent, string errorId, string errorMsg) { - SaveError(extent, errorExpr, false, null); + SaveError(extent, errorId, errorMsg, false, null); } - internal void ReportError(IScriptExtent extent, Expression> errorExpr, object arg) + internal void ReportError(IScriptExtent extent, string errorId, string errorMsg, object arg) { arrayOfOneArg[0] = arg; - SaveError(extent, errorExpr, false, arrayOfOneArg); + SaveError(extent, errorId, errorMsg, false, arrayOfOneArg); } - internal void ReportError(IScriptExtent extent, Expression> errorExpr, object arg1, object arg2) + internal void ReportError(IScriptExtent extent, string errorId, string errorMsg, object arg1, object arg2) { arrayOfTwoArgs[0] = arg1; arrayOfTwoArgs[1] = arg2; - SaveError(extent, errorExpr, false, arrayOfTwoArgs); + SaveError(extent, errorId, errorMsg, false, arrayOfTwoArgs); } - internal void ReportError(IScriptExtent extent, Expression> errorExpr, params object[] args) + internal void ReportError(IScriptExtent extent, string errorId, string errorMsg, params object[] args) { - SaveError(extent, errorExpr, false, args); + SaveError(extent, errorId, errorMsg, false, args); } internal void ReportError(ParseError error) diff --git a/src/System.Management.Automation/engine/parser/tokenizer.cs b/src/System.Management.Automation/engine/parser/tokenizer.cs index 1a1045afc5a..393fef5ce17 100644 --- a/src/System.Management.Automation/engine/parser/tokenizer.cs +++ b/src/System.Management.Automation/engine/parser/tokenizer.cs @@ -980,38 +980,40 @@ internal void CheckAstIsBeforeSignature(Ast ast) if (_beginSignatureExtent.StartOffset < ast.Extent.StartOffset) { - ReportError(ast.Extent, () => ParserStrings.TokenAfterEndOfValidScriptText); + ReportError(ast.Extent, + nameof(ParserStrings.TokenAfterEndOfValidScriptText), + ParserStrings.TokenAfterEndOfValidScriptText); } } - private void ReportError(int errorOffset, Expression> message, params object[] args) + private void ReportError(int errorOffset, string errorId, string errorMsg, params object[] args) { - _parser.ReportError(NewScriptExtent(errorOffset, errorOffset + 1), message, args); + _parser.ReportError(NewScriptExtent(errorOffset, errorOffset + 1), errorId, errorMsg, args); } - private void ReportError(IScriptExtent extent, Expression> message) + private void ReportError(IScriptExtent extent, string errorId, string errorMsg) { - _parser.ReportError(extent, message); + _parser.ReportError(extent, errorId, errorMsg); } - private void ReportError(IScriptExtent extent, Expression> message, object arg) + private void ReportError(IScriptExtent extent, string errorId, string errorMsg, object arg) { - _parser.ReportError(extent, message, arg); + _parser.ReportError(extent, errorId, errorMsg, arg); } - private void ReportError(IScriptExtent extent, Expression> message, object arg1, object arg2) + private void ReportError(IScriptExtent extent, string errorId, string errorMsg, object arg1, object arg2) { - _parser.ReportError(extent, message, arg1, arg2); + _parser.ReportError(extent, errorId, errorMsg, arg1, arg2); } - private void ReportIncompleteInput(int errorOffset, Expression> message) + private void ReportIncompleteInput(int errorOffset, string errorId, string errorMsg) { - _parser.ReportIncompleteInput(NewScriptExtent(errorOffset, _currentIndex), message); + _parser.ReportIncompleteInput(NewScriptExtent(errorOffset, _currentIndex), errorId, errorMsg); } - private void ReportIncompleteInput(int errorOffset, Expression> message, object arg) + private void ReportIncompleteInput(int errorOffset, string errorId, string errorMsg, object arg) { - _parser.ReportIncompleteInput(NewScriptExtent(errorOffset, _currentIndex), message, arg); + _parser.ReportIncompleteInput(NewScriptExtent(errorOffset, _currentIndex), errorId, errorMsg, arg); } private InternalScriptExtent NewScriptExtent(int start, int end) @@ -1259,7 +1261,9 @@ private char ScanUnicodeEscape(out char surrogateCharacter) UngetChar(); IScriptExtent errorExtent = NewScriptExtent(escSeqStartIndex, _currentIndex); - ReportError(errorExtent, () => ParserStrings.InvalidUnicodeEscapeSequence); + ReportError(errorExtent, + nameof(ParserStrings.InvalidUnicodeEscapeSequence), + ParserStrings.InvalidUnicodeEscapeSequence); return s_invalidChar; } @@ -1278,7 +1282,9 @@ private char ScanUnicodeEscape(out char surrogateCharacter) // Sequence must have at least one hex char. Release(sb); IScriptExtent errorExtent = NewScriptExtent(escSeqStartIndex, _currentIndex); - ReportError(errorExtent, () => ParserStrings.InvalidUnicodeEscapeSequence); + ReportError(errorExtent, + nameof(ParserStrings.InvalidUnicodeEscapeSequence), + ParserStrings.InvalidUnicodeEscapeSequence); return s_invalidChar; } @@ -1289,10 +1295,18 @@ private char ScanUnicodeEscape(out char surrogateCharacter) UngetChar(); Release(sb); - ReportError(_currentIndex, - i < s_maxNumberOfUnicodeHexDigits - ? (Expression>)(() => ParserStrings.InvalidUnicodeEscapeSequence) - : () => ParserStrings.MissingUnicodeEscapeSequenceTerminator); + if (i < s_maxNumberOfUnicodeHexDigits) + { + ReportError(_currentIndex, + nameof(ParserStrings.InvalidUnicodeEscapeSequence), + ParserStrings.InvalidUnicodeEscapeSequence); + } + else + { + ReportError(_currentIndex, + nameof(ParserStrings.MissingUnicodeEscapeSequenceTerminator), + ParserStrings.MissingUnicodeEscapeSequenceTerminator); + } return s_invalidChar; } else if (i == s_maxNumberOfUnicodeHexDigits) { From 0a25f1435fca90e5cb22ea69b23bf3994fff61aa Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Sun, 25 Mar 2018 18:57:35 -0700 Subject: [PATCH 02/15] Finish changing ReportError usage --- .../engine/parser/SemanticChecks.cs | 456 +++++++++++++----- .../engine/parser/SymbolResolver.cs | 65 ++- .../engine/parser/tokenizer.cs | 197 ++++++-- .../engine/runtime/CompiledScriptBlock.cs | 4 +- 4 files changed, 552 insertions(+), 170 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/SemanticChecks.cs b/src/System.Management.Automation/engine/parser/SemanticChecks.cs index 8656cb6d9c1..efbf9e7ea1c 100644 --- a/src/System.Management.Automation/engine/parser/SemanticChecks.cs +++ b/src/System.Management.Automation/engine/parser/SemanticChecks.cs @@ -63,11 +63,22 @@ private bool IsValidAttributeArgument(Ast ast, IsConstantValueVisitor visitor) return (bool)ast.Accept(visitor); } - private Expression> GetNonConstantAttributeArgErrorExpr(IsConstantValueVisitor visitor) + private Tuple GetNonConstantAttributeArgErrorExpr(IsConstantValueVisitor visitor) { - return visitor.CheckingClassAttributeArguments - ? (Expression>)(() => ParserStrings.ParameterAttributeArgumentNeedsToBeConstant) - : () => ParserStrings.ParameterAttributeArgumentNeedsToBeConstantOrScriptBlock; + string errorId; + string errorMsg; + if (visitor.CheckingClassAttributeArguments) + { + errorId = nameof(ParserStrings.ParameterAttributeArgumentNeedsToBeConstant); + errorMsg = ParserStrings.ParameterAttributeArgumentNeedsToBeConstant; + } + else + { + errorId = nameof(ParserStrings.ParameterAttributeArgumentNeedsToBeConstantOrScriptBlock); + errorMsg = ParserStrings.ParameterAttributeArgumentNeedsToBeConstantOrScriptBlock; + } + + return new Tuple(errorId, errorMsg); } private void CheckForDuplicateParameters(ReadOnlyCollection parameters) @@ -80,7 +91,10 @@ private void CheckForDuplicateParameters(ReadOnlyCollection parame string parameterName = parameter.Name.VariablePath.UserPath; if (parametersSet.Contains(parameterName)) { - _parser.ReportError(parameter.Name.Extent, () => ParserStrings.DuplicateFormalParameter, parameterName); + _parser.ReportError(parameter.Name.Extent, + nameof(ParserStrings.DuplicateFormalParameter), + ParserStrings.DuplicateFormalParameter, + parameterName); } else { @@ -91,7 +105,9 @@ private void CheckForDuplicateParameters(ReadOnlyCollection parame if (voidConstraint != null) { - _parser.ReportError(voidConstraint.Extent, () => ParserStrings.VoidTypeConstraintNotAllowed); + _parser.ReportError(voidConstraint.Extent, + nameof(ParserStrings.VoidTypeConstraintNotAllowed), + ParserStrings.VoidTypeConstraintNotAllowed); } } } @@ -169,7 +185,11 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) var usage = attributeType.GetTypeInfo().GetCustomAttribute(true); if (usage != null && (usage.ValidOn & attributeTargets) == 0) { - _parser.ReportError(attributeAst.Extent, () => ParserStrings.AttributeNotAllowedOnDeclaration, ToStringCodeMethods.Type(attributeType), usage.ValidOn); + _parser.ReportError(attributeAst.Extent, + nameof(ParserStrings.AttributeNotAllowedOnDeclaration), + ParserStrings.AttributeNotAllowedOnDeclaration, + ToStringCodeMethods.Type(attributeType), + usage.ValidOn); } foreach (var namedArg in attributeAst.NamedArguments) @@ -181,7 +201,8 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) if (members.Length != 1 || !(members[0] is PropertyInfo || members[0] is FieldInfo)) { _parser.ReportError(namedArg.Extent, - () => ParserStrings.PropertyNotFoundForAttribute, + nameof(ParserStrings.PropertyNotFoundForAttribute), + ParserStrings.PropertyNotFoundForAttribute, name, ToStringCodeMethods.Type(attributeType), GetValidNamedAttributeProperties(attributeType)); @@ -194,7 +215,10 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) { if (propertyInfo.GetSetMethod() == null) { - _parser.ReportError(namedArg.Extent, () => ExtendedTypeSystem.ReadOnlyProperty, name); + _parser.ReportError(namedArg.Extent, + nameof(ExtendedTypeSystem.ReadOnlyProperty), + ExtendedTypeSystem.ReadOnlyProperty, + name); } continue; @@ -203,7 +227,10 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) var fieldInfo = (FieldInfo)members[0]; if (fieldInfo.IsInitOnly || fieldInfo.IsLiteral) { - _parser.ReportError(namedArg.Extent, () => ExtendedTypeSystem.ReadOnlyProperty, name); + _parser.ReportError(namedArg.Extent, + nameof(ExtendedTypeSystem.ReadOnlyProperty), + ExtendedTypeSystem.ReadOnlyProperty, + name); } } } @@ -214,7 +241,10 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) string name = namedArg.ArgumentName; if (names.Contains(name)) { - _parser.ReportError(namedArg.Extent, () => ParserStrings.DuplicateNamedArgument, name); + _parser.ReportError(namedArg.Extent, + nameof(ParserStrings.DuplicateNamedArgument), + ParserStrings.DuplicateNamedArgument, + name); } else { @@ -222,7 +252,8 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) if (!namedArg.ExpressionOmitted && !IsValidAttributeArgument(namedArg.Argument, constantValueVisitor)) { - _parser.ReportError(namedArg.Argument.Extent, GetNonConstantAttributeArgErrorExpr(constantValueVisitor)); + Tuple errorInfo = GetNonConstantAttributeArgErrorExpr(constantValueVisitor); + _parser.ReportError(namedArg.Argument.Extent, errorInfo.Item1, errorInfo.Item2); } } } @@ -231,7 +262,8 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) { if (!IsValidAttributeArgument(posArg, constantValueVisitor)) { - _parser.ReportError(posArg.Extent, GetNonConstantAttributeArgErrorExpr(constantValueVisitor)); + Tuple errorInfo = GetNonConstantAttributeArgErrorExpr(constantValueVisitor); + _parser.ReportError(posArg.Extent, errorInfo.Item1, errorInfo.Item2); } } @@ -273,7 +305,10 @@ public override AstVisitAction VisitParameter(ParameterAst parameterAst) { if (attribute.TypeName.FullName.Equals(LanguagePrimitives.OrderedAttribute, StringComparison.OrdinalIgnoreCase)) { - _parser.ReportError(attribute.Extent, () => ParserStrings.OrderedAttributeOnlyOnHashLiteralNode, attribute.TypeName.FullName); + _parser.ReportError(attribute.Extent, + nameof(ParserStrings.OrderedAttributeOnlyOnHashLiteralNode), + ParserStrings.OrderedAttributeOnlyOnHashLiteralNode, + attribute.TypeName.FullName); } else { @@ -282,7 +317,9 @@ public override AstVisitAction VisitParameter(ParameterAst parameterAst) // attribute represent parameter type. if (isParamTypeDefined) { - _parser.ReportError(attribute.Extent, () => ParserStrings.MultipleTypeConstraintsOnMethodParam); + _parser.ReportError(attribute.Extent, + nameof(ParserStrings.MultipleTypeConstraintsOnMethodParam), + ParserStrings.MultipleTypeConstraintsOnMethodParam); } isParamTypeDefined = true; } @@ -315,7 +352,9 @@ internal static void CheckArrayTypeNameDepth(ITypeName typeName, IScriptExtent e count++; if (count > 200) { - parser.ReportError(extent, () => ParserStrings.ScriptTooComplicated); + parser.ReportError(extent, + nameof(ParserStrings.ScriptTooComplicated), + ParserStrings.ScriptTooComplicated); break; } if (type is ArrayTypeName) @@ -356,7 +395,9 @@ public override AstVisitAction VisitFunctionMember(FunctionMemberAst functionMem var body = functionMemberAst.Body; if (body.ParamBlock != null) { - _parser.ReportError(body.ParamBlock.Extent, () => ParserStrings.ParamBlockNotAllowedInMethod); + _parser.ReportError(body.ParamBlock.Extent, + nameof(ParserStrings.ParamBlockNotAllowedInMethod), + ParserStrings.ParamBlockNotAllowedInMethod); } if (body.BeginBlock != null || @@ -365,19 +406,24 @@ public override AstVisitAction VisitFunctionMember(FunctionMemberAst functionMem !body.EndBlock.Unnamed) { _parser.ReportError(Parser.ExtentFromFirstOf(body.DynamicParamBlock, body.BeginBlock, body.ProcessBlock, body.EndBlock), - () => ParserStrings.NamedBlockNotAllowedInMethod); + nameof(ParserStrings.NamedBlockNotAllowedInMethod), + ParserStrings.NamedBlockNotAllowedInMethod); } if (functionMemberAst.IsConstructor && functionMemberAst.ReturnType != null) { - _parser.ReportError(functionMemberAst.ReturnType.Extent, () => ParserStrings.ConstructorCantHaveReturnType); + _parser.ReportError(functionMemberAst.ReturnType.Extent, + nameof(ParserStrings.ConstructorCantHaveReturnType), + ParserStrings.ConstructorCantHaveReturnType); } // Analysis determines if all paths return and do data flow for variables. var allCodePathsReturned = VariableAnalysis.AnalyzeMemberFunction(functionMemberAst); if (!allCodePathsReturned && !functionMemberAst.IsReturnTypeVoid()) { - _parser.ReportError(functionMemberAst.NameExtent ?? functionMemberAst.Extent, () => ParserStrings.MethodHasCodePathNotReturn); + _parser.ReportError(functionMemberAst.NameExtent ?? functionMemberAst.Extent, + nameof(ParserStrings.MethodHasCodePathNotReturn), + ParserStrings.MethodHasCodePathNotReturn); } return AstVisitAction.Continue; @@ -388,7 +434,9 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun if (functionDefinitionAst.Parameters != null && functionDefinitionAst.Body.ParamBlock != null) { - _parser.ReportError(functionDefinitionAst.Body.ParamBlock.Extent, () => ParserStrings.OnlyOneParameterListAllowed); + _parser.ReportError(functionDefinitionAst.Body.ParamBlock.Extent, + nameof(ParserStrings.OnlyOneParameterListAllowed), + ParserStrings.OnlyOneParameterListAllowed); } else if (functionDefinitionAst.Parameters != null) { @@ -397,7 +445,9 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun if (functionDefinitionAst.IsWorkflow) { - _parser.ReportError(functionDefinitionAst.Extent, () => ParserStrings.WorkflowNotSupportedInPowerShellCore); + _parser.ReportError(functionDefinitionAst.Extent, + nameof(ParserStrings.WorkflowNotSupportedInPowerShellCore), + ParserStrings.WorkflowNotSupportedInPowerShellCore); } return AstVisitAction.Continue; @@ -411,7 +461,9 @@ public override AstVisitAction VisitSwitchStatement(SwitchStatementAst switchSta bool reportError = !switchStatementAst.IsInWorkflow(); if (reportError) { - _parser.ReportError(switchStatementAst.Extent, () => ParserStrings.ParallelNotSupported); + _parser.ReportError(switchStatementAst.Extent, + nameof(ParserStrings.ParallelNotSupported), + ParserStrings.ParallelNotSupported); } } @@ -445,7 +497,9 @@ public override AstVisitAction VisitForEachStatement(ForEachStatementAst forEach bool reportError = !forEachStatementAst.IsInWorkflow(); if (reportError) { - _parser.ReportError(forEachStatementAst.Extent, () => ParserStrings.ParallelNotSupported); + _parser.ReportError(forEachStatementAst.Extent, + nameof(ParserStrings.ParallelNotSupported), + ParserStrings.ParallelNotSupported); } } @@ -453,7 +507,9 @@ public override AstVisitAction VisitForEachStatement(ForEachStatementAst forEach if ((forEachStatementAst.ThrottleLimit != null) && ((forEachStatementAst.Flags & ForEachFlags.Parallel) != ForEachFlags.Parallel)) { - _parser.ReportError(forEachStatementAst.Extent, () => ParserStrings.ThrottleLimitRequiresParallelFlag); + _parser.ReportError(forEachStatementAst.Extent, + nameof(ParserStrings.ThrottleLimitRequiresParallelFlag), + ParserStrings.ThrottleLimitRequiresParallelFlag); } return AstVisitAction.Continue; @@ -472,7 +528,9 @@ public override AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst if (block1.IsCatchAll) { - _parser.ReportError(Parser.Before(block2.Extent), () => ParserStrings.EmptyCatchNotLast); + _parser.ReportError(Parser.Before(block2.Extent), + nameof(ParserStrings.EmptyCatchNotLast), + ParserStrings.EmptyCatchNotLast); break; } @@ -494,7 +552,10 @@ public override AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst if (type1 == type2 || type2.IsSubclassOf(type1)) { - _parser.ReportError(typeLiteral2.Extent, () => ParserStrings.ExceptionTypeAlreadyCaught, type2.FullName); + _parser.ReportError(typeLiteral2.Extent, + nameof(ParserStrings.ExceptionTypeAlreadyCaught), + ParserStrings.ExceptionTypeAlreadyCaught, + type2.FullName); } } } @@ -524,7 +585,10 @@ private void CheckLabelExists(StatementAst ast, string label) { if (parent.Parent is FunctionMemberAst) { - _parser.ReportError(ast.Extent, () => ParserStrings.LabelNotFound, label); + _parser.ReportError(ast.Extent, + nameof(ParserStrings.LabelNotFound), + ParserStrings.LabelNotFound, + label); } break; } @@ -573,7 +637,9 @@ private void CheckForFlowOutOfFinally(Ast ast, string label) var tryStatementAst = stmtBlock.Parent as TryStatementAst; if (tryStatementAst != null && tryStatementAst.Finally == stmtBlock) { - _parser.ReportError(ast.Extent, () => ParserStrings.ControlLeavingFinally); + _parser.ReportError(ast.Extent, + nameof(ParserStrings.ControlLeavingFinally), + ParserStrings.ControlLeavingFinally); break; } } @@ -622,14 +688,18 @@ private void CheckForReturnStatement(ReturnStatementAst ast) { if (functionMemberAst.IsReturnTypeVoid()) { - _parser.ReportError(ast.Extent, () => ParserStrings.VoidMethodHasReturn); + _parser.ReportError(ast.Extent, + nameof(ParserStrings.VoidMethodHasReturn), + ParserStrings.VoidMethodHasReturn); } } else { if (!functionMemberAst.IsReturnTypeVoid()) { - _parser.ReportError(ast.Extent, () => ParserStrings.NonVoidMethodMissingReturnValue); + _parser.ReportError(ast.Extent, + nameof(ParserStrings.NonVoidMethodMissingReturnValue), + ParserStrings.NonVoidMethodMissingReturnValue); } } } @@ -701,7 +771,9 @@ private void CheckAssignmentTarget(ExpressionAst ast, bool simpleAssignment, Act } else if (typeof(void) == lastConvertType) { - _parser.ReportError(convertExpr.Type.Extent, () => ParserStrings.VoidTypeConstraintNotAllowed); + _parser.ReportError(convertExpr.Type.Extent, + nameof(ParserStrings.VoidTypeConstraintNotAllowed), + ParserStrings.VoidTypeConstraintNotAllowed); } } expr = ((AttributedExpressionAst)expr).Child; @@ -709,7 +781,9 @@ private void CheckAssignmentTarget(ExpressionAst ast, bool simpleAssignment, Act if ((errorPosition != null) && converts > 1) { - _parser.ReportError(errorPosition, () => ParserStrings.ReferenceNeedsToBeByItselfInTypeConstraint); + _parser.ReportError(errorPosition, + nameof(ParserStrings.ReferenceNeedsToBeByItselfInTypeConstraint), + ParserStrings.ReferenceNeedsToBeByItselfInTypeConstraint); } else { @@ -727,7 +801,10 @@ private void CheckAssignmentTarget(ExpressionAst ast, bool simpleAssignment, Act var expectedType = SpecialVariables.AutomaticVariableTypes[specialIndex]; if (expectedType != lastConvertType) { - _parser.ReportError(ast.Extent, () => ParserStrings.AssignmentStatementToAutomaticNotSupported, varPath.UnqualifiedPath, expectedType); + _parser.ReportError(ast.Extent, + nameof(ParserStrings.AssignmentStatementToAutomaticNotSupported), + ParserStrings.AssignmentStatementToAutomaticNotSupported, + varPath.UnqualifiedPath, expectedType); } break; } @@ -758,7 +835,9 @@ public override AstVisitAction VisitAssignmentStatement(AssignmentStatementAst a { // Make sure LHS is something that can be assigned to. CheckAssignmentTarget(assignmentStatementAst.Left, assignmentStatementAst.Operator == TokenKind.Equals, - ast => _parser.ReportError(ast.Extent, () => ParserStrings.InvalidLeftHandSide)); + ast => _parser.ReportError(ast.Extent, + nameof(ParserStrings.InvalidLeftHandSide), + ParserStrings.InvalidLeftHandSide)); return AstVisitAction.Continue; } @@ -768,7 +847,9 @@ public override AstVisitAction VisitBinaryExpression(BinaryExpressionAst binaryE if (binaryExpressionAst.Operator == TokenKind.AndAnd || binaryExpressionAst.Operator == TokenKind.OrOr) { - _parser.ReportError(binaryExpressionAst.ErrorPosition, () => ParserStrings.InvalidEndOfLine, + _parser.ReportError(binaryExpressionAst.ErrorPosition, + nameof(ParserStrings.InvalidEndOfLine), + ParserStrings.InvalidEndOfLine, binaryExpressionAst.Operator.Text()); } @@ -784,7 +865,9 @@ public override AstVisitAction VisitUnaryExpression(UnaryExpressionAst unaryExpr case TokenKind.MinusMinus: case TokenKind.PostfixMinusMinus: CheckAssignmentTarget(unaryExpressionAst.Child, false, - ast => _parser.ReportError(ast.Extent, () => ParserStrings.OperatorRequiresVariableOrProperty, + ast => _parser.ReportError(ast.Extent, + nameof(ParserStrings.OperatorRequiresVariableOrProperty), + ParserStrings.OperatorRequiresVariableOrProperty, unaryExpressionAst.TokenKind.Text())); break; } @@ -801,7 +884,10 @@ public override AstVisitAction VisitConvertExpression(ConvertExpressionAst conve // We allow the ordered attribute only on hashliteral node. // This check covers the following scenario // $a = [ordered]10 - _parser.ReportError(convertExpressionAst.Extent, () => ParserStrings.OrderedAttributeOnlyOnHashLiteralNode, convertExpressionAst.Type.TypeName.FullName); + _parser.ReportError(convertExpressionAst.Extent, + nameof(ParserStrings.OrderedAttributeOnlyOnHashLiteralNode), + ParserStrings.OrderedAttributeOnlyOnHashLiteralNode, + convertExpressionAst.Type.TypeName.FullName); } } @@ -820,7 +906,8 @@ public override AstVisitAction VisitConvertExpression(ConvertExpressionAst conve { multipleRefs = true; _parser.ReportError(childConvert.Type.Extent, - () => ParserStrings.ReferenceNeedsToBeByItselfInTypeSequence); + nameof(ParserStrings.ReferenceNeedsToBeByItselfInTypeSequence), + ParserStrings.ReferenceNeedsToBeByItselfInTypeSequence); } child = childAttrExpr.Child; continue; @@ -862,7 +949,8 @@ public override AstVisitAction VisitConvertExpression(ConvertExpressionAst conve if (!skipError) { _parser.ReportError(convertExpressionAst.Type.Extent, - () => ParserStrings.ReferenceNeedsToBeLastTypeInTypeConversion); + nameof(ParserStrings.ReferenceNeedsToBeLastTypeInTypeConversion), + ParserStrings.ReferenceNeedsToBeLastTypeInTypeConversion); } } parent = parent.Child as AttributedExpressionAst; @@ -888,7 +976,9 @@ public override AstVisitAction VisitUsingExpression(UsingExpressionAst usingExpr var badExpr = CheckUsingExpression(exprAst); if (badExpr != null) { - _parser.ReportError(badExpr.Extent, () => ParserStrings.InvalidUsingExpression); + _parser.ReportError(badExpr.Extent, + nameof(ParserStrings.InvalidUsingExpression), + ParserStrings.InvalidUsingExpression); } return AstVisitAction.Continue; @@ -927,11 +1017,17 @@ public override AstVisitAction VisitVariableExpression(VariableExpressionAst var { if (variableExpressionAst.Parent is ArrayLiteralAst && variableExpressionAst.Parent.Parent is CommandAst) { - _parser.ReportError(variableExpressionAst.Extent, () => ParserStrings.SplattingNotPermittedInArgumentList, variableExpressionAst.VariablePath.UserPath); + _parser.ReportError(variableExpressionAst.Extent, + nameof(ParserStrings.SplattingNotPermittedInArgumentList), + ParserStrings.SplattingNotPermittedInArgumentList, + variableExpressionAst.VariablePath.UserPath); } else { - _parser.ReportError(variableExpressionAst.Extent, () => ParserStrings.SplattingNotPermitted, variableExpressionAst.VariablePath.UserPath); + _parser.ReportError(variableExpressionAst.Extent, + nameof(ParserStrings.SplattingNotPermitted), + ParserStrings.SplattingNotPermitted, + variableExpressionAst.VariablePath.UserPath); } } @@ -944,7 +1040,9 @@ public override AstVisitAction VisitVariableExpression(VariableExpressionAst var && !variableExpressionAst.IsConstantVariable() && !SpecialVariables.IsImplicitVariableAccessibleInClassMethod(variableExpressionAst.VariablePath)) { - _parser.ReportError(variableExpressionAst.Extent, () => ParserStrings.VariableNotLocal); + _parser.ReportError(variableExpressionAst.Extent, + nameof(ParserStrings.VariableNotLocal), + ParserStrings.VariableNotLocal); } } @@ -952,7 +1050,10 @@ public override AstVisitAction VisitVariableExpression(VariableExpressionAst var { if (AnalyzingStaticMember()) { - _parser.ReportError(variableExpressionAst.Extent, () => ParserStrings.NonStaticMemberAccessInStaticMember, variableExpressionAst.VariablePath.UserPath); + _parser.ReportError(variableExpressionAst.Extent, + nameof(ParserStrings.NonStaticMemberAccessInStaticMember), + ParserStrings.NonStaticMemberAccessInStaticMember, + variableExpressionAst.VariablePath.UserPath); } } @@ -970,13 +1071,23 @@ public override AstVisitAction VisitHashtable(HashtableAst hashtableAst) var keyStr = keyStrAst.Value.ToString(); if (keys.Contains(keyStr)) { - // Note - the error handling function inspects the error message body to extra the ParserStrings property name. It uses this value as the errorid. - var errorMessageExpression = hashtableAst.IsSchemaElement - ? (() => ParserStrings.DuplicatePropertyInInstanceDefinition) - : (Expression>)(() => ParserStrings.DuplicateKeyInHashLiteral); + string errorId; + string errorMsg; + if (hashtableAst.IsSchemaElement) + { + errorId = nameof(ParserStrings.DuplicatePropertyInInstanceDefinition); + errorMsg = ParserStrings.DuplicatePropertyInInstanceDefinition; + } + else + { + errorId = nameof(ParserStrings.DuplicateKeyInHashLiteral); + errorMsg = ParserStrings.DuplicateKeyInHashLiteral; + } - _parser.ReportError(entry.Item1.Extent, errorMessageExpression, - keyStr); + _parser.ReportError(entry.Item1.Extent, + errorId, + errorMsg, + keyStr); } else { @@ -1002,7 +1113,10 @@ public override AstVisitAction VisitAttributedExpression(AttributedExpressionAst attributedExpressionAst = attributedExpressionAst.Child as AttributedExpressionAst; } - _parser.ReportError(errorAst.Extent, () => ParserStrings.UnexpectedAttribute, errorAst.TypeName.FullName); + _parser.ReportError(errorAst.Extent, + nameof(ParserStrings.UnexpectedAttribute), + ParserStrings.UnexpectedAttribute, + errorAst.TypeName.FullName); return AstVisitAction.Continue; } @@ -1014,7 +1128,10 @@ public override AstVisitAction VisitBlockStatement(BlockStatementAst blockStatem return AstVisitAction.Continue; } - _parser.ReportError(blockStatementAst.Kind.Extent, () => ParserStrings.UnexpectedKeyword, blockStatementAst.Kind.Text); + _parser.ReportError(blockStatementAst.Kind.Extent, + nameof(ParserStrings.UnexpectedKeyword), + ParserStrings.UnexpectedKeyword, + blockStatementAst.Kind.Text); return AstVisitAction.Continue; } @@ -1125,7 +1242,10 @@ public override AstVisitAction VisitScriptBlockExpression(ScriptBlockExpressionA var commandNameAst = commandAst.CommandElements[0] as StringConstantExpressionAst; if (commandNameAst != null) { - _parser.ReportError(commandNameAst.Extent, () => ParserStrings.ResourceNotDefined, commandNameAst.Extent.Text); + _parser.ReportError(commandNameAst.Extent, + nameof(ParserStrings.ResourceNotDefined), + ParserStrings.ResourceNotDefined, + commandNameAst.Extent.Text); } } } @@ -1148,7 +1268,9 @@ public override AstVisitAction VisitUsingStatement(UsingStatementAst usingStatem if (!usingKindSupported || usingStatementAst.Alias != null) { - _parser.ReportError(usingStatementAst.Extent, () => ParserStrings.UsingStatementNotSupported); + _parser.ReportError(usingStatementAst.Extent, + nameof(ParserStrings.UsingStatementNotSupported), + ParserStrings.UsingStatementNotSupported); } return AstVisitAction.Continue; @@ -1167,7 +1289,9 @@ public override AstVisitAction VisitConfigurationDefinition(ConfigurationDefinit { if (namedBlock != null) { - _parser.ReportError(namedBlock.OpenCurlyExtent, () => ParserStrings.UnsupportedNamedBlockInConfiguration); + _parser.ReportError(namedBlock.OpenCurlyExtent, + nameof(ParserStrings.UnsupportedNamedBlockInConfiguration), + ParserStrings.UnsupportedNamedBlockInConfiguration); } } @@ -1192,7 +1316,10 @@ public override AstVisitAction VisitDynamicKeywordStatement(DynamicKeywordStatem } catch (Exception e) { - _parser.ReportError(dynamicKeywordStatementAst.Extent, () => ParserStrings.DynamicKeywordSemanticCheckException, dynamicKeywordStatementAst.Keyword.ResourceName, e.ToString()); + _parser.ReportError(dynamicKeywordStatementAst.Extent, + nameof(ParserStrings.DynamicKeywordSemanticCheckException), + ParserStrings.DynamicKeywordSemanticCheckException, + dynamicKeywordStatementAst.Keyword.ResourceName, e.ToString()); } } DynamicKeyword keyword = dynamicKeywordStatementAst.Keyword; @@ -1208,13 +1335,15 @@ public override AstVisitAction VisitDynamicKeywordStatement(DynamicKeywordStatem if (propName == null) { _parser.ReportError(keyValueTuple.Item1.Extent, - () => ParserStrings.ConfigurationInvalidPropertyName, + nameof(ParserStrings.ConfigurationInvalidPropertyName), + ParserStrings.ConfigurationInvalidPropertyName, dynamicKeywordStatementAst.FunctionName.Extent, keyValueTuple.Item1.Extent); } else if (!keyword.Properties.ContainsKey(propName.Value)) { _parser.ReportError(propName.Extent, - () => ParserStrings.InvalidInstanceProperty, + nameof(ParserStrings.InvalidInstanceProperty), + ParserStrings.InvalidInstanceProperty, propName.Value, string.Join("', '", keyword.Properties.Keys.OrderBy(key => key, StringComparer.OrdinalIgnoreCase))); } @@ -1234,13 +1363,15 @@ public override AstVisitAction VisitDynamicKeywordStatement(DynamicKeywordStatem if (configAst.ConfigurationType == ConfigurationType.Meta && !dynamicKeywordStatementAst.Keyword.IsMetaDSCResource()) { _parser.ReportError(nameAst.Extent, - () => ParserStrings.RegularResourceUsedInMetaConfig, + nameof(ParserStrings.RegularResourceUsedInMetaConfig), + ParserStrings.RegularResourceUsedInMetaConfig, nameAst.Extent.Text); } else if (configAst.ConfigurationType != ConfigurationType.Meta && dynamicKeywordStatementAst.Keyword.IsMetaDSCResource()) { _parser.ReportError(nameAst.Extent, - () => ParserStrings.MetaConfigurationUsedInRegularConfig, + nameof(ParserStrings.MetaConfigurationUsedInRegularConfig), + ParserStrings.MetaConfigurationUsedInRegularConfig, nameAst.Extent.Text); } } @@ -1258,7 +1389,9 @@ public override AstVisitAction VisitPropertyMember(PropertyMemberAst propertyMem if (type != null && (type == typeof(void) || type.GetTypeInfo().IsGenericTypeDefinition)) { - _parser.ReportError(propertyMemberAst.PropertyType.Extent, () => ParserStrings.TypeNotAllowedForProperty, + _parser.ReportError(propertyMemberAst.PropertyType.Extent, + nameof(ParserStrings.TypeNotAllowedForProperty), + ParserStrings.TypeNotAllowedForProperty, propertyMemberAst.PropertyType.TypeName.FullName); } } @@ -1346,27 +1479,42 @@ internal static void CheckType(Parser parser, TypeDefinitionAst typeDefinitionAs if (!hasSet) { - parser.ReportError(dscResourceAttributeAst.Extent, () => ParserStrings.DscResourceMissingSetMethod, name); + parser.ReportError(dscResourceAttributeAst.Extent, + nameof(ParserStrings.DscResourceMissingSetMethod), + ParserStrings.DscResourceMissingSetMethod, + name); } if (!hasGet) { - parser.ReportError(dscResourceAttributeAst.Extent, () => ParserStrings.DscResourceMissingGetMethod, name); + parser.ReportError(dscResourceAttributeAst.Extent, + nameof(ParserStrings.DscResourceMissingGetMethod), + ParserStrings.DscResourceMissingGetMethod, + name); } if (!hasTest) { - parser.ReportError(dscResourceAttributeAst.Extent, () => ParserStrings.DscResourceMissingTestMethod, name); + parser.ReportError(dscResourceAttributeAst.Extent, + nameof(ParserStrings.DscResourceMissingTestMethod), + ParserStrings.DscResourceMissingTestMethod, + name); } if (!hasDefaultCtor && hasNonDefaultCtor) { - parser.ReportError(dscResourceAttributeAst.Extent, () => ParserStrings.DscResourceMissingDefaultConstructor, name); + parser.ReportError(dscResourceAttributeAst.Extent, + nameof(ParserStrings.DscResourceMissingDefaultConstructor), + ParserStrings.DscResourceMissingDefaultConstructor, + name); } if (!hasKey) { - parser.ReportError(dscResourceAttributeAst.Extent, () => ParserStrings.DscResourceMissingKeyProperty, name); + parser.ReportError(dscResourceAttributeAst.Extent, + nameof(ParserStrings.DscResourceMissingKeyProperty), + ParserStrings.DscResourceMissingKeyProperty, + name); } } /// @@ -1450,12 +1598,18 @@ private static void CheckGet(Parser parser, FunctionMemberAst functionMemberAst, TypeName; if (typeName == null || typeName._typeDefinitionAst != functionMemberAst.Parent) { - parser.ReportError(functionMemberAst.Extent, () => ParserStrings.DscResourceInvalidGetMethod, ((TypeDefinitionAst)functionMemberAst.Parent).Name); + parser.ReportError(functionMemberAst.Extent, + nameof(ParserStrings.DscResourceInvalidGetMethod), + ParserStrings.DscResourceInvalidGetMethod, + ((TypeDefinitionAst)functionMemberAst.Parent).Name); } } else { - parser.ReportError(functionMemberAst.Extent, () => ParserStrings.DscResourceInvalidGetMethod, ((TypeDefinitionAst)functionMemberAst.Parent).Name); + parser.ReportError(functionMemberAst.Extent, + nameof(ParserStrings.DscResourceInvalidGetMethod), + ParserStrings.DscResourceInvalidGetMethod, + ((TypeDefinitionAst)functionMemberAst.Parent).Name); } //Set hasGet to true to stop look up; it may have invalid get hasGet = true; @@ -1535,7 +1689,9 @@ private static void CheckKey(Parser parser, PropertyMemberAst propertyMemberAst, } if (!keyPropertyTypeAllowed) { - parser.ReportError(propertyMemberAst.Extent, () => ParserStrings.DscResourceInvalidKeyProperty); + parser.ReportError(propertyMemberAst.Extent, + nameof(ParserStrings.DscResourceInvalidKeyProperty), + ParserStrings.DscResourceInvalidKeyProperty); } return; } @@ -1596,7 +1752,9 @@ internal static void CheckDataStatementLanguageModeAtRuntime(DataStatementAst da if (executionContext.LanguageMode == PSLanguageMode.ConstrainedLanguage) { var parser = new Parser(); - parser.ReportError(dataStatementAst.CommandsAllowed[0].Extent, () => ParserStrings.DataSectionAllowedCommandDisallowed); + parser.ReportError(dataStatementAst.CommandsAllowed[0].Extent, + nameof(ParserStrings.DataSectionAllowedCommandDisallowed), + ParserStrings.DataSectionAllowedCommandDisallowed); throw new ParseException(parser.ErrorList.ToArray()); } } @@ -1617,28 +1775,32 @@ internal static void EnsureUtilityModuleLoaded(ExecutionContext context) Utils.EnsureModuleLoaded("Microsoft.PowerShell.Utility", context); } - private void ReportError(Ast ast, Expression> errorExpr, params object[] args) + private void ReportError(Ast ast, string errorId, string errorMsg, params object[] args) { - ReportError(ast.Extent, errorExpr, args); + ReportError(ast.Extent, errorId, errorMsg, args); FoundError = true; } - private void ReportError(IScriptExtent extent, Expression> errorExpr, params object[] args) + private void ReportError(IScriptExtent extent, string errorId, string errorMsg, params object[] args) { - _parser.ReportError(extent, errorExpr, args); + _parser.ReportError(extent, errorId, errorMsg, args); FoundError = true; } public override AstVisitAction VisitScriptBlock(ScriptBlockAst scriptBlockAst) { - ReportError(scriptBlockAst, () => ParserStrings.ScriptBlockNotSupportedInDataSection); + ReportError(scriptBlockAst, + nameof(ParserStrings.ScriptBlockNotSupportedInDataSection), + ParserStrings.ScriptBlockNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitParamBlock(ParamBlockAst paramBlockAst) { - ReportError(paramBlockAst, () => ParserStrings.ParameterDeclarationNotSupportedInDataSection); + ReportError(paramBlockAst, + nameof(ParserStrings.ParameterDeclarationNotSupportedInDataSection), + ParserStrings.ParameterDeclarationNotSupportedInDataSection); return AstVisitAction.Continue; } @@ -1661,7 +1823,10 @@ private void CheckTypeName(Ast ast, ITypeName typename) // If we couldn't resolve the type, then it's definitely an error. if (type == null || ((type.IsArray ? type.GetElementType() : type).GetTypeCode() == TypeCode.Object)) { - ReportError(ast, () => ParserStrings.TypeNotAllowedInDataSection, typename.FullName); + ReportError(ast, + nameof(ParserStrings.TypeNotAllowedInDataSection), + ParserStrings.TypeNotAllowedInDataSection, + typename.FullName); } } @@ -1675,7 +1840,9 @@ public override AstVisitAction VisitTypeConstraint(TypeConstraintAst typeConstra public override AstVisitAction VisitAttribute(AttributeAst attributeAst) { Diagnostics.Assert(FoundError, "an error should have been reported elsewhere, making this redunant"); - ReportError(attributeAst, () => ParserStrings.AttributeNotSupportedInDataSection); + ReportError(attributeAst, + nameof(ParserStrings.AttributeNotSupportedInDataSection), + ParserStrings.AttributeNotSupportedInDataSection); return AstVisitAction.Continue; } @@ -1696,7 +1863,9 @@ public override AstVisitAction VisitTypeExpression(TypeExpressionAst typeExpress public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst functionDefinitionAst) { - ReportError(functionDefinitionAst, () => ParserStrings.FunctionDeclarationNotSupportedInDataSection); + ReportError(functionDefinitionAst, + nameof(ParserStrings.FunctionDeclarationNotSupportedInDataSection), + ParserStrings.FunctionDeclarationNotSupportedInDataSection); return AstVisitAction.Continue; } @@ -1717,49 +1886,63 @@ public override AstVisitAction VisitIfStatement(IfStatementAst ifStmtAst) public override AstVisitAction VisitTrap(TrapStatementAst trapStatementAst) { - ReportError(trapStatementAst, () => ParserStrings.TrapStatementNotSupportedInDataSection); + ReportError(trapStatementAst, + nameof(ParserStrings.TrapStatementNotSupportedInDataSection), + ParserStrings.TrapStatementNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitSwitchStatement(SwitchStatementAst switchStatementAst) { - ReportError(switchStatementAst, () => ParserStrings.SwitchStatementNotSupportedInDataSection); + ReportError(switchStatementAst, + nameof(ParserStrings.SwitchStatementNotSupportedInDataSection), + ParserStrings.SwitchStatementNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitDataStatement(DataStatementAst dataStatementAst) { - ReportError(dataStatementAst, () => ParserStrings.DataSectionStatementNotSupportedInDataSection); + ReportError(dataStatementAst, + nameof(ParserStrings.DataSectionStatementNotSupportedInDataSection), + ParserStrings.DataSectionStatementNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitForEachStatement(ForEachStatementAst forEachStatementAst) { - ReportError(forEachStatementAst, () => ParserStrings.ForeachStatementNotSupportedInDataSection); + ReportError(forEachStatementAst, + nameof(ParserStrings.ForeachStatementNotSupportedInDataSection), + ParserStrings.ForeachStatementNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitDoWhileStatement(DoWhileStatementAst doWhileStatementAst) { - ReportError(doWhileStatementAst, () => ParserStrings.DoWhileStatementNotSupportedInDataSection); + ReportError(doWhileStatementAst, + nameof(ParserStrings.DoWhileStatementNotSupportedInDataSection), + ParserStrings.DoWhileStatementNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitForStatement(ForStatementAst forStatementAst) { - ReportError(forStatementAst, () => ParserStrings.ForWhileStatementNotSupportedInDataSection); + ReportError(forStatementAst, + nameof(ParserStrings.ForWhileStatementNotSupportedInDataSection), + ParserStrings.ForWhileStatementNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitWhileStatement(WhileStatementAst whileStatementAst) { - ReportError(whileStatementAst, () => ParserStrings.ForWhileStatementNotSupportedInDataSection); + ReportError(whileStatementAst, + nameof(ParserStrings.ForWhileStatementNotSupportedInDataSection), + ParserStrings.ForWhileStatementNotSupportedInDataSection); return AstVisitAction.Continue; } @@ -1773,49 +1956,63 @@ public override AstVisitAction VisitCatchClause(CatchClauseAst catchClauseAst) public override AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst) { - ReportError(tryStatementAst, () => ParserStrings.TryStatementNotSupportedInDataSection); + ReportError(tryStatementAst, + nameof(ParserStrings.TryStatementNotSupportedInDataSection), + ParserStrings.TryStatementNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitBreakStatement(BreakStatementAst breakStatementAst) { - ReportError(breakStatementAst, () => ParserStrings.FlowControlStatementNotSupportedInDataSection); + ReportError(breakStatementAst, + nameof(ParserStrings.FlowControlStatementNotSupportedInDataSection), + ParserStrings.FlowControlStatementNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitContinueStatement(ContinueStatementAst continueStatementAst) { - ReportError(continueStatementAst, () => ParserStrings.FlowControlStatementNotSupportedInDataSection); + ReportError(continueStatementAst, + nameof(ParserStrings.FlowControlStatementNotSupportedInDataSection), + ParserStrings.FlowControlStatementNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitReturnStatement(ReturnStatementAst returnStatementAst) { - ReportError(returnStatementAst, () => ParserStrings.FlowControlStatementNotSupportedInDataSection); + ReportError(returnStatementAst, + nameof(ParserStrings.FlowControlStatementNotSupportedInDataSection), + ParserStrings.FlowControlStatementNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitExitStatement(ExitStatementAst exitStatementAst) { - ReportError(exitStatementAst, () => ParserStrings.FlowControlStatementNotSupportedInDataSection); + ReportError(exitStatementAst, + nameof(ParserStrings.FlowControlStatementNotSupportedInDataSection), + ParserStrings.FlowControlStatementNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitThrowStatement(ThrowStatementAst throwStatementAst) { - ReportError(throwStatementAst, () => ParserStrings.FlowControlStatementNotSupportedInDataSection); + ReportError(throwStatementAst, + nameof(ParserStrings.FlowControlStatementNotSupportedInDataSection), + ParserStrings.FlowControlStatementNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitDoUntilStatement(DoUntilStatementAst doUntilStatementAst) { - ReportError(doUntilStatementAst, () => ParserStrings.DoWhileStatementNotSupportedInDataSection); + ReportError(doUntilStatementAst, + nameof(ParserStrings.DoWhileStatementNotSupportedInDataSection), + ParserStrings.DoWhileStatementNotSupportedInDataSection); return AstVisitAction.Continue; } @@ -1823,7 +2020,9 @@ public override AstVisitAction VisitDoUntilStatement(DoUntilStatementAst doUntil public override AstVisitAction VisitAssignmentStatement(AssignmentStatementAst assignmentStatementAst) { // Assignments are never allowed. - ReportError(assignmentStatementAst, () => ParserStrings.AssignmentStatementNotSupportedInDataSection); + ReportError(assignmentStatementAst, + nameof(ParserStrings.AssignmentStatementNotSupportedInDataSection), + ParserStrings.AssignmentStatementNotSupportedInDataSection); return AstVisitAction.Continue; } @@ -1844,7 +2043,9 @@ public override AstVisitAction VisitCommand(CommandAst commandAst) if (commandAst.InvocationOperator == TokenKind.Dot) { - ReportError(commandAst, () => ParserStrings.DotSourcingNotSupportedInDataSection); + ReportError(commandAst, + nameof(ParserStrings.DotSourcingNotSupportedInDataSection), + ParserStrings.DotSourcingNotSupportedInDataSection); return AstVisitAction.Continue; } @@ -1856,12 +2057,17 @@ public override AstVisitAction VisitCommand(CommandAst commandAst) { if (commandAst.InvocationOperator == TokenKind.Ampersand) { - ReportError(commandAst, () => ParserStrings.OperatorNotSupportedInDataSection, - TokenKind.Ampersand.Text()); + ReportError(commandAst, + nameof(ParserStrings.OperatorNotSupportedInDataSection), + ParserStrings.OperatorNotSupportedInDataSection, + TokenKind.Ampersand.Text()); } else { - ReportError(commandAst, () => ParserStrings.CmdletNotInAllowedListForDataSection, commandAst.Extent.Text); + ReportError(commandAst, + nameof(ParserStrings.CmdletNotInAllowedListForDataSection), + ParserStrings.CmdletNotInAllowedListForDataSection, + commandAst.Extent.Text); } return AstVisitAction.Continue; } @@ -1871,7 +2077,10 @@ public override AstVisitAction VisitCommand(CommandAst commandAst) return AstVisitAction.Continue; } - ReportError(commandAst, () => ParserStrings.CmdletNotInAllowedListForDataSection, commandName); + ReportError(commandAst, + nameof(ParserStrings.CmdletNotInAllowedListForDataSection), + ParserStrings.CmdletNotInAllowedListForDataSection, + commandName); return AstVisitAction.Continue; } @@ -1892,14 +2101,18 @@ public override AstVisitAction VisitCommandParameter(CommandParameterAst command public override AstVisitAction VisitMergingRedirection(MergingRedirectionAst mergingRedirectionAst) { - ReportError(mergingRedirectionAst, () => ParserStrings.RedirectionNotSupportedInDataSection); + ReportError(mergingRedirectionAst, + nameof(ParserStrings.RedirectionNotSupportedInDataSection), + ParserStrings.RedirectionNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitFileRedirection(FileRedirectionAst fileRedirectionAst) { - ReportError(fileRedirectionAst, () => ParserStrings.RedirectionNotSupportedInDataSection); + ReportError(fileRedirectionAst, + nameof(ParserStrings.RedirectionNotSupportedInDataSection), + ParserStrings.RedirectionNotSupportedInDataSection); return AstVisitAction.Continue; } @@ -1918,7 +2131,10 @@ public override AstVisitAction VisitBinaryExpression(BinaryExpressionAst binaryE if (binaryExpressionAst.Operator.HasTrait(TokenFlags.DisallowedInRestrictedMode)) { - ReportError(binaryExpressionAst.ErrorPosition, () => ParserStrings.OperatorNotSupportedInDataSection, binaryExpressionAst.Operator.Text()); + ReportError(binaryExpressionAst.ErrorPosition, + nameof(ParserStrings.OperatorNotSupportedInDataSection), + ParserStrings.OperatorNotSupportedInDataSection, + binaryExpressionAst.Operator.Text()); } return AstVisitAction.Continue; @@ -1928,7 +2144,10 @@ public override AstVisitAction VisitUnaryExpression(UnaryExpressionAst unaryExpr { if (unaryExpressionAst.TokenKind.HasTrait(TokenFlags.DisallowedInRestrictedMode)) { - ReportError(unaryExpressionAst, () => ParserStrings.OperatorNotSupportedInDataSection, unaryExpressionAst.TokenKind.Text()); + ReportError(unaryExpressionAst, + nameof(ParserStrings.OperatorNotSupportedInDataSection), + ParserStrings.OperatorNotSupportedInDataSection, + unaryExpressionAst.TokenKind.Text()); } return AstVisitAction.Continue; @@ -2011,21 +2230,28 @@ public override AstVisitAction VisitVariableExpression(VariableExpressionAst var resourceArg = argBuilder.ToString(); } - ReportError(variableExpressionAst, () => ParserStrings.VariableReferenceNotSupportedInDataSection, resourceArg); + ReportError(variableExpressionAst, + nameof(ParserStrings.VariableReferenceNotSupportedInDataSection), + ParserStrings.VariableReferenceNotSupportedInDataSection, + resourceArg); return AstVisitAction.Continue; } public override AstVisitAction VisitMemberExpression(MemberExpressionAst memberExpressionAst) { - ReportError(memberExpressionAst, () => ParserStrings.PropertyReferenceNotSupportedInDataSection); + ReportError(memberExpressionAst, + nameof(ParserStrings.PropertyReferenceNotSupportedInDataSection), + ParserStrings.PropertyReferenceNotSupportedInDataSection); return AstVisitAction.Continue; } public override AstVisitAction VisitInvokeMemberExpression(InvokeMemberExpressionAst methodCallAst) { - ReportError(methodCallAst, () => ParserStrings.MethodCallNotSupportedInDataSection); + ReportError(methodCallAst, + nameof(ParserStrings.MethodCallNotSupportedInDataSection), + ParserStrings.MethodCallNotSupportedInDataSection); return AstVisitAction.Continue; } @@ -2053,7 +2279,9 @@ public override AstVisitAction VisitHashtable(HashtableAst hashtableAst) public override AstVisitAction VisitScriptBlockExpression(ScriptBlockExpressionAst scriptBlockExpressionAst) { - ReportError(scriptBlockExpressionAst, () => ParserStrings.ScriptBlockNotSupportedInDataSection); + ReportError(scriptBlockExpressionAst, + nameof(ParserStrings.ScriptBlockNotSupportedInDataSection), + ParserStrings.ScriptBlockNotSupportedInDataSection); return AstVisitAction.Continue; } @@ -2077,7 +2305,9 @@ public override AstVisitAction VisitExpandableStringExpression(ExpandableStringE public override AstVisitAction VisitIndexExpression(IndexExpressionAst indexExpressionAst) { // Array references are never allowed. They could turn into function calls. - ReportError(indexExpressionAst, () => ParserStrings.ArrayReferenceNotSupportedInDataSection); + ReportError(indexExpressionAst, + nameof(ParserStrings.ArrayReferenceNotSupportedInDataSection), + ParserStrings.ArrayReferenceNotSupportedInDataSection); return AstVisitAction.Continue; } @@ -2085,7 +2315,9 @@ public override AstVisitAction VisitIndexExpression(IndexExpressionAst indexExpr public override AstVisitAction VisitAttributedExpression(AttributedExpressionAst attributedExpressionAst) { // Attributes are not allowed, they may code in attribute constructors. - ReportError(attributedExpressionAst, () => ParserStrings.AttributeNotSupportedInDataSection); + ReportError(attributedExpressionAst, + nameof(ParserStrings.AttributeNotSupportedInDataSection), + ParserStrings.AttributeNotSupportedInDataSection); return AstVisitAction.Continue; } @@ -2093,7 +2325,9 @@ public override AstVisitAction VisitAttributedExpression(AttributedExpressionAst public override AstVisitAction VisitBlockStatement(BlockStatementAst blockStatementAst) { // Keyword blocks are not allowed - ReportError(blockStatementAst, () => ParserStrings.ParallelAndSequenceBlockNotSupportedInDataSection); + ReportError(blockStatementAst, + nameof(ParserStrings.ParallelAndSequenceBlockNotSupportedInDataSection), + ParserStrings.ParallelAndSequenceBlockNotSupportedInDataSection); return AstVisitAction.Continue; } diff --git a/src/System.Management.Automation/engine/parser/SymbolResolver.cs b/src/System.Management.Automation/engine/parser/SymbolResolver.cs index 7e078c76c29..c5195daa133 100644 --- a/src/System.Management.Automation/engine/parser/SymbolResolver.cs +++ b/src/System.Management.Automation/engine/parser/SymbolResolver.cs @@ -92,7 +92,10 @@ internal void AddType(Parser parser, TypeDefinitionAst typeDefinitionAst) } else { - parser.ReportError(typeDefinitionAst.Extent, () => ParserStrings.MemberAlreadyDefined, typeDefinitionAst.Name); + parser.ReportError(typeDefinitionAst.Extent, + nameof(ParserStrings.MemberAlreadyDefined), + ParserStrings.MemberAlreadyDefined, + typeDefinitionAst.Name); } } else @@ -125,7 +128,10 @@ internal void AddTypeFromUsingModule(Parser parser, TypeDefinitionAst typeDefini string fullName = SymbolResolver.GetModuleQualifiedName(moduleInfo.Name, typeDefinitionAst.Name); if (_typeTable.TryGetValue(fullName, out result)) { - parser.ReportError(typeDefinitionAst.Extent, () => ParserStrings.MemberAlreadyDefined, fullName); + parser.ReportError(typeDefinitionAst.Extent, + nameof(ParserStrings.MemberAlreadyDefined), + ParserStrings.MemberAlreadyDefined, + fullName); } else { @@ -393,12 +399,19 @@ public override AstVisitAction VisitAssignmentStatement(AssignmentStatementAst a { var typeAst = _symbolTable.GetCurrentTypeDefinitionAst(); Diagnostics.Assert(typeAst != null, "Method scopes can exist only inside type definitions."); - _parser.ReportError(variableExpressionAst.Extent, () => ParserStrings.MissingTypeInStaticPropertyAssignment, - String.Format(CultureInfo.InvariantCulture, "[{0}]::", typeAst.Name), propertyMember.Name); + _parser.ReportError(variableExpressionAst.Extent, + nameof(ParserStrings.MissingTypeInStaticPropertyAssignment), + ParserStrings.MissingTypeInStaticPropertyAssignment, + String.Format(CultureInfo.InvariantCulture, "[{0}]::", typeAst.Name), + propertyMember.Name); } else { - _parser.ReportError(variableExpressionAst.Extent, () => ParserStrings.MissingThis, "$this.", propertyMember.Name); + _parser.ReportError(variableExpressionAst.Extent, + nameof(ParserStrings.MissingThis), + ParserStrings.MissingThis, + "$this.", + propertyMember.Name); } } } @@ -521,16 +534,23 @@ public override AstVisitAction VisitUsingStatement(UsingStatementAst usingStatem var moduleInfo = GetModulesFromUsingModule(usingStatementAst, out exception, out wildcardCharactersUsed, out isConstant); if (!isConstant) { - _parser.ReportError(usingStatementAst.Extent, () => ParserStrings.RequiresArgumentMustBeConstant); + _parser.ReportError(usingStatementAst.Extent, + nameof(ParserStrings.RequiresArgumentMustBeConstant), + ParserStrings.RequiresArgumentMustBeConstant); } else if (exception != null) { // we re-using RequiresModuleInvalid string, semantic is very similar so it's fine to do that. - _parser.ReportError(usingStatementAst.Extent, () => ParserStrings.RequiresModuleInvalid, exception.Message); + _parser.ReportError(usingStatementAst.Extent, + nameof(ParserStrings.RequiresModuleInvalid), + ParserStrings.RequiresModuleInvalid, + exception.Message); } else if (wildcardCharactersUsed) { - _parser.ReportError(usingStatementAst.Extent, () => ParserStrings.WildCardModuleNameError); + _parser.ReportError(usingStatementAst.Extent, + nameof(ParserStrings.WildCardModuleNameError), + ParserStrings.WildCardModuleNameError); } else if (moduleInfo != null && moduleInfo.Count > 0) { @@ -549,7 +569,10 @@ public override AstVisitAction VisitUsingStatement(UsingStatementAst usingStatem { // if there is no exception, but we didn't find the module then it's not present string moduleText = usingStatementAst.Name != null ? usingStatementAst.Name.Value : usingStatementAst.ModuleSpecification.Extent.Text; - _parser.ReportError(usingStatementAst.Extent, () => ParserStrings.ModuleNotFoundDuringParse, moduleText); + _parser.ReportError(usingStatementAst.Extent, + nameof(ParserStrings.ModuleNotFoundDuringParse), + ParserStrings.ModuleNotFoundDuringParse, + moduleText); } } @@ -607,7 +630,9 @@ private bool VisitTypeName(TypeName typeName, int genericArgumentCount, bool isA if (classDefn != null && classDefn.IsAmbiguous()) { - _parser.ReportError(typeName.Extent, () => ParserStrings.AmbiguousTypeReference, + _parser.ReportError(typeName.Extent, + nameof(ParserStrings.AmbiguousTypeReference), + ParserStrings.AmbiguousTypeReference, typeName.Name, GetModuleQualifiedName(classDefn.ExternalNamespaces[0], typeName.Name), GetModuleQualifiedName(classDefn.ExternalNamespaces[1], typeName.Name)); @@ -631,10 +656,22 @@ private bool VisitTypeName(TypeName typeName, int genericArgumentCount, bool isA // [ordered] is an attribute, but it's looks like a type constraint. if (!typeName.FullName.Equals(LanguagePrimitives.OrderedAttribute, StringComparison.OrdinalIgnoreCase)) { + string errorId; + string errorMsg; + if (isAttribute) + { + errorId = nameof(ParserStrings.CustomAttributeTypeNotFound); + errorMsg = ParserStrings.CustomAttributeTypeNotFound; + } + else + { + errorId = nameof(ParserStrings.TypeNotFound); + errorMsg = ParserStrings.TypeNotFound; + } _parser.ReportError(typeName.Extent, - isAttribute - ? (Expression>)(() => ParserStrings.CustomAttributeTypeNotFound) - : () => ParserStrings.TypeNotFound, typeName.Name); + errorId, + errorMsg, + typeName.Name); } } } @@ -716,4 +753,4 @@ public override object VisitFunctionMember(FunctionMemberAst functionMemberAst) return null; } } -} \ No newline at end of file +} diff --git a/src/System.Management.Automation/engine/parser/tokenizer.cs b/src/System.Management.Automation/engine/parser/tokenizer.cs index 393fef5ce17..523160dfcee 100644 --- a/src/System.Management.Automation/engine/parser/tokenizer.cs +++ b/src/System.Management.Automation/engine/parser/tokenizer.cs @@ -1313,7 +1313,9 @@ private char ScanUnicodeEscape(out char surrogateCharacter) UngetChar(); Release(sb); - ReportError(_currentIndex, () => ParserStrings.TooManyDigitsInUnicodeEscapeSequence); + ReportError(_currentIndex, + nameof(ParserStrings.TooManyDigitsInUnicodeEscapeSequence), + ParserStrings.TooManyDigitsInUnicodeEscapeSequence); return s_invalidChar; } @@ -1335,7 +1337,9 @@ private char ScanUnicodeEscape(out char surrogateCharacter) { // Place the error indicator under only the hex digits in the esc sequence. IScriptExtent errorExtent = NewScriptExtent(escSeqStartIndex + 3, _currentIndex - 1); - ReportError(errorExtent, () => ParserStrings.InvalidUnicodeEscapeSequenceValue); + ReportError(errorExtent, + nameof(ParserStrings.InvalidUnicodeEscapeSequenceValue), + ParserStrings.InvalidUnicodeEscapeSequenceValue); return s_invalidChar; } } @@ -1561,7 +1565,9 @@ private void ScanBlockComment() else if (c == '\0' && AtEof()) { UngetChar(); - ReportIncompleteInput(errorIndex, () => ParserStrings.MissingTerminatorMultiLineComment); + ReportIncompleteInput(errorIndex, + nameof(ParserStrings.MissingTerminatorMultiLineComment), + ParserStrings.MissingTerminatorMultiLineComment); break; } } @@ -1657,7 +1663,9 @@ internal ScriptRequirements GetScriptRequirements() var commandName = commandAst.GetCommandName(); if (!string.Equals(commandName, "requires", StringComparison.OrdinalIgnoreCase)) { - ReportError(commandAst.Extent, () => DiscoveryExceptions.ScriptRequiresInvalidFormat); + ReportError(commandAst.Extent, + nameof(DiscoveryExceptions.ScriptRequiresInvalidFormat), + DiscoveryExceptions.ScriptRequiresInvalidFormat); } var snapinSpecified = false; @@ -1688,7 +1696,9 @@ internal ScriptRequirements GetScriptRequirements() } else { - ReportError(commandAst.CommandElements[i].Extent, () => DiscoveryExceptions.ScriptRequiresInvalidFormat); + ReportError(commandAst.CommandElements[i].Extent, + nameof(DiscoveryExceptions.ScriptRequiresInvalidFormat), + DiscoveryExceptions.ScriptRequiresInvalidFormat); } } if (snapinName != null) @@ -1747,21 +1757,29 @@ private void HandleRequiresParameter(CommandParameterAst parameter, requiresElevation = true; if (argumentAst != null) { - ReportError(parameter.Extent, () => ParserStrings.ParameterCannotHaveArgument, parameter.ParameterName); + ReportError(parameter.Extent, + nameof(ParserStrings.ParameterCannotHaveArgument), + ParserStrings.ParameterCannotHaveArgument, + parameter.ParameterName); } return; } if (argumentAst == null) { - ReportError(parameter.Extent, () => ParserStrings.ParameterRequiresArgument, parameter.ParameterName); + ReportError(parameter.Extent, + nameof(ParserStrings.ParameterRequiresArgument), + ParserStrings.ParameterRequiresArgument, + parameter.ParameterName); return; } object argumentValue; if (!IsConstantValueVisitor.IsConstant(argumentAst, out argumentValue, forRequires: true)) { - ReportError(argumentAst.Extent, () => ParserStrings.RequiresArgumentMustBeConstant); + ReportError(argumentAst.Extent, + nameof(ParserStrings.RequiresArgumentMustBeConstant), + ParserStrings.RequiresArgumentMustBeConstant); return; } @@ -1769,12 +1787,19 @@ private void HandleRequiresParameter(CommandParameterAst parameter, { if (requiredShellId != null) { - ReportError(parameter.Extent, () => ParameterBinderStrings.ParameterAlreadyBound, null, shellIDToken); + ReportError(parameter.Extent, + nameof(ParameterBinderStrings.ParameterAlreadyBound), + ParameterBinderStrings.ParameterAlreadyBound, + null, + shellIDToken); return; } if (!(argumentValue is string)) { - ReportError(argumentAst.Extent, () => ParserStrings.RequiresInvalidStringArgument, shellIDToken); + ReportError(argumentAst.Extent, + nameof(ParserStrings.RequiresInvalidStringArgument), + ParserStrings.RequiresInvalidStringArgument, + shellIDToken); return; } requiredShellId = (string)argumentValue; @@ -1783,17 +1808,26 @@ private void HandleRequiresParameter(CommandParameterAst parameter, { if (!(argumentValue is string)) { - ReportError(argumentAst.Extent, () => ParserStrings.RequiresInvalidStringArgument, PSSnapinToken); + ReportError(argumentAst.Extent, + nameof(ParserStrings.RequiresInvalidStringArgument), + ParserStrings.RequiresInvalidStringArgument, + PSSnapinToken); return; } if (snapinName != null) { - ReportError(parameter.Extent, () => ParameterBinderStrings.ParameterAlreadyBound, null, PSSnapinToken); + ReportError(parameter.Extent, + nameof(ParameterBinderStrings.ParameterAlreadyBound), + ParameterBinderStrings.ParameterAlreadyBound, + null, + PSSnapinToken); return; } if (!PSSnapInInfo.IsPSSnapinIdValid((string)argumentValue)) { - ReportError(argumentAst.Extent, () => MshSnapInCmdletResources.InvalidPSSnapInName); + ReportError(argumentAst.Extent, + nameof(MshSnapInCmdletResources.InvalidPSSnapInName), + MshSnapInCmdletResources.InvalidPSSnapInName); return; } @@ -1803,7 +1837,11 @@ private void HandleRequiresParameter(CommandParameterAst parameter, { if (requiredEditions != null) { - ReportError(parameter.Extent, () => ParameterBinderStrings.ParameterAlreadyBound, null, editionToken); + ReportError(parameter.Extent, + nameof(ParameterBinderStrings.ParameterAlreadyBound), + ParameterBinderStrings.ParameterAlreadyBound, + null, + editionToken); return; } @@ -1825,7 +1863,9 @@ private void HandleRequiresParameter(CommandParameterAst parameter, var version = Utils.StringToVersion(argumentText); if (version == null) { - ReportError(argumentAst.Extent, () => ParserStrings.RequiresVersionInvalid); + ReportError(argumentAst.Extent, + nameof(ParserStrings.RequiresVersionInvalid), + ParserStrings.RequiresVersionInvalid); return; } @@ -1833,7 +1873,11 @@ private void HandleRequiresParameter(CommandParameterAst parameter, { if (snapinVersion != null) { - ReportError(parameter.Extent, () => ParameterBinderStrings.ParameterAlreadyBound, null, versionToken); + ReportError(parameter.Extent, + nameof(ParameterBinderStrings.ParameterAlreadyBound), + ParameterBinderStrings.ParameterAlreadyBound, + null, + versionToken); return; } snapinVersion = version; @@ -1842,7 +1886,11 @@ private void HandleRequiresParameter(CommandParameterAst parameter, { if (requiredVersion != null && !requiredVersion.Equals(version)) { - ReportError(parameter.Extent, () => ParameterBinderStrings.ParameterAlreadyBound, null, versionToken); + ReportError(parameter.Extent, + nameof(ParameterBinderStrings.ParameterAlreadyBound), + ParameterBinderStrings.ParameterAlreadyBound, + null, + versionToken); return; } requiredVersion = version; @@ -1874,12 +1922,18 @@ private void HandleRequiresParameter(CommandParameterAst parameter, } catch (InvalidCastException e) { - ReportError(argumentAst.Extent, () => ParserStrings.RequiresModuleInvalid, e.Message); + ReportError(argumentAst.Extent, + nameof(ParserStrings.RequiresModuleInvalid), + ParserStrings.RequiresModuleInvalid, + e.Message); return; } catch (ArgumentException e) { - ReportError(argumentAst.Extent, () => ParserStrings.RequiresModuleInvalid, e.Message); + ReportError(argumentAst.Extent, + nameof(ParserStrings.RequiresModuleInvalid), + ParserStrings.RequiresModuleInvalid, + e.Message); return; } if (requiredModules == null) @@ -1889,7 +1943,9 @@ private void HandleRequiresParameter(CommandParameterAst parameter, } else { - ReportError(parameter.Extent, () => DiscoveryExceptions.ScriptRequiresInvalidFormat); + ReportError(parameter.Extent, + nameof(DiscoveryExceptions.ScriptRequiresInvalidFormat), + DiscoveryExceptions.ScriptRequiresInvalidFormat); } } @@ -1897,7 +1953,10 @@ private List HandleRequiresAssemblyArgument(Ast argumentAst, object arg, { if (!(arg is string)) { - ReportError(argumentAst.Extent, () => ParserStrings.RequiresInvalidStringArgument, assemblyToken); + ReportError(argumentAst.Extent, + nameof(ParserStrings.RequiresInvalidStringArgument), + ParserStrings.RequiresInvalidStringArgument, + assemblyToken); } else { @@ -1916,7 +1975,10 @@ private List HandleRequiresPSEditionArgument(Ast argumentAst, object arg { if (!(arg is string)) { - ReportError(argumentAst.Extent, () => ParserStrings.RequiresInvalidStringArgument, editionToken); + ReportError(argumentAst.Extent, + nameof(ParserStrings.RequiresInvalidStringArgument), + ParserStrings.RequiresInvalidStringArgument, + editionToken); } else { @@ -1926,7 +1988,10 @@ private List HandleRequiresPSEditionArgument(Ast argumentAst, object arg var edition = (string)arg; if (!Utils.IsValidPSEditionValue(edition)) { - ReportError(argumentAst.Extent, () => ParserStrings.RequiresPSEditionInvalid, editionToken); + ReportError(argumentAst.Extent, + nameof(ParserStrings.RequiresPSEditionInvalid), + ParserStrings.RequiresPSEditionInvalid, + editionToken); } if (!requiredEditions.Contains(edition, StringComparer.OrdinalIgnoreCase)) @@ -1935,7 +2000,10 @@ private List HandleRequiresPSEditionArgument(Ast argumentAst, object arg } else { - ReportError(argumentAst.Extent, () => ParserStrings.RequiresPSEditionValueIsAlreadySpecified, editionToken); + ReportError(argumentAst.Extent, + nameof(ParserStrings.RequiresPSEditionValueIsAlreadySpecified), + ParserStrings.RequiresPSEditionValueIsAlreadySpecified, + editionToken); } } return requiredEditions; @@ -2008,7 +2076,10 @@ private TokenFlags ScanStringLiteral(StringBuilder sb) { // error - reached end of input without seeing terminator UngetChar(); - ReportIncompleteInput(errorIndex, () => ParserStrings.TerminatorExpectedAtEndOfString, "'"); + ReportIncompleteInput(errorIndex, + nameof(ParserStrings.TerminatorExpectedAtEndOfString), + ParserStrings.TerminatorExpectedAtEndOfString, + "'"); flags = TokenFlags.TokenInError; } @@ -2073,7 +2144,9 @@ private Token ScanSubExpression(bool hereString) goto default; UngetChar(); - ReportIncompleteInput(_tokenStart, () => ParserStrings.IncompleteDollarSubexpressionReference); + ReportIncompleteInput(_tokenStart, + nameof(ParserStrings.IncompleteDollarSubexpressionReference), + ParserStrings.IncompleteDollarSubexpressionReference); flags = TokenFlags.TokenInError; scanning = false; break; @@ -2161,7 +2234,10 @@ private TokenFlags ScanStringExpandable(StringBuilder sb, StringBuilder formatSb if (c == '\0') { UngetChar(); - ReportIncompleteInput(errorIndex, () => ParserStrings.TerminatorExpectedAtEndOfString, "\""); + ReportIncompleteInput(errorIndex, + nameof(ParserStrings.TerminatorExpectedAtEndOfString), + ParserStrings.TerminatorExpectedAtEndOfString, + "\""); flags = TokenFlags.TokenInError; } @@ -2249,7 +2325,10 @@ private bool ScanAfterHereStringHeader(string header) if (c == '\0' && AtEof()) { UngetChar(); - ReportIncompleteInput(headerOffset, () => ParserStrings.TerminatorExpectedAtEndOfString, string.Concat(header[1], '@')); + ReportIncompleteInput(headerOffset, + nameof(ParserStrings.TerminatorExpectedAtEndOfString), + ParserStrings.TerminatorExpectedAtEndOfString, + string.Concat(header[1], '@')); return false; } @@ -2259,7 +2338,9 @@ private bool ScanAfterHereStringHeader(string header) // scanning at the end of the line. Don't skip the newline so we have a newline to terminate the current // expression. - ReportError(_currentIndex, () => ParserStrings.UnexpectedCharactersAfterHereStringHeader); + ReportError(_currentIndex, + nameof(ParserStrings.UnexpectedCharactersAfterHereStringHeader), + ParserStrings.UnexpectedCharactersAfterHereStringHeader); do { @@ -2377,11 +2458,16 @@ private Token ScanHereStringLiteral() UngetChar(); if (falseFooterOffset != -1) { - ReportIncompleteInput(falseFooterOffset, () => ParserStrings.WhitespaceBeforeHereStringFooter); + ReportIncompleteInput(falseFooterOffset, + nameof(ParserStrings.WhitespaceBeforeHereStringFooter), + ParserStrings.WhitespaceBeforeHereStringFooter); } else { - ReportIncompleteInput(headerOffset, () => ParserStrings.TerminatorExpectedAtEndOfString, "'@"); + ReportIncompleteInput(headerOffset, + nameof(ParserStrings.TerminatorExpectedAtEndOfString), + ParserStrings.TerminatorExpectedAtEndOfString, + "'@"); } flags = TokenFlags.TokenInError; break; @@ -2479,11 +2565,16 @@ private Token ScanHereStringExpandable() UngetChar(); if (falseFooterOffset != -1) { - ReportIncompleteInput(falseFooterOffset, () => ParserStrings.WhitespaceBeforeHereStringFooter); + ReportIncompleteInput(falseFooterOffset, + nameof(ParserStrings.WhitespaceBeforeHereStringFooter), + ParserStrings.WhitespaceBeforeHereStringFooter); } else { - ReportIncompleteInput(headerOffset, () => ParserStrings.TerminatorExpectedAtEndOfString, "\"@"); + ReportIncompleteInput(headerOffset, + nameof(ParserStrings.TerminatorExpectedAtEndOfString), + ParserStrings.TerminatorExpectedAtEndOfString, + "\"@"); } flags = TokenFlags.TokenInError; break; @@ -2559,7 +2650,9 @@ private Token ScanVariable(bool splatted, bool inStringExpandable) } break; case '{': - ReportError(_currentIndex, () => ParserStrings.OpenBraceNeedsToBeBackTickedInVariableName); + ReportError(_currentIndex, + nameof(ParserStrings.OpenBraceNeedsToBeBackTickedInVariableName), + ParserStrings.OpenBraceNeedsToBeBackTickedInVariableName); break; case '\0': if (AtEof()) @@ -2578,13 +2671,17 @@ private Token ScanVariable(bool splatted, bool inStringExpandable) string name = GetStringAndRelease(sb); if (c != '}') { - ReportIncompleteInput(errorStartPosition, () => ParserStrings.IncompleteDollarVariableReference); + ReportIncompleteInput(errorStartPosition, + nameof(ParserStrings.IncompleteDollarVariableReference), + ParserStrings.IncompleteDollarVariableReference); } if (name.Length == 0) { if (c == '}') { - ReportError(_currentIndex - 1, () => ParserStrings.EmptyVariableReference); + ReportError(_currentIndex - 1, + nameof(ParserStrings.EmptyVariableReference), + ParserStrings.EmptyVariableReference); } name = ":Error:"; } @@ -2612,7 +2709,9 @@ private Token ScanVariable(bool splatted, bool inStringExpandable) //{ // return NewToken(TokenKind.Unknown); //} - ReportError(NewScriptExtent(_tokenStart, _currentIndex), () => ParserStrings.InvalidBracedVariableReference); + ReportError(NewScriptExtent(_tokenStart, _currentIndex), + nameof(ParserStrings.InvalidBracedVariableReference), + ParserStrings.InvalidBracedVariableReference); } return NewVariableToken(path, false); @@ -2772,16 +2871,19 @@ private Token ScanVariable(bool splatted, bool inStringExpandable) path = new VariablePath(GetStringAndRelease(sb)); if (string.IsNullOrEmpty(path.UnqualifiedPath)) { - Expression> msg; + string errorId; + string errorMsg; if (path.IsDriveQualified) { - msg = () => ParserStrings.InvalidVariableReferenceWithDrive; + errorId = nameof(ParserStrings.InvalidVariableReferenceWithDrive); + errorMsg = ParserStrings.InvalidVariableReferenceWithDrive; } else { - msg = () => ParserStrings.InvalidVariableReference; + errorId = nameof(ParserStrings.InvalidVariableReference); + errorMsg = ParserStrings.InvalidVariableReference; } - ReportError(NewScriptExtent(_tokenStart, _currentIndex), msg); + ReportError(NewScriptExtent(_tokenStart, _currentIndex), errorId, errorMsg); } return NewVariableToken(path, splatted); @@ -3299,7 +3401,10 @@ private Token ScanNumber(char firstChar) return ScanGenericToken(GetStringBuilder()); } - ReportError(_currentIndex, () => ParserStrings.BadNumericConstant, _script.Substring(_tokenStart, _currentIndex - _tokenStart)); + ReportError(_currentIndex, + nameof(ParserStrings.BadNumericConstant), + ParserStrings.BadNumericConstant, + _script.Substring(_tokenStart, _currentIndex - _tokenStart)); } return NewNumberToken(value); @@ -3909,7 +4014,9 @@ internal Token NextToken() return ScanVariable(true, false); } - ReportError(_currentIndex - 1, () => ParserStrings.UnrecognizedToken); + ReportError(_currentIndex - 1, + nameof(ParserStrings.UnrecognizedToken), + ParserStrings.UnrecognizedToken); return NewToken(TokenKind.Unknown); case '#': @@ -3936,7 +4043,9 @@ internal Token NextToken() } if (c1 == '\0' && AtEof()) { - ReportIncompleteInput(_currentIndex, () => ParserStrings.IncompleteString); + ReportIncompleteInput(_currentIndex, + nameof(ParserStrings.IncompleteString), + ParserStrings.IncompleteString); // Unget the EOF so we can return an EOF token. UngetChar(); diff --git a/src/System.Management.Automation/engine/runtime/CompiledScriptBlock.cs b/src/System.Management.Automation/engine/runtime/CompiledScriptBlock.cs index c85086cd677..a586a5cff84 100644 --- a/src/System.Management.Automation/engine/runtime/CompiledScriptBlock.cs +++ b/src/System.Management.Automation/engine/runtime/CompiledScriptBlock.cs @@ -755,7 +755,9 @@ public void CheckRestrictedLanguage(IEnumerable allowedCommands, IEnumer if (HasBeginBlock || HasProcessBlock || ast.Body.ParamBlock != null) { Ast errorAst = ast.Body.BeginBlock ?? (Ast)ast.Body.ProcessBlock ?? ast.Body.ParamBlock; - parser.ReportError(errorAst.Extent, () => ParserStrings.InvalidScriptBlockInDataSection); + parser.ReportError(errorAst.Extent, + nameof(ParserStrings.InvalidScriptBlockInDataSection), + ParserStrings.InvalidScriptBlockInDataSection); } if (HasEndBlock) From 5be2916a14dbeb62f2903434a44b3196954abf11 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 26 Mar 2018 09:19:52 -0700 Subject: [PATCH 03/15] Separate out error parameters --- .../engine/parser/PSType.cs | 3 +- .../engine/parser/SemanticChecks.cs | 32 +++++++++++-------- .../engine/parser/SymbolResolver.cs | 4 ++- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/PSType.cs b/src/System.Management.Automation/engine/parser/PSType.cs index 769218bc7e1..a62e083d93c 100644 --- a/src/System.Management.Automation/engine/parser/PSType.cs +++ b/src/System.Management.Automation/engine/parser/PSType.cs @@ -775,7 +775,8 @@ private void DefineMethod(FunctionMemberAst functionMemberAst) var parameters = functionMemberAst.Parameters; if (parameters.Count > 0) { - _parser.ReportError(Parser.ExtentOf(parameters.First(), parameters.Last()), + IScriptExtent errorExtent = Parser.ExtentOf(parameters.First(), parameters.Last()); + _parser.ReportError(errorExtent, nameof(ParserStrings.StaticConstructorCantHaveParameters), ParserStrings.StaticConstructorCantHaveParameters); return; diff --git a/src/System.Management.Automation/engine/parser/SemanticChecks.cs b/src/System.Management.Automation/engine/parser/SemanticChecks.cs index efbf9e7ea1c..415e8282b77 100644 --- a/src/System.Management.Automation/engine/parser/SemanticChecks.cs +++ b/src/System.Management.Automation/engine/parser/SemanticChecks.cs @@ -63,10 +63,8 @@ private bool IsValidAttributeArgument(Ast ast, IsConstantValueVisitor visitor) return (bool)ast.Accept(visitor); } - private Tuple GetNonConstantAttributeArgErrorExpr(IsConstantValueVisitor visitor) + private void GetNonConstantAttributeArgErrorExpr(IsConstantValueVisitor visitor, out string errorId, out string errorMsg) { - string errorId; - string errorMsg; if (visitor.CheckingClassAttributeArguments) { errorId = nameof(ParserStrings.ParameterAttributeArgumentNeedsToBeConstant); @@ -77,8 +75,6 @@ private Tuple GetNonConstantAttributeArgErrorExpr(IsConstantValu errorId = nameof(ParserStrings.ParameterAttributeArgumentNeedsToBeConstantOrScriptBlock); errorMsg = ParserStrings.ParameterAttributeArgumentNeedsToBeConstantOrScriptBlock; } - - return new Tuple(errorId, errorMsg); } private void CheckForDuplicateParameters(ReadOnlyCollection parameters) @@ -252,8 +248,10 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) if (!namedArg.ExpressionOmitted && !IsValidAttributeArgument(namedArg.Argument, constantValueVisitor)) { - Tuple errorInfo = GetNonConstantAttributeArgErrorExpr(constantValueVisitor); - _parser.ReportError(namedArg.Argument.Extent, errorInfo.Item1, errorInfo.Item2); + string errorId; + string errorMsg; + GetNonConstantAttributeArgErrorExpr(constantValueVisitor, out errorId, out errorMsg); + _parser.ReportError(namedArg.Argument.Extent, errorId, errorMsg); } } } @@ -262,8 +260,10 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) { if (!IsValidAttributeArgument(posArg, constantValueVisitor)) { - Tuple errorInfo = GetNonConstantAttributeArgErrorExpr(constantValueVisitor); - _parser.ReportError(posArg.Extent, errorInfo.Item1, errorInfo.Item2); + string errorId; + string errorMsg; + GetNonConstantAttributeArgErrorExpr(constantValueVisitor, out errorId, out errorMsg); + _parser.ReportError(posArg.Extent, errorId, errorId); } } @@ -804,7 +804,8 @@ private void CheckAssignmentTarget(ExpressionAst ast, bool simpleAssignment, Act _parser.ReportError(ast.Extent, nameof(ParserStrings.AssignmentStatementToAutomaticNotSupported), ParserStrings.AssignmentStatementToAutomaticNotSupported, - varPath.UnqualifiedPath, expectedType); + varPath.UnqualifiedPath, + expectedType); } break; } @@ -1319,7 +1320,8 @@ public override AstVisitAction VisitDynamicKeywordStatement(DynamicKeywordStatem _parser.ReportError(dynamicKeywordStatementAst.Extent, nameof(ParserStrings.DynamicKeywordSemanticCheckException), ParserStrings.DynamicKeywordSemanticCheckException, - dynamicKeywordStatementAst.Keyword.ResourceName, e.ToString()); + dynamicKeywordStatementAst.Keyword.ResourceName, + e.ToString()); } } DynamicKeyword keyword = dynamicKeywordStatementAst.Keyword; @@ -1337,15 +1339,19 @@ public override AstVisitAction VisitDynamicKeywordStatement(DynamicKeywordStatem _parser.ReportError(keyValueTuple.Item1.Extent, nameof(ParserStrings.ConfigurationInvalidPropertyName), ParserStrings.ConfigurationInvalidPropertyName, - dynamicKeywordStatementAst.FunctionName.Extent, keyValueTuple.Item1.Extent); + dynamicKeywordStatementAst.FunctionName.Extent, + keyValueTuple.Item1.Extent); } else if (!keyword.Properties.ContainsKey(propName.Value)) { + IOrderedEnumerable tableKeys = keyword.Properties.Keys + .OrderBy(key => key, StringComparer.OrdinalIgnoreCase); + _parser.ReportError(propName.Extent, nameof(ParserStrings.InvalidInstanceProperty), ParserStrings.InvalidInstanceProperty, propName.Value, - string.Join("', '", keyword.Properties.Keys.OrderBy(key => key, StringComparer.OrdinalIgnoreCase))); + String.Join("', '", tableKeys)); } } } diff --git a/src/System.Management.Automation/engine/parser/SymbolResolver.cs b/src/System.Management.Automation/engine/parser/SymbolResolver.cs index c5195daa133..f360c7ab5c5 100644 --- a/src/System.Management.Automation/engine/parser/SymbolResolver.cs +++ b/src/System.Management.Automation/engine/parser/SymbolResolver.cs @@ -399,10 +399,12 @@ public override AstVisitAction VisitAssignmentStatement(AssignmentStatementAst a { var typeAst = _symbolTable.GetCurrentTypeDefinitionAst(); Diagnostics.Assert(typeAst != null, "Method scopes can exist only inside type definitions."); + + string typeString = String.Format(CultureInfo.InvariantCulture, "[{0}]::", typeAst.Name); _parser.ReportError(variableExpressionAst.Extent, nameof(ParserStrings.MissingTypeInStaticPropertyAssignment), ParserStrings.MissingTypeInStaticPropertyAssignment, - String.Format(CultureInfo.InvariantCulture, "[{0}]::", typeAst.Name), + typeString, propertyMember.Name); } else From 4e1cdcbefddb7d491ac00b2c1d7391a1c8fbb9bb Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 26 Mar 2018 11:33:39 -0700 Subject: [PATCH 04/15] Changed errorId null check to assertion --- src/System.Management.Automation/engine/parser/Parser.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 490487628e3..6a537818aea 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -7267,10 +7267,7 @@ private void SaveError(ParseError error) private void SaveError(IScriptExtent extent, string errorId, string errorMsg, bool incompleteInput, params object[] args) { - if (String.IsNullOrEmpty(errorId)) - { - errorId = "ParserError"; - } + Diagnostics.Assert(!String.IsNullOrEmpty(errorId), "Errors must have IDs"); if (args != null && args.Any()) { From ccd712ddbde986e3cd26c3ae9f04d6a736c98851 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 26 Mar 2018 13:48:36 -0700 Subject: [PATCH 05/15] Add assertion that errorIds and messages correspond --- .../engine/parser/Parser.cs | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 6a537818aea..69bf5b7d506 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -752,6 +752,35 @@ internal static bool TryParseAsConstantHashtable(string input, out Hashtable res return true; } + // Collect types that keep .resx file strings + // for errors thrown with "SaveError" + private static readonly Type[] s_resxTypes = new [] + { + typeof(ParserStrings), + typeof(ExtendedTypeSystem), + typeof(DiscoveryExceptions) + }; + + /// + /// Given an errorId and an errorMsg, verify that they correspond to one another + /// in some .resx file + /// + /// the ID (or RESX key) of the error + /// the message (or RESX value) of the error + /// true if the ID and message are paired in some .resx file, false otherwise + private static bool ErrorIdCorrespondsToMsg(string errorId, string errorMsg) + { + foreach (Type resxType in s_resxTypes) + { + if (errorMsg.Equals(resxType.GetProperty(errorId)?.GetValue(null))) + { + return true; + } + } + + return false; + } + #endregion Utilities #region Statements @@ -7267,7 +7296,7 @@ private void SaveError(ParseError error) private void SaveError(IScriptExtent extent, string errorId, string errorMsg, bool incompleteInput, params object[] args) { - Diagnostics.Assert(!String.IsNullOrEmpty(errorId), "Errors must have IDs"); + Diagnostics.Assert(ErrorIdCorrespondsToMsg(errorId, errorMsg), "ErrorMsg must correspond the the ErrorId in ParserStrings"); if (args != null && args.Any()) { From fd4d95092129b9ccbfd97f55de2eb1609e0ab406 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 26 Mar 2018 13:54:00 -0700 Subject: [PATCH 06/15] Fixed ReportError references in SUPPORT_PUBLIC_PRIVATE --- .../engine/parser/Parser.cs | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 69bf5b7d506..08eebd9905a 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -4305,11 +4305,18 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) case TokenKind.Public: if (publicToken != null) { - ReportError(token.Extent, () => ParserStrings.DuplicateQualifier, token.Text); + ReportError(token.Extent, + nameof(ParserStrings.DuplicateQualifier), + ParserStrings.DuplicateQualifier, + token.Text); } if (privateToken != null) { - ReportError(token.Extent, () => ParserStrings.ModifiersCannotBeCombined, privateToken.Text, token.Text); + ReportError(token.Extent, + nameof(ParserStrings.ModifiersCannotBeCombined), + ParserStrings.ModifiersCannotBeCombined, + privateToken.Text, + token.Text); } publicToken = token; SkipToken(); @@ -4318,11 +4325,18 @@ private MemberAst ClassMemberRule(string className, out List astsOnError) case TokenKind.Private: if (privateToken != null) { - ReportError(token.Extent, () => ParserStrings.DuplicateQualifier, token.Text); + ReportError(token.Extent, + nameof(ParserStrings.DuplicateQualifier), + ParserStrings.DuplicateQualifier, + token.Text); } if (publicToken != null) { - ReportError(token.Extent, () => ParserStrings.ModifiersCannotBeCombined, publicToken.Text, token.Text); + ReportError(token.Extent, + nameof(ParserStrings.ModifiersCannotBeCombined), + ParserStrings.ModifiersCannotBeCombined, + publicToken.Text, + token.Text); } privateToken = token; SkipToken(); From 566f337cfb7757d3e9109fb6f88444b8e777fcc1 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 26 Mar 2018 14:33:38 -0700 Subject: [PATCH 07/15] Fixed lines, added msg, changed to tuple usage --- .../engine/parser/Parser.cs | 1 + .../engine/parser/SemanticChecks.cs | 27 +++++++------------ .../engine/parser/SymbolResolver.cs | 5 +--- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 08eebd9905a..83c81706178 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -2431,6 +2431,7 @@ private StatementAst IfStatementRule(Token ifToken) ReportIncompleteInput(rParen.Extent, nameof(ParserStrings.MissingStatementBlock), + ParserStrings.MissingStatementBlock, keyword.Text); return new ErrorStatementAst(ExtentOf(ifToken, rParen), componentAsts); } diff --git a/src/System.Management.Automation/engine/parser/SemanticChecks.cs b/src/System.Management.Automation/engine/parser/SemanticChecks.cs index 415e8282b77..e13effea703 100644 --- a/src/System.Management.Automation/engine/parser/SemanticChecks.cs +++ b/src/System.Management.Automation/engine/parser/SemanticChecks.cs @@ -63,18 +63,16 @@ private bool IsValidAttributeArgument(Ast ast, IsConstantValueVisitor visitor) return (bool)ast.Accept(visitor); } - private void GetNonConstantAttributeArgErrorExpr(IsConstantValueVisitor visitor, out string errorId, out string errorMsg) + (string id, string msg) GetNonConstantAttributeArgErrorExpr(IsConstantValueVisitor visitor) { if (visitor.CheckingClassAttributeArguments) { - errorId = nameof(ParserStrings.ParameterAttributeArgumentNeedsToBeConstant); - errorMsg = ParserStrings.ParameterAttributeArgumentNeedsToBeConstant; - } - else - { - errorId = nameof(ParserStrings.ParameterAttributeArgumentNeedsToBeConstantOrScriptBlock); - errorMsg = ParserStrings.ParameterAttributeArgumentNeedsToBeConstantOrScriptBlock; + return (nameof(ParserStrings.ParameterAttributeArgumentNeedsToBeConstant), + ParserStrings.ParameterAttributeArgumentNeedsToBeConstant); } + + return (nameof(ParserStrings.ParameterAttributeArgumentNeedsToBeConstantOrScriptBlock), + ParserStrings.ParameterAttributeArgumentNeedsToBeConstantOrScriptBlock); } private void CheckForDuplicateParameters(ReadOnlyCollection parameters) @@ -248,9 +246,7 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) if (!namedArg.ExpressionOmitted && !IsValidAttributeArgument(namedArg.Argument, constantValueVisitor)) { - string errorId; - string errorMsg; - GetNonConstantAttributeArgErrorExpr(constantValueVisitor, out errorId, out errorMsg); + (string errorId, string errorMsg) = GetNonConstantAttributeArgErrorExpr(constantValueVisitor); _parser.ReportError(namedArg.Argument.Extent, errorId, errorMsg); } } @@ -260,9 +256,7 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) { if (!IsValidAttributeArgument(posArg, constantValueVisitor)) { - string errorId; - string errorMsg; - GetNonConstantAttributeArgErrorExpr(constantValueVisitor, out errorId, out errorMsg); + (string errorId, string errorMsg) = GetNonConstantAttributeArgErrorExpr(constantValueVisitor); _parser.ReportError(posArg.Extent, errorId, errorId); } } @@ -1085,10 +1079,7 @@ public override AstVisitAction VisitHashtable(HashtableAst hashtableAst) errorMsg = ParserStrings.DuplicateKeyInHashLiteral; } - _parser.ReportError(entry.Item1.Extent, - errorId, - errorMsg, - keyStr); + _parser.ReportError(entry.Item1.Extent, errorId, errorMsg, keyStr); } else { diff --git a/src/System.Management.Automation/engine/parser/SymbolResolver.cs b/src/System.Management.Automation/engine/parser/SymbolResolver.cs index f360c7ab5c5..bf69ec8f98f 100644 --- a/src/System.Management.Automation/engine/parser/SymbolResolver.cs +++ b/src/System.Management.Automation/engine/parser/SymbolResolver.cs @@ -670,10 +670,7 @@ private bool VisitTypeName(TypeName typeName, int genericArgumentCount, bool isA errorId = nameof(ParserStrings.TypeNotFound); errorMsg = ParserStrings.TypeNotFound; } - _parser.ReportError(typeName.Extent, - errorId, - errorMsg, - typeName.Name); + _parser.ReportError(typeName.Extent, errorId, errorMsg, typeName.Name); } } } From 6f1acc38570d9b81fce50ee10ec9dbc6f7374f5d Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 26 Mar 2018 14:35:15 -0700 Subject: [PATCH 08/15] Remove defunct comment --- src/System.Management.Automation/engine/parser/Parser.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 83c81706178..37074cd82fd 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -6772,7 +6772,6 @@ private ExpressionAst HashExpressionRule(Token atCurlyToken, bool parsingSchemaE if (rCurly.Kind != TokenKind.RCurly) { UngetToken(rCurly); - // Note - the error handling function inspects the error message body to extra the ParserStrings property name. It uses this value as the errorid. string errorId; string errorMsg; if (parsingSchemaElement) From 6e386f46263ad880494300c5ddef7d10b9cb2640 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 26 Mar 2018 15:07:07 -0700 Subject: [PATCH 09/15] Consolidate parser error strings to ParserStrings --- .../engine/CoreAdapter.cs | 4 +-- .../engine/parser/Parser.cs | 32 ++----------------- .../engine/parser/SemanticChecks.cs | 8 ++--- .../engine/parser/tokenizer.cs | 12 +++---- .../resources/DiscoveryExceptions.resx | 10 ------ .../resources/ExtendedTypeSystem.resx | 3 -- .../resources/ParserStrings.resx | 16 ++++++++++ 7 files changed, 30 insertions(+), 55 deletions(-) diff --git a/src/System.Management.Automation/engine/CoreAdapter.cs b/src/System.Management.Automation/engine/CoreAdapter.cs index 1092fa290f3..a79b030246c 100644 --- a/src/System.Management.Automation/engine/CoreAdapter.cs +++ b/src/System.Management.Automation/engine/CoreAdapter.cs @@ -3667,9 +3667,9 @@ protected override void PropertySet(PSProperty property, object setValue, bool c if (adapterData.readOnly) { - throw new SetValueException("ReadOnlyProperty", + throw new SetValueException(nameof(ParserStrings.ReadOnlyProperty), null, - ExtendedTypeSystem.ReadOnlyProperty, + ParserStrings.ReadOnlyProperty, adapterData.member.Name); } diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 37074cd82fd..78f03f17f9f 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -752,35 +752,6 @@ internal static bool TryParseAsConstantHashtable(string input, out Hashtable res return true; } - // Collect types that keep .resx file strings - // for errors thrown with "SaveError" - private static readonly Type[] s_resxTypes = new [] - { - typeof(ParserStrings), - typeof(ExtendedTypeSystem), - typeof(DiscoveryExceptions) - }; - - /// - /// Given an errorId and an errorMsg, verify that they correspond to one another - /// in some .resx file - /// - /// the ID (or RESX key) of the error - /// the message (or RESX value) of the error - /// true if the ID and message are paired in some .resx file, false otherwise - private static bool ErrorIdCorrespondsToMsg(string errorId, string errorMsg) - { - foreach (Type resxType in s_resxTypes) - { - if (errorMsg.Equals(resxType.GetProperty(errorId)?.GetValue(null))) - { - return true; - } - } - - return false; - } - #endregion Utilities #region Statements @@ -7310,7 +7281,8 @@ private void SaveError(ParseError error) private void SaveError(IScriptExtent extent, string errorId, string errorMsg, bool incompleteInput, params object[] args) { - Diagnostics.Assert(ErrorIdCorrespondsToMsg(errorId, errorMsg), "ErrorMsg must correspond the the ErrorId in ParserStrings"); + Diagnostics.Assert(errorMsg.Equals(typeof(ParserStrings).GetProperty(errorId, BindingFlags.Static | BindingFlags.NonPublic, null, typeof(string), new Type[0], null)?.GetValue(null, null)), + "ErrorMsg must correspond the the ErrorId in ParserStrings"); if (args != null && args.Any()) { diff --git a/src/System.Management.Automation/engine/parser/SemanticChecks.cs b/src/System.Management.Automation/engine/parser/SemanticChecks.cs index e13effea703..8b106123ced 100644 --- a/src/System.Management.Automation/engine/parser/SemanticChecks.cs +++ b/src/System.Management.Automation/engine/parser/SemanticChecks.cs @@ -210,8 +210,8 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) if (propertyInfo.GetSetMethod() == null) { _parser.ReportError(namedArg.Extent, - nameof(ExtendedTypeSystem.ReadOnlyProperty), - ExtendedTypeSystem.ReadOnlyProperty, + nameof(ParserStrings.ReadOnlyProperty), + ParserStrings.ReadOnlyProperty, name); } @@ -222,8 +222,8 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) if (fieldInfo.IsInitOnly || fieldInfo.IsLiteral) { _parser.ReportError(namedArg.Extent, - nameof(ExtendedTypeSystem.ReadOnlyProperty), - ExtendedTypeSystem.ReadOnlyProperty, + nameof(ParserStrings.ReadOnlyProperty), + ParserStrings.ReadOnlyProperty, name); } } diff --git a/src/System.Management.Automation/engine/parser/tokenizer.cs b/src/System.Management.Automation/engine/parser/tokenizer.cs index 523160dfcee..5ae84ab0a18 100644 --- a/src/System.Management.Automation/engine/parser/tokenizer.cs +++ b/src/System.Management.Automation/engine/parser/tokenizer.cs @@ -1664,8 +1664,8 @@ internal ScriptRequirements GetScriptRequirements() if (!string.Equals(commandName, "requires", StringComparison.OrdinalIgnoreCase)) { ReportError(commandAst.Extent, - nameof(DiscoveryExceptions.ScriptRequiresInvalidFormat), - DiscoveryExceptions.ScriptRequiresInvalidFormat); + nameof(ParserStrings.ScriptRequiresInvalidFormat), + ParserStrings.ScriptRequiresInvalidFormat); } var snapinSpecified = false; @@ -1697,8 +1697,8 @@ internal ScriptRequirements GetScriptRequirements() else { ReportError(commandAst.CommandElements[i].Extent, - nameof(DiscoveryExceptions.ScriptRequiresInvalidFormat), - DiscoveryExceptions.ScriptRequiresInvalidFormat); + nameof(ParserStrings.ScriptRequiresInvalidFormat), + ParserStrings.ScriptRequiresInvalidFormat); } } if (snapinName != null) @@ -1944,8 +1944,8 @@ private void HandleRequiresParameter(CommandParameterAst parameter, else { ReportError(parameter.Extent, - nameof(DiscoveryExceptions.ScriptRequiresInvalidFormat), - DiscoveryExceptions.ScriptRequiresInvalidFormat); + nameof(ParserStrings.ScriptRequiresInvalidFormat), + ParserStrings.ScriptRequiresInvalidFormat); } } diff --git a/src/System.Management.Automation/resources/DiscoveryExceptions.resx b/src/System.Management.Automation/resources/DiscoveryExceptions.resx index 7e1a3bcf578..fbd85fbfcef 100644 --- a/src/System.Management.Automation/resources/DiscoveryExceptions.resx +++ b/src/System.Management.Automation/resources/DiscoveryExceptions.resx @@ -160,16 +160,6 @@ Check the spelling of the name, or if a path was included, verify that the path A script named '{0}' already exists. Scripts must have unique names. - - Cannot process the #requires statement because it is not in the correct format. -The #requires statement must be in one of the following formats: - "#requires -shellid <shellID>" - "#requires -version <major.minor>" - "#requires -psedition <edition>" - "#requires -pssnapin <psSnapInName> [-version <major.minor>]" - "#requires -modules <ModuleSpecification>" - "#requires -runasadministrator" - The script '{0}' cannot be run because it contained a "#requires" statement with a shell ID of {1} that is incompatible with the current shell. To run this script you must use the shell located at '{2}'. diff --git a/src/System.Management.Automation/resources/ExtendedTypeSystem.resx b/src/System.Management.Automation/resources/ExtendedTypeSystem.resx index 9b836fb66bb..583a373450e 100644 --- a/src/System.Management.Automation/resources/ExtendedTypeSystem.resx +++ b/src/System.Management.Automation/resources/ExtendedTypeSystem.resx @@ -228,9 +228,6 @@ Cannot get property value because "{0}" is a write-only property. - - "{0}" is a ReadOnly property. - Cannot set "{0}" because only strings can be used as values to set XmlNode properties. diff --git a/src/System.Management.Automation/resources/ParserStrings.resx b/src/System.Management.Automation/resources/ParserStrings.resx index fc98af9421a..9ea50535df0 100644 --- a/src/System.Management.Automation/resources/ParserStrings.resx +++ b/src/System.Management.Automation/resources/ParserStrings.resx @@ -1461,4 +1461,20 @@ ModuleVersion : Version of module to import. If used, ModuleName must represent Conflict in using PsDscRunAsCredential for Resource {0} because it already specifies PsDscRunAsCredential value. We can only use one PsDscRunAsCredential for the composite resource. + + Cannot process the #requires statement because it is not in the correct format. +The #requires statement must be in one of the following formats: + "#requires -shellid <shellID>" + "#requires -version <major.minor>" + "#requires -psedition <edition>" + "#requires -pssnapin <psSnapInName> [-version <major.minor>]" + "#requires -modules <ModuleSpecification>" + "#requires -runasadministrator" + + + "{0}" is a ReadOnly property. + + + {0} + From 18dad8a3e609bda6b06e6c611499b1b3a33a4840 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 26 Mar 2018 15:12:23 -0700 Subject: [PATCH 10/15] [feature] Fix up tuple usage --- .../engine/parser/SemanticChecks.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/SemanticChecks.cs b/src/System.Management.Automation/engine/parser/SemanticChecks.cs index 8b106123ced..ce83c37d586 100644 --- a/src/System.Management.Automation/engine/parser/SemanticChecks.cs +++ b/src/System.Management.Automation/engine/parser/SemanticChecks.cs @@ -63,7 +63,7 @@ private bool IsValidAttributeArgument(Ast ast, IsConstantValueVisitor visitor) return (bool)ast.Accept(visitor); } - (string id, string msg) GetNonConstantAttributeArgErrorExpr(IsConstantValueVisitor visitor) + private (string id, string msg) GetNonConstantAttributeArgErrorExpr(IsConstantValueVisitor visitor) { if (visitor.CheckingClassAttributeArguments) { @@ -246,8 +246,8 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) if (!namedArg.ExpressionOmitted && !IsValidAttributeArgument(namedArg.Argument, constantValueVisitor)) { - (string errorId, string errorMsg) = GetNonConstantAttributeArgErrorExpr(constantValueVisitor); - _parser.ReportError(namedArg.Argument.Extent, errorId, errorMsg); + var error = GetNonConstantAttributeArgErrorExpr(constantValueVisitor); + _parser.ReportError(namedArg.Argument.Extent, error.id, error.msg); } } } @@ -256,8 +256,8 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) { if (!IsValidAttributeArgument(posArg, constantValueVisitor)) { - (string errorId, string errorMsg) = GetNonConstantAttributeArgErrorExpr(constantValueVisitor); - _parser.ReportError(posArg.Extent, errorId, errorId); + var error = GetNonConstantAttributeArgErrorExpr(constantValueVisitor); + _parser.ReportError(posArg.Extent, error.id, error.msg); } } From aa75e54ec5b3687a16ade6c18799691a5ef895ea Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 26 Mar 2018 15:46:28 -0700 Subject: [PATCH 11/15] [feature] Change raw ParserError strings to resrouce references --- src/System.Management.Automation/engine/parser/Parser.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 78f03f17f9f..0f1f401de4c 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -2952,7 +2952,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, - "ParserError", + nameof(ParserStrings.ParserError), + ParserStrings.ParserError, e.ToString()); return null; } @@ -3140,7 +3141,8 @@ private StatementAst ConfigurationStatementRule(IEnumerable custom { // 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, - "ParserError", + nameof(ParserStrings.ParserError), + ParserStrings.ParserError, "ConfigurationStatementToken: " + e); return null; } @@ -7281,7 +7283,7 @@ private void SaveError(ParseError error) private void SaveError(IScriptExtent extent, string errorId, string errorMsg, bool incompleteInput, params object[] args) { - Diagnostics.Assert(errorMsg.Equals(typeof(ParserStrings).GetProperty(errorId, BindingFlags.Static | BindingFlags.NonPublic, null, typeof(string), new Type[0], null)?.GetValue(null, null)), + Diagnostics.Assert(String.Equals(errorMsg, typeof(ParserStrings).GetProperty(errorId, BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as string, StringComparison.CurrentCulture), "ErrorMsg must correspond the the ErrorId in ParserStrings"); if (args != null && args.Any()) From 0b3f24961a740a2ecf9b9dd5205e037310ad424a Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 26 Mar 2018 16:11:47 -0700 Subject: [PATCH 12/15] [feature] Move errors into ParserStrings.resx for SaveError --- .../engine/CmdletParameterBinderController.cs | 4 ++-- .../PseudoParameterBinder.cs | 4 ++-- .../engine/ParameterBinderController.cs | 4 ++-- .../engine/parser/tokenizer.cs | 24 +++++++++---------- .../engine/scriptparameterbindercontroller.cs | 4 ++-- .../resources/MshSnapInCmdletResources.resx | 3 --- .../resources/ParameterBinderStrings.resx | 3 --- .../resources/ParserStrings.resx | 6 +++++ .../singleshell/config/MshSnapinInfo.cs | 4 ++-- 9 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/System.Management.Automation/engine/CmdletParameterBinderController.cs b/src/System.Management.Automation/engine/CmdletParameterBinderController.cs index 184e8fcd002..14fb2f8be92 100644 --- a/src/System.Management.Automation/engine/CmdletParameterBinderController.cs +++ b/src/System.Management.Automation/engine/CmdletParameterBinderController.cs @@ -1136,8 +1136,8 @@ private Collection BindParameters(uint parameterSets, argument.ParameterName, null, null, - ParameterBinderStrings.ParameterAlreadyBound, - "ParameterAlreadyBound"); + ParserStrings.ParameterAlreadyBound, + nameof(ParserStrings.ParameterAlreadyBound)); // Multiple values assigned to the same parameter. // Not caused by default parameter binding diff --git a/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs b/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs index 7e44b051dbf..b1cffa14a82 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs @@ -586,8 +586,8 @@ private void AddDuplicateParameterBindingException(CommandParameterAst duplicate duplicateParameter.ParameterName, null, null, - ParameterBinderStrings.ParameterAlreadyBound, - "ParameterAlreadyBound"); + ParserStrings.ParameterAlreadyBound, + nameof(ParserStrings.ParameterAlreadyBound)); // if the duplicated Parameter Name appears more than twice, we will ignore as we already have similar bindingException. if (!BindingExceptions.ContainsKey(duplicateParameter.ParameterName)) { diff --git a/src/System.Management.Automation/engine/ParameterBinderController.cs b/src/System.Management.Automation/engine/ParameterBinderController.cs index 72f9fd01697..64f714b58a1 100644 --- a/src/System.Management.Automation/engine/ParameterBinderController.cs +++ b/src/System.Management.Automation/engine/ParameterBinderController.cs @@ -442,8 +442,8 @@ internal virtual bool BindParameter( argument.ParameterName, null, null, - ParameterBinderStrings.ParameterAlreadyBound, - "ParameterAlreadyBound"); + ParserStrings.ParameterAlreadyBound, + nameof(ParserStrings.ParameterAlreadyBound)); throw bindingException; } diff --git a/src/System.Management.Automation/engine/parser/tokenizer.cs b/src/System.Management.Automation/engine/parser/tokenizer.cs index 5ae84ab0a18..805f2dc43c3 100644 --- a/src/System.Management.Automation/engine/parser/tokenizer.cs +++ b/src/System.Management.Automation/engine/parser/tokenizer.cs @@ -1788,8 +1788,8 @@ private void HandleRequiresParameter(CommandParameterAst parameter, if (requiredShellId != null) { ReportError(parameter.Extent, - nameof(ParameterBinderStrings.ParameterAlreadyBound), - ParameterBinderStrings.ParameterAlreadyBound, + nameof(ParserStrings.ParameterAlreadyBound), + ParserStrings.ParameterAlreadyBound, null, shellIDToken); return; @@ -1817,8 +1817,8 @@ private void HandleRequiresParameter(CommandParameterAst parameter, if (snapinName != null) { ReportError(parameter.Extent, - nameof(ParameterBinderStrings.ParameterAlreadyBound), - ParameterBinderStrings.ParameterAlreadyBound, + nameof(ParserStrings.ParameterAlreadyBound), + ParserStrings.ParameterAlreadyBound, null, PSSnapinToken); return; @@ -1826,8 +1826,8 @@ private void HandleRequiresParameter(CommandParameterAst parameter, if (!PSSnapInInfo.IsPSSnapinIdValid((string)argumentValue)) { ReportError(argumentAst.Extent, - nameof(MshSnapInCmdletResources.InvalidPSSnapInName), - MshSnapInCmdletResources.InvalidPSSnapInName); + nameof(ParserStrings.InvalidPSSnapInName), + ParserStrings.InvalidPSSnapInName); return; } @@ -1838,8 +1838,8 @@ private void HandleRequiresParameter(CommandParameterAst parameter, if (requiredEditions != null) { ReportError(parameter.Extent, - nameof(ParameterBinderStrings.ParameterAlreadyBound), - ParameterBinderStrings.ParameterAlreadyBound, + nameof(ParserStrings.ParameterAlreadyBound), + ParserStrings.ParameterAlreadyBound, null, editionToken); return; @@ -1874,8 +1874,8 @@ private void HandleRequiresParameter(CommandParameterAst parameter, if (snapinVersion != null) { ReportError(parameter.Extent, - nameof(ParameterBinderStrings.ParameterAlreadyBound), - ParameterBinderStrings.ParameterAlreadyBound, + nameof(ParserStrings.ParameterAlreadyBound), + ParserStrings.ParameterAlreadyBound, null, versionToken); return; @@ -1887,8 +1887,8 @@ private void HandleRequiresParameter(CommandParameterAst parameter, if (requiredVersion != null && !requiredVersion.Equals(version)) { ReportError(parameter.Extent, - nameof(ParameterBinderStrings.ParameterAlreadyBound), - ParameterBinderStrings.ParameterAlreadyBound, + nameof(ParserStrings.ParameterAlreadyBound), + ParserStrings.ParameterAlreadyBound, null, versionToken); return; diff --git a/src/System.Management.Automation/engine/scriptparameterbindercontroller.cs b/src/System.Management.Automation/engine/scriptparameterbindercontroller.cs index 0d316b12972..7e3353d706b 100644 --- a/src/System.Management.Automation/engine/scriptparameterbindercontroller.cs +++ b/src/System.Management.Automation/engine/scriptparameterbindercontroller.cs @@ -191,8 +191,8 @@ internal override Collection BindParameters(Collection argument.ParameterName, null, null, - ParameterBinderStrings.ParameterAlreadyBound, - "ParameterAlreadyBound"); + ParserStrings.ParameterAlreadyBound, + nameof(ParserStrings.ParameterAlreadyBound)); throw bindingException; } diff --git a/src/System.Management.Automation/resources/MshSnapInCmdletResources.resx b/src/System.Management.Automation/resources/MshSnapInCmdletResources.resx index d23249ed109..c00d61f8fe7 100644 --- a/src/System.Management.Automation/resources/MshSnapInCmdletResources.resx +++ b/src/System.Management.Automation/resources/MshSnapInCmdletResources.resx @@ -123,9 +123,6 @@ No PowerShell snap-ins matching the pattern '{0}' were found. Check the pattern and then try the command again. - - The format of the specified snap-in name was not valid. PowerShell snap-in names can only contain alpha-numeric characters, dashes, underscores and periods. Correct the name and then try the operation again. - Cannot add PowerShell snap-in {0} because it is a system PowerShell module. Use Import-Module to load the module. diff --git a/src/System.Management.Automation/resources/ParameterBinderStrings.resx b/src/System.Management.Automation/resources/ParameterBinderStrings.resx index 8c49becc278..dd31161a383 100644 --- a/src/System.Management.Automation/resources/ParameterBinderStrings.resx +++ b/src/System.Management.Automation/resources/ParameterBinderStrings.resx @@ -150,9 +150,6 @@ Parameter '{1}' cannot be specified in parameter set '{6}'. - - Cannot bind parameter because parameter '{1}' is specified more than once. To provide multiple values to parameters that can accept multiple values, use the array syntax. For example, "-parameter value1,value2,value3". - Cannot evaluate parameter '{1}' because its argument is specified as a script block and there is no input. A script block cannot be evaluated without input. diff --git a/src/System.Management.Automation/resources/ParserStrings.resx b/src/System.Management.Automation/resources/ParserStrings.resx index 9ea50535df0..d3667bcd2b0 100644 --- a/src/System.Management.Automation/resources/ParserStrings.resx +++ b/src/System.Management.Automation/resources/ParserStrings.resx @@ -1477,4 +1477,10 @@ The #requires statement must be in one of the following formats: {0} + + The format of the specified snap-in name was not valid. PowerShell snap-in names can only contain alpha-numeric characters, dashes, underscores and periods. Correct the name and then try the operation again. + + + Cannot bind parameter because parameter '{1}' is specified more than once. To provide multiple values to parameters that can accept multiple values, use the array syntax. For example, "-parameter value1,value2,value3". + diff --git a/src/System.Management.Automation/singleshell/config/MshSnapinInfo.cs b/src/System.Management.Automation/singleshell/config/MshSnapinInfo.cs index 74f0a1170a5..33b5107e1be 100644 --- a/src/System.Management.Automation/singleshell/config/MshSnapinInfo.cs +++ b/src/System.Management.Automation/singleshell/config/MshSnapinInfo.cs @@ -453,8 +453,8 @@ internal static void VerifyPSSnapInFormatThrowIfError(string psSnapinId) // argument exception if (!IsPSSnapinIdValid(psSnapinId)) { - throw PSTraceSource.NewArgumentException("mshSnapInId", - MshSnapInCmdletResources.InvalidPSSnapInName, + throw PSTraceSource.NewArgumentException(nameof(psSnapinId), + ParserStrings.InvalidPSSnapInName, psSnapinId); } From d098b668dc7096e7304989023bf9a00b7848dbfc Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 26 Mar 2018 16:14:14 -0700 Subject: [PATCH 13/15] [feature] Add explicit errorId and errorMsg to assertion --- 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 0f1f401de4c..7f78947024d 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -7284,7 +7284,7 @@ private void SaveError(ParseError error) private void SaveError(IScriptExtent extent, string errorId, string errorMsg, bool incompleteInput, params object[] args) { Diagnostics.Assert(String.Equals(errorMsg, typeof(ParserStrings).GetProperty(errorId, BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as string, StringComparison.CurrentCulture), - "ErrorMsg must correspond the the ErrorId in ParserStrings"); + String.Format("ErrorMsg \"{0}\" must correspond the the ErrorId \"{1}\" in ParserStrings", errorMsg, errorId)); if (args != null && args.Any()) { From b6ae29cda66120a04fb54e3dbf833f20d8076d44 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Tue, 27 Mar 2018 10:02:50 -0700 Subject: [PATCH 14/15] [feature] Add error id assertion, replace strings in rex files --- .../engine/CmdletParameterBinderController.cs | 4 +- .../PseudoParameterBinder.cs | 4 +- .../engine/CoreAdapter.cs | 4 +- .../engine/ParameterBinderController.cs | 4 +- .../engine/parser/Parser.cs | 37 ++++++++++++++++++- .../engine/parser/SemanticChecks.cs | 8 ++-- .../engine/parser/tokenizer.cs | 36 +++++++++--------- .../engine/scriptparameterbindercontroller.cs | 4 +- .../resources/DiscoveryExceptions.resx | 10 +++++ .../resources/ExtendedTypeSystem.resx | 3 ++ .../resources/MshSnapInCmdletResources.resx | 3 ++ .../resources/ParameterBinderStrings.resx | 3 ++ .../resources/ParserStrings.resx | 19 ---------- .../singleshell/config/MshSnapinInfo.cs | 2 +- 14 files changed, 87 insertions(+), 54 deletions(-) diff --git a/src/System.Management.Automation/engine/CmdletParameterBinderController.cs b/src/System.Management.Automation/engine/CmdletParameterBinderController.cs index 14fb2f8be92..6eb9a2ce35b 100644 --- a/src/System.Management.Automation/engine/CmdletParameterBinderController.cs +++ b/src/System.Management.Automation/engine/CmdletParameterBinderController.cs @@ -1136,8 +1136,8 @@ private Collection BindParameters(uint parameterSets, argument.ParameterName, null, null, - ParserStrings.ParameterAlreadyBound, - nameof(ParserStrings.ParameterAlreadyBound)); + ParameterBinderStrings.ParameterAlreadyBound, + nameof(ParameterBinderStrings.ParameterAlreadyBound)); // Multiple values assigned to the same parameter. // Not caused by default parameter binding diff --git a/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs b/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs index b1cffa14a82..0fd8288ec42 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs @@ -586,8 +586,8 @@ private void AddDuplicateParameterBindingException(CommandParameterAst duplicate duplicateParameter.ParameterName, null, null, - ParserStrings.ParameterAlreadyBound, - nameof(ParserStrings.ParameterAlreadyBound)); + ParameterBinderStrings.ParameterAlreadyBound, + nameof(ParameterBinderStrings.ParameterAlreadyBound)); // if the duplicated Parameter Name appears more than twice, we will ignore as we already have similar bindingException. if (!BindingExceptions.ContainsKey(duplicateParameter.ParameterName)) { diff --git a/src/System.Management.Automation/engine/CoreAdapter.cs b/src/System.Management.Automation/engine/CoreAdapter.cs index a79b030246c..1698c1672a0 100644 --- a/src/System.Management.Automation/engine/CoreAdapter.cs +++ b/src/System.Management.Automation/engine/CoreAdapter.cs @@ -3667,9 +3667,9 @@ protected override void PropertySet(PSProperty property, object setValue, bool c if (adapterData.readOnly) { - throw new SetValueException(nameof(ParserStrings.ReadOnlyProperty), + throw new SetValueException(nameof(ExtendedTypeSystem.ReadOnlyProperty), null, - ParserStrings.ReadOnlyProperty, + ExtendedTypeSystem.ReadOnlyProperty, adapterData.member.Name); } diff --git a/src/System.Management.Automation/engine/ParameterBinderController.cs b/src/System.Management.Automation/engine/ParameterBinderController.cs index 64f714b58a1..c54c805d6eb 100644 --- a/src/System.Management.Automation/engine/ParameterBinderController.cs +++ b/src/System.Management.Automation/engine/ParameterBinderController.cs @@ -442,8 +442,8 @@ internal virtual bool BindParameter( argument.ParameterName, null, null, - ParserStrings.ParameterAlreadyBound, - nameof(ParserStrings.ParameterAlreadyBound)); + ParameterBinderStrings.ParameterAlreadyBound, + nameof(ParameterBinderStrings.ParameterAlreadyBound)); throw bindingException; } diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 7f78947024d..fbc7de4b2c0 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -7283,8 +7283,7 @@ private void SaveError(ParseError error) private void SaveError(IScriptExtent extent, string errorId, string errorMsg, bool incompleteInput, params object[] args) { - Diagnostics.Assert(String.Equals(errorMsg, typeof(ParserStrings).GetProperty(errorId, BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as string, StringComparison.CurrentCulture), - String.Format("ErrorMsg \"{0}\" must correspond the the ErrorId \"{1}\" in ParserStrings", errorMsg, errorId)); + AssertErrorIdCorrespondsToMsgString(errorId, errorMsg); if (args != null && args.Any()) { @@ -7295,6 +7294,40 @@ private void SaveError(IScriptExtent extent, string errorId, string errorMsg, bo SaveError(errorToSave); } + /// + /// Assertion to ensure that .resx resource files are where all errors + /// saved by the parser are stored. Goes through the known resource types + /// and checks that the given error ID and message match some entry in one of them + /// + /// The error ID string (.resx key) + /// The error message, which may be a template string (.resx value) + [System.Diagnostics.Conditional("DEBUG")] + [System.Diagnostics.Conditional("ASSERTIONS_TRACE")] + private static void AssertErrorIdCorrespondsToMsgString(string errorId, string errorMsg) + { + Type[] resxTypes = new [] + { + typeof(ParserStrings), + typeof(DiscoveryExceptions), + typeof(ExtendedTypeSystem), + typeof(MshSnapInCmdletResources), + typeof(ParameterBinderStrings) + }; + + bool msgCorrespondsToString = false; + foreach (Type resxType in resxTypes) + { + string resxErrorBody = resxType.GetProperty(errorId, BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as string; + if (String.Equals(errorMsg, resxErrorBody)) + { + msgCorrespondsToString = true; + break; + } + } + + Diagnostics.Assert(msgCorrespondsToString, String.Format("Parser error ID \"{0}\" must correspond to the error message \"{1}\"", errorId, errorMsg)); + } + private static object[] arrayOfOneArg { get { return t_arrayOfOneArg ?? (t_arrayOfOneArg = new object[1]); } diff --git a/src/System.Management.Automation/engine/parser/SemanticChecks.cs b/src/System.Management.Automation/engine/parser/SemanticChecks.cs index ce83c37d586..6f96c8c81ad 100644 --- a/src/System.Management.Automation/engine/parser/SemanticChecks.cs +++ b/src/System.Management.Automation/engine/parser/SemanticChecks.cs @@ -210,8 +210,8 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) if (propertyInfo.GetSetMethod() == null) { _parser.ReportError(namedArg.Extent, - nameof(ParserStrings.ReadOnlyProperty), - ParserStrings.ReadOnlyProperty, + nameof(ExtendedTypeSystem.ReadOnlyProperty), + ExtendedTypeSystem.ReadOnlyProperty, name); } @@ -222,8 +222,8 @@ public override AstVisitAction VisitAttribute(AttributeAst attributeAst) if (fieldInfo.IsInitOnly || fieldInfo.IsLiteral) { _parser.ReportError(namedArg.Extent, - nameof(ParserStrings.ReadOnlyProperty), - ParserStrings.ReadOnlyProperty, + nameof(ExtendedTypeSystem.ReadOnlyProperty), + ExtendedTypeSystem.ReadOnlyProperty, name); } } diff --git a/src/System.Management.Automation/engine/parser/tokenizer.cs b/src/System.Management.Automation/engine/parser/tokenizer.cs index 805f2dc43c3..523160dfcee 100644 --- a/src/System.Management.Automation/engine/parser/tokenizer.cs +++ b/src/System.Management.Automation/engine/parser/tokenizer.cs @@ -1664,8 +1664,8 @@ internal ScriptRequirements GetScriptRequirements() if (!string.Equals(commandName, "requires", StringComparison.OrdinalIgnoreCase)) { ReportError(commandAst.Extent, - nameof(ParserStrings.ScriptRequiresInvalidFormat), - ParserStrings.ScriptRequiresInvalidFormat); + nameof(DiscoveryExceptions.ScriptRequiresInvalidFormat), + DiscoveryExceptions.ScriptRequiresInvalidFormat); } var snapinSpecified = false; @@ -1697,8 +1697,8 @@ internal ScriptRequirements GetScriptRequirements() else { ReportError(commandAst.CommandElements[i].Extent, - nameof(ParserStrings.ScriptRequiresInvalidFormat), - ParserStrings.ScriptRequiresInvalidFormat); + nameof(DiscoveryExceptions.ScriptRequiresInvalidFormat), + DiscoveryExceptions.ScriptRequiresInvalidFormat); } } if (snapinName != null) @@ -1788,8 +1788,8 @@ private void HandleRequiresParameter(CommandParameterAst parameter, if (requiredShellId != null) { ReportError(parameter.Extent, - nameof(ParserStrings.ParameterAlreadyBound), - ParserStrings.ParameterAlreadyBound, + nameof(ParameterBinderStrings.ParameterAlreadyBound), + ParameterBinderStrings.ParameterAlreadyBound, null, shellIDToken); return; @@ -1817,8 +1817,8 @@ private void HandleRequiresParameter(CommandParameterAst parameter, if (snapinName != null) { ReportError(parameter.Extent, - nameof(ParserStrings.ParameterAlreadyBound), - ParserStrings.ParameterAlreadyBound, + nameof(ParameterBinderStrings.ParameterAlreadyBound), + ParameterBinderStrings.ParameterAlreadyBound, null, PSSnapinToken); return; @@ -1826,8 +1826,8 @@ private void HandleRequiresParameter(CommandParameterAst parameter, if (!PSSnapInInfo.IsPSSnapinIdValid((string)argumentValue)) { ReportError(argumentAst.Extent, - nameof(ParserStrings.InvalidPSSnapInName), - ParserStrings.InvalidPSSnapInName); + nameof(MshSnapInCmdletResources.InvalidPSSnapInName), + MshSnapInCmdletResources.InvalidPSSnapInName); return; } @@ -1838,8 +1838,8 @@ private void HandleRequiresParameter(CommandParameterAst parameter, if (requiredEditions != null) { ReportError(parameter.Extent, - nameof(ParserStrings.ParameterAlreadyBound), - ParserStrings.ParameterAlreadyBound, + nameof(ParameterBinderStrings.ParameterAlreadyBound), + ParameterBinderStrings.ParameterAlreadyBound, null, editionToken); return; @@ -1874,8 +1874,8 @@ private void HandleRequiresParameter(CommandParameterAst parameter, if (snapinVersion != null) { ReportError(parameter.Extent, - nameof(ParserStrings.ParameterAlreadyBound), - ParserStrings.ParameterAlreadyBound, + nameof(ParameterBinderStrings.ParameterAlreadyBound), + ParameterBinderStrings.ParameterAlreadyBound, null, versionToken); return; @@ -1887,8 +1887,8 @@ private void HandleRequiresParameter(CommandParameterAst parameter, if (requiredVersion != null && !requiredVersion.Equals(version)) { ReportError(parameter.Extent, - nameof(ParserStrings.ParameterAlreadyBound), - ParserStrings.ParameterAlreadyBound, + nameof(ParameterBinderStrings.ParameterAlreadyBound), + ParameterBinderStrings.ParameterAlreadyBound, null, versionToken); return; @@ -1944,8 +1944,8 @@ private void HandleRequiresParameter(CommandParameterAst parameter, else { ReportError(parameter.Extent, - nameof(ParserStrings.ScriptRequiresInvalidFormat), - ParserStrings.ScriptRequiresInvalidFormat); + nameof(DiscoveryExceptions.ScriptRequiresInvalidFormat), + DiscoveryExceptions.ScriptRequiresInvalidFormat); } } diff --git a/src/System.Management.Automation/engine/scriptparameterbindercontroller.cs b/src/System.Management.Automation/engine/scriptparameterbindercontroller.cs index 7e3353d706b..81c0f225dba 100644 --- a/src/System.Management.Automation/engine/scriptparameterbindercontroller.cs +++ b/src/System.Management.Automation/engine/scriptparameterbindercontroller.cs @@ -191,8 +191,8 @@ internal override Collection BindParameters(Collection argument.ParameterName, null, null, - ParserStrings.ParameterAlreadyBound, - nameof(ParserStrings.ParameterAlreadyBound)); + ParameterBinderStrings.ParameterAlreadyBound, + nameof(ParameterBinderStrings.ParameterAlreadyBound)); throw bindingException; } diff --git a/src/System.Management.Automation/resources/DiscoveryExceptions.resx b/src/System.Management.Automation/resources/DiscoveryExceptions.resx index fbd85fbfcef..7e1a3bcf578 100644 --- a/src/System.Management.Automation/resources/DiscoveryExceptions.resx +++ b/src/System.Management.Automation/resources/DiscoveryExceptions.resx @@ -160,6 +160,16 @@ Check the spelling of the name, or if a path was included, verify that the path A script named '{0}' already exists. Scripts must have unique names. + + Cannot process the #requires statement because it is not in the correct format. +The #requires statement must be in one of the following formats: + "#requires -shellid <shellID>" + "#requires -version <major.minor>" + "#requires -psedition <edition>" + "#requires -pssnapin <psSnapInName> [-version <major.minor>]" + "#requires -modules <ModuleSpecification>" + "#requires -runasadministrator" + The script '{0}' cannot be run because it contained a "#requires" statement with a shell ID of {1} that is incompatible with the current shell. To run this script you must use the shell located at '{2}'. diff --git a/src/System.Management.Automation/resources/ExtendedTypeSystem.resx b/src/System.Management.Automation/resources/ExtendedTypeSystem.resx index 583a373450e..9b836fb66bb 100644 --- a/src/System.Management.Automation/resources/ExtendedTypeSystem.resx +++ b/src/System.Management.Automation/resources/ExtendedTypeSystem.resx @@ -228,6 +228,9 @@ Cannot get property value because "{0}" is a write-only property. + + "{0}" is a ReadOnly property. + Cannot set "{0}" because only strings can be used as values to set XmlNode properties. diff --git a/src/System.Management.Automation/resources/MshSnapInCmdletResources.resx b/src/System.Management.Automation/resources/MshSnapInCmdletResources.resx index c00d61f8fe7..d23249ed109 100644 --- a/src/System.Management.Automation/resources/MshSnapInCmdletResources.resx +++ b/src/System.Management.Automation/resources/MshSnapInCmdletResources.resx @@ -123,6 +123,9 @@ No PowerShell snap-ins matching the pattern '{0}' were found. Check the pattern and then try the command again. + + The format of the specified snap-in name was not valid. PowerShell snap-in names can only contain alpha-numeric characters, dashes, underscores and periods. Correct the name and then try the operation again. + Cannot add PowerShell snap-in {0} because it is a system PowerShell module. Use Import-Module to load the module. diff --git a/src/System.Management.Automation/resources/ParameterBinderStrings.resx b/src/System.Management.Automation/resources/ParameterBinderStrings.resx index dd31161a383..8c49becc278 100644 --- a/src/System.Management.Automation/resources/ParameterBinderStrings.resx +++ b/src/System.Management.Automation/resources/ParameterBinderStrings.resx @@ -150,6 +150,9 @@ Parameter '{1}' cannot be specified in parameter set '{6}'. + + Cannot bind parameter because parameter '{1}' is specified more than once. To provide multiple values to parameters that can accept multiple values, use the array syntax. For example, "-parameter value1,value2,value3". + Cannot evaluate parameter '{1}' because its argument is specified as a script block and there is no input. A script block cannot be evaluated without input. diff --git a/src/System.Management.Automation/resources/ParserStrings.resx b/src/System.Management.Automation/resources/ParserStrings.resx index d3667bcd2b0..c63a63d1a4d 100644 --- a/src/System.Management.Automation/resources/ParserStrings.resx +++ b/src/System.Management.Automation/resources/ParserStrings.resx @@ -1461,26 +1461,7 @@ ModuleVersion : Version of module to import. If used, ModuleName must represent Conflict in using PsDscRunAsCredential for Resource {0} because it already specifies PsDscRunAsCredential value. We can only use one PsDscRunAsCredential for the composite resource. - - Cannot process the #requires statement because it is not in the correct format. -The #requires statement must be in one of the following formats: - "#requires -shellid <shellID>" - "#requires -version <major.minor>" - "#requires -psedition <edition>" - "#requires -pssnapin <psSnapInName> [-version <major.minor>]" - "#requires -modules <ModuleSpecification>" - "#requires -runasadministrator" - - - "{0}" is a ReadOnly property. - {0} - - The format of the specified snap-in name was not valid. PowerShell snap-in names can only contain alpha-numeric characters, dashes, underscores and periods. Correct the name and then try the operation again. - - - Cannot bind parameter because parameter '{1}' is specified more than once. To provide multiple values to parameters that can accept multiple values, use the array syntax. For example, "-parameter value1,value2,value3". - diff --git a/src/System.Management.Automation/singleshell/config/MshSnapinInfo.cs b/src/System.Management.Automation/singleshell/config/MshSnapinInfo.cs index 33b5107e1be..32741bea030 100644 --- a/src/System.Management.Automation/singleshell/config/MshSnapinInfo.cs +++ b/src/System.Management.Automation/singleshell/config/MshSnapinInfo.cs @@ -454,7 +454,7 @@ internal static void VerifyPSSnapInFormatThrowIfError(string psSnapinId) if (!IsPSSnapinIdValid(psSnapinId)) { throw PSTraceSource.NewArgumentException(nameof(psSnapinId), - ParserStrings.InvalidPSSnapInName, + MshSnapInCmdletResources.InvalidPSSnapInName, psSnapinId); } From 78154ea312c680aacc77b5d90e26e2f1fc0bacb6 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Tue, 27 Mar 2018 14:22:39 -0700 Subject: [PATCH 15/15] [feature] Use explicit ordinal string comparison, reword comments --- .../engine/parser/Parser.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index fbc7de4b2c0..ebdae013f2f 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -7295,9 +7295,8 @@ private void SaveError(IScriptExtent extent, string errorId, string errorMsg, bo } /// - /// Assertion to ensure that .resx resource files are where all errors - /// saved by the parser are stored. Goes through the known resource types - /// and checks that the given error ID and message match some entry in one of them + /// Debug assertion to ensure that all errors saved by the parser come + /// from resource (.resx) files. /// /// The error ID string (.resx key) /// The error message, which may be a template string (.resx value) @@ -7305,6 +7304,8 @@ private void SaveError(IScriptExtent extent, string errorId, string errorMsg, bo [System.Diagnostics.Conditional("ASSERTIONS_TRACE")] private static void AssertErrorIdCorrespondsToMsgString(string errorId, string errorMsg) { + // These types are the ones known to contain + // strings used by the parser as errors Type[] resxTypes = new [] { typeof(ParserStrings), @@ -7314,11 +7315,12 @@ private static void AssertErrorIdCorrespondsToMsgString(string errorId, string e typeof(ParameterBinderStrings) }; + // Go through each resource type and see if the errorId key is in it, and whether the value corresponds to the errorMsg bool msgCorrespondsToString = false; foreach (Type resxType in resxTypes) { string resxErrorBody = resxType.GetProperty(errorId, BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as string; - if (String.Equals(errorMsg, resxErrorBody)) + if (String.Equals(errorMsg, resxErrorBody, StringComparison.Ordinal)) { msgCorrespondsToString = true; break;