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); }
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; }
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); }
private LocalBinderFactory(MethodSymbol method, Binder enclosing) { Debug.Assert((object)method != null); _map = new SmallDictionary<CSharpSyntaxNode, Binder>(ReferenceEqualityComparer.Instance); _method = method; _enclosing = enclosing; }
/// <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(); }
/// <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; }
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); }
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; }
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); }
/// <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; }
// 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)); } }
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); }
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; }
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; }; }
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); }
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); } }
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); }
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"); }
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); }
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()); }
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)); }
public SynthesizedRecordObjEquals(SourceMemberContainerTypeSymbol containingType, MethodSymbol typedRecordEquals, int memberOffset, DiagnosticBag diagnostics) : base(containingType, WellKnownMemberNames.ObjectEquals, memberOffset, diagnostics) { _typedRecordEquals = typedRecordEquals; }
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) { }
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) { }
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; }
/// <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); } } }
/// <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))); }
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; }
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)); }