Beispiel #1
0
        private void BackpatchUnreferencedDeclarations(string referencesFolder)
        {
            string declarationMapFile = Path.Combine(ProjectDestinationFolder, Constants.DeclarationMap + ".txt");

            if (!File.Exists(declarationMapFile))
            {
                return;
            }

            Log.Write("Backpatching unreferenced declarations in " + this.AssemblyId);

            var symbolIDToListOfLocationsMap = ReadSymbolIDToListOfLocationsMap(declarationMapFile);

            ProjectGenerator.GenerateRedirectFile(
                this.SolutionFinalizer.SolutionDestinationFolder,
                this.ProjectDestinationFolder,
                symbolIDToListOfLocationsMap.ToDictionary(
                    kvp => kvp.Key,
                    kvp => kvp.Value.Select(t => t.Item1.Replace('\\', '/'))));

            var locationsToPatch = new Dictionary <string, List <long> >();

            GetLocationsToPatch(referencesFolder, locationsToPatch, symbolIDToListOfLocationsMap);
            Patch(locationsToPatch);
        }
 public DocumentGenerator(
     ProjectGenerator projectGenerator,
     Document document)
 {
     this.projectGenerator = projectGenerator;
     this.Document         = document;
 }
 public DocumentGenerator(
     ProjectGenerator projectGenerator,
     Document document)
 {
     this.projectGenerator = projectGenerator;
     this.Document = document;
 }
Beispiel #4
0
        public void Generate(IEnumerable <string> typeScriptFiles)
        {
            if (typeScriptFiles == null || !typeScriptFiles.Any())
            {
                return;
            }

            declarations = new List <string>();
            references   = new Dictionary <string, List <Reference> >(StringComparer.OrdinalIgnoreCase);
            SymbolIDToListOfLocationsMap = new Dictionary <string, List <Tuple <string, long> > >();

            var    list    = new List <string>();
            string libFile = null;

            foreach (var file in typeScriptFiles)
            {
                if (!alreadyProcessed.Contains(file))
                {
                    if (libFile == null && string.Equals(Path.GetFileName(file), "lib.d.ts", StringComparison.OrdinalIgnoreCase))
                    {
                        libFile = file;
                    }
                    else
                    {
                        list.Add(file);
                    }
                }
            }

            if (libFile == null)
            {
                libFile = Path.Combine(Common.Paths.BaseAppFolder, "TypeScriptSupport", "lib.d.ts");
            }

            try
            {
                GenerateCore(list, libFile);
            }
            catch (Exception ex)
            {
                Log.Exception(ex, "Error when generating TypeScript files");
                return;
            }

            ProjectGenerator.GenerateReferencesDataFilesToAssembly(
                Paths.SolutionDestinationFolder,
                Constants.TypeScriptFiles,
                references);

            declarations.Sort();

            Serialization.WriteDeclaredSymbols(
                ProjectDestinationFolder,
                declarations);

            ProjectGenerator.GenerateSymbolIDToListOfDeclarationLocationsMap(
                ProjectDestinationFolder,
                SymbolIDToListOfLocationsMap);
        }
        /// <returns>true if only part of the solution was processed and the method needs to be called again, false if all done</returns>
        public bool Generate(HashSet <string> processedAssemblyList = null, Folder <Project> solutionExplorerRoot = null)
        {
            if (solution == null)
            {
                // we failed to open the solution earlier; just return
                Log.Message("Solution is null: " + this.ProjectFilePath);
                return(false);
            }

            var allProjects = solution.Projects.ToArray();

            if (allProjects.Length == 0)
            {
                Log.Exception("Solution " + this.ProjectFilePath + " has 0 projects - this is suspicious");
            }

            var projectsToProcess = allProjects
                                    .Where(p => processedAssemblyList == null || !processedAssemblyList.Contains(p.AssemblyName))
                                    .ToArray();
            var currentBatch = projectsToProcess
                               .ToArray();

            foreach (var project in currentBatch)
            {
                try
                {
                    CurrentAssemblyName = project.AssemblyName;

                    var generator = new ProjectGenerator(this, project);
                    generator.Generate().GetAwaiter().GetResult();

                    File.AppendAllText(Paths.ProcessedAssemblies, project.AssemblyName + Environment.NewLine, Encoding.UTF8);
                    if (processedAssemblyList != null)
                    {
                        processedAssemblyList.Add(project.AssemblyName);
                    }
                }
                finally
                {
                    CurrentAssemblyName = null;
                }
            }

            new TypeScriptSupport().Generate(typeScriptFiles, SolutionDestinationFolder);

            if (currentBatch.Length > 1)
            {
                AddProjectsToSolutionExplorer(
                    solutionExplorerRoot,
                    currentBatch);
            }

            return(currentBatch.Length < projectsToProcess.Length);
        }
Beispiel #6
0
        private string ProcessPropertyName(
            string lineText,
            int lineNumber,
            int startPositionOnLine,
            string text,
            bool isRootProject,
            bool isUsage)
        {
            var propertyName        = text.Trim();
            var leadingTriviaWidth  = text.IndexOf(propertyName, StringComparison.Ordinal);
            var trailingTriviaWidth = text.Length - propertyName.Length - leadingTriviaWidth;

            if (propertyName.IndexOfAny(complexCharsInProperties) != -1)
            {
                return(Markup.HtmlEscape(text));
            }

            if (propertyName.IndexOfAny(Path.GetInvalidFileNameChars()) != -1)
            {
                Log.Exception(string.Format("Invalid property name {0} in project {1}", propertyName, this.sourceXmlFilePath));
                return(Markup.HtmlEscape(text));
            }

            var href =
                "/" +
                Constants.MSBuildPropertiesAssembly +
                "/" +
                Constants.ReferencesFileName +
                "/" +
                propertyName +
                ".html";

            text = string.Format(
                "{2}<a href=\"{1}\" target=\"n\" class=\"msbuildlink\">{0}</a>{3}",
                propertyName,
                href,
                text.Substring(0, leadingTriviaWidth),
                text.Substring(text.Length - trailingTriviaWidth));

            ProjectGenerator.AddReference(
                destinationHtmlFilePath,
                lineText,
                startPositionOnLine,
                propertyName.Length,
                lineNumber,
                isRootProject ? ProjectGenerator.AssemblyName : Constants.MSBuildFiles,
                Constants.MSBuildPropertiesAssembly,
                null,
                propertyName,
                isUsage ? ReferenceKind.MSBuildPropertyUsage : ReferenceKind.MSBuildPropertyAssignment);

            return(text);
        }
Beispiel #7
0
        private string ProcessItemName(
            string lineText,
            int lineNumber,
            int startPositionOnLine,
            string text,
            bool isRootProject,
            bool isUsage)
        {
            var itemName = text.Trim();

            var leadingTriviaWidth  = text.IndexOf(itemName);
            var trailingTriviaWidth = text.Length - itemName.Length - leadingTriviaWidth;

            if (itemName.IndexOfAny(complexCharsInProperties) != -1)
            {
                return(Markup.HtmlEscape(text));
            }

            var href =
                "/" +
                Constants.MSBuildItemsAssembly +
                "/" +
                Constants.ReferencesFileName +
                "/" +
                itemName +
                ".html";

            text = string.Format(
                "{2}<a href=\"{1}\" target=\"n\" class=\"msbuildlink\">{0}</a>{3}",
                itemName,
                href,
                text.Substring(0, leadingTriviaWidth),
                text.Substring(text.Length - trailingTriviaWidth));

            ProjectGenerator.AddReference(
                destinationHtmlFilePath,
                lineText,
                startPositionOnLine,
                itemName.Length,
                lineNumber,
                isRootProject ? ProjectGenerator.AssemblyName : Constants.MSBuildFiles,
                Constants.MSBuildItemsAssembly,
                null,
                itemName,
                isUsage ? ReferenceKind.MSBuildItemUsage : ReferenceKind.MSBuildItemAssignment);

            return(text);
        }
Beispiel #8
0
        private string ProcessTaskName(
            string lineText,
            int lineNumber,
            int startPositionOnLine,
            string text,
            string taskName,
            bool isRootProject,
            bool isUsage)
        {
            var trimmedText         = text.Trim();
            var leadingTriviaWidth  = text.IndexOf(trimmedText, StringComparison.Ordinal);
            var trailingTriviaWidth = text.Length - trimmedText.Length - leadingTriviaWidth;

            var href =
                "/" +
                Constants.MSBuildTasksAssembly +
                "/" +
                Constants.ReferencesFileName +
                "/" +
                taskName +
                ".html";

            text = string.Format(
                "{2}<a href=\"{1}\" target=\"n\" class=\"msbuildlink\">{0}</a>{3}",
                trimmedText,
                href,
                text.Substring(0, leadingTriviaWidth),
                text.Substring(text.Length - trailingTriviaWidth));

            ProjectGenerator.AddReference(
                destinationHtmlFilePath,
                lineText,
                startPositionOnLine,
                trimmedText.Length,
                lineNumber,
                isRootProject ? ProjectGenerator.AssemblyName : Constants.MSBuildFiles,
                Constants.MSBuildTasksAssembly,
                null,
                taskName,
                isUsage ? ReferenceKind.MSBuildTaskUsage : ReferenceKind.MSBuildTaskDeclaration);

            return(text);
        }
Beispiel #9
0
 public XamlSupport(ProjectGenerator projectGenerator)
 {
     this.projectGenerator = projectGenerator;
 }
Beispiel #10
0
        private void GenerateRange(
            StringBuilder sb,
            ClassifiedRange range,
            string destinationFilePath,
            Dictionary <string, int> localSymbolIdMap)
        {
            var html = range.text;

            html = Markup.HtmlEscape(html);

            var localRelativePath = destinationFilePath.Substring(
                Path.Combine(
                    Paths.SolutionDestinationFolder,
                    Constants.TypeScriptFiles).Length + 1);

            localRelativePath = localRelativePath.Substring(0, localRelativePath.Length - ".html".Length);

            string          classAttributeValue = GetSpanClass(range.classification);
            HtmlElementInfo hyperlinkInfo       = GenerateLinks(range, destinationFilePath, localSymbolIdMap);

            if (hyperlinkInfo == null)
            {
                if (classAttributeValue == null)
                {
                    sb.Append(html);
                    return;
                }

                if (classAttributeValue == "k")
                {
                    sb.Append("<b>").Append(html).Append("</b>");
                    return;
                }
            }

            var elementName = "span";

            if (hyperlinkInfo != null)
            {
                elementName = hyperlinkInfo.Name;
            }

            sb.Append("<").Append(elementName);
            bool overridingClassAttributeSpecified = false;

            if (hyperlinkInfo != null)
            {
                foreach (var attribute in hyperlinkInfo.Attributes)
                {
                    const string typeScriptFilesR = "/TypeScriptFiles/R/";
                    if (attribute.Key == "href" && attribute.Value.StartsWith(typeScriptFilesR, StringComparison.Ordinal))
                    {
                        var streamPosition = sb.Length + 7 + typeScriptFilesR.Length; // exact offset into <a href="HERE
                        ProjectGenerator.AddDeclaredSymbolToRedirectMap(
                            SymbolIDToListOfLocationsMap,
                            attribute.Value.Substring(typeScriptFilesR.Length, 16),
                            localRelativePath,
                            streamPosition);
                    }

                    AddAttribute(sb, attribute.Key, attribute.Value);
                    if (attribute.Key == "class")
                    {
                        overridingClassAttributeSpecified = true;
                    }
                }
            }

            if (!overridingClassAttributeSpecified)
            {
                AddAttribute(sb, "class", classAttributeValue);
            }

            sb.Append('>');

            sb.Append(html);
            sb.Append("</").Append(elementName).Append(">");
        }
Beispiel #11
0
 private static void GenerateLooseFilesProject(string projectName, string solutionDestinationPath)
 {
     var projectGenerator = new ProjectGenerator(projectName, solutionDestinationPath);
     projectGenerator.GenerateNonProjectFolder();
 }
        /// <returns>true if only part of the solution was processed and the method needs to be called again, false if all done</returns>
        public bool Generate(HashSet<string> processedAssemblyList = null, Folder<Project> solutionExplorerRoot = null)
        {
            if (solution == null)
            {
                // we failed to open the solution earlier; just return
                Log.Message("Solution is null: " + this.ProjectFilePath);
                return false;
            }

            var allProjects = solution.Projects.ToArray();
            if (allProjects.Length == 0)
            {
                Log.Exception("Solution " + this.ProjectFilePath + " has 0 projects - this is suspicious");
            }

            var projectsToProcess = allProjects
                .Where(p => processedAssemblyList == null || !processedAssemblyList.Contains(p.AssemblyName))
                .ToArray();
            var currentBatch = projectsToProcess
                .ToArray();
            foreach (var project in currentBatch)
            {
                try
                {
                    CurrentAssemblyName = project.AssemblyName;

                    var generator = new ProjectGenerator(this, project);
                    generator.Generate().GetAwaiter().GetResult();

                    File.AppendAllText(Paths.ProcessedAssemblies, project.AssemblyName + Environment.NewLine, Encoding.UTF8);
                    if (processedAssemblyList != null)
                    {
                        processedAssemblyList.Add(project.AssemblyName);
                    }
                }
                finally
                {
                    CurrentAssemblyName = null;
                }
            }

            new TypeScriptSupport().Generate(typeScriptFiles, SolutionDestinationFolder);

            if (currentBatch.Length > 1)
            {
                AddProjectsToSolutionExplorer(
                    solutionExplorerRoot,
                    currentBatch);
            }

            return currentBatch.Length < projectsToProcess.Length;
        }
Beispiel #13
0
        private static void GenerateLooseFilesProject(string projectName, string solutionDestinationPath)
        {
            var projectGenerator = new ProjectGenerator(projectName, solutionDestinationPath);

            projectGenerator.GenerateNonProjectFolder();
        }
 public XmlSupport(ProjectGenerator generator)
 {
     ProjectGenerator = generator;
 }
 public XamlSupport(ProjectGenerator projectGenerator)
 {
     this.projectGenerator = projectGenerator;
 }
 public MSBuildSupport(ProjectGenerator projectGenerator)
 {
     this.projectGenerator = projectGenerator;
 }
Beispiel #17
0
 public MSBuildSupport(ProjectGenerator projectGenerator)
 {
     this.projectGenerator = projectGenerator;
 }
Beispiel #18
0
 public MSBuildSupport(ProjectGenerator projectGenerator)
     : base(projectGenerator)
 {
 }
        public async Task Generate()
        {
            if (Configuration.CalculateRoslynSemantics)
            {
                this.Text = await Document.GetTextAsync();

                this.Root = await Document.GetSyntaxRootAsync();

                this.SemanticModel = await Document.GetSemanticModelAsync();

                this.SemanticFactsService = WorkspaceHacks.GetSemanticFactsService(this.Document);
                this.SyntaxFactsService   = WorkspaceHacks.GetSyntaxFactsService(this.Document);

                var semanticFactsServiceType = SemanticFactsService.GetType();
                var isWrittenTo = semanticFactsServiceType.GetMethod("IsWrittenTo");
                this.isWrittenToDelegate = (Func <SemanticModel, SyntaxNode, CancellationToken, bool>)
                                           Delegate.CreateDelegate(typeof(Func <SemanticModel, SyntaxNode, CancellationToken, bool>), SemanticFactsService, isWrittenTo);

                var syntaxFactsServiceType = SyntaxFactsService.GetType();
                var getBindableParent      = syntaxFactsServiceType.GetMethod("GetBindableParent");
                this.getBindableParentDelegate = (Func <SyntaxToken, SyntaxNode>)
                                                 Delegate.CreateDelegate(typeof(Func <SyntaxToken, SyntaxNode>), SyntaxFactsService, getBindableParent);

                this.DeclaredSymbols = new HashSet <ISymbol>();

                Interlocked.Increment(ref projectGenerator.DocumentCount);
                Interlocked.Add(ref projectGenerator.LinesOfCode, Text.Lines.Count);
                Interlocked.Add(ref projectGenerator.BytesOfCode, Text.Length);
            }

            CalculateDocumentDestinationPath();
            CalculateRelativePathToRoot();

            // add the file itself as a "declared symbol", so that clicking on document in search
            // results redirects to the document
            ProjectGenerator.AddDeclaredSymbolToRedirectMap(
                this.projectGenerator.SymbolIDToListOfLocationsMap,
                SymbolIdService.GetId(this.Document),
                documentRelativeFilePathWithoutHtmlExtension,
                0);

            if (File.Exists(documentDestinationFilePath))
            {
                // someone already generated this file, likely a shared linked file from elsewhere
                return;
            }

            this.classifier = new Classification();

            Log.Write(documentDestinationFilePath);

            try
            {
                var directoryName = Path.GetDirectoryName(documentDestinationFilePath);
                var sanitized     = Paths.SanitizeFolder(directoryName);
                if (directoryName != sanitized)
                {
                    Log.Exception("Illegal characters in path: " + directoryName + " Project: " + this.projectGenerator.AssemblyName);
                }

                if (Configuration.CreateFoldersOnDisk)
                {
                    Directory.CreateDirectory(directoryName);
                }
            }
            catch (PathTooLongException)
            {
                // there's one case where a path is too long - we don't care enough about it
                return;
            }

            if (Configuration.WriteDocumentsToDisk)
            {
                using (var streamWriter = new StreamWriter(
                           documentDestinationFilePath,
                           append: false,
                           encoding: Encoding.UTF8))
                {
                    await GenerateHtml(streamWriter);
                }
            }
            else
            {
                using (var memoryStream = new MemoryStream())
                    using (var streamWriter = new StreamWriter(memoryStream))
                    {
                        await GeneratePre(streamWriter);
                    }
            }
        }
Beispiel #20
0
        private string ProcessAttributeValue(ClassifiedRange range, string text, bool isRootProject)
        {
            var node            = range.Node;
            var attributeSyntax = node.GetParent(2) as XmlAttributeSyntax;

            if (attributeSyntax != null)
            {
                var parentElement = attributeSyntax.ParentElement;

                if (parentElement?.Name == "Output" &&
                    (attributeSyntax.Name == "ItemName" || attributeSyntax.Name == "PropertyName") &&
                    !text.Contains("%"))
                {
                    if (attributeSyntax.Name == "ItemName")
                    {
                        return(ProcessItemName(
                                   range.LineText,
                                   range.LineNumber + 1,
                                   range.Column,
                                   text,
                                   isRootProject,
                                   isUsage: false));
                    }
                    else
                    {
                        return(ProcessPropertyName(
                                   range.LineText,
                                   range.LineNumber + 1,
                                   range.Column,
                                   text,
                                   isRootProject,
                                   isUsage: false));
                    }
                }

                if (parentElement?.Name == "Target")
                {
                    if (attributeSyntax.Name == "Name")
                    {
                        return(ProcessTargetName(
                                   range.LineText,
                                   range.LineNumber + 1,
                                   range.Column,
                                   text,
                                   isRootProject,
                                   isUsage: false));
                    }

                    if (attributeSyntax.Name == "DependsOnTargets" ||
                        attributeSyntax.Name == "BeforeTargets" ||
                        attributeSyntax.Name == "AfterTargets")
                    {
                        return(ProcessExpressions(range, text, isRootProject, ProcessSemicolonSeparatedList));
                    }
                }

                if (parentElement?.Name == "CallTarget" && attributeSyntax.Name == "Targets")
                {
                    return(ProcessExpressions(range, text, isRootProject, ProcessSemicolonSeparatedList));
                }

                if (parentElement?.Name == "UsingTask" && attributeSyntax.Name == "TaskName")
                {
                    var    taskName = attributeSyntax.Value;
                    var    assemblyFileAttribute = parentElement.Attributes.FirstOrDefault(a => a.Name == "AssemblyFile");
                    var    assemblyNameAttribute = parentElement.Attributes.FirstOrDefault(a => a.Name == "AssemblyName");
                    string assemblyName          = null;
                    if (assemblyFileAttribute != null && !string.IsNullOrWhiteSpace(assemblyFileAttribute.Value))
                    {
                        var assemblyFilePath = assemblyFileAttribute.Value;
                        assemblyFilePath = project.ExpandString(assemblyFilePath);
                        assemblyName     = Path.GetFileNameWithoutExtension(assemblyFilePath);
                    }
                    else if (assemblyNameAttribute != null && !string.IsNullOrWhiteSpace(assemblyNameAttribute.Value))
                    {
                        assemblyName = assemblyNameAttribute.Value;
                        assemblyName = project.ExpandString(assemblyName);
                        int comma = assemblyName.IndexOf(',');
                        if (comma > -1)
                        {
                            assemblyName = assemblyName.Substring(0, comma);
                        }
                    }

                    if (assemblyName != null)
                    {
                        var symbolId = SymbolIdService.GetId("T:" + taskName);
                        ProjectGenerator.AddReference(
                            destinationHtmlFilePath,
                            range.LineText,
                            range.Column,
                            taskName.Length,
                            range.LineNumber,
                            isRootProject ? ProjectGenerator.AssemblyName : Constants.MSBuildFiles,
                            assemblyName,
                            null,
                            symbolId,
                            ReferenceKind.Instantiation);

                        var url    = string.Format("/{0}/A.html#{1}", assemblyName, symbolId);
                        var result = string.Format("<a href=\"{0}\" class=\"msbuildlink\">{1}</a>", url, text);
                        return(result);
                    }
                }
            }

            return(ProcessExpressions(range, text, isRootProject));
        }