提交 1993d900 编写于 作者: V vsadov

merge from master

上级 e763d1dc
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Emit;
using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.PooledObjects;
...@@ -108,7 +109,7 @@ internal sealed class SourceOrdinaryMethodSymbol : SourceMemberMethodSymbol ...@@ -108,7 +109,7 @@ internal sealed class SourceOrdinaryMethodSymbol : SourceMemberMethodSymbol
bool hasBlockBody = syntax.Body != null; bool hasBlockBody = syntax.Body != null;
_isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null; _isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null;
syntax.ReturnType.SkipRef(out _refKind); _refKind = syntax.ReturnType.GetRefKind();
if (hasBlockBody || _isExpressionBodied) if (hasBlockBody || _isExpressionBodied)
{ {
...@@ -152,6 +153,8 @@ public override bool ReturnsVoid ...@@ -152,6 +153,8 @@ public override bool ReturnsVoid
private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsBinder, DiagnosticBag diagnostics) private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsBinder, DiagnosticBag diagnostics)
{ {
Debug.Assert(this.MethodKind != MethodKind.UserDefinedOperator, "SourceUserDefinedOperatorSymbolBase overrides this");
SyntaxToken arglistToken; SyntaxToken arglistToken;
// Constraint checking for parameter and return types must be delayed until // Constraint checking for parameter and return types must be delayed until
...@@ -165,6 +168,7 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB ...@@ -165,6 +168,7 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB
signatureBinder, this, syntax.ParameterList, out arglistToken, signatureBinder, this, syntax.ParameterList, out arglistToken,
allowRefOrOut: true, allowRefOrOut: true,
allowThis: true, allowThis: true,
addRefReadOnlyModifier: IsVirtual || IsAbstract,
diagnostics: diagnostics); diagnostics: diagnostics);
_lazyIsVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword); _lazyIsVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword);
...@@ -172,7 +176,8 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB ...@@ -172,7 +176,8 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB
var returnTypeSyntax = syntax.ReturnType.SkipRef(out refKind); var returnTypeSyntax = syntax.ReturnType.SkipRef(out refKind);
_lazyReturnType = signatureBinder.BindType(returnTypeSyntax, diagnostics); _lazyReturnType = signatureBinder.BindType(returnTypeSyntax, diagnostics);
if (_lazyReturnType.IsRestrictedType()) // span-like types are returnable in general
if (_lazyReturnType.IsRestrictedType(ignoreSpanLikeTypes: true))
{ {
if (_lazyReturnType.SpecialType == SpecialType.System_TypedReference && if (_lazyReturnType.SpecialType == SpecialType.System_TypedReference &&
(this.ContainingType.SpecialType == SpecialType.System_TypedReference || this.ContainingType.SpecialType == SpecialType.System_ArgIterator)) (this.ContainingType.SpecialType == SpecialType.System_TypedReference || this.ContainingType.SpecialType == SpecialType.System_ArgIterator))
...@@ -208,6 +213,7 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB ...@@ -208,6 +213,7 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB
if (IsExtensionMethod) if (IsExtensionMethod)
{ {
var parameter0Type = this.Parameters[0].Type; var parameter0Type = this.Parameters[0].Type;
var parameter0RefKind = this.Parameters[0].RefKind;
if (!parameter0Type.IsValidExtensionParameterType()) if (!parameter0Type.IsValidExtensionParameterType())
{ {
// Duplicate Dev10 behavior by selecting the parameter type. // Duplicate Dev10 behavior by selecting the parameter type.
...@@ -216,6 +222,14 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB ...@@ -216,6 +222,14 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB
var loc = parameterSyntax.Type.Location; var loc = parameterSyntax.Type.Location;
diagnostics.Add(ErrorCode.ERR_BadTypeforThis, loc, parameter0Type); diagnostics.Add(ErrorCode.ERR_BadTypeforThis, loc, parameter0Type);
} }
else if (parameter0RefKind == RefKind.Ref && !parameter0Type.IsValueType)
{
diagnostics.Add(ErrorCode.ERR_RefExtensionMustBeValueTypeOrConstrainedToOne, location, Name);
}
else if (parameter0RefKind == RefKind.RefReadOnly && parameter0Type.TypeKind != TypeKind.Struct)
{
diagnostics.Add(ErrorCode.ERR_RefReadOnlyExtensionMustBeValueType, location, Name);
}
else if ((object)ContainingType.ContainingType != null) else if ((object)ContainingType.ContainingType != null)
{ {
diagnostics.Add(ErrorCode.ERR_ExtensionMethodsDecl, location, ContainingType.Name); diagnostics.Add(ErrorCode.ERR_ExtensionMethodsDecl, location, ContainingType.Name);
...@@ -249,18 +263,7 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB ...@@ -249,18 +263,7 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB
} }
} }
if (this.MethodKind == MethodKind.UserDefinedOperator) if (IsPartial)
{
foreach (var p in this.Parameters)
{
if (p.RefKind != RefKind.None)
{
diagnostics.Add(ErrorCode.ERR_IllegalRefParam, location);
break;
}
}
}
else if (IsPartial)
{ {
// check that there are no out parameters in a partial // check that there are no out parameters in a partial
foreach (var p in this.Parameters) foreach (var p in this.Parameters)
...@@ -328,11 +331,19 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB ...@@ -328,11 +331,19 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB
if ((object)overriddenMethod != null) if ((object)overriddenMethod != null)
{ {
CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType, CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType,
out _lazyCustomModifiers, out _lazyCustomModifiers,
out _lazyParameters, alsoCopyParamsModifier: true); out _lazyParameters, alsoCopyParamsModifier: true);
} }
} }
else if (_refKind == RefKind.RefReadOnly)
{
var modifierType = withTypeParamsBinder.GetWellKnownType(WellKnownType.System_Runtime_InteropServices_InAttribute, diagnostics, syntax.ReturnType);
_lazyCustomModifiers = CustomModifiersTuple.Create(
typeCustomModifiers: ImmutableArray<CustomModifier>.Empty,
refCustomModifiers: ImmutableArray.Create(CSharpCustomModifier.CreateRequired(modifierType)));
}
} }
else if ((object)_explicitInterfaceType != null) else if ((object)_explicitInterfaceType != null)
{ {
...@@ -344,7 +355,7 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB ...@@ -344,7 +355,7 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB
Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault); Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
_lazyExplicitInterfaceImplementations = ImmutableArray.Create<MethodSymbol>(implementedMethod); _lazyExplicitInterfaceImplementations = ImmutableArray.Create<MethodSymbol>(implementedMethod);
CustomModifierUtils.CopyMethodCustomModifiers(implementedMethod, this, out _lazyReturnType, CustomModifierUtils.CopyMethodCustomModifiers(implementedMethod, this, out _lazyReturnType,
out _lazyCustomModifiers, out _lazyCustomModifiers,
out _lazyParameters, alsoCopyParamsModifier: false); out _lazyParameters, alsoCopyParamsModifier: false);
} }
...@@ -959,9 +970,9 @@ private void CheckModifiers(Location location, DiagnosticBag diagnostics) ...@@ -959,9 +970,9 @@ private void CheckModifiers(Location location, DiagnosticBag diagnostics)
} }
} }
internal override void AddSynthesizedAttributes(ModuleCompilationState compilationState, ref ArrayBuilder<SynthesizedAttributeData> attributes) internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder<SynthesizedAttributeData> attributes)
{ {
base.AddSynthesizedAttributes(compilationState, ref attributes); base.AddSynthesizedAttributes(moduleBuilder, ref attributes);
if (this.IsExtensionMethod) if (this.IsExtensionMethod)
{ {
...@@ -1010,6 +1021,13 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, ...@@ -1010,6 +1021,13 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions,
{ {
PartialMethodChecks(this, implementingPart, diagnostics); PartialMethodChecks(this, implementingPart, diagnostics);
} }
if (_refKind == RefKind.RefReadOnly)
{
this.DeclaringCompilation.EnsureIsReadOnlyAttributeExists(diagnostics, GetSyntax().ReturnType.Location, modifyCompilationForRefReadOnly: true);
}
ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilationForRefReadOnly: true);
} }
/// <summary> /// <summary>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册