work on module ignoring

This commit is contained in:
John Bintz 2008-10-08 21:20:30 -04:00
parent a059b00bac
commit 09215aaeea
7 changed files with 128 additions and 41 deletions

22
README
View File

@ -5,7 +5,7 @@ To build & use Harmonious Code on Unix-like operating systems:
* Make sure you're running haXe 2.
* Download the PHP documentation from CVS.
* Copy/symlink the phpdoc/phpbook/phpbook-xsl/version.xml file from the
PHP documentationinto the data directory as version.xml.
PHP documentation into the data directory as version.xml.
* Run build/test.sh. This will take a while as functions_tokens_cache.hxd is
built in the data directory. It will also ensure everything's working
correctly.
@ -15,6 +15,26 @@ To build & use Harmonious Code on Unix-like operating systems:
* Run build/command_line.sh and pass the path to a PHP file as the first
parameter. A basic analysis should appear.
To automatically ignore certain tokens and modules, place lines like
the following in your code:
* To globally ignore a token (ex: json_decode()), place at the top of
the file the following:
//harmonious json_decode
* To ignore a token within a block of code, surround the code in the
following:
//harmonious json_decode
...your code...
//harmonious_end
* To ignore a particular module throughout the code (ex: maxdb), place
at the top of the file the following:
//harmonious @maxdb
No build instructions for Windows yet, but Cygwin + haXe for Windows should
be able to perform the build.

View File

@ -1,8 +1,10 @@
class CodeParser {
public var tokenProcessors(getTokenProcessors, null) : Hash<TokenProcessor>;
public var token_processors(get_token_processors, null) : Hash<TokenProcessor>;
public var ignored_modules(get_ignored_modules, null) : Hash<Bool>;
public function new() {
this.tokenProcessors = new Hash<TokenProcessor>();
this.token_processors = new Hash<TokenProcessor>();
this.ignored_modules = new Hash<Bool>();
}
#if neko
@ -13,7 +15,7 @@ class CodeParser {
functionProcessor.save_to_cache();
}
this.tokenProcessors.set(Type.getClassName(Type.getClass(functionProcessor)), functionProcessor);
this.token_processors.set(Type.getClassName(Type.getClass(functionProcessor)), functionProcessor);
}
#end
@ -21,10 +23,11 @@ class CodeParser {
var functionProcessor = new FunctionTokenProcessor();
functionProcessor.load_from_resource();
this.tokenProcessors.set(Type.getClassName(Type.getClass(functionProcessor)), functionProcessor);
this.token_processors.set(Type.getClassName(Type.getClass(functionProcessor)), functionProcessor);
}
public function getTokenProcessors() { return this.tokenProcessors; }
public function get_token_processors() { return this.token_processors; }
public function get_ignored_modules() { return this.ignored_modules; }
private function flatten_tokens_to_ignore(tokens_to_ignore : Array<Hash<Bool>>) : Hash<Bool> {
var flattened_tokens = new Hash<Bool>();
@ -38,8 +41,9 @@ class CodeParser {
public function parse(s : String) : Array<Result> {
var results = new Array<Result>();
this.ignored_modules = new Hash<Bool>();
var function_token_processor = this.tokenProcessors.get("FunctionTokenProcessor");
var function_token_processor = this.token_processors.get("FunctionTokenProcessor");
var function_tokens_found = new Hash<Bool>();
var tokens_to_ignore = new Array<Hash<Bool>>();
@ -120,7 +124,13 @@ class CodeParser {
new_tokens_to_ignore.shift();
var tokens_to_ignore_hash = new Hash<Bool>();
for (token in new_tokens_to_ignore) {
tokens_to_ignore_hash.set(token, true);
if (token.charAt(0) == "@") {
if (token.toLowerCase() != "@php") {
this.ignored_modules.set(token.substr(1), true);
}
} else {
tokens_to_ignore_hash.set(token, true);
}
}
tokens_to_ignore.push(tokens_to_ignore_hash);
}

View File

@ -106,27 +106,24 @@ class CodeVersionInformation {
var version_lists = new Hash<Array<String>>();
var version_match = ~/^([^\ ]+) (.*)$/;
for (part in s.split(", ")) {
if (version_match.match(part)) {
var source = version_match.matched(1);
if (!version_lists.exists(source)) {
version_lists.set(source, new Array<String>());
}
var tmp = version_lists.get(source);
tmp.push(version_match.matched(2));
version_lists.set(source, tmp);
var parts = breakdown_php_version_string(part);
var source = parts[0];
if (!version_lists.exists(source)) {
version_lists.set(source, new Array<String>());
}
var tmp = version_lists.get(source);
tmp.push(parts[1]);
version_lists.set(source, tmp);
}
var final_versions = new Hash<String>();
for (source in version_lists.keys()) {
var tmp = version_lists.get(source);
tmp.sort(CodeVersionInformation.version_compare);
final_versions.set(source, tmp.join(", "));
final_versions.set(source, CodeVersionInformation.get_lowest_version(version_lists.get(source)));
}
return final_versions;
}
public function new(results : Array<Result>) {
public function new(results : Array<Result>, ?ignored_modules : Hash<Bool>) {
var start_minimum_versions = new Hash<Array<String>>();
var start_maximum_versions = new Hash<Array<String>>();
@ -140,22 +137,29 @@ class CodeVersionInformation {
if (version_string_info.length > 0) {
var source = version_string_info[0];
if (!internal_minimum_version.exists(source)) {
internal_minimum_version.set(source, new Array<String>());
var ok_to_use = true;
if (ignored_modules != null) {
ok_to_use = !ignored_modules.exists(source);
}
var version_info = internal_minimum_version.get(source);
version_info.push(version_string_info[1]);
internal_minimum_version.set(source, version_info);
var is_lower_than = get_version_lower_than(part);
if (is_lower_than != null) {
if (!internal_maximum_version.exists(source)) {
internal_maximum_version.set(source, new Array<String>());
if (ok_to_use) {
if (!internal_minimum_version.exists(source)) {
internal_minimum_version.set(source, new Array<String>());
}
var version_info = internal_minimum_version.get(source);
version_info.push(version_string_info[1]);
internal_minimum_version.set(source, version_info);
var versions = internal_maximum_version.get(source);
versions.push(is_lower_than);
internal_maximum_version.set(source, versions);
var is_lower_than = get_version_lower_than(part);
if (is_lower_than != null) {
if (!internal_maximum_version.exists(source)) {
internal_maximum_version.set(source, new Array<String>());
}
var versions = internal_maximum_version.get(source);
versions.push(is_lower_than);
internal_maximum_version.set(source, versions);
}
}
}
}

View File

@ -2,6 +2,7 @@ class JavaScriptTarget {
static public var code_parser : CodeParser;
static public var current_results : Array<Result>;
static public var show_only_modules : Hash<Bool>;
static public var ignored_modules : Hash<Bool>;
static public function main() {
var function_token = new FunctionToken("a","a");
@ -10,6 +11,7 @@ class JavaScriptTarget {
code_parser.loadProcessorsFromResources();
show_only_modules = new Hash<Bool>();
ignored_modules = new Hash<Bool>();
#if js
var loading_div = js.Lib.document.getElementById("loading");
@ -22,6 +24,7 @@ class JavaScriptTarget {
static public function get_results(s : String) {
current_results = code_parser.parse(s);
ignored_modules = code_parser.ignored_modules;
}
static public function change_result(index_id : Int, state : Bool) : Bool {
@ -39,6 +42,17 @@ class JavaScriptTarget {
show_only_modules.set(module, !show_only_modules.get(module));
}
static public function change_module_ignore(module : String, state : Bool) {
ignored_modules.set(module, state);
}
static public function toggle_ignore_module(module: String) {
if (!ignored_modules.exists(module)) {
ignored_modules.set(module, false);
}
ignored_modules.set(module, !ignored_modules.get(module));
}
#if js
static public function change_result_and_redraw(result_checkbox : Dynamic) {
var index_id_search = ~/^result-enabled-([0-9]+)$/;
@ -51,12 +65,16 @@ class JavaScriptTarget {
}
static public function display_version_information() {
var version_info = new CodeVersionInformation(current_results);
var version_info = new CodeVersionInformation(current_results, ignored_modules);
var output = "Your code in requires the following minimum PHP & PECL module versions:<ul>";
var output = "Your code in requires the following minimum PHP & PECL module versions:";
var minimum = version_info.final_versions.get("minimum");
output += "<form action=\"\" onsubmit=\"return false\">";
output += "<ul>";
for (module in minimum.keys()) {
output += "<li>" + module + ": " + minimum.get(module) + "</li>";
}
@ -80,8 +98,6 @@ class JavaScriptTarget {
output += "<p><strong>This code may not run!</strong></p>";
}
output += "<form action=\"\" onsubmit=\"return false\">";
output += "<table cellspacing=\"0\" id=\"results-list\">";
output += "<tr><th>Token</th><th>Ignore?</th>";
@ -104,6 +120,7 @@ class JavaScriptTarget {
for (result in current_results) {
var ok_to_show = true;
var modules_check_out = true;
var any_visible_modules = false;
if (!result.is_enabled) { ignored_tokens.push(result.token); }
@ -116,7 +133,16 @@ class JavaScriptTarget {
}
}
for (module in max_versions.keys()) {
if (ignored_modules.exists(module)) {
if (!ignored_modules.get(module)) { any_visible_modules = true; }
} else {
any_visible_modules = true;
}
}
if (modules_check_out) { ok_to_show = true; }
if (!any_visible_modules) { ok_to_show = false; }
if (ok_to_show) {
var result_class = (result.is_enabled ? "enabled" : "disabled");
@ -174,5 +200,10 @@ class JavaScriptTarget {
JavaScriptTarget.toggle_module(module);
JavaScriptTarget.display_version_information();
}
static public function toggle_ignore_module_and_redraw(module : String) {
JavaScriptTarget.toggle_ignore_module(module);
JavaScriptTarget.display_version_information();
}
#end
}

View File

@ -5,14 +5,16 @@ class TestCodeParser extends haxe.unit.TestCase {
[ "this is my array_shift() json_encode() cpdf_arc()", "3", "{minimum => {PHP => 5.2.0, json => 1.2.0}, maximum => {PHP => 5.0.5}}" ],
[ "array_shift()", "1", "{minimum => {PHP => 4}, maximum => {}}" ],
[ "//harmonious json_encode\narray_shift() json_encode()\n//harmonious_end", "1", "{minimum => {PHP => 4}, maximum => {}}" ],
[ "//harmonious json_encode\narray_shift() json_encode()\n//harmonious_end\njson_encode()", "2", "{minimum => {PHP => 5.2.0, json => 1.2.0}, maximum => {}}" ]
[ "//harmonious json_encode\narray_shift() json_encode()\n//harmonious_end\njson_encode()", "2", "{minimum => {PHP => 5.2.0, json => 1.2.0}, maximum => {}}" ],
[ "//harmonious @json\narray_shift() json_encode()\n//harmonious_end\njson_encode()", "2", "{minimum => {PHP => 5.2.0}, maximum => {}}" ],
[ "//harmonious @PHP\narray_shift()", "1", "{minimum => {PHP => 4}, maximum => {}}" ]
];
#if neko
function testCodeParserLoadTokens() {
var p = new CodeParser();
p.loadProcessorsFromDisk();
assertTrue(p.tokenProcessors.exists("FunctionTokenProcessor"));
assertTrue(p.token_processors.exists("FunctionTokenProcessor"));
}
function testProcessCode() {
@ -21,8 +23,9 @@ class TestCodeParser extends haxe.unit.TestCase {
for (code in test_code) {
var result = p.parse(code[0]);
var ignored_modules = p.ignored_modules;
assertEquals(Std.parseInt(code[1]), result.length);
var code_version_info = new CodeVersionInformation(result);
var code_version_info = new CodeVersionInformation(result, ignored_modules);
assertEquals(code[2], code_version_info.final_versions.toString());
}
}

View File

@ -70,8 +70,8 @@ class TestCodeVersionInformation extends haxe.unit.TestCase {
function testGetVersionStringSplit() {
assertEquals("{xmlwriter => 2.0.4, PHP => 4}", CodeVersionInformation.split_version_string("PHP 4, xmlwriter 2.0.4").toString());
assertEquals("{xmlwriter => 2.0.4, PHP => 4 &gt;= 4.0.3}", CodeVersionInformation.split_version_string("PHP 4 &gt;= 4.0.3, xmlwriter 2.0.4").toString());
assertEquals("{PHP => 4, 5}", CodeVersionInformation.split_version_string("PHP 5, PHP 4").toString());
assertEquals("{xmlwriter => 2.0.4, PHP => 4.0.3}", CodeVersionInformation.split_version_string("PHP 4 &gt;= 4.0.3, xmlwriter 2.0.4").toString());
assertEquals("{PHP => 4}", CodeVersionInformation.split_version_string("PHP 5, PHP 4").toString());
}
function testGetModuleInformation() {
@ -83,4 +83,17 @@ class TestCodeVersionInformation extends haxe.unit.TestCase {
assertEquals("[PHP, xmod, zmod]", v.all_modules.toString());
}
function testIgnoreModules() {
var valid_results = [
new Result(ResultType.Function, "one", "PHP 4, zmod 5"),
new Result(ResultType.Function, "two", "PHP 4 &gt;= 4.0.6, xmod 5"),
new Result(ResultType.Function, "three", "zmod 5"),
];
var ignored_modules = new Hash<Bool>();
ignored_modules.set("xmod", true);
var v = new CodeVersionInformation(valid_results, ignored_modules);
assertEquals("[PHP, zmod]", v.all_modules.toString());
}
}

View File

@ -14,5 +14,11 @@ class TestJavaScriptTarget extends haxe.unit.TestCase {
assertEquals("{}", JavaScriptTarget.show_only_modules.toString());
JavaScriptTarget.toggle_module("zip");
assertEquals("{zip => true}", JavaScriptTarget.show_only_modules.toString());
assertEquals("{}", JavaScriptTarget.ignored_modules.toString());
JavaScriptTarget.change_module_ignore("zip", true);
assertEquals("{zip => true}", JavaScriptTarget.ignored_modules.toString());
JavaScriptTarget.change_module_ignore("zip", false);
assertEquals("{zip => false}", JavaScriptTarget.ignored_modules.toString());
}
}