initial commit, all seems to work
This commit is contained in:
commit
59a795ee9d
|
@ -0,0 +1,14 @@
|
||||||
|
Harmonious Code is Copyright 2008 John Bintz.
|
||||||
|
|
||||||
|
Harmonious Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Harmonious Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
|
@ -0,0 +1,8 @@
|
||||||
|
To build Harmonious Code:
|
||||||
|
|
||||||
|
* 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
|
||||||
|
* Run test.sh. This will take a while as functions_tokens_cache.hxd is
|
||||||
|
built in the data directory.
|
|
@ -0,0 +1,3 @@
|
||||||
|
-main CommandLineInterface
|
||||||
|
-neko ../neko/codeparser.n
|
||||||
|
-cp ../src
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
./setup.sh
|
||||||
|
haxe command_line.hxml && neko ../neko/codeparser.n $1 $2 $3 $4 $5
|
|
@ -0,0 +1,4 @@
|
||||||
|
-js ../htdocs/harmoniouscode.js
|
||||||
|
-main JavaScriptTarget
|
||||||
|
-resource ../data/functions_tokens_cache.hxd
|
||||||
|
-cp ../src
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
./setup.sh
|
||||||
|
haxe -cp ../src -neko ../neko/regenerate.n -main RegenerateDataFiles && neko ../neko/regenerate.n
|
||||||
|
rm ../htdocs/harmoniouscode.js
|
||||||
|
haxe javascript.hxml
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
for dir in neko data; do
|
||||||
|
if [ ! -e "../${dir}" ]; then mkdir "../${dir}" 2>&1; fi
|
||||||
|
done
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
./setup.sh
|
||||||
|
haxe tests.hxml && neko ../neko/my_tests.n
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
-main MyTests
|
||||||
|
-neko ../neko/my_tests.n
|
||||||
|
-resource ../data/functions_tokens_cache.hxd
|
||||||
|
-cp ../src
|
|
@ -0,0 +1,43 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Harmonious Code: Will my PHP code and Web hosting work together?</title>
|
||||||
|
<meta name="keywords" content="php, static code analysis, web hosting, functions, constants, language features" />
|
||||||
|
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Harmonious Code</h1>
|
||||||
|
<div id="loading">
|
||||||
|
Loading...
|
||||||
|
</div>
|
||||||
|
<div id="form" style="display: none">
|
||||||
|
<div id="form-holder">
|
||||||
|
<form action="" method="post" onsubmit="return false;">
|
||||||
|
<textarea name="source" id="source" rows="15" cols="80"></textarea><br />
|
||||||
|
<input id="analyze-code-button" type="button" value="Analyze Code" onclick="JavaScriptTarget.do_analysis(this.form.elements.source)" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div id="output"></div>
|
||||||
|
<div id="permanent-ignore" style="display: none">
|
||||||
|
To permanently ignore tokens, do one of the following:
|
||||||
|
<ul>
|
||||||
|
<li>To ignore globally, place at the top of the file on its own line:
|
||||||
|
<blockquote><code>//harmonious <span class="ignore-code-holder"></span></code></blockquote>
|
||||||
|
</li>
|
||||||
|
<li>To ignore within a particular block of code, wrap the code in the following:
|
||||||
|
<blockquote><code>//harmonious <span class="ignore-code-holder"></span><br />
|
||||||
|
...your code...<br />
|
||||||
|
//harmonious_end</code></blockquote>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="local-info">
|
||||||
|
<?php @include('local-info.php') ?>
|
||||||
|
</div>
|
||||||
|
<div id="haxe:trace"></div>
|
||||||
|
<div id="footer">
|
||||||
|
Harmonious Code is Copyright © 2008 John Bintz — Licensed under the GPL Version 2
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript" src="harmoniouscode.js"> </script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,73 @@
|
||||||
|
body {
|
||||||
|
background-color: #def
|
||||||
|
}
|
||||||
|
|
||||||
|
body, td, div, li, p, span {
|
||||||
|
font-family: tahoma, verdana, arial, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#form-holder {
|
||||||
|
text-align: center
|
||||||
|
}
|
||||||
|
|
||||||
|
input#analyze-code-button {
|
||||||
|
width: 200px;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#loading {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-left: solid #aaa 1px
|
||||||
|
}
|
||||||
|
|
||||||
|
td, th {
|
||||||
|
border-right: solid #aaa 1px
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 0 3px
|
||||||
|
}
|
||||||
|
|
||||||
|
td.token {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.enabled {
|
||||||
|
background-color: #bfb
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
padding: 0 15px
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.disabled {
|
||||||
|
background-color: #fbb
|
||||||
|
}
|
||||||
|
|
||||||
|
th.filter {
|
||||||
|
text-decoration: underline;
|
||||||
|
cursor: pointer;
|
||||||
|
cursor: hand;
|
||||||
|
}
|
||||||
|
|
||||||
|
th.is-filtering {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#footer {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 10px;
|
||||||
|
color: #555;
|
||||||
|
font-style: oblique
|
||||||
|
}
|
||||||
|
|
||||||
|
span.ignore-code-holder {
|
||||||
|
font-family: monospace
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
class CodeParser {
|
||||||
|
public var tokenProcessors(getTokenProcessors, null) : Hash<TokenProcessor>;
|
||||||
|
|
||||||
|
public function new() {
|
||||||
|
this.tokenProcessors = new Hash<TokenProcessor>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if neko
|
||||||
|
public function loadProcessorsFromDisk() {
|
||||||
|
var functionProcessor = new FunctionTokenProcessor();
|
||||||
|
if (!functionProcessor.load_from_cache()) {
|
||||||
|
functionProcessor.populate_from_file();
|
||||||
|
functionProcessor.save_to_cache();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tokenProcessors.set(Type.getClassName(Type.getClass(functionProcessor)), functionProcessor);
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
|
||||||
|
public function loadProcessorsFromResources() {
|
||||||
|
var functionProcessor = new FunctionTokenProcessor();
|
||||||
|
functionProcessor.load_from_resource();
|
||||||
|
|
||||||
|
this.tokenProcessors.set(Type.getClassName(Type.getClass(functionProcessor)), functionProcessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTokenProcessors() { return this.tokenProcessors; }
|
||||||
|
|
||||||
|
private function flatten_tokens_to_ignore(tokens_to_ignore : Array<Hash<Bool>>) : Hash<Bool> {
|
||||||
|
var flattened_tokens = new Hash<Bool>();
|
||||||
|
for (token_hash in tokens_to_ignore) {
|
||||||
|
for (token in token_hash.keys()) {
|
||||||
|
flattened_tokens.set(token, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return flattened_tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parse(s : String) : Array<Result> {
|
||||||
|
var results = new Array<Result>();
|
||||||
|
|
||||||
|
var function_token_processor = this.tokenProcessors.get("FunctionTokenProcessor");
|
||||||
|
|
||||||
|
var function_tokens_found = new Hash<Bool>();
|
||||||
|
var tokens_to_ignore = new Array<Hash<Bool>>();
|
||||||
|
var flattened_tokens = new Hash<Bool>();
|
||||||
|
|
||||||
|
var index = 0;
|
||||||
|
var capture_index = null;
|
||||||
|
var s_length = s.length;
|
||||||
|
var is_capturing = false;
|
||||||
|
|
||||||
|
var capturable_search = ~/[a-zA-Z0-9\_]/;
|
||||||
|
var stoppable_search = ~/[a-zA-Z0-9\_\/]/;
|
||||||
|
|
||||||
|
while (index < s_length) {
|
||||||
|
var current = s.charAt(index);
|
||||||
|
var is_capturable = capturable_search.match(current);
|
||||||
|
|
||||||
|
if (is_capturable) {
|
||||||
|
if (!is_capturing) {
|
||||||
|
is_capturing = true;
|
||||||
|
capture_index = index;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (is_capturing) {
|
||||||
|
var token = s.substr(capture_index, index - capture_index);
|
||||||
|
|
||||||
|
var is_function = false;
|
||||||
|
var is_function_searching = true;
|
||||||
|
var paren_search_index = index;
|
||||||
|
|
||||||
|
do {
|
||||||
|
var function_character = s.charAt(paren_search_index);
|
||||||
|
if (function_character == "(") {
|
||||||
|
is_function = true;
|
||||||
|
is_function_searching = false;
|
||||||
|
index = paren_search_index;
|
||||||
|
} else {
|
||||||
|
if (stoppable_search.match(function_character)) {
|
||||||
|
is_function_searching = false;
|
||||||
|
index = paren_search_index - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_function_searching) {
|
||||||
|
paren_search_index++;
|
||||||
|
if (paren_search_index >= s_length) {
|
||||||
|
is_function_searching = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (is_function_searching);
|
||||||
|
|
||||||
|
is_capturing = false;
|
||||||
|
|
||||||
|
if (!flattened_tokens.exists(token)) {
|
||||||
|
if (is_function) {
|
||||||
|
if (!function_tokens_found.exists(token)) {
|
||||||
|
if (function_token_processor.tokenHash.exists(token)) {
|
||||||
|
results.push(function_token_processor.tokenHash.get(token).toResult());
|
||||||
|
}
|
||||||
|
function_tokens_found.set(token, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (current == "/") {
|
||||||
|
if (s.indexOf("//harmonious", index) == index) {
|
||||||
|
var end_of_line = s.indexOf("\n", index);
|
||||||
|
var ok_to_capture = false;
|
||||||
|
if (end_of_line > index) { ok_to_capture = true; }
|
||||||
|
if (end_of_line == -1) {
|
||||||
|
ok_to_capture = true;
|
||||||
|
end_of_line = s_length - 1;
|
||||||
|
}
|
||||||
|
if (ok_to_capture) {
|
||||||
|
if (s.indexOf("//harmonious_end", index) == index) {
|
||||||
|
tokens_to_ignore.pop();
|
||||||
|
} else {
|
||||||
|
var new_tokens_to_ignore = s.substr(index, end_of_line - index).split(" ");
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
tokens_to_ignore.push(tokens_to_ignore_hash);
|
||||||
|
}
|
||||||
|
flattened_tokens = flatten_tokens_to_ignore(tokens_to_ignore);
|
||||||
|
index = end_of_line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
results.sort(Result.compare);
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
class CodeToken {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,204 @@
|
||||||
|
class CodeVersionInformation {
|
||||||
|
public var final_versions : Hash<Hash<String>>;
|
||||||
|
public var minimum_versions : Hash<String>;
|
||||||
|
public var maximum_versions : Hash<String>;
|
||||||
|
public var all_modules : Array<String>;
|
||||||
|
|
||||||
|
public static function breakdown_version_number(version : String) {
|
||||||
|
return version.split(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function get_version_lower_than(s : String) : String {
|
||||||
|
var greater_than = ~/\<= (.*)$/;
|
||||||
|
|
||||||
|
if (greater_than.match(s)) {
|
||||||
|
return greater_than.matched(1);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function breakdown_php_version_string(s : String) {
|
||||||
|
var parts = new Array<String>();
|
||||||
|
|
||||||
|
for (regexp in [ ~/^([^\ ]*) (.*)$/ ]) {
|
||||||
|
if (regexp.match(s)) {
|
||||||
|
var version = regexp.matched(2).split("-").shift();
|
||||||
|
|
||||||
|
var greater_than = ~/\>= (.*)$/;
|
||||||
|
if (greater_than.match(version)) {
|
||||||
|
version = greater_than.matched(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
parts.push(regexp.matched(1));
|
||||||
|
parts.push(version);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function get_highest_version(versions : Array<String>) : String {
|
||||||
|
return get_terminal_version(versions, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function get_lowest_version(versions : Array<String>) : String {
|
||||||
|
return get_terminal_version(versions, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function version_compare(one : String, two : String) {
|
||||||
|
var one_parts = one.split(".");
|
||||||
|
var two_parts = two.split(".");
|
||||||
|
var shortest = Math.floor(Math.min(one_parts.length, two_parts.length));
|
||||||
|
for (i in 0...shortest) {
|
||||||
|
var one_int = Std.parseInt(one_parts[i]);
|
||||||
|
var two_int = Std.parseInt(two_parts[i]);
|
||||||
|
if (one_int != two_int) {
|
||||||
|
return (one_int < two_int) ? -1 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (one_parts.length < two_parts.length) { return -1; }
|
||||||
|
if (one_parts.length > two_parts.length) { return 1; }
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function get_terminal_version(versions : Array<String>, ?find_highest : Bool = true) : String {
|
||||||
|
var terminal_version = null;
|
||||||
|
|
||||||
|
for (version in versions) {
|
||||||
|
if (terminal_version == null) {
|
||||||
|
terminal_version = version;
|
||||||
|
} else {
|
||||||
|
switch (version_compare(terminal_version, version)) {
|
||||||
|
case -1:
|
||||||
|
terminal_version = (find_highest) ? version : terminal_version;
|
||||||
|
case 1:
|
||||||
|
terminal_version = (find_highest) ? terminal_version : version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (terminal_version != null) {
|
||||||
|
return terminal_version;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function merge_versions(target_hash : Hash<Array<String>>,
|
||||||
|
source_hash : Hash<Array<String>>,
|
||||||
|
is_lower : Bool) : Hash<Array<String>> {
|
||||||
|
for (source in source_hash.keys()) {
|
||||||
|
if (!target_hash.exists(source)) { target_hash.set(source, new Array<String>()); }
|
||||||
|
var version_info = target_hash.get(source);
|
||||||
|
if (is_lower) {
|
||||||
|
version_info.push(get_lowest_version(source_hash.get(source)));
|
||||||
|
} else {
|
||||||
|
version_info.push(get_highest_version(source_hash.get(source)));
|
||||||
|
}
|
||||||
|
target_hash.set(source, version_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return target_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function split_version_string(s : String) : Hash<String> {
|
||||||
|
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 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(", "));
|
||||||
|
}
|
||||||
|
return final_versions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function new(results : Array<Result>) {
|
||||||
|
var start_minimum_versions = new Hash<Array<String>>();
|
||||||
|
var start_maximum_versions = new Hash<Array<String>>();
|
||||||
|
|
||||||
|
for (result in results) {
|
||||||
|
if (result.is_enabled) {
|
||||||
|
var internal_minimum_version = new Hash<Array<String>>();
|
||||||
|
var internal_maximum_version = new Hash<Array<String>>();
|
||||||
|
|
||||||
|
for (part in result.version.split(", ")) {
|
||||||
|
var version_string_info = breakdown_php_version_string(part);
|
||||||
|
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 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>());
|
||||||
|
}
|
||||||
|
|
||||||
|
var versions = internal_maximum_version.get(source);
|
||||||
|
versions.push(is_lower_than);
|
||||||
|
internal_maximum_version.set(source, versions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
merge_versions(start_minimum_versions, internal_minimum_version, true);
|
||||||
|
merge_versions(start_maximum_versions, internal_maximum_version, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.minimum_versions = new Hash<String>();
|
||||||
|
this.maximum_versions = new Hash<String>();
|
||||||
|
this.all_modules = new Array<String>();
|
||||||
|
|
||||||
|
for (source in start_minimum_versions.keys()) {
|
||||||
|
this.minimum_versions.set(source, get_highest_version(start_minimum_versions.get(source)));
|
||||||
|
this.all_modules.push(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.all_modules.sort(function(a, b) {
|
||||||
|
if (a == "PHP") { return -1; }
|
||||||
|
if (b == "PHP") { return -1; }
|
||||||
|
if (a == b) { return 0; }
|
||||||
|
return (a < b) ? -1 : 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (source in start_maximum_versions.keys()) {
|
||||||
|
this.maximum_versions.set(source, get_lowest_version(start_maximum_versions.get(source)));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.final_versions = new Hash<Hash<String>>();
|
||||||
|
|
||||||
|
this.final_versions.set("minimum", minimum_versions);
|
||||||
|
this.final_versions.set("maximum", maximum_versions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function is_valid() {
|
||||||
|
for (source in this.maximum_versions.keys()) {
|
||||||
|
var versions = [ this.maximum_versions.get(source), this.minimum_versions.get(source) ];
|
||||||
|
|
||||||
|
if (get_highest_version(versions) == this.minimum_versions.get(source)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
class CommandLineInterface {
|
||||||
|
static public function main() {
|
||||||
|
var arguments = neko.Sys.args();
|
||||||
|
|
||||||
|
if (arguments.length > 0) {
|
||||||
|
if (neko.FileSystem.exists(arguments[0])) {
|
||||||
|
var code = neko.io.File.getContent(arguments[0]);
|
||||||
|
|
||||||
|
var parser = new CodeParser();
|
||||||
|
parser.loadProcessorsFromDisk();
|
||||||
|
|
||||||
|
var results = parser.parse(code);
|
||||||
|
|
||||||
|
var version_info = new CodeVersionInformation(results);
|
||||||
|
|
||||||
|
neko.Lib.print("Your code in " + arguments[0] + " requires the following minimum PHP & PECL module versions:\n");
|
||||||
|
|
||||||
|
var minimum = version_info.final_versions.get("minimum");
|
||||||
|
|
||||||
|
for (module in minimum.keys()) {
|
||||||
|
neko.Lib.print("* " + module + ": " + minimum.get(module) + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
var maximum = version_info.final_versions.get("maximum");
|
||||||
|
var printed_message = false;
|
||||||
|
|
||||||
|
for (module in maximum.keys()) {
|
||||||
|
if (!printed_message) {
|
||||||
|
neko.Lib.print("Your code also can't use PHP or PECL modules newer than:\n");
|
||||||
|
printed_message = true;
|
||||||
|
}
|
||||||
|
neko.Lib.print("* " + module + ": " + maximum.get(module) + "\n");
|
||||||
|
|
||||||
|
if (!version_info.is_valid()) {
|
||||||
|
neko.Lib.print("This code may not run!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
class ConstantToken extends Token {
|
||||||
|
override public function getTokenType() {
|
||||||
|
return ResultType.Constant;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
class ConstantTokenProcessor extends TokenProcessor {
|
||||||
|
public static var cachePath : String = "constant_tokens_cache.hxd";
|
||||||
|
override public function get_cache_path() { return ConstantTokenProcessor.cachePath; }
|
||||||
|
|
||||||
|
#if neko
|
||||||
|
public function populate_from_file(path : String) {
|
||||||
|
this.populate_from_string(neko.io.File.getContent(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function populate_from_string(s : String) {
|
||||||
|
this.tokenHash = new Hash<Token>();
|
||||||
|
for (child in Xml.parse(s).firstElement()) {
|
||||||
|
if (child.nodeType == Xml.Element) {
|
||||||
|
if (child.nodeName == "function") {
|
||||||
|
var version = child.get("from");
|
||||||
|
version = ~/PECL /.replace(version, "");
|
||||||
|
version = ~/\:/.replace(version, " ");
|
||||||
|
var token = child.get("name");
|
||||||
|
this.tokenHash.set(token, new FunctionToken(child.get("name"), version));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
class FunctionToken extends Token {
|
||||||
|
override public function getTokenType() {
|
||||||
|
return ResultType.Function;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
class FunctionTokenProcessor extends TokenProcessor {
|
||||||
|
public static var cachePath : String = "../data/functions_tokens_cache.hxd";
|
||||||
|
override public function get_cache_path() { return FunctionTokenProcessor.cachePath; }
|
||||||
|
public static var sourcePath : String = "../data/versions.xml";
|
||||||
|
|
||||||
|
#if neko
|
||||||
|
public function populate_from_file() {
|
||||||
|
this.populate_from_string(neko.io.File.getContent(sourcePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function populate_from_string(s : String) {
|
||||||
|
this.tokenHash = new Hash<Token>();
|
||||||
|
for (child in Xml.parse(s).firstElement()) {
|
||||||
|
if (child.nodeType == Xml.Element) {
|
||||||
|
if (child.nodeName == "function") {
|
||||||
|
var version = child.get("from");
|
||||||
|
version = ~/PECL /.replace(version, "");
|
||||||
|
version = ~/\:/.replace(version, " ");
|
||||||
|
var token = child.get("name");
|
||||||
|
this.tokenHash.set(token, new FunctionToken(child.get("name"), version));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
class JavaScriptCallback {
|
||||||
|
public function parse(t : Token) {
|
||||||
|
js.Lib.document.getElementById("Current token: " + t.token);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,178 @@
|
||||||
|
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 function main() {
|
||||||
|
var function_token = new FunctionToken("a","a");
|
||||||
|
|
||||||
|
code_parser = new CodeParser();
|
||||||
|
code_parser.loadProcessorsFromResources();
|
||||||
|
|
||||||
|
show_only_modules = new Hash<Bool>();
|
||||||
|
|
||||||
|
#if js
|
||||||
|
var loading_div = js.Lib.document.getElementById("loading");
|
||||||
|
var form_div = js.Lib.document.getElementById("form");
|
||||||
|
|
||||||
|
loading_div.style.display = "none";
|
||||||
|
form_div.style.display = "";
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function get_results(s : String) {
|
||||||
|
current_results = code_parser.parse(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function change_result(index_id : Int, state : Bool) : Bool {
|
||||||
|
if (index_id < current_results.length) {
|
||||||
|
current_results[index_id].is_enabled = state;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function toggle_module(module : String) {
|
||||||
|
if (!show_only_modules.exists(module)) {
|
||||||
|
show_only_modules.set(module, false);
|
||||||
|
}
|
||||||
|
show_only_modules.set(module, !show_only_modules.get(module));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if js
|
||||||
|
static public function change_result_and_redraw(result_checkbox : Dynamic) {
|
||||||
|
var index_id_search = ~/^result-enabled-([0-9]+)$/;
|
||||||
|
if (index_id_search.match(result_checkbox.id)) {
|
||||||
|
var index_id = Std.parseInt(index_id_search.matched(1));
|
||||||
|
if (change_result(index_id, !result_checkbox.checked)) {
|
||||||
|
display_version_information();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function display_version_information() {
|
||||||
|
var version_info = new CodeVersionInformation(current_results);
|
||||||
|
|
||||||
|
var output = "Your code in requires the following minimum PHP & PECL module versions:<ul>";
|
||||||
|
|
||||||
|
var minimum = version_info.final_versions.get("minimum");
|
||||||
|
|
||||||
|
for (module in minimum.keys()) {
|
||||||
|
output += "<li>" + module + ": " + minimum.get(module) + "</li>";
|
||||||
|
}
|
||||||
|
|
||||||
|
output += "</ul>";
|
||||||
|
|
||||||
|
var maximum = version_info.final_versions.get("maximum");
|
||||||
|
var printed_message = false;
|
||||||
|
|
||||||
|
for (module in maximum.keys()) {
|
||||||
|
if (!printed_message) {
|
||||||
|
output += "Your code also can't use PHP or PECL modules newer than:<ul>";
|
||||||
|
printed_message = true;
|
||||||
|
}
|
||||||
|
output += ("<li>" + module + ": " + maximum.get(module) + "</li>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (printed_message) { output += "</ul>"; }
|
||||||
|
|
||||||
|
if (!version_info.is_valid()) {
|
||||||
|
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>";
|
||||||
|
|
||||||
|
for (module in version_info.all_modules) {
|
||||||
|
var classes = ["filter"];
|
||||||
|
if (show_only_modules.exists(module)) {
|
||||||
|
if (show_only_modules.get(module)) {
|
||||||
|
classes.push("is-filtering");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output += "<th title=\"click to toggle filter\" class=\"" + classes.join(" ") + "\" onclick=\"JavaScriptTarget.toggle_module_and_redraw('" + module + "')\">" + module + "</th>";
|
||||||
|
}
|
||||||
|
|
||||||
|
output += "</tr>";
|
||||||
|
|
||||||
|
var ignored_tokens = new Array<String>();
|
||||||
|
|
||||||
|
var id_index = 0;
|
||||||
|
for (result in current_results) {
|
||||||
|
var ok_to_show = true;
|
||||||
|
var modules_check_out = true;
|
||||||
|
|
||||||
|
if (!result.is_enabled) { ignored_tokens.push(result.token); }
|
||||||
|
|
||||||
|
var max_versions = CodeVersionInformation.split_version_string(result.version);
|
||||||
|
|
||||||
|
for (module in show_only_modules.keys()) {
|
||||||
|
if (show_only_modules.get(module)) {
|
||||||
|
ok_to_show = false;
|
||||||
|
if (!max_versions.exists(module)) { modules_check_out = false; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modules_check_out) { ok_to_show = true; }
|
||||||
|
|
||||||
|
if (ok_to_show) {
|
||||||
|
var result_class = (result.is_enabled ? "enabled" : "disabled");
|
||||||
|
var result_id = "result-" + id_index;
|
||||||
|
var enabled_id = "result-enabled-" + id_index;
|
||||||
|
output += "<tr id=\"" + result_id + "\" class=\"" + result_class + "\">";
|
||||||
|
|
||||||
|
output += "<td class=\"token\">" + result.token + "</td>";
|
||||||
|
|
||||||
|
output += "<td align=\"center\"><input onclick=\"JavaScriptTarget.change_result_and_redraw(this)\" type=\"checkbox\" name=\"" + enabled_id + "\" id=\"" + enabled_id + "\""
|
||||||
|
+ ((!result.is_enabled) ? " checked" : "") + " /></td>";
|
||||||
|
|
||||||
|
for (module in version_info.all_modules) {
|
||||||
|
output += "<td>";
|
||||||
|
if (max_versions.exists(module)) {
|
||||||
|
output += max_versions.get(module);
|
||||||
|
} else {
|
||||||
|
output += " ";
|
||||||
|
}
|
||||||
|
output += "</td>";
|
||||||
|
}
|
||||||
|
|
||||||
|
output += "</tr>";
|
||||||
|
id_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output += "</table>";
|
||||||
|
|
||||||
|
output += "</form>";
|
||||||
|
|
||||||
|
var permanent_ignore_div = js.Lib.document.getElementById('permanent-ignore');
|
||||||
|
if (ignored_tokens.length > 0) {
|
||||||
|
var spans = js.Lib.document.getElementsByTagName("span");
|
||||||
|
for (span_index in 0...spans.length) {
|
||||||
|
if (spans[span_index].className == "ignore-code-holder") {
|
||||||
|
spans[span_index].innerHTML = ignored_tokens.join(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
permanent_ignore_div.style.display = "";
|
||||||
|
} else {
|
||||||
|
permanent_ignore_div.style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
js.Lib.document.getElementById('output').innerHTML = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function do_analysis(textarea) {
|
||||||
|
show_only_modules = new Hash<Bool>();
|
||||||
|
|
||||||
|
JavaScriptTarget.get_results(textarea.value);
|
||||||
|
JavaScriptTarget.display_version_information();
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function toggle_module_and_redraw(module : String) {
|
||||||
|
JavaScriptTarget.toggle_module(module);
|
||||||
|
JavaScriptTarget.display_version_information();
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
class MyTests {
|
||||||
|
static function main() {
|
||||||
|
var r = new haxe.unit.TestRunner();
|
||||||
|
r.add(new TestToken());
|
||||||
|
r.add(new TestFunctionToken());
|
||||||
|
r.add(new TestFunctionTokenProcessor());
|
||||||
|
r.add(new TestConstantToken());
|
||||||
|
r.add(new TestCodeParser());
|
||||||
|
r.add(new TestCodeVersionInformation());
|
||||||
|
r.add(new TestResult());
|
||||||
|
r.add(new TestJavaScriptTarget());
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
class RegenerateDataFiles {
|
||||||
|
public static function main() {
|
||||||
|
var functionProcessor = new FunctionTokenProcessor();
|
||||||
|
if (!functionProcessor.load_from_cache()) {
|
||||||
|
neko.Lib.print("Regenerating functions cache...\n");
|
||||||
|
functionProcessor.populate_from_file();
|
||||||
|
functionProcessor.save_to_cache();
|
||||||
|
}
|
||||||
|
|
||||||
|
var constantProcessor = new ConstantTokenProcessor();
|
||||||
|
if (!constantProcessor.load_from_cache()) {
|
||||||
|
neko.Lib.print("Regenerating constants cache...\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
class Result {
|
||||||
|
public var type(getType, null) : ResultType;
|
||||||
|
public var token(getToken, null) : String;
|
||||||
|
public var version(getVersion, null) : String;
|
||||||
|
public var is_enabled : Bool;
|
||||||
|
|
||||||
|
public function new(type : ResultType, token : String, version : String) {
|
||||||
|
this.type = type;
|
||||||
|
this.token = token;
|
||||||
|
this.version = version;
|
||||||
|
this.is_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getType() { return this.type; }
|
||||||
|
public function getToken() { return this.token; }
|
||||||
|
public function getVersion() { return this.version; }
|
||||||
|
|
||||||
|
public static function change_enabled(results : Array<Result>, token : String, set_is_enabled : Bool) {
|
||||||
|
for (result in results) {
|
||||||
|
if (result.token == token) {
|
||||||
|
result.is_enabled = set_is_enabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function compare(a : Result, b : Result) : Int{
|
||||||
|
if (a.token == b.token) { return 0; }
|
||||||
|
return (a.token < b.token) ? -1 : 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
enum ResultType {
|
||||||
|
Generic;
|
||||||
|
Function;
|
||||||
|
Constant;
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
class TestCodeParser extends haxe.unit.TestCase {
|
||||||
|
static var test_code = [
|
||||||
|
[ "this is my array_shift() method", "1", "{minimum => {PHP => 4}, maximum => {}}" ],
|
||||||
|
[ "this is my array_shift() json_encode() method", "2", "{minimum => {PHP => 5.2.0, json => 1.2.0}, maximum => {}}" ],
|
||||||
|
[ "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 => {}}" ]
|
||||||
|
];
|
||||||
|
|
||||||
|
#if neko
|
||||||
|
function testCodeParserLoadTokens() {
|
||||||
|
var p = new CodeParser();
|
||||||
|
p.loadProcessorsFromDisk();
|
||||||
|
assertTrue(p.tokenProcessors.exists("FunctionTokenProcessor"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testProcessCode() {
|
||||||
|
var p = new CodeParser();
|
||||||
|
p.loadProcessorsFromDisk();
|
||||||
|
|
||||||
|
for (code in test_code) {
|
||||||
|
var result = p.parse(code[0]);
|
||||||
|
assertEquals(Std.parseInt(code[1]), result.length);
|
||||||
|
var code_version_info = new CodeVersionInformation(result);
|
||||||
|
assertEquals(code[2], code_version_info.final_versions.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
class TestCodeVersionInformation extends haxe.unit.TestCase {
|
||||||
|
function testIsInvalid() {
|
||||||
|
var valid_results = [
|
||||||
|
new Result(ResultType.Function, "one", "PHP 4, PHP 5"),
|
||||||
|
new Result(ResultType.Function, "two", "PHP 4 <= 4.2.0")
|
||||||
|
];
|
||||||
|
|
||||||
|
var code_version_info = new CodeVersionInformation(valid_results);
|
||||||
|
assertTrue(code_version_info.is_valid());
|
||||||
|
|
||||||
|
var invalid_results = [
|
||||||
|
new Result(ResultType.Function, "one", "PHP 5 >= 5.2.0"),
|
||||||
|
new Result(ResultType.Function, "two", "PHP 4 <= 4.2.0")
|
||||||
|
];
|
||||||
|
|
||||||
|
var code_version_info = new CodeVersionInformation(invalid_results);
|
||||||
|
assertFalse(code_version_info.is_valid());
|
||||||
|
}
|
||||||
|
|
||||||
|
function testBreakdownVersionString() {
|
||||||
|
assertEquals("[PHP, 4]", CodeVersionInformation.breakdown_php_version_string("PHP 4").toString());
|
||||||
|
assertEquals("[PHP, 5.2.0]", CodeVersionInformation.breakdown_php_version_string("PHP 5 >= 5.2.0").toString());
|
||||||
|
assertEquals("[xmlwriter, 2.0.4]", CodeVersionInformation.breakdown_php_version_string("xmlwriter 2.0.4").toString());
|
||||||
|
|
||||||
|
assertEquals("[xmlwriter, 0.1]", CodeVersionInformation.breakdown_php_version_string("xmlwriter 0.1-2.0.4").toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
function testVersionCompare() {
|
||||||
|
assertEquals(-1, CodeVersionInformation.version_compare("4", "5"));
|
||||||
|
assertEquals(1, CodeVersionInformation.version_compare("5", "4"));
|
||||||
|
assertEquals(-1, CodeVersionInformation.version_compare("4", "4.5"));
|
||||||
|
assertEquals(1, CodeVersionInformation.version_compare("4.5", "4"));
|
||||||
|
assertEquals(1, CodeVersionInformation.version_compare("4.10", "4.5"));
|
||||||
|
assertEquals(-1, CodeVersionInformation.version_compare("4.5", "4.10"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetHighestVersion() {
|
||||||
|
assertEquals("5.2.0", CodeVersionInformation.get_highest_version(["5.2.0"]));
|
||||||
|
assertEquals("5.2.0", CodeVersionInformation.get_highest_version(["5.1.0", "5.2.0"]));
|
||||||
|
assertEquals("5", CodeVersionInformation.get_highest_version(["4", "4.1", "5"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetLowestVersion() {
|
||||||
|
assertEquals("5.2.0", CodeVersionInformation.get_lowest_version(["5.2.0"]));
|
||||||
|
assertEquals("5.1.0", CodeVersionInformation.get_lowest_version(["5.1.0", "5.2.0"]));
|
||||||
|
assertEquals("4", CodeVersionInformation.get_lowest_version(["4", "4.1", "5"]));
|
||||||
|
assertEquals("4.0.6", CodeVersionInformation.get_lowest_version(["4.0.6", "5"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetVersionLowerThan() {
|
||||||
|
assertEquals(null, CodeVersionInformation.get_version_lower_than("PHP 5"));
|
||||||
|
assertEquals(null, CodeVersionInformation.get_version_lower_than("PHP 5 >= 5.2.0"));
|
||||||
|
assertEquals("4.0.4", CodeVersionInformation.get_version_lower_than("PHP 4 <= 4.0.4"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCreate() {
|
||||||
|
var valid_results = [
|
||||||
|
new Result(ResultType.Function, "one", "PHP 4, PHP 5"),
|
||||||
|
new Result(ResultType.Function, "two", "PHP 4 >= 4.0.6, PHP 5"),
|
||||||
|
];
|
||||||
|
var v = new CodeVersionInformation(valid_results);
|
||||||
|
|
||||||
|
assertEquals("4.0.6", v.minimum_versions.get("PHP"));
|
||||||
|
|
||||||
|
Result.change_enabled(valid_results, "two", false);
|
||||||
|
|
||||||
|
v = new CodeVersionInformation(valid_results);
|
||||||
|
assertEquals("4", v.minimum_versions.get("PHP"));
|
||||||
|
}
|
||||||
|
|
||||||
|
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 >= 4.0.3}", CodeVersionInformation.split_version_string("PHP 4 >= 4.0.3, xmlwriter 2.0.4").toString());
|
||||||
|
assertEquals("{PHP => 4, 5}", CodeVersionInformation.split_version_string("PHP 5, PHP 4").toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetModuleInformation() {
|
||||||
|
var valid_results = [
|
||||||
|
new Result(ResultType.Function, "one", "PHP 4, zmod 5"),
|
||||||
|
new Result(ResultType.Function, "two", "PHP 4 >= 4.0.6, xmod 5"),
|
||||||
|
];
|
||||||
|
var v = new CodeVersionInformation(valid_results);
|
||||||
|
|
||||||
|
assertEquals("[PHP, xmod, zmod]", v.all_modules.toString());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
class TestConstantToken extends haxe.unit.TestCase {
|
||||||
|
function testCreateConstantToken() {
|
||||||
|
var t = new ConstantToken("meow", "hiss");
|
||||||
|
assertEquals("meow", t.token);
|
||||||
|
assertEquals("hiss", t.version);
|
||||||
|
assertEquals(ResultType.Constant, t.token_type);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
class TestFunctionToken extends haxe.unit.TestCase {
|
||||||
|
function testCreateFunctionToken() {
|
||||||
|
var t = new FunctionToken("meow", "hiss");
|
||||||
|
assertEquals("meow", t.token);
|
||||||
|
assertEquals("hiss", t.version);
|
||||||
|
assertEquals(ResultType.Function, t.token_type);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
class TestFunctionTokenProcessor extends haxe.unit.TestCase {
|
||||||
|
static var functionName : String = "test";
|
||||||
|
static var functionFrom : String = "5.2";
|
||||||
|
var testXml : String;
|
||||||
|
var tokenProcessor : FunctionTokenProcessor;
|
||||||
|
|
||||||
|
public override function setup() {
|
||||||
|
testXml = "<versions><function name='" + functionName + "' from='" + functionFrom + "'/></versions>";
|
||||||
|
tokenProcessor = new FunctionTokenProcessor();
|
||||||
|
tokenProcessor.populate_from_string(testXml);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGenerateSampleToken() {
|
||||||
|
var testTokenArray = [ new FunctionToken(functionName, functionFrom) ];
|
||||||
|
assertTrue(tokenProcessor.tokenHash.exists(functionName));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
class TestJavaScriptTarget extends haxe.unit.TestCase {
|
||||||
|
function testGetResults() {
|
||||||
|
JavaScriptTarget.main();
|
||||||
|
JavaScriptTarget.get_results("this is my array_shift()");
|
||||||
|
assertEquals(1, JavaScriptTarget.current_results.length);
|
||||||
|
assertTrue(JavaScriptTarget.current_results[0].is_enabled);
|
||||||
|
|
||||||
|
JavaScriptTarget.change_result(0, false);
|
||||||
|
assertFalse(JavaScriptTarget.current_results[0].is_enabled);
|
||||||
|
|
||||||
|
JavaScriptTarget.get_results("this is my array_shift() zip_close()");
|
||||||
|
assertEquals(2, JavaScriptTarget.current_results.length);
|
||||||
|
|
||||||
|
assertEquals("{}", JavaScriptTarget.show_only_modules.toString());
|
||||||
|
JavaScriptTarget.toggle_module("zip");
|
||||||
|
assertEquals("{zip => true}", JavaScriptTarget.show_only_modules.toString());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
class TestResult extends haxe.unit.TestCase {
|
||||||
|
function testInstantiateResult() {
|
||||||
|
var result = new Result(ResultType.Function, "test", "5.2");
|
||||||
|
assertEquals(ResultType.Function, result.type);
|
||||||
|
assertEquals("test", result.token);
|
||||||
|
assertEquals("5.2", result.version);
|
||||||
|
assertEquals(true, result.is_enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testResultArraySort() {
|
||||||
|
var result_array = [
|
||||||
|
new Result(ResultType.Function, "dog", "4"),
|
||||||
|
new Result(ResultType.Function, "cat", "4"),
|
||||||
|
];
|
||||||
|
|
||||||
|
assertEquals("dog", result_array[0].token);
|
||||||
|
|
||||||
|
result_array.sort(Result.compare);
|
||||||
|
|
||||||
|
assertEquals("cat", result_array[0].token);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
class TestToken extends haxe.unit.TestCase {
|
||||||
|
static var tokenName : String = "test";
|
||||||
|
static var tokenVersion : String = "5.2";
|
||||||
|
var t : Token;
|
||||||
|
|
||||||
|
public override function setup() {
|
||||||
|
t = new Token(tokenName, tokenVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInstantiateToken() {
|
||||||
|
assertEquals(tokenName, t.token);
|
||||||
|
assertEquals(tokenVersion, t.version);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testToResult() {
|
||||||
|
var result = t.toResult();
|
||||||
|
assertEquals(ResultType.Generic, result.type);
|
||||||
|
assertEquals(tokenName, result.token);
|
||||||
|
assertEquals(tokenVersion, result.version);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
class Token {
|
||||||
|
public var token(getToken, null) : String;
|
||||||
|
public var version(getVersion, null) : String;
|
||||||
|
public var token_type(getTokenType, null) : ResultType;
|
||||||
|
|
||||||
|
public function new(t : String, ?m : String) {
|
||||||
|
this.token = t;
|
||||||
|
this.version = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToken() { return this.token; }
|
||||||
|
public function getVersion() { return this.version; }
|
||||||
|
public function getTokenType() { return ResultType.Generic; }
|
||||||
|
|
||||||
|
public function toResult() {
|
||||||
|
return new Result(this.token_type, this.token, this.version);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
class TokenProcessor {
|
||||||
|
public var tokenHash : Hash<Token>;
|
||||||
|
public static var cachePath : String = null;
|
||||||
|
|
||||||
|
public function new() { this.tokenHash = new Hash<Token>(); }
|
||||||
|
public function get_cache_path() { return TokenProcessor.cachePath; }
|
||||||
|
|
||||||
|
#if neko
|
||||||
|
public function load_from_cache() : Bool {
|
||||||
|
if (neko.FileSystem.exists(this.get_cache_path())) {
|
||||||
|
this.tokenHash = haxe.Unserializer.run(neko.io.File.getContent(this.get_cache_path()));
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save_to_cache() {
|
||||||
|
var fh = neko.io.File.write(this.get_cache_path(), true);
|
||||||
|
fh.writeString(haxe.Serializer.run(this.tokenHash));
|
||||||
|
fh.close();
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
|
||||||
|
public function load_from_resource() {
|
||||||
|
this.tokenHash = haxe.Unserializer.run(haxe.Resource.getString(this.get_cache_path()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
//harmonious cpdf_arc
|
||||||
|
this is my array_shift() json_decode() cpdf_arc() test code
|
||||||
|
//harmonious_end
|
||||||
|
|
||||||
|
?>
|
Loading…
Reference in New Issue