提交 9d323082 编写于 作者: V VSadov 提交者: vsadov

Made the rest of the codebase build and existing tests to pass.

上级 9a86ecaf
......@@ -403,6 +403,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to Cannot use ref local &apos;{0}&apos; inside an anonymous method, lambda expression, or query expression.
/// </summary>
internal static string ERR_AnonDelegateCantUseLocal {
get {
return ResourceManager.GetString("ERR_AnonDelegateCantUseLocal", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Foreach cannot operate on a &apos;{0}&apos;. Did you intend to invoke the &apos;{0}&apos;?.
/// </summary>
......@@ -736,6 +745,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to Auto-implemented properties cannot return by reference.
/// </summary>
internal static string ERR_AutoPropertyCannotBeRefReturning {
get {
return ResourceManager.GetString("ERR_AutoPropertyCannotBeRefReturning", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Auto-implemented properties inside interfaces cannot have initializers..
/// </summary>
......@@ -898,6 +916,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to Async methods cannot have by reference locals.
/// </summary>
internal static string ERR_BadAsyncLocalType {
get {
return ResourceManager.GetString("ERR_BadAsyncLocalType", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The return type of an async method must be void, Task or Task&lt;T&gt;.
/// </summary>
......@@ -1555,6 +1582,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to Iterators cannot have by reference locals.
/// </summary>
internal static string ERR_BadIteratorLocalType {
get {
return ResourceManager.GetString("ERR_BadIteratorLocalType", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The body of &apos;{0}&apos; cannot be an iterator block because &apos;{1}&apos; is not an iterator interface type.
/// </summary>
......@@ -1564,6 +1600,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to The body of &apos;{0}&apos; cannot be an iterator block because &apos;{0}&apos; returns by reference.
/// </summary>
internal static string ERR_BadIteratorReturnRef {
get {
return ResourceManager.GetString("ERR_BadIteratorReturnRef", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The modifier &apos;{0}&apos; is not valid for this item.
/// </summary>
......@@ -1735,6 +1780,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to Lambda expressions that return by reference cannot be converted to expression trees.
/// </summary>
internal static string ERR_BadRefReturnExpressionTree {
get {
return ResourceManager.GetString("ERR_BadRefReturnExpressionTree", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The parameter modifier &apos;ref&apos; cannot be used with &apos;this&apos; .
/// </summary>
......@@ -2266,6 +2320,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to &apos;{0}&apos; must {2}return by reference to match overridden member &apos;{1}&apos;.
/// </summary>
internal static string ERR_CantChangeRefReturnOnOverride {
get {
return ResourceManager.GetString("ERR_CantChangeRefReturnOnOverride", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &apos;{0}&apos;: return type must be &apos;{2}&apos; to match overridden member &apos;{1}&apos;.
/// </summary>
......@@ -2617,6 +2680,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to &apos;{0}&apos; does not implement interface member &apos;{1}&apos;. &apos;{2}&apos; cannot implement &apos;{1}&apos; because it does not return by {3}.
/// </summary>
internal static string ERR_CloseUnimplementedInterfaceMemberWrongRefReturn {
get {
return ResourceManager.GetString("ERR_CloseUnimplementedInterfaceMemberWrongRefReturn", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &apos;{0}&apos; does not implement interface member &apos;{1}&apos;. &apos;{2}&apos; cannot implement &apos;{1}&apos; because it does not have the matching return type of &apos;{3}&apos;..
/// </summary>
......@@ -4858,6 +4930,24 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to Cannot initialize a by-reference variable with a value.
/// </summary>
internal static string ERR_InitializeByReferenceVariableWithValue {
get {
return ResourceManager.GetString("ERR_InitializeByReferenceVariableWithValue", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cannot initialize a by-value variable with a reference.
/// </summary>
internal static string ERR_InitializeByValueVariableWithReference {
get {
return ResourceManager.GetString("ERR_InitializeByValueVariableWithReference", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The best overloaded method match &apos;{0}&apos; for the collection initializer element cannot be used. Collection initializer &apos;Add&apos; methods cannot have ref or out parameters..
/// </summary>
......@@ -5884,6 +5974,24 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to &apos;{0}&apos; cannot be assigned a reference because it is not a by-reference local.
/// </summary>
internal static string ERR_MustBeRefAssignable {
get {
return ResourceManager.GetString("ERR_MustBeRefAssignable", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Expected a by-reference local.
/// </summary>
internal static string ERR_MustBeRefAssignableLocal {
get {
return ResourceManager.GetString("ERR_MustBeRefAssignableLocal", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to In order for &apos;{0}&apos; to be applicable as a short circuit operator, its declaring type &apos;{1}&apos; must define operator true and operator false.
/// </summary>
......@@ -5893,6 +6001,24 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to By-value returns may only be used in methods that return by value.
/// </summary>
internal static string ERR_MustHaveRefReturn {
get {
return ResourceManager.GetString("ERR_MustHaveRefReturn", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to By-reference returns may only be used in methods that return by reference.
/// </summary>
internal static string ERR_MustNotHaveRefReturn {
get {
return ResourceManager.GetString("ERR_MustNotHaveRefReturn", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Compilation options &apos;{0}&apos; and &apos;{1}&apos; can&apos;t both be specified at the same time..
/// </summary>
......@@ -7414,6 +7540,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to The expression must be of type &apos;{0}&apos; because it is being assigned by reference.
/// </summary>
internal static string ERR_RefAssignmentMustHaveIdentityConversion {
get {
return ResourceManager.GetString("ERR_RefAssignmentMustHaveIdentityConversion", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The type &apos;{2}&apos; must be a reference type in order to use it as parameter &apos;{1}&apos; in the generic type or method &apos;{0}&apos;.
/// </summary>
......@@ -7459,6 +7594,24 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to Properties which return by reference cannot have set accessors.
/// </summary>
internal static string ERR_RefPropertyCannotHaveSetAccessor {
get {
return ResourceManager.GetString("ERR_RefPropertyCannotHaveSetAccessor", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Properties which return by reference must have a get accessor.
/// </summary>
internal static string ERR_RefPropertyMustHaveGetAccessor {
get {
return ResourceManager.GetString("ERR_RefPropertyMustHaveGetAccessor", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to A readonly field cannot be passed ref or out (except in a constructor).
/// </summary>
......@@ -7522,6 +7675,186 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to Cannot return or assign a reference to the result of &apos;{0}&apos; because the argument passed to parameter &apos;{1}&apos; cannot be returned or assigned by reference.
/// </summary>
internal static string ERR_RefReturnCall {
get {
return ResourceManager.GetString("ERR_RefReturnCall", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cannot return or assign a reference to a member ther result of &apos;{0}&apos; because the argument passed to parameter &apos;{1}&apos; cannot be returned or assigned by reference.
/// </summary>
internal static string ERR_RefReturnCall2 {
get {
return ResourceManager.GetString("ERR_RefReturnCall2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &apos;await&apos; cannot be used in an expression containing a call to &apos;{0}&apos; because it returns by reference.
/// </summary>
internal static string ERR_RefReturningCallAndAwait {
get {
return ResourceManager.GetString("ERR_RefReturningCallAndAwait", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to An expression tree lambda may not contain a call to a method, property, or indexer that returns by reference.
/// </summary>
internal static string ERR_RefReturningCallInExpressionTree {
get {
return ResourceManager.GetString("ERR_RefReturningCallInExpressionTree", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cannot return or assign a reference to local &apos;{0}&apos; because it is not a ref local.
/// </summary>
internal static string ERR_RefReturnLocal {
get {
return ResourceManager.GetString("ERR_RefReturnLocal", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cannot return or assign a reference to a member of local &apos;{0}&apos; because it is not a ref local.
/// </summary>
internal static string ERR_RefReturnLocal2 {
get {
return ResourceManager.GetString("ERR_RefReturnLocal2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The argument to a by reference return or assignment must be an assignable variable or a property or call that returns by reference.
/// </summary>
internal static string ERR_RefReturnLvalueExpected {
get {
return ResourceManager.GetString("ERR_RefReturnLvalueExpected", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The argument to a by reference return or assignment must be an assignable variable or a property or call that returns by reference.
/// </summary>
internal static string ERR_RefReturnLvalueExpected2 {
get {
return ResourceManager.GetString("ERR_RefReturnLvalueExpected2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The return expression must be of type &apos;{0}&apos; because this method returns by reference.
/// </summary>
internal static string ERR_RefReturnMustHaveIdentityConversion {
get {
return ResourceManager.GetString("ERR_RefReturnMustHaveIdentityConversion", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cannot return or assign a reference to parameter &apos;{0}&apos; because it is not a ref or out parameter.
/// </summary>
internal static string ERR_RefReturnParameter {
get {
return ResourceManager.GetString("ERR_RefReturnParameter", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cannot return or assign a reference to a member of parameter &apos;{0}&apos; because it is not a ref or out parameter.
/// </summary>
internal static string ERR_RefReturnParameter2 {
get {
return ResourceManager.GetString("ERR_RefReturnParameter2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cannot return the range variable &apos;{0}&apos; by reference.
/// </summary>
internal static string ERR_RefReturnRangeVariable {
get {
return ResourceManager.GetString("ERR_RefReturnRangeVariable", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to A readonly field cannot be returned by reference.
/// </summary>
internal static string ERR_RefReturnReadonly {
get {
return ResourceManager.GetString("ERR_RefReturnReadonly", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Members of readonly field &apos;{0}&apos; cannot be returned by reference.
/// </summary>
internal static string ERR_RefReturnReadonly2 {
get {
return ResourceManager.GetString("ERR_RefReturnReadonly2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cannot return &apos;{0}&apos; by reference because it is read-only.
/// </summary>
internal static string ERR_RefReturnReadonlyLocal {
get {
return ResourceManager.GetString("ERR_RefReturnReadonlyLocal", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cannot return fields of &apos;{0}&apos; by reference because it is a &apos;{1}&apos;.
/// </summary>
internal static string ERR_RefReturnReadonlyLocal2Cause {
get {
return ResourceManager.GetString("ERR_RefReturnReadonlyLocal2Cause", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cannot return &apos;{0}&apos; by reference because it is a &apos;{1}&apos;.
/// </summary>
internal static string ERR_RefReturnReadonlyLocalCause {
get {
return ResourceManager.GetString("ERR_RefReturnReadonlyLocalCause", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to A static readonly field cannot be returned by reference.
/// </summary>
internal static string ERR_RefReturnReadonlyStatic {
get {
return ResourceManager.GetString("ERR_RefReturnReadonlyStatic", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Fields of static readonly field &apos;{0}&apos; cannot be returned by reference.
/// </summary>
internal static string ERR_RefReturnReadonlyStatic2 {
get {
return ResourceManager.GetString("ERR_RefReturnReadonlyStatic2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cannot return or assign a reference to &apos;{0}&apos; because its receiver may not be returned or assigned by reference.
/// </summary>
internal static string ERR_RefReturnReceiver {
get {
return ResourceManager.GetString("ERR_RefReturnReceiver", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The &apos;class&apos; or &apos;struct&apos; constraint must come before any other constraints.
/// </summary>
......@@ -8656,6 +8989,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to Void-returning methods cannot return by reference.
/// </summary>
internal static string ERR_VoidReturningMethodCannotReturnByRef {
get {
return ResourceManager.GetString("ERR_VoidReturningMethodCannotReturnByRef", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &apos;{0}&apos;: a field cannot be both volatile and readonly.
/// </summary>
......
......@@ -954,6 +954,16 @@ private static bool IsIndirectAssignment(BoundAssignmentOperator node)
}
break;
case BoundKind.Call:
Debug.Assert(((BoundCall)lhs).Method.RefKind == RefKind.Ref, "only ref returning methods are assignable");
Debug.Assert(node.RefKind == RefKind.None, "methods cannot be ref-assignable");
return true;
case BoundKind.AssignmentOperator:
Debug.Assert(((BoundAssignmentOperator)lhs).RefKind == RefKind.Ref, "only ref assignments are assignable");
Debug.Assert(node.RefKind == RefKind.None, "assignments cannot be ref-assignable");
return true;
}
Debug.Assert(node.RefKind == RefKind.None, "this is not something that can be assigned indirectly");
......
......@@ -58,7 +58,7 @@ internal class FlowAnalysisPass
Debug.Assert(submissionResultType.SpecialType != SpecialType.System_Void);
var trailingExpression = new BoundDefaultOperator(method.GetNonNullSyntaxNode(), submissionResultType);
var newStatements = block.Statements.Add(new BoundReturnStatement(trailingExpression.Syntax, trailingExpression));
var newStatements = block.Statements.Add(new BoundReturnStatement(trailingExpression.Syntax, RefKind.None, trailingExpression));
block = new BoundBlock(block.Syntax, ImmutableArray<LocalSymbol>.Empty, ImmutableArray<LocalFunctionSymbol>.Empty, newStatements) { WasCompilerGenerated = true };
#if DEBUG
// It should not be necessary to repeat analysis after adding this node, because adding a trailing
......@@ -118,7 +118,7 @@ internal static BoundBlock AppendImplicitReturn(BoundBlock body, MethodSymbol me
? (BoundStatement)BoundYieldBreakStatement.Synthesized(syntax)
: BoundReturnStatement.Synthesized(syntax, RefKind.None, null);
// Implicitly added return for async method does not need sequence points since lowering would add one.
// Implicitly added return for async method does not need sequence points since lowering would add one.
if (syntax.IsKind(SyntaxKind.Block) && !method.IsAsync)
{
var blockSyntax = (BlockSyntax)syntax;
......
......@@ -60,7 +60,7 @@ internal static BoundTypeOrInstanceInitializers RewriteScriptInitializer(Immutab
Debug.Assert(submissionResultType.SpecialType != SpecialType.System_Void);
// Note: The trailing expression was already converted to the submission result type in Binder.BindGlobalStatement.
boundStatements.Add(new BoundReturnStatement(lastStatement.Syntax, trailingExpression));
boundStatements.Add(new BoundReturnStatement(lastStatement.Syntax, RefKind.None, trailingExpression));
hasTrailingExpression = true;
}
else
......
......@@ -700,13 +700,11 @@ private void CheckNewModifier(Symbol symbol, bool isNew, DiagnosticBag diagnosti
// Check for mismatched byref returns and return type. Ignore custom modifiers, because this diagnostic is based on the C# semantics.
if ((overridingProperty.RefKind != RefKind.None) != (overriddenProperty.RefKind != RefKind.None))
// Ignore custom modifiers because this diagnostic is based on the C# semantics.
if (!overridingMemberType.Equals(overriddenMemberType, ignoreCustomModifiersAndArraySizesAndLowerBounds: true, ignoreDynamic: true))
{
diagnostics.Add(ErrorCode.ERR_CantChangeRefReturnOnOverride, overridingMemberLocation, overridingMember, overriddenMember, overridingProperty.RefKind != RefKind.None ? "not " : "");
suppressAccessors = true; //we get really unhelpful errors from the accessor if the ref kind is mismatched
}
else if (!overridingMemberType.Equals(overriddenMemberType, ignoreCustomModifiers: true, ignoreDynamic: true))
else if (!overridingMemberType.Equals(overriddenMemberType, ignoreCustomModifiersAndArraySizesAndLowerBounds: true, ignoreDynamic: true))
{
diagnostics.Add(ErrorCode.ERR_CantChangeTypeOnOverride, overridingMemberLocation, overridingMember, overriddenMember, overriddenMemberType);
suppressAccessors = true; //we get really unhelpful errors from the accessor if the type is mismatched
......
......@@ -409,6 +409,7 @@ internal override BoundBlock CreateBody()
// return;
new BoundReturnStatement(
syntax,
RefKind.None,
null)
{ WasCompilerGenerated = true }))
{ WasCompilerGenerated = true };
......@@ -490,6 +491,7 @@ internal override BoundBlock CreateBody()
Debug.Assert(initializeResult.Type == _returnType);
var returnStatement = new BoundReturnStatement(
syntax,
RefKind.None,
initializeResult)
{ WasCompilerGenerated = true };
......
......@@ -5,6 +5,7 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.Reflection;
using System;
namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
......@@ -104,6 +105,11 @@ public override bool IsVararg
get { return false; }
}
internal override RefKind RefKind
{
get { return RefKind.None; }
}
public override bool IsVirtual
{
get { return false; }
......
......@@ -2443,7 +2443,6 @@ public static BlockSyntax Block(IEnumerable<StatementSyntax> statements)
public static PropertyDeclarationSyntax PropertyDeclaration(
SyntaxList<AttributeListSyntax> attributeLists,
SyntaxTokenList modifiers,
SyntaxToken refKeyword,
TypeSyntax type,
ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier,
SyntaxToken identifier,
......@@ -2452,14 +2451,12 @@ public static BlockSyntax Block(IEnumerable<StatementSyntax> statements)
return SyntaxFactory.PropertyDeclaration(
attributeLists,
modifiers,
refKeyword,
type,
explicitInterfaceSpecifier,
identifier,
accessorList,
default(ArrowExpressionClauseSyntax),
default(EqualsValueClauseSyntax),
default(SyntaxToken));
default(EqualsValueClauseSyntax));
}
public static MethodDeclarationSyntax MethodDeclaration(
......@@ -2537,7 +2534,6 @@ public static BlockSyntax Block(IEnumerable<StatementSyntax> statements)
public static IndexerDeclarationSyntax IndexerDeclaration(
SyntaxList<AttributeListSyntax> attributeLists,
SyntaxTokenList modifiers,
SyntaxToken refKeyword,
TypeSyntax type,
ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier,
BracketedParameterListSyntax parameterList,
......@@ -2546,11 +2542,11 @@ public static BlockSyntax Block(IEnumerable<StatementSyntax> statements)
return SyntaxFactory.IndexerDeclaration(
attributeLists: attributeLists,
modifiers: modifiers,
refKeyword: refKeyword,
type: type,
explicitInterfaceSpecifier: explicitInterfaceSpecifier,
parameterList: parameterList,
accessorList: accessorList);
accessorList: accessorList,
expressionBody: default(ArrowExpressionClauseSyntax));
}
/// <summary>Creates a new UsingDirectiveSyntax instance.</summary>
......
......@@ -1770,13 +1770,12 @@ static void N(out int i)
CompileAndVerify(text, options: TestOptions.UnsafeDebugDll).VerifyIL("Program.Main()", @"
{
// Code size 106 (0x6a)
// Code size 98 (0x62)
.maxstack 3
.locals init (int& V_0, //rl
System.TypedReference V_1, //tr
int& V_2,
int V_3,
pinned int& V_4) //i
pinned int& V_2, //i
int& V_3)
IL_0000: nop
IL_0001: ldsflda ""int Program.field""
IL_0006: dup
......@@ -1786,56 +1785,50 @@ .maxstack 3
IL_000a: ldsflda ""int Program.field""
IL_000f: dup
IL_0010: stloc.0
IL_0011: stloc.2
IL_0012: ldloc.2
IL_0013: ldloc.2
IL_0014: ldind.i4
IL_0015: ldc.i4.1
IL_0016: add
IL_0017: stind.i4
IL_0018: ldsflda ""int Program.field""
IL_0011: dup
IL_0012: ldind.i4
IL_0013: ldc.i4.1
IL_0014: add
IL_0015: stind.i4
IL_0016: ldsflda ""int Program.field""
IL_001b: dup
IL_001c: stloc.0
IL_001d: dup
IL_001e: stloc.0
IL_001f: stloc.2
IL_0020: ldloc.2
IL_0021: ldloc.2
IL_0022: ldind.i4
IL_0023: stloc.3
IL_0024: ldloc.3
IL_0025: ldc.i4.1
IL_0026: add
IL_0027: stind.i4
IL_0028: ldsflda ""int Program.field""
IL_002d: dup
IL_002e: stloc.0
IL_002f: call ""void Program.M(ref int)""
IL_0034: nop
IL_0035: ldsflda ""int Program.field""
IL_003a: dup
IL_003b: stloc.0
IL_003c: call ""void Program.N(out int)""
IL_0041: nop
IL_0042: ldsflda ""int Program.field""
IL_0047: dup
IL_0048: stloc.0
IL_0049: stloc.s V_4
IL_004b: nop
IL_004c: nop
IL_004d: ldc.i4.0
IL_004e: conv.u
IL_004f: stloc.s V_4
IL_0051: ldsflda ""int Program.field""
IL_0056: dup
IL_0057: stloc.0
IL_0058: mkrefany ""int""
IL_005d: stloc.1
IL_005e: ldsflda ""int Program.field""
IL_0063: dup
IL_0064: stloc.0
IL_0065: stloc.2
IL_0066: br.s IL_0068
IL_0068: ldloc.2
IL_0069: ret
IL_001e: ldind.i4
IL_001f: ldc.i4.1
IL_0020: add
IL_0021: stind.i4
IL_0022: ldsflda ""int Program.field""
IL_0027: dup
IL_0028: stloc.0
IL_0029: call ""void Program.M(ref int)""
IL_002e: nop
IL_002f: ldsflda ""int Program.field""
IL_0034: dup
IL_0035: stloc.0
IL_0036: call ""void Program.N(out int)""
IL_003b: nop
IL_003c: ldsflda ""int Program.field""
IL_0041: dup
IL_0042: stloc.0
IL_0043: stloc.2
IL_0044: nop
IL_0045: nop
IL_0046: ldc.i4.0
IL_0047: conv.u
IL_0048: stloc.2
IL_0049: ldsflda ""int Program.field""
IL_004e: dup
IL_004f: stloc.0
IL_0050: mkrefany ""int""
IL_0055: stloc.1
IL_0056: ldsflda ""int Program.field""
IL_005b: dup
IL_005c: stloc.0
IL_005d: stloc.3
IL_005e: br.s IL_0060
IL_0060: ldloc.3
IL_0061: ret
}");
}
......@@ -1872,12 +1865,11 @@ static unsafe void Main()
CompileAndVerify(text, options: TestOptions.UnsafeDebugDll).VerifyIL("Program.Main()", @"
{
// Code size 53 (0x35)
// Code size 51 (0x33)
.maxstack 3
.locals init (int& V_0, //rl
System.TypedReference V_1, //tr
int V_2,
pinned int& V_3) //i
pinned int& V_2) //i
IL_0000: nop
IL_0001: ldsflda ""int Program.field""
IL_0006: stloc.0
......@@ -1893,28 +1885,26 @@ .maxstack 3
IL_0010: ldloc.0
IL_0011: ldloc.0
IL_0012: ldind.i4
IL_0013: stloc.2
IL_0014: ldloc.2
IL_0015: ldc.i4.1
IL_0016: add
IL_0017: stind.i4
IL_0018: ldloc.0
IL_0019: call ""void Program.M(ref int)""
IL_001e: nop
IL_001f: ldloc.0
IL_0020: call ""void Program.N(out int)""
IL_0025: nop
IL_0026: ldloc.0
IL_0027: stloc.3
IL_0028: nop
IL_0029: nop
IL_002a: ldc.i4.0
IL_002b: conv.u
IL_002c: stloc.3
IL_002d: ldloc.0
IL_002e: mkrefany ""int""
IL_0033: stloc.1
IL_0034: ret
IL_0013: ldc.i4.1
IL_0014: add
IL_0015: stind.i4
IL_0016: ldloc.0
IL_0017: call ""void Program.M(ref int)""
IL_001c: nop
IL_001d: ldloc.0
IL_001e: call ""void Program.N(out int)""
IL_0023: nop
IL_0024: ldloc.0
IL_0025: stloc.2
IL_0026: nop
IL_0027: nop
IL_0028: ldc.i4.0
IL_0029: conv.u
IL_002a: stloc.2
IL_002b: ldloc.0
IL_002c: mkrefany ""int""
IL_0031: stloc.1
IL_0032: ret
}");
}
......
......@@ -1426,7 +1426,7 @@ .maxstack 4
IL_0022: conv.i8
IL_0023: stloc.1
IL_0024: ldloc.0
IL_0025: dup
IL_0025: ldloc.0
IL_0026: callvirt ""ref int Program.P.get""
IL_002b: ldind.i4
IL_002c: callvirt ""void Program.N(int)""
......@@ -1451,13 +1451,13 @@ .maxstack 4
IL_0053: add
IL_0054: stloc.1
IL_0055: ldloc.0
IL_0056: dup
IL_0056: ldloc.0
IL_0057: ldc.i4.0
IL_0058: callvirt ""ref int Program.this[int].get""
IL_005d: ldind.i4
IL_005e: callvirt ""void Program.N(int)""
IL_0063: ldloc.0
IL_0064: dup
IL_0064: ldloc.0
IL_0065: ldflda ""int Program.field""
IL_006a: callvirt ""ref int Program.M(ref int)""
IL_006f: ldind.i4
......@@ -1465,14 +1465,14 @@ .maxstack 4
IL_0071: add
IL_0072: add
IL_0073: ldloc.0
IL_0074: dup
IL_0074: ldloc.0
IL_0075: ldflda ""int Program.field""
IL_007a: callvirt ""ref int Program.M(ref int)""
IL_007f: call ""string int.ToString()""
IL_0084: pop
IL_0085: ldloc.1
IL_0086: ldloc.0
IL_0087: dup
IL_0087: ldloc.0
IL_0088: ldflda ""int Program.field""
IL_008d: callvirt ""ref int Program.M(ref int)""
IL_0092: ldind.i4
......@@ -1480,8 +1480,8 @@ .maxstack 4
IL_0094: add
IL_0095: stloc.1
IL_0096: ldloc.0
IL_0097: dup
IL_0098: dup
IL_0097: ldloc.0
IL_0098: ldloc.0
IL_0099: ldflda ""int Program.field""
IL_009e: callvirt ""ref int Program.M(ref int)""
IL_00a3: ldind.i4
......
......@@ -2867,9 +2867,15 @@ public static void Main()
}
}";
CreateCompilationWithMscorlib(source).VerifyDiagnostics(
// (6,51): error CS0133: The expression being assigned to 'b' must be constant
// const Func<int> a = () => { const int b = a(); return 1; };
Diagnostic(ErrorCode.ERR_NotConstantExpression, "a()").WithArguments("b").WithLocation(6, 51)
// (6,51): error CS0133: The expression being assigned to 'b' must be constant
// const Func<int> a = () => { const int b = a(); return 1; };
Diagnostic(ErrorCode.ERR_NotConstantExpression, "a()").WithArguments("b").WithLocation(6, 51),
// (6,51): error CS0110: The evaluation of the constant value for 'a' involves a circular definition
// const Func<int> a = () => { const int b = a(); return 1; };
Diagnostic(ErrorCode.ERR_CircConstValue, "a").WithArguments("a").WithLocation(6, 51),
// (6,51): error CS0133: The expression being assigned to 'b' must be constant
// const Func<int> a = () => { const int b = a(); return 1; };
Diagnostic(ErrorCode.ERR_NotConstantExpression, "a()").WithArguments("b").WithLocation(6, 51)
);
}
......
......@@ -1115,6 +1115,8 @@ static void M()
MD(() => ref i);
MD(() => { return ref i; });
MD(delegate { return ref i; });
}
}
";
CreateCompilationWithMscorlib(text).VerifyDiagnostics();
......
......@@ -2897,8 +2897,6 @@ class C
// ref int P { get { return ref field; } set { } }
Diagnostic(ErrorCode.ERR_RefPropertyCannotHaveSetAccessor, "set").WithArguments("C.P.set").WithLocation(5, 47));
}
}
[Fact, WorkItem(4696, "https://github.com/dotnet/roslyn/issues/4696")]
public void LangVersioAndReadonlyAutoProperty()
......
......@@ -947,7 +947,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
End If
' paramInfo(0) contains information about return "parameter"
Debug.Assert(Not paramInfo(0).IsByRef)
Dim returnParam = PEParameterSymbol.Create(moduleSymbol, Me, 0, paramInfo(0), isBad)
If mrEx IsNot Nothing OrElse hasBadParameter OrElse isBad Then
......
......@@ -2088,9 +2088,9 @@ lReportErrorOnTwoTokens:
fakeTypeParameters,
fakeParamsBuilder.ToImmutableAndFree(),
returnsByRef:=False,
retType.InternalSubstituteTypeParameters(replaceMethodTypeParametersWithFakeTypeParameters).AsTypeSymbolOnly(),
ImmutableArray(Of CustomModifier).Empty,
ImmutableArray(Of MethodSymbol).Empty,
returnType:=retType.InternalSubstituteTypeParameters(replaceMethodTypeParametersWithFakeTypeParameters).AsTypeSymbolOnly(),
returnTypeCustomModifiers:=ImmutableArray(Of CustomModifier).Empty,
explicitInterfaceImplementations:=ImmutableArray(Of MethodSymbol).Empty,
isOverrides:=True))
End If
......
......@@ -110,7 +110,14 @@ protected override ImmutableArray<LocalSymbol> BuildLocals()
var kind = declaration.IsConst ? LocalDeclarationKind.Constant : LocalDeclarationKind.RegularVariable;
foreach (var variable in declaration.Declaration.Variables)
{
var local = SourceLocalSymbol.MakeLocal(_containingMethod, this, declaration.Declaration.Type, variable.Identifier, kind, variable.Initializer);
var local = SourceLocalSymbol.MakeLocal(
_containingMethod,
this,
declaration.RefKeyword.Kind() == SyntaxKind.RefKeyword? RefKind.Ref: RefKind.None,
declaration.Declaration.Type,
variable.Identifier,
kind,
variable.Initializer);
builder.Add(local);
}
}
......
......@@ -308,7 +308,7 @@ private static string GetNextMethodName(ArrayBuilder<MethodSymbol> builder)
var aliasMethod = this.CreateMethod(container, methodName, syntax, (method, diags) =>
{
var expression = new BoundLocal(syntax, local, constantValueOpt: null, type: local.Type);
return new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
return new BoundReturnStatement(syntax, RefKind.None, expression) { WasCompilerGenerated = true };
});
var flags = local.IsWritable ? DkmClrCompilationResultFlags.None : DkmClrCompilationResultFlags.ReadOnlyResult;
localBuilder.Add(MakeLocalAndMethod(local, aliasMethod, flags));
......@@ -497,7 +497,7 @@ private EEMethodSymbol GetLocalMethod(EENamedTypeSymbol container, string method
{
var local = method.LocalsForBinding[localIndex];
var expression = new BoundLocal(syntax, local, constantValueOpt: local.GetConstantValue(null, null, diagnostics), type: local.Type);
return new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
return new BoundReturnStatement(syntax, RefKind.None, expression) { WasCompilerGenerated = true };
});
}
......@@ -508,7 +508,7 @@ private EEMethodSymbol GetParameterMethod(EENamedTypeSymbol container, string me
{
var parameter = method.Parameters[parameterIndex];
var expression = new BoundParameter(syntax, parameter);
return new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
return new BoundReturnStatement(syntax, RefKind.None, expression) { WasCompilerGenerated = true };
});
}
......@@ -518,7 +518,7 @@ private EEMethodSymbol GetThisMethod(EENamedTypeSymbol container, string methodN
return this.CreateMethod(container, methodName, syntax, (method, diagnostics) =>
{
var expression = new BoundThisReference(syntax, GetNonDisplayClassContainer(container.SubstitutedSourceType));
return new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
return new BoundReturnStatement(syntax, RefKind.None, expression) { WasCompilerGenerated = true };
});
}
......@@ -529,7 +529,7 @@ private EEMethodSymbol GetTypeVariablesMethod(EENamedTypeSymbol container, strin
{
var type = method.TypeMap.SubstituteNamedType(typeVariablesType);
var expression = new BoundObjectCreationExpression(syntax, type.InstanceConstructors[0]);
var statement = new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
var statement = new BoundReturnStatement(syntax, RefKind.None, expression) { WasCompilerGenerated = true };
return statement;
});
}
......@@ -570,6 +570,7 @@ private static BoundStatement BindExpression(Binder binder, ExpressionSyntax syn
syntax,
diagnostics,
expression,
RefKind.None,
binder.Compilation.GetSpecialType(SpecialType.System_Object));
if (diagnostics.HasAnyErrors())
{
......@@ -595,7 +596,7 @@ private static BoundStatement BindExpression(Binder binder, ExpressionSyntax syn
}
resultProperties = expression.ExpressionSymbol.GetResultProperties(flags, expression.ConstantValue != null);
return new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
return new BoundReturnStatement(syntax, RefKind.None, expression) { WasCompilerGenerated = true };
}
private static BoundStatement BindStatement(Binder binder, StatementSyntax syntax, DiagnosticBag diagnostics, out ResultProperties properties)
......
......@@ -29,7 +29,7 @@ internal override void GenerateMethodBody(TypeCompilationState compilationState,
noLocalFunctions,
ImmutableArray.Create<BoundStatement>(
new BoundExpressionStatement(syntax, initializerInvocation),
new BoundReturnStatement(syntax, null))));
new BoundReturnStatement(syntax, RefKind.None, null))));
}
}
}
......@@ -260,6 +260,11 @@ public override bool IsVararg
get { return this.SubstitutedSourceMethod.IsVararg; }
}
internal override RefKind RefKind
{
get { return this.SubstitutedSourceMethod.RefKind; }
}
public override bool ReturnsVoid
{
get { return this.ReturnType.SpecialType == SpecialType.System_Void; }
......@@ -427,185 +432,187 @@ internal override void GenerateMethodBody(TypeCompilationState compilationState,
try
{
var declaredLocals = PooledHashSet<LocalSymbol>.GetInstance();
try
{
// Rewrite local declaration statement.
body = (BoundStatement)LocalDeclarationRewriter.Rewrite(compilation, _container, declaredLocals, body);
// Verify local declaration names.
foreach (var local in declaredLocals)
var declaredLocals = PooledHashSet<LocalSymbol>.GetInstance();
try
{
Debug.Assert(local.Locations.Length > 0);
var name = local.Name;
if (name.StartsWith("$", StringComparison.Ordinal))
// Rewrite local declaration statement.
body = (BoundStatement)LocalDeclarationRewriter.Rewrite(compilation, _container, declaredLocals, body);
// Verify local declaration names.
foreach (var local in declaredLocals)
{
diagnostics.Add(ErrorCode.ERR_UnexpectedCharacter, local.Locations[0], name[0]);
return;
Debug.Assert(local.Locations.Length > 0);
var name = local.Name;
if (name.StartsWith("$", StringComparison.Ordinal))
{
diagnostics.Add(ErrorCode.ERR_UnexpectedCharacter, local.Locations[0], name[0]);
return;
}
}
}
// Rewrite references to placeholder "locals".
body = (BoundStatement)PlaceholderLocalRewriter.Rewrite(compilation, _container, declaredLocals, body, diagnostics);
// Rewrite references to placeholder "locals".
body = (BoundStatement)PlaceholderLocalRewriter.Rewrite(compilation, _container, declaredLocals, body, diagnostics);
if (diagnostics.HasAnyErrors())
if (diagnostics.HasAnyErrors())
{
return;
}
}
finally
{
return;
declaredLocals.Free();
}
}
finally
{
declaredLocals.Free();
}
var syntax = body.Syntax;
var statementsBuilder = ArrayBuilder<BoundStatement>.GetInstance();
statementsBuilder.Add(body);
// Insert an implicit return statement if necessary.
if (body.Kind != BoundKind.ReturnStatement)
{
statementsBuilder.Add(new BoundReturnStatement(syntax, expressionOpt: null));
}
var syntax = body.Syntax;
var statementsBuilder = ArrayBuilder<BoundStatement>.GetInstance();
statementsBuilder.Add(body);
// Insert an implicit return statement if necessary.
if (body.Kind != BoundKind.ReturnStatement)
{
statementsBuilder.Add(new BoundReturnStatement(syntax, RefKind.None, expressionOpt: null));
}
var localsBuilder = ArrayBuilder<LocalSymbol>.GetInstance();
var localsSet = PooledHashSet<LocalSymbol>.GetInstance();
foreach (var local in this.LocalsForBinding)
{
Debug.Assert(!localsSet.Contains(local));
localsBuilder.Add(local);
localsSet.Add(local);
}
foreach (var local in this.Locals)
{
if (!localsSet.Contains(local))
var localsBuilder = ArrayBuilder<LocalSymbol>.GetInstance();
var localsSet = PooledHashSet<LocalSymbol>.GetInstance();
foreach (var local in this.LocalsForBinding)
{
Debug.Assert(!localsSet.Contains(local));
localsBuilder.Add(local);
localsSet.Add(local);
}
}
localsSet.Free();
foreach (var local in this.Locals)
{
if (!localsSet.Contains(local))
{
Debug.Assert(!localsSet.Contains(local));
localsBuilder.Add(local);
localsSet.Add(local);
}
}
localsSet.Free();
body = new BoundBlock(syntax, localsBuilder.ToImmutableAndFree(), ImmutableArray<LocalFunctionSymbol>.Empty, statementsBuilder.ToImmutableAndFree()) { WasCompilerGenerated = true };
Debug.Assert(!diagnostics.HasAnyErrors());
Debug.Assert(!body.HasErrors);
Debug.Assert(!diagnostics.HasAnyErrors());
Debug.Assert(!body.HasErrors);
bool sawLambdas;
bool sawLambdas;
bool sawLocalFunctions;
bool sawAwaitInExceptionHandler;
body = LocalRewriter.Rewrite(
compilation: this.DeclaringCompilation,
method: this,
methodOrdinal: _methodOrdinal,
containingType: _container,
statement: body,
compilationState: compilationState,
previousSubmissionFields: null,
allowOmissionOfConditionalCalls: false,
diagnostics: diagnostics,
sawLambdas: out sawLambdas,
bool sawAwaitInExceptionHandler;
body = LocalRewriter.Rewrite(
compilation: this.DeclaringCompilation,
method: this,
methodOrdinal: _methodOrdinal,
containingType: _container,
statement: body,
compilationState: compilationState,
previousSubmissionFields: null,
allowOmissionOfConditionalCalls: false,
diagnostics: diagnostics,
sawLambdas: out sawLambdas,
sawLocalFunctions: out sawLocalFunctions,
sawAwaitInExceptionHandler: out sawAwaitInExceptionHandler);
sawAwaitInExceptionHandler: out sawAwaitInExceptionHandler);
Debug.Assert(!sawAwaitInExceptionHandler);
Debug.Assert(!sawAwaitInExceptionHandler);
if (body.HasErrors)
{
return;
}
if (body.HasErrors)
{
return;
}
// Variables may have been captured by lambdas in the original method
// or in the expression, and we need to preserve the existing values of
// those variables in the expression. This requires rewriting the variables
// in the expression based on the closure classes from both the original
// method and the expression, and generating a preamble that copies
// values into the expression closure classes.
//
// Consider the original method:
// static void M()
// {
// int x, y, z;
// ...
// F(() => x + y);
// }
// and the expression in the EE: "F(() => x + z)".
//
// The expression is first rewritten using the closure class and local <1>
// from the original method: F(() => <1>.x + z)
// Then lambda rewriting introduces a new closure class that includes
// the locals <1> and z, and a corresponding local <2>: F(() => <2>.<1>.x + <2>.z)
// And a preamble is added to initialize the fields of <2>:
// <2> = new <>c__DisplayClass0();
// <2>.<1> = <1>;
// <2>.z = z;
// Rewrite "this" and "base" references to parameter in this method.
// Rewrite variables within body to reference existing display classes.
body = (BoundStatement)CapturedVariableRewriter.Rewrite(
this.SubstitutedSourceMethod.IsStatic ? null : _parameters[0],
compilation.Conversions,
_displayClassVariables,
body,
diagnostics);
if (body.HasErrors)
{
Debug.Assert(false, "Please add a test case capturing whatever caused this assert.");
return;
}
// Variables may have been captured by lambdas in the original method
// or in the expression, and we need to preserve the existing values of
// those variables in the expression. This requires rewriting the variables
// in the expression based on the closure classes from both the original
// method and the expression, and generating a preamble that copies
// values into the expression closure classes.
//
// Consider the original method:
// static void M()
// {
// int x, y, z;
// ...
// F(() => x + y);
// }
// and the expression in the EE: "F(() => x + z)".
//
// The expression is first rewritten using the closure class and local <1>
// from the original method: F(() => <1>.x + z)
// Then lambda rewriting introduces a new closure class that includes
// the locals <1> and z, and a corresponding local <2>: F(() => <2>.<1>.x + <2>.z)
// And a preamble is added to initialize the fields of <2>:
// <2> = new <>c__DisplayClass0();
// <2>.<1> = <1>;
// <2>.z = z;
// Rewrite "this" and "base" references to parameter in this method.
// Rewrite variables within body to reference existing display classes.
body = (BoundStatement)CapturedVariableRewriter.Rewrite(
this.SubstitutedSourceMethod.IsStatic ? null : _parameters[0],
compilation.Conversions,
_displayClassVariables,
body,
diagnostics);
if (body.HasErrors)
{
Debug.Assert(false, "Please add a test case capturing whatever caused this assert.");
return;
}
if (diagnostics.HasAnyErrors())
{
return;
}
if (diagnostics.HasAnyErrors())
{
return;
}
if (sawLambdas || sawLocalFunctions)
{
var closureDebugInfoBuilder = ArrayBuilder<ClosureDebugInfo>.GetInstance();
var lambdaDebugInfoBuilder = ArrayBuilder<LambdaDebugInfo>.GetInstance();
body = LambdaRewriter.Rewrite(
loweredBody: body,
thisType: this.SubstitutedSourceMethod.ContainingType,
thisParameter: _thisParameter,
method: this,
methodOrdinal: _methodOrdinal,
{
var closureDebugInfoBuilder = ArrayBuilder<ClosureDebugInfo>.GetInstance();
var lambdaDebugInfoBuilder = ArrayBuilder<LambdaDebugInfo>.GetInstance();
body = LambdaRewriter.Rewrite(
loweredBody: body,
thisType: this.SubstitutedSourceMethod.ContainingType,
thisParameter: _thisParameter,
method: this,
methodOrdinal: _methodOrdinal,
substitutedSourceMethod: this.SubstitutedSourceMethod.OriginalDefinition,
closureDebugInfoBuilder: closureDebugInfoBuilder,
lambdaDebugInfoBuilder: lambdaDebugInfoBuilder,
slotAllocatorOpt: null,
compilationState: compilationState,
diagnostics: diagnostics,
assignLocals: true);
// we don't need this information:
closureDebugInfoBuilder.Free();
lambdaDebugInfoBuilder.Free();
}
closureDebugInfoBuilder: closureDebugInfoBuilder,
lambdaDebugInfoBuilder: lambdaDebugInfoBuilder,
slotAllocatorOpt: null,
compilationState: compilationState,
diagnostics: diagnostics,
assignLocals: true);
// we don't need this information:
closureDebugInfoBuilder.Free();
lambdaDebugInfoBuilder.Free();
}
// Insert locals from the original method,
// followed by any new locals.
var block = (BoundBlock)body;
var localBuilder = ArrayBuilder<LocalSymbol>.GetInstance();
foreach (var local in this.Locals)
{
Debug.Assert(!(local is EELocalSymbol) || (((EELocalSymbol)local).Ordinal == localBuilder.Count));
localBuilder.Add(local);
}
foreach (var local in block.Locals)
{
var oldLocal = local as EELocalSymbol;
if (oldLocal != null)
// Insert locals from the original method,
// followed by any new locals.
var block = (BoundBlock)body;
var localBuilder = ArrayBuilder<LocalSymbol>.GetInstance();
foreach (var local in this.Locals)
{
Debug.Assert(localBuilder[oldLocal.Ordinal] == oldLocal);
continue;
Debug.Assert(!(local is EELocalSymbol) || (((EELocalSymbol)local).Ordinal == localBuilder.Count));
localBuilder.Add(local);
}
foreach (var local in block.Locals)
{
var oldLocal = local as EELocalSymbol;
if (oldLocal != null)
{
Debug.Assert(localBuilder[oldLocal.Ordinal] == oldLocal);
continue;
}
localBuilder.Add(local);
}
localBuilder.Add(local);
}
body = block.Update(localBuilder.ToImmutableAndFree(), block.LocalFunctions, block.Statements);
TypeParameterChecker.Check(body, _allTypeParameters);
compilationState.AddSynthesizedMethod(this, body);
}
TypeParameterChecker.Check(body, _allTypeParameters);
compilationState.AddSynthesizedMethod(this, body);
}
catch (BoundTreeVisitor.CancelledByStackGuardException ex)
{
ex.AddAnError(diagnostics);
......
......@@ -65,7 +65,9 @@ internal override BoundExpression GetAddress(BoundPseudoVariable variable)
// so the return type of GetVariableAddress(Of T)(name As String)
// is an error type. Since the method is only used for emit, an
// updated placeholder method is used instead.
Debug.Assert(method.ReturnType.TypeKind == TypeKind.Error); // If byref return types are supported in the future, use method as is.
// TODO: refs are available
// Debug.Assert(method.ReturnType.TypeKind == TypeKind.Error); // If byref return types are supported in the future, use method as is.
method = new PlaceholderMethodSymbol(
method.ContainingType,
method.Name,
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
......@@ -142,6 +143,11 @@ public override bool ReturnsVoid
get { return false; }
}
internal override RefKind RefKind
{
get { return RefKind.None; }
}
public override TypeSymbol ReturnType
{
get { return _returnType; }
......
......@@ -118,6 +118,11 @@ public override bool ReturnsVoid
get { return true; }
}
internal override RefKind RefKind
{
get { return RefKind.None; }
}
public override TypeSymbol ReturnType
{
get { throw ExceptionUtilities.Unreachable; }
......
......@@ -68,7 +68,7 @@ internal static class SyntaxHelpers
var targetSyntax = SyntaxHelpers.ParseDebuggerExpressionInternal(SourceText.From(target), consumeFullText: true);
Debug.Assert(!targetSyntax.GetDiagnostics().Any(), "The target of an assignment should never contain Diagnostics if we're being allowed to assign to it in the debugger.");
var assignment = InternalSyntax.SyntaxFactory.AssignmentExpression(
var assignment = InternalSyntax.SyntaxFactory.ValueAssignmentExpression(
SyntaxKind.SimpleAssignmentExpression,
targetSyntax,
InternalSyntax.SyntaxFactory.Token(SyntaxKind.EqualsToken),
......
......@@ -211,30 +211,29 @@ .maxstack 1
IL_0000: ldnull
IL_0001: ret
}");
// Check return type is from runtime assembly.
var assemblyReference = AssemblyMetadata.CreateFromImage(result.Assembly).GetReference();
var compilation = CSharpCompilation.Create(
assemblyName: ExpressionCompilerUtilities.GenerateUniqueName(),
references: runtimeReferences.Concat(ImmutableArray.Create<MetadataReference>(assemblyReference)));
var assembly = ImmutableArray.CreateRange(result.Assembly);
using (var metadata = ModuleMetadata.CreateFromImage(ImmutableArray.CreateRange(assembly)))
{
var reader = metadata.MetadataReader;
var typeDef = reader.GetTypeDef("<>x");
var methodHandle = reader.GetMethodDefHandle(typeDef, "<>m0");
var module = (PEModuleSymbol)compilation.GetMember("<>x").ContainingModule;
var metadataDecoder = new MetadataDecoder(module);
SignatureHeader signatureHeader;
BadImageFormatException metadataException;
var parameters = metadataDecoder.GetSignatureForMethod(methodHandle, out signatureHeader, out metadataException);
Assert.Equal(parameters.Length, 5);
var actualReturnType = parameters[0].Type;
Assert.Equal(actualReturnType.TypeKind, TypeKind.Class); // not error
var expectedReturnType = compilation.GetMember("Windows.Storage.StorageFolder");
Assert.Equal(expectedReturnType, actualReturnType);
Assert.Equal(storageAssemblyName, actualReturnType.ContainingAssembly.Name);
}
});
// Check return type is from runtime assembly.
var assemblyReference = AssemblyMetadata.CreateFromImage(result.Assembly).GetReference();
var compilation = CSharpCompilation.Create(
assemblyName: ExpressionCompilerUtilities.GenerateUniqueName(),
references: runtimeReferences.Concat(ImmutableArray.Create<MetadataReference>(assemblyReference)));
var assembly = ImmutableArray.CreateRange(result.Assembly);
using (var metadata = ModuleMetadata.CreateFromImage(ImmutableArray.CreateRange(assembly)))
{
var reader = metadata.MetadataReader;
var typeDef = reader.GetTypeDef("<>x");
var methodHandle = reader.GetMethodDefHandle(typeDef, "<>m0");
var module = (PEModuleSymbol)compilation.GetMember("<>x").ContainingModule;
var metadataDecoder = new MetadataDecoder(module);
SignatureHeader signatureHeader;
BadImageFormatException metadataException;
var parameters = metadataDecoder.GetSignatureForMethod(methodHandle, out signatureHeader, out metadataException, allowByRefReturn: true);
Assert.Equal(parameters.Length, 5);
var actualReturnType = parameters[0].Type;
Assert.Equal(actualReturnType.TypeKind, TypeKind.Class); // not error
var expectedReturnType = compilation.GetMember("Windows.Storage.StorageFolder");
Assert.Equal(expectedReturnType, actualReturnType);
Assert.Equal(storageAssemblyName, actualReturnType.ContainingAssembly.Name);
}
}
/// <summary>
......
......@@ -244,6 +244,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
End Get
End Property
Public Overrides ReadOnly Property ReturnsByRef As Boolean
Get
Return False
End Get
End Property
Public Overrides ReadOnly Property IsSub As Boolean
Get
Return ReturnType.SpecialType = SpecialType.System_Void
......
......@@ -83,7 +83,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
' so the return type of GetVariableAddress(Of T)(name As String)
' is an error type. Since the method is only used for emit, an
' updated placeholder method is used instead.
Debug.Assert(method.ReturnType.TypeKind = TypeKind.Error) ' If byref return types are supported in the future, use method as is.
' TODO: refs are available
'Debug.Assert(method.ReturnType.TypeKind = TypeKind.Error) ' If byref return types are supported in the future, use method as is.
method = New PlaceholderMethodSymbol(
method.ContainingType,
method.Name,
......
......@@ -246,7 +246,7 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
.WithLeadingTrivia(lambda.Parameter.GetLeadingTrivia())
.WithTrailingTrivia(lambda.Parameter.GetTrailingTrivia());
return SyntaxFactory.ParenthesizedLambdaExpression(lambda.AsyncKeyword, emptyParameterList, lambda.ArrowToken, lambda.Body);
return SyntaxFactory.ParenthesizedLambdaExpression(lambda.AsyncKeyword, emptyParameterList, lambda.ArrowToken, lambda.RefKeyword, lambda.Body);
}
}
......
......@@ -103,6 +103,7 @@ private static SyntaxNode ConvertParenthesizedLambdaToAsync(ParenthesizedLambdaE
SyntaxFactory.Token(SyntaxKind.AsyncKeyword),
parenthesizedLambda.ParameterList,
parenthesizedLambda.ArrowToken,
parenthesizedLambda.RefKeyword,
parenthesizedLambda.Body)
.WithTriviaFrom(parenthesizedLambda)
.WithAdditionalAnnotations(Formatter.Annotation);
......@@ -114,6 +115,7 @@ private static SyntaxNode ConvertSimpleLambdaToAsync(SimpleLambdaExpressionSynta
SyntaxFactory.Token(SyntaxKind.AsyncKeyword),
simpleLambda.Parameter,
simpleLambda.ArrowToken,
simpleLambda.RefKeyword,
simpleLambda.Body)
.WithTriviaFrom(simpleLambda)
.WithAdditionalAnnotations(Formatter.Annotation);
......
......@@ -41,10 +41,10 @@ private bool IsReference(SimpleNameSyntax name)
&& symbol.Equals(_localSymbol);
}
public override SyntaxNode VisitAssignmentExpression(AssignmentExpressionSyntax node)
public override SyntaxNode VisitValueAssignmentExpression(ValueAssignmentExpressionSyntax node)
{
// Note - leave this as SyntaxNode for now, we might have already re-written it
var newNode = base.VisitAssignmentExpression(node);
var newNode = base.VisitValueAssignmentExpression(node);
if (newNode.Kind() == SyntaxKind.SimpleAssignmentExpression)
{
......
......@@ -119,6 +119,7 @@ public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatem
return
SyntaxFactory.LocalDeclarationStatement(
node.Modifiers,
node.RefKeyword,
SyntaxFactory.VariableDeclaration(
node.Declaration.Type,
SyntaxFactory.SeparatedList(list)),
......
......@@ -380,6 +380,7 @@ private OperationStatus CheckActiveStatements(IEnumerable<StatementSyntax> state
yield return
SyntaxFactory.LocalDeclarationStatement(
declarationStatement.Modifiers,
declarationStatement.RefKeyword,
SyntaxFactory.VariableDeclaration(
declarationStatement.Declaration.Type,
SyntaxFactory.SeparatedList(list)),
......@@ -456,7 +457,7 @@ private static SyntaxToken GetIdentifierTokenAndTrivia(SyntaxToken identifier, T
private ExpressionSyntax CreateAssignmentExpression(SyntaxToken identifier, ExpressionSyntax rvalue)
{
return SyntaxFactory.AssignmentExpression(
return SyntaxFactory.ValueAssignmentExpression(
SyntaxKind.SimpleAssignmentExpression,
SyntaxFactory.IdentifierName(identifier),
rvalue);
......
......@@ -137,7 +137,7 @@ protected override void AddDescriptionForProperty(IPropertySymbol symbol)
private async Task<IEnumerable<SymbolDisplayPart>> GetInitializerSourcePartsAsync(IFieldSymbol symbol)
{
EqualsValueClauseSyntax initializer = null;
EqualsClauseSyntax initializer = null;
var variableDeclarator = await this.GetFirstDeclaration<VariableDeclaratorSyntax>(symbol).ConfigureAwait(false);
if (variableDeclarator != null)
......@@ -198,7 +198,7 @@ private async Task<IEnumerable<SymbolDisplayPart>> GetInitializerSourcePartsAsyn
return null;
}
private async Task<IEnumerable<SymbolDisplayPart>> GetInitializerSourcePartsAsync(EqualsValueClauseSyntax equalsValue)
private async Task<IEnumerable<SymbolDisplayPart>> GetInitializerSourcePartsAsync(EqualsClauseSyntax equalsValue)
{
if (equalsValue != null && equalsValue.Value != null)
{
......
......@@ -16,6 +16,7 @@ internal class IndexerDeclarationOrganizer : AbstractSyntaxNodeOrganizer<Indexer
{
return syntax.Update(syntax.AttributeLists,
ModifiersOrganizer.Organize(syntax.Modifiers),
syntax.RefKeyword,
syntax.Type,
syntax.ExplicitInterfaceSpecifier,
syntax.ThisKeyword,
......
......@@ -16,6 +16,7 @@ internal class MethodDeclarationOrganizer : AbstractSyntaxNodeOrganizer<MethodDe
{
return syntax.Update(syntax.AttributeLists,
ModifiersOrganizer.Organize(syntax.Modifiers),
syntax.RefKeyword,
syntax.ReturnType,
syntax.ExplicitInterfaceSpecifier,
syntax.Identifier,
......
......@@ -234,7 +234,7 @@ public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node)
// But also add a simplification annotation so we can remove the parens if possible.
var argumentExpression = currentInvocation.ArgumentList.Arguments[0].Expression.Parenthesize();
var expression = SyntaxFactory.AssignmentExpression(
var expression = SyntaxFactory.ValueAssignmentExpression(
SyntaxKind.SimpleAssignmentExpression, currentInvocation.Expression, argumentExpression);
return expression.Parenthesize();
......
......@@ -170,6 +170,14 @@ public bool ReturnsVoid
}
}
public bool ReturnsByRef
{
get
{
return _symbol.ReturnsByRef;
}
}
public ITypeSymbol ReturnType
{
get
......
......@@ -67,6 +67,14 @@ public bool IsWriteOnly
}
}
public bool ReturnsByRef
{
get
{
return _symbol.ReturnsByRef;
}
}
public IPropertySymbol OverriddenProperty
{
get
......
......@@ -49,6 +49,7 @@ public void UpdateNode()
var newMethod = method.Update(
method.AttributeLists,
method.Modifiers,
method.RefKeyword,
method.ReturnType,
method.ExplicitInterfaceSpecifier,
SyntaxFactory.Identifier("NewMethodName"),
......
......@@ -221,6 +221,11 @@ namespace My
int minInt32Value = -2147483648;
int minInt64Value = -9223372036854775808L;
ref string stringRef;
stringRef = ref System.String.Empty;
ref string stringRef1 = ref System.String.Empty;
bool @bool;
byte @byte;
char @char = 'c', \u0066 = '\u0066', hexchar = '\x0130', hexchar2 = (char)0xBAD;
......
......@@ -139,6 +139,7 @@ private SyntaxTokenList GetParameterModifiers(RefKind refKind)
return SyntaxFactory.MethodDeclaration(
default(SyntaxList<AttributeListSyntax>),
AsModifierList(accessibility, modifiers, SyntaxKind.MethodDeclaration),
default(SyntaxToken),
returnType != null ? (TypeSyntax)returnType : SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword)),
default(ExplicitInterfaceSpecifierSyntax),
name.ToIdentifierToken(),
......@@ -2663,7 +2664,7 @@ private SyntaxNode WithExpressionInternal(SyntaxNode declaration, SyntaxNode exp
}
}
private EqualsValueClauseSyntax GetEqualsValue(SyntaxNode declaration)
private EqualsClauseSyntax GetEqualsValue(SyntaxNode declaration)
{
switch (declaration.Kind())
{
......@@ -3611,7 +3612,7 @@ public override SyntaxNode ConvertExpression(SyntaxNode type, SyntaxNode express
public override SyntaxNode AssignmentStatement(SyntaxNode left, SyntaxNode right)
{
return SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, (ExpressionSyntax)left, Parenthesize(right));
return SyntaxFactory.ValueAssignmentExpression(SyntaxKind.SimpleAssignmentExpression, (ExpressionSyntax)left, Parenthesize(right));
}
private SyntaxNode CreateBinaryExpression(SyntaxKind syntaxKind, SyntaxNode left, SyntaxNode right)
......
......@@ -79,6 +79,7 @@ internal static class MethodGenerator
return AddCleanupAnnotationsTo(SyntaxFactory.MethodDeclaration(
attributeLists: GenerateAttributes(method, options, explicitInterfaceSpecifier != null),
modifiers: GenerateModifiers(method, destination, options),
refKeyword: method.ReturnsByRef ? SyntaxFactory.Token(SyntaxKind.RefKeyword) : default(SyntaxToken),
returnType: method.ReturnType.GenerateTypeSyntax(),
explicitInterfaceSpecifier: explicitInterfaceSpecifier,
identifier: method.Name.ToIdentifierToken(),
......
......@@ -2080,12 +2080,12 @@ private static bool IsThisOrTypeOrNamespace(MemberAccessExpressionSyntax memberA
private static bool EqualsValueClauseNotSuitableForVar(
SyntaxToken identifier,
TypeSyntax simpleName,
EqualsValueClauseSyntax equalsValueClause,
EqualsClauseSyntax equalsClause,
SemanticModel semanticModel,
CancellationToken cancellationToken)
{
// var cannot be assigned null
if (equalsValueClause.IsKind(SyntaxKind.NullLiteralExpression))
if (equalsClause.IsKind(SyntaxKind.NullLiteralExpression))
{
return true;
}
......@@ -2099,7 +2099,7 @@ private static bool IsThisOrTypeOrNamespace(MemberAccessExpressionSyntax memberA
return true;
}
var initializerType = semanticModel.GetTypeInfo(equalsValueClause.Value, cancellationToken).Type;
var initializerType = semanticModel.GetTypeInfo(equalsClause.Value, cancellationToken).Type;
if (!type.Equals(initializerType))
{
......@@ -2107,7 +2107,7 @@ private static bool IsThisOrTypeOrNamespace(MemberAccessExpressionSyntax memberA
}
// The assign expression in the initializer cannot be the same symbol as the i
var possibleSameLocals = equalsValueClause.DescendantNodesAndSelf().Where(n => n.Kind() == SyntaxKind.IdentifierName && ((IdentifierNameSyntax)n).Identifier.ValueText.Equals(identifier.ValueText));
var possibleSameLocals = equalsClause.DescendantNodesAndSelf().Where(n => n.Kind() == SyntaxKind.IdentifierName && ((IdentifierNameSyntax)n).Identifier.ValueText.Equals(identifier.ValueText));
var anyUse = possibleSameLocals.Any(n =>
{
var symbol = semanticModel.GetSymbolInfo(n, cancellationToken).Symbol;
......
......@@ -86,6 +86,7 @@ public override IExpressionRewriter CreateExpressionRewriter(OptionSet optionSet
parenthesizedLambda.AsyncKeyword,
newParameterSyntax.WithTrailingTrivia(parenthesizedLambda.ParameterList.GetTrailingTrivia()),
parenthesizedLambda.ArrowToken,
parenthesizedLambda.RefKeyword,
parenthesizedLambda.Body);
return SimplificationHelpers.CopyAnnotations(parenthesizedLambda, newSimpleLambda).WithoutAnnotations(Simplifier.Annotation);
......
......@@ -242,6 +242,7 @@ public override SyntaxNode VisitSimpleLambdaExpression(SimpleLambdaExpressionSyn
.WithTrailingTrivia(simpleLambda.Parameter.GetTrailingTrivia())
.WithLeadingTrivia(simpleLambda.Parameter.GetLeadingTrivia()),
simpleLambda.ArrowToken,
simpleLambda.RefKeyword,
simpleLambda.Body).WithAdditionalAnnotations(Simplifier.Annotation);
return SimplificationHelpers.CopyAnnotations(from: simpleLambda, to: parenthesizedLambda);
......
......@@ -150,6 +150,7 @@ public async Task FormatElasticTriviaBetweenPropertiesWithoutAccessors()
var property = SyntaxFactory.PropertyDeclaration(
attributeLists: default(SyntaxList<AttributeListSyntax>),
modifiers: SyntaxFactory.TokenList(),
refKeyword: default(SyntaxToken),
type: SyntaxFactory.PredefinedType(
SyntaxFactory.Token(
SyntaxKind.StringKeyword)),
......
......@@ -116,9 +116,9 @@ public static IMethodSymbol CreateDestructorSymbol(IList<AttributeData> attribut
return result;
}
internal static IMethodSymbol CreateMethodSymbol(INamedTypeSymbol containingType, IList<AttributeData> attributes, Accessibility accessibility, DeclarationModifiers modifiers, ITypeSymbol returnType, IMethodSymbol explicitInterfaceSymbol, string name, IList<ITypeParameterSymbol> typeParameters, IList<IParameterSymbol> parameters, IList<SyntaxNode> statements = null, IList<SyntaxNode> handlesExpressions = null, IList<AttributeData> returnTypeAttributes = null, MethodKind methodKind = MethodKind.Ordinary)
internal static IMethodSymbol CreateMethodSymbol(INamedTypeSymbol containingType, IList<AttributeData> attributes, Accessibility accessibility, DeclarationModifiers modifiers, ITypeSymbol returnType, IMethodSymbol explicitInterfaceSymbol, string name, IList<ITypeParameterSymbol> typeParameters, IList<IParameterSymbol> parameters, IList<SyntaxNode> statements = null, IList<SyntaxNode> handlesExpressions = null, IList<AttributeData> returnTypeAttributes = null, MethodKind methodKind = MethodKind.Ordinary, bool returnsByRef = false)
{
var result = new CodeGenerationMethodSymbol(containingType, attributes, accessibility, modifiers, returnType, explicitInterfaceSymbol, name, typeParameters, parameters, returnTypeAttributes, methodKind);
var result = new CodeGenerationMethodSymbol(containingType, attributes, accessibility, modifiers, returnType, returnsByRef, explicitInterfaceSymbol, name, typeParameters, parameters, returnTypeAttributes, methodKind);
CodeGenerationMethodInfo.Attach(result, modifiers.IsNew, modifiers.IsUnsafe, modifiers.IsPartial, modifiers.IsAsync, statements, handlesExpressions);
return result;
}
......
......@@ -33,6 +33,7 @@ public virtual ImmutableArray<AttributeData> GetReturnTypeAttributes()
public abstract int Arity { get; }
public abstract bool ReturnsVoid { get; }
public abstract bool ReturnsByRef { get; }
public abstract ITypeSymbol ReturnType { get; }
public abstract ImmutableArray<ITypeSymbol> TypeArguments { get; }
public abstract ImmutableArray<ITypeParameterSymbol> TypeParameters { get; }
......
......@@ -42,6 +42,14 @@ public override bool ReturnsVoid
}
}
public override bool ReturnsByRef
{
get
{
return _constructedFrom.ReturnsByRef;
}
}
public override ITypeSymbol ReturnType
{
get
......
......@@ -20,6 +20,7 @@ internal class CodeGenerationConstructorSymbol : CodeGenerationMethodSymbol
accessibility,
modifiers,
returnType: null,
returnsByRef: false,
explicitInterfaceSymbolOpt: null,
name: string.Empty,
typeParameters: SpecializedCollections.EmptyList<ITypeParameterSymbol>(),
......
......@@ -26,6 +26,7 @@ internal class CodeGenerationConversionSymbol : CodeGenerationMethodSymbol
declaredAccessibility,
modifiers,
returnType: toType,
returnsByRef: false,
explicitInterfaceSymbolOpt: null,
name: isImplicit ?
WellKnownMemberNames.ImplicitConversionName :
......
......@@ -17,6 +17,7 @@ internal class CodeGenerationDestructorSymbol : CodeGenerationMethodSymbol
Accessibility.NotApplicable,
default(DeclarationModifiers),
returnType: null,
returnsByRef: false,
explicitInterfaceSymbolOpt: null,
name: string.Empty,
typeParameters: SpecializedCollections.EmptyList<ITypeParameterSymbol>(),
......
......@@ -14,6 +14,7 @@ namespace Microsoft.CodeAnalysis.CodeGeneration
internal partial class CodeGenerationMethodSymbol : CodeGenerationAbstractMethodSymbol
{
private readonly ITypeSymbol _returnType;
private readonly bool _returnsByRef;
private readonly ImmutableArray<ITypeParameterSymbol> _typeParameters;
private readonly ImmutableArray<IParameterSymbol> _parameters;
private readonly ImmutableArray<IMethodSymbol> _explicitInterfaceImplementations;
......@@ -25,6 +26,7 @@ internal partial class CodeGenerationMethodSymbol : CodeGenerationAbstractMethod
Accessibility declaredAccessibility,
DeclarationModifiers modifiers,
ITypeSymbol returnType,
bool returnsByRef,
IMethodSymbol explicitInterfaceSymbolOpt,
string name,
IList<ITypeParameterSymbol> typeParameters,
......@@ -34,6 +36,7 @@ internal partial class CodeGenerationMethodSymbol : CodeGenerationAbstractMethod
: base(containingType, attributes, declaredAccessibility, modifiers, name, returnTypeAttributes)
{
_returnType = returnType;
_returnsByRef = returnsByRef;
_typeParameters = typeParameters.AsImmutableOrEmpty();
_parameters = parameters.AsImmutableOrEmpty();
_explicitInterfaceImplementations = explicitInterfaceSymbolOpt == null
......@@ -80,7 +83,7 @@ protected override CodeGenerationSymbol Clone()
{
var result = new CodeGenerationMethodSymbol(this.ContainingType,
this.GetAttributes(), this.DeclaredAccessibility, this.Modifiers,
this.ReturnType, this.ExplicitInterfaceImplementations.FirstOrDefault(),
this.ReturnType, this.ReturnsByRef, this.ExplicitInterfaceImplementations.FirstOrDefault(),
this.Name, this.TypeParameters, this.Parameters, this.GetReturnTypeAttributes());
CodeGenerationMethodInfo.Attach(result,
......@@ -110,6 +113,14 @@ public override bool ReturnsVoid
}
}
public override bool ReturnsByRef
{
get
{
return _returnsByRef;
}
}
public override ImmutableArray<ITypeSymbol> TypeArguments
{
get
......
......@@ -27,6 +27,7 @@ internal class CodeGenerationOperatorSymbol : CodeGenerationMethodSymbol
accessibility,
modifiers,
returnType: returnType,
returnsByRef: false,
explicitInterfaceSymbolOpt: null,
name: GetMetadataName(operatorKind),
typeParameters: SpecializedCollections.EmptyList<ITypeParameterSymbol>(),
......
......@@ -93,6 +93,14 @@ public bool IsWriteOnly
}
}
public bool ReturnsByRef
{
get
{
return this.GetMethod != null && this.GetMethod.ReturnsByRef;
}
}
public new IPropertySymbol OriginalDefinition
{
get
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册