提交 9bf6bd8f 编写于 作者: A AlekseyTs 提交者: GitHub

Merge pull request #15410 from AlekseyTs/Issue8948_7

Add new property RefCustomModifiers to IParameterSymbol, IPropertySymbol and IMethodSymbol.
......@@ -741,7 +741,7 @@ private static ImmutableArray<Symbol> PerformCrefOverloadResolution(ArrayBuilder
refKind: RefKind.None,
returnType: null,
returnTypeCustomModifiers: ImmutableArray<CustomModifier>.Empty,
countOfCustomModifiersPrecedingByRef: 0,
refCustomModifiers: ImmutableArray<CustomModifier>.Empty,
explicitInterfaceImplementations: ImmutableArray<MethodSymbol>.Empty);
break;
}
......@@ -757,7 +757,7 @@ private static ImmutableArray<Symbol> PerformCrefOverloadResolution(ArrayBuilder
refKind: RefKind.None,
type: null,
typeCustomModifiers: ImmutableArray<CustomModifier>.Empty,
countOfCustomModifiersPrecedingByRef: 0,
refCustomModifiers: ImmutableArray<CustomModifier>.Empty,
isStatic: false,
explicitInterfaceImplementations: ImmutableArray<PropertySymbol>.Empty);
break;
......@@ -872,7 +872,7 @@ private ImmutableArray<ParameterSymbol> BindCrefParameters(BaseCrefParameterList
TypeSymbol type = BindCrefParameterOrReturnType(parameter.Type, (MemberCrefSyntax)parameterListSyntax.Parent, diagnostics);
parameterBuilder.Add(new SignatureOnlyParameterSymbol(type, ImmutableArray<CustomModifier>.Empty, isParams: false, refKind: refKind));
parameterBuilder.Add(new SignatureOnlyParameterSymbol(type, ImmutableArray<CustomModifier>.Empty, ImmutableArray<CustomModifier>.Empty, isParams: false, refKind: refKind));
}
return parameterBuilder.ToImmutableAndFree();
......
......@@ -280,7 +280,7 @@ public static void GetDelegateArguments(SyntaxNode syntax, AnalyzedArguments ana
// If we don't have System.Object, then we'll get an error type, which will cause overload resolution to fail,
// which will cause some error to be reported. That's sufficient (i.e. no need to specifically report its absence here).
parameter = new SignatureOnlyParameterSymbol(
compilation.GetSpecialType(SpecialType.System_Object), parameter.CustomModifiers, parameter.IsParams, parameter.RefKind);
compilation.GetSpecialType(SpecialType.System_Object), parameter.CustomModifiers, parameter.RefCustomModifiers, parameter.IsParams, parameter.RefKind);
}
analyzedArguments.Arguments.Add(new BoundParameter(syntax, parameter) { WasCompilerGenerated = true });
......
......@@ -1014,6 +1014,7 @@ private static bool HadLambdaConversionError(DiagnosticBag diagnostics, Analyzed
SignatureOnlyParameterSymbol displayArg = new SignatureOnlyParameterSymbol(
argType,
ImmutableArray<CustomModifier>.Empty,
ImmutableArray<CustomModifier>.Empty,
isParams: false,
refKind: refArg);
......
......@@ -101,9 +101,9 @@ ImmutableArray<Cci.ICustomModifier> Cci.ISignature.ReturnValueCustomModifiers
get { return _underlyingMethod.ReturnValueCustomModifiers; }
}
ushort Cci.ISignature.CountOfCustomModifiersPrecedingByRef
ImmutableArray<Cci.ICustomModifier> Cci.ISignature.RefCustomModifiers
{
get { return _underlyingMethod.CountOfCustomModifiersPrecedingByRef; }
get { return _underlyingMethod.RefCustomModifiers; }
}
bool Cci.ISignature.ReturnValueIsByRef
......
......@@ -94,11 +94,11 @@ ImmutableArray<Cci.ICustomModifier> Cci.ISignature.ReturnValueCustomModifiers
}
}
ushort Cci.ISignature.CountOfCustomModifiersPrecedingByRef
ImmutableArray<Cci.ICustomModifier> Cci.ISignature.RefCustomModifiers
{
get
{
return UnderlyingMethod.CountOfCustomModifiersPrecedingByRef;
return UnderlyingMethod.RefCustomModifiers.As<Cci.ICustomModifier>();
}
}
......
......@@ -214,11 +214,11 @@ ImmutableArray<Cci.ICustomModifier> Cci.ISignature.ReturnValueCustomModifiers
}
}
ushort Cci.ISignature.CountOfCustomModifiersPrecedingByRef
ImmutableArray<Cci.ICustomModifier> Cci.ISignature.RefCustomModifiers
{
get
{
return this.CountOfCustomModifiersPrecedingByRef;
return this.RefCustomModifiers.As<Cci.ICustomModifier>();
}
}
......
......@@ -29,11 +29,11 @@ bool Cci.IParameterTypeInformation.IsByReference
}
}
ushort Cci.IParameterTypeInformation.CountOfCustomModifiersPrecedingByRef
ImmutableArray<Cci.ICustomModifier> Cci.IParameterTypeInformation.RefCustomModifiers
{
get
{
return this.CountOfCustomModifiersPrecedingByRef;
return this.RefCustomModifiers.As<Cci.ICustomModifier>();
}
}
......
......@@ -36,11 +36,11 @@ bool Cci.IParameterTypeInformation.IsByReference
}
}
ushort Cci.IParameterTypeInformation.CountOfCustomModifiersPrecedingByRef
ImmutableArray<Cci.ICustomModifier> Cci.IParameterTypeInformation.RefCustomModifiers
{
get
{
return _underlyingParameter.CountOfCustomModifiersPrecedingByRef;
return _underlyingParameter.RefCustomModifiers.As<Cci.ICustomModifier>();
}
}
......@@ -86,9 +86,9 @@ bool Cci.IParameterTypeInformation.IsByReference
get { return _isByRef; }
}
ushort Cci.IParameterTypeInformation.CountOfCustomModifiersPrecedingByRef
ImmutableArray<Cci.ICustomModifier> Cci.IParameterTypeInformation.RefCustomModifiers
{
get { return 0; }
get { return ImmutableArray<Cci.ICustomModifier>.Empty; }
}
Cci.ITypeReference Cci.IParameterTypeInformation.GetType(EmitContext context)
......
......@@ -174,12 +174,12 @@ ImmutableArray<Cci.ICustomModifier> Cci.ISignature.ReturnValueCustomModifiers
}
}
ushort Cci.ISignature.CountOfCustomModifiersPrecedingByRef
ImmutableArray<Cci.ICustomModifier> Cci.ISignature.RefCustomModifiers
{
get
{
CheckDefinitionInvariantAllowEmbedded();
return this.CountOfCustomModifiersPrecedingByRef;
return this.RefCustomModifiers.As<Cci.ICustomModifier>();
}
}
......
......@@ -19,7 +19,7 @@ internal IteratorConstructor(IteratorStateMachine container)
{
var intType = container.DeclaringCompilation.GetSpecialType(SpecialType.System_Int32);
_parameters = ImmutableArray.Create<ParameterSymbol>(
new SynthesizedParameterSymbol(this, intType, 0, RefKind.None, GeneratedNames.MakeStateMachineStateFieldName()));
SynthesizedParameterSymbol.Create(this, intType, 0, RefKind.None, GeneratedNames.MakeStateMachineStateFieldName()));
}
internal override void AddSynthesizedAttributes(ModuleCompilationState compilationState, ref ArrayBuilder<SynthesizedAttributeData> attributes)
......
......@@ -167,9 +167,9 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return 0; }
get { return ImmutableArray<CustomModifier>.Empty; }
}
public override Symbol AssociatedSymbol
......
......@@ -48,9 +48,9 @@ public override ImmutableArray<CustomModifier> TypeCustomModifiers
get { return _getter.ReturnTypeCustomModifiers; }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return _getter.CountOfCustomModifiersPrecedingByRef; }
get { return _getter.RefCustomModifiers; }
}
public override ImmutableArray<ParameterSymbol> Parameters
......
......@@ -113,14 +113,14 @@ private ImmutableArray<ParameterSymbol> MakeParameters()
var parameters = this.BaseMethodParameters;
foreach (var p in parameters)
{
builder.Add(new SynthesizedParameterSymbol(this, this.TypeMap.SubstituteType(p.OriginalDefinition.Type).Type, ordinal++, p.RefKind, p.Name));
builder.Add(SynthesizedParameterSymbol.Create(this, this.TypeMap.SubstituteType(p.OriginalDefinition.Type).Type, ordinal++, p.RefKind, p.Name));
}
var extraSynthed = ExtraSynthesizedRefParameters;
if (!extraSynthed.IsDefaultOrEmpty)
{
foreach (var extra in extraSynthed)
{
builder.Add(new SynthesizedParameterSymbol(this, this.TypeMap.SubstituteType(extra).Type, ordinal++, RefKind.Ref));
builder.Add(SynthesizedParameterSymbol.Create(this, this.TypeMap.SubstituteType(extra).Type, ordinal++, RefKind.Ref));
}
}
return builder.ToImmutableAndFree();
......
......@@ -495,7 +495,7 @@ public void CloseMethod(BoundStatement body)
public ParameterSymbol SynthesizedParameter(TypeSymbol type, string name, MethodSymbol container = null, int ordinal = 0)
{
return new SynthesizedParameterSymbol(container, type, ordinal, RefKind.None, name);
return SynthesizedParameterSymbol.Create(container, type, ordinal, RefKind.None, name);
}
public BoundBinaryOperator Binary(BinaryOperatorKind kind, TypeSymbol type, BoundExpression left, BoundExpression right)
......
......@@ -65,31 +65,12 @@ public override void VisitProperty(IPropertySymbol symbol)
AddRefIfRequired();
}
ushort countOfCustomModifiersPrecedingByRef = 0;
var property = symbol as PropertySymbol;
if ((object)property != null)
{
countOfCustomModifiersPrecedingByRef = property.CountOfCustomModifiersPrecedingByRef;
}
ImmutableArray<CustomModifier> typeCustomModifiers = symbol.TypeCustomModifiers;
if (countOfCustomModifiersPrecedingByRef > 0)
{
AddCustomModifiersIfRequired(ImmutableArray.Create(typeCustomModifiers, 0, countOfCustomModifiersPrecedingByRef), leadingSpace: false, trailingSpace: true);
}
AddCustomModifiersIfRequired(symbol.RefCustomModifiers);
symbol.Type.Accept(this.NotFirstVisitor);
AddSpace();
if (countOfCustomModifiersPrecedingByRef == 0)
{
AddCustomModifiersIfRequired(typeCustomModifiers);
}
else if (countOfCustomModifiersPrecedingByRef < typeCustomModifiers.Length)
{
AddCustomModifiersIfRequired(ImmutableArray.Create(typeCustomModifiers, countOfCustomModifiersPrecedingByRef,
typeCustomModifiers.Length - countOfCustomModifiersPrecedingByRef));
}
AddCustomModifiersIfRequired(symbol.TypeCustomModifiers);
}
if (format.MemberOptions.IncludesOption(SymbolDisplayMemberOptions.IncludeContainingType) &&
......@@ -257,8 +238,7 @@ public override void VisitMethod(IMethodSymbol symbol)
AddRefIfRequired();
}
ushort countOfCustomModifiersPrecedingByRef = 0;
ImmutableArray<CustomModifier> returnTypeCustomModifiers = symbol.ReturnTypeCustomModifiers;
AddCustomModifiersIfRequired(symbol.RefCustomModifiers);
if (symbol.ReturnsVoid)
{
......@@ -266,32 +246,11 @@ public override void VisitMethod(IMethodSymbol symbol)
}
else if (symbol.ReturnType != null)
{
var method = symbol as MethodSymbol;
if ((object)method != null)
{
countOfCustomModifiersPrecedingByRef = method.CountOfCustomModifiersPrecedingByRef;
}
if (countOfCustomModifiersPrecedingByRef > 0)
{
AddCustomModifiersIfRequired(ImmutableArray.Create(returnTypeCustomModifiers, 0, countOfCustomModifiersPrecedingByRef), leadingSpace: false, trailingSpace: true);
}
symbol.ReturnType.Accept(this.NotFirstVisitor);
}
AddSpace();
if (countOfCustomModifiersPrecedingByRef == 0)
{
AddCustomModifiersIfRequired(returnTypeCustomModifiers);
}
else if (countOfCustomModifiersPrecedingByRef < returnTypeCustomModifiers.Length)
{
AddCustomModifiersIfRequired(ImmutableArray.Create(returnTypeCustomModifiers, countOfCustomModifiersPrecedingByRef,
returnTypeCustomModifiers.Length - countOfCustomModifiersPrecedingByRef));
}
AddCustomModifiersIfRequired(symbol.ReturnTypeCustomModifiers);
break;
}
}
......@@ -459,7 +418,7 @@ public override void VisitMethod(IMethodSymbol symbol)
if (!isAccessor)
{
AddTypeArguments(symbol.TypeArguments, null);
AddTypeArguments(symbol.TypeArguments);
AddParameters(symbol);
AddTypeParameterConstraints(symbol);
}
......@@ -506,6 +465,7 @@ public override void VisitParameter(IParameterSymbol symbol)
if (includeType)
{
AddRefKindIfRequired(symbol.RefKind);
AddCustomModifiersIfRequired(symbol.RefCustomModifiers, leadingSpace: false, trailingSpace: true);
if (symbol.IsParams && format.ParameterOptions.IncludesOption(SymbolDisplayParameterOptions.IncludeParamsRefOut))
{
......@@ -513,30 +473,8 @@ public override void VisitParameter(IParameterSymbol symbol)
AddSpace();
}
ushort countOfCustomModifiersPrecedingByRef = 0;
var parameter = symbol as ParameterSymbol;
if ((object)parameter != null)
{
countOfCustomModifiersPrecedingByRef = parameter.CountOfCustomModifiersPrecedingByRef;
}
if (countOfCustomModifiersPrecedingByRef > 0)
{
AddCustomModifiersIfRequired(ImmutableArray.Create(symbol.CustomModifiers, 0, countOfCustomModifiersPrecedingByRef), leadingSpace: false, trailingSpace: true);
}
symbol.Type.Accept(this.NotFirstVisitor);
if (countOfCustomModifiersPrecedingByRef == 0)
{
AddCustomModifiersIfRequired(symbol.CustomModifiers, leadingSpace: true, trailingSpace: false);
}
else if (countOfCustomModifiersPrecedingByRef < symbol.CustomModifiers.Length)
{
AddCustomModifiersIfRequired(ImmutableArray.Create(symbol.CustomModifiers, countOfCustomModifiersPrecedingByRef,
symbol.CustomModifiers.Length - countOfCustomModifiersPrecedingByRef),
leadingSpace: true, trailingSpace: false);
}
AddCustomModifiersIfRequired(symbol.CustomModifiers, leadingSpace: true, trailingSpace: false);
}
if (includeName && includeType)
......
......@@ -587,7 +587,7 @@ private void AddTypeParameterVarianceIfRequired(ITypeParameterSymbol symbol)
}
//returns true if there are constraints
private void AddTypeArguments(ImmutableArray<ITypeSymbol> typeArguments, INamedTypeSymbol modifiersSourceOpt)
private void AddTypeArguments(ImmutableArray<ITypeSymbol> typeArguments, INamedTypeSymbol modifiersSourceOpt = null)
{
if (typeArguments.Length > 0 && format.GenericsOptions.IncludesOption(SymbolDisplayGenericsOptions.IncludeTypeParameters))
{
......
......@@ -33,7 +33,7 @@ internal AnonymousTypeConstructorSymbol(NamedTypeSymbol container, ImmutableArra
for (int index = 0; index < fieldsCount; index++)
{
PropertySymbol property = properties[index];
paramsArr[index] = new SynthesizedParameterSymbol(this, property.Type, index, RefKind.None, property.Name);
paramsArr[index] = SynthesizedParameterSymbol.Create(this, property.Type, index, RefKind.None, property.Name);
}
_parameters = paramsArr.AsImmutableOrNull();
}
......
......@@ -26,7 +26,7 @@ internal AnonymousTypeEqualsMethodSymbol(NamedTypeSymbol container)
: base(container, WellKnownMemberNames.ObjectEquals)
{
_parameters = ImmutableArray.Create<ParameterSymbol>(
new SynthesizedParameterSymbol(this, this.Manager.System_Object, 0, RefKind.None, "value")
SynthesizedParameterSymbol.Create(this, this.Manager.System_Object, 0, RefKind.None, "value")
);
}
......
......@@ -128,9 +128,9 @@ public override ImmutableArray<CustomModifier> TypeCustomModifiers
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return 0; }
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override Microsoft.Cci.CallingConvention CallingConvention
......
......@@ -120,9 +120,9 @@ public sealed override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public sealed override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return 0; }
get { return ImmutableArray<CustomModifier>.Empty; }
}
public override Symbol AssociatedSymbol
......
......@@ -117,9 +117,9 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return 0; }
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override bool IsExplicitInterfaceImplementation
......
......@@ -85,6 +85,6 @@ public ErrorPropertySymbol(Symbol containingSymbol, TypeSymbol type, string name
public override ImmutableArray<CustomModifier> TypeCustomModifiers { get { return ImmutableArray<CustomModifier>.Empty; } }
internal override ushort CountOfCustomModifiersPrecedingByRef { get { return 0; } }
public override ImmutableArray<CustomModifier> RefCustomModifiers { get { return ImmutableArray<CustomModifier>.Empty; } }
}
}
......@@ -456,9 +456,8 @@ public int GetHashCode(Symbol member)
{
RefKind refKind;
TypeSymbol returnType;
ImmutableArray<CustomModifier> returnTypeCustomModifiers;
ushort countOfCustomModifiersPrecedingByRef;
member.GetTypeOrReturnType(out refKind, out returnType, out returnTypeCustomModifiers, out countOfCustomModifiersPrecedingByRef);
ImmutableArray<CustomModifier> customModifiers_Ignored;
member.GetTypeOrReturnType(out refKind, out returnType, out customModifiers_Ignored, out customModifiers_Ignored);
hash = Hash.Combine((int)refKind, hash);
......@@ -488,14 +487,14 @@ private static bool HaveSameReturnTypes(Symbol member1, TypeMap typeMap1, Symbol
RefKind refKind1;
TypeSymbol unsubstitutedReturnType1;
ImmutableArray<CustomModifier> returnTypeCustomModifiers1;
ushort countOfCustomModifiersPrecedingByRef1;
member1.GetTypeOrReturnType(out refKind1, out unsubstitutedReturnType1, out returnTypeCustomModifiers1, out countOfCustomModifiersPrecedingByRef1);
ImmutableArray<CustomModifier> refCustomModifiers1;
member1.GetTypeOrReturnType(out refKind1, out unsubstitutedReturnType1, out returnTypeCustomModifiers1, out refCustomModifiers1);
RefKind refKind2;
TypeSymbol unsubstitutedReturnType2;
ImmutableArray<CustomModifier> returnTypeCustomModifiers2;
ushort countOfCustomModifiersPrecedingByRef2;
member2.GetTypeOrReturnType(out refKind2, out unsubstitutedReturnType2, out returnTypeCustomModifiers2, out countOfCustomModifiersPrecedingByRef2);
ImmutableArray<CustomModifier> refCustomModifiers2;
member2.GetTypeOrReturnType(out refKind2, out unsubstitutedReturnType2, out returnTypeCustomModifiers2, out refCustomModifiers2);
// short-circuit type map building in the easiest cases
if ((refKind1 != RefKind.None) != (refKind2 != RefKind.None))
......@@ -511,24 +510,13 @@ private static bool HaveSameReturnTypes(Symbol member1, TypeMap typeMap1, Symbol
return false;
}
if (isVoid1)
{
if (considerCustomModifiers &&
!(returnTypeCustomModifiers1.SequenceEqual(returnTypeCustomModifiers2) && countOfCustomModifiersPrecedingByRef1 == countOfCustomModifiersPrecedingByRef2))
{
return false;
}
return true;
}
var returnType1 = SubstituteType(typeMap1, new TypeWithModifiers(unsubstitutedReturnType1, returnTypeCustomModifiers1));
var returnType2 = SubstituteType(typeMap2, new TypeWithModifiers(unsubstitutedReturnType2, returnTypeCustomModifiers2));
// the runtime compares custom modifiers using (effectively) SequenceEqual
return considerCustomModifiers ?
returnType1.Equals(returnType2, TypeCompareKind.ConsiderEverything.AddIgnoreDynamic(ignoreDynamic).AddIgnoreTupleNames(ignoreTupleNames)) &&
countOfCustomModifiersPrecedingByRef1 == countOfCustomModifiersPrecedingByRef2 :
SubstituteModifiers(typeMap1, refCustomModifiers1).SequenceEqual(SubstituteModifiers(typeMap2, refCustomModifiers2)) :
returnType1.Type.Equals(returnType2.Type, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds.AddIgnoreDynamic(ignoreDynamic).AddIgnoreTupleNames(ignoreTupleNames));
}
......@@ -672,7 +660,7 @@ private static void SubstituteConstraintTypes(ImmutableArray<TypeSymbol> types,
if (considerCustomModifiers)
{
if (!type1.Equals(type2, TypeCompareKind.ConsiderEverything.AddIgnoreDynamic(ignoreDynamic).AddIgnoreTupleNames(ignoreTupleNames)) ||
(param1.CountOfCustomModifiersPrecedingByRef != param2.CountOfCustomModifiersPrecedingByRef))
!SubstituteModifiers(typeMap1, param1.RefCustomModifiers).SequenceEqual(SubstituteModifiers(typeMap2, param2.RefCustomModifiers)))
{
return false;
}
......@@ -710,6 +698,11 @@ private static TypeWithModifiers SubstituteType(TypeMap typeMap, TypeWithModifie
return typeMap == null ? typeSymbol : typeSymbol.SubstituteType(typeMap);
}
private static ImmutableArray<CustomModifier> SubstituteModifiers(TypeMap typeMap, ImmutableArray<CustomModifier> customModifiers)
{
return typeMap == null ? customModifiers : typeMap.SubstituteCustomModifiers(customModifiers);
}
private static Cci.CallingConvention GetCallingConvention(Symbol member)
{
switch (member.Kind)
......
......@@ -168,12 +168,12 @@ public static int CustomModifierCount(this MethodSymbol method)
{
int count = 0;
count += method.ReturnTypeCustomModifiers.Length;
count += method.ReturnTypeCustomModifiers.Length + method.RefCustomModifiers.Length;
count += method.ReturnType.CustomModifierCount();
foreach (ParameterSymbol param in method.Parameters)
{
count += param.CustomModifiers.Length;
count += param.CustomModifiers.Length + param.RefCustomModifiers.Length;
count += param.Type.CustomModifierCount();
}
......@@ -214,12 +214,12 @@ public static int CustomModifierCount(this PropertySymbol property)
{
int count = 0;
count += property.TypeCustomModifiers.Length;
count += property.TypeCustomModifiers.Length + property.RefCustomModifiers.Length;
count += property.Type.CustomModifierCount();
foreach (ParameterSymbol param in property.Parameters)
{
count += param.CustomModifiers.Length;
count += param.CustomModifiers.Length + param.RefCustomModifiers.Length;
count += param.Type.CustomModifierCount();
}
......
......@@ -242,10 +242,12 @@ private static bool MethodSymbolMatchesParamInfo(MethodSymbol candidateMethod, P
private static bool ParametersMatch(ParameterSymbol candidateParam, TypeMap candidateMethodTypeMap, ref ParamInfo<TypeSymbol> targetParam)
{
Debug.Assert(candidateMethodTypeMap != null);
// This could be combined into a single return statement with a more complicated expression, but that would
// be harder to debug.
if ((candidateParam.RefKind != RefKind.None) != targetParam.IsByRef || candidateParam.CountOfCustomModifiersPrecedingByRef != targetParam.CountOfCustomModifiersPrecedingByRef)
if ((candidateParam.RefKind != RefKind.None) != targetParam.IsByRef)
{
return false;
}
......@@ -257,7 +259,8 @@ private static bool ParametersMatch(ParameterSymbol candidateParam, TypeMap cand
return false;
}
if (!CustomModifiersMatch(substituted.CustomModifiers, targetParam.CustomModifiers))
if (!CustomModifiersMatch(substituted.CustomModifiers, targetParam.CustomModifiers) ||
!CustomModifiersMatch(candidateMethodTypeMap.SubstituteCustomModifiers(candidateParam.RefCustomModifiers), targetParam.RefCustomModifiers))
{
return false;
}
......@@ -267,7 +270,9 @@ private static bool ParametersMatch(ParameterSymbol candidateParam, TypeMap cand
private static bool ReturnTypesMatch(MethodSymbol candidateMethod, TypeMap candidateMethodTypeMap, ref ParamInfo<TypeSymbol> targetReturnParam)
{
if (candidateMethod.ReturnsByRef != targetReturnParam.IsByRef || candidateMethod.CountOfCustomModifiersPrecedingByRef != targetReturnParam.CountOfCustomModifiersPrecedingByRef)
Debug.Assert(candidateMethodTypeMap != null);
if (candidateMethod.ReturnsByRef != targetReturnParam.IsByRef)
{
return false;
}
......@@ -282,7 +287,8 @@ private static bool ReturnTypesMatch(MethodSymbol candidateMethod, TypeMap candi
return false;
}
if (!CustomModifiersMatch(substituted.CustomModifiers, targetReturnParam.CustomModifiers))
if (!CustomModifiersMatch(substituted.CustomModifiers, targetReturnParam.CustomModifiers) ||
!CustomModifiersMatch(candidateMethodTypeMap.SubstituteCustomModifiers(candidateMethod.RefCustomModifiers), targetReturnParam.RefCustomModifiers))
{
return false;
}
......
......@@ -501,7 +501,7 @@ internal override int ParameterCount
public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers => Signature.ReturnParam.CustomModifiers;
internal override ushort CountOfCustomModifiersPrecedingByRef => Signature.ReturnParam.CountOfCustomModifiersPrecedingByRef;
public override ImmutableArray<CustomModifier> RefCustomModifiers => Signature.ReturnParam.RefCustomModifiers;
/// <summary>
/// Associate the method with a particular property. Returns
......
......@@ -1818,7 +1818,7 @@ private void CreateProperties(Dictionary<MethodDefinitionHandle, PEMethodSymbol>
if (((object)getMethod != null) || ((object)setMethod != null))
{
members.Add(new PEPropertySymbol(moduleSymbol, this, propertyDef, getMethod, setMethod));
members.Add(PEPropertySymbol.Create(moduleSymbol, this, propertyDef, getMethod, setMethod));
}
}
catch (BadImageFormatException)
......
......@@ -143,7 +143,7 @@ public bool TryGetWellKnownAttribute(WellKnownAttributeFlags flag, out bool valu
ParamInfo<TypeSymbol> parameter,
out bool isBad)
{
return Create(moduleSymbol, containingSymbol, ordinal, parameter.IsByRef, parameter.CountOfCustomModifiersPrecedingByRef, parameter.Type, parameter.Handle, parameter.CustomModifiers, out isBad);
return Create(moduleSymbol, containingSymbol, ordinal, parameter.IsByRef, parameter.RefCustomModifiers, parameter.Type, parameter.Handle, parameter.CustomModifiers, out isBad);
}
/// <summary>
......@@ -165,7 +165,7 @@ public bool TryGetWellKnownAttribute(WellKnownAttributeFlags flag, out bool valu
ParamInfo<TypeSymbol> parameter,
out bool isBad)
{
return Create(moduleSymbol, containingSymbol, ordinal, parameter.IsByRef, parameter.CountOfCustomModifiersPrecedingByRef, parameter.Type, handle, parameter.CustomModifiers, out isBad);
return Create(moduleSymbol, containingSymbol, ordinal, parameter.IsByRef, parameter.RefCustomModifiers, parameter.Type, handle, parameter.CustomModifiers, out isBad);
}
private PEParameterSymbol(
......@@ -253,42 +253,43 @@ private bool HasNameInMetadata
Symbol containingSymbol,
int ordinal,
bool isByRef,
ushort countOfCustomModifiersPrecedingByRef,
ImmutableArray<ModifierInfo<TypeSymbol>> refCustomModifiers,
TypeSymbol type,
ParameterHandle handle,
ImmutableArray<ModifierInfo<TypeSymbol>> customModifiers,
out bool isBad)
{
if (customModifiers.IsDefaultOrEmpty)
if (customModifiers.IsDefaultOrEmpty && refCustomModifiers.IsDefaultOrEmpty)
{
return new PEParameterSymbol(moduleSymbol, containingSymbol, ordinal, isByRef, type, handle, 0, out isBad);
}
return new PEParameterSymbolWithCustomModifiers(moduleSymbol, containingSymbol, ordinal, isByRef, countOfCustomModifiersPrecedingByRef, type, handle, customModifiers, out isBad);
return new PEParameterSymbolWithCustomModifiers(moduleSymbol, containingSymbol, ordinal, isByRef, refCustomModifiers, type, handle, customModifiers, out isBad);
}
private sealed class PEParameterSymbolWithCustomModifiers : PEParameterSymbol
{
private readonly ImmutableArray<CustomModifier> _customModifiers;
private readonly ushort _countOfCustomModifiersPrecedingByRef;
private readonly ImmutableArray<CustomModifier> _refCustomModifiers;
public PEParameterSymbolWithCustomModifiers(
PEModuleSymbol moduleSymbol,
Symbol containingSymbol,
int ordinal,
bool isByRef,
ushort countOfCustomModifiersPrecedingByRef,
ImmutableArray<ModifierInfo<TypeSymbol>> refCustomModifiers,
TypeSymbol type,
ParameterHandle handle,
ImmutableArray<ModifierInfo<TypeSymbol>> customModifiers,
out bool isBad) :
base(moduleSymbol, containingSymbol, ordinal, isByRef, type, handle, customModifiers.Length, out isBad)
base(moduleSymbol, containingSymbol, ordinal, isByRef, type, handle,
refCustomModifiers.NullToEmpty().Length + customModifiers.NullToEmpty().Length,
out isBad)
{
_customModifiers = CSharpCustomModifier.Convert(customModifiers);
_countOfCustomModifiersPrecedingByRef = countOfCustomModifiersPrecedingByRef;
_refCustomModifiers = CSharpCustomModifier.Convert(refCustomModifiers);
Debug.Assert(_countOfCustomModifiersPrecedingByRef == 0 || isByRef);
Debug.Assert(_countOfCustomModifiersPrecedingByRef <= _customModifiers.Length);
Debug.Assert(_refCustomModifiers.IsEmpty || isByRef);
}
public override ImmutableArray<CustomModifier> CustomModifiers
......@@ -299,11 +300,11 @@ public override ImmutableArray<CustomModifier> CustomModifiers
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return _countOfCustomModifiersPrecedingByRef;
return _refCustomModifiers;
}
}
}
......@@ -602,11 +603,11 @@ public override ImmutableArray<CustomModifier> CustomModifiers
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return 0;
return ImmutableArray<CustomModifier>.Empty;
}
}
......
......@@ -17,7 +17,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE
/// <summary>
/// The class to represent all properties imported from a PE/module.
/// </summary>
internal sealed class PEPropertySymbol
internal class PEPropertySymbol
: PropertySymbol
{
private readonly string _name;
......@@ -28,8 +28,6 @@ internal sealed class PEPropertySymbol
private readonly TypeSymbol _propertyType;
private readonly PEMethodSymbol _getMethod;
private readonly PEMethodSymbol _setMethod;
private readonly ImmutableArray<CustomModifier> _typeCustomModifiers;
private readonly ushort _countOfCustomModifiersPrecedingByRef;
private ImmutableArray<CSharpAttributeData> _lazyCustomAttributes;
private Tuple<CultureInfo, string> _lazyDocComment;
private DiagnosticInfo _lazyUseSiteDiagnostic = CSDiagnosticInfo.EmptyErrorInfo; // Indicates unknown state.
......@@ -53,7 +51,7 @@ private enum Flags : byte
CallMethodsDirectly = 4
}
internal PEPropertySymbol(
internal static PEPropertySymbol Create(
PEModuleSymbol moduleSymbol,
PENamedTypeSymbol containingType,
PropertyDefinitionHandle handle,
......@@ -64,6 +62,42 @@ private enum Flags : byte
Debug.Assert((object)containingType != null);
Debug.Assert(!handle.IsNil);
var metadataDecoder = new MetadataDecoder(moduleSymbol, containingType);
SignatureHeader callingConvention;
BadImageFormatException propEx;
var propertyParams = metadataDecoder.GetSignatureForProperty(handle, out callingConvention, out propEx);
Debug.Assert(propertyParams.Length > 0);
var returnInfo = propertyParams[0];
PEPropertySymbol result;
if (returnInfo.CustomModifiers.IsDefaultOrEmpty && returnInfo.RefCustomModifiers.IsDefaultOrEmpty)
{
result = new PEPropertySymbol(moduleSymbol, containingType, handle, getMethod, setMethod, 0, propertyParams, metadataDecoder);
}
else
{
result = new PEPropertySymbolWithCustomModifiers(moduleSymbol, containingType, handle, getMethod, setMethod, propertyParams, metadataDecoder);
}
if (propEx != null)
{
result._lazyUseSiteDiagnostic = new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, result);
}
return result;
}
private PEPropertySymbol(
PEModuleSymbol moduleSymbol,
PENamedTypeSymbol containingType,
PropertyDefinitionHandle handle,
PEMethodSymbol getMethod,
PEMethodSymbol setMethod,
int countOfCustomModifiers,
ParamInfo<TypeSymbol>[] propertyParams,
MetadataDecoder metadataDecoder)
{
_containingType = containingType;
var module = moduleSymbol.Module;
PropertyAttributes mdFlags = 0;
......@@ -87,12 +121,6 @@ private enum Flags : byte
_setMethod = setMethod;
_handle = handle;
var metadataDecoder = new MetadataDecoder(moduleSymbol, containingType);
SignatureHeader callingConvention;
BadImageFormatException propEx;
var propertyParams = metadataDecoder.GetSignatureForProperty(handle, out callingConvention, out propEx);
Debug.Assert(propertyParams.Length > 0);
SignatureHeader unusedCallingConvention;
BadImageFormatException getEx = null;
var getMethodParams = (object)getMethod == null ? null : metadataDecoder.GetSignatureForMethod(getMethod.Handle, out unusedCallingConvention, out getEx);
......@@ -105,19 +133,17 @@ private enum Flags : byte
bool isBad;
_parameters = GetParameters(moduleSymbol, this, propertyParams, setMethodParams ?? getMethodParams, out isBad);
if (propEx != null || getEx != null || setEx != null || mrEx != null || isBad)
if (getEx != null || setEx != null || mrEx != null || isBad)
{
_lazyUseSiteDiagnostic = new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this);
}
var returnInfo = propertyParams[0];
_typeCustomModifiers = CSharpCustomModifier.Convert(returnInfo.CustomModifiers);
_countOfCustomModifiersPrecedingByRef = returnInfo.CountOfCustomModifiersPrecedingByRef;
_refKind = returnInfo.IsByRef ? RefKind.Ref : RefKind.None;
// CONSIDER: Can we make parameter type computation lazy?
TypeSymbol originalPropertyType = returnInfo.Type;
_propertyType = DynamicTypeDecoder.TransformType(originalPropertyType, _typeCustomModifiers.Length, handle, moduleSymbol, _refKind);
_propertyType = DynamicTypeDecoder.TransformType(originalPropertyType, countOfCustomModifiers, handle, moduleSymbol, _refKind);
// Dynamify object type if necessary
_propertyType = _propertyType.AsDynamicIfNoPia(_containingType);
......@@ -441,12 +467,12 @@ public override TypeSymbol Type
public override ImmutableArray<CustomModifier> TypeCustomModifiers
{
get { return _typeCustomModifiers; }
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return _countOfCustomModifiersPrecedingByRef; }
get { return ImmutableArray<CustomModifier>.Empty; }
}
public override MethodSymbol GetMethod
......@@ -676,5 +702,38 @@ internal override bool HasRuntimeSpecialName
{
get { return null; }
}
private sealed class PEPropertySymbolWithCustomModifiers : PEPropertySymbol
{
private readonly ImmutableArray<CustomModifier> _typeCustomModifiers;
private readonly ImmutableArray<CustomModifier> _refCustomModifiers;
public PEPropertySymbolWithCustomModifiers(
PEModuleSymbol moduleSymbol,
PENamedTypeSymbol containingType,
PropertyDefinitionHandle handle,
PEMethodSymbol getMethod,
PEMethodSymbol setMethod,
ParamInfo<TypeSymbol>[] propertyParams,
MetadataDecoder metadataDecoder)
: base (moduleSymbol, containingType, handle, getMethod, setMethod,
propertyParams[0].CustomModifiers.NullToEmpty().Length + propertyParams[0].RefCustomModifiers.NullToEmpty().Length,
propertyParams, metadataDecoder)
{
var returnInfo = propertyParams[0];
_typeCustomModifiers = CSharpCustomModifier.Convert(returnInfo.CustomModifiers);
_refCustomModifiers = CSharpCustomModifier.Convert(returnInfo.RefCustomModifiers);
}
public override ImmutableArray<CustomModifier> TypeCustomModifiers
{
get { return _typeCustomModifiers; }
}
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return _refCustomModifiers; }
}
}
}
}
......@@ -275,16 +275,14 @@ internal virtual bool IsExplicitInterfaceImplementation
public abstract ImmutableArray<MethodSymbol> ExplicitInterfaceImplementations { get; }
/// <summary>
/// Returns the list of custom modifiers, if any, associated with the returned value.
/// Returns the list of custom modifiers, if any, associated with the return type.
/// </summary>
public abstract ImmutableArray<CustomModifier> ReturnTypeCustomModifiers { get; }
/// <summary>
/// In order to avoid breaking interop scenarios, we need to support signatures
/// with modifiers preceding ByRef.
/// Should be 0 for non-ref returns.
/// Custom modifiers associated with the ref modifier, or an empty array if there are none.
/// </summary>
internal abstract ushort CountOfCustomModifiersPrecedingByRef { get; }
public abstract ImmutableArray<CustomModifier> RefCustomModifiers { get; }
/// <summary>
/// Gets the attributes on method's return type.
......@@ -872,6 +870,7 @@ internal bool CalculateUseSiteDiagnostic(ref DiagnosticInfo result)
// Check return type, custom modifiers, parameters
if (DeriveUseSiteDiagnosticFromType(ref result, this.ReturnType) ||
DeriveUseSiteDiagnosticFromCustomModifiers(ref result, this.RefCustomModifiers) ||
DeriveUseSiteDiagnosticFromCustomModifiers(ref result, this.ReturnTypeCustomModifiers) ||
DeriveUseSiteDiagnosticFromParameters(ref result, this.Parameters))
{
......@@ -885,6 +884,7 @@ internal bool CalculateUseSiteDiagnostic(ref DiagnosticInfo result)
HashSet<TypeSymbol> unificationCheckedTypes = null;
if (this.ReturnType.GetUnificationUseSiteDiagnosticRecursive(ref result, this, ref unificationCheckedTypes) ||
GetUnificationUseSiteDiagnosticRecursive(ref result, this.RefCustomModifiers, this, ref unificationCheckedTypes) ||
GetUnificationUseSiteDiagnosticRecursive(ref result, this.ReturnTypeCustomModifiers, this, ref unificationCheckedTypes) ||
GetUnificationUseSiteDiagnosticRecursive(ref result, this.Parameters, this, ref unificationCheckedTypes) ||
GetUnificationUseSiteDiagnosticRecursive(ref result, this.TypeParameters, this, ref unificationCheckedTypes))
......@@ -1152,6 +1152,14 @@ ImmutableArray<CustomModifier> IMethodSymbol.ReturnTypeCustomModifiers
}
}
ImmutableArray<CustomModifier> IMethodSymbol.RefCustomModifiers
{
get
{
return this.RefCustomModifiers;
}
}
ImmutableArray<AttributeData> IMethodSymbol.GetReturnTypeAttributes()
{
return this.GetReturnTypeAttributes().Cast<CSharpAttributeData, AttributeData>();
......
......@@ -570,7 +570,7 @@ private static OverriddenOrHiddenMembersResult MakeInterfaceOverriddenOrHiddenMe
// exact and so we would already have applied the custom modifier count as a tie-breaker.
foreach (ParameterSymbol param in currTypeBestMatch.GetParameters())
{
Debug.Assert(!param.CustomModifiers.Any());
Debug.Assert(!(param.CustomModifiers.Any() || param.RefCustomModifiers.Any()));
Debug.Assert(!param.Type.HasCustomModifiers(flagNonDefaultArraySizesOrLowerBounds: false));
}
#endif
......@@ -823,10 +823,12 @@ private static bool TypeOrReturnTypeHasCustomModifiers(Symbol member)
{
case SymbolKind.Method:
MethodSymbol method = (MethodSymbol)member;
return method.ReturnTypeCustomModifiers.Any() || method.ReturnType.HasCustomModifiers(flagNonDefaultArraySizesOrLowerBounds: false);
return method.ReturnTypeCustomModifiers.Any() || method.RefCustomModifiers.Any() ||
method.ReturnType.HasCustomModifiers(flagNonDefaultArraySizesOrLowerBounds: false);
case SymbolKind.Property:
PropertySymbol property = (PropertySymbol)member;
return property.TypeCustomModifiers.Any() || property.Type.HasCustomModifiers(flagNonDefaultArraySizesOrLowerBounds: false);
return property.TypeCustomModifiers.Any() || property.RefCustomModifiers.Any() ||
property.Type.HasCustomModifiers(flagNonDefaultArraySizesOrLowerBounds: false);
case SymbolKind.Event:
EventSymbol @event = (EventSymbol)member;
return @event.Type.HasCustomModifiers(flagNonDefaultArraySizesOrLowerBounds: false); //can't have custom modifiers on (vs in) type
......
......@@ -55,10 +55,15 @@ protected override sealed Symbol OriginalSymbolDefinition
public abstract RefKind RefKind { get; }
/// <summary>
/// The list of custom modifiers, if any, associated with the parameter.
/// The list of custom modifiers, if any, associated with the parameter type.
/// </summary>
public abstract ImmutableArray<CustomModifier> CustomModifiers { get; }
/// <summary>
/// Custom modifiers associated with the ref modifier, or an empty array if there are none.
/// </summary>
public abstract ImmutableArray<CustomModifier> RefCustomModifiers { get; }
/// <summary>
/// Describes how the parameter is marshalled when passed to native code.
/// Null if no specific marshalling information is available for the parameter.
......@@ -387,14 +392,6 @@ public sealed override bool HasUnsupportedMetadata
}
}
/// <summary>
/// The CLI spec says that custom modifiers must precede the ByRef type code in the encoding of a parameter.
/// Unfortunately, the managed C++ compiler emits them in the reverse order. In order to avoid breaking
/// interop scenarios, we need to support such signatures.
/// Should be 0 for non-ref parameters.
/// </summary>
internal abstract ushort CountOfCustomModifiersPrecedingByRef { get; }
#region IParameterSymbol Members
ITypeSymbol IParameterSymbol.Type
......@@ -407,6 +404,11 @@ ImmutableArray<CustomModifier> IParameterSymbol.CustomModifiers
get { return this.CustomModifiers; }
}
ImmutableArray<CustomModifier> IParameterSymbol.RefCustomModifiers
{
get { return this.RefCustomModifiers; }
}
IParameterSymbol IParameterSymbol.OriginalDefinition
{
get { return this.OriginalDefinition; }
......
......@@ -71,11 +71,9 @@ protected override sealed Symbol OriginalSymbolDefinition
public abstract ImmutableArray<CustomModifier> TypeCustomModifiers { get; }
/// <summary>
/// In order to avoid breaking interop scenarios, we need to support signatures
/// with modifiers preceding ByRef.
/// Should be 0 for non-ref returns.
/// Custom modifiers associated with the ref modifier, or an empty array if there are none.
/// </summary>
internal abstract ushort CountOfCustomModifiersPrecedingByRef { get; }
public abstract ImmutableArray<CustomModifier> RefCustomModifiers { get; }
/// <summary>
/// The parameters of this property. If this property has no parameters, returns
......@@ -340,6 +338,7 @@ internal bool CalculateUseSiteDiagnostic(ref DiagnosticInfo result)
// Check return type, custom modifiers and parameters:
if (DeriveUseSiteDiagnosticFromType(ref result, this.Type) ||
DeriveUseSiteDiagnosticFromCustomModifiers(ref result, this.RefCustomModifiers) ||
DeriveUseSiteDiagnosticFromCustomModifiers(ref result, this.TypeCustomModifiers) ||
DeriveUseSiteDiagnosticFromParameters(ref result, this.Parameters))
{
......@@ -352,6 +351,7 @@ internal bool CalculateUseSiteDiagnostic(ref DiagnosticInfo result)
{
HashSet<TypeSymbol> unificationCheckedTypes = null;
if (this.Type.GetUnificationUseSiteDiagnosticRecursive(ref result, this, ref unificationCheckedTypes) ||
GetUnificationUseSiteDiagnosticRecursive(ref result, this.RefCustomModifiers, this, ref unificationCheckedTypes) ||
GetUnificationUseSiteDiagnosticRecursive(ref result, this.TypeCustomModifiers, this, ref unificationCheckedTypes) ||
GetUnificationUseSiteDiagnosticRecursive(ref result, this.Parameters, this, ref unificationCheckedTypes))
{
......@@ -469,6 +469,11 @@ ImmutableArray<CustomModifier> IPropertySymbol.TypeCustomModifiers
get { return this.TypeCustomModifiers; }
}
ImmutableArray<CustomModifier> IPropertySymbol.RefCustomModifiers
{
get { return this.RefCustomModifiers; }
}
#endregion
#region ISymbol Members
......
......@@ -346,9 +346,9 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
get { return _typeMap.SubstituteCustomModifiers(_reducedFrom.ReturnType, _reducedFrom.ReturnTypeCustomModifiers); }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return _reducedFrom.CountOfCustomModifiersPrecedingByRef; }
get { return _typeMap.SubstituteCustomModifiers(_reducedFrom.RefCustomModifiers); }
}
internal override int ParameterCount
......@@ -467,6 +467,14 @@ public override ImmutableArray<CustomModifier> CustomModifiers
}
}
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return _containingMethod._typeMap.SubstituteCustomModifiers(this._underlyingParameter.RefCustomModifiers);
}
}
public sealed override bool Equals(object obj)
{
if ((object)this == obj)
......
......@@ -35,7 +35,7 @@ internal sealed class RetargetingMethodSymbol : WrappedMethodSymbol
private ImmutableArray<ParameterSymbol> _lazyParameters;
private ImmutableArray<CustomModifier> _lazyCustomModifiers;
private CustomModifiersTuple _lazyCustomModifiers;
/// <summary>
/// Retargeted custom attributes
......@@ -147,17 +147,25 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
{
get
{
return RetargetingTranslator.RetargetModifiers(
_underlyingMethod.ReturnTypeCustomModifiers,
ref _lazyCustomModifiers);
return CustomModifiersTuple.TypeCustomModifiers;
}
}
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return CustomModifiersTuple.RefCustomModifiers;
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
private CustomModifiersTuple CustomModifiersTuple
{
get
{
return _underlyingMethod.CountOfCustomModifiersPrecedingByRef;
return RetargetingTranslator.RetargetModifiers(
_underlyingMethod.ReturnTypeCustomModifiers, _underlyingMethod.RefCustomModifiers,
ref _lazyCustomModifiers);
}
}
......
......@@ -17,7 +17,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols.Retargeting
/// </summary>
internal abstract class RetargetingParameterSymbol : WrappedParameterSymbol
{
private ImmutableArray<CustomModifier> _lazyCustomModifiers;
private CustomModifiersTuple _lazyCustomModifiers;
/// <summary>
/// Retargeted custom attributes
......@@ -44,11 +44,27 @@ public sealed override TypeSymbol Type
}
public sealed override ImmutableArray<CustomModifier> CustomModifiers
{
get
{
return CustomModifiersTuple.TypeCustomModifiers;
}
}
public sealed override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return CustomModifiersTuple.RefCustomModifiers;
}
}
private CustomModifiersTuple CustomModifiersTuple
{
get
{
return RetargetingModule.RetargetingTranslator.RetargetModifiers(
_underlyingParameter.CustomModifiers,
_underlyingParameter.CustomModifiers, _underlyingParameter.RefCustomModifiers,
ref _lazyCustomModifiers);
}
}
......
......@@ -24,7 +24,7 @@ internal sealed class RetargetingPropertySymbol : WrappedPropertySymbol
//we want to compute this lazily since it may be expensive for the underlying symbol
private ImmutableArray<PropertySymbol> _lazyExplicitInterfaceImplementations;
private ImmutableArray<ParameterSymbol> _lazyParameters;
private ImmutableArray<CustomModifier> _lazyTypeCustomModifiers;
private CustomModifiersTuple _lazyCustomModifiers;
/// <summary>
/// Retargeted custom attributes
......@@ -77,17 +77,25 @@ public override ImmutableArray<CustomModifier> TypeCustomModifiers
{
get
{
return RetargetingTranslator.RetargetModifiers(
_underlyingProperty.TypeCustomModifiers,
ref _lazyTypeCustomModifiers);
return CustomModifiersTuple.TypeCustomModifiers;
}
}
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return CustomModifiersTuple.RefCustomModifiers;
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
private CustomModifiersTuple CustomModifiersTuple
{
get
{
return _underlyingProperty.CountOfCustomModifiersPrecedingByRef;
return RetargetingTranslator.RetargetModifiers(
_underlyingProperty.TypeCustomModifiers, _underlyingProperty.RefCustomModifiers,
ref _lazyCustomModifiers);
}
}
......
......@@ -701,36 +701,34 @@ public ArrayTypeSymbol Retarget(ArrayTypeSymbol type)
internal ImmutableArray<CustomModifier> RetargetModifiers(ImmutableArray<CustomModifier> oldModifiers, out bool modifiersHaveChanged)
{
int i;
int count = oldModifiers.Length;
modifiersHaveChanged = false;
ArrayBuilder<CustomModifier> newModifiers = null;
if (count != 0)
for (int i = 0; i < oldModifiers.Length; i++)
{
CustomModifier[] newModifiers = new CustomModifier[count];
var oldModifier = oldModifiers[i];
NamedTypeSymbol newModifier = Retarget((NamedTypeSymbol)oldModifier.Modifier, RetargetOptions.RetargetPrimitiveTypesByName); // should be retargeted by name
for (i = 0; i < count; i++)
if (!newModifier.Equals(oldModifier.Modifier))
{
var oldModifier = oldModifiers[i];
NamedTypeSymbol newModifier = Retarget((NamedTypeSymbol)oldModifier.Modifier, RetargetOptions.RetargetPrimitiveTypesByName); // should be retargeted by name
if (!newModifier.Equals(oldModifier.Modifier))
if (newModifiers == null)
{
modifiersHaveChanged = true;
newModifiers[i] = oldModifier.IsOptional ?
CSharpCustomModifier.CreateOptional(newModifier) :
CSharpCustomModifier.CreateRequired(newModifier);
newModifiers = ArrayBuilder<CustomModifier>.GetInstance(oldModifiers.Length);
newModifiers.AddRange(oldModifiers, i);
}
else
{
newModifiers[i] = oldModifier;
}
}
return newModifiers.AsImmutableOrNull();
newModifiers.Add(oldModifier.IsOptional ?
CSharpCustomModifier.CreateOptional(newModifier) :
CSharpCustomModifier.CreateRequired(newModifier));
}
else if (newModifiers != null)
{
newModifiers.Add(oldModifier);
}
}
return oldModifiers;
Debug.Assert(newModifiers == null || newModifiers.Count == oldModifiers.Length);
modifiersHaveChanged = (newModifiers != null);
return modifiersHaveChanged ? newModifiers.ToImmutableAndFree() : oldModifiers;
}
public PointerTypeSymbol Retarget(PointerTypeSymbol type)
......@@ -923,7 +921,7 @@ private static MethodSymbol FindWorker
IEqualityComparer<MethodSymbol> retargetedMethodComparer
)
{
bool modifiersHaveChanged; //ignored
bool modifiersHaveChanged_Ignored; //ignored
var targetParamsBuilder = ArrayBuilder<ParameterSymbol>.GetInstance(method.Parameters.Length);
foreach (var param in method.Parameters)
......@@ -931,7 +929,8 @@ IEqualityComparer<MethodSymbol> retargetedMethodComparer
targetParamsBuilder.Add(
new SignatureOnlyParameterSymbol(
translator.Retarget(param.Type, RetargetOptions.RetargetPrimitiveTypesByTypeCode),
translator.RetargetModifiers(param.CustomModifiers, out modifiersHaveChanged),
translator.RetargetModifiers(param.CustomModifiers, out modifiersHaveChanged_Ignored),
translator.RetargetModifiers(param.RefCustomModifiers, out modifiersHaveChanged_Ignored),
param.IsParams,
param.RefKind));
}
......@@ -949,8 +948,8 @@ IEqualityComparer<MethodSymbol> retargetedMethodComparer
targetParamsBuilder.ToImmutableAndFree(),
method.RefKind,
translator.Retarget(method.ReturnType, RetargetOptions.RetargetPrimitiveTypesByTypeCode),
translator.RetargetModifiers(method.ReturnTypeCustomModifiers, out modifiersHaveChanged),
method.CountOfCustomModifiersPrecedingByRef,
translator.RetargetModifiers(method.ReturnTypeCustomModifiers, out modifiersHaveChanged_Ignored),
translator.RetargetModifiers(method.RefCustomModifiers, out modifiersHaveChanged_Ignored),
ImmutableArray<MethodSymbol>.Empty);
foreach (var retargetedMember in retargetedType.GetMembers(method.Name))
......@@ -985,7 +984,7 @@ public override TypeParameterSymbol Retarget(TypeParameterSymbol typeParameter)
private PropertySymbol FindPropertyInRetargetedType(PropertySymbol property, NamedTypeSymbol retargetedType, IEqualityComparer<PropertySymbol> retargetedPropertyComparer)
{
bool modifiersHaveChanged; //ignored
bool modifiersHaveChanged_Ignored; //ignored
var targetParamsBuilder = ArrayBuilder<ParameterSymbol>.GetInstance(property.Parameters.Length);
foreach (var param in property.Parameters)
......@@ -993,7 +992,8 @@ private PropertySymbol FindPropertyInRetargetedType(PropertySymbol property, Nam
targetParamsBuilder.Add(
new SignatureOnlyParameterSymbol(
Retarget(param.Type, RetargetOptions.RetargetPrimitiveTypesByTypeCode),
RetargetModifiers(param.CustomModifiers, out modifiersHaveChanged),
RetargetModifiers(param.CustomModifiers, out modifiersHaveChanged_Ignored),
RetargetModifiers(param.RefCustomModifiers, out modifiersHaveChanged_Ignored),
param.IsParams,
param.RefKind));
}
......@@ -1004,8 +1004,8 @@ private PropertySymbol FindPropertyInRetargetedType(PropertySymbol property, Nam
targetParamsBuilder.ToImmutableAndFree(),
property.RefKind,
Retarget(property.Type, RetargetOptions.RetargetPrimitiveTypesByTypeCode),
RetargetModifiers(property.TypeCustomModifiers, out modifiersHaveChanged),
property.CountOfCustomModifiersPrecedingByRef,
RetargetModifiers(property.TypeCustomModifiers, out modifiersHaveChanged_Ignored),
RetargetModifiers(property.RefCustomModifiers, out modifiersHaveChanged_Ignored),
property.IsStatic,
ImmutableArray<PropertySymbol>.Empty);
......@@ -1051,13 +1051,24 @@ private EventSymbol FindEventInRetargetedType(EventSymbol @event, NamedTypeSymbo
{
bool modifiersHaveChanged;
ImmutableArray<CustomModifier> newModifiers = this.RetargetModifiers(oldModifiers, out modifiersHaveChanged);
ImmutableInterlocked.InterlockedCompareExchange(ref lazyCustomModifiers, newModifiers, default(ImmutableArray<CustomModifier>));
}
if (!modifiersHaveChanged)
{
newModifiers = oldModifiers;
}
return lazyCustomModifiers;
}
ImmutableInterlocked.InterlockedCompareExchange(ref lazyCustomModifiers, newModifiers, default(ImmutableArray<CustomModifier>));
internal CustomModifiersTuple RetargetModifiers(
ImmutableArray<CustomModifier> oldTypeModifiers,
ImmutableArray<CustomModifier> oldRefModifiers,
ref CustomModifiersTuple lazyCustomModifiers)
{
if (lazyCustomModifiers == null)
{
bool modifiersHaveChanged;
ImmutableArray<CustomModifier> newTypeModifiers = this.RetargetModifiers(oldTypeModifiers, out modifiersHaveChanged);
ImmutableArray<CustomModifier> newRefModifiers = this.RetargetModifiers(oldRefModifiers, out modifiersHaveChanged);
System.Threading.Interlocked.CompareExchange(ref lazyCustomModifiers, CustomModifiersTuple.Create(newTypeModifiers, newRefModifiers), null);
}
return lazyCustomModifiers;
......
......@@ -23,7 +23,7 @@ internal sealed class SignatureOnlyMethodSymbol : MethodSymbol
private readonly RefKind _refKind;
private readonly TypeSymbol _returnType;
private readonly ImmutableArray<CustomModifier> _returnTypeCustomModifiers;
private readonly ushort _countOfCustomModifiersPrecedingByRef;
private readonly ImmutableArray<CustomModifier> _refCustomModifiers;
private readonly ImmutableArray<MethodSymbol> _explicitInterfaceImplementations;
public SignatureOnlyMethodSymbol(
......@@ -36,7 +36,7 @@ internal sealed class SignatureOnlyMethodSymbol : MethodSymbol
RefKind refKind,
TypeSymbol returnType,
ImmutableArray<CustomModifier> returnTypeCustomModifiers,
ushort countOfCustomModifiersPrecedingByRef,
ImmutableArray<CustomModifier> refCustomModifiers,
ImmutableArray<MethodSymbol> explicitInterfaceImplementations)
{
_callingConvention = callingConvention;
......@@ -44,7 +44,7 @@ internal sealed class SignatureOnlyMethodSymbol : MethodSymbol
_refKind = refKind;
_returnType = returnType;
_returnTypeCustomModifiers = returnTypeCustomModifiers;
_countOfCustomModifiersPrecedingByRef = countOfCustomModifiersPrecedingByRef;
_refCustomModifiers = refCustomModifiers;
_parameters = parameters;
_explicitInterfaceImplementations = explicitInterfaceImplementations.NullToEmpty();
_containingType = containingType;
......@@ -70,7 +70,7 @@ internal sealed class SignatureOnlyMethodSymbol : MethodSymbol
public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers { get { return _returnTypeCustomModifiers; } }
internal override ushort CountOfCustomModifiersPrecedingByRef { get { return _countOfCustomModifiersPrecedingByRef; } }
public override ImmutableArray<CustomModifier> RefCustomModifiers { get { return _refCustomModifiers; } }
public override ImmutableArray<ParameterSymbol> Parameters { get { return _parameters; } }
......
......@@ -2,6 +2,7 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Symbols
......@@ -13,20 +14,24 @@ internal sealed class SignatureOnlyParameterSymbol : ParameterSymbol
{
private readonly TypeSymbol _type;
private readonly ImmutableArray<CustomModifier> _customModifiers;
private readonly ImmutableArray<CustomModifier> _refCustomModifiers;
private readonly bool _isParams;
private readonly RefKind _refKind;
public SignatureOnlyParameterSymbol(
TypeSymbol type,
ImmutableArray<CustomModifier> customModifiers,
ImmutableArray<CustomModifier> refCustomModifiers,
bool isParams,
RefKind refKind)
{
Debug.Assert(type != null);
Debug.Assert(!customModifiers.IsDefault);
Debug.Assert(!refCustomModifiers.IsDefault);
_type = type;
_customModifiers = customModifiers;
_refCustomModifiers = refCustomModifiers;
_isParams = isParams;
_refKind = refKind;
}
......@@ -35,6 +40,8 @@ internal sealed class SignatureOnlyParameterSymbol : ParameterSymbol
public override ImmutableArray<CustomModifier> CustomModifiers { get { return _customModifiers; } }
public override ImmutableArray<CustomModifier> RefCustomModifiers { get { return _refCustomModifiers; } }
public override bool IsParams { get { return _isParams; } }
public override RefKind RefKind { get { return _refKind; } }
......@@ -70,8 +77,6 @@ public override bool IsImplicitlyDeclared
internal override bool IsCallerMemberName { get { throw ExceptionUtilities.Unreachable; } }
internal sealed override ushort CountOfCustomModifiersPrecedingByRef { get { return 0; } }
public override Symbol ContainingSymbol { get { throw ExceptionUtilities.Unreachable; } }
public override ImmutableArray<Location> Locations { get { throw ExceptionUtilities.Unreachable; } }
......@@ -94,7 +99,8 @@ public override bool Equals(object obj)
var other = obj as SignatureOnlyParameterSymbol;
return (object)other != null &&
_type == other._type &&
_customModifiers.Equals(other._customModifiers) &&
_customModifiers.SequenceEqual(other._customModifiers) &&
_refCustomModifiers.SequenceEqual(other._refCustomModifiers) &&
_isParams == other._isParams &&
_refKind == other._refKind;
}
......@@ -104,10 +110,8 @@ public override int GetHashCode()
return Hash.Combine(
_type.GetHashCode(),
Hash.Combine(
Hash.CombineValues(_customModifiers),
Hash.Combine(
_isParams.GetHashCode(),
_refKind.GetHashCode())));
_isParams.GetHashCode(),
_refKind.GetHashCode()));
}
}
}
......@@ -22,7 +22,7 @@ internal sealed class SignatureOnlyPropertySymbol : PropertySymbol
private readonly RefKind _refKind;
private readonly TypeSymbol _type;
private readonly ImmutableArray<CustomModifier> _typeCustomModifiers;
private readonly ushort _countOfCustomModifiersPrecedingByRef;
private readonly ImmutableArray<CustomModifier> _refCustomModifiers;
private readonly bool _isStatic;
private readonly ImmutableArray<PropertySymbol> _explicitInterfaceImplementations;
......@@ -33,14 +33,14 @@ internal sealed class SignatureOnlyPropertySymbol : PropertySymbol
RefKind refKind,
TypeSymbol type,
ImmutableArray<CustomModifier> typeCustomModifiers,
ushort countOfCustomModifiersPrecedingByRef,
ImmutableArray<CustomModifier> refCustomModifiers,
bool isStatic,
ImmutableArray<PropertySymbol> explicitInterfaceImplementations)
{
_refKind = refKind;
_type = type;
_typeCustomModifiers = typeCustomModifiers;
_countOfCustomModifiersPrecedingByRef = countOfCustomModifiersPrecedingByRef;
_refCustomModifiers = refCustomModifiers;
_isStatic = isStatic;
_parameters = parameters;
_explicitInterfaceImplementations = explicitInterfaceImplementations.NullToEmpty();
......@@ -54,7 +54,7 @@ internal sealed class SignatureOnlyPropertySymbol : PropertySymbol
public override ImmutableArray<CustomModifier> TypeCustomModifiers { get { return _typeCustomModifiers; } }
internal override ushort CountOfCustomModifiersPrecedingByRef { get { return _countOfCustomModifiersPrecedingByRef; } }
public override ImmutableArray<CustomModifier> RefCustomModifiers { get { return _refCustomModifiers; } }
public override bool IsStatic { get { return _isStatic; } }
......
......@@ -18,8 +18,7 @@ internal static class CustomModifierUtils
MethodSymbol sourceMethod,
MethodSymbol destinationMethod,
out TypeSymbol returnType,
out ImmutableArray<CustomModifier> returnTypeCustomModifiers,
out ushort countOfCustomModifiersPrecedingByRef,
out CustomModifiersTuple customModifiers,
out ImmutableArray<ParameterSymbol> parameters,
bool alsoCopyParamsModifier) // Last since always named.
{
......@@ -36,8 +35,8 @@ internal static class CustomModifierUtils
// have already been compared.
MethodSymbol constructedSourceMethod = sourceMethod.ConstructIfGeneric(destinationMethod.TypeArguments);
returnTypeCustomModifiers = constructedSourceMethod.ReturnTypeCustomModifiers;
countOfCustomModifiersPrecedingByRef = destinationMethod.ReturnsByRef ? constructedSourceMethod.CountOfCustomModifiersPrecedingByRef : (ushort)0;
customModifiers = CustomModifiersTuple.Create(constructedSourceMethod.ReturnTypeCustomModifiers,
destinationMethod.ReturnsByRef ? constructedSourceMethod.RefCustomModifiers : ImmutableArray<CustomModifier>.Empty);
parameters = CopyParameterCustomModifiers(constructedSourceMethod.Parameters, destinationMethod.Parameters, alsoCopyParamsModifier);
......@@ -102,8 +101,10 @@ internal static ImmutableArray<ParameterSymbol> CopyParameterCustomModifiers(Imm
SourceParameterSymbolBase destinationParameter = (SourceParameterSymbolBase)destinationParameters[i];
ParameterSymbol sourceParameter = sourceParameters[i];
if (sourceParameter.CustomModifiers.Any() || sourceParameter.Type.HasCustomModifiers(flagNonDefaultArraySizesOrLowerBounds: true) ||
destinationParameter.CustomModifiers.Any() || destinationParameter.Type.HasCustomModifiers(flagNonDefaultArraySizesOrLowerBounds: true) || // Could happen if the associated property has custom modifiers.
if (sourceParameter.CustomModifiers.Any() || sourceParameter.RefCustomModifiers.Any() ||
sourceParameter.Type.HasCustomModifiers(flagNonDefaultArraySizesOrLowerBounds: true) ||
destinationParameter.CustomModifiers.Any() || destinationParameter.RefCustomModifiers.Any() ||
destinationParameter.Type.HasCustomModifiers(flagNonDefaultArraySizesOrLowerBounds: true) || // Could happen if the associated property has custom modifiers.
(alsoCopyParamsModifier && (sourceParameter.IsParams != destinationParameter.IsParams)))
{
if (builder == null)
......@@ -113,8 +114,9 @@ internal static ImmutableArray<ParameterSymbol> CopyParameterCustomModifiers(Imm
}
bool newParams = alsoCopyParamsModifier ? sourceParameter.IsParams : destinationParameter.IsParams;
builder.Add(destinationParameter.WithCustomModifiersAndParams(sourceParameter.Type, sourceParameter.CustomModifiers,
destinationParameter.RefKind != RefKind.None ? sourceParameter.CountOfCustomModifiersPrecedingByRef : (ushort)0,
builder.Add(destinationParameter.WithCustomModifiersAndParams(sourceParameter.Type,
sourceParameter.CustomModifiers,
destinationParameter.RefKind != RefKind.None ? sourceParameter.RefCustomModifiers : ImmutableArray<CustomModifier>.Empty,
newParams));
}
else if (builder != null)
......
......@@ -196,9 +196,9 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return 0; }
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override bool IsExplicitInterfaceImplementation
......@@ -341,7 +341,7 @@ public override bool HidesBaseMethodsByName
private static ParameterSymbol CopyParameter(ParameterSymbol parameter, MethodSymbol owner)
{
return new SynthesizedParameterSymbol(
return SynthesizedParameterSymbol.Create(
owner,
parameter.Type,
parameter.Ordinal,
......
......@@ -267,7 +267,7 @@ internal override TypeSymbol IteratorElementType
public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers => ImmutableArray<CustomModifier>.Empty;
internal override ushort CountOfCustomModifiersPrecedingByRef => 0;
public override ImmutableArray<CustomModifier> RefCustomModifiers => ImmutableArray<CustomModifier>.Empty;
internal override MethodImplAttributes ImplementationAttributes => default(MethodImplAttributes);
......
......@@ -70,10 +70,10 @@ internal override ConstantValue DefaultValueFromAttributes
get { return _originalParam.DefaultValueFromAttributes; }
}
internal override ParameterSymbol WithCustomModifiersAndParams(TypeSymbol newType, ImmutableArray<CustomModifier> newCustomModifiers, ushort countOfCustomModifiersPrecedingByRef, bool newIsParams)
internal override ParameterSymbol WithCustomModifiersAndParams(TypeSymbol newType, ImmutableArray<CustomModifier> newCustomModifiers, ImmutableArray<CustomModifier> newRefCustomModifiers, bool newIsParams)
{
return new SourceClonedParameterSymbol(
_originalParam.WithCustomModifiersAndParamsCore(newType, newCustomModifiers, countOfCustomModifiersPrecedingByRef, newIsParams),
_originalParam.WithCustomModifiersAndParamsCore(newType, newCustomModifiers, newRefCustomModifiers, newIsParams),
this.ContainingSymbol,
this.Ordinal,
_suppressOptional);
......@@ -121,6 +121,11 @@ public override ImmutableArray<CustomModifier> CustomModifiers
get { return _originalParam.CustomModifiers; }
}
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return _originalParam.RefCustomModifiers; }
}
internal override MarshalPseudoCustomAttributeData MarshallingInformation
{
get { return _originalParam.MarshallingInformation; }
......
......@@ -1038,11 +1038,11 @@ public override ImmutableArray<CustomModifier> CustomModifiers
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return 0;
return ImmutableArray<CustomModifier>.Empty;
}
}
......@@ -1058,7 +1058,7 @@ internal override void ForceComplete(SourceLocation locationOpt, CancellationTok
internal sealed class SourceComplexParameterSymbolWithCustomModifiers : SourceComplexParameterSymbol
{
private readonly ImmutableArray<CustomModifier> _customModifiers;
private readonly ushort _countOfCustomModifiersPrecedingByRef;
private readonly ImmutableArray<CustomModifier> _refCustomModifiers;
internal SourceComplexParameterSymbolWithCustomModifiers(
Symbol owner,
......@@ -1066,7 +1066,7 @@ internal sealed class SourceComplexParameterSymbolWithCustomModifiers : SourceCo
TypeSymbol parameterType,
RefKind refKind,
ImmutableArray<CustomModifier> customModifiers,
ushort countOfCustomModifiersPrecedingByRef,
ImmutableArray<CustomModifier> refCustomModifiers,
string name,
ImmutableArray<Location> locations,
SyntaxReference syntaxRef,
......@@ -1075,13 +1075,12 @@ internal sealed class SourceComplexParameterSymbolWithCustomModifiers : SourceCo
bool isExtensionMethodThis)
: base(owner, ordinal, parameterType, refKind, name, locations, syntaxRef, defaultSyntaxValue, isParams, isExtensionMethodThis)
{
Debug.Assert(!customModifiers.IsDefaultOrEmpty);
Debug.Assert(!customModifiers.IsEmpty || !refCustomModifiers.IsEmpty);
_customModifiers = customModifiers;
_countOfCustomModifiersPrecedingByRef = countOfCustomModifiersPrecedingByRef;
_refCustomModifiers = refCustomModifiers;
Debug.Assert(refKind != RefKind.None || _countOfCustomModifiersPrecedingByRef == 0);
Debug.Assert(_countOfCustomModifiersPrecedingByRef <= _customModifiers.Length);
Debug.Assert(refKind != RefKind.None || _refCustomModifiers.IsEmpty);
}
public override ImmutableArray<CustomModifier> CustomModifiers
......@@ -1092,11 +1091,11 @@ public override ImmutableArray<CustomModifier> CustomModifiers
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return _countOfCustomModifiersPrecedingByRef;
return _refCustomModifiers;
}
}
}
......
......@@ -197,8 +197,8 @@ private sealed class Constructor : SourceDelegateMethodSymbol
: base(delegateType, voidType, syntax, MethodKind.Constructor, DeclarationModifiers.Public)
{
InitializeParameters(ImmutableArray.Create<ParameterSymbol>(
new SynthesizedParameterSymbol(this, objectType, 0, RefKind.None, "object"),
new SynthesizedParameterSymbol(this, intPtrType, 1, RefKind.None, "method")));
SynthesizedParameterSymbol.Create(this, objectType, 0, RefKind.None, "object"),
SynthesizedParameterSymbol.Create(this, intPtrType, 1, RefKind.None, "method")));
}
public override string Name
......@@ -297,8 +297,8 @@ private sealed class BeginInvokeMethod : SourceDelegateMethodSymbol
}
int paramCount = invoke.ParameterCount;
parameters.Add(new SynthesizedParameterSymbol(this, asyncCallbackType, paramCount, RefKind.None, GetUniqueParameterName(parameters, "callback")));
parameters.Add(new SynthesizedParameterSymbol(this, objectType, paramCount + 1, RefKind.None, GetUniqueParameterName(parameters, "object")));
parameters.Add(SynthesizedParameterSymbol.Create(this, asyncCallbackType, paramCount, RefKind.None, GetUniqueParameterName(parameters, "callback")));
parameters.Add(SynthesizedParameterSymbol.Create(this, objectType, paramCount + 1, RefKind.None, GetUniqueParameterName(parameters, "object")));
InitializeParameters(parameters.ToImmutableAndFree());
}
......@@ -346,7 +346,7 @@ private sealed class EndInvokeMethod : SourceDelegateMethodSymbol
}
}
parameters.Add(new SynthesizedParameterSymbol(this, iAsyncResultType, ordinal++, RefKind.None, GetUniqueParameterName(parameters, "result")));
parameters.Add(SynthesizedParameterSymbol.Create(this, iAsyncResultType, ordinal++, RefKind.None, GetUniqueParameterName(parameters, "result")));
InitializeParameters(parameters.ToImmutableAndFree());
}
......
......@@ -134,11 +134,11 @@ public sealed override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public sealed override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return 0;
return ImmutableArray<CustomModifier>.Empty; // Same as base, but this is clear and explicit.
}
}
......
......@@ -20,8 +20,7 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol
private readonly RefKind _refKind;
private ImmutableArray<MethodSymbol> _lazyExplicitInterfaceImplementations;
private ImmutableArray<CustomModifier> _lazyReturnTypeCustomModifiers;
private ushort _lazyCountOfCustomModifiersPrecedingByRef;
private CustomModifiersTuple _lazyCustomModifiers;
private ImmutableArray<ParameterSymbol> _lazyParameters;
private TypeSymbol _lazyReturnType;
private bool _lazyIsVararg;
......@@ -269,6 +268,11 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB
// implementation) with the correct custom modifiers
// (see SourceNamedTypeSymbol.ImplementInterfaceMember).
// This value may not be correct, but we need something while we compute overridden/implemented method.
// May be re-assigned below.
Debug.Assert(_lazyCustomModifiers == null);
_lazyCustomModifiers = CustomModifiersTuple.Empty;
// Note: we're checking if the syntax indicates explicit implementation rather,
// than if explicitInterfaceType is null because we don't want to look for an
// overridden property if this is supposed to be an explicit implementation.
......@@ -277,13 +281,6 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB
Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
_lazyExplicitInterfaceImplementations = ImmutableArray<MethodSymbol>.Empty;
// This value may not be correct, but we need something while we compute this.OverriddenMethod.
// May be re-assigned below.
Debug.Assert(_lazyReturnTypeCustomModifiers.IsDefault);
Debug.Assert(_lazyCountOfCustomModifiersPrecedingByRef == 0);
_lazyReturnTypeCustomModifiers = ImmutableArray<CustomModifier>.Empty;
_lazyCountOfCustomModifiersPrecedingByRef = 0;
// If this method is an override, we may need to copy custom modifiers from
// the overridden method (so that the runtime will recognize it as an override).
// We check for this case here, while we can still modify the parameters and
......@@ -301,7 +298,7 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB
if ((object)overriddenMethod != null)
{
CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType,
out _lazyReturnTypeCustomModifiers, out _lazyCountOfCustomModifiersPrecedingByRef,
out _lazyCustomModifiers,
out _lazyParameters, alsoCopyParamsModifier: true);
}
}
......@@ -317,18 +314,13 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB
_lazyExplicitInterfaceImplementations = ImmutableArray.Create<MethodSymbol>(implementedMethod);
CustomModifierUtils.CopyMethodCustomModifiers(implementedMethod, this, out _lazyReturnType,
out _lazyReturnTypeCustomModifiers, out _lazyCountOfCustomModifiersPrecedingByRef,
out _lazyCustomModifiers,
out _lazyParameters, alsoCopyParamsModifier: false);
}
else
{
Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
_lazyExplicitInterfaceImplementations = ImmutableArray<MethodSymbol>.Empty;
Debug.Assert(_lazyReturnTypeCustomModifiers.IsDefault);
Debug.Assert(_lazyCountOfCustomModifiersPrecedingByRef == 0);
_lazyReturnTypeCustomModifiers = ImmutableArray<CustomModifier>.Empty;
_lazyCountOfCustomModifiersPrecedingByRef = 0;
}
}
......@@ -678,16 +670,16 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
get
{
LazyMethodChecks();
return _lazyReturnTypeCustomModifiers;
return _lazyCustomModifiers.TypeCustomModifiers;
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
LazyMethodChecks();
return _lazyCountOfCustomModifiersPrecedingByRef;
return _lazyCustomModifiers.RefCustomModifiers;
}
}
......
......@@ -602,11 +602,11 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return 0;
return ImmutableArray<CustomModifier>.Empty;
}
}
......@@ -962,7 +962,7 @@ internal override void AddSynthesizedReturnTypeAttributes(ref ArrayBuilder<Synth
if (this.ReturnType.ContainsDynamic())
{
var compilation = this.DeclaringCompilation;
AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.ReturnType, this.ReturnTypeCustomModifiers.Length, this.RefKind));
AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.ReturnType, this.ReturnTypeCustomModifiers.Length + this.RefCustomModifiers.Length, this.RefKind));
}
if (ReturnType.ContainsTupleNames())
......
......@@ -106,16 +106,16 @@ internal abstract class SourceParameterSymbol : SourceParameterSymbolBase
_locations = locations;
}
internal override ParameterSymbol WithCustomModifiersAndParams(TypeSymbol newType, ImmutableArray<CustomModifier> newCustomModifiers, ushort countOfCustomModifiersPrecedingByRef, bool newIsParams)
internal override ParameterSymbol WithCustomModifiersAndParams(TypeSymbol newType, ImmutableArray<CustomModifier> newCustomModifiers, ImmutableArray<CustomModifier> newRefCustomModifiers, bool newIsParams)
{
return WithCustomModifiersAndParamsCore(newType, newCustomModifiers, countOfCustomModifiersPrecedingByRef, newIsParams);
return WithCustomModifiersAndParamsCore(newType, newCustomModifiers, newRefCustomModifiers, newIsParams);
}
internal SourceParameterSymbol WithCustomModifiersAndParamsCore(TypeSymbol newType, ImmutableArray<CustomModifier> newCustomModifiers, ushort countOfCustomModifiersPrecedingByRef, bool newIsParams)
internal SourceParameterSymbol WithCustomModifiersAndParamsCore(TypeSymbol newType, ImmutableArray<CustomModifier> newCustomModifiers, ImmutableArray<CustomModifier> newRefCustomModifiers, bool newIsParams)
{
newType = CustomModifierUtils.CopyTypeCustomModifiers(newType, this.Type, this.ContainingAssembly);
if (newCustomModifiers.IsDefaultOrEmpty)
if (newCustomModifiers.IsEmpty && newRefCustomModifiers.IsEmpty)
{
return new SourceComplexParameterSymbol(
this.ContainingSymbol,
......@@ -136,7 +136,7 @@ internal SourceParameterSymbol WithCustomModifiersAndParamsCore(TypeSymbol newTy
newType,
_refKind,
newCustomModifiers,
countOfCustomModifiersPrecedingByRef,
newRefCustomModifiers,
_name,
_locations,
this.SyntaxReference,
......
......@@ -79,7 +79,7 @@ internal sealed override void AddSynthesizedAttributes(ModuleCompilationState co
if (this.Type.ContainsDynamic())
{
AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.Type, this.CustomModifiers.Length, this.RefKind));
AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.Type, this.CustomModifiers.Length + this.RefCustomModifiers.Length, this.RefKind));
}
if (Type.ContainsTupleNames())
......@@ -89,14 +89,6 @@ internal sealed override void AddSynthesizedAttributes(ModuleCompilationState co
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
{
get
{
return 0;
}
}
internal abstract ParameterSymbol WithCustomModifiersAndParams(TypeSymbol newType, ImmutableArray<CustomModifier> newCustomModifiers, ushort countOfCustomModifiersPrecedingByRef, bool newIsParams);
internal abstract ParameterSymbol WithCustomModifiersAndParams(TypeSymbol newType, ImmutableArray<CustomModifier> newCustomModifiers, ImmutableArray<CustomModifier> newRefCustomModifiers, bool newIsParams);
}
}
......@@ -16,8 +16,7 @@ internal sealed class SourcePropertyAccessorSymbol : SourceMethodSymbol
private readonly SourcePropertySymbol _property;
private ImmutableArray<ParameterSymbol> _lazyParameters;
private TypeSymbol _lazyReturnType;
private ImmutableArray<CustomModifier> _lazyReturnTypeCustomModifiers;
private ushort _lazyCountOfCustomModifiersPrecedingByRef;
private CustomModifiersTuple _lazyCustomModifiers;
private readonly ImmutableArray<MethodSymbol> _explicitInterfaceImplementations;
private readonly string _name;
private readonly bool _isAutoPropertyAccessor;
......@@ -261,15 +260,14 @@ protected override void MethodChecks(DiagnosticBag diagnostics)
// event that we need to find the overridden accessor.
_lazyParameters = ComputeParameters(diagnostics);
_lazyReturnType = ComputeReturnType(diagnostics);
_lazyReturnTypeCustomModifiers = ImmutableArray<CustomModifier>.Empty;
_lazyCountOfCustomModifiersPrecedingByRef = 0;
_lazyCustomModifiers = CustomModifiersTuple.Empty;
if (_explicitInterfaceImplementations.Length > 0)
{
Debug.Assert(_explicitInterfaceImplementations.Length == 1);
MethodSymbol implementedMethod = _explicitInterfaceImplementations[0];
CustomModifierUtils.CopyMethodCustomModifiers(implementedMethod, this, out _lazyReturnType,
out _lazyReturnTypeCustomModifiers, out _lazyCountOfCustomModifiersPrecedingByRef,
out _lazyCustomModifiers,
out _lazyParameters, alsoCopyParamsModifier: false);
}
else if (this.IsOverride)
......@@ -280,7 +278,7 @@ protected override void MethodChecks(DiagnosticBag diagnostics)
if ((object)overriddenMethod != null)
{
CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType,
out _lazyReturnTypeCustomModifiers, out _lazyCountOfCustomModifiersPrecedingByRef,
out _lazyCustomModifiers,
out _lazyParameters, alsoCopyParamsModifier: true);
}
}
......@@ -288,8 +286,7 @@ protected override void MethodChecks(DiagnosticBag diagnostics)
{
PropertySymbol associatedProperty = _property;
_lazyReturnType = CustomModifierUtils.CopyTypeCustomModifiers(associatedProperty.Type, _lazyReturnType, this.ContainingAssembly);
_lazyReturnTypeCustomModifiers = associatedProperty.TypeCustomModifiers;
_lazyCountOfCustomModifiersPrecedingByRef = associatedProperty.CountOfCustomModifiersPrecedingByRef;
_lazyCustomModifiers = CustomModifiersTuple.Create(associatedProperty.TypeCustomModifiers, associatedProperty.RefCustomModifiers);
}
}
......@@ -384,16 +381,16 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
get
{
LazyMethodChecks();
return _lazyReturnTypeCustomModifiers;
return _lazyCustomModifiers.TypeCustomModifiers;
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
LazyMethodChecks();
return _lazyCountOfCustomModifiersPrecedingByRef;
return _lazyCustomModifiers.RefCustomModifiers;
}
}
......
......@@ -24,8 +24,7 @@ internal sealed class SourcePropertySymbol : PropertySymbol, IAttributeTargetSym
private readonly SyntaxReference _syntaxRef;
private readonly Location _location;
private readonly DeclarationModifiers _modifiers;
private readonly ImmutableArray<CustomModifier> _typeCustomModifiers;
private readonly ushort _countOfCustomModifiersPrecedingByRef;
private readonly CustomModifiersTuple _customModifiers;
private readonly SourcePropertyAccessorSymbol _getMethod;
private readonly SourcePropertyAccessorSymbol _setMethod;
private readonly SynthesizedBackingFieldSymbol _backingField;
......@@ -192,8 +191,7 @@ internal sealed class SourcePropertySymbol : PropertySymbol, IAttributeTargetSym
}
PropertySymbol explicitlyImplementedProperty = null;
_typeCustomModifiers = ImmutableArray<CustomModifier>.Empty;
_countOfCustomModifiersPrecedingByRef = 0;
_customModifiers = CustomModifiersTuple.Empty;
// The runtime will not treat the accessors of this property as overrides or implementations
// of those of another property unless both the signatures and the custom modifiers match.
......@@ -238,8 +236,8 @@ internal sealed class SourcePropertySymbol : PropertySymbol, IAttributeTargetSym
if ((object)overriddenOrImplementedProperty != null)
{
_typeCustomModifiers = overriddenOrImplementedProperty.TypeCustomModifiers;
_countOfCustomModifiersPrecedingByRef = _refKind != RefKind.None ? overriddenOrImplementedProperty.CountOfCustomModifiersPrecedingByRef : (ushort)0;
_customModifiers = CustomModifiersTuple.Create(overriddenOrImplementedProperty.TypeCustomModifiers,
_refKind != RefKind.None ? overriddenOrImplementedProperty.RefCustomModifiers : ImmutableArray<CustomModifier>.Empty);
TypeSymbol overriddenPropertyType = overriddenOrImplementedProperty.Type;
......@@ -611,12 +609,12 @@ public override ImmutableArray<PropertySymbol> ExplicitInterfaceImplementations
public override ImmutableArray<CustomModifier> TypeCustomModifiers
{
get { return _typeCustomModifiers; }
get { return _customModifiers.TypeCustomModifiers; }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return _countOfCustomModifiersPrecedingByRef; }
get { return _customModifiers.RefCustomModifiers; }
}
public override Accessibility DeclaredAccessibility
......@@ -1055,7 +1053,7 @@ internal override void AddSynthesizedAttributes(ModuleCompilationState compilati
if (Type.ContainsDynamic())
{
AddSynthesizedAttribute(ref attributes,
DeclaringCompilation.SynthesizeDynamicAttribute(Type, TypeCustomModifiers.Length, _refKind));
DeclaringCompilation.SynthesizeDynamicAttribute(Type, TypeCustomModifiers.Length + RefCustomModifiers.Length, _refKind));
}
if (Type.ContainsTupleNames())
......
......@@ -53,6 +53,11 @@ public override ImmutableArray<CustomModifier> CustomModifiers
get { return ImmutableArray<CustomModifier>.Empty; }
}
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override SyntaxReference SyntaxReference
{
get { return null; }
......
......@@ -112,6 +112,11 @@ public override ImmutableArray<CustomModifier> CustomModifiers
get { return ImmutableArray<CustomModifier>.Empty; }
}
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return ImmutableArray<CustomModifier>.Empty; }
}
// TODO: structs
public override bool IsThis
{
......@@ -138,10 +143,5 @@ internal override MarshalPseudoCustomAttributeData MarshallingInformation
{
get { return null; }
}
internal sealed override ushort CountOfCustomModifiersPrecedingByRef
{
get { return 0; }
}
}
}
......@@ -252,11 +252,11 @@ public sealed override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public sealed override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return OriginalDefinition.CountOfCustomModifiersPrecedingByRef;
return Map.SubstituteCustomModifiers(OriginalDefinition.RefCustomModifiers);
}
}
......
......@@ -57,7 +57,9 @@ public override TypeSymbol Type
type = substituted.Type;
if (substituted.CustomModifiers.IsDefaultOrEmpty && this._underlyingParameter.CustomModifiers.IsDefaultOrEmpty)
if (substituted.CustomModifiers.IsEmpty &&
this._underlyingParameter.CustomModifiers.IsEmpty &&
this._underlyingParameter.RefCustomModifiers.IsEmpty)
{
_mapOrType = type;
}
......@@ -75,6 +77,15 @@ public override ImmutableArray<CustomModifier> CustomModifiers
}
}
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
var map = _mapOrType as TypeMap;
return map != null ? map.SubstituteCustomModifiers(this._underlyingParameter.RefCustomModifiers) : this._underlyingParameter.RefCustomModifiers;
}
}
public sealed override bool Equals(object obj)
{
if ((object)this == obj)
......
......@@ -69,9 +69,9 @@ public override ImmutableArray<CustomModifier> TypeCustomModifiers
get { return _containingType.TypeSubstitution.SubstituteCustomModifiers(OriginalDefinition.Type, OriginalDefinition.TypeCustomModifiers); }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return OriginalDefinition.CountOfCustomModifiersPrecedingByRef; }
get { return _containingType.TypeSubstitution.SubstituteCustomModifiers(OriginalDefinition.RefCustomModifiers); }
}
public override ImmutableArray<ParameterSymbol> Parameters
......
......@@ -916,6 +916,7 @@ internal bool DeriveUseSiteDiagnosticFromType(ref DiagnosticInfo result, TypeSym
internal bool DeriveUseSiteDiagnosticFromParameter(ref DiagnosticInfo result, ParameterSymbol param)
{
return DeriveUseSiteDiagnosticFromType(ref result, param.Type) ||
DeriveUseSiteDiagnosticFromCustomModifiers(ref result, param.RefCustomModifiers) ||
DeriveUseSiteDiagnosticFromCustomModifiers(ref result, param.CustomModifiers);
}
......@@ -984,6 +985,7 @@ internal static bool GetUnificationUseSiteDiagnosticRecursive(ref DiagnosticInfo
foreach (var parameter in parameters)
{
if (parameter.Type.GetUnificationUseSiteDiagnosticRecursive(ref result, owner, ref checkedTypes) ||
GetUnificationUseSiteDiagnosticRecursive(ref result, parameter.RefCustomModifiers, owner, ref checkedTypes) ||
GetUnificationUseSiteDiagnosticRecursive(ref result, parameter.CustomModifiers, owner, ref checkedTypes))
{
return true;
......
......@@ -336,15 +336,14 @@ internal static TypeSymbol GetTypeOrReturnType(this Symbol symbol)
{
RefKind refKind;
TypeSymbol returnType;
ImmutableArray<CustomModifier> returnTypeCustomModifiers;
ushort countOfCustomModifiersPrecedingByRef;
GetTypeOrReturnType(symbol, out refKind, out returnType, out returnTypeCustomModifiers, out countOfCustomModifiersPrecedingByRef);
ImmutableArray<CustomModifier> customModifiers_Ignored;
GetTypeOrReturnType(symbol, out refKind, out returnType, out customModifiers_Ignored, out customModifiers_Ignored);
return returnType;
}
internal static void GetTypeOrReturnType(this Symbol symbol, out RefKind refKind, out TypeSymbol returnType,
out ImmutableArray<CustomModifier> returnTypeCustomModifiers,
out ushort countOfCustomModifiersPrecedingByRef)
out ImmutableArray<CustomModifier> refCustomModifiers)
{
switch (symbol.Kind)
{
......@@ -353,35 +352,35 @@ internal static TypeSymbol GetTypeOrReturnType(this Symbol symbol)
refKind = RefKind.None;
returnType = field.Type;
returnTypeCustomModifiers = field.CustomModifiers;
countOfCustomModifiersPrecedingByRef = 0;
refCustomModifiers = ImmutableArray<CustomModifier>.Empty;
break;
case SymbolKind.Method:
MethodSymbol method = (MethodSymbol)symbol;
refKind = method.RefKind;
returnType = method.ReturnType;
returnTypeCustomModifiers = method.ReturnTypeCustomModifiers;
countOfCustomModifiersPrecedingByRef = method.CountOfCustomModifiersPrecedingByRef;
refCustomModifiers = method.RefCustomModifiers;
break;
case SymbolKind.Property:
PropertySymbol property = (PropertySymbol)symbol;
refKind = property.RefKind;
returnType = property.Type;
returnTypeCustomModifiers = property.TypeCustomModifiers;
countOfCustomModifiersPrecedingByRef = property.CountOfCustomModifiersPrecedingByRef;
refCustomModifiers = property.RefCustomModifiers;
break;
case SymbolKind.Event:
EventSymbol @event = (EventSymbol)symbol;
refKind = RefKind.None;
returnType = @event.Type;
returnTypeCustomModifiers = ImmutableArray<CustomModifier>.Empty;
countOfCustomModifiersPrecedingByRef = 0;
refCustomModifiers = ImmutableArray<CustomModifier>.Empty;
break;
case SymbolKind.Local:
LocalSymbol local = (LocalSymbol)symbol;
refKind = local.RefKind;
returnType = local.Type;
returnTypeCustomModifiers = ImmutableArray<CustomModifier>.Empty;
countOfCustomModifiersPrecedingByRef = 0;
refCustomModifiers = ImmutableArray<CustomModifier>.Empty;
break;
default:
throw ExceptionUtilities.UnexpectedValue(symbol.Kind);
......
......@@ -35,11 +35,11 @@ public override ImmutableArray<CustomModifier> CustomModifiers
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return 0; // since RefKind is always None.
return ImmutableArray<CustomModifier>.Empty; // since RefKind is always None.
}
}
......
......@@ -89,8 +89,8 @@ public DelegateConstructor(NamedTypeSymbol containingType, TypeSymbol objectType
: base(containingType)
{
_parameters = ImmutableArray.Create<ParameterSymbol>(
new SynthesizedParameterSymbol(this, objectType, 0, RefKind.None, "object"),
new SynthesizedParameterSymbol(this, intPtrType, 1, RefKind.None, "method"));
SynthesizedParameterSymbol.Create(this, objectType, 0, RefKind.None, "object"),
SynthesizedParameterSymbol.Create(this, intPtrType, 1, RefKind.None, "method"));
}
public override ImmutableArray<ParameterSymbol> Parameters
......@@ -120,7 +120,7 @@ internal InvokeMethod(SynthesizedDelegateSymbol containingType, BitVector byRefP
// we don't need to distinguish between out and ref since this is an internal synthesized symbol:
var refKind = !byRefParameters.IsNull && byRefParameters[i] ? RefKind.Ref : RefKind.None;
parameters[i] = new SynthesizedParameterSymbol(this, typeParams[i], i, refKind);
parameters[i] = SynthesizedParameterSymbol.Create(this, typeParams[i], i, refKind);
}
_parameters = parameters.AsImmutableOrNull();
......@@ -254,9 +254,9 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return 0; }
get { return ImmutableArray<CustomModifier>.Empty; }
}
public override Symbol AssociatedSymbol
......
......@@ -138,9 +138,9 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return 0; }
get { return ImmutableArray<CustomModifier>.Empty; }
}
public override ImmutableArray<TypeSymbol> TypeArguments
......@@ -429,7 +429,7 @@ private sealed class SubmissionEntryPoint : SynthesizedEntryPointSymbol
{
Debug.Assert(containingType.IsSubmissionClass);
Debug.Assert(returnType.SpecialType != SpecialType.System_Void);
_parameters = ImmutableArray.Create<ParameterSymbol>(new SynthesizedParameterSymbol(this, submissionArrayType, 0, RefKind.None, "submissionArray"));
_parameters = ImmutableArray.Create<ParameterSymbol>(SynthesizedParameterSymbol.Create(this, submissionArrayType, 0, RefKind.None, "submissionArray"));
}
public override string Name
......
......@@ -197,9 +197,9 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return 0; }
get { return ImmutableArray<CustomModifier>.Empty; }
}
public override ImmutableArray<TypeSymbol> TypeArguments
......
......@@ -72,9 +72,9 @@ public sealed override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
get { return _interfaceMethod.ReturnTypeCustomModifiers; }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public sealed override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return _interfaceMethod.CountOfCustomModifiersPrecedingByRef; }
get { return _interfaceMethod.RefCustomModifiers; }
}
#endregion
......@@ -86,7 +86,7 @@ internal override void AddSynthesizedAttributes(ModuleCompilationState compilati
var compilation = this.DeclaringCompilation;
if (this.ReturnType.ContainsDynamic() && compilation.HasDynamicEmitAttributes() && compilation.CanEmitBoolean())
{
AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.ReturnType, this.ReturnTypeCustomModifiers.Length));
AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.ReturnType, this.ReturnTypeCustomModifiers.Length + this.RefCustomModifiers.Length, this.RefKind));
}
if (ReturnType.ContainsTupleNames() &&
......
......@@ -155,9 +155,9 @@ public sealed override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return 0; }
get { return ImmutableArray<CustomModifier>.Empty; }
}
public sealed override ImmutableArray<TypeSymbol> TypeArguments
......
......@@ -145,9 +145,9 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
get { return ImmutableArray<CustomModifier>.Empty; }
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return 0; }
get { return ImmutableArray<CustomModifier>.Empty; }
}
public override ImmutableArray<TypeSymbol> TypeArguments
......
......@@ -272,11 +272,11 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return 0;
return ImmutableArray<CustomModifier>.Empty;
}
}
......@@ -449,15 +449,14 @@ public override int GetHashCode()
return Hash.Combine(_name, Hash.Combine(_containingType, _parameters.Length));
}
private sealed class SynthesizedOperatorParameterSymbol : SynthesizedParameterSymbol
private sealed class SynthesizedOperatorParameterSymbol : SynthesizedParameterSymbolBase
{
public SynthesizedOperatorParameterSymbol(
SynthesizedIntrinsicOperatorSymbol container,
TypeSymbol type,
int ordinal,
string name
) : base(container, type, ordinal, RefKind.None, name, ImmutableArray<CustomModifier>.Empty)
) : base(container, type, ordinal, RefKind.None, name)
{
}
......@@ -482,6 +481,16 @@ public override int GetHashCode()
{
return Hash.Combine(ContainingSymbol, Ordinal.GetHashCode());
}
public override ImmutableArray<CustomModifier> CustomModifiers
{
get { return ImmutableArray<CustomModifier>.Empty; }
}
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return ImmutableArray<CustomModifier>.Empty; }
}
}
}
}
......@@ -12,24 +12,20 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols
/// <summary>
/// Represents a simple compiler generated parameter of a given type.
/// </summary>
internal class SynthesizedParameterSymbol : ParameterSymbol
internal abstract class SynthesizedParameterSymbolBase : ParameterSymbol
{
private readonly MethodSymbol _container;
private readonly TypeSymbol _type;
private readonly int _ordinal;
private readonly string _name;
private readonly ImmutableArray<CustomModifier> _customModifiers;
private readonly ushort _countOfCustomModifiersPrecedingByRef;
private readonly RefKind _refKind;
public SynthesizedParameterSymbol(
public SynthesizedParameterSymbolBase(
MethodSymbol container,
TypeSymbol type,
int ordinal,
RefKind refKind,
string name = "",
ImmutableArray<CustomModifier> customModifiers = default(ImmutableArray<CustomModifier>),
ushort countOfCustomModifiersPrecedingByRef = 0)
string name = "")
{
Debug.Assert((object)type != null);
Debug.Assert(name != null);
......@@ -40,8 +36,6 @@ internal class SynthesizedParameterSymbol : ParameterSymbol
_ordinal = ordinal;
_refKind = refKind;
_name = name;
_customModifiers = customModifiers.NullToEmpty();
_countOfCustomModifiersPrecedingByRef = countOfCustomModifiersPrecedingByRef;
}
public override TypeSymbol Type
......@@ -74,10 +68,9 @@ public override string Name
get { return _name; }
}
public override ImmutableArray<CustomModifier> CustomModifiers
{
get { return _customModifiers; }
}
public abstract override ImmutableArray<CustomModifier> CustomModifiers { get; }
public abstract override ImmutableArray<CustomModifier> RefCustomModifiers { get; }
public override int Ordinal
{
......@@ -129,11 +122,6 @@ internal override bool IsCallerMemberName
get { return false; }
}
internal sealed override ushort CountOfCustomModifiersPrecedingByRef
{
get { return _countOfCustomModifiersPrecedingByRef; }
}
public override Symbol ContainingSymbol
{
get { return _container; }
......@@ -161,7 +149,7 @@ internal override void AddSynthesizedAttributes(ModuleCompilationState compilati
var compilation = this.DeclaringCompilation;
if (Type.ContainsDynamic() && compilation.HasDynamicEmitAttributes() && compilation.CanEmitBoolean())
{
AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.Type, this.CustomModifiers.Length, this.RefKind));
AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.Type, this.CustomModifiers.Length + this.RefCustomModifiers.Length, this.RefKind));
}
if (Type.ContainsTupleNames() &&
......@@ -172,6 +160,36 @@ internal override void AddSynthesizedAttributes(ModuleCompilationState compilati
compilation.SynthesizeTupleNamesAttribute(Type));
}
}
}
internal sealed class SynthesizedParameterSymbol : SynthesizedParameterSymbolBase
{
private SynthesizedParameterSymbol(
MethodSymbol container,
TypeSymbol type,
int ordinal,
RefKind refKind,
string name)
: base(container, type, ordinal, refKind, name)
{
}
public static ParameterSymbol Create(
MethodSymbol container,
TypeSymbol type,
int ordinal,
RefKind refKind,
string name = "",
ImmutableArray<CustomModifier> customModifiers = default(ImmutableArray<CustomModifier>),
ImmutableArray<CustomModifier> refCustomModifiers = default(ImmutableArray<CustomModifier>))
{
if (customModifiers.IsDefaultOrEmpty && refCustomModifiers.IsDefaultOrEmpty)
{
return new SynthesizedParameterSymbol(container, type, ordinal, refKind, name);
}
return new SynthesizedParameterSymbolWithCustomModifiers(container, type, ordinal, refKind, name, customModifiers, refCustomModifiers);
}
/// <summary>
/// For each parameter of a source method, construct a corresponding synthesized parameter
......@@ -187,11 +205,51 @@ internal static ImmutableArray<ParameterSymbol> DeriveParameters(MethodSymbol so
foreach (var oldParam in sourceMethod.Parameters)
{
//same properties as the old one, just change the owner
builder.Add(new SynthesizedParameterSymbol(destinationMethod, oldParam.Type, oldParam.Ordinal,
oldParam.RefKind, oldParam.Name, oldParam.CustomModifiers, oldParam.CountOfCustomModifiersPrecedingByRef));
builder.Add(SynthesizedParameterSymbol.Create(destinationMethod, oldParam.Type, oldParam.Ordinal,
oldParam.RefKind, oldParam.Name, oldParam.CustomModifiers, oldParam.RefCustomModifiers));
}
return builder.ToImmutableAndFree();
}
public override ImmutableArray<CustomModifier> CustomModifiers
{
get { return ImmutableArray<CustomModifier>.Empty; }
}
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return ImmutableArray<CustomModifier>.Empty; }
}
private sealed class SynthesizedParameterSymbolWithCustomModifiers : SynthesizedParameterSymbolBase
{
private readonly ImmutableArray<CustomModifier> _customModifiers;
private readonly ImmutableArray<CustomModifier> _refCustomModifiers;
public SynthesizedParameterSymbolWithCustomModifiers(
MethodSymbol container,
TypeSymbol type,
int ordinal,
RefKind refKind,
string name,
ImmutableArray<CustomModifier> customModifiers,
ImmutableArray<CustomModifier> refCustomModifiers)
: base(container, type, ordinal, refKind, name)
{
_customModifiers = customModifiers.NullToEmpty();
_refCustomModifiers = refCustomModifiers.NullToEmpty();
}
public override ImmutableArray<CustomModifier> CustomModifiers
{
get { return _customModifiers; }
}
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return _refCustomModifiers; }
}
}
}
}
......@@ -222,12 +222,12 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
return _overriddenAccessor.ReturnTypeCustomModifiers;
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return _overriddenAccessor.CountOfCustomModifiersPrecedingByRef;
return _overriddenAccessor.RefCustomModifiers;
}
}
......
......@@ -144,11 +144,11 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return 0;
return ImmutableArray<CustomModifier>.Empty;
}
}
......
......@@ -19,7 +19,7 @@ internal sealed partial class SynthesizedStringSwitchHashMethod : SynthesizedGlo
internal SynthesizedStringSwitchHashMethod(SourceModuleSymbol containingModule, PrivateImplementationDetails privateImplType, TypeSymbol returnType, TypeSymbol paramType)
: base(containingModule, privateImplType, returnType, PrivateImplementationDetails.SynthesizedStringHashFunctionName)
{
this.SetParameters(ImmutableArray.Create<ParameterSymbol>(new SynthesizedParameterSymbol(this, paramType, 0, RefKind.None, "s")));
this.SetParameters(ImmutableArray.Create<ParameterSymbol>(SynthesizedParameterSymbol.Create(this, paramType, 0, RefKind.None, "s")));
}
}
}
......@@ -25,7 +25,7 @@ internal SynthesizedSubmissionConstructor(NamedTypeSymbol containingType, Diagno
}
_parameters = ImmutableArray.Create<ParameterSymbol>(
new SynthesizedParameterSymbol(this, submissionArrayType, 0, RefKind.None, "submissionArray"));
SynthesizedParameterSymbol.Create(this, submissionArrayType, 0, RefKind.None, "submissionArray"));
}
public override ImmutableArray<ParameterSymbol> Parameters
......
......@@ -128,11 +128,11 @@ public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return _underlyingMethod.CountOfCustomModifiersPrecedingByRef;
return _underlyingMethod.RefCustomModifiers;
}
}
......
......@@ -52,11 +52,11 @@ public override ImmutableArray<CustomModifier> TypeCustomModifiers
}
}
internal override ushort CountOfCustomModifiersPrecedingByRef
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
return _underlyingProperty.CountOfCustomModifiersPrecedingByRef;
return _underlyingProperty.RefCustomModifiers;
}
}
......
......@@ -1034,7 +1034,7 @@ private static void CheckForImplementationOfCorrespondingPropertyOrEvent(MethodS
interfaceMethod.RefKind,
interfaceMethod.ReturnType,
interfaceMethod.ReturnTypeCustomModifiers,
interfaceMethod.CountOfCustomModifiersPrecedingByRef,
interfaceMethod.RefCustomModifiers,
interfaceMethod.ExplicitInterfaceImplementations);
// Make sure that the corresponding accessor is a real implementation.
......
......@@ -116,6 +116,11 @@ public override ImmutableArray<CustomModifier> CustomModifiers
get { return _underlyingParameter.CustomModifiers; }
}
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return _underlyingParameter.RefCustomModifiers; }
}
internal override MarshalPseudoCustomAttributeData MarshallingInformation
{
get { return _underlyingParameter.MarshallingInformation; }
......@@ -151,11 +156,6 @@ internal override bool IsCallerMemberName
get { return _underlyingParameter.IsCallerMemberName; }
}
internal sealed override ushort CountOfCustomModifiersPrecedingByRef
{
get { return _underlyingParameter.CountOfCustomModifiersPrecedingByRef; }
}
public override string GetDocumentationCommentXml(CultureInfo preferredCulture = null, bool expandIncludes = false, CancellationToken cancellationToken = default(CancellationToken))
{
return _underlyingParameter.GetDocumentationCommentXml(preferredCulture, expandIncludes, cancellationToken);
......
......@@ -600,7 +600,7 @@ static void Main()
Assert.Equal(RefKind.Ref, parameter.RefKind);
Assert.False(parameter.CustomModifiers.IsEmpty);
Assert.Equal(0, parameter.CountOfCustomModifiersPrecedingByRef);
Assert.True(parameter.RefCustomModifiers.IsEmpty);
CompileAndVerify(comp, expectedOutput: "2");
}
......@@ -656,7 +656,7 @@ static void Main()
Assert.Equal(RefKind.Ref, baseParameter.RefKind);
Assert.False(baseParameter.CustomModifiers.IsEmpty);
Assert.Equal(0, baseParameter.CountOfCustomModifiersPrecedingByRef);
Assert.True(baseParameter.RefCustomModifiers.IsEmpty);
var derivedType = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("D");
var derivedMethod = derivedType.GetMember<MethodSymbol>("M");
......@@ -664,7 +664,7 @@ static void Main()
Assert.Equal(RefKind.Ref, derivedParameter.RefKind);
Assert.False(derivedParameter.CustomModifiers.IsEmpty);
Assert.Equal(0, derivedParameter.CountOfCustomModifiersPrecedingByRef);
Assert.True(derivedParameter.RefCustomModifiers.IsEmpty);
CompileAndVerify(comp, expectedOutput: "2");
}
......
......@@ -604,6 +604,7 @@
<Compile Include="Symbols\Attributes\WellKnownAttributeData.cs" />
<Compile Include="Symbols\CommonAttributeDataExtensions.cs" />
<Compile Include="Symbols\CustomModifier.cs" />
<Compile Include="Symbols\CustomModifiersTuple.cs" />
<Compile Include="Symbols\IAliasSymbol.cs" />
<Compile Include="Symbols\IArrayTypeSymbol.cs" />
<Compile Include="Symbols\IAssemblySymbol.cs" />
......
......@@ -246,15 +246,14 @@ public static ArrayMethodParameterInfo GetIndexParameter(ushort index)
return new ArrayMethodParameterInfo(index);
}
public ImmutableArray<Cci.ICustomModifier> RefCustomModifiers
=> ImmutableArray<Cci.ICustomModifier>.Empty;
public ImmutableArray<Cci.ICustomModifier> CustomModifiers
=> ImmutableArray<Cci.ICustomModifier>.Empty;
public bool IsByReference => false;
public bool IsModified => false;
public ushort CountOfCustomModifiersPrecedingByRef => 0;
public virtual Cci.ITypeReference GetType(EmitContext context)
=> context.Module.GetPlatformType(Cci.PlatformType.SystemInt32, context);
......@@ -337,10 +336,11 @@ public ImmutableArray<Cci.IParameterTypeInformation> ExtraParameters
public ushort ParameterCount => (ushort)_parameters.Length;
public ImmutableArray<Cci.ICustomModifier> ReturnValueCustomModifiers
public ImmutableArray<Cci.ICustomModifier> RefCustomModifiers
=> ImmutableArray<Cci.ICustomModifier>.Empty;
public ushort CountOfCustomModifiersPrecedingByRef => 0;
public ImmutableArray<Cci.ICustomModifier> ReturnValueCustomModifiers
=> ImmutableArray<Cci.ICustomModifier>.Empty;
public Cci.ITypeReference GetContainingType(EmitContext context)
{
......
......@@ -284,12 +284,12 @@ ImmutableArray<Cci.IParameterTypeInformation> Cci.ISignature.GetParameters(EmitC
return StaticCast<Cci.IParameterTypeInformation>.From(_parameters);
}
ImmutableArray<Cci.ICustomModifier> Cci.ISignature.RefCustomModifiers =>
UnderlyingMethodSignature.RefCustomModifiers;
ImmutableArray<Cci.ICustomModifier> Cci.ISignature.ReturnValueCustomModifiers =>
UnderlyingMethodSignature.ReturnValueCustomModifiers;
ushort Cci.ISignature.CountOfCustomModifiersPrecedingByRef =>
UnderlyingMethodSignature.CountOfCustomModifiersPrecedingByRef;
bool Cci.ISignature.ReturnValueIsByRef => UnderlyingMethodSignature.ReturnValueIsByRef;
Cci.ITypeReference Cci.ISignature.GetType(EmitContext context)
......
......@@ -233,11 +233,11 @@ bool Cci.IParameterTypeInformation.IsByReference
}
}
ushort Cci.IParameterTypeInformation.CountOfCustomModifiersPrecedingByRef
ImmutableArray<Cci.ICustomModifier> Cci.IParameterTypeInformation.RefCustomModifiers
{
get
{
return UnderlyingParameterTypeInformation.CountOfCustomModifiersPrecedingByRef;
return UnderlyingParameterTypeInformation.RefCustomModifiers;
}
}
......
......@@ -150,11 +150,11 @@ ImmutableArray<Cci.ICustomModifier> Cci.ISignature.ReturnValueCustomModifiers
}
}
ushort Cci.ISignature.CountOfCustomModifiersPrecedingByRef
ImmutableArray<Cci.ICustomModifier> Cci.ISignature.RefCustomModifiers
{
get
{
return UnderlyingPropertySignature.CountOfCustomModifiersPrecedingByRef;
return UnderlyingPropertySignature.RefCustomModifiers;
}
}
......
......@@ -241,9 +241,9 @@ ImmutableArray<Cci.ICustomModifier> Cci.ISignature.ReturnValueCustomModifiers
get { return ImmutableArray<Cci.ICustomModifier>.Empty; }
}
ushort Cci.ISignature.CountOfCustomModifiersPrecedingByRef
ImmutableArray<Cci.ICustomModifier> Cci.ISignature.RefCustomModifiers
{
get { return 0; }
get { return ImmutableArray<Cci.ICustomModifier>.Empty; }
}
bool Cci.ISignature.ReturnValueIsByRef
......
......@@ -31,9 +31,9 @@ internal struct ParamInfo<TypeSymbol>
where TypeSymbol : class
{
internal bool IsByRef;
internal ushort CountOfCustomModifiersPrecedingByRef;
internal TypeSymbol Type;
internal ParameterHandle Handle; // may be nil
internal ImmutableArray<ModifierInfo<TypeSymbol>> RefCustomModifiers;
internal ImmutableArray<ModifierInfo<TypeSymbol>> CustomModifiers;
}
......@@ -1101,29 +1101,8 @@ private void DecodeParameterOrThrow(ref BlobReader signatureReader, /*out*/ ref
if (typeCode == SignatureTypeCode.ByReference)
{
info.IsByRef = true;
// The spec says that custom modifiers must precede SignatureTypeCode.ByReference, but the managed C++
// compiler emits them in the reverse order. In order to avoid breaking interop scenarios, we need to
// support decoding (and later emitting) such signatures.
var additionalModifiers = DecodeModifiersOrThrow(ref signatureReader, out typeCode);
if (!info.CustomModifiers.IsDefault)
{
info.CountOfCustomModifiersPrecedingByRef = (ushort)info.CustomModifiers.Length;
if (info.CountOfCustomModifiersPrecedingByRef != info.CustomModifiers.Length)
{
throw new UnsupportedSignatureContent();
}
if (!additionalModifiers.IsDefaultOrEmpty)
{
info.CustomModifiers = info.CustomModifiers.Concat(additionalModifiers);
}
}
else
{
info.CustomModifiers = additionalModifiers;
}
info.RefCustomModifiers = info.CustomModifiers;
info.CustomModifiers = DecodeModifiersOrThrow(ref signatureReader, out typeCode);
}
info.Type = DecodeTypeOrThrow(ref signatureReader, typeCode, out refersToNoPiaLocalType);
......
......@@ -777,7 +777,7 @@ internal interface ISignature
ImmutableArray<IParameterTypeInformation> GetParameters(EmitContext context);
/// <summary>
/// Returns the list of custom modifiers, if any, associated with the returned value.
/// Returns the list of custom modifiers, if any, associated with the return type.
/// </summary>
ImmutableArray<ICustomModifier> ReturnValueCustomModifiers
{
......@@ -785,14 +785,17 @@ ImmutableArray<ICustomModifier> ReturnValueCustomModifiers
}
/// <summary>
/// True if the return value is passed by reference (using a managed pointer).
/// Returns the list of custom modifiers, if any, associated with the ref modifier.
/// </summary>
bool ReturnValueIsByRef { get; }
ImmutableArray<ICustomModifier> RefCustomModifiers
{
get;
}
/// <summary>
/// In order to avoid breaking interop scenarios, we need to support such signatures.
/// True if the return value is passed by reference (using a managed pointer).
/// </summary>
ushort CountOfCustomModifiersPrecedingByRef { get; }
bool ReturnValueIsByRef { get; }
/// <summary>
/// The return type of the method or type of the property.
......
......@@ -3227,39 +3227,23 @@ private static bool MayUseSmallExceptionHeaders(ImmutableArray<ExceptionHandlerR
private void SerializeParameterInformation(ParameterTypeEncoder encoder, IParameterTypeInformation parameterTypeInformation)
{
var modifiers = parameterTypeInformation.CustomModifiers;
var type = parameterTypeInformation.GetType(Context);
if (module.IsPlatformType(type, PlatformType.SystemTypedReference))
{
Debug.Assert(!parameterTypeInformation.IsByReference);
if (modifiers.Length > 0)
{
SerializeCustomModifiers(encoder.CustomModifiers(), modifiers);
}
SerializeCustomModifiers(encoder.CustomModifiers(), parameterTypeInformation.CustomModifiers);
encoder.TypedReference();
}
else
{
ushort numberOfModifiersPrecedingByRef = parameterTypeInformation.CountOfCustomModifiersPrecedingByRef;
int numberOfRemainingModifiers = modifiers.Length - numberOfModifiersPrecedingByRef;
Debug.Assert(numberOfModifiersPrecedingByRef == 0 || parameterTypeInformation.IsByReference);
if (numberOfModifiersPrecedingByRef > 0)
{
SerializeCustomModifiers(encoder.CustomModifiers(), modifiers, 0, numberOfModifiersPrecedingByRef);
}
Debug.Assert(parameterTypeInformation.RefCustomModifiers.Length == 0 || parameterTypeInformation.IsByReference);
SerializeCustomModifiers(encoder.CustomModifiers(), parameterTypeInformation.RefCustomModifiers);
var typeEncoder = encoder.Type(parameterTypeInformation.IsByReference);
if (numberOfRemainingModifiers > 0)
{
SerializeCustomModifiers(typeEncoder.CustomModifiers(), modifiers, numberOfModifiersPrecedingByRef, numberOfRemainingModifiers);
}
SerializeCustomModifiers(typeEncoder.CustomModifiers(), parameterTypeInformation.CustomModifiers);
SerializeTypeReference(typeEncoder, type);
}
}
......@@ -3602,46 +3586,28 @@ private void SerializeReturnValueAndParameters(MethodSignatureEncoder encoder, I
encoder.Parameters(declaredParameters.Length + varargParameters.Length, out returnTypeEncoder, out parametersEncoder);
var modifiers = signature.ReturnValueCustomModifiers;
if (module.IsPlatformType(returnType, PlatformType.SystemTypedReference))
{
Debug.Assert(!signature.ReturnValueIsByRef);
if (modifiers.Length > 0)
{
SerializeCustomModifiers(returnTypeEncoder.CustomModifiers(), modifiers);
}
SerializeCustomModifiers(returnTypeEncoder.CustomModifiers(), signature.ReturnValueCustomModifiers);
returnTypeEncoder.TypedReference();
}
else if (module.IsPlatformType(returnType, PlatformType.SystemVoid))
{
Debug.Assert(!signature.ReturnValueIsByRef);
if (modifiers.Length > 0)
{
SerializeCustomModifiers(returnTypeEncoder.CustomModifiers(), modifiers);
}
SerializeCustomModifiers(returnTypeEncoder.CustomModifiers(), signature.ReturnValueCustomModifiers);
returnTypeEncoder.Void();
}
else
{
ushort numberOfModifiersPrecedingByRef = signature.CountOfCustomModifiersPrecedingByRef;
int numberOfRemainingModifiers = modifiers.Length - numberOfModifiersPrecedingByRef;
Debug.Assert(numberOfModifiersPrecedingByRef == 0 || signature.ReturnValueIsByRef);
if (numberOfModifiersPrecedingByRef > 0)
{
SerializeCustomModifiers(returnTypeEncoder.CustomModifiers(), modifiers, 0, numberOfModifiersPrecedingByRef);
}
Debug.Assert(signature.RefCustomModifiers.Length == 0 || signature.ReturnValueIsByRef);
SerializeCustomModifiers(returnTypeEncoder.CustomModifiers(), signature.RefCustomModifiers);
var typeEncoder = returnTypeEncoder.Type(signature.ReturnValueIsByRef);
if (numberOfRemainingModifiers > 0)
{
SerializeCustomModifiers(typeEncoder.CustomModifiers(), modifiers, numberOfModifiersPrecedingByRef, numberOfRemainingModifiers);
}
SerializeCustomModifiers(typeEncoder.CustomModifiers(), signature.ReturnValueCustomModifiers);
SerializeTypeReference(typeEncoder, returnType);
}
......@@ -3950,14 +3916,8 @@ private static void SerializePrimitiveType(CustomAttributeElementTypeEncoder enc
private void SerializeCustomModifiers(CustomModifiersEncoder encoder, ImmutableArray<ICustomModifier> modifiers)
{
SerializeCustomModifiers(encoder, modifiers, 0, modifiers.Length);
}
private void SerializeCustomModifiers(CustomModifiersEncoder encoder, ImmutableArray<ICustomModifier> modifiers, int start, int count)
{
for (int i = 0; i < count; i++)
foreach (var modifier in modifiers)
{
var modifier = modifiers[start + i];
encoder = encoder.AddModifier(GetTypeHandle(modifier.GetModifier(Context)), modifier.IsOptional);
}
}
......
......@@ -30,6 +30,11 @@ public IMetadataConstant Constant
get { return null; }
}
public ImmutableArray<Cci.ICustomModifier> RefCustomModifiers
{
get { return _containingMethod.RefCustomModifiers; }
}
public ImmutableArray<Cci.ICustomModifier> CustomModifiers
{
get { return _containingMethod.ReturnValueCustomModifiers; }
......@@ -64,11 +69,6 @@ public bool IsByReference
get { return _containingMethod.ReturnValueIsByRef; }
}
public ushort CountOfCustomModifiersPrecedingByRef
{
get { return 0; }
}
public bool IsMarshalledExplicitly
{
get { return _containingMethod.ReturnValueIsMarshalledExplicitly; }
......
......@@ -93,7 +93,7 @@ internal interface ICustomModifier
internal interface IParameterTypeInformation : IParameterListEntry
{
/// <summary>
/// The list of custom modifiers, if any, associated with the parameter. Evaluate this property only if IsModified is true.
/// The list of custom modifiers, if any, associated with the parameter type.
/// </summary>
ImmutableArray<ICustomModifier> CustomModifiers
{
......@@ -101,16 +101,17 @@ ImmutableArray<ICustomModifier> CustomModifiers
}
/// <summary>
/// True if the parameter is passed by reference (using a managed pointer).
/// The list of custom modifiers, if any, associated with the ref modifier.
/// </summary>
bool IsByReference { get; }
ImmutableArray<ICustomModifier> RefCustomModifiers
{
get;
}
/// <summary>
/// The CLI spec says that custom modifiers must precede the ByRef type code in the encoding of a parameter.
/// Unfortunately, the managed C++ compiler emits them in the reverse order. In order to avoid breaking
/// interop scenarios, we need to support such signatures.
/// True if the parameter is passed by reference (using a managed pointer).
/// </summary>
ushort CountOfCustomModifiersPrecedingByRef { get; }
bool IsByReference { get; }
/// <summary>
/// The type of argument value that corresponds to this parameter.
......@@ -364,7 +365,7 @@ public Cci.ITypeDefinition ContainingType
internal interface IModifiedTypeReference : ITypeReference
{
/// <summary>
/// Returns the list of custom modifiers associated with the type reference. Evaluate this property only if IsModified is true.
/// Returns the list of custom modifiers associated with the type reference.
/// </summary>
ImmutableArray<ICustomModifier> CustomModifiers { get; }
......
......@@ -87,6 +87,7 @@ Microsoft.CodeAnalysis.IArrayTypeSymbol.IsSZArray.get -> bool
Microsoft.CodeAnalysis.IArrayTypeSymbol.LowerBounds.get -> System.Collections.Immutable.ImmutableArray<int>
Microsoft.CodeAnalysis.IArrayTypeSymbol.Sizes.get -> System.Collections.Immutable.ImmutableArray<int>
Microsoft.CodeAnalysis.IFieldSymbol.CorrespondingTupleField.get -> Microsoft.CodeAnalysis.IFieldSymbol
Microsoft.CodeAnalysis.IMethodSymbol.RefCustomModifiers.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.CustomModifier>
Microsoft.CodeAnalysis.IMethodSymbol.ReturnsByRef.get -> bool
Microsoft.CodeAnalysis.INamedTypeSymbol.GetTypeArgumentCustomModifiers(int ordinal) -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.CustomModifier>
Microsoft.CodeAnalysis.INamedTypeSymbol.IsComImport.get -> bool
......@@ -100,6 +101,8 @@ Microsoft.CodeAnalysis.IOperation.IsInvalid.get -> bool
Microsoft.CodeAnalysis.IOperation.Kind.get -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.IOperation.Syntax.get -> Microsoft.CodeAnalysis.SyntaxNode
Microsoft.CodeAnalysis.IOperation.Type.get -> Microsoft.CodeAnalysis.ITypeSymbol
Microsoft.CodeAnalysis.IParameterSymbol.RefCustomModifiers.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.CustomModifier>
Microsoft.CodeAnalysis.IPropertySymbol.RefCustomModifiers.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.CustomModifier>
Microsoft.CodeAnalysis.IPropertySymbol.ReturnsByRef.get -> bool
Microsoft.CodeAnalysis.ITypeSymbol.IsTupleType.get -> bool
Microsoft.CodeAnalysis.MethodKind.LocalFunction = 17 -> Microsoft.CodeAnalysis.MethodKind
......
// 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.Collections.Immutable;
namespace Microsoft.CodeAnalysis
{
internal sealed class CustomModifiersTuple
{
private readonly ImmutableArray<CustomModifier> _typeCustomModifiers;
private readonly ImmutableArray<CustomModifier> _refCustomModifiers;
public static readonly CustomModifiersTuple Empty = new CustomModifiersTuple(ImmutableArray<CustomModifier>.Empty, ImmutableArray<CustomModifier>.Empty);
private CustomModifiersTuple(ImmutableArray<CustomModifier> typeCustomModifiers, ImmutableArray<CustomModifier> refCustomModifiers)
{
_typeCustomModifiers = typeCustomModifiers.NullToEmpty();
_refCustomModifiers = refCustomModifiers.NullToEmpty();
}
public static CustomModifiersTuple Create(ImmutableArray<CustomModifier> typeCustomModifiers, ImmutableArray<CustomModifier> refCustomModifiers)
{
if (typeCustomModifiers.IsDefaultOrEmpty && refCustomModifiers.IsDefaultOrEmpty)
{
return Empty;
}
return new CustomModifiersTuple(typeCustomModifiers, refCustomModifiers);
}
public ImmutableArray<CustomModifier> TypeCustomModifiers { get { return _typeCustomModifiers; } }
public ImmutableArray<CustomModifier> RefCustomModifiers { get { return _refCustomModifiers; } }
}
}
......@@ -157,10 +157,15 @@ public interface IMethodSymbol : ISymbol
ImmutableArray<IMethodSymbol> ExplicitInterfaceImplementations { get; }
/// <summary>
/// Returns the list of custom modifiers, if any, associated with the returned value.
/// Returns the list of custom modifiers, if any, associated with the return type.
/// </summary>
ImmutableArray<CustomModifier> ReturnTypeCustomModifiers { get; }
/// <summary>
/// Custom modifiers associated with the ref modifier, or an empty array if there are none.
/// </summary>
ImmutableArray<CustomModifier> RefCustomModifiers { get; }
/// <summary>
/// Returns the list of custom attributes, if any, associated with the returned value.
/// </summary>
......
......@@ -75,7 +75,7 @@ public interface INamedTypeSymbol : ITypeSymbol
/// <summary>
/// Returns custom modifiers for the type argument that has been substituted for the type parameter.
/// The modifiers correspond to the type argument at the same ordinal within the <see cref="TypeArguments"/>
/// array.
/// array. Returns an empty array if there are no modifiers.
/// </summary>
ImmutableArray<CustomModifier> GetTypeArgumentCustomModifiers(int ordinal);
......
......@@ -41,10 +41,15 @@ public interface IParameterSymbol : ISymbol
ITypeSymbol Type { get; }
/// <summary>
/// Custom modifiers associated with the parameter, or an empty array if there are none.
/// Custom modifiers associated with the parameter type, or an empty array if there are none.
/// </summary>
ImmutableArray<CustomModifier> CustomModifiers { get; }
/// <summary>
/// Custom modifiers associated with the ref modifier, or an empty array if there are none.
/// </summary>
ImmutableArray<CustomModifier> RefCustomModifiers { get; }
/// <summary>
/// Gets the ordinal position of the parameter. The first parameter has ordinal zero.
/// The 'this' parameter ('Me' in Visual Basic) has ordinal -1.
......
......@@ -82,6 +82,11 @@ public interface IPropertySymbol : ISymbol
/// </remarks>
ImmutableArray<IPropertySymbol> ExplicitInterfaceImplementations { get; }
/// <summary>
/// Custom modifiers associated with the ref modifier, or an empty array if there are none.
/// </summary>
ImmutableArray<CustomModifier> RefCustomModifiers { get; }
/// <summary>
/// The list of custom modifiers, if any, associated with the type of the property.
/// </summary>
......
......@@ -589,9 +589,9 @@ Friend Class MockMethodSymbol
End Get
End Property
Friend Overrides ReadOnly Property CountOfCustomModifiersPrecedingByRef As UShort
Public Overrides ReadOnly Property RefCustomModifiers As ImmutableArray(Of CustomModifier)
Get
Return 0
Return ImmutableArray(Of CustomModifier).Empty
End Get
End Property
......
......@@ -509,6 +509,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim candidateProperty = DirectCast(candidate, PropertySymbol)
If candidateProperty.Type.SpecialType <> SpecialType.System_String OrElse
candidateProperty.RefCustomModifiers.Length > 0 OrElse
candidateProperty.TypeCustomModifiers.Length > 0 OrElse
candidateProperty.ParameterCount <> 1 Then
......@@ -516,7 +517,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
Dim parameter = candidateProperty.Parameters(0)
If parameter.CustomModifiers.Length > 0 Then
If parameter.CustomModifiers.Length > 0 OrElse parameter.RefCustomModifiers.Length > 0 Then
Continue For
End If
......
......@@ -1691,9 +1691,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
Friend Overrides ReadOnly Property CountOfCustomModifiersPrecedingByRef As UShort
Public Overrides ReadOnly Property RefCustomModifiers As ImmutableArray(Of CustomModifier)
Get
Return _originalDefinition.CountOfCustomModifiersPrecedingByRef
Return _originalDefinition.RefCustomModifiers
End Get
End Property
......@@ -1939,9 +1939,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
Friend Overrides ReadOnly Property CountOfCustomModifiersPrecedingByRef As UShort
Public Overrides ReadOnly Property RefCustomModifiers As ImmutableArray(Of CustomModifier)
Get
Return _originalDefinition.CountOfCustomModifiersPrecedingByRef
Return _originalDefinition.RefCustomModifiers
End Get
End Property
......
......@@ -73,9 +73,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
End Get
End Property
Private ReadOnly Property ISignatureCountOfCustomModifiersPrecedingByRef As UShort Implements Cci.ISignature.CountOfCustomModifiersPrecedingByRef
Private ReadOnly Property ISignatureRefCustomModifiers As ImmutableArray(Of Cci.ICustomModifier) Implements Cci.ISignature.RefCustomModifiers
Get
Return m_UnderlyingMethod.CountOfCustomModifiersPrecedingByRef
Return m_UnderlyingMethod.RefCustomModifiers.As(Of Cci.ICustomModifier)
End Get
End Property
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册