private TypeMap WithAlphaRename(ImmutableArray <TypeParameterSymbol> oldTypeParameters, Symbol newOwner, out ImmutableArray <TypeParameterSymbol> newTypeParameters) { if (oldTypeParameters.Length == 0) { newTypeParameters = ImmutableArray <TypeParameterSymbol> .Empty; return(this); } // Note: the below assertion doesn't hold while rewriting async lambdas defined inside generic methods. // The async rewriter adds a synthesized struct inside the lambda frame and construct a typemap from // the lambda frame's substituted type parameters. // Debug.Assert(!oldTypeParameters.Any(tp => tp is SubstitutedTypeParameterSymbol)); // warning: we expose result to the SubstitutedTypeParameterSymbol constructor, below, even before it's all filled in. TypeMap result = new TypeMap(this.Mapping); ArrayBuilder <TypeParameterSymbol> newTypeParametersBuilder = ArrayBuilder <TypeParameterSymbol> .GetInstance(); // The case where it is "synthesized" is when we're creating type parameters for a synthesized (generic) // class or method for a lambda appearing in a generic method. bool synthesized = !ReferenceEquals(oldTypeParameters[0].ContainingSymbol.OriginalDefinition, newOwner.OriginalDefinition); int ordinal = 0; foreach (var tp in oldTypeParameters) { var newTp = synthesized ? new SynthesizedSubstitutedTypeParameterSymbol(newOwner, result, tp, ordinal) : new SubstitutedTypeParameterSymbol(newOwner, result, tp, ordinal); result.Mapping.Add(tp, TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, newTp)); newTypeParametersBuilder.Add(newTp); ordinal++; } newTypeParameters = newTypeParametersBuilder.ToImmutableAndFree(); return(result); }
internal static ImmutableArray <TypeSymbolWithAnnotations> TypeParametersAsTypeSymbolsWithAnnotations(INonNullTypesContext nonNullTypesContext, ImmutableArray <TypeParameterSymbol> typeParameters) { return(typeParameters.SelectAsArray((tp, c) => TypeSymbolWithAnnotations.Create(nonNullTypesContext: c, tp, isAnnotated: false, customModifiers: ImmutableArray <CustomModifier> .Empty), nonNullTypesContext)); }
/// <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> public static MethodSymbol InferExtensionMethodTypeArguments(this MethodSymbol method, TypeSymbol thisType, Compilation 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); } int firstNullInTypeArgs = -1; // 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. var notInferredTypeParameters = PooledHashSet <TypeParameterSymbol> .GetInstance(); var typeParams = method.TypeParameters; var typeArgsForConstraintsCheck = typeArgs; for (int i = 0; i < typeArgsForConstraintsCheck.Length; i++) { if (typeArgsForConstraintsCheck[i].IsNull) { firstNullInTypeArgs = i; var builder = ArrayBuilder <TypeSymbolWithAnnotations> .GetInstance(); builder.AddRange(typeArgsForConstraintsCheck, firstNullInTypeArgs); for (; i < typeArgsForConstraintsCheck.Length; i++) { var typeArg = typeArgsForConstraintsCheck[i]; if (typeArg.IsNull) { notInferredTypeParameters.Add(typeParams[i]); builder.Add(TypeSymbolWithAnnotations.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, warningsBuilderOpt: 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. var typeArgsForConstruct = typeArgs; if (firstNullInTypeArgs != -1) { var builder = ArrayBuilder <TypeSymbolWithAnnotations> .GetInstance(); builder.AddRange(typeArgs, firstNullInTypeArgs); for (int i = firstNullInTypeArgs; i < typeArgsForConstruct.Length; i++) { var typeArgForConstruct = typeArgsForConstruct[i]; builder.Add(!typeArgForConstruct.IsNull ? typeArgForConstruct : TypeSymbolWithAnnotations.Create(typeParams[i])); } typeArgsForConstruct = builder.ToImmutableAndFree(); } return(method.Construct(typeArgsForConstruct)); }
protected virtual TypeSymbolWithAnnotations SubstituteTypeParameter(TypeParameterSymbol typeParameter) { return(TypeSymbolWithAnnotations.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 TypeSymbolWithAnnotations Substitute(AbstractTypeMap typeMap) { return(TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, (ErrorTypeSymbol)typeMap.SubstituteNamedType(this))); }
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, TypeSymbolWithAnnotations.Create(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(); }
internal static ImmutableArray <TypeSymbolWithAnnotations> TypeParametersAsTypeSymbolsWithAnnotations(ImmutableArray <TypeParameterSymbol> typeParameters) { return(typeParameters.SelectAsArray((tp) => TypeSymbolWithAnnotations.Create(tp))); }
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 = TypeSymbolWithAnnotations.Create(eventTokenType); var parameter = new SynthesizedAccessorValueParameterSymbol(this, _event.Type, 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 = TypeSymbolWithAnnotations.Create(voidType); this.SetReturnsVoid(returnsVoid: true); var parameter = new SynthesizedAccessorValueParameterSymbol(this, TypeSymbolWithAnnotations.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 = TypeSymbolWithAnnotations.Create(voidType); this.SetReturnsVoid(returnsVoid: true); var parameter = new SynthesizedAccessorValueParameterSymbol(this, _event.Type, 0); _lazyParameters = ImmutableArray.Create <ParameterSymbol>(parameter); } } }
// 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, TypeSymbolWithAnnotations.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(initializeResult.Type == _returnType.TypeSymbol); var returnStatement = new BoundReturnStatement( syntax, RefKind.None, initializeResult) { WasCompilerGenerated = true }; return(new BoundBlock(syntax, ImmutableArray.Create <LocalSymbol>(submissionLocal.LocalSymbol), ImmutableArray.Create <BoundStatement>(submissionAssignment, returnStatement)) { WasCompilerGenerated = true }); }
internal SubmissionEntryPoint(NamedTypeSymbol containingType, TypeSymbolWithAnnotations returnType, TypeSymbol submissionArrayType) : base(containingType) { Debug.Assert(containingType.IsSubmissionClass); Debug.Assert(returnType.SpecialType != SpecialType.System_Void); _parameters = ImmutableArray.Create(SynthesizedParameterSymbol.Create(this, TypeSymbolWithAnnotations.Create(nonNullTypesContext: ContainingModule, submissionArrayType), 0, RefKind.None, "submissionArray")); _returnType = returnType; }
// 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, TypeSymbolWithAnnotations.Create(_containingType), SynthesizedLocalKind.LoweringTemp), null, _containingType) { WasCompilerGenerated = true }; var initializeCall = CreateParameterlessCall(syntax, scriptLocal, initializer); BoundExpression getAwaiterGetResultCall; if (!binder.GetAwaitableExpressionInfo(initializeCall, out _, out _, out _, 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 }); }
internal static ImmutableArray <TypeSymbolWithAnnotations> TypeParametersAsTypeSymbolsWithAnnotations(ImmutableArray <TypeParameterSymbol> typeParameters) { return(typeParameters.SelectAsArray((tp) => TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, tp, isAnnotated: false, customModifiers: ImmutableArray <CustomModifier> .Empty) )); }
/// <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, TypeSymbolWithAnnotations.Create(symbol), rank)); } else if (typeInfo.IsPointer) { TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences); if ((object)symbol == null) { return(null); } return(new PointerTypeSymbol(TypeSymbolWithAnnotations.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); } }
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; 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, TypeSymbolWithAnnotations.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)); }
private ImmutableArray <ParameterSymbol> MakeParameters( CSharpCompilation compilation, UnboundLambda unboundLambda, ImmutableArray <TypeSymbolWithAnnotations> 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!) TypeSymbolWithAnnotations type; RefKind refKind; if (hasExplicitlyTypedParameterList) { type = unboundLambda.ParameterType(p); refKind = unboundLambda.RefKind(p); } else if (p < numDelegateParameters) { type = parameterTypes[p]; refKind = parameterRefKinds[p]; } else { type = TypeSymbolWithAnnotations.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(this, type, p, refKind, name, locations); builder.Add(parameter); } var result = builder.ToImmutableAndFree(); return(result); }
protected virtual TypeSymbolWithAnnotations SubstituteTypeParameter(TypeParameterSymbol typeParameter) { return(TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, typeParameter)); }
internal AnonymousTypeEqualsMethodSymbol(NamedTypeSymbol container) : base(container, WellKnownMemberNames.ObjectEquals) { _parameters = ImmutableArray.Create <ParameterSymbol>( SynthesizedParameterSymbol.Create(this, TypeSymbolWithAnnotations.Create(this.Manager.System_Object), 0, RefKind.None, "value")); }
internal SynthesizedStringSwitchHashMethod(SourceModuleSymbol containingModule, PrivateImplementationDetails privateImplType, TypeSymbol returnType, TypeSymbol paramType) : base(containingModule, privateImplType, returnType, PrivateImplementationDetails.SynthesizedStringHashFunctionName) { this.SetParameters(ImmutableArray.Create <ParameterSymbol>(SynthesizedParameterSymbol.Create(this, TypeSymbolWithAnnotations.Create(paramType), 0, RefKind.None, "s"))); }
internal override TypeSymbolWithAnnotations GetFieldType(ConsList <FieldSymbol> fieldsBeingBound) { return(TypeSymbolWithAnnotations.Create(this.ContainingType)); }
// https://github.com/dotnet/roslyn/issues/30071: Replace with Construct(ImmutableArray<TypeSymbolWithAnnotations>). /// <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 => TypeSymbolWithAnnotations.Create(a)))); }
internal sealed override TypeSymbolWithAnnotations GetFieldType(ConsList <FieldSymbol> fieldsBeingBound) { Debug.Assert(fieldsBeingBound != null); if (!_lazyType.IsNull) { return(_lazyType.ToType()); } var declarator = VariableDeclaratorNode; var fieldSyntax = GetFieldDeclaration(declarator); var typeSyntax = fieldSyntax.Declaration.Type; var compilation = this.DeclaringCompilation; var diagnostics = DiagnosticBag.GetInstance(); TypeSymbolWithAnnotations 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 = TypeSymbolWithAnnotations.Create(tokenTableType.Construct(ImmutableArray.Create(@event.Type))); } else { type = @event.Type; } } else { var binderFactory = compilation.GetBinderFactory(SyntaxTree); var binder = binderFactory.GetBinder(typeSyntax); binder = binder.WithContainingMemberOrLambda(this); if (!ContainingType.IsScriptClass) { type = binder.BindType(typeSyntax, diagnosticsForFirstDeclarator); } else { bool isVar; type = binder.BindTypeOrVarKeyword(typeSyntax, diagnostics, out isVar); Debug.Assert(!type.IsNull || 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 = TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, initializerOpt.Type); } _lazyFieldTypeInferred = 1; } } if (type.IsNull) { type = TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, binder.CreateErrorType("var")); } } } if (IsFixed) { type = TypeSymbolWithAnnotations.Create(new PointerTypeSymbol(type)); if (ContainingType.TypeKind != TypeKind.Struct) { diagnostics.Add(ErrorCode.ERR_FixedNotInStruct, ErrorLocation); } var elementType = ((PointerTypeSymbol)type.TypeSymbol).PointedAtType.TypeSymbol; 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.TypeSymbol, 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()); }
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 = TypeSymbolWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_Void, diagnostics, syntax)); // https://github.com/dotnet/roslyn/issues/30079: Should the 'object' parameter be considered nullable? var objectType = TypeSymbolWithAnnotations.Create(nonNullTypesContext: delegateType, binder.GetSpecialType(SpecialType.System_Object, diagnostics, syntax)); var intPtrType = TypeSymbolWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_IntPtr, diagnostics, syntax)); if (returnType.IsRestrictedType(ignoreSpanLikeTypes: true)) { // Method or delegate cannot return type '{0}' diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, returnTypeSyntax.Location, returnType.TypeSymbol); } // 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 = TypeSymbolWithAnnotations.Create(nonNullTypesContext: delegateType, binder.GetSpecialType(SpecialType.System_IAsyncResult, diagnostics, syntax)); var asyncCallbackType = TypeSymbolWithAnnotations.Create(nonNullTypesContext: delegateType, 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.ReturnType, ref useSiteDiagnostics)) { // Inconsistent accessibility: return type '{1}' is less accessible than delegate '{0}' diagnostics.Add(ErrorCode.ERR_BadVisDelegateReturn, delegateType.Locations[0], delegateType, invoke.ReturnType.TypeSymbol); } foreach (var parameter in invoke.Parameters) { if (!parameter.Type.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.TypeSymbol); } } diagnostics.Add(delegateType.Locations[0], useSiteDiagnostics); }
/// <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 TypeSymbolWithAnnotations Substitute(AbstractTypeMap typeMap) { return(TypeSymbolWithAnnotations.Create(typeMap.SubstituteNamedType(this))); }
internal override TypeSymbolWithAnnotations GetFieldType(ConsList <FieldSymbol> fieldsBeingBound) { return(TypeSymbolWithAnnotations.Create(((SourceNamedTypeSymbol)ContainingType).EnumUnderlyingType)); }