def docMethod(self): #print 'doc: ', self.document, self.document.getClass().getName() #print 'editor: ', self.editor, self.editor.getClass().getName() #line = self.selection.getCursorLine() lineStartScopeObj = self.selection.getPreviousLineThatStartsScope() # the number of the line that starts the scope. print 'start of scope is:', lineStartScopeObj.iLineStartingScope parser = FastParser.parseToKnowGloballyAccessiblePath(self.document, lineStartScopeObj.iLineStartingScope) for stmt in parser: print 'stmt', stmt if isinstance(stmt, FunctionDef): #print 'begin line?', stmt.beginLine # now get the return values and the args sent to the function grammarVersion = self.editor.getGrammarVersion() parseInfoObj = PyParser.ParserInfo(self.document, grammarVersion) parseOut = PyParser.reparseDocument(parseInfoObj) body = NodeUtils.getBody(parseOut.ast) funcDef = self.searchFuncs(body, stmt.beginLine) argList = self.parseFunc(funcDef) returnState = self.hasReturn(funcDef) #lineOffset = self.document.getLineOffset(stmt.beginLine) #startLine = self.selection.getLine(self.document, stmt.beginLine-1) prevLine = self.selection.getLine(self.document, stmt.beginLine) indentation = self.selection.getIndentationFromLine(prevLine) docString = self.prepOutputMethodString2(indentation, argList, returnState) self.selection.addLine(indentation + docString, stmt.beginLine-1) return docString
def docMethod(self): #print 'doc: ', self.document, self.document.getClass().getName() #print 'editor: ', self.editor, self.editor.getClass().getName() #line = self.selection.getCursorLine() lineStartScopeObj = self.selection.getPreviousLineThatStartsScope( ) # the number of the line that starts the scope. print 'start of scope is:', lineStartScopeObj.iLineStartingScope parser = FastParser.parseToKnowGloballyAccessiblePath( self.document, lineStartScopeObj.iLineStartingScope) for stmt in parser: print 'stmt', stmt if isinstance(stmt, FunctionDef): #print 'begin line?', stmt.beginLine # now get the return values and the args sent to the function grammarVersion = self.editor.getGrammarVersion() parseInfoObj = PyParser.ParserInfo( self.document, grammarVersion) parseOut = PyParser.reparseDocument(parseInfoObj) body = NodeUtils.getBody(parseOut.ast) funcDef = self.searchFuncs(body, stmt.beginLine) argList = self.parseFunc(funcDef) returnState = self.hasReturn(funcDef) #lineOffset = self.document.getLineOffset(stmt.beginLine) #startLine = self.selection.getLine(self.document, stmt.beginLine-1) prevLine = self.selection.getLine( self.document, stmt.beginLine) indentation = self.selection.getIndentationFromLine( prevLine) docString = self.prepOutputMethodString2( indentation, argList, returnState) self.selection.addLine(indentation + docString, stmt.beginLine - 1) return docString
def _GetPreviousOrNextClassOrMethod(context, searchForward): from org.python.pydev.parser.visitors import NodeUtils from org.python.pydev.parser.fastparser import FastParser doc = context.getDocument() selection = _CreateSelection(context) startLine = selection.getStartLineIndex() found = FastParser.firstClassOrFunction(doc, startLine, searchForward, context.isCythonFile()) if found: return NodeUtils.getRepresentationString(found) return ''
def _GetPreviousOrNextClassOrMethod(context, searchForward): from org.python.pydev.parser.visitors import NodeUtils from org.python.pydev.parser.fastparser import FastParser doc = context.getDocument() selection = _CreateSelection(context) startLine = selection.getStartLineIndex() found = FastParser.firstClassOrFunction(doc, startLine, searchForward) if found: return NodeUtils.getRepresentationString(found) return ''
def _GetCurrentASTPath(context, reverse=False): ''' @return: ArrayList(SimpleNode) ''' from org.python.pydev.parser.fastparser import FastParser selection = _CreateSelection(context) ret = FastParser.parseToKnowGloballyAccessiblePath( context.getDocument(), selection.getStartLineIndex()) if reverse: from java.util import Collections Collections.reverse(ret) return ret
def docClass(self): print 'doc Class' lineNum = self.selection.getCursorLine() isInClass = self.testScope(lineNum) print 'isInClass', isInClass if isInClass: lineNum = self.getUncommentLine(lineNum) # need to put a check in here to determine if the scope # of the current cursor position is ultimately contained # by a class. Should work up looking for a classDef. # This has not been implemented as running out of time, but # its something that should get added. lineStartScopeObj = self.selection.getPreviousLineThatStartsScope( ) print 'lineNum', lineNum lineStartScopeNumber = lineStartScopeObj.iLineStartingScope lineStartScopeObj = self.selection.getPreviousLineThatStartsScope( lineNum) print 'line start scope: ', lineStartScopeObj.getClass( ).getName() print 'start of scope line is: ', lineStartScopeNumber parser = FastParser.parseToKnowGloballyAccessiblePath( self.document, lineNum) classLineNum = None print 'parser', parser if parser: for stmt in parser: print 'stmt:', stmt.beginLine if isinstance(stmt, ClassDef): # TODO: Need to find out what the indentation is for the class and # put it into the variable indentation #endLineOfScope = None LineScopeObj = self.selection.getLineThatStartsScope( True, self.selection.INDENT_TOKENS, stmt.beginLine, 9999) #print 'LineScopeObj number', LineScopeObj.iLineStartingScope #if LineScopeObj: #endLineOfScope = LineScopeObj.iLineStartingScope # now know the start and end of the class scope, next step is to try # to extract the class variables. # pass #else: # pass # Looks like if the class that is being described is the last one in the document # then the LineScopeObj object will always be null here. Assume this means # that is I get a null LineStartingScope object here I can assume the scope goes # to the end of the doc. #print 'from where we are now to the end of doc is the scope' #classArgs = getClassArgs(selection, stmt.beginLine) #print 'stmt.beginLine', stmt.beginLine classVars = self.getClassArgs(stmt.beginLine) classLineNum = stmt.beginLine #print 'classVars are:', classVars # Finnally format the class vars into a docstring print 'classLineNum:', classLineNum classDefLine = self.selection.getLine( self.document, classLineNum) indentation = self.selection.getIndentationFromLine( classDefLine) # format the docstring docString = self.getClassDocString(classVars, indentation) # insert the line just below the classdef that the cursor line # falls under. self.selection.addLine(indentation + docString, isInClass - 1)
def testScope(self, lineNum): ''' Determines if the line that the cursor is currently on is inside the scope of a class. Does it using the following steps: a) gets the line for where the cursor is. b) gets the line number where the scope that the cursor is in starts c) iterates through classdefs and funcdefs from the top of the script to the bottom. d) when the iteration's line is greater than the start scope line, the script checks the indentation to see if it could be part of any previously defined classes. Does not work in some situations. For example, when there is a class defined inside of a class, if the inner class is followed by function definition for the outer class, it will not recognise that function as belonging to a class. If the method finds that the current line falls under a class then it will return the line where that class is defined. If not it will return a False. ''' classDefPointer = None # this value is returned. It indicates whether the # line that the cursor was on when this method # was initiated is in a class scope. isInClassScope = False lineStartScopeObj = self.selection.getPreviousLineThatStartsScope( lineNum) if lineStartScopeObj: print 'lineStartScopeObj', lineStartScopeObj print 'startScope', lineStartScopeObj.iLineStartingScope + 1 scopeStartLine = lineStartScopeObj.iLineStartingScope + 1 print 'scopeStartLine', scopeStartLine scopeStartLineContents = self.selection.getLine( self.document, lineStartScopeObj.iLineStartingScope) scopeStartLineIndentation = self.selection.getIndentationFromLine( scopeStartLineContents) # trying to determine if this line that starts the current scope for the # statement the cursor was on, is enclosed in a class scope #stmtTypes = FastParser.parseClassesAndFunctions(self.document, 1, True, False) stmtTypes = FastParser.parseCython(self.document) classLineList = [] # as we read the stmtDict = [] for stmt in stmtTypes: print 'stmt', stmt.beginLine, stmt.getClass().getName() # has the current start scope line been passed. if scopeStartLine <= stmt.beginLine: if classDefPointer: if classDefPointer['indentation'].count( ' ') < scopeStartLineIndentation.count( ' '): # assume the line is part of a this class isInClassScope = True break if isinstance( stmt, ClassDef ) and scopeStartLine == stmt.beginLine: isInClassScope = True classDefPointer = {} classDefPointer['startLine'] = scopeStartLine break if isinstance(stmt, ClassDef): classLineList.append(stmt.beginLine) classDefLine = self.selection.getLine( self.document, stmt.beginLine - 1) print 'ClassDefLine:', classDefLine print 'ClassDefLineNumber:', stmt.beginLine indentation = self.selection.getIndentationFromLine( classDefLine) classLineList.append({ 'startLine': stmt.beginLine, 'indentation': indentation, 'line': classDefLine }) classDefPointer = classLineList[len(classLineList) - 1] else: lineContents = self.selection.getLine( self.document, stmt.beginLine - 1) indentation = self.selection.getIndentationFromLine( lineContents) if classDefPointer: if indentation.count(" ") > classDefPointer[ 'indentation'].count(' '): stmtDict.append({ 'classPnter': classDefPointer, 'indent': indentation, 'beginLine': stmt.beginLine }) else: stmtDict.append({ 'classPnter': None, 'indent': indentation, 'beginLine': stmt.beginLine }) print 'scopeStartLine', scopeStartLine if isInClassScope: isInClassScope = classDefPointer['startLine'] return isInClassScope
def GetClassVars(idocument): ''' Recieves the PyDocumentTemplateContext object that all code completion operations recieve. Finds the line from which the method was called, determines what class the line is part of, scans the class for all the class or instance variables, and finally returns a docstring template. :param idocument: The input pydev object that all code completion templates recieve. :type idocument: org.python.pydev.editor.codecompletion.templates.PyDocumentTemplateContext :returns: a docstring template the describes the class from which this method was called (from a pydev template) :rtype: string ''' from org.python.pydev.parser.jython.ast import ClassDef from org.python.pydev.parser.fastparser import FastParser from org.python.pydev.core.docutils import PySelection indentation = ' ' classVars = None # 1 - get the current document doc = idocument.getDocument() # 2 - create a selection object that gets the line that this method gets calle from. #selection = PySelection(doc, idocument.getStart()) selection = idocument.createPySelection() # lineStart = selection.getPreviousLineThatStartsScope() # startLineNumber = doc.getLineOfOffset(idocument.getStart()) print 'selection:', selection # startLineNumber = doc.getLineOfOffset(idocument.getStart()) # 3 - create a parser object with the hierarchy of methods, classes etc to which the current line belongs parser = FastParser.parseToKnowGloballyAccessiblePath( doc, selection.getStartLineIndex() ) # only continuing if the parser found a class definition. if parser: # 4 - iterate through the parser object for stmt in parser: # 5 - if the parser contains a class definition if isinstance(stmt, ClassDef): # TODO: Need to find out what the indentation is for the class and # put it into the variable indentation endLineOfScope = None LineScopeObj = selection.getLineThatStartsScope(True, selection.INDENT_TOKENS, stmt.beginLine, 9999) if LineScopeObj: endLineOfScope = LineScopeObj.iLineStartingScope print 'endLineOfScope', endLineOfScope # now know the start and end of the class scope, next step is to try # to extract the class variables. else: # Looks like if the class that is being described is the last one in the document # then the LineScopeObj object will always be null here. Assume this means # that is I get a null LineStartingScope object here I can assume the scope goes # to the end of the doc. print 'from where we are now to the end of doc is the scope' #classArgs = getClassArgs(selection, stmt.beginLine) classVars = getClassArgs(idocument, selection, stmt.beginLine) # Finnally format the class vars into a docstring docString = getClassDocString(classVars, indentation) print '----------doc string--------------' print docString # When this is finished will return the docstring for the class. Not finished yet return docString
def GetMethodArg(idocument): ''' This is an older version of the GetMethodArg2 function. After figuring out how to parse a document using the pydev parsers rewrote the method parsing functions. This will get deleted once I am comfortable that the the GetMethodArg2 is working well. :param idocument: an idocument object containing the entire module that was created for this method. :type idocument: org.python.pydev.editor.codecompletion.templates.PyDocumentTemplateContext :returns: a formatted docstring template for the method on which this function was called :rtype: string ''' # TODO: parse the method looking for the return type from org.python.pydev.parser.jython.ast import FunctionDef from org.python.pydev.parser.fastparser import FastParser from org.python.pydev.core.docutils import PySelection # 1 - get the current document doc = idocument.getDocument() # 2 - get a selection object for the current line selection = PySelection(idocument.getDocument(), idocument.getStart()) startLineNumber = doc.getLineOfOffset(idocument.getStart()) startLineContents = selection.getLine(startLineNumber) startIndentation = selection.getIndentationFromLine(startLineContents) print 'the line is', startLineNumber print 'contents is', startLineContents # 3 - create a parser object with the hierarchy of methods, classes etc to which the current line belongs parser = FastParser.parseToKnowGloballyAccessiblePath( idocument.getDocument(), selection.getStartLineIndex()) if parser: # only continuing if the parser found a method definition. print 'parser', parser print 'begin line', parser[0].beginLine print 'rettype', type(parser) print 'start is', idocument.getStart() from java.util import Collections Collections.reverse(parser) # 4 - iterate through the parser object for stmt in parser: print 'stmt', stmt print type(stmt) # 5 - if the parser contains a method definition if isinstance(stmt, FunctionDef): # 6 - get the line number for the method definition print 'method line', stmt.beginLine functionDefinitionStmt = selection.getLine(stmt.beginLine-1) print 'defstatement:', functionDefinitionStmt print 'woke up' afterLine = stmt.beginLine - 1 # listOfStringLines = [] string2Add = prepOutputMethodString(startIndentation, functionDefinitionStmt) #selection.addLine( indentationString + string2Add, stmt.beginLine - 1) offset = doc.getLineInformation(afterLine + 1).getOffset(); print 'offset 1 - ', offset if doc.getNumberOfLines() > stmt.beginLine - 1: offset = doc.getLineInformation(afterLine + 1).getOffset(); print 'offset 2 - ', offset else: offset = doc.getLineInformation(afterLine).getOffset() print 'offset 2 - ', offset #doc.replace(offset, 0, string2Add) # inserting into the doc immediately after the method is # not working, instead will return the doc string return string2Add #selection.addLine( indentationString + string2Add, stmt.beginLine - 1) #offset = doc.getLineInformation(afterLine + 1).getOffset(); #selection = PySelection(idocument.getDocument(), idocument.getStart()) #offset = doc.getLineInformation(stmt.beginLine).getOffset() #print 'offset is now ',offset #print 'on line number', selection.getLineNumber() #args = NodeUtils.getNodeArgs(stmt) #print 'args are', args #print '.getRepresentationString' , NodeUtils.getRepresentationString(stmt) #print 'full rep string:', NodeUtils.getFullRepresentationString(stmt) #return NodeUtils.getRepresentationString(stmt) # if nothing was found then return null. return ""
def GetMethodArg2(idocument): ''' This method will receive a PyDocumentTemplateContext. From that object it is able to determine the cursor position, from the cursor position it can determine what method / function the cursor position is a part of. Once it knows the function name it can retrieve the parameters that are being sent to the method as well as determine whether the method has any return types. Based on that information it will return a docstring template the uses the Sphinx documentation systems tags, in a restructured text format that Sphinx can consume. This is a revised version of the original method GetMethodArg. This new version will use the pydev ast document structure. In other words uses the same code that pydev uses to parse the individual elements in the function. Versions prior to this version retrieved the functions code, and parsed it using my own simple python based function parser. :param idocument: The input document context. From this object you can get an iDocument object, and from there get any parameter you require. :type idocument: org.python.pydev.editor.codecompletion.templates.PyDocumentTemplateContext :returns: a docstring for the method that the cursor was in when this method was invoked through the templateing system in pydev. :rtype: string ''' from org.python.pydev.parser.fastparser import FastParser from org.python.pydev.core.docutils import PySelection from org.python.pydev.parser.jython.ast import FunctionDef docString = None print 'using method:GetMethodArg2' print 'here' # 1 - get the current document doc = idocument.getDocument() # 2 - create a selection object that gets the line that this method gets called # from, ie the line the cursor was on when this method is called, or again # the position where the returned docstring will get inserted. #selection = PySelection(doc, idocument.getStart()) selection = idocument.createPySelection() lineStart = selection.getPreviousLineThatStartsScope() startLineNumber = doc.getLineOfOffset(idocument.getStart()) print 'startlinenumber', startLineNumber, lineStart.iLineStartingScope # 3 find out the start line of the function that encloses # the cursor position from which this function was called # the fast parser is a quick way to get the class and function start lines. #parser = FastParser.parseToKnowGloballyAccessiblePath(idocument.getDocument(), selection.getStartLineIndex()) parser = FastParser.parseToKnowGloballyAccessiblePath(doc, startLineNumber) print 'got here now! now' if parser: from java.util import Collections Collections.reverse(parser) print 'parser-----' print parser for stmt in parser: print 'stmt', stmt # found a function definition, can now retrieve the line # number of the function definition if isinstance(stmt, FunctionDef): # Getting the line number of the func def here. #print 'method line', stmt.beginLine # Now going to do a full parse of the doc and retrieve # the full function definition info (fast parser just # gets the headlines, this parser will retrieve the # full function def in an AST hierarchy from which # we can extract args and return values. functionDefinitionStmt = selection.getLine(stmt.beginLine-1) print 'defstatement:', functionDefinitionStmt docString = getFuncArgs(idocument, stmt.beginLine) # found what we need, no need to continue wiht the rest of the doc break return docString
def docClass(self): print 'doc Class' lineNum = self.selection.getCursorLine() isInClass = self.testScope(lineNum) print 'isInClass', isInClass if isInClass: lineNum = self.getUncommentLine(lineNum) # need to put a check in here to determine if the scope # of the current cursor position is ultimately contained # by a class. Should work up looking for a classDef. # This has not been implemented as running out of time, but # its something that should get added. lineStartScopeObj = self.selection.getPreviousLineThatStartsScope() print 'lineNum', lineNum lineStartScopeNumber = lineStartScopeObj.iLineStartingScope lineStartScopeObj = self.selection.getPreviousLineThatStartsScope( lineNum) print 'line start scope: ', lineStartScopeObj.getClass().getName() print 'start of scope line is: ', lineStartScopeNumber parser = FastParser.parseToKnowGloballyAccessiblePath( self.document, lineNum ) classLineNum = None print 'parser', parser if parser: for stmt in parser: print 'stmt:', stmt.beginLine if isinstance(stmt, ClassDef): # TODO: Need to find out what the indentation is for the class and # put it into the variable indentation #endLineOfScope = None LineScopeObj = self.selection.getLineThatStartsScope(True, self.selection.INDENT_TOKENS, stmt.beginLine, 9999) #print 'LineScopeObj number', LineScopeObj.iLineStartingScope #if LineScopeObj: #endLineOfScope = LineScopeObj.iLineStartingScope # now know the start and end of the class scope, next step is to try # to extract the class variables. # pass #else: # pass # Looks like if the class that is being described is the last one in the document # then the LineScopeObj object will always be null here. Assume this means # that is I get a null LineStartingScope object here I can assume the scope goes # to the end of the doc. #print 'from where we are now to the end of doc is the scope' #classArgs = getClassArgs(selection, stmt.beginLine) #print 'stmt.beginLine', stmt.beginLine classVars = self.getClassArgs(stmt.beginLine) classLineNum = stmt.beginLine #print 'classVars are:', classVars # Finnally format the class vars into a docstring print 'classLineNum:', classLineNum classDefLine = self.selection.getLine(self.document, classLineNum) indentation = self.selection.getIndentationFromLine(classDefLine) # format the docstring docString = self.getClassDocString(classVars, indentation) # insert the line just below the classdef that the cursor line # falls under. self.selection.addLine(indentation + docString, isInClass - 1)
def testScope(self, lineNum): ''' Determines if the line that the cursor is currently on is inside the scope of a class. Does it using the following steps: a) gets the line for where the cursor is. b) gets the line number where the scope that the cursor is in starts c) iterates through classdefs and funcdefs from the top of the script to the bottom. d) when the iteration's line is greater than the start scope line, the script checks the indentation to see if it could be part of any previously defined classes. Does not work in some situations. For example, when there is a class defined inside of a class, if the inner class is followed by function definition for the outer class, it will not recognise that function as belonging to a class. If the method finds that the current line falls under a class then it will return the line where that class is defined. If not it will return a False. ''' classDefPointer = None # this value is returned. It indicates whether the # line that the cursor was on when this method # was initiated is in a class scope. isInClassScope = False lineStartScopeObj = self.selection.getPreviousLineThatStartsScope(lineNum) if lineStartScopeObj: print 'lineStartScopeObj',lineStartScopeObj print 'startScope', lineStartScopeObj.iLineStartingScope + 1 scopeStartLine = lineStartScopeObj.iLineStartingScope + 1 print 'scopeStartLine', scopeStartLine scopeStartLineContents = self.selection.getLine(self.document, lineStartScopeObj.iLineStartingScope) scopeStartLineIndentation = self.selection.getIndentationFromLine(scopeStartLineContents) # trying to determine if this line that starts the current scope for the # statement the cursor was on, is enclosed in a class scope #stmtTypes = FastParser.parseClassesAndFunctions(self.document, 1, True, False) stmtTypes = FastParser.parseCython(self.document) classLineList = [] # as we read the stmtDict = [] for stmt in stmtTypes: print 'stmt', stmt.beginLine, stmt.getClass().getName() # has the current start scope line been passed. if scopeStartLine <= stmt.beginLine: if classDefPointer: if classDefPointer['indentation'].count(' ') < scopeStartLineIndentation.count(' '): # assume the line is part of a this class isInClassScope = True break if isinstance(stmt, ClassDef) and scopeStartLine == stmt.beginLine: isInClassScope = True classDefPointer = {} classDefPointer['startLine'] = scopeStartLine break if isinstance(stmt, ClassDef): classLineList.append(stmt.beginLine) classDefLine = self.selection.getLine(self.document, stmt.beginLine - 1) print 'ClassDefLine:', classDefLine print 'ClassDefLineNumber:', stmt.beginLine indentation = self.selection.getIndentationFromLine(classDefLine) classLineList.append( {'startLine':stmt.beginLine, 'indentation':indentation, 'line': classDefLine} ) classDefPointer = classLineList[len(classLineList) - 1] else: lineContents = self.selection.getLine(self.document, stmt.beginLine - 1) indentation = self.selection.getIndentationFromLine(lineContents) if classDefPointer: if indentation.count(" ") > classDefPointer['indentation'].count(' '): stmtDict.append({'classPnter': classDefPointer, 'indent': indentation, 'beginLine': stmt.beginLine}) else: stmtDict.append({'classPnter': None, 'indent': indentation, 'beginLine': stmt.beginLine}) print 'scopeStartLine', scopeStartLine if isInClassScope: isInClassScope = classDefPointer['startLine'] return isInClassScope