Esempio n. 1
0
        public QaInstanceCriteria ResolveCriteria(int criteriaId, int qaId, ResolvedType resolvedAs)
        {
            QaInstance qa = _qaInstanceRepository.Get(qaId);

            QaInstanceCriteria criteria;
            foreach (QaInstanceCategory cat in qa.Categories)
            {
                criteria = cat.Criterias.Where(x => x.Id == criteriaId).FirstOrDefault();
                if (criteria != null)
                {
                    criteria.ResolvedAs = resolvedAs;
                    _qaInstanceRepository.SaveQaInstance(qa);
                    return criteria;
                }
            }
            throw new NullReferenceException("No criteria with ID " + criteriaId + " in QA Instance #" + qaId);
        }
Esempio n. 2
0
        public IEnumerable <MemberResult> GetMembers(GetMultipleMembersInput input)
        {
            bool dummyDef;
            List <MemberResult> members = new List <MemberResult>();

            if (Children.Count == 1)
            {
                // we have an array type or a record type definition
                var node = Children[Children.Keys[0]];
                if (node is ArrayTypeReference)
                {
                    return((node as ArrayTypeReference).GetMembersInternal(input));
                }
                else if (node is RecordDefinitionNode)
                {
                    return((node as RecordDefinitionNode).GetMembers(input));
                }
                else if (node is DictionaryDefinitionNode)
                {
                    return((node as DictionaryDefinitionNode).GetMembersInternal(input));
                }
            }
            else if (!string.IsNullOrEmpty(_typeNameString))
            {
                if (!string.IsNullOrWhiteSpace(TableName))
                {
                    // TODO: return the table's columns
                }
                else if (_typeNameString.Equals("string", StringComparison.OrdinalIgnoreCase))
                {
                    return(Genero4glAst.StringFunctions.Values.Where(x => input.AST.LanguageVersion >= x.MinimumLanguageVersion && input.AST.LanguageVersion <= x.MaximumLanguageVersion)
                           .Select(x => new MemberResult(x.Name, x, GeneroMemberType.Method, input.AST)));
                }
                else if (_typeNameString.Equals("text", StringComparison.OrdinalIgnoreCase))
                {
                    return(Genero4glAst.TextFunctions.Values.Where(x => input.AST.LanguageVersion >= x.MinimumLanguageVersion && input.AST.LanguageVersion <= x.MaximumLanguageVersion)
                           .Select(x => new MemberResult(x.Name, x, GeneroMemberType.Method, input.AST)));
                }
                else if (_typeNameString.Equals("byte", StringComparison.OrdinalIgnoreCase))
                {
                    return(Genero4glAst.ByteFunctions.Values.Where(x => input.AST.LanguageVersion >= x.MinimumLanguageVersion && input.AST.LanguageVersion <= x.MaximumLanguageVersion)
                           .Select(x => new MemberResult(x.Name, x, GeneroMemberType.Method, input.AST)));
                }
                else
                {
                    if (ResolvedType != null)
                    {
                        return(ResolvedType.GetMembers(input));
                    }

                    // try to determine if the _typeNameString is a user defined type (or package class), in which case we need to call its GetMembers function
                    IAnalysisResult udt = (input.AST as Genero4glAst).TryGetUserDefinedType(_typeNameString, LocationIndex);
                    if (udt != null)
                    {
                        return(udt.GetMembers(input));
                    }

                    foreach (var includedFile in input.AST.ProjectEntry.GetIncludedFiles())
                    {
                        if (includedFile.Analysis != null)
                        {
                            IGeneroProject dummyProj;
                            IProjectEntry  dummyProjEntry;
                            var            res = includedFile.Analysis.GetValueByIndex(_typeNameString, 1, null, null, null, false, out dummyDef, out dummyProj, out dummyProjEntry);
                            if (res != null)
                            {
                                return(res.GetMembers(input));
                            }
                        }
                    }

                    if (input.AST.ProjectEntry.ParentProject.ReferencedProjects.Count > 0)
                    {
                        foreach (var refProj in input.AST.ProjectEntry.ParentProject.ReferencedProjects.Values)
                        {
                            if (refProj is GeneroProject)
                            {
                                IProjectEntry dummyProj;
                                udt = (refProj as GeneroProject).GetMemberOfType(_typeNameString, input.AST, false, true, false, false, out dummyProj);
                                if (udt != null)
                                {
                                    return(udt.GetMembers(input));
                                }
                            }
                        }
                    }

                    // check for package class
                    IGeneroProject dummyProject;
                    IProjectEntry  projEntry;
                    udt = input.AST.GetValueByIndex(_typeNameString, LocationIndex, input.AST._functionProvider, input.AST._databaseProvider, input.AST._programFileProvider, false, out dummyDef, out dummyProject, out projEntry);
                    if (udt != null)
                    {
                        return(udt.GetMembers(input));
                    }
                }
            }
            return(members);
        }
 public StaticClassReference(Token firstToken, TopLevelEntity parent, ClassLikeDefinition classDef)
     : base(firstToken, parent)
 {
     this.ClassDef     = classDef;
     this.ResolvedType = ResolvedType.FromClass(classDef);
 }
Esempio n. 4
0
        public override ITypeSymbol ResolveTypeSymbol(PhpCompilation compilation)
        {
            if (ResolvedType.IsValidType() && !ResolvedType.IsUnreachable)
            {
                return(ResolvedType);
            }

            TypeSymbol type = null;

            if (_self != null)
            {
                if (_self.FullName == ClassName)
                {
                    type = _self;
                }
                else if (_self.BaseType != null && _self.BaseType.PhpQualifiedName() == ClassName)
                {
                    type = _self.BaseType;
                }
            }

            if (type == null)
            {
                type = (_arity <= 0)
                 ? (TypeSymbol)compilation.GlobalSemantics.ResolveType(ClassName)
                       // generic types only exist in external references, use this method to resolve the symbol including arity (needs metadataname instead of QualifiedName)
                 : compilation.GlobalSemantics.GetTypeFromNonExtensionAssemblies(MetadataHelpers.ComposeAritySuffixedMetadataName(ClassName.ClrName(), _arity));
            }

            var containingFile = _routine?.ContainingFile ?? _self?.ContainingFile;

            if (type is AmbiguousErrorTypeSymbol ambiguous && containingFile != null)
            {
                TypeSymbol best = null;

                // choose the one declared in this file unconditionally
                foreach (var x in ambiguous
                         .CandidateSymbols
                         .Cast <TypeSymbol>()
                         .Where(t => !t.IsUnreachable)
                         .Where(x => x is SourceTypeSymbol srct && !srct.Syntax.IsConditional && srct.ContainingFile == containingFile))
                {
                    if (best == null)
                    {
                        best = x;
                    }
                    else
                    {
                        best = null;
                        break;
                    }
                }

                if (best != null)
                {
                    type = (NamedTypeSymbol)best;
                }
            }

            // translate trait prototype to constructed trait type
            if (type.IsTraitType())
            {
                // <!TSelf> -> <T<Object>>
                var t = (NamedTypeSymbol)type;
                type = t.Construct(t.Construct(compilation.CoreTypes.Object));
            }

            //
            return(ResolvedType = type);
        }
Esempio n. 5
0
        public void ParseOp()
        {
            ArgDeclType BuildArgument(string name, ResolvedType t)
            {
                var validName = QsLocalSymbol.NewValidName(NonNullable <string> .New(name));
                var info      = new InferredExpressionInformation(false, false);

                return(new ArgDeclType(validName, t, info, QsNullable <Tuple <int, int> > .Null, EmptyRange));
            }

            string[] comments =
            {
                "# Summary",
                "Convenience function that performs state preparation by applying a ",
                "`statePrepUnitary` on the input state, followed by adiabatic state ",
                "preparation using a `adiabaticUnitary`, and finally phase estimation ",
                "with respect to `qpeUnitary`on the resulting state using a ",
                "`phaseEstAlgorithm`.",
                "",
                "# Input",
                "## statePrepUnitary",
                "An oracle representing state preparation for the initial dynamical",
                "generator.",
                "## adiabaticUnitary",
                "An oracle representing the adiabatic evolution algorithm to be used",
                "to implement the sweeps to the final state of the algorithm.",
                "## qpeUnitary",
                "An oracle representing a unitary operator $U$ representing evolution",
                "for time $\\delta t$ under a dynamical generator with ground state",
                "$\\ket{\\phi}$ and ground state energy $E = \\phi\\\\,\\delta t$.",
                "## phaseEstAlgorithm",
                "An operation that performs phase estimation on a given unitary operation.",
                "See [iterative phase estimation](/quantum/libraries/characterization#iterative-phase-estimation)",
                "for more details.",
                "## qubits",
                "A register of qubits to be used to perform the simulation.",
                "",
                "# Output",
                "An estimate $\\hat{\\phi}$ of the ground state energy $\\phi$",
                "of the generator represented by $U$."
            };
            string expected = @"### YamlMime:QSharpType
uid: microsoft.quantum.canon.adiabaticstateenergyunitary
name: AdiabaticStateEnergyUnitary
type: operation
namespace: Microsoft.Quantum.Canon
summary: |-
  Convenience function that performs state preparation by applying a
  `statePrepUnitary` on the input state, followed by adiabatic state
  preparation using a `adiabaticUnitary`, and finally phase estimation
  with respect to `qpeUnitary`on the resulting state using a
  `phaseEstAlgorithm`.
syntax: 'operation AdiabaticStateEnergyUnitary (statePrepUnitary : (Qubit[] => Unit), adiabaticUnitary : (Qubit[] => Unit), qpeUnitary : (Qubit[] => Unit is Adj + Ctl), phaseEstAlgorithm : ((Microsoft.Quantum.Canon.DiscreteOracle, Qubit[]) => Double), qubits : Qubit[]) : Double'
input:
  content: '(statePrepUnitary : (Qubit[] => Unit), adiabaticUnitary : (Qubit[] => Unit), qpeUnitary : (Qubit[] => Unit is Adj + Ctl), phaseEstAlgorithm : ((Microsoft.Quantum.Canon.DiscreteOracle, Qubit[]) => Double), qubits : Qubit[])'
  types:
  - name: statePrepUnitary
    summary: |-
      An oracle representing state preparation for the initial dynamical
      generator.
    isOperation: true
    input:
      types:
      - isArray: true
        isPrimitive: true
        uid: Qubit
    output:
      types:
      - isPrimitive: true
        uid: Unit
  - name: adiabaticUnitary
    summary: |-
      An oracle representing the adiabatic evolution algorithm to be used
      to implement the sweeps to the final state of the algorithm.
    isOperation: true
    input:
      types:
      - isArray: true
        isPrimitive: true
        uid: Qubit
    output:
      types:
      - isPrimitive: true
        uid: Unit
  - name: qpeUnitary
    summary: |-
      An oracle representing a unitary operator $U$ representing evolution
      for time $\delta t$ under a dynamical generator with ground state
      $\ket{\phi}$ and ground state energy $E = \phi\\,\delta t$.
    isOperation: true
    input:
      types:
      - isArray: true
        isPrimitive: true
        uid: Qubit
    output:
      types:
      - isPrimitive: true
        uid: Unit
    functors:
    - Adjoint
    - Controlled
  - name: phaseEstAlgorithm
    summary: |-
      An operation that performs phase estimation on a given unitary operation.
      See [iterative phase estimation](/quantum/libraries/characterization#iterative-phase-estimation)
      for more details.
    isOperation: true
    input:
      types:
      - uid: microsoft.quantum.canon.discreteoracle
      - isArray: true
        isPrimitive: true
        uid: Qubit
    output:
      types:
      - isPrimitive: true
        uid: Double
  - name: qubits
    summary: A register of qubits to be used to perform the simulation.
    isArray: true
    isPrimitive: true
    uid: Qubit
output:
  content: Double
  types:
  - summary: |-
      An estimate $\hat{\phi}$ of the ground state energy $\phi$
      of the generator represented by $U$.
    isPrimitive: true
    uid: Double
...
";

            var qubitArrayType = ResolvedType.New(QsType.NewArrayType(ResolvedType.New(QsType.Qubit)));
            var unitType       = ResolvedType.New(QsType.UnitType);
            var doubleType     = ResolvedType.New(QsType.Double);
            var oracleType     = ResolvedType.New(QsType.NewUserDefinedType(new UserDefinedType(CanonName,
                                                                                                NonNullable <string> .New("DiscreteOracle"),
                                                                                                QsNullable <Tuple <QsPositionInfo, QsPositionInfo> > .Null)));
            var noInfo = CallableInformation.NoInformation;
            var acFunctors = ResolvedCharacteristics.FromProperties(new[] { OpProperty.Adjointable, OpProperty.Controllable });
            var acInfo = new CallableInformation(acFunctors, InferredCallableInformation.NoInformation);
            var qubitToUnitOp = ResolvedType.New(QsType.NewOperation(new SigTypeTuple(qubitArrayType, unitType), noInfo));
            var qubitToUnitOpAC = ResolvedType.New(QsType.NewOperation(new SigTypeTuple(qubitArrayType, unitType), acInfo));
            var phaseEstArgs = new ResolvedType[] { oracleType, qubitArrayType }.ToImmutableArray();
            var phaseEstArgTuple = ResolvedType.New(QsType.NewTupleType(phaseEstArgs));
            var phaseEstOp       = ResolvedType.New(QsType.NewOperation(new SigTypeTuple(phaseEstArgTuple, doubleType), noInfo));

            var typeParams = new QsLocalSymbol[] { }.ToImmutableArray();
            var argTypes = new ResolvedType[] { qubitToUnitOp, qubitToUnitOp, qubitToUnitOpAC, phaseEstOp, qubitArrayType }.ToImmutableArray();
            var argTupleType = ResolvedType.New(QsType.NewTupleType(argTypes));
            var signature    = new ResolvedSignature(typeParams, argTupleType, doubleType, noInfo);

            var args = new List <ArgDeclType> {
                BuildArgument("statePrepUnitary", qubitToUnitOp),
                BuildArgument("adiabaticUnitary", qubitToUnitOp),
                BuildArgument("qpeUnitary", qubitToUnitOpAC),
                BuildArgument("phaseEstAlgorithm", phaseEstOp),
                BuildArgument("qubits", qubitArrayType)
            }
            .ConvertAll(arg => QsTuple <ArgDeclType> .NewQsTupleItem(arg))
            .ToImmutableArray();
            var argTuple = QsTuple <ArgDeclType> .NewQsTuple(args);

            var specs = new QsSpecialization[] { }.ToImmutableArray();

            var qsCallable = new QsCallable(QsCallableKind.Operation,
                                            MakeFullName("AdiabaticStateEnergyUnitary"),
                                            ImmutableArray <QsDeclarationAttribute> .Empty,
                                            NonNullable <string> .New("Techniques.qs"),
                                            ZeroLocation,
                                            signature,
                                            argTuple,
                                            specs,
                                            comments.ToImmutableArray(),
                                            QsComments.Empty);
            var callable = new DocCallable("Microsoft.Quantum.Canon", qsCallable);

            var stream = new StringWriter();

            callable.WriteToFile(stream);
            var s = stream.ToString();

            Assert.Equal(expected, s);
        }
Esempio n. 6
0
 /// <summary>
 /// Creates a callable value that stores the given LLVM value representing a Q# callable.
 /// </summary>
 /// <param name="value">The LLVM value to store</param>
 /// <param name="type">The Q# of the value</param>
 internal CallableValue FromCallable(Value value, ResolvedType type) =>
 new CallableValue(value, type, this.sharedState);
Esempio n. 7
0
 /// <summary>
 /// Creates a simple value that stores the given LLVM value as well as its Q# type.
 /// </summary>
 /// <param name="value">The LLVM value to store</param>
 /// <param name="type">The Q# of the value</param>
 internal SimpleValue FromSimpleValue(Value value, ResolvedType type) =>
 new SimpleValue(value, type);
Esempio n. 8
0
 internal QirValues(GenerationContext context, Constants constants)
 {
     this.sharedState = context;
     this.Unit        = new SimpleValue(constants.UnitValue, ResolvedType.New(ResolvedTypeKind.UnitType));
 }
Esempio n. 9
0
        public ResolvedType GetEnumerableItemTypeGuess(ParserContext context)
        {
            ResolvedType rootType = this.RootValue.ResolvedType;

            return(rootType.GetEnumerableItemType());
        }
Esempio n. 10
0
        private void ResolveFrameworkMethodReference(ResolvedType[] argTypes)
        {
            ResolvedType resolvedType = this.RootValue.ResolvedType;

            if (resolvedType.IsEnum)
            {
                if (resolvedType.FrameworkClass != null)
                {
                    if (!resolvedType.HasEnumField(this.Name.Value))
                    {
                        throw new ParserException(
                                  this.Name,
                                  resolvedType.ToString() + " doesn't have a field called " + this.Name.Value);
                    }
                    this.ResolvedType = ResolvedType.CreateEnumField(resolvedType);
                }
                else
                {
                    throw new NotImplementedException();
                }
                return;
            }
            string className  = resolvedType.FrameworkClass;
            string methodName = this.Name.Value;

            this.Type = MethodRefType.FRAMEWORK_METHOD;
            switch (className + ":" + methodName)
            {
            case "System.Collections.Generic.HashSet:Contains":
            case "System.Collections.Generic.ISet:Contains":
                ResolvedType itemType = resolvedType.Generics[0];
                this.ResolvedType = ResolvedType.CreateFunction(ResolvedType.Bool(), new ResolvedType[] { itemType });
                return;

            case "System.Collections.Generic.Dictionary:Keys":
            case "System.Collections.Generic.IDictionary:Keys":
                ResolvedType keyType = resolvedType.Generics[0];
                this.ResolvedType = ResolvedType.CreateEnumerableType(keyType);
                return;

            case "System.Collections.Generic.Dictionary:Values":
            case "System.Collections.Generic.IDictionary:Values":
                ResolvedType valueType = resolvedType.Generics[1];
                this.ResolvedType = ResolvedType.CreateEnumerableType(valueType);
                return;

            case "CommonUtil.Collections.Pair:First":
                this.ResolvedType = resolvedType.Generics[0];
                break;

            case "CommonUtil.Collections.Pair:Second":
                this.ResolvedType = resolvedType.Generics[1];
                break;

            case "CommonUtil.DateTime.Time:UnixTimeNow":
            case "System.Collections.Generic.HashSet:Count":
            case "System.Collections.Generic.Dictionary:Count":
            case "System.Collections.Generic.IDictionary:Count":
                this.ResolvedType = ResolvedType.Int();
                return;

            default:
                throw new ParserException(this.FirstToken, "Not implemented --> " + className + ":" + methodName);
            }
        }
 public EnumDefinitionReference(Token firstToken, TopLevelEntity parent, ResolvedType enumAsType)
     : base(firstToken, parent)
 {
     this.ResolvedType = enumAsType;
 }
Esempio n. 12
0
        internal override Expression ResolveTypes(ParserContext parser, TypeResolver typeResolver)
        {
            this.Root = this.Root.ResolveTypes(parser, typeResolver);

            for (int i = 0; i < this.Args.Length; ++i)
            {
                this.Args[i] = this.Args[i].ResolveTypes(parser, typeResolver);
            }

            ResolvedType rootType = this.Root.ResolvedType;

            if (rootType == ResolvedType.ANY)
            {
                this.ResolvedType = ResolvedType.ANY;
                return(this);
            }

            if (rootType.Category == ResolvedTypeCategory.FUNCTION_POINTER)
            {
                int maxArgCount = rootType.FunctionArgs.Length;
                int minArgCount = maxArgCount - rootType.FunctionOptionalArgCount;
                if (this.Args.Length < minArgCount || this.Args.Length > maxArgCount)
                {
                    throw new ParserException(this.ParenToken, "This function has the incorrect number of arguments.");
                }

                for (int i = 0; i < this.Args.Length; ++i)
                {
                    if (!this.Args[i].ResolvedType.CanAssignToA(rootType.FunctionArgs[i]))
                    {
                        throw new ParserException(this.Args[i], "Incorrect argument type.");
                    }
                }
                this.ResolvedType = rootType.FunctionReturnType;

                if (!this.CompilationScope.IsStaticallyTyped && this.Root is FunctionReference)
                {
                    FunctionDefinition fn = ((FunctionReference)this.Root).FunctionDefinition;
                    if (fn.CompilationScope.IsStaticallyTyped)
                    {
                        for (int i = 0; i < this.Args.Length; ++i)
                        {
                            ResolvedType actualType   = this.Args[i].ResolvedType;
                            ResolvedType expectedType = fn.ResolvedArgTypes[i];
                            if (expectedType != ResolvedType.OBJECT && actualType == ResolvedType.ANY)
                            {
                                this.Args[i] = new Cast(this.Args[i].FirstToken, expectedType, this.Args[i], this.Owner, false);
                            }
                        }
                    }
                }

                // TODO: this is temporary until the Math library is converted to Acrylic
                if (this.ResolvedType == ResolvedType.ANY &&
                    this.Root is FunctionReference &&
                    ((FunctionReference)this.Root).FunctionDefinition.CompilationScope.Metadata.ID == "Math")
                {
                    FunctionReference func = (FunctionReference)this.Root;
                    switch (func.FunctionDefinition.NameToken.Value)
                    {
                    case "abs":
                    case "min":
                    case "max":
                    case "ensureRange":
                        if (this.Args.Count(ex => ex.ResolvedType == ResolvedType.FLOAT) > 0)
                        {
                            this.ResolvedType = ResolvedType.FLOAT;
                        }
                        else
                        {
                            this.ResolvedType = ResolvedType.INTEGER;
                        }
                        break;

                    case "floor":
                    case "sign":
                        this.ResolvedType = ResolvedType.INTEGER;
                        break;

                    default:
                        this.ResolvedType = ResolvedType.FLOAT;
                        break;
                    }
                }

                if (this.ResolvedType == ResolvedType.ANY &&
                    this.CompilationScope.IsStaticallyTyped)
                {
                    // ANY types are not allowed in statically typed compilation scopes.
                    // Convert this into an object and require the user to perform any specific casts.
                    this.ResolvedType = ResolvedType.OBJECT;
                }

                return(this);
            }

            throw new System.NotImplementedException();
        }
Esempio n. 13
0
 public override QsResolvedTypeKind OnFunction(ResolvedType it, ResolvedType ot)
 {
     this.SharedState.BuiltType = this.SharedState.Types.Callable;
     return(QsResolvedTypeKind.InvalidType);
 }
Esempio n. 14
0
        // public overrides

        public override QsResolvedTypeKind OnArrayType(ResolvedType b)
        {
            this.SharedState.BuiltType = this.SharedState.Types.Array;
            return(QsResolvedTypeKind.InvalidType);
        }
Esempio n. 15
0
 public override Expression ResolveTypes(ParserContext context, VariableScope varScope)
 {
     this.ResolvedType = ResolvedType.CreatePrimitive("string", this.FirstToken);
     return(this);
 }
Esempio n. 16
0
 /// <summary>
 /// Creates a new array value of the given length. Expects a value of type i64 for the length of the array.
 /// Registers the value with the scope manager, unless registerWithScopeManager is set to false.
 /// </summary>
 /// <param name="length">Value of type i64 indicating the number of elements in the array</param>
 /// <param name="elementType">Q# type of the array elements</param>
 internal ArrayValue CreateArray(Value length, ResolvedType elementType, bool registerWithScopeManager = true) =>
 new ArrayValue(length, elementType, this.sharedState, registerWithScopeManager);
Esempio n. 17
0
        public void TryResolveFieldReference(ParserContext context, ResolvedType[] argTypes, VariableScope varScope)
        {
            if (this.StaticMethodSource != null)
            {
                if (this.StaticMethodSource.CustomType != null)
                {
                    this.ResolveClassStaticMethodReference(argTypes);
                }
                else if (this.StaticMethodSource.FrameworkClass != null)
                {
                    this.ResolveFrameworkStaticMethodReference(argTypes);
                }
                else if (this.StaticMethodSource.PrimitiveType != null)
                {
                    this.ResolvePrimitiveStaticMethodReference(argTypes);
                }
                else
                {
                    throw new ParserException(this.FirstToken, "Not implemented");
                }
            }
            else
            {
                if (this.RootValue.ResolvedType == null && this.RootValue is VerifiedFieldReference)
                {
                    this.RootValue.ResolveTypes(context, varScope);
                }
                ResolvedType rootType = this.RootValue.ResolvedType;
                if (this.FileContext.HasLinq && rootType.IsEnumerable(context))
                {
                    this.Type = MethodRefType.LINQ;
                    switch (this.Name.Value)
                    {
                    case "OrderBy":
                    {
                        ResolvedType itemType           = rootType.GetEnumerableItemType();
                        ResolvedType functionReturnType = ResolvedType.GetPrimitiveType("object");         // int or string or float or something, but whatever.
                        ResolvedType function           = ResolvedType.CreateFunction(functionReturnType, new ResolvedType[] { itemType });
                        this.ResolvedType = ResolvedType.CreateFunction(
                            ResolvedType.CreateEnumerableType(itemType),
                            new ResolvedType[] { function });
                    }
                    break;

                    case "ToArray":
                    {
                        ResolvedType itemType = rootType.GetEnumerableItemType();
                        this.ResolvedType = ResolvedType.CreateFunction(
                            ResolvedType.CreateArray(itemType),
                            new ResolvedType[0]);
                    }
                    break;

                    case "Select": throw new System.NotImplementedException();

                    case "Where": throw new System.NotImplementedException();

                    default:
                        this.Type = MethodRefType.UNKNOWN;
                        break;
                    }
                    if (this.Type == MethodRefType.LINQ)
                    {
                        return;
                    }
                }

                if (rootType.CustomType != null)
                {
                    if (argTypes == null)
                    {
                        this.ResolveCustomFieldReference();
                    }
                    else
                    {
                        this.ResolveCustomMethodReference(argTypes);
                    }
                }
                else if (rootType.FrameworkClass != null)
                {
                    this.ResolveFrameworkMethodReference(argTypes);
                }
                else if (rootType.PrimitiveType != null)
                {
                    this.Type            = MethodRefType.PRIMITIVE_METHOD;
                    this.PrimitiveMethod = rootType.PrimitiveType + "." + this.Name.Value;

                    switch (this.PrimitiveMethod)
                    {
                    case "string.ToLowerInvariant":
                        this.ResolvedType = ResolvedType.CreateFunction(ResolvedType.String(), new ResolvedType[0]);
                        break;

                    default:
                        throw new ParserException(this.Name, "string does not have a method called '" + this.Name.Value + "'");
                    }
                }
                else if (rootType.IsArray)
                {
                    switch (this.Name.Value)
                    {
                    case "Length":
                        this.ResolvedType = ResolvedType.Int();
                        break;

                    default:
                        throw new ParserException(this.FirstToken, "not implemented");
                    }
                }
                else
                {
                    throw new ParserException(this.FirstToken, "Not implemented");
                }
            }
        }
Esempio n. 18
0
 /// <summary>
 /// Builds an array that containsthe given array elements.
 /// Registers the value with the scope manager.
 /// Increases the reference count for the array elements.
 /// </summary>
 /// <param name="arrayElements">The elements in the array</param>
 internal ArrayValue CreateArray(ResolvedType elementType, params IValue[] arrayElements) =>
 this.CreateArray(elementType, true, arrayElements);
Esempio n. 19
0
        internal override Expression ResolveTypes(ParserContext parser, TypeResolver typeResolver)
        {
            this.Root.ResolveTypes(parser, typeResolver);

            string field = this.FieldToken.Value;

            if (this.Root is EnumReference)
            {
                throw new System.NotImplementedException();
            }

            ResolvedType rootType = this.Root.ResolvedType;
            TypeContext  tc       = parser.TypeContext;

            // TODO: all of this needs to be localized.
            switch (rootType.Category)
            {
            case ResolvedTypeCategory.NULL:
                throw new ParserException(this.DotToken, "Cannot dereference a field from null.");

            case ResolvedTypeCategory.ANY:
                // ¯\_(ツ)_/¯
                this.ResolvedType = parser.TypeContext.ANY;
                return(this);

            case ResolvedTypeCategory.INTEGER:
                throw new ParserException(this.DotToken, "Integers do not have any fields.");

            case ResolvedTypeCategory.FLOAT:
                throw new ParserException(this.DotToken, "Floating point decimals do not have any fields.");

            case ResolvedTypeCategory.BOOLEAN:
                throw new ParserException(this.DotToken, "Booleans do not have any fields.");

            case ResolvedTypeCategory.STRING:
                switch (field)
                {
                case "length":
                    this.ResolvedType = tc.INTEGER;
                    if (this.Root is StringConstant)
                    {
                        return(new IntegerConstant(this.FirstToken, ((StringConstant)this.Root).Value.Length, this.Owner));
                    }
                    return(this);

                case "contains": return(BuildPrimitiveMethod(tc.BOOLEAN, tc.STRING));

                case "endsWith": return(BuildPrimitiveMethod(tc.BOOLEAN, tc.STRING));

                case "indexOf": return(BuildPrimitiveMethod(tc.INTEGER, tc.STRING));

                case "lower": return(BuildPrimitiveMethod(tc.STRING));

                case "ltrim": return(BuildPrimitiveMethod(tc.STRING));

                case "replace": return(BuildPrimitiveMethod(tc.STRING, tc.STRING, tc.STRING));

                case "reverse": return(BuildPrimitiveMethod(tc.STRING));

                case "rtrim": return(BuildPrimitiveMethod(tc.STRING));

                case "split": return(BuildPrimitiveMethod(ResolvedType.ListOrArrayOf(tc.STRING), tc.STRING));

                case "startsWith": return(BuildPrimitiveMethod(tc.BOOLEAN, tc.STRING));

                case "trim": return(BuildPrimitiveMethod(tc.STRING));

                case "upper": return(BuildPrimitiveMethod(tc.STRING));

                // common mistakes
                case "join":
                    throw new ParserException(this.DotToken, "Strings do not have a .join(list) method. Did you mean to do list.join(string)?");

                case "size":
                    throw new ParserException(this.DotToken, "Strings do not have a .size() method. Did you mean to use .length?");

                default:
                    throw new ParserException(this.DotToken, "Strings do not have that method.");
                }

            case ResolvedTypeCategory.LIST:
                ResolvedType itemType = rootType.ListItemType;
                switch (field)
                {
                case "length":
                    this.ResolvedType = tc.INTEGER;
                    return(this);

                case "filter":
                case "map":
                    if (this.CompilationScope.IsStaticallyTyped)
                    {
                        // TODO: for Acrylic, this needs to have a way to indicate that resolution should be attempted
                        // again once the function return type is known.
                        throw new System.NotImplementedException();
                    }
                    this.ResolvedType = tc.ANY;
                    return(this);

                case "add": return(BuildPrimitiveMethod(tc.VOID, itemType));

                case "choice": return(BuildPrimitiveMethod(tc.VOID));

                case "clear": return(BuildPrimitiveMethod(tc.VOID));

                case "clone": return(BuildPrimitiveMethod(rootType));

                case "concat": return(BuildPrimitiveMethod(rootType, rootType));

                case "contains": return(BuildPrimitiveMethod(tc.BOOLEAN, itemType));

                case "insert": return(BuildPrimitiveMethod(tc.VOID, tc.INTEGER, itemType));

                case "join": return(BuildPrimitiveMethodWithOptionalArgs(tc.STRING, 1, tc.STRING));

                case "pop": return(BuildPrimitiveMethod(itemType));

                case "remove": return(BuildPrimitiveMethod(tc.VOID, tc.INTEGER));

                case "reverse": return(BuildPrimitiveMethod(tc.VOID));

                case "shuffle": return(BuildPrimitiveMethod(tc.VOID));

                case "sort": return(BuildPrimitiveMethod(tc.VOID));

                // common mistakes
                case "count":
                case "size":
                    throw new ParserException(this.DotToken, "Lists do not have a ." + this.FieldToken.Value + "() method. Did you mean to use .length?");

                default:
                    throw new ParserException(this.DotToken, "Lists do not have that method.");
                }

            case ResolvedTypeCategory.DICTIONARY:
                ResolvedType keyType   = rootType.DictionaryKeyType;
                ResolvedType valueType = rootType.DictionaryValueType;
                switch (field)
                {
                case "length":
                    this.ResolvedType = tc.INTEGER;
                    return(this);

                case "clear": return(BuildPrimitiveMethod(tc.VOID));

                case "clone": return(BuildPrimitiveMethod(rootType));

                case "contains": return(BuildPrimitiveMethod(tc.BOOLEAN, keyType));

                case "get": return(BuildPrimitiveMethodWithOptionalArgs(valueType, 1, keyType, valueType));

                case "keys": return(BuildPrimitiveMethod(ResolvedType.ListOrArrayOf(keyType)));

                case "merge": return(BuildPrimitiveMethod(tc.VOID, rootType));

                case "remove": return(BuildPrimitiveMethod(tc.VOID, keyType));

                case "values": return(BuildPrimitiveMethod(ResolvedType.ListOrArrayOf(valueType)));

                default:
                    throw new ParserException(this.DotToken, "Dictionaries do not have that field.");
                }

            case ResolvedTypeCategory.CLASS_DEFINITION:
                throw new ParserException(this.DotToken, "Class definitions do not have that field.");

            case ResolvedTypeCategory.FUNCTION_POINTER:
                switch (field)
                {
                case "invoke":
                    return(BuildPrimitiveMethod(tc.ANY, ResolvedType.ListOrArrayOf(tc.ANY)));

                default:
                    throw new ParserException(this.DotToken, "Fucntions do not have that field.");
                }

            case ResolvedTypeCategory.INSTANCE:
                FieldDefinition fieldDef = rootType.ClassTypeOrReference.GetField(field, true);
                if (fieldDef != null)
                {
                    if (!Node.IsAccessAllowed(this, fieldDef))
                    {
                        ClassDefinition cd = fieldDef.ClassOwner;
                        throw new ParserException(FieldToken, "The field '" + cd.NameToken.Value + "." + this.FieldToken.Value + "' is not accessible from here due to its access scope.");
                    }

                    this.ResolvedType = fieldDef.ResolvedFieldType;
                    return(this);
                }
                FunctionDefinition funcDef = rootType.ClassTypeOrReference.GetMethod(field, true);
                if (funcDef != null)
                {
                    this.ResolvedType = ResolvedType.GetFunctionType(funcDef);
                    return(this);
                }
                throw new ParserException(this.DotToken, "The class '" + rootType.ClassTypeOrReference.NameToken.Value + "' does not have a field called '" + field + "'.");

            default:
                throw new ParserException(this.DotToken, "This field does not exist.");
            }
        }
Esempio n. 20
0
 /// <summary>
 /// Creates a new array value from the given opaque array of elements of the given type.
 /// </summary>
 /// <param name="elementType">Q# type of the array elements</param>
 internal ArrayValue FromArray(Value value, ResolvedType elementType) =>
 new ArrayValue(value, null, elementType, this.sharedState);
Esempio n. 21
0
 private Expression BuildPrimitiveMethod(ResolvedType returnType, params ResolvedType[] argTypes)
 {
     return(BuildPrimitiveMethodWithOptionalArgs(returnType, 0, argTypes));
 }
Esempio n. 22
0
 /// <summary>
 /// Creates a suitable class to pass around a built LLVM value that represents a Q# value of the given type.
 /// </summary>
 /// <param name="value">The LLVM value to store</param>
 /// <param name="type">The Q# of the value</param>
 internal IValue From(Value value, ResolvedType type) =>
 type.Resolution is ResolvedTypeKind.ArrayType it ? this.sharedState.Values.FromArray(value, it.Item) :
Esempio n. 23
0
 private Expression BuildPrimitiveMethodWithOptionalArgs(ResolvedType returnType, int optionalCount, params ResolvedType[] argTypes)
 {
     return(new PrimitiveMethodReference(this.Root, this.DotToken, this.FieldToken, ResolvedType.GetFunctionType(returnType, argTypes, optionalCount), this.Owner));
 }
Esempio n. 24
0
        public void ExcludeInaccessible()
        {
            var elements =
                new[] { AccessModifier.DefaultAccess, AccessModifier.Internal }
            .SelectMany(access =>
            {
                var source = "Tests.qs";
                var unit   = ResolvedType.New(QsType.UnitType);

                var signature = new ResolvedSignature(
                    Array.Empty <QsLocalSymbol>().ToImmutableArray(),
                    unit,
                    unit,
                    CallableInformation.NoInformation);
                var argumentTuple = QsTuple <ArgDeclType> .NewQsTuple(ImmutableArray.Create <QsTuple <ArgDeclType> >());
                var callable      = new QsCallable(
                    kind: QsCallableKind.Operation,
                    fullName: MakeFullName(access + "Operation"),
                    attributes: ImmutableArray <QsDeclarationAttribute> .Empty,
                    modifiers: new Modifiers(access),
                    sourceFile: source,
                    location: ZeroLocation,
                    signature: signature,
                    argumentTuple: argumentTuple,
                    specializations: ImmutableArray.Create <QsSpecialization>(),
                    documentation: ImmutableArray.Create <string>(),
                    comments: QsComments.Empty);

                var typeItems = QsTuple <QsTypeItem> .NewQsTuple(
                    ImmutableArray.Create(QsTuple <QsTypeItem> .NewQsTupleItem(QsTypeItem.NewAnonymous(unit))));
                var type = new QsCustomType(
                    fullName: MakeFullName(access + "Type"),
                    attributes: ImmutableArray <QsDeclarationAttribute> .Empty,
                    modifiers: new Modifiers(access),
                    sourceFile: source,
                    location: ZeroLocation,
                    type: unit,
                    typeItems: typeItems,
                    documentation: ImmutableArray.Create <string>(),
                    comments: QsComments.Empty);
                return(new[]
                {
                    QsNamespaceElement.NewQsCallable(callable),
                    QsNamespaceElement.NewQsCustomType(type)
                });
            });
            var emptyLookup = Array.Empty <ImmutableArray <string> >().ToLookup(x => "");
            var ns          = new QsNamespace(CanonName, elements.ToImmutableArray(), emptyLookup);
            var docNs       = new DocNamespace(ns);
            var stream      = new MemoryStream();

            docNs.WriteToStream(stream, null);

            var expected = @"### YamlMime:QSharpNamespace
# This file is automatically generated.
# Please do not modify this file manually, or your changes may be lost when
# documentation is rebuilt.

uid: microsoft.quantum.canon
name: Microsoft.Quantum.Canon
operations:
- uid: microsoft.quantum.canon.defaultaccessoperation
  summary: ''
newtypes:
- uid: microsoft.quantum.canon.defaultaccesstype
  summary: ''
...
";
            var actual   = Encoding.UTF8.GetString(stream.ToArray());

            Assert.Equal(expected, actual);
        }
Esempio n. 25
0
        private void EnsureModifiersAndTypeSignatureConsistencyForClassMethods(TypeContext tc)
        {
            ClassDefinition classDef     = (ClassDefinition)this.Owner;
            ClassDefinition baseClass    = classDef.BaseClass;
            bool            hasBaseClass = baseClass != null;

            if (hasBaseClass)
            {
                FieldDefinition hiddenField = baseClass.GetField(this.NameToken.Value, true);
                if (hiddenField != null)
                {
                    throw new ParserException(this, "This function definition hides a field from a parent class.");
                }
            }

            if (!hasBaseClass)
            {
                if (this.Modifiers.HasOverride)
                {
                    throw new ParserException(this, "Cannot mark a method as 'override' if it has no base class.");
                }
            }
            else
            {
                FunctionDefinition overriddenFunction = baseClass.GetMethod(this.NameToken.Value, true);
                if (overriddenFunction != null)
                {
                    if (!this.Modifiers.HasOverride)
                    {
                        if (this.CompilationScope.IsCrayon)
                        {
                            // TODO: just warn if not present
                        }
                        else
                        {
                            throw new ParserException(this, "This function hides another function from a parent class. If overriding is intentional, use the 'override' keyword.");
                        }
                    }

                    if (overriddenFunction.Modifiers.HasStatic)
                    {
                        throw new ParserException(this, "Cannot override a static method.");
                    }

                    if (overriddenFunction.Modifiers.AccessModifierType != this.Modifiers.AccessModifierType)
                    {
                        throw new ParserException(this, "This method defines a different access modifier than its overridden parent.");
                    }

                    if (overriddenFunction.Modifiers.AccessModifierType == AccessModifierType.PRIVATE)
                    {
                        throw new ParserException(this, "Cannot override a private method.");
                    }

                    if (overriddenFunction.Modifiers.HasInternal &&
                        overriddenFunction.CompilationScope != this.CompilationScope)
                    {
                        throw new ParserException(this, "Cannot override this method. It is marked as internal and is located in a different assembly.");
                    }

                    if (overriddenFunction.ResolvedReturnType != this.ResolvedReturnType)
                    {
                        if (overriddenFunction.ResolvedReturnType == tc.ANY &&
                            this.ResolvedReturnType == tc.OBJECT)
                        {
                            // This is fine.
                        }
                        else
                        {
                            throw new ParserException(this, "This function returns a different type than its overridden parent.");
                        }
                    }

                    if (overriddenFunction.ArgTypes.Length != this.ArgTypes.Length)
                    {
                        throw new ParserException(this, "This function has a different number of arguments than its overridden parent.");
                    }

                    if (overriddenFunction.MinArgCount != this.MinArgCount)
                    {
                        throw new ParserException(this, "This function has a different number of optional arguments than its overridden parent.");
                    }

                    // TODO: if you are overridding a function between a statically and dynamically typed languagte,
                    // the dynamic language should pick up the types from the statically typed language or the
                    // statically typed language should require "object" types in its signature for the other direction.
                    for (int i = 0; i < this.ArgTypes.Length; ++i)
                    {
                        ResolvedType expected = overriddenFunction.ResolvedArgTypes[i];
                        ResolvedType actual   = this.ResolvedArgTypes[i];
                        if (actual != expected &&
                            !(actual == tc.OBJECT && expected == tc.ANY))
                        {
                            throw new ParserException(this, "This function has arguments that are different types than its overridden parent.");
                        }
                    }
                }
                else
                {
                    if (this.Modifiers.HasOverride)
                    {
                        throw new ParserException(this, "This function is marked as 'override', but there is no method in a parent class with the same name.");
                    }
                }
            }
        }
Esempio n. 26
0
        public void ParseUdt()
        {
            string[] comments =
            {
                "# Summary",
                "Represents a single primitive term in the set of all dynamical generators, e.g.",
                "Hermitian operators, for which there exists a map from that generator",
                "to time-evolution by that that generator, through \"EvolutionSet\".",
                "",
                "# Description",
                "The first element",
                "(Int[], Double[]) is indexes that single term -- For instance, the Pauli string",
                "XXY with coefficient 0.5 would be indexed by ([1,1,2], [0.5]). Alternatively,",
                "Hamiltonians parameterized by a continuous variable, such as X cos φ + Y sin φ,",
                "might for instance be represented by ([], [φ]). The second",
                "element indexes the subsystem on which the generator acts on.",
                "",
                "# Remarks",
                "> [!WARNING]",
                "> The interpretation of an `GeneratorIndex` is not defined except",
                "> with reference to a particular set of generators.",
                "",
                "# Example",
                "Using  <xref:microsoft.quantum.canon.paulievolutionset>, the operator",
                "$\\pi X_2 X_5 Y_9$ is represented as:",
                "```qsharp",
                "let index = GeneratorIndex(([1; 1; 2], [PI()]), [2; 5; 9]);",
                "```",
                "",
                "# See Also",
                "- @\"microsoft.quantum.canon.paulievolutionset\"",
                "- @\"microsoft.quantum.canon.evolutionset\""
            };
            string expected = @"### YamlMime:QSharpType
# This file is automatically generated.
# Please do not modify this file manually, or your changes may be lost when
# documentation is rebuilt.

uid: microsoft.quantum.canon.generatorindex
name: GeneratorIndex
type: newtype
namespace: Microsoft.Quantum.Canon
summary: |-
  Represents a single primitive term in the set of all dynamical generators, e.g.
  Hermitian operators, for which there exists a map from that generator
  to time-evolution by that that generator, through ""EvolutionSet"".

  The first element
  (Int[], Double[]) is indexes that single term -- For instance, the Pauli string
  XXY with coefficient 0.5 would be indexed by ([1,1,2], [0.5]). Alternatively,
  Hamiltonians parameterized by a continuous variable, such as X cos φ + Y sin φ,
  might for instance be represented by ([], [φ]). The second
  element indexes the subsystem on which the generator acts on.
remarks: |-
  > [!WARNING]
  > The interpretation of an `GeneratorIndex` is not defined except
  > with reference to a particular set of generators.

  ### Examples
  Using  <xref:microsoft.quantum.canon.paulievolutionset>, the operator
  $\pi X_2 X_5 Y_9$ is represented as:

  ```qsharp
  let index = GeneratorIndex(([1; 1; 2], [PI()]), [2; 5; 9]);
  ```
syntax: newtype GeneratorIndex = ((Int[], Double[]), Int[]);
seeAlso:
- microsoft.quantum.canon.paulievolutionset
- microsoft.quantum.canon.evolutionset
...
";
            var    intArrayType = ResolvedType.New(QsType.NewArrayType(ResolvedType.New(QsType.Int)));
            var    doubleArrayType = ResolvedType.New(QsType.NewArrayType(ResolvedType.New(QsType.Double)));
            var    innerTuple = new ResolvedType[] { intArrayType, doubleArrayType }.ToImmutableArray();
            var    innerTupleType = ResolvedType.New(QsType.NewTupleType(innerTuple));
            var    baseTuple = new ResolvedType[] { innerTupleType, intArrayType }.ToImmutableArray();
            var    baseType      = ResolvedType.New(QsType.NewTupleType(baseTuple));
            var    anonymousItem = QsTuple <QsTypeItem> .NewQsTupleItem(QsTypeItem.NewAnonymous(baseType));

            var typeItems = QsTuple <QsTypeItem> .NewQsTuple(ImmutableArray.Create(anonymousItem));

            var generatorIndexType = new QsCustomType(
                MakeFullName("GeneratorIndex"),
                ImmutableArray <QsDeclarationAttribute> .Empty,
                new Modifiers(AccessModifier.DefaultAccess),
                NonNullable <string> .New("GeneratorRepresentation.qs"),
                ZeroLocation,
                baseType,
                typeItems,
                comments.ToImmutableArray(),
                QsComments.Empty);
            var udt = new DocUdt("Microsoft.Quantum.Canon", generatorIndexType);

            var stream = new StringWriter();

            udt.WriteToFile(stream);
            var s = stream.ToString();

            Assert.Equal(expected, s);
        }
Esempio n. 27
0
 internal override Expression ResolveTypes(ParserContext parser, TypeResolver typeResolver)
 {
     this.ResolvedType = ResolvedType.ListOrArrayOf(parser.TypeContext.ANY);
     return(this);
 }
Esempio n. 28
0
 internal override Expression ResolveTypes(ParserContext parser, TypeResolver typeResolver)
 {
     this.ResolvedType = ResolvedType.GetClassRefType(this.ClassDefinition);
     return(this);
 }
Esempio n. 29
0
        public StaticFrameworkClassReference(Token firstToken, TopLevelEntity parent, ResolvedType frameworkType)
            : base(firstToken, parent)
        {
            if (frameworkType.FrameworkClass == null)
            {
                throw new System.InvalidOperationException();
            }

            this.ResolvedType = frameworkType;
        }
Esempio n. 30
0
 public override Expression ResolveTypes(ParserContext context, VariableScope varScope)
 {
     this.ResolvedType = ResolvedType.CreateNull();
     return(this);
 }
Esempio n. 31
0
        /// <summary>
        /// Populates a YAML mapping node with information describing a Q# resolved type.
        /// </summary>
        /// <param name="t">The resolved type to describe</param>
        /// <param name="map">The YAML node to populate</param>
        internal static void ResolvedTypeToYaml(ResolvedType t, YamlMappingNode map)
        {
            IEnumerable <ResolvedType> FlattenType(ResolvedType ty)
            {
                var resol = ty.Resolution;

                if (resol.IsTupleType)
                {
                    var elements = ((QsTypeKind.TupleType)resol).Item;
                    foreach (var element in elements)
                    {
                        foreach (var subelement in FlattenType(element))
                        {
                            yield return(subelement);
                        }
                    }
                }
                else
                {
                    yield return(ty);
                }
            }

            void CallableCore(ResolvedType inputType, ResolvedType outputType, IEnumerable <QsFunctor> functors)
            {
                var types = new YamlSequenceNode();
                var input = new YamlMappingNode();

                input.Add("types", types);
                foreach (var argType in FlattenType(inputType))
                {
                    var argNode = new YamlMappingNode();
                    ResolvedTypeToYaml(argType, argNode);
                    types.Add(argNode);
                }
                map.Add("input", input);
                var otypes = new YamlSequenceNode();
                var output = new YamlMappingNode();

                output.Add("types", otypes);
                var otype = new YamlMappingNode();

                ResolvedTypeToYaml(outputType, otype);
                otypes.Add(otype);
                map.Add("output", output);
            }

            var resolution = t.Resolution;

            if (resolution.IsUnitType)
            {
                map.AddStringMapping("isPrimitive", "true");
                map.AddStringMapping("uid", "Unit");
            }
            else if (resolution.IsInt || resolution.IsBigInt || resolution.IsDouble || resolution.IsBool || resolution.IsString ||
                     resolution.IsQubit || resolution.IsResult || resolution.IsPauli || resolution.IsRange)
            {
                map.AddStringMapping("isPrimitive", "true");
                map.AddStringMapping("uid", ResolvedTypeToString(t));
            }
            else if (resolution.IsArrayType)
            {
                map.AddStringMapping("isArray", "true");
                var elementType = ((QsTypeKind.ArrayType)resolution).Item;
                if (elementType.Resolution.IsArrayType)
                {
                    var seq  = new YamlSequenceNode();
                    var node = new YamlMappingNode();
                    ResolvedTypeToYaml(elementType, node);
                    seq.Add(node);
                    map.Add(BuildStringNode("types"), seq);
                }
                else
                {
                    ResolvedTypeToYaml(elementType, map);
                }
            }
            else if (resolution.IsTupleType)
            {
                var elements = ((QsTypeKind.TupleType)resolution).Item;
                var seq      = new YamlSequenceNode();
                foreach (var element in elements)
                {
                    var node = new YamlMappingNode();
                    ResolvedTypeToYaml(element, node);
                    seq.Add(node);
                }
                map.Add(BuildStringNode("types"), seq);
            }
            else if (resolution.IsUserDefinedType)
            {
                var udtName = ((QsTypeKind.UserDefinedType)resolution).Item;
                map.AddStringMapping("uid", (udtName.Namespace + "." + udtName.Name).ToLowerInvariant());
            }
            else if (resolution.IsTypeParameter)
            {
                var typeParam = ((QsTypeKind.TypeParameter)resolution).Item;
                map.AddStringMapping("uid", "'" + typeParam.TypeName);
                map.AddStringMapping("isLocal", "true");
            }
            else if (resolution.IsOperation)
            {
                var op         = (QsTypeKind.Operation)resolution;
                var inputType  = op.Item1.Item1;
                var outputType = op.Item1.Item2;
                var functors   = op.Item2.Characteristics.SupportedFunctors.ValueOr(ImmutableHashSet <QsFunctor> .Empty);

                map.AddStringMapping("isOperation", "true");
                CallableCore(inputType, outputType, functors);
                if (!functors.IsEmpty)
                {
                    var seq = new YamlSequenceNode();
                    map.Add("functors", seq);
                    foreach (var f in functors)
                    {
                        if (f.IsAdjoint)
                        {
                            seq.AddString("Adjoint");
                        }
                        else if (f.IsControlled)
                        {
                            seq.AddString("Controlled");
                        }
                    }
                }
            }
            else if (resolution.IsFunction)
            {
                var fct        = (QsTypeKind.Function)resolution;
                var inputType  = fct.Item1;
                var outputType = fct.Item2;

                map.AddStringMapping("isFunction", "true");
                CallableCore(inputType, outputType, Enumerable.Empty <QsFunctor>());
            }
        }