Example #1
0
    def test_extent(self):
        tu = get_tu(baseInput)
        one = get_cursor(tu, 'one')
        two = get_cursor(tu, 'two')

        self.assert_location(one.extent.start, line=1, column=1, offset=0)
        self.assert_location(one.extent.end, line=1, column=8, offset=7)
        self.assertEqual(
            baseInput[one.extent.start.offset:one.extent.end.offset],
            "int one")

        self.assert_location(two.extent.start, line=2, column=1, offset=9)
        self.assert_location(two.extent.end, line=2, column=8, offset=16)
        self.assertEqual(
            baseInput[two.extent.start.offset:two.extent.end.offset],
            "int two")

        file = File.from_name(tu, 't.c')
        location1 = SourceLocation.from_position(tu, file, 1, 1)
        location2 = SourceLocation.from_position(tu, file, 1, 8)

        range1 = SourceRange.from_locations(location1, location2)
        range2 = SourceRange.from_locations(location1, location2)
        self.assertEqual(range1, range2)

        location3 = SourceLocation.from_position(tu, file, 1, 6)
        range3 = SourceRange.from_locations(location1, location3)
        self.assertNotEqual(range1, range3)
Example #2
0
def test_extent():
    tu = get_tu(baseInput)
    one = get_cursor(tu, 'one')
    two = get_cursor(tu, 'two')

    assert_location(one.extent.start, line=1, column=1, offset=0)
    assert_location(one.extent.end, line=1, column=8, offset=7)
    assert baseInput[one.extent.start.offset:one.extent.end.
                     offset] == "int one"

    assert_location(two.extent.start, line=2, column=1, offset=9)
    assert_location(two.extent.end, line=2, column=8, offset=16)
    assert baseInput[two.extent.start.offset:two.extent.end.
                     offset] == "int two"

    file = File.from_name(tu, 't.c')
    location1 = SourceLocation.from_position(tu, file, 1, 1)
    location2 = SourceLocation.from_position(tu, file, 1, 8)

    range1 = SourceRange.from_locations(location1, location2)
    range2 = SourceRange.from_locations(location1, location2)
    assert range1 == range2

    location3 = SourceLocation.from_position(tu, file, 1, 6)
    range3 = SourceRange.from_locations(location1, location3)
    assert range1 != range3
Example #3
0
    def _fn_get_parameter(self, fn, parameter):
        """
        The parser does not seem to provide access to the complete text of a parameter.
        This makes it hard to find any default values, so we:

            1. Run the lexer from "here" to the end of the file, bailing out when we see the ","
            or a ")" marking the end.
            2. Watch for the assignment.
        """
        info = Info("parameter", parameter)
        info["type"] = parameter.type.spelling
        for member in parameter.get_children():
            if member.kind.is_expression():
                #
                # Get the text after the "=". Macro expansion can make relying on tokens fraught...and
                # member.get_tokens() simply does not always return anything.
                #
                possible_extent = SourceRange.from_locations(
                    parameter.extent.start, fn.extent.end)
                text = ""
                bracket_level = 0
                found_start = False
                found_end = False
                was_punctuated = True
                for token in self.tu.get_tokens(extent=possible_extent):
                    #
                    # Now count balanced anything-which-can-contain-a-comma till we get to the end.
                    #
                    if bracket_level == 0 and token.spelling == "=" and not found_start:
                        found_start = True
                    elif bracket_level == 0 and token.spelling in ",)":
                        found_end = True
                        text = text[1:]
                        break
                    elif token.spelling in "<(":
                        bracket_level += 1
                    elif token.spelling in ")>":
                        bracket_level -= 1
                    if found_start:
                        if (token.kind != TokenKind.PUNCTUATION
                                and not was_punctuated) or (token.spelling
                                                            in "*&"):
                            text += " "
                        text += token.spelling
                        was_punctuated = token.kind == TokenKind.PUNCTUATION
                if not found_end and text:
                    raise RuntimeError(
                        _("No end found for {}::{}, '{}'").format(
                            fn.spelling, parameter.spelling, text))
                info["default"] = text
        return info
Example #4
0
def test_extent():
    tu = get_tu(baseInput)
    one = get_cursor(tu, 'one')
    two = get_cursor(tu, 'two')

    assert_location(one.extent.start, line=1, column=1, offset=0)
    assert_location(one.extent.end, line=1, column=8, offset=7)
    assert baseInput[one.extent.start.offset:one.extent.end.offset] == "int one"

    assert_location(two.extent.start, line=2, column=1, offset=9)
    assert_location(two.extent.end, line=2, column=8, offset=16)
    assert baseInput[two.extent.start.offset:two.extent.end.offset] == "int two"

    file = File.from_name(tu, 't.c')
    location1 = SourceLocation.from_position(tu, file, 1, 1)
    location2 = SourceLocation.from_position(tu, file, 1, 8)

    range1 = SourceRange.from_locations(location1, location2)
    range2 = SourceRange.from_locations(location1, location2)
    assert range1 == range2

    location3 = SourceLocation.from_position(tu, file, 1, 6)
    range3 = SourceRange.from_locations(location1, location3)
    assert range1 != range3
Example #5
0
    def test_extent(self):
        tu = get_tu(baseInput)
        one = get_cursor(tu, 'one')
        two = get_cursor(tu, 'two')

        self.assert_location(one.extent.start,line=1,column=1,offset=0)
        self.assert_location(one.extent.end,line=1,column=8,offset=7)
        self.assertEqual(baseInput[one.extent.start.offset:one.extent.end.offset], "int one")

        self.assert_location(two.extent.start,line=2,column=1,offset=9)
        self.assert_location(two.extent.end,line=2,column=8,offset=16)
        self.assertEqual(baseInput[two.extent.start.offset:two.extent.end.offset], "int two")

        file = File.from_name(tu, 't.c')
        location1 = SourceLocation.from_position(tu, file, 1, 1)
        location2 = SourceLocation.from_position(tu, file, 1, 8)

        range1 = SourceRange.from_locations(location1, location2)
        range2 = SourceRange.from_locations(location1, location2)
        self.assertEqual(range1, range2)

        location3 = SourceLocation.from_position(tu, file, 1, 6)
        range3 = SourceRange.from_locations(location1, location3)
        self.assertNotEqual(range1, range3)
Example #6
0
    def _fn_get_parameter(self, fn, parameter):
        """
        The parser does not seem to provide access to the complete text of a parameter.
        This makes it hard to find any default values, so we:

            1. Run the lexer from "here" to the end of the file, bailing out when we see the ","
            or a ")" marking the end.
            2. Watch for the assignment.
        """
        info = Info("parameter", parameter)
        info["type"] = parameter.type.spelling
        for member in parameter.get_children():
            if member.kind.is_expression():
                #
                # Get the text after the "=". Macro expansion can make relying on tokens fraught...and
                # member.get_tokens() simply does not always return anything.
                #
                possible_extent = SourceRange.from_locations(parameter.extent.start, fn.extent.end)
                text = ""
                bracket_level = 0
                found_start = False
                found_end = False
                was_punctuated = True
                for token in self.tu.get_tokens(extent=possible_extent):
                    #
                    # Now count balanced anything-which-can-contain-a-comma till we get to the end.
                    #
                    if bracket_level == 0 and token.spelling == "=" and not found_start:
                        found_start = True
                    elif bracket_level == 0 and token.spelling in ",)":
                        found_end = True
                        text = text[1:]
                        break
                    elif token.spelling in "<(":
                        bracket_level += 1
                    elif token.spelling in ")>":
                        bracket_level -= 1
                    if found_start:
                        if (token.kind != TokenKind.PUNCTUATION and not was_punctuated) or (token.spelling in "*&"):
                            text += " "
                        text += token.spelling
                        was_punctuated = token.kind == TokenKind.PUNCTUATION
                if not found_end and text:
                    raise RuntimeError(_("No end found for {}::{}, '{}'").format(fn.spelling, parameter.spelling,
                                                                                 text))
                info["default"] = text
        return info
Example #7
0
    def do_it(cursor, result):

        class Reference(object):
            def __init__(self, referenced_range, referencing_range):
                self.referenced_range = referenced_range
                self.referencing_range = referencing_range

        referenced_cursor = get_definition_or_reference(cursor)
        if referenced_cursor:
            if not intersects_with_selection(referenced_cursor):
                # Limit the extent to start at the name
                constrained_extent = SourceRange.from_locations(
                    referenced_cursor.location,
                    referenced_cursor.extent.end)
                result.add(Reference(
                           constrained_extent,
                           cursor.extent))

        for child in cursor.get_children():
            if intersects_with_selection(child):
                do_it(child, result)
    def _fn_get_parameter_default(self, function, parameter):
        """
        The parser does not seem to provide access to the complete text of a parameter.
        This makes it hard to find any default values, so we:

            1. Run the lexer from "here" to the end of the file, bailing out when we see the ","
            or a ")" marking the end.
            2. Watch for the assignment.
        """
        def _get_param_type(parameter):
            result = parameter.type.get_declaration().type

            if result.kind != TypeKind.ENUM and result.kind != TypeKind.TYPEDEF and parameter.type.kind == TypeKind.LVALUEREFERENCE:
                if parameter.type.get_pointee().get_declaration(
                ).type.kind != TypeKind.INVALID:
                    return parameter.type.get_pointee().get_declaration().type
                return parameter.type.get_pointee()

            if parameter.type.get_declaration().type.kind == TypeKind.INVALID:
                return parameter.type

            if (parameter.type.get_declaration().type.kind == TypeKind.TYPEDEF
                ):
                isQFlags = False
                for member in parameter.type.get_declaration().get_children():
                    if member.kind == CursorKind.TEMPLATE_REF and member.spelling == "QFlags":
                        isQFlags = True
                    if isQFlags and member.kind == CursorKind.TYPE_REF:
                        result = member.type
                        break

            return result

        def _get_param_value(text, parameterType):
            if text == "0" or text == "nullptr":
                return text
            if text == "{}":
                if parameterType.kind == TypeKind.ENUM:
                    return "0"
                if parameterType.kind == TypeKind.POINTER:
                    return "nullptr"
                if parameterType.spelling.startswith("const "):
                    return parameterType.spelling[6:] + "()"
                return parameterType.spelling + "()"
            if not "::" in parameterType.spelling:
                return text
            try:
                typeText, typeInit = text.split("(")
                typeInit = "(" + typeInit
            except:
                typeText = text
                typeInit = ""

            if parameterType.kind == TypeKind.ENUM and parameterType.get_declaration(
            ).is_scoped_enum():
                prefix = parameterType.spelling
            else:
                prefix = parameterType.spelling.rsplit("::", 1)[0]
            if "::" in typeText:
                typeText = typeText.rsplit("::", 1)[1]
            return prefix + "::" + typeText + typeInit

        for member in parameter.get_children():
            if member.kind.is_expression():

                possible_extent = SourceRange.from_locations(
                    parameter.extent.start, function.extent.end)
                text = ""
                bracket_level = 0
                found_start = False
                found_end = False
                for token in self.tu.get_tokens(extent=possible_extent):
                    if (token.spelling == "="):
                        found_start = True
                        continue
                    if token.spelling == "," and bracket_level == 0:
                        found_end = True
                        break
                    elif token.spelling == "(":
                        bracket_level += 1
                        text += token.spelling
                    elif token.spelling == ")":
                        if bracket_level == 0:
                            found_end = True
                            break
                        bracket_level -= 1
                        text += token.spelling
                        if bracket_level == 0:
                            found_end = True
                            break
                    elif found_start:
                        text += token.spelling
                if not found_end and text:
                    RuntimeError(
                        _("No end found for {}::{}, '{}'").format(
                            function.spelling, parameter.spelling, text))

                parameterType = _get_param_type(parameter)

                return _get_param_value(text, parameterType)
        return ""
Example #9
0
    def _fn_get_parameter_default(self, function, parameter):
        """
        The parser does not seem to provide access to the complete text of a parameter.
        This makes it hard to find any default values, so we:

            1. Run the lexer from "here" to the end of the file, bailing out when we see the ","
            or a ")" marking the end.
            2. Watch for the assignment.
        """
        def _get_param_type(parameter):
            result = parameter.type.get_declaration().type

            if (parameter.type.get_declaration().type.kind == TypeKind.TYPEDEF):
                isQFlags = False
                for member in parameter.type.get_declaration().get_children():
                    if member.kind == CursorKind.TEMPLATE_REF and member.spelling == "QFlags":
                        isQFlags = True
                    if isQFlags and member.kind == CursorKind.TYPE_REF:
                        result = member.type
                        break

            return result

        def _get_param_value(text, parameterType):
            if text == "0":
                return text
            if not "::" in parameterType.spelling:
                return text
            try:
                typeText, typeInit = text.split("(")
                typeInit = "(" + typeInit
            except:
                typeText = text
                typeInit = ""

            prefix = parameterType.spelling.rsplit("::", 1)[0]
            if "::" in typeText:
                typeText = typeText.rsplit("::", 1)[1]
            return prefix + "::" + typeText + typeInit


        for member in parameter.get_children():
            if member.kind.is_expression():

                possible_extent = SourceRange.from_locations(parameter.extent.start, function.extent.end)
                text = ""
                bracket_level = 0
                found_start = False
                found_end = False
                for token in self.tu.get_tokens(extent=possible_extent):
                    if (token.spelling == "="):
                        found_start = True
                        continue
                    if token.spelling == "," and bracket_level == 0:
                        found_end = True
                        break
                    elif token.spelling == "(":
                        bracket_level += 1
                        text += token.spelling
                    elif token.spelling == ")":
                        if bracket_level == 0:
                            found_end = True
                            break
                        bracket_level -= 1
                        text += token.spelling
                        if bracket_level == 0:
                            found_end = True
                            break
                    elif found_start:
                        text += token.spelling
                if not found_end and text:
                    RuntimeError(_("No end found for {}::{}, '{}'").format(function.spelling, parameter.spelling, text))

                parameterType = _get_param_type(parameter)

                return _get_param_value(text, parameterType)
        return ""
    def _fn_get_parameter_default(self, function, parameter):
        """
        The parser does not seem to provide access to the complete text of a parameter.
        This makes it hard to find any default values, so we:

            1. Run the lexer from "here" to the end of the file, bailing out when we see the ","
            or a ")" marking the end.
            2. Watch for the assignment.
        """

        for member in parameter.get_children():
            if member.kind.is_expression():
                value = ""
                for exm in member.get_tokens():
                    value += exm.spelling

                if (value.startswith("=")):
                    value = "0)" # HACK: Something strange happening in kitemmodels

                parameterType = parameter.type.get_declaration().type

                if (parameter.type.get_declaration().type.kind == TypeKind.TYPEDEF):
                    isQFlags = False
                    for member in parameter.type.get_declaration().get_children():
                        if member.kind == CursorKind.TEMPLATE_REF and member.spelling == "QFlags":
                            isQFlags = True
                        if isQFlags and member.kind == CursorKind.TYPE_REF:
                            parameterType = member.type
                            break

                if not value:
                    # QStringLiteral case
                    possible_extent = SourceRange.from_locations(parameter.extent.start, function.extent.end)
                    text = ""
                    bracket_level = 0
                    found_end = False
                    was_punctuated = True
                    default_value = None
                    for token in self.tu.get_tokens(extent=possible_extent):
                        if bracket_level <= 0 and token.spelling in [",", ")", ";"]:
                            found_end = True
                            break
                        elif token.spelling == "(":
                            was_punctuated = True
                            bracket_level += 1
                            text += token.spelling
                        elif token.spelling == ")":
                            was_punctuated = True
                            bracket_level -= 1
                            text += token.spelling
                        elif token.kind == TokenKind.PUNCTUATION:
                            was_punctuated = True
                            text += token.spelling
                            if token.spelling == "=" and default_value is None:
                                default_value = len(text)
                        else:
                            if not was_punctuated:
                                text += " "
                            text += token.spelling
                            was_punctuated = False
                    if not found_end and text or not default_value:
                        RuntimeError(_("No end found for {}::{}, '{}'").format(function.spelling, parameter.spelling, text))
                    value = text[default_value:]
                else:
                    value = value[:-1]

                if "::" in parameterType.spelling and value != "0":
                    prefix = parameterType.spelling.rsplit("::", 1)[0]
                    if "::" in value:
                        value = value.rsplit("::", 1)[1]
                    value = prefix + "::" + value
                return value
        return ""
Example #11
0
def find_diagnostics(translation_unit):
    for diagnostic in translation_unit.diagnostics:
        if diagnostic.severity in (diagnostic.Warning, diagnostic.Error, diagnostic.Note):
            yield SourceRange.from_locations(diagnostic.location, diagnostic.location)
            for range in diagnostic.ranges:
                yield range