# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/.
# This modules provides functionality for dealing with code completion.
import os from collections import OrderedDict, defaultdict
import mozpack.path as mozpath
from mozbuild.backend.common import CommonBackend from mozbuild.frontend.data import (
ComputedFlags,
DirectoryTraversal,
PerSourceFlag,
Sources,
VariablePassthru,
) from mozbuild.shellutil import quote as shell_quote from mozbuild.util import expand_variables
class CompileDBBackend(CommonBackend): def _init(self):
CommonBackend._init(self)
# The database we're going to dump out to.
self._db = OrderedDict()
# The cache for per-directory flags
self._flags = {}
def consume_object(self, obj): # Those are difficult directories, that will be handled later. if obj.relsrcdir in ( "build/unix/elfhack", "build/unix/elfhack/inject", "build/clang-plugin", "build/clang-plugin/tests",
): returnTrue
if isinstance(obj, DirectoryTraversal):
self._envs[obj.objdir] = obj.config
elif isinstance(obj, Sources): # For other sources, include each source file. for f in obj.files:
self._build_db_line(
obj.objdir, obj.relsrcdir, obj.config, f, obj.canonical_suffix
)
elif isinstance(obj, VariablePassthru): for var in ("MOZBUILD_CMFLAGS", "MOZBUILD_CMMFLAGS"): if var in obj.variables:
self._local_flags[obj.objdir][var] = obj.variables[var]
for (directory, filename, unified), cmd in self._db.items():
env = self._envs[directory]
cmd = self._build_cmd(cmd, filename, unified)
variables = { "DIST": mozpath.join(env.topobjdir, "dist"), "DEPTH": env.topobjdir, "MOZILLA_DIR": env.topsrcdir, "topsrcdir": env.topsrcdir, "topobjdir": env.topobjdir,
}
variables.update(self._local_flags[directory])
c = [] for a in cmd:
accum = "" for word in expand_variables(a, variables).split(): # We can't just split() the output of expand_variables since # there can be spaces enclosed by quotes, e.g. '"foo bar"'. # Handle that case by checking whether there are an even # number of double-quotes in the word and appending it to # the accumulator if not. Meanwhile, shlex.split() and # mozbuild.shellutil.split() aren't able to properly handle # this and break in various ways, so we can't use something # off-the-shelf.
has_quote = bool(word.count('"') % 2) if accum and has_quote:
c.append(accum + " " + word)
accum = "" elif accum andnot has_quote:
accum += " " + word elifnot accum and has_quote:
accum = word else:
c.append(word) # Tell clangd to keep parsing to the end of a file, regardless of # how many errors are encountered. (Unified builds mean that we # encounter a lot of errors parsing some files.)
c.insert(-1, "-ferror-limit=0")
outputfile = self._outputfile_path() with self._write_file(outputfile) as jsonout:
json.dump(db, jsonout, indent=0)
def _outputfile_path(self): # Output the database (a JSON file) to objdir/compile_commands.json return os.path.join(self.environment.topobjdir, "compile_commands.json")
def _process_unified_sources_without_mapping(self, obj): for f in list(sorted(obj.files)):
self._build_db_line(
obj.objdir, obj.relsrcdir, obj.config, f, obj.canonical_suffix
)
# For unified sources, only include the unified source file. # Note that unified sources are never used for host sources. for f in obj.unified_source_mapping:
self._build_db_line(
obj.objdir, obj.relsrcdir, obj.config, f[0], obj.canonical_suffix
) for entry in f[1]:
self._build_db_line(
obj.objdir,
obj.relsrcdir,
obj.config,
entry,
obj.canonical_suffix,
unified=f[0],
)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.