internal override SymbolInfo GetSymbolInfoWorker(LanguageSyntaxNode node, SymbolInfoOptions options, CancellationToken cancellationToken = default(CancellationToken)) { ValidateSymbolInfoOptions(options); // in case this is right side of a qualified name or member access (or part of a cref) node = SyntaxFactory.GetStandaloneNode(node); var model = this.GetMemberModel(node); SymbolInfo result; if (model != null) { // Expression occurs in an executable code (method body or initializer) context. Use that // model to get the information. result = model.GetSymbolInfoWorker(node, options, cancellationToken); // If we didn't get anything and were in Type/Namespace only context, let's bind normally and see // if any symbol comes out. if ((object)result.Symbol == null && result.CandidateReason == CandidateReason.None && this.Language.SyntaxFacts.IsInNamespaceOrTypeContext(node)) { var binder = this.GetEnclosingBinder(GetAdjustedNodePosition(node)); if (binder != null) { // Wrap the binder in a LocalScopeBinder because Binder.BindExpression assumes there // will be one in the binder chain and one isn't necessarily required for the batch case. binder = new LocalScopeBinder(binder); BoundExpression bound = binder.BindExpression(node, _boundTree); SymbolInfo info = GetSymbolInfoForNode(options, bound, bound, boundNodeForSyntacticParent: null, binderOpt: null); if ((object)info.Symbol != null) { result = new SymbolInfo(null, ImmutableArray.Create <ISymbol>(info.Symbol), CandidateReason.NotATypeOrNamespace); } else if (!info.CandidateSymbols.IsEmpty) { result = new SymbolInfo(null, info.CandidateSymbols, CandidateReason.NotATypeOrNamespace); } } } } else { // if expression is not part of a member context then caller may really just have a // reference to a type or namespace name var symbol = GetSemanticInfoSymbolInNonMemberContext(node, bindVarAsAliasFirst: (options & SymbolInfoOptions.PreserveAliases) != 0); result = (object)symbol != null?GetSymbolInfoForSymbol(symbol, options) : SymbolInfo.None; } return(result); }
private static BoundExpression BindFieldOrEnumInitializer( Binder binder, FieldSymbol fieldSymbol, EqualsValueClauseSyntax initializer, DiagnosticBag diagnostics) { var enumConstant = fieldSymbol as SourceEnumConstantSymbol; var collisionDetector = new LocalScopeBinder(binder); if ((object)enumConstant != null) { return collisionDetector.BindEnumConstantInitializer(enumConstant, initializer.Value, diagnostics); } else { return collisionDetector.BindVariableOrAutoPropInitializer(initializer, fieldSymbol.Type, diagnostics); } }
private static BoundExpression BindFieldOrEnumInitializer( Binder binder, FieldSymbol fieldSymbol, EqualsValueClauseSyntax initializer, DiagnosticBag diagnostics) { var enumConstant = fieldSymbol as SourceEnumConstantSymbol; var collisionDetector = new LocalScopeBinder(binder); if ((object)enumConstant != null) { return(collisionDetector.BindEnumConstantInitializer(enumConstant, initializer.Value, diagnostics)); } else { return(collisionDetector.BindVariableOrAutoPropInitializer(initializer, fieldSymbol.Type, diagnostics)); } }
private static BoundFieldEqualsValue BindFieldOrEnumInitializer( Binder binder, FieldSymbol fieldSymbol, EqualsValueClauseSyntax initializer, BindingDiagnosticBag diagnostics) { var enumConstant = fieldSymbol as SourceEnumConstantSymbol; Binder collisionDetector = new LocalScopeBinder(binder); collisionDetector = new ExecutableCodeBinder(initializer, fieldSymbol, collisionDetector); BoundFieldEqualsValue result; if ((object)enumConstant != null) { result = collisionDetector.BindEnumConstantInitializer(enumConstant, initializer, diagnostics); } else { result = collisionDetector.BindFieldInitializer(fieldSymbol, initializer, diagnostics); } return(result); }
private static BoundExpression BindFieldOrEnumInitializer( Binder binder, FieldSymbol fieldSymbol, EqualsValueClauseSyntax initializer, DiagnosticBag diagnostics) { var enumConstant = fieldSymbol as SourceEnumConstantSymbol; Binder collisionDetector = new LocalScopeBinder(binder); collisionDetector = new ExecutableCodeBinder(initializer, fieldSymbol, collisionDetector); BoundExpression result; if ((object)enumConstant != null) { result = collisionDetector.BindEnumConstantInitializer(enumConstant, initializer, diagnostics); } else { result = collisionDetector.BindVariableOrAutoPropInitializer(initializer, RefKind.None, fieldSymbol.Type, diagnostics); } return(result); }
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 (existingRangeVariable.Name == name) { 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; }
internal override SymbolInfo GetSymbolInfoWorker(CSharpSyntaxNode node, SymbolInfoOptions options, CancellationToken cancellationToken = default(CancellationToken)) { ValidateSymbolInfoOptions(options); // in case this is right side of a qualified name or member access (or part of a cref) node = SyntaxFactory.GetStandaloneNode(node); var model = this.GetMemberModel(node); SymbolInfo result; XmlNameAttributeSyntax attrSyntax; CrefSyntax crefSyntax; if (model != null) { // Expression occurs in an executable code (method body or initializer) context. Use that // model to get the information. result = model.GetSymbolInfoWorker(node, options, cancellationToken); // If we didn't get anything and were in Type/Namespace only context, let's bind normally and see // if any symbol comes out. if ((object)result.Symbol == null && result.CandidateReason == CandidateReason.None && node is ExpressionSyntax && SyntaxFacts.IsInNamespaceOrTypeContext((ExpressionSyntax)node)) { var binder = this.GetEnclosingBinder(GetAdjustedNodePosition(node)); if (binder != null) { // Wrap the binder in a LocalScopeBinder because Binder.BindExpression assumes there // will be one in the binder chain and one isn't necessarily required for the batch case. binder = new LocalScopeBinder(binder); var diagnostics = DiagnosticBag.GetInstance(); BoundExpression bound = binder.BindExpression((ExpressionSyntax)node, diagnostics); diagnostics.Free(); SymbolInfo info = GetSymbolInfoForNode(options, bound, bound, boundNodeForSyntacticParent: null, binderOpt: null); if ((object)info.Symbol != null) { result = new SymbolInfo(null, ImmutableArray.Create<ISymbol>(info.Symbol), CandidateReason.NotATypeOrNamespace); } else if (!info.CandidateSymbols.IsEmpty) { result = new SymbolInfo(null, info.CandidateSymbols, CandidateReason.NotATypeOrNamespace); } } } } else if (node.Parent.Kind() == SyntaxKind.XmlNameAttribute && (attrSyntax = (XmlNameAttributeSyntax)node.Parent).Identifier == node) { result = SymbolInfo.None; var binder = this.GetEnclosingBinder(GetAdjustedNodePosition(node)); if (binder != null) { HashSet<DiagnosticInfo> useSiteDiagnostics = null; var symbols = binder.BindXmlNameAttribute(attrSyntax, ref useSiteDiagnostics); // NOTE: We don't need to call GetSymbolInfoForSymbol because the symbols // can only be parameters or type parameters. Debug.Assert(symbols.All(s => s.Kind == SymbolKind.TypeParameter || s.Kind == SymbolKind.Parameter)); switch (symbols.Length) { case 0: result = SymbolInfo.None; break; case 1: result = SymbolInfoFactory.Create(symbols, LookupResultKind.Viable, isDynamic: false); break; default: result = SymbolInfoFactory.Create(symbols, LookupResultKind.Ambiguous, isDynamic: false); break; } } } else if ((crefSyntax = node as CrefSyntax) != null) { int adjustedPosition = GetAdjustedNodePosition(crefSyntax); result = GetCrefSymbolInfo(adjustedPosition, crefSyntax, options, HasParameterList(crefSyntax)); } else { // if expression is not part of a member context then caller may really just have a // reference to a type or namespace name var symbol = GetSemanticInfoSymbolInNonMemberContext(node, bindVarAsAliasFirst: (options & SymbolInfoOptions.PreserveAliases) != 0); result = (object)symbol != null ? GetSymbolInfoForSymbol(symbol, options) : SymbolInfo.None; } return result; }
private static BoundFieldInitializer BindFieldInitializer(Binder binder, FieldSymbol fieldSymbol, EqualsValueClauseSyntax equalsValueClauseNode, DiagnosticBag diagnostics) { Debug.Assert(!fieldSymbol.IsMetadataConstant); var fieldsBeingBound = binder.FieldsBeingBound; var sourceField = fieldSymbol as SourceMemberFieldSymbol; bool isImplicitlyTypedField = (object)sourceField != null && sourceField.FieldTypeInferred(fieldsBeingBound); // If the type is implicitly typed, the initializer diagnostics have already been reported, so ignore them here: // CONSIDER (tomat): reusing the bound field initializers for implicitly typed fields. DiagnosticBag initializerDiagnostics; if (isImplicitlyTypedField) { initializerDiagnostics = DiagnosticBag.GetInstance(); } else { initializerDiagnostics = diagnostics; } var collisionDetector = new LocalScopeBinder(binder); var boundInitValue = collisionDetector.BindVariableOrAutoPropInitializer(equalsValueClauseNode, fieldSymbol.GetFieldType(fieldsBeingBound), initializerDiagnostics); if (isImplicitlyTypedField) { initializerDiagnostics.Free(); } return new BoundFieldInitializer( equalsValueClauseNode.Value, //we want the attached sequence point to indicate the value node fieldSymbol, boundInitValue); }
/// <summary> /// In script C#, some field initializers are assignments to fields and others are global /// statements. There are no restrictions on accessing instance members. /// </summary> private static void BindScriptFieldInitializers(CSharpCompilation compilation, MethodSymbol scriptCtor, ImmutableArray<ImmutableArray<FieldInitializer>> initializers, ArrayBuilder<BoundInitializer> boundInitializers, DiagnosticBag diagnostics, bool generateDebugInfo, out ConsList<Imports> firstDebugImports) { Debug.Assert((object)scriptCtor != null); firstDebugImports = null; for (int i = 0; i < initializers.Length; i++) { ImmutableArray<FieldInitializer> siblingInitializers = initializers[i]; // All sibling initializers share the same parent node and tree so we can reuse the binder // factory across siblings. Unfortunately, we cannot reuse the binder itself, because // individual fields might have their own binders (e.g. because of being declared unsafe). BinderFactory binderFactory = null; for (int j = 0; j < siblingInitializers.Length; j++) { var initializer = siblingInitializers[j]; var fieldSymbol = initializer.Field; if ((object)fieldSymbol != null && fieldSymbol.IsConst) { // Constants do not need field initializers. continue; } var syntaxRef = initializer.Syntax; Debug.Assert(syntaxRef.SyntaxTree.Options.Kind != SourceCodeKind.Regular); var initializerNode = (CSharpSyntaxNode)syntaxRef.GetSyntax(); if (binderFactory == null) { binderFactory = compilation.GetBinderFactory(syntaxRef.SyntaxTree); } Binder scriptClassBinder = binderFactory.GetBinder(initializerNode); Debug.Assert(((ImplicitNamedTypeSymbol)scriptClassBinder.ContainingMemberOrLambda).IsScriptClass); if (generateDebugInfo && firstDebugImports == null) { firstDebugImports = scriptClassBinder.ImportsList; } Binder parentBinder = new ExecutableCodeBinder((CSharpSyntaxNode)syntaxRef.SyntaxTree.GetRoot(), scriptCtor, scriptClassBinder); BoundInitializer boundInitializer; if ((object)fieldSymbol != null) { boundInitializer = BindFieldInitializer( new LocalScopeBinder(parentBinder).WithAdditionalFlagsAndContainingMemberOrLambda(parentBinder.Flags | BinderFlags.FieldInitializer, fieldSymbol), fieldSymbol, (EqualsValueClauseSyntax)initializerNode, diagnostics); } else if (initializerNode.Kind == SyntaxKind.LabeledStatement) { // TODO: labels in interactive var boundStatement = new BoundBadStatement(initializerNode, ImmutableArray<BoundNode>.Empty, true); boundInitializer = new BoundGlobalStatementInitializer(initializerNode, boundStatement); } else { var collisionDetector = new LocalScopeBinder(parentBinder); boundInitializer = BindGlobalStatement(collisionDetector, (StatementSyntax)initializerNode, diagnostics, isLast: i == initializers.Length - 1 && j == siblingInitializers.Length - 1); } boundInitializers.Add(boundInitializer); } } }
/// <summary> /// In regular C#, all field initializers are assignments to fields and the assigned expressions /// may not reference instance members. /// </summary> internal static void BindRegularCSharpFieldInitializers( CSharpCompilation compilation, ImmutableArray<ImmutableArray<FieldOrPropertyInitializer>> initializers, ArrayBuilder<BoundInitializer> boundInitializers, DiagnosticBag diagnostics, out ImportChain firstDebugImports) { firstDebugImports = null; foreach (ImmutableArray<FieldOrPropertyInitializer> siblingInitializers in initializers) { // All sibling initializers share the same parent node and tree so we can reuse the binder // factory across siblings. Unfortunately, we cannot reuse the binder itself, because // individual fields might have their own binders (e.g. because of being declared unsafe). BinderFactory binderFactory = null; foreach (FieldOrPropertyInitializer initializer in siblingInitializers) { FieldSymbol fieldSymbol = initializer.FieldOpt; Debug.Assert((object)fieldSymbol != null); // A constant field of type decimal needs a field initializer, so // check if it is a metadata constant, not just a constant to exclude // decimals. Other constants do not need field initializers. if (!fieldSymbol.IsMetadataConstant) { //Can't assert that this is a regular C# compilation, because we could be in a nested type of a script class. SyntaxReference syntaxRef = initializer.Syntax; var initializerNode = (EqualsValueClauseSyntax)syntaxRef.GetSyntax(); if (binderFactory == null) { binderFactory = compilation.GetBinderFactory(syntaxRef.SyntaxTree); } Binder parentBinder = binderFactory.GetBinder(initializerNode); Debug.Assert(parentBinder.ContainingMemberOrLambda == fieldSymbol.ContainingType || //should be the binder for the type fieldSymbol.ContainingType.IsImplicitClass); //however, we also allow fields in namespaces to help support script scenarios if (firstDebugImports == null) { firstDebugImports = parentBinder.ImportChain; } parentBinder = new LocalScopeBinder(parentBinder).WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.FieldInitializer, fieldSymbol); BoundFieldInitializer boundInitializer = BindFieldInitializer(parentBinder, fieldSymbol, initializerNode, diagnostics); boundInitializers.Add(boundInitializer); } } } }
private UnboundLambda BindAnonymousFunction(CSharpSyntaxNode syntax, DiagnosticBag diagnostics) { Debug.Assert(syntax != null); Debug.Assert(syntax.IsAnonymousFunction()); var results = AnalyzeAnonymousFunction(syntax, diagnostics); var refKinds = results.Item1; var types = results.Item2; var names = results.Item3; var isAsync = results.Item4; if (!types.IsDefault) { foreach (var type in types) { // UNDONE: Where do we report improper use of pointer types? if ((object)type != null && type.IsStatic) { Error(diagnostics, ErrorCode.ERR_ParameterIsStaticClass, syntax, type); } } } var lambda = new UnboundLambda(syntax, this, refKinds, types, names, isAsync); if (!names.IsDefault) { var binder = new LocalScopeBinder(this.ContainingMemberOrLambda as MethodSymbol, this); for (int n = 0; n < names.Length; ++n) { string name = lambda.ParameterName(n); binder.ValidateLambdaParameterNameConflictsInScope(lambda.ParameterLocation(n), name, diagnostics); } } return lambda; }
private Binder GetFieldOrPropertyInitializerBinder(FieldSymbol symbol, Binder outer, EqualsValueClauseSyntax initializer) { BinderFlags flags = BinderFlags.None; // NOTE: checking for a containing script class is sufficient, but the regular C# test is quick and easy. if (this.IsRegularCSharp || !symbol.ContainingType.IsScriptClass) { flags |= BinderFlags.FieldInitializer; } outer = new LocalScopeBinder(outer).WithAdditionalFlagsAndContainingMemberOrLambda(flags, symbol); if (initializer != null) { outer = new ExecutableCodeBinder(initializer, symbol, outer); } return outer; }
public static ImmutableArray<ParameterSymbol> MakeParameters( Binder binder, Symbol owner, BaseParameterListSyntax syntax, bool allowRefOrOut, out SyntaxToken arglistToken, DiagnosticBag diagnostics) { arglistToken = default(SyntaxToken); int parameterIndex = 0; int firstDefault = -1; var builder = ArrayBuilder<ParameterSymbol>.GetInstance(); ImmutableArray<ParameterSymbol> result; var parameterBinder = new LocalScopeBinder(binder); foreach (var parameterSyntax in syntax.Parameters) { SyntaxToken outKeyword; SyntaxToken refKeyword; SyntaxToken paramsKeyword; SyntaxToken thisKeyword; var refKind = GetModifiers(parameterSyntax.Modifiers, out outKeyword, out refKeyword, out paramsKeyword, out thisKeyword); if (parameterSyntax.IsArgList) { arglistToken = parameterSyntax.Identifier; // The native compiler produces "Expected type" here, in the parser. Roslyn produces // the somewhat more informative "arglist not valid" error. if (paramsKeyword.CSharpKind() != SyntaxKind.None || outKeyword.CSharpKind() != SyntaxKind.None || refKeyword.CSharpKind() != SyntaxKind.None || thisKeyword.CSharpKind() != SyntaxKind.None) { // CS1669: __arglist is not valid in this context diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, arglistToken.GetLocation()); } continue; } if (parameterSyntax.Default != null && firstDefault == -1) { firstDefault = parameterIndex; } Debug.Assert(parameterSyntax.Type != null); var parameterType = binder.BindType(parameterSyntax.Type, diagnostics); if (!allowRefOrOut && (refKind != RefKind.None)) { var outOrRefKeyword = (outKeyword.CSharpKind() != SyntaxKind.None) ? outKeyword : refKeyword; Debug.Assert(outOrRefKeyword.CSharpKind() != SyntaxKind.None); // error CS0631: ref and out are not valid in this context diagnostics.Add(ErrorCode.ERR_IllegalRefParam, outOrRefKeyword.GetLocation()); } var parameter = SourceParameterSymbol.Create( binder, owner, parameterType, parameterSyntax, refKind, parameterSyntax.Identifier, parameterIndex, (paramsKeyword.CSharpKind() != SyntaxKind.None), parameterIndex == 0 && thisKeyword.CSharpKind() != SyntaxKind.None, diagnostics); ReportParameterErrors(owner, parameterSyntax, parameter, firstDefault, diagnostics); builder.Add(parameter); ++parameterIndex; } result = builder.ToImmutableAndFree(); parameterBinder.EnterParameters(owner as MethodSymbol, result, diagnostics); return result; }
internal static ImmutableArray<LocalSymbol> GetFieldInitializerInfos( CSharpCompilation compilation, FieldInitializers siblingInitializers, ArrayBuilder<FieldInitializerInfo> infos, bool generateDebugInfo, ref ConsList<Imports> firstDebugImports) { // All sibling initializers share the same parent node and tree so we can reuse the binder // factory across siblings. Unfortunately, we cannot reuse the binder itself, because // individual fields might have their own binders (e.g. because of being declared unsafe). BinderFactory binderFactory = null; foreach (FieldInitializer initializer in siblingInitializers.Initializers) { FieldSymbol fieldSymbol = initializer.Field; Debug.Assert((object)fieldSymbol != null); // A constant field of type decimal needs a field initializer, so // check if it is a metadata constant, not just a constant to exclude // decimals. Other constants do not need field initializers. if (!fieldSymbol.IsMetadataConstant) { //Can't assert that this is a regular C# compilation, because we could be in a nested type of a script class. SyntaxReference syntaxRef = initializer.Syntax; var initializerNode = (EqualsValueClauseSyntax)syntaxRef.GetSyntax(); if (binderFactory == null) { binderFactory = compilation.GetBinderFactory(syntaxRef.SyntaxTree); } Binder parentBinder = binderFactory.GetBinder(initializerNode); Debug.Assert(parentBinder.ContainingMemberOrLambda == fieldSymbol.ContainingType || //should be the binder for the type fieldSymbol.ContainingType.IsImplicitClass); //however, we also allow fields in namespaces to help support script scenarios if (generateDebugInfo && firstDebugImports == null) { firstDebugImports = parentBinder.ImportsList; } parentBinder = new LocalScopeBinder(parentBinder).WithAdditionalFlagsAndContainingMemberOrLambda(parentBinder.Flags | BinderFlags.FieldInitializer, fieldSymbol); if (!fieldSymbol.IsConst && !fieldSymbol.IsStatic) { parentBinder = parentBinder.WithPrimaryConstructorParametersIfNecessary(fieldSymbol.ContainingType); } infos.Add(new FieldInitializerInfo(initializer, parentBinder, initializerNode)); } } // See if there are locals that we need to bring into the scope. var locals = default(ImmutableArray<LocalSymbol>); if (siblingInitializers.TypeDeclarationSyntax != null) { locals = GetInitializationScopeLocals(infos); if (!locals.IsDefaultOrEmpty) { for (int i = 0; i < infos.Count; i++) { FieldInitializerInfo info = infos[i]; // Constant initializers is not part of the initialization scope. if (!info.Initializer.Field.IsConst) { infos[i] = new FieldInitializerInfo(info.Initializer, new SimpleLocalScopeBinder(locals, info.Binder), info.EqualsValue); } } } } return locals; }
private UnboundLambda BindAnonymousFunction(CSharpSyntaxNode syntax, DiagnosticBag diagnostics) { Debug.Assert(syntax != null); Debug.Assert(syntax.IsAnonymousFunction()); var results = AnalyzeAnonymousFunction(syntax, diagnostics); var refKinds = results.Item1; var types = results.Item2; var names = results.Item3; var isAsync = results.Item4; if (!types.IsDefault) { foreach (var type in types) { // UNDONE: Where do we report improper use of pointer types? if ((object)type != null && type.IsStatic) { Error(diagnostics, ErrorCode.ERR_ParameterIsStaticClass, syntax, type); } } } var lambda = new UnboundLambda(syntax, this, refKinds, types, names, isAsync); if (!names.IsDefault) { var binder = new LocalScopeBinder(this); var pNames = PooledHashSet<string>.GetInstance(); for (int i = 0; i < lambda.ParameterCount; i ++) { var name = lambda.ParameterName(i); if (string.IsNullOrEmpty(name)) { continue; } if (pNames.Contains(name)) { // The parameter name '{0}' is a duplicate diagnostics.Add(ErrorCode.ERR_DuplicateParamName, lambda.ParameterLocation(i), name); } else { pNames.Add(name); binder.ValidateLambdaParameterNameConflictsInScope(lambda.ParameterLocation(i), name, diagnostics); } } pNames.Free(); } return lambda; }
public static ImmutableArray <ParameterSymbol> MakeParameters( Binder binder, Symbol owner, BaseParameterListSyntax syntax, bool allowRefOrOut, out SyntaxToken arglistToken, DiagnosticBag diagnostics) { arglistToken = default(SyntaxToken); int parameterIndex = 0; int firstDefault = -1; var builder = ArrayBuilder <ParameterSymbol> .GetInstance(); ImmutableArray <ParameterSymbol> result; var parameterBinder = new LocalScopeBinder(binder); foreach (var parameterSyntax in syntax.Parameters) { SyntaxToken outKeyword; SyntaxToken refKeyword; SyntaxToken paramsKeyword; SyntaxToken thisKeyword; var refKind = GetModifiers(parameterSyntax.Modifiers, out outKeyword, out refKeyword, out paramsKeyword, out thisKeyword); if (parameterSyntax.IsArgList) { arglistToken = parameterSyntax.Identifier; // The native compiler produces "Expected type" here, in the parser. Roslyn produces // the somewhat more informative "arglist not valid" error. if (paramsKeyword.CSharpKind() != SyntaxKind.None || outKeyword.CSharpKind() != SyntaxKind.None || refKeyword.CSharpKind() != SyntaxKind.None || thisKeyword.CSharpKind() != SyntaxKind.None) { // CS1669: __arglist is not valid in this context diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, arglistToken.GetLocation()); } continue; } if (parameterSyntax.Default != null && firstDefault == -1) { firstDefault = parameterIndex; } Debug.Assert(parameterSyntax.Type != null); var parameterType = binder.BindType(parameterSyntax.Type, diagnostics); if (!allowRefOrOut && (refKind != RefKind.None)) { var outOrRefKeyword = (outKeyword.CSharpKind() != SyntaxKind.None) ? outKeyword : refKeyword; Debug.Assert(outOrRefKeyword.CSharpKind() != SyntaxKind.None); // error CS0631: ref and out are not valid in this context diagnostics.Add(ErrorCode.ERR_IllegalRefParam, outOrRefKeyword.GetLocation()); } var parameter = SourceParameterSymbol.Create( binder, owner, parameterType, parameterSyntax, refKind, parameterSyntax.Identifier, parameterIndex, (paramsKeyword.CSharpKind() != SyntaxKind.None), parameterIndex == 0 && thisKeyword.CSharpKind() != SyntaxKind.None, diagnostics); ReportParameterErrors(owner, parameterSyntax, parameter, firstDefault, diagnostics); builder.Add(parameter); ++parameterIndex; } result = builder.ToImmutableAndFree(); parameterBinder.EnterParameters(owner as MethodSymbol, result, diagnostics); return(result); }