meson: Only perform macos checks on macos
[geany-mirror.git] / scripts / create_php_tags.py
blobbee996fd47694683e71004e73e30239508f66644
1 #!/usr/bin/env python3
3 # Author: Enrico Tröger
4 # License: GPL v2 or later
6 # This script downloads the PHP tag definitions in JSON format from
7 # http://doc.php.net/downloads/json/php_manual_en.json.
8 # From those defintions all function tags are extracted and written
9 # to ../data/tags/std.php.tags (relative to the script's location, not $CWD).
11 import re
12 import sys
13 from json import loads
14 from os.path import dirname, join
15 from urllib.request import urlopen
17 from create_tags_helper import format_tag, write_ctags_file
19 UPSTREAM_TAG_DEFINITION = 'http://doc.php.net/downloads/json/php_manual_en.json'
20 PROTOTYPE_RE = r'^(?P<return_type>.*) {tag_name}(?P<arg_list>\(.*\))$'
22 # (from src/tagmanager/tm_tag.c:90)
23 TA_NAME = 200
24 TA_TYPE = 204
25 TA_ARGLIST = 205
26 TA_SCOPE = 206
27 TA_VARTYPE = 207
29 # PHP kinds
30 KIND_CLASS = 'class'
31 KIND_FUNCTION = 'function'
32 KIND_VARIABLE = 'variable'
35 def normalize_name(name):
36 """ Replace namespace separator with class separators, as Geany only
37 understands the latter """
38 return name.replace('\\', '::')
41 def split_scope(name):
42 """ Splits the scope from the member, and returns (scope, member).
43 Returned scope is None if the name is not a member """
44 name = normalize_name(name)
45 sep_pos = name.rfind('::')
46 if sep_pos < 0:
47 return None, name
48 else:
49 return name[:sep_pos], name[sep_pos + 2:]
52 def parse_and_create_php_tags_file():
53 # download upstream definition
54 response = urlopen(UPSTREAM_TAG_DEFINITION)
55 try:
56 html = response.read()
57 finally:
58 response.close()
60 # parse JSON
61 definitions = loads(html)
63 # generate tags
64 tag_list = []
65 for tag_name, tag_definition in definitions.items():
66 prototype_re = PROTOTYPE_RE.format(tag_name=re.escape(tag_name))
67 match = re.match(prototype_re, tag_definition['prototype'])
68 if match:
69 return_type = normalize_name(match.group('return_type'))
70 arg_list = match.group('arg_list')
72 scope, tag_name = split_scope(tag_name)
73 if tag_name[0] == '$':
74 kind = KIND_VARIABLE
75 else:
76 kind = KIND_FUNCTION
78 tag_list.append(format_tag(tag_name, kind, arg_list, scope, ('unknown', return_type)))
79 # Also create a class tag when encountering a __construct()
80 if tag_name == '__construct' and scope is not None:
81 scope, tag_name = split_scope(scope)
82 tag_list.append(format_tag(tag_name, KIND_CLASS, arg_list, scope or ''))
84 # write tags
85 script_dir = dirname(__file__)
86 filename = join(script_dir, '..', 'data', 'tags', 'std.php.tags')
87 write_ctags_file(filename, tag_list, sys.argv[0])
88 print(f'Created: {filename} with {len(tag_list)} tags')
91 if __name__ == '__main__':
92 parse_and_create_php_tags_file()