コード例 #1
0
                private void AddEdge(QsQualifiedName identifier, QsSpecializationKind kind, TypeParameterResolutions typeRes, Range referenceRange)
                {
                    if (this.CurrentNode is null)
                    {
                        throw new ArgumentException("AddEdge requires CurrentNode to be non-null.");
                    }

                    // Add an edge to the specific specialization kind referenced
                    var called = new ConcreteCallGraphNode(identifier, kind, typeRes);
                    var edge   = new ConcreteCallGraphEdge(referenceRange);

                    this.Graph.AddDependency(this.CurrentNode, called, edge);

                    // Add all the specializations of the referenced callable to the graph
                    var newNodes = this.GetSpecializationKinds(identifier)
                                   .Select(specKind => new ConcreteCallGraphNode(identifier, specKind, typeRes));

                    foreach (var node in newNodes)
                    {
                        if (!this.RequestStack.Contains(node) && !this.ResolvedNodeSet.Contains(node))
                        {
                            this.Graph.AddNode(node);
                            this.RequestStack.Push(node);
                        }
                    }
                }
コード例 #2
0
                internal override void AddDependency(QsQualifiedName identifier)
                {
                    if (this.CurrentNode is null)
                    {
                        throw new ArgumentException("AddDependency requires CurrentNode to be non-null.");
                    }

                    var combination = new TypeResolutionCombination(this.ExprTypeParamResolutions);
                    var typeRes     = combination.CombinedResolutionDictionary.FilterByOrigin(identifier);

                    this.ExprTypeParamResolutions.Clear();

                    var referenceRange = Range.Zero;

                    if (this.CurrentStatementOffset.IsValue &&
                        this.CurrentExpressionRange.IsValue)
                    {
                        referenceRange = this.CurrentStatementOffset.Item + this.CurrentExpressionRange.Item;
                    }

                    var called = new CallGraphNode(identifier);
                    var edge   = new CallGraphEdge(typeRes, referenceRange);

                    this.Graph.AddDependency(this.CurrentNode, called, edge);
                    // If we are not processing all elements, then we need to keep track of what elements
                    // have been processed, and which elements still need to be processed.
                    if (this.WithTrimming &&
                        !this.RequestStack.Contains(called) &&
                        !this.ResolvedNodeSet.Contains(called))
                    {
                        this.RequestStack.Push(called);
                    }
                }
コード例 #3
0
 private static TypedExpression IdentifierForCallable(QsQualifiedName cName, TypeKind cType) =>
 SyntaxGenerator.AutoGeneratedExpression(
     ExpressionKind.NewIdentifier(
         Identifier.NewGlobalCallable(cName),
         QsNullable <ImmutableArray <ResolvedType> > .Null),
     cType,
     false);
コード例 #4
0
        /// <summary>
        /// Constructor for ConcreteCallGraphNode objects.
        /// Strips position info from the given type parameter resolutions.
        /// </summary>
        public ConcreteCallGraphNode(QsQualifiedName callableName, QsSpecializationKind kind, TypeParameterResolutions paramResolutions) : base(callableName)
        {
            this.Kind = kind;

            // Remove position info from type parameter resolutions
            this.ParamResolutions = paramResolutions.ToImmutableDictionary(
                kvp => kvp.Key,
                kvp => StripPositionInfo.Apply(kvp.Value));
        }
コード例 #5
0
        // static methods for convenience

        public static IEnumerable <Location> Find(QsQualifiedName idName, QsNamespace ns, QsLocation defaultOffset,
                                                  out Tuple <NonNullable <string>, QsLocation> declarationLocation, IImmutableSet <NonNullable <string> > limitToSourceFiles = null)
        {
            var finder = new IdentifierReferences(idName, defaultOffset, limitToSourceFiles);

            finder.Transform(ns ?? throw new ArgumentNullException(nameof(ns)));
            declarationLocation = finder.DeclarationLocation;
            return(finder.Locations);
        }
コード例 #6
0
                internal override void AddDependency(QsQualifiedName identifier)
                {
                    if (this.CurrentNode is null)
                    {
                        throw new ArgumentException("AddDependency requires CurrentNode to be non-null.");
                    }

                    var combination = new TypeResolutionCombination(this.ExprTypeParamResolutions.Append(this.CurrentNode.ParamResolutions));
                    var typeRes     = combination.CombinedResolutionDictionary.FilterByOrigin(identifier);

                    this.ExprTypeParamResolutions.Clear();

                    var referenceRange = Range.Zero;

                    if (this.CurrentStatementOffset.IsValue &&
                        this.CurrentExpressionRange.IsValue)
                    {
                        referenceRange = this.CurrentStatementOffset.Item + this.CurrentExpressionRange.Item;
                    }
                    this.lastReferenceRange = referenceRange;

                    void AddEdge(QsSpecializationKind kind) => this.AddEdge(identifier, kind, typeRes, referenceRange);

                    if (this.IsInCall)
                    {
                        if (this.HasAdjointDependency && this.HasControlledDependency)
                        {
                            AddEdge(QsSpecializationKind.QsControlledAdjoint);
                        }
                        else if (this.HasAdjointDependency)
                        {
                            AddEdge(QsSpecializationKind.QsAdjoint);
                        }
                        else if (this.HasControlledDependency)
                        {
                            AddEdge(QsSpecializationKind.QsControlled);
                        }
                        else
                        {
                            AddEdge(QsSpecializationKind.QsBody);
                        }
                    }
                    else
                    {
                        // The callable is being used in a non-call context, such as being
                        // assigned to a variable or passed as an argument to another callable,
                        // which means it could get a functor applied at some later time.
                        // We're conservative and add all possible kinds defined for the callable.
                        foreach (var kind in this.GetSpecializationKinds(identifier))
                        {
                            AddEdge(kind);
                        }
                    }
                }
コード例 #7
0
                /// <summary>
                /// Handles adding the dependencies for specializations marked as self-inverse.
                /// </summary>
                internal void AddSelfInverseDependency(QsQualifiedName identifier, QsSpecializationKind targetSpec)
                {
                    if (this.CurrentNode is null)
                    {
                        throw new ArgumentException("AddDependency requires CurrentNode to be non-null.");
                    }

                    var combination = new TypeResolutionCombination(new[] { this.CurrentNode.ParamResolutions });
                    var typeRes     = combination.CombinedResolutionDictionary.FilterByOrigin(identifier);

                    this.AddEdge(identifier, targetSpec, typeRes, this.lastReferenceRange);
                }
コード例 #8
0
                private void AddEdge(QsQualifiedName identifier, QsSpecializationKind kind, TypeParameterResolutions typeRes, Range referenceRange)
                {
                    if (this.CurrentNode is null)
                    {
                        throw new ArgumentException("AddEdge requires CurrentNode to be non-null.");
                    }

                    var called = new ConcreteCallGraphNode(identifier, kind, typeRes);
                    var edge   = new ConcreteCallGraphEdge(referenceRange);

                    this.Graph.AddDependency(this.CurrentNode, called, edge);
                    if (!this.RequestStack.Contains(called) && !this.ResolvedNodeSet.Contains(called))
                    {
                        this.RequestStack.Push(called);
                    }
                }
コード例 #9
0
 private CheckForConstriction(QsQualifiedName origin)
     : base(new TransformationState(origin), TransformationOptions.NoRebuild)
 {
 }
コード例 #10
0
 public TransformationState(QsQualifiedName origin)
 {
     this.Origin = origin;
 }
コード例 #11
0
 private UpdateGeneratedOp(ImmutableArray <LocalVariableDeclaration <NonNullable <string> > > parameters, QsQualifiedName oldName, QsQualifiedName newName)
     : base(new TransformationState(parameters, oldName, newName))
 {
     this.Expressions     = new ExpressionTransformation(this);
     this.ExpressionKinds = new ExpressionKindTransformation(this);
     this.Types           = new TypeTransformation(this);
 }
コード例 #12
0
            public static QsCallable Apply(QsCallable qsCallable, ImmutableArray <LocalVariableDeclaration <NonNullable <string> > > parameters, QsQualifiedName oldName, QsQualifiedName newName)
            {
                var filter = new UpdateGeneratedOp(parameters, oldName, newName);

                return(filter.Namespaces.OnCallableDeclaration(qsCallable));
            }
コード例 #13
0
 /// <summary>
 /// Returns true if the declaration with the given qualified name would be accessible if it was referenced using
 /// its unqualified name, given the current namespace and a list of open namespaces.
 /// <para/>
 /// Note: Names that start with "_" are treated as "private;" they are only accessible from the namespace in
 /// which they are declared.
 /// </summary>
 private static bool IsAccessibleAsUnqualifiedName(
     QsQualifiedName qualifiedName,
     string?currentNamespace,
     IEnumerable <string> openNamespaces) =>
 openNamespaces.Contains(qualifiedName.Namespace) &&
 (!qualifiedName.Name.StartsWith("_") || qualifiedName.Namespace == currentNamespace);
コード例 #14
0
 public ImmutableHashSet <string> IdentifiersInCallable(QsQualifiedName name) =>
 this.Identifiers.TryGetValue(name, out var ids) ? ids.ToImmutable() : null;
コード例 #15
0
 /// <summary>
 /// Generates an substitution class for a given callable with a given name
 /// </summary>
 ///
 /// <para>
 /// In the following we illustrate the syntax that is generated using
 /// as an example the `Microsoft.Quantum.Canon.ApplyAnd` operation with
 /// `Microsoft.Quantum.Intrinsic.CCNOT` as an alternative when using
 /// `ToffoliSimulator`.
 ///
 /// The generated code looks as follows:
 ///
 /// <code>
 /// namespace Microsoft.Quantum.Canon {
 ///   public partial class ApplyAnd {
 ///     public class Native : ApplyAnd {
 ///       public Native(Microsoft.Quantum.Simulation.Core.IOperationFactory m) : base(m) {
 ///         sim0 = m as ToffoliSimulator;
 ///       }
 ///
 ///       public override void __Init__() {
 ///         base.Init();
 ///         if (sim0 != null) alternative0 = __Factory__.Get&lt;Microsoft.Quantum.Intrinsic.CCNOT&gt;(typeof(Microsoft.Quantum.Intrinsic.CCNOT));
 ///       }
 ///
 ///       public override Func&lt;(Qubit, Qubit, Qubit), QVoid&gt; __Body__ =&gt; args =&gt; {
 ///         if (sim0 != null) return alternative0.__Body__(args);
 ///         else return base.__Body__(args);
 ///       }
 ///
 ///       // methods for other specializations ...
 ///
 ///       private ToffoliSimulator sim0 = null;
 ///       private Microsoft.Quantum.Intrinsic.CCNOT alternative0 = null;
 ///     }
 ///   }
 /// }
 /// </code>
 /// </para>
 ///
 /// <param name="name">Namespace and name of the callable</param>
 /// <param name="callable">Q# Callable</param>
 /// <param name="substitutionAttributes">All attribute values from @HasSubstitutionAttribute attributes of that callable</param>
 public void AddCallable(QsQualifiedName name, QsCallable callable, IEnumerable <(string AlternativeOperation, string InSimulator)> substitutionAttributes)
コード例 #16
0
 /// <summary>
 ///      Formats a qualified name using dotted-name syntax.
 /// <summary>
 public static string ToFullName(this QsQualifiedName name) =>
 name?.Namespace.Value + "." + name?.Name.Value;
コード例 #17
0
 /// <summary>
 /// Base constructor for call graph nodes. Initializes CallableName.
 /// </summary>
 protected CallGraphNodeBase(QsQualifiedName callableName) => this.CallableName = callableName;
コード例 #18
0
            private static IEnumerable <QsSpecializationKind> GetSpecializationKinds(ImmutableDictionary <QsQualifiedName, QsCallable> globals, QsQualifiedName callableName)
            {
                // If there is a call to an unknown callable, throw exception
                if (!globals.TryGetValue(callableName, out QsCallable currentCallable))
                {
                    throw new ArgumentException($"Couldn't find definition for callable: {callableName}");
                }

                return(currentCallable.Specializations.Select(x => x.Kind).Distinct());
            }
コード例 #19
0
 public IdentifierReferences(QsQualifiedName idName, QsLocation defaultOffset, IImmutableSet <NonNullable <string> > limitToSourceFiles = null) :
     base(new IdentifierLocation(idName, defaultOffset))
 {
     this.IdentifierName      = idName ?? throw new ArgumentNullException(nameof(idName));
     this.RelevantSourseFiles = limitToSourceFiles;
 }
コード例 #20
0
 internal bool SetCurrentCallable(QsQualifiedName name)
 {
     this.CurrentCallable = name;
     return(name != null && this.Identifiers.TryAdd(name, ImmutableHashSet.CreateBuilder <string>()));
 }
コード例 #21
0
        // Rewrite Implementations

        private static Access GetAccessModifier(ImmutableDictionary <QsQualifiedName, QsCustomType> userDefinedTypes, QsQualifiedName typeName)
        {
            // If there is a reference to an unknown type, throw exception
            if (!userDefinedTypes.TryGetValue(typeName, out var type))
            {
                throw new ArgumentException($"Couldn't find definition for user defined type: {typeName}");
            }
            return(type.Access);
        }
コード例 #22
0
 /// <summary>
 /// Adds dependency to the graph from the current callable to the callable referenced by the given identifier.
 /// </summary>
 internal abstract void AddDependency(QsQualifiedName identifier);
コード例 #23
0
 /// <summary>
 /// Returns true if the qualified name is visible given the current namespace and a list of open namespaces.
 /// <para/>
 /// Names that start with "_" are treated as "private"; they are only visible from the namespace in which they
 /// are declared.
 /// </summary>
 private static bool IsVisible(QsQualifiedName qualifiedName,
                               string currentNamespace,
                               IEnumerable <string> openNamespaces) =>
 openNamespaces.Contains(qualifiedName.Namespace.Value) &&
 (!qualifiedName.Name.Value.StartsWith("_") || qualifiedName.Namespace.Value == currentNamespace);
コード例 #24
0
        // public static methods

        /// <summary>
        /// Returns a Q# attribute with the given name and argument that can be attached to a declaration.
        /// The attribute id is set to Null if the given name is null.
        /// The attribute argument is set to an invalid expression if the given argument is null.
        /// </summary>
        public static QsDeclarationAttribute BuildAttribute(QsQualifiedName name, TypedExpression arg) =>
        new QsDeclarationAttribute(BuildId(name), QsNullable <Range> .Null, arg, Position.Zero, QsComments.Empty);
コード例 #25
0
 public TransformationState(ImmutableArray <LocalVariableDeclaration <NonNullable <string> > > parameters, QsQualifiedName oldName, QsQualifiedName newName)
 {
     this.Parameters = parameters;
     this.OldName    = oldName;
     this.NewName    = newName;
 }
コード例 #26
0
        // public static methods

        /// <summary>
        /// Returns a Q# attribute with the given name and argument that can be attached to a declaration.
        /// The attribute id is set to Null if the given name is null.
        /// The attribute argument is set to an invalid expression if the given argument is null.
        /// </summary>
        public static QsDeclarationAttribute BuildAttribute(QsQualifiedName name, TypedExpression arg) =>
        new QsDeclarationAttribute(BuildId(name), arg ?? SyntaxGenerator.InvalidExpression, Position.Zero, QsComments.Empty);
コード例 #27
0
            private (ResolvedSignature, IEnumerable <QsSpecialization>) MakeSpecializations(
                QsQualifiedName callableName, ResolvedType paramsType, SpecializationImplementation bodyImplementation)
            {
                QsSpecialization MakeSpec(QsSpecializationKind kind, ResolvedSignature signature, SpecializationImplementation impl) =>
                new QsSpecialization(
                    kind,
                    callableName,
                    ImmutableArray <QsDeclarationAttribute> .Empty,
                    this.CurrentCallable.Callable.SourceFile,
                    QsNullable <QsLocation> .Null,
                    QsNullable <ImmutableArray <ResolvedType> > .Null,
                    signature,
                    impl,
                    ImmutableArray <string> .Empty,
                    QsComments.Empty);

                var adj    = this.CurrentCallable.Adjoint;
                var ctl    = this.CurrentCallable.Controlled;
                var ctlAdj = this.CurrentCallable.ControlledAdjoint;

                bool addAdjoint    = false;
                bool addControlled = false;
                bool isSelfAdjoint = false;

                if (this.InWithinBlock)
                {
                    addAdjoint    = true;
                    addControlled = false;
                }
                else if (this.InBody)
                {
                    if (adj != null && adj.Implementation is SpecializationImplementation.Generated adjGen)
                    {
                        addAdjoint    = adjGen.Item.IsInvert;
                        isSelfAdjoint = adjGen.Item.IsSelfInverse;
                    }
                    if (ctl != null && ctl.Implementation is SpecializationImplementation.Generated ctlGen)
                    {
                        addControlled = ctlGen.Item.IsDistribute;
                    }
                    if (ctlAdj != null && ctlAdj.Implementation is SpecializationImplementation.Generated ctlAdjGen)
                    {
                        addAdjoint    = addAdjoint || (ctlAdjGen.Item.IsInvert && ctl.Implementation.IsGenerated);
                        addControlled = addControlled || (ctlAdjGen.Item.IsDistribute && adj.Implementation.IsGenerated);
                        isSelfAdjoint = isSelfAdjoint || ctlAdjGen.Item.IsSelfInverse;
                    }
                }
                else if (ctlAdj != null && ctlAdj.Implementation is SpecializationImplementation.Generated gen)
                {
                    addControlled = this.InAdjoint && gen.Item.IsDistribute;
                    addAdjoint    = this.InControlled && gen.Item.IsInvert;
                    isSelfAdjoint = gen.Item.IsSelfInverse;
                }

                var props = new List <OpProperty>();

                if (addAdjoint)
                {
                    props.Add(OpProperty.Adjointable);
                }
                if (addControlled)
                {
                    props.Add(OpProperty.Controllable);
                }
                var newSig = new ResolvedSignature(
                    this.CurrentCallable.Callable.Signature.TypeParameters,
                    paramsType,
                    ResolvedType.New(ResolvedTypeKind.UnitType),
                    new CallableInformation(ResolvedCharacteristics.FromProperties(props), new InferredCallableInformation(isSelfAdjoint, false)));

                var controlledSig = new ResolvedSignature(
                    newSig.TypeParameters,
                    ResolvedType.New(ResolvedTypeKind.NewTupleType(ImmutableArray.Create(
                                                                       ResolvedType.New(ResolvedTypeKind.NewArrayType(ResolvedType.New(ResolvedTypeKind.Qubit))),
                                                                       newSig.ArgumentType))),
                    newSig.ReturnType,
                    newSig.Information);

                var specializations = new List <QsSpecialization>()
                {
                    MakeSpec(QsSpecializationKind.QsBody, newSig, bodyImplementation)
                };

                if (addAdjoint)
                {
                    specializations.Add(MakeSpec(
                                            QsSpecializationKind.QsAdjoint,
                                            newSig,
                                            SpecializationImplementation.NewGenerated(QsGeneratorDirective.Invert)));
                }

                if (addControlled)
                {
                    specializations.Add(MakeSpec(
                                            QsSpecializationKind.QsControlled,
                                            controlledSig,
                                            SpecializationImplementation.NewGenerated(QsGeneratorDirective.Distribute)));
                }

                if (addAdjoint && addControlled)
                {
                    specializations.Add(MakeSpec(
                                            QsSpecializationKind.QsControlledAdjoint,
                                            controlledSig,
                                            SpecializationImplementation.NewGenerated(QsGeneratorDirective.Distribute)));
                }

                return(newSig, specializations);
            }
コード例 #28
0
        public bool Transformation(QsCompilation compilation, [NotNullWhen(true)] out QsCompilation?transformed)
        {
            // we do not change the Q# syntax tree
            transformed = compilation;

            // global callables
            var globalCallables = compilation.Namespaces.GlobalCallableResolutions();

            // collect all callables that have an substitution attribute
            var globals = globalCallables.Where(p => p.Value.Source.CodeFile.EndsWith(".qs"))
                          .Where(p => p.Value.Attributes.Any(HasSubstitutionAttribute));

            if (!globals.Any())
            {
                diagnostics.Add(new IRewriteStep.Diagnostic
                {
                    Severity = DiagnosticSeverity.Info,
                    Message  = "AutoSubstitution: no operations have @SubstitutableOnTarget attribute",
                    Stage    = IRewriteStep.Stage.Transformation
                });
                return(true);
            }

            // no need to generate any C# file, if there is no substitution attribute, or if we cannot retrieve the output path
            if (!AssemblyConstants.TryGetValue(Microsoft.Quantum.QsCompiler.ReservedKeywords.AssemblyConstants.OutputPath, out var outputPath))
            {
                diagnostics.Add(new IRewriteStep.Diagnostic
                {
                    Severity = DiagnosticSeverity.Error,
                    Message  = "AutoSubstitution: cannot determine output path for generated C# code",
                    Stage    = IRewriteStep.Stage.Transformation
                });
                return(false);
            }

            diagnostics.Add(new IRewriteStep.Diagnostic
            {
                Severity = DiagnosticSeverity.Info,
                Message  = $"AutoSubstitution: Generating file __AutoSubstitution__.g.cs in {outputPath}",
                Stage    = IRewriteStep.Stage.Transformation
            });

            using var writer = new StreamWriter(Path.Combine(outputPath, "__AutoSubstitution__.g.cs"));
            var context = CodegenContext.Create(compilation, AssemblyConstants);

            var generator = new CodeGenerator(context);

            foreach (var(key, callable) in globals)
            {
                var attributeArguments = callable.Attributes.Where(HasSubstitutionAttribute).Select(GetSubstitutionAttributeArguments);
                foreach (var(alternativeOperation, _) in attributeArguments)
                {
                    var period = alternativeOperation.LastIndexOf('.');
                    if (period == -1)
                    {
                        diagnostics.Add(new IRewriteStep.Diagnostic
                        {
                            Severity = DiagnosticSeverity.Error,
                            Message  = $"AutoSubstitution: name of alternative operation in {key.Namespace}.{key.Name} must be completely specified (including namespace)",
                            Stage    = IRewriteStep.Stage.Transformation
                        });
                        return(false);
                    }

                    var qualifiedName = new QsQualifiedName(alternativeOperation.Substring(0, period), alternativeOperation.Substring(period + 1));
                    if (!globalCallables.TryGetValue(qualifiedName, out var alternativeCallable))
                    {
                        diagnostics.Add(new IRewriteStep.Diagnostic
                        {
                            Severity = DiagnosticSeverity.Error,
                            Message  = $"AutoSubstitution: cannot find alternative operation `{alternativeOperation}`",
                            Stage    = IRewriteStep.Stage.Transformation
                        });
                        return(false);
                    }

                    var callableSignature    = callable.Signature;
                    var alternativeSignature = alternativeCallable.Signature;

                    if (!callableSignature.ArgumentType.Equals(alternativeSignature.ArgumentType) || !callableSignature.ReturnType.Equals(alternativeSignature.ReturnType))
                    {
                        diagnostics.Add(new IRewriteStep.Diagnostic
                        {
                            Severity = DiagnosticSeverity.Error,
                            Message  = $"AutoSubstitution: signature of `{alternativeOperation}` does not match the one of {key.Namespace}.{key.Name}",
                            Stage    = IRewriteStep.Stage.Transformation
                        });
                        return(false);
                    }

                    if (!GetSpecializationKinds(callable).IsSubsetOf(GetSpecializationKinds(alternativeCallable)))
                    {
                        diagnostics.Add(new IRewriteStep.Diagnostic
                        {
                            Severity = DiagnosticSeverity.Error,
                            Message  = $"AutoSubstitution: specializations of `{alternativeOperation}` must be a superset of specializations of {key.Namespace}.{key.Name}",
                            Stage    = IRewriteStep.Stage.Transformation
                        });
                        return(false);
                    }
                }
                generator.AddCallable(key, callable, attributeArguments);
            }
            generator.WriteTo(writer);


            return(true);
        }
コード例 #29
0
        private static Identifier GetConcreteIdentifier(
            Response currentResponse,
            Stack <Request> requests,
            List <Response> responses,
            Identifier.GlobalCallable globalCallable,
            ImmutableConcretion types)
        {
            QsQualifiedName concreteName = globalCallable.Item;

            var typesHashSet = ImmutableHashSet <KeyValuePair <Tuple <QsQualifiedName, NonNullable <string> >, ResolvedType> > .Empty;

            if (types != null && !types.IsEmpty)
            {
                typesHashSet = types.ToImmutableHashSet();
            }

            string name = null;

            // Check for recursive call
            if (currentResponse.OriginalName.Equals(globalCallable.Item) &&
                typesHashSet.SetEquals(currentResponse.TypeResolutions))
            {
                name = currentResponse.ConcreteCallable.FullName.Name.Value;
            }

            // Search requests for identifier
            if (name == null)
            {
                name = requests
                       .Where(req =>
                              req.OriginalName.Equals(globalCallable.Item) &&
                              typesHashSet.SetEquals(req.TypeResolutions))
                       .Select(req => req.ConcreteName.Name.Value)
                       .FirstOrDefault();
            }

            // Search responses for identifier
            if (name == null)
            {
                name = responses
                       .Where(res =>
                              res.OriginalName.Equals(globalCallable.Item) &&
                              typesHashSet.SetEquals(res.TypeResolutions))
                       .Select(res => res.ConcreteCallable.FullName.Name.Value)
                       .FirstOrDefault();
            }

            // If identifier can't be found, make a new request
            if (name == null)
            {
                // If this is not a generic, do not change the name
                if (!typesHashSet.IsEmpty)
                {
                    // Create new name
                    concreteName = UniqueVariableNames.PrependGuid(globalCallable.Item);
                }

                requests.Push(new Request()
                {
                    OriginalName    = globalCallable.Item,
                    TypeResolutions = types,
                    ConcreteName    = concreteName
                });
            }
            else
            {
                // If the identifier was found, update with the name
                concreteName = new QsQualifiedName(globalCallable.Item.Namespace, NonNullable <string> .New(name));
            }

            return(Identifier.NewGlobalCallable(concreteName));
        }
コード例 #30
0
 private static AttributeId BuildId(QsQualifiedName name) =>
 name != null
     ? AttributeId.NewValue(new UserDefinedType(name.Namespace, name.Name, QsNullable <Range> .Null))
     : AttributeId.Null;