提交 3f19fb53 编写于 作者: J Julien Couvreur 提交者: GitHub

More tests and suggestions on default literal (#18604)

上级 605963e2
......@@ -2180,7 +2180,7 @@ private BoundExpression BindUnaryOperatorCore(CSharpSyntaxNode node, string oper
{
UnaryOperatorKind kind = SyntaxKindToUnaryOperatorKind(node.Kind());
bool isOperandTypeNull = (object)operand.Type == null;
bool isOperandTypeNull = operand.IsLiteralNull();
if (isOperandTypeNull)
{
// Dev10 does not allow unary prefix operators to be applied to the null literal
......
......@@ -512,7 +512,7 @@ private bool GetEnumeratorInfo(ref ForEachEnumeratorInfo.Builder builder, BoundE
if ((object)collectionExprType == null) // There's no way to enumerate something without a type.
{
if (collectionExpr.Kind == BoundKind.DefaultExpression && (object)collectionExpr.Type == null)
if (collectionExpr.Kind == BoundKind.DefaultExpression)
{
diagnostics.Add(ErrorCode.ERR_DefaultLiteralNotValid, _syntax.Expression.Location);
}
......
......@@ -518,7 +518,7 @@
</Node>
<Node Name="BoundDefaultExpression" Base="BoundExpression">
<!-- Type is null in the case of a default literal, and non-null in the case of a fully-spelled out default operator. -->
<!-- Type is null in the case of a default literal, and non-null for default(T). -->
<Field Name="Type" Type="TypeSymbol" Override="true" Null="allow"/>
<Field Name="ConstantValueOpt" Type="ConstantValue" Null="allow"/>
</Node>
......
......@@ -529,11 +529,6 @@ public BoundDefaultExpression(SyntaxNode syntax, TypeSymbol type, bool hasErrors
: this(syntax, type.GetDefaultValue(), type, hasErrors)
{
}
public BoundDefaultExpression(SyntaxNode syntax)
: this(syntax, constantValueOpt: null, type: null, hasErrors: false)
{
}
}
internal partial class BoundTryStatement
......
......@@ -449,7 +449,7 @@ internal class CSharpResources {
}
/// <summary>
/// Looks up a localized string similar to Cannot assign {0} to anonymous type property.
/// Looks up a localized string similar to Cannot assign &apos;{0}&apos; to anonymous type property.
/// </summary>
internal static string ERR_AnonymousTypePropertyAssignedBadValue {
get {
......@@ -8855,7 +8855,7 @@ internal class CSharpResources {
}
/// <summary>
/// Looks up a localized string similar to The switch expression must be a value; found {0}..
/// Looks up a localized string similar to The switch expression must be a value; found &apos;{0}&apos;..
/// </summary>
internal static string ERR_SwitchExpressionValueExpected {
get {
......
......@@ -2142,7 +2142,7 @@ If such a class is used as a base class and if the deriving class defines a dest
<value>No best type found for implicitly-typed array</value>
</data>
<data name="ERR_AnonymousTypePropertyAssignedBadValue" xml:space="preserve">
<value>Cannot assign {0} to anonymous type property</value>
<value>Cannot assign '{0}' to anonymous type property</value>
</data>
<data name="ERR_ExpressionTreeContainsBaseAccess" xml:space="preserve">
<value>An expression tree may not contain a base access</value>
......@@ -4886,7 +4886,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<value>Deconstruct assignment requires an expression with a type on the right-hand-side.</value>
</data>
<data name="ERR_SwitchExpressionValueExpected" xml:space="preserve">
<value>The switch expression must be a value; found {0}.</value>
<value>The switch expression must be a value; found '{0}'.</value>
</data>
<data name="ERR_PatternIsSubsumed" xml:space="preserve">
<value>The switch case has already been handled by a previous case.</value>
......
......@@ -14,6 +14,7 @@ public static class TestOptions
public static readonly CSharpParseOptions Script = new CSharpParseOptions(kind: SourceCodeKind.Script, documentationMode: DocumentationMode.None);
public static readonly CSharpParseOptions Regular = new CSharpParseOptions(kind: SourceCodeKind.Regular, documentationMode: DocumentationMode.None);
public static readonly CSharpParseOptions Regular6 = Regular.WithLanguageVersion(LanguageVersion.CSharp6);
public static readonly CSharpParseOptions Regular7_1 = Regular.WithLanguageVersion(LanguageVersion.CSharp7_1);
public static readonly CSharpParseOptions RegularWithDocumentationComments = new CSharpParseOptions(kind: SourceCodeKind.Regular, documentationMode: DocumentationMode.Diagnose);
private static readonly SmallDictionary<string, string> s_experimentalFeatures = new SmallDictionary<string, string> { };
......
......@@ -194,9 +194,11 @@ private static ExpressionSyntax ParseDebuggerExpression(string text, bool consum
return expression.MakeDebuggerExpression(source);
}
static readonly CSharpParseOptions s_CSharpParseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest);
private static InternalSyntax.ExpressionSyntax ParseDebuggerExpressionInternal(SourceText source, bool consumeFullText)
{
using (var lexer = new InternalSyntax.Lexer(source, CSharpParseOptions.Default, allowPreprocessorDirectives: false))
using (var lexer = new InternalSyntax.Lexer(source, s_CSharpParseOptions, allowPreprocessorDirectives: false))
{
using (var parser = new InternalSyntax.LanguageParser(lexer, oldTree: null, changes: null, lexerMode: InternalSyntax.LexerMode.DebuggerSyntax))
{
......@@ -210,7 +212,7 @@ private static InternalSyntax.ExpressionSyntax ParseDebuggerExpressionInternal(S
private static StatementSyntax ParseDebuggerStatement(string text)
{
var source = SourceText.From(text);
using (var lexer = new InternalSyntax.Lexer(source, CSharpParseOptions.Default))
using (var lexer = new InternalSyntax.Lexer(source, s_CSharpParseOptions))
{
using (var parser = new InternalSyntax.LanguageParser(lexer, oldTree: null, changes: null, lexerMode: InternalSyntax.LexerMode.DebuggerSyntax))
{
......
......@@ -6205,5 +6205,109 @@ .maxstack 3
}");
});
}
[Fact]
public void AssignDefaultToLocal()
{
var source = @"
class C
{
void Test()
{
int a = 1;
}
}
";
var comp = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular);
WithRuntimeInstance(comp, runtime =>
{
var context = CreateMethodContext(runtime, methodName: "C.Test");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
context.CompileAssignment("a", "default", NoAliases, DebuggerDiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData);
Assert.Null(error);
Assert.Empty(missingAssemblyIdentities);
Assert.Equal(DkmClrCompilationResultFlags.PotentialSideEffect, resultProperties.Flags);
Assert.Equal(default(DkmEvaluationResultCategory), resultProperties.Category); // Not Data
Assert.Equal(default(DkmEvaluationResultAccessType), resultProperties.AccessType); // Not Public
Assert.Equal(default(DkmEvaluationResultStorageType), resultProperties.StorageType);
Assert.Equal(default(DkmEvaluationResultTypeModifierFlags), resultProperties.ModifierFlags); // Not Virtual
testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
// Code size 3 (0x3)
.maxstack 1
.locals init (int V_0) //a
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: ret
}");
testData = new CompilationTestData();
context.CompileExpression("a = default;", DkmEvaluationFlags.None, ImmutableArray<Alias>.Empty, out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
// Code size 4 (0x4)
.maxstack 2
.locals init (int V_0) //a
IL_0000: ldc.i4.0
IL_0001: dup
IL_0002: stloc.0
IL_0003: ret
}");
testData = new CompilationTestData();
context.CompileExpression("int b = default;", DkmEvaluationFlags.None, ImmutableArray<Alias>.Empty, out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
// Code size 43 (0x2b)
.maxstack 4
.locals init (int V_0, //a
System.Guid V_1)
IL_0000: ldtoken ""int""
IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)""
IL_000a: ldstr ""b""
IL_000f: ldloca.s V_1
IL_0011: initobj ""System.Guid""
IL_0017: ldloc.1
IL_0018: ldnull
IL_0019: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])""
IL_001e: ldstr ""b""
IL_0023: call ""int Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress<int>(string)""
IL_0028: ldc.i4.0
IL_0029: stind.i4
IL_002a: ret
}");
testData = new CompilationTestData();
context.CompileExpression("default", DkmEvaluationFlags.None, ImmutableArray<Alias>.Empty, out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //a
IL_0000: ldnull
IL_0001: ret
}");
Assert.Equal(SpecialType.System_Object, testData.GetMethodData("<>x.<>m0").Method.ReturnType.SpecialType);
testData = new CompilationTestData();
context.CompileExpression("null", DkmEvaluationFlags.None, ImmutableArray<Alias>.Empty, out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //a
IL_0000: ldnull
IL_0001: ret
}");
});
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册