예제 #1
0
        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);
        }
예제 #2
0
        protected override bool HasImplicitTupleConversion(BoundExpression source, TypeSymbol destination, ref HashSet <DiagnosticInfo> useSiteDiagnostics)
        {
            if (source.Kind != BoundKind.TupleLiteral)
            {
                // source must be a tuple literal with no conversions
                return(false);
            }

            var tupleExpression = (BoundTupleLiteral)source;
            var arguments       = tupleExpression.Arguments;

            // check if the type is actually compatible type for a tuple of given cardinality
            if (!destination.IsTupleOrCompatibleWithTupleOfCardinality(arguments.Length))
            {
                return(false);
            }

            var targetElementTypes = ArrayBuilder <TypeSymbol> .GetInstance(arguments.Length);

            TupleTypeSymbol.AddElementTypes((NamedTypeSymbol)destination, targetElementTypes);
            Debug.Assert(arguments.Length == targetElementTypes.Count);

            try
            {
                // check arguments against flattened list of target element types
                for (int i = 0; i < arguments.Length; i++)
                {
                    var argument = arguments[i];
                    var result   = ClassifyImplicitConversionFromExpression(argument, targetElementTypes[i], ref useSiteDiagnostics);
                    if (!result.Exists)
                    {
                        return(false);
                    }
                }

                return(true);
            }
            finally
            {
                targetElementTypes.Free();
            }
        }
예제 #3
0
        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());
        }