Exemple #1
0
        public void ParseDeprecated()
        {
            string[] comments = { "# Summary",
                                  "This is some text",
                                  "# Deprecated",
                                  "Some other text" };
            string   dep         = "NewName";
            string   warning     = "> [!WARNING]\n> Deprecated\n";
            string   warningText = "name has been deprecated. Please use @\"newname\" instead.";

            // Test with just the Deprecated comment section
            var dc = new DocComment(comments);

            Assert.Equal(comments[1] + "\r" + warning + "\r" + comments[3], dc.Summary);
            Assert.Equal(warning + "\r" + comments[3], dc.ShortSummary);
            Assert.Equal(comments[3], dc.Documentation);

            // Test with just the deprecated attribute
            dc = new DocComment(comments.Take(2), "name", true, dep);
            Assert.Equal(comments[1] + "\r" + warning + "\r" + warningText, dc.Summary);
            Assert.Equal(warning + "\r" + warningText, dc.ShortSummary);
            Assert.Equal(warningText, dc.Documentation);

            // Test with both
            dc = new DocComment(comments, "name", true, dep);
            Assert.Equal(comments[1] + "\r" + warning + "\r" + warningText + "\r" + comments[3], dc.Summary);
            Assert.Equal(warning + "\r" + warningText, dc.ShortSummary);
            Assert.Equal(warningText, dc.Documentation);
        }
Exemple #2
0
            public override QsCallable OnCallableDeclaration(QsCallable callable)
            {
                callable = base.OnCallableDeclaration(callable);
                // If the callable didn't come from a Q# source file, then it
                // came in from a reference, and shouldn't be documented in this
                // project.
                if (!callable.IsInCompilationUnit())
                {
                    return(callable);
                }

                var isDeprecated = callable.IsDeprecated(out var replacement);
                var docComment   = new DocComment(
                    callable.Documentation, callable.FullName.Name,
                    deprecated: isDeprecated,
                    replacement: replacement
                    );
                var callableName =
                    $"{callable.FullName.Namespace}.{callable.FullName.Name}";

                // Validate input and type parameter names.
                var inputDeclarations = callable.ArgumentTuple.ToDictionaryOfDeclarations();

                this.ValidateNames(
                    callableName,
                    "input",
                    name => inputDeclarations.ContainsKey(name),
                    docComment.Input.Keys,
                    range: null, // TODO: provide more exact locations once supported by DocParser.
                    source: callable.SourceFile
                    );
                this.ValidateNames(
                    callableName,
                    "type parameter",
                    name => callable.Signature.TypeParameters.Any(
                        typeParam =>
                        typeParam is QsLocalSymbol.ValidName validName &&
                        validName.Item == name.TrimStart('\'')
                        ),
                    docComment.TypeParameters.Keys,
                    range: null, // TODO: provide more exact locations once supported by DocParser.
                    source: callable.SourceFile
                    );

                this.writer?.WriteOutput(callable, docComment)?.Wait();

                return(callable
                       .AttributeBuilder()
                       .MaybeWithSimpleDocumentationAttribute("Summary", docComment.Summary)
                       .MaybeWithSimpleDocumentationAttribute("Description", docComment.Description)
                       .MaybeWithSimpleDocumentationAttribute("Remarks", docComment.Remarks)
                       .MaybeWithSimpleDocumentationAttribute("References", docComment.References)
                       .WithListOfDocumentationAttributes("SeeAlso", docComment.SeeAlso)
                       .WithListOfDocumentationAttributes("Example", docComment.Examples)
                       .WithDocumentationAttributesFromDictionary("Input", docComment.Input)
                       .MaybeWithSimpleDocumentationAttribute("Output", docComment.Output)
                       .WithDocumentationAttributesFromDictionary("TypeParameter", docComment.TypeParameters)
                       .Build());
            }
Exemple #3
0
        public async Task <IViewComponentResult> InvokeAsync(Doc entity, DocComment reply)
        {
            // Populate previous and next entity
            var model = await GetModelAsync(entity);

            // Return view
            return(View(model));
        }
        public void DocCommentAccessibleObject_Ctor_Default()
        {
            using PropertyGrid propertyGrid = new PropertyGrid();
            using DocComment docComment     = new DocComment(propertyGrid);
            DocCommentAccessibleObject accessibleObject = new DocCommentAccessibleObject(docComment, propertyGrid);

            Assert.Equal(docComment, accessibleObject.Owner);
            Assert.False(propertyGrid.IsHandleCreated);
            Assert.False(docComment.IsHandleCreated);
        }
Exemple #5
0
        public void DocCommentAccessibleObject_ControlType_IsPane_IfAccessibleRoleIsDefault()
        {
            using PropertyGrid propertyGrid = new PropertyGrid();
            using DocComment docComment     = new DocComment(propertyGrid);
            // AccessibleRole is not set = Default

            object actual = docComment.AccessibilityObject.GetPropertyValue(UiaCore.UIA.ControlTypePropertyId);

            Assert.Equal(UiaCore.UIA.PaneControlTypeId, actual);
            Assert.False(propertyGrid.IsHandleCreated);
            Assert.False(docComment.IsHandleCreated);
        }
Exemple #6
0
        public void ParseDocComments()
        {
            string[] comments =
            {
                "# Summary",
                "Encodes a multi-qubit Pauli operator represented as an array of",
                "single-qubit Pauli operators into an integer.",
                "",
                "Test second paragraph.",
                "",
                "# Description",
                "This is some text",
                "",
                "This is some more text",
                "",
                "# Input",
                "## paulies",
                "An array of at most 31 single-qubit Pauli operators.",
                "",
                "# Output",
                "An integer uniquely identifying `paulies`, as described below.",
                "",
                "# Remarks",
                "Each Pauli operator can be encoded using two bits:",
                "$$",
                "\\begin{align}",
                "\\boldone \\mapsto 00, \\quad X \\mapsto 01, \\quad Y \\mapsto 11,",
                "\\quad Z \\mapsto 10.",
                "\\end{align}",
                "$$",
                "",
                "Given an array of Pauli operators `[P0, ..., Pn]`, this function returns an",
                "integer with binary expansion formed by concatenating",
                "the mappings of each Pauli operator in big-endian order",
                "`bits(Pn) ... bits(P0)`."
            };
            var dc = new DocComment(comments);

            Assert.Equal(comments[1] + "\r" + comments[2] + "\r" + comments[3] + "\r" + comments[4], dc.Summary);
            Assert.Equal(comments[1] + "\r" + comments[2], dc.ShortSummary);
            Assert.Equal(comments[1] + "\r" + comments[2], dc.FullSummary);
            Assert.Equal(comments[1] + "\r" + comments[2] + "\r" + comments[3] + "\r" + comments[4] + "\r" + comments[5] + "\r" + comments[7] + "\r" + comments[8] + "\r" + comments[9], dc.Documentation);
            Assert.Single(dc.Input);
            Assert.Equal(comments[13], dc.Input["paulies"]);
            Assert.Equal(comments[16], dc.Output);
            Assert.Empty(dc.TypeParameters);
#pragma warning disable 618 // Example is obsolete.
            Assert.Equal("", dc.Example);
#pragma warning restore 618
            var remarks = string.Join("\r", comments.AsSpan(19, 12).ToArray());
            Assert.Equal(remarks, dc.Remarks);
        }
 public override QsNamespace OnNamespace(QsNamespace ns)
 {
     ns = base.OnNamespace(ns);
     if (ns.Elements.Any(element => element.IsInCompilationUnit()))
     {
         // Concatenate everything into one documentation comment.
         var comment = new DocComment(
             ns.Documentation.SelectMany(group => group).SelectMany(comments => comments));
         if (ns.Elements.Any(element => element switch
         {
             QsNamespaceElement.QsCallable {
                 Item: var callable
             } => callable.Access.IsPublic,
Exemple #8
0
            public override QsNamespace OnNamespace(QsNamespace ns)
            {
                ns = base.OnNamespace(ns);
                if (ns.Elements.Any(element => element.IsInCompilationUnit()))
                {
                    // Concatenate everything into one documentation comment.
                    var comment = new DocComment(
                        ns.Documentation.SelectMany(group => group).SelectMany(comments => comments)
                        );
                    writer?.WriteOutput(ns, comment)?.Wait();
                }

                return(ns);
            }
        public async Task <IActionResult> SendFile(DocComment doc)
        {
            foreach (var uploadedFile in doc.files)
            {
                var name = uploadedFile.FileName;
                var path = "/docs/" + name;
                using (var fileStream = new FileStream(AppSettings.WebRootPath + path, FileMode.Create))
                {
                    await uploadedFile.CopyToAsync(fileStream);
                }
            }

            return(Ok(new
            {
                message = "Idi naxyi"
            }));
        }
Exemple #10
0
        public void DocCommentAccessibleObject_Role_IsExpected_ByDefault(bool createControl, AccessibleRole expectedRole)
        {
            using PropertyGrid propertyGrid = new PropertyGrid();
            using DocComment docComment     = new DocComment(propertyGrid);
            // AccessibleRole is not set = Default

            if (createControl)
            {
                docComment.CreateControl();
            }

            AccessibleRole actual = docComment.AccessibilityObject.Role;

            Assert.Equal(expectedRole, actual);
            Assert.False(propertyGrid.IsHandleCreated);
            Assert.Equal(createControl, docComment.IsHandleCreated);
        }
Exemple #11
0
            public override QsCustomType OnTypeDeclaration(QsCustomType type)
            {
                type = base.OnTypeDeclaration(type);
                // If the UDT didn't come from a Q# source file, then it
                // came in from a reference, and shouldn't be documented in this
                // project.
                if (!type.IsInCompilationUnit())
                {
                    return(type);
                }

                var isDeprecated = type.IsDeprecated(out var replacement);
                var docComment   = new DocComment(
                    type.Documentation, type.FullName.Name,
                    deprecated: isDeprecated,
                    replacement: replacement
                    );

                // Validate named item names.
                var inputDeclarations = type.TypeItems.ToDictionaryOfDeclarations();

                this.ValidateNames(
                    $"{type.FullName.Namespace}.{type.FullName.Name}",
                    "named item",
                    name => inputDeclarations.ContainsKey(name),
                    docComment.Input.Keys,
                    range: null, // TODO: provide more exact locations once supported by DocParser.
                    source: type.SourceFile
                    );

                this.writer?.WriteOutput(type, docComment)?.Wait();

                return(type
                       .AttributeBuilder()
                       .MaybeWithSimpleDocumentationAttribute("Summary", docComment.Summary)
                       .MaybeWithSimpleDocumentationAttribute("Description", docComment.Description)
                       .MaybeWithSimpleDocumentationAttribute("Remarks", docComment.Remarks)
                       .MaybeWithSimpleDocumentationAttribute("References", docComment.References)
                       .WithListOfDocumentationAttributes("SeeAlso", docComment.SeeAlso)
                       .WithListOfDocumentationAttributes("Example", docComment.Examples)
                       .WithDocumentationAttributesFromDictionary("NamedItem", docComment.NamedItems)
                       .Build());
            }
        public async Task <IViewComponentResult> InvokeAsync(Doc entity, DocComment reply)
        {
            // We always need a entity to display tags
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }

            // Get tags and return view
            var tags = await _tagStore.GetByEntityIdAsync(entity.Id);

            return(View(new TagListViewModel()
            {
                Topic = entity,
                Reply = reply,
                Tags = tags?
                       .Where(t => t.EntityReplyId == (reply?.Id ?? 0))
                       .OrderByDescending(t => t.TotalEntities)
            }));
        }
        /// <summary>
        ///     Given a documentation comment describing a Q# namespace,
        ///     writes a Markdown file documenting that namespace to
        ///     <see cref="OutputPath" />.
        /// </summary>
        /// <param name="ns">The Q# namespace being documented.</param>
        /// <param name="docComment">
        ///     The API documentation comment describing <paramref name="ns" />.
        /// </param>
        /// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
        public async Task WriteOutput(QsNamespace ns, DocComment docComment)
        {
            var name   = ns.Name;
            var uid    = name;
            var title  = $"{name} namespace";
            var header = new Dictionary <string, object>
            {
                // DocFX metadata
                ["uid"]   = name,
                ["title"] = title,

                // docs.ms metadata
                ["ms.date"]  = DateTime.Today.ToString(),
                ["ms.topic"] = "managed-reference",

                // Q# metadata
                ["qsharp.kind"]    = "namespace",
                ["qsharp.name"]    = name,
                ["qsharp.summary"] = docComment.Summary,
            };
            var document = $@"
# {title}

{docComment.Summary}

"
                           .MaybeWithSection("Description", docComment.Description)
                           .WithSectionForEach("Example", docComment.Examples)
                           .MaybeWithSection(
                "See Also",
                string.Join("\n", docComment.SeeAlso.Select(
                                seeAlso => AsSeeAlsoLink(seeAlso)
                                ))
                )
                           .WithYamlHeader(header);

            // Open a file to write the new doc to.
            await this.WriteAllTextAsync(
                $"{name}.md", document
                );
        }
Exemple #14
0
        async Task <ICommandResultBase> ResetEditDetails(Doc entity, DocComment reply, IUser user)
        {
            var result = new CommandResultBase();

            // We need to be authenticated to make changes
            if (user == null)
            {
                return(result.Success());
            }

            if (reply != null)
            {
                reply.ModifiedUserId = user.Id;
                reply.ModifiedDate   = DateTimeOffset.UtcNow;
                reply.EditedUserId   = 0;
                reply.EditedDate     = null;

                var updateResult = await _entityReplyStore.UpdateAsync(reply);

                if (updateResult != null)
                {
                    return(result.Success());
                }
            }
            else
            {
                entity.ModifiedUserId = user.Id;
                entity.ModifiedDate   = DateTimeOffset.UtcNow;
                entity.EditedUserId   = 0;
                entity.EditedDate     = null;

                var updateResult = await _entityStore.UpdateAsync(entity);

                if (updateResult != null)
                {
                    return(result.Success());
                }
            }

            return(result.Success());
        }
Exemple #15
0
        public async Task <IActionResult> Rollback(int id)
        {
            // Validate
            if (id <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(id));
            }

            // Get history point
            var history = await _entityHistoryStore.GetByIdAsync(id);

            // Ensure we found the history point
            if (history == null)
            {
                return(NotFound());
            }

            // Get entity for history point
            var entity = await _entityStore.GetByIdAsync(history.EntityId);

            // Ensure we found the entity
            if (entity == null)
            {
                return(NotFound());
            }

            // Get reply
            DocComment reply = null;

            if (history.EntityReplyId > 0)
            {
                reply = await _entityReplyStore.GetByIdAsync(history.EntityReplyId);

                // Ensure we found a reply if supplied
                if (reply == null)
                {
                    return(NotFound());
                }
            }

            // Get current user
            var user = await _contextFacade.GetAuthenticatedUserAsync();

            // We always need to be logged in to edit entities
            if (user == null)
            {
                return(Unauthorized());
            }

            // Ensure we have permission
            if (!await _authorizationService.AuthorizeAsync(HttpContext.User,
                                                            entity.CategoryId, reply != null
                    ? Permissions.RevertReplyHistory
                    : Permissions.RevertEntityHistory))
            {
                return(Unauthorized());
            }

            ICommandResultBase result;

            if (reply != null)
            {
                // Only update edited information if the message changes
                if (history.Message != reply.Message)
                {
                    reply.Message      = history.Message;
                    reply.EditedUserId = user?.Id ?? 0;
                    reply.EditedDate   = DateTimeOffset.UtcNow;
                }

                // Update reply to history point
                result = await _entityReplyManager.UpdateAsync(reply);
            }
            else
            {
                // Only update edited information if the message changes
                if (history.Message != entity.Message)
                {
                    entity.Message      = history.Message;
                    entity.EditedUserId = user?.Id ?? 0;
                    entity.EditedDate   = DateTimeOffset.UtcNow;
                }

                // Update entity to history point
                result = await _entityManager.UpdateAsync(entity);
            }

            // Add result
            if (result.Succeeded)
            {
                _alerter.Success(T["Version Rolled Back Successfully!"]);
            }
            else
            {
                foreach (var error in result.Errors)
                {
                    _alerter.Danger(T[error.Description]);
                }
            }

            // Redirect
            return(Redirect(_contextFacade.GetRouteUrl(new RouteValueDictionary()
            {
                ["area"] = "Plato.Docs",
                ["controller"] = "Home",
                ["action"] = "Reply",
                ["opts.id"] = entity.Id,
                ["opts.alias"] = entity.Alias,
                ["opts.replyId"] = reply?.Id ?? 0
            })));
        }
Exemple #16
0
        public async Task UpdateAsync(int categoryId)
        {
            // Get supplied category and all parent categories
            var parents = await _channelStore.GetParentsByIdAsync(categoryId);

            // Update details within current and all parents
            foreach (var parent in parents)
            {
                // Get all children for current category
                var children = await _channelStore.GetChildrenByIdAsync(parent.Id);

                // Get latest topic & total topic count for current channel
                var topics = await _topicStore.QueryAsync()
                             .Take(1, 1) // we only need the latest topic
                             .Select <EntityQueryParams>(q =>
                {
                    // Include entities from child channels?
                    if (children != null)
                    {
                        var channelIds = children
                                         .Select(c => c.Id)
                                         .Append(parent.Id)
                                         .ToArray();
                        q.CategoryId.IsIn(channelIds);
                    }
                    else
                    {
                        // Get topics for current channel
                        q.CategoryId.Equals(parent.Id);
                    }

                    q.HidePrivate.True();
                    q.HideHidden.True();
                    q.HideSpam.True();
                    q.HideDeleted.True();
                })
                             .OrderBy("LastReplyDate", OrderBy.Desc)
                             .ToList();

                // Get latest reply & total reply count for current channel
                var replies = await _replyStore.QueryAsync()
                              .Take(1, 1) // we only need the latest reply
                              .Select <EntityReplyQueryParams>(q =>
                {
                    // Include entities from child channels?
                    if (children != null)
                    {
                        var channelIds = children
                                         .Select(c => c.Id)
                                         .Append(parent.Id)
                                         .ToArray();
                        q.CategoryId.IsIn(channelIds);
                    }
                    else
                    {
                        // Get topics for current channel
                        q.CategoryId.Equals(parent.Id);
                    }

                    q.HideHidden.True();
                    q.HideSpam.True();
                    q.HideDeleted.True();
                })
                              .OrderBy("CreatedDate", OrderBy.Desc)
                              .ToList();

                var totalEntities = 0;
                Doc latestEntity  = null;
                if (topics?.Data != null)
                {
                    totalEntities = topics.Total;
                    latestEntity  = topics.Data[0];
                }

                var        totalReplies = 0;
                DocComment latestReply  = null;
                if (replies?.Data != null)
                {
                    totalReplies = replies.Total;
                    latestReply  = replies.Data[0];
                }

                // Update channel details with latest entity details
                var details = parent.GetOrCreate <CategoryDetails>();
                details.TotalEntities = totalEntities;
                details.TotalReplies  = totalReplies;

                if (latestEntity != null)
                {
                    details.LatestEntity = new LatestPost
                    {
                        Id          = latestEntity.Id,
                        Alias       = latestEntity.Alias,
                        CreatedBy   = latestEntity.CreatedBy,
                        CreatedDate = latestEntity.CreatedDate
                    };
                }
                else
                {
                    details.LatestEntity = null;
                }

                if (latestReply != null)
                {
                    details.LatestReply = new LatestPost
                    {
                        Id          = latestReply.Id,
                        CreatedBy   = latestReply.CreatedBy,
                        CreatedDate = latestReply.CreatedDate
                    };
                }
                else
                {
                    details.LatestReply = null;
                }

                parent.AddOrUpdate <CategoryDetails>(details);

                // Save the updated details
                await _channelManager.UpdateAsync(parent);
            }
        }
Exemple #17
0
 private void toolStripMenuItemInsertComment_Click(object sender, EventArgs e)
 {
     TreeNode tnParent = this.treeView.SelectedNode;
     DocSchema docSchema = (DocSchema)tnParent.Tag;
     DocComment docComment = new DocComment();
     InitDefinition(docComment);
     docComment.Name = null;
     docSchema.Comments.Add(docComment);
     this.treeView.SelectedNode = this.LoadNode(tnParent.Nodes[9], docComment, docComment.ToString(), false);
     toolStripMenuItemEditProperties_Click(this, e);
 }
        /// <summary>
        ///     Given a documentation comment describing a Q# function or operation
        ///     declaration, writes a Markdown file documenting that callable
        ///     declaration to <see cref="OutputPath" />.
        /// </summary>
        /// <param name="callable">The Q# callable being documented.</param>
        /// <param name="docComment">
        ///     The API documentation comment describing <paramref name="callable"/>.
        /// </param>
        /// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
        public async Task WriteOutput(QsCallable callable, DocComment docComment)
        {
            // Make a new Markdown document for the type declaration.
            var kind = callable.Kind.Tag switch
            {
                QsCallableKind.Tags.Function => "function",
                QsCallableKind.Tags.Operation => "operation",
                QsCallableKind.Tags.TypeConstructor => "type constructor",
                _ => "<unknown>",
            };
            var title  = $@"{callable.FullName.Name} {kind}";
            var header = new Dictionary <string, object>
            {
                // DocFX metadata
                ["uid"]   = callable.FullName.ToString(),
                ["title"] = title,

                // docs.ms metadata
                ["ms.date"]  = DateTime.Today.ToString(),
                ["ms.topic"] = "article",

                // Q# metadata
                ["qsharp.kind"]      = kind,
                ["qsharp.namespace"] = callable.FullName.Namespace,
                ["qsharp.name"]      = callable.FullName.Name,
                ["qsharp.summary"]   = docComment.Summary,
            };
            var document = $@"
# {title}

Namespace: [{callable.FullName.Namespace}](xref:{callable.FullName.Namespace})
{this.packageLink}

{docComment.Summary}

```{this.LanguageMode}
{
    callable.Kind.Tag switch
    {
        QsCallableKind.Tags.Function => "function ",
        QsCallableKind.Tags.Operation => "operation ",
        QsCallableKind.Tags.TypeConstructor => "newtype ",
        _ => ""
    }
}{callable.ToSyntax()}
```
"
                           .MaybeWithSection("Description", docComment.Description)
                           .MaybeWithSection(
                "Input",
                string.Join("\n", callable.ArgumentTuple.InputDeclarations().Select(
                                (item) =>
            {
                (var inputName, var resolvedType) = item;
                var documentation = docComment.Input.TryGetValue(inputName, out var inputComment)
                            ? inputComment
                            : string.Empty;
                return($"### {inputName} : {resolvedType.ToMarkdownLink()}\n\n{documentation}\n\n");
            }
                                ))
                )
                           .WithSection($"Output : {callable.Signature.ReturnType.ToMarkdownLink()}", docComment.Output)
                           .MaybeWithSection(
                "Type Parameters",
                string.Join("\n", callable.Signature.TypeParameters.Select(
                                typeParam =>
                                typeParam is QsLocalSymbol.ValidName name
                        ? $@"### '{name.Item}{"\n\n"}{(
                            docComment.TypeParameters.TryGetValue($"'{name.Item}", out var comment)
                            ? comment
                            : string.Empty
                          )}"
                        : string.Empty
                                ))
                )
                           .MaybeWithSection("Remarks", docComment.Remarks)
                           .MaybeWithSection("References", docComment.References)
                           .MaybeWithSection(
                "See Also",
                string.Join("\n", docComment.SeeAlso.Select(
                                seeAlso => AsSeeAlsoLink(seeAlso, callable.FullName.Namespace)
                                ))
                )
                           .WithYamlHeader(header);

            // Open a file to write the new doc to.
            await this.WriteAllTextAsync(
                $"{callable.FullName.Namespace}.{callable.FullName.Name}.md",
                document
                );
        }
        /// <summary>
        ///     Given a documentation comment describing a Q# user-defined type
        ///     declaration, writes a Markdown file documenting that UDT
        ///     declaration to <see cref="OutputPath" />.
        /// </summary>
        /// <param name="type">The Q# UDT being documented.</param>
        /// <param name="docComment">
        ///     The API documentation comment describing <paramref name="type"/>.
        /// </param>
        /// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
        public async Task WriteOutput(QsCustomType type, DocComment docComment)
        {
            var namedItemDeclarations = type.TypeItems.ToDictionaryOfDeclarations();

            // Make a new Markdown document for the type declaration.
            var title  = $"{type.FullName.Name} user defined type";
            var header = new Dictionary <string, object>
            {
                // DocFX metadata
                ["uid"]   = type.FullName.ToString(),
                ["title"] = title,

                // docs.ms metadata
                ["ms.date"]  = DateTime.Today.ToString(),
                ["ms.topic"] = "article",

                // Q# metadata
                ["qsharp.kind"]      = "udt",
                ["qsharp.namespace"] = type.FullName.Namespace,
                ["qsharp.name"]      = type.FullName.Name,
                ["qsharp.summary"]   = docComment.Summary,
            };
            var document = $@"
# {title}

Namespace: [{type.FullName.Namespace}](xref:{type.FullName.Namespace})
{this.packageLink}

{docComment.Summary}

```{this.LanguageMode}
{type.WithoutDocumentationAndComments().ToSyntax()}
```

"
                           .MaybeWithSection(
                "Named Items",
                string.Join("\n", type.TypeItems.TypeDeclarations().Select(
                                item =>
            {
                (var itemName, var resolvedType) = item;
                var documentation =
                    docComment.NamedItems.TryGetValue(itemName, out var comment)
                            ? comment
                            : string.Empty;
                return($"### {itemName} : {resolvedType.ToMarkdownLink()}\n\n{documentation}");
            }
                                ))
                )
                           .MaybeWithSection("Description", docComment.Description)
                           .MaybeWithSection("Remarks", docComment.Remarks)
                           .MaybeWithSection("References", docComment.References)
                           .MaybeWithSection(
                "See Also",
                string.Join("\n", docComment.SeeAlso.Select(
                                seeAlso => AsSeeAlsoLink(seeAlso, type.FullName.Namespace)
                                ))
                )
                           .WithYamlHeader(header);

            // Open a file to write the new doc to.
            await this.WriteAllTextAsync(
                $"{type.FullName.Namespace}.{type.FullName.Name}.md",
                document
                );
        }
Exemple #20
0
        /// <summary>
        /// Creates a documentation schema from a VEX schema
        /// </summary>
        /// <param name="schemata">The VEX schema to import</param>
        /// <param name="project">The documentation project where the imported schema is to be created</param>
        /// <returns>The imported documentation schema</returns>
        internal static DocSchema ImportVex(SCHEMATA schemata, DocProject docProject, bool updateDescriptions)
        {
            DocSchema docSchema = docProject.RegisterSchema(schemata.name);
            if (updateDescriptions && schemata.comment != null && schemata.comment.text != null)
            {
                docSchema.Documentation = schemata.comment.text.text;
            }
            docSchema.DiagramPagesHorz = schemata.settings.page.nhorizontalpages;
            docSchema.DiagramPagesVert = schemata.settings.page.nverticalpages;

            // remember current types for deletion if they no longer exist
            List<DocObject> existing = new List<DocObject>();
            foreach (DocType doctype in docSchema.Types)
            {
                existing.Add(doctype);
            }
            foreach (DocEntity docentity in docSchema.Entities)
            {
                existing.Add(docentity);
            }
            foreach (DocFunction docfunction in docSchema.Functions)
            {
                existing.Add(docfunction);
            }
            foreach (DocGlobalRule docrule in docSchema.GlobalRules)
            {
                existing.Add(docrule);
            }

            docSchema.PageTargets.Clear();
            docSchema.SchemaRefs.Clear();
            docSchema.Comments.Clear();

            // remember references for fixing up attributes afterwords
            Dictionary<object, DocDefinition> mapRefs = new Dictionary<object, DocDefinition>();
            Dictionary<ATTRIBUTE_DEF, DocAttribute> mapAtts = new Dictionary<ATTRIBUTE_DEF, DocAttribute>();
            //Dictionary<SELECT_DEF, DocSelectItem> mapSels = new Dictionary<SELECT_DEF, DocSelectItem>();
            Dictionary<SELECT_DEF, DocLine> mapSL = new Dictionary<SELECT_DEF, DocLine>();
            Dictionary<SUBTYPE_DEF, DocLine> mapSubs = new Dictionary<SUBTYPE_DEF, DocLine>();
            Dictionary<PAGE_REF, DocPageTarget> mapPage = new Dictionary<PAGE_REF, DocPageTarget>();

            // entities and types
            foreach (object obj in schemata.objects)
            {
                if (obj is ENTITIES)
                {
                    ENTITIES ent = (ENTITIES)obj; // filter out orphaned entities having upper flags set
                    if ((ent.flag & 0xFFFF0000) == 0 && (ent.interfaceto == null || ent.interfaceto.theschema == null))
                    {
                        // create if doesn't exist
                        string name = ent.name.text;

                        string super = null;
                        if (ent.supertypes.Count > 0 && ent.supertypes[0].the_supertype is ENTITIES)
                        {
                            ENTITIES superent = (ENTITIES)ent.supertypes[0].the_supertype;
                            super = superent.name.text;
                        }

                        DocEntity docEntity = docSchema.RegisterEntity(name);
                        if (existing.Contains(docEntity))
                        {
                            existing.Remove(docEntity);
                        }
                        mapRefs.Add(obj, docEntity);

                        // clear out existing if merging
                        docEntity.BaseDefinition = null;

                        foreach(DocSubtype docSub in docEntity.Subtypes)
                        {
                            docSub.Delete();
                        }
                        docEntity.Subtypes.Clear();

                        foreach(DocUniqueRule docUniq in docEntity.UniqueRules)
                        {
                            docUniq.Delete();
                        }
                        docEntity.UniqueRules.Clear();

                        foreach(DocLine docLine in docEntity.Tree)
                        {
                            docLine.Delete();
                        }
                        docEntity.Tree.Clear();

                        if (updateDescriptions && ent.comment != null && ent.comment.text != null)
                        {
                            docEntity.Documentation = ent.comment.text.text;
                        }
                        if (ent.supertypes.Count > 0 && ent.supertypes[0].the_supertype is ENTITIES)
                        {
                            docEntity.BaseDefinition = ((ENTITIES)ent.supertypes[0].the_supertype).name.text;
                        }

                        docEntity.EntityFlags = ent.flag;
                        if (ent.subtypes != null)
                        {
                            foreach (SUBTYPE_DEF sd in ent.subtypes)
                            {
                                // new (3.8): intermediate subtypes for diagrams
                                DocLine docLine = new DocLine();
                                ImportVexLine(sd.layout, null, docLine.DiagramLine, null);
                                docEntity.Tree.Add(docLine);

                                OBJECT od = (OBJECT)sd.the_subtype;

                                // tunnel through page ref
                                if (od is PAGE_REF_TO)
                                {
                                    od = ((PAGE_REF_TO)od).pageref;
                                }

                                if (od is TREE)
                                {
                                    TREE tree = (TREE)od;
                                    foreach (OBJECT o in tree.list)
                                    {
                                        OBJECT os = o;
                                        OBJECT_LINE_LAYOUT linelayout = null;

                                        if (o is SUBTYPE_DEF)
                                        {
                                            SUBTYPE_DEF osd = (SUBTYPE_DEF)o;
                                            linelayout = osd.layout;

                                            os = ((SUBTYPE_DEF)o).the_subtype;
                                        }

                                        if (os is PAGE_REF_TO)
                                        {
                                            os = ((PAGE_REF_TO)os).pageref;
                                        }

                                        if (os is ENTITIES)
                                        {
                                            DocSubtype docSub = new DocSubtype();
                                            docSub.DefinedType = ((ENTITIES)os).name.text;
                                            docEntity.Subtypes.Add(docSub);

                                            DocLine docSubline = new DocLine();
                                            docLine.Tree.Add(docSubline);

                                            if (o is SUBTYPE_DEF)
                                            {
                                                mapSubs.Add((SUBTYPE_DEF)o, docSubline);
                                            }

                                            ImportVexLine(linelayout, null, docSubline.DiagramLine, null);
                                        }
                                        else
                                        {
                                            Debug.Assert(false);
                                        }
                                    }
                                }
                                else if (od is ENTITIES)
                                {
                                    DocSubtype docInt = new DocSubtype();
                                    docEntity.Subtypes.Add(docInt);

                                    docInt.DefinedType = ((ENTITIES)od).name.text;
                                }
                                else
                                {
                                    Debug.Assert(false);
                                }
                            }
                        }

                        // determine EXPRESS-G page based on placement (required for generating hyperlinks)
                        if (ent.layout != null)
                        {
                            ImportVexRectangle(docEntity, ent.layout.rectangle, schemata);
                        }

                        if (ent.attributes != null)
                        {
                            List<DocAttribute> existingattr = new List<DocAttribute>();
                            foreach (DocAttribute docAttr in docEntity.Attributes)
                            {
                                existingattr.Add(docAttr);
                            }

                            // attributes are replaced, not merged (template don't apply here)
                            foreach (ATTRIBUTE_DEF attr in ent.attributes)
                            {
                                if (attr.name != null)
                                {
                                    DocAttribute docAttr = docEntity.RegisterAttribute(attr.name.text);
                                    mapAtts.Add(attr, docAttr);

                                    if (existingattr.Contains(docAttr))
                                    {
                                        existingattr.Remove(docAttr);
                                    }

                                    if (updateDescriptions && attr.comment != null && attr.comment.text != null)
                                    {
                                        docAttr.Documentation = attr.comment.text.text;
                                    }

                                    if (docAttr.DiagramLabel != null)
                                    {
                                        docAttr.DiagramLabel.Delete();
                                        docAttr.DiagramLabel = null;
                                    }

                                    foreach(DocPoint docPoint in docAttr.DiagramLine)
                                    {
                                        docPoint.Delete();
                                    }
                                    docAttr.DiagramLine.Clear();

                                    if (attr.layout != null)
                                    {
                                        if (attr.layout.pline != null)
                                        {
                                            // intermediate lines
                                            if (attr.layout.pline.rpoint != null)
                                            {
                                                docAttr.DiagramLabel = new DocRectangle();
                                                ImportVexLine(attr.layout, attr.name.layout, docAttr.DiagramLine, docAttr.DiagramLabel);
                                            }
                                        }
                                    }

                                    OBJECT def = attr.the_attribute;
                                    if (attr.the_attribute is PAGE_REF_TO)
                                    {
                                        PAGE_REF_TO pr = (PAGE_REF_TO)attr.the_attribute;
                                        def = pr.pageref;
                                    }

                                    if (def is DEFINED_TYPE)
                                    {
                                        DEFINED_TYPE dt = (DEFINED_TYPE)def;
                                        docAttr.DefinedType = dt.name.text;
                                    }
                                    else if (def is ENTITIES)
                                    {
                                        ENTITIES en = (ENTITIES)def;
                                        docAttr.DefinedType = en.name.text;
                                    }
                                    else if (def is ENUMERATIONS)
                                    {
                                        ENUMERATIONS en = (ENUMERATIONS)def;
                                        docAttr.DefinedType = en.name.text;
                                    }
                                    else if (def is SELECTS)
                                    {
                                        SELECTS en = (SELECTS)def;
                                        docAttr.DefinedType = en.name.text;
                                    }
                                    else if (def is PRIMITIVE_TYPE)
                                    {
                                        PRIMITIVE_TYPE en = (PRIMITIVE_TYPE)def;

                                        string length = "";
                                        if (en.constraints > 0)
                                        {
                                            length = " (" + en.constraints.ToString() + ")";
                                        }
                                        else if (en.constraints < 0)
                                        {
                                            int len = -en.constraints;
                                            length = " (" + len.ToString() + ") FIXED";
                                        }

                                        docAttr.DefinedType = en.name.text + length;
                                    }
                                    else if (def is SCHEMA_REF)
                                    {
                                        SCHEMA_REF en = (SCHEMA_REF)def;
                                        docAttr.DefinedType = en.name.text;
                                    }
                                    else
                                    {
                                        Debug.Assert(false);
                                    }

                                    docAttr.AttributeFlags = attr.attributeflag;

                                    AGGREGATES vexAggregates = attr.aggregates;
                                    DocAttribute docAggregate = docAttr;
                                    while (vexAggregates != null)
                                    {
                                        // traverse nested aggregation (e.g. IfcStructuralLoadConfiguration)
                                        docAggregate.AggregationType = vexAggregates.aggrtype + 1;
                                        docAggregate.AggregationLower = vexAggregates.lower;
                                        docAggregate.AggregationUpper = vexAggregates.upper;
                                        docAggregate.AggregationFlag = vexAggregates.flag;

                                        vexAggregates = vexAggregates.next;
                                        if (vexAggregates != null)
                                        {
                                            // inner array (e.g. IfcStructuralLoadConfiguration)
                                            docAggregate.AggregationAttribute = new DocAttribute();
                                            docAggregate = docAggregate.AggregationAttribute;
                                        }
                                    }

                                    docAttr.Derived = attr.is_derived;

                                    if (attr.user_redeclaration != null)
                                    {
                                        docAttr.Inverse = attr.user_redeclaration;
                                    }
                                    else if (attr.is_inverse is ATTRIBUTE_DEF)
                                    {
                                        ATTRIBUTE_DEF adef = (ATTRIBUTE_DEF)attr.is_inverse;
                                        docAttr.Inverse = adef.name.text;
                                    }
                                    else if (attr.is_inverse != null)
                                    {
                                        Debug.Assert(false);
                                    }
                                }
                            }

                            foreach(DocAttribute docAttr in existingattr)
                            {
                                docEntity.Attributes.Remove(docAttr);
                                docAttr.Delete();
                            }
                        }

                        // unique rules
                        if (ent.uniquenes != null)
                        {
                            // rules are replaced, not merged (template don't apply here)
                            //docEntity.UniqueRules = new List<DocUniqueRule>();
                            foreach (UNIQUE_RULE rule in ent.uniquenes)
                            {
                                DocUniqueRule docRule = new DocUniqueRule();
                                docEntity.UniqueRules.Add(docRule);
                                docRule.Name = rule.name;

                                docRule.Items = new List<DocUniqueRuleItem>();
                                foreach (ATTRIBUTE_DEF ruleitem in rule.for_attribute)
                                {
                                    DocUniqueRuleItem item = new DocUniqueRuleItem();
                                    item.Name = ruleitem.name.text;
                                    docRule.Items.Add(item);
                                }
                            }
                        }

                        // where rules
                        if (ent.wheres != null)
                        {
                            List<DocWhereRule> existingattr = new List<DocWhereRule>();
                            foreach (DocWhereRule docWhere in docEntity.WhereRules)
                            {
                                existingattr.Add(docWhere);
                            }

                            foreach (WHERE_RULE where in ent.wheres)
                            {
                                DocWhereRule docWhere = docEntity.RegisterWhereRule(where.name);
                                docWhere.Expression = where.rule_context;

                                if(existingattr.Contains(docWhere))
                                {
                                    existingattr.Remove(docWhere);
                                }

                                if (updateDescriptions && where.comment != null && where.comment.text != null)
                                {
                                    docWhere.Documentation = where.comment.text.text;
                                }
                            }

                            foreach(DocWhereRule exist in existingattr)
                            {
                                exist.Delete();
                                docEntity.WhereRules.Remove(exist);
                            }
                        }
                    }
                }
                else if (obj is ENUMERATIONS)
                {
                    ENUMERATIONS ent = (ENUMERATIONS)obj;
                    if (ent.interfaceto == null || ent.interfaceto.theschema == null)
                    {
                        if (schemata.name.Equals("IfcConstructionMgmtDomain", StringComparison.OrdinalIgnoreCase) && ent.name.text.Equals("IfcNullStyle", StringComparison.OrdinalIgnoreCase))
                        {
                            // hack to workaround vex bug
                            Debug.Assert(true);
                        }
                        else
                        {

                            DocEnumeration docEnumeration = docSchema.RegisterType<DocEnumeration>(ent.name.text);
                            if (existing.Contains(docEnumeration))
                            {
                                existing.Remove(docEnumeration);
                            }
                            mapRefs.Add(obj, docEnumeration);

                            if (updateDescriptions && ent.comment != null && ent.comment.text != null)
                            {
                                docEnumeration.Documentation = ent.comment.text.text;
                            }

                            // determine EXPRESS-G page based on placement (required for generating hyperlinks)
                            if (ent.typelayout != null && schemata.settings != null && schemata.settings.page != null)
                            {
                                ImportVexRectangle(docEnumeration, ent.typelayout.rectangle, schemata);
                            }

                            // enumeration values are replaced, not merged (template don't apply here)
                            docEnumeration.Constants.Clear();
                            foreach (string s in ent.enums)
                            {
                                DocConstant docConstant = new DocConstant();
                                docEnumeration.Constants.Add(docConstant);
                                docConstant.Name = s;
                            }
                        }
                    }
                }
                else if (obj is DEFINED_TYPE)
                {
                    DEFINED_TYPE ent = (DEFINED_TYPE)obj;

                    if (ent.interfaceto == null || ent.interfaceto.theschema == null)
                    {
                        DocDefined docDefined = docSchema.RegisterType<DocDefined>(ent.name.text);
                        if (existing.Contains(docDefined))
                        {
                            existing.Remove(docDefined);
                        }

                        mapRefs.Add(obj, docDefined);

                        if (updateDescriptions && ent.comment != null && ent.comment.text != null)
                        {
                            docDefined.Documentation = ent.comment.text.text;
                        }

                        if (ent.layout != null)
                        {
                            ImportVexRectangle(docDefined, ent.layout.rectangle, schemata);
                        }

                        if(ent.defined.object_line_layout != null)
                        {
                            foreach(DocPoint docPoint in docDefined.DiagramLine)
                            {
                                docPoint.Delete();
                            }
                            docDefined.DiagramLine.Clear();
                            ImportVexLine(ent.defined.object_line_layout, null, docDefined.DiagramLine, null);
                        }

                        OBJECT os = (OBJECT)ent.defined.defined;
                        if (os is PAGE_REF_TO)
                        {
                            os = ((PAGE_REF_TO)os).pageref;
                        }

                        if (os is PRIMITIVE_TYPE)
                        {
                            PRIMITIVE_TYPE pt = (PRIMITIVE_TYPE)os;
                            docDefined.DefinedType = pt.name.text;

                            if (pt.constraints != 0)
                            {
                                docDefined.Length = pt.constraints;
                            }
                        }
                        else if (os is DEFINED_TYPE)
                        {
                            DEFINED_TYPE dt = (DEFINED_TYPE)os;
                            docDefined.DefinedType = dt.name.text;
                        }
                        else if (os is ENTITIES)
                        {
                            ENTITIES et = (ENTITIES)os;
                            docDefined.DefinedType = et.name.text;
                        }
                        else
                        {
                            Debug.Assert(false);
                        }

                        // aggregation
                        AGGREGATES vexAggregates = ent.defined.aggregates;
                        if (vexAggregates != null)
                        {
                            DocAttribute docAggregate = new DocAttribute();
                            docDefined.Aggregation = docAggregate;

                            docAggregate.AggregationType = vexAggregates.aggrtype + 1;
                            docAggregate.AggregationLower = vexAggregates.lower;
                            docAggregate.AggregationUpper = vexAggregates.upper;
                            docAggregate.AggregationFlag = vexAggregates.flag;
                        }

                        // where rules
                        if (ent.whererules != null)
                        {
                            // rules are replaced, not merged (template don't apply here)
                            foreach(DocWhereRule docWhere in docDefined.WhereRules)
                            {
                                docWhere.Delete();
                            }
                            docDefined.WhereRules.Clear();
                            foreach (WHERE_RULE where in ent.whererules)
                            {
                                DocWhereRule docWhere = new DocWhereRule();
                                docDefined.WhereRules.Add(docWhere);
                                docWhere.Name = where.name;
                                docWhere.Expression = where.rule_context;

                                if (where.comment != null && where.comment.text != null)
                                {
                                    docWhere.Documentation = where.comment.text.text;
                                }
                            }
                        }

                    }
                }
                else if (obj is SELECTS)
                {
                    SELECTS ent = (SELECTS)obj;
                    if (ent.interfaceto == null || ent.interfaceto.theschema == null)
                    {
                        DocSelect docSelect = docSchema.RegisterType<DocSelect>(ent.name.text);
                        if (existing.Contains(docSelect))
                        {
                            existing.Remove(docSelect);
                        }
                        mapRefs.Add(obj, docSelect);

                        if (updateDescriptions && ent.comment != null && ent.comment.text != null)
                        {
                            docSelect.Documentation = ent.comment.text.text;
                        }

                        // determine EXPRESS-G page based on placement (required for generating hyperlinks)
                        if (ent.typelayout != null)
                        {
                            ImportVexRectangle(docSelect, ent.typelayout.rectangle, schemata);
                        }

                        docSelect.Selects.Clear();
                        docSelect.Tree.Clear();
                        foreach (SELECT_DEF sdef in ent.selects)
                        {
                            DocLine docLine = new DocLine();
                            docSelect.Tree.Add(docLine);
                            ImportVexLine(sdef.layout, null, docLine.DiagramLine, null);

                            mapSL.Add(sdef, docLine);

                            if (sdef.def is TREE)
                            {
                                TREE tree = (TREE)sdef.def;

                                foreach (OBJECT o in tree.list)
                                {
                                    DocSelectItem dsi = new DocSelectItem();
                                    docSelect.Selects.Add(dsi);

                                    OBJECT os = o;
                                    if (o is SELECT_DEF)
                                    {
                                        SELECT_DEF selectdef = (SELECT_DEF)o;

                                        DocLine docLineSub = new DocLine();
                                        docLine.Tree.Add(docLineSub);
                                        ImportVexLine(selectdef.layout, null, docLineSub.DiagramLine, null);

                                        mapSL.Add(selectdef, docLineSub);

                                        os = ((SELECT_DEF)o).def;
                                    }
                                    else
                                    {
                                        Debug.Assert(false);
                                    }

                                    if (os is PAGE_REF_TO)
                                    {
                                        PAGE_REF_TO pr = (PAGE_REF_TO)os;
                                        os = pr.pageref;
                                    }

                                    if (os is DEFINITION)
                                    {
                                        dsi.Name = ((DEFINITION)os).name.text;
                                    }
                                }
                            }
                            else
                            {
                                OBJECT os = (OBJECT)sdef.def;

                                if (os is PAGE_REF_TO)
                                {
                                    PAGE_REF_TO pr = (PAGE_REF_TO)os;
                                    os = pr.pageref;
                                }

                                DocSelectItem dsi = new DocSelectItem();
                                docSelect.Selects.Add(dsi);
                                if (os is DEFINITION)
                                {
                                    dsi.Name = ((DEFINITION)os).name.text;
                                }
                            }
                        }
                    }
                }
                else if (obj is GLOBAL_RULE)
                {
                    GLOBAL_RULE func = (GLOBAL_RULE)obj;

                    DocGlobalRule docFunction = docSchema.RegisterRule(func.name);
                    if (existing.Contains(docFunction))
                    {
                        existing.Remove(docFunction);
                    }

                    // clear out existing if merging
                    docFunction.WhereRules.Clear();

                    if (updateDescriptions && func.comment != null && func.comment.text != null)
                    {
                        docFunction.Documentation = func.comment.text.text;
                    }
                    docFunction.Expression = func.rule_context;

                    foreach (WHERE_RULE wr in func.where_rule)
                    {
                        DocWhereRule docW = new DocWhereRule();
                        docW.Name = wr.name;
                        docW.Expression = wr.rule_context;
                        if (wr.comment != null)
                        {
                            docW.Documentation = wr.comment.text.text;
                        }
                        docFunction.WhereRules.Add(docW);
                    }

                    if (func.for_entities.Count == 1)
                    {
                        docFunction.ApplicableEntity = func.for_entities[0].ToString();
                    }
                }
                else if (obj is USER_FUNCTION)
                {
                    USER_FUNCTION func = (USER_FUNCTION)obj;

                    DocFunction docFunction = docSchema.RegisterFunction(func.name);
                    if (existing.Contains(docFunction))
                    {
                        existing.Remove(docFunction);
                    }

                    if (updateDescriptions && func.comment != null && func.comment.text != null)
                    {
                        docFunction.Documentation = func.comment.text.text;
                    }
                    docFunction.Expression = func.rule_context;

                    // NOTE: While the VEX schema can represent parameters and return values, Visual Express does not implement it!
                    // Rather, parameter info is also included in the 'rule_context'
                    if (func.return_value != null)
                    {
                        docFunction.ReturnValue = func.return_value.ToString();
                    }
                    else
                    {
                        docFunction.ReturnValue = null;
                    }
                    docFunction.Parameters.Clear();
                    if (func.parameter_list != null)
                    {
                        foreach (PARAMETER par in func.parameter_list)
                        {
                            DocParameter docParameter = new DocParameter();
                            docParameter.Name = par.name;
                            docParameter.DefinedType = par.parameter_type.ToString();
                            docFunction.Parameters.Add(docParameter);
                        }
                    }
                }
                else if (obj is PRIMITIVE_TYPE)
                {
                    PRIMITIVE_TYPE prim = (PRIMITIVE_TYPE)obj;

                    DocPrimitive docPrimitive = new DocPrimitive();
                    docPrimitive.Name = prim.name.text;
                    if (prim.layout != null)
                    {
                        ImportVexRectangle(docPrimitive, prim.layout.rectangle, schemata);
                    }

                    docSchema.Primitives.Add(docPrimitive);
                    mapRefs.Add(obj, docPrimitive);
                }
                else if (obj is COMMENT)
                {
                    COMMENT comment = (COMMENT)obj;

                    // only deal with comments that are part of EXPRESS-G layout -- ignore those referenced by definitions and old cruft left behind due to older versions of VisualE that were buggy
                    if (comment.layout != null)
                    {
                        DocComment docComment = new DocComment();
                        docComment.Documentation = comment.text.text;
                        ImportVexRectangle(docComment, comment.layout.rectangle, schemata);

                        docSchema.Comments.Add(docComment);
                    }
                }
                else if (obj is INTERFACE_SCHEMA)
                {
                    INTERFACE_SCHEMA iface = (INTERFACE_SCHEMA)obj;

                    DocSchemaRef docSchemaRef = new DocSchemaRef();
                    docSchema.SchemaRefs.Add(docSchemaRef);

                    docSchemaRef.Name = iface.schema_name;

                    foreach (object o in iface.item)
                    {
                        if (o is DEFINITION)
                        {
                            DocDefinitionRef docDefRef = new DocDefinitionRef();
                            docSchemaRef.Definitions.Add(docDefRef);
                            mapRefs.Add(o, docDefRef);

                            docDefRef.Name = ((DEFINITION)o).name.text;

                            if (o is DEFINED_TYPE)
                            {
                                DEFINED_TYPE dt = (DEFINED_TYPE)o;
                                if (dt.layout != null)
                                {
                                    ImportVexRectangle(docDefRef, dt.layout.rectangle, schemata);
                                }
                            }
                            else if (o is ENTITIES)
                            {
                                ENTITIES ents = (ENTITIES)o;
                                if (ents.layout != null) // null for IfcPolyline reference in IfcGeometricModelResource
                                {
                                    ImportVexRectangle(docDefRef, ents.layout.rectangle, schemata);
                                }

                                if (ents.subtypes != null)
                                {
                                    foreach (SUBTYPE_DEF subdef in ents.subtypes)
                                    {
                                        OBJECT_LINE_LAYOUT linelayout = subdef.layout;

                                        DocLine docSub = new DocLine();
                                        ImportVexLine(subdef.layout, null, docSub.DiagramLine, null);
                                        docDefRef.Tree.Add(docSub);

                                        if(subdef.the_subtype is TREE)
                                        {
                                            TREE tree = (TREE)subdef.the_subtype;
                                            foreach(object oo in tree.list)
                                            {
                                                if(oo is SUBTYPE_DEF)
                                                {
                                                    SUBTYPE_DEF subsubdef = (SUBTYPE_DEF)oo;
                                                    DocLine docSubSub = new DocLine();
                                                    docSub.Tree.Add(docSubSub);

                                                    ImportVexLine(subsubdef.layout, null, docSubSub.DiagramLine, null);

                                                    mapSubs.Add(subsubdef, docSubSub);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            else if (o is ENUMERATIONS)
                            {
                                ENUMERATIONS enums = (ENUMERATIONS)o;
                                if (enums.typelayout != null)
                                {
                                    ImportVexRectangle(docDefRef, enums.typelayout.rectangle, schemata);
                                }
                            }
                            else if (o is SELECTS)
                            {
                                SELECTS sels = (SELECTS)o;
                                if (sels.typelayout != null)
                                {
                                    ImportVexRectangle(docDefRef, sels.typelayout.rectangle, schemata);
                                }
                            }
                            else if(o is SCHEMA_REF)
                            {
                                SCHEMA_REF sref = (SCHEMA_REF)o;
                                if(sref.layout != null)
                                {
                                    ImportVexRectangle(docDefRef, sref.layout.rectangle, schemata);
                                }
                            }
                        }
                        else if (o is USER_FUNCTION)
                        {
                            DocDefinitionRef docDefRef = new DocDefinitionRef();
                            docSchemaRef.Definitions.Add(docDefRef);

                            USER_FUNCTION uf = (USER_FUNCTION)o;
                            docDefRef.Name = uf.name;
                        }
                    }
                }
                else if (obj is PAGE_REF)
                {
                    PAGE_REF pageref = (PAGE_REF)obj;

                    DocPageTarget docPageTarget = new DocPageTarget();
                    docSchema.PageTargets.Add(docPageTarget);
                    docPageTarget.Name = pageref.text.text;
                    docPageTarget.DiagramNumber = pageref.pagenr;
                    ImportVexLine(pageref.pageline.layout, null, docPageTarget.DiagramLine, null);
                    ImportVexRectangle(docPageTarget, pageref.layout.rectangle, schemata);

                    foreach (PAGE_REF_TO pagerefto in pageref.pagerefto)
                    {
                        DocPageSource docPageSource = new DocPageSource();
                        docPageTarget.Sources.Add(docPageSource);

                        docPageSource.DiagramNumber = pagerefto.pagenr;
                        docPageSource.Name = pagerefto.text.text;
                        ImportVexRectangle(docPageSource, pagerefto.layout.rectangle, schemata);

                        mapRefs.Add(pagerefto, docPageSource);
                    }

                    mapPage.Add(pageref, docPageTarget);
                }
            }

            foreach (DocObject docobj in existing)
            {
                if (docobj is DocEntity)
                {
                    docSchema.Entities.Remove((DocEntity)docobj);
                }
                else if (docobj is DocType)
                {
                    docSchema.Types.Remove((DocType)docobj);
                }
                else if (docobj is DocFunction)
                {
                    docSchema.Functions.Remove((DocFunction)docobj);
                }
                else if (docobj is DocGlobalRule)
                {
                    docSchema.GlobalRules.Remove((DocGlobalRule)docobj);
                }

                docobj.Delete();
            }

            // now fix up attributes
            foreach (ATTRIBUTE_DEF docAtt in mapAtts.Keys)
            {
                DocAttribute docAttr = mapAtts[docAtt];
                docAttr.Definition = mapRefs[docAtt.the_attribute];
            }

            foreach (PAGE_REF page in mapPage.Keys)
            {
                DocPageTarget docPage = mapPage[page];
                docPage.Definition = mapRefs[page.pageline.pageref];
            }

            foreach (SELECT_DEF sd in mapSL.Keys)
            {
                DocLine docLine = mapSL[sd];
                if (mapRefs.ContainsKey(sd.def))
                {
                    docLine.Definition = mapRefs[sd.def];
                }
            }

            foreach (SUBTYPE_DEF sd in mapSubs.Keys)
            {
                DocLine docLine = mapSubs[sd];
                if (mapRefs.ContainsKey(sd.the_subtype))
                {
                    docLine.Definition = mapRefs[sd.the_subtype];
                }
            }

            foreach(object o in mapRefs.Keys)
            {
                if (o is DEFINED_TYPE)
                {
                    DEFINED_TYPE def = (DEFINED_TYPE)o;
                    if (def.interfaceto == null || def.interfaceto.theschema == null)
                    {
                        // declared within
                        DocDefined docDef = (DocDefined)mapRefs[o];
                        docDef.Definition = mapRefs[def.defined.defined];
                    }
                }
            }

            return docSchema;
        }
Exemple #21
0
        // --------------------

        async Task <ICommandResultBase> ApplyLatestHistoryPoint(Doc entity, DocComment reply)
        {
            // Get current user
            var user = await _contextFacade.GetAuthenticatedUserAsync();

            // We need to be authenticated to make changes
            if (user == null)
            {
                return(await ResetEditDetails(entity, reply, user));
            }

            // Get newest / most recent history entry
            var histories = await _entityHistoryStore.QueryAsync()
                            .Take(1, false)
                            .Select <EntityHistoryQueryParams>(q =>
            {
                q.EntityId.Equals(entity.Id);
                q.EntityReplyId.Equals(reply?.Id ?? 0);
            })
                            .OrderBy("Id", OrderBy.Desc)
                            .ToList();

            // No history point, return success
            if (histories == null)
            {
                return(await ResetEditDetails(entity, reply, user));
            }

            // No history point, return success
            if (histories.Data == null)
            {
                return(await ResetEditDetails(entity, reply, user));
            }

            // No history point, return success
            if (histories.Data.Count == 0)
            {
                return(await ResetEditDetails(entity, reply, user));
            }

            var history = histories.Data[0];

            // No history available reset edit details
            if (history == null)
            {
                return(await ResetEditDetails(entity, reply, user));
            }

            // Update edit details based on latest history point

            var result = new CommandResultBase();

            if (reply != null)
            {
                reply.ModifiedUserId = user.Id;
                reply.ModifiedDate   = DateTimeOffset.UtcNow;
                reply.EditedUserId   = history.CreatedUserId;
                reply.EditedDate     = history.CreatedDate;

                // Update reply to history point
                var updateResult = await _entityReplyStore.UpdateAsync(reply);

                if (updateResult != null)
                {
                    return(result.Success());
                }
            }
            else
            {
                entity.ModifiedUserId = user.Id;
                entity.ModifiedDate   = DateTimeOffset.UtcNow;
                entity.EditedUserId   = history.CreatedUserId;
                entity.EditedDate     = history.CreatedDate;

                // Update entity to history point
                var updateResult = await _entityStore.UpdateAsync(entity);

                if (updateResult != null)
                {
                    return(result.Success());
                }
            }

            return(result.Success());
        }
Exemple #22
0
        public async Task <IActionResult> Delete(int id)
        {
            // Validate
            if (id <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(id));
            }

            // Get history point
            var history = await _entityHistoryStore.GetByIdAsync(id);

            // Ensure we found the entity
            if (history == null)
            {
                return(NotFound());
            }

            // Get entity
            var entity = await _entityStore.GetByIdAsync(history.EntityId);

            // Ensure we found the entity
            if (entity == null)
            {
                return(NotFound());
            }

            // Get reply
            DocComment reply = null;

            if (history.EntityReplyId > 0)
            {
                reply = await _entityReplyStore.GetByIdAsync(history.EntityReplyId);

                // Ensure we found a reply if supplied
                if (reply == null)
                {
                    return(NotFound());
                }
            }

            // Ensure we have permission
            if (!await _authorizationService.AuthorizeAsync(HttpContext.User,
                                                            entity.CategoryId, reply != null
                    ? Permissions.DeleteReplyHistory
                    : Permissions.DeleteEntityHistory))
            {
                return(Unauthorized());
            }

            // Delete history point
            var result = await _entityHistoryManager.DeleteAsync(history);

            // Add result
            if (result.Succeeded)
            {
                // Update edit details for entity or reply based on latest history point
                var entityResult = await ApplyLatestHistoryPoint(entity, reply);

                if (entityResult.Succeeded)
                {
                    _alerter.Success(T["Version Deleted Successfully!"]);
                }
                else
                {
                    foreach (var error in entityResult.Errors)
                    {
                        _alerter.Danger(T[error.Description]);
                    }
                }
            }
            else
            {
                foreach (var error in result.Errors)
                {
                    _alerter.Danger(T[error.Description]);
                }
            }

            // Redirect
            return(Redirect(_contextFacade.GetRouteUrl(new RouteValueDictionary()
            {
                ["area"] = "Plato.Docs",
                ["controller"] = "Home",
                ["action"] = "Reply",
                ["opts.id"] = entity.Id,
                ["opts.alias"] = entity.Alias,
                ["opts.replyId"] = reply?.Id ?? 0
            })));
        }