230 lines
9.7 KiB
PHP
Executable File
230 lines
9.7 KiB
PHP
Executable File
<?php
|
|
|
|
namespace WMarkDown\ScriptsAnalyzer;
|
|
|
|
class CSharp extends \WMarkDown\Abstracts\ScriptsAnalyzer{
|
|
|
|
private static function get_parameter(&$parameter, $value){
|
|
|
|
if(preg_match('/^(.+) ([^ ]+)$/', trim($value), $submatches, PREG_OFFSET_CAPTURE)){
|
|
$parameter["name"] = $submatches[2][0];
|
|
$parameter["type"] = $submatches[1][0];
|
|
};
|
|
|
|
}
|
|
|
|
private static function get_parameters(&$content, $i = 0){
|
|
|
|
$parameters = [];
|
|
$secure = true;
|
|
$security = 0;
|
|
$value = "";
|
|
$parameter = [];
|
|
$ended = false;
|
|
|
|
while(!$ended && ($secure && $security ++ < 100) && preg_match('/[=,\(\[\{\<>\}\]\)]|("([^\\\\"]+|\\\\.)*"|\'([^\\\\\']+|\\\\.)*\')/', $content, $matches, PREG_OFFSET_CAPTURE)){
|
|
switch($matches[0][0]){
|
|
case "{":
|
|
case "[":
|
|
case "(":
|
|
case "<":
|
|
$value .= substr($content, 0, $matches[0][1] + 1);
|
|
$i ++;
|
|
break;
|
|
case ">":
|
|
case ")":
|
|
case "]":
|
|
case "}":
|
|
$value .= substr($content, 0, $matches[0][1]);
|
|
if(-- $i < 1){
|
|
$ended = true;
|
|
if(trim($value)){
|
|
if(isset($parameter["name"]))
|
|
$parameter["default"] = $value;
|
|
else
|
|
self::get_parameter($parameter, $value);
|
|
$parameters[] = $parameter;
|
|
$parameter = [];
|
|
$value = "";
|
|
};
|
|
}else
|
|
$value .= $matches[0][0];
|
|
break;
|
|
case ",":
|
|
$value .= substr($content, 0, $matches[0][1]);
|
|
if($i > 1)
|
|
$value .= ",";
|
|
else{
|
|
if(isset($parameter["name"]))
|
|
$parameter["default"] = $value;
|
|
else
|
|
self::get_parameter($parameter, $value);
|
|
$parameters[] = $parameter;
|
|
$parameter = [];
|
|
$value = "";
|
|
};
|
|
break;
|
|
case "=":
|
|
$value .= substr($content, 0, $matches[0][1]);
|
|
if($i > 1)
|
|
$value .= "=";
|
|
else{
|
|
self::get_parameter($parameter, $value);
|
|
$value = "";
|
|
};
|
|
break;
|
|
default:
|
|
$value .= substr($content, 0, $matches[0][1]) . $matches[1][0];
|
|
break;
|
|
};
|
|
$content = substr($content, $matches[0][1] + strlen($matches[0][0]));
|
|
};
|
|
|
|
return $parameters;
|
|
}
|
|
|
|
private static function get_body(&$content){
|
|
|
|
$i = 0;
|
|
$secure = true;
|
|
$security = 0;
|
|
$has_body = trim($content)[0] == "{";
|
|
$body = "";
|
|
$ended = false;
|
|
|
|
while(!$ended && ($secure && $security ++ < 100) && preg_match('/[\{\}]|("([^\\\\"]+|\\\\.)*"|\'([^\\\\\']+|\\\\.)*\')/', $content, $matches, PREG_OFFSET_CAPTURE)){
|
|
switch($matches[0][0]){
|
|
case "{":
|
|
$i ++;
|
|
break;
|
|
case "}":
|
|
-- $i < 1 && ($ended = true);
|
|
break;
|
|
};
|
|
$body .= substr($content, 0, $matches[0][1]) . $matches[0][0];
|
|
$content = substr($content, $matches[0][1] + strlen($matches[0][0]));
|
|
};
|
|
|
|
return $body;
|
|
}
|
|
|
|
private static function remove_blocks(&$content, $i = 0){
|
|
while(preg_match('/[\(\[\{<>\}\]\)]/', $content, $matches, PREG_OFFSET_CAPTURE)){
|
|
$content = substr($content, $matches[0][1] + strlen($matches[0][0]));
|
|
if(in_array($matches[0][0], ["]", "}", ">", ")"])){
|
|
if(!-- $i)
|
|
break;
|
|
}else
|
|
$i ++;
|
|
};
|
|
}
|
|
|
|
public function analyze($file, $path = null, &$languages = [], $level = 0){
|
|
|
|
if(!($content = \WMarkDown\ScriptsAnalyzer::get_content($file, $path)))
|
|
return;
|
|
|
|
$wmd_path = $this->parent->get_wmd_path($file, $path);
|
|
|
|
!isset($languages["c_sharp"]) && ($languages["c_sharp"] = []);
|
|
$namespace = "";
|
|
$class_name = "";
|
|
$secure = true;
|
|
$security = [0];
|
|
$y = [2, 3, 8, 12];
|
|
$data = $this->get_data("cs", $wmd_path = $this->parent->get_wmd_path($file, $path));
|
|
$languages["c_sharp"][$i = count($languages["c_sharp"])] = ["path" => $wmd_path, "level" => $level, "methods" => []];
|
|
$last_method = null;
|
|
|
|
$content = preg_replace_callback('/("([^\\\\"]+|\\\\.)*"|\'([^\\\\\']+|\\\\.)*\')|(\/{2}[^\r\n]*|\/\*([^\*]+|[\r\n]+|\*[^\/])*\*\/)|([\r\n]|[\s\t])+/', function($values){
|
|
return $values[1] ? $values[1] : ($values[4] ? "" : " ");
|
|
}, $content);
|
|
|
|
while((!$secure || $security[0] ++ < 100) && preg_match('/\b(' .
|
|
'namespace ([a-zA-Z\d_]+) ?\{' .
|
|
'|((abstract|internal) ){0,2}class ([a-zA-Z0-9_]+)( ?\: ?([a-zA-Z\d_]+, ?)+)? ?[<\{]' .
|
|
'|((private|public|protected) )?(~)?([a-zA-Z0-9_]+ ?)\(' .
|
|
'|((private|public|protected) )?(static )?((?!(using|static|public|private|protected))[a-zA-Z\d_]+)( ?<|(\[[0-9]*\])? ([a-zA-Z0-9_]+) ?[<\(])' .
|
|
')/', $content, $matches, PREG_OFFSET_CAPTURE)){
|
|
|
|
$content = substr($content, $matches[0][1] + strlen($matches[0][0]));
|
|
$parameters = null;
|
|
$body = null;
|
|
$method = null;
|
|
$type = null;
|
|
$return = null;
|
|
$access = null;
|
|
|
|
if($matches[$y[0] + 0][0])
|
|
$class_name = $namespace = $matches[$y[0] + 0][0];
|
|
elseif($matches[$y[1] + 2][0])
|
|
$class_name = $namespace . "." . $matches[$y[1] + 2][0];
|
|
elseif($matches[$y[2] + 3][0]){
|
|
|
|
$parameters = self::get_parameters($content, 1);
|
|
$body = self::get_body($content);
|
|
$method = $class_name . "." . $matches[$y[2] + 3][0];
|
|
$access = $matches[$y[2] + 0][0] ? $matches[$y[2] + 0][0] : "public";
|
|
$type = $matches[$y[2] + 2][0] ? "destructor" : "constructor";
|
|
|
|
}elseif($matches[$y[3] + 3][0]){
|
|
|
|
$diamonds = false;
|
|
$return = $matches[$y[3] + 3][0];
|
|
$type = $matches[$y[3] + 2][0] ? "estático" : "objeto";
|
|
$method = $class_name . ".";
|
|
$access = $matches[$y[3] + 1][0] ? $matches[$y[3] + 1][0] : "public";
|
|
|
|
if(trim($matches[$y[3] + 5][0])[0] == "<"){ // Aún está terminando de procesar el tipado por diamantes.
|
|
self::remove_blocks($content, 1);
|
|
if(preg_match('/^(\[[0-9]*\])? ([a-zA-Z0-9_]+) ?[<\(]/', $content, $submatches, PREG_OFFSET_CAPTURE)){
|
|
$content = substr($content, $submatches[0][1] + strlen($submatches[0][0]));
|
|
$diamonds = substr($submatches[0][0], -1) == "<";
|
|
$submatches[1][0] && ($return .= $submatches[1][0]);
|
|
$method .= $submatches[2][0];
|
|
}else{ // Es una variable Ojeto o de clase u otro tipo de elemento no computable.
|
|
$content = preg_replace('/^ ?;/', "", $content);
|
|
continue; // Rompemos para buscar métodos, clases o constructores.
|
|
};
|
|
|
|
}else{
|
|
$diamonds = substr($matches[0][0], -1) == "<";
|
|
$matches[$y[3] + 6][0] && ($return .= $matches[$y[3] + 6][0]);
|
|
$method .= $matches[$y[3] + 7][0];
|
|
};
|
|
|
|
$diamonds && self::remove_blocks($content, 1);
|
|
|
|
$parameters = self::get_parameters($content, 1);
|
|
$body = self::get_body($content);
|
|
|
|
};
|
|
|
|
if($body){
|
|
|
|
$see = [];
|
|
|
|
!in_array($method, $languages["c_sharp"][$i]["methods"]) && ($languages["c_sharp"][$i]["methods"][] = $method);
|
|
|
|
$data = $this->parent->add_method($data, $last_method, [
|
|
"access" => $access,
|
|
"language_script" => "C#",
|
|
"name" => $method,
|
|
"type" => $type,
|
|
"see" => $see,
|
|
"parameters" => $parameters,
|
|
"return" => $return,
|
|
"hash" => md5($body)
|
|
]);
|
|
$last_method = $method;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
\WMarkDown::save_file($wmd_path, $data);
|
|
|
|
}
|
|
|
|
};
|