public ParseInformation Parse(FileName fileName, ITextSource fileContent, bool fullParseInformationRequested, IProject parentProject, CancellationToken cancellationToken) { AXmlParser parser = new AXmlParser(); AXmlDocument document; IncrementalParserState newParserState; if (fileContent.Version is OnDiskTextSourceVersion) { document = parser.Parse(fileContent, cancellationToken); newParserState = null; } else { document = parser.ParseIncremental(parserState, fileContent, out newParserState, cancellationToken); } parserState = newParserState; XamlUnresolvedFile unresolvedFile = XamlUnresolvedFile.Create(fileName, fileContent, document); ParseInformation parseInfo; if (fullParseInformationRequested) { parseInfo = new XamlFullParseInformation(unresolvedFile, document, fileContent.CreateSnapshot()); } else { parseInfo = new ParseInformation(unresolvedFile, fileContent.Version, false); } AddTagComments(document, parseInfo, fileContent); return(parseInfo); }
public static Context CreateContext(AbsoluteFilePath filePath, string code, int offset, SourcePackage package) { var parser = new AXmlParser(); var result = parser.Parse(new StringTextSource(code)); var file = new SourceFile(package, filePath.NativePath, code); return(new Context(file, result, offset)); }
/// <summary> /// Parse the given text and enter read lock. /// No parsing is done if the text is older than seen before. /// </summary> public IDisposable ParseAndLock(ITextBuffer fileContent) { // Copy to ensure thread-safety var lastVer = this.lastParsedVersion; if (lastVer == null || // First parse fileContent.Version == null || // Versioning not supported !fileContent.Version.BelongsToSameDocumentAs(lastVer) || // Different document instance? Can happen after closing and reopening of file. fileContent.Version.CompareAge(lastVer) > 0) // Is fileContent newer? { parser.Lock.EnterWriteLock(); // Double check, now that we are thread-safe lastVer = this.lastParsedVersion; if (lastVer == null || fileContent.Version == null || !fileContent.Version.BelongsToSameDocumentAs(lastVer)) { // First parse or versioning not supported using (DebugTimer.Time("normal parse")) parser.Parse(fileContent.Text, null); this.lastParsedVersion = fileContent.Version; } else if (fileContent.Version.CompareAge(lastParsedVersion) > 0) { // Incremental parse var changes = lastParsedVersion.GetChangesTo(fileContent.Version). Select(c => new DocumentChangeEventArgs(c.Offset, c.RemovedText, c.InsertedText)); using (DebugTimer.Time("incremental parse")) parser.Parse(fileContent.Text, changes); this.lastParsedVersion = fileContent.Version; } else { // fileContent is older - no need to parse } parser.Lock.EnterReadLock(); parser.Lock.ExitWriteLock(); } else { // fileContent is older - no need to parse parser.Lock.EnterReadLock(); } return(new CallbackOnDispose(() => parser.Lock.ExitReadLock())); }
void Button_Click(object sender, RoutedEventArgs e) { if (!textDirty) { return; } AXmlDocument doc; parser.Lock.EnterWriteLock(); try { doc = parser.Parse(editor.Document.Text, changes); changes.Clear(); } finally { parser.Lock.ExitWriteLock(); } if (treeView.Items.Count == 0) { treeView.Items.Add(doc); } PrettyPrintAXmlVisitor visitor = new PrettyPrintAXmlVisitor(); visitor.VisitDocument(doc); string prettyPrintedText = visitor.Output; if (prettyPrintedText != editor.Document.Text) { MessageBox.Show("Error - Original and pretty printed version of XML differ"); } markerService.RemoveAll(m => true); foreach (var error in doc.SyntaxErrors) { var marker = markerService.Create(error.StartOffset, error.EndOffset - error.StartOffset); marker.Tag = error.Message; marker.BackgroundColor = Color.FromRgb(255, 150, 150); } textDirty = false; }
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"); }