rules_constants.py

Code Hygiene Score: 100

Keine Issues gefunden.

Dependencies 5

Klassen 2

Code

#!/usr/bin/env python3
"""
Constants Rules (W7) - Magic Number Warnings.

Regeln für benannte Konstanten: Warnt bei Magic Numbers,
empfiehlt die Verwendung von Domain\\Constants.
"""

import re
from typing import List
from .rule_base import Rule, COMMON_NUMBERS


# =============================================================================
# CONSTANTS ALLOWLIST
# =============================================================================

CONSTANTS_ALLOWLIST = [
    "/Constants.php",
    "/constants.py",
    "/config.py",
    "/Config.php",
    "/config/",
    "CodeQualityChecker.php",
]

# Suspicious magic numbers that should be named
SUSPICIOUS_MAGIC = {
    '100': 'DEFAULT_LIMIT or PERCENT_FULL',
    '1000': 'BATCH_LIMIT or MS_PER_SECOND',
    '60': 'SECONDS_PER_MINUTE',
    '24': 'HOURS_PER_DAY',
    '365': 'DAYS_PER_YEAR',
    '30': 'HTTP_TIMEOUT',
    '120': 'LLM_TIMEOUT',
}


# =============================================================================
# W7: CONSTANTS - Named Constants
# =============================================================================

class W7_1_MagicNumbers(Rule):
    """W7.1: Magic Numbers sollten benannte Konstanten sein."""

    def __init__(self):
        super().__init__(allowlist=CONSTANTS_ALLOWLIST)

    def check(self, file_path: str, content: str) -> List[str]:
        # Nur PHP und Python
        if not (file_path.endswith('.php') or file_path.endswith('.py')):
            return []

        warnings = []
        lines = content.split('\n')

        for line_num, line in enumerate(lines, 1):
            # Skip Kommentare
            stripped = line.strip()
            if stripped.startswith('//') or stripped.startswith('#') or stripped.startswith('*'):
                continue

            # Skip const/define/Constants
            if re.search(r'\bconst\b|\bdefine\b|Constants::|from constants import', line, re.IGNORECASE):
                continue

            # Prüfe auf verdächtige Magic Numbers
            for magic, suggestion in SUSPICIOUS_MAGIC.items():
                # Nur alleinstehende Zahlen (nicht in größeren Zahlen)
                pattern = rf'(?<![0-9]){magic}(?![0-9])'
                if re.search(pattern, line):
                    # Nicht warnen wenn bereits Constants verwendet wird
                    if 'Constants::' in line or 'CONSTANTS' in line.upper():
                        continue

                    warnings.append(
                        f"W7.1: Magic number {magic} at line {line_num}. "
                        f"Consider using Constants::{suggestion}"
                    )
                    break  # Eine Warnung pro Zeile reicht

        # Maximal 5 Warnungen pro Datei
        return warnings[:5]


class W7_2_MissingConstantsImport(Rule):
    """W7.2: Constants Import fehlt aber Magic Numbers verwendet."""

    def __init__(self):
        super().__init__(allowlist=CONSTANTS_ALLOWLIST)

    def check(self, file_path: str, content: str) -> List[str]:
        if file_path.endswith('.php'):
            # PHP: Prüfe auf use Domain\Constants
            has_import = 'use Domain\\Constants' in content or 'Domain\\Constants::' in content

            if not has_import:
                # Hat die Datei verdächtige Magic Numbers?
                for magic in ['3600', '86400', '1000']:
                    if re.search(rf'\b{magic}\b', content):
                        return [
                            f"W7.2: File uses magic number {magic} but missing 'use Domain\\Constants'. "
                            "Add import and use named constants."
                        ]

        elif file_path.endswith('.py'):
            # Python: Prüfe auf from constants import
            has_import = 'from constants import' in content or 'import constants' in content

            if not has_import:
                for magic in ['3600', '86400', '1000']:
                    if re.search(rf'\b{magic}\b', content):
                        return [
                            f"W7.2: File uses magic number {magic} but missing constants import. "
                            "Add 'from constants import ...' and use named constants."
                        ]

        return []


# =============================================================================
# RULE COLLECTION
# =============================================================================

RULES = [
    W7_1_MagicNumbers(),
    W7_2_MissingConstantsImport(),
]
← Übersicht Graph