private BoundExpression BindElementAccess(ElementAccessExpressionSyntax node) { Debug.Assert(node != null); var expr = BindExpression(node.Expression); // , BIND_RVALUEREQUIRED); var arguments = node.ArgumentList.Arguments .Select(arg => BindExpression(arg.Expression)) .ToList(); var argumentNames = node.ArgumentList.Arguments .Select(arg => arg.NameColonOpt) .Select(namecolon => namecolon != null ? namecolon.Identifier.GetText() : null) .ToList(); if (expr.GetExpressionType() == null) { return(BoundArrayAccess.AsError(node, expr, arguments, null)); } if (!expr.IsOK || arguments.Any(x => !x.IsOK)) { // At this point we definitely have reported an error, but we still might be // able to get more semantic analysis of the indexing operation. We do not // want to report cascading errors. // UNDONE: Set the error bit on the result? return(GetErrorSuppressingAnalyzer().BindElementAccessCore(node, expr, arguments, argumentNames)); } return(BindElementAccessCore(node, expr, arguments, argumentNames)); }
private BoundExpression BindArrayAccess(ElementAccessExpressionSyntax node, BoundExpression expr, IList <BoundExpression> arguments, IList <string> argumentNames) { Debug.Assert(node != null); Debug.Assert(expr != null); Debug.Assert(arguments != null); Debug.Assert(argumentNames != null); // For an array access, the primary-no-array-creation-expression of the element-access must // be a value of an array-type. Furthermore, the argument-list of an array access is not // allowed to contain named arguments.The number of expressions in the argument-list must // be the same as the rank of the array-type, and each expression must be of type // int, uint, long, ulong, or must be implicitly convertible to one or more of these types. if (argumentNames.Any(x => x != null)) { Error(ErrorCode.ERR_NamedArgumentForArray, node); } var arrayType = (ArrayTypeSymbol)expr.GetExpressionType(); // Note that the spec says to determine which of {int, uint, long, ulong} *each* // index expression is convertible to. That is not what C# 1 through 4 // did; the implementations instead determined which of those four // types *all* of the index expressions converted to. int rank = arrayType.Rank; if (arguments.Count != arrayType.Rank) { Error(ErrorCode.ERR_BadIndexCount, node, rank); return(BoundArrayAccess.AsError(node, expr, arguments, arrayType.ElementType)); } var convertedArguments = arguments.Select(x => ConvertToArrayIndex(x)).ToList(); return(new BoundArrayAccess(node, expr, convertedArguments, arrayType.ElementType)); }