Represents a method or method-like symbol (including constructor, destructor, operator, or property/event accessor).
Inheritance: Symbol, IMethodSymbol
Esempio n. 1
0
 internal ExecutableCodeBinder(CSharpSyntaxNode root, Symbol memberSymbol, Binder next, BinderFlags additionalFlags)
     : base(next, (next.Flags | additionalFlags) & ~BinderFlags.AllClearedAtExecutableCodeBoundary)
 {
     this.memberSymbol = memberSymbol;
     this.root = root;
     this.owner = memberSymbol as MethodSymbol;
 }
        public SynthesizedImplementationMethod(
            MethodSymbol interfaceMethod,
            NamedTypeSymbol implementingType,
            string name = null,
            bool generateDebugInfo = true,
            PropertySymbol associatedProperty = null)
        {
            //it does not make sense to add methods to substituted types
            Debug.Assert(implementingType.IsDefinition);

            _name = name ?? ExplicitInterfaceHelpers.GetMemberName(interfaceMethod.Name, interfaceMethod.ContainingType, aliasQualifierOpt: null);
            _interfaceMethod = interfaceMethod;
            _implementingType = implementingType;
            _generateDebugInfo = generateDebugInfo;
            _associatedProperty = associatedProperty;
            _explicitInterfaceImplementations = ImmutableArray.Create<MethodSymbol>(interfaceMethod);

            // alpha-rename to get the implementation's type parameters
            var typeMap = interfaceMethod.ContainingType.TypeSubstitution ?? TypeMap.Empty;
            typeMap.WithAlphaRename(interfaceMethod, this, out _typeParameters);

            var substitutedInterfaceMethod = interfaceMethod.ConstructIfGeneric(_typeParameters.Cast<TypeParameterSymbol, TypeSymbol>());
            _returnType = substitutedInterfaceMethod.ReturnType;
            _parameters = SynthesizedParameterSymbol.DeriveParameters(substitutedInterfaceMethod, this);
        }
Esempio n. 3
0
 public static SmallDictionary<CSharpSyntaxNode, Binder> BuildMap(MethodSymbol method, CSharpSyntaxNode syntax, Binder enclosing, out bool sawYield)
 {
     var builder = new LocalBinderFactory(method, enclosing);
     builder.Visit(syntax);
     sawYield = builder._sawYield;
     return builder._map;
 }
Esempio n. 4
0
 public AsyncStruct(MethodSymbol method)
     : base(method, GeneratedNames.MakeIteratorOrAsyncDisplayClassName(method.Name, SequenceNumber(method)), TypeKind.Struct)
 {
     // TODO: report use-site errors on these types
     this.interfaces = ImmutableArray.Create<NamedTypeSymbol>(method.DeclaringCompilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IAsyncStateMachine));
     this.constructor = new SynthesizedInstanceConstructor(this);
 }
Esempio n. 5
0
 private LocalBinderFactory(MethodSymbol method, Binder enclosing)
 {
     Debug.Assert((object)method != null);
     _map = new SmallDictionary<CSharpSyntaxNode, Binder>(ReferenceEqualityComparer.Instance);
     _method = method;
     _enclosing = enclosing;
 }
Esempio n. 6
0
        /// <summary>
        /// Rewrite an iterator method into a state machine class.
        /// </summary>
        /// <param name="body">The original body of the method</param>
        /// <param name="method">The method's identity</param>
        /// <param name="compilationState">The collection of generated methods that result from this transformation and which must be emitted</param>
        /// <param name="diagnostics">Diagnostic bag for diagnostics.</param>
        /// <param name="generateDebugInfo"></param>
        internal static BoundStatement Rewrite(
            BoundStatement body,
            MethodSymbol method,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics,
            bool generateDebugInfo)
        {
            TypeSymbol elementType = method.IteratorElementType;
            if ((object)elementType == null)
            {
                return body;
            }

            // Figure out what kind of iterator we are generating.
            bool isEnumerable;
            switch (method.ReturnType.OriginalDefinition.SpecialType)
            {
                case SpecialType.System_Collections_IEnumerable:
                case SpecialType.System_Collections_Generic_IEnumerable_T:
                    isEnumerable = true;
                    break;

                case SpecialType.System_Collections_IEnumerator:
                case SpecialType.System_Collections_Generic_IEnumerator_T:
                    isEnumerable = false;
                    break;

                default:
                    throw ExceptionUtilities.UnexpectedValue(method.ReturnType.OriginalDefinition.SpecialType);
            }

            var iteratorClass = new IteratorStateMachine(method, isEnumerable, elementType, compilationState);
            return new IteratorRewriter(body, method, isEnumerable, iteratorClass, compilationState, diagnostics, generateDebugInfo).Rewrite();
        }
Esempio n. 7
0
        /// <summary>
        /// Rewrite an async method into a state machine type.
        /// </summary>
        internal static BoundStatement Rewrite(
            BoundStatement body,
            MethodSymbol method,
            int methodOrdinal,
            VariableSlotAllocator slotAllocatorOpt,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics,
            out AsyncStateMachine stateMachineType)
        {
            if (!method.IsAsync)
            {
                stateMachineType = null;
                return body;
            }

            // The CLR doesn't support adding fields to structs, so in order to enable EnC in an async method we need to generate a class.
            var typeKind = compilationState.Compilation.Options.EnableEditAndContinue ? TypeKind.Class : TypeKind.Struct;

            var bodyWithAwaitLifted = AwaitExpressionSpiller.Rewrite(body, method, compilationState, diagnostics);

            stateMachineType = new AsyncStateMachine(slotAllocatorOpt, compilationState, method, methodOrdinal, typeKind);
            compilationState.ModuleBuilderOpt.CompilationState.SetStateMachineType(method, stateMachineType);
            var rewriter = new AsyncRewriter(bodyWithAwaitLifted, method, methodOrdinal, stateMachineType, slotAllocatorOpt, compilationState, diagnostics);

            if (!rewriter.VerifyPresenceOfRequiredAPIs())
            {
                return body;
            }

            return rewriter.Rewrite();
        }
        internal TempLocalSymbol(TypeSymbol type, RefKind refKind, MethodSymbol containingMethod) : base(containingMethod, type, null)
        {
            this.refKind = refKind;
#if TEMPNAMES
            this.name = "_" + Interlocked.Increment(ref nextName);
#endif
        }
        internal SourceAttributeData(
            SyntaxReference applicationNode,
            NamedTypeSymbol attributeClass,
            MethodSymbol attributeConstructor,
            ImmutableArray<TypedConstant> constructorArguments,
            ImmutableArray<int> constructorArgumentsSourceIndices,
            ImmutableArray<KeyValuePair<string, TypedConstant>> namedArguments,
            bool hasErrors,
            bool isConditionallyOmitted)
        {
            Debug.Assert(!isConditionallyOmitted || (object)attributeClass != null && attributeClass.IsConditional);
            Debug.Assert(!constructorArguments.IsDefault);
            Debug.Assert(!namedArguments.IsDefault);
            Debug.Assert(constructorArgumentsSourceIndices.IsDefault ||
                constructorArgumentsSourceIndices.Any() && constructorArgumentsSourceIndices.Length == constructorArguments.Length);

            this.attributeClass = attributeClass;
            this.attributeConstructor = attributeConstructor;
            this.constructorArguments = constructorArguments;
            this.constructorArgumentsSourceIndices = constructorArgumentsSourceIndices;
            this.namedArguments = namedArguments;
            this.isConditionallyOmitted = isConditionallyOmitted;
            this.hasErrors = hasErrors;
            this.applicationNode = applicationNode;
        }
 public SynthesizedExplicitImplementationMethod(
     MethodSymbol interfaceMethod,
     MethodSymbol implementingMethod,
     NamedTypeSymbol implementingType) : base(interfaceMethod, implementingType)
 {
     this.implementingMethod = implementingMethod;
 }
Esempio n. 11
0
        public static DynamicAnalysisInjector TryCreate(MethodSymbol method, BoundStatement methodBody, SyntheticBoundNodeFactory methodBodyFactory, DiagnosticBag diagnostics, DebugDocumentProvider debugDocumentProvider, Instrumenter previous)
        {
            // Do not instrument implicitly-declared methods, except for constructors.
            // Instrument implicit constructors in order to instrument member initializers.
            if (method.IsImplicitlyDeclared && !method.IsImplicitConstructor)
            {
                return null;
            }

            // Do not instrument methods marked with or in scope of ExcludeFromCodeCoverageAttribute.
            if (IsExcludedFromCodeCoverage(method))
            {
                return null;
            }

            MethodSymbol createPayload = GetCreatePayload(methodBodyFactory.Compilation, methodBody.Syntax, diagnostics);

            // Do not instrument any methods if CreatePayload is not present.
            if ((object)createPayload == null)
            {
                return null;
            }

            // Do not instrument CreatePayload if it is part of the current compilation (which occurs only during testing).
            // CreatePayload will fail at run time with an infinite recursion if it is instrumented.
            if (method.Equals(createPayload))
            {
                return null;
            }

            return new DynamicAnalysisInjector(method, methodBody, methodBodyFactory, createPayload, diagnostics, debugDocumentProvider, previous);
        }
Esempio n. 12
0
        public EELocalSymbol(
            MethodSymbol method,
            ImmutableArray<Location> locations,
            string nameOpt,
            int ordinal,
            LocalDeclarationKind declarationKind,
            TypeSymbol type,
            RefKind refKind,
            bool isPinned,
            bool isCompilerGenerated,
            bool canScheduleToStack)
        {
            Debug.Assert(method != null);
            Debug.Assert(ordinal >= -1);
            Debug.Assert(!locations.IsDefault);
            Debug.Assert(type != null);

            _method = method;
            _locations = locations;
            _nameOpt = nameOpt;
            _ordinal = ordinal;
            _declarationKind = declarationKind;
            _type = type;
            _refKind = refKind;
            _isPinned = isPinned;
            _isCompilerGenerated = isCompilerGenerated;
            _canScheduleToStack = canScheduleToStack;
        }
        internal AsyncMethodToStateMachineRewriter(
            MethodSymbol method,
            int methodOrdinal,
            AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection,
            SyntheticBoundNodeFactory F,
            FieldSymbol state,
            FieldSymbol builder,
            IReadOnlySet<Symbol> hoistedVariables,
            IReadOnlyDictionary<Symbol, CapturedSymbolReplacement> nonReusableLocalProxies,
            SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals,
            VariableSlotAllocator slotAllocatorOpt,
            int nextFreeHoistedLocalSlot,
            DiagnosticBag diagnostics)
            : base(F, method, state, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics, useFinalizerBookkeeping: false)
        {
            _method = method;
            _asyncMethodBuilderMemberCollection = asyncMethodBuilderMemberCollection;
            _asyncMethodBuilderField = builder;
            _exprReturnLabel = F.GenerateLabel("exprReturn");
            _exitLabel = F.GenerateLabel("exitLabel");

            _exprRetValue = method.IsGenericTaskReturningAsync(F.Compilation)
                ? F.SynthesizedLocal(asyncMethodBuilderMemberCollection.ResultType, syntax: F.Syntax, kind: SynthesizedLocalKind.AsyncMethodReturnValue)
                : null;

            _dynamicFactory = new LoweredDynamicOperationFactory(F, methodOrdinal);
            _awaiterFields = new Dictionary<TypeSymbol, FieldSymbol>(TypeSymbol.EqualsIgnoringDynamicComparer);
            _nextAwaiterId = slotAllocatorOpt?.PreviousAwaiterSlotCount ?? 0;
        }
        /// <summary>
        /// Return the extension method in reduced form if the extension method
        /// is applicable, and satisfies type parameter constraints, based on the
        /// "this" argument type. Otherwise, returns null.
        /// </summary>
        public static MethodSymbol Create(MethodSymbol method, TypeSymbol receiverType, Compilation compilation)
        {
            Debug.Assert(method.IsExtensionMethod && method.MethodKind != MethodKind.ReducedExtension);
            Debug.Assert(method.ParameterCount > 0);
            Debug.Assert((object)receiverType != null);

            HashSet<DiagnosticInfo> useSiteDiagnostics = null;

            method = method.InferExtensionMethodTypeArguments(receiverType, compilation, ref useSiteDiagnostics);
            if ((object)method == null)
            {
                return null;
            }

            var conversions = new TypeConversions(method.ContainingAssembly.CorLibrary);
            var conversion = conversions.ConvertExtensionMethodThisArg(method.Parameters[0].Type, receiverType, ref useSiteDiagnostics);
            if (!conversion.Exists)
            {
                return null;
            }

            if (useSiteDiagnostics != null)
            {
                foreach (var diag in useSiteDiagnostics)
                {
                    if (diag.Severity == DiagnosticSeverity.Error)
                    {
                        return null;
                    }
                }
            }

            return Create(method);
        }
        private ForEachEnumeratorInfo(
            TypeSymbol collectionType,
            TypeSymbol elementType,
            MethodSymbol getEnumeratorMethod,
            MethodSymbol currentPropertyGetter,
            MethodSymbol moveNextMethod,
            bool needsDisposeMethod,
            Conversion collectionConversion,
            Conversion currentConversion,
            Conversion enumeratorConversion,
            BinderFlags location)
        {
            Debug.Assert((object)collectionType != null, "Field 'collectionType' cannot be null");
            Debug.Assert((object)elementType != null, "Field 'elementType' cannot be null");
            Debug.Assert((object)getEnumeratorMethod != null, "Field 'getEnumeratorMethod' cannot be null");
            Debug.Assert((object)currentPropertyGetter != null, "Field 'currentPropertyGetter' cannot be null");
            Debug.Assert((object)moveNextMethod != null, "Field 'moveNextMethod' cannot be null");

            this.CollectionType = collectionType;
            this.ElementType = elementType;
            this.GetEnumeratorMethod = getEnumeratorMethod;
            this.CurrentPropertyGetter = currentPropertyGetter;
            this.MoveNextMethod = moveNextMethod;
            this.NeedsDisposeMethod = needsDisposeMethod;
            this.CollectionConversion = collectionConversion;
            this.CurrentConversion = currentConversion;
            this.EnumeratorConversion = enumeratorConversion;
            this.Location = location;
        }
Esempio n. 16
0
        public SynthesizedImplementationMethod(
            MethodSymbol interfaceMethod,
            NamedTypeSymbol implementingType,
            string name = null,
            bool debuggerHidden = false,
            PropertySymbol associatedProperty = null,
            MethodSymbol asyncKickoffMethod = null)
        {
            //it does not make sense to add methods to substituted types
            Debug.Assert(implementingType.IsDefinition);

            this.name = name ?? ExplicitInterfaceHelpers.GetMemberName(interfaceMethod.Name, interfaceMethod.ContainingType, aliasQualifierOpt: null);
            this.interfaceMethod = interfaceMethod;
            this.implementingType = implementingType;
            this.debuggerHidden = debuggerHidden;
            this.associatedProperty = associatedProperty;
            this.explicitInterfaceImplementations = ImmutableArray.Create<MethodSymbol>(interfaceMethod);
            this.asyncKickoffMethod = asyncKickoffMethod;

            // alpha-rename to get the implementation's type parameters
            var typeMap = interfaceMethod.ContainingType.TypeSubstitution ?? TypeMap.Empty;
            typeMap.WithAlphaRename(interfaceMethod, this, out this.typeParameters);

            var substitutedInterfaceMethod = interfaceMethod.ConstructIfGeneric(this.typeParameters.Cast<TypeParameterSymbol, TypeSymbol>());
            this.returnType = substitutedInterfaceMethod.ReturnType;
            this.parameters = SynthesizedParameterSymbol.DeriveParameters(substitutedInterfaceMethod, this);
        }
Esempio n. 17
0
        /// <summary>
        /// The flow analysis pass.  This pass reports required diagnostics for unreachable
        /// statements and uninitialized variables (through the call to FlowAnalysisWalker.Analyze),
        /// and inserts a final return statement if the end of a void-returning method is reachable.
        /// </summary>
        /// <param name="method">the method to be analyzed</param>
        /// <param name="block">the method's body</param>
        /// <param name="diagnostics">the receiver of the reported diagnostics</param>
        /// <returns>the rewritten block for the method (with a return statement possibly inserted)</returns>
        public static BoundBlock Rewrite(
            MethodSymbol method,
            BoundBlock block,
            DiagnosticBag diagnostics)
        {
            var compilation = method.DeclaringCompilation;

            if (method.ReturnsVoid || (object)method.IteratorElementType != null
                || (method.IsAsync && compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task) == method.ReturnType))
            {
                if (method.IsImplicitlyDeclared || Analyze(compilation, method, block, diagnostics))
                {
                    // we don't analyze synthesized void methods.
                    var sourceMethod = method as SourceMethodSymbol;
                    block = AppendImplicitReturn(block, method, (object)sourceMethod != null ? sourceMethod.BlockSyntax : null);
                }
            }
            else if (Analyze(compilation, method, block, diagnostics))
            {
                // If the method is a lambda expression being converted to a non-void delegate type
                // and the end point is reachable then suppress the error here; a special error
                // will be reported by the lambda binder.
                Debug.Assert(method.MethodKind != MethodKind.AnonymousFunction);

                // If there's more than one location, then the method is partial and we
                // have already reported a non-void partial method error.
                if (method.Locations.Length == 1)
                {
                    diagnostics.Add(ErrorCode.ERR_ReturnExpected, method.Locations[0], method);
                }
            }

            return block;
        }
Esempio n. 18
0
        // insert the implicit "return" statement at the end of the method body
        // Normally, we wouldn't bother attaching syntax trees to compiler-generated nodes, but these
        // ones are going to have sequence points.
        internal static BoundBlock AppendImplicitReturn(BoundStatement node, MethodSymbol method = null, CSharpSyntaxNode syntax = null)
        {
            if (syntax == null)
            {
                syntax = node.Syntax;
            }

            BoundStatement ret =
                (object)method != null && (object)method.IteratorElementType != null
                ? BoundYieldBreakStatement.Synthesized(syntax) as BoundStatement
                : BoundReturnStatement.Synthesized(syntax, null);

            if (syntax.Kind == SyntaxKind.Block)
            {
                var blockSyntax = (BlockSyntax)syntax;

                ret = new BoundSequencePointWithSpan(
                    blockSyntax,
                    ret,
                    blockSyntax.CloseBraceToken.Span)
                { WasCompilerGenerated = true };
            }

            switch (node.Kind)
            {
                case BoundKind.Block:
                    var block = (BoundBlock)node;
                    return block.Update(block.LocalsOpt, block.Statements.Add(ret));

                default:
                    return new BoundBlock(syntax, ImmutableArray<LocalSymbol>.Empty, ImmutableArray.Create(ret, node));
            }
        }
Esempio n. 19
0
 public UnaryOperatorSignature(UnaryOperatorKind kind, TypeSymbol operandType, TypeSymbol returnType, MethodSymbol method = null)
 {
     this.Kind = kind;
     this.OperandType = operandType;
     this.ReturnType = returnType;
     this.Method = method;
 }
            internal AsyncMethodToClassRewriter(
                MethodSymbol method,
                AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection,
                SyntheticBoundNodeFactory F,
                FieldSymbol state,
                FieldSymbol builder,
                HashSet<Symbol> variablesCaptured,
                Dictionary<Symbol, CapturedSymbolReplacement> initialProxies,
                DiagnosticBag diagnostics,
                bool generateDebugInfo)
                : base(F, method, state, variablesCaptured, initialProxies, diagnostics,
                      useFinalizerBookkeeping: false,
                      generateDebugInfo: generateDebugInfo)
            {
                this.method = method;
                this.asyncMethodBuilderMemberCollection = asyncMethodBuilderMemberCollection;
                this.asyncMethodBuilderField = builder;
                this.exprReturnLabel = F.GenerateLabel("exprReturn");
                this.exitLabel = F.GenerateLabel("exitLabel");

                this.exprRetValue = method.IsGenericTaskReturningAsync(F.Compilation)
                    ? F.SynthesizedLocal(asyncMethodBuilderMemberCollection.ResultType, GeneratedNames.AsyncExprRetValueFieldName())
                    : null;

                this.dynamicFactory = new LoweredDynamicOperationFactory(F);
            }
Esempio n. 21
0
        internal PlaceholderLocalBinder(
            CSharpSyntaxNode syntax,
            ImmutableArray<Alias> aliases,
            MethodSymbol containingMethod,
            EETypeNameDecoder typeNameDecoder,
            Binder next) :
            base(next)
        {
            _syntax = syntax;
            _containingMethod = containingMethod;

            var compilation = next.Compilation;
            var sourceAssembly = compilation.SourceAssembly;

            var aliasesBuilder = ArrayBuilder<LocalSymbol>.GetInstance(aliases.Length);
            var lowercaseBuilder = ImmutableDictionary.CreateBuilder<string, LocalSymbol>();
            foreach (Alias alias in aliases)
            {
                var local = PlaceholderLocalSymbol.Create(
                    typeNameDecoder,
                    containingMethod,
                    sourceAssembly,
                    alias);
                aliasesBuilder.Add(local);

                if (alias.Kind == DkmClrAliasKind.ReturnValue)
                {
                    lowercaseBuilder.Add(local.Name.ToLower(), local);
                }
            }
            _lowercaseReturnValueAliases = lowercaseBuilder.ToImmutableDictionary();
            _aliases = aliasesBuilder.ToImmutableAndFree();
        }
        internal WithPrimaryConstructorParametersBinder(MethodSymbol primaryCtor, Binder next)
            : base(next)
        {
            Debug.Assert((object)primaryCtor != null);
            this.primaryCtor = primaryCtor;
            var parameters = primaryCtor.Parameters;

            var definitionMap = new SmallDictionary<string, ParameterSymbol>();

            for (int i = parameters.Length - 1; i >= 0; i--)
            {
                var parameter = parameters[i];
                definitionMap[parameter.Name] = parameter;
            }

            this.definitionMap = definitionMap;

            var parameterMap = new MultiDictionary<string, ParameterSymbol>(parameters.Length, EqualityComparer<string>.Default);

            foreach (var parameter in parameters)
            {
                parameterMap.Add(parameter.Name, parameter);
            }

            this.parameterMap = parameterMap;
        }
Esempio n. 23
0
        internal static Func<SyntaxNode, SyntaxNode> GetEquivalentNodesMap(MethodSymbol method1, MethodSymbol method0)
        {
            var tree1 = method1.Locations[0].SourceTree;
            var tree0 = method0.Locations[0].SourceTree;
            Assert.NotEqual(tree1, tree0);

            var locals0 = GetAllLocals(method0);
            return s =>
            {
                var s1 = s;
                Assert.Equal(s1.SyntaxTree, tree1);
                foreach (var s0 in locals0)
                {
                    if (!SyntaxFactory.AreEquivalent(s0, s1))
                    {
                        continue;
                    }
                    // Make sure the containing statements are the same.
                    var p0 = GetNearestStatement(s0);
                    var p1 = GetNearestStatement(s1);
                    if (SyntaxFactory.AreEquivalent(p0, p1))
                    {
                        return s0;
                    }
                }
                return null;
            };
        }
Esempio n. 24
0
            internal SynthesizedLambdaMethod(NamedTypeSymbol containingType, MethodSymbol topLevelMethod, BoundLambda node, bool isStatic, TypeCompilationState compilationState)
                : base(containingType,
                       node.Symbol,
                       null,
                       node.SyntaxTree.GetReference(node.Body.Syntax),
                       node.Syntax.GetLocation(),
                       GeneratedNames.MakeLambdaMethodName(topLevelMethod.Name, compilationState.GenerateTempNumber()),
                       (containingType is LambdaFrame ? DeclarationModifiers.Internal : DeclarationModifiers.Private)
                            | (isStatic ? DeclarationModifiers.Static : 0)
                            | (node.Symbol.IsAsync ? DeclarationModifiers.Async : 0))
            {
                TypeMap typeMap;
                ImmutableArray<TypeParameterSymbol> typeParameters;
                LambdaFrame lambdaFrame;

                if (!topLevelMethod.IsGenericMethod)
                {
                    typeMap = TypeMap.Empty;
                    typeParameters = ImmutableArray<TypeParameterSymbol>.Empty;
                }
                else if ((object)(lambdaFrame = this.ContainingType as LambdaFrame) != null)
                {
                    typeMap = lambdaFrame.TypeMap;
                    typeParameters = ImmutableArray<TypeParameterSymbol>.Empty;
                }
                else
                {
                    typeMap = TypeMap.Empty.WithAlphaRename(topLevelMethod, this, out typeParameters);
                }

                AssignTypeMapAndTypeParameters(typeMap, typeParameters);
            }
Esempio n. 25
0
        internal static void BindFieldInitializers(
            SourceMemberContainerTypeSymbol typeSymbol,
            MethodSymbol scriptCtor,
            ImmutableArray<FieldInitializers> fieldInitializers,
            bool generateDebugInfo,
            DiagnosticBag diagnostics,
            ref ProcessedFieldInitializers processedInitializers) //by ref so that we can store the results of lowering
        {
            DiagnosticBag diagsForInstanceInitializers = DiagnosticBag.GetInstance();
            try
            {
                ConsList<Imports> firstDebugImports;

                processedInitializers.BoundInitializers = BindFieldInitializers(typeSymbol, scriptCtor, fieldInitializers,
                    diagsForInstanceInitializers, generateDebugInfo, out firstDebugImports);

                processedInitializers.HasErrors = diagsForInstanceInitializers.HasAnyErrors();
                processedInitializers.FirstDebugImports = firstDebugImports;
            }
            finally
            {
                diagnostics.AddRange(diagsForInstanceInitializers);
                diagsForInstanceInitializers.Free();
            }
        }
        private BoundExpression MakePropertyGetAccess(
            SyntaxNode syntax,
            BoundExpression rewrittenReceiver,
            PropertySymbol property,
            ImmutableArray<BoundExpression> rewrittenArguments,
            MethodSymbol getMethodOpt = null,
            BoundPropertyAccess oldNodeOpt = null)
        {
            if (_inExpressionLambda && rewrittenArguments.IsEmpty)
            {
                return oldNodeOpt != null ?
                    oldNodeOpt.Update(rewrittenReceiver, property, LookupResultKind.Viable, property.Type) :
                    new BoundPropertyAccess(syntax, rewrittenReceiver, property, LookupResultKind.Viable, property.Type);
            }
            else
            {
                var getMethod = getMethodOpt ?? property.GetOwnOrInheritedGetMethod();

                Debug.Assert((object)getMethod != null);
                Debug.Assert(getMethod.ParameterCount == rewrittenArguments.Length);
                Debug.Assert(((object)getMethodOpt == null) || ReferenceEquals(getMethod, getMethodOpt));

                return BoundCall.Synthesized(
                    syntax,
                    rewrittenReceiver,
                    getMethod,
                    rewrittenArguments);
            }
        }
        public MethodToStateMachineRewriter(
            SyntheticBoundNodeFactory F,
            MethodSymbol originalMethod,
            FieldSymbol state,
            IReadOnlySet<Symbol> variablesCaptured,
            IReadOnlyDictionary<Symbol, CapturedSymbolReplacement> nonReusableLocalProxies,
            DiagnosticBag diagnostics,
            bool useFinalizerBookkeeping)
            : base(F.CompilationState, diagnostics)
        {
            Debug.Assert(F != null);
            Debug.Assert(originalMethod != null);
            Debug.Assert(state != null);
            Debug.Assert(nonReusableLocalProxies != null);
            Debug.Assert(diagnostics != null);
            Debug.Assert(variablesCaptured != null);

            this.F = F;
            this.stateField = state;
            this.cachedState = F.SynthesizedLocal(F.SpecialType(SpecialType.System_Int32), kind: SynthesizedLocalKind.StateMachineCachedState);
            this.useFinalizerBookkeeping = useFinalizerBookkeeping;
            this.hasFinalizerState = useFinalizerBookkeeping;
            this.originalMethod = originalMethod;
            this.variablesCaptured = variablesCaptured;

            foreach (var proxy in nonReusableLocalProxies)
            {
                this.proxies.Add(proxy.Key, proxy.Value);
            }
        }
Esempio n. 28
0
        protected StateMachineRewriter(
            BoundStatement body,
            MethodSymbol method,
            SynthesizedContainer stateMachineType,
            VariableSlotAllocator slotAllocatorOpt,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(body != null);
            Debug.Assert(method != null);
            Debug.Assert(stateMachineType != null);
            Debug.Assert(compilationState != null);
            Debug.Assert(diagnostics != null);

            this.body = body;
            this.method = method;
            this.stateMachineType = stateMachineType;
            this.slotAllocatorOpt = slotAllocatorOpt;
            this.synthesizedLocalOrdinals = new SynthesizedLocalOrdinalsDispenser();
            this.diagnostics = diagnostics;

            this.F = new SyntheticBoundNodeFactory(method, body.Syntax, compilationState, diagnostics);
            Debug.Assert(F.CurrentType == method.ContainingType);
            Debug.Assert(F.Syntax == body.Syntax);
        }
Esempio n. 29
0
        internal static ImmutableArray<BoundInitializer> BindFieldInitializers(
            SourceMemberContainerTypeSymbol containingType,
            MethodSymbol scriptCtor,
            ImmutableArray<FieldInitializers> initializers,
            DiagnosticBag diagnostics,
            bool generateDebugInfo,
            out ConsList<Imports> firstDebugImports)
        {
            if (initializers.IsEmpty)
            {
                firstDebugImports = null;
                return ImmutableArray<BoundInitializer>.Empty;
            }

            CSharpCompilation compilation = containingType.DeclaringCompilation;
            ArrayBuilder<BoundInitializer> boundInitializers = ArrayBuilder<BoundInitializer>.GetInstance();

            if ((object)scriptCtor == null)
            {
                BindRegularCSharpFieldInitializers(compilation, initializers, boundInitializers, diagnostics, generateDebugInfo, out firstDebugImports);
            }
            else
            {
                BindScriptFieldInitializers(compilation, scriptCtor, initializers, boundInitializers, diagnostics, generateDebugInfo, out firstDebugImports);
            }

            return boundInitializers.ToImmutableAndFree();
        }
        public static MultiDictionary<Symbol, CSharpSyntaxNode> Analyze(CSharpCompilation compilation, MethodSymbol method, BoundNode node)
        {
            var emptyStructs = new CaptureWalkerEmptyStructTypeCache();
            var initiallyAssignedVariables = UnassignedVariablesWalker.Analyze(compilation, method, node, emptyStructs);

            var walker = new IteratorAndAsyncCaptureWalker(compilation, method, node, emptyStructs, initiallyAssignedVariables);

            bool badRegion = false;
            walker.Analyze(ref badRegion);
            Debug.Assert(!badRegion);

            var result = walker.variablesCaptured;


            if (!method.IsStatic && method.ContainingType.TypeKind == TypeKind.Struct)
            {
                // It is possible that the enclosing method only *writes* to the enclosing struct, but in that
                // case it should be considered captured anyway so that we have a proxy for it to write to.
                result.Add(method.ThisParameter, node.Syntax);
            }

            foreach (var variable in result.Keys.ToArray()) // take a snapshot, as we are modifying the underlying multidictionary
            {
                var local = variable as LocalSymbol;
                if ((object)local != null && local.RefKind != RefKind.None)
                {
                    walker.AddSpillsForRef(walker.refLocalInitializers[local], result[local]);
                }
            }

            walker.Free();
            return result;
        }
        public override IExpression VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
        {
            var             o        = this.semanticModel.GetSymbolInfo(node);
            IExpression     instance = null;
            BoundExpression be       = null;
            var             onLHS    = this.lhs;

            this.lhs = false; // only the right-most member is a l-value: all other member accesses are for r-value.
            var s = o.Symbol;

            if (s != null)
            {
                switch (s.Kind)
                {
                case CommonSymbolKind.Method:
                    R.MethodSymbol ms = (R.MethodSymbol)s;
                    instance = null;
                    if (!s.IsStatic)
                    {
                        instance = this.Visit(node.Expression);
                    }
                    var mr = this.mapper.Map(ms);
                    be = new BoundExpression()
                    {
                        Definition = mr,
                        Instance   = instance,
                        Locations  = Helper.SourceLocation(this.tree, node),
                        Type       = mr.Type,
                    };
                    return(be);

                case CommonSymbolKind.Field:
                    FieldSymbol fs = (FieldSymbol)s;
                    instance = null;
                    if (!fs.IsStatic)
                    {
                        instance = this.Visit(node.Expression);
                    }
                    var fr = this.mapper.Map(fs);
                    // Certain fields represent compile-time constants
                    // REVIEW: Is this the right place to do this?
                    // TODO: All the rest of the constants...
                    if (fr.ContainingType.InternedKey == this.host.PlatformType.SystemInt32.InternedKey)
                    {
                        if (fr.Name.Value.Equals("MinValue"))
                        {
                            return(new CompileTimeConstant()
                            {
                                Type = fr.Type, Value = Int32.MinValue,
                            });
                        }
                        else if (fr.Name.Value.Equals("MaxValue"))
                        {
                            return(new CompileTimeConstant()
                            {
                                Type = fr.Type, Value = Int32.MaxValue,
                            });
                        }
                    }

                    be = new BoundExpression()
                    {
                        Definition = fr,
                        Instance   = instance,
                        Locations  = Helper.SourceLocation(this.tree, node),
                        Type       = fr.Type,
                    };
                    return(be);

                case CommonSymbolKind.Property:
                    R.PropertySymbol ps = (R.PropertySymbol)s;
                    instance = null;
                    if (!ps.IsStatic)
                    {
                        instance = this.Visit(node.Expression);
                    }
                    var accessor = onLHS ? this.mapper.Map(ps.SetMethod) : this.mapper.Map(ps.GetMethod);
                    if (!onLHS && MemberHelper.GetMemberSignature(accessor, NameFormattingOptions.None).Contains("Length"))
                    {
                        return(new VectorLength()
                        {
                            Locations = Helper.SourceLocation(this.tree, node),
                            Type = accessor.Type,
                            Vector = instance,
                        });
                    }
                    return(new MethodCall()
                    {
                        MethodToCall = accessor,
                        IsStaticCall = ps.IsStatic,
                        Locations = Helper.SourceLocation(this.tree, node),
                        ThisArgument = instance,
                        Type = accessor.Type,
                    });

                default:
                    throw new InvalidDataException("VisitMemberAccessExpression: uknown definition kind: " + s.Kind);
                }
            }
            throw new InvalidDataException("VisitMemberAccessExpression couldn't find something to return");
        }
Esempio n. 32
0
 public EmbeddedMethod(EmbeddedType containingType, MethodSymbolAdapter underlyingMethod) :
     base(containingType, underlyingMethod)
 {
 }
            internal AsyncForwardEntryPoint(CSharpCompilation compilation, NamedTypeSymbol containingType, MethodSymbol userMain) :
                base(containingType)
            {
                // There should be no way for a userMain to be passed in unless it already passed the
                // parameter checks for determining entrypoint validity.
                Debug.Assert(userMain.ParameterCount == 0 || userMain.ParameterCount == 1);

                UserMain = userMain;
                _userMainReturnTypeSyntax = userMain.ExtractReturnTypeSyntax();
                var binder = compilation.GetBinder(_userMainReturnTypeSyntax);

                _parameters = SynthesizedParameterSymbol.DeriveParameters(userMain, this);

                var arguments = Parameters.SelectAsArray((p, s) => (BoundExpression) new BoundParameter(s, p, p.Type), _userMainReturnTypeSyntax);

                // Main(args) or Main()
                BoundCall userMainInvocation = new BoundCall(
                    syntax: _userMainReturnTypeSyntax,
                    receiverOpt: null,
                    method: userMain,
                    arguments: arguments,
                    argumentNamesOpt: default(ImmutableArray <string>),
                    argumentRefKindsOpt: default(ImmutableArray <RefKind>),
                    isDelegateCall: false,
                    expanded: false,
                    invokedAsExtensionMethod: false,
                    argsToParamsOpt: default(ImmutableArray <int>),
                    defaultArguments: default(BitVector),
                    resultKind: LookupResultKind.Viable,
                    type: userMain.ReturnType)
                {
                    WasCompilerGenerated = true
                };

                // The diagnostics that would be produced here will already have been captured and returned.
                var success = binder.GetAwaitableExpressionInfo(userMainInvocation, out _getAwaiterGetResultCall !, _userMainReturnTypeSyntax, BindingDiagnosticBag.Discarded);

                Debug.Assert(
                    ReturnType.IsVoidType() ||
                    ReturnType.SpecialType == SpecialType.System_Int32);
            }
 public static MethodSymbol ConstructIfGeneric(this MethodSymbol method, ImmutableArray <TypeWithAnnotations> typeArguments)
 {
     Debug.Assert(method.IsGenericMethod == (typeArguments.Length > 0));
     return(method.IsGenericMethod ? method.Construct(typeArguments) : method);
 }
 internal static bool IsSynthesizedLambda(this MethodSymbol method)
 {
     Debug.Assert((object)method != null);
     return(method.IsImplicitlyDeclared && method.MethodKind == MethodKind.AnonymousFunction);
 }
 public static bool IsParams(this MethodSymbol method)
 {
     return(method.ParameterCount != 0 && method.Parameters[method.ParameterCount - 1].IsParams);
 }
            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, 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();
            }
 /// <summary>
 /// default zero-init constructor symbol is added to a struct when it does not define
 /// its own parameterless public constructor.
 /// We do not emit this constructor and do not call it
 /// </summary>
 internal static bool IsDefaultValueTypeConstructor(this MethodSymbol method)
 {
     return(method.IsImplicitlyDeclared &&
            method.ContainingType.IsValueType &&
            method.IsParameterlessConstructor());
 }
 public static bool IsOperator(this MethodSymbol methodSymbol)
 {
     return(methodSymbol.MethodKind == MethodKind.UserDefinedOperator || methodSymbol.MethodKind == MethodKind.Conversion);
 }
 private static BoundCall CreateParameterlessCall(CSharpSyntaxNode syntax, BoundExpression receiver, MethodSymbol method)
 {
     return(new BoundCall(
                syntax,
                receiver,
                method,
                ImmutableArray <BoundExpression> .Empty,
                default(ImmutableArray <string>),
                default(ImmutableArray <RefKind>),
                isDelegateCall: false,
                expanded: false,
                invokedAsExtensionMethod: false,
                argsToParamsOpt: default(ImmutableArray <int>),
                defaultArguments: default(BitVector),
                resultKind: LookupResultKind.Viable,
                type: method.ReturnType)
     {
         WasCompilerGenerated = true
     });
 }
 public static bool IsAccessor(this MethodSymbol methodSymbol)
 {
     return((object)methodSymbol.AssociatedSymbol != null);
 }
 /// <summary>
 /// NOTE: every struct has a public parameterless constructor either used-defined or default one
 /// </summary>
 internal static bool IsParameterlessConstructor(this MethodSymbol method)
 {
     return(method.MethodKind == MethodKind.Constructor && method.ParameterCount == 0);
 }
Esempio n. 43
0
 protected SubstitutedMethodSymbol(NamedTypeSymbol containingSymbol, TypeMap map, MethodSymbol originalDefinition, MethodSymbol constructedFrom)
 {
     Debug.Assert((object)originalDefinition != null);
     Debug.Assert(originalDefinition.IsDefinition);
     _containingType   = containingSymbol;
     _underlyingMethod = originalDefinition;
     _inputMap         = map;
     if ((object)constructedFrom != null)
     {
         _constructedFrom = constructedFrom;
         Debug.Assert(ReferenceEquals(constructedFrom.ConstructedFrom, constructedFrom));
         _lazyTypeParameters = constructedFrom.TypeParameters;
         _lazyMap            = map;
     }
     else
     {
         _constructedFrom = this;
     }
 }
        public static bool IsIndexedPropertyAccessor(this MethodSymbol methodSymbol)
        {
            var propertyOrEvent = methodSymbol.AssociatedSymbol;

            return(((object)propertyOrEvent != null) && propertyOrEvent.IsIndexedProperty());
        }
Esempio n. 45
0
 public static bool HaveSameReturnTypes(MethodSymbol member1, MethodSymbol member2, TypeCompareKind typeComparison)
 {
     return(HaveSameReturnTypes(member1, GetTypeMap(member1), member2, GetTypeMap(member2), typeComparison));
 }
 public static bool IsImplementable(this MethodSymbol methodOpt)
 {
     return((object)methodOpt != null && (methodOpt.IsAbstract || methodOpt.IsVirtual));
 }
Esempio n. 47
0
 public SynthesizedRecordObjEquals(SourceMemberContainerTypeSymbol containingType, MethodSymbol typedRecordEquals, int memberOffset, DiagnosticBag diagnostics)
     : base(containingType, WellKnownMemberNames.ObjectEquals, memberOffset, diagnostics)
 {
     _typedRecordEquals = typedRecordEquals;
 }
Esempio n. 48
0
        private int _hashCode; // computed on demand

        internal SubstitutedMethodSymbol(NamedTypeSymbol containingSymbol, MethodSymbol originalDefinition)
            : this(containingSymbol, containingSymbol.TypeSubstitution, originalDefinition, constructedFrom : null)
        {
            Debug.Assert(containingSymbol is SubstitutedNamedTypeSymbol || containingSymbol is SubstitutedErrorTypeSymbol);
            Debug.Assert(TypeSymbol.Equals(originalDefinition.ContainingType, containingSymbol.OriginalDefinition, TypeCompareKind.ConsiderEverything2));
        }
 internal ThisParameterSymbol(MethodSymbol forMethod) : this(forMethod, forMethod.ContainingType)
 {
 }
Esempio n. 50
0
        private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsBinder, DiagnosticBag diagnostics)
        {
            SyntaxToken arglistToken;

            // Constraint checking for parameter and return types must be delayed until
            // the method has been added to the containing type member list since
            // evaluating the constraints may depend on accessing this method from
            // the container (comparing this method to others to find overrides for
            // instance). Constraints are checked in AfterAddingTypeMembersChecks.
            var signatureBinder = withTypeParamsBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this);

            _lazyParameters = ParameterHelpers.MakeParameters(signatureBinder, this, syntax.ParameterList, true, out arglistToken, diagnostics);
            _lazyIsVararg   = (arglistToken.Kind() == SyntaxKind.ArgListKeyword);
            _lazyReturnType = signatureBinder.BindType(syntax.ReturnType, diagnostics);

            if (_lazyReturnType.IsRestrictedType())
            {
                if (_lazyReturnType.SpecialType == SpecialType.System_TypedReference &&
                    (this.ContainingType.SpecialType == SpecialType.System_TypedReference || this.ContainingType.SpecialType == SpecialType.System_ArgIterator))
                {
                    // Two special cases: methods in the special types TypedReference and ArgIterator are allowed to return TypedReference
                }
                else
                {
                    // Method or delegate cannot return type '{0}'
                    diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, syntax.ReturnType.Location, _lazyReturnType);
                }
            }

            // set ReturnsVoid flag
            this.SetReturnsVoid(_lazyReturnType.SpecialType == SpecialType.System_Void);

            var location = this.Locations[0];

            this.CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics);

            // Checks taken from MemberDefiner::defineMethod
            if (this.Name == WellKnownMemberNames.DestructorName && this.ParameterCount == 0 && this.Arity == 0 && this.ReturnsVoid)
            {
                diagnostics.Add(ErrorCode.WRN_FinalizeMethod, location);
            }

            // errors relevant for extension methods
            if (IsExtensionMethod)
            {
                var parameter0Type = this.Parameters[0].Type;
                if (!parameter0Type.IsValidExtensionParameterType())
                {
                    // Duplicate Dev10 behavior by selecting the parameter type.
                    var parameterSyntax = syntax.ParameterList.Parameters[0];
                    Debug.Assert(parameterSyntax.Type != null);
                    var loc = parameterSyntax.Type.Location;
                    diagnostics.Add(ErrorCode.ERR_BadTypeforThis, loc, parameter0Type);
                }
                else if ((object)ContainingType.ContainingType != null)
                {
                    diagnostics.Add(ErrorCode.ERR_ExtensionMethodsDecl, location, ContainingType.Name);
                }
                else if (!ContainingType.IsScriptClass && !(ContainingType.IsStatic && ContainingType.Arity == 0))
                {
                    // Duplicate Dev10 behavior by selecting the containing type identifier. However if there
                    // is no containing type (in the interactive case for instance), select the method identifier.
                    var typeDecl   = syntax.Parent as TypeDeclarationSyntax;
                    var identifier = (typeDecl != null) ? typeDecl.Identifier : syntax.Identifier;
                    var loc        = identifier.GetLocation();
                    diagnostics.Add(ErrorCode.ERR_BadExtensionAgg, loc);
                }
                else if (!IsStatic)
                {
                    diagnostics.Add(ErrorCode.ERR_BadExtensionMeth, location);
                }
                else
                {
                    // Verify ExtensionAttribute is available.
                    var attributeConstructor = withTypeParamsBinder.Compilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_ExtensionAttribute__ctor);
                    if ((object)attributeConstructor == null)
                    {
                        var memberDescriptor = WellKnownMembers.GetDescriptor(WellKnownMember.System_Runtime_CompilerServices_ExtensionAttribute__ctor);
                        // do not use Binder.ReportUseSiteErrorForAttributeCtor in this case, because we'll need to report a special error id, not a generic use site error.
                        diagnostics.Add(
                            ErrorCode.ERR_ExtensionAttrNotFound,
                            syntax.ParameterList.Parameters[0].Modifiers.FirstOrDefault(SyntaxKind.ThisKeyword).GetLocation(),
                            memberDescriptor.DeclaringTypeMetadataName);
                    }
                }
            }

            if (this.MethodKind == MethodKind.UserDefinedOperator)
            {
                foreach (var p in this.Parameters)
                {
                    if (p.RefKind != RefKind.None)
                    {
                        diagnostics.Add(ErrorCode.ERR_IllegalRefParam, location);
                        break;
                    }
                }
            }
            else if (IsPartial)
            {
                // check that there are no out parameters in a partial
                foreach (var p in this.Parameters)
                {
                    if (p.RefKind == RefKind.Out)
                    {
                        diagnostics.Add(ErrorCode.ERR_PartialMethodCannotHaveOutParameters, location);
                        break;
                    }
                }

                if (MethodKind == MethodKind.ExplicitInterfaceImplementation)
                {
                    diagnostics.Add(ErrorCode.ERR_PartialMethodNotExplicit, location);
                }

                if (!ContainingType.IsPartial() || ContainingType.IsInterface)
                {
                    diagnostics.Add(ErrorCode.ERR_PartialMethodOnlyInPartialClass, location);
                }
            }

            if (!IsPartial)
            {
                LazyAsyncMethodChecks(CancellationToken.None);
                Debug.Assert(state.HasComplete(CompletionPart.FinishAsyncMethodChecks));
            }

            // The runtime will not treat this method as an override or implementation of another
            // method 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 signature of the overridden/implemented method.  (From source, we know
            // that there can only be one such method, so there are no conflicts.)  This is
            // unnecessary for implicit implementations because, if the custom modifiers don't match,
            // we'll insert a bridge method (an explicit implementation that delegates to the implicit
            // implementation) with the correct custom modifiers
            // (see SourceNamedTypeSymbol.ImplementInterfaceMember).

            // 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 property if this is supposed to be an explicit implementation.
            if (syntax.ExplicitInterfaceSpecifier == null)
            {
                Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;

                // This value may not be correct, but we need something while we compute this.OverriddenMethod.
                // May be re-assigned below.
                Debug.Assert(_lazyReturnTypeCustomModifiers.IsDefault);
                _lazyReturnTypeCustomModifiers = ImmutableArray <CustomModifier> .Empty;

                // If this method is an override, we may need to copy custom modifiers from
                // the overridden method (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)
                {
                    // This computation will necessarily be performed with partially incomplete
                    // information.  There is no way we can determine the complete signature
                    // (i.e. including custom modifiers) until we have found the method that
                    // this method overrides.  To accommodate this, MethodSymbol.OverriddenOrHiddenMembers
                    // is written to allow relaxed matching of custom modifiers for source methods,
                    // on the assumption that they will be updated appropriately.
                    MethodSymbol overriddenMethod = this.OverriddenMethod;

                    if ((object)overriddenMethod != null)
                    {
                        CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType, out _lazyReturnTypeCustomModifiers, out _lazyParameters, alsoCopyParamsModifier: true);
                    }
                }
            }
            else if ((object)_explicitInterfaceType != null)
            {
                //do this last so that it can assume the method symbol is constructed (except for ExplicitInterfaceImplementation)
                MethodSymbol implementedMethod = this.FindExplicitlyImplementedMethod(_explicitInterfaceType, syntax.Identifier.ValueText, syntax.ExplicitInterfaceSpecifier, diagnostics);

                if ((object)implementedMethod != null)
                {
                    Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                    _lazyExplicitInterfaceImplementations = ImmutableArray.Create <MethodSymbol>(implementedMethod);

                    CustomModifierUtils.CopyMethodCustomModifiers(implementedMethod, this, out _lazyReturnType, out _lazyReturnTypeCustomModifiers, out _lazyParameters, alsoCopyParamsModifier: false);
                }
                else
                {
                    Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                    _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;

                    Debug.Assert(_lazyReturnTypeCustomModifiers.IsDefault);
                    _lazyReturnTypeCustomModifiers = ImmutableArray <CustomModifier> .Empty;
                }
            }

            CheckModifiers(location, diagnostics);
        }
        /// <summary>
        /// Construct a body for a method containing a call to a single other method with the same signature (modulo name).
        /// </summary>
        /// <param name="F">Bound node factory.</param>
        /// <param name="methodToInvoke">Method to invoke in constructed body.</param>
        /// <param name="useBaseReference">True for "base.", false for "this.".</param>
        /// <returns>Body for implementedMethod.</returns>
        internal static BoundBlock ConstructSingleInvocationMethodBody(SyntheticBoundNodeFactory F, MethodSymbol methodToInvoke, bool useBaseReference)
        {
            var argBuilder = ArrayBuilder <BoundExpression> .GetInstance();

            //var refKindBuilder = ArrayBuilder<RefKind>.GetInstance();

            foreach (var param in F.CurrentFunction.Parameters)
            {
                argBuilder.Add(F.Parameter(param));
                //refKindBuilder.Add(param.RefKind);
            }

            BoundExpression invocation = F.Call(useBaseReference ? (BoundExpression)F.Base() : F.This(),
                                                methodToInvoke,
                                                argBuilder.ToImmutableAndFree());

            return(F.CurrentFunction.ReturnsVoid
                        ? F.Block(F.ExpressionStatement(invocation), F.Return())
                        : F.Block(F.Return(invocation)));
        }
 internal SubstitutedParameterSymbol(MethodSymbol containingSymbol, TypeMap map, ParameterSymbol originalParameter) :
     this((Symbol)containingSymbol, map, originalParameter)
 {
 }
Esempio n. 53
0
 internal SourceAttributeData(SyntaxReference applicationNode, NamedTypeSymbol attributeClass, MethodSymbol attributeConstructor, bool hasErrors)
     : this(
         applicationNode,
         attributeClass,
         attributeConstructor,
         constructorArguments : ImmutableArray <TypedConstant> .Empty,
         constructorArgumentsSourceIndices : default(ImmutableArray <int>),
         namedArguments : ImmutableArray <KeyValuePair <string, TypedConstant> > .Empty,
         hasErrors : hasErrors,
         isConditionallyOmitted : false)
 {
 }
            internal ScriptEntryPoint(NamedTypeSymbol containingType, TypeSymbol returnType, MethodSymbol getAwaiterMethod, MethodSymbol getResultMethod) :
                base(containingType, returnType)
            {
                Debug.Assert(containingType.IsScriptClass);
                Debug.Assert(returnType.SpecialType == SpecialType.System_Void);

                _getAwaiterMethod = getAwaiterMethod;
                _getResultMethod  = getResultMethod;
            }
Esempio n. 55
0
 /// <summary>
 /// Accumulate diagnostics related to the variance safety of an interface method type parameters.
 /// </summary>
 private static void CheckTypeParametersVarianceSafety(ImmutableArray <TypeParameterSymbol> typeParameters, MethodSymbol context, DiagnosticBag diagnostics)
 {
     foreach (TypeParameterSymbol typeParameter in typeParameters)
     {
         foreach (TypeSymbol constraintType in typeParameter.ConstraintTypesNoUseSiteDiagnostics)
         {
             IsVarianceUnsafe(constraintType,
                              requireOutputSafety: false,
                              requireInputSafety: true,
                              context: context,
                              locationProvider: t => t.Locations[0],
                              locationArg: typeParameter,
                              diagnostics: diagnostics);
         }
     }
 }
Esempio n. 56
0
        /// <summary>
        /// For each parameter of a source method, construct a corresponding synthesized parameter
        /// for a destination method.
        /// </summary>
        /// <param name="sourceMethod">Has parameters.</param>
        /// <param name="destinationMethod">Needs parameters.</param>
        /// <returns>Synthesized parameters to add to destination method.</returns>
        internal static ImmutableArray <ParameterSymbol> DeriveParameters(MethodSymbol sourceMethod, MethodSymbol destinationMethod)
        {
            var builder = ArrayBuilder <ParameterSymbol> .GetInstance();

            foreach (var oldParam in sourceMethod.Parameters)
            {
                //same properties as the old one, just change the owner
                builder.Add(new SynthesizedParameterSymbol(destinationMethod, oldParam.Type, oldParam.Ordinal,
                                                           oldParam.RefKind, oldParam.Name, oldParam.CustomModifiers, oldParam.CountOfCustomModifiersPrecedingByRef));
            }

            return(builder.ToImmutableAndFree());
        }
            internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics)
            {
                AnonymousTypeManager      manager = ((AnonymousTypeTemplateSymbol)this.ContainingType).Manager;
                SyntheticBoundNodeFactory F       = this.CreateBoundNodeFactory(compilationState, diagnostics);

                //  Method body:
                //
                //  HASH_FACTOR = 0xa5555529;
                //  INIT_HASH = (...((0 * HASH_FACTOR) + GetFNVHashCode(backingFld_1.Name)) * HASH_FACTOR
                //                                     + GetFNVHashCode(backingFld_2.Name)) * HASH_FACTOR
                //                                     + ...
                //                                     + GetFNVHashCode(backingFld_N.Name)
                //
                //  {
                //      return (...((INITIAL_HASH * HASH_FACTOR) + EqualityComparer<T_1>.Default.GetHashCode(this.backingFld_1)) * HASH_FACTOR
                //                                               + EqualityComparer<T_2>.Default.GetHashCode(this.backingFld_2)) * HASH_FACTOR
                //                                               ...
                //                                               + EqualityComparer<T_N>.Default.GetHashCode(this.backingFld_N)
                //  }
                //
                // Where GetFNVHashCode is the FNV-1a hash code.

                const int HASH_FACTOR = -1521134295; // (int)0xa5555529

                // Type expression
                AnonymousTypeTemplateSymbol anonymousType = (AnonymousTypeTemplateSymbol)this.ContainingType;

                //  INIT_HASH
                int initHash = 0;

                foreach (var property in anonymousType.Properties)
                {
                    initHash = unchecked (initHash * HASH_FACTOR + Hash.GetFNVHashCode(property.BackingField.Name));
                }

                //  Generate expression for return statement
                //      retExpression <= 'INITIAL_HASH'
                BoundExpression retExpression = F.Literal(initHash);

                //  prepare symbols
                MethodSymbol    equalityComparer_GetHashCode = manager.System_Collections_Generic_EqualityComparer_T__GetHashCode;
                MethodSymbol    equalityComparer_get_Default = manager.System_Collections_Generic_EqualityComparer_T__get_Default;
                NamedTypeSymbol equalityComparerType         = equalityComparer_GetHashCode.ContainingType;

                //  bound HASH_FACTOR
                BoundLiteral boundHashFactor = F.Literal(HASH_FACTOR);

                // Process fields
                for (int index = 0; index < anonymousType.Properties.Length; index++)
                {
                    // Prepare constructed symbols
                    TypeParameterSymbol typeParameter = anonymousType.TypeParameters[index];
                    NamedTypeSymbol     constructedEqualityComparer = equalityComparerType.Construct(typeParameter);

                    // Generate 'retExpression' <= 'retExpression * HASH_FACTOR
                    retExpression = F.Binary(BinaryOperatorKind.IntMultiplication, manager.System_Int32, retExpression, boundHashFactor);

                    // Generate 'retExpression' <= 'retExpression + EqualityComparer<T_index>.Default.GetHashCode(this.backingFld_index)'
                    retExpression = F.Binary(BinaryOperatorKind.IntAddition,
                                             manager.System_Int32,
                                             retExpression,
                                             F.Call(
                                                 F.StaticCall(constructedEqualityComparer,
                                                              equalityComparer_get_Default.AsMember(constructedEqualityComparer)),
                                                 equalityComparer_GetHashCode.AsMember(constructedEqualityComparer),
                                                 F.Field(F.This(), anonymousType.Properties[index].BackingField)));
                }

                // Create a bound block
                F.CloseMethod(F.Block(F.Return(retExpression)));
            }
Esempio n. 58
0
 public SynthesizedParameterSymbolWithDefaultValue(MethodSymbol container, TypeSymbolWithAnnotations type, int ordinal, ConstantValue defaultValue, string name)
     : base(container, type, ordinal, RefKind.None, name)
 {
     Debug.Assert(!defaultValue.IsBad);
     _defaultValue = defaultValue;
 }
Esempio n. 59
0
 internal XsFoxMemberAccessSymbol(string alias, string name, MethodSymbol getMethod, MethodSymbol setMethod, TypeSymbol type) :
     base(alias, name, getMethod, setMethod, type)
 {
 }
            internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics)
            {
                AnonymousTypeManager      manager = ((AnonymousTypeTemplateSymbol)this.ContainingType).Manager;
                SyntheticBoundNodeFactory F       = this.CreateBoundNodeFactory(compilationState, diagnostics);

                //  Method body:
                //
                //  {
                //      $anonymous$ local = value as $anonymous$;
                //      return local != null
                //             && System.Collections.Generic.EqualityComparer<T_1>.Default.Equals(this.backingFld_1, local.backingFld_1)
                //             ...
                //             && System.Collections.Generic.EqualityComparer<T_N>.Default.Equals(this.backingFld_N, local.backingFld_N);
                //  }

                // Type and type expression
                AnonymousTypeTemplateSymbol anonymousType = (AnonymousTypeTemplateSymbol)this.ContainingType;

                //  local
                BoundAssignmentOperator assignmentToTemp;
                BoundLocal boundLocal = F.StoreToTemp(F.As(F.Parameter(_parameters[0]), anonymousType), out assignmentToTemp);

                //  Generate: statement <= 'local = value as $anonymous$'
                BoundStatement assignment = F.ExpressionStatement(assignmentToTemp);

                //  Generate expression for return statement
                //      retExpression <= 'local != null'
                BoundExpression retExpression = F.Binary(BinaryOperatorKind.ObjectNotEqual,
                                                         manager.System_Boolean,
                                                         F.Convert(manager.System_Object, boundLocal),
                                                         F.Null(manager.System_Object));

                //  prepare symbols
                MethodSymbol    equalityComparer_Equals      = manager.System_Collections_Generic_EqualityComparer_T__Equals;
                MethodSymbol    equalityComparer_get_Default = manager.System_Collections_Generic_EqualityComparer_T__get_Default;
                NamedTypeSymbol equalityComparerType         = equalityComparer_Equals.ContainingType;

                // Compare fields
                for (int index = 0; index < anonymousType.Properties.Length; index++)
                {
                    // Prepare constructed symbols
                    TypeParameterSymbol typeParameter = anonymousType.TypeParameters[index];
                    FieldSymbol         fieldSymbol   = anonymousType.Properties[index].BackingField;
                    NamedTypeSymbol     constructedEqualityComparer = equalityComparerType.Construct(typeParameter);

                    // Generate 'retExpression' = 'retExpression && System.Collections.Generic.EqualityComparer<T_index>.
                    //                                                  Default.Equals(this.backingFld_index, local.backingFld_index)'
                    retExpression = F.LogicalAnd(retExpression,
                                                 F.Call(F.StaticCall(constructedEqualityComparer,
                                                                     equalityComparer_get_Default.AsMember(constructedEqualityComparer)),
                                                        equalityComparer_Equals.AsMember(constructedEqualityComparer),
                                                        F.Field(F.This(), fieldSymbol),
                                                        F.Field(boundLocal, fieldSymbol)));
                }

                // Final return statement
                BoundStatement retStatement = F.Return(retExpression);

                // Create a bound block
                F.CloseMethod(F.Block(ImmutableArray.Create <LocalSymbol>(boundLocal.LocalSymbol), assignment, retStatement));
            }