xref: /openbsd-src/gnu/llvm/clang/bindings/python/tests/cindex/util.py (revision e5dd70708596ae51455a0ffa086a00c5b29f8583)
1*e5dd7070Spatrick# This file provides common utility functions for the test suite.
2*e5dd7070Spatrick
3*e5dd7070Spatrickimport os
4*e5dd7070SpatrickHAS_FSPATH = hasattr(os, 'fspath')
5*e5dd7070Spatrick
6*e5dd7070Spatrickif HAS_FSPATH:
7*e5dd7070Spatrick    from pathlib import Path as str_to_path
8*e5dd7070Spatrickelse:
9*e5dd7070Spatrick    str_to_path = None
10*e5dd7070Spatrick
11*e5dd7070Spatrickimport unittest
12*e5dd7070Spatrick
13*e5dd7070Spatrickfrom clang.cindex import Cursor
14*e5dd7070Spatrickfrom clang.cindex import TranslationUnit
15*e5dd7070Spatrick
16*e5dd7070Spatrickdef get_tu(source, lang='c', all_warnings=False, flags=[]):
17*e5dd7070Spatrick    """Obtain a translation unit from source and language.
18*e5dd7070Spatrick
19*e5dd7070Spatrick    By default, the translation unit is created from source file "t.<ext>"
20*e5dd7070Spatrick    where <ext> is the default file extension for the specified language. By
21*e5dd7070Spatrick    default it is C, so "t.c" is the default file name.
22*e5dd7070Spatrick
23*e5dd7070Spatrick    Supported languages are {c, cpp, objc}.
24*e5dd7070Spatrick
25*e5dd7070Spatrick    all_warnings is a convenience argument to enable all compiler warnings.
26*e5dd7070Spatrick    """
27*e5dd7070Spatrick    args = list(flags)
28*e5dd7070Spatrick    name = 't.c'
29*e5dd7070Spatrick    if lang == 'cpp':
30*e5dd7070Spatrick        name = 't.cpp'
31*e5dd7070Spatrick        args.append('-std=c++11')
32*e5dd7070Spatrick    elif lang == 'objc':
33*e5dd7070Spatrick        name = 't.m'
34*e5dd7070Spatrick    elif lang != 'c':
35*e5dd7070Spatrick        raise Exception('Unknown language: %s' % lang)
36*e5dd7070Spatrick
37*e5dd7070Spatrick    if all_warnings:
38*e5dd7070Spatrick        args += ['-Wall', '-Wextra']
39*e5dd7070Spatrick
40*e5dd7070Spatrick    return TranslationUnit.from_source(name, args, unsaved_files=[(name,
41*e5dd7070Spatrick                                       source)])
42*e5dd7070Spatrick
43*e5dd7070Spatrickdef get_cursor(source, spelling):
44*e5dd7070Spatrick    """Obtain a cursor from a source object.
45*e5dd7070Spatrick
46*e5dd7070Spatrick    This provides a convenient search mechanism to find a cursor with specific
47*e5dd7070Spatrick    spelling within a source. The first argument can be either a
48*e5dd7070Spatrick    TranslationUnit or Cursor instance.
49*e5dd7070Spatrick
50*e5dd7070Spatrick    If the cursor is not found, None is returned.
51*e5dd7070Spatrick    """
52*e5dd7070Spatrick    # Convenience for calling on a TU.
53*e5dd7070Spatrick    root_cursor = source if isinstance(source, Cursor) else source.cursor
54*e5dd7070Spatrick
55*e5dd7070Spatrick    for cursor in root_cursor.walk_preorder():
56*e5dd7070Spatrick        if cursor.spelling == spelling:
57*e5dd7070Spatrick            return cursor
58*e5dd7070Spatrick
59*e5dd7070Spatrick    return None
60*e5dd7070Spatrick
61*e5dd7070Spatrickdef get_cursors(source, spelling):
62*e5dd7070Spatrick    """Obtain all cursors from a source object with a specific spelling.
63*e5dd7070Spatrick
64*e5dd7070Spatrick    This provides a convenient search mechanism to find all cursors with
65*e5dd7070Spatrick    specific spelling within a source. The first argument can be either a
66*e5dd7070Spatrick    TranslationUnit or Cursor instance.
67*e5dd7070Spatrick
68*e5dd7070Spatrick    If no cursors are found, an empty list is returned.
69*e5dd7070Spatrick    """
70*e5dd7070Spatrick    # Convenience for calling on a TU.
71*e5dd7070Spatrick    root_cursor = source if isinstance(source, Cursor) else source.cursor
72*e5dd7070Spatrick
73*e5dd7070Spatrick    cursors = []
74*e5dd7070Spatrick    for cursor in root_cursor.walk_preorder():
75*e5dd7070Spatrick        if cursor.spelling == spelling:
76*e5dd7070Spatrick            cursors.append(cursor)
77*e5dd7070Spatrick
78*e5dd7070Spatrick    return cursors
79*e5dd7070Spatrick
80*e5dd7070Spatrick
81*e5dd7070Spatrickskip_if_no_fspath = unittest.skipUnless(HAS_FSPATH,
82*e5dd7070Spatrick                                        "Requires file system path protocol / Python 3.6+")
83*e5dd7070Spatrick
84*e5dd7070Spatrick__all__ = [
85*e5dd7070Spatrick    'get_cursor',
86*e5dd7070Spatrick    'get_cursors',
87*e5dd7070Spatrick    'get_tu',
88*e5dd7070Spatrick    'skip_if_no_fspath',
89*e5dd7070Spatrick    'str_to_path',
90*e5dd7070Spatrick]
91