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)
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
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
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
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)
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
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 ""
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 ""
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