コード例 #1
0
        private BoundExpression MakePair(CSharpSyntaxNode node, string field1Name, BoundExpression field1Value, string field2Name, BoundExpression field2Value, QueryTranslationState state, DiagnosticBag diagnostics)
        {
            if (field1Name == field2Name)
            {
                // we will generate a diagnostic elsewhere
                field2Name  = state.TransparentRangeVariableName();
                field2Value = new BoundBadExpression(field2Value.Syntax, LookupResultKind.Empty, ImmutableArray <Symbol> .Empty, ImmutableArray.Create(field2Value), field2Value.Type, true);
            }

            AnonymousTypeDescriptor typeDescriptor = new AnonymousTypeDescriptor(
                ImmutableArray.Create <AnonymousTypeField>(
                    new AnonymousTypeField(field1Name, field1Value.Syntax.Location,
                                           TypeSymbolWithAnnotations.Create(TypeOrError(field1Value))),
                    new AnonymousTypeField(field2Name, field2Value.Syntax.Location,
                                           TypeSymbolWithAnnotations.Create(TypeOrError(field2Value)))
                    ),
                node.Location
                );

            AnonymousTypeManager manager       = this.Compilation.AnonymousTypeManager;
            NamedTypeSymbol      anonymousType = manager.ConstructAnonymousTypeSymbol(typeDescriptor);

            return(MakeConstruction(node, anonymousType, ImmutableArray.Create(field1Value, field2Value), diagnostics));
        }
コード例 #2
0
ファイル: SymbolFactory.cs プロジェクト: stark-lang/stark
        internal override TypeSymbol MakeExtendedTypeSymbol(PEModuleSymbol moduleSymbol, TypeSymbol type, TypeAccessModifiers typeAccessModifiers)
        {
            switch (type.TypeKind)
            {
            case TypeKind.Array:
                return(new ExtendedArrayTypeSymbol(TypeSymbolWithAnnotations.Create(type), (ArrayTypeSymbol)type, typeAccessModifiers));

            case TypeKind.Class:
            case TypeKind.Interface:
            case TypeKind.Struct:
            case TypeKind.Enum:
                return(new ExtendedNamedTypeSymbol(TypeSymbolWithAnnotations.Create(type), typeAccessModifiers));

            case TypeKind.TypeParameter:
                return(new ExtendedTypeParameterSymbol((TypeParameterSymbol)type, typeAccessModifiers));

            case TypeKind.ConstLiteral:
            case TypeKind.Module:
            case TypeKind.Submission:
            case TypeKind.Pointer:
            default:
                throw ExceptionUtilities.UnexpectedValue(type.TypeKind);
            }
        }
コード例 #3
0
ファイル: TupleTypeDecoder.cs プロジェクト: zyonet/roslyn
        public static TypeSymbolWithAnnotations DecodeTupleTypesIfApplicable(
            TypeSymbolWithAnnotations metadataType,
            EntityHandle targetHandle,
            PEModuleSymbol containingModule)
        {
            ImmutableArray <string> elementNames;
            var hasTupleElementNamesAttribute = containingModule
                                                .Module
                                                .HasTupleElementNamesAttribute(targetHandle, out elementNames);

            // If we have the TupleElementNamesAttribute, but no names, that's
            // bad metadata
            if (hasTupleElementNamesAttribute && elementNames.IsDefaultOrEmpty)
            {
                return(TypeSymbolWithAnnotations.Create(new UnsupportedMetadataTypeSymbol()));
            }

            TypeSymbol type    = metadataType.TypeSymbol;
            TypeSymbol decoded = DecodeTupleTypesInternal(type, elementNames, hasTupleElementNamesAttribute);

            return((object)decoded == (object)type ?
                   metadataType :
                   TypeSymbolWithAnnotations.Create(decoded, metadataType.NullableAnnotation, metadataType.CustomModifiers));
        }
コード例 #4
0
            public LabelSymbol ProxyReturnIfNeeded(
                MethodSymbol containingMethod,
                BoundExpression valueOpt,
                out SynthesizedLocal returnValue)
            {
                returnValue = null;

                // no need to proxy returns  at the root
                if (this.IsRoot())
                {
                    return(null);
                }

                var returnProxy = this.returnProxyLabel;

                if (returnProxy == null)
                {
                    this.returnProxyLabel = returnProxy = new GeneratedLabelSymbol("returnProxy");
                }

                if (valueOpt != null)
                {
                    returnValue = this.returnValue;
                    if (returnValue == null)
                    {
                        Debug.Assert(_statementSyntaxOpt != null);
                        this.returnValue = returnValue = new SynthesizedLocal(containingMethod, TypeSymbolWithAnnotations.Create(valueOpt.Type), SynthesizedLocalKind.AsyncMethodReturnValue, _statementSyntaxOpt);
                    }
                }

                return(returnProxy);
            }
コード例 #5
0
            public AwaitCatchFrame(SyntheticBoundNodeFactory F, TryStatementSyntax tryStatementSyntax)
            {
                this.pendingCaughtException = new SynthesizedLocal(F.CurrentFunction, TypeSymbolWithAnnotations.Create(F.SpecialType(SpecialType.System_Object)), SynthesizedLocalKind.TryAwaitPendingCaughtException, tryStatementSyntax);
                this.pendingCatch           = new SynthesizedLocal(F.CurrentFunction, TypeSymbolWithAnnotations.Create(F.SpecialType(SpecialType.System_Int32)), SynthesizedLocalKind.TryAwaitPendingCatch, tryStatementSyntax);

                this.handlers         = new List <BoundBlock>();
                _hoistedLocals        = new Dictionary <LocalSymbol, LocalSymbol>();
                _orderedHoistedLocals = new List <LocalSymbol>();
            }
コード例 #6
0
ファイル: TypeMap.cs プロジェクト: stark-lang/stark
 internal static ImmutableArray <TypeSymbolWithAnnotations> TypeParametersAsTypeSymbolsWithAnnotations(ImmutableArray <TypeParameterSymbol> typeParameters)
 {
     return(typeParameters.SelectAsArray((tp) => TypeSymbolWithAnnotations.Create(tp)));
 }
コード例 #7
0
ファイル: PEEventSymbol.cs プロジェクト: zyonet/roslyn
        internal PEEventSymbol(
            PEModuleSymbol moduleSymbol,
            PENamedTypeSymbol containingType,
            EventDefinitionHandle handle,
            PEMethodSymbol addMethod,
            PEMethodSymbol removeMethod,
            MultiDictionary <string, PEFieldSymbol> privateFieldNameToSymbols)
        {
            Debug.Assert((object)moduleSymbol != null);
            Debug.Assert((object)containingType != null);
            Debug.Assert(!handle.IsNil);
            Debug.Assert((object)addMethod != null);
            Debug.Assert((object)removeMethod != null);

            _addMethod      = addMethod;
            _removeMethod   = removeMethod;
            _handle         = handle;
            _containingType = containingType;

            EventAttributes mdFlags   = 0;
            EntityHandle    eventType = default(EntityHandle);

            try
            {
                var module = moduleSymbol.Module;
                module.GetEventDefPropsOrThrow(handle, out _name, out mdFlags, out eventType);
            }
            catch (BadImageFormatException mrEx)
            {
                if ((object)_name == null)
                {
                    _name = string.Empty;
                }

                _lazyUseSiteDiagnostic = new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this);

                if (eventType.IsNil)
                {
                    _eventType = TypeSymbolWithAnnotations.Create(new UnsupportedMetadataTypeSymbol(mrEx));
                }
            }

            TypeSymbol originalEventType = _eventType.TypeSymbol;

            if (_eventType.IsNull)
            {
                var metadataDecoder = new MetadataDecoder(moduleSymbol, containingType);
                originalEventType = metadataDecoder.GetTypeOfToken(eventType);

                const int targetSymbolCustomModifierCount = 0;
                var       typeSymbol = DynamicTypeDecoder.TransformType(originalEventType, targetSymbolCustomModifierCount, handle, moduleSymbol);

                // We start without annotation (they will be decoded below)
                var type = TypeSymbolWithAnnotations.Create(typeSymbol);

                // Decode nullable before tuple types to avoid converting between
                // NamedTypeSymbol and TupleTypeSymbol unnecessarily.
                type       = NullableTypeDecoder.TransformType(type, handle, moduleSymbol);
                type       = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, handle, moduleSymbol);
                _eventType = type;
            }

            // IsWindowsRuntimeEvent checks the signatures, so we just have to check the accessors.
            bool isWindowsRuntimeEvent = IsWindowsRuntimeEvent;
            bool callMethodsDirectly   = isWindowsRuntimeEvent
                ? !DoModifiersMatch(_addMethod, _removeMethod)
                : !DoSignaturesMatch(moduleSymbol, originalEventType, _addMethod, _removeMethod);

            if (callMethodsDirectly)
            {
                _flags |= Flags.CallMethodsDirectly;
            }
            else
            {
                _addMethod.SetAssociatedEvent(this, MethodKind.EventAdd);
                _removeMethod.SetAssociatedEvent(this, MethodKind.EventRemove);

                PEFieldSymbol associatedField = GetAssociatedField(privateFieldNameToSymbols, isWindowsRuntimeEvent);
                if ((object)associatedField != null)
                {
                    _associatedFieldOpt = associatedField;
                    associatedField.SetAssociatedEvent(this);
                }
            }

            if ((mdFlags & EventAttributes.SpecialName) != 0)
            {
                _flags |= Flags.IsSpecialName;
            }

            if ((mdFlags & EventAttributes.RTSpecialName) != 0)
            {
                _flags |= Flags.IsRuntimeSpecialName;
            }
        }
コード例 #8
0
 internal override TypeSymbolWithAnnotations GetFieldType(ConsList <FieldSymbol> fieldsBeingBound)
 {
     return(TypeSymbolWithAnnotations.Create(((SourceNamedTypeSymbol)ContainingType).EnumUnderlyingType));
 }
コード例 #9
0
ファイル: TypeUnification.cs プロジェクト: stark-lang/stark
 private static bool CanUnifyHelper(TypeSymbol t1, TypeSymbol t2, ref MutableTypeMap substitution)
 {
     return(CanUnifyHelper(TypeSymbolWithAnnotations.Create(t1), TypeSymbolWithAnnotations.Create(t2), ref substitution));
 }
コード例 #10
0
        /// <summary>
        /// If the extension method is applicable based on the "this" argument type, return
        /// the method constructed with the inferred type arguments. If the method is not an
        /// unconstructed generic method, type inference is skipped. If the method is not
        /// applicable, or if constraints when inferring type parameters from the "this" type
        /// are not satisfied, the return value is null.
        /// </summary>
        public static MethodSymbol InferExtensionMethodTypeArguments(this MethodSymbol method, TypeSymbol thisType, Compilation compilation, ref HashSet <DiagnosticInfo> useSiteDiagnostics)
        {
            Debug.Assert(method.IsExtensionMethod);
            Debug.Assert((object)thisType != null);

            if (!method.IsGenericMethod || method != method.ConstructedFrom)
            {
                return(method);
            }

            // We never resolve extension methods on a dynamic receiver.
            if (thisType.IsDynamic())
            {
                return(null);
            }

            var containingAssembly = method.ContainingAssembly;
            var errorNamespace     = containingAssembly.GlobalNamespace;
            var conversions        = new TypeConversions(containingAssembly.CorLibrary);

            // There is absolutely no plausible syntax/tree that we could use for these
            // synthesized literals.  We could be speculatively binding a call to a PE method.
            var syntaxTree = CSharpSyntaxTree.Dummy;
            var syntax     = (CSharpSyntaxNode)syntaxTree.GetRoot();

            // Create an argument value for the "this" argument of specific type,
            // and pass the same bad argument value for all other arguments.
            var thisArgumentValue = new BoundLiteral(syntax, ConstantValue.Bad, thisType)
            {
                WasCompilerGenerated = true
            };
            var otherArgumentType  = new ExtendedErrorTypeSymbol(errorNamespace, name: string.Empty, arity: 0, errorInfo: null, unreported: false);
            var otherArgumentValue = new BoundLiteral(syntax, ConstantValue.Bad, otherArgumentType)
            {
                WasCompilerGenerated = true
            };

            var paramCount = method.ParameterCount;
            var arguments  = new BoundExpression[paramCount];

            for (int i = 0; i < paramCount; i++)
            {
                var argument = (i == 0) ? thisArgumentValue : otherArgumentValue;
                arguments[i] = argument;
            }

            var typeArgs = MethodTypeInferrer.InferTypeArgumentsFromFirstArgument(
                conversions,
                method,
                arguments.AsImmutable(),
                useSiteDiagnostics: ref useSiteDiagnostics);

            if (typeArgs.IsDefault)
            {
                return(null);
            }

            int firstNullInTypeArgs = -1;

            // For the purpose of constraint checks we use error type symbol in place of type arguments that we couldn't infer from the first argument.
            // This prevents constraint checking from failing for corresponding type parameters.
            var notInferredTypeParameters = PooledHashSet <TypeParameterSymbol> .GetInstance();

            var typeParams = method.TypeParameters;
            var typeArgsForConstraintsCheck = typeArgs;

            for (int i = 0; i < typeArgsForConstraintsCheck.Length; i++)
            {
                if (typeArgsForConstraintsCheck[i].IsNull)
                {
                    firstNullInTypeArgs = i;
                    var builder = ArrayBuilder <TypeSymbolWithAnnotations> .GetInstance();

                    builder.AddRange(typeArgsForConstraintsCheck, firstNullInTypeArgs);

                    for (; i < typeArgsForConstraintsCheck.Length; i++)
                    {
                        var typeArg = typeArgsForConstraintsCheck[i];
                        if (typeArg.IsNull)
                        {
                            notInferredTypeParameters.Add(typeParams[i]);
                            builder.Add(TypeSymbolWithAnnotations.Create(ErrorTypeSymbol.UnknownResultType));
                        }
                        else
                        {
                            builder.Add(typeArg);
                        }
                    }

                    typeArgsForConstraintsCheck = builder.ToImmutableAndFree();
                    break;
                }
            }

            // Check constraints.
            var diagnosticsBuilder = ArrayBuilder <TypeParameterDiagnosticInfo> .GetInstance();

            var substitution = new TypeMap(typeParams, typeArgsForConstraintsCheck);
            ArrayBuilder <TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
            var success = method.CheckConstraints(conversions, substitution, typeParams, typeArgsForConstraintsCheck, compilation, diagnosticsBuilder, warningsBuilderOpt: null, ref useSiteDiagnosticsBuilder,
                                                  ignoreTypeConstraintsDependentOnTypeParametersOpt: notInferredTypeParameters.Count > 0 ? notInferredTypeParameters : null);

            diagnosticsBuilder.Free();
            notInferredTypeParameters.Free();

            if (useSiteDiagnosticsBuilder != null && useSiteDiagnosticsBuilder.Count > 0)
            {
                if (useSiteDiagnostics == null)
                {
                    useSiteDiagnostics = new HashSet <DiagnosticInfo>();
                }

                foreach (var diag in useSiteDiagnosticsBuilder)
                {
                    useSiteDiagnostics.Add(diag.DiagnosticInfo);
                }
            }

            if (!success)
            {
                return(null);
            }

            // For the purpose of construction we use original type parameters in place of type arguments that we couldn't infer from the first argument.
            var typeArgsForConstruct = typeArgs;

            if (firstNullInTypeArgs != -1)
            {
                var builder = ArrayBuilder <TypeSymbolWithAnnotations> .GetInstance();

                builder.AddRange(typeArgs, firstNullInTypeArgs);

                for (int i = firstNullInTypeArgs; i < typeArgsForConstruct.Length; i++)
                {
                    var typeArgForConstruct = typeArgsForConstruct[i];
                    builder.Add(!typeArgForConstruct.IsNull ? typeArgForConstruct : TypeSymbolWithAnnotations.Create(typeParams[i]));
                }

                typeArgsForConstruct = builder.ToImmutableAndFree();
            }

            return(method.Construct(typeArgsForConstruct));
        }
コード例 #11
0
 public BoundDeconstructValuePlaceholder FailInference(Binder binder)
 {
     return(SetInferredType(TypeSymbolWithAnnotations.Create(binder.CreateErrorType()), binder, success: false));
 }
コード例 #12
0
        public void TypeMap()
        {
            var source = @"
struct S<T> where T : struct
{
}
";

            var comp = CreateCompilation(source);

            comp.VerifyDiagnostics();

            var intType         = comp.GetSpecialType(SpecialType.System_Int32);
            var customModifiers = ImmutableArray.Create(CSharpCustomModifier.CreateOptional(intType));

            var structType    = comp.GlobalNamespace.GetMember <NamedTypeSymbol>("S");
            var typeParamType = structType.TypeParameters.Single();

            var pointerType = new PointerTypeSymbol(TypeSymbolWithAnnotations.Create(typeParamType, customModifiers: customModifiers));                            // NOTE: We're constructing this manually, since it's illegal.
            var arrayType   = ArrayTypeSymbol.CreateCSharpArray(comp.Assembly, TypeSymbolWithAnnotations.Create(typeParamType, customModifiers: customModifiers)); // This is legal, but we're already manually constructing types.

            var typeMap = new TypeMap(ImmutableArray.Create(typeParamType), ImmutableArray.Create(TypeSymbolWithAnnotations.Create(intType)));

            var substitutedPointerType = (PointerTypeSymbol)typeMap.SubstituteType(pointerType).AsTypeSymbolOnly();
            var substitutedArrayType   = (ArrayTypeSymbol)typeMap.SubstituteType(arrayType).AsTypeSymbolOnly();

            // The map changed the types.
            Assert.Equal(intType, substitutedPointerType.PointedAtType.TypeSymbol);
            Assert.Equal(intType, substitutedArrayType.ElementType.TypeSymbol);

            // The map preserved the custom modifiers.
            Assert.Equal(customModifiers, substitutedPointerType.PointedAtType.CustomModifiers);
            Assert.Equal(customModifiers, substitutedArrayType.ElementType.CustomModifiers);
        }
コード例 #13
0
        private DynamicAnalysisInjector(
            MethodSymbol method,
            BoundStatement methodBody,
            SyntheticBoundNodeFactory methodBodyFactory,
            MethodSymbol createPayloadForMethodsSpanningSingleFile,
            MethodSymbol createPayloadForMethodsSpanningMultipleFiles,
            DiagnosticBag diagnostics,
            DebugDocumentProvider debugDocumentProvider,
            Instrumenter previous) : base(previous)
        {
            _createPayloadForMethodsSpanningSingleFile    = createPayloadForMethodsSpanningSingleFile;
            _createPayloadForMethodsSpanningMultipleFiles = createPayloadForMethodsSpanningMultipleFiles;
            _method       = method;
            _methodBody   = methodBody;
            _spansBuilder = ArrayBuilder <SourceSpan> .GetInstance();

            TypeSymbol payloadElementType = methodBodyFactory.SpecialType(SpecialType.System_Boolean);

            _payloadType           = ArrayTypeSymbol.CreateCSharpArray(methodBodyFactory.Compilation.Assembly, TypeSymbolWithAnnotations.Create(payloadElementType));
            _diagnostics           = diagnostics;
            _debugDocumentProvider = debugDocumentProvider;
            _methodBodyFactory     = methodBodyFactory;

            // Set the factory context to generate nodes for the current method
            var oldMethod = methodBodyFactory.CurrentFunction;

            methodBodyFactory.CurrentFunction = method;

            _methodPayload = methodBodyFactory.SynthesizedLocal(_payloadType, kind: SynthesizedLocalKind.InstrumentationPayload, syntax: methodBody.Syntax);
            // The first point indicates entry into the method and has the span of the method definition.
            SyntaxNode syntax = MethodDeclarationIfAvailable(methodBody.Syntax);

            if (!method.IsImplicitlyDeclared)
            {
                _methodEntryInstrumentation = AddAnalysisPoint(syntax, SkipAttributes(syntax), methodBodyFactory);
            }

            // Restore context
            methodBodyFactory.CurrentFunction = oldMethod;
        }
コード例 #14
0
        public override BoundStatement CreateBlockPrologue(BoundBlock original, out LocalSymbol synthesizedLocal)
        {
            BoundStatement previousPrologue = base.CreateBlockPrologue(original, out synthesizedLocal);

            if (_methodBody == original)
            {
                _dynamicAnalysisSpans = _spansBuilder.ToImmutableAndFree();
                // In the future there will be multiple analysis kinds.
                const int analysisKind = 0;

                ArrayTypeSymbol modulePayloadType =
                    ArrayTypeSymbol.CreateCSharpArray(_methodBodyFactory.Compilation.Assembly, TypeSymbolWithAnnotations.Create(_payloadType));

                // Synthesize the initialization of the instrumentation payload array, using concurrency-safe code:
                //
                // var payload = PID.PayloadRootField[methodIndex];
                // if (payload == null)
                //     payload = Instrumentation.CreatePayload(mvid, methodIndex, fileIndexOrIndices, ref PID.PayloadRootField[methodIndex], payloadLength);

                BoundStatement payloadInitialization =
                    _methodBodyFactory.Assignment(
                        _methodBodyFactory.Local(_methodPayload),
                        _methodBodyFactory.ArrayAccess(
                            _methodBodyFactory.InstrumentationPayloadRoot(analysisKind, modulePayloadType),
                            ImmutableArray.Create(_methodBodyFactory.MethodDefIndex(_method))));

                BoundExpression mvid        = _methodBodyFactory.ModuleVersionId();
                BoundExpression methodToken = _methodBodyFactory.MethodDefIndex(_method);

                BoundExpression payloadSlot =
                    _methodBodyFactory.ArrayAccess(
                        _methodBodyFactory.InstrumentationPayloadRoot(analysisKind, modulePayloadType),
                        ImmutableArray.Create(_methodBodyFactory.MethodDefIndex(_method)));

                BoundStatement createPayloadCall =
                    GetCreatePayloadStatement(
                        _dynamicAnalysisSpans,
                        _methodBody.Syntax,
                        _methodPayload,
                        _createPayloadForMethodsSpanningSingleFile,
                        _createPayloadForMethodsSpanningMultipleFiles,
                        mvid,
                        methodToken,
                        payloadSlot,
                        _methodBodyFactory,
                        _debugDocumentProvider);

                BoundExpression payloadNullTest =
                    _methodBodyFactory.Binary(
                        BinaryOperatorKind.ObjectEqual,
                        _methodBodyFactory.SpecialType(SpecialType.System_Boolean),
                        _methodBodyFactory.Local(_methodPayload),
                        _methodBodyFactory.Null(_payloadType));

                BoundStatement payloadIf = _methodBodyFactory.If(payloadNullTest, createPayloadCall);

                Debug.Assert(synthesizedLocal == null);
                synthesizedLocal = _methodPayload;

                ArrayBuilder <BoundStatement> prologueStatements = ArrayBuilder <BoundStatement> .GetInstance(previousPrologue == null? 3 : 4);

                prologueStatements.Add(payloadInitialization);
                prologueStatements.Add(payloadIf);
                if (_methodEntryInstrumentation != null)
                {
                    prologueStatements.Add(_methodEntryInstrumentation);
                }

                if (previousPrologue != null)
                {
                    prologueStatements.Add(previousPrologue);
                }

                return(_methodBodyFactory.StatementList(prologueStatements.ToImmutableAndFree()));
            }

            return(previousPrologue);
        }
コード例 #15
0
        internal static void AddDelegateMembers(
            SourceMemberContainerTypeSymbol delegateType,
            ArrayBuilder <Symbol> symbols,
            DelegateDeclarationSyntax syntax,
            DiagnosticBag diagnostics)
        {
            var        compilation      = delegateType.DeclaringCompilation;
            Binder     binder           = delegateType.GetBinder(syntax.ParameterList);
            RefKind    refKind          = syntax.ReturnType.GetRefKind();
            TypeSyntax returnTypeSyntax = syntax.ReturnType;
            var        returnType       = binder.BindType(returnTypeSyntax, diagnostics);

            // reuse types to avoid reporting duplicate errors if missing:
            var voidType = TypeSymbolWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_Void, diagnostics, syntax));
            // https://github.com/dotnet/roslyn/issues/30079: Should the 'object', IAsyncResult and AsyncCallback parameters be considered nullable or not nullable?
            var objectType = TypeSymbolWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_Object, diagnostics, syntax));
            var intPtrType = TypeSymbolWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_Int, diagnostics, syntax));

            if (returnType.IsRestrictedType(ignoreSpanLikeTypes: true))
            {
                // Method or delegate cannot return type '{0}'
                diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, returnTypeSyntax.Location, returnType.TypeSymbol);
            }

            // A delegate has the following members: (see CLI spec 13.6)
            // (1) a method named Invoke with the specified signature
            var invoke = new InvokeMethod(delegateType, refKind, returnType, syntax, binder, diagnostics);

            invoke.CheckDelegateVarianceSafety(diagnostics);
            symbols.Add(invoke);

            // (2) a constructor with argument types (object, System.IntPtr)
            symbols.Add(new Constructor(delegateType, voidType, objectType, intPtrType, syntax));

            if (binder.Compilation.GetSpecialType(SpecialType.System_IAsyncResult).TypeKind != TypeKind.Error &&
                binder.Compilation.GetSpecialType(SpecialType.System_AsyncCallback).TypeKind != TypeKind.Error &&
                // WinRT delegates don't have Begin/EndInvoke methods
                !delegateType.IsCompilationOutputWinMdObj())
            {
                var iAsyncResultType  = TypeSymbolWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_IAsyncResult, diagnostics, syntax));
                var asyncCallbackType = TypeSymbolWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_AsyncCallback, diagnostics, syntax));

                // (3) BeginInvoke
                symbols.Add(new BeginInvokeMethod(invoke, iAsyncResultType, objectType, asyncCallbackType, syntax));

                // and (4) EndInvoke methods
                symbols.Add(new EndInvokeMethod(invoke, iAsyncResultType, syntax));
            }

            if (delegateType.DeclaredAccessibility <= Accessibility.Private)
            {
                return;
            }

            HashSet <DiagnosticInfo> useSiteDiagnostics = null;

            if (!delegateType.IsNoMoreVisibleThan(invoke.ReturnType, ref useSiteDiagnostics))
            {
                // Inconsistent accessibility: return type '{1}' is less accessible than delegate '{0}'
                diagnostics.Add(ErrorCode.ERR_BadVisDelegateReturn, delegateType.Locations[0], delegateType, invoke.ReturnType.TypeSymbol);
            }

            foreach (var parameter in invoke.Parameters)
            {
                if (!parameter.Type.IsAtLeastAsVisibleAs(delegateType, ref useSiteDiagnostics))
                {
                    // Inconsistent accessibility: parameter type '{1}' is less accessible than delegate '{0}'
                    diagnostics.Add(ErrorCode.ERR_BadVisDelegateParam, delegateType.Locations[0], delegateType, parameter.Type.TypeSymbol);
                }
            }

            diagnostics.Add(delegateType.Locations[0], useSiteDiagnostics);
        }
コード例 #16
0
        /// <remarks>
        /// These won't be returned by GetAttributes on source methods, but they
        /// will be returned by GetAttributes on metadata symbols.
        /// </remarks>
        internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes)
        {
            base.AddSynthesizedAttributes(moduleBuilder, ref attributes);

            CSharpCompilation compilation = this.DeclaringCompilation;

            if (this.ContainsExtensionMethods)
            {
                // No need to check if [Extension] attribute was explicitly set since
                // we'll issue CS1112 error in those cases and won't generate IL.
                AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_ExtensionAttribute__ctor));
            }

            if (this.IsRefLikeType)
            {
                AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsByRefLikeAttribute(this));

                var obsoleteData = ObsoleteAttributeData;
                Debug.Assert(obsoleteData != ObsoleteAttributeData.Uninitialized, "getting synthesized attributes before attributes are decoded");

                // If user specified an Obsolete attribute, we cannot emit ours.
                // NB: we do not check the kind of deprecation.
                //     we will not emit Obsolete even if Deprecated or Experimental was used.
                //     we do not want to get into a scenario where different kinds of deprecation are combined together.
                //
                if (obsoleteData == null && !this.IsRestrictedType(ignoreSpanLikeTypes: true))
                {
                    AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(WellKnownMember.System_ObsoleteAttribute__ctor,
                                                                                               ImmutableArray.Create(
                                                                                                   new TypedConstant(compilation.GetSpecialType(SpecialType.System_String), TypedConstantKind.Primitive, PEModule.ByRefLikeMarker), // message
                                                                                                   new TypedConstant(compilation.GetSpecialType(SpecialType.System_Boolean), TypedConstantKind.Primitive, true)),                   // error=true
                                                                                               isOptionalUse: true));
                }
            }

            if (this.IsReadOnly)
            {
                AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsReadOnlyAttribute(this));
            }

            if (this.Indexers.Any())
            {
                string defaultMemberName         = this.Indexers.First().MetadataName; // UNDONE: IndexerNameAttribute
                var    defaultMemberNameConstant = new TypedConstant(compilation.GetSpecialType(SpecialType.System_String), TypedConstantKind.Primitive, defaultMemberName);

                AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(
                                            WellKnownMember.core_runtime_DefaultMemberAttribute__ctor,
                                            ImmutableArray.Create(defaultMemberNameConstant)));
            }

            NamedTypeSymbol baseType = this.BaseTypeNoUseSiteDiagnostics;

            if ((object)baseType != null)
            {
                if (baseType.ContainsTupleNames())
                {
                    AddSynthesizedAttribute(ref attributes, compilation.SynthesizeTupleNamesAttribute(baseType));
                }

                if (baseType.NeedsNullableAttribute())
                {
                    AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttribute(this, TypeSymbolWithAnnotations.Create(baseType)));
                }
            }
        }
コード例 #17
0
ファイル: BestTypeInferrer.cs プロジェクト: zarenner/roslyn
        /// <summary>
        /// Returns the better type amongst the two, with some possible modifications (dynamic/object or tuple names).
        /// </summary>
        private static TypeSymbol Better(
            TypeSymbol type1,
            TypeSymbol type2,
            ConversionsBase conversions,
            out bool hadNullabilityMismatch,
            ref HashSet <DiagnosticInfo> useSiteDiagnostics)
        {
            hadNullabilityMismatch = false;

            // Anything is better than an error sym.
            if (type1.IsErrorType())
            {
                return(type2);
            }

            if ((object)type2 == null || type2.IsErrorType())
            {
                return(type1);
            }

            var conversionsWithoutNullability = conversions.WithNullability(false);
            var t1tot2 = conversionsWithoutNullability.ClassifyImplicitConversionFromType(type1, type2, ref useSiteDiagnostics).Exists;
            var t2tot1 = conversionsWithoutNullability.ClassifyImplicitConversionFromType(type2, type1, ref useSiteDiagnostics).Exists;

            if (t1tot2 && t2tot1)
            {
                if (type1.IsDynamic())
                {
                    return(type1);
                }

                if (type2.IsDynamic())
                {
                    return(type2);
                }

                if (type1.Equals(type2, TypeCompareKind.IgnoreDynamicAndTupleNames | TypeCompareKind.IgnoreNullableModifiersForReferenceTypes))
                {
                    return(MethodTypeInferrer.Merge(
                               TypeSymbolWithAnnotations.Create(type1),
                               TypeSymbolWithAnnotations.Create(type2),
                               VarianceKind.Out,
                               conversions,
                               out hadNullabilityMismatch).TypeSymbol);
                }

                return(null);
            }

            if (t1tot2)
            {
                return(type2);
            }

            if (t2tot1)
            {
                return(type1);
            }

            return(null);
        }
コード例 #18
0
            internal AnonymousTypeTemplateSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr)
            {
                this.Manager           = manager;
                this.TypeDescriptorKey = typeDescr.Key;
                _smallestLocation      = typeDescr.Location;

                // Will be set when the type's metadata is ready to be emitted,
                // <anonymous-type>.Name will throw exception if requested
                // before that moment.
                _nameAndIndex = null;

                int fieldsCount = typeDescr.Fields.Length;

                // members
                Symbol[] members     = new Symbol[fieldsCount * 3 + 1];
                int      memberIndex = 0;

                // The array storing property symbols to be used in
                // generation of constructor and other methods
                if (fieldsCount > 0)
                {
                    AnonymousTypePropertySymbol[] propertiesArray     = new AnonymousTypePropertySymbol[fieldsCount];
                    TypeParameterSymbol[]         typeParametersArray = new TypeParameterSymbol[fieldsCount];

                    // Process fields
                    for (int fieldIndex = 0; fieldIndex < fieldsCount; fieldIndex++)
                    {
                        AnonymousTypeField field = typeDescr.Fields[fieldIndex];

                        // Add a type parameter
                        AnonymousTypeParameterSymbol typeParameter =
                            new AnonymousTypeParameterSymbol(this, fieldIndex, GeneratedNames.MakeAnonymousTypeParameterName(field.Name));
                        typeParametersArray[fieldIndex] = typeParameter;

                        // Add a property
                        AnonymousTypePropertySymbol property = new AnonymousTypePropertySymbol(this, field, TypeSymbolWithAnnotations.Create(typeParameter));
                        propertiesArray[fieldIndex] = property;

                        // Property related symbols
                        members[memberIndex++] = property;
                        members[memberIndex++] = property.BackingField;
                        members[memberIndex++] = property.GetMethod;
                    }

                    _typeParameters = typeParametersArray.AsImmutable();
                    this.Properties = propertiesArray.AsImmutable();
                }
                else
                {
                    _typeParameters = ImmutableArray <TypeParameterSymbol> .Empty;
                    this.Properties = ImmutableArray <AnonymousTypePropertySymbol> .Empty;
                }

                // Add a constructor
                members[memberIndex++] = new AnonymousTypeConstructorSymbol(this, this.Properties);
                _members = members.AsImmutable();

                Debug.Assert(memberIndex == _members.Length);

                // fill nameToSymbols map
                foreach (var symbol in _members)
                {
                    _nameToSymbols.Add(symbol.Name, symbol);
                }

                // special members: Equals, GetHashCode, ToString
                MethodSymbol[] specialMembers = new MethodSymbol[3];
                specialMembers[0]   = new AnonymousTypeEqualsMethodSymbol(this);
                specialMembers[1]   = new AnonymousTypeGetHashCodeMethodSymbol(this);
                specialMembers[2]   = new AnonymousTypeToStringMethodSymbol(this);
                this.SpecialMembers = specialMembers.AsImmutable();
            }
コード例 #19
0
ファイル: TypeUnification.cs プロジェクト: stark-lang/stark
        /// <summary>
        /// Determine whether there is any substitution of type parameters that will
        /// make two types identical.
        /// </summary>
        /// <param name="t1">LHS</param>
        /// <param name="t2">RHS</param>
        /// <param name="substitution">
        /// Substitutions performed so far (or null for none).
        /// Keys are type parameters, values are types (possibly type parameters).
        /// Will be updated with new substitutions by the callee.
        /// Should be ignored when false is returned.
        /// </param>
        /// <returns>True if there exists a type map such that Map(LHS) == Map(RHS).</returns>
        /// <remarks>
        /// Derived from Dev10's BSYMMGR::UnifyTypes.
        /// Two types will not unify if they have different custom modifiers.
        /// </remarks>
        private static bool CanUnifyHelper(TypeSymbolWithAnnotations t1, TypeSymbolWithAnnotations t2, ref MutableTypeMap substitution)
        {
            if (t1.IsNull || t2.IsNull)
            {
                return(t1.IsSameAs(t2));
            }

            if (TypeSymbol.Equals(t1.TypeSymbol, t2.TypeSymbol, TypeCompareKind.ConsiderEverything2) && t1.CustomModifiers.SequenceEqual(t2.CustomModifiers))
            {
                return(true);
            }

            if (substitution != null)
            {
                t1 = t1.SubstituteType(substitution);
                t2 = t2.SubstituteType(substitution);
            }

            // If one of the types is a type parameter, then the substitution could make them equal.
            if (TypeSymbol.Equals(t1.TypeSymbol, t2.TypeSymbol, TypeCompareKind.ConsiderEverything2) && t1.CustomModifiers.SequenceEqual(t2.CustomModifiers))
            {
                return(true);
            }

            // We can avoid a lot of redundant checks if we ensure that we only have to check
            // for type parameters on the LHS
            if (!t1.TypeSymbol.IsTypeParameter() && t2.TypeSymbol.IsTypeParameter())
            {
                TypeSymbolWithAnnotations tmp = t1;
                t1 = t2;
                t2 = tmp;
            }

            // If t1 is not a type parameter, then neither is t2
            Debug.Assert(t1.TypeSymbol.IsTypeParameter() || !t2.TypeSymbol.IsTypeParameter());

            switch (t1.Kind)
            {
            case SymbolKind.ArrayType:
            {
                if (t2.TypeKind != t1.TypeKind || !t2.CustomModifiers.SequenceEqual(t1.CustomModifiers))
                {
                    return(false);
                }

                ArrayTypeSymbol at1 = (ArrayTypeSymbol)t1.TypeSymbol;
                ArrayTypeSymbol at2 = (ArrayTypeSymbol)t2.TypeSymbol;

                return(CanUnifyHelper(at1.ElementType, at2.ElementType, ref substitution));
            }

            case SymbolKind.PointerType:
            {
                if (t2.TypeKind != t1.TypeKind || !t2.CustomModifiers.SequenceEqual(t1.CustomModifiers))
                {
                    return(false);
                }

                PointerTypeSymbol pt1 = (PointerTypeSymbol)t1.TypeSymbol;
                PointerTypeSymbol pt2 = (PointerTypeSymbol)t2.TypeSymbol;

                return(CanUnifyHelper(pt1.PointedAtType, pt2.PointedAtType, ref substitution));
            }

            case SymbolKind.NamedType:
            case SymbolKind.ErrorType:
            {
                if (t2.TypeKind != t1.TypeKind || !t2.CustomModifiers.SequenceEqual(t1.CustomModifiers))
                {
                    return(false);
                }

                NamedTypeSymbol nt1 = (NamedTypeSymbol)t1.TypeSymbol;
                NamedTypeSymbol nt2 = (NamedTypeSymbol)t2.TypeSymbol;

                if (nt1.IsTupleType)
                {
                    if (!nt2.IsTupleType)
                    {
                        return(false);
                    }

                    return(CanUnifyHelper(nt1.TupleUnderlyingType, nt2.TupleUnderlyingType, ref substitution));
                }

                if (!nt1.IsGenericType)
                {
                    return(!nt2.IsGenericType && TypeSymbol.Equals(nt1, nt2, TypeCompareKind.ConsiderEverything2));
                }
                else if (!nt2.IsGenericType)
                {
                    return(false);
                }

                int arity = nt1.Arity;

                if (nt2.Arity != arity || !TypeSymbol.Equals(nt2.OriginalDefinition, nt1.OriginalDefinition, TypeCompareKind.ConsiderEverything2))
                {
                    return(false);
                }

                var nt1Arguments = nt1.TypeArgumentsNoUseSiteDiagnostics;
                var nt2Arguments = nt2.TypeArgumentsNoUseSiteDiagnostics;

                for (int i = 0; i < arity; i++)
                {
                    if (!CanUnifyHelper(nt1Arguments[i],
                                        nt2Arguments[i],
                                        ref substitution))
                    {
                        return(false);
                    }
                }

                // Note: Dev10 folds this into the loop since GetTypeArgsAll includes type args for containing types
                // TODO: Calling CanUnifyHelper for the containing type is an overkill, we simply need to go through type arguments for all containers.
                return((object)nt1.ContainingType == null || CanUnifyHelper(nt1.ContainingType, nt2.ContainingType, ref substitution));
            }

            case SymbolKind.TypeParameter:
            {
                // These substitutions are not allowed in C#
                if (t2.TypeKind == TypeKind.Pointer || t2.SpecialType == SpecialType.System_Void)
                {
                    return(false);
                }

                TypeParameterSymbol tp1 = (TypeParameterSymbol)t1.TypeSymbol;

                // Perform the "occurs check" - i.e. ensure that t2 doesn't contain t1 to avoid recursive types
                // Note: t2 can't be the same type param - we would have caught that with ReferenceEquals above
                if (Contains(t2.TypeSymbol, tp1))
                {
                    return(false);
                }

                if (t1.CustomModifiers.IsDefaultOrEmpty)
                {
                    AddSubstitution(ref substitution, tp1, t2);
                    return(true);
                }

                if (t1.CustomModifiers.SequenceEqual(t2.CustomModifiers))
                {
                    AddSubstitution(ref substitution, tp1, TypeSymbolWithAnnotations.Create(t2.TypeSymbol));
                    return(true);
                }

                if (t1.CustomModifiers.Length < t2.CustomModifiers.Length &&
                    t1.CustomModifiers.SequenceEqual(t2.CustomModifiers.Take(t1.CustomModifiers.Length)))
                {
                    AddSubstitution(ref substitution, tp1,
                                    TypeSymbolWithAnnotations.Create(t2.TypeSymbol,
                                                                     customModifiers: ImmutableArray.Create(t2.CustomModifiers, t1.CustomModifiers.Length, t2.CustomModifiers.Length - t1.CustomModifiers.Length)));
                    return(true);
                }

                if (t2.TypeSymbol.IsTypeParameter())
                {
                    var tp2 = (TypeParameterSymbol)t2.TypeSymbol;

                    if (t2.CustomModifiers.IsDefaultOrEmpty)
                    {
                        AddSubstitution(ref substitution, tp2, t1);
                        return(true);
                    }

                    if (t2.CustomModifiers.Length < t1.CustomModifiers.Length &&
                        t2.CustomModifiers.SequenceEqual(t1.CustomModifiers.Take(t2.CustomModifiers.Length)))
                    {
                        AddSubstitution(ref substitution, tp2,
                                        TypeSymbolWithAnnotations.Create(t1.TypeSymbol,
                                                                         customModifiers: ImmutableArray.Create(t1.CustomModifiers, t2.CustomModifiers.Length, t1.CustomModifiers.Length - t2.CustomModifiers.Length)));
                        return(true);
                    }
                }

                return(false);
            }

            default:
            {
                return(false);
            }
            }
        }
コード例 #20
0
ファイル: SymbolFactory.cs プロジェクト: zuckerthoben/roslyn
 private static TypeSymbolWithAnnotations CreateType(TypeSymbol type, ImmutableArray <ModifierInfo <TypeSymbol> > customModifiers)
 {
     // NonNullTypesContext is unset because the actual context will
     // be set when these types are transformed by the caller.
     return(TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, type, customModifiers: CSharpCustomModifier.Convert(customModifiers)));
 }
コード例 #21
0
        /// <summary>
        /// For cases where the RHS of a deconstruction-declaration is a tuple literal, we merge type information from both the LHS and RHS.
        /// For cases where the RHS of a deconstruction-assignment is a tuple literal, the type information from the LHS determines the merged type, since all variables have a type.
        /// Returns null if a merged tuple type could not be fabricated.
        /// </summary>
        private static TypeSymbol MakeMergedTupleType(ArrayBuilder <DeconstructionVariable> lhsVariables, BoundTupleLiteral rhsLiteral, CSharpSyntaxNode syntax, CSharpCompilation compilation, DiagnosticBag diagnostics)
        {
            int leftLength  = lhsVariables.Count;
            int rightLength = rhsLiteral.Arguments.Length;

            var typesBuilder = ArrayBuilder <TypeSymbolWithAnnotations> .GetInstance(leftLength);

            var locationsBuilder = ArrayBuilder <Location> .GetInstance(leftLength);

            for (int i = 0; i < rightLength; i++)
            {
                BoundExpression element    = rhsLiteral.Arguments[i];
                TypeSymbol      mergedType = element.Type;

                if (i < leftLength)
                {
                    var variable = lhsVariables[i];
                    if (variable.HasNestedVariables)
                    {
                        if (element.Kind == BoundKind.TupleLiteral)
                        {
                            // (variables) on the left and (elements) on the right
                            mergedType = MakeMergedTupleType(variable.NestedVariables, (BoundTupleLiteral)element, syntax, compilation, diagnostics);
                        }
                        else if ((object)mergedType == null)
                        {
                            // (variables) on the left and null on the right
                            Error(diagnostics, ErrorCode.ERR_DeconstructRequiresExpression, element.Syntax);
                        }
                    }
                    else
                    {
                        if ((object)variable.Single.Type != null)
                        {
                            // typed-variable on the left
                            mergedType = variable.Single.Type;
                        }
                    }
                }
                else
                {
                    if ((object)mergedType == null)
                    {
                        // a typeless element on the right, matching no variable on the left
                        Error(diagnostics, ErrorCode.ERR_DeconstructRequiresExpression, element.Syntax);
                    }
                }

                typesBuilder.Add(TypeSymbolWithAnnotations.Create(mergedType));
                locationsBuilder.Add(element.Syntax.Location);
            }

            if (typesBuilder.Any(t => !t.HasType))
            {
                typesBuilder.Free();
                locationsBuilder.Free();
                return(null);
            }

            // The tuple created here is not identical to the one created by
            // DeconstructionVariablesAsTuple. It represents a smaller
            // tree of types used for figuring out natural types in tuple literal.
            return(TupleTypeSymbol.Create(
                       locationOpt: null,
                       elementTypes: typesBuilder.ToImmutableAndFree(),
                       elementLocations: locationsBuilder.ToImmutableAndFree(),
                       elementNames: default(ImmutableArray <string>),
                       compilation: compilation,
                       diagnostics: diagnostics,
                       shouldCheckConstraints: true,
                       includeNullability: false,
                       errorPositions: default(ImmutableArray <bool>),
                       syntax: syntax));
        }
コード例 #22
0
        /// <summary>
        /// Generate a thread-safe accessor for a regular field-like event.
        ///
        /// DelegateType tmp0 = _event; //backing field
        /// DelegateType tmp1;
        /// DelegateType tmp2;
        /// do {
        ///     tmp1 = tmp0;
        ///     tmp2 = (DelegateType)Delegate.Combine(tmp1, value); //Remove for -=
        ///     tmp0 = Interlocked.CompareExchange&lt;DelegateType&gt;(ref _event, tmp2, tmp1);
        /// } while ((object)tmp0 != (object)tmp1);
        ///
        /// Note, if System.Threading.Interlocked.CompareExchange&lt;T&gt; is not available,
        /// we emit the following code and mark the method Synchronized (unless it is a struct).
        ///
        /// _event = (DelegateType)Delegate.Combine(_event, value); //Remove for -=
        ///
        /// </summary>
        internal static BoundBlock ConstructFieldLikeEventAccessorBody_Regular(SourceEventSymbol eventSymbol, bool isAddMethod, CSharpCompilation compilation, DiagnosticBag diagnostics)
        {
            CSharpSyntaxNode syntax = eventSymbol.CSharpSyntaxNode;

            TypeSymbol      delegateType  = eventSymbol.Type.TypeSymbol;
            MethodSymbol    accessor      = isAddMethod ? eventSymbol.AddMethod : eventSymbol.RemoveMethod;
            ParameterSymbol thisParameter = accessor.ThisParameter;

            TypeSymbol boolType = compilation.GetSpecialType(SpecialType.System_Boolean);

            SpecialMember updateMethodId = isAddMethod ? SpecialMember.System_Delegate__Combine : SpecialMember.System_Delegate__Remove;
            MethodSymbol  updateMethod   = (MethodSymbol)compilation.GetSpecialTypeMember(updateMethodId);

            BoundStatement @return = new BoundReturnStatement(syntax,
                                                              refKind: RefKind.None,
                                                              expressionOpt: null)
            {
                WasCompilerGenerated = true
            };

            if (updateMethod == null)
            {
                MemberDescriptor memberDescriptor = SpecialMembers.GetDescriptor(updateMethodId);
                diagnostics.Add(new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_MissingPredefinedMember,
                                                                      memberDescriptor.DeclaringTypeMetadataName,
                                                                      memberDescriptor.Name),
                                                 syntax.Location));

                return(BoundBlock.SynthesizedNoLocals(syntax, @return));
            }

            Binder.ReportUseSiteDiagnostics(updateMethod, diagnostics, syntax);

            BoundThisReference fieldReceiver = eventSymbol.IsStatic ?
                                               null :
                                               new BoundThisReference(syntax, thisParameter.Type.TypeSymbol)
            {
                WasCompilerGenerated = true
            };

            BoundFieldAccess boundBackingField = new BoundFieldAccess(syntax,
                                                                      receiver: fieldReceiver,
                                                                      fieldSymbol: eventSymbol.AssociatedField,
                                                                      constantValueOpt: null)
            {
                WasCompilerGenerated = true
            };

            BoundParameter boundParameter = new BoundParameter(syntax,
                                                               parameterSymbol: accessor.Parameters[0])
            {
                WasCompilerGenerated = true
            };

            BoundExpression delegateUpdate;

            MethodSymbol compareExchangeMethod = (MethodSymbol)compilation.GetWellKnownTypeMember(WellKnownMember.System_Threading_Interlocked__CompareExchange_T);

            if ((object)compareExchangeMethod == null)
            {
                // (DelegateType)Delegate.Combine(_event, value)
                delegateUpdate = BoundConversion.SynthesizedNonUserDefined(syntax,
                                                                           operand: BoundCall.Synthesized(syntax,
                                                                                                          receiverOpt: null,
                                                                                                          method: updateMethod,
                                                                                                          arguments: ImmutableArray.Create <BoundExpression>(boundBackingField, boundParameter)),
                                                                           conversion: Conversion.ExplicitReference,
                                                                           type: delegateType);

                // _event = (DelegateType)Delegate.Combine(_event, value);
                BoundStatement eventUpdate = new BoundExpressionStatement(syntax,
                                                                          expression: new BoundAssignmentOperator(syntax,
                                                                                                                  left: boundBackingField,
                                                                                                                  right: delegateUpdate,
                                                                                                                  type: delegateType)
                {
                    WasCompilerGenerated = true
                })
                {
                    WasCompilerGenerated = true
                };

                return(BoundBlock.SynthesizedNoLocals(syntax,
                                                      statements: ImmutableArray.Create <BoundStatement>(
                                                          eventUpdate,
                                                          @return)));
            }

            compareExchangeMethod = compareExchangeMethod.Construct(ImmutableArray.Create <TypeSymbol>(delegateType));

            Binder.ReportUseSiteDiagnostics(compareExchangeMethod, diagnostics, syntax);

            GeneratedLabelSymbol loopLabel = new GeneratedLabelSymbol("loop");

            const int numTemps = 3;

            LocalSymbol[] tmps      = new LocalSymbol[numTemps];
            BoundLocal[]  boundTmps = new BoundLocal[numTemps];

            for (int i = 0; i < numTemps; i++)
            {
                tmps[i]      = new SynthesizedLocal(accessor, TypeSymbolWithAnnotations.Create(delegateType), SynthesizedLocalKind.LoweringTemp);
                boundTmps[i] = new BoundLocal(syntax, tmps[i], null, delegateType);
            }

            // tmp0 = _event;
            BoundStatement tmp0Init = new BoundExpressionStatement(syntax,
                                                                   expression: new BoundAssignmentOperator(syntax,
                                                                                                           left: boundTmps[0],
                                                                                                           right: boundBackingField,
                                                                                                           type: delegateType)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            };

            // LOOP:
            BoundStatement loopStart = new BoundLabelStatement(syntax,
                                                               label: loopLabel)
            {
                WasCompilerGenerated = true
            };

            // tmp1 = tmp0;
            BoundStatement tmp1Update = new BoundExpressionStatement(syntax,
                                                                     expression: new BoundAssignmentOperator(syntax,
                                                                                                             left: boundTmps[1],
                                                                                                             right: boundTmps[0],
                                                                                                             type: delegateType)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            };

            // (DelegateType)Delegate.Combine(tmp1, value)
            delegateUpdate = BoundConversion.SynthesizedNonUserDefined(syntax,
                                                                       operand: BoundCall.Synthesized(syntax,
                                                                                                      receiverOpt: null,
                                                                                                      method: updateMethod,
                                                                                                      arguments: ImmutableArray.Create <BoundExpression>(boundTmps[1], boundParameter)),
                                                                       conversion: Conversion.ExplicitReference,
                                                                       type: delegateType);

            // tmp2 = (DelegateType)Delegate.Combine(tmp1, value);
            BoundStatement tmp2Update = new BoundExpressionStatement(syntax,
                                                                     expression: new BoundAssignmentOperator(syntax,
                                                                                                             left: boundTmps[2],
                                                                                                             right: delegateUpdate,
                                                                                                             type: delegateType)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            };

            // Interlocked.CompareExchange<DelegateType>(ref _event, tmp2, tmp1)
            BoundExpression compareExchange = BoundCall.Synthesized(syntax,
                                                                    receiverOpt: null,
                                                                    method: compareExchangeMethod,
                                                                    arguments: ImmutableArray.Create <BoundExpression>(boundBackingField, boundTmps[2], boundTmps[1]));

            // tmp0 = Interlocked.CompareExchange<DelegateType>(ref _event, tmp2, tmp1);
            BoundStatement tmp0Update = new BoundExpressionStatement(syntax,
                                                                     expression: new BoundAssignmentOperator(syntax,
                                                                                                             left: boundTmps[0],
                                                                                                             right: compareExchange,
                                                                                                             type: delegateType)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            };

            // tmp0 == tmp1 // i.e. exit when they are equal, jump to start otherwise
            BoundExpression loopExitCondition = new BoundBinaryOperator(syntax,
                                                                        operatorKind: BinaryOperatorKind.ObjectEqual,
                                                                        left: boundTmps[0],
                                                                        right: boundTmps[1],
                                                                        constantValueOpt: null,
                                                                        methodOpt: null,
                                                                        resultKind: LookupResultKind.Viable,
                                                                        type: boolType)
            {
                WasCompilerGenerated = true
            };

            // branchfalse (tmp0 == tmp1) LOOP
            BoundStatement loopEnd = new BoundConditionalGoto(syntax,
                                                              condition: loopExitCondition,
                                                              jumpIfTrue: false,
                                                              label: loopLabel)
            {
                WasCompilerGenerated = true
            };

            return(new BoundBlock(syntax,
                                  locals: tmps.AsImmutable(),
                                  statements: ImmutableArray.Create <BoundStatement>(
                                      tmp0Init,
                                      loopStart,
                                      tmp1Update,
                                      tmp2Update,
                                      tmp0Update,
                                      loopEnd,
                                      @return))
            {
                WasCompilerGenerated = true
            });
        }
コード例 #23
0
ファイル: AssemblySymbol.cs プロジェクト: stark-lang/stark
        /// <summary>
        /// Resolves <see cref="System.Type"/> to a <see cref="TypeSymbol"/> available in this assembly
        /// its referenced assemblies.
        /// </summary>
        /// <param name="type">The type to resolve.</param>
        /// <param name="includeReferences">Use referenced assemblies for resolution.</param>
        /// <returns>The resolved symbol if successful or null on failure.</returns>
        internal TypeSymbol GetTypeByReflectionType(Type type, bool includeReferences)
        {
            System.Reflection.TypeInfo typeInfo = type.GetTypeInfo();

            Debug.Assert(!typeInfo.IsByRef);

            // not supported (we don't accept open types as submission results nor host types):
            Debug.Assert(!typeInfo.ContainsGenericParameters);

            if (typeInfo.IsArray)
            {
                TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences);
                if ((object)symbol == null)
                {
                    return(null);
                }

                int rank = typeInfo.GetArrayRank();
                if (rank != 1)
                {
                    throw new NotSupportedException($"An array of rank {rank} is not supported in stark via reflection");
                }

                return(ArrayTypeSymbol.CreateArray(this, TypeSymbolWithAnnotations.Create(symbol)));
            }
            else if (typeInfo.IsPointer)
            {
                TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences);
                if ((object)symbol == null)
                {
                    return(null);
                }

                return(new PointerTypeSymbol(TypeSymbolWithAnnotations.Create(symbol)));
            }
            else if (typeInfo.DeclaringType != null)
            {
                Debug.Assert(!typeInfo.IsArray);

                // consolidated generic arguments (includes arguments of all declaring types):
                Type[] genericArguments  = typeInfo.GenericTypeArguments;
                int    typeArgumentIndex = 0;

                var currentTypeInfo = typeInfo.IsGenericType ? typeInfo.GetGenericTypeDefinition().GetTypeInfo() : typeInfo;
                var nestedTypes     = ArrayBuilder <System.Reflection.TypeInfo> .GetInstance();

                while (true)
                {
                    Debug.Assert(currentTypeInfo.IsGenericTypeDefinition || !currentTypeInfo.IsGenericType);

                    nestedTypes.Add(currentTypeInfo);
                    if (currentTypeInfo.DeclaringType == null)
                    {
                        break;
                    }

                    currentTypeInfo = currentTypeInfo.DeclaringType.GetTypeInfo();
                }

                int i      = nestedTypes.Count - 1;
                var symbol = (NamedTypeSymbol)GetTypeByReflectionType(nestedTypes[i].AsType(), includeReferences);
                if ((object)symbol == null)
                {
                    return(null);
                }

                while (--i >= 0)
                {
                    int forcedArity         = nestedTypes[i].GenericTypeParameters.Length - nestedTypes[i + 1].GenericTypeParameters.Length;
                    MetadataTypeName mdName = MetadataTypeName.FromTypeName(nestedTypes[i].Name, forcedArity: forcedArity);

                    symbol = symbol.LookupMetadataType(ref mdName);
                    if ((object)symbol == null || symbol.IsErrorType())
                    {
                        return(null);
                    }

                    symbol = ApplyGenericArguments(symbol, genericArguments, ref typeArgumentIndex, includeReferences);
                    if ((object)symbol == null)
                    {
                        return(null);
                    }
                }

                nestedTypes.Free();
                Debug.Assert(typeArgumentIndex == genericArguments.Length);
                return(symbol);
            }
            else
            {
                AssemblyIdentity assemblyId = AssemblyIdentity.FromAssemblyDefinition(typeInfo.Assembly);

                MetadataTypeName mdName = MetadataTypeName.FromNamespaceAndTypeName(
                    typeInfo.Namespace ?? string.Empty,
                    typeInfo.Name,
                    forcedArity: typeInfo.GenericTypeArguments.Length);

                NamedTypeSymbol symbol = GetTopLevelTypeByMetadataName(ref mdName, assemblyId, includeReferences, isWellKnownType: false, conflicts: out var _);

                if ((object)symbol == null || symbol.IsErrorType())
                {
                    return(null);
                }

                int    typeArgumentIndex = 0;
                Type[] genericArguments  = typeInfo.GenericTypeArguments;
                symbol = ApplyGenericArguments(symbol, genericArguments, ref typeArgumentIndex, includeReferences);
                Debug.Assert(typeArgumentIndex == genericArguments.Length);
                return(symbol);
            }
        }
コード例 #24
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(TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_DynamicAttribute__ctor));
            }
            else
            {
                NamedTypeSymbol booleanType = GetSpecialType(SpecialType.System_Boolean);
                Debug.Assert((object)booleanType != null);
                var transformFlags = DynamicTransformsEncoder.Encode(type, refKindOpt, customModifiersCount, booleanType);
                var boolArray      = ArrayTypeSymbol.CreateSZArray(booleanType.ContainingAssembly, TypeSymbolWithAnnotations.Create(booleanType));
                var arguments      = ImmutableArray.Create <TypedConstant>(new TypedConstant(boolArray, transformFlags));
                return(TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_DynamicAttribute__ctorTransformFlags, arguments));
            }
        }
コード例 #25
0
        private ImmutableArray <TypeSymbolWithAnnotations> GetDeclaredConstraintTypes()
        {
            if (_lazyDeclaredConstraintTypes.IsDefault)
            {
                ImmutableArray <TypeSymbolWithAnnotations> 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;
                var metadataReader = moduleSymbol.Module.MetadataReader;
                GenericParameterConstraintHandleCollection constraints;

                try
                {
                    constraints = metadataReader.GetGenericParameter(_handle).GetConstraints();
                }
                catch (BadImageFormatException)
                {
                    constraints = default(GenericParameterConstraintHandleCollection);
                    Interlocked.CompareExchange(ref _lazyConstraintsUseSiteErrorInfo, new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this), CSDiagnosticInfo.EmptyErrorInfo);
                }

                bool hasUnmanagedModreqPattern = false;

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

                    MetadataDecoder tokenDecoder;

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

                    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 = TypeSymbolWithAnnotations.Create(typeSymbol);
                        type = NullableTypeDecoder.TransformType(type, constraintHandle, moduleSymbol);

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

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

                        symbolsBuilder.Add(type);
                    }

                    declaredConstraintTypes = symbolsBuilder.ToImmutableAndFree();
                }
                else
                {
                    declaredConstraintTypes = ImmutableArray <TypeSymbolWithAnnotations> .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 != moduleSymbol.Module.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);
        }
コード例 #26
0
        internal SynthesizedAttributeData SynthesizeTupleNamesAttribute(TypeSymbol type)
        {
            Debug.Assert((object)type != null);
            Debug.Assert(type.ContainsTuple());

            var stringType = GetSpecialType(SpecialType.System_String);

            Debug.Assert((object)stringType != null);
            var names = TupleNamesEncoder.Encode(type, stringType);

            Debug.Assert(!names.IsDefault, "should not need the attribute when no tuple names");

            var stringArray = ArrayTypeSymbol.CreateSZArray(stringType.ContainingAssembly, TypeSymbolWithAnnotations.Create(stringType));
            var args        = ImmutableArray.Create(new TypedConstant(stringArray, names));

            return(TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_TupleElementNamesAttribute__ctorTransformNames, args));
        }
コード例 #27
0
        public override BoundNode VisitTryStatement(BoundTryStatement node)
        {
            var tryStatementSyntax = node.Syntax;

            // If you add a syntax kind to the assertion below, please also ensure
            // that the scenario has been tested with Edit-and-Continue.
            Debug.Assert(
                tryStatementSyntax.IsKind(SyntaxKind.TryStatement) ||
                tryStatementSyntax.IsKind(SyntaxKind.UsingStatement) ||
                tryStatementSyntax.IsKind(SyntaxKind.ForEachStatement) ||
                tryStatementSyntax.IsKind(SyntaxKind.ForEachVariableStatement));

            BoundStatement finalizedRegion;
            BoundBlock     rewrittenFinally;

            var finallyContainsAwaits = _analysis.FinallyContainsAwaits(node);

            if (!finallyContainsAwaits)
            {
                finalizedRegion  = RewriteFinalizedRegion(node);
                rewrittenFinally = (BoundBlock)this.Visit(node.FinallyBlockOpt);

                if (rewrittenFinally == null)
                {
                    return(finalizedRegion);
                }

                var asTry = finalizedRegion as BoundTryStatement;
                if (asTry != null)
                {
                    // since finalized region is a try we can just attach finally to it
                    Debug.Assert(asTry.FinallyBlockOpt == null);
                    return(asTry.Update(asTry.TryBlock, asTry.CatchBlocks, rewrittenFinally, asTry.PreferFaultHandler));
                }
                else
                {
                    // wrap finalizedRegion into a Try with a finally.
                    return(_F.Try((BoundBlock)finalizedRegion, ImmutableArray <BoundCatchBlock> .Empty, rewrittenFinally));
                }
            }

            // rewrite finalized region (try and catches) in the current frame
            var frame = PushFrame(node);

            finalizedRegion  = RewriteFinalizedRegion(node);
            rewrittenFinally = (BoundBlock)this.VisitBlock(node.FinallyBlockOpt);
            PopFrame();

            var exceptionType         = _F.SpecialType(SpecialType.System_Object);
            var pendingExceptionLocal = new SynthesizedLocal(_F.CurrentFunction, TypeSymbolWithAnnotations.Create(exceptionType), SynthesizedLocalKind.TryAwaitPendingException, tryStatementSyntax);
            var finallyLabel          = _F.GenerateLabel("finallyLabel");
            var pendingBranchVar      = new SynthesizedLocal(_F.CurrentFunction, TypeSymbolWithAnnotations.Create(_F.SpecialType(SpecialType.System_Int32)), SynthesizedLocalKind.TryAwaitPendingBranch, tryStatementSyntax);

            var catchAll = _F.Catch(_F.Local(pendingExceptionLocal), _F.Block());

            var catchAndPendException = _F.Try(
                _F.Block(
                    finalizedRegion,
                    _F.HiddenSequencePoint(),
                    _F.Goto(finallyLabel),
                    PendBranches(frame, pendingBranchVar, finallyLabel)),
                ImmutableArray.Create(catchAll));

            var syntheticFinally = _F.Block(
                _F.HiddenSequencePoint(),
                _F.Label(finallyLabel),
                rewrittenFinally,
                _F.HiddenSequencePoint(),
                UnpendException(pendingExceptionLocal),
                UnpendBranches(
                    frame,
                    pendingBranchVar,
                    pendingExceptionLocal));


            var locals = ArrayBuilder <LocalSymbol> .GetInstance();

            var statements = ArrayBuilder <BoundStatement> .GetInstance();

            statements.Add(_F.HiddenSequencePoint());

            locals.Add(pendingExceptionLocal);
            statements.Add(_F.Assignment(_F.Local(pendingExceptionLocal), _F.Default(pendingExceptionLocal.Type.TypeSymbol)));
            locals.Add(pendingBranchVar);
            statements.Add(_F.Assignment(_F.Local(pendingBranchVar), _F.Default(pendingBranchVar.Type.TypeSymbol)));

            LocalSymbol returnLocal = frame.returnValue;

            if (returnLocal != null)
            {
                locals.Add(returnLocal);
            }

            statements.Add(catchAndPendException);
            statements.Add(syntheticFinally);

            var completeTry = _F.Block(
                locals.ToImmutableAndFree(),
                statements.ToImmutableAndFree());

            return(completeTry);
        }
コード例 #28
0
ファイル: SymbolFactory.cs プロジェクト: zhouweiaccp/roslyn
 private static TypeSymbolWithAnnotations CreateType(TypeSymbol type, ImmutableArray <ModifierInfo <TypeSymbol> > customModifiers)
 {
     // The actual annotation will be set when these types are transformed by the caller.
     return(TypeSymbolWithAnnotations.Create(type, NullableAnnotation.Oblivious, CSharpCustomModifier.Convert(customModifiers)));
 }
コード例 #29
0
        internal override MethodSymbol ConstructMethod(MethodSymbol method, ImmutableArray <TypeParameterSymbol> typeParameters, ImmutableArray <TypeSymbol> typeArguments)
        {
            var methodArity = method.Arity;
            var methodArgumentStartIndex = typeParameters.Length - methodArity;
            var typeMap = new TypeMap(
                ImmutableArray.Create(typeParameters, 0, methodArgumentStartIndex),
                ImmutableArray.CreateRange(typeArguments, 0, methodArgumentStartIndex, t => TypeSymbolWithAnnotations.Create(t)));
            var substitutedType = typeMap.SubstituteNamedType(method.ContainingType);

            method = method.AsMember(substitutedType);
            if (methodArity > 0)
            {
                method = method.Construct(ImmutableArray.Create(typeArguments, methodArgumentStartIndex, methodArity));
            }
            return(method);
        }
コード例 #30
0
ファイル: PEParameterSymbol.cs プロジェクト: skynode/roslyn
        private PEParameterSymbol(
            PEModuleSymbol moduleSymbol,
            Symbol containingSymbol,
            int ordinal,
            bool isByRef,
            TypeSymbolWithAnnotations type,
            ImmutableArray <bool> 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)
                {
                    // https://github.com/dotnet/roslyn/issues/29821 any external annotation is taken to imply a `[NonNullTypes(true)]` context
                    type = NullableTypeDecoder.TransformType(type, extraAnnotations, nonNullTypesContext: NonNullTypesTrueContext.Instance);
                }

                _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, nonNullTypesContext: this, 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);
        }