/// <summary> /// Converts access to a tuple instance into access into the underlying ValueTuple(s). /// /// For instance, tuple.Item8 /// produces fieldAccess(field=Item1, receiver=fieldAccess(field=Rest, receiver=ValueTuple for tuple)) /// </summary> private BoundExpression MakeTupleFieldAccess( SyntaxNode syntax, FieldSymbol tupleField, BoundExpression rewrittenReceiver, ConstantValue constantValueOpt, LookupResultKind resultKind) { var tupleType = tupleField.ContainingType; NamedTypeSymbol currentLinkType = tupleType.TupleUnderlyingType; FieldSymbol underlyingField = tupleField.TupleUnderlyingField; if ((object)underlyingField == null) { // Use-site error must have been reported elsewhere. return(_factory.BadExpression(tupleField.Type.TypeSymbol)); } if (rewrittenReceiver.Kind == BoundKind.DefaultExpression) { // Optimization: `default((int, string)).Item2` is simply `default(string)` return(new BoundDefaultExpression(syntax, tupleField.Type.TypeSymbol)); } if (!TypeSymbol.Equals(underlyingField.ContainingType, currentLinkType, TypeCompareKind.ConsiderEverything2)) { WellKnownMember wellKnownTupleRest = TupleTypeSymbol.GetTupleTypeMember(TupleTypeSymbol.RestPosition, TupleTypeSymbol.RestPosition); var tupleRestField = (FieldSymbol)TupleTypeSymbol.GetWellKnownMemberInType(currentLinkType.OriginalDefinition, wellKnownTupleRest, _diagnostics, syntax); if ((object)tupleRestField == null) { // error tolerance for cases when Rest is missing return(_factory.BadExpression(tupleField.Type.TypeSymbol)); } // make nested field accesses to Rest do { FieldSymbol nestedFieldSymbol = tupleRestField.AsMember(currentLinkType); rewrittenReceiver = _factory.Field(rewrittenReceiver, nestedFieldSymbol); currentLinkType = currentLinkType.TypeArgumentsNoUseSiteDiagnostics[TupleTypeSymbol.RestPosition - 1].TypeSymbol.TupleUnderlyingType; }while (!TypeSymbol.Equals(underlyingField.ContainingType, currentLinkType, TypeCompareKind.ConsiderEverything2)); } // make a field access for the most local access return(_factory.Field(rewrittenReceiver, underlyingField)); }
/// <summary> /// Converts access to a tuple instance into access into the underlying ValueTuple(s). /// /// For instance, tuple.Item8 /// produces fieldAccess(field=Item1, receiver=fieldAccess(field=Rest, receiver=ValueTuple for tuple)) /// </summary> private BoundExpression MakeTupleFieldAccess( CSharpSyntaxNode syntax, FieldSymbol tupleField, BoundExpression rewrittenReceiver, ConstantValue constantValueOpt, LookupResultKind resultKind, TypeSymbol type) { var tupleType = tupleField.ContainingType; NamedTypeSymbol currentLinkType = tupleType.TupleUnderlyingType; FieldSymbol underlyingField = tupleField.TupleUnderlyingField; if ((object)underlyingField == null) { // Use-site error must have been reported elsewhere. return(new BoundFieldAccess(syntax, rewrittenReceiver, tupleField, constantValueOpt, resultKind, type, hasErrors: true)); } if (underlyingField.ContainingType != currentLinkType) { WellKnownMember wellKnownTupleRest = TupleTypeSymbol.GetTupleTypeMember(TupleTypeSymbol.RestPosition, TupleTypeSymbol.RestPosition); var tupleRestField = (FieldSymbol)TupleTypeSymbol.GetWellKnownMemberInType(currentLinkType.OriginalDefinition, wellKnownTupleRest, _diagnostics, syntax); if ((object)tupleRestField == null) { // error tolerance for cases when Rest is missing return(new BoundFieldAccess(syntax, rewrittenReceiver, tupleField, constantValueOpt, resultKind, type, hasErrors: true)); } // make nested field accesses to Rest do { FieldSymbol nestedFieldSymbol = tupleRestField.AsMember(currentLinkType); currentLinkType = currentLinkType.TypeArgumentsNoUseSiteDiagnostics[TupleTypeSymbol.RestPosition - 1].TupleUnderlyingType; rewrittenReceiver = new BoundFieldAccess(syntax, rewrittenReceiver, nestedFieldSymbol, ConstantValue.NotAvailable, LookupResultKind.Viable, currentLinkType); }while (underlyingField.ContainingType != currentLinkType); } // make a field access for the most local access return(new BoundFieldAccess(syntax, rewrittenReceiver, underlyingField, constantValueOpt, resultKind, type)); }