/// <summary> /// Parses the specified file on disk. /// </summary> /// <param name="filename"></param> public void EnqueueFile(IProjectEntry projEntry, string filename) { var severity = _parser.PyService.GeneralOptions.IndentationInconsistencySeverity; EnqueWorker(() => { for (int i = 0; i < 10; i++) { try { if (!File.Exists(filename)) { break; } using (var reader = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) { _parser.ParseFile(projEntry, filename, reader, severity); return; } } catch (IOException) { // file being copied, try again... Thread.Sleep(100); } catch (UnauthorizedAccessException) { // file is inaccessible, try again... Thread.Sleep(100); } } IPythonProjectEntry pyEntry = projEntry as IPythonProjectEntry; if (pyEntry != null) { // failed to parse, keep the UpdateTree calls balanced pyEntry.UpdateTree(null, null); } }); }
public void EnqueueZipArchiveEntry(IProjectEntry projEntry, string zipFileName, ZipArchiveEntry entry, Action onComplete) { var pathInArchive = entry.FullName.Replace('/', '\\'); var fileName = Path.Combine(zipFileName, pathInArchive); var severity = _parser.PyService.GeneralOptions.IndentationInconsistencySeverity; EnqueWorker(() => { try { using (var stream = entry.Open()) { _parser.ParseFile(projEntry, fileName, stream, severity); return; } } catch (IOException ex) { Debug.Fail(ex.Message); } catch (InvalidDataException ex) { Debug.Fail(ex.Message); } finally { onComplete(); } IPythonProjectEntry pyEntry = projEntry as IPythonProjectEntry; if (pyEntry != null) { // failed to parse, keep the UpdateTree calls balanced pyEntry.UpdateTree(null, null); } }); }
private static void AnalyzeCode( out PythonAnalyzer analyzer, out IPythonProjectEntry entry, string code, Version preferredVersion = null, InterpreterArchitecture preferredArch = null, string module = "test-module" ) { var provider = InterpFactory; var factory = provider.GetInterpreterFactories().OrderByDescending(f => f.Configuration.Version) .Where(f => preferredVersion == null || f.Configuration.Version == preferredVersion) .Where(f => preferredArch == null || f.Configuration.Architecture == preferredArch) .FirstOrDefault(); Assert.IsNotNull(factory, "no factory found"); analyzer = PythonAnalyzer.CreateSynchronously(factory); var path = Path.Combine(TestData.GetTempPath(), module.Replace('.', '\\')); Directory.CreateDirectory(PathUtils.GetParent(path)); File.WriteAllText(path, code); entry = analyzer.AddModule(module, path); PythonAst ast; using (var p = Parser.CreateParser(new StringReader(code), factory.GetLanguageVersion())) { ast = p.ParseFile(); entry.UpdateTree(ast, null); } entry.Analyze(CancellationToken.None, true); }
public void UpdateModule(IPythonProjectEntry entry, string code) { CollectingErrorSink errors = null; if (code != null) { PythonAst ast; errors = new CollectingErrorSink(); var p = Parser.CreateParser( new StringReader(code), _analyzer.LanguageVersion, new ParserOptions { BindReferences = true, ErrorSink = errors } ); ast = p.ParseFile(); entry.UpdateTree(ast, null); if (errors.Errors.Any() || errors.Warnings.Any()) { if (AssertOnParseErrors) { var errorMsg = MakeMessage(errors); Trace.TraceError(errorMsg); Assert.Fail("Errors parsing " + entry.FilePath, errorMsg); } } } entry.Analyze(CancellationToken.None, true); }
public static void Prepare(IPythonProjectEntry entry, TextReader sourceUnit, PythonLanguageVersion version = PythonLanguageVersion.V27) { CollectingErrorSink errorSink = new CollectingErrorSink(); using (var parser = Parser.CreateParser(sourceUnit, errorSink, version)) { entry.UpdateTree(parser.ParseFile(), null); } }
public static void Prepare(IPythonProjectEntry entry, TextReader sourceUnit, PythonLanguageVersion version = PythonLanguageVersion.V27) { using (var parser = Parser.CreateParser(sourceUnit, version, new ParserOptions() { BindReferences = true })) { entry.UpdateTree(parser.ParseFile(), null); } }
/// <summary> /// Called when we race and are not actually re-parsing a buffer, balances the calls /// of BeginParsingTree when we aren't parsing. /// </summary> private void NotReparsing() { lock (this) { IPythonProjectEntry pyEntry = _currentProjEntry as IPythonProjectEntry; if (pyEntry != null) { pyEntry.UpdateTree(null, null); } } }
private static void UpdateAnalysisTree(IPythonProjectEntry pyEntry, SortedDictionary<int, ParseResult> parseResults) { IAnalysisCookie cookie = new VersionCookie( parseResults.ToDictionary( x => x.Key, x => new BufferVersion(x.Value.Version, x.Value.Ast) ) ); var asts = parseResults.Where(x => x.Value.Ast != null).Select(x => x.Value.Ast).ToArray(); PythonAst finalAst; if (asts.Length == 1) { finalAst = asts[0]; } else if (asts.Length > 0) { // multiple ASTs, merge them together finalAst = new PythonAst( new SuiteStatement( asts.Select(ast => ast.Body).ToArray() ), new NewLineLocation[0], asts[0].LanguageVersion ); } else { // we failed to get any sort of AST out, so we can't analyze... // But we need to balance the UpdateTree call, so just fetch the // last valid ast and cookie. pyEntry.GetTreeAndCookie(out finalAst, out cookie); } pyEntry.UpdateTree(finalAst, cookie); }
private static void AnalyzeCode( out PythonAnalyzer analyzer, out IPythonProjectEntry entry, string code, Version preferredVersion = null, InterpreterArchitecture preferredArch = null, string module = "test-module" ) { var provider = InterpFactory; var factory = provider.GetInterpreterFactories().OrderByDescending(f => f.Configuration.Version) .Where(f => preferredVersion == null || f.Configuration.Version == preferredVersion) .Where(f => preferredArch == null || f.Configuration.Architecture == preferredArch) .FirstOrDefault(); Assert.IsNotNull(factory, "no factory found"); analyzer = PythonAnalyzer.CreateSynchronously(factory); var path = Path.Combine(TestData.GetTempPath(randomSubPath: true), module.Replace('.', '\\')); Directory.CreateDirectory(PathUtils.GetParent(path)); File.WriteAllText(path, code); entry = analyzer.AddModule(module, path); PythonAst ast; using (var p = Parser.CreateParser(new StringReader(code), factory.GetLanguageVersion())) { ast = p.ParseFile(); entry.UpdateTree(ast, null); } entry.Analyze(CancellationToken.None, true); }
public static void Parse(this IPythonProjectEntry entry, PythonLanguageVersion version, string code) { using (var parser = Parser.CreateParser(new StringReader(code), version)) { entry.UpdateTree(parser.ParseFile(), null); } }
public void ParseBuffers(BufferParser bufferParser, Severity indentationSeverity, params ITextSnapshot[] snapshots) { IProjectEntry analysis; lock (_openFiles) { if (!_openFiles.TryGetValue(bufferParser, out analysis)) { return; } } IPythonProjectEntry pyProjEntry = analysis as IPythonProjectEntry; List <PythonAst> asts = new List <PythonAst>(); bool hasErrors = false; foreach (var snapshot in snapshots) { var snapshotContent = new SnapshotSpanSourceCodeReader(new SnapshotSpan(snapshot, new Span(0, snapshot.Length))); if (pyProjEntry != null && snapshot.TextBuffer.ContentType.IsOfType(PythonCoreConstants.ContentType)) { if (!snapshot.IsReplBufferWithCommand()) { PythonAst ast; CollectingErrorSink errorSink; ParsePythonCode(snapshotContent, indentationSeverity, out ast, out errorSink); if (ast != null) { asts.Add(ast); if (errorSink.Errors.Count != 0) { hasErrors = true; } // update squiggles for the buffer var buffer = snapshot.TextBuffer; SimpleTagger <ErrorTag> squiggles = _errorProvider.GetErrorTagger(snapshot.TextBuffer); squiggles.RemoveTagSpans(x => true); TaskProvider provider = GetTaskListProviderForProject(bufferParser._currentProjEntry); AddWarnings(snapshot, errorSink, squiggles, provider); AddErrors(snapshot, errorSink, squiggles, provider); UpdateErrorList(errorSink, buffer.GetFilePath(), provider); } } } else { // other file such as XAML IExternalProjectEntry externalEntry; if ((externalEntry = (analysis as IExternalProjectEntry)) != null) { externalEntry.ParseContent(snapshotContent, new SnapshotCookie(snapshotContent.Snapshot)); _analysisQueue.Enqueue(analysis, AnalysisPriority.High); } } } if ((!hasErrors && asts.Count > 0) || asts.Count > 1) { // only update the AST when we're error free, this way we don't remove // a useful analysis with an incomplete and useless analysis. // If we have more than one AST we're in the REPL - we'll update the // AST in that case as errors won't go away. PythonAst finalAst; if (asts.Count == 1) { finalAst = asts[0]; } else { // multiple ASTs, merge them together List <Statement> bodies = new List <Statement>(); foreach (var ast in asts) { bodies.Add(ast.Body); } finalAst = new PythonAst(new SuiteStatement(bodies.ToArray()), new int[0]); } pyProjEntry.UpdateTree(finalAst, new SnapshotCookie(snapshots[0])); // SnapshotCookie is ot entirely right, we should merge the snapshots _analysisQueue.Enqueue(analysis, AnalysisPriority.High); } }