public static bool TryGetElementTypesIfTupleOrCompatible(this TypeSymbol type, out ImmutableArray <TypeSymbol> elementTypes) { if (type.IsTupleType) { elementTypes = ((TupleTypeSymbol)type).TupleElementTypes; return(true); } // The following codepath should be very uncommon since it would be rare // to see a tuple underlying type not represented as a tuple. // It still might happen since tuple underlying types are creatable via public APIs // and it is also possible that they would be passed in. // PERF: if allocations here become nuisance, consider caching the results // in the type symbols that can actually be tuple compatible int cardinality; if (!type.IsTupleCompatible(out cardinality)) { // source not a tuple or compatible elementTypes = default(ImmutableArray <TypeSymbol>); return(false); } var elementTypesBuilder = ArrayBuilder <TypeSymbol> .GetInstance(cardinality); TupleTypeSymbol.AddElementTypes((NamedTypeSymbol)type, elementTypesBuilder); Debug.Assert(elementTypesBuilder.Count == cardinality); elementTypes = elementTypesBuilder.ToImmutableAndFree(); return(true); }
/// <summary> /// Same as <see cref="SubstituteType"/>, but with special behavior around tuples. /// In particular, if substitution makes type tuple compatible, transform it into a tuple type. /// </summary> internal TypeWithModifiers SubstituteTypeWithTupleUnification(TypeSymbol previous) { TypeWithModifiers result = SubstituteType(previous); // Make it a tuple if it became compatible with one. if ((object)result.Type != null && !previous.IsTupleCompatible()) { var possiblyTuple = TupleTypeSymbol.TransformToTupleIfCompatible(result.Type); if ((object)result.Type != possiblyTuple) { result = new TypeWithModifiers(possiblyTuple, result.CustomModifiers); } } return(result); }
public static ImmutableArray <TypeSymbol> GetElementTypesOfTupleOrCompatible(this TypeSymbol type) { if (type.IsTupleType) { return(((TupleTypeSymbol)type).TupleElementTypes); } // The following codepath should be very uncommon since it would be rare // to see a tuple underlying type not represented as a tuple. // It still might happen since tuple underlying types are creatable via public APIs // and it is also possible that they would be passed in. Debug.Assert(type.IsTupleCompatible()); // PERF: if allocations here become nuisance, consider caching the results // in the type symbols that can actually be tuple compatible var elementTypesBuilder = ArrayBuilder <TypeSymbol> .GetInstance(); TupleTypeSymbol.AddElementTypes((NamedTypeSymbol)type, elementTypesBuilder); return(elementTypesBuilder.ToImmutableAndFree()); }
/// <summary> /// Same as <see cref="SubstituteType"/>, but with special behavior around tuples. /// In particular, if substitution makes type tuple compatible, transform it into a tuple type. /// </summary> internal TypeWithModifiers SubstituteTypeWithTupleUnification(TypeSymbol previous) { TypeWithModifiers result = SubstituteType(previous); // Make it a tuple if it became compatible with one. if ((object)result.Type != null && !previous.IsTupleCompatible()) { var possiblyTuple = TupleTypeSymbol.TransformToTupleIfCompatible(result.Type); if ((object)result.Type != possiblyTuple) { result = new TypeWithModifiers(possiblyTuple, result.CustomModifiers); } } return result; }