Ejemplo n.º 1
0
        internal SourceCustomEventSymbol(SourceMemberContainerTypeSymbol containingType, Binder binder, EventDeclarationSyntax syntax, DiagnosticBag diagnostics) :
            base(containingType, syntax, syntax.Modifiers, isFieldLike: false,
                 interfaceSpecifierSyntaxOpt: syntax.ExplicitInterfaceSpecifier,
                 nameTokenSyntax: syntax.Identifier, diagnostics: diagnostics)
        {
            ExplicitInterfaceSpecifierSyntax?interfaceSpecifier = syntax.ExplicitInterfaceSpecifier;
            SyntaxToken nameToken = syntax.Identifier;
            bool        isExplicitInterfaceImplementation = interfaceSpecifier != null;

            string?aliasQualifierOpt;

            _name = ExplicitInterfaceHelpers.GetMemberNameAndInterfaceSymbol(binder, interfaceSpecifier, nameToken.ValueText, diagnostics, out _explicitInterfaceType, out aliasQualifierOpt);

            _type = BindEventType(binder, syntax.Type, diagnostics);

            var explicitlyImplementedEvent = this.FindExplicitlyImplementedEvent(_explicitInterfaceType, nameToken.ValueText, interfaceSpecifier, diagnostics);

            this.FindExplicitlyImplementedMemberVerification(explicitlyImplementedEvent, diagnostics);

            // The runtime will not treat the accessors of this event as overrides or implementations
            // of those of another event unless both the signatures and the custom modifiers match.
            // Hence, in the case of overrides and *explicit* implementations, we need to copy the custom
            // modifiers that are in the signatures of the overridden/implemented event accessors.
            // (From source, we know that there can only be one overridden/implemented event, so there
            // are no conflicts.)  This is unnecessary for implicit implementations because, if the custom
            // modifiers don't match, we'll insert bridge methods for the accessors (explicit implementations
            // that delegate to the implicit implementations) with the correct custom modifiers
            // (see SourceMemberContainerTypeSymbol.SynthesizeInterfaceMemberImplementation).

            // Note: we're checking if the syntax indicates explicit implementation rather,
            // than if explicitInterfaceType is null because we don't want to look for an
            // overridden event if this is supposed to be an explicit implementation.
            if (!isExplicitInterfaceImplementation)
            {
                // If this event is an override, we may need to copy custom modifiers from
                // the overridden event (so that the runtime will recognize it as an override).
                // We check for this case here, while we can still modify the parameters and
                // return type without losing the appearance of immutability.
                if (this.IsOverride)
                {
                    EventSymbol?overriddenEvent = this.OverriddenEvent;
                    if ((object?)overriddenEvent != null)
                    {
                        CopyEventCustomModifiers(overriddenEvent, ref _type, ContainingAssembly);
                    }
                }
            }
            else if ((object)explicitlyImplementedEvent != null)
            {
                CopyEventCustomModifiers(explicitlyImplementedEvent, ref _type, ContainingAssembly);
            }

            AccessorDeclarationSyntax?addSyntax    = null;
            AccessorDeclarationSyntax?removeSyntax = null;

            if (syntax.AccessorList != null)
            {
                foreach (AccessorDeclarationSyntax accessor in syntax.AccessorList.Accessors)
                {
                    bool checkBody = false;

                    switch (accessor.Kind())
                    {
                    case SyntaxKind.AddAccessorDeclaration:
                        if (addSyntax == null)
                        {
                            addSyntax = accessor;
                            checkBody = true;
                        }
                        else
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateAccessor, accessor.Keyword.GetLocation());
                        }
                        break;

                    case SyntaxKind.RemoveAccessorDeclaration:
                        if (removeSyntax == null)
                        {
                            removeSyntax = accessor;
                            checkBody    = true;
                        }
                        else
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateAccessor, accessor.Keyword.GetLocation());
                        }
                        break;

                    case SyntaxKind.GetAccessorDeclaration:
                    case SyntaxKind.SetAccessorDeclaration:
                    case SyntaxKind.InitAccessorDeclaration:
                        diagnostics.Add(ErrorCode.ERR_AddOrRemoveExpected, accessor.Keyword.GetLocation());
                        break;

                    case SyntaxKind.UnknownAccessorDeclaration:
                        // Don't need to handle UnknownAccessorDeclaration.  An error will have
                        // already been produced for it in the parser.
                        break;

                    default:
                        throw ExceptionUtilities.UnexpectedValue(accessor.Kind());
                    }

                    if (checkBody && !IsAbstract && accessor.Body == null && accessor.ExpressionBody == null && accessor.SemicolonToken.Kind() == SyntaxKind.SemicolonToken)
                    {
                        diagnostics.Add(ErrorCode.ERR_AddRemoveMustHaveBody, accessor.SemicolonToken.GetLocation());
                    }
                }

                if (IsAbstract)
                {
                    if (!syntax.AccessorList.OpenBraceToken.IsMissing)
                    {
                        diagnostics.Add(ErrorCode.ERR_AbstractEventHasAccessors, syntax.AccessorList.OpenBraceToken.GetLocation(), this);
                    }
                }
                else if ((addSyntax == null || removeSyntax == null) && (!syntax.AccessorList.OpenBraceToken.IsMissing || !isExplicitInterfaceImplementation))
                {
                    diagnostics.Add(ErrorCode.ERR_EventNeedsBothAccessors, this.Locations[0], this);
                }
            }
            else if (isExplicitInterfaceImplementation && !IsAbstract)
            {
                diagnostics.Add(ErrorCode.ERR_ExplicitEventFieldImpl, this.Locations[0]);
            }

            if (isExplicitInterfaceImplementation && IsAbstract && syntax.AccessorList == null)
            {
                Debug.Assert(containingType.IsInterface);

                Binder.CheckFeatureAvailability(syntax, MessageID.IDS_DefaultInterfaceImplementation, diagnostics, this.Locations[0]);

                if (!ContainingAssembly.RuntimeSupportsDefaultInterfaceImplementation)
                {
                    diagnostics.Add(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, this.Locations[0]);
                }

                _addMethod    = new SynthesizedEventAccessorSymbol(this, isAdder: true, explicitlyImplementedEvent, aliasQualifierOpt);
                _removeMethod = new SynthesizedEventAccessorSymbol(this, isAdder: false, explicitlyImplementedEvent, aliasQualifierOpt);
            }
            else
            {
                _addMethod    = CreateAccessorSymbol(DeclaringCompilation, addSyntax, explicitlyImplementedEvent, aliasQualifierOpt, diagnostics);
                _removeMethod = CreateAccessorSymbol(DeclaringCompilation, removeSyntax, explicitlyImplementedEvent, aliasQualifierOpt, diagnostics);
            }

            _explicitInterfaceImplementations =
                (object?)explicitlyImplementedEvent == null ?
                ImmutableArray <EventSymbol> .Empty :
                ImmutableArray.Create <EventSymbol>(explicitlyImplementedEvent);
        }
Ejemplo n.º 2
0
 public DiscardSymbol(TypeWithAnnotations typeWithAnnotations)
 {
     Debug.Assert(typeWithAnnotations.Type is object);
     TypeWithAnnotations = typeWithAnnotations;
 }
Ejemplo n.º 3
0
 internal Boxed(TypeWithAnnotations value)
 {
     Value = value;
 }
Ejemplo n.º 4
0
        internal static void GetTypeOrReturnType(this Symbol symbol, out RefKind refKind, out TypeWithAnnotations returnType,
                                                 out ImmutableArray <CustomModifier> refCustomModifiers)
        {
            switch (symbol.Kind)
            {
            case SymbolKind.Field:
                FieldSymbol field = (FieldSymbol)symbol;
                refKind            = RefKind.None;
                returnType         = field.TypeWithAnnotations;
                refCustomModifiers = ImmutableArray <CustomModifier> .Empty;
                break;

            case SymbolKind.Method:
                MethodSymbol method = (MethodSymbol)symbol;
                refKind            = method.RefKind;
                returnType         = method.ReturnTypeWithAnnotations;
                refCustomModifiers = method.RefCustomModifiers;
                break;

            case SymbolKind.Property:
                PropertySymbol property = (PropertySymbol)symbol;
                refKind            = property.RefKind;
                returnType         = property.TypeWithAnnotations;
                refCustomModifiers = property.RefCustomModifiers;
                break;

            case SymbolKind.Event:
                EventSymbol @event = (EventSymbol)symbol;
                refKind            = RefKind.None;
                returnType         = @event.TypeWithAnnotations;
                refCustomModifiers = ImmutableArray <CustomModifier> .Empty;
                break;

            case SymbolKind.Local:
                LocalSymbol local = (LocalSymbol)symbol;
                refKind            = local.RefKind;
                returnType         = local.TypeWithAnnotations;
                refCustomModifiers = ImmutableArray <CustomModifier> .Empty;
                break;

            case SymbolKind.Parameter:
                ParameterSymbol parameter = (ParameterSymbol)symbol;
                refKind            = parameter.RefKind;
                returnType         = parameter.TypeWithAnnotations;
                refCustomModifiers = parameter.RefCustomModifiers;
                break;

            default:
                throw ExceptionUtilities.UnexpectedValue(symbol.Kind);
            }
        }
Ejemplo n.º 5
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>
        private static MethodSymbol InferExtensionMethodTypeArguments(MethodSymbol method, TypeSymbol thisType, 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);
            }

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

            if (typeArgs.Any(t => !t.HasType))
            {
                typeArgsForConstruct = typeArgs.ZipAsArray(
                    method.TypeParameters,
                    (t, tp) => t.HasType ? t : TypeWithAnnotations.Create(tp));
            }

            return(method.Construct(typeArgsForConstruct));
        }
 internal UpdatedContainingSymbolAndNullableAnnotationLocal(SourceLocalSymbol underlyingLocal, Symbol updatedContainingSymbol, TypeWithAnnotations updatedType)
     : this(underlyingLocal, updatedContainingSymbol, updatedType, assertContaining : true)
 {
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Called by <see cref="AbstractTypeMap.SubstituteType(TypeSymbol)"/> to perform substitution
 /// on types with TypeKind ErrorType.  The general pattern is to use the type map
 /// to perform substitution on the wrapped type, if any, and then construct a new
 /// error type symbol from the result (if there was a change).
 /// </summary>
 internal TypeWithAnnotations Substitute(AbstractTypeMap typeMap)
 {
     return(TypeWithAnnotations.Create(typeMap.SubstituteNamedType(this)));
 }
Ejemplo n.º 8
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>
        /// <param name="compilation">Compilation used to check constraints.  The latest language version is assumed if this is null.</param>
        private static MethodSymbol InferExtensionMethodTypeArguments(MethodSymbol method, TypeSymbol thisType, CSharpCompilation 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);
            }

            // 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.
            int firstNullInTypeArgs       = -1;
            var notInferredTypeParameters = PooledHashSet <TypeParameterSymbol> .GetInstance();

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

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

                    builder.AddRange(typeArgsForConstraintsCheck, firstNullInTypeArgs);

                    for (; i < typeArgsForConstraintsCheck.Length; i++)
                    {
                        var typeArg = typeArgsForConstraintsCheck[i];
                        if (!typeArg.HasType)
                        {
                            notInferredTypeParameters.Add(typeParams[i]);
                            builder.Add(TypeWithAnnotations.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, nullabilityDiagnosticsBuilderOpt: 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.
            ImmutableArray <TypeWithAnnotations> typeArgsForConstruct = typeArgs;

            if (typeArgs.Any(t => !t.HasType))
            {
                typeArgsForConstruct = typeArgs.ZipAsArray(
                    method.TypeParameters,
                    (t, tp) => t.HasType ? t : TypeWithAnnotations.Create(tp));
            }

            return(method.Construct(typeArgsForConstruct));
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Create a new PointerTypeSymbol.
        /// </summary>
        /// <param name="pointedAtType">The type being pointed at.</param>
        internal PointerTypeSymbol(TypeWithAnnotations pointedAtType)
        {
            Debug.Assert(pointedAtType.HasType);

            _pointedAtType = pointedAtType;
        }
            internal SubmissionEntryPoint(NamedTypeSymbol containingType, TypeWithAnnotations returnType, TypeSymbol submissionArrayType) :
                base(containingType)
            {
                Debug.Assert(containingType.IsSubmissionClass);
                Debug.Assert(!returnType.IsVoidType());
                _parameters = ImmutableArray.Create(SynthesizedParameterSymbol.Create(this,
                                                                                      TypeWithAnnotations.Create(submissionArrayType), 0, RefKind.None, "submissionArray"));

                _returnType = returnType;
            }
            internal override BoundBlock CreateBody(DiagnosticBag diagnostics)
            {
                var syntax = DummySyntax();

                var ctor = _containingType.GetScriptConstructor();

                Debug.Assert(ctor.ParameterCount == 1);

                var initializer = _containingType.GetScriptInitializer();

                Debug.Assert(initializer.ParameterCount == 0);

                var submissionArrayParameter = new BoundParameter(syntax, _parameters[0])
                {
                    WasCompilerGenerated = true
                };
                var submissionLocal = new BoundLocal(
                    syntax,
                    new SynthesizedLocal(this, TypeWithAnnotations.Create(_containingType), SynthesizedLocalKind.LoweringTemp),
                    null,
                    _containingType)
                {
                    WasCompilerGenerated = true
                };

                // var submission = new Submission#N(submissionArray);
                var submissionAssignment = new BoundExpressionStatement(
                    syntax,
                    new BoundAssignmentOperator(
                        syntax,
                        submissionLocal,
                        new BoundObjectCreationExpression(
                            syntax,
                            ctor,
                            ImmutableArray.Create <BoundExpression>(submissionArrayParameter),
                            default(ImmutableArray <string>),
                            default(ImmutableArray <RefKind>),
                            false,
                            default(ImmutableArray <int>),
                            null,
                            null,
                            null,
                            _containingType)
                {
                    WasCompilerGenerated = true
                },
                        _containingType)
                {
                    WasCompilerGenerated = true
                })
                {
                    WasCompilerGenerated = true
                };

                // return submission.<Initialize>();
                var initializeResult = CreateParameterlessCall(
                    syntax,
                    submissionLocal,
                    initializer);

                Debug.Assert(TypeSymbol.Equals(initializeResult.Type, _returnType.Type, TypeCompareKind.ConsiderEverything2));
                var returnStatement = new BoundReturnStatement(
                    syntax,
                    RefKind.None,
                    initializeResult)
                {
                    WasCompilerGenerated = true
                };

                return(new BoundBlock(syntax,
                                      ImmutableArray.Create <LocalSymbol>(submissionLocal.LocalSymbol),
                                      ImmutableArray.Create <BoundStatement>(submissionAssignment, returnStatement))
                {
                    WasCompilerGenerated = true
                });
            }
            internal override BoundBlock CreateBody(DiagnosticBag diagnostics)
            {
                var syntax      = DummySyntax();
                var compilation = _containingType.DeclaringCompilation;

                // Creates a new top-level binder that just contains the global imports for the compilation.
                // The imports are required if a consumer of the scripting API is using a Task implementation
                // that uses extension methods.
                var binder = new InContainerBinder(
                    container: null,
                    next: new BuckStopsHereBinder(compilation),
                    imports: compilation.GlobalImports);

                binder = new InContainerBinder(compilation.GlobalNamespace, binder);

                var ctor = _containingType.GetScriptConstructor();

                Debug.Assert(ctor.ParameterCount == 0);

                var initializer = _containingType.GetScriptInitializer();

                Debug.Assert(initializer.ParameterCount == 0);

                var scriptLocal = new BoundLocal(
                    syntax,
                    new SynthesizedLocal(this, TypeWithAnnotations.Create(_containingType), SynthesizedLocalKind.LoweringTemp),
                    null,
                    _containingType)
                {
                    WasCompilerGenerated = true
                };

                Debug.Assert(!initializer.ReturnType.IsDynamic());
                var             initializeCall = CreateParameterlessCall(syntax, scriptLocal, initializer);
                BoundExpression getAwaiterGetResultCall;

                if (!binder.GetAwaitableExpressionInfo(initializeCall, out getAwaiterGetResultCall, syntax, diagnostics))
                {
                    return(new BoundBlock(
                               syntax: syntax,
                               locals: ImmutableArray <LocalSymbol> .Empty,
                               statements: ImmutableArray <BoundStatement> .Empty,
                               hasErrors: true));
                }

                return(new BoundBlock(syntax,
                                      ImmutableArray.Create <LocalSymbol>(scriptLocal.LocalSymbol),
                                      ImmutableArray.Create <BoundStatement>(
                                          // var script = new Script();
                                          new BoundExpressionStatement(
                                              syntax,
                                              new BoundAssignmentOperator(
                                                  syntax,
                                                  scriptLocal,
                                                  new BoundObjectCreationExpression(
                                                      syntax,
                                                      ctor,
                                                      null)
                {
                    WasCompilerGenerated = true
                },
                                                  _containingType)
                {
                    WasCompilerGenerated = true
                })
                {
                    WasCompilerGenerated = true
                },
                                          // script.<Initialize>().GetAwaiter().GetResult();
                                          new BoundExpressionStatement(syntax, getAwaiterGetResultCall)
                {
                    WasCompilerGenerated = true
                },
                                          // return;
                                          new BoundReturnStatement(
                                              syntax,
                                              RefKind.None,
                                              null)
                {
                    WasCompilerGenerated = true
                }))
                {
                    WasCompilerGenerated = true
                });
            }
Ejemplo n.º 13
0
 public AnonymousTypeField(string name, Location location, TypeWithAnnotations typeWithAnnotations)
 {
     this.Name                = name;
     this.Location            = location;
     this.TypeWithAnnotations = typeWithAnnotations;
 }
Ejemplo n.º 14
0
 public SynthesizedAccessorValueParameterSymbol(SourceMemberMethodSymbol accessor, TypeWithAnnotations paramType, int ordinal)
     : base(accessor, ordinal, paramType, RefKind.None, ParameterSymbol.ValueParameterName, accessor.Locations,
            syntaxRef: null,
            isParams: false,
            isExtensionMethodThis: false)
 {
 }
Ejemplo n.º 15
0
 internal static UpdatedContainingSymbolAndNullableAnnotationLocal CreateForTest(SourceLocalSymbol underlyingLocal, Symbol updatedContainingSymbol, TypeWithAnnotations updatedType)
 {
     return(new UpdatedContainingSymbolAndNullableAnnotationLocal(underlyingLocal, updatedContainingSymbol, updatedType, assertContaining: false));
 }
Ejemplo n.º 16
0
 internal PointerTypeSymbol WithPointedAtType(TypeWithAnnotations newPointedAtType)
 {
     return(PointedAtTypeWithAnnotations.IsSameAs(newPointedAtType) ? this : new PointerTypeSymbol(newPointedAtType));
 }
Ejemplo n.º 17
0
 private UpdatedContainingSymbolAndNullableAnnotationLocal(SourceLocalSymbol underlyingLocal, Symbol updatedContainingSymbol, TypeWithAnnotations updatedType, bool assertContaining)
 {
     RoslynDebug.Assert(underlyingLocal is object);
     RoslynDebug.Assert(updatedContainingSymbol is object);
     Debug.Assert(!assertContaining || updatedContainingSymbol.Equals(underlyingLocal.ContainingSymbol, TypeCompareKind.AllNullableIgnoreOptions));
     ContainingSymbol    = updatedContainingSymbol;
     TypeWithAnnotations = updatedType;
     _underlyingLocal    = underlyingLocal;
 }
Ejemplo n.º 18
0
        internal void ComputeReturnType()
        {
            if (_lazyReturnType is object)
            {
                return;
            }

            var                 diagnostics      = BindingDiagnosticBag.GetInstance(_declarationDiagnostics);
            TypeSyntax          returnTypeSyntax = Syntax.ReturnType;
            TypeWithAnnotations returnType       = _binder.BindType(
                returnTypeSyntax.SkipRef(),
                diagnostics
                );

            var compilation = DeclaringCompilation;

            // Skip some diagnostics when the local function is not associated with a compilation
            // (specifically, local functions nested in expressions in the EE).
            if (compilation is object)
            {
                var location = returnTypeSyntax.Location;
                if (_refKind == RefKind.RefReadOnly)
                {
                    compilation.EnsureIsReadOnlyAttributeExists(
                        diagnostics,
                        location,
                        modifyCompilation: false
                        );
                }

                if (returnType.Type.ContainsNativeInteger())
                {
                    compilation.EnsureNativeIntegerAttributeExists(
                        diagnostics,
                        location,
                        modifyCompilation: false
                        );
                }

                if (
                    compilation.ShouldEmitNullableAttributes(this) &&
                    returnType.NeedsNullableAttribute()
                    )
                {
                    compilation.EnsureNullableAttributeExists(
                        diagnostics,
                        location,
                        modifyCompilation: false
                        );
                    // Note: we don't need to warn on annotations used in #nullable disable context for local functions, as this is handled in binding already
                }
            }

            // span-like types are returnable in general
            if (returnType.IsRestrictedType(ignoreSpanLikeTypes: true))
            {
                // The return type of a method, delegate, or function pointer cannot be '{0}'
                diagnostics.Add(
                    ErrorCode.ERR_MethodReturnCantBeRefAny,
                    returnTypeSyntax.Location,
                    returnType.Type
                    );
            }

            Debug.Assert(
                _refKind == RefKind.None || !returnType.IsVoidType() || returnTypeSyntax.HasErrors
                );
            lock (_declarationDiagnostics)
            {
                if (_lazyReturnType is object)
                {
                    diagnostics.Free();
                    return;
                }

                _declarationDiagnostics.AddRangeAndFree(diagnostics);
                Interlocked.CompareExchange(
                    ref _lazyReturnType,
                    new TypeWithAnnotations.Boxed(returnType),
                    null
                    );
            }
        }
        internal SourceFieldLikeEventSymbol(SourceMemberContainerTypeSymbol containingType, Binder binder, SyntaxTokenList modifiers, VariableDeclaratorSyntax declaratorSyntax, DiagnosticBag diagnostics)
            : base(containingType, declaratorSyntax, modifiers, isFieldLike: true, interfaceSpecifierSyntaxOpt: null,
                   nameTokenSyntax: declaratorSyntax.Identifier, diagnostics: diagnostics)
        {
            _name = declaratorSyntax.Identifier.ValueText;

            var declaratorDiagnostics = DiagnosticBag.GetInstance();
            var declarationSyntax     = (VariableDeclarationSyntax)declaratorSyntax.Parent;

            _type = BindEventType(binder, declarationSyntax.Type, declaratorDiagnostics);

            // The runtime will not treat the accessors of this event as overrides or implementations
            // of those of another event unless both the signatures and the custom modifiers match.
            // Hence, in the case of overrides and *explicit* implementations (not possible for field-like
            // events), we need to copy the custom modifiers that are in the signatures of the
            // overridden/implemented event accessors. (From source, we know that there can only be one
            // overridden/implemented event, so there are no conflicts.)  This is unnecessary for implicit
            // implementations because, if the custom modifiers don't match, we'll insert bridge methods
            // for the accessors (explicit implementations that delegate to the implicit implementations)
            // with the correct custom modifiers (see SourceMemberContainerTypeSymbol.SynthesizeInterfaceMemberImplementation).

            // If this event is an override, we may need to copy custom modifiers from
            // the overridden event (so that the runtime will recognize it as an override).
            // We check for this case here, while we can still modify the parameters and
            // return type without losing the appearance of immutability.
            if (this.IsOverride)
            {
                EventSymbol overriddenEvent = this.OverriddenEvent;
                if ((object)overriddenEvent != null)
                {
                    CopyEventCustomModifiers(overriddenEvent, ref _type, ContainingAssembly);
                }
            }

            bool hasInitializer  = declaratorSyntax.Initializer != null;
            bool inInterfaceType = containingType.IsInterfaceType();

            if (hasInitializer)
            {
                if (inInterfaceType && !this.IsStatic)
                {
                    diagnostics.Add(ErrorCode.ERR_InterfaceEventInitializer, this.Locations[0], this);
                }
                else if (this.IsAbstract)
                {
                    diagnostics.Add(ErrorCode.ERR_AbstractEventInitializer, this.Locations[0], this);
                }
            }

            // NOTE: if there's an initializer in source, we'd better create a backing field, regardless of
            // whether or not the initializer is legal.
            if (hasInitializer || !(this.IsExtern || this.IsAbstract))
            {
                _associatedField = MakeAssociatedField(declaratorSyntax);
                // Don't initialize this.type - we'll just use the type of the field (which is lazy and handles var)
            }

            if (!IsStatic && ContainingType.IsReadOnly)
            {
                diagnostics.Add(ErrorCode.ERR_FieldlikeEventsInRoStruct, this.Locations[0]);
            }

            if (inInterfaceType)
            {
                if (this.IsExtern || this.IsStatic)
                {
                    if (!ContainingAssembly.RuntimeSupportsDefaultInterfaceImplementation)
                    {
                        diagnostics.Add(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, this.Locations[0]);
                    }
                }
                else if (!this.IsAbstract)
                {
                    diagnostics.Add(ErrorCode.ERR_EventNeedsBothAccessors, this.Locations[0], this);
                }
            }

            // Accessors will assume that Type is available.
            _addMethod    = new SynthesizedEventAccessorSymbol(this, isAdder: true);
            _removeMethod = new SynthesizedEventAccessorSymbol(this, isAdder: false);

            if (declarationSyntax.Variables[0] == declaratorSyntax)
            {
                // Don't report these diagnostics for every declarator in this declaration.
                diagnostics.AddRange(declaratorDiagnostics);
            }

            declaratorDiagnostics.Free();
        }
        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;
            TypeSyntax returnTypeSyntax = syntax.ReturnType.SkipRef(out refKind);
            var        returnType       = binder.BindType(returnTypeSyntax, diagnostics);

            // reuse types to avoid reporting duplicate errors if missing:
            var voidType = TypeWithAnnotations.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 = TypeWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_Object, diagnostics, syntax));
            var intPtrType = TypeWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_IntPtr, diagnostics, syntax));

            if (returnType.IsRestrictedType(ignoreSpanLikeTypes: true))
            {
                // The return type of a method, delegate, or function pointer cannot be '{0}'
                diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, returnTypeSyntax.Location, returnType.Type);
            }

            // 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  = TypeWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_IAsyncResult, diagnostics, syntax));
                var asyncCallbackType = TypeWithAnnotations.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.ReturnTypeWithAnnotations, ref useSiteDiagnostics))
            {
                // Inconsistent accessibility: return type '{1}' is less accessible than delegate '{0}'
                diagnostics.Add(ErrorCode.ERR_BadVisDelegateReturn, delegateType.Locations[0], delegateType, invoke.ReturnType);
            }

            foreach (var parameter in invoke.Parameters)
            {
                if (!parameter.TypeWithAnnotations.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);
                }
            }

            diagnostics.Add(delegateType.Locations[0], useSiteDiagnostics);
        }
Ejemplo n.º 21
0
 public static bool IsNoMoreVisibleThan(this Symbol symbol, TypeWithAnnotations type, ref HashSet <DiagnosticInfo> useSiteDiagnostics)
 {
     return(type.IsAtLeastAsVisibleAs(symbol, ref useSiteDiagnostics));
 }
Ejemplo n.º 22
0
 internal TypeWithAnnotations SubstituteType(TypeWithAnnotations previous)
 {
     return previous.SubstituteType(this);
 }
Ejemplo n.º 23
0
 static int customModifierCountForTypeWithAnnotations(TypeWithAnnotations typeWithAnnotations)
 => typeWithAnnotations.CustomModifiers.Length + typeWithAnnotations.Type.CustomModifierCount();
Ejemplo n.º 24
0
 protected virtual TypeWithAnnotations SubstituteTypeParameter(TypeParameterSymbol typeParameter)
 {
     return TypeWithAnnotations.Create(typeParameter);
 }
Ejemplo n.º 25
0
        internal override ImmutableArray <TypeWithAnnotations> GetConstraintTypes(
            ConsList <TypeParameterSymbol> inProgress
            )
        {
            var constraintTypes = ArrayBuilder <TypeWithAnnotations> .GetInstance();

            _map.SubstituteConstraintTypesDistinctWithoutModifiers(
                _underlyingTypeParameter,
                _underlyingTypeParameter.GetConstraintTypes(inProgress),
                constraintTypes,
                null
                );

            TypeWithAnnotations bestObjectConstraint = default;

            // Strip all Object constraints.
            for (int i = constraintTypes.Count - 1; i >= 0; i--)
            {
                TypeWithAnnotations type = constraintTypes[i];
                if (ConstraintsHelper.IsObjectConstraint(type, ref bestObjectConstraint))
                {
                    constraintTypes.RemoveAt(i);
                }
            }

            if (bestObjectConstraint.HasType)
            {
                // See if we need to put Object! or Object~ back in order to preserve nullability information for the type parameter.
                if (
                    ConstraintsHelper.IsObjectConstraintSignificant(
                        CalculateIsNotNullableFromNonTypeConstraints(),
                        bestObjectConstraint
                        )
                    )
                {
                    Debug.Assert(!HasNotNullConstraint && !HasValueTypeConstraint);
                    if (constraintTypes.Count == 0)
                    {
                        if (
                            bestObjectConstraint.NullableAnnotation.IsOblivious() &&
                            !HasReferenceTypeConstraint
                            )
                        {
                            bestObjectConstraint = default;
                        }
                    }
                    else
                    {
                        foreach (TypeWithAnnotations constraintType in constraintTypes)
                        {
                            if (
                                !ConstraintsHelper.IsObjectConstraintSignificant(
                                    IsNotNullableFromConstraintType(constraintType, out _),
                                    bestObjectConstraint
                                    )
                                )
                            {
                                bestObjectConstraint = default;
                                break;
                            }
                        }
                    }

                    if (bestObjectConstraint.HasType)
                    {
                        constraintTypes.Insert(0, bestObjectConstraint);
                    }
                }
            }

            return(constraintTypes.ToImmutableAndFree());
        }
 internal SynthesizedThrowMethod(SourceModuleSymbol containingModule, PrivateImplementationDetails privateImplType, TypeSymbol returnType, TypeSymbol paramType)
     : base(containingModule, privateImplType, returnType, PrivateImplementationDetails.SynthesizedThrowFunctionName)
 {
     this.SetParameters(ImmutableArray.Create <ParameterSymbol>(SynthesizedParameterSymbol.Create(this, TypeWithAnnotations.Create(paramType), 0, RefKind.None, "paramName")));
 }
Ejemplo n.º 27
0
        private ImmutableArray <ParameterSymbol> MakeParameters(
            CSharpCompilation compilation,
            UnboundLambda unboundLambda,
            ImmutableArray <TypeWithAnnotations> parameterTypes,
            ImmutableArray <RefKind> parameterRefKinds,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(parameterTypes.Length == parameterRefKinds.Length);

            if (!unboundLambda.HasSignature || unboundLambda.ParameterCount == 0)
            {
                // The parameters may be omitted in source, but they are still present on the symbol.
                return(parameterTypes.SelectAsArray((type, ordinal, arg) =>
                                                    SynthesizedParameterSymbol.Create(
                                                        arg.owner,
                                                        type,
                                                        ordinal,
                                                        arg.refKinds[ordinal],
                                                        GeneratedNames.LambdaCopyParameterName(ordinal)),     // Make sure nothing binds to this.
                                                    (owner: this, refKinds: parameterRefKinds)));
            }

            var builder = ArrayBuilder <ParameterSymbol> .GetInstance(unboundLambda.ParameterCount);

            var hasExplicitlyTypedParameterList = unboundLambda.HasExplicitlyTypedParameterList;
            var numDelegateParameters           = parameterTypes.Length;

            for (int p = 0; p < unboundLambda.ParameterCount; ++p)
            {
                // If there are no types given in the lambda then used the delegate type.
                // If the lambda is typed then the types probably match the delegate types;
                // if they do not, use the lambda types for binding. Either way, if we
                // can, then we use the lambda types. (Whatever you do, do not use the names
                // in the delegate parameters; they are not in scope!)

                TypeWithAnnotations type;
                RefKind             refKind;
                if (hasExplicitlyTypedParameterList)
                {
                    type    = unboundLambda.ParameterTypeWithAnnotations(p);
                    refKind = unboundLambda.RefKind(p);
                }
                else if (p < numDelegateParameters)
                {
                    type    = parameterTypes[p];
                    refKind = parameterRefKinds[p];
                }
                else
                {
                    type    = TypeWithAnnotations.Create(new ExtendedErrorTypeSymbol(compilation, name: string.Empty, arity: 0, errorInfo: null));
                    refKind = RefKind.None;
                }

                var name      = unboundLambda.ParameterName(p);
                var location  = unboundLambda.ParameterLocation(p);
                var locations = location == null ? ImmutableArray <Location> .Empty : ImmutableArray.Create <Location>(location);

                var parameter = new SourceSimpleParameterSymbol(owner: this, type, ordinal: p, refKind, name, unboundLambda.ParameterIsDiscard(p), locations);

                builder.Add(parameter);
            }

            var result = builder.ToImmutableAndFree();

            return(result);
        }
Ejemplo n.º 28
0
 /// <summary>
 /// Replaces references to underlying type with references to native integer type.
 /// </summary>
 internal TypeWithAnnotations SubstituteUnderlyingType(TypeWithAnnotations type) => type.SubstituteType(GetTypeMap());
Ejemplo n.º 29
0
 // https://github.com/dotnet/roslyn/issues/30071: Replace with Construct(ImmutableArray<TypeWithAnnotations>).
 /// <summary>
 /// Apply type substitution to a generic method to create an method symbol with the given type parameters supplied.
 /// </summary>
 /// <param name="typeArguments"></param>
 /// <returns></returns>
 public MethodSymbol Construct(ImmutableArray <TypeSymbol> typeArguments)
 {
     return(Construct(typeArguments.SelectAsArray(a => TypeWithAnnotations.Create(a))));
 }
Ejemplo n.º 30
0
 internal ArrayTypeSymbol WithElementType(TypeWithAnnotations elementTypeWithAnnotations)
 {
     return(ElementTypeWithAnnotations.IsSameAs(elementTypeWithAnnotations) ? this : WithElementTypeCore(elementTypeWithAnnotations));
 }