Example #1
0
        /// <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;
        }
Example #2
0
        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();
        }
Example #3
0
        /// <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
 }
Example #5
0
        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;
            }
Example #10
0
 protected override void WriteArgument(BoundExpression arg, RefKind refKind, MethodSymbol method)
 {
     // ref parameter does not "always" assign.
     if (refKind == RefKind.Out)
     {
         Assign(arg, value: null);
     }
 }
Example #11
0
            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;
 }
Example #17
0
 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;
 }
Example #18
0
 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;
 }
Example #19
0
        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);
        }
Example #20
0
 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);
 }
Example #21
0
 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);
 }
Example #22
0
        /// <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;
        }
Example #23
0
 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);
        }
Example #27
0
        /// <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;
        }
Example #31
0
 protected override TypeSymbol GetCurrentReturnType(out RefKind refKind)
 {
     refKind = lambdaSymbol.RefKind;
     return(lambdaSymbol.ReturnType.TypeSymbol);
 }
Example #32
0
        public static bool IsManagedReference(this RefKind refKind)
        {
            Debug.Assert(refKind <= RefKind.RefReadOnly);

            return(refKind != RefKind.None);
        }
Example #33
0
            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);
            }
Example #34
0
 private TypeSymbol GetDynamicType(TypeSymbol type, RefKind refKind, ImmutableArray <bool> dynamicFlags)
 {
     return(DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(type, _sourceAssembly, refKind, dynamicFlags, checkLength: false));
 }
Example #35
0
        /// <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);
        }
Example #36
0
        /// <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));
            }
        }
Example #37
0
        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("&");
            }
        }
Example #39
0
 // 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());
 }
Example #40
0
        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;
            }
        }
Example #41
0
            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));
Example #46
0
        /// <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));
        }
Example #47
0
            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
     });
 }
Example #51
0
        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)));
 }
Example #53
0
 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);
        }
Example #55
0
        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);
        }
Example #56
0
 internal static RefKind GetRefKindForHashCode(RefKind refKind)
 => refKind == RefKind.None ? RefKind.None : RefKind.Ref;
Example #57
0
 internal static bool RefKindEquals(TypeCompareKind compareKind, RefKind refKind1, RefKind refKind2)
 => (compareKind & TypeCompareKind.FunctionPointerRefMatchesOutInRefReadonly) != 0
        ? (refKind1 == RefKind.None) == (refKind2 == RefKind.None)
        : refKind1 == refKind2;
Example #58
0
        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);
        }
Example #59
0
            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;
 }