summaryrefslogtreecommitdiff
path: root/codegen/vulkan/scripts/spec_tools/macro_checker.py
diff options
context:
space:
mode:
Diffstat (limited to 'codegen/vulkan/scripts/spec_tools/macro_checker.py')
-rw-r--r--codegen/vulkan/scripts/spec_tools/macro_checker.py220
1 files changed, 0 insertions, 220 deletions
diff --git a/codegen/vulkan/scripts/spec_tools/macro_checker.py b/codegen/vulkan/scripts/spec_tools/macro_checker.py
deleted file mode 100644
index a8a75aa8..00000000
--- a/codegen/vulkan/scripts/spec_tools/macro_checker.py
+++ /dev/null
@@ -1,220 +0,0 @@
-"""Provides the MacroChecker class."""
-
-# Copyright (c) 2018-2019 Collabora, Ltd.
-#
-# SPDX-License-Identifier: Apache-2.0
-#
-# Author(s): Ryan Pavlik <ryan.pavlik@collabora.com>
-
-from io import StringIO
-import re
-
-
-class MacroChecker(object):
- """Perform and track checking of one or more files in an API spec.
-
- This does not necessarily need to be subclassed per-API: it is sufficiently
- parameterized in the constructor for expected usage.
- """
-
- def __init__(self, enabled_messages, entity_db,
- macro_checker_file_type, root_path):
- """Construct an object that tracks checking one or more files in an API spec.
-
- enabled_messages -- a set of MessageId that should be enabled.
- entity_db -- an object of a EntityDatabase subclass for this API.
- macro_checker_file_type -- Type to instantiate to create the right
- MacroCheckerFile subclass for this API.
- root_path -- A Path object for the root of this repository.
- """
- self.enabled_messages = enabled_messages
- self.entity_db = entity_db
- self.macro_checker_file_type = macro_checker_file_type
- self.root_path = root_path
-
- self.files = []
-
- self.refpages = set()
-
- # keys: entity names. values: MessageContext
- self.links = {}
- self.apiIncludes = {}
- self.validityIncludes = {}
- self.headings = {}
-
- # Regexes that are members because they depend on the name prefix.
-
- # apiPrefix, followed by some word characters or * as many times as desired,
- # NOT followed by >> and NOT preceded by one of the characters in that first character class.
- # (which distinguish "names being used somewhere other than prose").
- self.suspected_missing_macro_re = re.compile(
- r'\b(?<![-=:/[\.`+,])(?P<entity_name>{}[\w*]+)\b(?!>>)'.format(
- self.entity_db.case_insensitive_name_prefix_pattern)
- )
- self.heading_command_re = re.compile(
- r'=+ (?P<command>{}[\w]+)'.format(self.entity_db.name_prefix)
- )
-
- macros_pattern = '|'.join((re.escape(macro)
- for macro in self.entity_db.macros))
- # the "formatting" group is to strip matching */**/_/__
- # surrounding an entire macro.
- self.macro_re = re.compile(
- r'(?P<formatting>\**|_*)(?P<macro>{}):(?P<entity_name>[\w*]+((?P<subscript>[\[][^\]]*[\]]))?)(?P=formatting)'.format(macros_pattern))
-
- def haveLinkTarget(self, entity):
- """Report if we have parsed an API include (or heading) for an entity.
-
- None if there is no entity with that name.
- """
- if not self.findEntity(entity):
- return None
- if entity in self.apiIncludes:
- return True
- return entity in self.headings
-
- def hasFixes(self):
- """Report if any files have auto-fixes."""
- for f in self.files:
- if f.hasFixes():
- return True
- return False
-
- def addLinkToEntity(self, entity, context):
- """Record seeing a link to an entity's docs from a context."""
- if entity not in self.links:
- self.links[entity] = []
- self.links[entity].append(context)
-
- def seenRefPage(self, entity):
- """Check if a ref-page markup block has been seen for an entity."""
- return entity in self.refpages
-
- def addRefPage(self, entity):
- """Record seeing a ref-page markup block for an entity."""
- self.refpages.add(entity)
-
- def findMacroAndEntity(self, macro, entity):
- """Look up EntityData by macro and entity pair.
-
- Forwards to the EntityDatabase.
- """
- return self.entity_db.findMacroAndEntity(macro, entity)
-
- def findEntity(self, entity):
- """Look up EntityData by entity name (case-sensitive).
-
- Forwards to the EntityDatabase.
- """
- return self.entity_db.findEntity(entity)
-
- def findEntityCaseInsensitive(self, entity):
- """Look up EntityData by entity name (case-insensitive).
-
- Forwards to the EntityDatabase.
- """
- return self.entity_db.findEntityCaseInsensitive(entity)
-
- def getMemberNames(self, commandOrStruct):
- """Given a command or struct name, retrieve the names of each member/param.
-
- Returns an empty list if the entity is not found or doesn't have members/params.
-
- Forwards to the EntityDatabase.
- """
- return self.entity_db.getMemberNames(commandOrStruct)
-
- def likelyRecognizedEntity(self, entity_name):
- """Guess (based on name prefix alone) if an entity is likely to be recognized.
-
- Forwards to the EntityDatabase.
- """
- return self.entity_db.likelyRecognizedEntity(entity_name)
-
- def isLinkedMacro(self, macro):
- """Identify if a macro is considered a "linked" macro.
-
- Forwards to the EntityDatabase.
- """
- return self.entity_db.isLinkedMacro(macro)
-
- def processFile(self, filename):
- """Parse an .adoc file belonging to the spec and check it for errors."""
- class FileStreamMaker(object):
- def __init__(self, filename):
- self.filename = filename
-
- def make_stream(self):
- return open(self.filename, 'r', encoding='utf-8')
-
- f = self.macro_checker_file_type(self, filename, self.enabled_messages,
- FileStreamMaker(filename))
- f.process()
- self.files.append(f)
-
- def processString(self, s):
- """Process a string as if it were a spec file.
-
- Used for testing purposes.
- """
- if "\n" in s.rstrip():
- # remove leading spaces from each line to allow easier
- # block-quoting in tests
- s = "\n".join((line.lstrip() for line in s.split("\n")))
- # fabricate a "filename" that will display better.
- filename = "string{}\n****START OF STRING****\n{}\n****END OF STRING****\n".format(
- len(self.files), s.rstrip())
-
- else:
- filename = "string{}: {}".format(
- len(self.files), s.rstrip())
-
- class StringStreamMaker(object):
- def __init__(self, string):
- self.string = string
-
- def make_stream(self):
- return StringIO(self.string)
-
- f = self.macro_checker_file_type(self, filename, self.enabled_messages,
- StringStreamMaker(s))
- f.process()
- self.files.append(f)
- return f
-
- def numDiagnostics(self):
- """Return the total number of diagnostics (warnings and errors) over all the files processed."""
- return sum((f.numDiagnostics() for f in self.files))
-
- def numErrors(self):
- """Return the total number of errors over all the files processed."""
- return sum((f.numErrors() for f in self.files))
-
- def getMissingUnreferencedApiIncludes(self):
- """Return the unreferenced entity names that we expected to see an API include or link target for, but did not.
-
- Counterpart to getBrokenLinks(): This method returns the entity names
- that were not used in a linking macro (and thus wouldn't create a broken link),
- but were nevertheless expected and not seen.
- """
- return (entity for entity in self.entity_db.generating_entities
- if (not self.haveLinkTarget(entity)) and entity not in self.links)
-
- def getBrokenLinks(self):
- """Return the entity names and usage contexts that we expected to see an API include or link target for, but did not.
-
- Counterpart to getMissingUnreferencedApiIncludes(): This method returns only the
- entity names that were used in a linking macro (and thus create a broken link),
- but were not seen. The values of the dictionary are a list of MessageContext objects
- for each linking macro usage for this entity name.
- """
- return {entity: contexts for entity, contexts in self.links.items()
- if self.entity_db.entityGenerates(entity) and not self.haveLinkTarget(entity)}
-
- def getMissingRefPages(self):
- """Return a list of entities that we expected, but did not see, a ref page block for.
-
- The heuristics here are rather crude: we expect a ref page for every generating entry.
- """
- return (entity for entity in sorted(self.entity_db.generating_entities)
- if entity not in self.refpages)