public override Declarations GetDeclarations(IVsTextView view, int line, int col, TokenInfo info, ParseReason reason) { // Check that the text view is not null. if (null == view) { throw new ArgumentNullException("view"); } // In order to get the correct text for this line we have to figure out if this line // contains part of the read-only region of the buffer because this region is not // supposed to be used (it is the output of the engine). // Use the function exposed by the console window to get the text of the line // without the part inside the read-only region. string lineText = PythonConsole.TextOfLine(line, col, true); if (null == lineText) { // there is no text to parse, so there is no delaration to return. // Return an empty Declarations object. return(new MethodDeclarations()); } // Get the text buffer. IVsTextLines buffer; Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure( view.GetBuffer(out buffer)); // Get the scanner from the language service. IScanner scanner = Language.GetScanner(buffer); scanner.SetSource(lineText, 0); // Now use the scanner to parse this line and build the list of the tokens. List <TokenInfo> tokens = new List <TokenInfo>(); TokenInfo lastToken = null; TokenInfo currentToken = new TokenInfo(); int state = 0; while (scanner.ScanTokenAndProvideInfoAboutIt(currentToken, ref state)) { if ((null != lastToken) && (currentToken.StartIndex > lastToken.EndIndex + 1)) { tokens.Clear(); } tokens.Add(currentToken); lastToken = currentToken; currentToken = new TokenInfo(); } // Now that we have the tokens we can use them to find the text to pass to the // IronPython engine to evaluate the expression. if (0 == tokens.Count) { // If the list of tokens is empty, then return an emty set of declarations. return(new MethodDeclarations()); } // Check if the last token is the one that generated the parse request. if (tokens[tokens.Count - 1].Trigger == TokenTriggers.None) { tokens.RemoveAt(tokens.Count - 1); if (0 == tokens.Count) { return(new MethodDeclarations()); } } // Remove the token that generated the request if (tokens[tokens.Count - 1].Trigger != TokenTriggers.None) { tokens.RemoveAt(tokens.Count - 1); if (0 == tokens.Count) { return(new MethodDeclarations()); } } // Now build the string to pass to the engine. int startIndex = tokens[0].StartIndex; int len = tokens[tokens.Count - 1].EndIndex - startIndex + 1; string engineCommand = string.Format( System.Globalization.CultureInfo.InvariantCulture, "dir({0})", lineText.Substring(startIndex, len)); MethodDeclarations declarations = new MethodDeclarations(); try { IEnumerable members = Engine.Evaluate(engineCommand) as IEnumerable; if (null != members) { foreach (string member in members) { declarations.AddMethod(member); } } } catch (Exception) { // Do nothing } return(declarations); }
public override Declarations GetDeclarations(IVsTextView view, int line, int col, TokenInfo info, ParseReason reason) { // Check that the text view is not null. if (null == view) { throw new ArgumentNullException("view"); } // In order to get the correct text for this line we have to figure out if this line // contains part of the read-only region of the buffer because this region is not // supposed to be used (it is the output of the engine). // Use the function exposed by the console window to get the text of the line // without the part inside the read-only region. string lineText = PythonConsole.TextOfLine(line, col, true); if (null == lineText) { // there is no text to parse, so there is no delaration to return. // Return an empty Declarations object. return new MethodDeclarations(); } // Get the text buffer. IVsTextLines buffer; Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure( view.GetBuffer(out buffer)); // Get the scanner from the language service. IScanner scanner = Language.GetScanner(buffer); scanner.SetSource(lineText, 0); // Now use the scanner to parse this line and build the list of the tokens. List<TokenInfo> tokens = new List<TokenInfo>(); TokenInfo lastToken = null; TokenInfo currentToken = new TokenInfo(); int state = 0; while (scanner.ScanTokenAndProvideInfoAboutIt(currentToken, ref state)) { if ((null != lastToken) && (currentToken.StartIndex > lastToken.EndIndex + 1)) { tokens.Clear(); } tokens.Add(currentToken); lastToken = currentToken; currentToken = new TokenInfo(); } // Now that we have the tokens we can use them to find the text to pass to the // IronPython engine to evaluate the expression. if (0 == tokens.Count) { // If the list of tokens is empty, then return an emty set of declarations. return new MethodDeclarations(); } // Check if the last token is the one that generated the parse request. if (tokens[tokens.Count - 1].Trigger == TokenTriggers.None) { tokens.RemoveAt(tokens.Count - 1); if (0 == tokens.Count) { return new MethodDeclarations(); } } // Remove the token that generated the request if (tokens[tokens.Count - 1].Trigger != TokenTriggers.None) { tokens.RemoveAt(tokens.Count - 1); if (0 == tokens.Count) { return new MethodDeclarations(); } } // Now build the string to pass to the engine. int startIndex = tokens[0].StartIndex; int len = tokens[tokens.Count - 1].EndIndex - startIndex + 1; string engineCommand = string.Format( System.Globalization.CultureInfo.InvariantCulture, "dir({0})", lineText.Substring(startIndex, len)); MethodDeclarations declarations = new MethodDeclarations(); try { IEnumerable members = Engine.Evaluate(engineCommand) as IEnumerable; if (null != members) { foreach (string member in members) { declarations.AddMethod(member); } } } catch (Exception) { // Do nothing } return declarations; }