private BoundExpression BindElementAccessCore(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); // UNDONE: Suppose we have an indexed property P on an instance c. Suppose the // UNDONE: type of the property is int[]. When binding c.P[123] we must // UNDONE: treat this as an invocation of the indexed property, not as a // UNDONE: dereference of the array returned by the property. //if (expr.isPROP() && expr.asPROP().IsUnboundIndexedProperty() && // !IsPropertyBindingInsideBindIndexerContext(node.Expression)) //{ // return BindIndexerAccess(node, expr, arguments, argumentNames); //} var exprType = expr.GetExpressionType(); // UNDONE: Ensure that the type of the expression has members defined. if (exprType is ArrayTypeSymbol) { return BindArrayAccess(node, expr, arguments, argumentNames); } else if (exprType is PointerTypeSymbol) { return BindPointerElementAccess(node, expr, arguments, argumentNames); } else { return BindIndexerAccess(node, expr, arguments, argumentNames); } }
private BoundExpression BindElementAccessCore(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); // UNDONE: Suppose we have an indexed property P on an instance c. Suppose the // UNDONE: type of the property is int[]. When binding c.P[123] we must // UNDONE: treat this as an invocation of the indexed property, not as a // UNDONE: dereference of the array returned by the property. //if (expr.isPROP() && expr.asPROP().IsUnboundIndexedProperty() && // !IsPropertyBindingInsideBindIndexerContext(node.Expression)) //{ // return BindIndexerAccess(node, expr, arguments, argumentNames); //} var exprType = expr.GetExpressionType(); // UNDONE: Ensure that the type of the expression has members defined. if (exprType is ArrayTypeSymbol) { return(BindArrayAccess(node, expr, arguments, argumentNames)); } else if (exprType is PointerTypeSymbol) { return(BindPointerElementAccess(node, expr, arguments, argumentNames)); } else { return(BindIndexerAccess(node, expr, arguments, argumentNames)); } }
public static string GetErrorReportingName(BoundExpression expression) { switch (expression.Kind) { case BoundKind.Literal: if (expression.ConstantValue.IsNull) { return("<null>"); } break; case BoundKind.Lambda: case BoundKind.UnboundLambda: return("lambda expression"); // UNDONE: or "anonymous method" case BoundKind.MethodGroup: return("method group"); } return(GetErrorReportingName(expression.GetExpressionType())); }
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)); }
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); }
public static string GetErrorReportingName(BoundExpression expression) { switch(expression.Kind) { case BoundKind.Literal: if (expression.ConstantValue.IsNull) return "<null>"; break; case BoundKind.Lambda: case BoundKind.UnboundLambda: return "lambda expression"; // UNDONE: or "anonymous method" case BoundKind.MethodGroup: return "method group"; } return GetErrorReportingName(expression.GetExpressionType()); }