Step 659: entropy scanner model

This commit is contained in:
Bill
2026-02-17 22:13:24 -07:00
parent 796d052733
commit c5d7b5b0ad
4 changed files with 122 additions and 0 deletions

View File

@@ -4810,4 +4810,13 @@ target_link_libraries(step658_test PRIVATE
tree_sitter_javascript tree_sitter_typescript
tree_sitter_java tree_sitter_rust tree_sitter_go)
add_executable(step659_test tests/step659_test.cpp)
target_include_directories(step659_test PRIVATE src)
target_link_libraries(step659_test PRIVATE
nlohmann_json::nlohmann_json
unofficial::tree-sitter::tree-sitter
tree_sitter_python tree_sitter_cpp tree_sitter_elisp
tree_sitter_javascript tree_sitter_typescript
tree_sitter_java tree_sitter_rust tree_sitter_go)
# Step 12: Dear ImGui shell scaffolding created (main.cpp exists but not built due to dependencies)

View File

@@ -0,0 +1,65 @@
#pragma once
// Step 659: Entropy scanner - editor side
#include <set>
#include <string>
#include <vector>
struct EntropyObservation {
int duplicateSignatures = 0;
int similarModuleNames = 0;
int unusedExports = 0;
};
class EntropyScannerModel {
public:
static EntropyObservation scan(const std::vector<std::string>& signatures,
const std::vector<std::string>& moduleNames,
const std::vector<std::string>& exports,
const std::set<std::string>& usedExports) {
EntropyObservation o;
o.duplicateSignatures = countDuplicates(signatures);
o.similarModuleNames = countPrefixSimilar(moduleNames);
o.unusedExports = countUnused(exports, usedExports);
return o;
}
static int entropyScore(const EntropyObservation& o) {
return o.duplicateSignatures + o.similarModuleNames + o.unusedExports;
}
static bool shouldSuggestRefactor(const EntropyObservation& o, int threshold = 3) {
return entropyScore(o) >= threshold;
}
private:
static int countDuplicates(const std::vector<std::string>& values) {
std::set<std::string> seen;
int duplicates = 0;
for (const auto& v : values) {
if (!seen.insert(v).second) ++duplicates;
}
return duplicates;
}
static int countPrefixSimilar(const std::vector<std::string>& names) {
int similar = 0;
for (std::size_t i = 0; i < names.size(); ++i) {
for (std::size_t j = i + 1; j < names.size(); ++j) {
if (names[i].size() >= 3 && names[j].rfind(names[i].substr(0, 3), 0) == 0) {
++similar;
}
}
}
return similar;
}
static int countUnused(const std::vector<std::string>& exports,
const std::set<std::string>& used) {
int unused = 0;
for (const auto& e : exports) {
if (used.find(e) == used.end()) ++unused;
}
return unused;
}
};

View File

@@ -0,0 +1,24 @@
// Step 659: Entropy scanner - editor side (12 tests)
#include "EntropyScannerModel.h"
#include <iostream>
static int p=0,f=0;
#define T(n) { std::cout<<" "<<#n<<"... "; }
#define P() { std::cout<<"PASS\n"; ++p; }
#define F(m) { std::cout<<"FAIL: "<<m<<"\n"; ++f; }
#define C(c,m) if(!(c)){F(m);return;}
void t1(){T(scan_counts_duplicate_signatures);auto o=EntropyScannerModel::scan({"a()","a()"},{},{},{});C(o.duplicateSignatures==1,"dup");P();}
void t2(){T(scan_counts_similar_module_names);auto o=EntropyScannerModel::scan({}, {"modAlpha","modBeta"},{},{});C(o.similarModuleNames>=1,"similar");P();}
void t3(){T(scan_counts_unused_exports);auto o=EntropyScannerModel::scan({}, {},{"x","y"},{"x"});C(o.unusedExports==1,"unused");P();}
void t4(){T(score_sums_components);EntropyObservation o{1,2,3};C(EntropyScannerModel::entropyScore(o)==6,"score");P();}
void t5(){T(suggest_refactor_true_at_threshold);EntropyObservation o{1,1,1};C(EntropyScannerModel::shouldSuggestRefactor(o,3),"suggest");P();}
void t6(){T(suggest_refactor_false_below_threshold);EntropyObservation o{1,0,0};C(!EntropyScannerModel::shouldSuggestRefactor(o,3),"no suggest");P();}
void t7(){T(empty_inputs_yield_zeroes);auto o=EntropyScannerModel::scan({}, {}, {}, {});C(o.duplicateSignatures==0&&o.similarModuleNames==0&&o.unusedExports==0,"zero");P();}
void t8(){T(multiple_duplicate_signatures_counted);auto o=EntropyScannerModel::scan({"a","a","a"},{},{},{});C(o.duplicateSignatures==2,"dups");P();}
void t9(){T(used_export_not_counted_unused);auto o=EntropyScannerModel::scan({}, {}, {"x"}, {"x"});C(o.unusedExports==0,"used");P();}
void t10(){T(threshold_parameter_changes_behavior);EntropyObservation o{1,1,0};C(EntropyScannerModel::shouldSuggestRefactor(o,2)&&!EntropyScannerModel::shouldSuggestRefactor(o,3),"threshold");P();}
void t11(){T(similar_prefix_requires_min_length);auto o=EntropyScannerModel::scan({}, {"ab","ac"},{},{});C(o.similarModuleNames==0,"prefix");P();}
void t12(){T(scan_combined_case);auto o=EntropyScannerModel::scan({"a","a"},{"modA","modB"},{"x"},{});C(EntropyScannerModel::entropyScore(o)>=3,"combined");P();}
int main(){std::cout<<"Step 659: Entropy scanner\n";t1();t2();t3();t4();t5();t6();t7();t8();t9();t10();t11();t12();std::cout<<"\nResults: "<<p<<"/"<<(p+f)<<" passed\n";return f?1:0;}