Exemple #1
0
        private void AddAdditionalReferenceSymbols(ISymbol symbol, ReferenceSpan symbolSpan, SyntaxToken token)
        {
            //var bindableParent = GetBindableParent(token);

            if (symbol.Kind == SymbolKind.Method)
            {
                // Case: Constructor
                IMethodSymbol methodSymbol = symbol as IMethodSymbol;
                if (methodSymbol != null)
                {
                    if (methodSymbol.MethodKind == MethodKind.Constructor)
                    {
                        // Add special reference kind for instantiation
                        references.Add(symbolSpan.CreateReference(GetReferenceSymbol(methodSymbol.ContainingType, ReferenceKind.Instantiation)));
                    }
                }
            }
            else if (symbol.Kind == SymbolKind.Property)
            {
            }
            else if (symbol.Kind == SymbolKind.Field)
            {
            }
            else if (symbol.Kind == SymbolKind.NamedType)
            {
                // Case: Derived class

                // Case: Partial class
            }
        }
Exemple #2
0
        private void GetBestReference(ref int referenceIndex, ref ReferenceSpan currentReference, IReadOnlyList <ReferenceSpan> referenceSpans)
        {
            for (int i = referenceIndex; i < referenceSpans.Count; i++)
            {
                var reference = referenceSpans[i];
                if (reference.Start != currentReference.Start)
                {
                    break;
                }

                if (currentReference.Reference.IsImplicitlyDeclared || reference.Reference.ReferenceKind == nameof(ReferenceKind.Definition))
                {
                    currentReference = reference;
                    referenceIndex   = i;
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Gets the contents of the source file with <span> tags added around
        /// all the spans specified for this BoundSourceFile that have a
        /// class of the Classification for the Symbol
        /// </summary>
        /// <returns></returns>
        public async Task <EditorModel> RenderAsync()
        {
            var filePath = _sourceFile.SourceFile?.Info?.Path;
            var model    = new EditorModel()
            {
                ProjectId        = projectId,
                FilePath         = filePath,
                WebLink          = _sourceFile.SourceFile?.Info?.WebAddress,
                RepoRelativePath = _sourceFile.SourceFile?.Info?.RepoRelativePath
            };

            string sourceText = await _sourceFile.SourceFile.GetContentsAsync();

            int lineCount = GetLineCount(sourceText);
            var url       = $"/?rightProject={HttpUtility.UrlEncode(projectId)}&file={HttpUtility.UrlEncode(filePath)}";

            model.LineNumberText = GenerateLineNumberText(lineCount, url);
            var ret       = new StringBuilder();
            int textIndex = 0;

            Span prevSpan = null;

            using (StringWriter sw = new StringWriter(ret))
            {
                int           referenceIndex = -1;
                ReferenceSpan referenceSpan  = null;

                foreach (ClassificationSpan span in _sourceFile.ClassificationSpans.OrderBy(s => s.Start))
                {
                    if (span.Start > sourceText.Length)
                    { //Not sure how this happened but a span is off the end of our text
                        Debug.WriteLine(
                            $"Span had Start of {span.Start}, which is greater than text length for file '{_sourceFile.SourceFile.Info.Path}'", "BoundSourceFileMarkup");
                        break;
                    }
                    if (prevSpan != null && span.Start == prevSpan.Start)
                    {
                        //  Overlapping spans?
                        continue;
                    }

                    if (span.Start > textIndex)
                    { //Span is ahead of our current index, just write the normal text between the two to the buffer
                        ret.Append(HttpUtility.HtmlEncode(sourceText.Substring(textIndex, span.Start - textIndex)));
                        textIndex = span.Start;
                    }

                    string spanText = sourceText.Substring(span.Start, span.Length);
                    GenerateSpan(sw, span, spanText, ref referenceIndex, ref referenceSpan, _sourceFile.References);

                    textIndex += span.Length;
                    prevSpan   = span;
                }

                // Append any leftover text
                ret.Append(HttpUtility.HtmlEncode(sourceText.Substring(textIndex)));

                model.Text = ret.ToString();
                return(model);
            }
        }
Exemple #4
0
        private void GenerateSpan(TextWriter tw, ClassificationSpan span, string spanText, ref int referenceIndex, ref ReferenceSpan currentReference, IReadOnlyList <ReferenceSpan> referenceSpans)
        {
            while ((currentReference == null || currentReference.Start < span.Start) && referenceIndex < referenceSpans.Count)
            {
                referenceIndex++;
                if (referenceIndex < referenceSpans.Count)
                {
                    currentReference = referenceSpans[referenceIndex];
                }
                else
                {
                    currentReference = null;
                }
            }

            if (currentReference != null)
            {
                GetBestReference(ref referenceIndex, ref currentReference, referenceSpans);
            }

            string cssClass       = MapClassificationToCssClass(span.Classification);
            string referenceClass = string.Empty;

            if (span.LocalGroupId > 0)
            {
                referenceClass = $"r{span.LocalGroupId} r";
                cssClass       = string.IsNullOrEmpty(cssClass) ? referenceClass : $"{referenceClass} {cssClass}";
            }

            HtmlElementInfo htmlElementInfo = null;

            if (currentReference?.SpanEquals(span) == true)
            {
                htmlElementInfo = GenerateHyperlinkForReference(currentReference.Reference);
            }

            if (htmlElementInfo == null && !span.Contains(currentReference))
            {
                if (cssClass == null)
                {
                    tw.Write(HttpUtility.HtmlEncode(spanText));
                    return;
                }
            }

            string elementName             = "span";
            bool   classAttributeSpecified = false;

            if (htmlElementInfo != null)
            {
                elementName = htmlElementInfo.Name;

                if (htmlElementInfo.RequiresWrappingSpan)
                {
                    tw.Write("<span");
                    AddAttribute(tw, "class", cssClass);
                    tw.Write(">");
                    classAttributeSpecified = true;
                }
            }

            tw.Write("<" + elementName);

            if (htmlElementInfo != null)
            {
                foreach (var attribute in htmlElementInfo.Attributes)
                {
                    if (AddAttribute(tw, attribute.Key, attribute.Value))
                    {
                        if (attribute.Key == "class")
                        {
                            classAttributeSpecified = true;
                        }
                    }
                }
            }

            if (!classAttributeSpecified)
            {
                AddAttribute(tw, "class", cssClass);
            }

            if (span.LocalGroupId > 0 && (htmlElementInfo?.Attributes?.ContainsKey("onclick") != true))
            {
                AddAttribute(tw, "onclick", "t(this);");
            }

            tw.Write(">");
            if (htmlElementInfo != null || !span.Contains(currentReference))
            {
                tw.Write(HttpUtility.HtmlEncode(spanText));
            }
            else
            {
                WriteReferenceText(tw, span, spanText, ref referenceIndex, ref currentReference, referenceSpans);
            }

            tw.Write("</" + elementName + ">");

            if (htmlElementInfo?.RequiresWrappingSpan == true)
            {
                tw.Write("</span>");
            }
        }
Exemple #5
0
        private void WriteReferenceText(TextWriter tw, ClassificationSpan span, string spanText, ref int referenceIndex, ref ReferenceSpan currentReference, IReadOnlyList <ReferenceSpan> referenceSpans)
        {
            int startPosition   = span.Start;
            int currentPosition = span.Start;
            int end             = span.End;

            while (currentReference != null && currentReference.Start >= currentPosition && currentReference.Start < end && currentReference.End <= end)
            {
                if (currentReference != null)
                {
                    GetBestReference(ref referenceIndex, ref currentReference, referenceSpans);
                }

                if (currentReference.Start > currentPosition)
                {
                    HttpUtility.HtmlEncode(spanText.Substring(currentPosition - startPosition, currentReference.Start - currentPosition), tw);
                    currentPosition = currentReference.Start;
                }

                if (currentReference.Length > 0)
                {
                    var htmlElementInfo = GenerateHyperlinkForReference(currentReference.Reference);
                    WriteHtmlElement(tw, htmlElementInfo, spanText.Substring(currentReference.Start - startPosition, currentReference.Length));

                    currentPosition = currentReference.End;
                }

                referenceIndex++;
                if (referenceIndex < referenceSpans.Count)
                {
                    currentReference = referenceSpans[referenceIndex];
                }
                else
                {
                    break;
                }
            }

            if (currentPosition < end)
            {
                HttpUtility.HtmlEncode(spanText.Substring(currentPosition - startPosition, end - currentPosition), tw);
            }
        }
        public BoundSourceFile Build()
        {
            if (stringBuilder != null)
            {
                SourceFile.Content = stringBuilder.ToString();
                stringBuilder      = null;
            }

            SourceText text = SourceText;
            var        info = BoundSourceFile.SourceFile.Info;

            var checksumKey = GetChecksumKey(text.ChecksumAlgorithm);

            if (checksumKey != null)
            {
                var checksum = text.GetChecksum().ToHex();
                info.Properties[checksumKey] = checksum;

                AnnotateDefinition(0, 0,
                                   new DefinitionSymbol()
                {
                    Id        = SymbolId.CreateFromId($"{checksumKey}|{checksum}"),
                    ShortName = checksum,
                    ContainerQualifiedName = checksumKey,
                    ProjectId     = BoundSourceFile.ProjectId,
                    ReferenceKind = nameof(ReferenceKind.Definition),
                    Kind          = checksumKey,
                });
            }

            classifications.Sort((cs1, cs2) => cs1.Start.CompareTo(cs2.Start));
            references.Sort((cs1, cs2) => cs1.Start.CompareTo(cs2.Start));
            BoundSourceFile.Definitions.Sort((cs1, cs2) => cs1.Start.CompareTo(cs2.Start));

            ReferenceSpan lastReference = null;

            foreach (var reference in references)
            {
                if (lastReference?.Start == reference.Start)
                {
                    reference.LineNumber    = lastReference.LineNumber;
                    reference.LineSpanStart = lastReference.LineSpanStart;
                    reference.LineSpanText  = lastReference.LineSpanText;
                    continue;
                }

                var line = text.Lines.GetLineFromPosition(reference.Start);
                if (lastReference?.LineNumber == line.LineNumber)
                {
                    reference.LineNumber    = line.LineNumber;
                    reference.LineSpanStart = lastReference.LineSpanStart + (reference.Start - lastReference.Start);
                    reference.LineSpanText  = lastReference.LineSpanText;
                    continue;
                }

                reference.LineNumber    = line.LineNumber;
                reference.LineSpanStart = reference.Start - line.Start;
                reference.LineSpanText  = line.ToString();
                reference.Trim();
            }

            foreach (var definitionSpan in BoundSourceFile.Definitions)
            {
                definitionSpan.Definition.ProjectId = definitionSpan.Definition.ProjectId ?? ProjectId;
                var line = text.Lines.GetLineFromPosition(definitionSpan.Start);
                definitionSpan.LineNumber    = line.LineNumber;
                definitionSpan.LineSpanStart = definitionSpan.Start - line.Start;
            }

            return(BoundSourceFile);
        }
        private void RenderReference(ReferenceSpan referenceSpan)
        {
            if (referenceSpan.ResolutionException == null)
            {
                Push("reference");

                switch (referenceSpan.KindTag)
                {
                    case "link":
                        SetAttribute("kind", "link");
                        break;

                    case "image":
                        SetAttribute("kind", "image");
                        break;
                }

                SetAttribute("to", referenceSpan.Reference);

                if (referenceSpan.ChildSpan != null)
                {
                    RenderSpan(referenceSpan.ChildSpan);
                }

                Pop();
            }
            else
            {
                Push("reference-exception");

                SetAttribute("to", referenceSpan.Reference);
                SetAttribute("message", referenceSpan.ResolutionException.Message);

                if (referenceSpan.ResolutionException is AdornedReferenceResolutionException)
                {
                    AdornedReferenceResolutionException ex =
                        referenceSpan.ResolutionException as AdornedReferenceResolutionException;

                    if (ex.ConsoleOutput != null)
                    {
                        string consoleText = ex.ConsoleOutput;

                        Push("console-output");

                        foreach (string line in consoleText.Split('\n'))
                        {
                            Push("console-output-line");

                            Write(line.TrimEnd());

                            Pop();

                            WriteNewLine();
                        }

                        Pop();
                    }
                }

                Pop();
            }
        }