private bool saveCodeBehind(RoslynDocument doc, bool mapLines) { doc.SyntaxRoot = doc.SyntaxRoot .NormalizeWhitespace(elasticTrivia: true); //td: optimize var solution = _workspace.CurrentSolution; if (mapLines) { var mapper = doc.Mapper; var vsDocument = solution.GetDocument(_id); var filePath = vsDocument?.FilePath; if (filePath != null) { filePath = filePath.Remove(filePath.Length - ".cs".Length); } solution = solution.WithDocumentText(_id, SourceText.From(doc.Mapper .RenderMapping(doc.SyntaxRoot, filePath))); } else { solution = solution.WithDocumentSyntaxRoot(_id, _document.SyntaxRoot); } return(_workspace.TryApplyChanges(solution)); }
public RoslynDocument CreateExcessDocument(string text, DocumentId document) { ProjectCache cache; if (!_projects.TryGetValue(document.ProjectId, out cache)) { ensureNuget(); cache = new ProjectCache(_workspace, document.ProjectId, _nuget, _nugetEvents); _projects[document.ProjectId] = cache; } //td: we need the using list in order to deduct the extensions //however, we don't need to parse the whole document. //We must optimize this (maybe a custom using parser?) var compilationUnit = CSharp.ParseCompilationUnit(text); var extensions = new List <UsingDirectiveSyntax>(compilationUnit.Usings); var keywords = null as IEnumerable <string>; var compiler = cache.GetCompiler(document, extensions, out keywords); //build a new document var result = new RoslynDocument(compiler.Scope, text); result.Mapper = new MappingService(); compiler.apply(result); var scanner = null as Scanner; if (keywords != null && keywords.Any() && _scannerCache.TryGetValue(document, out scanner)) { scanner.Keywords = XSKeywords.Values.Union(keywords); } return(result); }
public override void BeginParse() { if (_document != null) { //td: cancel } var service = (ExcessLanguageService)LanguageService; _document = service.CreateExcessDocument(GetText(), _id); _document.applyChanges(CompilerStage.Syntactical); //td: check saving error & SemanticalChanges saveCodeBehind(_document, false); if (_document.HasSemanticalChanges()) { var doc = _workspace.CurrentSolution.GetDocument(_id); var semanticRoot = doc.GetSyntaxRootAsync().Result; _document.Mapper.Map(_document.SyntaxRoot, semanticRoot); var model = doc.GetSemanticModelAsync().Result; _document.Model = model; _document.applyChanges(CompilerStage.Semantical); } saveCodeBehind(_document, true); base.BeginParse(); }
public static SyntaxTree Compile(string code, Action <Compiler> builder = null, Mapper mapper = null) { //build a compiler var compiler = new RoslynCompiler(); if (builder == null) { builder = (c) => XSLanguage.Apply(c); } builder(compiler); //then a document var document = new RoslynDocument(compiler.Scope, code); //mapping document.Mapper = mapper; //do the compilation compiler.apply(document); document.applyChanges(CompilerStage.Syntactical); if (mapper != null) { var translated = mapper.RenderMapping(document.SyntaxRoot, string.Empty); return(CSharp.ParseCompilationUnit(translated).SyntaxTree); } return(document.SyntaxRoot.SyntaxTree); }
public static Assembly Build(string code, Action <Compiler> builder, IEnumerable <Type> referenceTypes) { //build a compiler var compiler = new RoslynCompiler(); if (builder == null) { builder = (c) => XSLanguage.Apply(c); } builder(compiler); //then a document var document = new RoslynDocument(compiler.Scope, code); //do the compilation compiler.apply(document); document.applyChanges(CompilerStage.Syntactical); var node = document.SyntaxRoot; var references = referenceTypes .Select(refType => MetadataReference.CreateFromFile(refType.Assembly.Location)) .Union(new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location), MetadataReference.CreateFromFile(typeof(IEnumerable).Assembly.Location), MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location), MetadataReference.CreateFromFile(typeof(Dictionary <int, int>).Assembly.Location), }); var compilation = CSharpCompilation.Create("mock-assembly", syntaxTrees: new[] { node.SyntaxTree }, references: references, options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); document.SyntaxRoot = node; document.Model = compilation.GetSemanticModel(node.SyntaxTree); document.applyChanges(CompilerStage.Finished); //build compilation = compilation.ReplaceSyntaxTree( compilation.SyntaxTrees.Single(), document.SyntaxRoot.SyntaxTree); var stream = new MemoryStream(); var result = compilation.Emit(stream); if (!result.Success) { return(null); } return(Assembly.Load(stream.GetBuffer())); }
private static RoslynDocument CreateExcessDocument(string text, Scope scope, List <string> extensionNames) { //td: we need the using list in order to deduct the extensions //however, we don't need to parse the whole document. //We must optimize this (maybe a custom using parser?) var compilationUnit = CSharp.ParseCompilationUnit(text); var extensions = new List <UsingDirectiveSyntax>(compilationUnit.Usings); var keywords = null as IEnumerable <string>; var compiler = CreateCompiler(extensions, out keywords, scope, extensionNames); //build a new document var result = new RoslynDocument(compiler.Scope, text); result.Mapper = new MappingService(); compiler.apply(result); return(result); }
public RoslynDocument CreateExcessDocument(string text, DocumentId document) { RoslynCompiler compiler; if (!_projects.TryGetValue(document.ProjectId, out compiler)) { compiler = new RoslynCompiler(); XSLang.Apply(compiler); _projects[document.ProjectId] = compiler; } var result = new RoslynDocument(compiler.Scope, text); result.Mapper = new MappingService(); compiler.apply(result); return(result); }
public IEnumerable <ITagSpan <IClassificationTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (spans.Count == 0) { return(Enumerable.Empty <ITagSpan <IClassificationTag> >()); } if (this.cache == null || this.cache.Snapshot != spans[0].Snapshot) { var task = RoslynDocument.Resolve(theBuffer, spans[0].Snapshot); task.Wait(); if (task.IsFaulted) { return(Enumerable.Empty <ITagSpan <IClassificationTag> >()); } cache = task.Result; } return(FindBracketSpans(this.cache, spans)); }
public static SyntaxTree Link(string code, Action <Compiler> builder = null, Mapper mapper = null) { //build a compiler var compiler = new RoslynCompiler(); if (builder == null) { builder = (c) => XSLanguage.Apply(c); } builder(compiler); //then a document var document = new RoslynDocument(compiler.Scope, code); //mapping document.Mapper = mapper; //do the compilation compiler.apply(document); document.applyChanges(CompilerStage.Syntactical); var node = document.SyntaxRoot; if (mapper != null) { var translated = mapper.RenderMapping(node, string.Empty); node = CSharp.ParseCompilationUnit(translated); } var compilation = CSharpCompilation.Create("mock-assembly", syntaxTrees: new[] { node.SyntaxTree }, references: new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location), MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location), MetadataReference.CreateFromFile(typeof(Dictionary <int, int>).Assembly.Location), }); document.SyntaxRoot = node; document.Model = compilation.GetSemanticModel(node.SyntaxTree); document.applyChanges(CompilerStage.Finished); return(document.SyntaxRoot.SyntaxTree); }
private IEnumerable <ITagSpan <IClassificationTag> > GetTagsImpl( RoslynDocument doc, NormalizedSnapshotSpanCollection spans) { var snapshot = spans[0].Snapshot; IEnumerable <ClassifiedSpan> identifiers = GetIdentifiersInSpans(doc.Workspace, doc.SemanticModel, spans); foreach (var id in identifiers) { var node = doc.SyntaxRoot.FindNode(id.TextSpan); var symbol = doc.SemanticModel.GetSymbolInfo(GetExpression(node)).Symbol; if (symbol == null) { continue; } switch (symbol.Kind) { case SymbolKind.Parameter: yield return(id.TextSpan.ToTagSpan(snapshot, parameterType)); break; case SymbolKind.Field: if (symbol.ContainingType.TypeKind != TypeKind.Enum) { yield return(id.TextSpan.ToTagSpan(snapshot, fieldType)); } break; case SymbolKind.Method: if (IsExtensionMethod(symbol)) { yield return(id.TextSpan.ToTagSpan(snapshot, extensionMethodType)); } break; } } }
public IEnumerable <ITagSpan <IClassificationTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (spans.Count == 0) { return(Enumerable.Empty <ITagSpan <IClassificationTag> >()); } if (this.cache == null || this.cache.Snapshot != spans[0].Snapshot) { // this makes me feel dirty, but otherwise it will not // work reliably, as TryGetSemanticModel() often will return false // should make this into a completely async process somehow var task = RoslynDocument.Resolve(theBuffer, spans[0].Snapshot); task.Wait(); if (task.IsFaulted) { // TODO: report this to someone. return(Enumerable.Empty <ITagSpan <IClassificationTag> >()); } cache = task.Result; } return(GetTagsImpl(this.cache, spans)); }
public override void BeginParse() { if (_document != null) { //td: cancel } ExcessLanguageService service = (ExcessLanguageService)this.LanguageService; _document = service.CreateExcessDocument(GetText(), _id); _document.applyChanges(CompilerStage.Syntactical); _document.SyntaxRoot = _document.SyntaxRoot.NormalizeWhitespace(elasticTrivia: true); //td: optimize if (!saveCodeBehind(_document.SyntaxRoot)) { return; //td: error? } if (!_document.HasSemanticalChanges()) { return; } var doc = _workspace.CurrentSolution.GetDocument(_id); var semanticRoot = doc.GetSyntaxRootAsync().Result; _document.Mapper.SemanticalChange(_document.SyntaxRoot, semanticRoot); var model = doc.GetSemanticModelAsync().Result; _document.Model = model; _document.applyChanges(CompilerStage.Semantical); saveCodeBehind(_document.SyntaxRoot); base.BeginParse(); }
public IEnumerable <ITagSpan <IClassificationTag> > FindBracketSpans(RoslynDocument doc, NormalizedSnapshotSpanCollection spans) { var snapshot = spans[0].Snapshot; List <ITagSpan <IClassificationTag> > _tagspans = new List <ITagSpan <IClassificationTag> >(); var nodeOrToken = (SyntaxNodeOrToken)doc.SyntaxRoot; Action <List <ITagSpan <IClassificationTag> >, SyntaxNodeOrToken, int> _walkintochild = null; int _dept = 0; _walkintochild = (List <ITagSpan <IClassificationTag> > __tagspans, SyntaxNodeOrToken nOrT, int __dept) => { foreach (var child in nOrT.ChildNodesAndTokens()) { if (child.ChildNodesAndTokens().Count > 0) { _walkintochild(__tagspans, child, ++__dept); } } List <SyntaxNodeOrToken> __brace = nOrT.ChildNodesAndTokens().Where(child => child.IsKind(SyntaxKind.OpenBraceToken) || child.IsKind(SyntaxKind.CloseBraceToken) || child.IsKind(SyntaxKind.OpenParenToken) || child.IsKind(SyntaxKind.CloseParenToken) || child.IsKind(SyntaxKind.OpenBracketToken) || child.IsKind(SyntaxKind.CloseBracketToken) ).ToList(); if (__brace.Count == 0) { return; } if (__brace.Where(s => s.ToString() == "(").ToList().Count != __brace.Where(s => s.ToString() == ")").ToList().Count) { return; } if (__brace.Where(s => s.ToString() == "{").ToList().Count != __brace.Where(s => s.ToString() == "}").ToList().Count) { return; } if (__brace.Where(s => s.ToString() == "[").ToList().Count != __brace.Where(s => s.ToString() == "]").ToList().Count) { return; } while (__brace.Count > 0) { SyntaxNodeOrToken l1 = __brace.First(); SyntaxNodeOrToken l2 = null; string _start_check = l1.ToString(); string _end_check = ")"; if (_start_check == "{") { _end_check = "}"; } if (_start_check == "[") { _end_check = "]"; } if (_start_check != "{" && _start_check != "(" && _start_check != "[") { break; } __brace.Remove(l1); int par = 1; for (int i = 0; i < __brace.Count; ++i) { SyntaxNodeOrToken _ncheck = __brace[i]; if (_ncheck.ToString() == _end_check) { par--; } else if (_ncheck.ToString() == _start_check) { par++; } if (par == 0) { l2 = _ncheck; __brace.Remove(l2); break; } } string _tp = ((__dept % 8) + 1).ToString(); IClassificationType classificationType = _classificationTypeRegistry.GetClassificationType(_tp); __tagspans.Add(l1.Span.ToTagSpan(snapshot, classificationType)); if (l2 != null) { __tagspans.Add(l2.Span.ToTagSpan(snapshot, classificationType)); } else { return; } } }; _walkintochild(_tagspans, nodeOrToken, _dept); foreach (ITagSpan <IClassificationTag> _t in _tagspans) { yield return(_t); } }
public IEnumerable <ITagSpan <IClassificationTag> > FindBracketSpans(RoslynDocument doc, NormalizedSnapshotSpanCollection spans) { var snapshot = spans[0].Snapshot; var _nodeOrToken = (SyntaxNodeOrToken)doc.SyntaxRoot; int _dept = 0; List <ITagSpan <IClassificationTag> > _tagSpans = new List <ITagSpan <IClassificationTag> >(); void nextChildNode(List <ITagSpan <IClassificationTag> > tagSpans, SyntaxNodeOrToken nodeOrToken, int dept) { foreach (var child in nodeOrToken.ChildNodesAndTokens()) { if (child.ChildNodesAndTokens().Count > 0) { nextChildNode(tagSpans, child, ++dept); } } List <SyntaxNodeOrToken> brace = nodeOrToken.ChildNodesAndTokens().Where(child => child.IsKind(SyntaxKind.OpenBraceToken) || child.IsKind(SyntaxKind.CloseBraceToken) || child.IsKind(SyntaxKind.OpenParenToken) || child.IsKind(SyntaxKind.CloseParenToken) || child.IsKind(SyntaxKind.OpenBracketToken) || child.IsKind(SyntaxKind.CloseBracketToken)) .ToList(); if (brace.Count == 0) { return; } if (brace.Where(s => s.ToString() == "(").ToList().Count != brace.Where(s => s.ToString() == ")").ToList().Count) { return; } if (brace.Where(s => s.ToString() == "{").ToList().Count != brace.Where(s => s.ToString() == "}").ToList().Count) { return; } if (brace.Where(s => s.ToString() == "[").ToList().Count != brace.Where(s => s.ToString() == "]").ToList().Count) { return; } while (brace.Count > 0) { SyntaxNodeOrToken line1 = brace.First(); SyntaxNodeOrToken line2 = null; string start = line1.ToString(); string end = ")"; if (start == "{") { end = "}"; } if (start == "[") { end = "]"; } if (start != "(" && start != "{" && start != "[") { break; } brace.Remove(line1); int par = 1; for (int i = 0; i < brace.Count; ++i) { SyntaxNodeOrToken check = brace[i]; if (check.ToString() == end) { par--; } else if (check.ToString() == start) { par++; } if (par == 0) { line2 = check; brace.Remove(line2); break; } } string _tp = ((dept % 8) + 1).ToString(); IClassificationType classificationType = _registry.GetClassificationType(_tp); tagSpans.Add(line1.Span.ToTagSpan(snapshot, classificationType)); if (line2 != null) { tagSpans.Add(line2.Span.ToTagSpan(snapshot, classificationType)); } else { return; } } } nextChildNode(_tagSpans, _nodeOrToken, _dept); foreach (ITagSpan <IClassificationTag> tag in _tagSpans) { yield return(tag); } }