|  | #!/usr/bin/env python3 | 
|  | # | 
|  | # Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file | 
|  | # for details. All rights reserved. Use of this source code is governed by a | 
|  | # BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | # Simple tool for verifying that sources from the standalone embedder do not | 
|  | # directly include sources from the VM or vice versa. | 
|  |  | 
|  | import os | 
|  | import re | 
|  | import sys | 
|  |  | 
|  | INCLUDE_DIRECTIVE_RE = re.compile(r'^#include "(.*)"') | 
|  |  | 
|  | PLATFORM_LAYER_RE = re.compile(r'^runtime/platform/') | 
|  | VM_LAYER_RE = re.compile(r'^runtime/(vm|lib)/') | 
|  | BIN_LAYER_RE = re.compile(r'^runtime/bin/') | 
|  |  | 
|  | # Tests that don't match the simple case of *_test.cc. | 
|  | EXTRA_TEST_FILES = [ | 
|  | 'runtime/bin/run_vm_tests.cc', | 
|  | 'runtime/bin/ffi_unit_test/run_ffi_unit_tests.cc', | 
|  | 'runtime/vm/libfuzzer/dart_libfuzzer.cc' | 
|  | ] | 
|  |  | 
|  |  | 
|  | def CheckFile(sdk_root, path): | 
|  | includes = set() | 
|  | with open(os.path.join(sdk_root, path), encoding='utf-8') as file: | 
|  | for line in file: | 
|  | m = INCLUDE_DIRECTIVE_RE.match(line) | 
|  | if m is not None: | 
|  | header = os.path.join('runtime', m.group(1)) | 
|  | if os.path.isfile(os.path.join(sdk_root, header)): | 
|  | includes.add(header) | 
|  |  | 
|  | errors = [] | 
|  | for include in includes: | 
|  | if PLATFORM_LAYER_RE.match(path): | 
|  | if VM_LAYER_RE.match(include): | 
|  | errors.append( | 
|  | 'LAYERING ERROR: %s must not include %s' % (path, include)) | 
|  | elif BIN_LAYER_RE.match(include): | 
|  | errors.append( | 
|  | 'LAYERING ERROR: %s must not include %s' % (path, include)) | 
|  | elif VM_LAYER_RE.match(path): | 
|  | if BIN_LAYER_RE.match(include): | 
|  | errors.append( | 
|  | 'LAYERING ERROR: %s must not include %s' % (path, include)) | 
|  | elif BIN_LAYER_RE.match(path): | 
|  | if VM_LAYER_RE.match(include): | 
|  | errors.append( | 
|  | 'LAYERING ERROR: %s must not include %s' % (path, include)) | 
|  | return errors | 
|  |  | 
|  |  | 
|  | def CheckDir(sdk_root, dir): | 
|  | errors = [] | 
|  | for file in os.listdir(dir): | 
|  | path = os.path.join(dir, file) | 
|  | if os.path.isdir(path): | 
|  | errors += CheckDir(sdk_root, path) | 
|  | elif path.endswith('test.cc') or path in EXTRA_TEST_FILES: | 
|  | None  # Tests may violate layering. | 
|  | elif path.endswith('.cc') or path.endswith('.h'): | 
|  | errors += CheckFile(sdk_root, os.path.relpath(path, sdk_root)) | 
|  | return errors | 
|  |  | 
|  |  | 
|  | def DoCheck(sdk_root): | 
|  | return CheckDir(sdk_root, 'runtime') | 
|  |  | 
|  |  | 
|  | if __name__ == '__main__': | 
|  | errors = DoCheck('.') | 
|  | print('\n'.join(errors)) | 
|  | if errors: | 
|  | sys.exit(-1) |