internal SnapshotSpan?GetExpressionAtPointWorker(SnapshotSpan span, GetExpressionOptions options) { // First do some very quick tokenization to save a full analysis if (!IsPossibleExpressionAtPoint(span.Start)) { return(null); } if (span.End.GetContainingLine() != span.Start.GetContainingLine() && !IsPossibleExpressionAtPoint(span.End)) { return(null); } var sourceSpan = new SnapshotSpanSourceCodeReader( new SnapshotSpan(span.Snapshot, 0, span.End.Position) ); PythonAst ast; using (var parser = Parser.CreateParser(sourceSpan, LanguageVersion)) { ast = parser.ParseFile(); } var finder = new ExpressionFinder(ast, options); var actualExpr = finder.GetExpressionSpan(span.ToSourceSpan()); return(actualExpr?.ToSnapshotSpan(span.Snapshot)); }
/// <summary> /// Gets the smallest expression that fully contains the span. /// </summary> /// <remarks> /// When options specifies the member target, rather than the /// full expression, only the start of the span is used. /// </remarks> public SnapshotSpan?GetExpressionAtPoint(SnapshotSpan span, GetExpressionOptions options) { var timer = new Stopwatch(); timer.Start(); bool hasError = true, hasResult = false; try { var r = GetExpressionAtPointWorker(span, options); hasResult = r != null; hasError = false; return(r); } finally { timer.Stop(); try { int elapsed = (int)Math.Min(timer.ElapsedMilliseconds, int.MaxValue); if (elapsed > 10) { Services.Python.Logger.LogEvent(Logging.PythonLogEvent.GetExpressionAtPoint, new Logging.GetExpressionAtPointInfo { Milliseconds = elapsed, PartialAstLength = span.End.Position, ExpressionFound = hasResult, Success = !hasError }); } } catch (Exception ex) { Debug.Fail(ex.ToUnhandledExceptionMessage(GetType())); } } }
private static PythonAstAndSource Parse(string code, GetExpressionOptions options) { code += "\n"; var parser = Parser.CreateParser(new StringReader(code), PythonLanguageVersion.V35, new ParserOptions { Verbatim = true }); return(new PythonAstAndSource { Ast = parser.ParseFile(), Source = code, Options = options }); }