Flutter Engine
The Flutter Engine
rewrite_includes.py
Go to the documentation of this file.
1#!/usr/bin/python
2#
3# Copyright 2019 Google Inc.
4#
5# Use of this source code is governed by a BSD-style license that can be
6# found in the LICENSE file.
7
8
9import argparse
10import os
11import sys
12
13from io import StringIO
14
15
16parser = argparse.ArgumentParser()
17parser.add_argument('-n', '--dry-run', action='store_true',
18 help='Just check there is nothing to rewrite.')
19parser.add_argument('sources', nargs='*',
20 help='Source files to rewrite, or all if empty.')
21args = parser.parse_args()
22
23roots = [
24 'bench',
25 'dm',
26 'docs',
27 'experimental',
28 'fuzz',
29 'gm',
30 'include',
31 'modules',
32 'platform_tools/android/apps',
33 'samplecode',
34 'src',
35 'tests',
36 'third_party/etc1',
37 'third_party/gif',
38 'tools'
39]
40
41ignorelist = [
42 # Don't count our local Vulkan headers as Skia headers;
43 # we don't want #include <vulkan/vulkan_foo.h> rewritten to point to them.
44 'include/third_party/vulkan',
45 # Some node_modules/ files (used by CanvasKit et al) have c++ code which we should ignore.
46 'node_modules',
47 'include/third_party/skcms',
48 'src/gpu/vk/vulkanmemoryallocator',
49 # Used by Jetski and Graphite
50 'Surface.h',
51 # Used by Ganesh and Graphite
52 'Device.h',
53 # Temporary shims
54 'GrGLMakeEGLInterface.h',
55 'GrGLMakeEpoxyEGLInterface.h',
56 'GrGLMakeGLXInterface.h',
57 # Transitional
58 'tools/window',
59]
60
61assert '/' in [os.sep, os.altsep]
62def fix_path(p):
63 return p.replace(os.sep, os.altsep) if os.altsep else p
64
65# Map short name -> absolute path for all Skia headers.
66headers = {}
67for root in roots:
68 for path, _, files in os.walk(root):
69 if not any(snippet in fix_path(path) for snippet in ignorelist):
70 for file_name in files:
71 if file_name.endswith('.h') and not file_name in ignorelist:
72 if file_name in headers:
73 message = ('Header filename is used more than once!\n- ' + path + '/' + file_name +
74 '\n- ' + headers[file_name])
75 assert file_name not in headers, message
76 headers[file_name] = os.path.abspath(os.path.join(path, file_name))
77
79 if args.sources:
80 for path in args.sources:
81 yield path
82 else:
83 for root in roots:
84 for path, _, files in os.walk(root):
85 for file_name in files:
86 yield os.path.join(path, file_name)
87
88# Rewrite any #includes relative to Skia's top-level directory.
89need_rewriting = []
90for file_path in to_rewrite():
91 if ('/generated/' in file_path or
92 'tests/sksl/' in file_path or
93 'third_party/skcms' in file_path or
94 'modules/skcms' in file_path or
95 # transitional
96 'jetski' in file_path or
97 'tools/window' in file_path or
98 file_path.startswith('bazel/rbe') or
99 'example/external_client/' in file_path or
100 # We intentionally list SkUserConfig.h not from the root in this file.
101 file_path == 'include/private/base/SkLoadUserConfig.h'):
102 continue
103 if (file_path.endswith('.h') or
104 file_path.endswith('.c') or
105 file_path.endswith('.m') or
106 file_path.endswith('.mm') or
107 file_path.endswith('.inc') or
108 file_path.endswith('.cc') or
109 file_path.endswith('.cpp')):
110 # Read the whole file into memory.
111 lines = open(file_path).readlines()
112
113 # Write it back out again line by line with substitutions for #includes.
114 output = StringIO() if args.dry_run else open(file_path, 'w')
115
116 includes = []
117 for line in lines:
118 parts = line.replace('<', '"').replace('>', '"').split('"')
119 if (len(parts) == 3
120 and '#' in parts[0]
121 and 'include' in parts[0]
122 and os.path.basename(parts[1]) in headers):
123 header = fix_path(os.path.relpath(headers[os.path.basename(parts[1])], '.'))
124 includes.append(parts[0] + '"%s"' % header + parts[2])
125 else:
126 # deduplicate includes in this block. If a file needs to be included
127 # multiple times, the separate includes should go in different blocks.
128 includes = sorted(list(set(includes)))
129 for inc in includes:
130 output.write(inc.strip('\n') + '\n')
131 includes = []
132 output.write(line.strip('\n') + '\n')
133 # Fix any straggling includes, e.g. in a file that only includes something else.
134 for inc in sorted(includes):
135 output.write(inc.strip('\n') + '\n')
136 if args.dry_run and output.getvalue() != open(file_path).read():
137 need_rewriting.append(file_path)
138 rc = 1
139 output.close()
140
141if need_rewriting:
142 print('Some files need rewritten #includes:')
143 for path in need_rewriting:
144 print('\t' + path)
145 print('To do this automatically, run')
146 print('python3 tools/rewrite_includes.py ' + ' '.join(need_rewriting))
147 sys.exit(1)
static bool read(SkStream *stream, void *buffer, size_t amount)
static void readlines(const void *data, size_t size, F f)
Definition: editor.cpp:30
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
Definition: switches.h:76
def print(*args, **kwargs)
Definition: run_tests.py:49
SIT bool any(const Vec< 1, T > &x)
Definition: SkVx.h:530
static SkString join(const CommandLineFlags::StringArray &)
Definition: skpbench.cpp:741