private BoundExpression MakeIndexerAccess( SyntaxNode syntax, BoundExpression rewrittenReceiver, PropertySymbol indexer, ImmutableArray <BoundExpression> rewrittenArguments, ImmutableArray <string> argumentNamesOpt, ImmutableArray <RefKind> argumentRefKindsOpt, bool expanded, ImmutableArray <int> argsToParamsOpt, TypeSymbol type, BoundIndexerAccess oldNodeOpt, bool isLeftOfAssignment) { if (isLeftOfAssignment && indexer.RefKind == RefKind.None) { // This is an indexer set access. We return a BoundIndexerAccess node here. // This node will be rewritten with MakePropertyAssignment when rewriting the enclosing BoundAssignmentOperator. return(oldNodeOpt != null? oldNodeOpt.Update(rewrittenReceiver, indexer, rewrittenArguments, argumentNamesOpt, argumentRefKindsOpt, expanded, argsToParamsOpt, null, isLeftOfAssignment, type) : new BoundIndexerAccess(syntax, rewrittenReceiver, indexer, rewrittenArguments, argumentNamesOpt, argumentRefKindsOpt, expanded, argsToParamsOpt, null, isLeftOfAssignment, type)); } else { var getMethod = indexer.GetOwnOrInheritedGetMethod(); Debug.Assert((object)getMethod != null); // 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; rewrittenArguments = MakeArguments( syntax, rewrittenArguments, indexer, getMethod, expanded, argsToParamsOpt, ref argumentRefKindsOpt, out temps, enableCallerInfo: ThreeState.True); BoundExpression call = MakePropertyGetAccess(syntax, rewrittenReceiver, indexer, rewrittenArguments, getMethod); if (temps.IsDefaultOrEmpty) { return(call); } else { return(new BoundSequence( syntax, temps, ImmutableArray <BoundExpression> .Empty, call, type)); } } }
private BoundExpression MakeIndexerAccess( SyntaxNode syntax, BoundExpression rewrittenReceiver, PropertySymbol indexer, ImmutableArray <BoundExpression> rewrittenArguments, ImmutableArray <string> argumentNamesOpt, ImmutableArray <RefKind> argumentRefKindsOpt, bool expanded, ImmutableArray <int> argsToParamsOpt, TypeSymbol type, BoundIndexerAccess oldNodeOpt, bool isLeftOfAssignment) { // check for System.Array.[Length|LongLength] on a single dimensional array, // we have a special node for such cases. if (rewrittenReceiver != null && rewrittenReceiver.Type.IsArray() && !isLeftOfAssignment) { // NOTE: we are not interested in potential badness of Array.Length property. // If it is bad reference compare will not succeed. var specialIndexer = _compilation.GetSpecialTypeMember(SpecialMember.core_Array_T__item); if (ReferenceEquals(indexer.OriginalDefinition, specialIndexer)) { return(new BoundArrayAccess(syntax, rewrittenReceiver, rewrittenArguments[0], indexer.Type.TypeSymbol)); } } if (isLeftOfAssignment && indexer.RefKind == RefKind.None) { // This is an indexer set access. We return a BoundIndexerAccess node here. // This node will be rewritten with MakePropertyAssignment when rewriting the enclosing BoundAssignmentOperator. return(oldNodeOpt != null? oldNodeOpt.Update(rewrittenReceiver, indexer, rewrittenArguments, argumentNamesOpt, argumentRefKindsOpt, expanded, argsToParamsOpt, null, isLeftOfAssignment, type) : new BoundIndexerAccess(syntax, rewrittenReceiver, indexer, rewrittenArguments, argumentNamesOpt, argumentRefKindsOpt, expanded, argsToParamsOpt, null, isLeftOfAssignment, type)); } else { var getMethod = indexer.GetOwnOrInheritedGetMethod(); Debug.Assert((object)getMethod != null); // 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; rewrittenArguments = MakeArguments( syntax, rewrittenArguments, indexer, getMethod, expanded, argsToParamsOpt, ref argumentRefKindsOpt, out temps, enableCallerInfo: ThreeState.True); BoundExpression call = MakePropertyGetAccess(syntax, rewrittenReceiver, indexer, rewrittenArguments, getMethod); if (temps.IsDefaultOrEmpty) { return(call); } else { return(new BoundSequence( syntax, temps, ImmutableArray <BoundExpression> .Empty, call, type)); } } }