/// <param name="sourceType">Type that already has custom modifiers.</param> /// <param name="destinationType">Same as <paramref name="sourceType"/>, but without custom modifiers. May differ in object/dynamic.</param> /// <param name="refKind"><see cref="RefKind"/> of the parameter of which this is the type (or <see cref="RefKind.None"/> for a return type.</param> /// <param name="containingAssembly">The assembly containing the signature referring to the destination type.</param> /// <returns><paramref name="destinationType"/> with custom modifiers copied from <paramref name="sourceType"/>.</returns> internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSymbol destinationType, RefKind refKind, AssemblySymbol containingAssembly) { Debug.Assert(sourceType.Equals(destinationType, TypeCompareKind.AllIgnoreOptions)); // NOTE: overrides can differ by object/dynamic. If they do, we'll need to tweak newType before // we can use it in place of this.Type. We do so by computing the dynamic transform flags that // code gen uses and then passing them to the dynamic type decoder that metadata reading uses. ImmutableArray<bool> flags = CSharpCompilation.DynamicTransformsEncoder.EncodeWithoutCustomModifierFlags(destinationType, refKind); TypeSymbol typeWithDynamic = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(sourceType, containingAssembly, refKind, flags); TypeSymbol resultType; if (destinationType.ContainsTuple() && !sourceType.Equals(destinationType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | TypeCompareKind.IgnoreDynamic)) { // We also preserve tuple names, if present and different ImmutableArray<string> names = CSharpCompilation.TupleNamesEncoder.Encode(destinationType); resultType = TupleTypeDecoder.DecodeTupleTypesIfApplicable(typeWithDynamic, containingAssembly, names); } else { resultType = typeWithDynamic; } Debug.Assert(resultType.Equals(sourceType, TypeCompareKind.IgnoreDynamicAndTupleNames)); // Same custom modifiers as source type. Debug.Assert(resultType.Equals(destinationType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds)); // Same object/dynamic and tuple names as destination type. return resultType; }
public LocalFunctionSymbol( Binder binder, NamedTypeSymbol containingType, Symbol containingSymbol, LocalFunctionStatementSyntax syntax) { _syntax = syntax; _containingSymbol = containingSymbol; _refKind = syntax.RefKeyword.Kind().GetRefKind(); _declarationModifiers = DeclarationModifiers.Private | DeclarationModifiers.Static | syntax.Modifiers.ToDeclarationModifiers(); var diagnostics = DiagnosticBag.GetInstance(); if (_syntax.TypeParameterList != null) { binder = new WithMethodTypeParametersBinder(this, binder); _typeParameters = MakeTypeParameters(diagnostics); } else { _typeParameters = ImmutableArray<TypeParameterSymbol>.Empty; } if (IsExtensionMethod) { diagnostics.Add(ErrorCode.ERR_BadExtensionAgg, Locations[0]); } _binder = binder; _diagnostics = diagnostics.ToReadOnlyAndFree(); }
/// <param name="sourceType">Type that already has custom modifiers.</param> /// <param name="destinationType">Same as <paramref name="sourceType"/>, but without custom modifiers. May differ in object/dynamic.</param> /// <param name="refKind"><see cref="RefKind"/> of the parameter of which this is the type (or <see cref="RefKind.None"/> for a return type.</param> /// <param name="containingAssembly">The assembly containing the signature referring to the destination type.</param> /// <returns><paramref name="destinationType"/> with custom modifiers copied from <paramref name="sourceType"/>.</returns> internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSymbol destinationType, RefKind refKind, AssemblySymbol containingAssembly) { Debug.Assert(sourceType.Equals(destinationType, ignoreCustomModifiersAndArraySizesAndLowerBounds: true, ignoreDynamic: true)); if (sourceType.ContainsTuple()) { // TODO(https://github.com/dotnet/roslyn/issues/12389): // Need to save/restore tupleness as well if (sourceType.IsTupleType) { Debug.Assert(destinationType.IsTupleType); return destinationType; } ImmutableArray<bool> flags = CSharpCompilation.DynamicTransformsEncoder.EncodeWithoutCustomModifierFlags(destinationType, refKind); TypeSymbol resultType = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(sourceType, containingAssembly, refKind, flags); Debug.Assert(resultType.Equals(sourceType, ignoreCustomModifiersAndArraySizesAndLowerBounds: false, ignoreDynamic: true)); // Same custom modifiers as source type. return resultType; } else { // NOTE: overrides can differ by object/dynamic. If they do, we'll need to tweak newType before // we can use it in place of this.Type. We do so by computing the dynamic transform flags that // code gen uses and then passing them to the dynamic type decoder that metadata reading uses. ImmutableArray<bool> flags = CSharpCompilation.DynamicTransformsEncoder.EncodeWithoutCustomModifierFlags(destinationType, refKind); TypeSymbol resultType = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(sourceType, containingAssembly, refKind, flags); Debug.Assert(resultType.Equals(sourceType, ignoreCustomModifiersAndArraySizesAndLowerBounds: false, ignoreDynamic: true)); // Same custom modifiers as source type. Debug.Assert(resultType.Equals(destinationType, ignoreCustomModifiersAndArraySizesAndLowerBounds: true, ignoreDynamic: false)); // Same object/dynamic as destination type. return resultType; } }
internal SourceStrictComplexParameterSymbol( DiagnosticBag diagnostics, Binder binder, Symbol owner, int ordinal, TypeSymbol parameterType, RefKind refKind, string name, ImmutableArray<Location> locations, SyntaxReference syntaxRef, ConstantValue defaultSyntaxValue, bool isParams, bool isExtensionMethodThis) : base( owner: owner, ordinal: ordinal, parameterType: parameterType, refKind: refKind, name: name, locations: locations, syntaxRef: syntaxRef, defaultSyntaxValue: defaultSyntaxValue, isParams: isParams, isExtensionMethodThis: isExtensionMethodThis) { _tempBinder = binder; var unused = GetAttributesBag(diagnostics); _lazyDefaultSyntaxValue = MakeDefaultExpression(diagnostics, binder); _tempBinder = null; // no need to keep it around anymore, just uses up a lot of memory }
public EELocalSymbol( MethodSymbol method, ImmutableArray<Location> locations, string nameOpt, int ordinal, LocalDeclarationKind declarationKind, TypeSymbol type, RefKind refKind, bool isPinned, bool isCompilerGenerated, bool canScheduleToStack) { Debug.Assert(method != null); Debug.Assert(ordinal >= -1); Debug.Assert(!locations.IsDefault); Debug.Assert(type != null); _method = method; _locations = locations; _nameOpt = nameOpt; _ordinal = ordinal; _declarationKind = declarationKind; _type = type; _refKind = refKind; _isPinned = isPinned; _isCompilerGenerated = isCompilerGenerated; _canScheduleToStack = canScheduleToStack; }
public SignatureOnlyMethodSymbol( string name, TypeSymbol containingType, MethodKind methodKind, Cci.CallingConvention callingConvention, ImmutableArray<TypeParameterSymbol> typeParameters, ImmutableArray<ParameterSymbol> parameters, RefKind refKind, TypeSymbol returnType, ImmutableArray<CustomModifier> returnTypeCustomModifiers, ushort countOfCustomModifiersPrecedingByRef, ImmutableArray<MethodSymbol> explicitInterfaceImplementations) { _callingConvention = callingConvention; _typeParameters = typeParameters; _refKind = refKind; _returnType = returnType; _returnTypeCustomModifiers = returnTypeCustomModifiers; _countOfCustomModifiersPrecedingByRef = countOfCustomModifiersPrecedingByRef; _parameters = parameters; _explicitInterfaceImplementations = explicitInterfaceImplementations.NullToEmpty(); _containingType = containingType; _methodKind = methodKind; _name = name; }
internal TempLocalSymbol(TypeSymbol type, RefKind refKind, MethodSymbol containingMethod) : base(containingMethod, type, null) { this.refKind = refKind; #if TEMPNAMES this.name = "_" + Interlocked.Increment(ref nextName); #endif }
private static bool IsSafeForReordering(BoundExpression expression, RefKind kind) { // To be safe for reordering an expression must not cause any observable side effect *or // observe any side effect*. Accessing a local by value, for example, is possibly not // safe for reordering because reading a local can give a different result if reordered // with respect to a write elsewhere. var current = expression; while (true) { if (current.ConstantValue != null) { return true; } switch (current.Kind) { default: return false; case BoundKind.Parameter: case BoundKind.Local: // A ref to a local variable or formal parameter is safe to reorder; it // never has a side effect or consumes one. return kind != RefKind.None; case BoundKind.Conversion: { BoundConversion conv = (BoundConversion)current; switch (conv.ConversionKind) { case ConversionKind.AnonymousFunction: case ConversionKind.ImplicitConstant: case ConversionKind.MethodGroup: case ConversionKind.NullLiteral: return true; case ConversionKind.Boxing: case ConversionKind.Dynamic: case ConversionKind.ExplicitEnumeration: case ConversionKind.ExplicitNullable: case ConversionKind.ExplicitNumeric: case ConversionKind.ExplicitReference: case ConversionKind.Identity: case ConversionKind.ImplicitEnumeration: case ConversionKind.ImplicitNullable: case ConversionKind.ImplicitNumeric: case ConversionKind.ImplicitReference: case ConversionKind.Unboxing: current = conv.Operand; break; case ConversionKind.ExplicitUserDefined: case ConversionKind.ImplicitUserDefined: return false; default: Debug.Fail("Unhandled conversion kind in reordering logic"); return false; } break; } } } }
public PackedFlags(RefKind refKind, bool attributesAreComplete) { int refKindBits = ((int)refKind & RefKindMask) << RefKindOffset; int attributeBits = attributesAreComplete ? AllWellKnownAttributesCompleteNoData : 0; _bits = refKindBits | attributeBits; }
protected override void WriteArgument(BoundExpression arg, RefKind refKind, MethodSymbol method) { // ref parameter does not "always" assign. if (refKind == RefKind.Out) { Assign(arg, value: null); } }
public PackedFlags(RefKind refKind, bool attributesAreComplete, bool hasNameInMetadata) { int refKindBits = ((int)refKind & RefKindMask) << RefKindOffset; int attributeBits = attributesAreComplete ? AllWellKnownAttributesCompleteNoData : 0; int hasNameInMetadataBits = hasNameInMetadata ? HasNameInMetadataBit : 0; _bits = refKindBits | attributeBits | hasNameInMetadataBits; }
internal static TypeSymbol TransformTypeWithoutCustomModifierFlags( TypeSymbol type, AssemblySymbol containingAssembly, RefKind targetSymbolRefKind, ImmutableArray<bool> dynamicTransformFlags) { Debug.Assert(containingAssembly is SourceAssemblySymbol); // Doesn't happen during decoding. return TransformTypeInternal(type, containingAssembly, 0, targetSymbolRefKind, dynamicTransformFlags, haveCustomModifierFlags: false); }
public SourceSimpleParameterSymbol( Symbol owner, TypeSymbol parameterType, int ordinal, RefKind refKind, string name, ImmutableArray<Location> locations) : base(owner, parameterType, ordinal, refKind, name, locations) { }
public SignatureOnlyParameterSymbol( TypeSymbol type, ImmutableArray<CustomModifier> customModifiers, bool isParams, RefKind refKind) { this.type = type; this.customModifiers = customModifiers; this.isParams = isParams; this.refKind = refKind; }
public SignatureOnlyParameterSymbol( TypeSymbol type, ImmutableArray<CustomModifier> customModifiers, bool isParams, RefKind refKind) { Debug.Assert(type != null); Debug.Assert(!customModifiers.IsDefault); _type = type; _customModifiers = customModifiers; _isParams = isParams; _refKind = refKind; }
protected SourceParameterSymbol( Symbol owner, TypeSymbol parameterType, int ordinal, RefKind refKind, string name, ImmutableArray<Location> locations) : base(owner, ordinal) { Debug.Assert((owner.Kind == SymbolKind.Method) || (owner.Kind == SymbolKind.Property)); this.parameterType = parameterType; this.refKind = refKind; this.name = name; this.locations = locations; }
internal SynthesizedLocal( MethodSymbol containingMethodOpt, TypeSymbol type, SynthesizedLocalKind kind, CSharpSyntaxNode syntaxOpt = null, bool isPinned = false, RefKind refKind = RefKind.None) { this.containingMethodOpt = containingMethodOpt; this.type = type; this.kind = kind; this.syntaxOpt = syntaxOpt; this.isPinned = isPinned; this.refKind = refKind; }
internal SynthesizedLocal( MethodSymbol containingMethodOpt, TypeSymbol type, SynthesizedLocalKind kind, SyntaxNode syntaxOpt = null, bool isPinned = false, RefKind refKind = RefKind.None) { _containingMethodOpt = containingMethodOpt; _type = type; _kind = kind; _syntaxOpt = syntaxOpt; _isPinned = isPinned; _refKind = refKind; }
public static SourceParameterSymbol Create( Binder context, Symbol owner, TypeSymbol parameterType, ParameterSyntax syntax, RefKind refKind, SyntaxToken identifier, int ordinal, bool isParams, bool isExtensionMethodThis, DiagnosticBag diagnostics) { var name = identifier.ValueText; var locations = ImmutableArray.Create<Location>(new SourceLocation(identifier)); if (!isParams && !isExtensionMethodThis && (syntax.Default == null) && (syntax.AttributeLists.Count == 0) && !owner.IsPartialMethod()) { return new SourceSimpleParameterSymbol(owner, parameterType, ordinal, refKind, name, locations); } if (isParams) { // touch the constructor in order to generate proper use-site diagnostics Binder.ReportUseSiteDiagnosticForSynthesizedAttribute(context.Compilation, WellKnownMember.System_ParamArrayAttribute__ctor, diagnostics, identifier.Parent.GetLocation()); } var syntaxRef = syntax.GetReference(); return new SourceComplexParameterSymbol( owner, ordinal, parameterType, refKind, ImmutableArray<CustomModifier>.Empty, false, name, locations, syntaxRef, ConstantValue.Unset, isParams, isExtensionMethodThis); }
internal static TypeSymbol TransformTypeWithoutCustomModifierFlags( TypeSymbol type, AssemblySymbol containingAssembly, RefKind targetSymbolRefKind, ImmutableArray<bool> dynamicTransformFlags, bool checkLength = true) { return TransformTypeInternal( type, containingAssembly, 0, targetSymbolRefKind, dynamicTransformFlags, haveCustomModifierFlags: false, checkLength: checkLength); }
public LambdaSymbol( Symbol containingSymbol, ImmutableArray<ParameterSymbol> parameters, RefKind refKind, TypeSymbol returnType, MessageID messageID, CSharpSyntaxNode syntax, bool isSynthesized) { _containingSymbol = containingSymbol; _messageID = messageID; _syntax = syntax; _refKind = refKind; _returnType = returnType; _isSynthesized = isSynthesized; _parameters = parameters.SelectAsArray(CopyParameter, this); }
/// <param name="sourceType">Type that already has custom modifiers.</param> /// <param name="destinationType">Same as <paramref name="sourceType"/>, but without custom modifiers. May differ in object/dynamic.</param> /// <param name="refKind"><see cref="RefKind"/> of the parameter of which this is the type (or <see cref="RefKind.None"/> for a return type.</param> /// <param name="containingAssembly">The assembly containing the signature referring to the destination type.</param> /// <returns><paramref name="destinationType"/> with custom modifiers copied from <paramref name="sourceType"/>.</returns> internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSymbol destinationType, RefKind refKind, AssemblySymbol containingAssembly) { Debug.Assert(sourceType.Equals(destinationType, ignoreCustomModifiers: true, ignoreDynamic: true)); // NOTE: overrides can differ by object/dynamic. If they do, we'll need to tweak newType before // we can use it in place of this.Type. We do so by computing the dynamic transform flags that // code gen uses and then passing them to the dynamic type decoder that metadata reading uses. const int customModifierCount = 0;// Ignore custom modifiers, since we're not done copying them. ImmutableArray<bool> flags = CSharpCompilation.DynamicTransformsEncoder.Encode(destinationType, customModifierCount, refKind); TypeSymbol resultType = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(sourceType, containingAssembly, refKind, flags); Debug.Assert(resultType.Equals(sourceType, ignoreCustomModifiers: false, ignoreDynamic: true)); // Same custom modifiers as source type. Debug.Assert(resultType.Equals(destinationType, ignoreCustomModifiers: true, ignoreDynamic: false)); // Same object/dynamic as destination type. return resultType; }
public LambdaSymbol( CSharpCompilation compilation, Symbol containingSymbol, UnboundLambda unboundLambda, ImmutableArray<ParameterSymbol> delegateParameters, RefKind refKind, TypeSymbol returnType) { _containingSymbol = containingSymbol; _messageID = unboundLambda.Data.MessageID; _syntax = unboundLambda.Syntax; _refKind = refKind; _returnType = returnType; _isSynthesized = unboundLambda.WasCompilerGenerated; _isAsync = unboundLambda.IsAsync; // No point in making this lazy. We are always going to need these soon after creation of the symbol. _parameters = MakeParameters(compilation, unboundLambda, delegateParameters); }
public SynthesizedParameterSymbol( MethodSymbol container, TypeSymbol type, int ordinal, RefKind refKind, string name = "", ImmutableArray<CustomModifier> customModifiers = default(ImmutableArray<CustomModifier>)) { Debug.Assert((object)type != null); Debug.Assert(name != null); Debug.Assert(ordinal >= 0); this.container = container; this.type = type; this.ordinal = ordinal; this.refKind = refKind; this.name = name; this.customModifiers = customModifiers.NullToEmpty(); }
public SignatureOnlyPropertySymbol( string name, TypeSymbol containingType, ImmutableArray<ParameterSymbol> parameters, RefKind refKind, TypeSymbol type, ImmutableArray<CustomModifier> typeCustomModifiers, bool isStatic, ImmutableArray<PropertySymbol> explicitInterfaceImplementations) { _refKind = refKind; _type = type; _typeCustomModifiers = typeCustomModifiers; _isStatic = isStatic; _parameters = parameters; _explicitInterfaceImplementations = explicitInterfaceImplementations.NullToEmpty(); _containingType = containingType; _name = name; }
internal SourcePrimaryConstructorParameterSymbolWithBackingField( Symbol owner, int ordinal, TypeSymbol parameterType, RefKind refKind, string name, ImmutableArray<Location> locations, ParameterSyntax syntax, ConstantValue defaultSyntaxValue, bool isParams, bool isExtensionMethodThis, DiagnosticBag diagnostics ) : base(owner, ordinal, parameterType, refKind, ImmutableArray<CustomModifier>.Empty, false, name, locations, syntax.GetReference(), defaultSyntaxValue, isParams, isExtensionMethodThis) { bool modifierErrors; var modifiers = SourceMemberFieldSymbol.MakeModifiers(owner.ContainingType, syntax.Identifier, syntax.Modifiers, diagnostics, out modifierErrors, ignoreParameterModifiers: true); backingField = new BackingField(this, modifiers, modifierErrors, diagnostics); }
/// <summary> /// Takes an expression and returns the bound local expression "temp" /// and the bound assignment expression "temp = expr". /// </summary> /// <param name="argument"></param> /// <param name="refKind"></param> /// <param name="containingMethod"></param> /// <returns></returns> public static Pair<BoundAssignmentOperator, BoundLocal> StoreToTemp(BoundExpression argument, RefKind refKind, MethodSymbol containingMethod) { var syntax = argument.Syntax; var type = argument.Type; var local = new BoundLocal( syntax, // TODO: the following temp local symbol should have its ContainingSymbol set. new TempLocalSymbol(type, refKind, containingMethod), null, type); var store = new BoundAssignmentOperator( syntax, local, argument, refKind, type); return Pair.Make(store, local); }
/// <summary> /// Decodes the attributes applied to the given <see paramref="targetSymbol"/> from metadata and checks if <see cref="System.Runtime.CompilerServices.DynamicAttribute"/> is applied. /// If so, it transforms the given <see paramref="metadataType"/>, using the decoded dynamic transforms attribute argument, /// by replacing each occurrence of <see cref="System.Object"/> type with dynamic type. /// If no <see cref="System.Runtime.CompilerServices.DynamicAttribute"/> is applied or the decoded dynamic transforms attribute argument is errorneous, /// returns the unchanged <see paramref="metadataType"/>. /// </summary> /// <remarks>This method is a port of TypeManager::ImportDynamicTransformType from the native compiler.</remarks> internal static TypeSymbol TransformType( TypeSymbol metadataType, int targetSymbolCustomModifierCount, Handle targetSymbolToken, PEModuleSymbol containingModule, RefKind targetSymbolRefKind = RefKind.None) { Debug.Assert((object)metadataType != null); ImmutableArray<bool> dynamicTransformFlags; if (containingModule.Module.HasDynamicAttribute(targetSymbolToken, out dynamicTransformFlags)) { return TransformTypeInternal(metadataType, containingModule.ContainingAssembly, targetSymbolCustomModifierCount, targetSymbolRefKind, dynamicTransformFlags, haveCustomModifierFlags: true); } // No DynamicAttribute applied to the target symbol, return unchanged metadataType. return metadataType; }
internal SourceComplexParameterSymbol( Symbol owner, int ordinal, TypeSymbol parameterType, RefKind refKind, ImmutableArray<CustomModifier> customModifiers, bool hasByRefBeforeCustomModifiers, string name, ImmutableArray<Location> locations, SyntaxReference syntaxRef, ConstantValue defaultSyntaxValue, bool isParams, bool isExtensionMethodThis) : base(owner, parameterType, ordinal, refKind, name, locations) { Debug.Assert((syntaxRef == null) || (syntaxRef.GetSyntax().IsKind(SyntaxKind.Parameter))); Debug.Assert(!customModifiers.IsDefault); _lazyHasOptionalAttribute = ThreeState.Unknown; _syntaxRef = syntaxRef; if (isParams) { _parameterSyntaxKind |= ParameterSyntaxKind.ParamsParameter; } if (isExtensionMethodThis) { _parameterSyntaxKind |= ParameterSyntaxKind.ExtensionThisParameter; } var parameterSyntax = this.CSharpSyntaxNode; if (parameterSyntax != null && parameterSyntax.Default != null) { _parameterSyntaxKind |= ParameterSyntaxKind.DefaultParameter; } _lazyDefaultSyntaxValue = defaultSyntaxValue; _customModifiers = customModifiers; _hasByRefBeforeCustomModifiers = hasByRefBeforeCustomModifiers; }
public SynthesizedParameterSymbol( MethodSymbol container, TypeSymbol type, int ordinal, RefKind refKind, string name = "", ImmutableArray<CustomModifier> customModifiers = default(ImmutableArray<CustomModifier>), ushort countOfCustomModifiersPrecedingByRef = 0) { Debug.Assert((object)type != null); Debug.Assert(name != null); Debug.Assert(ordinal >= 0); _container = container; _type = type; _ordinal = ordinal; _refKind = refKind; _name = name; _customModifiers = customModifiers.NullToEmpty(); _countOfCustomModifiersPrecedingByRef = countOfCustomModifiersPrecedingByRef; }
protected override TypeSymbol GetCurrentReturnType(out RefKind refKind) { refKind = lambdaSymbol.RefKind; return(lambdaSymbol.ReturnType.TypeSymbol); }
public static bool IsManagedReference(this RefKind refKind) { Debug.Assert(refKind <= RefKind.RefReadOnly); return(refKind != RefKind.None); }
internal static void EncodeInternal(TypeSymbol type, int customModifiersCount, RefKind refKind, ArrayBuilder <bool> transformFlagsBuilder) { Debug.Assert(!transformFlagsBuilder.Any()); if (refKind != RefKind.None) { // Native compiler encodes an extra transform flag, always false, for ref/out parameters. transformFlagsBuilder.Add(false); } // Native compiler encodes an extra transform flag, always false, for each custom modifier. HandleCustomModifiers(customModifiersCount, transformFlagsBuilder); type.VisitType(s_encodeDynamicTransform, transformFlagsBuilder); }
private TypeSymbol GetDynamicType(TypeSymbol type, RefKind refKind, ImmutableArray <bool> dynamicFlags) { return(DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(type, _sourceAssembly, refKind, dynamicFlags, checkLength: false)); }
/// <param name="sourceType">Type that already has custom modifiers.</param> /// <param name="destinationType">Same as <paramref name="sourceType"/>, but without custom modifiers. May differ in object/dynamic.</param> /// <param name="refKind"><see cref="RefKind"/> of the parameter of which this is the type (or <see cref="RefKind.None"/> for a return type.</param> /// <param name="containingAssembly">The assembly containing the signature referring to the destination type.</param> /// <returns><paramref name="destinationType"/> with custom modifiers copied from <paramref name="sourceType"/>.</returns> internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSymbol destinationType, RefKind refKind, AssemblySymbol containingAssembly) { Debug.Assert(sourceType.Equals(destinationType, TypeCompareKind.AllIgnoreOptions)); // NOTE: overrides can differ by object/dynamic. If they do, we'll need to tweak newType before // we can use it in place of this.Type. We do so by computing the dynamic transform flags that // code gen uses and then passing them to the dynamic type decoder that metadata reading uses. ImmutableArray <bool> flags = CSharpCompilation.DynamicTransformsEncoder.EncodeWithoutCustomModifierFlags(destinationType, refKind); TypeSymbol typeWithDynamic = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(sourceType, containingAssembly, refKind, flags); TypeSymbol resultType; if (destinationType.ContainsTuple() && !sourceType.Equals(destinationType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | TypeCompareKind.IgnoreDynamic)) { // We also preserve tuple names, if present and different ImmutableArray <string> names = CSharpCompilation.TupleNamesEncoder.Encode(destinationType); resultType = TupleTypeDecoder.DecodeTupleTypesIfApplicable(typeWithDynamic, names); } else { resultType = typeWithDynamic; } Debug.Assert(resultType.Equals(sourceType, TypeCompareKind.IgnoreDynamicAndTupleNames)); // Same custom modifiers as source type. Debug.Assert(resultType.Equals(destinationType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds)); // Same object/dynamic and tuple names as destination type. return(resultType); }
/// <summary> /// Given a type <paramref name="type"/>, which is either dynamic type OR is a constructed type with dynamic type present in it's type argument tree, /// returns a synthesized DynamicAttribute with encoded dynamic transforms array. /// </summary> /// <remarks>This method is port of AttrBind::CompileDynamicAttr from the native C# compiler.</remarks> internal SynthesizedAttributeData SynthesizeDynamicAttribute(TypeSymbol type, int customModifiersCount, RefKind refKindOpt = RefKind.None) { Debug.Assert((object)type != null); Debug.Assert(type.ContainsDynamic()); if (type.IsDynamic() && refKindOpt == RefKind.None && customModifiersCount == 0) { return(SynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_DynamicAttribute__ctor)); } else { NamedTypeSymbol booleanType = GetSpecialType(SpecialType.System_Boolean); Debug.Assert((object)booleanType != null); var transformFlags = DynamicTransformsEncoder.Encode(type, booleanType, customModifiersCount, refKindOpt); var boolArray = new ArrayTypeSymbol(booleanType.ContainingAssembly, booleanType, customModifiers: ImmutableArray <CustomModifier> .Empty); var arguments = ImmutableArray.Create <TypedConstant>(new TypedConstant(boolArray, transformFlags)); return(SynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_DynamicAttribute__ctorTransformFlags, arguments)); } }
private PEParameterSymbol( PEModuleSymbol moduleSymbol, Symbol containingSymbol, int ordinal, bool isByRef, TypeSymbol type, ParameterHandle handle, out bool isBad) { Debug.Assert((object)moduleSymbol != null); Debug.Assert((object)containingSymbol != null); Debug.Assert(ordinal >= 0); Debug.Assert((object)type != null); isBad = false; _moduleSymbol = moduleSymbol; _containingSymbol = containingSymbol; _ordinal = (ushort)ordinal; _handle = handle; RefKind refKind = RefKind.None; if (handle.IsNil) { refKind = isByRef ? RefKind.Ref : RefKind.None; _type = type; _lazyCustomAttributes = ImmutableArray <AttributeData> .Empty; _lazyHiddenAttributes = ImmutableArray <AttributeData> .Empty; _lazyDefaultValue = ConstantValue.NotAvailable; _lazyIsParams = ThreeState.False; } else { try { moduleSymbol.Module.GetParamPropsOrThrow(handle, out _name, out _flags); } catch (BadImageFormatException) { isBad = true; } if (isByRef) { ParameterAttributes inOutFlags = _flags & (ParameterAttributes.Out | ParameterAttributes.In); refKind = (inOutFlags == ParameterAttributes.Out) ? RefKind.Out : RefKind.Ref; } // CONSIDER: Can we make parameter type computation lazy? _type = type; // DynamicTypeDecoder.TransformType(type, countOfCustomModifiers, handle, moduleSymbol, refKind); } bool hasNameInMetadata = !string.IsNullOrEmpty(_name); if (!hasNameInMetadata) { // As was done historically, if the parameter doesn't have a name, we give it the name "value". _name = "value"; } _packedFlags = new PackedFlags(refKind, attributesAreComplete: handle.IsNil, hasNameInMetadata: hasNameInMetadata); Debug.Assert(refKind == this.RefKind); Debug.Assert(hasNameInMetadata == this.HasNameInMetadata); }
private static void AppendSignatureType(StringBuilder result, TypeSymbol type, RefKind refKind) { result.Append(type); if (refKind != RefKind.None) { result.Append("&"); } }
// Native compiler encodes bools (always false) for custom modifiers and parameter ref-kinds, if ref-kind is ref or out. private bool HandleParameterRefKind(RefKind refKind) { Debug.Assert(_index >= 0); return(refKind == RefKind.None || !ConsumeFlag()); }
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; BadImageFormatException mrEx = null; try { module.GetPropertyDefPropsOrThrow(handle, out _name, out mdFlags); } catch (BadImageFormatException e) { mrEx = e; if ((object)_name == null) { _name = string.Empty; } } _getMethod = getMethod; _setMethod = setMethod; _handle = handle; SignatureHeader unusedCallingConvention; BadImageFormatException getEx = null; var getMethodParams = (object)getMethod == null ? null : metadataDecoder.GetSignatureForMethod(getMethod.Handle, out unusedCallingConvention, out getEx); BadImageFormatException setEx = null; var setMethodParams = (object)setMethod == null ? null : metadataDecoder.GetSignatureForMethod(setMethod.Handle, out unusedCallingConvention, out setEx); // NOTE: property parameter names are not recorded in metadata, so we have to // use the parameter names from one of the indexers // NB: prefer setter names to getter names if both are present. bool isBad; _parameters = setMethodParams is null ? GetParameters(moduleSymbol, this, propertyParams, getMethodParams, getMethod.IsMetadataVirtual(), out isBad) : GetParameters(moduleSymbol, this, propertyParams, setMethodParams, setMethod.IsMetadataVirtual(), out isBad); if (getEx != null || setEx != null || mrEx != null || isBad) { _lazyUseSiteDiagnostic = new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this); } var returnInfo = propertyParams[0]; var typeCustomModifiers = CSharpCustomModifier.Convert(returnInfo.CustomModifiers); if (returnInfo.IsByRef) { if (moduleSymbol.Module.HasIsReadOnlyAttribute(handle)) { _refKind = RefKind.RefReadOnly; } else { _refKind = RefKind.Ref; } } else { _refKind = RefKind.None; } // CONSIDER: Can we make parameter type computation lazy? TypeSymbol originalPropertyType = returnInfo.Type; originalPropertyType = DynamicTypeDecoder.TransformType(originalPropertyType, typeCustomModifiers.Length, handle, moduleSymbol, _refKind); // Dynamify object type if necessary originalPropertyType = originalPropertyType.AsDynamicIfNoPia(_containingType); // We start without annotation (they will be decoded below) var propertyType = TypeSymbolWithAnnotations.Create(originalPropertyType, customModifiers: typeCustomModifiers); // Decode nullable before tuple types to avoid converting between // NamedTypeSymbol and TupleTypeSymbol unnecessarily. propertyType = NullableTypeDecoder.TransformType(propertyType, handle, moduleSymbol); propertyType = TupleTypeDecoder.DecodeTupleTypesIfApplicable(propertyType, handle, moduleSymbol); _propertyType = propertyType; // A property is bogus and must be accessed by calling its accessors directly if the // accessor signatures do not agree, both with each other and with the property, // or if it has parameters and is not an indexer or indexed property. bool callMethodsDirectly = !DoSignaturesMatch(module, metadataDecoder, propertyParams, _getMethod, getMethodParams, _setMethod, setMethodParams) || MustCallMethodsDirectlyCore(); if (!callMethodsDirectly) { if ((object)_getMethod != null) { _getMethod.SetAssociatedProperty(this, MethodKind.PropertyGet); } if ((object)_setMethod != null) { _setMethod.SetAssociatedProperty(this, MethodKind.PropertySet); } } if (callMethodsDirectly) { _flags |= Flags.CallMethodsDirectly; } if ((mdFlags & PropertyAttributes.SpecialName) != 0) { _flags |= Flags.IsSpecialName; } if ((mdFlags & PropertyAttributes.RTSpecialName) != 0) { _flags |= Flags.IsRuntimeSpecialName; } }
internal static ImmutableArray <bool> Encode(TypeSymbol type, int customModifiersCount, RefKind refKind) { var transformFlagsBuilder = ArrayBuilder <bool> .GetInstance(); EncodeInternal(type, customModifiersCount, refKind, transformFlagsBuilder); return(transformFlagsBuilder.ToImmutableAndFree()); }
internal BoundExpression GetArgumentInfo( MethodSymbol argumentInfoFactory, BoundExpression boundArgument, string name, RefKind refKind, bool isStaticType) { CSharpArgumentInfoFlags flags = 0; if (isStaticType) { flags |= CSharpArgumentInfoFlags.IsStaticType; } if (name != null) { flags |= CSharpArgumentInfoFlags.NamedArgument; } Debug.Assert(refKind == RefKind.None || refKind == RefKind.Ref || refKind == RefKind.Out, "unexpected refKind in dynamic"); // by-ref type doesn't trigger dynamic dispatch and it can't be a null literal => set UseCompileTimeType if (refKind == RefKind.Out) { flags |= CSharpArgumentInfoFlags.IsOut | CSharpArgumentInfoFlags.UseCompileTimeType; } else if (refKind == RefKind.Ref) { flags |= CSharpArgumentInfoFlags.IsRef | CSharpArgumentInfoFlags.UseCompileTimeType; } var argType = boundArgument.Type; // Check "literal" constant. // What the runtime binder does with this LiteralConstant flag is just to create a constant, // which is a compelling enough reason to make sure that on the production end of the binder // data, we do the inverse (i.e., use the LiteralConstant flag whenever we encounter a constant // argument. // And in fact, the bug being fixed with this change is that the compiler will consider constants // for numeric and enum conversions even if they are not literals (such as, (1-1) --> enum), but // the runtime binder didn't. So we do need to set this flag whenever we see a constant. // But the complication is that null values lose their type when they get to the runtime binder, // and so we need a way to distinguish a null constant of any given type from the null literal. // The design is simple! We use UseCompileTimeType to determine whether we care about the type of // a null constant argument, so that the null literal gets "LiteralConstant" whereas every other // constant gets "LiteralConstant | UseCompileTimeType". Because obviously UseCompileTimeType is // wrong for the null literal. // We care, because we want to prevent this from working: // // const C x = null; // class C { public void M(SomeUnrelatedReferenceType x) { } } // ... // dynamic d = new C(); d.M(x); // This will pass a null constant and the type is gone! // // as well as the alternative where x is a const null of type object. if (boundArgument.ConstantValue != null) { flags |= CSharpArgumentInfoFlags.Constant; } // Check compile time type. // See also DynamicRewriter::GenerateCallingObjectFlags. if ((object)argType != null && !argType.IsDynamic()) { flags |= CSharpArgumentInfoFlags.UseCompileTimeType; } return(_factory.Call(null, argumentInfoFactory, _factory.Literal((int)flags), _factory.Literal(name))); }
internal NamedTypeSymbol GetDelegateType( BoundExpression loweredReceiver, RefKind receiverRefKind, ImmutableArray <BoundExpression> loweredArguments, ImmutableArray <RefKind> refKinds, BoundExpression loweredRight, TypeSymbol resultType) { Debug.Assert(refKinds.IsDefaultOrEmpty || refKinds.Length == loweredArguments.Length); var callSiteType = _factory.WellKnownType(WellKnownType.System_Runtime_CompilerServices_CallSite); if (callSiteType.IsErrorType()) { return(null); } var delegateSignature = MakeCallSiteDelegateSignature(callSiteType, loweredReceiver, loweredArguments, loweredRight, resultType); bool returnsVoid = resultType.IsVoidType(); bool hasByRefs = receiverRefKind != RefKind.None || !refKinds.IsDefaultOrEmpty; if (!hasByRefs) { var wkDelegateType = returnsVoid ? WellKnownTypes.GetWellKnownActionDelegate(invokeArgumentCount: delegateSignature.Length) : WellKnownTypes.GetWellKnownFunctionDelegate(invokeArgumentCount: delegateSignature.Length - 1); if (wkDelegateType != WellKnownType.Unknown) { var delegateType = _factory.Compilation.GetWellKnownType(wkDelegateType); if (!delegateType.HasUseSiteError) { return(delegateType.Construct(delegateSignature)); } } } BitVector byRefs; if (hasByRefs) { byRefs = BitVector.Create(1 + (loweredReceiver != null ? 1 : 0) + loweredArguments.Length + (loweredRight != null ? 1 : 0)); int j = 1; if (loweredReceiver != null) { byRefs[j++] = receiverRefKind != RefKind.None; } if (!refKinds.IsDefault) { for (int i = 0; i < refKinds.Length; i++, j++) { if (refKinds[i] != RefKind.None) { byRefs[j] = true; } } } } else { byRefs = default(BitVector); } int parameterCount = delegateSignature.Length - (returnsVoid ? 0 : 1); int generation = _factory.CompilationState.ModuleBuilderOpt.CurrentGenerationOrdinal; var synthesizedType = _factory.Compilation.AnonymousTypeManager.SynthesizeDelegate(parameterCount, byRefs, returnsVoid, generation); return(synthesizedType.Construct(delegateSignature)); }
internal LoweredDynamicOperation MakeDynamicOperation( BoundExpression binderConstruction, BoundExpression loweredReceiver, RefKind receiverRefKind, ImmutableArray <BoundExpression> loweredArguments, ImmutableArray <RefKind> refKinds, BoundExpression loweredRight, TypeSymbol resultType) { Debug.Assert(!loweredArguments.IsDefault); // get well-known types and members we need: NamedTypeSymbol delegateTypeOverMethodTypeParameters = GetDelegateType(loweredReceiver, receiverRefKind, loweredArguments, refKinds, loweredRight, resultType); NamedTypeSymbol callSiteTypeGeneric = _factory.WellKnownType(WellKnownType.System_Runtime_CompilerServices_CallSite_T); MethodSymbol callSiteFactoryGeneric = _factory.WellKnownMethod(WellKnownMember.System_Runtime_CompilerServices_CallSite_T__Create); FieldSymbol callSiteTargetFieldGeneric = (FieldSymbol)_factory.WellKnownMember(WellKnownMember.System_Runtime_CompilerServices_CallSite_T__Target); MethodSymbol delegateInvoke; if (binderConstruction == null || (object)delegateTypeOverMethodTypeParameters == null || delegateTypeOverMethodTypeParameters.IsErrorType() || (object)(delegateInvoke = delegateTypeOverMethodTypeParameters.DelegateInvokeMethod) == null || callSiteTypeGeneric.IsErrorType() || (object)callSiteFactoryGeneric == null || (object)callSiteTargetFieldGeneric == null) { // CS1969: One or more types required to compile a dynamic expression cannot be found. // Dev11 reports it with source location for each dynamic operation, which results in many error messages. // The diagnostic that names the specific missing type or member has already been reported. _factory.Diagnostics.Add(ErrorCode.ERR_DynamicRequiredTypesMissing, NoLocation.Singleton); return(LoweredDynamicOperation.Bad(loweredReceiver, loweredArguments, loweredRight, resultType)); } if ((object)_currentDynamicCallSiteContainer == null) { _currentDynamicCallSiteContainer = CreateCallSiteContainer(_factory, _methodOrdinal); } var containerDef = (SynthesizedContainer)_currentDynamicCallSiteContainer.OriginalDefinition; var methodToContainerTypeParametersMap = containerDef.TypeMap; ImmutableArray <LocalSymbol> temps = MakeTempsForDiscardArguments(ref loweredArguments); var callSiteType = callSiteTypeGeneric.Construct(new[] { delegateTypeOverMethodTypeParameters }); var callSiteFactoryMethod = callSiteFactoryGeneric.AsMember(callSiteType); var callSiteTargetField = callSiteTargetFieldGeneric.AsMember(callSiteType); var callSiteField = DefineCallSiteStorageSymbol(containerDef, delegateTypeOverMethodTypeParameters, methodToContainerTypeParametersMap); var callSiteFieldAccess = _factory.Field(null, callSiteField); var callSiteArguments = GetCallSiteArguments(callSiteFieldAccess, loweredReceiver, loweredArguments, loweredRight); var nullCallSite = _factory.Null(callSiteField.Type); var siteInitialization = _factory.Conditional( _factory.ObjectEqual(callSiteFieldAccess, nullCallSite), _factory.AssignmentExpression(callSiteFieldAccess, _factory.Call(null, callSiteFactoryMethod, binderConstruction)), nullCallSite, callSiteField.Type); var siteInvocation = _factory.Call( _factory.Field(callSiteFieldAccess, callSiteTargetField), delegateInvoke, callSiteArguments); return(new LoweredDynamicOperation(_factory, siteInitialization, siteInvocation, resultType, temps)); }
public static IParameterSymbol CreateParameterSymbol(RefKind refKind, ITypeSymbol type, string name) { return(CreateParameterSymbol( attributes: default, refKind, isParams: false, type: type, name: name, isOptional: false));
/// <summary> /// Behavior of this function should be kept aligned with <see cref="UnboundLambdaState.ReturnInferenceCacheKey"/>. /// </summary> private static TypeSymbol InferReturnType( BoundBlock block, Binder binder, TypeSymbol delegateType, bool isAsync, ref HashSet <DiagnosticInfo> useSiteDiagnostics, out RefKind refKind, out bool inferredFromSingleType) { int numberOfDistinctReturns; var resultTypes = BlockReturns.GetReturnTypes(block, out refKind, out numberOfDistinctReturns); inferredFromSingleType = numberOfDistinctReturns < 2; TypeSymbol bestResultType; if (resultTypes.IsDefaultOrEmpty) { bestResultType = null; } else if (resultTypes.Length == 1) { bestResultType = resultTypes[0]; } else { bestResultType = BestTypeInferrer.InferBestType(resultTypes, binder.Conversions, ref useSiteDiagnostics); } if (!isAsync) { return(bestResultType); } // For async lambdas, the return type is the return type of the // delegate Invoke method if Invoke has a Task-like return type. // Otherwise the return type is Task or Task<T>. NamedTypeSymbol taskType = null; var delegateReturnType = delegateType?.GetDelegateType()?.DelegateInvokeMethod?.ReturnType as NamedTypeSymbol; if ((object)delegateReturnType != null && delegateReturnType.SpecialType != SpecialType.System_Void) { object builderType; if (delegateReturnType.IsCustomTaskType(out builderType)) { taskType = delegateReturnType.ConstructedFrom; } } if (resultTypes.IsEmpty) { // No return statements have expressions; use delegate InvokeMethod // or infer type Task if delegate type not available. return((object)taskType != null && taskType.Arity == 0 ? taskType : binder.Compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task)); } if ((object)bestResultType == null || bestResultType.SpecialType == SpecialType.System_Void) { // If the best type was 'void', ERR_CantReturnVoid is reported while binding the "return void" // statement(s). return(null); } // Some non-void best type T was found; use delegate InvokeMethod // or infer type Task<T> if delegate type not available. var taskTypeT = (object)taskType != null && taskType.Arity == 1 ? taskType : binder.Compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task_T); return(taskTypeT.Construct(bestResultType)); }
internal static ImmutableArray <TypedConstant> Encode(TypeSymbol type, TypeSymbol booleanType, int customModifiersCount, RefKind refKind) { var flagsBuilder = ArrayBuilder <bool> .GetInstance(); EncodeInternal(type, customModifiersCount, refKind, flagsBuilder); Debug.Assert(flagsBuilder.Any()); Debug.Assert(flagsBuilder.Contains(true)); var constantsBuilder = ArrayBuilder <TypedConstant> .GetInstance(flagsBuilder.Count); foreach (bool flag in flagsBuilder) { constantsBuilder.Add(new TypedConstant(booleanType, TypedConstantKind.Primitive, flag)); } flagsBuilder.Free(); return(constantsBuilder.ToImmutableAndFree()); }
public LocalSymbol SynthesizedLocal(TypeSymbol type, CSharpSyntaxNode syntax = null, bool isPinned = false, RefKind refKind = RefKind.None, SynthesizedLocalKind kind = SynthesizedLocalKind.LoweringTemp) { return(new SynthesizedLocal(CurrentMethod, type, kind, syntax, isPinned, refKind)); }
/// <summary> /// Creates a parameter symbol that can be used to describe a parameter declaration. /// </summary> public static IParameterSymbol CreateParameterSymbol(IList <AttributeData> attributes, RefKind refKind, bool isParams, ITypeSymbol type, string name, bool isOptional = false, bool hasDefaultValue = false, object defaultValue = null) { return(new CodeGenerationParameterSymbol(null, attributes, refKind, isParams, type, name, isOptional, hasDefaultValue, defaultValue)); }
public BoundAssignmentOperator AssignmentExpression(BoundExpression left, BoundExpression right, RefKind refKind = RefKind.None) { Debug.Assert(left.Type.Equals(right.Type, ignoreDynamic: true) || right.Type.IsErrorType() || left.Type.IsErrorType()); return(new BoundAssignmentOperator(Syntax, left, right, left.Type, refKind: refKind) { WasCompilerGenerated = true }); }
private BoundExpression Spill( BoundSpillSequence2 spill, BoundExpression e, RefKind refKind = RefKind.None, bool sideEffectsOnly = false) { Debug.Assert(spill != null); while (true) { switch (e.Kind) { case BoundKind.ArrayInitialization: { Debug.Assert(refKind == RefKind.None); Debug.Assert(!sideEffectsOnly); var ai = (BoundArrayInitialization)e; var newInitializers = VisitExpressionList(ref spill, ai.Initializers, forceSpill: true); return(ai.Update(newInitializers)); } case BoundKind.ArgListOperator: { Debug.Assert(refKind == RefKind.None); Debug.Assert(!sideEffectsOnly); var al = (BoundArgListOperator)e; var newArgs = VisitExpressionList(ref spill, al.Arguments, al.ArgumentRefKindsOpt, forceSpill: true); return(al.Update(newArgs, al.ArgumentRefKindsOpt, al.Type)); } case SpillSequence2: { var ss = (BoundSpillSequence2)e; spill.IncludeSequence(ss); e = ss.Value; continue; } case BoundKind.Sequence: { var ss = (BoundSequence)e; spill.AddRange(ss.Locals); spill.AddRange(ss.SideEffects, MakeExpressionStatement); e = ss.Value; continue; } case BoundKind.ThisReference: case BoundKind.BaseReference: { if (refKind != RefKind.None || e.Type.IsReferenceType) { return(e); } goto default; } case BoundKind.Parameter: { if (refKind != RefKind.None) { return(e); } goto default; } case BoundKind.Local: { var local = (BoundLocal)e; if (writeOnceTemps.Contains(local.LocalSymbol) || refKind != RefKind.None) { return(local); } goto default; } case BoundKind.FieldAccess: { var field = (BoundFieldAccess)e; if (field.FieldSymbol.IsReadOnly) { if (field.FieldSymbol.IsStatic) { return(field); } if (field.FieldSymbol.ContainingType.IsValueType) { goto default; } // save the receiver; can get the field later. var receiver = Spill(spill, field.ReceiverOpt, (refKind != RefKind.None && field.FieldSymbol.Type.IsReferenceType) ? refKind : RefKind.None, sideEffectsOnly); return(field.Update(receiver, field.FieldSymbol, field.ConstantValueOpt, field.ResultKind, field.Type)); } goto default; } case BoundKind.Literal: case BoundKind.TypeExpression: return(e); default: { if (e.Type.SpecialType == SpecialType.System_Void || sideEffectsOnly) { spill.Add(F.ExpressionStatement(e)); return(null); } else { BoundAssignmentOperator assignToTemp; var replacement = F.StoreToTemp(e, out assignToTemp, refKind: refKind); spill.Add(replacement.LocalSymbol); writeOnceTemps.Add(replacement.LocalSymbol); spill.Add(F.ExpressionStatement(assignToTemp)); return(replacement); } } } } }
public BoundExpressionStatement Assignment(BoundExpression left, BoundExpression right, RefKind refKind = RefKind.None) { return(ExpressionStatement(AssignmentExpression(left, right, refKind))); }
protected abstract SyntaxNode GetByRefType(SyntaxNode type, RefKind refKind);
/// <summary> /// Takes an expression and returns the bound local expression "temp" /// and the bound assignment expression "temp = expr". /// </summary> public BoundLocal StoreToTemp(BoundExpression argument, out BoundAssignmentOperator store, RefKind refKind = RefKind.None, SynthesizedLocalKind kind = SynthesizedLocalKind.LoweringTemp) { MethodSymbol containingMethod = this.CurrentMethod; var syntax = argument.Syntax; var type = argument.Type; var local = new BoundLocal( syntax, new SynthesizedLocal(containingMethod, type, kind, syntax: kind.IsLongLived() ? syntax : null, refKind: refKind), null, type); store = new BoundAssignmentOperator( syntax, local, argument, refKind, type); return(local); }
public async Task <Solution> AddParameterAsync( Document invocationDocument, IMethodSymbol method, ITypeSymbol newParamaterType, RefKind refKind, string parameterName, int?newParameterIndex, bool fixAllReferences, CancellationToken cancellationToken) { var solution = invocationDocument.Project.Solution; var referencedSymbols = fixAllReferences ? await FindMethodDeclarationReferencesAsync(invocationDocument, method, cancellationToken).ConfigureAwait(false) : method.GetAllMethodSymbolsOfPartialParts(); var anySymbolReferencesNotInSource = referencedSymbols.Any(symbol => !symbol.IsFromSource()); var locationsInSource = referencedSymbols.Where(symbol => symbol.IsFromSource()); // Indexing Locations[0] is valid because IMethodSymbols have one location at most // and IsFromSource() tests if there is at least one location. var locationsByDocument = locationsInSource.ToLookup(declarationLocation => solution.GetDocument(declarationLocation.Locations[0].SourceTree)); foreach (var documentLookup in locationsByDocument) { var document = documentLookup.Key; var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>(); var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var editor = new SyntaxEditor(syntaxRoot, solution.Workspace); var generator = editor.Generator; foreach (var methodDeclaration in documentLookup) { var methodNode = syntaxRoot.FindNode(methodDeclaration.Locations[0].SourceSpan); var existingParameters = generator.GetParameters(methodNode); var insertionIndex = newParameterIndex ?? existingParameters.Count; // if the preceding parameter is optional, the new parameter must also be optional // see also BC30202 and CS1737 var parameterMustBeOptional = insertionIndex > 0 && syntaxFacts.GetDefaultOfParameter(existingParameters[insertionIndex - 1]) != null; var parameterSymbol = CreateParameterSymbol( methodDeclaration, newParamaterType, refKind, parameterMustBeOptional, parameterName); var argumentInitializer = parameterMustBeOptional ? generator.DefaultExpression(newParamaterType) : null; var parameterDeclaration = generator.ParameterDeclaration(parameterSymbol, argumentInitializer) .WithAdditionalAnnotations(Formatter.Annotation); if (anySymbolReferencesNotInSource && methodDeclaration == method) { parameterDeclaration = parameterDeclaration.WithAdditionalAnnotations( ConflictAnnotation.Create(FeaturesResources.Related_method_signatures_found_in_metadata_will_not_be_updated)); } if (method.MethodKind == MethodKind.ReducedExtension) { insertionIndex++; } AddParameter(syntaxFacts, editor, methodNode, insertionIndex, parameterDeclaration, cancellationToken); } var newRoot = editor.GetChangedRoot(); solution = solution.WithDocumentSyntaxRoot(document.Id, newRoot); } return(solution); }
internal static RefKind GetRefKindForHashCode(RefKind refKind) => refKind == RefKind.None ? RefKind.None : RefKind.Ref;
internal static bool RefKindEquals(TypeCompareKind compareKind, RefKind refKind1, RefKind refKind2) => (compareKind & TypeCompareKind.FunctionPointerRefMatchesOutInRefReadonly) != 0 ? (refKind1 == RefKind.None) == (refKind2 == RefKind.None) : refKind1 == refKind2;
private PEParameterSymbol( PEModuleSymbol moduleSymbol, Symbol containingSymbol, int ordinal, bool isByRef, TypeSymbolWithAnnotations type, ImmutableArray <byte> extraAnnotations, ParameterHandle handle, int countOfCustomModifiers, out bool isBad) { Debug.Assert((object)moduleSymbol != null); Debug.Assert((object)containingSymbol != null); Debug.Assert(ordinal >= 0); Debug.Assert(!type.IsNull); isBad = false; _moduleSymbol = moduleSymbol; _containingSymbol = containingSymbol; _ordinal = (ushort)ordinal; _handle = handle; RefKind refKind = RefKind.None; if (handle.IsNil) { refKind = isByRef ? RefKind.Ref : RefKind.None; type = TupleTypeSymbol.TryTransformToTuple(type.TypeSymbol, out TupleTypeSymbol tuple) ? TypeSymbolWithAnnotations.Create(tuple) : type; if (!extraAnnotations.IsDefault) { type = NullableTypeDecoder.TransformType(type, defaultTransformFlag: 0, extraAnnotations); } _lazyCustomAttributes = ImmutableArray <CSharpAttributeData> .Empty; _lazyHiddenAttributes = ImmutableArray <CSharpAttributeData> .Empty; _lazyDefaultValue = ConstantValue.NotAvailable; _lazyIsParams = ThreeState.False; } else { try { moduleSymbol.Module.GetParamPropsOrThrow(handle, out _name, out _flags); } catch (BadImageFormatException) { isBad = true; } if (isByRef) { ParameterAttributes inOutFlags = _flags & (ParameterAttributes.Out | ParameterAttributes.In); if (inOutFlags == ParameterAttributes.Out) { refKind = RefKind.Out; } else if (moduleSymbol.Module.HasIsReadOnlyAttribute(handle)) { refKind = RefKind.In; } else { refKind = RefKind.Ref; } } // CONSIDER: Can we make parameter type computation lazy? var typeSymbol = DynamicTypeDecoder.TransformType(type.TypeSymbol, countOfCustomModifiers, handle, moduleSymbol, refKind); type = type.WithTypeAndModifiers(typeSymbol, type.CustomModifiers); // Decode nullable before tuple types to avoid converting between // NamedTypeSymbol and TupleTypeSymbol unnecessarily. type = NullableTypeDecoder.TransformType(type, handle, moduleSymbol, extraAnnotations); type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, handle, moduleSymbol); } _type = type; bool hasNameInMetadata = !string.IsNullOrEmpty(_name); if (!hasNameInMetadata) { // As was done historically, if the parameter doesn't have a name, we give it the name "value". _name = "value"; } _packedFlags = new PackedFlags(refKind, attributesAreComplete: handle.IsNil, hasNameInMetadata: hasNameInMetadata); Debug.Assert(refKind == this.RefKind); Debug.Assert(hasNameInMetadata == this.HasNameInMetadata); }
public static ImmutableArray <TypeSymbol> GetReturnTypes(BoundBlock block, out RefKind refKind, out int numberOfDistinctReturns) { var inferrer = new BlockReturns(); inferrer.Visit(block); refKind = inferrer.refKind; var result = inferrer._types.ToImmutableAndFree(); numberOfDistinctReturns = result.Length; if (inferrer._hasReturnWithoutArgument) { numberOfDistinctReturns += 1; } return(result); }
public FunctionPointerParameterSymbol(TypeWithAnnotations typeWithAnnotations, RefKind refKind, int ordinal, FunctionPointerMethodSymbol containingSymbol, ImmutableArray <CustomModifier> refCustomModifiers) { TypeWithAnnotations = typeWithAnnotations; RefKind = refKind; Ordinal = ordinal; _containingSymbol = containingSymbol; RefCustomModifiers = refCustomModifiers; }