style: Run black formatter on 16 files
Applied black formatting to files modified in linting fixes: Source files (8): - config_extractor.py - doc_scraper.py - how_to_guide_builder.py - llms_txt_downloader.py - llms_txt_parser.py - pattern_recognizer.py - test_example_extractor.py - unified_codebase_analyzer.py Test files (8): - test_architecture_scenarios.py - test_async_scraping.py - test_github_scraper.py - test_guide_enhancer.py - test_install_agent.py - test_issue_219_e2e.py - test_llms_txt_downloader.py - test_skip_llms_txt.py All formatting issues resolved. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -237,7 +237,9 @@ class PatternRecognizer:
|
||||
self.detectors.append(TemplateMethodDetector(self.depth))
|
||||
self.detectors.append(ChainOfResponsibilityDetector(self.depth))
|
||||
|
||||
def analyze_file(self, file_path: str, content: str, language: str) -> PatternReport:
|
||||
def analyze_file(
|
||||
self, file_path: str, content: str, language: str
|
||||
) -> PatternReport:
|
||||
"""
|
||||
Analyze a single file for design patterns.
|
||||
|
||||
@@ -428,7 +430,9 @@ class SingletonDetector(BasePatternDetector):
|
||||
# Python: __init__ or __new__
|
||||
# Java/C#: private constructor (detected by naming)
|
||||
# Check if it has logic (not just pass)
|
||||
if method.name in ["__new__", "__init__", "constructor"] and (method.docstring or len(method.parameters) > 1):
|
||||
if method.name in ["__new__", "__init__", "constructor"] and (
|
||||
method.docstring or len(method.parameters) > 1
|
||||
):
|
||||
evidence.append(f"Controlled initialization: {method.name}")
|
||||
confidence += 0.3
|
||||
has_init_control = True
|
||||
@@ -535,17 +539,19 @@ class FactoryDetector(BasePatternDetector):
|
||||
for method in class_sig.methods:
|
||||
method_lower = method.name.lower()
|
||||
# Check if method returns something (has return type or is not void)
|
||||
if any(name in method_lower for name in factory_method_names) and (method.return_type or "create" in method_lower):
|
||||
if any(name in method_lower for name in factory_method_names) and (
|
||||
method.return_type or "create" in method_lower
|
||||
):
|
||||
return PatternInstance(
|
||||
pattern_type=self.pattern_type,
|
||||
category=self.category,
|
||||
confidence=0.6,
|
||||
location="",
|
||||
class_name=class_sig.name,
|
||||
method_name=method.name,
|
||||
line_number=method.line_number,
|
||||
evidence=[f"Factory method detected: {method.name}"],
|
||||
)
|
||||
pattern_type=self.pattern_type,
|
||||
category=self.category,
|
||||
confidence=0.6,
|
||||
location="",
|
||||
class_name=class_sig.name,
|
||||
method_name=method.name,
|
||||
line_number=method.line_number,
|
||||
evidence=[f"Factory method detected: {method.name}"],
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
@@ -575,7 +581,9 @@ class FactoryDetector(BasePatternDetector):
|
||||
|
||||
# Check if multiple factory methods exist (Abstract Factory pattern)
|
||||
if len(factory_methods) >= 2:
|
||||
evidence.append(f"Multiple factory methods: {', '.join(factory_methods[:3])}")
|
||||
evidence.append(
|
||||
f"Multiple factory methods: {', '.join(factory_methods[:3])}"
|
||||
)
|
||||
confidence += 0.2
|
||||
|
||||
# Check for inheritance (factory hierarchy)
|
||||
@@ -682,7 +690,13 @@ class ObserverDetector(BasePatternDetector):
|
||||
has_notify = False
|
||||
|
||||
attach_names = ["attach", "add", "subscribe", "register", "addeventlistener"]
|
||||
detach_names = ["detach", "remove", "unsubscribe", "unregister", "removeeventlistener"]
|
||||
detach_names = [
|
||||
"detach",
|
||||
"remove",
|
||||
"unsubscribe",
|
||||
"unregister",
|
||||
"removeeventlistener",
|
||||
]
|
||||
notify_names = ["notify", "update", "emit", "publish", "fire", "trigger"]
|
||||
|
||||
for method in class_sig.methods:
|
||||
@@ -786,25 +800,35 @@ class StrategyDetector(BasePatternDetector):
|
||||
]
|
||||
|
||||
if siblings:
|
||||
evidence.append(f"Part of strategy family with: {', '.join(siblings[:3])}")
|
||||
evidence.append(
|
||||
f"Part of strategy family with: {', '.join(siblings[:3])}"
|
||||
)
|
||||
confidence += 0.5
|
||||
|
||||
if base_class and ("strategy" in base_class.lower() or "policy" in base_class.lower()):
|
||||
if base_class and (
|
||||
"strategy" in base_class.lower() or "policy" in base_class.lower()
|
||||
):
|
||||
evidence.append(f"Inherits from strategy base: {base_class}")
|
||||
confidence += 0.3
|
||||
|
||||
# Check if this is a strategy base class
|
||||
# (has subclasses in same file)
|
||||
subclasses = [cls.name for cls in all_classes if class_sig.name in cls.base_classes]
|
||||
subclasses = [
|
||||
cls.name for cls in all_classes if class_sig.name in cls.base_classes
|
||||
]
|
||||
|
||||
if len(subclasses) >= 2:
|
||||
evidence.append(f"Strategy base with implementations: {', '.join(subclasses[:3])}")
|
||||
evidence.append(
|
||||
f"Strategy base with implementations: {', '.join(subclasses[:3])}"
|
||||
)
|
||||
confidence += 0.6
|
||||
|
||||
# Check for single dominant method (strategy interface)
|
||||
if len(class_sig.methods) == 1 or len(class_sig.methods) == 2:
|
||||
# Single method or method + __init__
|
||||
main_method = [m for m in class_sig.methods if m.name not in ["__init__", "__new__"]]
|
||||
main_method = [
|
||||
m for m in class_sig.methods if m.name not in ["__init__", "__new__"]
|
||||
]
|
||||
if main_method:
|
||||
evidence.append(f"Strategy interface method: {main_method[0].name}")
|
||||
confidence += 0.2
|
||||
@@ -1274,7 +1298,9 @@ class TemplateMethodDetector(BasePatternDetector):
|
||||
class_lower = class_sig.name.lower()
|
||||
if any(keyword in class_lower for keyword in template_keywords):
|
||||
# Check if has subclasses
|
||||
subclasses = [cls.name for cls in all_classes if class_sig.name in cls.base_classes]
|
||||
subclasses = [
|
||||
cls.name for cls in all_classes if class_sig.name in cls.base_classes
|
||||
]
|
||||
|
||||
if subclasses:
|
||||
return PatternInstance(
|
||||
@@ -1284,7 +1310,9 @@ class TemplateMethodDetector(BasePatternDetector):
|
||||
location="",
|
||||
class_name=class_sig.name,
|
||||
line_number=class_sig.line_number,
|
||||
evidence=[f"Abstract base with subclasses: {', '.join(subclasses[:2])}"],
|
||||
evidence=[
|
||||
f"Abstract base with subclasses: {', '.join(subclasses[:2])}"
|
||||
],
|
||||
related_classes=subclasses,
|
||||
)
|
||||
|
||||
@@ -1301,7 +1329,9 @@ class TemplateMethodDetector(BasePatternDetector):
|
||||
# 3. Has template method that orchestrates
|
||||
|
||||
# Check for subclasses
|
||||
subclasses = [cls.name for cls in all_classes if class_sig.name in cls.base_classes]
|
||||
subclasses = [
|
||||
cls.name for cls in all_classes if class_sig.name in cls.base_classes
|
||||
]
|
||||
|
||||
if len(subclasses) >= 1:
|
||||
evidence.append(f"Base class with {len(subclasses)} implementations")
|
||||
@@ -1437,7 +1467,8 @@ class ChainOfResponsibilityDetector(BasePatternDetector):
|
||||
|
||||
# Check for set_next() method
|
||||
has_set_next = any(
|
||||
"next" in m.name.lower() and ("set" in m.name.lower() or "add" in m.name.lower())
|
||||
"next" in m.name.lower()
|
||||
and ("set" in m.name.lower() or "add" in m.name.lower())
|
||||
for m in class_sig.methods
|
||||
)
|
||||
|
||||
@@ -1458,7 +1489,9 @@ class ChainOfResponsibilityDetector(BasePatternDetector):
|
||||
]
|
||||
|
||||
if siblings and has_next_ref:
|
||||
evidence.append(f"Part of handler chain with: {', '.join(siblings[:2])}")
|
||||
evidence.append(
|
||||
f"Part of handler chain with: {', '.join(siblings[:2])}"
|
||||
)
|
||||
confidence += 0.2
|
||||
|
||||
if confidence >= 0.5:
|
||||
@@ -1515,7 +1548,11 @@ class LanguageAdapter:
|
||||
pattern.confidence = min(pattern.confidence + 0.1, 1.0)
|
||||
|
||||
# Strategy: Duck typing common in Python
|
||||
elif pattern.pattern_type == "Strategy" and "duck typing" in evidence_str or "protocol" in evidence_str:
|
||||
elif (
|
||||
pattern.pattern_type == "Strategy"
|
||||
and "duck typing" in evidence_str
|
||||
or "protocol" in evidence_str
|
||||
):
|
||||
pattern.confidence = min(pattern.confidence + 0.05, 1.0)
|
||||
|
||||
# JavaScript/TypeScript adaptations
|
||||
@@ -1532,7 +1569,11 @@ class LanguageAdapter:
|
||||
pattern.confidence = min(pattern.confidence + 0.05, 1.0)
|
||||
|
||||
# Observer: Event emitters are built-in
|
||||
elif pattern.pattern_type == "Observer" and "eventemitter" in evidence_str or "event" in evidence_str:
|
||||
elif (
|
||||
pattern.pattern_type == "Observer"
|
||||
and "eventemitter" in evidence_str
|
||||
or "event" in evidence_str
|
||||
):
|
||||
pattern.confidence = min(pattern.confidence + 0.1, 1.0)
|
||||
pattern.evidence.append("EventEmitter pattern detected")
|
||||
|
||||
@@ -1549,7 +1590,9 @@ class LanguageAdapter:
|
||||
pattern.evidence.append("Abstract Factory pattern")
|
||||
|
||||
# Template Method: Abstract classes common
|
||||
elif pattern.pattern_type == "TemplateMethod" and "abstract" in evidence_str:
|
||||
elif (
|
||||
pattern.pattern_type == "TemplateMethod" and "abstract" in evidence_str
|
||||
):
|
||||
pattern.confidence = min(pattern.confidence + 0.1, 1.0)
|
||||
|
||||
# Go adaptations
|
||||
@@ -1602,7 +1645,9 @@ class LanguageAdapter:
|
||||
pattern.evidence.append("Ruby Singleton module")
|
||||
|
||||
# Builder: Method chaining is idiomatic
|
||||
elif pattern.pattern_type == "Builder" and "method chaining" in evidence_str:
|
||||
elif (
|
||||
pattern.pattern_type == "Builder" and "method chaining" in evidence_str
|
||||
):
|
||||
pattern.confidence = min(pattern.confidence + 0.05, 1.0)
|
||||
|
||||
# PHP adaptations
|
||||
@@ -1653,9 +1698,13 @@ Supported Languages:
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--file", action="append", help="Source file to analyze (can be specified multiple times)"
|
||||
"--file",
|
||||
action="append",
|
||||
help="Source file to analyze (can be specified multiple times)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--directory", help="Directory to analyze (analyzes all source files)"
|
||||
)
|
||||
parser.add_argument("--directory", help="Directory to analyze (analyzes all source files)")
|
||||
parser.add_argument(
|
||||
"--output", help="Output directory for results (default: current directory)"
|
||||
)
|
||||
@@ -1666,7 +1715,9 @@ Supported Languages:
|
||||
help="Detection depth: surface (fast), deep (default), full (thorough)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--json", action="store_true", help="Output JSON format instead of human-readable"
|
||||
"--json",
|
||||
action="store_true",
|
||||
help="Output JSON format instead of human-readable",
|
||||
)
|
||||
parser.add_argument("--verbose", action="store_true", help="Enable verbose output")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user