Ejemplo n.º 1
0
 def onScopeBegin(self):
     """The user requested jumping to the current scope begin"""
     if self.isPythonBuffer():
         info = getBriefModuleInfoFromMemory(self.text)
         context = getContext(self, info, True)
         if context.getScope() != context.GlobalScope:
             GlobalData().mainWindow.jumpToLine(context.getLastScopeLine())
Ejemplo n.º 2
0
 def highlightInOutline(self):
     """Triggered when highlight in outline browser is requested"""
     if self.isPythonBuffer():
         info = getBriefModuleInfoFromMemory(self.text)
         context = getContext(self, info, True, False)
         line, _ = self.cursorPosition
         GlobalData().mainWindow.highlightInOutline(context, int(line) + 1)
         self.setFocus()
Ejemplo n.º 3
0
    def __extractDocstring(self, content):
        """Extracts a docstring and sets it as a tooltip if needed"""
        if self.tooltip != "":
            return

        if isPythonFile(self.fileName):
            info = getBriefModuleInfoFromMemory("\n".join(content))
            self.tooltip = ""
            if info.docstring is not None:
                self.tooltip = info.docstring.text
Ejemplo n.º 4
0
    def getCurrentBufferInfo(self):
        """Provides the current buffer parsed info"""
        if self.__currentUUID is None:
            return None
        widget = self.__editorsManager.getWidgetByUUID(self.__currentUUID)
        if widget is None:
            return None

        editor = widget.getEditor()
        info = getBriefModuleInfoFromMemory(editor.text)
        return info
Ejemplo n.º 5
0
 def __populateFromOpened(self):
     """Populates the name dialog from the opened files"""
     mainWindow = GlobalData().mainWindow
     editorsManager = mainWindow.editorsManagerWidget.editorsManager
     for record in editorsManager.getTextEditors():
         # uuid = record[0]
         fname = record[1]
         widget = record[2]
         if isPythonFile(fname):
             content = widget.getEditor().text()
             info = getBriefModuleInfoFromMemory(content)
             self.__populateInfo(info, fname)
Ejemplo n.º 6
0
 def __populateFromProject(self):
     """Populates find name dialog from the project files"""
     mainWindow = GlobalData().mainWindow
     for fname in GlobalData().project.filesList:
         if isPythonFile(fname):
             widget = mainWindow.getWidgetForFileName(fname)
             if widget is None:
                 info = GlobalData().briefModinfoCache.get(fname)
             else:
                 info = getBriefModuleInfoFromMemory(
                     widget.getEditor().text)
             self.__populateInfo(info, fname)
Ejemplo n.º 7
0
def getImportsInLine(fileContent, lineNumber):
    """Provides a list of imports in in the given import line"""
    imports = []
    importsWhat = []
    info = getBriefModuleInfoFromMemory(str(fileContent))
    for importObj in info.imports:
        if importObj.line == lineNumber:
            if importObj.name not in imports:
                imports.append(importObj.name)
            for whatObj in importObj.what:
                if whatObj.name not in importsWhat:
                    importsWhat.append(whatObj.name)
    return imports, importsWhat
Ejemplo n.º 8
0
    def test_lone_import(self):
        """Test for lone import keyword"""
        pythonFile = self.dir + "loneimport.py"
        info = cdmpyparser.getBriefModuleInfoFromFile(pythonFile)
        if info.isOK:
            self.fail("lone import test failure. Expected error. Option: "
                      "directly from file: " + pythonFile)

        f = open(pythonFile)
        content = f.read()
        f.close()

        info = cdmpyparser.getBriefModuleInfoFromMemory(content)
        if info.isOK:
            self.fail("lone import test failure. Expected error. Option: "
                      "from memory. File: " + pythonFile)
Ejemplo n.º 9
0
    def __showParserError(self):
        """Shows the parser errors window"""
        if self.__currentUUID is None:
            return

        try:
            widget = self.__editorsManager.getWidgetByUUID(self.__currentUUID)
            if widget is None:
                return

            editor = widget.getEditor()
            info = getBriefModuleInfoFromMemory(editor.text)
            fName = self.__outlineBrowsers[self.__currentUUID].shortFileName
            dialog = ParserErrorsDialog(fName, info)
            dialog.exec_()
        except Exception as ex:
            logging.error(str(ex))
Ejemplo n.º 10
0
 def __populateFromOpened(self):
     """Populates the name dialog from the opened files"""
     mainWindow = GlobalData().mainWindow
     editorsManager = mainWindow.editorsManagerWidget.editorsManager
     showTooltips = Settings()['findFileTooltips']
     for record in editorsManager.getTextEditors():
         # uuid = record[0]
         fname = record[1]
         widget = record[2]
         mime, icon, _ = getFileProperties(fname)
         tooltip = ""
         if showTooltips and isPythonMime(mime):
             content = widget.getEditor().text
             info = getBriefModuleInfoFromMemory(content)
             if info.docstring is not None:
                 tooltip = info.docstring.text
         newItem = FileItem(self.rootItem, icon, fname, tooltip)
         self.rootItem.appendChild(newItem)
         self.count += 1
Ejemplo n.º 11
0
 def __populateFromProject(self):
     """Populates find name dialog from the project files"""
     mainWindow = GlobalData().mainWindow
     showTooltips = Settings()['findFileTooltips']
     for fname in GlobalData().project.filesList:
         if fname.endswith(os.path.sep):
             continue
         mime, icon, _ = getFileProperties(fname)
         tooltip = ""
         if showTooltips and isPythonMime(mime):
             widget = mainWindow.getWidgetForFileName(fname)
             if widget is None:
                 info = GlobalData().briefModinfoCache.get(fname)
             else:
                 content = widget.getEditor().text
                 info = getBriefModuleInfoFromMemory(content)
             if info.docstring is not None:
                 tooltip = info.docstring.text
         newItem = FileItem(self.rootItem, icon, fname, tooltip)
         self.rootItem.appendChild(newItem)
         self.count += 1
Ejemplo n.º 12
0
def encodingSanityCheck(fName, decodedText, expectedEncoding):
    """Checks if the expected encoding matches the encing in the file"""
    try:
        modInfo = getBriefModuleInfoFromMemory(decodedText)
        modEncoding = modInfo.encoding
        if modEncoding:
            if not isValidEncoding(modEncoding.name):
                logging.warning("Invalid encoding " + modEncoding.name +
                                " found in the file " + fName)
                return False
            if not areEncodingsEqual(modEncoding.name, expectedEncoding):
                if expectedEncoding.startswith('bom-'):
                    noBomEncoding = expectedEncoding[4:]
                    if areEncodingsEqual(modEncoding.name, noBomEncoding):
                        return True
                logging.warning("The explicitly set encoding " +
                                expectedEncoding +
                                " does not match encoding " +
                                modEncoding.name + " found in the file " +
                                fName)
                return False
    except:
        pass
    return True
Ejemplo n.º 13
0
    def meat(self, pythonFile, errorMsg):
        """The test process meat"""
        info = cdmpyparser.getBriefModuleInfoFromFile(pythonFile)
        if not info.isOK:
            self.fail("Error parsing the file " + pythonFile +
                      ". Option: directly from a file.")

        f = open(pythonFile)
        content = f.read()
        f.close()

        info = cdmpyparser.getBriefModuleInfoFromMemory(content)
        if not info.isOK:
            self.fail("Error parsing the file " + pythonFile +
                      ". Option: from memory.")

        outFileName = pythonFile.replace(".py", ".out")
        outFile = open(outFileName, "w")
        outFile.write(info.niceStringify())
        outFile.close()

        okFileName = pythonFile.replace(".py", ".ok")
        if not files_equal(outFileName, okFileName):
            self.fail(errorMsg)
Ejemplo n.º 14
0
def getImportsList(fileContent):
    """Parses a python file and provides a list imports in it"""
    info = getBriefModuleInfoFromMemory(fileContent)
    return info.imports
Ejemplo n.º 15
0
    def updateBar(self):
        """Triggered when the timer is fired"""
        self.__updateTimer.stop()  # just in case

        if not isPythonMime(self.__parentWidget.getMime()):
            return

        if not self.__connected:
            self.__connectEditorSignals()

        # Parse the buffer content
        self.__currentInfo = getBriefModuleInfoFromMemory(self.__editor.text)

        # Decide what icon to use
        if self.__currentInfo.isOK:
            self.__updateInfoIcon(self.STATE_OK_UTD)
        else:
            self.__updateInfoIcon(self.STATE_BROKEN_UTD)

        # Calc the cursor context
        context = getContext(self.__editor, self.__currentInfo, True, False)

        # Display the context
        self.__populateGlobalScope()
        if context.length == 0:
            self.__globalScopeCombo.setCurrentIndex(-1)
        else:
            index = self.__globalScopeCombo.findData(
                context.levels[0][0].line)
            self.__globalScopeCombo.setCurrentIndex(index)

        usedFromStore = 0
        index = 1
        while index < context.length:
            if len(self.__path) < index:
                newPathItem = PathElement(self)
                self.__path.append(newPathItem)
                self.__layout.addWidget(newPathItem.icon)
                self.__layout.addWidget(newPathItem.combo)
                combo = newPathItem.combo
                combo.pathIndex = len(self.__path) - 1
                combo.jumpToLine.connect(self.__onJumpToLine)
            else:
                self.__path[index - 1].icon.setVisible(True)
                self.__path[index - 1].combo.setVisible(True)
                combo = self.__path[index - 1].combo
                combo.clear()

            # Populate the combo box
            self.__populateClassesAndFunctions(context.levels[index - 1][0],
                                               combo)
            combo.setCurrentIndex(combo.findData(context.levels[index][0].line))
            index += 1
            usedFromStore += 1

        # it might need to have one more level with nothing selected
        if context.length > 0:
            if len(context.levels[context.length - 1][0].functions) > 0 or \
               len(context.levels[context.length - 1][0].classes) > 0:
                # Need to add a combo
                if len(self.__path) <= usedFromStore:
                    newPathItem = PathElement(self)
                    self.__path.append(newPathItem)
                    self.__layout.addWidget(newPathItem.icon)
                    self.__layout.addWidget(newPathItem.combo)
                    combo = newPathItem.combo
                    combo.pathIndex = len(self.__path) - 1
                    combo.jumpToLine.connect(self.__onJumpToLine)
                else:
                    self.__path[index - 1].icon.setVisible(True)
                    self.__path[index - 1].combo.setVisible(True)
                    combo = self.__path[index - 1].combo
                    combo.clear()

                self.__populateClassesAndFunctions(
                    context.levels[context.length - 1][0], combo)
                combo.setCurrentIndex(-1)
                usedFromStore += 1

        # Hide extra components if so
        index = usedFromStore
        while index < len(self.__path):
            self.__path[index].icon.setVisible(False)
            self.__path[index].combo.setVisible(False)
            index += 1

        # Make sure the spacer is the last item
        self.__layout.removeWidget(self.__spacer)
        self.__layout.addWidget(self.__spacer)
Ejemplo n.º 16
0
    def __onTabChanged(self, index):
        """Triggered when another tab becomes active"""
        # If the timer is still active that means the tab was switched before
        # the handler had a chance to work. Therefore update the previous tab
        # first if so.
        if self.__updateTimer.isActive():
            self.__updateTimer.stop()
            self.__updateView()

        # Now, switch the outline browser to the new tab
        if index == -1:
            widget = self.__editorsManager.currentWidget()
        else:
            widget = self.__editorsManager.getWidgetByIndex(index)
        if widget is None:
            self.__currentUUID = None
            self.__noneLabel.show()
            self.showParsingErrorsButton.setEnabled(False)
            return
        if widget.getType() not in [MainWindowTabWidgetBase.PlainTextEditor,
                                    MainWindowTabWidgetBase.VCSAnnotateViewer]:
            if self.__currentUUID is not None:
                self.__outlineBrowsers[self.__currentUUID].browser.hide()
                self.__currentUUID = None
            self.__noneLabel.show()
            self.showParsingErrorsButton.setEnabled(False)
            return

        # This is text editor, detect the file type
        if not isPythonMime(widget.getMime()):
            if self.__currentUUID is not None:
                self.__outlineBrowsers[self.__currentUUID].browser.hide()
                self.__currentUUID = None
            self.__noneLabel.show()
            self.showParsingErrorsButton.setEnabled(False)
            return

        # This is a python file, check if we already have the parsed info in
        # the cache
        uuid = widget.getUUID()
        if uuid in self.__outlineBrowsers:
            # We have it, hide the current and show the existed
            if self.__currentUUID is not None:
                self.__outlineBrowsers[self.__currentUUID].browser.hide()
                self.__currentUUID = None
            else:
                self.__noneLabel.hide()
            self.__currentUUID = uuid
            self.__outlineBrowsers[self.__currentUUID].browser.show()

            info = self.__outlineBrowsers[self.__currentUUID].info
            self.showParsingErrorsButton.setEnabled(info.isOK != True)
            return

        # It is first time we are here, create a new
        editor = widget.getEditor()
        editor.textChanged.connect(self.__onBufferChanged)
        editor.cursorPositionChanged.connect(self.__cursorPositionChanged)
        info = getBriefModuleInfoFromMemory(editor.text)

        self.showParsingErrorsButton.setEnabled(info.isOK != True)

        shortFileName = widget.getShortName()
        browser = OutlineBrowser(uuid, shortFileName, info, self)
        browser.setHeaderHighlight(info.isOK != True)
        self.__connectOutlineBrowser(browser)
        self.__layout.addWidget(browser)
        if self.__currentUUID is not None:
            self.__outlineBrowsers[self.__currentUUID].browser.hide()
            self.__currentUUID = None
        else:
            self.__noneLabel.hide()

        self.__currentUUID = uuid
        attributes = OutlineAttributes()
        attributes.browser = browser
        attributes.contextItem = None
        attributes.info = info
        attributes.shortFileName = shortFileName
        attributes.changed = False
        self.__outlineBrowsers[self.__currentUUID] = attributes
        self.__outlineBrowsers[self.__currentUUID].browser.show()
Ejemplo n.º 17
0
    def __process(self):
        """Accumulation process"""
        # Intermediate working data
        self.__participantFiles = []
        self.__projectImportDirs = []
        self.__projectImportsCache = {}

        self.dataModel.clear()
        self.__inProgress = True

        try:
            self.infoLabel.setText('Building the list of files to analyze...')
            QApplication.processEvents()

            # Build the list of participating python files
            self.__buildParticipants()
            self.__projectImportDirs = \
                GlobalData().project.getImportDirsAsAbsolutePaths()

            QApplication.processEvents()
            if self.__cancelRequest:
                QApplication.restoreOverrideCursor()
                self.close()
                return

            self.progressBar.setRange(0, len(self.__participantFiles))
            index = 1

            # Now, parse the files and build the diagram data model
            if self.__what == ImportsDiagramDialog.SingleBuffer:
                info = getBriefModuleInfoFromMemory(str(self.__buf))
                self.__addSingleFileToDataModel(info, self.__path)
            else:
                infoSrc = GlobalData().briefModinfoCache
                for fName in self.__participantFiles:
                    self.progressBar.setValue(index)
                    self.infoLabel.setText('Analyzing ' + fName + "...")
                    QApplication.processEvents()
                    if self.__cancelRequest:
                        QApplication.restoreOverrideCursor()
                        self.dataModel.clear()
                        self.close()
                        return
                    info = infoSrc.get(fName)
                    self.__addSingleFileToDataModel(info, fName)
                    index += 1

            # The import caches and other working data are not needed anymore
            self.__participantFiles = None
            self.__projectImportDirs = None
            self.__projectImportsCache = None

            # Generating the graphviz layout
            self.infoLabel.setText('Generating layout using graphviz...')
            QApplication.processEvents()

            graph = getGraphFromDescriptionData(self.dataModel.toGraphviz())
            graph.normalize(self.physicalDpiX(), self.physicalDpiY())
            QApplication.processEvents()
            if self.__cancelRequest:
                QApplication.restoreOverrideCursor()
                self.dataModel.clear()
                self.close()
                return

            # Generate graphics scene
            self.infoLabel.setText('Generating graphics scene...')
            QApplication.processEvents()
            self.__buildGraphicsScene(graph)

            # Clear the data model
            self.dataModel = None
        except Exception as exc:
            QApplication.restoreOverrideCursor()
            logging.error(str(exc))
            self.__inProgress = False
            self.__onClose()
            return

        QApplication.restoreOverrideCursor()
        self.infoLabel.setText('Done')
        QApplication.processEvents()
        self.__inProgress = False

        self.accept()
Ejemplo n.º 18
0
def getContext(editor, info=None, skipBlankLinesBack=False, skipDef=True):
    """Detects the context at the text cursor position.

    skipBlankLinesBack == False => current cursor position is used
    skipBlankLinesBack == True => skip blank lines back and use the first
                                  non-blank line as the cursor position.
    skipDef == True => treat a definition as belonging to an upper
                       level context (not included into the context stack)
    skipDef == False => treat a definition as starting a context level
                        (included into the context stack as the last one)
    """
    # It is expected that this is a python editor.
    # If non-python editor is given, then a global context is provided

    context = TextCursorContext()

    if not editor.isPythonBuffer():
        return context

    # It's not the first position, so the parsed module info is required
    if info is None:
        info = getBriefModuleInfoFromMemory(editor.text)

    line, pos = editor.cursorPosition
    if skipBlankLinesBack:
        while line >= 0:
            text = editor.lines[line]
            trimmedText = text.strip()
            if trimmedText != "":
                pos = len(text.rstrip())
                break
            line -= 1
        if line < 0:
            line = 0
            pos = 0

    _IdentifyScope(info, context, line + 1, pos, skipDef)

    if not skipDef:
        if _getDefinitionObject(info, line + 1, pos) is not None:
            return context

    if context.length == 0:
        return context

    continueLine = False
    currentLine = context.getLastScopeLine() + 1
    for currentLine in range(context.getLastScopeLine(), len(editor.lines)):
        if currentLine == line:
            break

        text = editor.lines[currentLine]
        textLen = len(text)
        trimmedText = text.strip()
        if not continueLine:
            if trimmedText == "" or trimmedText.startswith("#"):
                continue

            # Here: there must be characters in the line
            nonSpacePos = _getFirstNonSpacePos(text)
            context.stripLevels(nonSpacePos)
            if context.length == 0:
                return context

        if trimmedText.endswith(",") or trimmedText.endswith('\\') or \
           (textLen > 0 and editor.isStringLiteral(currentLine, textLen - 1)):
            continueLine = True
        else:
            continueLine = False

    if continueLine:
        context.stripLevels(nonSpacePos)
    else:
        nonSpacePos = _getFirstNonSpacePos(editor.lines[line])
        if nonSpacePos == -1:
            context.stripLevels(pos)
        else:
            context.stripLevels(min(pos, nonSpacePos))
    return context