Sistema de documentación y gestión de páginas Web para un entorno o proyecto Web.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
WMarkDown/PHP/ScriptsAnalyzer/WMarkDown.ScriptsAnalyzer.P...

186 lines
9.7 KiB

<?php
namespace WMarkDown\ScriptsAnalyzer;
class PHP extends \WMarkDown\Abstracts\ScriptsAnalyzer{
private static $custom_types = [
"__construct" => "constructor",
"__destruct" => "destructor",
"__call" => "mágico"
];
public function analyze($file, $path = null, &$languages = [], $level = 0){
if(!($content = \WMarkDown\ScriptsAnalyzer::get_content($file, $path)))
return;
$namespace = "";
$class_name = "";
$class_type = "default";
$security = [0];
$p = [1, 2, 4]; // Cursor position.
$data = \WMarkDown::string_variables(file_exists($wmd_path = $this->parent->get_wmd_path($file, $path)) ? file_get_contents($wmd_path) : $this->original_wmd, array_merge([
"subkey_words" => preg_match('/^.+' . $this->common["project"] . '\.([^\/]+)\.php\.w\.md$/', $wmd_path) ? preg_replace_callback('/^.+' . $this->common["project"] . '\.([^\/]+)\.php\.w\.md$/', function($values){
return substr(preg_replace('/[,\.]+/', ",", preg_replace_callback('/([A-Z]+)?([A-Z][a-z0-9]+)/', function($subvalues){
return ($subvalues[1] ? "," . $subvalues[1] : "") . "," . strtolower($subvalues[2]);
}, $values[1])), 1);
}, $wmd_path) : "main",
"path" => substr($wmd_path, $this->root_l + 8),
"subpath" => substr($wmd_path, $this->root_l + 8, -5),
"file" => preg_replace('/^.+\/([^\/]+)\.w\.md$/', "$1", $wmd_path)
], $this->common));
$last_method = null;
!isset($languages["php"]) && ($languages["php"] = []);
$languages["php"][$x = count($languages["php"])] = ["path" => $wmd_path, "level" => $level, "methods" => []];
// Limpiamos el Script de saltos de línea y comentarios y unificamos los espaciados.
$content = preg_replace_callback('/("(([^\\\\"]+|\\\\.)*)"|\'(([^\\\\\']+|\\\\.)*)\')|([\t\s]|[\r\n]|\/\/[^\r\n]*|\/\*(([\r\n]+|[^\*]+|\*[^\/])*)\*\/)+/', function($values){
return $values[1] ? $values[0] : " ";
}, $content);
// Buscamos espacios de nombres, clases, interfaces, abstracciones y métodos.
while((true || $security[0] ++ < 100) && preg_match('/\b(' .
'namespace ([^; ]+);|' .
'(class|interface) ([a-zA-Z0-9_]+)|' .
'((public|protected|private) )?(static )?function ([a-zA-Z0-9_]+) ?\(' .
')/', $content, $matches, PREG_OFFSET_CAPTURE)){
$l = count($matches);
$content = substr($content, $matches[0][1] + strlen($matches[0][0]));
if($l > $p[2] + 1){ // Método.
$method_access = trim($matches[$p[2] + 1][0]);
$method_name = $matches[$p[2] + 4][0];
$languages["php"][$x]["methods"][] = $method_full_name = $class_name . ($matches[$p[2] + 3][0] ? "::" : "->") . $method_name;
$method_type = isset(self::$custom_types[$method_name]) ? self::$custom_types[$method_name] : ($matches[$p[2] + 3][0] ? "static" : "object");
$parameters = [];
$see = [];
$return = null;
$security[1] = 0;
$security[2] = 0;
if(trim($content)[0] != ")"){ // Verificamos que tiene parámetros.
$i = 1; // Si llega a 0 es que se cerró el bloque de los parámetros.
$default_value = "";
$parameter_name = null;
$parameter_type = null;
$parameter_reference = false;
// Analizamos los parámetros.
while((true || $security[1] ++ < 20) && preg_match('/' .
'(((?![\$\&])[a-zA-Z0-9_])+ )?(\&)?\$([a-zA-Z0-9_]+)|' .
' ?(=) ?(null|true|false|\d+|"(([\\\\"]+|\\\\.)*)"|\'(([\\\\\']+|\\\\.)*)\')?|' .
' ?(,) ?|' .
'([^,\(\)\[\]\{\}"\']+|"(([\\\\"]+|\\\\.)*)"|\'(([\\\\\']+|\\\\.)*)\')|' .
'([\(\[\{])|([\}\]\)])' .
'/', $content, $submatches, PREG_OFFSET_CAPTURE)){
$m = count($submatches);
$content = substr($content, $submatches[0][1] + strlen($submatches[0][0]));
if($m > 17 && $submatches[17][0]) // Apertura de bloque.
$i ++;
else if($m > 18 && $submatches[18][0]){ // Cierre de bloque.
if(!-- $i){
$parameters[] = [
"name" => $parameter_name,
"type" => $parameter_type,
"reference" => $parameter_reference,
"default" => $default_value
];
break;
};
}elseif($m > 11 && $submatches[11][0]){ // Se cierra un parámetro.
if($i > 1)
$default_value = $default_value . $submatches[0][0];
else{
$parameters[] = [
"name" => $parameter_name,
"type" => $parameter_type,
"reference" => $parameter_reference,
"default" => $default_value
];
$default_value = "";
$parameter_name = null;
$parameter_type = null;
$parameter_reference = false;
};
}elseif($submatches[4][0]){ // Se crea un nuevo parámetro.
$parameter_name = ($submatches[3][0] ? "&" : "") . "$" . $submatches[4][0];
$parameter_type = $submatches[1][0] ? $submatches : null;
$parameter_reference = !!$submatches[3][0];
}elseif($m > 6 && $submatches[6][0]) // Valor por defecto.
$default_value = $submatches[6][0];
};
}else // No tiene párametros de entrada.
$content = substr($content, 1);
$i = 0;
$body = "";
// Analizamos bloques de sentencias para analizar inicio y fin del método.
while((true || $security[2] ++ < 40) && preg_match('/[\{\}]/', $content, $submatches, PREG_OFFSET_CAPTURE)){
$end = false;
$body .= substr($content, 0, $submatches[0][1]) . $submatches[0][0];
$content = substr($content, $submatches[0][1] + strlen($submatches[0][0]));
switch($submatches[0][0]){
case "{":
$i ++;
break;
case "}":
$end = !-- $i;
break;
};
if($end)
break;
};
// Analizamos retorno.
$return = preg_match('/\breturn[^;]+[; ]*}$/', $body) ? true : null;
// Buscamos dependencias de sí mismo.
preg_replace_callback('/"(([^\\\\"]+|\\\\.)*)"|\'(([^\\\\\']+|\\\\.)*)\'|(\$this\->([a-zA-Z0-9_]+|\->)+|\\\\?([a-zA-Z0-9_\\\\]+|\\\\)::[a-zA-Z0-9_]+)\(/', function($values) use(&$see, $class_name){
if(count($values) < 6 || ($values[6] && !preg_match('/\$this\->([^\-\(]+\(|wmarkdown\->)/', $values[0])))
return;
!in_array($method = ($method = preg_replace('/^(\$this(\->)|self(\:{2}))/', $class_name . "$2$3", preg_replace('/^\$this\->wmarkdown/', "\\WMarkDown", substr($values[0], 0, -1))))[0] == '\\' ? substr($method, 1) : $method, $see) && ($see[] = $method);
}, $body);
// Añadimos el método al código WMD almacenado en $data tras el último método registrado.
$data = $this->parent->add_method($data, $last_method, [
"access" => $method_access,
"language_script" => "PHP",
"name" => $method_full_name,
"type" => $method_type,
"see" => $see,
"parameters" => $parameters,
"return" => $return,
"hash" => md5($content)
]);
$last_method = $method_full_name;
}elseif($l > $p[1] + 1){ // Clase
$class_type = $matches[$p[1] + 1][0];
$class_name = $namespace . '\\' . $matches[$p[1] + 2][0];
}else // Espacio de nombres.
$class_name = $namespace = $matches[$p[0] + 1][0];
};
// Creamos el fichero WMD del fichero PHP.
\WMarkDown::save_file($wmd_path, $data);
}
};