├── DanTup.DartVS.Vsix
├── Screenshot.png
├── Resources
│ └── Package.ico
├── Properties
│ └── AssemblyInfo.cs
├── Classify
│ ├── DartClassifierProvider.cs
│ └── DartClassifier.cs
├── ContentType
│ └── DartContentTypeDefinition.cs
├── CommandExecutor.cs
├── LICENCE.txt
├── DartPackage.cs
├── source.extension.vsixmanifest
├── DartAnalyzer.cs
├── DartAnalyzerErrorService.cs
├── VsDocumentEvents.cs
├── DartAnalzyerOutputParser.cs
└── DanTup.DartVS.Vsix.csproj
├── README.md
├── DanTup.DartVS.sln
├── LICENCE.txt
├── UpdateVersions.fsx
└── .gitignore
/DanTup.DartVS.Vsix/Screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/DartVS/master/DanTup.DartVS.Vsix/Screenshot.png
--------------------------------------------------------------------------------
/DanTup.DartVS.Vsix/Resources/Package.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/DartVS/master/DanTup.DartVS.Vsix/Resources/Package.ico
--------------------------------------------------------------------------------
/DanTup.DartVS.Vsix/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | [assembly: AssemblyTitle("DanTup's DartVS: Visual Studio support for Google's Dart (VSIX)")]
5 | [assembly: AssemblyProduct("DanTup's DartVS: Visual Studio support for Google's Dart")]
6 | [assembly: AssemblyCompany("Danny Tuppeny")]
7 | [assembly: AssemblyCopyright("Copyright Danny Tuppeny © 2014")]
8 | [assembly: ComVisible(false)]
9 | [assembly: AssemblyVersion("0.2.*")]
10 | [assembly: AssemblyFileVersion("0.2.0.0")]
11 |
--------------------------------------------------------------------------------
/DanTup.DartVS.Vsix/Classify/DartClassifierProvider.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.Composition;
2 | using Microsoft.VisualStudio.Text;
3 | using Microsoft.VisualStudio.Text.Classification;
4 | using Microsoft.VisualStudio.Utilities;
5 |
6 | namespace DanTup.DartVS
7 | {
8 | [Export(typeof(IClassifierProvider))]
9 | [ContentType(DartContentTypeDefinition.DartContentType)]
10 | class DartClassifierProvider : IClassifierProvider
11 | {
12 | [Import]
13 | public IClassificationTypeRegistryService Registry { get; set; }
14 |
15 | public IClassifier GetClassifier(ITextBuffer textBuffer)
16 | {
17 | return textBuffer.Properties.GetOrCreateSingletonProperty(() => new DartClassifier(Registry));
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/DanTup.DartVS.Vsix/ContentType/DartContentTypeDefinition.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.Composition;
2 | using Microsoft.VisualStudio.Utilities;
3 |
4 | namespace DanTup.DartVS
5 | {
6 | class DartContentTypeDefinition
7 | {
8 | public const string DartContentType = "Dart";
9 |
10 | ///
11 | /// Exports the Dart content type
12 | ///
13 | [Export(typeof(ContentTypeDefinition))]
14 | [Name(DartContentType)]
15 | [BaseDefinition("code")]
16 | public ContentTypeDefinition IDartContentType { get; set; }
17 |
18 | [Export(typeof(FileExtensionToContentTypeDefinition))]
19 | [ContentType(DartContentType)]
20 | [FileExtension(".dart")]
21 | public FileExtensionToContentTypeDefinition DartFileExtension { get; set; }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | DartVS: Google Dart support for Visual Studio
2 | =========
3 |
4 | 
5 |
6 | ## Implemented
7 | - Use DartAnalyzer from the SDK when saving any .dart file and report errors/warnings/hints to the Visual Studio error list
8 | - Clicking errors navigates to the correct place in code
9 |
10 | ## Not Implemented
11 | - Use Batch Mode of DartAnalyzer for better performance
12 | - Syntax Highlighting
13 | - Intellisense
14 | - Debugging
15 |
16 | ## Installation
17 | - Install from the Visual Studio Gallery
18 | - Download and unzip the [Dart SDK](https://www.dartlang.org/tools/sdk/)
19 | - Set the DART_SDK environment variable to point at the SDK root
20 |
21 |
22 | Feedback
23 | ===
24 | Please send your feedback/issues/feature requests! :-)
25 |
26 | - GitHub Issues: [DartVS/issues](https://github.com/DanTup/DartVS/issues)
27 | - Twitter: [@DanTup](https://twitter.com/DanTup)
28 | - Google+: [Danny Tuppeny](http://profile.dantup.com/)
29 | - Email: [danny+dartvs@tuppeny.com](mailto:danny+dartvs@tuppeny.com)
30 |
--------------------------------------------------------------------------------
/DanTup.DartVS.Vsix/CommandExecutor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 |
5 | namespace DanTup.DartVS
6 | {
7 | ///
8 | /// Executes an external command and collects output. Anything written to STDERR will cause an exception to be thrown with the data,
9 | ///
10 | class CommandExecutor
11 | {
12 | public string ExecuteCommand(string file, string args)
13 | {
14 | var startInfo = new ProcessStartInfo(file, args)
15 | {
16 | WorkingDirectory = Path.GetDirectoryName(file),
17 | UseShellExecute = false,
18 | CreateNoWindow = true,
19 | RedirectStandardOutput = true,
20 | RedirectStandardError = true
21 | };
22 |
23 | using (var proc = new Process { StartInfo = startInfo })
24 | {
25 | proc.Start();
26 |
27 | var output = proc.StandardOutput.ReadToEnd();
28 | var error = proc.StandardError.ReadToEnd();
29 | proc.WaitForExit();
30 |
31 | if (!string.IsNullOrEmpty(error))
32 | throw new Exception(error);
33 |
34 | return output;
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/DanTup.DartVS.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.30501.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DanTup.DartVS.Vsix", "DanTup.DartVS.Vsix\DanTup.DartVS.Vsix.csproj", "{CFC8B136-5D0D-4439-9373-E7B1CA027118}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {CFC8B136-5D0D-4439-9373-E7B1CA027118}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {CFC8B136-5D0D-4439-9373-E7B1CA027118}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {CFC8B136-5D0D-4439-9373-E7B1CA027118}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {CFC8B136-5D0D-4439-9373-E7B1CA027118}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/LICENCE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Danny Tuppeny
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/DanTup.DartVS.Vsix/LICENCE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Danny Tuppeny
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/DanTup.DartVS.Vsix/DartPackage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using Microsoft.VisualStudio;
4 | using Microsoft.VisualStudio.Shell;
5 |
6 | namespace DanTup.DartVS
7 | {
8 | [InstalledProductRegistration("DanTup's DartVS: Visual Studio support for Google's Dart", @"Some support for coding Dart in Visual Studio.", "0.2")]
9 | [ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)]
10 | public sealed class DartPackage : Package
11 | {
12 | VsDocumentEvents events;
13 | ErrorListProvider errorListProvider;
14 |
15 | protected override void Initialize()
16 | {
17 | base.Initialize();
18 |
19 | events = new VsDocumentEvents();
20 | errorListProvider = new ErrorListProvider(this);
21 |
22 | events.FileSaved += events_FileSaved;
23 | }
24 |
25 | void events_FileSaved(object sender, string filename)
26 | {
27 | // Kick off a thread; because it might be slow!
28 | var isDartFile = string.Equals(Path.GetExtension(filename), ".dart", StringComparison.OrdinalIgnoreCase);
29 | if (isDartFile)
30 | System.Threading.Tasks.Task.Run(() => DartAnalyzerErrorService.Parse(errorListProvider, filename));
31 | }
32 |
33 | protected override void Dispose(bool disposing)
34 | {
35 | events.Dispose();
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/DanTup.DartVS.Vsix/source.extension.vsixmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | DartVS - Visual Studio support for Google's Dart
6 | Some support for coding Dart in Visual Studio.
7 | https://github.com/DanTup/DartVS/blob/master/README.md
8 | LICENCE.txt
9 | https://github.com/DanTup/DartVS/blob/master/README.md
10 | https://github.com/DanTup/DartVS/releases
11 | Resources\Package.ico
12 | Screenshot.png
13 | dart, google, dartlang, javascript, web
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/DanTup.DartVS.Vsix/DartAnalyzer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using Microsoft.VisualStudio.Shell;
6 |
7 | namespace DanTup.DartVS
8 | {
9 | ///
10 | /// Analyzes a dart file and reports back errors in the form of Visual Studio ErrorTasks.
11 | ///
12 | class DartAnalyzer
13 | {
14 | readonly CommandExecutor commandExecutor = new CommandExecutor();
15 | readonly DartAnalzyerOutputParser outputParser = new DartAnalzyerOutputParser();
16 |
17 | bool hasReportedDartSdkMissing = false;
18 |
19 | public IEnumerable Analyze(string filename)
20 | {
21 | var dartAnalyzerPath = GetDartAnalyzerPath();
22 |
23 | if (!string.IsNullOrWhiteSpace(dartAnalyzerPath))
24 | return AnalyzeFile(dartAnalyzerPath, filename);
25 | else if (!hasReportedDartSdkMissing)
26 | return new[] { new ErrorTask { Text = "The Dart SDK could not be found. Please set the DART_SDK environment variable to the SDK root." } };
27 | else
28 | return Enumerable.Empty();
29 | }
30 |
31 | private static string GetDartAnalyzerPath()
32 | {
33 | // For some reason, if I don't pass User/Machine here, I seem to always get null! :(
34 | var sdkRoot = Environment.GetEnvironmentVariable("DART_SDK", EnvironmentVariableTarget.User)
35 | ?? Environment.GetEnvironmentVariable("DART_SDK", EnvironmentVariableTarget.Machine);
36 | if (sdkRoot == null)
37 | return null;
38 |
39 | var analyzer = Path.Combine(sdkRoot, @"bin\dartanalyzer.bat");
40 | if (File.Exists(analyzer))
41 | return analyzer;
42 | else
43 | return null;
44 | }
45 |
46 | private IEnumerable AnalyzeFile(string dartAnalyzerPath, string filename)
47 | {
48 | var args = string.Format("--fatal-warnings \"{0}\"", filename.Replace("\"", "\\\""));
49 |
50 | var commandOutput = commandExecutor.ExecuteCommand(dartAnalyzerPath, args);
51 |
52 | return outputParser.Parse(commandOutput);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/UpdateVersions.fsx:
--------------------------------------------------------------------------------
1 | // This script copies the version from SharedAssemblyInfo into various other files that
2 | // contain the version, as I couldn't find a nice way to share them :(
3 |
4 | #r "System.Xml.Linq"
5 | open System
6 | open System.IO
7 | open System.Text
8 | open System.Text.RegularExpressions
9 | open System.Xml.Linq
10 |
11 | Directory.SetCurrentDirectory(__SOURCE_DIRECTORY__)
12 | let root = Directory.GetCurrentDirectory()
13 | let sharedAssemblyInfo = "DanTup.DartVS.Vsix\Properties\AssemblyInfo.cs"
14 |
15 | // Get the version from the master file (SharedAssemblyInfo)
16 | let regex pattern input = Regex.Match(input, pattern)
17 | let versionMatch =
18 | File.ReadAllLines(Path.Combine(root, sharedAssemblyInfo))
19 | |> Array.find (fun l -> l.Contains("AssemblyVersion"))
20 | |> regex "\(\"(\d+\.\d+)\."
21 | let version = versionMatch.Groups.[1].Value
22 |
23 |
24 | // Get the files we'll need to update
25 | // Only go on level deep for files; we don't want bin\Debug etc.
26 | let getFiles pattern dir = Directory.GetFiles(dir, pattern)
27 | let manifestFiles = Directory.GetDirectories(root) |> Array.collect (getFiles "*.vsixmanifest")
28 | let packageFiles = Directory.GetDirectories(root) |> Array.collect (getFiles "*Package.cs")
29 |
30 | // Print summary
31 | printfn "Updating %d manifests and %d packages to version: %s" manifestFiles.Length packageFiles.Length version
32 |
33 | // Replace manifest versions
34 | let updateManifest (file : string) =
35 | let xd = XDocument.Load(file, LoadOptions.PreserveWhitespace)
36 | let xname s = XName.Get(s, "http://schemas.microsoft.com/developer/vsx-schema/2011")
37 | let versionAttribute = (xd.Element(xname "PackageManifest").Element(xname "Metadata").Element(xname "Identity").Attribute(XName.Get("Version")))
38 | versionAttribute.Value <- version
39 | xd.Save(file)
40 | manifestFiles |> Array.iter updateManifest
41 |
42 | // Replace package versions
43 | let updatePackage (file : string) =
44 | let replaceVersion (s : string) =
45 | match s with
46 | | s when s.Contains("[InstalledProductRegistration") -> Regex.Replace(s, "\"\\d+\.\d+\"\)]", (sprintf "\"%s\")]" version))
47 | | s -> s
48 | let lines = File.ReadAllLines file
49 | lines |> Array.map replaceVersion |> fun l -> File.WriteAllLines(file, l, Encoding.UTF8)
50 | packageFiles |> Array.iter updatePackage
51 |
--------------------------------------------------------------------------------
/DanTup.DartVS.Vsix/DartAnalyzerErrorService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using Microsoft.VisualStudio.Shell;
6 |
7 | namespace DanTup.DartVS
8 | {
9 | ///
10 | /// Analyzes a dart file and updates the Visual Studio error list with the results.
11 | ///
12 | static class DartAnalyzerErrorService
13 | {
14 | public static void Parse(ErrorListProvider errorListProvider, string path)
15 | {
16 | lock (errorListProvider)
17 | {
18 | // Remove all tasks for the current file, since they're likely out-of-date
19 | // if the user has just saved
20 | RemoveStaleErrors(errorListProvider, path);
21 |
22 | // Show a message that we're executing; since this can be slow. Otherwise we'd
23 | // have to leave known-stale errors, or empty list (which suggests no errors).
24 | errorListProvider.Tasks.Add(new ErrorTask
25 | {
26 | ErrorCategory = TaskErrorCategory.Message,
27 | Document = path,
28 | Text = "Executing DartAnalyzer, please wait..."
29 | });
30 | }
31 |
32 |
33 | IEnumerable errors;
34 | try
35 | {
36 | errors = new DartAnalyzer().Analyze(path);
37 | }
38 | catch (Exception ex)
39 | {
40 | // Update the error list eith the new errors
41 | lock (errorListProvider)
42 | {
43 | RemoveStaleErrors(errorListProvider, path);
44 | errorListProvider.Tasks.Add(new ErrorTask(new Exception("Unable to execute DartAnalzyer: " + ex.ToString())));
45 | errorListProvider.Show();
46 | return;
47 | }
48 | }
49 |
50 | // Update the error list eith the new errors
51 | lock (errorListProvider)
52 | {
53 | RemoveStaleErrors(errorListProvider, path);
54 | foreach (var error in errors)
55 | {
56 | error.Navigate += (s, e) => errorListProvider.Navigate(error, new Guid(EnvDTE.Constants.vsViewKindCode));
57 | errorListProvider.Tasks.Add(error);
58 | }
59 | errorListProvider.Show();
60 | }
61 | }
62 |
63 | private static void RemoveStaleErrors(ErrorListProvider errorListProvider, string path)
64 | {
65 | var staleTasks = errorListProvider.Tasks.OfType().Where(t => t.Document == path).ToArray(); // Force execution so we don't modify while enumerating
66 | foreach (var staleTask in staleTasks)
67 | errorListProvider.Tasks.Remove(staleTask);
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/DanTup.DartVS.Vsix/VsDocumentEvents.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio;
3 | using Microsoft.VisualStudio.Shell;
4 | using Microsoft.VisualStudio.Shell.Interop;
5 |
6 | namespace DanTup.DartVS
7 | {
8 | ///
9 | /// Helper to hide away some of the not-so-elegant VS API for catching Document events.
10 | ///
11 | sealed class VsDocumentEvents : IVsRunningDocTableEvents, IDisposable
12 | {
13 | IVsRunningDocumentTable documentService;
14 | private uint cookie;
15 | public event EventHandler FileSaved;
16 |
17 | public VsDocumentEvents()
18 | {
19 | documentService = Package.GetGlobalService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable;
20 | if (documentService != null)
21 | documentService.AdviseRunningDocTableEvents(this, out cookie);
22 | }
23 |
24 | public void Dispose()
25 | {
26 | if (documentService != null && cookie != 0)
27 | documentService.UnadviseRunningDocTableEvents(cookie);
28 | }
29 |
30 | void OnFileSaved(string filename)
31 | {
32 | var handler = FileSaved;
33 | if (handler != null)
34 | handler(this, filename);
35 | }
36 |
37 | #region IVsRunningDocTableEvents Events
38 |
39 | public int OnAfterSave(uint docCookie)
40 | {
41 | string filename;
42 |
43 | uint pgrfRDTFlags, pdwReadLocks, pdwEditLocks;
44 | IVsHierarchy ppHier;
45 | uint pitemid;
46 | IntPtr ppunkDocData;
47 | documentService.GetDocumentInfo(docCookie, out pgrfRDTFlags, out pdwReadLocks, out pdwEditLocks, out filename, out ppHier, out pitemid, out ppunkDocData);
48 |
49 | OnFileSaved(filename);
50 |
51 | return VSConstants.S_OK;
52 | }
53 |
54 | #region Events we don't care about
55 |
56 | public int OnAfterAttributeChange(uint docCookie, uint grfAttribs)
57 | {
58 | return VSConstants.S_OK;
59 | }
60 |
61 | public int OnAfterDocumentWindowHide(uint docCookie, IVsWindowFrame pFrame)
62 | {
63 | return VSConstants.S_OK;
64 | }
65 |
66 | public int OnAfterFirstDocumentLock(uint docCookie, uint dwRDTLockType, uint dwReadLocksRemaining, uint dwEditLocksRemaining)
67 | {
68 | return VSConstants.S_OK;
69 | }
70 |
71 | public int OnBeforeDocumentWindowShow(uint docCookie, int fFirstShow, IVsWindowFrame pFrame)
72 | {
73 | return VSConstants.S_OK;
74 | }
75 |
76 | public int OnBeforeLastDocumentUnlock(uint docCookie, uint dwRDTLockType, uint dwReadLocksRemaining, uint dwEditLocksRemaining)
77 | {
78 | return VSConstants.S_OK;
79 | }
80 |
81 | #endregion
82 |
83 | #endregion
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/DanTup.DartVS.Vsix/Classify/DartClassifier.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text.RegularExpressions;
5 | using Microsoft.VisualStudio.Language.StandardClassification;
6 | using Microsoft.VisualStudio.Text;
7 | using Microsoft.VisualStudio.Text.Classification;
8 |
9 | namespace DanTup.DartVS
10 | {
11 | class DartClassifier : IClassifier
12 | {
13 | private static Regex _rxKeywords = new Regex(@"(var|import|class|super|library|new|with|extends|factory|if|else|throw|static|show)", RegexOptions.Compiled);
14 | private static Regex _rxIdentifier = new Regex(@"(int|bool|String|void|num|@\w+)", RegexOptions.Compiled);
15 | private static Regex _rxString = new Regex(@"'([^']+)'", RegexOptions.Compiled);
16 | private static Regex _rxComment = new Regex("//.*", RegexOptions.Compiled);
17 | private Dictionary _map;
18 |
19 | public DartClassifier(IClassificationTypeRegistryService registry)
20 | {
21 | _map = new Dictionary
22 | {
23 | {_rxComment, registry.GetClassificationType(PredefinedClassificationTypeNames.Comment)},
24 | {_rxString, registry.GetClassificationType(PredefinedClassificationTypeNames.String)},
25 | {_rxIdentifier, registry.GetClassificationType(PredefinedClassificationTypeNames.SymbolDefinition)},
26 | {_rxKeywords, registry.GetClassificationType(PredefinedClassificationTypeNames.Keyword)},
27 | };
28 | }
29 |
30 | public IList GetClassificationSpans(SnapshotSpan span)
31 | {
32 | IList list = new List();
33 | string text = span.GetText(); // the span is always a single line
34 |
35 | foreach (Regex regex in _map.Keys)
36 | foreach (Match match in regex.Matches(text))
37 | {
38 | var str = new SnapshotSpan(span.Snapshot, span.Start.Position + match.Index, match.Length);
39 |
40 | // Make sure we don't double classify
41 | if (list.Any(s => s.Span.IntersectsWith(str)))
42 | continue;
43 |
44 | list.Add(new ClassificationSpan(str, _map[regex]));
45 | }
46 |
47 | return list;
48 | }
49 |
50 | public event EventHandler ClassificationChanged
51 | {
52 | add { }
53 | remove { }
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/DanTup.DartVS.Vsix/DartAnalzyerOutputParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text.RegularExpressions;
5 | using Microsoft.VisualStudio.Shell;
6 |
7 | namespace DanTup.DartVS
8 | {
9 | ///
10 | /// Parses the output of DartAnalyzer into Visual Studio ErrorTasks.
11 | ///
12 | class DartAnalzyerOutputParser
13 | {
14 | static readonly Regex dartAnazlyserOutputLine = new Regex(@"^\[(\w+)\] (.+) \((.+), line (\d+), col (\d+)\)$", RegexOptions.Compiled);
15 |
16 | public IEnumerable Parse(string output)
17 | {
18 | // Analyzing [M:\Coding\TestApps\DartTests\Script.dart]...
19 | // No issues found
20 |
21 | // Analyzing [M:\Coding\TestApps\DartTests\Script.dart]...
22 | // [warning] Undefined name 'window2' (M:\Coding\TestApps\DartTests\Script.dart, line 4, col 2)
23 | // [hint] Unused import (M:\Coding\TestApps\DartTests\Script.dart, line 1, col 8)
24 | // 1 error found.
25 |
26 | // Analyzing [M:\Coding\TestApps\DartTests\Script.dart]...
27 | // [error] Expected to find ';' (M:\Coding\TestApps\DartTests\Script.dart, line 4, col 16)
28 | // [error] Expected to find ')' (M:\Coding\TestApps\DartTests\Script.dart, line 4, col 19)
29 | // [error] Expected to find ';' (M:\Coding\TestApps\DartTests\Script.dart, line 4, col 19)
30 | // [error] Expected an identifier (M:\Coding\TestApps\DartTests\Script.dart, line 4, col 24)
31 | // [error] Expected to find ';' (M:\Coding\TestApps\DartTests\Script.dart, line 4, col 24)
32 | // [error] Unexpected token ',' (M:\Coding\TestApps\DartTests\Script.dart, line 4, col 24)
33 | // [error] Expected to find ';' (M:\Coding\TestApps\DartTests\Script.dart, line 4, col 26)
34 | // [error] Expected to find ';' (M:\Coding\TestApps\DartTests\Script.dart, line 4, col 31)
35 | // [error] Unterminated string literal (M:\Coding\TestApps\DartTests\Script.dart, line 4, col 34)
36 | // [warning] Undefined name 'window2' (M:\Coding\TestApps\DartTests\Script.dart, line 4, col 2)
37 | // [warning] Undefined name 'Hello' (M:\Coding\TestApps\DartTests\Script.dart, line 4, col 19)
38 | // [warning] Undefined name 'world' (M:\Coding\TestApps\DartTests\Script.dart, line 4, col 26)
39 | // [hint] Unused import (M:\Coding\TestApps\DartTests\Script.dart, line 1, col 8)
40 | // 12 errors found.
41 |
42 | Func isIssue = l => l.StartsWith("[error]") || l.StartsWith("[warning]") || l.StartsWith("[hint]");
43 | Func createTask = l =>
44 | {
45 | var match = dartAnazlyserOutputLine.Match(l);
46 |
47 | return new ErrorTask
48 | {
49 | ErrorCategory =
50 | match.Groups[1].Value == "hint"
51 | ? TaskErrorCategory.Message
52 | : match.Groups[1].Value == "warning"
53 | ? TaskErrorCategory.Warning
54 | : TaskErrorCategory.Error,
55 | Text = match.Groups[2].Value,
56 | Document = match.Groups[3].Value,
57 | Line = int.Parse(match.Groups[4].Value),
58 | Column = int.Parse(match.Groups[5].Value),
59 | };
60 | };
61 |
62 | return output
63 | .Split('\n')
64 | .Select(l => l.Trim())
65 | .Where(isIssue)
66 | .Select(createTask);
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 | packages/
22 |
23 | # Locally stored "Eclipse launch configurations"
24 | *.launch
25 |
26 | # CDT-specific
27 | .cproject
28 |
29 | # PDT-specific
30 | .buildpath
31 |
32 |
33 | #################
34 | ## Visual Studio
35 | #################
36 |
37 | ## Ignore Visual Studio temporary files, build results, and
38 | ## files generated by popular Visual Studio add-ons.
39 |
40 | # User-specific files
41 | *.suo
42 | *.user
43 | *.sln.docstates
44 |
45 | # Build results
46 |
47 | [Dd]ebug/
48 | [Rr]elease/
49 | x64/
50 | [Bb]in/
51 | [Oo]bj/
52 |
53 | # MSTest test Results
54 | [Tt]est[Rr]esult*/
55 | [Bb]uild[Ll]og.*
56 |
57 | *_i.c
58 | *_p.c
59 | *.ilk
60 | *.meta
61 | *.obj
62 | *.pch
63 | *.pdb
64 | *.pgc
65 | *.pgd
66 | *.rsp
67 | *.sbr
68 | *.tlb
69 | *.tli
70 | *.tlh
71 | *.tmp
72 | *.tmp_proj
73 | *.log
74 | *.vspscc
75 | *.vssscc
76 | .builds
77 | *.pidb
78 | *.log
79 | *.scc
80 |
81 | # Visual C++ cache files
82 | ipch/
83 | *.aps
84 | *.ncb
85 | *.opensdf
86 | *.sdf
87 | *.cachefile
88 |
89 | # Visual Studio profiler
90 | *.psess
91 | *.vsp
92 | *.vspx
93 |
94 | # Guidance Automation Toolkit
95 | *.gpState
96 |
97 | # ReSharper is a .NET coding add-in
98 | _ReSharper*/
99 | *.[Rr]e[Ss]harper
100 |
101 | # TeamCity is a build add-in
102 | _TeamCity*
103 |
104 | # DotCover is a Code Coverage Tool
105 | *.dotCover
106 |
107 | # NCrunch
108 | .*crunch*.local.xml
109 | _NCrunch*
110 |
111 | # Installshield output folder
112 | [Ee]xpress/
113 |
114 | # DocProject is a documentation generator add-in
115 | DocProject/buildhelp/
116 | DocProject/Help/*.HxT
117 | DocProject/Help/*.HxC
118 | DocProject/Help/*.hhc
119 | DocProject/Help/*.hhk
120 | DocProject/Help/*.hhp
121 | DocProject/Help/Html2
122 | DocProject/Help/html
123 |
124 | # Click-Once directory
125 | publish/
126 |
127 | # Publish Web Output
128 | *.Publish.xml
129 | *.pubxml
130 |
131 | # NuGet Packages Directory
132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
133 | #packages/
134 |
135 | # Windows Azure Build Output
136 | csx
137 | *.build.csdef
138 |
139 | # Windows Store app package directory
140 | AppPackages/
141 |
142 | # Others
143 | *.ide
144 | sql/
145 | *.Cache
146 | ClientBin/
147 | [Ss]tyle[Cc]op.*
148 | ~$*
149 | *~
150 | *.dbmdl
151 | *.[Pp]ublish.xml
152 | *.pfx
153 | *.publishsettings
154 |
155 | # RIA/Silverlight projects
156 | Generated_Code/
157 |
158 | # Backup & report files from converting an old project file to a newer
159 | # Visual Studio version. Backup files are not needed, because we have git ;-)
160 | _UpgradeReport_Files/
161 | Backup*/
162 | UpgradeLog*.XML
163 | UpgradeLog*.htm
164 |
165 | # SQL Server files
166 | App_Data/*.mdf
167 | App_Data/*.ldf
168 |
169 | #############
170 | ## Windows detritus
171 | #############
172 |
173 | # Windows image file caches
174 | Thumbs.db
175 | ehthumbs.db
176 |
177 | # Folder config file
178 | Desktop.ini
179 |
180 | # Recycle Bin used on file shares
181 | $RECYCLE.BIN/
182 |
183 | # Mac crap
184 | .DS_Store
185 |
186 |
187 | #############
188 | ## Python
189 | #############
190 |
191 | *.py[co]
192 |
193 | # Packages
194 | *.egg
195 | *.egg-info
196 | dist/
197 | eggs/
198 | parts/
199 | var/
200 | sdist/
201 | develop-eggs/
202 | .installed.cfg
203 |
204 | # Installer logs
205 | pip-log.txt
206 |
207 | # Unit test / coverage reports
208 | .coverage
209 | .tox
210 |
211 | #Translations
212 | *.mo
213 |
214 | #Mr Developer
215 | .mr.developer.cfg
216 |
217 | # nodejs resources
218 | EditorExtensions/Resources/nodejs/
219 |
220 | # MergeTools
221 | *.orig
222 |
--------------------------------------------------------------------------------
/DanTup.DartVS.Vsix/DanTup.DartVS.Vsix.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 12.0
5 | 12.0
6 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
7 | Program
8 | $(DevEnvDir)\devenv.exe
9 | /rootsuffix Exp
10 | Normal
11 |
12 |
13 |
14 | Debug
15 | AnyCPU
16 | 2.0
17 | {CFC8B136-5D0D-4439-9373-E7B1CA027118}
18 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
19 | Library
20 | Properties
21 | DanTup.DartVS
22 | DanTup.DartVS.Vsix
23 | false
24 |
25 |
26 | v4.5
27 |
28 |
29 | true
30 | full
31 | false
32 | bin\Debug\
33 | DEBUG;TRACE
34 | prompt
35 | 4
36 | True
37 |
38 |
39 | pdbonly
40 | true
41 | bin\Release\
42 | TRACE
43 | prompt
44 | 4
45 | true
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | true
58 |
59 |
60 | true
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | {80CC9F66-E7D8-4DDD-85B6-D9E6CD0E93E2}
78 | 8
79 | 0
80 | 0
81 | primary
82 | False
83 | False
84 |
85 |
86 | {26AD1324-4B7C-44BC-84F8-B86AED45729F}
87 | 10
88 | 0
89 | 0
90 | primary
91 | False
92 | False
93 |
94 |
95 | {1A31287A-4D7D-413E-8E32-3B374931BD89}
96 | 8
97 | 0
98 | 0
99 | primary
100 | False
101 | False
102 |
103 |
104 | {2CE2370E-D744-4936-A090-3FFFE667B0E1}
105 | 9
106 | 0
107 | 0
108 | primary
109 | False
110 | False
111 |
112 |
113 | {1CBA492E-7263-47BB-87FE-639000619B15}
114 | 8
115 | 0
116 | 0
117 | primary
118 | False
119 | False
120 |
121 |
122 | {00020430-0000-0000-C000-000000000046}
123 | 2
124 | 0
125 | 0
126 | primary
127 | False
128 | False
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 | Designer
146 |
147 |
148 |
149 |
150 | Always
151 | true
152 |
153 |
154 | Always
155 | true
156 |
157 |
158 | Always
159 | true
160 |
161 |
162 |
163 | true
164 |
165 |
166 |
167 |
174 |
--------------------------------------------------------------------------------