예제 #1
0
        public void FormattedBookByName_ReturnsCorrectResult()
        {
            Book   b = new Book("1", "name1", "author1", "publisher1", 2019, 100, 10);
            string expectedString = "Book: Name - name1";

            b = new NameDecorator(b);

            Assert.AreEqual(expectedString, b.ToString());
        }
예제 #2
0
        /// <summary>
        /// Adds a TargetInstruction attribute to each intrinsic callable that doesn't have one,
        /// unless the automatically determined target instruction name conflicts with another target instruction name.
        /// The automatically determined name of the target instruction is the lower case version of the unqualified callable name.
        /// Type constructors and generic callables are left unchanged.
        /// </summary>
        /// <returns>Returns true if all missing attributes have been successfully added and false if some attributes could not be added.</returns>
        /// <exception cref="InvalidOperationException">All intrinsic callables need to have exactly one body specialization.</exception>
        public static bool TryAddMissingTargetInstructionAttributes(QsCompilation compilation, out QsCompilation transformed)
        {
            var           success          = true;
            List <string> instructionNames = new List <string>();

            // populate the intruction names with all manually specified ones first
            foreach (var callable in compilation.Namespaces.Callables())
            {
                var manuallySpecified = SymbolResolution.TryGetTargetInstructionName(callable.Attributes);
                if (manuallySpecified.IsValue)
                {
                    instructionNames.Add(manuallySpecified.Item);
                }
            }

            QsCallable AddAttribute(QsCallable callable)
            {
                if (callable.Specializations.Length != 1)
                {
                    throw new InvalidOperationException("intrinsic callable needs to have exactly one body specialization");
                }

                var instructionName = callable.FullName.Name.ToLowerInvariant();

                if (instructionNames.Contains(instructionName))
                {
                    success = false;
                    return(callable);
                }
                return(callable.AddAttribute(
                           AttributeUtils.BuildAttribute(
                               BuiltIn.TargetInstruction.FullName,
                               AttributeUtils.StringArgument(instructionName))));
            }

            QsNamespace AddAttributes(QsNamespace ns)
            {
                var elements = ns.Elements.Select(element =>
                                                  element is QsNamespaceElement.QsCallable callable &&
                                                  callable.Item.IsIntrinsic &&
                                                  callable.Item.Signature.TypeParameters.Length == 0 &&
                                                  !NameDecorator.IsAutoGeneratedName(callable.Item.FullName) &&
                                                  !callable.Item.Kind.IsTypeConstructor &&
                                                  !callable.Item.Attributes.Any(BuiltIn.DefinesTargetInstruction)
                    ? QsNamespaceElement.NewQsCallable(AddAttribute(callable.Item))
                    : element);

                return(new QsNamespace(ns.Name, elements.ToImmutableArray(), ns.Documentation));
            }

            var namespaces = compilation.Namespaces.Select(AddAttributes).ToImmutableArray();

            transformed = new QsCompilation(namespaces, compilation.EntryPoints);
            return(success);
        }
        public override QsCallable OnCallableDeclaration(QsCallable c)
        {
            var unmangledName = NameDecorator.OriginalNameFromMonomorphized(c.FullName);

            if (this.SharedState.Functions.BuiltIn.ContainsKey(unmangledName))
            {
                return(c);
            }

            this.context.SetCurrentCallable(c);
            c = base.OnCallableDeclaration(c);
            this.context.SetCurrentCallable(null);
            return(c);
        }
예제 #4
0
            private (QsCallable, ResolvedType) GenerateOperation(CallableDetails callable, QsScope contents)
            {
                var newName = NameDecorator.PrependGuid(callable.Callable.FullName);

                var knownVariables = contents.KnownSymbols.Variables;

                var parameters = QsTuple <LocalVariableDeclaration <QsLocalSymbol> > .NewQsTuple(knownVariables
                                                                                                 .Select(var => QsTuple <LocalVariableDeclaration <QsLocalSymbol> > .NewQsTupleItem(new LocalVariableDeclaration <QsLocalSymbol>(
                                                                                                                                                                                        QsLocalSymbol.NewValidName(var.VariableName),
                                                                                                                                                                                        var.Type,
                                                                                                                                                                                        new InferredExpressionInformation(false, false),
                                                                                                                                                                                        var.Position,
                                                                                                                                                                                        var.Range)))
                                                                                                 .ToImmutableArray());

                var paramTypes = ResolvedType.New(ResolvedTypeKind.UnitType);

                if (knownVariables.Length == 1)
                {
                    paramTypes = knownVariables.First().Type;
                }
                else if (knownVariables.Length > 1)
                {
                    paramTypes = ResolvedType.New(ResolvedTypeKind.NewTupleType(knownVariables
                                                                                .Select(var => var.Type)
                                                                                .ToImmutableArray()));
                }

                var(signature, specializations) = this.MakeSpecializations(callable, newName, paramTypes, SpecializationImplementation.NewProvided(parameters, contents));

                var generatedCallable = new QsCallable(
                    QsCallableKind.Operation,
                    newName,
                    ImmutableArray <QsDeclarationAttribute> .Empty,
                    Access.Internal,
                    callable.Callable.Source,
                    QsNullable <QsLocation> .Null,
                    signature,
                    parameters,
                    specializations.ToImmutableArray(),
                    ImmutableArray <string> .Empty,
                    QsComments.Empty);

                // Change the origin of all type parameter references to use the new name and make all variables immutable
                generatedCallable = UpdateGeneratedOp.Apply(generatedCallable, knownVariables, callable.Callable.FullName, newName);

                return(generatedCallable, signature.ArgumentType);
            }
예제 #5
0
        public void FormattedBookByAllFields_ReturnsCorrectResult()
        {
            Book   b = new Book("1", "name1", "author1", "publisher1", 2019, 100, 10);
            string expectedString = "Book: Isbn - 1 Name - name1 Author - author1 Publisher - publisher1 " +
                                    "Year of publication - 2019 Count of page - 100 Price - 10";

            b = new IsbnDecorator(b);
            b = new NameDecorator(b);
            b = new AuthorDecorator(b);
            b = new PublisherDecorator(b);
            b = new PublicationYearDecorator(b);
            b = new PageCountDecorator(b);
            b = new PriceDecorator(b);

            Assert.AreEqual(expectedString, b.ToString());
        }
예제 #6
0
        /// <summary>
        /// Performs Monomorphization on the given compilation. If the keepAllIntrinsics parameter
        /// is set to true, then unused intrinsics will not be removed from the resulting compilation.
        /// </summary>
        public static QsCompilation Apply(QsCompilation compilation, bool keepAllIntrinsics = true)
        {
            var globals         = compilation.Namespaces.GlobalCallableResolutions();
            var concretizations = new List <QsCallable>();
            var concreteNames   = new Dictionary <ConcreteCallGraphNode, QsQualifiedName>();

            var nodes = new ConcreteCallGraph(compilation).Nodes
                        // Remove specialization information so that we only deal with the full callables.
                        // Note: this only works fine if for all nodes in the call graph,
                        // all existing functor specializations and their dependencies are also in the call graph.
                        .Select(n => new ConcreteCallGraphNode(n.CallableName, QsSpecializationKind.QsBody, n.ParamResolutions))
                        .ToImmutableHashSet();

            var getAccessModifiers = new GetAccessModifiers((typeName) => GetAccessModifier(compilation.Namespaces.GlobalTypeResolutions(), typeName));

            // Loop through the nodes, getting a list of concrete callables
            foreach (var node in nodes)
            {
                // If there is a call to an unknown callable, throw exception
                if (!globals.TryGetValue(node.CallableName, out QsCallable originalGlobal))
                {
                    throw new ArgumentException($"Couldn't find definition for callable: {node.CallableName}");
                }

                if (node.ParamResolutions.Any())
                {
                    // Get concrete name
                    var concreteName = NameDecorator.PrependGuid(node.CallableName);

                    // Add to concrete name mapping
                    concreteNames[node] = concreteName;

                    // Generate the concrete version of the callable
                    var concrete = ReplaceTypeParamImplementations.Apply(originalGlobal, node.ParamResolutions, getAccessModifiers);
                    concretizations.Add(
                        concrete.WithFullName(oldName => concreteName)
                        .WithSpecializations(specs => specs.Select(spec => spec.WithParent(_ => concreteName)).ToImmutableArray()));
                }
                else
                {
                    concretizations.Add(originalGlobal);
                }
            }

            GetConcreteIdentifierFunc getConcreteIdentifier = (globalCallable, types) =>
                                                              GetConcreteIdentifier(concreteNames, globalCallable, types);

            var intrinsicCallableSet = globals
                                       .Where(kvp => kvp.Value.Specializations.Any(spec => spec.Implementation.IsIntrinsic))
                                       .Select(kvp => kvp.Key)
                                       .ToImmutableHashSet();

            var final = new List <QsCallable>();

            // Loop through concretizations, replacing all references to generics with their concrete counterparts
            foreach (var callable in concretizations)
            {
                final.Add(ReplaceTypeParamCalls.Apply(callable, getConcreteIdentifier, intrinsicCallableSet));
            }

            return(ResolveGenerics.Apply(compilation, final, intrinsicCallableSet, keepAllIntrinsics));
        }
예제 #7
0
        /// <summary>
        /// Performs Monomorphization on the given compilation. If the monomorphizeIntrinsics parameter
        /// is set to false, then intrinsics will not be monomorphized.
        /// </summary>
        public static QsCompilation Apply(QsCompilation compilation, bool monomorphizeIntrinsics = false)
        {
            var globals          = compilation.Namespaces.GlobalCallableResolutions();
            var concretizations  = new List <QsCallable>();
            var concreteNamesMap = new Dictionary <ConcreteCallGraphNode, QsQualifiedName>();

            var nodesWithResolutions = new ConcreteCallGraph(compilation).Nodes
                                       // Remove specialization information so that we only deal with the full callables.
                                       // Note: this only works fine if for all nodes in the call graph,
                                       // all existing functor specializations and their dependencies are also in the call graph.
                                       .Select(n => new ConcreteCallGraphNode(n.CallableName, QsSpecializationKind.QsBody, n.ParamResolutions))
                                       .Where(n => n.ParamResolutions.Any())
                                       .ToImmutableHashSet();

            var getAccessModifiers = new GetAccessModifiers((typeName) => GetAccessModifier(compilation.Namespaces.GlobalTypeResolutions(), typeName));

            // Loop through the nodes, getting a list of concrete callables
            foreach (var node in nodesWithResolutions)
            {
                // If there is a call to an unknown callable, throw exception
                if (!globals.TryGetValue(node.CallableName, out var originalGlobal))
                {
                    throw new ArgumentException($"Couldn't find definition for callable: {node.CallableName}");
                }

                if (monomorphizeIntrinsics || !originalGlobal.IsIntrinsic)
                {
                    // Get concrete name
                    var concreteName = NameDecorator.PrependGuid(node.CallableName);

                    // Add to concrete name mapping
                    concreteNamesMap[node] = concreteName;

                    // Generate the concrete version of the callable
                    var concrete =
                        ReplaceTypeParamImplementations.Apply(originalGlobal, node.ParamResolutions, getAccessModifiers)
                        .WithFullName(oldName => concreteName)
                        .WithSpecializations(specs => specs.Select(spec => spec.WithParent(_ => concreteName)).ToImmutableArray());
                    concretizations.Add(concrete);
                }
            }

            var callablesByNamespace = concretizations.ToLookup(x => x.FullName.Namespace);
            var namespacesWithImpls  = compilation.Namespaces.Select(ns =>
            {
                var elemsToAdd = callablesByNamespace[ns.Name].Select(call => QsNamespaceElement.NewQsCallable(call));

                return(ns.WithElements(elems =>
                                       elems
                                       .Where(elem =>
                                              !(elem is QsNamespaceElement.QsCallable call) ||
                                              !IsGeneric(call.Item) ||
                                              (call.Item.IsIntrinsic && !monomorphizeIntrinsics) ||
                                              BuiltIn.RewriteStepDependencies.Contains(call.Item.FullName))
                                       .Concat(elemsToAdd)
                                       .ToImmutableArray()));
            }).ToImmutableArray();

            var compWithImpls = new QsCompilation(namespacesWithImpls, compilation.EntryPoints);

            GetConcreteIdentifierFunc getConcreteIdentifier = (globalCallable, types) =>
                                                              GetConcreteIdentifier(concreteNamesMap, globalCallable, types);

            var intrinsicsToKeep = monomorphizeIntrinsics
                ? ImmutableHashSet <QsQualifiedName> .Empty
                : globals
                                   .Where(kvp => kvp.Value.Specializations.Any(spec => spec.Implementation.IsIntrinsic))
                                   .Select(kvp => kvp.Key)
                                   .ToImmutableHashSet();

            return(ReplaceTypeParamCalls.Apply(compWithImpls, getConcreteIdentifier, intrinsicsToKeep));
        }