예제 #1
0
    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)
예제 #2
0
    def getMessagesWithText(self, path, content):
        # type: (Path, AnyStr) -> Iterable[CheckerDiagnostic]
        """
        Dumps content to a temprary file and replaces the temporary file name
        for path on the diagnostics received
        """
        with self._lock:
            _logger.info("Getting messages for '%s' with content", path)

            ext = path.name.split(".")[-1]
            temporary_file = tempfile.NamedTemporaryFile(suffix="." + ext,
                                                         delete=False)

            temp_path = TemporaryPath(temporary_file.name)

            temporary_file.file.write(toBytes(content))  # type: ignore
            temporary_file.close()

            # If the reference path was added to the database, add the
            # temporary file with the same attributes
            if path in self.database.paths:
                library = self.database.getLibrary(path)
                self.database.addSource(
                    temp_path,
                    getattr(library, "display_name", None),
                    self.database.getFlags(path, BuildFlagScope.single),
                    self.database.getFlags(path, BuildFlagScope.dependencies),
                )

            diags = set()  # type: Set[CheckerDiagnostic]

            # Some messages may not include the filename field when checking a
            # file by content. In this case, we'll assume the empty filenames
            # refer to the same filename we got in the first place
            for diag in self.getMessagesByPath(temp_path):
                if diag.filename in (temp_path, None):
                    diag = diag.copy(
                        text=diag.text.replace(temporary_file.name, path.name),
                        filename=path,
                    )

                diags.add(diag)

            diags |= set(self.database.getDiagnosticsForPath(temporary_file))

            self.database.removeSource(temp_path)
            removeIfExists(temporary_file.name)

            if self.config_file and path not in self.database.paths:
                diags.add(PathNotInProjectFile(path))

        return diags
예제 #3
0
        def test():
            filename = Path(p.join(TEST_TEMP_PATH, "some_file.vhd"))
            writeListToFile(str(filename), ["library some_lib;"])

            diagnostics = it.project.getMessagesByPath(filename)

            _logger.info("Records found:")
            for diagnostic in diagnostics:
                _logger.info(diagnostic)

            it.assertIn(PathNotInProjectFile(filename), diagnostics)

            # The builder should find other issues as well...
            it.assertTrue(
                len(diagnostics) > 1,
                "It was expected that the builder added some "
                "message here indicating an error",
            )
예제 #4
0
        def test():
            filename = Path(p.join(TEST_TEMP_PATH, "some_file.vhd"))
            writeListToFile(str(filename), ["entity some_entity is end;"])

            content = "\n".join([
                "library work;", "use work.all;", "entity some_entity is end;"
            ])

            diagnostics = it.project.getMessagesWithText(filename, content)

            _logger.debug("Records received:")
            for diagnostic in diagnostics:
                _logger.debug("- %s", diagnostic)

            it.assertIn(
                LibraryShouldBeOmited(library="work",
                                      filename=filename,
                                      column_number=8,
                                      line_number=0),
                diagnostics,
            )

            it.assertIn(PathNotInProjectFile(filename), diagnostics)
예제 #5
0
        def test(_):
            with PatchBuilder():
                it.project.setConfig(Path(p.join(TEST_PROJECT, "vimhdl.prj")))
                it.project._updateConfigIfNeeded()

            entity_a = _SourceMock(
                filename=_path("entity_a.vhd"),
                library="some_lib",
                design_units=[{
                    "name": "entity_a",
                    "type": "entity"
                }],
                dependencies={("work", "foo")},
            )

            path_to_foo = Path(
                p.join(TEST_PROJECT, "another_library", "foo.vhd"))

            diags = {
                # entity_a.vhd is the path we're compiling, inject a diagnostic
                # from the builder
                str(entity_a.filename): [[
                    CheckerDiagnostic(filename=entity_a.filename,
                                      checker=None,
                                      text="some text")
                ]],
                # foo.vhd is on the build sequence, check that diagnostics from
                # the build sequence are only included when their severity is
                # DiagType.ERROR
                str(path_to_foo): [[
                    CheckerDiagnostic(
                        filename=path_to_foo,
                        checker=None,
                        text="should not be included",
                        severity=DiagType.WARNING,
                    ),
                    CheckerDiagnostic(
                        filename=path_to_foo,
                        checker=None,
                        text="style error should be included",
                        severity=DiagType.STYLE_ERROR,
                    ),
                    CheckerDiagnostic(
                        filename=path_to_foo,
                        checker=None,
                        text="should be included",
                        severity=DiagType.ERROR,
                    ),
                ]],
            }

            def build(  # pylint: disable=unused-argument
                    path,
                    library,
                    scope,
                    forced=False):
                _logger.debug("Building library=%s, path=%s", library, path)
                path_diags = diags.get(str(path), [])
                if path_diags:
                    return path_diags.pop(), []
                return [], []

            with patch.object(it.project.builder, "build", build):
                _logger.info("Project paths: %s", it.project.database._paths)
                messages = list(it.project.getMessagesByPath(
                    entity_a.filename))
                logIterable("Messages", messages, _logger.info)
                it.assertCountEqual(
                    messages,
                    [
                        LibraryShouldBeOmited(
                            library="work",
                            filename=entity_a.filename,
                            column_number=8,
                            line_number=0,
                        ),
                        PathNotInProjectFile(entity_a.filename),
                        CheckerDiagnostic(filename=entity_a.filename,
                                          checker=None,
                                          text="some text"),
                        CheckerDiagnostic(
                            filename=path_to_foo,
                            checker=None,
                            text="style error should be included",
                            severity=DiagType.STYLE_ERROR,
                        ),
                        CheckerDiagnostic(
                            filename=path_to_foo,
                            checker=None,
                            text="should be included",
                            severity=DiagType.ERROR,
                        ),
                    ],
                )