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);
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
    };
 |