public override ResolvedTypeKind OnTypeParameter(QsTypeParameter tp)
 {
     if (this.SharedState.TypeParams.TryGetValue(Tuple.Create(tp.Origin, tp.TypeName), out var typeParam))
     {
         return(typeParam.Resolution);
     }
     return(ResolvedTypeKind.NewTypeParameter(tp));
 }
 internal CallableDetails(QsCallable callable)
 {
     this.Callable = callable;
     // ToDo: this may need to be adapted once we support type specializations
     this.Adjoint = callable.Specializations.FirstOrDefault(spec => spec.Kind == QsSpecializationKind.QsAdjoint);
     this.Controlled = callable.Specializations.FirstOrDefault(spec => spec.Kind == QsSpecializationKind.QsControlled);
     this.ControlledAdjoint = callable.Specializations.FirstOrDefault(spec => spec.Kind == QsSpecializationKind.QsControlledAdjoint);
     // ToDo: this may need to be per-specialization
     this.TypeParameters = callable.Signature.TypeParameters.Any(param => param.IsValidName)
     ? QsNullable<ImmutableArray<ResolvedType>>.NewValue(callable.Signature.TypeParameters
         .Where(param => param.IsValidName)
         .Select(param =>
             ResolvedType.New(ResolvedTypeKind.NewTypeParameter(new QsTypeParameter(
                 callable.FullName,
                 ((QsLocalSymbol.ValidName)param).Item,
                 QsNullable<Range>.Null))))
         .ToImmutableArray())
     : QsNullable<ImmutableArray<ResolvedType>>.Null;
 }
                /// <summary>
                /// Creates an operation call from the conditional control API, given information
                /// about which operation to call and with what arguments.
                /// </summary>
                private TypedExpression CreateControlCall(BuiltIn opInfo, IEnumerable <OpProperty> properties, TypedExpression args, IEnumerable <ResolvedType> typeArgs)
                {
                    var characteristics = new CallableInformation(
                        ResolvedCharacteristics.FromProperties(properties),
                        new InferredCallableInformation(((BuiltInKind.Operation)opInfo.Kind).IsSelfAdjoint, false));

                    var unitType      = ResolvedType.New(ResolvedTypeKind.UnitType);
                    var operationType = ResolvedType.New(ResolvedTypeKind.NewOperation(
                                                             Tuple.Create(args.ResolvedType, unitType),
                                                             characteristics));

                    // Build the surrounding control call
                    var identifier = new TypedExpression(
                        ExpressionKind.NewIdentifier(
                            Identifier.NewGlobalCallable(opInfo.FullName),
                            typeArgs.Any()
                            ? QsNullable <ImmutableArray <ResolvedType> > .NewValue(typeArgs.ToImmutableArray())
                            : QsNullable <ImmutableArray <ResolvedType> > .Null),
                        typeArgs
                        .Zip(((BuiltInKind.Operation)opInfo.Kind).TypeParameters, (type, param) => Tuple.Create(opInfo.FullName, param, type))
                        .ToImmutableArray(),
                        operationType,
                        new InferredExpressionInformation(false, false),
                        QsNullable <Tuple <QsPositionInfo, QsPositionInfo> > .Null);

                    // Creates type resolutions for the call expression
                    var opTypeArgResolutions = typeArgs
                                               .SelectMany(x =>
                                                           x.Resolution is ResolvedTypeKind.TupleType tup
                            ? tup.Item
                            : ImmutableArray.Create(x))
                                               .Where(x => x.Resolution.IsTypeParameter)
                                               .Select(x => (x.Resolution as ResolvedTypeKind.TypeParameter).Item)
                                               .GroupBy(x => (x.Origin, x.TypeName))
                                               .Select(group =>
                    {
                        var typeParam = group.First();
                        return(Tuple.Create(typeParam.Origin, typeParam.TypeName, ResolvedType.New(ResolvedTypeKind.NewTypeParameter(typeParam))));
                    })
                                               .ToImmutableArray();

                    return(new TypedExpression(
                               ExpressionKind.NewCallLikeExpression(identifier, args),
                               opTypeArgResolutions,
                               unitType,
                               new InferredExpressionInformation(false, true),
                               QsNullable <Tuple <QsPositionInfo, QsPositionInfo> > .Null));
                }