<commit_before># Copyright 2015 The Meson development team
# Copyright © 2021 Intel Corporation

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations

import os
import shutil
import typing as T
import xml.etree.ElementTree as ET

from . import ModuleReturnValue, ExtensionModule
from .. import build
from .. import coredata
from .. import mlog
from ..dependencies import find_external_dependency, Dependency, ExternalLibrary
from ..mesonlib import MesonException, File, version_compare, Popen_safe
from ..interpreter import extract_required_kwarg
from ..interpreter.type_checking import NoneType
from ..interpreterbase import ContainerTypeInfo, FeatureDeprecated, KwargInfo, noPosargs, FeatureNew, typed_kwargs
from ..programs import NonExistingExternalProgram

if T.TYPE_CHECKING:
    from . import ModuleState
    from ..dependencies.qt import QtPkgConfigDependency, QmakeQtDependency
    from ..interpreter import Interpreter
    from ..interpreter import kwargs
    from ..mesonlib import FileOrString
    from ..programs import ExternalProgram

    QtDependencyType = T.Union[QtPkgConfigDependency, QmakeQtDependency]

    from typing_extensions import TypedDict

    class ResourceCompilerKwArgs(TypedDict):

        """Keyword arguments for the Resource Compiler method."""

        name: T.Optional[str]
        sources: T.Sequence[T.Union[FileOrString, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]]
        extra_args: T.List[str]
        method: str

    class UICompilerKwArgs(TypedDict):

        """Keyword arguments for the Ui Compiler method."""

        sources: T.Sequence[T.Union[FileOrString, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]]
        extra_args: T.List[str]
        method: str

    class MocCompilerKwArgs(TypedDict):

        """Keyword arguments for the Moc Compiler method."""

        sources: T.Sequence[T.Union[FileOrString, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]]
        headers: T.Sequence[T.Union[FileOrString, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]]
        extra_args: T.List[str]
        method: str
        include_directories: T.List[T.Union[str, build.IncludeDirs]]
        dependencies: T.List[T.Union[Dependency, ExternalLibrary]]

    class PreprocessKwArgs(TypedDict):

        sources: T.List[FileOrString]
        moc_sources: T.List[T.Union[FileOrString, build.CustomTarget]]
        moc_headers: T.List[T.Union[FileOrString, build.CustomTarget]]
        qresources: T.List[FileOrString]
        ui_files: T.List[T.Union[FileOrString, build.CustomTarget]]
        moc_extra_arguments: T.List[str]
        rcc_extra_arguments: T.List[str]
        uic_extra_arguments: T.List[str]
        include_directories: T.List[T.Union[str, build.IncludeDirs]]
        dependencies: T.List[T.Union[Dependency, ExternalLibrary]]
        method: str

    class HasToolKwArgs(kwargs.ExtractRequired):

        method: str

    class CompileTranslationsKwArgs(TypedDict):

        build_by_default: bool
        install: bool
        install_dir: T.Optional[str]
        method: str
        qresource: T.Optional[str]
        rcc_extra_arguments: T.List[str]
        ts_files: T.List[T.Union[str, File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]]

class QtBaseModule(ExtensionModule):
    _tools_detected = False
    _rcc_supports_depfiles = False
    _moc_supports_depfiles = False

    def __init__(self, interpreter: 'Interpreter', qt_version: int = 5):
        ExtensionModule.__init__(self, interpreter)
        self.qt_version = qt_version
        self.tools: T.Dict[str, ExternalProgram] = {
            'moc': NonExistingExternalProgram('moc'),
            'uic': NonExistingExternalProgram('uic'),
            'rcc': NonExistingExternalProgram('rcc'),
            'lrelease': NonExistingExternalProgram('lrelease'),
        }
        self.methods.update({
            'has_tools': self.has_tools,
            'preprocess': self.preprocess,
            'compile_translations': self.compile_translations,
            'compile_resources': self.compile_resources,
            'compile_ui': self.compile_ui,
            'compile_moc': self.compile_moc,
        })

    def compilers_detect(self, state: 'ModuleState', qt_dep: 'QtDependencyType') -> None:
        """Detect Qt (4 or 5) moc, uic, rcc in the specified bindir or in PATH"""
        # It is important that this list does not change order as the order of
        # the returned ExternalPrograms will change as well
        wanted = f'== {qt_dep.version}'

        def gen_bins() -> T.Generator[T.Tuple[str, str], None, None]:
            for b in self.tools:
                if qt_dep.bindir:
                    yield os.path.join(qt_dep.bindir, b), b
                if qt_dep.libexecdir:
                    yield os.path.join(qt_dep.libexecdir, b), b
                # prefer the (official) <tool><version> or (unofficial) <tool>-qt<version>
                # of the tool to the plain one, as we
                # don't know what the unsuffixed one points to without calling it.
                yield f'{b}{qt_dep.qtver}', b
                yield f'{b}-qt{qt_dep.qtver}', b
                yield b, b

        for b, name in gen_bins():
            if self.tools[name].found():
                continue

            if name == 'lrelease':
                arg = ['-version']
            elif version_compare(qt_dep.version, '>= 5'):
                arg = ['--version']
            else:
                arg = ['-v']

            # Ensure that the version of qt and each tool are the same
            def get_version(p: ExternalProgram) -> str:
                _, out, err = Popen_safe(p.get_command() + arg)<commit_msg>qt module: move comment to the correct location after refactoring<commit_after># Copyright 2015 The Meson development team
# Copyright © 2021 Intel Corporation

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations

import os
import shutil
import typing as T
import xml.etree.ElementTree as ET

from . import ModuleReturnValue, ExtensionModule
from .. import build
from .. import coredata
from .. import mlog
from ..dependencies import find_external_dependency, Dependency, ExternalLibrary
from ..mesonlib import MesonException, File, version_compare, Popen_safe
from ..interpreter import extract_required_kwarg
from ..interpreter.type_checking import NoneType
from ..interpreterbase import ContainerTypeInfo, FeatureDeprecated, KwargInfo, noPosargs, FeatureNew, typed_kwargs
from ..programs import NonExistingExternalProgram

if T.TYPE_CHECKING:
    from . import ModuleState
    from ..dependencies.qt import QtPkgConfigDependency, QmakeQtDependency
    from ..interpreter import Interpreter
    from ..interpreter import kwargs
    from ..mesonlib import FileOrString
    from ..programs import ExternalProgram

    QtDependencyType = T.Union[QtPkgConfigDependency, QmakeQtDependency]

    from typing_extensions import TypedDict

    class ResourceCompilerKwArgs(TypedDict):

        """Keyword arguments for the Resource Compiler method."""

        name: T.Optional[str]
        sources: T.Sequence[T.Union[FileOrString, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]]
        extra_args: T.List[str]
        method: str

    class UICompilerKwArgs(TypedDict):

        """Keyword arguments for the Ui Compiler method."""

        sources: T.Sequence[T.Union[FileOrString, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]]
        extra_args: T.List[str]
        method: str

    class MocCompilerKwArgs(TypedDict):

        """Keyword arguments for the Moc Compiler method."""

        sources: T.Sequence[T.Union[FileOrString, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]]
        headers: T.Sequence[T.Union[FileOrString, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]]
        extra_args: T.List[str]
        method: str
        include_directories: T.List[T.Union[str, build.IncludeDirs]]
        dependencies: T.List[T.Union[Dependency, ExternalLibrary]]

    class PreprocessKwArgs(TypedDict):

        sources: T.List[FileOrString]
        moc_sources: T.List[T.Union[FileOrString, build.CustomTarget]]
        moc_headers: T.List[T.Union[FileOrString, build.CustomTarget]]
        qresources: T.List[FileOrString]
        ui_files: T.List[T.Union[FileOrString, build.CustomTarget]]
        moc_extra_arguments: T.List[str]
        rcc_extra_arguments: T.List[str]
        uic_extra_arguments: T.List[str]
        include_directories: T.List[T.Union[str, build.IncludeDirs]]
        dependencies: T.List[T.Union[Dependency, ExternalLibrary]]
        method: str

    class HasToolKwArgs(kwargs.ExtractRequired):

        method: str

    class CompileTranslationsKwArgs(TypedDict):

        build_by_default: bool
        install: bool
        install_dir: T.Optional[str]
        method: str
        qresource: T.Optional[str]
        rcc_extra_arguments: T.List[str]
        ts_files: T.List[T.Union[str, File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]]

class QtBaseModule(ExtensionModule):
    _tools_detected = False
    _rcc_supports_depfiles = False
    _moc_supports_depfiles = False

    def __init__(self, interpreter: 'Interpreter', qt_version: int = 5):
        ExtensionModule.__init__(self, interpreter)
        self.qt_version = qt_version
        # It is important that this list does not change order as the order of
        # the returned ExternalPrograms will change as well
        self.tools: T.Dict[str, ExternalProgram] = {
            'moc': NonExistingExternalProgram('moc'),
            'uic': NonExistingExternalProgram('uic'),
            'rcc': NonExistingExternalProgram('rcc'),
            'lrelease': NonExistingExternalProgram('lrelease'),
        }
        self.methods.update({
            'has_tools': self.has_tools,
            'preprocess': self.preprocess,
            'compile_translations': self.compile_translations,
            'compile_resources': self.compile_resources,
            'compile_ui': self.compile_ui,
            'compile_moc': self.compile_moc,
        })

    def compilers_detect(self, state: 'ModuleState', qt_dep: 'QtDependencyType') -> None:
        """Detect Qt (4 or 5) moc, uic, rcc in the specified bindir or in PATH"""
        wanted = f'== {qt_dep.version}'

        def gen_bins() -> T.Generator[T.Tuple[str, str], None, None]:
            for b in self.tools:
                if qt_dep.bindir:
                    yield os.path.join(qt_dep.bindir, b), b
                if qt_dep.libexecdir:
                    yield os.path.join(qt_dep.libexecdir, b), b
                # prefer the (official) <tool><version> or (unofficial) <tool>-qt<version>
                # of the tool to the plain one, as we
                # don't know what the unsuffixed one points to without calling it.
                yield f'{b}{qt_dep.qtver}', b
                yield f'{b}-qt{qt_dep.qtver}', b
                yield b, b

        for b, name in gen_bins():
            if self.tools[name].found():
                continue

            if name == 'lrelease':
                arg = ['-version']
            elif version_compare(qt_dep.version, '>= 5'):
                arg = ['--version']
            else:
                arg = ['-v']

            # Ensure that the version of qt and each tool are the same
            def get_version(p: ExternalProgram) -> str:
                _, out, err = Popen_safe(p.get_command() + arg)
{'fraction_non_alphanumeric': 0.0920571882446386, 'fraction_numerical': 0.0025416997617156473, 'mean_word_length': 2.8693915181315304, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6684914', 'n_tokens_mistral': 3607, 'n_tokens_neox': 3501, 'n_words': 996}