Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Common/Product/SharedProject/ProjectNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,12 @@ public MSBuildExecution.ProjectInstance CurrentConfig {
}
}

public Dictionary<string, HierarchyNode> DiskNodes {
get {
return _diskNodes;
}
}

#region overridden properties

public override bool CanOpenCommandPrompt {
Expand Down
102 changes: 94 additions & 8 deletions Nodejs/Product/Nodejs/Commands/DiagnosticsCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//*********************************************************//

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
Expand All @@ -26,14 +27,23 @@

namespace Microsoft.NodejsTools.Commands {
internal sealed class DiagnosticsCommand : Command {
private static readonly string[] interestingDteProperties = new[] {
private static readonly string[] _interestingDteProperties = new[] {
"StartupFile",
"WorkingDirectory",
"PublishUrl",
"SearchPath",
"CommandLineArguments"
};

private static readonly string[] _interestingFileExtensions = new[] {
".js",
".jsx",
".tsx",
".d.ts",
".ts",
".html"
};

public DiagnosticsCommand(IServiceProvider serviceProvider) { }

public override int CommandId {
Expand Down Expand Up @@ -75,7 +85,7 @@ private static string GetSolutionInfo() {
res.AppendLine("Projects:");

foreach (EnvDTE.Project project in dte.Solution.Projects) {
res.AppendLine(Indent(4, GetProjectInfo(project)));
res.AppendLine(Indent(1, GetProjectInfo(project)));
}

return res.ToString();
Expand Down Expand Up @@ -105,20 +115,20 @@ private static string GetProjectInfo(EnvDTE.Project project) {
// about the exception. We'll add it to the output,
// rather than crashing.
res.AppendLine("Project: " + ex.Message);
res.AppendLine(Indent(8, "Kind: Node.js"));
res.AppendLine(Indent(2, "Kind: Node.js"));
}
return res.ToString();
}
res.AppendLine("Project: " + name);
res.AppendLine(Indent(4, GetProjectPropertiesInfo(project)));
res.AppendLine(Indent(1, GetProjectPropertiesInfo(project)));
return res.ToString();
}

private static string GetProjectPropertiesInfo(EnvDTE.Project project) {
var res = new StringBuilder();
if (Utilities.GuidEquals(Guids.NodejsBaseProjectFactoryString, project.Kind)) {
res.AppendLine("Kind: Node.js");
foreach (var prop in interestingDteProperties) {
foreach (var prop in _interestingDteProperties) {
res.AppendLine(prop + ": " + GetProjectProperty(project, prop));
}
var njsProj = project.GetNodejsProject();
Expand All @@ -141,9 +151,85 @@ private static string GetNodeJsProjectProperties(Project.NodejsProjectNode proje
jsAnalyzer.DumpLog(writer);
}
}
res.AppendLine(GetProjectNpmInfo(project));
res.AppendLine(GetProjectFileInfo(project));
return res.ToString();
}

/// <summary>
/// Stores information about a collection of files of a given type.
/// </summary>
private class FileTypeInfo {
private int _count = 0;
private int _maxLineLength = 0;
private int _totalLineLength = 0;

public int Count {
get { return _count; }
}

public int MaxLineLength {
get { return _maxLineLength; }
}

public int AverageLineLength {
get { return _count > 0 ? _totalLineLength / _count : 0; }
}

public void UpdateForFile(string file) {
try {
int length = File.ReadLines(file).Count();
++_count;
_totalLineLength += length;
_maxLineLength = Math.Max(_maxLineLength, length);
} catch (IOException) {
// noop
}
}
}

private static string GetProjectFileInfo(Project.NodejsProjectNode project) {
var fileTypeInfo = new Dictionary<string, FileTypeInfo>();
foreach (var node in project.DiskNodes) {
var file = node.Key;
var matchedExt = _interestingFileExtensions.Where(ext => file.EndsWith(ext, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

if (!string.IsNullOrEmpty(matchedExt)) {
var recordKey = string.Format("{0} ({1})", matchedExt, node.Value.ItemNode?.IsExcluded ?? true ? "excluded from project" : "included in project");
FileTypeInfo record;
if (!fileTypeInfo.TryGetValue(recordKey, out record)) {
record = fileTypeInfo[recordKey] = new FileTypeInfo();
}
record.UpdateForFile(file);
}
}

var res = new StringBuilder();

res.AppendLine("Project Info:");
foreach (var entry in fileTypeInfo) {
res.AppendLine(Indent(1, entry.Key + ":"));
res.AppendLine(Indent(2, "Number of Files: " + entry.Value.Count));
res.AppendLine(Indent(2, "Average Line Count: " + entry.Value.AverageLineLength));
res.AppendLine(Indent(2, "Max Line Count: " + entry.Value.MaxLineLength));
}

return res.ToString();
}

private static string GetProjectNpmInfo(Project.NodejsProjectNode project) {
var modules = project?.ModulesNode?.RootPackage?.Modules;
if (modules == null) {
return "";
}

var res = new StringBuilder();
res.AppendLine("Npm Info:");
res.AppendLine(Indent(1, string.Format("Number of Top Level Modules: " + modules.Count())));

return res.ToString();
}

private static string GetProjectProperty(EnvDTE.Project project, string name) {
try {
var item = project.Properties.Item(name);
Expand All @@ -167,7 +253,7 @@ private static string GetEventsAndStatsInfo() {
if (ex.IsCriticalException()) {
throw;
}
res.AppendLine(Indent(4, "Failed to access event log."));
res.AppendLine(Indent(1, "Failed to access event log."));
res.AppendLine(ex.ToString());
}
return res.ToString();
Expand All @@ -179,7 +265,7 @@ private static string GetLoadedAssemblyInfo() {
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies().OrderBy(assem => assem.FullName)) {
var assemFileVersion = assembly.GetCustomAttributes(typeof(AssemblyFileVersionAttribute), false).OfType<AssemblyFileVersionAttribute>().FirstOrDefault();

res.AppendLine(Indent(4, string.Format("{0}, FileVersion={1}",
res.AppendLine(Indent(1, string.Format("{0}, FileVersion={1}",
assembly.FullName,
assemFileVersion == null ? "(null)" : assemFileVersion.Version)));
}
Expand All @@ -204,7 +290,7 @@ private static string GetAnalysisLevelInfo() {
}

private static string Indent(int count, string text) {
var indent = new string(' ', count);
var indent = new string(' ', count * 4);
var lines = text.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
var indentedText = lines.Select(line =>
string.IsNullOrWhiteSpace(line) ? line : indent + line);
Expand Down