Example #1
0
    def get_singleline_strings(file, filename, text, string_start, string_end,
                               position):
        """
        Gets sourcerange of a single-line string and its end position.

        :param file:
            A tuple of strings, with each string being a line in the file.
        :param filename:
            The name of the file.
        :param string_start:
            The string which specifies how a string starts.
        :param string_end:
            The string which specifies how a string ends.
        :position:
            An integer identifying the position where the string started.
        :return:
            A SourceRange object identifying the range of the single-line
            string and the end_position of the string as an integer.
        """
        end_position = get_end_position(string_end, text,
                                        position + len(string_start) - 1)
        newline = get_end_position("\n", text, position)
        if newline == -1:
            newline = len(text)
        if end_position == -1:
            _range = SourceRange.from_absolute_position(
                filename, AbsolutePosition(file, position))
            raise NoCloseError(string_start, _range)
        if newline > end_position:
            return (SourceRange.from_absolute_position(
                filename, AbsolutePosition(file, position),
                AbsolutePosition(file, end_position)), end_position)
Example #2
0
    def get_multiline(file, filename, text, annotation_start, annotation_end,
                      position):
        """
        Gets sourcerange and end position of an annotation that can span
        multiple lines.

        :param file:
            A tuple of strings, with each string being a line in the file.
        :param filename:
            The name of the file.
        :param annotation_start:
            The string specifying the start of the annotation.
        :param annotation_end:
            The string specifying the end of the annotation.
        :param position:
            An integer identifying the position where the annotation started.
        :return:
            A SourceRange object holding the range of the multi-line annotation
            and the end_position of the annotation as an integer.
        """
        end_end = get_end_position(annotation_end, text,
                                   position + len(annotation_start) - 1)
        if end_end == -1:
            _range = SourceRange.from_absolute_position(
                filename, AbsolutePosition(file, position))
            raise NoCloseError(annotation_start, _range)

        return (SourceRange.from_absolute_position(
            filename, AbsolutePosition(file, position),
            AbsolutePosition(file, end_end)), end_end)
Example #3
0
    def get_singleline_comment(file, filename, text, comment, position):
        """
        Gets Sourcerange of a single-line comment where the start is the
        start of comment and the end is the end of line.

        :param file:
            A tuple of strings, with each string being a line in the file.
        :param filename:
            The name of the file.
        :param comment:
            The string which specifies the comment.
        :position:
            An integer identifying the position where the string started.
        :return:
            A SourceRange object identifying the range of the single-line
            comment and the end_position of the comment as an integer.
        """
        end_position = get_end_position('\n',
                                        text,
                                        position + len(comment) - 1)
        if end_position == -1:
            end_position = len(text) - 1
        return (SourceRange.from_absolute_position(
                    filename,
                    AbsolutePosition(file, position),
                    AbsolutePosition(file, end_position)),
                end_position)
Example #4
0
    def test_instantiation(self):
        with self.assertRaises(ValueError):
            uut = AbsolutePosition((), 0)

        uut = AbsolutePosition(position=5)
        self.assertEqual(uut.position, 5)
        self.assertEqual(uut.line, None)
        self.assertEqual(uut.column, None)
 def test_single_line_comment(self):
     text = ["some #coment with 'string'\n", "and next line"]
     compare = (SourceRange.from_absolute_position(
         "F", AbsolutePosition(text, text[0].find('#')),
         AbsolutePosition(text,
                          len(text[0]) - 1)), )
     with execute_bear(self.python_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], ())
         self.assertEqual(result[0].contents['comments'], compare)
 def test_multiline_comment(self):
     text = ["some string /*within \n", "'multiline comment'*/"]
     compare = (SourceRange.from_absolute_position(
         "F", AbsolutePosition(text, text[0].find('/*')),
         AbsolutePosition(text,
                          len(''.join(text)) - 1)), )
     with execute_bear(self.c_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], ())
         self.assertEqual(result[0].contents['comments'], compare)
 def test_multiline_string(self):
     text = ["'''multiline string, #comment within it'''\n"]
     compare = (SourceRange.from_absolute_position(
         "F", AbsolutePosition(text, 0),
         AbsolutePosition(text,
                          len(text[0]) - 2)), )
     with execute_bear(self.python_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], compare)
         self.assertEqual(result[0].contents['comments'], ())
 def test_single_line_string(self):
     text = [
         "'from start till the end with #comments'\n",
     ]
     compare = (SourceRange.from_absolute_position(
         "F", AbsolutePosition(text, 0),
         AbsolutePosition(text,
                          len(text[0]) - 2)), )
     with execute_bear(self.python_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], compare)
         self.assertEqual(result[0].contents['comments'], ())
Example #9
0
    def test_from_absolute_position(self):
        text = ('a\n', 'b\n')
        start = AbsolutePosition(text, 0)
        end = AbsolutePosition(text, 2)

        uut = SourceRange.from_absolute_position('F', start, end)
        compare = SourceRange.from_values('F', 1, 1, 2, 1)
        self.assertEqual(uut, compare)

        uut = SourceRange.from_absolute_position('F', start, None)
        compare = SourceRange(SourcePosition('F', 1, 1), None)
        self.assertEqual(uut, compare)
Example #10
0
    def test_multiline_comment(self):
        text = ['some string /*within \n', "'multiline comment'*/"]
        compare = (SourceRange.from_absolute_position(
            'F', AbsolutePosition(text, text[0].find('/*')),
            AbsolutePosition(text,
                             len(''.join(text)) - 1)), )
        with execute_bear(self.c_uut, 'F', text) as result:
            self.assertEqual(result[0].contents['strings'], ())
            self.assertEqual(result[0].contents['comments'], compare)

        text = ['/*Multiline which does not end']
        with execute_bear(self.c_uut, 'F', text) as result:
            self.assertEqual(result[0].message, '/* has no closure')
Example #11
0
    def test_property(self):
        uut = AbsolutePosition(('1', '2'), 1)
        self.assertEqual(uut.position, 1)
        self.assertEqual(uut.line, 2)
        self.assertEqual(uut.column, 1)

        uut = AbsolutePosition()
        self.assertEqual(uut.position, None)
        self.assertEqual(uut.line, None)
        self.assertEqual(uut.column, None)

        uut = AbsolutePosition(('a\n', 'b\n'), 0)
        self.assertEqual(uut.position, 0)
        self.assertEqual(uut.line, 1)
        self.assertEqual(uut.column, 1)
Example #12
0
 def test_string_with_comments(self):
     text = ["some #comment\n", "with 'string' in  next line"]
     comment_start = text[0].find('#')
     comment_end = len(text[0]) - 1
     string_start = ''.join(text).find("'")
     string_end = ''.join(text).find("'", string_start + 1)
     compare = [(SourceRange.from_absolute_position(
         "F", AbsolutePosition(text, string_start),
         AbsolutePosition(text, string_end)), ),
                (SourceRange.from_absolute_position(
                    "F", AbsolutePosition(text, comment_start),
                    AbsolutePosition(text, comment_end)), )]
     with execute_bear(self.python_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], compare[0])
         self.assertEqual(result[0].contents['comments'], compare[1])
Example #13
0
    def test_property(self):
        uut = AbsolutePosition(("1", "2"), 1)
        self.assertEqual(uut.position, 1)
        self.assertEqual(uut.line, 2)
        self.assertEqual(uut.column, 1)

        uut = AbsolutePosition()
        self.assertEqual(uut.position, None)
        self.assertEqual(uut.line, None)
        self.assertEqual(uut.column, None)

        uut = AbsolutePosition(("a\n", "b\n"), 0)
        self.assertEqual(uut.position, 0)
        self.assertEqual(uut.line, 1)
        self.assertEqual(uut.column, 1)
Example #14
0
    def test_escape_strings(self):
        text = [r"'I\'ll be back' -T1000"]
        uut = AnnotationBear(self.section1, Queue())
        test_range = SourceRange.from_absolute_position(
            'F',
            AbsolutePosition(text, 0),
            AbsolutePosition(text, text[0].find("'", 4)))
        with execute_bear(uut, 'F', text) as result:
            self.assertEqual(result[0].contents['strings'], (test_range,))

        text = ['''
            """"quoting inside quoting"
            """
            ''']
        uut = AnnotationBear(self.section1, Queue())
        with execute_bear(uut, 'F', text) as results:
            for result in results:
                # The """" was recognized as a string start and end before.
                # That lead to a Result being yielded because of unclosed
                # quotes, this asserts that no such thing happened.
                self.assertEqual(type(result), HiddenResult)
Example #15
0
 def test_combined_strings(self):
     file_text = [
         '"some string #with comment"\n', '"""\n',
         "now a multiline string ''' <- this one not\n", '"""\n', '"""\n'
         'another comment # rather harmless\n', '"""\n'
     ]
     string1_start = 0
     string1_end = len(file_text[0]) - 2
     string1 = SourceRange.from_absolute_position(
         "F", AbsolutePosition(file_text, string1_start),
         AbsolutePosition(file_text, string1_end))
     string2_start = string1_end + 2
     text = ''.join(file_text)
     string2_end = text.find('"""', string2_start + 1) + 2
     #+2 for length of """
     string2 = SourceRange.from_absolute_position(
         "F", AbsolutePosition(file_text, string2_start),
         AbsolutePosition(file_text, string2_end))
     string3_start = text.find('"""', string2_end + 1)
     string3_end = text.find('"""', string3_start + 1) + 2
     #+2 for length of """
     string3 = SourceRange.from_absolute_position(
         "F", AbsolutePosition(file_text, string3_start),
         AbsolutePosition(file_text, string3_end))
     with execute_bear(self.python_uut, "F", file_text) as results:
         self.assertIn(string1, results[0].contents['strings'])
         self.assertIn(string2, results[0].contents['strings'])
         self.assertIn(string3, results[0].contents['strings'])
         self.assertEqual(results[0].contents['comments'], ())
Example #16
0
    def find_with_start_end(filename, file, annot):
        """
        Gives all positions of annotations which have a start and end.

        :param filename: Name of the file on which the bear is running.
        :param file:     Contents of the file in the form of tuple of lines.
        :param annot:    A dict containing start of annotation as key and end of
                         annotation as value.
        :return:         A set of SourceRanges giving the range of annotation.
        """
        text = ''.join(file)
        found_pos = set()
        for annot_type in annot:
            found_pos.update(unescaped_search_in_between(
                                           annot_type, annot[annot_type], text))
        if found_pos:
            found_pos = set(SourceRange.from_absolute_position(
                                filename,
                                AbsolutePosition(file, position.begin.range[0]),
                                AbsolutePosition(
                                    file, position.end.range[1] - 1))
                            for position in found_pos)
        return found_pos
Example #17
0
    def find_singleline_comments(filename, file, comments):
        """
        Finds all single-line comments.

        :param filename: Name of the file on which the bear is running.
        :param file:     Contents of the file in the form of tuple of lines.
        :param comments: A list containing different types of
                         single-line comments.
        :return:         A set of SourceRange objects with start as the
                         beginning of the comment and end as
                         the termination of line.
        """
        text = ''.join(file)
        single_comments = set()
        for comment_type in comments:
            for found in unescaped_search_for(comment_type, text):
                start = found.start()
                end = text.find('\n', start)
                end = len(text) - 1 if end == -1 else end
                single_comments.add(SourceRange.from_absolute_position(
                                        filename,
                                        AbsolutePosition(file, start),
                                        AbsolutePosition(file, end)))
        return single_comments
    def get_valid_sequences(file,
                            sequence,
                            annotation_dict,
                            encapsulators=None,
                            check_ending=False):
        """
        A vaild sequence is a sequence that is outside of comments or strings.

        :param file:            File that needs to be checked in the form of
                                a list of strings.
        :param sequence:        Sequence whose validity is to be checked.
        :param annotation_dict: A dictionary containing sourceranges of all the
                                strings and comments within a file.
        :param encapsulators:   A tuple of SourceRanges of code regions
                                trapped in between a matching pair of
                                encapsulators.
        :param check_ending:    Check whether sequence falls at the end of the
                                line.
        :return:                A tuple of AbsolutePosition's of all occurances
                                of sequence outside of string's and comments.
        """
        file_string = ''.join(file)
        # tuple since order is important
        sequence_positions = tuple()

        for sequence_match in unescaped_search_for(sequence, file_string):
            valid = True
            sequence_position = AbsolutePosition(file, sequence_match.start())
            sequence_line_text = file[sequence_position.line - 1]

            # ignore if within string
            for string in annotation_dict['strings']:
                if (gt_eq(sequence_position, string.start)
                        and lt_eq(sequence_position, string.end)):
                    valid = False

            # ignore if within comments
            for comment in annotation_dict['comments']:
                if (gt_eq(sequence_position, comment.start)
                        and lt_eq(sequence_position, comment.end)):
                    valid = False

                if (comment.start.line == sequence_position.line
                        and comment.end.line == sequence_position.line
                        and check_ending):
                    sequence_line_text = sequence_line_text[:comment.start.
                                                            column -
                                                            1] + sequence_line_text[
                                                                comment.end.
                                                                column - 1:]

            if encapsulators:
                for encapsulator in encapsulators:
                    if (gt_eq(sequence_position, encapsulator.start)
                            and lt_eq(sequence_position, encapsulator.end)):
                        valid = False

            if not sequence_line_text.rstrip().endswith(':') and check_ending:
                valid = False

            if valid:
                sequence_positions += (sequence_position, )

        return sequence_positions