internal SubmissionEntryPoint(NamedTypeSymbol containingType, TypeWithAnnotations returnType, TypeSymbol submissionArrayType) : base(containingType) { Debug.Assert(containingType.IsSubmissionClass); Debug.Assert(!returnType.IsVoidType()); _parameters = ImmutableArray.Create(SynthesizedParameterSymbol.Create(this, TypeWithAnnotations.Create(submissionArrayType), 0, RefKind.None, "submissionArray")); _returnType = returnType; }
// private static T <Factory>(object[] submissionArray) // { // var submission = new Submission#N(submissionArray); // return submission.<Initialize>(); // } internal override BoundBlock CreateBody(DiagnosticBag diagnostics) { var syntax = DummySyntax(); var ctor = _containingType.GetScriptConstructor(); Debug.Assert(ctor.ParameterCount == 1); var initializer = _containingType.GetScriptInitializer(); Debug.Assert(initializer.ParameterCount == 0); var submissionArrayParameter = new BoundParameter(syntax, _parameters[0]) { WasCompilerGenerated = true }; var submissionLocal = new BoundLocal( syntax, new SynthesizedLocal(this, TypeWithAnnotations.Create(_containingType), SynthesizedLocalKind.LoweringTemp), null, _containingType) { WasCompilerGenerated = true }; // var submission = new Submission#N(submissionArray); var submissionAssignment = new BoundExpressionStatement( syntax, new BoundAssignmentOperator( syntax, submissionLocal, new BoundObjectCreationExpression( syntax, ctor, ImmutableArray.Create <BoundExpression>(submissionArrayParameter), default(ImmutableArray <string>), default(ImmutableArray <RefKind>), false, default(ImmutableArray <int>), null, null, null, _containingType) { WasCompilerGenerated = true }, _containingType) { WasCompilerGenerated = true }) { WasCompilerGenerated = true }; // return submission.<Initialize>(); var initializeResult = CreateParameterlessCall( syntax, submissionLocal, initializer); Debug.Assert(TypeSymbol.Equals(initializeResult.Type, _returnType.Type, TypeCompareKind.ConsiderEverything2)); var returnStatement = new BoundReturnStatement( syntax, RefKind.None, initializeResult) { WasCompilerGenerated = true }; return(new BoundBlock(syntax, ImmutableArray.Create <LocalSymbol>(submissionLocal.LocalSymbol), ImmutableArray.Create <BoundStatement>(submissionAssignment, returnStatement)) { WasCompilerGenerated = true }); }
/// <summary> /// Resolves <see cref="System.Type"/> to a <see cref="TypeSymbol"/> available in this assembly /// its referenced assemblies. /// </summary> /// <param name="type">The type to resolve.</param> /// <param name="includeReferences">Use referenced assemblies for resolution.</param> /// <returns>The resolved symbol if successful or null on failure.</returns> internal TypeSymbol GetTypeByReflectionType(Type type, bool includeReferences) { System.Reflection.TypeInfo typeInfo = type.GetTypeInfo(); Debug.Assert(!typeInfo.IsByRef); // not supported (we don't accept open types as submission results nor host types): Debug.Assert(!typeInfo.ContainsGenericParameters); if (typeInfo.IsArray) { TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences); if ((object)symbol == null) { return(null); } int rank = typeInfo.GetArrayRank(); return(ArrayTypeSymbol.CreateCSharpArray(this, TypeWithAnnotations.Create(symbol), rank)); } else if (typeInfo.IsPointer) { TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences); if ((object)symbol == null) { return(null); } return(new PointerTypeSymbol(TypeWithAnnotations.Create(symbol))); } else if (typeInfo.DeclaringType != null) { Debug.Assert(!typeInfo.IsArray); // consolidated generic arguments (includes arguments of all declaring types): Type[] genericArguments = typeInfo.GenericTypeArguments; int typeArgumentIndex = 0; var currentTypeInfo = typeInfo.IsGenericType ? typeInfo.GetGenericTypeDefinition().GetTypeInfo() : typeInfo; var nestedTypes = ArrayBuilder <System.Reflection.TypeInfo> .GetInstance(); while (true) { Debug.Assert(currentTypeInfo.IsGenericTypeDefinition || !currentTypeInfo.IsGenericType); nestedTypes.Add(currentTypeInfo); if (currentTypeInfo.DeclaringType == null) { break; } currentTypeInfo = currentTypeInfo.DeclaringType.GetTypeInfo(); } int i = nestedTypes.Count - 1; var symbol = (NamedTypeSymbol)GetTypeByReflectionType(nestedTypes[i].AsType(), includeReferences); if ((object)symbol == null) { return(null); } while (--i >= 0) { int forcedArity = nestedTypes[i].GenericTypeParameters.Length - nestedTypes[i + 1].GenericTypeParameters.Length; MetadataTypeName mdName = MetadataTypeName.FromTypeName(nestedTypes[i].Name, forcedArity: forcedArity); symbol = symbol.LookupMetadataType(ref mdName); if ((object)symbol == null || symbol.IsErrorType()) { return(null); } symbol = ApplyGenericArguments(symbol, genericArguments, ref typeArgumentIndex, includeReferences); if ((object)symbol == null) { return(null); } } nestedTypes.Free(); Debug.Assert(typeArgumentIndex == genericArguments.Length); return(symbol); } else { AssemblyIdentity assemblyId = AssemblyIdentity.FromAssemblyDefinition(typeInfo.Assembly); MetadataTypeName mdName = MetadataTypeName.FromNamespaceAndTypeName( typeInfo.Namespace ?? string.Empty, typeInfo.Name, forcedArity: typeInfo.GenericTypeArguments.Length); NamedTypeSymbol symbol = GetTopLevelTypeByMetadataName(ref mdName, assemblyId, includeReferences, isWellKnownType: false, conflicts: out var _); if ((object)symbol == null || symbol.IsErrorType()) { return(null); } int typeArgumentIndex = 0; Type[] genericArguments = typeInfo.GenericTypeArguments; symbol = ApplyGenericArguments(symbol, genericArguments, ref typeArgumentIndex, includeReferences); Debug.Assert(typeArgumentIndex == genericArguments.Length); return(symbol); } }
// private static void <Main>() // { // var script = new Script(); // script.<Initialize>().GetAwaiter().GetResult(); // } internal override BoundBlock CreateBody(DiagnosticBag diagnostics) { var syntax = DummySyntax(); var compilation = _containingType.DeclaringCompilation; // Creates a new top-level binder that just contains the global imports for the compilation. // The imports are required if a consumer of the scripting API is using a Task implementation // that uses extension methods. var binder = new InContainerBinder( container: null, next: new BuckStopsHereBinder(compilation), imports: compilation.GlobalImports); binder = new InContainerBinder(compilation.GlobalNamespace, binder); var ctor = _containingType.GetScriptConstructor(); Debug.Assert(ctor.ParameterCount == 0); var initializer = _containingType.GetScriptInitializer(); Debug.Assert(initializer.ParameterCount == 0); var scriptLocal = new BoundLocal( syntax, new SynthesizedLocal(this, TypeWithAnnotations.Create(_containingType), SynthesizedLocalKind.LoweringTemp), null, _containingType) { WasCompilerGenerated = true }; Debug.Assert(!initializer.ReturnType.IsDynamic()); var initializeCall = CreateParameterlessCall(syntax, scriptLocal, initializer); BoundExpression getAwaiterGetResultCall; if (!binder.GetAwaitableExpressionInfo(initializeCall, out getAwaiterGetResultCall, syntax, diagnostics)) { return(new BoundBlock( syntax: syntax, locals: ImmutableArray <LocalSymbol> .Empty, statements: ImmutableArray <BoundStatement> .Empty, hasErrors: true)); } return(new BoundBlock(syntax, ImmutableArray.Create <LocalSymbol>(scriptLocal.LocalSymbol), ImmutableArray.Create <BoundStatement>( // var script = new Script(); new BoundExpressionStatement( syntax, new BoundAssignmentOperator( syntax, scriptLocal, new BoundObjectCreationExpression( syntax, ctor, null) { WasCompilerGenerated = true }, _containingType) { WasCompilerGenerated = true }) { WasCompilerGenerated = true }, // script.<Initialize>().GetAwaiter().GetResult(); new BoundExpressionStatement(syntax, getAwaiterGetResultCall) { WasCompilerGenerated = true }, // return; new BoundReturnStatement( syntax, RefKind.None, null) { WasCompilerGenerated = true })) { WasCompilerGenerated = true }); }
protected override TypeWithAnnotations InferTypeOfVarVariable(BindingDiagnosticBag diagnostics) { BoundExpression initializerOpt = this._initializerBinder.BindInferredVariableInitializer(diagnostics, RefKind, _initializer, _initializer); return(TypeWithAnnotations.Create(initializerOpt?.Type)); }
internal sealed override TypeWithAnnotations GetFieldType(ConsList <FieldSymbol> fieldsBeingBound) { Debug.Assert(fieldsBeingBound != null); if (!_lazyType.IsDefault) { return(_lazyType.ToType()); } var declarator = VariableDeclaratorNode; var fieldSyntax = GetFieldDeclaration(declarator); var typeSyntax = fieldSyntax.Declaration.Type; var compilation = this.DeclaringCompilation; var diagnostics = DiagnosticBag.GetInstance(); TypeWithAnnotations type; // When we have multiple declarators, we report the type diagnostics on only the first. DiagnosticBag diagnosticsForFirstDeclarator = DiagnosticBag.GetInstance(); Symbol associatedPropertyOrEvent = this.AssociatedSymbol; if ((object)associatedPropertyOrEvent != null && associatedPropertyOrEvent.Kind == SymbolKind.Event) { EventSymbol @event = (EventSymbol)associatedPropertyOrEvent; if (@event.IsWindowsRuntimeEvent) { NamedTypeSymbol tokenTableType = this.DeclaringCompilation.GetWellKnownType(WellKnownType.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationTokenTable_T); Binder.ReportUseSiteDiagnostics(tokenTableType, diagnosticsForFirstDeclarator, this.ErrorLocation); // CONSIDER: Do we want to guard against the possibility that someone has created their own EventRegistrationTokenTable<T> // type that has additional generic constraints? type = TypeWithAnnotations.Create(tokenTableType.Construct(ImmutableArray.Create(@event.TypeWithAnnotations))); } else { type = @event.TypeWithAnnotations; } } else { var binderFactory = compilation.GetBinderFactory(SyntaxTree); var binder = binderFactory.GetBinder(typeSyntax); binder = binder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this); if (!ContainingType.IsScriptClass) { type = binder.BindType(typeSyntax, diagnosticsForFirstDeclarator); } else { bool isVar; type = binder.BindTypeOrVarKeyword(typeSyntax, diagnostics, out isVar); Debug.Assert(type.HasType || isVar); if (isVar) { if (this.IsConst) { diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_ImplicitlyTypedVariableCannotBeConst, typeSyntax.Location); } if (fieldsBeingBound.ContainsReference(this)) { diagnostics.Add(ErrorCode.ERR_RecursivelyTypedVariable, this.ErrorLocation, this); type = default; } else if (fieldSyntax.Declaration.Variables.Count > 1) { diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_ImplicitlyTypedVariableMultipleDeclarator, typeSyntax.Location); } else if (this.IsConst && this.ContainingType.IsScriptClass) { // For const var in script, we won't try to bind the initializer (case below), as it can lead to an unbound recursion type = default; } else { fieldsBeingBound = new ConsList <FieldSymbol>(this, fieldsBeingBound); var initializerBinder = new ImplicitlyTypedFieldBinder(binder, fieldsBeingBound); var initializerOpt = initializerBinder.BindInferredVariableInitializer(diagnostics, RefKind.None, (EqualsValueClauseSyntax)declarator.Initializer, declarator); if (initializerOpt != null) { if ((object)initializerOpt.Type != null && !initializerOpt.Type.IsErrorType()) { type = TypeWithAnnotations.Create(initializerOpt.Type); } _lazyFieldTypeInferred = 1; } } if (!type.HasType) { type = TypeWithAnnotations.Create(binder.CreateErrorType("var")); } } } if (IsFixedSizeBuffer) { type = TypeWithAnnotations.Create(new PointerTypeSymbol(type)); if (ContainingType.TypeKind != TypeKind.Struct) { diagnostics.Add(ErrorCode.ERR_FixedNotInStruct, ErrorLocation); } var elementType = ((PointerTypeSymbol)type.Type).PointedAtType; int elementSize = elementType.FixedBufferElementSizeInBytes(); if (elementSize == 0) { var loc = typeSyntax.Location; diagnostics.Add(ErrorCode.ERR_IllegalFixedType, loc); } if (!binder.InUnsafeRegion) { diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_UnsafeNeeded, declarator.Location); } } } // update the lazyType only if it contains value last seen by the current thread: if (_lazyType.InterlockedInitialize(type.WithModifiers(this.RequiredCustomModifiers))) { TypeChecks(type.Type, diagnostics); // CONSIDER: SourceEventFieldSymbol would like to suppress these diagnostics. compilation.DeclarationDiagnostics.AddRange(diagnostics); bool isFirstDeclarator = fieldSyntax.Declaration.Variables[0] == declarator; if (isFirstDeclarator) { compilation.DeclarationDiagnostics.AddRange(diagnosticsForFirstDeclarator); } state.NotePartComplete(CompletionPart.Type); } diagnostics.Free(); diagnosticsForFirstDeclarator.Free(); return(_lazyType.ToType()); }
protected virtual TypeWithAnnotations SubstituteTypeParameter(TypeParameterSymbol typeParameter) { return TypeWithAnnotations.Create(typeParameter); }
/// <summary> /// Called by <see cref="AbstractTypeMap.SubstituteType(TypeSymbol)"/> to perform substitution /// on types with TypeKind ErrorType. The general pattern is to use the type map /// to perform substitution on the wrapped type, if any, and then construct a new /// error type symbol from the result (if there was a change). /// </summary> internal TypeWithAnnotations Substitute(AbstractTypeMap typeMap) { return(TypeWithAnnotations.Create(typeMap.SubstituteNamedType(this))); }
/// <summary> /// If the extension method is applicable based on the "this" argument type, return /// the method constructed with the inferred type arguments. If the method is not an /// unconstructed generic method, type inference is skipped. If the method is not /// applicable, or if constraints when inferring type parameters from the "this" type /// are not satisfied, the return value is null. /// </summary> /// <param name="compilation">Compilation used to check constraints. The latest language version is assumed if this is null.</param> private static MethodSymbol InferExtensionMethodTypeArguments(MethodSymbol method, TypeSymbol thisType, CSharpCompilation compilation, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { Debug.Assert(method.IsExtensionMethod); Debug.Assert((object)thisType != null); if (!method.IsGenericMethod || method != method.ConstructedFrom) { return(method); } // We never resolve extension methods on a dynamic receiver. if (thisType.IsDynamic()) { return(null); } var containingAssembly = method.ContainingAssembly; var errorNamespace = containingAssembly.GlobalNamespace; var conversions = new TypeConversions(containingAssembly.CorLibrary); // There is absolutely no plausible syntax/tree that we could use for these // synthesized literals. We could be speculatively binding a call to a PE method. var syntaxTree = CSharpSyntaxTree.Dummy; var syntax = (CSharpSyntaxNode)syntaxTree.GetRoot(); // Create an argument value for the "this" argument of specific type, // and pass the same bad argument value for all other arguments. var thisArgumentValue = new BoundLiteral(syntax, ConstantValue.Bad, thisType) { WasCompilerGenerated = true }; var otherArgumentType = new ExtendedErrorTypeSymbol(errorNamespace, name: string.Empty, arity: 0, errorInfo: null, unreported: false); var otherArgumentValue = new BoundLiteral(syntax, ConstantValue.Bad, otherArgumentType) { WasCompilerGenerated = true }; var paramCount = method.ParameterCount; var arguments = new BoundExpression[paramCount]; for (int i = 0; i < paramCount; i++) { var argument = (i == 0) ? thisArgumentValue : otherArgumentValue; arguments[i] = argument; } var typeArgs = MethodTypeInferrer.InferTypeArgumentsFromFirstArgument( conversions, method, arguments.AsImmutable(), useSiteDiagnostics: ref useSiteDiagnostics); if (typeArgs.IsDefault) { return(null); } // For the purpose of constraint checks we use error type symbol in place of type arguments that we couldn't infer from the first argument. // This prevents constraint checking from failing for corresponding type parameters. int firstNullInTypeArgs = -1; var notInferredTypeParameters = PooledHashSet <TypeParameterSymbol> .GetInstance(); var typeParams = method.TypeParameters; var typeArgsForConstraintsCheck = typeArgs; for (int i = 0; i < typeArgsForConstraintsCheck.Length; i++) { if (!typeArgsForConstraintsCheck[i].HasType) { firstNullInTypeArgs = i; var builder = ArrayBuilder <TypeWithAnnotations> .GetInstance(); builder.AddRange(typeArgsForConstraintsCheck, firstNullInTypeArgs); for (; i < typeArgsForConstraintsCheck.Length; i++) { var typeArg = typeArgsForConstraintsCheck[i]; if (!typeArg.HasType) { notInferredTypeParameters.Add(typeParams[i]); builder.Add(TypeWithAnnotations.Create(ErrorTypeSymbol.UnknownResultType)); } else { builder.Add(typeArg); } } typeArgsForConstraintsCheck = builder.ToImmutableAndFree(); break; } } // Check constraints. var diagnosticsBuilder = ArrayBuilder <TypeParameterDiagnosticInfo> .GetInstance(); var substitution = new TypeMap(typeParams, typeArgsForConstraintsCheck); ArrayBuilder <TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null; var success = method.CheckConstraints(conversions, substitution, typeParams, typeArgsForConstraintsCheck, compilation, diagnosticsBuilder, nullabilityDiagnosticsBuilderOpt: null, ref useSiteDiagnosticsBuilder, ignoreTypeConstraintsDependentOnTypeParametersOpt: notInferredTypeParameters.Count > 0 ? notInferredTypeParameters : null); diagnosticsBuilder.Free(); notInferredTypeParameters.Free(); if (useSiteDiagnosticsBuilder != null && useSiteDiagnosticsBuilder.Count > 0) { if (useSiteDiagnostics == null) { useSiteDiagnostics = new HashSet <DiagnosticInfo>(); } foreach (var diag in useSiteDiagnosticsBuilder) { useSiteDiagnostics.Add(diag.DiagnosticInfo); } } if (!success) { return(null); } // For the purpose of construction we use original type parameters in place of type arguments that we couldn't infer from the first argument. ImmutableArray <TypeWithAnnotations> typeArgsForConstruct = typeArgs; if (typeArgs.Any(t => !t.HasType)) { typeArgsForConstruct = typeArgs.ZipAsArray( method.TypeParameters, (t, tp) => t.HasType ? t : TypeWithAnnotations.Create(tp)); } return(method.Construct(typeArgsForConstruct)); }
internal static void AddDelegateMembers( SourceMemberContainerTypeSymbol delegateType, ArrayBuilder <Symbol> symbols, DelegateDeclarationSyntax syntax, DiagnosticBag diagnostics) { var compilation = delegateType.DeclaringCompilation; Binder binder = delegateType.GetBinder(syntax.ParameterList); RefKind refKind; TypeSyntax returnTypeSyntax = syntax.ReturnType.SkipRef(out refKind); var returnType = binder.BindType(returnTypeSyntax, diagnostics); // reuse types to avoid reporting duplicate errors if missing: var voidType = TypeWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_Void, diagnostics, syntax)); // https://github.com/dotnet/roslyn/issues/30079: Should the 'object', IAsyncResult and AsyncCallback parameters be considered nullable or not nullable? var objectType = TypeWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_Object, diagnostics, syntax)); var intPtrType = TypeWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_IntPtr, diagnostics, syntax)); if (returnType.IsRestrictedType(ignoreSpanLikeTypes: true)) { // The return type of a method, delegate, or function pointer cannot be '{0}' diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, returnTypeSyntax.Location, returnType.Type); } // A delegate has the following members: (see CLI spec 13.6) // (1) a method named Invoke with the specified signature var invoke = new InvokeMethod(delegateType, refKind, returnType, syntax, binder, diagnostics); invoke.CheckDelegateVarianceSafety(diagnostics); symbols.Add(invoke); // (2) a constructor with argument types (object, System.IntPtr) symbols.Add(new Constructor(delegateType, voidType, objectType, intPtrType, syntax)); if (binder.Compilation.GetSpecialType(SpecialType.System_IAsyncResult).TypeKind != TypeKind.Error && binder.Compilation.GetSpecialType(SpecialType.System_AsyncCallback).TypeKind != TypeKind.Error && // WinRT delegates don't have Begin/EndInvoke methods !delegateType.IsCompilationOutputWinMdObj()) { var iAsyncResultType = TypeWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_IAsyncResult, diagnostics, syntax)); var asyncCallbackType = TypeWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_AsyncCallback, diagnostics, syntax)); // (3) BeginInvoke symbols.Add(new BeginInvokeMethod(invoke, iAsyncResultType, objectType, asyncCallbackType, syntax)); // and (4) EndInvoke methods symbols.Add(new EndInvokeMethod(invoke, iAsyncResultType, syntax)); } if (delegateType.DeclaredAccessibility <= Accessibility.Private) { return; } HashSet <DiagnosticInfo> useSiteDiagnostics = null; if (!delegateType.IsNoMoreVisibleThan(invoke.ReturnTypeWithAnnotations, ref useSiteDiagnostics)) { // Inconsistent accessibility: return type '{1}' is less accessible than delegate '{0}' diagnostics.Add(ErrorCode.ERR_BadVisDelegateReturn, delegateType.Locations[0], delegateType, invoke.ReturnType); } foreach (var parameter in invoke.Parameters) { if (!parameter.TypeWithAnnotations.IsAtLeastAsVisibleAs(delegateType, ref useSiteDiagnostics)) { // Inconsistent accessibility: parameter type '{1}' is less accessible than delegate '{0}' diagnostics.Add(ErrorCode.ERR_BadVisDelegateParam, delegateType.Locations[0], delegateType, parameter.Type); } } diagnostics.Add(delegateType.Locations[0], useSiteDiagnostics); }
internal override TypeWithAnnotations GetFieldType(ConsList <FieldSymbol> fieldsBeingBound) { return(TypeWithAnnotations.Create(this.ContainingType)); }
internal override TypeWithAnnotations GetFieldType(ConsList <FieldSymbol> fieldsBeingBound) { return(TypeWithAnnotations.Create(((SourceNamedTypeSymbol)ContainingType).EnumUnderlyingType)); }
internal AnonymousTypeEqualsMethodSymbol(NamedTypeSymbol container) : base(container, WellKnownMemberNames.ObjectEquals) { _parameters = ImmutableArray.Create <ParameterSymbol>( SynthesizedParameterSymbol.Create(this, TypeWithAnnotations.Create(this.Manager.System_Object), 0, RefKind.None, "value")); }
// https://github.com/dotnet/roslyn/issues/30071: Replace with Construct(ImmutableArray<TypeWithAnnotations>). /// <summary> /// Apply type substitution to a generic method to create an method symbol with the given type parameters supplied. /// </summary> /// <param name="typeArguments"></param> /// <returns></returns> public MethodSymbol Construct(ImmutableArray <TypeSymbol> typeArguments) { return(Construct(typeArguments.SelectAsArray(a => TypeWithAnnotations.Create(a)))); }
internal SynthesizedThrowMethod(SourceModuleSymbol containingModule, PrivateImplementationDetails privateImplType, TypeSymbol returnType, TypeSymbol paramType) : base(containingModule, privateImplType, returnType, PrivateImplementationDetails.SynthesizedThrowFunctionName) { this.SetParameters(ImmutableArray.Create <ParameterSymbol>(SynthesizedParameterSymbol.Create(this, TypeWithAnnotations.Create(paramType), 0, RefKind.None, "paramName"))); }
internal AnonymousTypeTemplateSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr) : base(manager, typeDescr.Location) { this.TypeDescriptorKey = typeDescr.Key; int fieldsCount = typeDescr.Fields.Length; int membersCount = fieldsCount * 3 + 1; // members var membersBuilder = ArrayBuilder <Symbol> .GetInstance(membersCount); var propertiesBuilder = ArrayBuilder <AnonymousTypePropertySymbol> .GetInstance(fieldsCount); var typeParametersBuilder = ArrayBuilder <TypeParameterSymbol> .GetInstance(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)); typeParametersBuilder.Add(typeParameter); // Add a property AnonymousTypePropertySymbol property = new AnonymousTypePropertySymbol(this, field, TypeWithAnnotations.Create(typeParameter), fieldIndex); propertiesBuilder.Add(property); // Property related symbols membersBuilder.Add(property); membersBuilder.Add(property.BackingField); membersBuilder.Add(property.GetMethod); } _typeParameters = typeParametersBuilder.ToImmutableAndFree(); this.Properties = propertiesBuilder.ToImmutableAndFree(); // Add a constructor membersBuilder.Add(new AnonymousTypeConstructorSymbol(this, this.Properties)); _members = membersBuilder.ToImmutableAndFree(); Debug.Assert(membersCount == _members.Length); // fill nameToSymbols map foreach (var symbol in _members) { _nameToSymbols.Add(symbol.Name, symbol); } // special members: Equals, GetHashCode, ToString this.SpecialMembers = ImmutableArray.Create <MethodSymbol>( new AnonymousTypeEqualsMethodSymbol(this), new AnonymousTypeGetHashCodeMethodSymbol(this), new AnonymousTypeToStringMethodSymbol(this)); }
/// <summary> /// If the extension method is applicable based on the "this" argument type, return /// the method constructed with the inferred type arguments. If the method is not an /// unconstructed generic method, type inference is skipped. If the method is not /// applicable, or if constraints when inferring type parameters from the "this" type /// are not satisfied, the return value is null. /// </summary> private static MethodSymbol InferExtensionMethodTypeArguments(MethodSymbol method, TypeSymbol thisType, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { Debug.Assert(method.IsExtensionMethod); Debug.Assert((object)thisType != null); if (!method.IsGenericMethod || method != method.ConstructedFrom) { return(method); } // We never resolve extension methods on a dynamic receiver. if (thisType.IsDynamic()) { return(null); } var containingAssembly = method.ContainingAssembly; var errorNamespace = containingAssembly.GlobalNamespace; var conversions = new TypeConversions(containingAssembly.CorLibrary); // There is absolutely no plausible syntax/tree that we could use for these // synthesized literals. We could be speculatively binding a call to a PE method. var syntaxTree = CSharpSyntaxTree.Dummy; var syntax = (CSharpSyntaxNode)syntaxTree.GetRoot(); // Create an argument value for the "this" argument of specific type, // and pass the same bad argument value for all other arguments. var thisArgumentValue = new BoundLiteral(syntax, ConstantValue.Bad, thisType) { WasCompilerGenerated = true }; var otherArgumentType = new ExtendedErrorTypeSymbol(errorNamespace, name: string.Empty, arity: 0, errorInfo: null, unreported: false); var otherArgumentValue = new BoundLiteral(syntax, ConstantValue.Bad, otherArgumentType) { WasCompilerGenerated = true }; var paramCount = method.ParameterCount; var arguments = new BoundExpression[paramCount]; for (int i = 0; i < paramCount; i++) { var argument = (i == 0) ? thisArgumentValue : otherArgumentValue; arguments[i] = argument; } var typeArgs = MethodTypeInferrer.InferTypeArgumentsFromFirstArgument( conversions, method, arguments.AsImmutable(), useSiteDiagnostics: ref useSiteDiagnostics); if (typeArgs.IsDefault) { return(null); } // For the purpose of construction we use original type parameters in place of type arguments that we couldn't infer from the first argument. ImmutableArray <TypeWithAnnotations> typeArgsForConstruct = typeArgs; if (typeArgs.Any(t => !t.HasType)) { typeArgsForConstruct = typeArgs.ZipAsArray( method.TypeParameters, (t, tp) => t.HasType ? t : TypeWithAnnotations.Create(tp)); } return(method.Construct(typeArgsForConstruct)); }
internal static ImmutableArray <TypeWithAnnotations> TypeParametersAsTypeSymbolsWithAnnotations(ImmutableArray <TypeParameterSymbol> typeParameters) { return(typeParameters.SelectAsArray((tp) => TypeWithAnnotations.Create(tp))); }
private ImmutableArray <ParameterSymbol> MakeParameters( CSharpCompilation compilation, UnboundLambda unboundLambda, ImmutableArray <TypeWithAnnotations> parameterTypes, ImmutableArray <RefKind> parameterRefKinds, DiagnosticBag diagnostics) { Debug.Assert(parameterTypes.Length == parameterRefKinds.Length); if (!unboundLambda.HasSignature || unboundLambda.ParameterCount == 0) { // The parameters may be omitted in source, but they are still present on the symbol. return(parameterTypes.SelectAsArray((type, ordinal, arg) => SynthesizedParameterSymbol.Create( arg.owner, type, ordinal, arg.refKinds[ordinal], GeneratedNames.LambdaCopyParameterName(ordinal)), // Make sure nothing binds to this. (owner: this, refKinds: parameterRefKinds))); } var builder = ArrayBuilder <ParameterSymbol> .GetInstance(unboundLambda.ParameterCount); var hasExplicitlyTypedParameterList = unboundLambda.HasExplicitlyTypedParameterList; var numDelegateParameters = parameterTypes.Length; for (int p = 0; p < unboundLambda.ParameterCount; ++p) { // If there are no types given in the lambda then used the delegate type. // If the lambda is typed then the types probably match the delegate types; // if they do not, use the lambda types for binding. Either way, if we // can, then we use the lambda types. (Whatever you do, do not use the names // in the delegate parameters; they are not in scope!) TypeWithAnnotations type; RefKind refKind; if (hasExplicitlyTypedParameterList) { type = unboundLambda.ParameterTypeWithAnnotations(p); refKind = unboundLambda.RefKind(p); } else if (p < numDelegateParameters) { type = parameterTypes[p]; refKind = parameterRefKinds[p]; } else { type = TypeWithAnnotations.Create(new ExtendedErrorTypeSymbol(compilation, name: string.Empty, arity: 0, errorInfo: null)); refKind = RefKind.None; } var name = unboundLambda.ParameterName(p); var location = unboundLambda.ParameterLocation(p); var locations = location == null ? ImmutableArray <Location> .Empty : ImmutableArray.Create <Location>(location); var parameter = new SourceSimpleParameterSymbol(owner: this, type, ordinal: p, refKind, name, unboundLambda.ParameterIsDiscard(p), locations); builder.Add(parameter); } var result = builder.ToImmutableAndFree(); return(result); }
protected override TypeWithAnnotations InferTypeOfVarVariable(BindingDiagnosticBag diagnostics) { switch (_nodeToBind.Kind()) { case SyntaxKind.ThisConstructorInitializer: case SyntaxKind.BaseConstructorInitializer: var initializer = (ConstructorInitializerSyntax)_nodeToBind; _nodeBinder.BindConstructorInitializer(initializer, diagnostics); break; case SyntaxKind.PrimaryConstructorBaseType: _nodeBinder.BindConstructorInitializer((PrimaryConstructorBaseTypeSyntax)_nodeToBind, diagnostics); break; case SyntaxKind.ArgumentList: switch (_nodeToBind.Parent) { case ConstructorInitializerSyntax ctorInitializer: _nodeBinder.BindConstructorInitializer(ctorInitializer, diagnostics); break; case PrimaryConstructorBaseTypeSyntax ctorInitializer: _nodeBinder.BindConstructorInitializer(ctorInitializer, diagnostics); break; default: throw ExceptionUtilities.UnexpectedValue(_nodeToBind.Parent); } break; case SyntaxKind.CasePatternSwitchLabel: _nodeBinder.BindPatternSwitchLabelForInference((CasePatternSwitchLabelSyntax)_nodeToBind, diagnostics); break; case SyntaxKind.VariableDeclarator: // This occurs, for example, in // int x, y[out var Z, 1 is int I]; // for (int x, y[out var Z, 1 is int I]; ;) {} _nodeBinder.BindDeclaratorArguments((VariableDeclaratorSyntax)_nodeToBind, diagnostics); break; case SyntaxKind.SwitchExpressionArm: var arm = (SwitchExpressionArmSyntax)_nodeToBind; var armBinder = (SwitchExpressionArmBinder)_nodeBinder; armBinder.BindSwitchExpressionArm(arm, diagnostics); break; case SyntaxKind.GotoCaseStatement: _nodeBinder.BindStatement((GotoStatementSyntax)_nodeToBind, diagnostics); break; default: _nodeBinder.BindExpression((ExpressionSyntax)_nodeToBind, diagnostics); break; } if (this._type == null) { Debug.Assert(this.DeclarationKind == LocalDeclarationKind.DeclarationExpressionVariable); SetTypeWithAnnotations(TypeWithAnnotations.Create(_nodeBinder.CreateErrorType("var"))); } return(_type.Value); }
protected sealed override void MethodChecks(DiagnosticBag diagnostics) { Debug.Assert(_lazyParameters.IsDefault != _lazyReturnType.HasType); // CONSIDER: currently, we're copying the custom modifiers of the event overridden // by this method's associated event (by using the associated event's type, which is // copied from the overridden event). It would be more correct to copy them from // the specific accessor that this method is overriding (as in SourceMemberMethodSymbol). if (_lazyReturnType.IsDefault) { CSharpCompilation compilation = this.DeclaringCompilation; Debug.Assert(compilation != null); // NOTE: LazyMethodChecks calls us within a lock, so we use regular assignments, // rather than Interlocked.CompareExchange. if (_event.IsWindowsRuntimeEvent) { TypeSymbol eventTokenType = compilation.GetWellKnownType(WellKnownType.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationToken); Binder.ReportUseSiteDiagnostics(eventTokenType, diagnostics, this.Location); if (this.MethodKind == MethodKind.EventAdd) { // EventRegistrationToken add_E(EventDelegate d); // Leave the returns void bit in this.flags false. _lazyReturnType = TypeWithAnnotations.Create(eventTokenType); var parameter = new SynthesizedAccessorValueParameterSymbol(this, _event.TypeWithAnnotations, 0); _lazyParameters = ImmutableArray.Create <ParameterSymbol>(parameter); } else { Debug.Assert(this.MethodKind == MethodKind.EventRemove); // void remove_E(EventRegistrationToken t); TypeSymbol voidType = compilation.GetSpecialType(SpecialType.System_Void); Binder.ReportUseSiteDiagnostics(voidType, diagnostics, this.Location); _lazyReturnType = TypeWithAnnotations.Create(voidType); this.SetReturnsVoid(returnsVoid: true); var parameter = new SynthesizedAccessorValueParameterSymbol(this, TypeWithAnnotations.Create(eventTokenType), 0); _lazyParameters = ImmutableArray.Create <ParameterSymbol>(parameter); } } else { // void add_E(EventDelegate d); // void remove_E(EventDelegate d); TypeSymbol voidType = compilation.GetSpecialType(SpecialType.System_Void); Binder.ReportUseSiteDiagnostics(voidType, diagnostics, this.Location); _lazyReturnType = TypeWithAnnotations.Create(voidType); this.SetReturnsVoid(returnsVoid: true); var parameter = new SynthesizedAccessorValueParameterSymbol(this, _event.TypeWithAnnotations, 0); _lazyParameters = ImmutableArray.Create <ParameterSymbol>(parameter); } } }
protected override TypeWithAnnotations ComputeType(Binder?binder, SyntaxNode syntax, DiagnosticBag diagnostics) { // No need to worry about reporting use-site diagnostics, we already did that in the constructor return(TypeWithAnnotations.Create(DeclaringCompilation.GetWellKnownType(WellKnownType.System_Type), NullableAnnotation.NotAnnotated)); }
protected sealed override void MethodChecks(BindingDiagnosticBag diagnostics) { var syntax = (CSharpSyntaxNode)syntaxReferenceOpt.GetSyntax(); var binderFactory = this.DeclaringCompilation.GetBinderFactory(syntax.SyntaxTree); ParameterListSyntax parameterList = GetParameterList(); // NOTE: if we asked for the binder for the body of the constructor, we'd risk a stack overflow because // we might still be constructing the member list of the containing type. However, getting the binder // for the parameters should be safe. var bodyBinder = binderFactory .GetBinder(parameterList, syntax, this) .WithContainingMemberOrLambda(this); // 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 = bodyBinder.WithAdditionalFlagsAndContainingMemberOrLambda( BinderFlags.SuppressConstraintChecks, this ); SyntaxToken arglistToken; _lazyParameters = ParameterHelpers.MakeParameters( signatureBinder, this, parameterList, out arglistToken, allowRefOrOut: AllowRefOrOut, allowThis: false, addRefReadOnlyModifier: false, diagnostics: diagnostics ); _lazyIsVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword); _lazyReturnType = TypeWithAnnotations.Create( bodyBinder.GetSpecialType(SpecialType.System_Void, diagnostics, syntax) ); var location = this.Locations[0]; // Don't report ERR_StaticConstParam if the ctor symbol name doesn't match the containing type name. // This avoids extra unnecessary errors. // There will already be a diagnostic saying Method must have a return type. if ( MethodKind == MethodKind.StaticConstructor && (_lazyParameters.Length != 0) && ContainingType.Name == ((ConstructorDeclarationSyntax)this.SyntaxNode).Identifier.ValueText ) { diagnostics.Add(ErrorCode.ERR_StaticConstParam, location, this); } this.CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics); if ( _lazyIsVararg && ( IsGenericMethod || ContainingType.IsGenericType || _lazyParameters.Length > 0 && _lazyParameters[_lazyParameters.Length - 1].IsParams ) ) { diagnostics.Add(ErrorCode.ERR_BadVarargs, location); } }