public IReadOnlyList<ParseError> GetDiagnostics(SourceText sourceText) { Requires.NotNull(sourceText, nameof(sourceText)); SyntaxTree syntaxTree = this.parseTreeCache.Get(sourceText); return syntaxTree.ErrorList; }
internal FormattingContext(ParsedToken currentToken, ParsedToken nextToken, SourceText sourceText) { Requires.NotNull(currentToken, nameof(currentToken)); Requires.NotNull(nextToken, nameof(nextToken)); Requires.NotNull(sourceText, nameof(sourceText)); this.CurrentToken = currentToken; this.NextToken = nextToken; this.SourceText = sourceText; }
public IEnumerable<TagInfo> ColorizeLexerTokens(SourceText sourceText, List<Range> ranges) { foreach (Token token in Lexer.Tokenize(sourceText.TextReader)) { foreach (TagInfo tagInfo in GetTokenTagInfoFromLexer(ranges, token)) { yield return tagInfo; } } }
/// <summary> /// This is main entry point for the VS side of things. For now, the implementation /// of the function is not final and it just used as a way seeing results in VS. /// Ideally, Format will also take in a "formatting option" object that dictates /// the rules that should be enabled, spacing and tabs. /// </summary> /// <param name="sourceText">The SourceText that represents the text to be formatted</param> /// <param name="range">The range of indicies to be formatted</param> /// <param name="formattingOptions">The options to format with, null leaves the options as they were</param> /// <returns> /// A list of TextEditInfo objects are returned for the spacing between tokens (starting from the /// first token in the document to the last token. After the spacing text edits, the indentation /// text edits follow (starting again from the beginning of the document). I might separate the /// indentation text edits from the spacing text edits in the future but for now they are in /// the same list. /// </returns> public List<TextEditInfo> Format(SourceText sourceText, Range range, FormattingOptions formattingOptions) { Requires.NotNull(formattingOptions, nameof(formattingOptions)); Requires.NotNull(sourceText, nameof(sourceText)); this.formattingOptions = formattingOptions; this.ruleMap = RuleMap.Create(this.formattingOptions.OptionalRuleMap); List<TextEditInfo> textEdits = new List<TextEditInfo>(); SyntaxTree syntaxTree = this.parseTreeProvider.Get(sourceText); List<ParsedToken> parsedTokens = new List<ParsedToken>(ParsedToken.GetParsedTokens(syntaxTree, range)); if (syntaxTree.ErrorList.Count == 0) { for (int i = 0; i < parsedTokens.Count - 1; ++i) { FormattingContext formattingContext = new FormattingContext(parsedTokens[i], parsedTokens[i + 1], sourceText); Rule rule = this.ruleMap.Get(formattingContext); if (rule != null) { textEdits.AddRange(rule.Apply(formattingContext)); } } } textEdits.AddRange(Indenter.GetIndentations(parsedTokens, this.formattingOptions)); textEdits.Sort((x, y) => x.Start < y.Start ? 1 : x.Start == y.Start ? 0 : -1); return textEdits; }
/// <summary> /// Creates a default element /// </summary> /// <param name="enclosingCollection"></param> /// <param name="sourceText"></param> /// <returns></returns> public static Translation CreateDefault(ICollection enclosingCollection, SourceText sourceText) { Translation retVal = (Translation)acceptor.getFactory().createTranslation(); Util.DontNotify(() => { if (sourceText != null) { retVal.Name = sourceText.Name; retVal.appendSourceTexts(sourceText); } else { retVal.Name = "Translation" + GetElementNumber(enclosingCollection); } retVal.appendSubSteps(SubStep.CreateDefault(retVal.SubSteps)); }); return retVal; }
/// <summary> /// Combines TranslateSpan and IsHiddenPosition to not search the entries twice when emitting sequence points /// </summary> internal abstract FileLinePositionSpan TranslateSpanAndVisibility( SourceText sourceText, string treeFilePath, TextSpan span, out bool isHiddenPosition );
static bool TryDetermineModifiers(ref SyntaxToken startToken, SourceText text, int startLine, out Accessibility seenAccessibility /*, out DeclarationModifiers modifiers*/) { var token = startToken; //modifiers = new DeclarationModifiers(); seenAccessibility = Accessibility.NotApplicable; var overrideToken = default(SyntaxToken); while (IsOnStartLine(text, startLine, token.SpanStart) && !token.IsKind(SyntaxKind.None)) { switch (token.Kind()) { //case SyntaxKind.UnsafeKeyword: // isUnsafe = true; //break; case SyntaxKind.OverrideKeyword: overrideToken = token; break; //case SyntaxKind.SealedKeyword: // isSealed = true; //break; //case SyntaxKind.AbstractKeyword: // isAbstract = true; //break; case SyntaxKind.ExternKeyword: break; // Filter on the most recently typed accessibility; keep the first one we see case SyntaxKind.PublicKeyword: if (seenAccessibility == Accessibility.NotApplicable) { seenAccessibility = Accessibility.Public; } break; case SyntaxKind.InternalKeyword: if (seenAccessibility == Accessibility.NotApplicable) { seenAccessibility = Accessibility.Internal; } // If we see internal AND protected, filter for protected internal if (seenAccessibility == Accessibility.Protected) { seenAccessibility = Accessibility.ProtectedOrInternal; } break; case SyntaxKind.ProtectedKeyword: if (seenAccessibility == Accessibility.NotApplicable) { seenAccessibility = Accessibility.Protected; } // If we see protected AND internal, filter for protected internal if (seenAccessibility == Accessibility.Internal) { seenAccessibility = Accessibility.ProtectedOrInternal; } break; default: // Anything else and we bail. return(false); } var previousToken = token.GetPreviousToken(); // We want only want to consume modifiers if (previousToken.IsKind(SyntaxKind.None) || !IsOnStartLine(text, startLine, previousToken.SpanStart)) { break; } token = previousToken; } startToken = token; /* modifiers = new DeclarationModifiers () * .WithIsUnsafe (isUnsafe) * .WithIsAbstract (isAbstract) * .WithIsOverride (true) * .WithIsSealed (isSealed);*/ return(overrideToken.IsKind(SyntaxKind.OverrideKeyword) && IsOnStartLine(text, startLine, overrideToken.Parent.SpanStart)); }
public override bool TryGetText(out SourceText text) { text = SourceText.From(string.Empty, Encoding.UTF8); return(true); }
public Lexer(SyntaxTree syntaxTree) { _syntaxTree = syntaxTree; _text = syntaxTree.Text; }
private static bool MatchesFilterText(CompletionHelper helper, CompletionItem item, SourceText text, Dictionary <TextSpan, string> textSpanToText) { var filterText = GetFilterText(item, text, textSpanToText); if (string.IsNullOrEmpty(filterText)) { return(true); } return(helper.MatchesFilterText(item, filterText)); }
public void ChangeDocument(DocumentId id, SourceText text) { ApplyDocumentTextChanged(id, text); }
public override IReadOnlyList <TextChange> GetTextChanges(SourceText oldText) => _sourceText.GetTextChanges(oldText);
public void SourceText_IncludesLastLine(string text, int expectedLineCount) { var sourceText = SourceText.From(text); Assert.Equal(expectedLineCount, sourceText.Lines.Length); }
public Document AddDocument(Project project, string source, params string[] additionalSources) { Document document = project.AddDocument(DefaultDocumentName, SourceText.From(source)); int length = additionalSources.Length; if (length > 0) { project = document.Project; for (int i = 0; i < length; i++) { project = project .AddDocument(PathHelpers.AppendNumberToFileName(document.Name, i + 2), SourceText.From(additionalSources[i])) .Project; } document = project.GetDocument(document.Id); } return(document); }
public override bool IsTriggerCharacter(SourceText text, int position) { return(IsTriggerAfterSpaceOrStartOfWordCharacter(text, position)); }
private bool TryGetSubTextChange( SourceText originalText, TextSpan visibleSpanInOriginalText, string rightText, TextSpan spanInOriginalText, TextSpan spanInRightText, out TextChange textChange) { textChange = default; var visibleFirstLineInOriginalText = originalText.Lines.GetLineFromPosition(visibleSpanInOriginalText.Start); var visibleLastLineInOriginalText = originalText.Lines.GetLineFromPosition(visibleSpanInOriginalText.End); // skip easy case // 1. things are out of visible span if (!visibleSpanInOriginalText.IntersectsWith(spanInOriginalText)) { return(false); } // 2. there are no intersects var snippetInRightText = rightText.Substring(spanInRightText.Start, spanInRightText.Length); if (visibleSpanInOriginalText.Contains(spanInOriginalText) && visibleSpanInOriginalText.End != spanInOriginalText.End) { textChange = new TextChange(spanInOriginalText, snippetInRightText); return(true); } // okay, more complex case. things are intersecting boundaries. var firstLineOfRightTextSnippet = snippetInRightText.GetFirstLineText(); var lastLineOfRightTextSnippet = snippetInRightText.GetLastLineText(); // there are 4 complex cases - these are all heuristic. not sure what better way I have. and the heuristic is heavily based on // text differ's behavior. // 1. it is a single line if (visibleFirstLineInOriginalText.LineNumber == visibleLastLineInOriginalText.LineNumber) { // don't do anything return(false); } // 2. replacement contains visible spans if (spanInOriginalText.Contains(visibleSpanInOriginalText)) { // header // don't do anything // body textChange = new TextChange( TextSpan.FromBounds(visibleFirstLineInOriginalText.EndIncludingLineBreak, visibleLastLineInOriginalText.Start), snippetInRightText.Substring(firstLineOfRightTextSnippet.Length, snippetInRightText.Length - firstLineOfRightTextSnippet.Length - lastLineOfRightTextSnippet.Length)); // footer // don't do anything return(true); } // 3. replacement intersects with start if (spanInOriginalText.Start < visibleSpanInOriginalText.Start && visibleSpanInOriginalText.Start <= spanInOriginalText.End && spanInOriginalText.End < visibleSpanInOriginalText.End) { // header // don't do anything // body if (visibleFirstLineInOriginalText.EndIncludingLineBreak <= spanInOriginalText.End) { textChange = new TextChange( TextSpan.FromBounds(visibleFirstLineInOriginalText.EndIncludingLineBreak, spanInOriginalText.End), snippetInRightText.Substring(firstLineOfRightTextSnippet.Length)); return(true); } return(false); } // 4. replacement intersects with end if (visibleSpanInOriginalText.Start < spanInOriginalText.Start && spanInOriginalText.Start <= visibleSpanInOriginalText.End && visibleSpanInOriginalText.End <= spanInOriginalText.End) { // body if (spanInOriginalText.Start <= visibleLastLineInOriginalText.Start) { textChange = new TextChange( TextSpan.FromBounds(spanInOriginalText.Start, visibleLastLineInOriginalText.Start), snippetInRightText.Substring(0, snippetInRightText.Length - lastLineOfRightTextSnippet.Length)); return(true); } // footer // don't do anything return(false); } // if it got hit, then it means there is a missing case throw ExceptionUtilities.Unreachable; }
private IEnumerable <TextChange> FilterTextChanges(SourceText originalText, List <TextSpan> editorVisibleSpansInOriginal, IReadOnlyList <TextChange> changes) { // no visible spans or changes if (editorVisibleSpansInOriginal.Count == 0 || changes.Count == 0) { // return empty one yield break; } using var pooledObject = SharedPools.Default <List <TextChange> >().GetPooledObject(); var changeQueue = pooledObject.Object; changeQueue.AddRange(changes); var spanIndex = 0; var changeIndex = 0; for (; spanIndex < editorVisibleSpansInOriginal.Count; spanIndex++) { var visibleSpan = editorVisibleSpansInOriginal[spanIndex]; var visibleTextSpan = GetVisibleTextSpan(originalText, visibleSpan, uptoFirstAndLastLine: true); for (; changeIndex < changeQueue.Count; changeIndex++) { var change = changeQueue[changeIndex]; // easy case first if (change.Span.End < visibleSpan.Start) { // move to next change continue; } if (visibleSpan.End < change.Span.Start) { // move to next visible span break; } // make sure we are not replacing whitespace around start and at the end of visible span if (WhitespaceOnEdges(originalText, visibleTextSpan, change)) { continue; } if (visibleSpan.Contains(change.Span)) { yield return(change); continue; } // now it is complex case where things are intersecting each other var subChanges = GetSubTextChanges(originalText, change, visibleSpan).ToList(); if (subChanges.Count > 0) { if (subChanges.Count == 1 && subChanges[0] == change) { // we can't break it. not much we can do here. just don't touch and ignore this change continue; } changeQueue.InsertRange(changeIndex + 1, subChanges); continue; } } } }
public virtual Project CreateProjectFromSourceCodesWithExistingSolution(Solution existingSolution, params string[] sourceCodes) { ProjectId projectId = ProjectId.CreateNewId(debugName: "TestProjectName"); existingSolution = existingSolution.AddProject(projectId, "TestProjectName", "TestProjectName", LanguageNames.CSharp); AppDomain.CurrentDomain.GetAssemblies() .Where(asm => !asm.IsDynamic) .ToList() .ForEach(asm => { existingSolution = existingSolution.AddMetadataReference(projectId, MetadataReference.CreateFromFile(asm.Location)); }); for (int i = 0; i < sourceCodes.Length; i++) { DocumentId fileDocId = DocumentId.CreateNewId(projectId, debugName: $"File{i}.cs"); existingSolution = existingSolution.AddDocument(fileDocId, $"File{i}.cs", SourceText.From(sourceCodes[i])); } return(existingSolution.GetProject(projectId)); }
protected static void AnalyzeWithRule <T>(string input, string ruleId, string output = null, int issueToFix = -1, int actionToRun = 0, Action <int, Diagnostic> diagnosticCheck = null) where T : DiagnosticAnalyzer, new() { var text = new StringBuilder(); var expectedDiagnosics = new List <TextSpan> (); int start = -1; for (int i = 0; i < input.Length; i++) { char ch = input [i]; if (ch == '$') { if (start < 0) { start = text.Length; continue; } expectedDiagnosics.Add(TextSpan.FromBounds(start, text.Length)); start = -1; } else { text.Append(ch); } } var syntaxTree = CSharpSyntaxTree.ParseText(text.ToString()); Compilation compilation = CreateCompilationWithMscorlib(new [] { syntaxTree }); var diagnostics = new List <Diagnostic>(); var compilationWithAnalyzers = compilation.WithAnalyzers(System.Collections.Immutable.ImmutableArray <DiagnosticAnalyzer> .Empty.Add(new T())); diagnostics.AddRange(compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().Result); if (expectedDiagnosics.Count != diagnostics.Count) { Console.WriteLine("Diagnostics: " + diagnostics.Count); foreach (var diag in diagnostics) { Console.WriteLine(diag.Id + "/" + diag.GetMessage()); } Assert.Fail("Diagnostic count mismatch expected: " + expectedDiagnosics.Count + " but was:" + diagnostics.Count); } for (int i = 0; i < expectedDiagnosics.Count; i++) { var d = diagnostics [i]; var wholeSpan = GetWholeSpan(d); if (wholeSpan != expectedDiagnosics [i]) { Assert.Fail("Diagnostic " + i + " span mismatch expected: " + expectedDiagnosics[i] + " but was " + wholeSpan); } if (diagnosticCheck != null) { diagnosticCheck(i, d); } } if (output == null) { return; } var workspace = new TestWorkspace(); var projectId = ProjectId.CreateNewId(); var documentId = DocumentId.CreateNewId(projectId); workspace.Open(ProjectInfo.Create( projectId, VersionStamp.Create(), "", "", LanguageNames.CSharp, null, null, null, null, new [] { DocumentInfo.Create( documentId, "a.cs", null, SourceCodeKind.Regular, TextLoader.From(TextAndVersion.Create(SourceText.From(text.ToString()), VersionStamp.Create()))) } )); if (issueToFix < 0) { diagnostics.Reverse(); foreach (var v in diagnostics) { RunFix(workspace, projectId, documentId, v); } } else { RunFix(workspace, projectId, documentId, diagnostics.ElementAt(issueToFix), actionToRun); } var txt = workspace.CurrentSolution.GetProject(projectId).GetDocument(documentId).GetTextAsync().Result.ToString(); if (output != txt) { Console.WriteLine("expected:"); Console.WriteLine(output); Console.WriteLine("got:"); Console.WriteLine(txt); Assert.Fail(); } }
private AvalonEditSourceText(AvalonEditTextContainer container, SourceText sourceText) { _container = container; _sourceText = sourceText; }
public void Execute(GeneratorExecutionContext context) { if (context.SyntaxReceiver is not ConfigurationTemplateInterfaceSyntaxReceiver receiver) { return; } var compilation = context.Compilation; var types = new ConfigurationTypes(compilation); if (!types.CheckContext(context)) { return; } foreach (var ifaceSyntax in receiver.CandidateInterfaces) { var model = compilation.GetSemanticModel(ifaceSyntax.SyntaxTree); var ifaceSymbol = model.GetDeclaredSymbol(ifaceSyntax, context.CancellationToken); if (ifaceSymbol == null) { continue; } if (!ifaceSymbol.GetAttributes() .Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, types.InputConfigurationAttribute))) { continue; } var diagnostics = Analyzers.AsParallel() .SelectMany(a => a.Analyze(context.Compilation, model, ifaceSyntax, context.CancellationToken)) .ToList(); foreach (var diag in diagnostics) { context.ReportDiagnostic(diag); } if (diagnostics.Any()) { return; } var configProperties = new List <(INamedTypeSymbol, IPropertySymbol)>(); var inputProperties = new List <(INamedTypeSymbol, IPropertySymbol)>(); foreach (var childIface in ifaceSymbol.AllInterfaces.Reverse().Concat(new[] { ifaceSymbol })) { // No need to check if child interfaces are partial because we only add to the root interface. foreach (var member in childIface.GetMembers()) { if (member is IMethodSymbol accessor && accessor.AssociatedSymbol is IPropertySymbol) { continue; } bool isConfigOption = member.GetAttributes() .Where(attr => attr?.AttributeClass? .Equals(types.ConfigurationOptionAttribute, SymbolEqualityComparer.Default) == true) .Any(); bool isInputOption = member.GetAttributes() .Where(attr => attr?.AttributeClass? .Equals(types.InputOptionAttribute, SymbolEqualityComparer.Default) == true) .Any(); // case where neither/both handled by analyzer guards above. if (isConfigOption && member is IPropertySymbol optionProperty) { configProperties.Add((childIface, optionProperty)); } else if (isInputOption && member is IPropertySymbol inputProperty) { inputProperties.Add((childIface, inputProperty)); } } } string classSource = GenerateSource(ifaceSymbol, configProperties, inputProperties, types); context.AddSource($"{ifaceSymbol.Name}_InputConfigurationSection.g.cs", SourceText.From(classSource, Encoding.UTF8)); } }
protected override bool ContentEqualsImpl(SourceText other) => _sourceText.ContentEquals(other);
internal TriviaToken( SourceText text, TextSpan span, PolyglotSyntaxTree?syntaxTree) : base(text, span, syntaxTree) { }
private static async Task <Document> RecreateDocumentAsync(Document document, CancellationToken cancellationToken) { var newText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); return(document.WithText(SourceText.From(newText.ToString(), newText.Encoding, newText.ChecksumAlgorithm))); }
public bool TryGetSpan(ActiveStatementId id, SourceText source, out TextSpan span) => _trackingService.TryGetSpan(id, source, out span);
static bool IsOnStartLine(SourceText text, int startLineNumber, int position) { return(text.Lines.IndexOf(position) == startLineNumber); }
internal override bool IsInsertionTrigger(SourceText text, int characterPosition, OptionSet options) { return(CompletionUtilities.IsTriggerCharacter(text, characterPosition, options)); }
public IEnumerable <ActiveStatementTextSpan> GetSpans(SourceText source) { throw new NotImplementedException(); }
public override SourceText GetText(CancellationToken cancellationToken) { return(SourceText.From(string.Empty, Encoding.UTF8)); }
public override bool IsTriggerCharacter(SourceText text, int characterPosition, OptionSet options) { return(CompletionUtilities.IsTriggerAfterSpaceOrStartOfWordCharacter(text, characterPosition, options)); }
public void AnalyzerOptionsArePassedToAllAnalyzers() { using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromFile(TestResource.AllInOneCSharpCode, TestOptions.Regular)) { var currentProject = workspace.CurrentSolution.Projects.Single(); var additionalDocId = DocumentId.CreateNewId(currentProject.Id); var newSln = workspace.CurrentSolution.AddAdditionalDocument(additionalDocId, "add.config", SourceText.From("random text")); currentProject = newSln.Projects.Single(); var additionalDocument = currentProject.GetAdditionalDocument(additionalDocId); AdditionalText additionalStream = new AdditionalTextDocument(additionalDocument.GetDocumentState()); AnalyzerOptions options = new AnalyzerOptions(ImmutableArray.Create(additionalStream)); var analyzer = new OptionsDiagnosticAnalyzer <SyntaxKind>(expectedOptions: options); var sourceDocument = currentProject.Documents.Single(); DiagnosticProviderTestUtilities.GetAllDiagnostics(analyzer, sourceDocument, new Text.TextSpan(0, sourceDocument.GetTextAsync().Result.Length)); analyzer.VerifyAnalyzerOptions(); } }
public IEnumerable<TagInfo> ColorizeParserTokens(SourceText sourceText) { SyntaxTree syntaxTree = this.ParseTreeCache.Get(sourceText); return GetTokenTagInfoFromParser(syntaxTree.Root, new HashSet<string>(), new HashSet<string>(), new HashSet<TagInfo>(), new Token[1]); }
private static void TestTemporaryStorage(ITemporaryStorageService temporaryStorageService, SourceText text) { // create a temporary storage location var temporaryStorage = temporaryStorageService.CreateTemporaryTextStorage(System.Threading.CancellationToken.None); // write text into it temporaryStorage.WriteTextAsync(text).Wait(); // read text back from it var text2 = temporaryStorage.ReadTextAsync().Result; Assert.NotSame(text, text2); Assert.Equal(text.ToString(), text2.ToString()); Assert.Equal(text.Encoding, text2.Encoding); temporaryStorage.Dispose(); }
/// <summary> /// Gets the indentation level at the specified position in the source text. /// </summary> /// <param name="sourceText">The content for the smart indenting</param> /// <param name="position">The position to check for the block level</param> /// <returns>The indentation amount in spaces</returns> public int SmartIndent(SourceText sourceText, int position) { SyntaxTree syntaxTree = this.parseTreeProvider.Get(sourceText); return Indenter.GetIndentationFromPosition(syntaxTree, this.formattingOptions, position); }
public override bool TryGetText(out SourceText text) { text = _source.SourceText; return(text != null); }
public override SyntaxTree WithChangedText(SourceText newText) { throw new NotImplementedException(); }
/// <summary> /// Determines whether the position is considered to be hidden from the debugger or not. /// </summary> public abstract LineVisibility GetLineVisibility(SourceText sourceText, int position);