public async Task <CodeAnalysisResults> RunCodeAnalysisAsync(ISourceFile file, List <UnsavedFile> unsavedFiles, Func <bool> interruptRequested) { var result = new CodeAnalysisResults(); var dataAssociation = GetAssociatedData(file); var response = await dataAssociation.Solution.Server.Highlight(file.FilePath, unsavedFiles.FirstOrDefault()?.Contents); if (response != null) { foreach (var highlight in response.Highlights) { result.SyntaxHighlightingData.Add(new LineColumnSyntaxHighlightingData { StartLine = highlight.StartLine, EndLine = highlight.EndLine, StartColumn = highlight.StartColumn, EndColumn = highlight.EndColumn, Type = ToAvalonHighlightType(highlight.Kind) }); } dataAssociation.TextColorizer.SetTransformations(result.SyntaxHighlightingData); } return(result); }
public async Task <CodeAnalysisResults> RunCodeAnalysisAsync(IEditor editor, List <UnsavedFile> unsavedFiles, Func <bool> interruptRequested) { var result = new CodeAnalysisResults(); var textLength = 0; await Dispatcher.UIThread.InvokeAsync(() => { textLength = editor.Document.TextLength; }); var dataAssociation = GetAssociatedData(editor); var document = GetDocument(dataAssociation, editor.SourceFile); if (document == null) { return(result); } // Example how to get file specific diagnostics. /*var model = await document.GetSemanticModelAsync(); * * var diagnostics = model.GetDiagnostics();*/ try { var highlightData = await Classifier.GetClassifiedSpansAsync(document, new Microsoft.CodeAnalysis.Text.TextSpan(0, textLength)); foreach (var span in highlightData) { result.SyntaxHighlightingData.Add(new OffsetSyntaxHighlightingData { Start = span.TextSpan.Start, Length = span.TextSpan.Length, Type = FromRoslynType(span.ClassificationType) }); } } catch (NullReferenceException) { } result.IndexItems = await IndexBuilder.Compute(document); return(result); }
public async Task <CodeAnalysisResults> RunCodeAnalysisAsync(IEnumerable <UnsavedFile> unsavedFiles, Func <bool> interruptRequested) { var result = new CodeAnalysisResults(); var clangUnsavedFiles = new List <ClangUnsavedFile>(); clangUnsavedFiles.AddRange(unsavedFiles.Select(f => new ClangUnsavedFile(f.FileName, f.Contents))); var diagnostics = new List <Diagnostic>(); await clangAccessJobRunner.InvokeAsync(() => { try { var translationUnit = GetAndParseTranslationUnit(clangUnsavedFiles); if (translationUnit != null) { if (_editor.SourceFile != null && translationUnit != null) { ScanTokens(translationUnit, result.SyntaxHighlightingData); GenerateHighlightData(translationUnit.GetCursor(), result.SyntaxHighlightingData, result.IndexItems); } GenerateDiagnostics(translationUnit.DiagnosticSet.Items, translationUnit, _editor.SourceFile, diagnostics); } } catch (Exception) { } }); var errorList = IoC.Get <IErrorList>(); errorList.Remove((this, _editor.SourceFile)); errorList.Create((this, _editor.SourceFile), _editor.SourceFile.FilePath, DiagnosticSourceKind.Analysis, diagnostics.ToImmutableArray()); return(result); }
public async Task <CodeAnalysisResults> RunCodeAnalysisAsync(ISourceFile file, List <UnsavedFile> unsavedFiles, Func <bool> interruptRequested) { var result = new CodeAnalysisResults(); var dataAssociation = GetAssociatedData(file); var clangUnsavedFiles = new List <ClangUnsavedFile>(); clangUnsavedFiles.AddRange(unsavedFiles.Select(f => new ClangUnsavedFile(f.FileName, f.Contents))); await clangAccessJobRunner.InvokeAsync(() => { try { var translationUnit = GetAndParseTranslationUnit(file, clangUnsavedFiles); if (translationUnit != null) { if (file != null && translationUnit != null) { ScanTokens(translationUnit, result.SyntaxHighlightingData); GenerateHighlightData(translationUnit.GetCursor(), result.SyntaxHighlightingData); } dataAssociation.TextMarkerService.Clear(); GenerateDiagnostics(translationUnit.DiagnosticSet.Items, translationUnit, file.Project, result.Diagnostics, dataAssociation.TextMarkerService); } } catch (Exception e) { } }); dataAssociation.TextColorizer.SetTransformations(result.SyntaxHighlightingData); return(result); }
public async Task <CodeAnalysisResults> RunCodeAnalysisAsync(IEditor editor, List <UnsavedFile> unsavedFiles, Func <bool> interruptRequested) { var result = new CodeAnalysisResults(); var dataAssociation = GetAssociatedData(editor.SourceFile); var clangUnsavedFiles = new List <ClangUnsavedFile>(); clangUnsavedFiles.AddRange(unsavedFiles.Select(f => new ClangUnsavedFile(f.FileName, f.Contents))); var diagnostics = new List <Diagnostic>(); await clangAccessJobRunner.InvokeAsync(() => { try { var translationUnit = GetAndParseTranslationUnit(editor, clangUnsavedFiles); if (translationUnit != null) { if (editor.SourceFile != null && translationUnit != null) { ScanTokens(translationUnit, result.SyntaxHighlightingData); GenerateHighlightData(translationUnit.GetCursor(), result.SyntaxHighlightingData, result.IndexItems); } GenerateDiagnostics(translationUnit.DiagnosticSet.Items, translationUnit, editor.SourceFile, diagnostics); } } catch (Exception e) { } }); DiagnosticsUpdated?.Invoke(this, new DiagnosticsUpdatedEventArgs(this, editor.SourceFile, diagnostics.Count > 0 ? DiagnosticsUpdatedKind.DiagnosticsCreated : DiagnosticsUpdatedKind.DiagnosticsRemoved, diagnostics.ToImmutableArray())); return(result); }
private void HighlightNode(INode node, CodeAnalysisResults result) { var highlightData = new OffsetSyntaxHighlightingData(); int startPos = 0, endPos = 0; // This will add highlighting data for declarations, but it will not show up because it is set to highlight as None if (node is IDeclaration) { var declaration = (IDeclaration)node; startPos = declaration.Position; endPos = declaration.End; if (startPos >= 0 && endPos > 0) { if (node is VariableDeclaration) { // For variables, we only want to highlight the name, not the expression startPos = ((VariableDeclaration)node).Name.Position; endPos = ((VariableDeclaration)node).Name.End; } else if (node is ClassDeclaration) { // For classes, we only want to highlight the name, not the entire contents startPos = ((ClassDeclaration)node).Name.Position; endPos = ((ClassDeclaration)node).Name.End; } else if (node is FunctionDeclaration) { // For functions, we only want to highlight the name, not the body startPos = ((FunctionDeclaration)node).Name.Position; endPos = ((FunctionDeclaration)node).Name.End; } highlightData.Start = startPos; highlightData.Length = endPos - startPos; result.SyntaxHighlightingData.Add(highlightData); } } // Originally, we meant to highlight CallExpression // We are leaving this out because the language service // marks the entire call, including the parameters, as part // of the call. This ends up looking weird. //else if (node is ExpressionStatement) //{ // var expressionNode = ((ExpressionStatement)node).Expression; // // TODO: Highlight expressions // if (expressionNode.Kind == SyntaxKind.CallExpression) // { // startPos = expressionNode.Position; // endPos = expressionNode.End; // highlightData.Type = HighlightType.CallExpression; // } // highlightData.Start = startPos; // highlightData.Length = endPos - startPos; // result.SyntaxHighlightingData.Add(highlightData); //} // This section will adjust highlight data, and set the highlight type switch (node.Kind) { case SyntaxKind.ClassDeclaration: var classDeclaration = node as ClassDeclaration; highlightData.Type = HighlightType.ClassName; foreach (var member in classDeclaration.Members) { HighlightNode(member, result); } break; case SyntaxKind.MethodDeclaration: var methodDeclaration = node as MethodDeclaration; highlightData.Type = HighlightType.Identifier; // TODO: Child nodes foreach (var statement in methodDeclaration.Body.Statements) { HighlightNode(statement, result); } break; case SyntaxKind.Constructor: highlightData.Type = HighlightType.Identifier; break; case SyntaxKind.VariableStatement: var variableStatement = node as VariableStatement; foreach (var declaration in variableStatement.DeclarationList.Declarations) { HighlightNode(declaration, result); } break; case SyntaxKind.VariableDeclaration: highlightData.Type = HighlightType.Identifier; break; default: // lol break; } }
public async Task <CodeAnalysisResults> RunCodeAnalysisAsync(ISourceFile file, List <UnsavedFile> unsavedFiles, Func <bool> interruptRequested) { var result = new CodeAnalysisResults(); var dataAssociation = GetAssociatedData(file); var currentUnsavedFile = unsavedFiles.FirstOrDefault(f => f.FileName == file.FilePath); var currentFileConts = currentUnsavedFile?.Contents ?? File.ReadAllText(file.FilePath); var currentFileName = currentUnsavedFile?.FileName ?? file.FilePath; TypeScriptSyntaxTree syntaxTree; // Only one analyzer at a time; the JS engine is single-threaded. TODO: Workaround with multiple JS engines await analysisThreadSemaphore.WaitAsync(); try { syntaxTree = await _typeScriptContext.BuildAstAsync(currentFileName, currentFileConts); } catch (JavaScriptException) { return(new CodeAnalysisResults { Diagnostics = new TextSegmentCollection <Diagnostic> { new Diagnostic { Project = file.Project, Line = 1, Spelling = "Code analysis language service call failed.", StartOffset = 0, File = file.Name, Level = DiagnosticLevel.Error, } } }); } finally { analysisThreadSemaphore.Release(); } #if DEBUG var syntaxTreeJsonDebug = JsonConvert.SerializeObject(syntaxTree); #endif var lineCommentMatches = LineCommentPattern.Matches(currentFileConts); foreach (Match commentMatch in lineCommentMatches) { result.SyntaxHighlightingData.Add(new OffsetSyntaxHighlightingData { Start = commentMatch.Index, Length = commentMatch.Length, Type = HighlightType.Comment }); } var blockCommentMatches = BlockCommentPattern.Matches(currentFileConts); foreach (Match commentMatch in blockCommentMatches) { result.SyntaxHighlightingData.Add(new OffsetSyntaxHighlightingData { Start = commentMatch.Index, Length = commentMatch.Length, Type = HighlightType.Comment }); } // Highlight keywords var keywordMatches = KeywordPattern.Matches(currentFileConts); foreach (Match keywordMatch in keywordMatches) { result.SyntaxHighlightingData.Add(new OffsetSyntaxHighlightingData { Start = keywordMatch.Index, Length = keywordMatch.Length, Type = HighlightType.Keyword }); } // Recursively highlight and analyze from parse tree foreach (var rootStatement in syntaxTree.Statements) { HighlightNode(rootStatement, result); } // Diagnostics // Language service has diagnostics foreach (var diagnostic in syntaxTree.ParseDiagnostics) { // Convert diagnostics result.Diagnostics.Add(new Diagnostic { Project = file.Project, Line = GetLineNumber(currentFileConts, diagnostic.Start), // TODO StartOffset = diagnostic.Start, EndOffset = diagnostic.Start + diagnostic.Length, Spelling = diagnostic.MessageText, Level = diagnostic.Category == TSBridge.Ast.Diagnostics.Diagnostic.DiagnosticCategory.Error ? DiagnosticLevel.Error : DiagnosticLevel.Warning }); } result.Diagnostics.Add(new Diagnostic { Project = file.Project, Line = 1, Spelling = "Code analysis for TypeScript is experimental and unstable. Use with caution.", StartOffset = 0, File = file.Name, Level = DiagnosticLevel.Warning, }); return(result); }
public async Task <CodeAnalysisResults> RunCodeAnalysisAsync(ISourceFile file, List <UnsavedFile> unsavedFiles, Func <bool> interruptRequested) { var result = new CodeAnalysisResults(); var dataAssociation = GetAssociatedData(file); var clangUnsavedFiles = new List <ClangUnsavedFile>(); foreach (var unsavedFile in unsavedFiles) { clangUnsavedFiles.Add(new ClangUnsavedFile(unsavedFile.FileName, unsavedFile.Contents)); } await clangAccessJobRunner.InvokeAsync(() => { var translationUnit = GetAndParseTranslationUnit(file, clangUnsavedFiles); if (file != null) { var callbacks = new ClangIndexerCallbacks(); callbacks.IndexDeclaration += (handle, e) => { if (e.Cursor.Spelling != null && e.Location.SourceLocation.IsFromMainFile) { switch (e.Cursor.Kind) { case NClang.CursorKind.FunctionDeclaration: case NClang.CursorKind.CXXMethod: case NClang.CursorKind.Constructor: case NClang.CursorKind.Destructor: case NClang.CursorKind.VarDeclaration: case NClang.CursorKind.ParmDeclaration: case NClang.CursorKind.StructDeclaration: case NClang.CursorKind.ClassDeclaration: case NClang.CursorKind.TypedefDeclaration: case NClang.CursorKind.ClassTemplate: case NClang.CursorKind.EnumDeclaration: case NClang.CursorKind.UnionDeclaration: result.IndexItems.Add(new IndexEntry(e.Cursor.Spelling, e.Cursor.CursorExtent.Start.FileLocation.Offset, e.Cursor.CursorExtent.End.FileLocation.Offset, (CursorKind)e.Cursor.Kind)); break; } switch (e.Cursor.Kind) { case NClang.CursorKind.StructDeclaration: case NClang.CursorKind.ClassDeclaration: case NClang.CursorKind.TypedefDeclaration: case NClang.CursorKind.ClassTemplate: case NClang.CursorKind.EnumDeclaration: case NClang.CursorKind.UnionDeclaration: case NClang.CursorKind.CXXBaseSpecifier: result.SyntaxHighlightingData.Add(new OffsetSyntaxHighlightingData { Start = e.Cursor.CursorExtent.Start.FileLocation.Offset, Length = e.Cursor.CursorExtent.End.FileLocation.Offset - e.Cursor.CursorExtent.Start.FileLocation.Offset, Type = HighlightType.ClassName }); break; } } }; callbacks.IndexEntityReference += (handle, e) => { if (e.Cursor.Spelling != null && e.Location.SourceLocation.IsFromMainFile) { switch (e.Cursor.Kind) { case NClang.CursorKind.TypeReference: case NClang.CursorKind.CXXBaseSpecifier: case NClang.CursorKind.TemplateReference: result.SyntaxHighlightingData.Add(new OffsetSyntaxHighlightingData { Start = e.Cursor.CursorExtent.Start.FileLocation.Offset, Length = e.Cursor.CursorExtent.End.FileLocation.Offset - e.Cursor.CursorExtent.Start.FileLocation.Offset, Type = HighlightType.ClassName }); break; } } }; if (translationUnit != null) { var tokens = translationUnit.Tokenize(translationUnit.GetCursor().CursorExtent); //var annotatedTokens = tokens.Annotate(); //TODO see if this can provide us with additional data. foreach (var token in tokens.Tokens) { var highlightData = new OffsetSyntaxHighlightingData(); highlightData.Start = token.Extent.Start.FileLocation.Offset; highlightData.Length = token.Extent.End.FileLocation.Offset - highlightData.Start; switch (token.Kind) { case TokenKind.Comment: highlightData.Type = HighlightType.Comment; break; case TokenKind.Identifier: highlightData.Type = HighlightType.Identifier; break; case TokenKind.Punctuation: highlightData.Type = HighlightType.Punctuation; break; case TokenKind.Keyword: highlightData.Type = HighlightType.Keyword; break; case TokenKind.Literal: highlightData.Type = HighlightType.Literal; break; } result.SyntaxHighlightingData.Add(highlightData); } var indexAction = index.CreateIndexAction(); indexAction.IndexTranslationUnit(IntPtr.Zero, new[] { callbacks }, IndexOptionFlags.SkipParsedBodiesInSession, translationUnit); indexAction.Dispose(); } } dataAssociation.TextMarkerService.Clear(); var diags = translationUnit.DiagnosticSet.Items; foreach (var diagnostic in diags) { if (diagnostic.Location.IsFromMainFile) { var diag = new Diagnostic { Project = file.Project, StartOffset = diagnostic.Location.FileLocation.Offset, Line = diagnostic.Location.FileLocation.Line, Spelling = diagnostic.Spelling, File = diagnostic.Location.FileLocation.File.FileName, Level = (DiagnosticLevel)diagnostic.Severity }; result.Diagnostics.Add(diag); var data = dataAssociation.TranslationUnit.GetLocationForOffset(dataAssociation.TranslationUnit.GetFile(file.Location), diag.StartOffset); var length = 0; if (diagnostic.RangeCount > 0) { length = Math.Abs(diagnostic.GetDiagnosticRange(0).End.FileLocation.Offset - diag.StartOffset); } if (diagnostic.FixItCount > 0) { // TODO implement fixits. } Color markerColor; switch (diag.Level) { case DiagnosticLevel.Error: case DiagnosticLevel.Fatal: markerColor = Color.FromRgb(253, 45, 45); break; case DiagnosticLevel.Warning: markerColor = Color.FromRgb(255, 207, 40); break; default: markerColor = Color.FromRgb(0, 42, 74); break; } dataAssociation.TextMarkerService.Create(diag.StartOffset, length, diag.Spelling, markerColor); } } }); dataAssociation.TextColorizer.SetTransformations(result.SyntaxHighlightingData); return(result); }
public async Task<CodeAnalysisResults> RunCodeAnalysisAsync(ISourceFile file, List<UnsavedFile> unsavedFiles, Func<bool> interruptRequested) { var result = new CodeAnalysisResults(); var dataAssociation = GetAssociatedData(file); var response = await dataAssociation.Solution.Server.Highlight(file.FilePath, unsavedFiles.FirstOrDefault()?.Contents); if (response != null) { foreach (var highlight in response.Highlights) { result.SyntaxHighlightingData.Add(new LineColumnSyntaxHighlightingData { StartLine = highlight.StartLine, EndLine = highlight.EndLine, StartColumn = highlight.StartColumn, EndColumn = highlight.EndColumn, Type = ToAvalonHighlightType(highlight.Kind) }); } dataAssociation.TextColorizer.SetTransformations(result.SyntaxHighlightingData); } return result; }
public async Task <CodeAnalysisResults> RunCodeAnalysisAsync(ISourceFile file, List <UnsavedFile> unsavedFiles, Func <bool> interruptRequested) { var result = new CodeAnalysisResults(); var dataAssociation = GetAssociatedData(file); var clangUnsavedFiles = new List <ClangUnsavedFile>(); foreach (var unsavedFile in unsavedFiles) { clangUnsavedFiles.Add(new ClangUnsavedFile(unsavedFile.FileName, unsavedFile.Contents)); } await clangAccessJobRunner.InvokeAsync(() => { var translationUnit = GetAndParseTranslationUnit(file, clangUnsavedFiles); if (file != null) { if (translationUnit != null) { ScanTokens(translationUnit, result.SyntaxHighlightingData); var cursor = translationUnit.GetCursor(); cursor.VisitChildren((current, parent, ptr) => { if (current.Location.IsFromMainFile) { var highlight = CreateOffsetData(current, parent); if (highlight != null) { result.SyntaxHighlightingData.Add(highlight); } return(ChildVisitResult.Recurse); } if (current.Location.IsInSystemHeader) { return(ChildVisitResult.Continue); } return(ChildVisitResult.Recurse); }, IntPtr.Zero); } } dataAssociation.TextMarkerService.Clear(); var diags = translationUnit.DiagnosticSet.Items; foreach (var diagnostic in diags) { if (diagnostic.Location.IsFromMainFile) { var diag = new Diagnostic { Project = file.Project, StartOffset = diagnostic.Location.FileLocation.Offset, Line = diagnostic.Location.FileLocation.Line, Spelling = diagnostic.Spelling, File = diagnostic.Location.FileLocation.File.FileName, Level = (DiagnosticLevel)diagnostic.Severity }; var cursor = translationUnit.GetCursor(diagnostic.Location); var tokens = translationUnit.Tokenize(cursor.CursorExtent); foreach (var token in tokens.Tokens) { if (token.Location == diagnostic.Location) { diag.EndOffset = diag.StartOffset + token.Spelling.Length; } } result.Diagnostics.Add(diag); tokens.Dispose(); Color markerColor; switch (diag.Level) { case DiagnosticLevel.Error: case DiagnosticLevel.Fatal: markerColor = Color.FromRgb(253, 45, 45); break; case DiagnosticLevel.Warning: markerColor = Color.FromRgb(255, 207, 40); break; default: markerColor = Color.FromRgb(0, 42, 74); break; } dataAssociation.TextMarkerService.Create(diag.StartOffset, diag.Length, diag.Spelling, markerColor); } } }); dataAssociation.TextColorizer.SetTransformations(result.SyntaxHighlightingData); return(result); }
public async Task<CodeAnalysisResults> RunCodeAnalysisAsync(ISourceFile file, List<UnsavedFile> unsavedFiles, Func<bool> interruptRequested) { var result = new CodeAnalysisResults(); var dataAssociation = GetAssociatedData(file); var clangUnsavedFiles = new List<ClangUnsavedFile>(); foreach (var unsavedFile in unsavedFiles) { clangUnsavedFiles.Add(new ClangUnsavedFile(unsavedFile.FileName, unsavedFile.Contents)); } await clangAccessJobRunner.InvokeAsync(() => { var translationUnit = GetAndParseTranslationUnit(file, clangUnsavedFiles); if (file != null) { if (translationUnit != null) { ScanTokens(translationUnit, result.SyntaxHighlightingData); var cursor = translationUnit.GetCursor(); cursor.VisitChildren((current, parent, ptr) => { if (current.Location.IsFromMainFile) { var highlight = CreateOffsetData(current, parent); if (highlight != null) { result.SyntaxHighlightingData.Add(highlight); } return ChildVisitResult.Recurse; } if(current.Location.IsInSystemHeader) { return ChildVisitResult.Continue; } return ChildVisitResult.Recurse; }, IntPtr.Zero); } } dataAssociation.TextMarkerService.Clear(); var diags = translationUnit.DiagnosticSet.Items; foreach (var diagnostic in diags) { if (diagnostic.Location.IsFromMainFile) { var diag = new Diagnostic { Project = file.Project, StartOffset = diagnostic.Location.FileLocation.Offset, Line = diagnostic.Location.FileLocation.Line, Spelling = diagnostic.Spelling, File = diagnostic.Location.FileLocation.File.FileName, Level = (DiagnosticLevel)diagnostic.Severity }; var cursor = translationUnit.GetCursor(diagnostic.Location); var tokens = translationUnit.Tokenize(cursor.CursorExtent); foreach (var token in tokens.Tokens) { if (token.Location == diagnostic.Location) { diag.EndOffset = diag.StartOffset + token.Spelling.Length; } } result.Diagnostics.Add(diag); tokens.Dispose(); Color markerColor; switch (diag.Level) { case DiagnosticLevel.Error: case DiagnosticLevel.Fatal: markerColor = Color.FromRgb(253, 45, 45); break; case DiagnosticLevel.Warning: markerColor = Color.FromRgb(255, 207, 40); break; default: markerColor = Color.FromRgb(0, 42, 74); break; } dataAssociation.TextMarkerService.Create(diag.StartOffset, diag.Length, diag.Spelling, markerColor); } } }); dataAssociation.TextColorizer.SetTransformations(result.SyntaxHighlightingData); return result; }
public async Task <CodeAnalysisResults> RunCodeAnalysisAsync( IEnumerable <UnsavedFile> unsavedFiles, Func <bool> interruptRequested) { var errorList = IoC.Get <IErrorList>(); var result = new CodeAnalysisResults(); var diagnostics = new List <Diagnostic>(); var file = _editor.SourceFile; var dataAssociation = GetAssociatedData(file); var currentUnsavedFile = unsavedFiles.FirstOrDefault(f => f.FileName == file.FilePath); var currentFileConts = currentUnsavedFile?.Contents ?? File.ReadAllText(file.FilePath); var currentFileName = currentUnsavedFile?.FileName ?? file.FilePath; TypeScriptSyntaxTree syntaxTree; // Only one analyzer at a time; the JS engine is single-threaded. TODO: Workaround with multiple JS engines await analysisThreadSemaphore.WaitAsync(); try { syntaxTree = await _typeScriptContext.BuildAstAsync(currentFileName, currentFileConts); } catch (JavaScriptException) { diagnostics.Add(new Diagnostic( 0, 0, _editor.SourceFile.Project.Name, _editor.SourceFile.Location, 0, "Code analysis language service call failed.", "INT001", DiagnosticLevel.Error, DiagnosticCategory.Compiler)); errorList.Remove((this, _editor.SourceFile)); errorList.Create((this, _editor.SourceFile), null, DiagnosticSourceKind.Analysis, diagnostics.ToImmutableArray()); return(new CodeAnalysisResults()); } finally { analysisThreadSemaphore.Release(); } #if DEBUG var syntaxTreeJsonDebug = JsonConvert.SerializeObject(syntaxTree); #endif var lineCommentMatches = LineCommentPattern.Matches(currentFileConts); foreach (Match commentMatch in lineCommentMatches) { result.SyntaxHighlightingData.Add(new OffsetSyntaxHighlightingData { Start = commentMatch.Index, Length = commentMatch.Length, Type = HighlightType.Comment }); } var blockCommentMatches = BlockCommentPattern.Matches(currentFileConts); foreach (Match commentMatch in blockCommentMatches) { result.SyntaxHighlightingData.Add(new OffsetSyntaxHighlightingData { Start = commentMatch.Index, Length = commentMatch.Length, Type = HighlightType.Comment }); } // Highlight keywords var keywordMatches = KeywordPattern.Matches(currentFileConts); foreach (Match keywordMatch in keywordMatches) { result.SyntaxHighlightingData.Add(new OffsetSyntaxHighlightingData { Start = keywordMatch.Index, Length = keywordMatch.Length, Type = HighlightType.Keyword }); } // Recursively highlight and analyze from parse tree foreach (var rootStatement in syntaxTree.Statements) { HighlightNode(rootStatement, result); } // Diagnostics foreach (var diagnostic in syntaxTree.ParseDiagnostics) { // Convert diagnostics diagnostics.Add(new Diagnostic( diagnostic.Start, diagnostic.Length, _editor.SourceFile.Project.Name, _editor.SourceFile.Location, GetLineNumber(currentFileConts, diagnostic.Start), diagnostic.MessageText, "INT002", diagnostic.Category == TSBridge.Ast.Diagnostics.Diagnostic.DiagnosticCategory.Error ? DiagnosticLevel.Error : DiagnosticLevel.Warning, DiagnosticCategory.Compiler )); } diagnostics.Add(new Diagnostic( 0, 0, _editor.SourceFile.Project.Name, _editor.SourceFile.Location, 0, "Code analysis for TypeScript is experimental and unstable. Use with caution.", "INT003", DiagnosticLevel.Warning, DiagnosticCategory.Compiler)); errorList.Remove((this, _editor.SourceFile)); errorList.Create((this, _editor.SourceFile), null, DiagnosticSourceKind.Analysis, diagnostics.ToImmutableArray()); return(result); }