def test(parse_builtins): # type: (...) -> None root = tempfile.mkdtemp() server = DummyServer(Path(root)) with tempfile.NamedTemporaryFile(suffix=".vhd") as filename: diags = server.getMessagesWithText( Path(filename.name), "library lib; use lib.pkg.all; library builtin; use builtin.foo;", ) parse_builtins.assert_called() logIterable("Diags", diags, _logger.info) it.assertCountEqual( diags, [ UnresolvedDependency( RequiredDesignUnit( name=Identifier("pkg"), library=Identifier("lib"), owner=Path(filename.name), locations=[Location(0, 17)], ), Location(0, 17), ) ], )
def test(): path = _Path(TEST_PROJECT, "another_library", "foo.vhd") numeric_std = RequiredDesignUnit( name=Identifier("numeric_std"), library=Identifier("ieee"), owner=path, locations=(), ) it.assertIs(it.project.resolveDependencyToPath(numeric_std), None)
def test_DependencyInfoForPathNotFound(self): path = Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")) dependency = RequiredDesignUnit( name=Identifier("clock_divider"), library=Identifier("basic_library"), owner=path, locations=(), ) self.assertEqual( self.server._getDependencyInfoForHover(dependency), "Couldn't find a source defining 'basic_library.clock_divider'", )
def test_ReportDependencyInfo(self): path = Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")) dependency = RequiredDesignUnit( name=Identifier("clock_divider"), library=Identifier("basic_library"), owner=path, locations=(), ) self.assertEqual( self.server._getDependencyInfoForHover(dependency), 'Path "some_path", library "some_library"', )
def test(): path = _Path(TEST_PROJECT, "basic_library", "package_with_functions.vhd") clock_divider = RequiredDesignUnit( name=Identifier("package_with_functions"), library=Identifier("basic_library"), owner=path, locations=(), ) it.assertEqual( it.project.resolveDependencyToPath(clock_divider), (path, Identifier("basic_library")), )
def getLibrary(self, path): # type: (Path) -> UnresolvedLibrary """ Gets the library the path is in, inferring and updating it if needed. Any unit that can be used from VHDL code can be bound to a library, even if Verilog and SystemVerilog don't have this concept. """ self._parseSourceIfNeeded(path) if path not in self.paths: # Add the path to the project but put it on a different library self._parseSourceIfNeeded(path) self._updatePathLibrary(path, Identifier("not_in_project", True)) # Report paths that are valid (that is, not temporary) when they # can't be found in the project file if not isinstance(path, TemporaryPath): self._addDiagnostic(PathNotInProjectFile(path)) elif path not in self._library_map: # Library is not defined, try to infer _logger.info("Library for '%s' not set, inferring it", path) library = self._inferLibraryForPath(path) if library is not None: self._updatePathLibrary(path, library) return self._library_map.get(path, None)
def addSource(self, path, library, single_flags=None, dependencies_flags=None): # type: (Path, Optional[str], Optional[BuildFlags], Optional[BuildFlags]) -> None """ Adds a source to the database, triggering its parsing even if the source has already been added previously """ _logger.info( "Adding %s, library=%s, flags=(single=%s, dependencies=%s)", path, library, single_flags, dependencies_flags, ) self._paths.add(path) self._flags_map[path] = { BuildFlagScope.single: tuple(single_flags or ()), BuildFlagScope.dependencies: tuple(dependencies_flags or ()), } if library is not None: self._library_map[path] = Identifier( library, case_sensitive=FileType.fromPath(path) != FileType.vhdl ) # TODO: Parse on a process pool self._parseSource(path)
def test(): path = _Path(TEST_PROJECT, "another_library", "foo.vhd") clock_divider = RequiredDesignUnit( name=Identifier("clock_divider"), library=Identifier("basic_library"), owner=path, locations=(), ) it.assertEqual( it.project.resolveDependencyToPath(clock_divider), ( _Path(TEST_PROJECT, "basic_library", "clock_divider.vhd"), Identifier("basic_library"), ), )
def __init__( self, design_units, # type: Iterable[Dict[str, str]] library=None, # type: str dependencies=None, # type: Iterable[MockDep] filename=None, # type: Optional[str] ): self._design_units = list(design_units or []) if filename is not None: self._filename = Path(p.join(self.base_path, filename)) else: library = "lib_not_set" if library is None else library self._filename = Path( p.join( self.base_path, library, "_{}.vhd".format(self._design_units[0]["name"]), )) self.filetype = FileType.fromPath(self.filename) # self.abspath = p.abspath(self.filename) self.flags = [] # type: ignore self.library = library self._dependencies = [] # type: List[RequiredDesignUnit] for dep_spec in dependencies or []: _name = dep_spec[0] _library = "work" try: _library, _name = dep_spec # type: ignore except ValueError: pass self._dependencies.append( RequiredDesignUnit( self._filename, Identifier(_name, False), Identifier(_library, False), )) self._createMockFile()
def test_GetRebuilds(self, rebuild_info, expected): # type: (...) -> Any _logger.info("Rebuild info is %s", rebuild_info) library = Identifier("some_lib", False) with patch.object(self.builder, "_searchForRebuilds", return_value=[rebuild_info]): self.builder._database.getDependenciesByPath = MagicMock( return_value=[ RequiredDesignUnit( owner=Path(""), name=Identifier("very_common_pkg"), library=Identifier("work"), ) ]) self.assertCountEqual( self.builder._getRebuilds(_source("source.vhd"), "", library), {expected}, )
def _parseBuiltinLibraries(self): "(Not used by XVHDL)" return (Identifier(x, case_sensitive=False) for x in ( "ieee", "std", "unisim", "xilinxcorelib", "synplify", "synopsis", "maxii", "family_support", ))
def _getRebuilds(self, path, line, library): # type: (Path, str, Identifier) -> Set[RebuildInfo] """ Gets info on what should be rebuilt to satisfy the builder """ try: parse_results = self._searchForRebuilds(line) except NotImplementedError: # pragma: no cover return set() rebuilds = set() # type: Set[RebuildInfo] for rebuild in parse_results: unit_type = rebuild.get("unit_type", None) # type: str library_name = rebuild.get("library_name", None) # type: str unit_name = rebuild.get("unit_name", None) # type: str rebuild_path = rebuild.get("rebuild_path", None) # type: str if None not in (unit_type, unit_name): for dependency in self._database.getDependenciesByPath(path): if dependency.name.name == rebuild["unit_name"]: rebuilds.add( RebuildUnit(Identifier(unit_name), DesignUnitType(unit_type))) break elif None not in (library_name, unit_name): if library_name == "work": library_name = library.name rebuilds.add( RebuildLibraryUnit(Identifier(unit_name), Identifier(library_name))) elif rebuild_path is not None: # GHDL sometimes gives the full path of the file that # should be recompiled rebuilds.add(RebuildPath(Path(rebuild_path))) else: # pragma: no cover self._logger.warning("Don't know what to do with %s", rebuild) return rebuilds
def test_VhdlCompilation(self, *args): # type: (...) -> Any if FileType.vhdl not in self.builder.file_types: raise unittest2.SkipTest("Builder {} doesn't support VHDL".format( self.builder_name)) source = _source("no_messages.vhd") records, rebuilds = self.builder.build(source, Identifier("work"), BuildFlagScope.single) self.assertNotIn( DiagType.ERROR, [x.severity for x in records], "This source should not generate errors.", ) self.assertFalse(rebuilds)
def getVunitSources(builder): # type: (AnyValidBuilder) -> Iterable[Tuple[Path, Optional[str], BuildFlags]] "Gets VUnit sources according to the file types supported by builder" if not foundVunit(): return _logger.debug("VUnit installation found") sources = [] # type: List[vunit.source_file.SourceFile] # Prefer VHDL VUnit if FileType.vhdl in builder.file_types: sources += _getSourcesFromVUnitModule(VUnit_VHDL) _logger.debug("Added VUnit VHDL files") if FileType.systemverilog in builder.file_types: _logger.debug("Builder supports Verilog, adding VUnit Verilog files") builder.addExternalLibrary(FileType.verilog, Identifier("vunit_lib", False)) sources += _getSourcesFromVUnitModule(VUnit_Verilog) if not sources: _logger.info("Vunit found but no file types are supported by %s", builder) return for source in sources: path = p.abspath(source.name) library = source.library.name # Get extra flags for building VUnit sources try: flags = _VUNIT_FLAGS[BuilderName( builder.builder_name)][source.vhdl_standard] except KeyError: flags = tuple() yield Path(path), library, flags if FileType.systemverilog in builder.file_types: for path in findRtlSourcesByPath(Path(p.dirname(vunit.__file__))): if _isHeader(path): yield Path(path), None, ()
def _buildAndGetDiagnostics( self, path, library, flags ): # type: (Path, Identifier, BuildFlags) -> Tuple[Set[CheckerDiagnostic],Set[RebuildInfo]] """ Runs _buildSource method and parses the output to find message records and units that should be rebuilt """ if library is None: library = self._database.getLibrary(path) # or Identifier("work") self._createLibraryIfNeeded(library) for lib in (x.library for x in self._database.getDependenciesByPath(path)): self._createLibraryIfNeeded(lib or Identifier("work")) diagnostics = set() # type: Set[CheckerDiagnostic] rebuilds = set() # type: Set[RebuildInfo] for line in self._buildSource(path, library, flags=flags): if self._shouldIgnoreLine(line): continue for record in self._makeRecords(line): try: # If no filename is set, assume it's for the current path if record.filename is None: diagnostics.add(record.copy(filename=path)) else: diagnostics.add(record) except: self._logger.exception( " - %s hash: %s | %s", record, record.__hash__, type(record).__mro__, ) raise rebuilds |= self._getRebuilds(path, line, library) self._logBuildResults(diagnostics, rebuilds) return diagnostics, rebuilds
def _parseBuiltinLibraries(self): # type: (...) -> Any """ Discovers libraries that exist regardless before we do anything """ for line in runShellCommand(["ghdl", "--dispconfig"]): library_path_match = self._scan_library_paths.search(line) if library_path_match: library_path = library_path_match.groupdict()["library_path"] self._logger.debug("library path is %s", library_path) # Up to v0.36 ghdl kept libraries at # <library_path>/<vhdl starndard>/<name> # but his has been changed to # <library_path>/<name>/<vhdl starndard> libraries_paths = glob( p.join(library_path, "v93", "*") if self._version < "0.36" else p.join(library_path, "*") ) for path in filter(p.isdir, libraries_paths): name = path.split(p.sep)[-1] yield Identifier(name.strip(), case_sensitive=False)
def test_CreateLibraryMultipleTimes(self): # pylint: disable=invalid-name # type: (...) -> Any self.builder._createLibraryIfNeeded(Identifier("random_lib")) self.builder._createLibraryIfNeeded(Identifier("random_lib"))
def builtin_libraries(_): return (Identifier("ieee"), )
class TestValidProject(TestCase): params = { "rootUri": uris.from_fs_path(TEST_PROJECT), "initializationOptions": {"project_file": "config.json"}, } def setUp(self): setupTestSuport(TEST_TEMP_PATH) _logger.debug("Creating server") tx_r, tx_w = os.pipe() self.tx_stream_reader = JsonRpcStreamReader(os.fdopen(tx_r, "rb")) rx_stream = MagicMock() rx_stream.closed = False self.server = lsp.HdlCheckerLanguageServer(rx_stream, os.fdopen(tx_w, "wb")) # Initialize server _logger.info("Calling m_initialize") self.assertEqual( self.server.m_initialize(**(self.params or {})), { "capabilities": { "textDocumentSync": 1, "definitionProvider": True, "hoverProvider": True, "referencesProvider": True, } }, ) _logger.info("Calling m_initialized") with patch("hdl_checker.lsp.onNewReleaseFound"): self.assertIsNone(self.server.m_initialized()) def teardown(self): _logger.debug("Shutting down server") msg = LSP_MSG_TEMPLATE.copy() msg.update({"method": "exit"}) self.server._endpoint.consume(msg) # Close the pipe from the server to stdout and empty any pending # messages self.tx_stream_reader.close() self.tx_stream_reader.listen(_logger.fatal) del self.server def _checkLintFileOnOpen(self, source): return self._checkLintFileOnMethod(source, "m_text_document__did_open") def _checkLintFileOnSave(self, source): return self._checkLintFileOnMethod(source, "m_text_document__did_save") def _checkLintFileOnMethod(self, source, method): with patch.object(self.server.workspace, "publish_diagnostics"): _logger.info("Sending %s request", method) getattr(self.server, method)( textDocument={"uri": unicode(uris.from_fs_path(source)), "text": None} ) mock_call = _waitOnMockCall(self.server.workspace.publish_diagnostics) doc_uri, diagnostics = mock_call[1] _logger.info("doc_uri: %s", doc_uri) _logger.info("diagnostics: %s", diagnostics) self.assertEqual(doc_uri, uris.from_fs_path(source)) return diagnostics def test_LintFileOnOpening(self): source = p.join(TEST_PROJECT, "basic_library", "clk_en_generator.vhd") with patch( "hdl_checker.lsp.Server.getMessagesByPath", return_value=[CheckerDiagnostic(filename=Path(source), text="some text")], ) as meth: self.assertCountEqual( self._checkLintFileOnOpen(source), [lsp.checkerDiagToLspDict(CheckerDiagnostic(text="some text"))], ) meth.assert_called_once_with(Path(source)) def runTestBuildSequenceTable(self, tablefmt): very_common_pkg = Path( p.join(TEST_PROJECT, "basic_library", "very_common_pkg.vhd") ) clk_en_generator = Path( p.join(TEST_PROJECT, "basic_library", "clk_en_generator.vhd") ) expected = [ "Build sequence for %s is" % str(clk_en_generator), "", tabulate( [ (1, "basic_library", str(very_common_pkg)), (2, DEFAULT_LIBRARY.name, str(clk_en_generator)), ], headers=("#", "Library", "Path"), tablefmt=tablefmt, ), ] self.assertEqual( self.server._getBuildSequenceForHover(clk_en_generator), "\n".join(expected) ) @patch("hdl_checker.lsp.HdlCheckerLanguageServer._use_markdown_for_hover", 0) @patch( "hdl_checker.builders.base_builder.BaseBuilder.builtin_libraries", (Identifier("ieee"),), ) def test_ReportBuildSequencePlain(self): self.runTestBuildSequenceTable(tablefmt="plain") @patch("hdl_checker.lsp.HdlCheckerLanguageServer._use_markdown_for_hover", 1) @patch( "hdl_checker.builders.base_builder.BaseBuilder.builtin_libraries", (Identifier("ieee"),), ) def test_ReportBuildSequenceMarkdown(self): self.runTestBuildSequenceTable(tablefmt="github") @patch.object( hdl_checker.base_server.BaseServer, "resolveDependencyToPath", lambda self, _: None, ) def test_DependencyInfoForPathNotFound(self): path = Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")) dependency = RequiredDesignUnit( name=Identifier("clock_divider"), library=Identifier("basic_library"), owner=path, locations=(), ) self.assertEqual( self.server._getDependencyInfoForHover(dependency), "Couldn't find a source defining 'basic_library.clock_divider'", ) @patch.object( hdl_checker.base_server.BaseServer, "resolveDependencyToPath", lambda self, _: (Path("some_path"), Identifier("some_library")), ) def test_ReportDependencyInfo(self): path = Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")) dependency = RequiredDesignUnit( name=Identifier("clock_divider"), library=Identifier("basic_library"), owner=path, locations=(), ) self.assertEqual( self.server._getDependencyInfoForHover(dependency), 'Path "some_path", library "some_library"', ) def test_ReportDesignUnitAccordingToPosition(self): UNIT_A = VhdlDesignUnit( owner=Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")), type_=DesignUnitType.entity, name="unit_a", locations=(Location(line=1, column=2), Location(line=3, column=4)), ) UNIT_B = VerilogDesignUnit( owner=Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")), type_=DesignUnitType.package, name="unit_b", locations=(Location(line=5, column=6), Location(line=7, column=8)), ) DEP_A = RequiredDesignUnit( name=Identifier("dep_a"), library=Identifier("lib_a"), owner=Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")), locations=(Location(line=9, column=10), Location(line=11, column=12)), ) DEP_B = RequiredDesignUnit( name=Identifier("dep_a"), library=Identifier("lib_a"), owner=Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")), locations=(Location(line=13, column=14), Location(line=15, column=16)), ) def getDesignUnitsByPath(self, path): # pylint: disable=unused-argument if path != Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")): it.fail("Expected foo.vhd but got %s" % path) return {UNIT_A, UNIT_B} def getDependenciesByPath(self, path): # pylint: disable=unused-argument if path != Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")): it.fail("Expected foo.vhd but got %s" % path) return {DEP_A, DEP_B} patches = ( patch.object( hdl_checker.database.Database, "getDesignUnitsByPath", getDesignUnitsByPath, ), patch.object( hdl_checker.database.Database, "getDependenciesByPath", getDependenciesByPath, ), ) path = Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")) for _patch in patches: _patch.start() # Check locations outside return nothing self.assertIsNone(self.server._getElementAtPosition(path, Location(0, 0))) # Check design units are found, ensure boundaries match self.assertIsNone(self.server._getElementAtPosition(path, Location(1, 1))) self.assertIs(self.server._getElementAtPosition(path, Location(1, 2)), UNIT_A) self.assertIs(self.server._getElementAtPosition(path, Location(1, 7)), UNIT_A) self.assertIsNone(self.server._getElementAtPosition(path, Location(1, 8))) self.assertIsNone(self.server._getElementAtPosition(path, Location(3, 3))) self.assertIs(self.server._getElementAtPosition(path, Location(3, 4)), UNIT_A) self.assertIs(self.server._getElementAtPosition(path, Location(3, 9)), UNIT_A) self.assertIsNone(self.server._getElementAtPosition(path, Location(3, 10))) self.assertIsNone(self.server._getElementAtPosition(path, Location(5, 5))) self.assertIs(self.server._getElementAtPosition(path, Location(5, 6)), UNIT_B) self.assertIs(self.server._getElementAtPosition(path, Location(5, 11)), UNIT_B) self.assertIsNone(self.server._getElementAtPosition(path, Location(5, 12))) self.assertIsNone(self.server._getElementAtPosition(path, Location(7, 7))) self.assertIs(self.server._getElementAtPosition(path, Location(7, 8)), UNIT_B) self.assertIs(self.server._getElementAtPosition(path, Location(7, 13)), UNIT_B) self.assertIsNone(self.server._getElementAtPosition(path, Location(7, 14))) # Now check dependencies self.assertIsNone(self.server._getElementAtPosition(path, Location(9, 9))) self.assertIs(self.server._getElementAtPosition(path, Location(9, 10)), DEP_A) self.assertIs(self.server._getElementAtPosition(path, Location(9, 20)), DEP_A) self.assertIsNone(self.server._getElementAtPosition(path, Location(9, 21))) self.assertIsNone(self.server._getElementAtPosition(path, Location(11, 11))) self.assertIs(self.server._getElementAtPosition(path, Location(11, 12)), DEP_A) self.assertIs(self.server._getElementAtPosition(path, Location(11, 22)), DEP_A) self.assertIsNone(self.server._getElementAtPosition(path, Location(11, 23))) self.assertIsNone(self.server._getElementAtPosition(path, Location(13, 13))) self.assertIs(self.server._getElementAtPosition(path, Location(13, 14)), DEP_B) self.assertIs(self.server._getElementAtPosition(path, Location(13, 24)), DEP_B) self.assertIsNone(self.server._getElementAtPosition(path, Location(13, 25))) self.assertIsNone(self.server._getElementAtPosition(path, Location(15, 15))) self.assertIs(self.server._getElementAtPosition(path, Location(15, 16)), DEP_B) self.assertIs(self.server._getElementAtPosition(path, Location(15, 26)), DEP_B) self.assertIsNone(self.server._getElementAtPosition(path, Location(15, 27))) for _patch in patches: _patch.stop() @patch( "hdl_checker.builders.base_builder.BaseBuilder.builtin_libraries", (Identifier("ieee"),), ) def test_HoverOnInvalidRange(self): path = p.join(TEST_PROJECT, "another_library", "foo.vhd") self.assertIsNone( self.server.hover(uris.from_fs_path(path), {"line": 0, "character": 0}) ) @patch( "hdl_checker.builders.base_builder.BaseBuilder.builtin_libraries", (Identifier("ieee"),), ) def test_HoverOnDesignUnit(self): path_to_foo = p.join(TEST_PROJECT, "another_library", "foo.vhd") very_common_pkg = p.join(TEST_PROJECT, "basic_library", "very_common_pkg.vhd") package_with_constants = p.join( TEST_PROJECT, "basic_library", "package_with_constants.vhd" ) clock_divider = p.join(TEST_PROJECT, "basic_library", "clock_divider.vhd") expected = [ "Build sequence for %s is" % str(path_to_foo), "", tabulate( [ (1, "basic_library", str(very_common_pkg)), (2, "basic_library", str(package_with_constants)), (3, "basic_library", str(clock_divider)), (4, DEFAULT_LIBRARY.name, str(path_to_foo)), ], headers=("#", "Library", "Path"), tablefmt="plain", ), ] self.assertDictEqual( self.server.hover( uris.from_fs_path(path_to_foo), {"line": 7, "character": 7} ), {"contents": "\n".join(expected)}, ) @patch( "hdl_checker.builders.base_builder.BaseBuilder.builtin_libraries", (Identifier("ieee"),), ) def test_HoverOnDependency(self): path_to_foo = p.join(TEST_PROJECT, "another_library", "foo.vhd") clock_divider = p.join(TEST_PROJECT, "basic_library", "clock_divider.vhd") self.assertDictEqual( self.server.hover( uris.from_fs_path(path_to_foo), {"line": 32, "character": 32} ), {"contents": 'Path "%s", library "basic_library"' % clock_divider}, ) @patch( "hdl_checker.builders.base_builder.BaseBuilder.builtin_libraries", (Identifier("ieee"),), ) def test_GetDefinitionMatchingDependency(self): source = p.join(TEST_PROJECT, "basic_library", "use_entity_a_and_b.vhd") target = p.join(TEST_PROJECT, "basic_library", "two_entities_one_file.vhd") definitions = self.server.definitions( uris.from_fs_path(source), {"line": 1, "character": 9} ) self.assertIn( { "uri": uris.from_fs_path(target), "range": { "start": {"line": 1, "character": 7}, "end": {"line": 1, "character": 15}, }, }, definitions, ) self.assertIn( { "uri": uris.from_fs_path(target), "range": { "start": {"line": 4, "character": 7}, "end": {"line": 4, "character": 15}, }, }, definitions, ) @patch( "hdl_checker.builders.base_builder.BaseBuilder.builtin_libraries", (Identifier("ieee"),), ) def test_GetDefinitionBuiltInLibrary(self): path_to_foo = p.join(TEST_PROJECT, "another_library", "foo.vhd") self.assertEqual( self.server.definitions( uris.from_fs_path(path_to_foo), {"line": 3, "character": 15} ), [], ) @patch( "hdl_checker.builders.base_builder.BaseBuilder.builtin_libraries", (Identifier("ieee"),), ) def test_GetDefinitionNotKnown(self): path_to_foo = p.join(TEST_PROJECT, "another_library", "foo.vhd") self.assertEqual( self.server.definitions( uris.from_fs_path(path_to_foo), {"line": 0, "character": 0} ), [], ) @patch.object( hdl_checker.database.Database, "getReferencesToDesignUnit", return_value=[ RequiredDesignUnit( name=Identifier("clock_divider"), library=Identifier("basic_library"), owner=Path("some_path"), locations=(Location(1, 2), Location(3, 4)), ) ], ) def test_ReferencesOfAValidElement(self, get_references): path_to_foo = p.join(TEST_PROJECT, "another_library", "foo.vhd") # Make sure we picked up an existing element unit = self.server._getElementAtPosition(Path(path_to_foo), Location(7, 7)) self.assertIsNotNone(unit) self.assertCountEqual( self.server.references( doc_uri=uris.from_fs_path(path_to_foo), position={"line": 7, "character": 7}, exclude_declaration=True, ), ( { "uri": uris.from_fs_path("some_path"), "range": { "start": {"line": 1, "character": 2}, "end": {"line": 1, "character": 2}, }, }, { "uri": uris.from_fs_path("some_path"), "range": { "start": {"line": 3, "character": 4}, "end": {"line": 3, "character": 4}, }, }, ), ) get_references.assert_called_once() get_references.reset_mock() self.assertCountEqual( self.server.references( doc_uri=uris.from_fs_path(path_to_foo), position={"line": 7, "character": 7}, exclude_declaration=False, ), ( { "uri": uris.from_fs_path(path_to_foo), "range": { "start": {"line": 7, "character": 7}, "end": {"line": 7, "character": 7}, }, }, { "uri": uris.from_fs_path("some_path"), "range": { "start": {"line": 1, "character": 2}, "end": {"line": 1, "character": 2}, }, }, { "uri": uris.from_fs_path("some_path"), "range": { "start": {"line": 3, "character": 4}, "end": {"line": 3, "character": 4}, }, }, ), ) def test_ReferencesOfAnInvalidElement(self): path_to_foo = p.join(TEST_PROJECT, "another_library", "foo.vhd") # Make sure there's no element at this location unit = self.server._getElementAtPosition(Path(path_to_foo), Location(0, 0)) self.assertIsNone(unit) for exclude_declaration in (True, False): self.assertIsNone( self.server.references( doc_uri=uris.from_fs_path(path_to_foo), position={"line": 0, "character": 0}, exclude_declaration=exclude_declaration, ) )
def test_ReportDesignUnitAccordingToPosition(self): UNIT_A = VhdlDesignUnit( owner=Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")), type_=DesignUnitType.entity, name="unit_a", locations=(Location(line=1, column=2), Location(line=3, column=4)), ) UNIT_B = VerilogDesignUnit( owner=Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")), type_=DesignUnitType.package, name="unit_b", locations=(Location(line=5, column=6), Location(line=7, column=8)), ) DEP_A = RequiredDesignUnit( name=Identifier("dep_a"), library=Identifier("lib_a"), owner=Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")), locations=(Location(line=9, column=10), Location(line=11, column=12)), ) DEP_B = RequiredDesignUnit( name=Identifier("dep_a"), library=Identifier("lib_a"), owner=Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")), locations=(Location(line=13, column=14), Location(line=15, column=16)), ) def getDesignUnitsByPath(self, path): # pylint: disable=unused-argument if path != Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")): it.fail("Expected foo.vhd but got %s" % path) return {UNIT_A, UNIT_B} def getDependenciesByPath(self, path): # pylint: disable=unused-argument if path != Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")): it.fail("Expected foo.vhd but got %s" % path) return {DEP_A, DEP_B} patches = ( patch.object( hdl_checker.database.Database, "getDesignUnitsByPath", getDesignUnitsByPath, ), patch.object( hdl_checker.database.Database, "getDependenciesByPath", getDependenciesByPath, ), ) path = Path(p.join(TEST_PROJECT, "another_library", "foo.vhd")) for _patch in patches: _patch.start() # Check locations outside return nothing self.assertIsNone(self.server._getElementAtPosition(path, Location(0, 0))) # Check design units are found, ensure boundaries match self.assertIsNone(self.server._getElementAtPosition(path, Location(1, 1))) self.assertIs(self.server._getElementAtPosition(path, Location(1, 2)), UNIT_A) self.assertIs(self.server._getElementAtPosition(path, Location(1, 7)), UNIT_A) self.assertIsNone(self.server._getElementAtPosition(path, Location(1, 8))) self.assertIsNone(self.server._getElementAtPosition(path, Location(3, 3))) self.assertIs(self.server._getElementAtPosition(path, Location(3, 4)), UNIT_A) self.assertIs(self.server._getElementAtPosition(path, Location(3, 9)), UNIT_A) self.assertIsNone(self.server._getElementAtPosition(path, Location(3, 10))) self.assertIsNone(self.server._getElementAtPosition(path, Location(5, 5))) self.assertIs(self.server._getElementAtPosition(path, Location(5, 6)), UNIT_B) self.assertIs(self.server._getElementAtPosition(path, Location(5, 11)), UNIT_B) self.assertIsNone(self.server._getElementAtPosition(path, Location(5, 12))) self.assertIsNone(self.server._getElementAtPosition(path, Location(7, 7))) self.assertIs(self.server._getElementAtPosition(path, Location(7, 8)), UNIT_B) self.assertIs(self.server._getElementAtPosition(path, Location(7, 13)), UNIT_B) self.assertIsNone(self.server._getElementAtPosition(path, Location(7, 14))) # Now check dependencies self.assertIsNone(self.server._getElementAtPosition(path, Location(9, 9))) self.assertIs(self.server._getElementAtPosition(path, Location(9, 10)), DEP_A) self.assertIs(self.server._getElementAtPosition(path, Location(9, 20)), DEP_A) self.assertIsNone(self.server._getElementAtPosition(path, Location(9, 21))) self.assertIsNone(self.server._getElementAtPosition(path, Location(11, 11))) self.assertIs(self.server._getElementAtPosition(path, Location(11, 12)), DEP_A) self.assertIs(self.server._getElementAtPosition(path, Location(11, 22)), DEP_A) self.assertIsNone(self.server._getElementAtPosition(path, Location(11, 23))) self.assertIsNone(self.server._getElementAtPosition(path, Location(13, 13))) self.assertIs(self.server._getElementAtPosition(path, Location(13, 14)), DEP_B) self.assertIs(self.server._getElementAtPosition(path, Location(13, 24)), DEP_B) self.assertIsNone(self.server._getElementAtPosition(path, Location(13, 25))) self.assertIsNone(self.server._getElementAtPosition(path, Location(15, 15))) self.assertIs(self.server._getElementAtPosition(path, Location(15, 16)), DEP_B) self.assertIs(self.server._getElementAtPosition(path, Location(15, 26)), DEP_B) self.assertIsNone(self.server._getElementAtPosition(path, Location(15, 27))) for _patch in patches: _patch.stop()
""" hdl_checker provides a Python API between a VHDL project and some HDL compilers to catch errors and warnings the compilers generate that can be used to populate syntax checkers and linters of text editors. It takes into account the sources dependencies when building so you don't need to provide a source list ordered by hand. """ import os from ._version import get_versions from hdl_checker.parsers.elements.identifier import Identifier from hdl_checker.utils import ON_WINDOWS __author__ = "Andre Souto ([email protected])" __license__ = "GPLv3" __status__ = "Development" __version__ = get_versions()["version"] del get_versions DEFAULT_PROJECT_FILE = os.environ.get( "HDL_CHECKER_DEFAULT_PROJECT_FILE", "_hdl_checker.config" if ON_WINDOWS else ".hdl_checker.config", ) CACHE_NAME = os.environ.get("HDL_CHECKER_CACHE_NAME", "cache.json") WORK_PATH = os.environ.get("HDL_CHECKER_WORK_PATH", "_hdl_checker" if ON_WINDOWS else ".hdl_checker") DEFAULT_LIBRARY = Identifier("default_library")
class TestBuilder(TestCase): # Create defaults so that pylint doesn't complain about non existing # members builder_name = None builder_path = None @classmethod def setUpClass(cls): setupTestSuport(TEST_TEMP_PATH) def setUp(self): # type: (...) -> Any # Add builder path to the env self.original_env = os.environ.copy() # Add the builder path to the environment so we can call it if self.builder_path: _logger.info("Adding '%s' to the system path", self.builder_path) self.patch = patch.dict( "os.environ", { "PATH": os.pathsep.join([self.builder_path, os.environ["PATH"]]) }, ) self.patch.start() assert self.builder_name is not None # To make mypy happy builder_class = BUILDER_CLASS_MAP[self.builder_name] work_folder = _temp("_%s" % self.builder_name) _logger.info("Builder class: %s, work folder is %s", builder_class, work_folder) self.builder = builder_class(work_folder, MagicMock()) # type: AnyBuilder self.builder_class = builder_class def tearDown(self): # type: (...) -> Any if self.builder_path: self.patch.stop() if p.exists("._%s" % self.builder_name): shutil.rmtree("._%s" % self.builder_name) def test_EnvironmentCheck(self): # type: (...) -> Any self.builder.checkEnvironment() def test_BuilderReportsItsAvailable(self): # pylint: disable=invalid-name # type: (...) -> Any self.assertTrue(self.builder_class.isAvailable()) # type: ignore def test_CreateLibraryMultipleTimes(self): # pylint: disable=invalid-name # type: (...) -> Any self.builder._createLibraryIfNeeded(Identifier("random_lib")) self.builder._createLibraryIfNeeded(Identifier("random_lib")) def test_BuilderDoesNothingWhenCreatingBuiltinLibraries(self): # pylint: disable=invalid-name # type: (...) -> Any self.builder._createLibraryIfNeeded(Identifier("ieee")) def test_FindsBuiltinLibraries(self): # type: (...) -> Any expected = [] # type: List[str] if not isinstance(self.builder, Fallback): expected += ["ieee", "std"] if isinstance(self.builder, MSim): expected += ["modelsim_lib"] for lib in map(Identifier, expected): self.assertIn(lib, self.builder.builtin_libraries) @parameterized.parameterized.expand([ ("/some/file/with/abs/path.vhd", ), ("some/file/with/relative/path.vhd", ), ("some_file_on_same_level.vhd", ), (r"C:\some\file\on\windows.vhd", ), ]) def test_ParseMsimResult(self, path): # type: (...) -> Any if not isinstance(self.builder, MSim): raise unittest2.SkipTest("ModelSim only test") self.assertEqual( list( self.builder._makeRecords( '** Error: %s(21): near "EOF": (vcom-1576) ' "expecting ';'." % path)), [ BuilderDiag( builder_name=self.builder_name, text="near \"EOF\": expecting ';'.", filename=Path(path), line_number=20, error_code="vcom-1576", severity=DiagType.ERROR, ) ], ) self.assertEqual( list( self.builder._makeRecords( "** Warning: %s(23): (vcom-1320) Type of expression " "\"(OTHERS => '0')\" is ambiguous; using element type " "STD_LOGIC_VECTOR, not aggregate type register_type." % path)), [ BuilderDiag( builder_name=self.builder_name, text="Type of expression \"(OTHERS => '0')\" is " "ambiguous; using element type STD_LOGIC_VECTOR, not " "aggregate type register_type.", filename=Path(path), line_number=22, error_code="vcom-1320", severity=DiagType.WARNING, ) ], ) self.assertEqual( list( self.builder._makeRecords( "** Warning: %s(39): (vcom-1514) Range choice direction " "(downto) does not determine aggregate index range " "direction (to)." % path)), [ BuilderDiag( builder_name=self.builder_name, text="Range choice direction (downto) does not determine " "aggregate index range direction (to).", filename=Path(path), line_number=38, error_code="vcom-1514", severity=DiagType.WARNING, ) ], ) self.assertEqual( list( self.builder._makeRecords( "** Error: (vcom-11) Could not find work.regfile_pkg.")), [ BuilderDiag( builder_name=self.builder_name, text="Could not find work.regfile_pkg.", error_code="vcom-11", severity=DiagType.ERROR, ) ], ) self.assertEqual( list( self.builder._makeRecords( "** Error (suppressible): %s(7): (vcom-1195) Cannot find " 'expanded name "work.regfile_pkg".' % path)), [ BuilderDiag( builder_name=self.builder_name, text='Cannot find expanded name "work.regfile_pkg".', filename=Path(path), line_number=6, error_code="vcom-1195", severity=DiagType.ERROR, ) ], ) self.assertEqual( list( self.builder._makeRecords( "** Error: %s(7): Unknown expanded name." % path)), [ BuilderDiag( builder_name=self.builder_name, text="Unknown expanded name.", line_number="6", filename=Path(path), severity=DiagType.ERROR, ) ], ) self.assertEqual( list( self.builder._makeRecords( "** Warning: [14] %s(103): (vcom-1272) Length of expected " "is 4; length of actual is 8." % path)), [ BuilderDiag( builder_name=self.builder_name, text="Length of expected is 4; length of actual is 8.", line_number="102", error_code="vcom-1272", filename=Path(path), severity=DiagType.WARNING, ) ], ) self.assertEqual( list( self.builder._makeRecords( "** Warning: [14] %s(31): (vcom-1246) Range -1 downto 0 " "is null." % path)), [ BuilderDiag( builder_name=self.builder_name, text="Range -1 downto 0 is null.", line_number="30", error_code="vcom-1246", filename=Path(path), severity=DiagType.WARNING, ) ], ) @parameterized.parameterized.expand([ ("/some/file/with/abs/path.vhd", ), ("some/file/with/relative/path.vhd", ), ("some_file_on_same_level.vhd", ), (r"C:\some\file\on\windows.vhd", ), ]) def test_ParseGhdlResult(self, path): # type: (...) -> Any if not isinstance(self.builder, GHDL): raise unittest2.SkipTest("GHDL only test") records = list( self.builder._makeRecords( "%s:11:35: extra ';' at end of interface list" % path)) expected = [ BuilderDiag( builder_name=self.builder_name, filename=Path(path), line_number=10, column_number=34, severity=DiagType.ERROR, text="extra ';' at end of interface list", ) ] self.assertCountEqual(records, expected) @parameterized.parameterized.expand([ ("/some/file/with/abs/path.vhd", ), ("some/file/with/relative/path.vhd", ), ("some_file_on_same_level.vhd", ), ]) def test_ParseXvhdlResult(self, path): # type: (...) -> Any if not isinstance(self.builder, XVHDL): raise unittest2.SkipTest("XVHDL only test") self.assertEqual( list( self.builder._makeRecords( "ERROR: [VRFC 10-1412] syntax error near ) [%s:12]" % path)), [ BuilderDiag( builder_name=self.builder_name, text="syntax error near )", filename=Path(path), line_number=11, error_code="VRFC 10-1412", severity=DiagType.ERROR, ) ], ) self.assertEqual( list( self.builder._makeRecords( "WARNING: [VRFC 10-1256] possible infinite loop; process " "does not have a wait statement [%s:119]" % path)), [ BuilderDiag( builder_name=self.builder_name, text= "possible infinite loop; process does not have a wait statement", filename=Path(path), line_number=118, error_code="VRFC 10-1256", severity=DiagType.WARNING, ) ], ) @patch("hdl_checker.database.Database.getLibrary", return_value=Identifier("work")) def test_VhdlCompilation(self, *args): # type: (...) -> Any if FileType.vhdl not in self.builder.file_types: raise unittest2.SkipTest("Builder {} doesn't support VHDL".format( self.builder_name)) source = _source("no_messages.vhd") records, rebuilds = self.builder.build(source, Identifier("work"), BuildFlagScope.single) self.assertNotIn( DiagType.ERROR, [x.severity for x in records], "This source should not generate errors.", ) self.assertFalse(rebuilds) @patch("hdl_checker.database.Database.getLibrary", return_value=Identifier("work")) def test_VerilogCompilation(self, *args): # type: (...) -> Any if FileType.verilog not in self.builder.file_types: raise unittest2.SkipTest( "Builder {} doesn't support Verilog".format(self.builder_name)) source = _source("no_messages.v") records, rebuilds = self.builder.build(source, Identifier("work"), BuildFlagScope.single) self.assertNotIn( DiagType.ERROR, [x.severity for x in records], "This source should not generate errors.", ) self.assertFalse(rebuilds) @patch("hdl_checker.database.Database.getLibrary", return_value=Identifier("work")) def test_SystemverilogCompilation(self, *args): # type: (...) -> Any if FileType.systemverilog not in self.builder.file_types: raise unittest2.SkipTest( "Builder {} doesn't support SystemVerilog".format( self.builder_name)) source = _source("no_messages.sv") records, rebuilds = self.builder.build(source, Identifier("work"), BuildFlagScope.single) self.assertNotIn( DiagType.ERROR, [x.severity for x in records], "This source should not generate errors.", ) self.assertFalse(rebuilds) def test_CatchAKnownError(self): # type: (...) -> Any source = _source("source_with_error.vhd") records, rebuilds = self.builder.build(source, Identifier("lib"), forced=True, scope=BuildFlagScope.single) for record in records: _logger.info(record) if self.builder_name == "msim": expected = [{ BuilderDiag( filename=source, builder_name=self.builder_name, text='Unknown identifier "some_lib".', line_number=3, error_code="vcom-1136", severity=DiagType.ERROR, ) }] elif self.builder_name == "ghdl": expected = [{ BuilderDiag( filename=source, builder_name=self.builder_name, text='no declaration for "some_lib"', line_number=3, column_number=4, severity=DiagType.ERROR, ), BuilderDiag( filename=source, builder_name=self.builder_name, text="entity 'source_with_error' was not analysed", line_number=17, column_number=13, severity=DiagType.ERROR, ), }] elif self.builder_name == "xvhdl": # XVHDL reports different errors depending on the version expected = [ { BuilderDiag( filename=source, builder_name=self.builder_name, text="some_lib is not declared", line_number=3, error_code="VRFC 10-91", severity=DiagType.ERROR, ) }, { BuilderDiag( filename=source, builder_name=self.builder_name, text="'some_lib' is not declared", line_number=3, error_code="VRFC 10-2989", severity=DiagType.ERROR, ) }, ] if not isinstance(self.builder, Fallback): self.assertIn(records, expected) else: self.assertFalse(records) self.assertFalse(rebuilds) def test_MsimRecompileMsg0(self): # type: (...) -> Any if not isinstance(self.builder, MSim): raise unittest2.SkipTest("ModelSim only test") line = ("** Error: (vcom-13) Recompile foo_lib.bar_component because " "foo_lib.foo_lib_pkg has changed.") self.assertEqual( [{ "library_name": "foo_lib", "unit_name": "bar_component" }], self.builder._searchForRebuilds(line), ) def test_MsimRecompileMsg1(self): # type: (...) -> Any if not isinstance(self.builder, MSim): raise unittest2.SkipTest("ModelSim only test") line = ( "** Error: (vcom-13) Recompile foo_lib.bar_component because " "foo_lib.foo_lib_pkg, base_library.very_common_package have changed." ) self.assertEqual( [{ "library_name": "foo_lib", "unit_name": "bar_component" }], self.builder._searchForRebuilds(line), ) def test_GhdlRecompileMsg(self): # type: (...) -> Any if not isinstance(self.builder, GHDL): raise unittest2.SkipTest("GHDL only test") line = 'somefile.vhd:12:13: package "leon3" is obsoleted by package "amba"' self.assertEqual( [{ "unit_type": "package", "unit_name": "leon3" }], self.builder._searchForRebuilds(line), ) def test_XvhdlRecompileMsg0(self): # type: (...) -> Any if not isinstance(self.builder, XVHDL): raise unittest2.SkipTest("XVHDL only test") line = ( "ERROR: [VRFC 10-113] {} needs to be re-saved since std.standard " "changed".format( p.join("some", "path", "xsim.dir", "some_library", "some_package.vdb"))) self.assertEqual( [{ "library_name": "some_library", "unit_name": "some_package" }], self.builder._searchForRebuilds(line), ) # Rebuild formats are: # - {unit_type: '', 'unit_name': } # - {library_name: '', 'unit_name': } # - {rebuild_path: ''} @parameterized.parameterized.expand([ ( { "unit_type": "package", "unit_name": "very_common_pkg" }, RebuildUnit(name=Identifier("very_common_pkg"), type_=DesignUnitType.package), ), # Should replace 'work' with the path's library ( { "library_name": "work", "unit_name": "foo" }, RebuildLibraryUnit(name=Identifier("foo"), library=Identifier("some_lib")), ), # Should not touch the library name when != 'work' ( { "library_name": "foo", "unit_name": "bar" }, RebuildLibraryUnit(name=Identifier("bar"), library=Identifier("foo")), ), ({ "rebuild_path": "some_path" }, RebuildPath(Path("some_path"))), ]) def test_GetRebuilds(self, rebuild_info, expected): # type: (...) -> Any _logger.info("Rebuild info is %s", rebuild_info) library = Identifier("some_lib", False) with patch.object(self.builder, "_searchForRebuilds", return_value=[rebuild_info]): self.builder._database.getDependenciesByPath = MagicMock( return_value=[ RequiredDesignUnit( owner=Path(""), name=Identifier("very_common_pkg"), library=Identifier("work"), ) ]) self.assertCountEqual( self.builder._getRebuilds(_source("source.vhd"), "", library), {expected}, )
open(source, "w").write("") project = DummyServer(_Path(path)) project.setConfig(Path(config)) # Get messages of anything to trigger reading the config project.getMessagesByPath(Path(source)) handle_ui_info.assert_called_once_with("No sources were added") removeIfExists(path) @it.should("warn when unable to resolve non-builtin dependencies" ) # type: ignore @patch( "hdl_checker.builders.fallback.Fallback._parseBuiltinLibraries", return_value=[Identifier("builtin")], ) def test(parse_builtins): # type: (...) -> None root = tempfile.mkdtemp() server = DummyServer(Path(root)) with tempfile.NamedTemporaryFile(suffix=".vhd") as filename: diags = server.getMessagesWithText( Path(filename.name), "library lib; use lib.pkg.all; library builtin; use builtin.foo;", ) parse_builtins.assert_called() logIterable("Diags", diags, _logger.info)
def includedPath(name): return IncludedPath( name=Identifier(name), owner=Path("owner"), locations=frozenset([Location(0, 0)]), )
def requiredDesignUnit(name): return RequiredDesignUnit( name=Identifier(name), owner=Path("owner"), locations=frozenset([Location(0, 0)]), )
def test_IncludedPaths(self, filetype): # type: (...) -> Any work_folder = mkdtemp() database = MagicMock(spec=Database) def includedPath(name): return IncludedPath( name=Identifier(name), owner=Path("owner"), locations=frozenset([Location(0, 0)]), ) def requiredDesignUnit(name): return RequiredDesignUnit( name=Identifier(name), owner=Path("owner"), locations=frozenset([Location(0, 0)]), ) included_results = Queue() # type: Queue[Optional[Path]] included_results.put(Path(p.join("", "library", "some", ""))) included_results.put(None) def resolveIncludedPath(*_): return included_results.get(block=False) database.getDependenciesByPath.return_value = [ includedPath(name="resolved/include"), includedPath(name="unresolved/include"), requiredDesignUnit(name="some_unit"), ] database.resolveIncludedPath = resolveIncludedPath calls = [] # type: List[List[str]] def shell(cmd_with_args, *args, **kwargs): calls.append(cmd_with_args) _logger.debug("$ %s", cmd_with_args) if "-version" in cmd_with_args: return ("vcom 10.2c Compiler 2013.07 Jul 18 2013", ) return ("", ) if filetype is FileType.verilog: source = _source("no_messages.v") else: source = _source("no_messages.sv") with patch("hdl_checker.builders.msim.runShellCommand", shell): builder = MSim(Path(work_folder), database=database) records, rebuilds = builder.build(source, Identifier("work"), BuildFlagScope.single) expected = [ "vlog", "-modelsimini", p.join(work_folder, "modelsim.ini"), "-quiet", "-work", p.join(work_folder, "work"), ] if filetype is FileType.systemverilog: expected += ["-sv"] expected += [ "-lint", "-hazards", "-pedanticerrors", "-L", "work", "+incdir+" + p.join("", "library", "some"), str(source), ] self.assertEqual(expected, calls[-1]) self.assertFalse(records) self.assertFalse(rebuilds)
def _RebuildLibraryUnit(name, library): return RebuildLibraryUnit(name=Identifier(name), library=Identifier(library))
def test_CatchAKnownError(self): # type: (...) -> Any source = _source("source_with_error.vhd") records, rebuilds = self.builder.build(source, Identifier("lib"), forced=True, scope=BuildFlagScope.single) for record in records: _logger.info(record) if self.builder_name == "msim": expected = [{ BuilderDiag( filename=source, builder_name=self.builder_name, text='Unknown identifier "some_lib".', line_number=3, error_code="vcom-1136", severity=DiagType.ERROR, ) }] elif self.builder_name == "ghdl": expected = [{ BuilderDiag( filename=source, builder_name=self.builder_name, text='no declaration for "some_lib"', line_number=3, column_number=4, severity=DiagType.ERROR, ), BuilderDiag( filename=source, builder_name=self.builder_name, text="entity 'source_with_error' was not analysed", line_number=17, column_number=13, severity=DiagType.ERROR, ), }] elif self.builder_name == "xvhdl": # XVHDL reports different errors depending on the version expected = [ { BuilderDiag( filename=source, builder_name=self.builder_name, text="some_lib is not declared", line_number=3, error_code="VRFC 10-91", severity=DiagType.ERROR, ) }, { BuilderDiag( filename=source, builder_name=self.builder_name, text="'some_lib' is not declared", line_number=3, error_code="VRFC 10-2989", severity=DiagType.ERROR, ) }, ] if not isinstance(self.builder, Fallback): self.assertIn(records, expected) else: self.assertFalse(records) self.assertFalse(rebuilds)
def _RebuildUnit(name, type_): return RebuildUnit(name=Identifier(name), type_=Identifier(type_))
def test_BuilderDoesNothingWhenCreatingBuiltinLibraries(self): # pylint: disable=invalid-name # type: (...) -> Any self.builder._createLibraryIfNeeded(Identifier("ieee"))