示例#1
0
        internal sealed override UseSiteInfo <AssemblySymbol> GetUseSiteInfo()
        {
            var result = new UseSiteInfo <AssemblySymbol>(PrimaryDependency);

            MergeUseSiteInfo(ref result, ReturnTypeWithAnnotations.Type.GetUseSiteInfo());
            return(result);
        }
示例#2
0
        public NamedTypeSymbol GetSystemStringType(SyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics)
        {
            if ((object)_lazySystemStringType == (object)ErrorTypeSymbol.UnknownResultType)
            {
                var typeSymbol = ModuleBeingBuilt.Compilation.GetSpecialType(SpecialType.System_String);

                UseSiteInfo <AssemblySymbol> info = typeSymbol.GetUseSiteInfo();

                if (typeSymbol.IsErrorType())
                {
                    typeSymbol = null;
                }

                if (TypeSymbol.Equals(Interlocked.CompareExchange(ref _lazySystemStringType, typeSymbol, ErrorTypeSymbol.UnknownResultType), ErrorTypeSymbol.UnknownResultType, TypeCompareKind.ConsiderEverything2))
                {
                    if (info.DiagnosticInfo != null)
                    {
                        Symbol.ReportUseSiteDiagnostic(info.DiagnosticInfo,
                                                       diagnostics,
                                                       syntaxNodeOpt != null ? syntaxNodeOpt.Location : NoLocation.Singleton);
                    }
                }
            }

            return(_lazySystemStringType);
        }
示例#3
0
        internal override UseSiteInfo <AssemblySymbol> GetUseSiteInfo()
        {
            AssemblySymbol primaryDependency = PrimaryDependency;

            if (!_lazyCachedUseSiteInfo.IsInitialized)
            {
                UseSiteInfo <AssemblySymbol> result = new UseSiteInfo <AssemblySymbol>(primaryDependency);
                CalculateUseSiteDiagnostic(ref result);
                deriveCompilerFeatureRequiredUseSiteInfo(ref result);
                _lazyCachedUseSiteInfo.Initialize(primaryDependency, result);
            }

            return(_lazyCachedUseSiteInfo.ToUseSiteInfo(primaryDependency));

            void deriveCompilerFeatureRequiredUseSiteInfo(ref UseSiteInfo <AssemblySymbol> result)
            {
                var            containingType     = (PENamedTypeSymbol)ContainingType;
                PEModuleSymbol containingPEModule = _containingType.ContainingPEModule;
                var            diag = PEUtilities.DeriveCompilerFeatureRequiredAttributeDiagnostic(
                    this,
                    containingPEModule,
                    Handle,
                    allowedFeatures: CompilerFeatureRequiredFeatures.None,
                    new MetadataDecoder(containingPEModule, containingType));

                diag ??= containingType.GetCompilerFeatureRequiredDiagnostic();

                if (diag != null)
                {
                    result = new UseSiteInfo <AssemblySymbol>(diag);
                }
            }
        }
示例#4
0
        internal bool CalculateUseSiteDiagnostic(ref UseSiteInfo <AssemblySymbol> result)
        {
            Debug.Assert(IsDefinition);

            // Check type, custom modifiers
            if (DeriveUseSiteInfoFromType(ref result, this.TypeWithAnnotations, AllowedRequiredModifierType.System_Runtime_CompilerServices_Volatile))
            {
                return(true);
            }

            // If the member is in an assembly with unified references,
            // we check if its definition depends on a type from a unified reference.
            if (this.ContainingModule.HasUnifiedReferences)
            {
                HashSet <TypeSymbol> unificationCheckedTypes = null;
                DiagnosticInfo       diagnosticInfo          = result.DiagnosticInfo;
                if (this.TypeWithAnnotations.GetUnificationUseSiteDiagnosticRecursive(ref diagnosticInfo, this, ref unificationCheckedTypes))
                {
                    result = result.AdjustDiagnosticInfo(diagnosticInfo);
                    return(true);
                }

                result = result.AdjustDiagnosticInfo(diagnosticInfo);
            }

            return(false);
        }
        internal override UseSiteInfo <AssemblySymbol> GetUseSiteInfo()
        {
            UseSiteInfo <AssemblySymbol> result = default;

            // Check type, custom modifiers
            DeriveUseSiteInfoFromType(ref result, this.PointedAtTypeWithAnnotations, AllowedRequiredModifierType.None);
            return(result);
        }
        internal override UseSiteInfo <AssemblySymbol> GetUseSiteInfo()
        {
            UseSiteInfo <AssemblySymbol> fromSignature = Signature.GetUseSiteInfo();

            if (fromSignature.DiagnosticInfo?.Code == (int)ErrorCode.ERR_BindToBogus && fromSignature.DiagnosticInfo.Arguments.AsSingleton() == (object)Signature)
            {
                return(new UseSiteInfo <AssemblySymbol>(new CSDiagnosticInfo(ErrorCode.ERR_BogusType, this)));
            }

            return(fromSignature);
        }
示例#7
0
        internal override UseSiteInfo <AssemblySymbol> GetUseSiteInfo()
        {
            if (!_lazyCachedUseSiteInfo.IsInitialized)
            {
                AssemblySymbol primaryDependency = PrimaryDependency;
                var            result            = new UseSiteInfo <AssemblySymbol>(primaryDependency);
                CalculateUseSiteDiagnostic(ref result);
                _lazyCachedUseSiteInfo.Initialize(primaryDependency, result);
            }

            return(_lazyCachedUseSiteInfo.ToUseSiteInfo(PrimaryDependency));
        }
        internal sealed override UseSiteInfo <AssemblySymbol> GetUseSiteInfo()
        {
            var type = this.TypeWithAnnotations;
            UseSiteInfo <AssemblySymbol> result = default;

            if (!DeriveUseSiteInfoFromType(ref result, type, AllowedRequiredModifierType.None) && this.ContainingModule.HasUnifiedReferences)
            {
                // If the member is in an assembly with unified references,
                // we check if its definition depends on a type from a unified reference.
                HashSet <TypeSymbol> unificationCheckedTypes = null;
                var diagnosticInfo = result.DiagnosticInfo;
                type.GetUnificationUseSiteDiagnosticRecursive(ref diagnosticInfo, this, ref unificationCheckedTypes);
                result = result.AdjustDiagnosticInfo(diagnosticInfo);
            }

            return(result);
        }
示例#9
0
        private BoundExpression MakeTupleFieldAccessAndReportUseSiteDiagnostics(BoundExpression tuple, SyntaxNode syntax, FieldSymbol field)
        {
            // Use default field rather than implicitly named fields since
            // fields from inferred names are not usable in C# 7.0.
            field = field.CorrespondingTupleField ?? field;

            UseSiteInfo <AssemblySymbol> useSiteInfo = field.GetUseSiteInfo();

            if (useSiteInfo.DiagnosticInfo?.Severity != DiagnosticSeverity.Error)
            {
                useSiteInfo = useSiteInfo.AdjustDiagnosticInfo(null);
            }

            _diagnostics.Add(useSiteInfo, syntax.Location);

            return(MakeTupleFieldAccess(syntax, field, tuple));
        }
示例#10
0
        internal override void GenerateMethodBody(TypeCompilationState compilationState, BindingDiagnosticBag diagnostics)
        {
            ImmutableArray <LocalSymbol> declaredLocalsArray;
            var body        = _generateMethodBody(this, diagnostics.DiagnosticBag, out declaredLocalsArray, out _lazyResultProperties);
            var compilation = compilationState.Compilation;

            _lazyReturnType = TypeWithAnnotations.Create(CalculateReturnType(compilation, body));

            // Can't do this until the return type has been computed.
            TypeParameterChecker.Check(this, _allTypeParameters);

            if (diagnostics.HasAnyErrors())
            {
                return;
            }

            DiagnosticsPass.IssueDiagnostics(compilation, body, diagnostics, this);
            if (diagnostics.HasAnyErrors())
            {
                return;
            }

            // Check for use-site diagnostics (e.g. missing types in the signature).
            UseSiteInfo <AssemblySymbol> useSiteInfo = default;

            this.CalculateUseSiteDiagnostic(ref useSiteInfo);
            if (useSiteInfo.DiagnosticInfo != null && useSiteInfo.DiagnosticInfo.Severity == DiagnosticSeverity.Error)
            {
                diagnostics.Add(useSiteInfo.DiagnosticInfo, this.Locations[0]);
                return;
            }

            try
            {
                var declaredLocals = PooledHashSet <LocalSymbol> .GetInstance();

                try
                {
                    // Rewrite local declaration statement.
                    body = (BoundStatement)LocalDeclarationRewriter.Rewrite(
                        compilation,
                        _container,
                        declaredLocals,
                        body,
                        declaredLocalsArray,
                        diagnostics.DiagnosticBag);

                    // Verify local declaration names.
                    foreach (var local in declaredLocals)
                    {
                        Debug.Assert(local.Locations.Length > 0);
                        var name = local.Name;
                        if (name.StartsWith("$", StringComparison.Ordinal))
                        {
                            diagnostics.Add(ErrorCode.ERR_UnexpectedCharacter, local.Locations[0], name[0]);
                            return;
                        }
                    }

                    // Rewrite references to placeholder "locals".
                    body = (BoundStatement)PlaceholderLocalRewriter.Rewrite(compilation, _container, declaredLocals, body, diagnostics.DiagnosticBag);

                    if (diagnostics.HasAnyErrors())
                    {
                        return;
                    }
                }
                finally
                {
                    declaredLocals.Free();
                }

                var syntax            = body.Syntax;
                var statementsBuilder = ArrayBuilder <BoundStatement> .GetInstance();

                statementsBuilder.Add(body);
                // Insert an implicit return statement if necessary.
                if (body.Kind != BoundKind.ReturnStatement)
                {
                    statementsBuilder.Add(new BoundReturnStatement(syntax, RefKind.None, expressionOpt: null, @checked: false));
                }

                var localsSet = PooledHashSet <LocalSymbol> .GetInstance();

                try
                {
                    var localsBuilder = ArrayBuilder <LocalSymbol> .GetInstance();

                    foreach (var local in this.LocalsForBinding)
                    {
                        Debug.Assert(!localsSet.Contains(local));
                        localsBuilder.Add(local);
                        localsSet.Add(local);
                    }
                    foreach (var local in this.Locals)
                    {
                        if (localsSet.Add(local))
                        {
                            localsBuilder.Add(local);
                        }
                    }

                    body = new BoundBlock(syntax, localsBuilder.ToImmutableAndFree(), statementsBuilder.ToImmutableAndFree())
                    {
                        WasCompilerGenerated = true
                    };

                    Debug.Assert(!diagnostics.HasAnyErrors());
                    Debug.Assert(!body.HasErrors);

                    bool sawLambdas;
                    bool sawLocalFunctions;
                    bool sawAwaitInExceptionHandler;
                    ImmutableArray <SourceSpan> dynamicAnalysisSpans = ImmutableArray <SourceSpan> .Empty;
                    body = LocalRewriter.Rewrite(
                        compilation: this.DeclaringCompilation,
                        method: this,
                        methodOrdinal: _methodOrdinal,
                        containingType: _container,
                        statement: body,
                        compilationState: compilationState,
                        previousSubmissionFields: null,
                        allowOmissionOfConditionalCalls: false,
                        instrumentForDynamicAnalysis: false,
                        debugDocumentProvider: null,
                        dynamicAnalysisSpans: ref dynamicAnalysisSpans,
                        diagnostics: diagnostics,
                        sawLambdas: out sawLambdas,
                        sawLocalFunctions: out sawLocalFunctions,
                        sawAwaitInExceptionHandler: out sawAwaitInExceptionHandler);

                    Debug.Assert(!sawAwaitInExceptionHandler);
                    Debug.Assert(dynamicAnalysisSpans.Length == 0);

                    if (body.HasErrors)
                    {
                        return;
                    }

                    // Variables may have been captured by lambdas in the original method
                    // or in the expression, and we need to preserve the existing values of
                    // those variables in the expression. This requires rewriting the variables
                    // in the expression based on the closure classes from both the original
                    // method and the expression, and generating a preamble that copies
                    // values into the expression closure classes.
                    //
                    // Consider the original method:
                    // static void M()
                    // {
                    //     int x, y, z;
                    //     ...
                    //     F(() => x + y);
                    // }
                    // and the expression in the EE: "F(() => x + z)".
                    //
                    // The expression is first rewritten using the closure class and local <1>
                    // from the original method: F(() => <1>.x + z)
                    // Then lambda rewriting introduces a new closure class that includes
                    // the locals <1> and z, and a corresponding local <2>: F(() => <2>.<1>.x + <2>.z)
                    // And a preamble is added to initialize the fields of <2>:
                    //     <2> = new <>c__DisplayClass0();
                    //     <2>.<1> = <1>;
                    //     <2>.z = z;

                    // Rewrite "this" and "base" references to parameter in this method.
                    // Rewrite variables within body to reference existing display classes.
                    body = (BoundStatement)CapturedVariableRewriter.Rewrite(
                        this.GenerateThisReference,
                        compilation.Conversions,
                        _displayClassVariables,
                        body,
                        diagnostics.DiagnosticBag);

                    if (body.HasErrors)
                    {
                        Debug.Assert(false, "Please add a test case capturing whatever caused this assert.");
                        return;
                    }

                    if (diagnostics.HasAnyErrors())
                    {
                        return;
                    }

                    if (sawLambdas || sawLocalFunctions)
                    {
                        var closureDebugInfoBuilder = ArrayBuilder <ClosureDebugInfo> .GetInstance();

                        var lambdaDebugInfoBuilder = ArrayBuilder <LambdaDebugInfo> .GetInstance();

                        body = ClosureConversion.Rewrite(
                            loweredBody: body,
                            thisType: this.SubstitutedSourceMethod.ContainingType,
                            thisParameter: _thisParameter,
                            method: this,
                            methodOrdinal: _methodOrdinal,
                            substitutedSourceMethod: this.SubstitutedSourceMethod.OriginalDefinition,
                            closureDebugInfoBuilder: closureDebugInfoBuilder,
                            lambdaDebugInfoBuilder: lambdaDebugInfoBuilder,
                            slotAllocatorOpt: null,
                            compilationState: compilationState,
                            diagnostics: diagnostics,
                            assignLocals: localsSet);

                        // we don't need this information:
                        closureDebugInfoBuilder.Free();
                        lambdaDebugInfoBuilder.Free();
                    }
                }
                finally
                {
                    localsSet.Free();
                }

                // Insert locals from the original method,
                // followed by any new locals.
                var block        = (BoundBlock)body;
                var localBuilder = ArrayBuilder <LocalSymbol> .GetInstance();

                foreach (var local in this.Locals)
                {
                    Debug.Assert(!(local is EELocalSymbol) || (((EELocalSymbol)local).Ordinal == localBuilder.Count));
                    localBuilder.Add(local);
                }
                foreach (var local in block.Locals)
                {
                    if (local is EELocalSymbol oldLocal)
                    {
                        Debug.Assert(localBuilder[oldLocal.Ordinal] == oldLocal);
                        continue;
                    }
                    localBuilder.Add(local);
                }

                body = block.Update(localBuilder.ToImmutableAndFree(), block.LocalFunctions, block.Statements);
                TypeParameterChecker.Check(body, _allTypeParameters);
                compilationState.AddSynthesizedMethod(this, body);
            }
            catch (BoundTreeVisitor.CancelledByStackGuardException ex)
            {
                ex.AddAnError(diagnostics);
            }
        }