internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison) { if (ReferenceEquals(this, t2)) { return(true); } // if ignoring dynamic, then treat dynamic the same as the type 'object' if ((comparison & TypeCompareKind.IgnoreDynamic) != 0 && (object)t2 != null && t2.TypeKind == TypeKind.Dynamic && this.SpecialType == Microsoft.CodeAnalysis.SpecialType.System_Object) { return(true); } var other = t2 as TopLevel; #if XSHARP return((object)other != null && XSharpString.Equals(MetadataName, other.MetadataName) && arity == other.arity && XSharpString.Equals(_namespaceName, other.NamespaceName) && _containingModule.Equals(other._containingModule)); #else return((object)other != null && string.Equals(MetadataName, other.MetadataName, StringComparison.Ordinal) && arity == other.arity && string.Equals(_namespaceName, other.NamespaceName, StringComparison.Ordinal) && _containingModule.Equals(other._containingModule)); #endif }
internal RangeVariableSymbol AddRangeVariable(Binder binder, SyntaxToken identifier, DiagnosticBag diagnostics) { string name = identifier.ValueText; var result = new RangeVariableSymbol(name, binder.ContainingMemberOrLambda, identifier.GetLocation()); bool error = false; foreach (var existingRangeVariable in allRangeVariables.Keys) { #if XSHARP if (XSharpString.Equals(existingRangeVariable.Name, name)) #else if (existingRangeVariable.Name == name) #endif { diagnostics.Add(ErrorCode.ERR_QueryDuplicateRangeVariable, identifier.GetLocation(), name); error = true; } } if (!error) { var collisionDetector = new LocalScopeBinder(binder); collisionDetector.ValidateDeclarationNameConflictsInScope(result, diagnostics); } allRangeVariables.Add(result, ArrayBuilder <string> .GetInstance()); return(result); }
public override bool Equals(object obj) { if (obj == null) { return(false); } else if (ReferenceEquals(this, obj)) { return(true); } var other = obj as AnonymousTypePropertySymbol; if ((object)other == null) { return(false); } // consider properties the same is the owning types are the same and // the names are equal #if XSHARP return(((object)other != null) && XSharpString.Equals(other.Name, this.Name) && other.ContainingType.Equals(this.ContainingType)); #else return(((object)other != null) && other.Name == this.Name && other.ContainingType.Equals(this.ContainingType)); #endif }
private BoundExpression MakePair(CSharpSyntaxNode node, string field1Name, BoundExpression field1Value, string field2Name, BoundExpression field2Value, QueryTranslationState state, DiagnosticBag diagnostics) { #if XSHARP if (XSharpString.Equals(field1Name, field2Name)) #else if (field1Name == field2Name) #endif { // we will generate a diagnostic elsewhere field2Name = state.TransparentRangeVariableName(); field2Value = new BoundBadExpression(field2Value.Syntax, LookupResultKind.Empty, ImmutableArray <Symbol> .Empty, ImmutableArray.Create(field2Value), field2Value.Type, true); } AnonymousTypeDescriptor typeDescriptor = new AnonymousTypeDescriptor( ImmutableArray.Create <AnonymousTypeField>( new AnonymousTypeField(field1Name, field1Value.Syntax.Location, TypeOrError(field1Value)), new AnonymousTypeField(field2Name, field2Value.Syntax.Location, TypeOrError(field2Value)) ), node.Location ); AnonymousTypeManager manager = this.Compilation.AnonymousTypeManager; NamedTypeSymbol anonymousType = manager.ConstructAnonymousTypeSymbol(typeDescriptor); return(MakeConstruction(node, anonymousType, ImmutableArray.Create(field1Value, field2Value), diagnostics)); }
public override ImmutableArray <Symbol> GetMembers(string name) { var ctor = Constructor; #if XSHARP return(((object)ctor != null && XSharpString.Equals(name, ctor.Name)) ? ImmutableArray.Create <Symbol>(ctor) : ImmutableArray <Symbol> .Empty); #else return(((object)ctor != null && name == ctor.Name) ? ImmutableArray.Create <Symbol>(ctor) : ImmutableArray <Symbol> .Empty); #endif }
protected SourceEnumConstantSymbol(SourceMemberContainerTypeSymbol containingEnum, EnumMemberDeclarationSyntax syntax, DiagnosticBag diagnostics) : base(containingEnum, syntax.Identifier.ValueText, syntax.GetReference(), syntax.Identifier.GetLocation()) { #if XSHARP if (XSharpString.Equals(this.Name, WellKnownMemberNames.EnumBackingFieldName)) #else if (this.Name == WellKnownMemberNames.EnumBackingFieldName) #endif { diagnostics.Add(ErrorCode.ERR_ReservedEnumerator, this.ErrorLocation, WellKnownMemberNames.EnumBackingFieldName); } }
public static bool IsOurAttribute(this NamedTypeSymbol atype, String name) { if (atype == null) { return(false); } if (atype.ContainingAssembly.IsRT()) { return(XSharpString.Equals(atype.Name, name)); } return(false); }
public override void EnterXppmethod([NotNull] XP.XppmethodContext context) { Check4ClipperCC(context, context.ParamList?._Params, null, context.Type); CheckInitMethods(context); string name; XppClassInfo current = null; if (context.ClassId == null) { current = _classes.LastOrDefault(); } else { // when context contains a classname, find the right class in the list of classes name = context.ClassId.GetText(); current = FindClassInfo(name); if (current == null) { context.AddError(new ParseErrorData(context, ErrorCode.ERR_XPPClassNotFound, name)); } current = _classes.LastOrDefault(); } current.ExternalMethods.Add(context); if (current != null) { // link to method name = context.Id.GetText(); var decl = current.FindMethod(name); if (decl == null) { decl = current.FindPropertyMethod(name); } if (decl != null) { if (decl.IsProperty) { if (XSharpString.Equals(decl.AccessMethod, name)) { decl.Entity = context; } if (XSharpString.Equals(decl.AssignMethod, name)) { decl.SetEntity = context; } } else { decl.Entity = context; } context.Info = decl; } } }
internal SourceDestructorSymbol( SourceMemberContainerTypeSymbol containingType, DestructorDeclarationSyntax syntax, DiagnosticBag diagnostics) : base(containingType, syntax.GetReference(), syntax.Identifier.GetLocation()) { const MethodKind methodKind = MethodKind.Destructor; Location location = this.Locations[0]; bool modifierErrors; var declarationModifiers = MakeModifiers(syntax.Modifiers, location, diagnostics, out modifierErrors); this.MakeFlags(methodKind, declarationModifiers, returnsVoid: true, isExtensionMethod: false); #if XSHARP if (!XSharpString.Equals(syntax.Identifier.ValueText, containingType.Name)) #else if (syntax.Identifier.ValueText != containingType.Name) #endif { diagnostics.Add(ErrorCode.ERR_BadDestructorName, syntax.Identifier.GetLocation()); } bool hasBlockBody = syntax.Body != null; _isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null; if (hasBlockBody || _isExpressionBodied) { if (IsExtern) { diagnostics.Add(ErrorCode.ERR_ExternHasBody, location, this); } } if (!modifierErrors && !hasBlockBody && !_isExpressionBodied && !IsExtern) { diagnostics.Add(ErrorCode.ERR_ConcreteMissingBody, location, this); } Debug.Assert(syntax.ParameterList.Parameters.Count == 0); if (containingType.IsStatic) { diagnostics.Add(ErrorCode.ERR_DestructorInStaticClass, location, this); } else if (!containingType.IsReferenceType) { diagnostics.Add(ErrorCode.ERR_OnlyClassesCanContainDestructors, location, this); } CheckForBlockAndExpressionBody( syntax.Body, syntax.ExpressionBody, syntax, diagnostics); }
internal XppDeclaredMethodInfo FindMethod(string name) { foreach (var decl in Methods) { if (!decl.IsProperty) { if (XSharpString.Equals(name, decl.Name)) { return(decl); } } } return(null); }
private static ImmutableArray <AliasAndExternAliasDirective> BuildExternAliases( SyntaxList <ExternAliasDirectiveSyntax> syntaxList, InContainerBinder binder, DiagnosticBag diagnostics) { CSharpCompilation compilation = binder.Compilation; var builder = ArrayBuilder <AliasAndExternAliasDirective> .GetInstance(); foreach (ExternAliasDirectiveSyntax aliasSyntax in syntaxList) { #if XSHARP if (compilation.IsSubmission && !aliasSyntax.ExternKeyword.HasTrailingTrivia) { continue; } #endif compilation.RecordImport(aliasSyntax); // Extern aliases not allowed in interactive submissions: if (compilation.IsSubmission) { diagnostics.Add(ErrorCode.ERR_ExternAliasNotAllowed, aliasSyntax.Location); continue; } // some n^2 action, but n should be very small. foreach (var existingAlias in builder) { #if XSHARP if (XSharpString.Equals(existingAlias.Alias.Name, aliasSyntax.Identifier.ValueText)) #else if (existingAlias.Alias.Name == aliasSyntax.Identifier.ValueText) #endif { diagnostics.Add(ErrorCode.ERR_DuplicateAlias, existingAlias.Alias.Locations[0], existingAlias.Alias.Name); break; } } if (aliasSyntax.Identifier.ContextualKind() == SyntaxKind.GlobalKeyword) { diagnostics.Add(ErrorCode.ERR_GlobalExternAlias, aliasSyntax.Identifier.GetLocation()); } builder.Add(new AliasAndExternAliasDirective(new AliasSymbol(binder, aliasSyntax), aliasSyntax)); } return(builder.ToImmutableAndFree()); }
public override ImmutableArray <Symbol> GetMembers(string name) { #if XSHARP return (XSharpString.Equals(name, _constructor.Name) ? ImmutableArray.Create <Symbol>(_constructor) : XSharpString.Equals(name, _invoke.Name) ? ImmutableArray.Create <Symbol>(_invoke) : ImmutableArray <Symbol> .Empty); #else return ((name == _constructor.Name) ? ImmutableArray.Create <Symbol>(_constructor) : (name == _invoke.Name) ? ImmutableArray.Create <Symbol>(_invoke) : ImmutableArray <Symbol> .Empty); #endif }
private SourceEventFieldSymbol MakeAssociatedField(VariableDeclaratorSyntax declaratorSyntax) { DiagnosticBag discardedDiagnostics = DiagnosticBag.GetInstance(); var field = new SourceEventFieldSymbol(this, declaratorSyntax, discardedDiagnostics); discardedDiagnostics.Free(); #if XSHARP Debug.Assert(XSharpString.Equals(field.Name, _name)); #else Debug.Assert(field.Name == _name); #endif return(field); }
internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison) { if ((object)t2 == (object)this) { return(true); } UnboundArgumentErrorTypeSymbol other = t2 as UnboundArgumentErrorTypeSymbol; #if XSHARP return((object)other != null && XSharpString.Equals(other._name, _name) && object.Equals(other._errorInfo, _errorInfo)); #else return((object)other != null && string.Equals(other._name, _name, StringComparison.Ordinal) && object.Equals(other._errorInfo, _errorInfo)); #endif }
internal void LookupSymbolInAliases( Binder originalBinder, LookupResult result, string name, int arity, ConsList <Symbol> basesBeingResolved, LookupOptions options, bool diagnose, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { bool callerIsSemanticModel = originalBinder.IsSemanticModelBinder; AliasAndUsingDirective alias; if (this.UsingAliases.TryGetValue(name, out alias)) { // Found a match in our list of normal aliases. Mark the alias as being seen so that // it won't be reported to the user as something that can be removed. var res = originalBinder.CheckViability(alias.Alias, arity, options, null, diagnose, ref useSiteDiagnostics, basesBeingResolved); if (res.Kind == LookupResultKind.Viable) { MarkImportDirective(alias.UsingDirective, callerIsSemanticModel); } result.MergeEqual(res); } foreach (var a in this.ExternAliases) { #if XSHARP if (XSharpString.Equals(a.Alias.Name, name)) #else if (a.Alias.Name == name) #endif { // Found a match in our list of extern aliases. Mark the extern alias as being // seen so that it won't be reported to the user as something that can be // removed. var res = originalBinder.CheckViability(a.Alias, arity, options, null, diagnose, ref useSiteDiagnostics, basesBeingResolved); if (res.Kind == LookupResultKind.Viable) { MarkImportDirective(a.ExternAliasDirective, callerIsSemanticModel); } result.MergeEqual(res); } } }
// Rewrite collection initializer element Add method call: // new List<int> { 1, 2, 3 }; OR new List<int> { { 1, 2 }, 3 }; // ~ ~~~~~~~~ private BoundExpression MakeCollectionInitializer(BoundExpression rewrittenReceiver, BoundCollectionElementInitializer initializer) { #if XSHARP Debug.Assert(XSharpString.Equals(initializer.AddMethod.Name, "Add")); #else Debug.Assert(initializer.AddMethod.Name == "Add"); #endif Debug.Assert(initializer.Arguments.Any()); Debug.Assert(rewrittenReceiver != null || _inExpressionLambda); var syntax = initializer.Syntax; MethodSymbol addMethod = initializer.AddMethod; if (_allowOmissionOfConditionalCalls) { // NOTE: Calls cannot be omitted within an expression tree (CS0765); this should already // have been checked. if (addMethod.CallsAreOmitted(initializer.SyntaxTree)) { return(null); } } var rewrittenArguments = VisitList(initializer.Arguments); var rewrittenType = VisitType(initializer.Type); // We have already lowered each argument, but we may need some additional rewriting for the arguments, // such as generating a params array, re-ordering arguments based on argsToParamsOpt map, inserting arguments for optional parameters, etc. ImmutableArray <LocalSymbol> temps; var argumentRefKindsOpt = default(ImmutableArray <RefKind>); rewrittenArguments = MakeArguments(syntax, rewrittenArguments, addMethod, addMethod, initializer.Expanded, initializer.ArgsToParamsOpt, ref argumentRefKindsOpt, out temps, enableCallerInfo: ThreeState.True); Debug.Assert(argumentRefKindsOpt.IsDefault); if (initializer.InvokedAsExtensionMethod) { // the add method was found as an extension method. Replace the implicit receiver (first argument) with the rewritten receiver. Debug.Assert(addMethod.IsStatic && addMethod.IsExtensionMethod); Debug.Assert(rewrittenArguments[0].Kind == BoundKind.ImplicitReceiver); Debug.Assert(!_inExpressionLambda, "Expression trees do not support extension Add"); rewrittenArguments = rewrittenArguments.SetItem(0, rewrittenReceiver); rewrittenReceiver = null; } if (_inExpressionLambda) { return(initializer.Update(addMethod, rewrittenArguments, rewrittenReceiver, expanded: false, argsToParamsOpt: default, initializer.InvokedAsExtensionMethod, initializer.ResultKind, initializer.BinderOpt, rewrittenType));
private void CheckInitMethods(XP.IEntityContext context) { context.Data.MustBeVoid = false; var idName = context.ShortName; if (XSharpString.Equals(idName, XSharpIntrinsicNames.InitMethod)) { context.Data.MustBeVoid = true; context.Data.IsInitAxit = true; // normal constructor } else if (XSharpString.Equals(idName, XSharpIntrinsicNames.InitClassMethod)) { context.Data.MustBeVoid = true; context.Data.IsInitAxit = true; // class constructor context.Data.HasClipperCallingConvention = false; } }
internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison) { if (ReferenceEquals(this, t2)) { return(true); } var other = t2 as Nested; #if XSHARP return((object)other != null && XSharpString.Equals(MetadataName, other.MetadataName) && arity == other.arity && _containingType.Equals(other._containingType, comparison)); #else return((object)other != null && string.Equals(MetadataName, other.MetadataName, StringComparison.Ordinal) && arity == other.arity && _containingType.Equals(other._containingType, comparison)); #endif }
private bool ImplementsStandardQueryInterface(TypeSymbol instanceType, string name, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { #if XSHARP if (instanceType.TypeKind == TypeKind.Array || XSharpString.Equals(name, "Cast") && HasCastToQueryProvider(instanceType, ref useSiteDiagnostics)) #else if (instanceType.TypeKind == TypeKind.Array || name == "Cast" && HasCastToQueryProvider(instanceType, ref useSiteDiagnostics)) #endif { return(true); } bool nonUnique = false; var originalType = instanceType.OriginalDefinition; var ienumerable_t = Compilation.GetSpecialType(SpecialType.System_Collections_Generic_IEnumerable_T); var iqueryable_t = Compilation.GetWellKnownType(WellKnownType.System_Linq_IQueryable_T); bool isIenumerable = originalType == ienumerable_t || HasUniqueInterface(instanceType, ienumerable_t, ref nonUnique, ref useSiteDiagnostics); bool isQueryable = originalType == iqueryable_t || HasUniqueInterface(instanceType, iqueryable_t, ref nonUnique, ref useSiteDiagnostics); return(isIenumerable != isQueryable && !nonUnique); }
internal AttributeArgumentSyntax GetNamedArgumentSyntax(string namedArgName) { Debug.Assert(!String.IsNullOrEmpty(namedArgName)); if (argumentList != null) { foreach (var argSyntax in argumentList.Arguments) { #if XSHARP if (argSyntax.NameEquals != null && XSharpString.Equals(argSyntax.NameEquals.Name.Identifier.ValueText, namedArgName)) #else if (argSyntax.NameEquals != null && argSyntax.NameEquals.Name.Identifier.ValueText == namedArgName) #endif { return(argSyntax); } } } return(null); }
internal override void LookupSymbolsInSingleBinder( LookupResult result, string name, int arity, ConsList <Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { if ((options & (LookupOptions.NamespaceAliasesOnly | LookupOptions.MustBeInvocableIfMember)) != 0) { return; } Debug.Assert(result.IsClear); foreach (ParameterSymbol parameter in _parameters) { #if XSHARP if (XSharpString.Equals(parameter.Name, name)) #else if (parameter.Name == name) #endif { result.MergeEqual(originalBinder.CheckViability(parameter, arity, options, null, diagnose, ref useSiteDiagnostics)); } } }
private static bool IsDegenerateQuery(QueryTranslationState state) { if (!state.clauses.IsEmpty()) { return(false); } // A degenerate query is of the form "from x in e select x". var select = state.selectOrGroup as SelectClauseSyntax; if (select == null) { return(false); } var name = select.Expression as IdentifierNameSyntax; #if XSHARP return(name != null && XSharpString.Equals(state.rangeVariable.Name, name.Identifier.ValueText)); #else return(name != null && state.rangeVariable.Name == name.Identifier.ValueText); #endif }
internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison) { if (ReferenceEquals(this, t2)) { return(true); } if ((object)t2 == null) { return(false); } CrefTypeParameterSymbol other = t2 as CrefTypeParameterSymbol; return((object)other != null && #if XSHARP XSharpString.Equals(other._name, _name) && #else other._name == _name && #endif other._ordinal == _ordinal && other._declaringSyntax.GetSyntax() == _declaringSyntax.GetSyntax()); }
internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison) { if (ReferenceEquals(this, t2)) { return(true); } var other = t2 as ExtendedErrorTypeSymbol; if ((object)other == null || _unreported || other._unreported) { return(false); } return (((object)this.ContainingType != null ? this.ContainingType.Equals(other.ContainingType, comparison) : (object)this.ContainingSymbol == null ? (object)other.ContainingSymbol == null : this.ContainingSymbol.Equals(other.ContainingSymbol)) && #if XSHARP XSharpString.Equals(this.Name, other.Name) && this.Arity == other.Arity); #else this.Name == other.Name && this.Arity == other.Arity; #endif }
internal TypeParameterSymbol MakeSymbol(int ordinal, IList <TypeParameterBuilder> builders, DiagnosticBag diagnostics) { var syntaxNode = (TypeParameterSyntax)_syntaxRef.GetSyntax(); var result = new SourceTypeParameterSymbol( _owner, syntaxNode.Identifier.ValueText, ordinal, syntaxNode.VarianceKeyword.VarianceKindFromToken(), ToLocations(builders), ToSyntaxRefs(builders)); // SPEC: A type parameter [of a type] cannot have the same name as the type itself. #if XSHARP if (XSharpString.Equals(result.Name, result.ContainingSymbol.Name)) #else if (result.Name == result.ContainingSymbol.Name) #endif { diagnostics.Add(ErrorCode.ERR_TypeVariableSameAsParent, result.Locations[0], result.Name); } return(result); }
protected void VisitUnoptimizedForm(BoundQueryClause queryClause) { BoundExpression unoptimizedForm = queryClause.UnoptimizedForm; // The unoptimized form of a query has an additional argument in the call, // which is typically the "trivial" expression x where x is the query // variable. So that we can make sense of x in this // context, we store the unoptimized form and visit this extra argument. var qc = unoptimizedForm as BoundQueryClause; if (qc != null) { unoptimizedForm = qc.Value; } var call = unoptimizedForm as BoundCall; if (call != null && (object)call.Method != null) { var arguments = call.Arguments; #if XSHARP if (XSharpString.Equals(call.Method.Name, "Select")) #else if (call.Method.Name == "Select") #endif { this.Visit(arguments[arguments.Length - 1]); } #if XSHARP else if (XSharpString.Equals(call.Method.Name, "GroupBy")) #else else if (call.Method.Name == "GroupBy") #endif { this.Visit(arguments[arguments.Length - 2]); } } }
public override bool Equals(object obj) { if (obj == (object)this) { return(true); } var other = obj as SynthesizedIntrinsicOperatorSymbol; if ((object)other == null) { return(false); } if (_isCheckedBuiltin == other._isCheckedBuiltin && _parameters.Length == other._parameters.Length && #if XSHARP XSharpString.Equals(_name, other._name) && #else string.Equals(_name, other._name, StringComparison.Ordinal) && #endif _containingType == other._containingType && _returnType == other._returnType) { for (int i = 0; i < _parameters.Length; i++) { if (_parameters[i].Type != other._parameters[i].Type) { return(false); } } return(true); } return(false); }
public void HoistLocal(LocalSymbol local, SyntheticBoundNodeFactory F) { #if XSHARP if (!_hoistedLocals.Keys.Any(l => XSharpString.Equals(l.Name, local.Name) && l.Type == local.Type)) #else if (!_hoistedLocals.Keys.Any(l => l.Name == local.Name && l.Type == local.Type)) #endif { _hoistedLocals.Add(local, local); _orderedHoistedLocals.Add(local); return; } // code uses "await" in two sibling catches with exception filters // locals with same names and types may cause problems if they are lifted // and become fields with identical signatures. // To avoid such problems we will mangle the name of the second local. // This will only affect debugging of this extremely rare case. Debug.Assert(pendingCatch.SyntaxOpt.IsKind(SyntaxKind.TryStatement)); var newLocal = F.SynthesizedLocal(local.Type, pendingCatch.SyntaxOpt, kind: SynthesizedLocalKind.ExceptionFilterAwaitHoistedExceptionLocal); _hoistedLocals.Add(local, newLocal); _orderedHoistedLocals.Add(newLocal); }
private static bool ReportQueryInferenceFailedSelectMany(FromClauseSyntax fromClause, string methodName, BoundExpression receiver, AnalyzedArguments arguments, ImmutableArray <Symbol> symbols, DiagnosticBag diagnostics) { #if XSHARP Debug.Assert(XSharpString.Equals(methodName, "SelectMany")); #else Debug.Assert(methodName == "SelectMany"); #endif // Estimate the return type of Select's lambda argument BoundExpression arg = arguments.Argument(arguments.IsExtensionMethodInvocation ? 1 : 0); TypeSymbol type = null; if (arg.Kind == BoundKind.UnboundLambda) { var unbound = (UnboundLambda)arg; foreach (var t in unbound.Data.InferredReturnTypes()) { if (!t.IsErrorType()) { type = t; break; } } } if ((object)type == null || type.IsErrorType()) { return(false); } TypeSymbol receiverType = receiver?.Type; diagnostics.Add(new DiagnosticInfoWithSymbols( ErrorCode.ERR_QueryTypeInferenceFailedSelectMany, new object[] { type, receiverType, methodName }, symbols), fromClause.Expression.Location); return(true); }
private static int?CorrespondsToAnyParameter( ImmutableArray <ParameterSymbol> memberParameters, bool expanded, AnalyzedArguments arguments, int argumentPosition, bool isValidParams, bool isVararg, out bool isNamedArgument, ref bool seenNamedParams, ref bool seenOutOfPositionNamedArgument) { // Spec 7.5.1.1: Corresponding parameters: // For each argument in an argument list there has to be a corresponding parameter in // the function member or delegate being invoked. The parameter list used in the // following is determined as follows: // - For virtual methods and indexers defined in classes, the parameter list is picked from the most specific // declaration or override of the function member, starting with the static type of the receiver, and searching through its base classes. // - For interface methods and indexers, the parameter list is picked form the most specific definition of the member, // starting with the interface type and searching through the base interfaces. If no unique parameter list is found, // a parameter list with inaccessible names and no optional parameters is constructed, so that invocations cannot use // named parameters or omit optional arguments. // - For partial methods, the parameter list of the defining partial method declaration is used. // - For all other function members and delegates there is only a single parameter list, which is the one used. // // The position of an argument or parameter is defined as the number of arguments or // parameters preceding it in the argument list or parameter list. // // The corresponding parameters for function member arguments are established as follows: // // Arguments in the argument-list of instance constructors, methods, indexers and delegates: isNamedArgument = arguments.Names.Count > argumentPosition && arguments.Names[argumentPosition] != null; if (!isNamedArgument) { // Spec: // - A positional argument where a fixed parameter occurs at the same position in the // parameter list corresponds to that parameter. // - A positional argument of a function member with a parameter array invoked in its // normal form corresponds to the parameter array, which must occur at the same // position in the parameter list. // - A positional argument of a function member with a parameter array invoked in its // expanded form, where no fixed parameter occurs at the same position in the // parameter list, corresponds to an element in the parameter array. if (seenNamedParams) { // Unnamed arguments after a named argument corresponding to a params parameter cannot correspond to any parameters return(null); } if (seenOutOfPositionNamedArgument) { // Unnamed arguments after an out-of-position named argument cannot correspond to any parameters return(null); } int parameterCount = memberParameters.Length + (isVararg ? 1 : 0); if (argumentPosition >= parameterCount) { return(expanded ? parameterCount - 1 : (int?)null); } return(argumentPosition); } else { // SPEC: A named argument corresponds to the parameter of the same name in the parameter list. // SPEC VIOLATION: The intention of this line of the specification, when contrasted with // SPEC VIOLATION: the lines on positional arguments quoted above, was to disallow a named // SPEC VIOLATION: argument from corresponding to an element of a parameter array when // SPEC VIOLATION: the method was invoked in its expanded form. That is to say that in // SPEC VIOLATION: this case: M(params int[] x) ... M(x : 1234); the named argument // SPEC VIOLATION: corresponds to x in the normal form (and is then inapplicable), but // SPEC VIOLATION: the named argument does *not* correspond to a member of params array // SPEC VIOLATION: x in the expanded form. // SPEC VIOLATION: Sadly that is not what we implemented in C# 4, and not what we are // SPEC VIOLATION: implementing here. If you do that, we make x correspond to the // SPEC VIOLATION: parameter array and allow the candidate to be applicable in its // SPEC VIOLATION: expanded form. var name = arguments.Names[argumentPosition]; for (int p = 0; p < memberParameters.Length; ++p) { // p is initialized to zero; it is ok for a named argument to "correspond" to // _any_ parameter (not just the parameters past the point of positional arguments) #if XSHARP if (XSharpString.Equals(memberParameters[p].Name, name.Identifier.ValueText)) #else if (memberParameters[p].Name == name.Identifier.ValueText) #endif { if (isValidParams && p == memberParameters.Length - 1) { seenNamedParams = true; } if (p != argumentPosition) { seenOutOfPositionNamedArgument = true; } return(p); } } } return(null); }