コード例 #1
0
ファイル: navpath.py プロジェクト: IFT-SE/pfis3
    def __removeGapNavigations(self):
        # We do a second pass over the navigations so that we remove any
        # parts of the navigation that have been previously identified as being
        # a navigation to a gap (a space between two method definitions).
        finalNavigations = []
        fromNav = None
        toNav = None
        foundGap = False

        for navigation in self._navigations:
            if not foundGap:
                if navigation.fromFileNav is None:
                    if navigation.toFileNav.isGap:
                        fromNav = navigation.fromFileNav
                        foundGap = True
                    else:
                        finalNavigations.append(navigation)
                elif not navigation.fromFileNav.isGap and navigation.toFileNav.isGap:
                    fromNav = navigation.fromFileNav
                    foundGap = True
                elif navigation.fromFileNav.isGap and navigation.toFileNav.isGap:
                    raise RuntimeError('removeGapNavigations: cannot have a navigation with a fromFileNav that is a gap without a prior navigation with a gap in the toFileNav')
                else:
                    if not navigation.isToSameMethod():
                        finalNavigations.append(navigation)
            elif foundGap:
                if navigation.fromFileNav.isGap and not navigation.toFileNav.isGap:
                    toNav = navigation.toFileNav
                    foundGap = False
                    newNavigation = Navigation(fromNav, toNav)
                    if not newNavigation.isToSameMethod():
                        finalNavigations.append(Navigation(fromNav, toNav))
                elif navigation.fromFileNav.isGap and navigation.toFileNav.isGap:
                    continue
                else:
                    raise RuntimeError('removeGapNavigations: cannot have a fromFileNav without a gap if the prior navigation had a gap in the toFileNav')

        self._navigations = finalNavigations
コード例 #2
0
ファイル: navpath.py プロジェクト: IFT-SE/pfis3
    def __findMethodsForFileNavigations(self, conn):
        # Here we map the file paths and offsets in the fileNavigations list to
        # FQNs of methods. This is done by querying for all the Method
        # declarations within the database and storing that data to the
        # self.knownMethods object. The insertions into knownMethods will create
        # entries if they are new or update them if they already exist. Since
        # code can be changed between navigations, we need to update
        # self.knownMethods to reflect the most recent state of the code up to
        # each navigation.
        # After building the known methods, we test an entry from
        # fileNavigations against the set of known methods by offset. This is
        # what maps Text selection offsets to methods.
        prevNavigation = None
        postProcessing = False

        # Iterate over the data gathered from the Text selection offsets
        for i in range(len(self.__fileNavigations)):
            toFileNavigation = self.__fileNavigations[i]
            if self.VERBOSE_PATH:
                print '\tProcessing text selection offset: ' + str(toFileNavigation)

            # For every navigation's timestamp, we fill the knownMethods object
            # with the details of every method declaration up to the timestamp
            # of the toFileNavigation. The knownMethods object will be queried to
            # determine in which method (if any) a text selection offset occurs.

            # Note that the queries here are by a method's FQN. This allows us
            # to update the method's declaration info if it gets updated at some
            # point in the future.

            c = conn.execute(self.METHOD_DECLARATIONS_QUERY, [toFileNavigation.timestamp])
            for row in c:
                action, target, referrer = row['action'], \
                    row['target'], row['referrer']

                if action == 'Method declaration':
                    self.knownPatches.addFilePatch(referrer)
                elif action == 'Method declaration offset':
                    method = self.knownPatches.findMethodByFqn(target)
                    if method is not None:
                        method.startOffset = int(referrer)
                elif action == 'Method declaration length':
                    method = self.knownPatches.findMethodByFqn(target)
                    if method is not None:
                        method.length = int(referrer);

            # Recall that navigations contains the navigation data after its
            # been translated to methods and headers

            # If there was at least 1 navigation already, the to destination
            # from the previous navigation serves as this navigations from. A
            # clone is necessary since this may be later transformed into a
            # PFIG header and we don't want to affect the to destination from
            # the previous navigation.

            fromFileNavigation = None
            fromMethodPatch = None

            if len(self._navigations) > 0:
                prevNavigation = self._navigations[-1]
                fromFileNavigation = prevNavigation.toFileNav.clone()
                self.__addPFIGFileHeadersIfNeeded(conn, prevNavigation, toFileNavigation)
                fromMethodPatch = self.knownPatches.findMethodByOffset(fromFileNavigation.filePath, fromFileNavigation.offset)


            # We query known methods here to see if the offset of the current
            # toFileNavigation is among the known patches.
            toMethodPatch = self.knownPatches.findMethodByOffset(toFileNavigation.filePath, toFileNavigation.offset)


            # Create the navigation object representing this navigation
            navigation = Navigation(fromFileNavigation, toFileNavigation.clone())

            # Set method FQN data
            if navigation.fromFileNav is not None and fromMethodPatch is not None:
                navigation.fromFileNav.methodFqn = fromMethodPatch.fqn
            if navigation.toFileNav is not None and toMethodPatch is not None:
                navigation.toFileNav.methodFqn = toMethodPatch.fqn

            if not navigation.isToSameMethod():
                self._navigations.append(navigation)

                if navigation.fromFileNav is not None:
                    if navigation.fromFileNav.methodFqn is None:
                        postProcessing = True
                        navigation.fromFileNav.isGap = True
                        prevNavigation.toFileNav.isGap = True
            c.close()

        if postProcessing:
            self.__removeGapNavigations()