SimpleReadonlyDocument (ITextSource readOnlyTextSource, string fileName, string mimeType) { textSource = readOnlyTextSource; FileName = fileName; MimeType = mimeType; Initalize (readOnlyTextSource.Text); }
/// <summary> /// Create <see cref="NewFolding"/>s for the specified document. /// </summary> public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document) { List<NewFolding> newFoldings = new List<NewFolding>(); Stack<int> startOffsets = new Stack<int>(); int lastNewLineOffset = 0; int len = document.TextLength; foreach(var segment in _tokenservice.GetSegments()) { if(segment.Token == Token.BlockOpen || segment.Token == Token.BlockClosed) { if(segment.Token == _openingBrace) { startOffsets.Push(segment.Range.Offset); } else if(segment.Token == _closingBrace && startOffsets.Count > 0) { int startOffset = startOffsets.Pop(); // don't fold if opening and closing brace are on the same line if(startOffset < lastNewLineOffset) { int endoffset = segment.Range.Offset + 1; if(startOffset < len && endoffset < len) { newFoldings.Add(new NewFolding(startOffset, endoffset)); } } } } else if(segment.Token == Token.NewLine) { lastNewLineOffset = segment.Range.Offset; } } newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset)); return newFoldings; }
public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document) { if (document == null) throw new ArgumentNullException("document"); var newFoldings = new List<NewFolding>(); var startOffsets = new Stack<int>(); int lastNewLineOffset = 0; char openingBrace = OpeningBrace; char closingBrace = ClosingBrace; for (int i = 0; i < document.TextLength; i++) { char c = document.GetCharAt(i); if (c == openingBrace) { startOffsets.Push(i); } else if (c == closingBrace && startOffsets.Count > 0) { int startOffset = startOffsets.Pop(); // don't fold if opening and closing brace are on the same line if (startOffset < lastNewLineOffset) { newFoldings.Add(new NewFolding(startOffset, i + 1)); } } else if (c == '\n' || c == '\r') { lastNewLineOffset = i + 1; } } newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset)); return newFoldings; }
void CheckNewLinesForConsistency(object state) { int numCRLF = 0; int numCR = 0; int numLF = 0; int offset = 0; while (offset >= 0) { string type; offset = TextUtilities.FindNextNewLine(snapshot, offset, out type); if (type != null) { offset += type.Length; switch (type) { case "\r\n": numCRLF++; break; case "\n": numLF++; break; case "\r": numCR++; break; } } } snapshot = null; // we don't need the snapshot anymore, allow the GC to collect it // don't allow mac-style newlines; accept either unix or windows-style newlines but avoid mixing them bool isConsistent = (numCR == 0) && (numLF == 0 || numCRLF == 0); if (!isConsistent) { SharpDevelop.Gui.WorkbenchSingleton.SafeThreadAsyncCall(ShowInconsistentWarning, numLF > numCRLF); } }
/// <summary> /// Gets a single indentation segment starting at <paramref name="offset" /> - at most one tab /// or <paramref name="indentationSize" /> spaces. /// </summary> /// <param name="textSource">The text source.</param> /// <param name="offset">The offset where the indentation segment starts.</param> /// <param name="indentationSize">The size of an indentation unit. See <see cref="TextEditorOptions.IndentationSize" />.</param> /// <returns> /// The indentation segment. /// If there is no indentation character at the specified <paramref name="offset" />, /// an empty segment is returned. /// </returns> public static ISegment GetSingleIndentationSegment(ITextSource textSource, int offset, int indentationSize) { if (textSource == null) throw new ArgumentNullException("textSource"); var pos = offset; while (pos < textSource.TextLength) { var c = textSource.GetCharAt(pos); if (c == '\t') { if (pos == offset) return new SimpleSegment(offset, 1); break; } if (c == ' ') { if (pos - offset >= indentationSize) break; } else { break; } // continue only if c==' ' and (pos-offset)<tabSize pos++; } return new SimpleSegment(offset, pos - offset); }
/// <summary> /// Create <see cref="NewFolding"/>s for the specified document. /// </summary> public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document) { List<NewFolding> newFoldings = new List<NewFolding>(); Stack<int> startOffsets = new Stack<int>(); int lastNewLineOffset = 0; char openingBrace = this.OpeningBrace; char closingBrace = this.ClosingBrace; for (int i = 0; i < document.TextLength; i++) { char c = document.GetCharAt(i); bool isFirstInLine = IsFirstInLine(document, i); if (c == openingBrace && isFirstInLine) startOffsets.Push(i); else if (c == closingBrace && isFirstInLine && startOffsets.Count > 0) { int startOffset = startOffsets.Pop(); // don't fold if opening and closing brace are on the same line if (startOffset < lastNewLineOffset) newFoldings.Add(new NewFolding(startOffset, i + 1)); } else if (c == '\n' || c == '\r') { lastNewLineOffset = i + 1; } } newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset)); return newFoldings; }
/// <summary> /// Create <see cref="NewFolding" />s for the specified document. /// </summary> public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document) { var newFoldings = new List<NewFolding>(); var startOffsets = new Stack<int>(); var lastNewLineOffset = 0; var openingBrace = OpeningBrace; var closingBrace = ClosingBrace; for (var i = 0; i < document.TextLength; i++) { var c = document.GetCharAt(i); if (c == openingBrace) startOffsets.Push(i); else if (c == closingBrace && startOffsets.Count > 0) { var startOffset = startOffsets.Pop(); // don't fold if opening and closing brace are on the same line if (startOffset < lastNewLineOffset) newFoldings.Add(new NewFolding(startOffset, i + 1)); } else if (c == '\n' || c == '\r') lastNewLineOffset = i + 1; } newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset)); return newFoldings; }
/// <summary> /// Finds the next new line character starting at offset. /// </summary> /// <param name="text">The text source to search in.</param> /// <param name="offset">The starting offset for the search.</param> /// <param name="newLineType">The string representing the new line that was found, or null if no new line was found.</param> /// <returns>The position of the first new line starting at or after <paramref name="offset"/>, /// or -1 if no new line was found.</returns> public static int FindNextNewLine(ITextSource text, int offset, out string newLineType) { if (text == null) throw new ArgumentNullException(nameof(text)); if (offset < 0 || offset > text.TextLength) throw new ArgumentOutOfRangeException(nameof(offset), offset, "offset is outside of text source"); SimpleSegment s = NewLineFinder.NextNewLine(text, offset); if (s == SimpleSegment.Invalid) { newLineType = null; return -1; } else { if (s.Length == 2) { newLineType = "\r\n"; } else if (text.GetCharAt(s.Offset) == '\n') { newLineType = "\n"; } else { newLineType = "\r"; } return s.Offset; } }
public MenuText(ContentManager content, Vector2 position, ITextSource textSource) { this.position = position; this.textSource = textSource; font = content.Load<SpriteFont>("Fonts/Menu_Font"); }
/// <summary> /// See 8.2.4 Tokenization /// </summary> /// <param name="source">The source code manager.</param> public HtmlTokenizer(ITextSource source) : base(source) { _state = HtmlParseMode.PCData; _acceptsCharacterData = false; _buffer = new StringBuilder(); }
public TagReader(AXmlParser tagSoupParser, ITextSource input, bool collapseProperlyNestedElements) : base(input) { this.tagSoupParser = tagSoupParser; if (collapseProperlyNestedElements) elementNameStack = new Stack<string>(); }
/// <summary> /// Skips the white space backwards. /// </summary> /// <param name="document">The document.</param> /// <param name="offset">The offset of the first character to check.</param> /// <returns>The offset of the first non-whitespace character before <paramref name="offset"/>.</returns> public int SkipWhiteSpaceBackwards(ITextSource document, int offset) { while (offset >= 1 && char.IsWhiteSpace(document.GetCharAt(offset))) --offset; return offset; }
public ParseInformation Parse( FileName fileName, ITextSource fileContent, TypeScriptProject project, IEnumerable<TypeScriptFile> files) { try { using (TypeScriptContext context = contextFactory.CreateContext()) { context.AddFile(fileName, fileContent.Text); context.RunInitialisationScript(); NavigationBarItem[] navigation = context.GetNavigationInfo(fileName); var unresolvedFile = new TypeScriptUnresolvedFile(fileName); unresolvedFile.AddNavigation(navigation, fileContent); if (project != null) { context.AddFiles(files); var document = new TextDocument(fileContent); Diagnostic[] diagnostics = context.GetDiagnostics(fileName, project.GetOptions()); TypeScriptService.TaskService.Update(diagnostics, fileName); } return new ParseInformation(unresolvedFile, fileContent.Version, true); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); LoggingService.Debug(ex.ToString()); } return new ParseInformation( new TypeScriptUnresolvedFile(fileName), fileContent.Version, true); }
public DocumentViewModel(ITextSource document) { Ensure.ArgumentNotNull(document, "document"); Document = document; Document.TextChanged += OnTextChanged; }
protected IEnumerable<NewFolding> getOffsets(char opening, char closing, ITextSource document) { List<NewFolding> ret = new List<NewFolding>(); Stack<int> openings = new Stack<int>(); bool multiline = false; //flag of multiline braces for(int pos = 0; pos < document.TextLength; ++pos) { char c = document.GetCharAt(pos); if(c == opening) { openings.Push(pos + 1); multiline = false; } else if(char.IsControl(c)) { multiline = true; } else if(openings.Count > 0 && c == closing) { int offset = openings.Pop(); if(multiline) { ret.Add(new NewFolding(offset, pos)); } } } return ret; }
public IEnumerable<ISearchResult> FindAllValidating(ITextSource document, int offset, int length) { using (var stream = document.CreateReader()) { var doc = (IDocument)document; var xmlDoc = new XPathDocument(stream); ; var navigator = xmlDoc.CreateNavigator(); XPathExpression expr = null; XPathNodeIterator iterator; try { expr = navigator.Compile(_xPath); iterator = navigator.Select(expr); } catch (System.Xml.XPath.XPathException) { yield break; } while (iterator.MoveNext()) { var current = iterator.Current; var segment = XmlSegment(doc, ((IXmlLineInfo)current).LineNumber, ((IXmlLineInfo)current).LinePosition); if (segment != null && segment.Offset >= offset && segment.EndOffset <= (offset + length)) { yield return new XPathSearchResult() { StartOffset = segment.Offset, Length = segment.Length }; } } } }
public ParseInformation Parse(FileName fileName, ITextSource fileContent, bool fullParseInformationRequested, IProject parentProject, CancellationToken cancellationToken) { var csharpProject = parentProject as CSharpProject; CSharpParser parser = new CSharpParser(csharpProject != null ? csharpProject.CompilerSettings : null); parser.GenerateTypeSystemMode = !fullParseInformationRequested; SyntaxTree cu = parser.Parse(fileContent, fileName); cu.Freeze(); CSharpUnresolvedFile file = cu.ToTypeSystem(); ParseInformation parseInfo; if (fullParseInformationRequested) parseInfo = new CSharpFullParseInformation(file, fileContent.Version, cu); else parseInfo = new ParseInformation(file, fileContent.Version, fullParseInformationRequested); IDocument document = fileContent as IDocument; AddCommentTags(cu, parseInfo.TagComments, fileContent, parseInfo.FileName, ref document); if (fullParseInformationRequested) { if (document == null) document = new ReadOnlyDocument(fileContent, parseInfo.FileName); ((CSharpFullParseInformation)parseInfo).newFoldings = CreateNewFoldings(cu, document); } return parseInfo; }
/// <summary> /// Creates a new StringBuilderDocument with the initial text copied from the specified text source. /// </summary> public StringBuilderDocument(ITextSource textSource) { if (textSource == null) throw new ArgumentNullException("textSource"); b = new StringBuilder(textSource.TextLength); textSource.WriteTextTo(new StringWriter(b)); }
/// <summary> /// Create <see cref="NewFolding"/>s for the specified document. /// </summary> public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document) { var newFoldings = new List<NewFolding>(); var template = FoldingTemplates[0]; var regexOpenFolding = new Regex(template.OpeningPhrase); var matchesOpenFolding = regexOpenFolding.Matches(document.Text); var regexCloseFolding = new Regex(template.ClosingPhrase); var matchesCloseFolding = regexCloseFolding.Matches(document.Text); var currentOpenIndex = 0; for (var i = 0; i < matchesCloseFolding.Count && currentOpenIndex < matchesOpenFolding.Count; i++) { if (matchesOpenFolding[currentOpenIndex].Index >= matchesCloseFolding[i].Index) continue; var folding = new NewFolding(matchesOpenFolding[currentOpenIndex].Index + 1, matchesCloseFolding[i].Index + 10) { DefaultClosed = template.IsDefaultFolded, Name = template.Name }; newFoldings.Add(folding); while (currentOpenIndex < matchesOpenFolding.Count && matchesOpenFolding[currentOpenIndex].Index < matchesCloseFolding[i].Index) { currentOpenIndex++; } } return newFoldings; }
/// <summary> /// Create <see cref="NewFolding"/>s for the specified document. /// </summary> public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document) { List<NewFolding> newFoldings = new List<NewFolding>(); Stack<int> startOffsets = new Stack<int>(); int lastNewLineOffset = 0; char openingBrace = OpeningBrace; char closingBrace = ClosingBrace; foreach (var startKeyword in foldingKeywords.Keys) { int lastKeywordPos = 0; int pos = 0; while ((pos = document.Text.IndexOf(startKeyword, pos)) > lastKeywordPos) { int endOffset = document.Text.IndexOf(foldingKeywords[startKeyword], pos); if (endOffset > pos) { var offset = document.Text.IndexOf("\r\n", pos); var name = document.Text.Substring(pos + 8, offset - (pos + 8)); var folding = new NewFolding(pos, endOffset + 10); folding.Name = name; // Add the folding newFoldings.Add(folding); } lastKeywordPos = pos; } } for (int i = 0; i < document.TextLength; i++) { char c = document.GetCharAt(i); if (c == openingBrace) { startOffsets.Push(i); } else if (c == closingBrace && startOffsets.Count > 0) { int startOffset = startOffsets.Pop(); // don't fold if opening and closing brace are on the same line if (startOffset < lastNewLineOffset) { newFoldings.Add(new NewFolding(startOffset, i + 1)); } } else if (c == '\n' || c == '\r') { lastNewLineOffset = i + 1; } } newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset)); return newFoldings; }
protected TextSourceAdapter(ITextSource textSource) { if (textSource == null) { throw new ArgumentNullException("textSource"); } TextSource = textSource; }
/// <summary> /// Creates a new TextChangeEventArgs object. /// </summary> public TextChangeEventArgs(int offset, ITextSource removedText, ITextSource insertedText) { if (offset < 0) throw new ArgumentOutOfRangeException("offset", offset, "offset must not be negative"); this.offset = offset; this.removedText = removedText ?? StringTextSource.Empty; this.insertedText = insertedText ?? StringTextSource.Empty; }
public TextScanner(ITextSource textSource) { if (textSource == null) { throw new ArgumentNullException(nameof(textSource)); } this.textSource = textSource; }
public IEnumerable<ISearchResult> FindAll(ITextSource document, int offset, int length) { int endOffset = offset + length; foreach (Match result in searchPattern.Matches(document.Text)) { if (offset <= result.Index && endOffset >= (result.Length + result.Index)) yield return new SearchResult { StartOffset = result.Index, Length = result.Length, Data = result }; } }
/// <summary> /// Parses a document incrementally into a flat list of tags. /// </summary> /// <param name="oldParserState">The parser state from a previous call to ParseIncremental(). Use null for the first call.</param> /// <param name="newTextSource">The text source for the new document version.</param> /// <param name="newParserState">Out: the new parser state, pass this to the next ParseIncremental() call.</param> /// <param name="cancellationToken">Optional: cancellation token.</param> /// <returns>Parsed tag soup.</returns> public IList<AXmlObject> ParseTagSoupIncremental( IncrementalParserState oldParserState, ITextSource newTextSource, out IncrementalParserState newParserState, CancellationToken cancellationToken = default(CancellationToken)) { if (newTextSource == null) throw new ArgumentNullException("newTextSource"); var internalObjects = InternalParseIncremental(oldParserState, newTextSource, out newParserState, false, cancellationToken); return CreatePublic(internalObjects); }
/// <summary> /// Parses a document into a flat list of tags. /// </summary> /// <returns>Parsed tag soup.</returns> public IList<AXmlObject> ParseTagSoup(ITextSource textSource, CancellationToken cancellationToken = default(CancellationToken)) { if (textSource == null) throw new ArgumentNullException("textSource"); var reader = new TagReader(this, textSource, false); var internalObjects = reader.ReadAllObjects(cancellationToken); return CreatePublic(internalObjects); }
public IList<FoldingRegion> GetFolds(ITextSource textSource) { try { GetFolds(textSource.CreateReader()); return folds; } catch (XmlException) { } return null; }
/// <summary> /// Parses a document. /// </summary> public AXmlDocument Parse(ITextSource textSource, CancellationToken cancellationToken = default(CancellationToken)) { if (textSource == null) throw new ArgumentNullException("textSource"); var reader = new TagReader(this, textSource, true); var internalObjects = reader.ReadAllObjects(cancellationToken); var heuristic = new TagMatchingHeuristics(textSource); return new AXmlDocument(null, 0, heuristic.CreateDocument(internalObjects, cancellationToken)); }
public void UpdateFoldings(FoldingManager manager, ITextSource document) { if (manager == null) throw new ArgumentNullException("manager"); int firstErrorOffset; IEnumerable<NewFolding> newFoldings = CreateNewFoldings(document, out firstErrorOffset); manager.UpdateFoldings(newFoldings, firstErrorOffset); }
/// <summary> /// Creates a new DocumentationComment. /// </summary> /// <param name="xml">The XML text.</param> /// <param name="context">Context for resolving cref attributes.</param> public DocumentationComment(string xml, ITypeResolveContext context) { if (xml == null) throw new ArgumentNullException("xml"); if (context == null) throw new ArgumentNullException("context"); this.xml = new StringTextSource(xml); this.context = context; }
public CSharpDocumentationComment(ITextSource xmlDoc, ITypeResolveContext context) : base(xmlDoc, context) { }
ProjectEntry DoParse(ITextSource fileContent, IProject parentProject, bool fullParseInformationRequested, CancellationToken cancellationToken) { if (parser == null) { return(default(ProjectEntry)); } if (fileContent == null) { // No file content was specified. Because the callers of this method already check for currently open files, // we can assume that the file isn't open and simply read it from disk. try { fileContent = SD.FileService.GetFileContentFromDisk(fileName, cancellationToken); } catch (IOException) { // It is possible that the file gets deleted/becomes inaccessible while a background parse // operation is enqueued, so we have to handle IO exceptions. return(default(ProjectEntry)); } catch (UnauthorizedAccessException) { return(default(ProjectEntry)); } } ProjectEntry result; rwLock.EnterUpgradeableReadLock(); try { int index = FindIndexForProject(parentProject); int versionComparison = CompareVersions(fileContent.Version); if (versionComparison > 0 || index < 0) { // We're going backwards in time, or are requesting a project that is not an owner // for this entry. var parseInfo = ParseWithExceptionHandling(fileContent, fullParseInformationRequested, parentProject, cancellationToken); FreezableHelper.Freeze(parseInfo.UnresolvedFile); return(new ProjectEntry(parentProject, parseInfo.UnresolvedFile, parseInfo)); } else { if (versionComparison == 0 && index >= 0) { // Ensure we have parse info for the specified project (entry.UnresolvedFile is null for newly registered projects) // If full parse info is requested, ensure we have full parse info. if (entries[index].UnresolvedFile != null && !(fullParseInformationRequested && entries[index].CachedParseInformation == null)) { // We already have the requested version parsed, just return it: return(entries[index]); } } } ParseInformationEventArgs[] results = new ParseInformationEventArgs[entries.Count]; for (int i = 0; i < entries.Count; i++) { var parseInfo = ParseWithExceptionHandling(fileContent, fullParseInformationRequested, entries[i].Project, cancellationToken); if (parseInfo == null) { throw new NullReferenceException(parser.GetType().Name + ".Parse() returned null"); } if (fullParseInformationRequested && !parseInfo.IsFullParseInformation) { throw new InvalidOperationException(parser.GetType().Name + ".Parse() did not return full parse info as requested."); } OnDiskTextSourceVersion onDiskVersion = fileContent.Version as OnDiskTextSourceVersion; if (onDiskVersion != null) { parseInfo.UnresolvedFile.LastWriteTime = onDiskVersion.LastWriteTime; } FreezableHelper.Freeze(parseInfo.UnresolvedFile); results[i] = new ParseInformationEventArgs(entries[i].Project, entries[i].UnresolvedFile, parseInfo); } // Only if all parse runs succeeded, register the parse information. rwLock.EnterWriteLock(); try { currentVersion = fileContent.Version; for (int i = 0; i < entries.Count; i++) { if (fullParseInformationRequested || (entries[i].CachedParseInformation != null && results[i].NewParseInformation.IsFullParseInformation)) { entries[i] = new ProjectEntry(entries[i].Project, results[i].NewUnresolvedFile, results[i].NewParseInformation); } else { entries[i] = new ProjectEntry(entries[i].Project, results[i].NewUnresolvedFile, null); } if (entries[i].Project != null) { entries[i].Project.OnParseInformationUpdated(results[i]); } parserService.RaiseParseInformationUpdated(results[i]); } result = entries[index]; } finally { rwLock.ExitWriteLock(); } } finally { rwLock.ExitUpgradeableReadLock(); } parserService.RegisterForCacheExpiry(this); return(result); }
void IDocument.Replace(int offset, int length, ITextSource newText) { throw new NotSupportedException(); }
void IDocument.Insert(int offset, ITextSource text) { throw new NotSupportedException(); }
public void FindLocalReferences(ParseInformation parseInfo, ITextSource fileContent, IVariable variable, ICompilation compilation, Action <SearchResultMatch> callback, CancellationToken cancellationToken) { throw new NotImplementedException(); }
// Methods public BookMarks(ITextSource Owner) { this.owner = Owner; }
public TokenReader(ITextSource input) { this.input = input; this.inputLength = input.TextLength; }
public static void Run(ITextSource originalXmlFile) { int seed; lock (sharedRnd) { seed = sharedRnd.Next(); } Console.WriteLine(seed); Random rnd = new Random(seed); AXmlParser parser = new AXmlParser(); StringBuilder b = new StringBuilder(originalXmlFile.Text); IncrementalParserState parserState = null; var versionProvider = new TextSourceVersionProvider(); int totalCharactersParsed = 0; int totalCharactersChanged = originalXmlFile.TextLength; TimeSpan incrementalParseTime = TimeSpan.Zero; TimeSpan nonIncrementalParseTime = TimeSpan.Zero; Stopwatch w = new Stopwatch(); for (int iteration = 0; iteration < 100; iteration++) { totalCharactersParsed += b.Length; var textSource = new StringTextSource(b.ToString(), versionProvider.CurrentVersion); w.Restart(); var incrementalResult = parser.ParseIncremental(parserState, textSource, out parserState); w.Stop(); incrementalParseTime += w.Elapsed; w.Restart(); var nonIncrementalResult = parser.Parse(textSource); w.Stop(); nonIncrementalParseTime += w.Elapsed; CompareResults(incrementalResult, nonIncrementalResult); incrementalResult.AcceptVisitor(new ValidationVisitor(textSource)); // Randomly mutate the file: List <TextChangeEventArgs> changes = new List <TextChangeEventArgs>(); int modifications = rnd.Next(0, 25); int offset = 0; for (int i = 0; i < modifications; i++) { if (i == 0 || rnd.Next(0, 10) == 0) { offset = rnd.Next(0, b.Length); } else { offset += rnd.Next(0, Math.Min(10, b.Length - offset)); } int originalOffset = rnd.Next(0, originalXmlFile.TextLength); int insertionLength; int removalLength; switch (rnd.Next(0, 21) / 10) { case 0: removalLength = 0; insertionLength = rnd.Next(0, Math.Min(50, originalXmlFile.TextLength - originalOffset)); break; case 1: removalLength = rnd.Next(0, Math.Min(20, b.Length - offset)); insertionLength = rnd.Next(0, Math.Min(20, originalXmlFile.TextLength - originalOffset)); break; default: removalLength = rnd.Next(0, b.Length - offset); insertionLength = rnd.Next(0, originalXmlFile.TextLength - originalOffset); break; } string removedText = b.ToString(offset, removalLength); b.Remove(offset, removalLength); string insertedText = originalXmlFile.GetText(originalOffset, insertionLength); b.Insert(offset, insertedText); versionProvider.AppendChange(new TextChangeEventArgs(offset, removedText, insertedText)); totalCharactersChanged += insertionLength; } } Console.WriteLine("Incremental parse time: " + incrementalParseTime + " for " + totalCharactersChanged + " characters changed"); Console.WriteLine("Non-Incremental parse time: " + nonIncrementalParseTime + " for " + totalCharactersParsed + " characters"); }
protected override ITextSource FormatImplementation(PolicyContainer policyParent, string mimeType, ITextSource input, int startOffset, int length) { var chain = DesktopService.GetMimeTypeInheritanceChain(mimeType); var policy = policyParent.Get <CSharpFormattingPolicy> (chain); var textPolicy = policyParent.Get <TextStylePolicy> (chain); return(new StringTextSource(FormatText(policy.CreateOptions(textPolicy), input.Text, startOffset, startOffset + length))); }
public ISearchResult FindNext(ITextSource document, int offset, int length) { return(FindAll(document, offset, length).FirstOrDefault()); }
static bool IsWordBorder(ITextSource document, int offset) { return(TextUtilities.GetNextCaretPosition(document, offset - 1, LogicalDirection.Forward, CaretPositioningMode.WordBorder) == offset); }
Task RunUpdateTask(ITextSource input, IDocumentLine startLine, int endOffset, CancellationToken token) { return(Task.Run(delegate { var matches = new List <(UrlType, Match, IDocumentLine)> (); var line = startLine; int o = 0; while (line != null && line.Offset <= endOffset) { if (token.IsCancellationRequested) { return; } string lineText = input.GetTextAt(line.Offset, line.Length); var match = UrlRegex.Match(lineText); while (match.Success) { if (token.IsCancellationRequested) { return; } matches.Add((UrlType.Url, match, line)); o = match.Index + match.Length; var len = line.Length - o; if (len <= 0) { break; } match = UrlRegex.Match(lineText, o, len); } o = 0; match = MailRegex.Match(lineText); while (match.Success) { if (token.IsCancellationRequested) { return; } matches.Add((UrlType.Email, match, line)); o = match.Index + match.Length; var len = line.Length - o; if (len <= 0) { break; } match = MailRegex.Match(lineText, o, len); } line = line.NextLine; } Runtime.RunInMainThread(delegate { if (token.IsCancellationRequested) { return; } line = startLine; while (line != null && line.Offset <= endOffset) { foreach (var u in Editor.GetLineMarkers(line).OfType <IUrlTextLineMarker> ()) { Editor.RemoveMarker(u); markers.Remove(u); } line = line.NextLine; } foreach (var m in matches) { var startCol = m.Item2.Index; var url = m.Item2.Value; var marker = Editor.TextMarkerFactory.CreateUrlTextMarker(Editor, url, m.Item1, "url", startCol, startCol + m.Item2.Length); markers.Add(marker); Editor.AddMarker(m.Item3, marker); } src.Remove(startLine.Offset); }); }));
public PrioritizedTextSource(ITextSource source, int priority = 0) { Source = source; Priority = priority; }
/// <summary> /// Gets the next caret position. /// </summary> /// <param name="textSource">The text source.</param> /// <param name="offset">The start offset inside the text source.</param> /// <param name="direction">The search direction (forwards or backwards).</param> /// <param name="mode">The mode for caret positioning.</param> /// <returns>The offset of the next caret position, or -1 if there is no further caret position /// in the text source.</returns> /// <remarks> /// This method is NOT equivalent to the actual caret movement when using VisualLine.GetNextCaretPosition. /// In real caret movement, there are additional caret stops at line starts and ends. This method /// treats linefeeds as simple whitespace. /// </remarks> public static int GetNextCaretPosition(ITextSource textSource, int offset, LogicalDirection direction, CaretPositioningMode mode) { if (textSource == null) { throw new ArgumentNullException("textSource"); } switch (mode) { case CaretPositioningMode.Normal: case CaretPositioningMode.EveryCodepoint: case CaretPositioningMode.WordBorder: case CaretPositioningMode.WordBorderOrSymbol: case CaretPositioningMode.WordStart: case CaretPositioningMode.WordStartOrSymbol: break; // OK default: throw new ArgumentException("Unsupported CaretPositioningMode: " + mode, "mode"); } if (direction != LogicalDirection.Backward && direction != LogicalDirection.Forward) { throw new ArgumentException("Invalid LogicalDirection: " + direction, "direction"); } int textLength = textSource.TextLength; if (textLength <= 0) { // empty document? has a normal caret position at 0, though no word borders if (IsNormal(mode)) { if (offset > 0 && direction == LogicalDirection.Backward) { return(0); } if (offset < 0 && direction == LogicalDirection.Forward) { return(0); } } return(-1); } while (true) { int nextPos = (direction == LogicalDirection.Backward) ? offset - 1 : offset + 1; // return -1 if there is no further caret position in the text source // we also need this to handle offset values outside the valid range if (nextPos < 0 || nextPos > textLength) { return(-1); } // check if we've run against the textSource borders. // a 'textSource' usually isn't the whole document, but a single VisualLineElement. if (nextPos == 0) { // at the document start, there's only a word border // if the first character is not whitespace if (IsNormal(mode) || !char.IsWhiteSpace(textSource.GetCharAt(0))) { return(nextPos); } } else if (nextPos == textLength) { // at the document end, there's never a word start if (mode != CaretPositioningMode.WordStart && mode != CaretPositioningMode.WordStartOrSymbol) { // at the document end, there's only a word border // if the last character is not whitespace if (IsNormal(mode) || !char.IsWhiteSpace(textSource.GetCharAt(textLength - 1))) { return(nextPos); } } } else { char charBefore = textSource.GetCharAt(nextPos - 1); char charAfter = textSource.GetCharAt(nextPos); // Don't stop in the middle of a surrogate pair if (!char.IsSurrogatePair(charBefore, charAfter)) { CharacterClass classBefore = GetCharacterClass(charBefore); CharacterClass classAfter = GetCharacterClass(charAfter); // get correct class for characters outside BMP: if (char.IsLowSurrogate(charBefore) && nextPos >= 2) { classBefore = GetCharacterClass(textSource.GetCharAt(nextPos - 2), charBefore); } if (char.IsHighSurrogate(charAfter) && nextPos + 1 < textLength) { classAfter = GetCharacterClass(charAfter, textSource.GetCharAt(nextPos + 1)); } if (StopBetweenCharacters(mode, classBefore, classAfter)) { return(nextPos); } } } // we'll have to continue searching... offset = nextPos; } }
void IDocument.Insert(int offset, ITextSource text, AnchorMovementType defaultAnchorMovementType) { throw new NotSupportedException(); }
public IEnumerable <NewFolding> CreateNewFoldings(ITextSource document) { var newFoldings = new List <NewFolding>(); Stack <int> startOffsets = new Stack <int>(); int lastNewLineOffset = 0; int CommentMode = 0; // 0 = None, 1 = Single, 2 = Multi, 3 = String for (int i = 0; i < document.TextLength; ++i) { var c = document.GetCharAt(i); if (c == '\n' || c == '\r') { lastNewLineOffset = i + 1; if (CommentMode == 1) { CommentMode = 0; } } else { switch (CommentMode) { case 0: { switch (c) { case '/': { if ((i + 1) < document.TextLength) { char oneCharAfter = document.GetCharAt(i + 1); if (oneCharAfter == '*') { CommentMode = 2; startOffsets.Push(i); } else if (oneCharAfter == '/') { CommentMode = 1; } } break; } case '{': { startOffsets.Push(i); break; } case '}': { if (startOffsets.Count > 0) { int startOffset = startOffsets.Pop(); if (startOffset < lastNewLineOffset) { newFoldings.Add(new NewFolding(startOffset, i + 1)); } } break; } case '\"': { CommentMode = 3; break; } } break; } case 2: { if (c == '/') { if (i > 0) { if (document.GetCharAt(i - 1) == '*') { int startOffset = startOffsets.Pop(); CommentMode = 0; if (startOffset < lastNewLineOffset) { newFoldings.Add(new NewFolding(startOffset, i + 1)); } } } } break; } case 3: { if (c == '\"') { CommentMode = 0; } break; } } } } /*Stack<int> startOffsets = new Stack<int>(); * int lastNewLineOffset = 0; * char openingBrace = this.OpeningBrace; * char closingBrace = this.ClosingBrace; * for (int i = 0; i < document.TextLength; i++) * { * char c = document.GetCharAt(i); * if (c == openingBrace) * { * startOffsets.Push(i); * } * else if (c == closingBrace && startOffsets.Count > 0) * { * int startOffset = startOffsets.Pop(); * // don't fold if opening and closing brace are on the same line * if (startOffset < lastNewLineOffset) * { * newFoldings.Add(new NewFolding(startOffset, i + 1)); * } * } * else if (c == '\n' || c == '\r') * { * lastNewLineOffset = i + 1; * } * }*/ newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset)); return(newFoldings); }
/// <summary> /// Creates a new ReadOnlyDocument from the given text source; /// and sets IDocument.FileName to the specified file name. /// </summary> public ReadOnlyDocument(ITextSource textSource, string fileName) : this(textSource) { this.fileName = fileName; }
void CreateNewCurrentSnapshot(IList <ITextChange> changes, int?reiteratedVersionNumber = null, ITextSource afterTextSource = null) { // It's null the first time it's called from the ctor if (changes != null) { currentTextVersion = currentTextVersion.SetChanges(changes, reiteratedVersionNumber); } var textSource = afterTextSource ?? Document.CreateSnapshot(); var textImage = new TextImage(this, textSource, currentTextVersion.ImageVersion); CurrentSnapshot = new TextSnapshot(textImage, ContentType, this, currentTextVersion); }
public async Task <ParseInformation> ParseAsync(ITextSource fileContent, IProject parentProject, CancellationToken cancellationToken) { return((await DoParseAsync(fileContent, parentProject, true, cancellationToken)).CachedParseInformation); }
void ParseFiles(List <FileName> filesToParse, IProgressMonitor progressMonitor) { IProjectContent cachedPC = TryReadFromCache(cacheFileName); ParseableFileContentFinder finder = new ParseableFileContentFinder(); object progressLock = new object(); double fileCountInverse = 1.0 / filesToParse.Count; int fileCountLoadedFromCache = 0; int fileCountParsed = 0; int fileCountParsedAndSerializable = 0; Parallel.ForEach( filesToParse, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = progressMonitor.CancellationToken }, fileName => { ITextSource content = finder.CreateForOpenFile(fileName); bool wasLoadedFromCache = false; IUnresolvedFile unresolvedFile = null; if (content == null && cachedPC != null) { unresolvedFile = cachedPC.GetFile(fileName); if (unresolvedFile != null && unresolvedFile.LastWriteTime == File.GetLastWriteTimeUtc(fileName)) { parserService.RegisterUnresolvedFile(fileName, project, unresolvedFile); wasLoadedFromCache = true; } } if (!wasLoadedFromCache) { if (content == null) { try { content = SD.FileService.GetFileContentFromDisk(fileName); } catch (IOException) { } catch (UnauthorizedAccessException) { } } if (content != null) { unresolvedFile = parserService.ParseFile(fileName, content, project); } } lock (progressLock) { if (wasLoadedFromCache) { fileCountLoadedFromCache++; } else { fileCountParsed++; if (IsSerializable(unresolvedFile)) { fileCountParsedAndSerializable++; } } // SD.MainThread.InvokeAsyncAndForget(delegate { assemblyModel.Update(null, unresolvedFile); }); progressMonitor.Progress += fileCountInverse; } }); LoggingService.Debug(projectContent.AssemblyName + ": ParseFiles() finished. " + fileCountLoadedFromCache + " files were re-used from CC cache; " + fileCountParsed + " files were parsed (" + fileCountParsedAndSerializable + " of those are serializable)"); lock (lockObj) { serializedProjectContentIsUpToDate = (fileCountLoadedFromCache > 0 && fileCountParsedAndSerializable == 0); } }
public IEnumerable <IEditorScript> GetScripts(ITextSource text, int offset) { return(Enumerable.Empty <IEditorScript>()); }
/// <summary> /// Fetches text runs. /// </summary> /// <param name="textSource">The text source.</param> /// <param name="firstTextSourceIndex">The first text source index.</param> /// <param name="previousLineBreak">Previous line break. Can be null.</param> /// <param name="nextLineBreak">Next line break. Can be null.</param> /// <returns> /// The formatted text runs. /// </returns> private static IReadOnlyList <ShapedTextCharacters> FetchTextRuns(ITextSource textSource, int firstTextSourceIndex, TextLineBreak previousLineBreak, out TextLineBreak nextLineBreak) { nextLineBreak = default; var currentLength = 0; var textRuns = new List <ShapedTextCharacters>(); if (previousLineBreak != null) { foreach (var shapedCharacters in previousLineBreak.RemainingCharacters) { textRuns.Add(shapedCharacters); if (TryGetLineBreak(shapedCharacters, out var runLineBreak)) { var splitResult = SplitTextRuns(textRuns, currentLength + runLineBreak.PositionWrap); nextLineBreak = new TextLineBreak(splitResult.Second); return(splitResult.First); } currentLength += shapedCharacters.Text.Length; } } firstTextSourceIndex += currentLength; var textRunEnumerator = new TextRunEnumerator(textSource, firstTextSourceIndex); while (textRunEnumerator.MoveNext()) { var textRun = textRunEnumerator.Current; switch (textRun) { case TextCharacters textCharacters: { var shapeableRuns = textCharacters.GetShapeableCharacters(); foreach (var run in shapeableRuns) { var glyphRun = TextShaper.Current.ShapeText(run.Text, run.Properties.Typeface, run.Properties.FontRenderingEmSize, run.Properties.CultureInfo); var shapedCharacters = new ShapedTextCharacters(glyphRun, textRun.Properties); textRuns.Add(shapedCharacters); } break; } } if (TryGetLineBreak(textRun, out var runLineBreak)) { var splitResult = SplitTextRuns(textRuns, currentLength + runLineBreak.PositionWrap); nextLineBreak = new TextLineBreak(splitResult.Second); return(splitResult.First); } currentLength += textRun.Text.Length; } return(textRuns); }
public abstract IEnumerable <NewFolding> CreateNewFoldings(ITextSource document);
/// <summary> /// Formats a text line. /// </summary> /// <param name="textSource">The text source.</param> /// <param name="firstTextSourceIndex">The first character index to start the text line from.</param> /// <param name="paragraphWidth">A <see cref="double"/> value that specifies the width of the paragraph that the line fills.</param> /// <param name="paragraphProperties">A <see cref="TextParagraphProperties"/> value that represents paragraph properties, /// such as TextWrapping, TextAlignment, or TextStyle.</param> /// <returns>The formatted line.</returns> public abstract TextLine FormatLine(ITextSource textSource, int firstTextSourceIndex, double paragraphWidth, TextParagraphProperties paragraphProperties);
public ScriptParser(ITextSource source, ParserSettings settings) : base(source, settings) { }
internal static Task <ParsedDocumentProjection> ParseProjection(Project project, string fileName, string mimeType, ITextSource content, CancellationToken cancellationToken = default(CancellationToken)) { return(ParseProjection(new ParseOptions { FileName = fileName, Project = project, Content = content }, mimeType, cancellationToken)); }
/// <summary> /// Gets the next caret position. /// </summary> /// <param name="textSource">The text source.</param> /// <param name="offset">The start offset inside the text source.</param> /// <param name="direction">The search direction (forwards or backwards).</param> /// <param name="mode">The mode for caret positioning.</param> /// <returns>The offset of the next caret position, or -1 if there is no further caret position /// in the text source.</returns> /// <remarks> /// This method is NOT equivalent to the actual caret movement when using VisualLine.GetNextCaretPosition. /// In real caret movement, there are additional caret stops at line starts and ends. This method /// treats linefeeds as simple whitespace. /// </remarks> public static int GetNextCaretPosition(ITextSource textSource, int offset, LogicalDirection direction, CaretPositioningMode mode) { if (textSource == null) { throw new ArgumentNullException("textSource"); } if (mode != CaretPositioningMode.Normal && mode != CaretPositioningMode.WordBorder && mode != CaretPositioningMode.WordStart && mode != CaretPositioningMode.WordBorderOrSymbol && mode != CaretPositioningMode.WordStartOrSymbol) { throw new ArgumentException("Unsupported CaretPositioningMode: " + mode, "mode"); } if (direction != LogicalDirection.Backward && direction != LogicalDirection.Forward) { throw new ArgumentException("Invalid LogicalDirection: " + direction, "direction"); } int textLength = textSource.TextLength; if (textLength <= 0) { // empty document? has a normal caret position at 0, though no word borders if (mode == CaretPositioningMode.Normal) { if (offset > 0 && direction == LogicalDirection.Backward) { return(0); } if (offset < 0 && direction == LogicalDirection.Forward) { return(0); } } return(-1); } while (true) { int nextPos = (direction == LogicalDirection.Backward) ? offset - 1 : offset + 1; // return -1 if there is no further caret position in the text source // we also need this to handle offset values outside the valid range if (nextPos < 0 || nextPos > textLength) { return(-1); } // stop at every caret position? we can stop immediately. if (mode == CaretPositioningMode.Normal) { return(nextPos); } // not normal mode? we're looking for word borders... // check if we've run against the textSource borders. // a 'textSource' usually isn't the whole document, but a single VisualLineElement. if (nextPos == 0) { // at the document start, there's only a word border // if the first character is not whitespace if (!char.IsWhiteSpace(textSource.GetCharAt(0))) { return(nextPos); } } else if (nextPos == textLength) { // at the document end, there's never a word start if (mode != CaretPositioningMode.WordStart && mode != CaretPositioningMode.WordStartOrSymbol) { // at the document end, there's only a word border // if the last character is not whitespace if (!char.IsWhiteSpace(textSource.GetCharAt(textLength - 1))) { return(nextPos); } } } else { CharacterClass charBefore = GetCharacterClass(textSource.GetCharAt(nextPos - 1)); CharacterClass charAfter = GetCharacterClass(textSource.GetCharAt(nextPos)); if (charBefore == charAfter) { if (charBefore == CharacterClass.Other && (mode == CaretPositioningMode.WordBorderOrSymbol || mode == CaretPositioningMode.WordStartOrSymbol)) { // With the "OrSymbol" modes, there's a word border and start between any two unknown characters return(nextPos); } } else { // this looks like a possible border // if we're looking for word starts, check that this is a word start (and not a word end) // if we're just checking for word borders, accept unconditionally if (!((mode == CaretPositioningMode.WordStart || mode == CaretPositioningMode.WordStartOrSymbol) && (charAfter == CharacterClass.Whitespace || charAfter == CharacterClass.LineTerminator))) { return(nextPos); } } } // we'll have to continue searching... offset = nextPos; } }
public static MSBuildRootDocument Parse( ITextSource textSource, MSBuildRootDocument previous, MSBuildSchemaProvider schemaProvider, IRuntimeInformation runtimeInfo, ITaskMetadataBuilder taskBuilder, CancellationToken token) { var xmlParser = new XmlParser(new XmlRootState(), true); try { xmlParser.Parse(textSource.CreateReader()); } catch (Exception ex) { LoggingService.LogError("Unhandled error parsing xml document", ex); } var xdocument = xmlParser.Nodes.GetRoot(); if (xdocument != null && xdocument.RootElement != null) { if (!xdocument.RootElement.IsEnded) { xdocument.RootElement.End(xmlParser.Position); } } var propVals = new PropertyValueCollector(true); string filepath = textSource.FileName; var doc = new MSBuildRootDocument(filepath) { XDocument = xdocument, Text = textSource, RuntimeInformation = runtimeInfo }; doc.Errors.AddRange(xmlParser.Diagnostics); var importedFiles = new HashSet <string> (StringComparer.OrdinalIgnoreCase); if (filepath != null) { try { doc.Schema = previous?.Schema ?? schemaProvider.GetSchema(filepath, null); } catch (Exception ex) { LoggingService.LogError("Error loading schema", ex); } importedFiles.Add(filepath); } var parseContext = new MSBuildParserContext( runtimeInfo, doc, previous, importedFiles, filepath, propVals, taskBuilder, schemaProvider, token); if (filepath != null) { doc.FileEvaluationContext = new MSBuildFileEvaluationContext(parseContext.RuntimeEvaluationContext, filepath, filepath); } else { doc.FileEvaluationContext = parseContext.RuntimeEvaluationContext; } string MakeRelativeMSBuildPathAbsolute(string path) { var dir = Path.GetDirectoryName(doc.Filename); path = path.Replace('\\', Path.DirectorySeparatorChar); return(Path.GetFullPath(Path.Combine(dir, path))); } Import TryImportFile(string label, string possibleFile) { try { var fi = new FileInfo(possibleFile); if (fi.Exists) { var imp = parseContext.GetCachedOrParse(label, possibleFile, null, fi.LastWriteTimeUtc); doc.AddImport(imp); return(imp); } } catch (Exception ex) { LoggingService.LogError($"Error importing '{possibleFile}'", ex); } return(null); } Import TryImportSibling(string ifHasThisExtension, string thenTryThisExtension) { if (filepath == null) { return(null); } var extension = Path.GetExtension(filepath); if (string.Equals(ifHasThisExtension, extension, StringComparison.OrdinalIgnoreCase)) { var siblingFilename = Path.ChangeExtension(filepath, thenTryThisExtension); return(TryImportFile("(implicit)", siblingFilename)); } return(null); } void TryImportIntellisenseImports(MSBuildSchema schema) { foreach (var intellisenseImport in schema.IntelliSenseImports) { TryImportFile("(from schema)", MakeRelativeMSBuildPathAbsolute(intellisenseImport)); } } try { //if this is a targets file, try to import the props _at the top_ var propsImport = TryImportSibling(".targets", ".props"); // this currently only happens in the root file // it's a quick hack to allow files to get some basic intellisense by // importing the files _that they themselves expect to be imported from_. // we also try to load them from the sibling props, as a paired targets/props // will likely share a schema file. var schema = doc.Schema ?? propsImport?.Document?.Schema; if (schema != null) { TryImportIntellisenseImports(doc.Schema); } doc.Build(xdocument, textSource, parseContext); //if this is a props file, try to import the targets _at the bottom_ var targetsImport = TryImportSibling(".props", ".targets"); //and if we didn't load intellisense import already, try to load them from the sibling targets if (schema == null && targetsImport?.Document?.Schema != null) { TryImportIntellisenseImports(targetsImport.Document.Schema); } } catch (Exception ex) { LoggingService.LogError($"Error building document '{filepath ?? "[unnamed]"}'", ex); } try { var binpath = parseContext.RuntimeInformation.BinPath; foreach (var t in Directory.GetFiles(binpath, "*.tasks")) { doc.LoadTasks(parseContext, "(core tasks)", t); } foreach (var t in Directory.GetFiles(binpath, "*.overridetasks")) { doc.LoadTasks(parseContext, "(core overridetasks)", t); } } catch (Exception ex) { LoggingService.LogError("Error resolving tasks", ex); } try { if (previous != null) { // try to recover some values that may have been collected from the imports, as they // will not have been re-evaluated var fx = previous.Frameworks.FirstOrDefault(); if (fx != null) { propVals.Collect("TargetFramework", fx.GetShortFolderName()); propVals.Collect("TargetFrameworkVersion", FrameworkInfoProvider.FormatDisplayVersion(fx.Version)); propVals.Collect("TargetFrameworkIdentifier", fx.Framework); } } doc.Frameworks = propVals.GetFrameworks(); } catch (Exception ex) { LoggingService.LogError("Error determining project framework", ex); doc.Frameworks = new List <NuGetFramework> (); } try { //this has to run in a second pass so that it runs after all the schemas are loaded var validator = new MSBuildDocumentValidator(); validator.Run(doc.XDocument, textSource, doc); } catch (Exception ex) { LoggingService.LogError("Error in validation", ex); } return(doc); }
public ValidationVisitor(ITextSource textSource) { this.textSource = textSource; }
public TextRunEnumerator(ITextSource textSource, int firstTextSourceIndex) { _textSource = textSource; _pos = firstTextSourceIndex; Current = null; }