提交 fc0a8f61 编写于 作者: G Gen Lu

Add InvalidExpression concrete type

Also fixes crash in `ArgumentBase.IsInvalid` property when code has error.
上级 7472f832
......@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using Microsoft.CodeAnalysis;
......@@ -141,7 +142,7 @@ private static IArgument DeriveArgument(int parameterIndex, int argumentIndex, I
}
// There is no supplied argument and there is no params parameter. Any action is suspect at this point.
return new SimpleArgument(null, null);
return new SimpleArgument(null, new InvalidExpression(invocationSyntax));
}
return s_argumentMappings.GetValue(
......@@ -197,7 +198,7 @@ private static IOperation CreateParamArray(IParameterSymbol parameter, Immutable
return new ArrayCreation(arrayType, paramArrayArguments, paramArrayArguments.Length > 0 ? paramArrayArguments[0].Syntax : invocationSyntax);
}
return null;
return new InvalidExpression(invocationSyntax);
}
internal static IArgument ArgumentMatchingParameter(ImmutableArray<BoundExpression> arguments, ImmutableArray<int> argumentsToParameters, ImmutableArray<string> argumentNames, ImmutableArray<RefKind> argumentRefKinds, ISymbol targetMethod, ImmutableArray<Symbols.ParameterSymbol> parameters, IParameterSymbol parameter, SyntaxNode invocationSyntax)
......@@ -232,6 +233,8 @@ private abstract class ArgumentBase : IArgument
{
public ArgumentBase(IParameterSymbol parameter, IOperation value)
{
Debug.Assert(value != null);
this.Value = value;
this.Parameter = parameter;
}
......
......@@ -1502,6 +1502,36 @@ public void Increment(string f)
Diagnostic(InvalidOperatorExpressionTestAnalyzer.InvalidIncrementDescriptor.Id, "f++").WithLocation(16, 9));
}
[WorkItem(9114, "https://github.com/dotnet/roslyn/issues/9114")]
[Fact]
public void InvalidArgumentCSharp()
{
const string source = @"
public class A
{
public static void Foo(params int a) {}
public static int Main()
{
Foo();
Foo(1);
return 1;
}
}
";
CreateCompilationWithMscorlib45(source)
.VerifyDiagnostics(
// (4,28): error CS0225: The params parameter must be a single dimensional array
// public static void Foo(params int a) {}
Diagnostic(ErrorCode.ERR_ParamsMustBeArray, "params").WithLocation(4, 28),
// (8,9): error CS7036: There is no argument given that corresponds to the required formal parameter 'a' of 'A.Foo(params int)'
// Foo();
Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "Foo").WithArguments("a", "A.Foo(params int)").WithLocation(8, 9))
.VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new InvocationTestAnalyzer() }, null, null, false,
Diagnostic(InvocationTestAnalyzer.InvalidArgumentDescriptor.Id, "Foo()").WithLocation(8, 9),
Diagnostic(InvocationTestAnalyzer.InvalidArgumentDescriptor.Id, "Foo(1)").WithLocation(9, 9));
}
[Fact]
public void ConditionalAccessOperationsCSharp()
{
......
......@@ -493,6 +493,14 @@ public class InvocationTestAnalyzer : DiagnosticAnalyzer
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public static readonly DiagnosticDescriptor InvalidArgumentDescriptor = new DiagnosticDescriptor(
"InvalidArgument",
"Invalid argument",
"Invocation has invalid argument",
ReliabilityCategory,
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
/// <summary>Gets the set of supported diagnostic descriptors from this analyzer.</summary>
public sealed override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
{
......@@ -500,7 +508,8 @@ public sealed override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
{
return ImmutableArray.Create(BigParamArrayArgumentsDescriptor,
OutOfNumericalOrderArgumentsDescriptor,
UseDefaultArgumentDescriptor);
UseDefaultArgumentDescriptor,
InvalidArgumentDescriptor);
}
}
......@@ -513,6 +522,12 @@ public sealed override void Initialize(AnalysisContext context)
long priorArgumentValue = long.MinValue;
foreach (IArgument argument in invocation.ArgumentsInParameterOrder)
{
if (argument.IsInvalid)
{
operationContext.ReportDiagnostic(Diagnostic.Create(InvalidArgumentDescriptor, argument.Syntax.GetLocation()));
return;
}
if (argument.ArgumentKind == ArgumentKind.DefaultValue)
{
operationContext.ReportDiagnostic(Diagnostic.Create(UseDefaultArgumentDescriptor, invocation.Syntax.GetLocation(), argument.Parameter.Name));
......
......@@ -450,4 +450,32 @@ public void Accept(OperationVisitor visitor)
}
}
}
internal sealed class InvalidExpression : IInvalidExpression
{
public InvalidExpression(SyntaxNode syntax)
{
this.Syntax = syntax;
}
public Optional<object> ConstantValue => default(Optional<object>);
public bool IsInvalid => true;
public OperationKind Kind => OperationKind.InvalidExpression;
public SyntaxNode Syntax { get; }
public ITypeSymbol Type => null;
public void Accept(OperationVisitor visitor)
{
visitor.VisitInvalidExpression(this);
}
public TResult Accept<TArgument, TResult>(OperationVisitor<TArgument, TResult> visitor, TArgument argument)
{
return visitor.VisitInvalidExpression(this, argument);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册