harmoniouscode/src/ConstantTokenProcessor.hx

189 lines
7.1 KiB
Haxe

/**
ConstantTokenProcessor attempts to parse the PHP constants documentation
to glean version information about constants. This is done by examining
the descriptions of constants to see if the string:
~/since php ([0-9\.]+)/i
exists in the description and taking that as the minimum version
necessary to use that constant. This method is imperfect and probably
inaccurate, and one should always remember to test one's code on
the target platform to ensure maximum compatibility.
**/
class ConstantTokenProcessor extends TokenProcessor {
override public function get_default_token_type() { return ConstantToken; }
public static var source_path : String = "../data";
public static var source_file_pattern : EReg = ~/phpdoc_constants_.*\.xml/;
public static var version_match = ~/since php ([0-9\.]+)/i;
public static var node_skip_information = [
[ "para", "variablelist" ],
[ "section", "para" ],
[ "section", "table" ],
[ "para", "table" ],
[ "para", "informaltable" ],
[ "para", "itemizedlist" ],
[ "section", "variablelist" ]
];
#if neko
public override function populate_from_file() {
this.token_hash = new Hash<Token>();
for (file in neko.FileSystem.readDirectory(source_path)) {
if (source_file_pattern.match(file)) {
//trace(file + ": " + this.append_from_string(neko.io.File.getContent(source_path + "/" + file)));
this.append_from_string(neko.io.File.getContent(source_path + "/" + file));
}
}
}
/**
Process an XML string and append any tokens found to the token store
for this processor.
**/
public function append_from_string(s : String) : String {
var type = "none";
for (child in Xml.parse(s).firstElement()) {
if (child.nodeType == Xml.Element) {
var any_skipped;
// dig past unnecessary nodes at the top of the tree
do {
any_skipped = false;
for (nodes_to_skip in node_skip_information) {
if (child.nodeName == nodes_to_skip[0]) {
for (subchild in child) {
if (subchild.nodeType == Xml.Element) {
if (subchild.nodeName == nodes_to_skip[1]) {
child = subchild;
any_skipped = true;
break;
}
}
}
}
}
} while (any_skipped == true);
// itemizedlist
if (child.nodeName == "itemizedlist") {
type = "itemizedlist";
var fast_child = new haxe.xml.Fast(child);
if (fast_child.hasNode.listitem) {
for (item in fast_child.nodes.listitem) {
if (item.hasNode.simpara) {
var token_name : String = null;
var token_version : String = "4";
for (simpara in item.nodes.simpara) {
if (simpara.hasNode.constant) {
try {
token_name = simpara.node.constant.innerData;
} catch (e : Dynamic) {}
}
try {
var description_string = simpara.innerHTML;
if (version_match.match(description_string)) {
token_version = ~/\.$/.replace(version_match.matched(1), "");
}
} catch (e : Dynamic) {}
}
if (token_name != null) {
this.token_hash.set(token_name, new ConstantToken(token_name, "PHP " + token_version));
}
}
}
}
}
// variablelist
if (child.nodeName == "variablelist") {
type = "variablelist";
for (variable in child) {
if (variable.nodeType == Xml.Element) {
var token_name : String = null;
var token_version : String = "4";
var fast_variable = new haxe.xml.Fast(variable);
if (fast_variable.hasNode.term) {
var term_variable = fast_variable.node.term;
if (term_variable.hasNode.constant) {
try {
token_name = term_variable.node.constant.innerData;
} catch (e : Dynamic) {}
}
}
if (fast_variable.hasNode.listitem) {
var listitem_variable = fast_variable.node.listitem;
if (listitem_variable.hasNode.simpara) {
try {
var description_string = listitem_variable.node.simpara.innerData;
if (version_match.match(description_string)) {
token_version = ~/\.$/.replace(version_match.matched(1), "");
}
} catch (e : Dynamic) {}
}
}
if (token_name != null) {
this.token_hash.set(token_name, new ConstantToken(token_name, "PHP " + token_version));
}
}
}
}
// table
if ((child.nodeName == "table") || (child.nodeName == "informaltable")) {
type = "table";
var node_drilldown = [ "tgroup" ];
for (node_name in node_drilldown) {
for (node in child) {
if (node.nodeType == Xml.Element) {
if (node.nodeName == node_name) {
child = node; break;
}
}
}
}
var fast_child = new haxe.xml.Fast(child);
if (fast_child.hasNode.tbody) {
if (fast_child.node.tbody.hasNode.row) {
for (row in fast_child.node.tbody.nodes.row) {
var token_name : String = null;
var token_version : String = "4";
if (row.hasNode.entry) {
for (entry in row.nodes.entry) {
if (entry.hasNode.constant) {
try {
token_name = entry.node.constant.innerData;
} catch (e : Dynamic) {}
} else {
try {
var description_string = entry.innerHTML;
if (version_match.match(description_string)) {
token_version = ~/\.$/.replace(version_match.matched(1), "");
}
} catch (e : Dynamic) {}
}
}
}
if (token_name != null) {
this.token_hash.set(token_name, new ConstantToken(token_name, "PHP " + token_version));
}
}
}
}
}
}
}
return type;
}
/**
Populate a new token store from the provided XML string.
**/
public function populate_from_string(s : String) {
this.token_hash = new Hash<Token>();
this.append_from_string(s);
}
#end
}