public TypeSymbol InferredReturnType(ref HashSet<DiagnosticInfo> useSiteDiagnostics)
        {
            if (inferredReturnType == null)
            {
                HashSet<DiagnosticInfo> inferenceUseSiteDiagnostics = null;
                bool inferredFromSingleType;
                var inferredType = InferReturnType(ref inferenceUseSiteDiagnostics, out inferredFromSingleType);

                Debug.Assert(this.inferredFromSingleType == ThreeState.Unknown || this.inferredFromSingleType == inferredFromSingleType.ToThreeState(), "inferredFromSingleType cannot change");
                this.inferredFromSingleType = inferredFromSingleType.ToThreeState();

                Debug.Assert(inferredFromSingleType == false || inferenceUseSiteDiagnostics == null);

                // inferredReturnTypeUseSiteDiagnostics does not need to be unique, so we can just assign it.
                this.inferredReturnTypeUseSiteDiagnostics = inferenceUseSiteDiagnostics;

                // inferredReturnType must be observably unique, only one assignment must succeed
                Interlocked.CompareExchange(ref this.inferredReturnType, inferredType, null);
            }

            if (!this.inferredReturnTypeUseSiteDiagnostics.IsNullOrEmpty())
            {
                if (useSiteDiagnostics == null)
                {
                    useSiteDiagnostics = new HashSet<DiagnosticInfo>();
                }

                foreach (var info in this.inferredReturnTypeUseSiteDiagnostics)
                {
                    useSiteDiagnostics.Add(info);
                }
            }

            return this.inferredReturnType;
        }
Ejemplo n.º 2
0
        protected bool IsEqual(ThreeState x, ThreeState y)
        {
            if (x == ThreeState.Unknown || y == ThreeState.Unknown)
                return false;

            //quick check
            return (x == y);
        }
Ejemplo n.º 3
0
 public void Clear()
 {
     this.Arguments.Clear();
     this.Names.Clear();
     this.RefKinds.Clear();
     this.IsExtensionMethodInvocation = false;
     this.lazyHasDynamicArgument = ThreeState.Unknown;
 }
Ejemplo n.º 4
0
 protected string ThreeStateToString(ThreeState ts, string value)
 {
     switch (ts)
     {
         case ThreeState.False:
             return "false";
         case ThreeState.True:
             return "true";
     }
     return value;
 }
Ejemplo n.º 5
0
        internal SourceNamedTypeSymbol(NamespaceOrTypeSymbol containingSymbol, MergedTypeDeclaration declaration, DiagnosticBag diagnostics)
            : base(containingSymbol, declaration, diagnostics)
        {
            Debug.Assert(declaration.Kind == DeclarationKind.Struct ||
                         declaration.Kind == DeclarationKind.Interface ||
                         declaration.Kind == DeclarationKind.Enum ||
                         declaration.Kind == DeclarationKind.Delegate ||
                         declaration.Kind == DeclarationKind.Class);

            if (containingSymbol.Kind == SymbolKind.NamedType)
            {
                // Nested types are never unified.
                _lazyIsExplicitDefinitionOfNoPiaLocalType = ThreeState.False;
            }
        }
        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;
        }
Ejemplo n.º 7
0
        private void EnsureClassAndConstructorSymbolsAreLoaded()
        {
#pragma warning disable 0252
            if ((object)_lazyAttributeClass == ErrorTypeSymbol.UnknownResultType)
            {
                TypeSymbol attributeClass;
                MethodSymbol attributeConstructor;

                if (!_decoder.GetCustomAttribute(_handle, out attributeClass, out attributeConstructor))
                {
                    // TODO: should we create CSErrorTypeSymbol for attribute class??
                    _lazyHasErrors = ThreeState.True;
                }
                else if ((object)attributeClass == null || attributeClass.IsErrorType() || (object)attributeConstructor == null)
                {
                    _lazyHasErrors = ThreeState.True;
                }

                Interlocked.CompareExchange(ref _lazyAttributeConstructor, attributeConstructor, null);
                Interlocked.CompareExchange(ref _lazyAttributeClass, (NamedTypeSymbol)attributeClass, ErrorTypeSymbol.UnknownResultType); // Serves as a flag, so do it last.
            }
#pragma warning restore 0252
        }
Ejemplo n.º 8
0
 private void InsertMissingOptionalArguments(SyntaxNode syntax,
     ImmutableArray<ParameterSymbol> parameters,
     BoundExpression[] arguments,
     ThreeState enableCallerInfo = ThreeState.Unknown)
 {
     for (int p = 0; p < arguments.Length; ++p)
     {
         if (arguments[p] == null)
         {
             ParameterSymbol parameter = parameters[p];
             Debug.Assert(parameter.IsOptional);
             arguments[p] = GetDefaultParameterValue(syntax, parameter, enableCallerInfo);
             Debug.Assert(arguments[p].Type == parameter.Type);
         }
     }
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Rewrites arguments of an invocation according to the receiving method or indexer.
        /// It is assumed that each argument has already been lowered, but we may need
        /// additional rewriting for the arguments, such as generating a params array, re-ordering
        /// arguments based on <paramref name="argsToParamsOpt"/> map, inserting arguments for optional parameters, etc.
        /// <paramref name="optionalParametersMethod"/> is the method used for values of any optional parameters.
        /// For indexers, this method must be an accessor, and for methods it must be the method
        /// itself. <paramref name="optionalParametersMethod"/> is needed for indexers since getter and setter
        /// may have distinct optional parameter values.
        /// </summary>
        private ImmutableArray<BoundExpression> MakeArguments(
            SyntaxNode syntax,
            ImmutableArray<BoundExpression> rewrittenArguments,
            Symbol methodOrIndexer,
            MethodSymbol optionalParametersMethod,
            bool expanded,
            ImmutableArray<int> argsToParamsOpt,
            ref ImmutableArray<RefKind> argumentRefKindsOpt,
            out ImmutableArray<LocalSymbol> temps,
            bool invokedAsExtensionMethod = false,
            ThreeState enableCallerInfo = ThreeState.Unknown)
        {
            // Either the methodOrIndexer is a property, in which case the method used
            // for optional parameters is an accessor of that property (or an overridden
            // property), or the methodOrIndexer is used for optional parameters directly.
            Debug.Assert(((methodOrIndexer.Kind == SymbolKind.Property) && optionalParametersMethod.IsAccessor()) ||
                ReferenceEquals(methodOrIndexer, optionalParametersMethod));

            // We need to do a fancy rewrite under the following circumstances:
            // (1) a params array is being used; we need to generate the array.
            // (2) there were named arguments that reordered the arguments; we might
            //     have to generate temporaries to ensure that the arguments are 
            //     evaluated in source code order, not the actual call order.
            // (3) there were optional parameters that had no corresponding arguments.
            //
            // If none of those are the case then we can just take an early out.

            // An applicable "vararg" method could not possibly be applicable in its expanded
            // form, and cannot possibly have named arguments or used optional parameters, 
            // because the __arglist() argument has to be positional and in the last position. 


            if (methodOrIndexer.GetIsVararg())
            {
                Debug.Assert(rewrittenArguments.Length == methodOrIndexer.GetParameterCount() + 1);
                Debug.Assert(argsToParamsOpt.IsDefault);
                Debug.Assert(!expanded);
                temps = default(ImmutableArray<LocalSymbol>);
                return rewrittenArguments;
            }

            var receiverNamedType = invokedAsExtensionMethod ?
                                    ((MethodSymbol)methodOrIndexer).Parameters[0].Type as NamedTypeSymbol :
                                    methodOrIndexer.ContainingType;

            bool isComReceiver = (object)receiverNamedType != null && receiverNamedType.IsComImport;

            if (rewrittenArguments.Length == methodOrIndexer.GetParameterCount() &&
                argsToParamsOpt.IsDefault &&
                !expanded &&
                !isComReceiver)
            {
                temps = default(ImmutableArray<LocalSymbol>);
                return rewrittenArguments;
            }


            // We have:
            // * a list of arguments, already converted to their proper types, 
            //   in source code order. Some optional arguments might be missing.
            // * a map showing which parameter each argument corresponds to. If
            //   this is null, then the argument to parameter mapping is one-to-one.
            // * the ref kind of each argument, in source code order. That is, whether
            //   the argument was marked as ref, out, or value (neither).
            // * a method symbol.
            // * whether the call is expanded or normal form.

            // We rewrite the call so that:
            // * if in its expanded form, we create the params array.
            // * if the call requires reordering of arguments because of named arguments, temporaries are generated as needed

            // Doing this transformation can move around refness in interesting ways. For example, consider
            //
            // A().M(y : ref B()[C()], x : out D());
            //
            // This will be created as a call with receiver A(), symbol M, argument list ( B()[C()], D() ),
            // name list ( y, x ) and ref list ( ref, out ).  We can rewrite this into temporaries:
            //
            // A().M( 
            //    seq ( ref int temp_y = ref B()[C()], out D() ),
            //    temp_y );
            // 
            // Now we have a call with receiver A(), symbol M, argument list as shown, no name list,
            // and ref list ( out, value ). We do not want to pass a *ref* to temp_y; the temporary
            // storage is not the thing being ref'd! We want to pass the *value* of temp_y, which
            // *contains* a reference.

            // We attempt to minimize the number of temporaries required. Arguments which neither
            // produce nor observe a side effect can be placed into their proper position without
            // recourse to a temporary. For example:
            //
            // Where(predicate: x=>x.Length!=0, sequence: S())
            //
            // can be rewritten without any temporaries because the conversion from lambda to
            // delegate does not produce any side effect that could be observed by S().
            //
            // By contrast:
            //
            // Foo(z: this.p, y: this.Q(), x: (object)10)
            //
            // The boxing of 10 can be reordered, but the fetch of this.p has to happen before the
            // call to this.Q() because the call could change the value of this.p. 
            //
            // We start by binding everything that is not obviously reorderable as a temporary, and
            // then run an optimizer to remove unnecessary temporaries.

            ImmutableArray<ParameterSymbol> parameters = methodOrIndexer.GetParameters();
            BoundExpression[] actualArguments = new BoundExpression[parameters.Length]; // The actual arguments that will be passed; one actual argument per formal parameter.
            ArrayBuilder<BoundAssignmentOperator> storesToTemps = ArrayBuilder<BoundAssignmentOperator>.GetInstance(rewrittenArguments.Length);
            ArrayBuilder<RefKind> refKinds = ArrayBuilder<RefKind>.GetInstance(parameters.Length, RefKind.None);

            // Step one: Store everything that is non-trivial into a temporary; record the
            // stores in storesToTemps and make the actual argument a reference to the temp.
            // Do not yet attempt to deal with params arrays or optional arguments.
            BuildStoresToTemps(expanded, argsToParamsOpt, argumentRefKindsOpt, rewrittenArguments, actualArguments, refKinds, storesToTemps);


            // all the formal arguments, except missing optionals, are now in place. 
            // Optimize away unnecessary temporaries.
            // Necessary temporaries have their store instructions merged into the appropriate 
            // argument expression.
            ArrayBuilder<LocalSymbol> temporariesBuilder = ArrayBuilder<LocalSymbol>.GetInstance();
            OptimizeTemporaries(actualArguments, refKinds, storesToTemps, temporariesBuilder);

            // Step two: If we have a params array, build the array and fill in the argument.
            if (expanded)
            {
                actualArguments[actualArguments.Length - 1] = BuildParamsArray(syntax, methodOrIndexer, argsToParamsOpt, rewrittenArguments, parameters, actualArguments[actualArguments.Length - 1]);
            }

            // Step three: Now fill in the optional arguments.
            InsertMissingOptionalArguments(syntax, optionalParametersMethod.Parameters, actualArguments, enableCallerInfo);

            if (isComReceiver)
            {
                RewriteArgumentsForComCall(parameters, actualArguments, refKinds, temporariesBuilder);
            }

            temps = temporariesBuilder.ToImmutableAndFree();
            storesToTemps.Free();

            // * The refkind map is now filled out to match the arguments.
            // * The list of parameter names is now null because the arguments have been reordered.
            // * The args-to-params map is now null because every argument exactly matches its parameter.
            // * The call is no longer in its expanded form.

            argumentRefKindsOpt = GetRefKindsOrNull(refKinds);
            refKinds.Free();

            return actualArguments.AsImmutableOrNull();
        }
Ejemplo n.º 10
0
        private void EnsureAttributeArgumentsAreLoaded()
        {
            if (_lazyConstructorArguments.IsDefault || _lazyNamedArguments.IsDefault)
            {
                TypedConstant[] lazyConstructorArguments = null;
                KeyValuePair<string, TypedConstant>[] lazyNamedArguments = null;

                if (!_decoder.GetCustomAttribute(_handle, out lazyConstructorArguments, out lazyNamedArguments))
                {
                    _lazyHasErrors = ThreeState.True;
                }

                Debug.Assert(lazyConstructorArguments != null && lazyNamedArguments != null);

                ImmutableInterlocked.InterlockedInitialize(ref _lazyConstructorArguments,
                    ImmutableArray.Create<TypedConstant>(lazyConstructorArguments));

                ImmutableInterlocked.InterlockedInitialize(ref _lazyNamedArguments,
                    ImmutableArray.Create<KeyValuePair<string, TypedConstant>>(lazyNamedArguments));
            }
        }
Ejemplo n.º 11
0
 public static bool Value(this ThreeState value)
 {
     Debug.Assert(value != ThreeState.Unknown);
     return(value == ThreeState.True);
 }
Ejemplo n.º 12
0
        internal sealed override void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArguments<AttributeSyntax, CSharpAttributeData, AttributeLocation> arguments)
        {
            Debug.Assert((object)arguments.AttributeSyntaxOpt != null);

            var attribute = arguments.Attribute;
            Debug.Assert(!attribute.HasErrors);
            Debug.Assert(arguments.SymbolPart == AttributeLocation.None);

            if (attribute.IsTargetAttribute(this, AttributeDescription.AttributeUsageAttribute))
            {
                DecodeAttributeUsageAttribute(attribute, arguments.AttributeSyntaxOpt, diagnose: true, diagnosticsOpt: arguments.Diagnostics);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.DefaultMemberAttribute))
            {
                arguments.GetOrCreateData<TypeWellKnownAttributeData>().HasDefaultMemberAttribute = true;
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.CoClassAttribute))
            {
                DecodeCoClassAttribute(ref arguments);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.ConditionalAttribute))
            {
                ValidateConditionalAttribute(attribute, arguments.AttributeSyntaxOpt, arguments.Diagnostics);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.GuidAttribute))
            {
                arguments.GetOrCreateData<TypeWellKnownAttributeData>().GuidString = attribute.DecodeGuidAttribute(arguments.AttributeSyntaxOpt, arguments.Diagnostics);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.SpecialNameAttribute))
            {
                arguments.GetOrCreateData<TypeWellKnownAttributeData>().HasSpecialNameAttribute = true;
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.SerializableAttribute))
            {
                arguments.GetOrCreateData<TypeWellKnownAttributeData>().HasSerializableAttribute = true;
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.StructLayoutAttribute))
            {
                AttributeData.DecodeStructLayoutAttribute<TypeWellKnownAttributeData, AttributeSyntax, CSharpAttributeData, AttributeLocation>(
                    ref arguments, this.DefaultMarshallingCharSet, defaultAutoLayoutSize: 0, messageProvider: MessageProvider.Instance);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.SuppressUnmanagedCodeSecurityAttribute))
            {
                arguments.GetOrCreateData<TypeWellKnownAttributeData>().HasSuppressUnmanagedCodeSecurityAttribute = true;
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.ClassInterfaceAttribute))
            {
                attribute.DecodeClassInterfaceAttribute(arguments.AttributeSyntaxOpt, arguments.Diagnostics);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.InterfaceTypeAttribute))
            {
                attribute.DecodeInterfaceTypeAttribute(arguments.AttributeSyntaxOpt, arguments.Diagnostics);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.WindowsRuntimeImportAttribute))
            {
                arguments.GetOrCreateData<TypeWellKnownAttributeData>().HasWindowsRuntimeImportAttribute = true;
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.RequiredAttributeAttribute))
            {
                // CS1608: The Required attribute is not permitted on C# types
                arguments.Diagnostics.Add(ErrorCode.ERR_CantUseRequiredAttribute, arguments.AttributeSyntaxOpt.Name.Location);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.CaseSensitiveExtensionAttribute))
            {
                // ExtensionAttribute should not be set explicitly.
                arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitExtension, arguments.AttributeSyntaxOpt.Location);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.DynamicAttribute))
            {
                // DynamicAttribute should not be set explicitly.
                arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitDynamicAttr, arguments.AttributeSyntaxOpt.Location);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.SecurityCriticalAttribute)
                || attribute.IsTargetAttribute(this, AttributeDescription.SecuritySafeCriticalAttribute))
            {
                arguments.GetOrCreateData<TypeWellKnownAttributeData>().HasSecurityCriticalAttributes = true;
            }
            else if (_lazyIsExplicitDefinitionOfNoPiaLocalType == ThreeState.Unknown && attribute.IsTargetAttribute(this, AttributeDescription.TypeIdentifierAttribute))
            {
                _lazyIsExplicitDefinitionOfNoPiaLocalType = ThreeState.True;
            }
            else
            {
                var compilation = this.DeclaringCompilation;
                if (attribute.IsSecurityAttribute(compilation))
                {
                    attribute.DecodeSecurityAttribute<TypeWellKnownAttributeData>(this, compilation, ref arguments);
                }
            }
        }
Ejemplo n.º 13
0
        private PEParameterSymbol(
            PEModuleSymbol moduleSymbol,
            Symbol containingSymbol,
            int ordinal,
            bool isByRef,
            bool hasByRefBeforeCustomModifiers,
            TypeSymbol type,
            ParameterHandle handle,
            ImmutableArray<MetadataDecoder.ModifierInfo> customModifiers,
            out bool isBad)
        {
            Debug.Assert((object)moduleSymbol != null);
            Debug.Assert((object)containingSymbol != null);
            Debug.Assert(ordinal >= 0);
            Debug.Assert((object)type != null);

            isBad = false;
            this.moduleSymbol = moduleSymbol;
            this.containingSymbol = containingSymbol;
            this.customModifiers = CSharpCustomModifier.Convert(customModifiers);
            this.ordinal = (ushort)ordinal;

            this.handle = handle;

            RefKind refKind = RefKind.None;

            if (handle.IsNil)
            {
                refKind = isByRef ? RefKind.Ref : RefKind.None;

                this.type = type;
                this.lazyCustomAttributes = ImmutableArray<CSharpAttributeData>.Empty;
                this.lazyHiddenAttributes = ImmutableArray<CSharpAttributeData>.Empty;
                this.lazyWellKnownAttributeData = (int)WellKnownAttributeFlags.AllCompletedNoAttributes;
                this.lazyDefaultValue = ConstantValue.NotAvailable;
                this.lazyIsParams = ThreeState.False;
            }
            else
            {
                try
                {
                    moduleSymbol.Module.GetParamPropsOrThrow(handle, out this.name, out this.flags);
                }
                catch (BadImageFormatException)
                {
                    isBad = true;
                }

                if (isByRef)
                {
                    ParameterAttributes inOutFlags = this.flags & (ParameterAttributes.Out | ParameterAttributes.In);
                    refKind = (inOutFlags == ParameterAttributes.Out) ? RefKind.Out : RefKind.Ref;
                }

                // CONSIDER: Can we make parameter type computation lazy?
                this.type = DynamicTypeDecoder.TransformType(type, this.customModifiers.Length, handle, moduleSymbol, refKind);
            }

            if (string.IsNullOrEmpty(this.name))
            {
                // As was done historically, if the parameter doesn't have a name, we give it the name "value".
                this.name = "value";
            }

            this.packed = Pack(refKind, hasByRefBeforeCustomModifiers);

            Debug.Assert(refKind == this.RefKind);
            Debug.Assert(hasByRefBeforeCustomModifiers == this.HasByRefBeforeCustomModifiers);
        }
Ejemplo n.º 14
0
        public override ImmutableArray <CSharpAttributeData> GetAttributes()
        {
            if (_lazyCustomAttributes.IsDefault)
            {
                Debug.Assert(!_handle.IsNil);
                var containingPEModuleSymbol = (PEModuleSymbol)this.ContainingModule;

                // Filter out ParamArrayAttributes if necessary and cache
                // the attribute handle for GetCustomAttributesToEmit
                bool filterOutParamArrayAttribute = (!_lazyIsParams.HasValue() || _lazyIsParams.Value());

                ConstantValue        defaultValue = this.ExplicitDefaultConstantValue;
                AttributeDescription filterOutConstantAttributeDescription = default(AttributeDescription);

                if ((object)defaultValue != null)
                {
                    if (defaultValue.Discriminator == ConstantValueTypeDiscriminator.DateTime)
                    {
                        filterOutConstantAttributeDescription = AttributeDescription.DateTimeConstantAttribute;
                    }
                    else if (defaultValue.Discriminator == ConstantValueTypeDiscriminator.Decimal)
                    {
                        filterOutConstantAttributeDescription = AttributeDescription.DecimalConstantAttribute;
                    }
                }

                if (filterOutParamArrayAttribute || filterOutConstantAttributeDescription.Signatures != null)
                {
                    CustomAttributeHandle paramArrayAttribute;
                    CustomAttributeHandle constantAttribute;

                    ImmutableArray <CSharpAttributeData> attributes =
                        containingPEModuleSymbol.GetCustomAttributesForToken(
                            _handle,
                            out paramArrayAttribute,
                            filterOutParamArrayAttribute ? AttributeDescription.ParamArrayAttribute : default(AttributeDescription),
                            out constantAttribute,
                            filterOutConstantAttributeDescription);

                    if (!paramArrayAttribute.IsNil || !constantAttribute.IsNil)
                    {
                        var builder = ArrayBuilder <CSharpAttributeData> .GetInstance();

                        if (!paramArrayAttribute.IsNil)
                        {
                            builder.Add(new PEAttributeData(containingPEModuleSymbol, paramArrayAttribute));
                        }

                        if (!constantAttribute.IsNil)
                        {
                            builder.Add(new PEAttributeData(containingPEModuleSymbol, constantAttribute));
                        }

                        ImmutableInterlocked.InterlockedInitialize(ref _lazyHiddenAttributes, builder.ToImmutableAndFree());
                    }
                    else
                    {
                        ImmutableInterlocked.InterlockedInitialize(ref _lazyHiddenAttributes, ImmutableArray <CSharpAttributeData> .Empty);
                    }

                    if (!_lazyIsParams.HasValue())
                    {
                        Debug.Assert(filterOutParamArrayAttribute);
                        _lazyIsParams = (!paramArrayAttribute.IsNil).ToThreeState();
                    }

                    ImmutableInterlocked.InterlockedInitialize(
                        ref _lazyCustomAttributes,
                        attributes);
                }
                else
                {
                    ImmutableInterlocked.InterlockedInitialize(ref _lazyHiddenAttributes, ImmutableArray <CSharpAttributeData> .Empty);
                    containingPEModuleSymbol.LoadCustomAttributes(_handle, ref _lazyCustomAttributes);
                }
            }

            Debug.Assert(!_lazyHiddenAttributes.IsDefault);
            return(_lazyCustomAttributes);
        }
Ejemplo n.º 15
0
        private PEParameterSymbol(
            PEModuleSymbol moduleSymbol,
            Symbol containingSymbol,
            int ordinal,
            bool isByRef,
            TypeSymbol type,
            ParameterHandle handle,
            int countOfCustomModifiers,
            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 = TupleTypeSymbol.TransformToTupleIfCompatible(type); // temporary shallow unification
                _type = type;

                _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);
                    refKind = (inOutFlags == ParameterAttributes.Out) ? RefKind.Out : RefKind.Ref;
                }

                // CONSIDER: Can we make parameter type computation lazy?
                type = DynamicTypeDecoder.TransformType(type, countOfCustomModifiers, handle, moduleSymbol, refKind);

                _type = TupleTypeSymbol.TransformToTupleIfCompatible(type); // temporary shallow unification
            }

            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);
        }
Ejemplo n.º 16
0
 private static bool IsViableSourceMethod(MethodSymbol candidateMethod, string desiredMethodName, ImmutableArray<TypeParameterSymbol> desiredTypeParameters, ThreeState isDesiredMethodStatic)
 {
     return
         !candidateMethod.IsAbstract &&
         (isDesiredMethodStatic == ThreeState.Unknown || isDesiredMethodStatic.Value() == candidateMethod.IsStatic) &&
         candidateMethod.Name == desiredMethodName &&
         HaveSameConstraints(candidateMethod.TypeParameters, desiredTypeParameters);
 }
Ejemplo n.º 17
0
        internal static void ReportDiagnosticsIfObsolete(
            DiagnosticBag diagnostics,
            Symbol symbol,
            SyntaxNodeOrToken node,
            bool hasBaseReceiver,
            Symbol containingMember,
            NamedTypeSymbol containingType,
            BinderFlags location)
        {
            Debug.Assert((object)symbol != null);

            Debug.Assert(symbol.Kind == SymbolKind.NamedType ||
                         symbol.Kind == SymbolKind.Field ||
                         symbol.Kind == SymbolKind.Method ||
                         symbol.Kind == SymbolKind.Event ||
                         symbol.Kind == SymbolKind.Property);

            // Dev11 also reports on the unconstructed method.  It would be nice to report on
            // the constructed method, but then we wouldn't be able to walk the override chain.
            if (symbol.Kind == SymbolKind.Method)
            {
                symbol = ((MethodSymbol)symbol).ConstructedFrom;
            }

            // There are two reasons to walk up to the least-overridden member:
            //   1) That's the method to which we will actually emit a call.
            //   2) We don't know what virtual dispatch will do at runtime so an
            //      overriding member is basically a shot in the dark.  Better to
            //      just be consistent and always use the least-overridden member.
            Symbol leastOverriddenSymbol = symbol.GetLeastOverriddenMember(containingType);

            bool checkOverridingSymbol = hasBaseReceiver && !ReferenceEquals(symbol, leastOverriddenSymbol);

            if (checkOverridingSymbol)
            {
                // If we have a base receiver, we must be done with declaration binding, so it should
                // be safe to decode diagnostics.  We want to do this since reporting for the overriding
                // member is conditional on reporting for the overridden member (i.e. we need a definite
                // answer so we don't double-report).  You might think that double reporting just results
                // in cascading diagnostics, but it's possible that the second diagnostic is an error
                // while the first is merely a warning.
                leastOverriddenSymbol.GetAttributes();
            }

            ThreeState reportedOnOverridden = ReportDiagnosticsIfObsoleteInternal(diagnostics, leastOverriddenSymbol, node, containingMember, location);

            // CONSIDER: In place of hasBaseReceiver, dev11 also accepts cases where symbol.ContainingType is a "simple type" (e.g. int)
            // or a special by-ref type (e.g. ArgumentHandle).  These cases are probably more important for other checks performed by
            // ExpressionBinder::PostBindMethod, but they do appear to ObsoleteAttribute as well.  We're skipping them because they
            // don't make much sense for ObsoleteAttribute (e.g. this would seem to address the case where int.ToString has been made
            // obsolete but object.ToString has not).

            // If the overridden member was not definitely obsolete and this is a (non-virtual) base member
            // access, then check the overriding symbol as well.
            if (reportedOnOverridden != ThreeState.True && checkOverridingSymbol)
            {
                Debug.Assert(reportedOnOverridden != ThreeState.Unknown, "We forced attribute binding above.");

                ReportDiagnosticsIfObsoleteInternal(diagnostics, symbol, node, containingMember, location);
            }
        }
Ejemplo n.º 18
0
        private ImmutableArray <TypeWithAnnotations> GetDeclaredConstraintTypes()
        {
            if (_lazyDeclaredConstraintTypes.IsDefault)
            {
                ImmutableArray <TypeWithAnnotations> declaredConstraintTypes;

                PEMethodSymbol    containingMethod = null;
                PENamedTypeSymbol containingType;

                if (_containingSymbol.Kind == SymbolKind.Method)
                {
                    containingMethod = (PEMethodSymbol)_containingSymbol;
                    containingType   = (PENamedTypeSymbol)containingMethod.ContainingSymbol;
                }
                else
                {
                    containingType = (PENamedTypeSymbol)_containingSymbol;
                }

                var      moduleSymbol = containingType.ContainingPEModule;
                PEModule peModule     = moduleSymbol.Module;
                GenericParameterConstraintHandleCollection constraints = GetConstraintHandleCollection(peModule);

                bool hasUnmanagedModreqPattern = false;

                if (constraints.Count > 0)
                {
                    var symbolsBuilder = ArrayBuilder <TypeWithAnnotations> .GetInstance();

                    MetadataDecoder tokenDecoder;

                    if ((object)containingMethod != null)
                    {
                        tokenDecoder = new MetadataDecoder(moduleSymbol, containingMethod);
                    }
                    else
                    {
                        tokenDecoder = new MetadataDecoder(moduleSymbol, containingType);
                    }

                    var metadataReader = peModule.MetadataReader;
                    foreach (var constraintHandle in constraints)
                    {
                        var constraint = metadataReader.GetGenericParameterConstraint(constraintHandle);
                        var typeSymbol = tokenDecoder.DecodeGenericParameterConstraint(constraint.Type, out bool hasUnmanagedModreq);

                        if (typeSymbol.SpecialType == SpecialType.System_ValueType)
                        {
                            // recognize "(class [mscorlib]System.ValueType modreq([mscorlib]System.Runtime.InteropServices.UnmanagedType" pattern as "unmanaged"
                            if (hasUnmanagedModreq)
                            {
                                hasUnmanagedModreqPattern = true;
                            }

                            // Drop 'System.ValueType' constraint type if the 'valuetype' constraint was also specified.
                            if (((_flags & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0))
                            {
                                continue;
                            }
                        }

                        var type = TypeWithAnnotations.Create(typeSymbol);
                        type = NullableTypeDecoder.TransformType(type, constraintHandle, moduleSymbol);

                        // Drop 'System.Object?' constraint type.
                        if (type.SpecialType == SpecialType.System_Object && type.NullableAnnotation.IsAnnotated())
                        {
                            continue;
                        }

                        type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, constraintHandle, moduleSymbol);

                        symbolsBuilder.Add(type);
                    }

                    declaredConstraintTypes = symbolsBuilder.ToImmutableAndFree();
                }
                else
                {
                    declaredConstraintTypes = ImmutableArray <TypeWithAnnotations> .Empty;
                }

                // - presence of unmanaged pattern has to be matched with `valuetype`
                // - IsUnmanagedAttribute is allowed iif there is an unmanaged pattern
                if (hasUnmanagedModreqPattern && (_flags & GenericParameterAttributes.NotNullableValueTypeConstraint) == 0 ||
                    hasUnmanagedModreqPattern != peModule.HasIsUnmanagedAttribute(_handle))
                {
                    // we do not recognize these combinations as "unmanaged"
                    hasUnmanagedModreqPattern = false;
                    Interlocked.CompareExchange(ref _lazyConstraintsUseSiteErrorInfo, new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this), CSDiagnosticInfo.EmptyErrorInfo);
                }

                _lazyHasIsUnmanagedConstraint = hasUnmanagedModreqPattern.ToThreeState();
                ImmutableInterlocked.InterlockedInitialize(ref _lazyDeclaredConstraintTypes, declaredConstraintTypes);
            }

            return(_lazyDeclaredConstraintTypes);
        }
 protected void SealTemplates()
 {
     templatesSealed = ThreeState.True;
 }
Ejemplo n.º 20
0
        internal sealed override void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArguments <AttributeSyntax, CSharpAttributeData, AttributeLocation> arguments)
        {
            Debug.Assert((object)arguments.AttributeSyntaxOpt != null);

            var attribute = arguments.Attribute;

            Debug.Assert(!attribute.HasErrors);
            Debug.Assert(arguments.SymbolPart == AttributeLocation.None);

            if (attribute.IsTargetAttribute(this, AttributeDescription.AttributeUsageAttribute))
            {
                DecodeAttributeUsageAttribute(attribute, arguments.AttributeSyntaxOpt, diagnose: true, diagnosticsOpt: arguments.Diagnostics);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.DefaultMemberAttribute))
            {
                arguments.GetOrCreateData <TypeWellKnownAttributeData>().HasDefaultMemberAttribute = true;
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.CoClassAttribute))
            {
                DecodeCoClassAttribute(ref arguments);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.ConditionalAttribute))
            {
                ValidateConditionalAttribute(attribute, arguments.AttributeSyntaxOpt, arguments.Diagnostics);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.GuidAttribute))
            {
                arguments.GetOrCreateData <TypeWellKnownAttributeData>().GuidString = attribute.DecodeGuidAttribute(arguments.AttributeSyntaxOpt, arguments.Diagnostics);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.SpecialNameAttribute))
            {
                arguments.GetOrCreateData <TypeWellKnownAttributeData>().HasSpecialNameAttribute = true;
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.SerializableAttribute))
            {
                arguments.GetOrCreateData <TypeWellKnownAttributeData>().HasSerializableAttribute = true;
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.StructLayoutAttribute))
            {
                AttributeData.DecodeStructLayoutAttribute <TypeWellKnownAttributeData, AttributeSyntax, CSharpAttributeData, AttributeLocation>(
                    ref arguments, this.DefaultMarshallingCharSet, defaultAutoLayoutSize: 0, messageProvider: MessageProvider.Instance);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.SuppressUnmanagedCodeSecurityAttribute))
            {
                arguments.GetOrCreateData <TypeWellKnownAttributeData>().HasSuppressUnmanagedCodeSecurityAttribute = true;
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.ClassInterfaceAttribute))
            {
                attribute.DecodeClassInterfaceAttribute(arguments.AttributeSyntaxOpt, arguments.Diagnostics);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.InterfaceTypeAttribute))
            {
                attribute.DecodeInterfaceTypeAttribute(arguments.AttributeSyntaxOpt, arguments.Diagnostics);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.WindowsRuntimeImportAttribute))
            {
                arguments.GetOrCreateData <TypeWellKnownAttributeData>().HasWindowsRuntimeImportAttribute = true;
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.RequiredAttributeAttribute))
            {
                // CS1608: The Required attribute is not permitted on C# types
                arguments.Diagnostics.Add(ErrorCode.ERR_CantUseRequiredAttribute, arguments.AttributeSyntaxOpt.Name.Location);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.CaseSensitiveExtensionAttribute))
            {
                // ExtensionAttribute should not be set explicitly.
                arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitExtension, arguments.AttributeSyntaxOpt.Location);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.DynamicAttribute))
            {
                // DynamicAttribute should not be set explicitly.
                arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitDynamicAttr, arguments.AttributeSyntaxOpt.Location);
            }
            else if (attribute.IsTargetAttribute(this, AttributeDescription.SecurityCriticalAttribute) ||
                     attribute.IsTargetAttribute(this, AttributeDescription.SecuritySafeCriticalAttribute))
            {
                arguments.GetOrCreateData <TypeWellKnownAttributeData>().HasSecurityCriticalAttributes = true;
            }
            else if (_lazyIsExplicitDefinitionOfNoPiaLocalType == ThreeState.Unknown && attribute.IsTargetAttribute(this, AttributeDescription.TypeIdentifierAttribute))
            {
                _lazyIsExplicitDefinitionOfNoPiaLocalType = ThreeState.True;
            }
            else
            {
                var compilation = this.DeclaringCompilation;
                if (attribute.IsSecurityAttribute(compilation))
                {
                    attribute.DecodeSecurityAttribute <TypeWellKnownAttributeData>(this, compilation, ref arguments);
                }
            }
        }
Ejemplo n.º 21
0
        private static SourceLocation GetCallerLocation(SyntaxNode syntax, ThreeState enableCallerInfo)
        {
            switch (enableCallerInfo)
            {
                case ThreeState.False:
                    return null;
                case ThreeState.True:
                    return new SourceLocation(syntax.GetFirstToken());
            }

            Debug.Assert(enableCallerInfo == ThreeState.Unknown);

            switch (syntax.Kind())
            {
                case SyntaxKind.InvocationExpression:
                    return new SourceLocation(((InvocationExpressionSyntax)syntax).ArgumentList.OpenParenToken);
                case SyntaxKind.ObjectCreationExpression:
                    return new SourceLocation(((ObjectCreationExpressionSyntax)syntax).NewKeyword);
                case SyntaxKind.BaseConstructorInitializer:
                case SyntaxKind.ThisConstructorInitializer:
                    return new SourceLocation(((ConstructorInitializerSyntax)syntax).ArgumentList.OpenParenToken);
                case SyntaxKind.ElementAccessExpression:
                    return new SourceLocation(((ElementAccessExpressionSyntax)syntax).ArgumentList.OpenBracketToken);
                case SyntaxKind.FromClause:
                case SyntaxKind.GroupClause:
                case SyntaxKind.JoinClause:
                case SyntaxKind.JoinIntoClause:
                case SyntaxKind.LetClause:
                case SyntaxKind.OrderByClause:
                case SyntaxKind.SelectClause:
                case SyntaxKind.WhereClause:
                    return new SourceLocation(syntax.GetFirstToken());
                default:
                    return null;
            }
        }
Ejemplo n.º 22
0
        private PEParameterSymbol(
            PEModuleSymbol moduleSymbol,
            Symbol containingSymbol,
            int ordinal,
            bool isByRef,
            TypeWithAnnotations typeWithAnnotations,
            ParameterHandle handle,
            Symbol nullableContext,
            int countOfCustomModifiers,
            out bool isBad)
        {
            Debug.Assert((object)moduleSymbol != null);
            Debug.Assert((object)containingSymbol != null);
            Debug.Assert(ordinal >= 0);
            Debug.Assert(typeWithAnnotations.HasType);

            isBad             = false;
            _moduleSymbol     = moduleSymbol;
            _containingSymbol = containingSymbol;
            _ordinal          = (ushort)ordinal;

            _handle = handle;

            RefKind refKind = RefKind.None;

            if (handle.IsNil)
            {
                refKind = isByRef ? RefKind.Ref : RefKind.None;
                byte?value = nullableContext.GetNullableContextValue();
                if (value.HasValue)
                {
                    typeWithAnnotations = NullableTypeDecoder.TransformType(typeWithAnnotations, value.GetValueOrDefault(), default);
                }
                _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;
                    }
                }

                var typeSymbol = DynamicTypeDecoder.TransformType(typeWithAnnotations.Type, countOfCustomModifiers, handle, moduleSymbol, refKind);
                typeWithAnnotations = typeWithAnnotations.WithTypeAndModifiers(typeSymbol, typeWithAnnotations.CustomModifiers);
                // Decode nullable before tuple types to avoid converting between
                // NamedTypeSymbol and TupleTypeSymbol unnecessarily.

                // The containing type is passed to NullableTypeDecoder.TransformType to determine access
                // for property parameters because the property does not have explicit accessibility in metadata.
                var accessSymbol = containingSymbol.Kind == SymbolKind.Property ? containingSymbol.ContainingSymbol : containingSymbol;
                typeWithAnnotations = NullableTypeDecoder.TransformType(typeWithAnnotations, handle, moduleSymbol, accessSymbol: accessSymbol, nullableContext: nullableContext);
                typeWithAnnotations = TupleTypeDecoder.DecodeTupleTypesIfApplicable(typeWithAnnotations, handle, moduleSymbol);
            }

            _typeWithAnnotations = typeWithAnnotations;

            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);
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Gets the default value for the <paramref name="parameter"/>.
        /// </summary>
        /// <param name="syntax">
        /// A syntax node corresponding to the invocation.
        /// </param>
        /// <param name="parameter">
        /// A parameter to get the default value for.
        /// </param>
        /// <param name="enableCallerInfo">
        /// Indicates if caller info is to be enabled when processing this optional parameter.
        /// The value <see cref="ThreeState.Unknown"/> means the decision is to be made based on the shape of the <paramref name="syntax"/> node.
        /// </param>
        /// <remarks>
        /// DELIBERATE SPEC VIOLATION: When processing an implicit invocation of an <c>Add</c> method generated
        /// for an element-initializer in a collection-initializer, the parameter <paramref name="enableCallerInfo"/> 
        /// is set to <see cref="ThreeState.True"/>. It means that if the optional parameter is annotated with <see cref="CallerLineNumberAttribute"/>,
        /// <see cref="CallerFilePathAttribute"/> or <see cref="CallerMemberNameAttribute"/>, and there is no explicit argument corresponding to it,
        /// we will provide caller information as a value of this parameter.
        /// This is done to match the native compiler behavior and user requests (see http://roslyn.codeplex.com/workitem/171). This behavior
        /// does not match the C# spec that currently requires to provide caller information only in explicit invocations and query expressions.
        /// </remarks>
        private BoundExpression GetDefaultParameterValue(SyntaxNode syntax, ParameterSymbol parameter, ThreeState enableCallerInfo)
        {
            // TODO: Ideally, the enableCallerInfo parameter would be of just bool type with only 'true' and 'false' values, and all callers
            // explicitly provided one of those values, so that we do not rely on shape of syntax nodes in the rewriter. There are not many immediate callers, 
            // but often the immediate caller does not have the required information, so all possible call chains should be analyzed and possibly updated
            // to pass this information, and this might be a big task. We should consider doing this when the time permits.

            TypeSymbol parameterType = parameter.Type;
            Debug.Assert(parameter.IsOptional);
            ConstantValue defaultConstantValue = parameter.ExplicitDefaultConstantValue;
            BoundExpression defaultValue;
            SourceLocation callerSourceLocation;

            // For compatibility with the native compiler we treat all bad imported constant
            // values as default(T).  
            if (defaultConstantValue != null && defaultConstantValue.IsBad)
            {
                defaultConstantValue = ConstantValue.Null;
            }

            if (parameter.IsCallerLineNumber && ((callerSourceLocation = GetCallerLocation(syntax, enableCallerInfo)) != null))
            {
                int line = callerSourceLocation.SourceTree.GetDisplayLineNumber(callerSourceLocation.SourceSpan);
                BoundExpression lineLiteral = MakeLiteral(syntax, ConstantValue.Create(line), _compilation.GetSpecialType(SpecialType.System_Int32));

                if (parameterType.IsNullableType())
                {
                    defaultValue = MakeConversionNode(lineLiteral, parameterType.GetNullableUnderlyingType(), false);

                    // wrap it in a nullable ctor.
                    defaultValue = new BoundObjectCreationExpression(
                        syntax,
                        GetNullableMethod(syntax, parameterType, SpecialMember.System_Nullable_T__ctor),
                        defaultValue);
                }
                else
                {
                    defaultValue = MakeConversionNode(lineLiteral, parameterType, false);
                }
            }
            else if (parameter.IsCallerFilePath && ((callerSourceLocation = GetCallerLocation(syntax, enableCallerInfo)) != null))
            {
                string path = callerSourceLocation.SourceTree.GetDisplayPath(callerSourceLocation.SourceSpan, _compilation.Options.SourceReferenceResolver);
                BoundExpression memberNameLiteral = MakeLiteral(syntax, ConstantValue.Create(path), _compilation.GetSpecialType(SpecialType.System_String));
                defaultValue = MakeConversionNode(memberNameLiteral, parameterType, false);
            }
            else if (parameter.IsCallerMemberName && ((callerSourceLocation = GetCallerLocation(syntax, enableCallerInfo)) != null))
            {
                string memberName;

                switch (_factory.TopLevelMethod.MethodKind)
                {
                    case MethodKind.Constructor:
                    case MethodKind.StaticConstructor:
                        // See if the code is actually part of a field, field-like event or property initializer and return the name of the corresponding member.
                        var memberDecl = syntax.Ancestors().OfType<MemberDeclarationSyntax>().FirstOrDefault();

                        if (memberDecl != null)
                        {
                            BaseFieldDeclarationSyntax fieldDecl;

                            if (memberDecl.Kind() == SyntaxKind.PropertyDeclaration)
                            {
                                var propDecl = (PropertyDeclarationSyntax)memberDecl;
                                EqualsValueClauseSyntax initializer = propDecl.Initializer;

                                if (initializer != null && initializer.Span.Contains(syntax.Span))
                                {
                                    memberName = propDecl.Identifier.ValueText;
                                    break;
                                }
                            }
                            else if ((fieldDecl = memberDecl as BaseFieldDeclarationSyntax) != null)
                            {
                                memberName = null;

                                foreach (VariableDeclaratorSyntax varDecl in fieldDecl.Declaration.Variables)
                                {
                                    EqualsValueClauseSyntax initializer = varDecl.Initializer;

                                    if (initializer != null && initializer.Span.Contains(syntax.Span))
                                    {
                                        memberName = varDecl.Identifier.ValueText;
                                        break;
                                    }
                                }

                                if (memberName != null)
                                {
                                    break;
                                }
                            }
                        }

                        goto default;

                    default:
                        memberName = _factory.TopLevelMethod.GetMemberCallerName();
                        break;
                }

                BoundExpression memberNameLiteral = MakeLiteral(syntax, ConstantValue.Create(memberName), _compilation.GetSpecialType(SpecialType.System_String));
                defaultValue = MakeConversionNode(memberNameLiteral, parameterType, false);
            }
            else if (defaultConstantValue == ConstantValue.NotAvailable)
            {
                // There is no constant value given for the parameter in source/metadata.
                if (parameterType.IsDynamic() || parameterType.SpecialType == SpecialType.System_Object)
                {
                    // We have something like M([Optional] object x). We have special handling for such situations.
                    defaultValue = GetDefaultParameterSpecial(syntax, parameter);
                }
                else
                {
                    // The argument to M([Optional] int x) becomes default(int)
                    defaultValue = new BoundDefaultOperator(syntax, parameterType);
                }
            }
            else if (defaultConstantValue.IsNull && parameterType.IsValueType)
            {
                // We have something like M(int? x = null) or M(S x = default(S)),
                // so replace the argument with default(int?).
                defaultValue = new BoundDefaultOperator(syntax, parameterType);
            }
            else if (parameterType.IsNullableType())
            {
                // We have something like M(double? x = 1.23), so replace the argument
                // with new double?(1.23).

                TypeSymbol constantType = _compilation.GetSpecialType(defaultConstantValue.SpecialType);
                defaultValue = MakeLiteral(syntax, defaultConstantValue, constantType);

                // The parameter's underlying type might not match the constant type. For example, we might have
                // a default value of 5 (an integer) but a parameter type of decimal?.

                defaultValue = MakeConversionNode(defaultValue, parameterType.GetNullableUnderlyingType(), @checked: false, acceptFailingConversion: true);

                // Finally, wrap it in a nullable ctor.
                defaultValue = new BoundObjectCreationExpression(
                    syntax,
                    GetNullableMethod(syntax, parameterType, SpecialMember.System_Nullable_T__ctor),
                    defaultValue);
            }
            else if (defaultConstantValue.IsNull || defaultConstantValue.IsBad)
            {
                defaultValue = MakeLiteral(syntax, defaultConstantValue, parameterType);
            }
            else
            {
                // We have something like M(double x = 1.23), so replace the argument with 1.23.

                TypeSymbol constantType = _compilation.GetSpecialType(defaultConstantValue.SpecialType);
                defaultValue = MakeLiteral(syntax, defaultConstantValue, constantType);
                // The parameter type might not match the constant type.
                defaultValue = MakeConversionNode(defaultValue, parameterType, @checked: false, acceptFailingConversion: true);
            }

            return defaultValue;
        }
        internal override void EarlyDecodeWellKnownAttributeType(NamedTypeSymbol attributeType, AttributeSyntax attributeSyntax)
        {
            Debug.Assert(!attributeType.IsErrorType());

            // NOTE: OptionalAttribute is decoded specially before any of the other attributes and stored in the parameter
            // symbol (rather than in the EarlyWellKnownAttributeData) because it is needed during overload resolution.
            if (CSharpAttributeData.IsTargetEarlyAttribute(attributeType, attributeSyntax, AttributeDescription.OptionalAttribute))
            {
                _lazyHasOptionalAttribute = ThreeState.True;
            }
        }
Ejemplo n.º 25
0
        private PEParameterSymbol(
            PEModuleSymbol moduleSymbol,
            Symbol containingSymbol,
            int ordinal,
            bool isByRef,
            bool hasByRefBeforeCustomModifiers,
            TypeSymbol type,
            ParameterHandle handle,
            ImmutableArray <ModifierInfo <TypeSymbol> > customModifiers,
            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;
            _customModifiers  = CSharpCustomModifier.Convert(customModifiers);
            _ordinal          = (ushort)ordinal;

            _handle = handle;

            RefKind refKind = RefKind.None;

            if (handle.IsNil)
            {
                refKind = isByRef ? RefKind.Ref : RefKind.None;

                _type = type;
                _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);
                    refKind = (inOutFlags == ParameterAttributes.Out) ? RefKind.Out : RefKind.Ref;
                }

                // CONSIDER: Can we make parameter type computation lazy?
                _type = DynamicTypeDecoder.TransformType(type, _customModifiers.Length, handle, moduleSymbol, refKind);
            }

            if (string.IsNullOrEmpty(_name))
            {
                // As was done historically, if the parameter doesn't have a name, we give it the name "value".
                _name = "value";
            }

            _packedFlags = new PackedFlags(refKind, hasByRefBeforeCustomModifiers, attributesAreComplete: handle.IsNil);

            Debug.Assert(refKind == this.RefKind);
            Debug.Assert(hasByRefBeforeCustomModifiers == this.HasByRefBeforeCustomModifiers);
        }
        internal override void PostEarlyDecodeWellKnownAttributeTypes()
        {
            if (_lazyHasOptionalAttribute == ThreeState.Unknown)
            {
                _lazyHasOptionalAttribute = ThreeState.False;
            }

            base.PostEarlyDecodeWellKnownAttributeTypes();
        }
        internal bool ContainsNoPiaLocalTypes()
        {
            if (this.lazyContainsNoPiaLocalTypes == ThreeState.Unknown)
            {
                foreach (PEModule module in Modules)
                {
                    if (module.ContainsNoPiaLocalTypes())
                    {
                        this.lazyContainsNoPiaLocalTypes = ThreeState.True;
                        return true;
                    }
                }

                this.lazyContainsNoPiaLocalTypes = ThreeState.False;
            }

            return this.lazyContainsNoPiaLocalTypes == ThreeState.True;
        }
Ejemplo n.º 28
0
 public static bool HasValue(this ThreeState value)
 {
     return(value != ThreeState.Unknown);
 }
Ejemplo n.º 29
0
        public override ImmutableArray<CSharpAttributeData> GetAttributes()
        {
            if (_lazyCustomAttributes.IsDefault)
            {
                Debug.Assert(!_handle.IsNil);
                var containingPEModuleSymbol = (PEModuleSymbol)this.ContainingModule;

                // Filter out ParamArrayAttributes if necessary and cache
                // the attribute handle for GetCustomAttributesToEmit
                bool filterOutParamArrayAttribute = (!_lazyIsParams.HasValue() || _lazyIsParams.Value());

                ConstantValue defaultValue = this.ExplicitDefaultConstantValue;
                AttributeDescription filterOutConstantAttributeDescription = default(AttributeDescription);

                if ((object)defaultValue != null)
                {
                    if (defaultValue.Discriminator == ConstantValueTypeDiscriminator.DateTime)
                    {
                        filterOutConstantAttributeDescription = AttributeDescription.DateTimeConstantAttribute;
                    }
                    else if (defaultValue.Discriminator == ConstantValueTypeDiscriminator.Decimal)
                    {
                        filterOutConstantAttributeDescription = AttributeDescription.DecimalConstantAttribute;
                    }
                }

                if (filterOutParamArrayAttribute || filterOutConstantAttributeDescription.Signatures != null)
                {
                    CustomAttributeHandle paramArrayAttribute;
                    CustomAttributeHandle constantAttribute;

                    ImmutableArray<CSharpAttributeData> attributes =
                        containingPEModuleSymbol.GetCustomAttributesForToken(
                            _handle,
                            out paramArrayAttribute,
                            filterOutParamArrayAttribute ? AttributeDescription.ParamArrayAttribute : default(AttributeDescription),
                            out constantAttribute,
                            filterOutConstantAttributeDescription);

                    if (!paramArrayAttribute.IsNil || !constantAttribute.IsNil)
                    {
                        var builder = ArrayBuilder<CSharpAttributeData>.GetInstance();

                        if (!paramArrayAttribute.IsNil)
                        {
                            builder.Add(new PEAttributeData(containingPEModuleSymbol, paramArrayAttribute));
                        }

                        if (!constantAttribute.IsNil)
                        {
                            builder.Add(new PEAttributeData(containingPEModuleSymbol, constantAttribute));
                        }

                        ImmutableInterlocked.InterlockedInitialize(ref _lazyHiddenAttributes, builder.ToImmutableAndFree());
                    }
                    else
                    {
                        ImmutableInterlocked.InterlockedInitialize(ref _lazyHiddenAttributes, ImmutableArray<CSharpAttributeData>.Empty);
                    }

                    if (!_lazyIsParams.HasValue())
                    {
                        Debug.Assert(filterOutParamArrayAttribute);
                        _lazyIsParams = (!paramArrayAttribute.IsNil).ToThreeState();
                    }

                    ImmutableInterlocked.InterlockedInitialize(
                        ref _lazyCustomAttributes,
                        attributes);
                }
                else
                {
                    ImmutableInterlocked.InterlockedInitialize(ref _lazyHiddenAttributes, ImmutableArray<CSharpAttributeData>.Empty);
                    containingPEModuleSymbol.LoadCustomAttributes(_handle, ref _lazyCustomAttributes);
                }
            }

            Debug.Assert(!_lazyHiddenAttributes.IsDefault);
            return _lazyCustomAttributes;
        }
Ejemplo n.º 30
0
 protected void SealTemplates()
 {
     _templatesSealed = ThreeState.True;
 }