Index: clang-tidy-vs/.gitignore
===================================================================
--- clang-tidy-vs/.gitignore
+++ clang-tidy-vs/.gitignore
@@ -5,3 +5,4 @@
clang-tidy.exe
packages/
*.csproj.user
+*.suo
Index: clang-tidy-vs/CMakeLists.txt
===================================================================
--- clang-tidy-vs/CMakeLists.txt
+++ clang-tidy-vs/CMakeLists.txt
@@ -11,15 +11,25 @@
"${CLANG_SOURCE_DIR}/LICENSE.TXT"
"${CMAKE_CURRENT_SOURCE_DIR}/ClangTidy/license.txt")
+ # Build number added to Clang version to ensure that new VSIX can be upgraded
+ string(TIMESTAMP CLANG_TIDY_VSIX_BUILD %y%m%d%H%M UTC)
+
if (NOT CLANG_TIDY_VS_VERSION)
- set(CLANG_TIDY_VS_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
+ set(CLANG_TIDY_VS_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}.${CLANG_TIDY_VSIX_BUILD}")
endif()
configure_file("source.extension.vsixmanifest.in"
"${CMAKE_CURRENT_SOURCE_DIR}/ClangTidy/source.extension.vsixmanifest")
+ find_program(NUGET_EXE nuget PATHS ${NUGET_EXE_DIR})
+ if (NOT NUGET_EXE)
+ message(FATAL_ERROR "Could not find nuget.exe. Download from https://www.nuget.org/nuget.exe"
+ " and add parent directory to PATH or pass it via NUGET_EXE_DIR var.")
+ endif()
+
add_custom_target(clang_tidy_vsix ALL
- devenv "${CMAKE_CURRENT_SOURCE_DIR}/ClangTidy.sln" /Build Release
+ COMMAND ${NUGET_EXE} restore "${CMAKE_CURRENT_SOURCE_DIR}/ClangTidy.sln"
+ COMMAND devenv "${CMAKE_CURRENT_SOURCE_DIR}/ClangTidy.sln" /Build Release
DEPENDS clang_tidy_exe_for_vsix "${CMAKE_CURRENT_SOURCE_DIR}/ClangTidy/source.extension.vsixmanifest"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_CURRENT_SOURCE_DIR}/ClangTidy/bin/Release/ClangTidy.vsix"
Index: clang-tidy-vs/ClangTidy/ClangTidy.csproj
===================================================================
--- clang-tidy-vs/ClangTidy/ClangTidy.csproj
+++ clang-tidy-vs/ClangTidy/ClangTidy.csproj
@@ -1,5 +1,6 @@
´╗┐
+
Debug
@@ -36,6 +37,8 @@
false
true
+
+
true
@@ -59,26 +62,54 @@
false
+
-
+
+ ..\packages\Microsoft.VisualStudio.CoreUtility.14.3.25407\lib\net45\Microsoft.VisualStudio.CoreUtility.dll
+ True
+
+
+
+
+ ..\packages\Microsoft.VisualStudio.Text.Data.14.3.25407\lib\net45\Microsoft.VisualStudio.Text.Data.dll
+ True
+
+
+ ..\packages\Microsoft.VisualStudio.Text.Logic.14.3.25407\lib\net45\Microsoft.VisualStudio.Text.Logic.dll
+ True
+
+
+ ..\packages\Microsoft.VisualStudio.Text.UI.14.3.25407\lib\net45\Microsoft.VisualStudio.Text.UI.dll
+ True
+
+
+ ..\packages\Microsoft.VisualStudio.Text.UI.Wpf.14.3.25407\lib\net45\Microsoft.VisualStudio.Text.UI.Wpf.dll
+ True
+
+
+
+
+
+
+
..\packages\YamlDotNet.3.3.0\lib\net35\YamlDotNet.dll
True
@@ -98,33 +129,6 @@
False
False
-
- {26AD1324-4B7C-44BC-84F8-B86AED45729F}
- 10
- 0
- 0
- primary
- False
- False
-
-
- {1A31287A-4D7D-413E-8E32-3B374931BD89}
- 8
- 0
- 0
- primary
- False
- False
-
-
- {2CE2370E-D744-4936-A090-3FFFE667B0E1}
- 9
- 0
- 0
- primary
- False
- False
-
{1CBA492E-7263-47BB-87FE-639000619B15}
8
@@ -145,6 +149,7 @@
+
@@ -155,6 +160,17 @@
Component
+
+
+
+
+
+
+
+
+
+
+
@@ -199,6 +215,7 @@
+
Designer
@@ -210,15 +227,13 @@
-
-
-
true
true
+
@@ -250,18 +265,30 @@
10.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+
- if not exist $(ProjectDir)Key.snk ("$(SDKToolsPath)\sn.exe" -k $(ProjectDir)Key.snk)
+ if not exist $(ProjectDir)Key.snk ("$(FrameworkSDKDir)Bin\NETFX 4.6 Tools\sn.exe" -k $(ProjectDir)Key.snk)
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
\ No newline at end of file
Index: clang-tidy-vs/ClangTidy/ClangTidy.vsct
===================================================================
--- clang-tidy-vs/ClangTidy/ClangTidy.vsct
+++ clang-tidy-vs/ClangTidy/ClangTidy.vsct
@@ -21,8 +21,6 @@
-
-
@@ -34,6 +32,16 @@
group; your package should define its own command set in order to avoid collisions
with command ids defined by other packages. -->
+
+
+
-
+ must be the actual index (1-based) of the bitmap inside the bitmap strip. -->
+
@@ -101,17 +118,14 @@
+
+
-
-
-
-
-
-
-
-
+
+
+
Index: clang-tidy-vs/ClangTidy/ClangTidyPackage.cs
===================================================================
--- clang-tidy-vs/ClangTidy/ClangTidyPackage.cs
+++ clang-tidy-vs/ClangTidy/ClangTidyPackage.cs
@@ -24,6 +24,7 @@
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Xml.Linq;
+using System.Diagnostics;
namespace LLVM.ClangTidy
{
@@ -51,6 +52,7 @@
private void MenuItemCallback(object sender, EventArgs args)
{
+ ClangTidyRunner.RunClangTidyProcess();
}
}
}
Index: clang-tidy-vs/ClangTidy/ClassifierAndTagger/Classifier.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ClassifierAndTagger/Classifier.cs
@@ -0,0 +1,75 @@
+´╗┐using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.Text.Classification;
+using Microsoft.VisualStudio.Text.Tagging;
+using Microsoft.VisualStudio.Text;
+
+namespace LLVM.ClangTidy
+{
+ ///
+ /// Tag classifier finds every instance of ValidationTag within a given span.
+ ///
+ class ValidationClassifier : IClassifier
+ {
+ private IClassificationType ClassificationType;
+ private ITagAggregator Tagger;
+ private static ValidationClassifier ActiveClassifier = null;
+ private SnapshotSpan CurrentSpan;
+
+ internal ValidationClassifier(ITagAggregator tagger, IClassificationType classificationType)
+ {
+ Tagger = tagger;
+ ClassificationType = classificationType;
+ }
+
+ ///
+ /// Get every ValidationTag instance within the given span. Generally, the span in
+ /// question is the displayed portion of the file currently open in the Editor
+ ///
+ /// The span of text that will be searched for validation tags
+ /// A list of every relevant tag in the given span
+ public IList GetClassificationSpans(SnapshotSpan span)
+ {
+ ActiveClassifier = this;
+
+ // After clang-tidy returns new results, tags will be automatically created only for
+ // newly appearing text lines or focused code window.
+ // To force-refresh tags in current window store single span for the whole file and
+ // call Invalidate() on this span when clang-tidy results are ready.
+ var WholeSpan = new SnapshotSpan(span.Snapshot, 0, span.Snapshot.Length);
+ CurrentSpan = WholeSpan;
+
+ IList classifiedSpans = new List();
+
+ var tags = Tagger.GetTags(span);
+
+ foreach (IMappingTagSpan tagSpan in tags)
+ {
+ var validationSpan = tagSpan.Span.GetSpans(span.Snapshot).First();
+ classifiedSpans.Add(new ClassificationSpan(validationSpan, ClassificationType));
+ }
+
+ return classifiedSpans;
+ }
+
+ ///
+ /// Create an event for when the Classification changes
+ ///
+ public event EventHandler ClassificationChanged;
+
+ ///
+ /// Force refresh a span stored on last update (assume it corresponds to currently active document)
+ ///
+ public void Invalidate()
+ {
+ ClassificationChanged?.Invoke(this, new ClassificationChangedEventArgs(CurrentSpan));
+ }
+
+ static public void InvalidateActiveClassifier()
+ {
+ if (ActiveClassifier != null)
+ ActiveClassifier.Invalidate();
+ }
+ }
+}
Index: clang-tidy-vs/ClangTidy/ClassifierAndTagger/ClassifierProvider.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ClassifierAndTagger/ClassifierProvider.cs
@@ -0,0 +1,53 @@
+´╗┐using System.ComponentModel.Composition;
+using Microsoft.VisualStudio.Text.Classification;
+using Microsoft.VisualStudio.Utilities;
+using Microsoft.VisualStudio.Text.Tagging;
+using Microsoft.VisualStudio.Text;
+using System.Windows.Media;
+
+namespace LLVM.ClangTidy
+{
+ ///
+ /// Export a
+ ///
+ [Export(typeof(IClassifierProvider))]
+ [ContentType("code")]
+ internal class ClassifierProvider : IClassifierProvider
+ {
+ [Export(typeof(ClassificationTypeDefinition))]
+ [Name("clang-tidy-validation")]
+ internal ClassificationTypeDefinition ValidationClassificationType = null;
+
+ [Import]
+ internal IClassificationTypeRegistryService ClassificationRegistry = null;
+
+ [Import]
+ internal IBufferTagAggregatorFactoryService TagAggregatorFactory = null;
+
+ public IClassifier GetClassifier(ITextBuffer buffer)
+ {
+ IClassificationType classificationType = ClassificationRegistry.GetClassificationType("clang-tidy-validation");
+
+ var tagAggregator = TagAggregatorFactory.CreateTagAggregator(buffer);
+ return new ValidationClassifier(tagAggregator, classificationType);
+ }
+ }
+
+ ///
+ /// Set the display values for the classification
+ ///
+ [Export(typeof(EditorFormatDefinition))]
+ [ClassificationType(ClassificationTypeNames = "clang-tidy-validation")]
+ [Name("clang-tidy validation")]
+ [UserVisible(false)]
+ [Order(After = Priority.High)]
+ internal sealed class ValidationWarningFormat : ClassificationFormatDefinition
+ {
+ public ValidationWarningFormat()
+ {
+ DisplayName = "clang-tidy validation failed";
+ BackgroundOpacity = 0.3f;
+ BackgroundColor = Colors.Red;
+ }
+ }
+}
Index: clang-tidy-vs/ClangTidy/ClassifierAndTagger/QuickInfoController.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ClassifierAndTagger/QuickInfoController.cs
@@ -0,0 +1,71 @@
+´╗┐using System.Collections.Generic;
+using Microsoft.VisualStudio.Language.Intellisense;
+using Microsoft.VisualStudio.Text;
+using Microsoft.VisualStudio.Text.Editor;
+
+namespace LLVM.ClangTidy
+{
+ internal class QuickInfoController : IIntellisenseController
+ {
+ private ITextView TextView;
+ private IList SubjectBuffers;
+ private QuickInfoControllerProvider Provider;
+ private IQuickInfoSession Session;
+
+ internal QuickInfoController(ITextView textView, IList subjectBuffers, QuickInfoControllerProvider provider)
+ {
+ TextView = textView;
+ SubjectBuffers = subjectBuffers;
+ Provider = provider;
+
+ TextView.MouseHover += OnTextViewMouseHover;
+ }
+
+ private void OnTextViewMouseHover(object sender, MouseHoverEventArgs e)
+ {
+ SnapshotPoint? point = GetMousePosition(new SnapshotPoint(TextView.TextSnapshot, e.Position));
+
+ if (point != null)
+ {
+ ITrackingPoint triggerPoint = point.Value.Snapshot.CreateTrackingPoint(point.Value.Position,
+ PointTrackingMode.Positive);
+
+ // Find the broker for this buffer
+ if (!Provider.QuickInfoBroker.IsQuickInfoActive(TextView))
+ {
+ Session = Provider.QuickInfoBroker.CreateQuickInfoSession(TextView, triggerPoint, true);
+ Session.Start();
+ }
+ }
+ }
+
+ public void Detach(ITextView textView)
+ {
+ if (TextView == textView)
+ {
+ TextView.MouseHover -= this.OnTextViewMouseHover;
+ TextView = null;
+ }
+ }
+
+ private SnapshotPoint? GetMousePosition(SnapshotPoint topPosition)
+ {
+ // Map this point down to the appropriate subject buffer.
+ return TextView.BufferGraph.MapDownToFirstMatch
+ (
+ topPosition,
+ PointTrackingMode.Positive,
+ snapshot => SubjectBuffers.Contains(snapshot.TextBuffer),
+ PositionAffinity.Predecessor
+ );
+ }
+
+ public void ConnectSubjectBuffer(ITextBuffer subjectBuffer)
+ {
+ }
+
+ public void DisconnectSubjectBuffer(ITextBuffer subjectBuffer)
+ {
+ }
+ }
+}
Index: clang-tidy-vs/ClangTidy/ClassifierAndTagger/QuickInfoControllerProvider.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ClassifierAndTagger/QuickInfoControllerProvider.cs
@@ -0,0 +1,23 @@
+´╗┐using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using Microsoft.VisualStudio.Language.Intellisense;
+using Microsoft.VisualStudio.Text;
+using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Utilities;
+
+namespace LLVM.ClangTidy
+{
+ [Export(typeof(IIntellisenseControllerProvider))]
+ [Name("ClangTidy QuickInfo Controller")]
+ [ContentType("text")]
+ internal class QuickInfoControllerProvider : IIntellisenseControllerProvider
+ {
+ [Import]
+ internal IQuickInfoBroker QuickInfoBroker { get; set; }
+
+ public IIntellisenseController TryCreateIntellisenseController(ITextView textView, IList subjectBuffers)
+ {
+ return new QuickInfoController(textView, subjectBuffers, this);
+ }
+ }
+}
Index: clang-tidy-vs/ClangTidy/ClassifierAndTagger/QuickInfoSource.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ClassifierAndTagger/QuickInfoSource.cs
@@ -0,0 +1,51 @@
+´╗┐using System;
+using System.Collections.Generic;
+using Microsoft.VisualStudio.Language.Intellisense;
+using Microsoft.VisualStudio.Text;
+using Microsoft.VisualStudio.Text.Tagging;
+using System.Linq;
+
+namespace LLVM.ClangTidy
+{
+ internal class QuickInfoSource : IQuickInfoSource
+ {
+ private ITagAggregator Aggregator;
+ private ITextBuffer Buffer;
+ private bool IsDisposed = false;
+
+ public QuickInfoSource(ITextBuffer buffer, ITagAggregator aggregator)
+ {
+ Aggregator = aggregator;
+ Buffer = buffer;
+ }
+
+ public void AugmentQuickInfoSession(IQuickInfoSession session, IList