├── .gitignore ├── LICENSE ├── README.md ├── bin ├── phpstormWatcher.php └── scriptformatter.php ├── composer.json ├── composer.lock ├── lib ├── bootstrap.php └── phptojs │ ├── Autoloader.php │ ├── JsPrinter │ ├── JsPrinter.php │ ├── JsPrinterAbstract.php │ └── JsPrinterInterface.php │ ├── Printer │ ├── SourceWriter.php │ └── SourceWriterInterface.php │ └── lib │ ├── js │ ├── Exceptions.js │ ├── HashArray.js │ ├── JsArray.js │ ├── JsObject.js │ ├── classManager.js │ └── phpJsCore.js │ └── php │ ├── HashArray.php │ ├── JsArray.php │ └── JsObject.php ├── phpunit.xml.dist ├── public_html ├── .htaccess ├── beautify.js ├── convert.php ├── favicon.ico ├── getTemplate.php ├── index.php └── scripts.php └── test ├── PhpToJs └── PhpToJsTest.php └── code └── jsPrinter ├── jsSrc ├── generated │ └── JsPrinter │ │ ├── AssigningThis.js.php.js │ │ ├── JsArray.js.php.js │ │ ├── JsClass.js.php.js │ │ ├── anonymousClass.js.php.js │ │ ├── array.js.php.js │ │ ├── class.js.php.js │ │ ├── closure.js.php.js │ │ ├── continue.js.php.js │ │ ├── defaultArg.js.php.js │ │ ├── function.js.php.js │ │ ├── include.js.php.js │ │ ├── includeIt.php.js │ │ ├── inheritance.js.php.js │ │ ├── list.js.php.js │ │ ├── loops.js.php.js │ │ ├── magicConstants.js.php.js │ │ ├── magicMethods.js.php.js │ │ ├── multiline.js.php.js │ │ ├── namespaces.js.php.js │ │ ├── operators.js.php.js │ │ ├── private.js.php.js │ │ ├── switchStatement.js.php.js │ │ └── tryCatch.js.php.js ├── php.js └── runTest.js └── phpSrc ├── JsPrinter └── array.js.php ├── global ├── AssigningThis.js.php ├── JsArray.js.php ├── JsClass.js.php ├── anonymousClass.js.php ├── array.js.php ├── class.js.php ├── closure.js.php ├── continue.js.php ├── defaultArg.js.php ├── function.js.php ├── include.js.php ├── includeIt.php ├── inheritance.js.php ├── list.js.php ├── loops.js.php ├── magicConstants.js.php ├── magicMethods.js.php ├── multiline.js.php ├── namespaces.js.php ├── operators.js.php ├── phpCore.js.php ├── private.js.php ├── switchStatement.js.php └── tryCatch.js.php └── runTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | .gitignore 3 | .idea/ 4 | vendor 5 | /dev/ 6 | /test/code/jsPrinter/jsSrc/generated/JsPrinter/ 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Jozef Mostka 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PHP to JavaScript convertor 2 | =================== 3 | #### See playground: [Online Convertor](http://phptojs.orava.sk/) #### 4 | 5 | #### Suports #### 6 | - Namespaces, use 7 | - Class, abstract class 8 | - extends and interfaces 9 | - constants and define 10 | - Exceptions and catch 11 | - continue ,break 12 | - anonymous classes 13 | - magic constants 14 | - list() 15 | - magic methods __get __set and __call (only in ES6 [see Proxy in compatibility table](https://kangax.github.io/compat-table/es6/#test-Proxy)) 16 | - private methods and properties (only in ES6 [see WeakMap in compatibility table](https://kangax.github.io/compat-table/es6/#test-WeakMap)) 17 | 18 | #### Planed #### 19 | - include and require 20 | - class generation 21 | - yield 22 | 23 | #### Limitations #### 24 | Its there more differences between PHP and JS. Array in PHP is asociate, but in JS is not. 25 | For that reason you can use [```jsphp\JsArray```](https://github.com/tito10047/PHP-to-Javascript/blob/master/test/code/jsPrinter/phpSrc/global/JsArray.js.php) wich has same funcionality as build in JS Array. 26 | 27 | In JS you have object wich is similarly to PHP arrays, but there is diferent ordering. Also is not working 28 | with builtin php functions for manipulating with arrays. So if you need this object, wich working with 29 | foreach loop, the you can use [```jsphp\JsObject```](https://github.com/tito10047/PHP-to-Javascript/blob/master/test/code/jsPrinter/phpSrc/global/JsClass.js.php). This object has same funcionality as 30 | JsObject. But if you want extend it, your extended object cant have public or protected members, just use it, but not declare it. 31 | 32 | If you need some like associated array you can also use [```jsphp\HashArray```](https://github.com/tito10047/PHP-to-Javascript/blob/master/test/code/jsPrinter/phpSrc/JsPrinter/array.js.php) 33 | 34 | You can't define class constant and static properties with same name. in JS will be override. 35 | 36 | #### Not suport #### 37 | - trait 38 | - goto 39 | - declare(ticks) 40 | 41 | Usage 42 | =================== 43 | ```php 44 | $parser = (new \PhpParser\ParserFactory())->create(\PhpParser\ParserFactory::PREFER_PHP7); 45 | $jsPrinter = new \phptojs\JsPrinter\JsPrinter(); 46 | 47 | $phpCode = file_get_contents('path/to/phpCode'); 48 | $stmts = $parser->parse($phpCode); 49 | $jsCode = $jsPrinter->jsPrint($stmts); 50 | ``` 51 | ---- 52 | ### Use auto converter ### 53 | You can create file watcher for auto generation js script from your php 54 | code when is saved. 55 | 56 | #### PHPStorm #### 57 | go to `File/Setting/Tools/File Watchers` add custom watcher and set 58 | 59 | - File type: PHP 60 | - Scope: Create new scope to your php scripts to convert 61 | - Program: chose yor location to `php.exe` 62 | - Arguments: 63 | - `-f` 64 | - `$ProjectFileDir$/../PHP-to-Javascript/bin/phpstormWatcher.php` 65 | - `$FileName$` 66 | - `$ProjectFileDir$/phpJs` php scripts to generate 67 | - `$ProjectFileDir$/public/js/phpjs` output directory 68 | - `[-p]` enable support of private properties and method. If is disabled, all private fields is converted as public 69 | 70 | - Output paths to refresh: `$ProjectFileDir$/public/js/phpjs` 71 | 72 | 73 | 74 | Example 75 | =================== 76 | 77 | ```php 78 | interface FooInt{ 79 | function fooIntFunc1($a, $b = 5); 80 | } 81 | 82 | abstract class FooAbs implements FooInt 83 | { 84 | abstract function fooAbsFunc1($a, $b); 85 | 86 | function fooAbsFunc2($a, $b){ 87 | return $a + $b + 10; 88 | } 89 | } 90 | 91 | class FooParent extends FooAbs{ 92 | public $foo = 5; 93 | 94 | public function __construct() { 95 | $this->foo=5; 96 | } 97 | 98 | function fooAbsFunc1($a, $b){ 99 | parent::fooAbsFunc2(1,5); 100 | return $a + $b; 101 | } 102 | 103 | function fooIntFunc1($a, $b = 5){ 104 | return $a + $b + 5; 105 | } 106 | 107 | public static function fooStatic(){ 108 | return 10; 109 | } 110 | } 111 | 112 | class FooChild extends FooParent 113 | { 114 | public $foo = 6; 115 | 116 | function fooIntFunc1($a, $b = 5){ 117 | return $a + $b; 118 | } 119 | 120 | function testParent(){ 121 | assert_($this->fooIntFunc1(5, 5), 10, 'testParent 1'); 122 | assert_(parent::fooIntFunc1(5, 5), 15, 'testParent 2'); 123 | } 124 | } 125 | 126 | $fooParent = new FooParent(); 127 | $fooChild = new FooChild(); 128 | 129 | assert_($fooParent instanceof FooParent, true, 'fooParent instanceof FooParent'); 130 | assert_($fooParent instanceof FooInt, true, 'fooParent instanceof FooInt'); 131 | 132 | assert_($fooChild instanceof FooChild, true, 'fooChild instanceof FooChild'); 133 | assert_($fooChild instanceof FooParent, true, 'fooChild instanceof FooParent'); 134 | assert_($fooChild instanceof FooAbs, true, 'fooChild instanceof FooAbs'); 135 | assert_($fooChild instanceof FooInt, true, 'fooChild instanceof FooInt'); 136 | 137 | assert_(FooChild::fooStatic(),10, "FooChild::fooStatic()"); 138 | 139 | $fooChild->testParent(); 140 | ``` 141 | 142 | Is converted to 143 | ```javascript 144 | var FooInt = (function() { 145 | function FooInt() { 146 | window.__IS_INHERITANCE__ = false; 147 | __INTERFACE_NEW__(); 148 | } 149 | FooInt.prototype.fooIntFunc1 = function(a, b) { 150 | __INTERFACE_FUNC__(); 151 | }; 152 | return FooInt; 153 | })(); 154 | var FooAbs = (function() { 155 | function FooAbs() { 156 | window.__IS_INHERITANCE__ = false; 157 | } 158 | __extends(FooAbs, null, arguments[1]); 159 | FooAbs.prototype.__isAbstract__ = true; 160 | FooAbs.prototype.fooAbsFunc1 = function(a, b) { 161 | __ABSTRACT_FUNC__(); 162 | }; 163 | FooAbs.prototype.fooAbsFunc2 = function(a, b) { 164 | return a + b + 10; 165 | }; 166 | return FooAbs; 167 | })(null, [FooInt]); 168 | var FooParent = (function(parent) { 169 | function FooParent() { 170 | var __isInheritance = __IS_INHERITANCE__; 171 | window.__IS_INHERITANCE__ = true; 172 | parent.call(this); 173 | this.foo = 5; 174 | if (__isInheritance == false) { 175 | this.__construct(); 176 | } 177 | } 178 | __extends(FooParent, parent); 179 | FooParent.prototype.__construct = function() { 180 | this.foo = 5; 181 | }; 182 | FooParent.prototype.fooAbsFunc1 = function(a, b) { 183 | parent.prototype.fooAbsFunc2.call(this, 1, 5); 184 | return a + b; 185 | }; 186 | FooParent.prototype.fooIntFunc1 = function(a, b) { 187 | if (typeof b == 'undefined') b = 5; 188 | return a + b + 5; 189 | }; 190 | FooParent.fooStatic = function() { 191 | return 10; 192 | }; 193 | return FooParent; 194 | })(FooAbs); 195 | var FooChild = (function(parent) { 196 | function FooChild() { 197 | window.__IS_INHERITANCE__ = true; 198 | parent.call(this); 199 | this.foo = 6; 200 | } 201 | __extends(FooChild, parent); 202 | FooChild.prototype.fooIntFunc1 = function(a, b) { 203 | if (typeof b == 'undefined') b = 5; 204 | return a + b; 205 | }; 206 | FooChild.prototype.testParent = function() { 207 | assert_(this.fooIntFunc1(5, 5), 10, 'testParent 1'); 208 | assert_(parent.prototype.fooIntFunc1.call(this, 5, 5), 15, 'testParent 2'); 209 | }; 210 | return FooChild; 211 | })(FooParent); 212 | var fooParent; 213 | fooParent = new FooParent(); 214 | var fooChild; 215 | fooChild = new FooChild(); 216 | assert_(fooParent instanceof FooParent, true, 'fooParent instanceof FooParent'); 217 | assert_(fooParent instanceof FooInt, true, 'fooParent instanceof FooInt'); 218 | assert_(fooChild instanceof FooChild, true, 'fooChild instanceof FooChild'); 219 | assert_(fooChild instanceof FooParent, true, 'fooChild instanceof FooParent'); 220 | assert_(fooChild instanceof FooAbs, true, 'fooChild instanceof FooAbs'); 221 | assert_(fooChild instanceof FooInt, true, 'fooChild instanceof FooInt'); 222 | assert_(FooChild.fooStatic(), 10, 'FooChild::fooStatic()'); 223 | fooChild.testParent(); 224 | ``` 225 | [More Examples](https://github.com/tito10047/PHP-to-Javascript/tree/master/test/code/jsPrinter/jsSrc/generated/JsPrinter) 226 | -------------------------------------------------------------------------------- /bin/phpstormWatcher.php: -------------------------------------------------------------------------------- 1 | create(\PhpParser\ParserFactory::PREFER_PHP7); 60 | $jsPrinter = new \phptojs\JsPrinter\JsPrinter($usePrivate); 61 | 62 | $stmts = $parser->parse($phpContent); 63 | ob_start(); 64 | $jsCode = $jsPrinter->jsPrint($stmts); 65 | $errors = ob_get_clean(); 66 | $errors = explode(PHP_EOL, $errors); 67 | foreach ($errors as $error) { 68 | if ($error != "") { 69 | $errorCount++; 70 | echo "Warning: " . $error.PHP_EOL; 71 | } 72 | } 73 | foreach ($jsPrinter->getErrors() as $error) { 74 | $errorCount++; 75 | echo "Warning: " . $error . PHP_EOL; 76 | } 77 | $dotPos = strrpos($phpFilename,"."); 78 | $phpFilenameWithoutExtension = substr($phpFilename,0,$dotPos); 79 | $filePathWithoutExtension = substr($phpFilenameWithoutExtension,strlen($phpRootDir)); 80 | if (in_array(substr($filePathWithoutExtension,0,1),["/","\\"])){ 81 | $filePathWithoutExtension = substr($filePathWithoutExtension,1); 82 | } 83 | $jsFileName = realpath($jsRootDir).DIRECTORY_SEPARATOR.$filePathWithoutExtension.".js"; 84 | $parentDir = dirname($jsFileName); 85 | if (!file_exists($parentDir)){ 86 | mkdir($parentDir,777,true); 87 | } 88 | $jsCode = "/** 89 | * File generated by PHP to JS converter 90 | * Don't modify this file because changes will be lost 91 | */ 92 | ".$jsCode; 93 | 94 | $sourceCode=$jsCode; 95 | require_once __DIR__.'/scriptformatter.php'; 96 | $jsCode=$sourceCode; 97 | 98 | file_put_contents($jsFileName, $jsCode); 99 | 100 | } catch (PhpParser\Error $e) { 101 | echo 'ERROR:', $e->getMessage(); 102 | $errorCount++; 103 | } catch (Exception $e) { 104 | echo "ERROR:Some is wrong".PHP_EOL.$e->getMessage(); 105 | $errorCount++; 106 | } 107 | if ($errorCount>0){ 108 | exit(1); 109 | } 110 | $libDir = $jsRootDir.DIRECTORY_SEPARATOR.'lib'; 111 | if (!file_exists($libDir)){ 112 | mkdir($libDir); 113 | } 114 | $libFiles = glob(JS_LIB_DIR.DIRECTORY_SEPARATOR.'*'); 115 | foreach ($libFiles as $file){ 116 | $name = substr($file,strlen(JS_LIB_DIR)); 117 | $exportName = $libDir.DIRECTORY_SEPARATOR.$name; 118 | if (file_exists($exportName) && filemtime($exportName)>=filemtime($file)){ 119 | continue; 120 | } 121 | copy($file,$exportName); 122 | } -------------------------------------------------------------------------------- /bin/scriptformatter.php: -------------------------------------------------------------------------------- 1 | $len){ 31 | $len=mb_strlen($s); 32 | } 33 | } 34 | while($index>0){ 35 | $char=mb_substr($str,--$index,1); 36 | $subStr=$char.$subStr; 37 | if (mb_strlen($subStr)>$len){ 38 | $subStr=mb_substr($subStr,0,$len); 39 | } 40 | foreach($search as $s){ 41 | if ($s==mb_substr($subStr,mb_strlen($subStr)-mb_strlen($s))){ 42 | return true; 43 | } 44 | } 45 | if (in_array($char,$endChar)){ 46 | return false; 47 | } 48 | } 49 | return false; 50 | } 51 | } 52 | $debug=false; 53 | $start = time(); 54 | $url = isset( $_GET['url'] ) ? $_GET['url'] : ''; 55 | 56 | if( isset($sourceCode) && $sourceCode ) { 57 | $code = $sourceCode; 58 | // $code = str_replace("\r\n","\n",$code); 59 | $code = preg_replace('~(*BSR_ANYCRLF)\R~', "\n", $code); 60 | }else{ 61 | /* enable command line usage */ 62 | if (!isset($source_file) || !$source_file) { 63 | $source_file=(isset($argv[1]) && is_file($argv[1])) ? $argv[1] : ''; 64 | } 65 | $code = file_get_contents($source_file); 66 | } 67 | 68 | 69 | // echo ( ' loaded stuff in ' . (time() - $start) . "ms\n"); 70 | 71 | if( empty( $code ) ){echo( 'could not retrieve '.$url ); exit;} 72 | 73 | $output=''; /* would array perform better as in JS? */ 74 | $num_indents = 0; 75 | $character_index = 0; 76 | $char=''; 77 | 78 | $scope = CODE; 79 | $before_escape_scope=0; 80 | $at_start_of_statement_or_expression=true; /* used to distinguish divisor from regexp literal */ 81 | $last_complete_word = ''; /* some rudimentary tokenisation is required for the divisor-or-regexp problem */ 82 | $statement_words = array('return', 'typeof', 'instanceof', 'break', 'continue', 'delete', 'in', 'new', 'throw'); 83 | 84 | while( $character_index < strlen( $code ) ){ 85 | $char = mb_substr( $code, $character_index, 1 ); 86 | if($debug)echo ( (time() - $start). "ms elapsed, now on $character_index / ".strlen($code)." $char, mode: $scope, last word: '$last_complete_word' - start of expression? $at_start_of_statement_or_expression \n"); 87 | $pre = ''; /* add this string *before* this character when constructing output */ 88 | $post = ''; /* add this string *after* this character when constructing output */ 89 | switch( $char ){ 90 | case '"': /* double quote */ 91 | switch( $scope ){ 92 | case STRING_DBL: 93 | $scope=CODE ; break; /* a non-escaped quote inside string terminates string */ 94 | case ESCAPE: 95 | $scope = $before_escape_scope; break; /* the quote was escaped, return to previous scope */ 96 | case CODE: 97 | $scope = STRING_DBL ; /* start-of-string double quote */ 98 | $at_start_of_statement_or_expression=false; 99 | } 100 | break; 101 | case '\'': /* single quote */ 102 | switch( $scope ){ 103 | case STRING_SGL: 104 | $scope=CODE ; break; /* a non-escaped quote inside string terminates string */ 105 | case ESCAPE: 106 | $scope = $before_escape_scope; break; /* the quote was escaped, return to previous scope */ 107 | case CODE: 108 | $scope = STRING_SGL ; /* start-of-string single quote */ 109 | $at_start_of_statement_or_expression=false; 110 | } 111 | break; 112 | case '\\': 113 | if( $scope == STRING_DBL || $scope == STRING_SGL || $scope == REGEXP || $scope == REGEXP_CHAR_CLASS){ 114 | $before_escape_scope = $scope ; 115 | $scope = ESCAPE ; /* next character not to be taken seriously (well..) */ 116 | }else if( $scope == ESCAPE ){ /* handle escaped backslashes "\\" */ 117 | $scope = $before_escape_scope ; 118 | } 119 | break; 120 | case '/': 121 | if( $scope == CODE ){ /* lookahead: start of comment or something else? */ 122 | $tmp = mb_substr( $code, $character_index+1, 1 ); 123 | if( $tmp == '*' ){ /* start of multi-line comment */ 124 | $scope = MULTI_LINE_COMMENT ; 125 | }else if( $tmp == '/' ){ /* start of single-line comment */ 126 | $scope = SINGLE_LINE_COMMENT ; 127 | }else if( $at_start_of_statement_or_expression || in_array( $last_complete_word, $statement_words ) ){ /* start of regexp */ 128 | $scope = REGEXP ; 129 | } 130 | }else if( $scope == ESCAPE ){ 131 | $scope = $before_escape_scope ; 132 | }else if( $scope == REGEXP ){ 133 | $scope = CODE ; 134 | }else if( $scope == MULTI_LINE_COMMENT ){ /* time to leave the comment?? */ 135 | $tmp = mb_substr( $code, $character_index - 1, 1 ); 136 | if( $tmp == '*' ) { 137 | $scope = CODE ; 138 | $post = "\n"; 139 | $post .= str_repeat( "\t", $num_indents ); 140 | } /* we only enter multi-line-comment mode from CODE scope AFAIK */ 141 | } 142 | break; 143 | case '{': 144 | if( $scope == CODE ){ /* start-of-block curly brace */ 145 | /* Sigbj�rn special: do not wrap and indent empty blocks (object literal) */ 146 | if( lookahead( $code, $character_index, true )=='}' ){ /* we have an object literal. We'll simply add a closing brace and jump ahead */ 147 | $character_index=strpos( $code, '}', $character_index ); 148 | $t = str_repeat("\t", $num_indents); 149 | $post="};\n{$t}"; 150 | break; 151 | } 152 | $num_indents ++ ; 153 | $post = "\n"; 154 | $post .= str_repeat( "\t", $num_indents ); 155 | $at_start_of_statement_or_expression = true; 156 | }else if( $scope == ESCAPE ){ 157 | $scope = $before_escape_scope ; 158 | } 159 | break; 160 | case '}': 161 | if( $scope == CODE ){ /* end-of-block curly brace */ 162 | if( $num_indents>0 )$num_indents -- ; 163 | $tmp = mb_substr( $code, $character_index +1, 1 ); 164 | $pre="\n"; 165 | $pre.=str_repeat("\t", $num_indents); 166 | if ($tmp!=";") { 167 | $post="\n".str_repeat("\t", $num_indents); 168 | } 169 | }else if( $scope == ESCAPE ){ 170 | $scope = $before_escape_scope ; 171 | } 172 | break; 173 | case ';': 174 | if( $scope == CODE ){ /* end-of-statement semicolon //, or between-variables comma */ 175 | if (!lookReverseForTo($code,$character_index,"for","\n")) { 176 | $post="\n"; 177 | $post.=str_repeat("\t", $num_indents); 178 | $at_start_of_statement_or_expression=true; 179 | } 180 | }else if( $scope == ESCAPE ){ 181 | $scope = $before_escape_scope ; 182 | } 183 | break; 184 | case "\n": 185 | if( $scope == SINGLE_LINE_COMMENT ){ 186 | $scope = CODE; /* we only enter SINGLE_LINE_COMMENT mode from CODE, right? */ 187 | }else if( $scope == ESCAPE ){ 188 | $scope = $before_escape_scope ; 189 | } /* no break, we want to get to the $at_start_of_statement_or_expression bit below */ 190 | case '(': 191 | case '!': 192 | case '=': 193 | case '-': 194 | case '+': 195 | case '?': 196 | case '*': 197 | case '&': 198 | case ':': 199 | case ',': 200 | case '|': 201 | if($char=="*" & $scope == MULTI_LINE_COMMENT ) { /* time to leave the comment?? */ 202 | $tmp=mb_substr($code, $character_index-1, 3); 203 | if ($tmp==' * ' || $tmp==" */") { 204 | $pre="\n".str_repeat( "\t", $num_indents )." "; 205 | } 206 | }else if( $scope == CODE ){ 207 | $at_start_of_statement_or_expression=true; /* at start of parens, after equal sign etc.. if the next char is a forward slash it will be a start-of-regexp, not a divisor */ 208 | }else if( $scope == ESCAPE ){ 209 | $scope = $before_escape_scope ; 210 | } 211 | break; 212 | case '[': 213 | if( $scope == REGEXP ){ 214 | $scope=REGEXP_CHAR_CLASS; 215 | $at_start_of_statement_or_expression=false; 216 | }else if( $scope == ESCAPE ){ 217 | $scope = $before_escape_scope ; 218 | } 219 | break; 220 | case ']': 221 | if( $scope == REGEXP_CHAR_CLASS ){ 222 | $scope=REGEXP; 223 | $at_start_of_statement_or_expression=false; 224 | }else if( $scope == ESCAPE ){ 225 | $scope = $before_escape_scope ; 226 | } 227 | break; 228 | default: 229 | if( $scope == ESCAPE ){ 230 | // $scope = $before_escape_scope ; /* always drop out of escape mode on next character.. yes, multi-char escapes exist but it's OK to treat the rest of it as part of the string */ 231 | } 232 | if( $scope == CODE ){ /* reset at_start_of_statement_or_expression flag (but ignore whitespace!) */ 233 | if( !( $char==' ' || $char=="\t" ) ) $at_start_of_statement_or_expression = false; 234 | } 235 | // if ($char=="\t" ) { 236 | // $character_index++; 237 | // continue 2; 238 | // } 239 | } 240 | if( preg_match('/[a-zA-Z0-9]/', $char) ){ 241 | /* if the previous character was whitespace or punctuation, this starts a new word.. */ 242 | if( ! preg_match('/[a-zA-Z0-9]/', mb_substr( $code, $character_index - 1, 1 )) ){ 243 | $last_complete_word=''; 244 | } 245 | $last_complete_word .= $char; 246 | } 247 | if( ($scope == CODE) && ( $char == "\t" || $char == "\n" ) ){ /* this script will add formatting whitespace */ // proven too fragile.. 248 | 249 | }else{ 250 | $output .= $pre . $char . $post ; 251 | } 252 | $character_index++; 253 | } 254 | $output = preg_replace( '/\n\s*\n/', "\n", $output ); 255 | if(!isset($sourceCode) || !$sourceCode){ 256 | $f=fopen($source_file, 'w'); 257 | fwrite($f, $output); 258 | fclose($f); 259 | echo $source_file; 260 | }else{ 261 | $sourceCode=$output; 262 | } 263 | 264 | ?> 265 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mostka/phptojs", 3 | "description": "Php to JS converter convert PHP code into JavaScript. Support Classes, namespaces, inheritance and more. ", 4 | "keywords": ["converter"], 5 | "minimum-stability": "dev", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Jozef Môstka", 10 | "email": "jozef@mostka.com" 11 | } 12 | ], 13 | "autoload": { 14 | "psr-4": { 15 | "phptojs\\": "lib/phptojs" 16 | } 17 | }, 18 | "require": { 19 | "php": "^5.3.3 || ^7.0", 20 | "nikic/php-parser": "3.x" 21 | }, 22 | "require-dev": { 23 | "phpunit/phpunit": "5.3.4" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/bootstrap.php: -------------------------------------------------------------------------------- 1 | ' . PHP_EOL); 12 | define('JS_SCRIPT_END', ''); 13 | 14 | 15 | use PhpParser\Node; 16 | use PhpParser\Node\Expr; 17 | use PhpParser\Node\Expr\AssignOp; 18 | use PhpParser\Node\Expr\BinaryOp; 19 | use PhpParser\Node\Expr\Cast; 20 | use PhpParser\Node\Name; 21 | use PhpParser\Node\Scalar; 22 | use PhpParser\Node\Scalar\MagicConst; 23 | use PhpParser\Node\Stmt; 24 | use PhpParser\ParserFactory; 25 | use PhpParser\PrettyPrinterAbstract; 26 | use PhpToJs\Printer\SourceWriter; 27 | 28 | abstract class JsPrinterAbstract extends PrettyPrinterAbstract { 29 | public static $enableVariadic = false; 30 | /** @var SourceWriter */ 31 | protected $writer; 32 | 33 | protected $ROOT_PATH_FROM = null; 34 | protected $ROOT_PATH_TO = null; 35 | protected $ROOT_PATH_TO_EXT = null; 36 | protected $isOnlyJsFile = false; 37 | 38 | /** 39 | * @return array 40 | */ 41 | public function getErrors() { 42 | return $this->errors; 43 | } 44 | 45 | public static $throwErrors = true; 46 | protected $errors = []; 47 | 48 | protected function notImplemented($expression, $message, $throw = false) { 49 | if ($expression) { 50 | $msg = "not implemented " . $message; 51 | $this->errors[] = $msg; 52 | if ($throw) { 53 | if (self::$throwErrors == true) { 54 | throw new \RuntimeException($msg); 55 | } else { 56 | } 57 | } 58 | } 59 | } 60 | 61 | /** 62 | * Pretty prints a file of statements (includes the opening ROOT_PATH_FROM = dirname($filePath) . DIRECTORY_SEPARATOR; 70 | $this->isOnlyJsFile = $isOnlyJsFile; 71 | 72 | $code = file_get_contents($filePath); 73 | 74 | $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7); 75 | $stmts = $parser->parse($code); 76 | 77 | $code = $this->jsPrint($stmts); 78 | 79 | if (!$isOnlyJsFile) { 80 | $code = JS_SCRIPT_BEGIN . $code . JS_SCRIPT_END; 81 | } 82 | $code = str_replace(JS_SCRIPT_BEGIN . JS_SCRIPT_END, "", $code); 83 | 84 | return $code; 85 | } 86 | 87 | public function jsPrintFileTo($filePath, $dstFilePath) { 88 | $this->ROOT_PATH_TO = dirname($dstFilePath) . DIRECTORY_SEPARATOR; 89 | $this->ROOT_PATH_TO_EXT = pathinfo($dstFilePath, PATHINFO_EXTENSION); 90 | $isOnlyJsFile = $this->ROOT_PATH_TO_EXT == 'js'; 91 | $code = $this->jsPrintFile($filePath, $isOnlyJsFile); 92 | if (!file_exists(dirname($dstFilePath))) { 93 | mkdir(dirname($dstFilePath), 0777, true); 94 | } 95 | return file_put_contents($dstFilePath, $code); 96 | } 97 | 98 | /** 99 | * Pretty prints a node. 100 | * 101 | * @param Node $node Node to be pretty printed 102 | * 103 | * @return void 104 | */ 105 | protected function p(Node $node) { 106 | $this->{'p' . $node->getType()}($node); 107 | } 108 | 109 | /** 110 | * Pretty prints an array of statements. 111 | * 112 | * @param Node[] $stmts Array of statements 113 | * 114 | * @return string Pretty printed statements 115 | */ 116 | public function jsPrint(array $stmts) { 117 | $this->pStmts($stmts, false); 118 | return $this->writer->getResetCode(); 119 | } 120 | 121 | 122 | /** 123 | * @see PhpParser\Printer\PrinterAbstract::pStmts 124 | * @param array $nodes 125 | * @param bool $indent 126 | * @return string|void 127 | */ 128 | protected function pStmts(array $nodes, $indent = true) { 129 | foreach ($nodes as $node) { 130 | $comments=$node->getAttribute('comments', array()); 131 | if ($comments && !($node instanceof Stmt\ClassMethod || $node instanceof Stmt\ClassConst)){ 132 | $this->pComments($comments); 133 | } 134 | 135 | $this->writer->pushDelay(); 136 | $this->p($node); 137 | $this->writer->popDelayToVar($stmts); 138 | 139 | $this->printVarDef(); 140 | $this->printUseByRefDef(); 141 | $this->writer->print_($stmts); 142 | 143 | $this->writer->println($node instanceof Node\Expr ? ';' : ''); 144 | } 145 | } 146 | 147 | abstract protected function printUseByRefDef(); 148 | 149 | abstract protected function printVarDef(); 150 | 151 | /** 152 | * @param \PhpParser\Comment[] $comments 153 | * @return void 154 | * @return string 155 | */ 156 | protected function pComments(array $comments) { 157 | foreach ($comments as $comment) { 158 | $comment=$comment->getReformattedText(); 159 | $comment=preg_replace('/(@(param|var) )([\w\|\\\\]+)( \$\w*)?/',"$1{\$3}$4",$comment); 160 | $comment=preg_replace('/(@(param|var) )({[\w\|\\\\]*} )?\$(\w*)/',"$1$3$4",$comment); 161 | $comment=str_replace(["@var","{\\","\\"],["@type","{N.","."],$comment); 162 | $this->writer->println($comment); 163 | } 164 | } 165 | 166 | /** 167 | * @see PhpParser\Printer\PrinterAbstract::pInfixOp 168 | * @param $type 169 | * @param \PhpParser\Node $leftNode 170 | * @param string|int $operator or delayId 171 | * @param \PhpParser\Node $rightNode 172 | * @return void 173 | */ 174 | protected function pInfixOp($type, Node $leftNode, $operator, Node $rightNode) { 175 | list($precedence, $associativity) = $this->precedenceMap[$type]; 176 | 177 | $this->pPrec($leftNode, $precedence, $associativity, -1); 178 | if (gettype($operator) == "integer") { 179 | $this->writer->writeDelay($operator); 180 | } else { 181 | $this->writer->print_($operator); 182 | } 183 | $this->pPrec($rightNode, $precedence, $associativity, 1); 184 | } 185 | 186 | /** 187 | * @see PhpParser\Printer\PrinterAbstract::pPrefixOp 188 | * @param $type 189 | * @param $operatorString 190 | * @param \PhpParser\Node $node 191 | * @return void 192 | */ 193 | protected function pPrefixOp($type, $operatorString, Node $node) { 194 | list($precedence, $associativity) = $this->precedenceMap[$type]; 195 | $this->writer->print_($operatorString); 196 | $this->pPrec($node, $precedence, $associativity, 1); 197 | } 198 | 199 | /** 200 | * @see PhpParser\Printer\PrinterAbstract::pPostfixOp 201 | * @param $type 202 | * @param \PhpParser\Node $node 203 | * @param $operatorString 204 | * @return void 205 | */ 206 | protected function pPostfixOp($type, Node $node, $operatorString) { 207 | list($precedence, $associativity) = $this->precedenceMap[$type]; 208 | $this->pPrec($node, $precedence, $associativity, -1); 209 | $this->writer->print_($operatorString); 210 | } 211 | 212 | /** 213 | * @see PhpParser\Printer\PrinterAbstract::pPrec 214 | * @param \PhpParser\Node $node 215 | * @param int $parentPrecedence 216 | * @param int $parentAssociativity 217 | * @param int $childPosition 218 | * @return void 219 | */ 220 | protected function pPrec(Node $node, $parentPrecedence, $parentAssociativity, $childPosition) { 221 | $type = $node->getType(); 222 | if (isset($this->precedenceMap[$type])) { 223 | $childPrecedence = $this->precedenceMap[$type][0]; 224 | if ($childPrecedence > $parentPrecedence || 225 | ($parentPrecedence == $childPrecedence && $parentAssociativity != $childPosition) 226 | ) { 227 | $this->writer->print_("("); 228 | $this->{'p' . $type}($node); 229 | $this->writer->print_(")"); 230 | return; 231 | } 232 | } 233 | 234 | $this->{'p' . $type}($node); 235 | } 236 | 237 | /** 238 | * @param array $nodes 239 | * @param string $glue 240 | * @return void 241 | */ 242 | protected function pImplode(array $nodes, $glue = '') { 243 | $l = count($nodes); 244 | for ($i = 0; $i < $l; $i++) { 245 | $node = $nodes[$i]; 246 | $this->p($node); 247 | if ($i < $l - 1) { 248 | $this->writer->print_($glue); 249 | } 250 | } 251 | } 252 | 253 | 254 | public function pScalar_LNumber(Scalar\LNumber $node) { 255 | $this->print_((string)$node->value); 256 | } 257 | 258 | public function pScalar_DNumber(Scalar\DNumber $node) { 259 | $stringValue = (string)$node->value; 260 | if ($stringValue == 'INF') { 261 | $stringValue = 'Infinity'; 262 | } 263 | // ensure that number is really printed as float 264 | $stringValue = ctype_digit($stringValue) ? $stringValue . '.0' : $stringValue; 265 | $this->print_($stringValue); 266 | } 267 | 268 | public function pExpr_Assign(Expr\Assign $node) { 269 | $this->pInfixOp('Expr_Assign', $node->var, ' = ', $node->expr); 270 | } 271 | 272 | public function pExpr_AssignRef(Expr\AssignRef $node) { 273 | $this->pInfixOp('Expr_AssignRef', $node->var, ' =& ', $node->expr); 274 | } 275 | 276 | public function pExpr_AssignOp_Plus(AssignOp\Plus $node) { 277 | $this->pInfixOp('Expr_AssignOp_Plus', $node->var, ' += ', $node->expr); 278 | } 279 | 280 | public function pExpr_AssignOp_Minus(AssignOp\Minus $node) { 281 | $this->pInfixOp('Expr_AssignOp_Minus', $node->var, ' -= ', $node->expr); 282 | } 283 | 284 | public function pExpr_AssignOp_Mul(AssignOp\Mul $node) { 285 | $this->pInfixOp('Expr_AssignOp_Mul', $node->var, ' *= ', $node->expr); 286 | } 287 | 288 | public function pExpr_AssignOp_Div(AssignOp\Div $node) { 289 | $this->pInfixOp('Expr_AssignOp_Div', $node->var, ' /= ', $node->expr); 290 | } 291 | 292 | public function pExpr_AssignOp_Concat(AssignOp\Concat $node) { 293 | $this->pInfixOp('Expr_AssignOp_Concat', $node->var, ' += ', $node->expr); 294 | } 295 | 296 | public function pExpr_AssignOp_Mod(AssignOp\Mod $node) { 297 | $this->pInfixOp('Expr_AssignOp_Mod', $node->var, ' %= ', $node->expr); 298 | } 299 | 300 | public function pExpr_AssignOp_BitwiseAnd(AssignOp\BitwiseAnd $node) { 301 | $this->pInfixOp('Expr_AssignOp_BitwiseAnd', $node->var, ' &= ', $node->expr); 302 | } 303 | 304 | public function pExpr_AssignOp_BitwiseOr(AssignOp\BitwiseOr $node) { 305 | $this->pInfixOp('Expr_AssignOp_BitwiseOr', $node->var, ' |= ', $node->expr); 306 | } 307 | 308 | public function pExpr_AssignOp_BitwiseXor(AssignOp\BitwiseXor $node) { 309 | $this->pInfixOp('Expr_AssignOp_BitwiseXor', $node->var, ' ^= ', $node->expr); 310 | } 311 | 312 | public function pExpr_AssignOp_ShiftLeft(AssignOp\ShiftLeft $node) { 313 | $this->pInfixOp('Expr_AssignOp_ShiftLeft', $node->var, ' <<= ', $node->expr); 314 | } 315 | 316 | public function pExpr_AssignOp_ShiftRight(AssignOp\ShiftRight $node) { 317 | $this->pInfixOp('Expr_AssignOp_ShiftRight', $node->var, ' >>= ', $node->expr); 318 | } 319 | 320 | public function pExpr_AssignOp_Pow(AssignOp\Pow $node) {//TODO: implement this 321 | $this->pInfixOp('Expr_AssignOp_Pow', $node->var, ' **= ', $node->expr); 322 | } 323 | 324 | // Binary expressions 325 | 326 | public function pExpr_BinaryOp_Plus(BinaryOp\Plus $node) { 327 | $this->pInfixOp('Expr_BinaryOp_Plus', $node->left, ' + ', $node->right); 328 | } 329 | 330 | public function pExpr_BinaryOp_Minus(BinaryOp\Minus $node) { 331 | $this->pInfixOp('Expr_BinaryOp_Minus', $node->left, ' - ', $node->right); 332 | } 333 | 334 | public function pExpr_BinaryOp_Mul(BinaryOp\Mul $node) { 335 | $this->pInfixOp('Expr_BinaryOp_Mul', $node->left, ' * ', $node->right); 336 | } 337 | 338 | public function pExpr_BinaryOp_Div(BinaryOp\Div $node) { 339 | $this->pInfixOp('Expr_BinaryOp_Div', $node->left, ' / ', $node->right); 340 | } 341 | 342 | public function pExpr_BinaryOp_Concat(BinaryOp\Concat $node) { 343 | if ($this->isConcatString($node)){ 344 | $this->p($node->left); 345 | $this->writer->print_("+"); 346 | $this->p($node->right); 347 | }else { 348 | $this->pInfixOp('Expr_BinaryOp_Concat', $node->left, ' . ', $node->right); 349 | } 350 | } 351 | 352 | private function isConcatString(BinaryOp\Concat $node){ 353 | if ($node->left instanceof BinaryOp\Concat){ 354 | if($this->isConcatString($node->left)){ 355 | return true; 356 | } 357 | } 358 | if ($node->right instanceof BinaryOp\Concat){ 359 | if($this->isConcatString($node->right)){ 360 | return true; 361 | } 362 | } 363 | if ($node->left instanceof Scalar\String_ || $node->right instanceof Scalar\String_){ 364 | return true; 365 | } 366 | return false; 367 | } 368 | 369 | public function pExpr_BinaryOp_Mod(BinaryOp\Mod $node) { 370 | $this->pInfixOp('Expr_BinaryOp_Mod', $node->left, ' % ', $node->right); 371 | } 372 | 373 | public function pExpr_BinaryOp_BooleanAnd(BinaryOp\BooleanAnd $node) { 374 | $this->pInfixOp('Expr_BinaryOp_BooleanAnd', $node->left, ' && ', $node->right); 375 | } 376 | 377 | public function pExpr_BinaryOp_BooleanOr(BinaryOp\BooleanOr $node) { 378 | $this->pInfixOp('Expr_BinaryOp_BooleanOr', $node->left, ' || ', $node->right); 379 | } 380 | 381 | public function pExpr_BinaryOp_BitwiseAnd(BinaryOp\BitwiseAnd $node) { 382 | $this->pInfixOp('Expr_BinaryOp_BitwiseAnd', $node->left, ' & ', $node->right); 383 | } 384 | 385 | public function pExpr_BinaryOp_BitwiseOr(BinaryOp\BitwiseOr $node) { 386 | $this->pInfixOp('Expr_BinaryOp_BitwiseOr', $node->left, ' | ', $node->right); 387 | } 388 | 389 | public function pExpr_BinaryOp_BitwiseXor(BinaryOp\BitwiseXor $node) { 390 | $this->pInfixOp('Expr_BinaryOp_BitwiseXor', $node->left, ' ^ ', $node->right); 391 | } 392 | 393 | public function pExpr_BinaryOp_ShiftLeft(BinaryOp\ShiftLeft $node) { 394 | $this->pInfixOp('Expr_BinaryOp_ShiftLeft', $node->left, ' << ', $node->right); 395 | } 396 | 397 | public function pExpr_BinaryOp_ShiftRight(BinaryOp\ShiftRight $node) { 398 | $this->pInfixOp('Expr_BinaryOp_ShiftRight', $node->left, ' >> ', $node->right); 399 | } 400 | 401 | public function pExpr_BinaryOp_Pow(BinaryOp\Pow $node) {//TODO: implement this 402 | $this->pInfixOp('Expr_BinaryOp_Pow', $node->left, ' ** ', $node->right); 403 | } 404 | 405 | public function pExpr_BinaryOp_LogicalAnd(BinaryOp\LogicalAnd $node) { 406 | $this->pInfixOp('Expr_BinaryOp_LogicalAnd', $node->left, ' && ', $node->right); 407 | } 408 | 409 | public function pExpr_BinaryOp_LogicalOr(BinaryOp\LogicalOr $node) { 410 | $this->pInfixOp('Expr_BinaryOp_LogicalOr', $node->left, ' || ', $node->right); 411 | } 412 | 413 | public function pExpr_BinaryOp_LogicalXor(BinaryOp\LogicalXor $node) {//TODO: implement this 414 | $this->pInfixOp('Expr_BinaryOp_LogicalXor', $node->left, ' ^ ', $node->right); 415 | } 416 | 417 | public function pExpr_BinaryOp_Equal(BinaryOp\Equal $node) { 418 | $this->pInfixOp('Expr_BinaryOp_Equal', $node->left, ' == ', $node->right); 419 | } 420 | 421 | public function pExpr_BinaryOp_NotEqual(BinaryOp\NotEqual $node) { 422 | $this->pInfixOp('Expr_BinaryOp_NotEqual', $node->left, ' != ', $node->right); 423 | } 424 | 425 | public function pExpr_BinaryOp_Identical(BinaryOp\Identical $node) { 426 | $this->pInfixOp('Expr_BinaryOp_Identical', $node->left, ' === ', $node->right); 427 | } 428 | 429 | public function pExpr_BinaryOp_NotIdentical(BinaryOp\NotIdentical $node) { 430 | $this->pInfixOp('Expr_BinaryOp_NotIdentical', $node->left, ' !== ', $node->right); 431 | } 432 | 433 | public function pExpr_BinaryOp_Spaceship(BinaryOp\Spaceship $node) { 434 | //TODO: Implement pExpr_BinaryOp_Spaceship() method. 435 | $this->notImplemented(true, __METHOD__); 436 | } 437 | 438 | public function pExpr_BinaryOp_Greater(BinaryOp\Greater $node) { 439 | $this->pInfixOp('Expr_BinaryOp_Greater', $node->left, ' > ', $node->right); 440 | } 441 | 442 | public function pExpr_BinaryOp_GreaterOrEqual(BinaryOp\GreaterOrEqual $node) { 443 | $this->pInfixOp('Expr_BinaryOp_GreaterOrEqual', $node->left, ' >= ', $node->right); 444 | } 445 | 446 | public function pExpr_BinaryOp_Smaller(BinaryOp\Smaller $node) { 447 | $this->pInfixOp('Expr_BinaryOp_Smaller', $node->left, ' < ', $node->right); 448 | } 449 | 450 | public function pExpr_BinaryOp_SmallerOrEqual(BinaryOp\SmallerOrEqual $node) { 451 | $this->pInfixOp('Expr_BinaryOp_SmallerOrEqual', $node->left, ' <= ', $node->right); 452 | } 453 | 454 | public function pExpr_BinaryOp_Coalesce(BinaryOp\Coalesce $node) { 455 | // TODO: Implement pExpr_BinaryOp_Coalesce() method. 456 | $this->notImplemented(true, __METHOD__); 457 | } 458 | 459 | // Unary expressions 460 | 461 | public function pExpr_BooleanNot(Expr\BooleanNot $node) { 462 | $this->pPrefixOp('Expr_BooleanNot', '!', $node->expr); 463 | } 464 | 465 | public function pExpr_BitwiseNot(Expr\BitwiseNot $node) {//TODO: implement this 466 | $this->pPrefixOp('Expr_BitwiseNot', '~', $node->expr); 467 | } 468 | 469 | public function pExpr_UnaryMinus(Expr\UnaryMinus $node) { 470 | $this->pPrefixOp('Expr_UnaryMinus', '-', $node->expr); 471 | } 472 | 473 | public function pExpr_UnaryPlus(Expr\UnaryPlus $node) { 474 | $this->pPrefixOp('Expr_UnaryPlus', '+', $node->expr); 475 | } 476 | 477 | public function pExpr_PreInc(Expr\PreInc $node) { 478 | $this->pPrefixOp('Expr_PreInc', '++', $node->var); 479 | } 480 | 481 | public function pExpr_PreDec(Expr\PreDec $node) { 482 | $this->pPrefixOp('Expr_PreDec', '--', $node->var); 483 | } 484 | 485 | public function pExpr_PostInc(Expr\PostInc $node) { 486 | $this->pPostfixOp('Expr_PostInc', $node->var, '++'); 487 | } 488 | 489 | public function pExpr_PostDec(Expr\PostDec $node) { 490 | $this->pPostfixOp('Expr_PostDec', $node->var, '--'); 491 | } 492 | 493 | public function pExpr_ErrorSuppress(Expr\ErrorSuppress $node) {//TODO: implement this 494 | $this->notImplemented(true, 'ErrorSuppress by @', true); 495 | $this->pPrefixOp('Expr_ErrorSuppress', '@', $node->expr); 496 | } 497 | 498 | public function pExpr_YieldFrom(Expr\YieldFrom $node) { 499 | // TODO: Implement pExpr_YieldFrom() method. 500 | $this->notImplemented(true, __METHOD__); 501 | } 502 | 503 | public function pExpr_Print(Expr\Print_ $node) { 504 | // TODO: Implement pExpr_Print() method. 505 | $this->print_("console.log("); 506 | $this->p($node->expr); 507 | $this->print_(")"); 508 | } 509 | 510 | // Casts 511 | 512 | public function pExpr_Cast_Int(Cast\Int_ $node) { 513 | $this->print_("parseInt("); 514 | $this->p($node->expr); 515 | $this->print_(")"); 516 | } 517 | 518 | public function pExpr_Cast_Double(Cast\Double $node) { 519 | $this->print_("parseFloat("); 520 | $this->p($node->expr); 521 | $this->print_(")"); 522 | } 523 | 524 | public function pExpr_Cast_String(Cast\String_ $node) { 525 | $this->print_("("); 526 | $this->p($node->expr); 527 | $this->print_(").toString()"); 528 | } 529 | 530 | public function pExpr_Cast_Array(Cast\Array_ $node) {//TODO: implement this 531 | $this->notImplemented(true, ' conversion to (array)', true); 532 | $this->pPrefixOp('Expr_Cast_Array', '(array) ', $node->expr); 533 | } 534 | 535 | public function pExpr_Cast_Object(Cast\Object_ $node) {//TODO: implement this 536 | $this->notImplemented(true, ' conversion to (object)', true); 537 | $this->pPrefixOp('Expr_Cast_Object', '(object) ', $node->expr); 538 | } 539 | 540 | public function pExpr_Cast_Bool(Cast\Bool_ $node) { 541 | return "Boolean(" . $this->p($node->expr) . ")"; 542 | } 543 | 544 | public function pExpr_Cast_Unset(Cast\Unset_ $node) {//TODO: implement this 545 | $this->notImplemented(true, __METHOD__); 546 | $this->pPrefixOp('Expr_Cast_Unset', 'delete ', $node->expr); 547 | } 548 | 549 | public function pExpr_Empty(Expr\Empty_ $node) {//TODO: implement this 550 | $this->print_('empty('); 551 | $this->p($node->expr); 552 | $this->print_(')'); 553 | } 554 | 555 | public function pExpr_Isset(Expr\Isset_ $node) {//TODO: implement this 556 | $this->print_('isset('); 557 | $this->pCommaSeparated($node->vars); 558 | $this->print_(')'); 559 | } 560 | 561 | public function pExpr_Eval(Expr\Eval_ $node) {//TODO: implement this 562 | $this->print_('eval('); 563 | $this->p($node->expr); 564 | $this->print_(')'); 565 | } 566 | 567 | /** 568 | * @param null $atStart 569 | * @return JsPrinter 570 | */ 571 | public function pushDelay($atStart = null) { 572 | call_user_func_array(array($this->writer, __FUNCTION__), func_get_args()); 573 | return $this; 574 | } 575 | 576 | /** 577 | * @param null $id 578 | * @return JsPrinter 579 | */ 580 | public function popDelay(&$id = null) { 581 | $this->writer->popDelay($id); 582 | return $this; 583 | } 584 | 585 | /** 586 | * @param $var 587 | * @return $this 588 | */ 589 | public function popDelayToVar(&$var) { 590 | $this->writer->popDelayToVar($var); 591 | return $this; 592 | } 593 | 594 | /** 595 | * @param $id 596 | * @return JsPrinter 597 | */ 598 | public function writeDelay($id) { 599 | call_user_func_array(array($this->writer, __FUNCTION__), func_get_args()); 600 | return $this; 601 | } 602 | 603 | /** 604 | * @return JsPrinter 605 | */ 606 | public function writeLastDelay() { 607 | call_user_func_array(array($this->writer, __FUNCTION__), func_get_args()); 608 | return $this; 609 | } 610 | 611 | /** 612 | * @param $string 613 | * @param ... $objects 614 | * @return JsPrinter 615 | */ 616 | public function println($string = '', $objects = null) { 617 | call_user_func_array(array($this->writer, __FUNCTION__), func_get_args()); 618 | return $this; 619 | } 620 | 621 | /** 622 | * @param $string 623 | * @param ... $objects 624 | * @return JsPrinter 625 | */ 626 | public function print_($string, $objects = null) { 627 | call_user_func_array(array($this->writer, __FUNCTION__), func_get_args()); 628 | return $this; 629 | } 630 | 631 | /** 632 | * @return JsPrinter 633 | */ 634 | public function indent() { 635 | call_user_func_array(array($this->writer, __FUNCTION__), func_get_args()); 636 | return $this; 637 | } 638 | 639 | /** 640 | * @return JsPrinter 641 | */ 642 | public function outdent() { 643 | call_user_func_array(array($this->writer, __FUNCTION__), func_get_args()); 644 | return $this; 645 | } 646 | 647 | /** 648 | * @param $string 649 | * @param ... $objects 650 | * @return JsPrinter 651 | */ 652 | public function indentln($string, $objects = null) { 653 | call_user_func_array(array($this->writer, __FUNCTION__), func_get_args()); 654 | return $this; 655 | } 656 | } -------------------------------------------------------------------------------- /lib/phptojs/JsPrinter/JsPrinterInterface.php: -------------------------------------------------------------------------------- 1 | code = ""; 28 | $this->codeStack = array(); 29 | $this->atStartStack = array(); 30 | $this->delayStack = array(); 31 | $this->finalCode = ""; 32 | 33 | $this->indent = 0; 34 | $this->indentStr = ""; 35 | $this->atStart = true; 36 | } 37 | 38 | /** 39 | * @param null $atStart 40 | * @return $this 41 | */ 42 | public function pushDelay($atStart = null) { 43 | $this->codeStack[] = $this->code; 44 | $this->atStartStack[] = $this->atStart; 45 | $this->code = ""; 46 | if ($atStart !== null) { 47 | $this->atStart = $atStart; 48 | } 49 | return $this; 50 | } 51 | 52 | private $lastDelay; 53 | private $lastKey = 0; 54 | 55 | /** 56 | * @param null $id 57 | * @return $this 58 | * @throws \Exception 59 | */ 60 | public function popDelay(&$id = null) { 61 | $this->delayStack[$id = $this->lastDelay = $this->lastKey++] = $this->code; 62 | $this->code = array_pop($this->codeStack); 63 | $this->atStart = array_pop($this->atStartStack); 64 | return $this; 65 | } 66 | 67 | /** 68 | * @param $var 69 | * @return $this 70 | */ 71 | public function popDelayToVar(&$var) { 72 | $var = $this->code; 73 | $this->code = array_pop($this->codeStack); 74 | $this->atStart = array_pop($this->atStartStack); 75 | return $this; 76 | } 77 | 78 | /** 79 | * @param $id 80 | * @return $this 81 | */ 82 | public function writeDelay($id) { 83 | $this->code .= $this->delayStack[$id]; 84 | unset($this->delayStack[$id]); 85 | return $this; 86 | } 87 | 88 | /** 89 | * @return $this 90 | */ 91 | public function writeLastDelay() { 92 | return $this->writeDelay($this->lastDelay); 93 | } 94 | 95 | /** 96 | * @param $string 97 | * @param ... $objects 98 | * @return $this 99 | */ 100 | public function println($string = '', $objects = null) { 101 | if ($string && $objects !== null) { 102 | //$string = call_user_func_array('sprintf',func_get_args()); 103 | $string = $this->printf(func_get_args()); 104 | } 105 | $this->print_($string . self::$EOL); 106 | $this->atStart = true; 107 | return $this; 108 | } 109 | 110 | /** 111 | * @param $string 112 | * @param ... $objects 113 | * @return $this 114 | */ 115 | public function print_($string, $objects = null) { 116 | if ($string && $objects !== null) { 117 | //$string = call_user_func_array('sprintf',func_get_args()); 118 | $string = $this->printf(func_get_args()); 119 | } 120 | if ($this->atStart) { 121 | $this->code .= $this->indentStr; 122 | $this->atStart = false; 123 | } 124 | $this->code .= $string; 125 | return $this; 126 | } 127 | 128 | /** 129 | * @return $this 130 | */ 131 | public function indent() { 132 | $this->indentStr = str_repeat(self::$indentChr, ++$this->indent); 133 | return $this; 134 | } 135 | 136 | /** 137 | * @return $this 138 | */ 139 | public function outdent() { 140 | $this->indentStr = str_repeat(self::$indentChr, --$this->indent); 141 | return $this; 142 | } 143 | 144 | /** 145 | * @param $string 146 | * @param ... $objects 147 | * @return $this 148 | */ 149 | public function indentln($string, $objects = null) { 150 | if ($string && $objects !== null) { 151 | //$string = call_user_func_array('sprintf',func_get_args()); 152 | $string = $this->printf(func_get_args()); 153 | } 154 | $this->indent(); 155 | $this->println($string); 156 | $this->outdent(); 157 | return $this; 158 | } 159 | 160 | public function getCode() { 161 | if (count($this->delayStack) > 0) { 162 | throw new \Exception("DelayStack is not empty (" . count($this->delayStack) . ")"); 163 | } 164 | if (count($this->codeStack) > 0) { 165 | throw new \Exception("CodeStack is not empty (" . count($this->codeStack) . ")"); 166 | } 167 | return $this->finalCode . $this->code; 168 | } 169 | 170 | public function getResetCode() { 171 | $res = $this->getCode(); 172 | $this->reset(); 173 | return $res; 174 | } 175 | 176 | private function printf($args) { 177 | $string = array_shift($args); 178 | foreach ($args as $arg) { 179 | $string = preg_replace('/%{\w*}/', $arg, $string, 1); 180 | } 181 | return $string; 182 | } 183 | 184 | } -------------------------------------------------------------------------------- /lib/phptojs/Printer/SourceWriterInterface.php: -------------------------------------------------------------------------------- 1 | this.___key_int) { 18 | this.___key_int = parseInt(key) + 1; 19 | } 20 | }; 21 | HashArray.prototype.push = function (value) { 22 | var key = this.___key_int++; 23 | this.___keys.push(key); 24 | this[key] = value; 25 | }; 26 | HashArray.prototype.delete_ = function (key) { 27 | delete this[key]; 28 | this.___keys.splice(this.___keys.indexOf(item), 1); 29 | }; 30 | HashArray.prototype.data = function () { 31 | return this; 32 | }; 33 | HashArray.prototype.count = function () { 34 | return this.___keys.length; 35 | }; 36 | HashArray.prototype.current = function () { 37 | return this[this.___keys[this.___key_pos]]; 38 | }; 39 | HashArray.prototype.next = function () { 40 | this.___key_pos++; 41 | }; 42 | HashArray.prototype.key = function () { 43 | return this.___keys[this.___key_pos]; 44 | }; 45 | HashArray.prototype.valid = function () { 46 | return typeof this[this.___keys[this.___key_pos]] != 'undefined'; 47 | }; 48 | return HashArray; 49 | })(); 50 | } 51 | -------------------------------------------------------------------------------- /lib/phptojs/lib/js/JsArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by PhpStorm. 3 | * User: Jozef Môstka 4 | * Date: 4.6.2016 5 | * Time: 22:41 6 | */ 7 | if (typeof N == 'undefined') N = {}; 8 | if (typeof N.jsphp == 'undefined') N.jsphp = {}; 9 | (function () { 10 | var functions = ["indexOf", "concat", "copyWithin", "entries", "every", 11 | "filter", "find", "findIndex", "forEach", "includes", "indexOf", 12 | "join", "keys", "lastIndexOf", "map", "pop", "push", "reduce", 13 | "reduceRight", "reverse", "shift", "slice", "some", "sort", 14 | "splice", "toLocaleString", "toSource", "toString", "unshift", 15 | "values", "fill" 16 | ]; 17 | 18 | var JsArray = this.JsArray = function () { 19 | var arr = []; 20 | arr.push.apply(arr, arguments); 21 | arr.__proto__ = JsArray.prototype; 22 | if (arr.forEach === undefined) { 23 | // FIXED: for nodejs 24 | for (var i = 0; i < functions.length; i++) { 25 | arr.__proto__[functions[i]] = Array.prototype[functions[i]]; 26 | } 27 | } 28 | return arr; 29 | }; 30 | __extends(JsArray,Array); 31 | var arrayStaticMethods = ["from", "isArray", "of"]; 32 | for (var i = 0; i < arrayStaticMethods.length; i++) { 33 | JsArray[arrayStaticMethods[i]] = Array[arrayStaticMethods[i]]; 34 | } 35 | }).call(N.jsphp); -------------------------------------------------------------------------------- /lib/phptojs/lib/js/JsObject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by PhpStorm. 3 | * User: Jozef Môstka 4 | * Date: 4.6.2016 5 | * Time: 11:38 6 | */ 7 | if (typeof N == 'undefined') N = {}; 8 | if (typeof N.jsphp == 'undefined') N.jsphp = {}; 9 | N.jsphp.JsObject=function () { 10 | if (arguments.length>0){ 11 | if (arguments[0] instanceof Object){ 12 | for(var i in arguments[0]){ 13 | if (!arguments[0].hasOwnProperty(i)) continue; 14 | this[i]=arguments[0][i]; 15 | } 16 | } 17 | } 18 | }; 19 | N.jsphp.JsObject.prototype = new Object(); 20 | N.jsphp.JsObject.assign=function (target) { 21 | if (target===null || typeof target=="undefined"){ 22 | throw new Exception("Cannot convert undefined or null to object"); 23 | } 24 | if (!target instanceof N.jsphp.JsObject){ 25 | if (target instanceof Array || target.constructor.name=="Object") { 26 | target = new N.jsphp.JsObject(target); 27 | }else if (typeof target=="function"){ 28 | return target; 29 | }else{ 30 | throw new Exception("This type is not implemented yet "+(typeof target)); 31 | } 32 | } 33 | if (arguments.length>1){ 34 | for(var i=1;i 20 | * Return the current element 21 | * @link http://php.net/manual/en/iterator.current.php 22 | * @return mixed Can return any type. 23 | */ 24 | public function current() { 25 | $this->a = &$this->data; 26 | return current($this->data); 27 | } 28 | 29 | /** 30 | * (PHP 5 >= 5.0.0)
31 | * Move forward to next element 32 | * @link http://php.net/manual/en/iterator.next.php 33 | * @return mixed next value. 34 | */ 35 | public function next() { 36 | next($this->data); 37 | return $this->current(); 38 | } 39 | 40 | /** 41 | * (PHP 5 >= 5.0.0)
42 | * Return the key of the current element 43 | * @link http://php.net/manual/en/iterator.key.php 44 | * @return mixed scalar on success, or null on failure. 45 | */ 46 | public function key() { 47 | return key($this->data); 48 | } 49 | 50 | /** 51 | * (PHP 5 >= 5.0.0)
52 | * Checks if current position is valid 53 | * @link http://php.net/manual/en/iterator.valid.php 54 | * @return boolean The return value will be casted to boolean and then evaluated. 55 | * Returns true on success or false on failure. 56 | */ 57 | public function valid() { 58 | return key($this->data) !== null; 59 | } 60 | 61 | /** 62 | * (PHP 5 >= 5.0.0)
63 | * Rewind the Iterator to the first element 64 | * @link http://php.net/manual/en/iterator.rewind.php 65 | * @return void Any returned value is ignored. 66 | */ 67 | public function rewind() { 68 | reset($this->data); 69 | } 70 | 71 | /** 72 | * (PHP 5 >= 5.0.0)
73 | * Whether a offset exists 74 | * @link http://php.net/manual/en/arrayaccess.offsetexists.php 75 | * @param mixed $offset

76 | * An offset to check for. 77 | *

78 | * @return boolean true on success or false on failure. 79 | *

80 | *

81 | * The return value will be casted to boolean if non-boolean was returned. 82 | */ 83 | public function offsetExists($offset) { 84 | return isset($this->data); 85 | } 86 | 87 | /** 88 | * (PHP 5 >= 5.0.0)
89 | * Offset to retrieve 90 | * @link http://php.net/manual/en/arrayaccess.offsetget.php 91 | * @param mixed $offset

92 | * The offset to retrieve. 93 | *

94 | * @return mixed Can return all value types. 95 | */ 96 | public function offsetGet($offset) { 97 | return $this->data[$offset]; 98 | } 99 | 100 | /** 101 | * @deprecated 102 | * @param mixed $offset 103 | * @param mixed $value 104 | * @return void 105 | */ 106 | public function offsetSet($offset, $value) { 107 | throw new \BadMethodCallException("You cant set data to HashArray by \$hashArray[0]=0. use \$hasArray->set(0,0)"); 108 | } 109 | 110 | /** 111 | * (PHP 5 >= 5.0.0)
112 | * Offset to unset 113 | * @link http://php.net/manual/en/arrayaccess.offsetunset.php 114 | * @param mixed $offset

115 | * The offset to unset. 116 | *

117 | * @return void 118 | */ 119 | public function offsetUnset($offset) { 120 | throw new \BadMethodCallException("You cant unset data to HashArray by unset \$hashArray[0]. use \$hasArray->delete(0)"); 121 | } 122 | 123 | public function set($offset, $value) { 124 | $this->data[$offset] = $value; 125 | } 126 | 127 | public function push($value) { 128 | $this->data[] = $value; 129 | } 130 | 131 | public function delete($offset) { 132 | unset($this->data[$offset]); 133 | } 134 | 135 | public function __get($name) { 136 | return $this->data[$name]; 137 | } 138 | 139 | /** 140 | * (PHP 5 >= 5.1.0)
141 | * Count elements of an object 142 | * @link http://php.net/manual/en/countable.count.php 143 | * @return int The custom count as an integer. 144 | *

145 | *

146 | * The return value is cast to an integer. 147 | */ 148 | public function count() { 149 | return count($this->data); 150 | } 151 | 152 | public function arr() { 153 | return $this->data; 154 | } 155 | } -------------------------------------------------------------------------------- /lib/phptojs/lib/php/JsArray.php: -------------------------------------------------------------------------------- 1 | onlyKeys=$onlyKeys; 35 | $this->onlyValues=$onlyValues; 36 | if ($data instanceof JsArray) { 37 | $this->data = []; 38 | for ($i = 0; $i < $data->length; $i++) { 39 | if ($onlyKeys) { 40 | $this->data[] = $data[$i]; 41 | } else if ($onlyValues) { 42 | $this->data[] = $data[$i]; 43 | }else{ 44 | $this->data[] = $data[$i]; 45 | } 46 | } 47 | } else if (gettype($data) == "array" && array_values($data) === $data) { 48 | foreach ($data as $key => $value) { 49 | if ($onlyKeys) { 50 | $this->data[] = $key; 51 | } else if ($onlyValues) { 52 | $this->data[] = $value; 53 | } else { 54 | $this->data[] = $value; 55 | } 56 | } 57 | } else { 58 | throw new \Exception("Iterator can get only JsArray o indexed array"); 59 | } 60 | } 61 | 62 | /** 63 | * @internal 64 | */ 65 | public function current() { 66 | return current($this->data); 67 | } 68 | 69 | /** 70 | * Move forward to next element 71 | * @link http://php.net/manual/en/iterator.next.php 72 | * @return JsArrayIteratorPair Any returned value is ignored. 73 | * @since 5.0.0 74 | */ 75 | public function next() { 76 | $ret = new JsArrayIteratorPair(); 77 | $current = current($this->data); 78 | if ($current===false){ 79 | $ret->done=true; 80 | if ($this->onlyKeys || $this->onlyValues){ 81 | $ret->value=undefined; 82 | }else { 83 | $ret->value = new JsArray( 84 | undefined, 85 | undefined 86 | ); 87 | } 88 | }else { 89 | $ret->done = false; 90 | if ($this->onlyKeys) { 91 | $ret->value = key($this->data); 92 | } else if ($this->onlyValues) { 93 | $ret->value = current($this->data); 94 | }else{ 95 | $ret->value = new JsArray( 96 | key($this->data), 97 | current($this->data) 98 | ); 99 | } 100 | next($this->data); 101 | } 102 | return $ret; 103 | } 104 | 105 | /** 106 | * @internal 107 | */ 108 | public function key() { 109 | return key($this->data); 110 | } 111 | 112 | /** 113 | * @internal 114 | */ 115 | public function valid() { 116 | return key($this->data)!==null; 117 | } 118 | 119 | /** 120 | * @internal 121 | */ 122 | public function rewind() { 123 | // reset($this->data); 124 | } 125 | } 126 | 127 | namespace jsphp; 128 | use jsphp\util\JsArrayIterator; 129 | 130 | /** 131 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array 132 | * The JavaScript Array object is a global object that is used in the construction of arrays; which are high-level, list-like objects. 133 | * @property int length 134 | * @package jsphp 135 | */ 136 | class JsArray implements \ArrayAccess, \JsonSerializable{ 137 | 138 | private $data; 139 | 140 | /** 141 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array 142 | * The JavaScript Array object is a global object that is used in the construction of arrays; which are high-level, list-like objects. 143 | * @param int|mixed $length If the only argument passed to the Array constructor is an integer between 0 and 232-1 (inclusive), this returns a new JavaScript array with length set to that number. If the argument is any other number, a RangeError exception is thrown. 144 | * @param mixed [$elementN] A JavaScript array is initialized with the given elements, except in the case where a single argument is passed to the Array constructor and that argument is a number (see the arrayLength parameter below).Note that this special case only applies to JavaScript arrays created with the Array constructor, not array literals created with the bracket syntax. 145 | */ 146 | public function __construct() { 147 | $args=func_get_args(); 148 | if (count($args)==1 && is_numeric($args[0])){ 149 | while($args[0]-->0){ 150 | $this->data[]=undefined; 151 | } 152 | }else if(count($args)>0){ 153 | foreach($args as $arg){ 154 | $this->data[]=$arg; 155 | } 156 | } 157 | } 158 | 159 | /** 160 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach 161 | * Calls a defined callback function on each element of an array, and returns an array that contains the results. 162 | * @param callback $callback A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array. 163 | */ 164 | public function forEach($callback){ 165 | 166 | foreach ($this->data as $index=>$value){ 167 | call_user_func_array($callback,[$value,$index,$this]); 168 | } 169 | } 170 | 171 | /** 172 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from 173 | * The Array::from() method creates a new Array instance from an array-like or iterable object. 174 | * @param array|JsArray|string|JsObject $arrayLike An array-like or iterable object to convert to an array. 175 | * @param callable $mapFunction Optional. Map function to call on every element of the array. 176 | * @return JsArray 177 | * @throws \Exception 178 | */ 179 | public static function from($arrayLike, $mapFunction=null){ 180 | $ret = new JsArray(); 181 | if ($mapFunction!==null){ 182 | if (gettype($arrayLike)=="array" && array_key_exists("length",$arrayLike)) { 183 | for($i=0;$i<$arrayLike["length"];$i++){ 184 | $ret->data[] = call_user_func_array($mapFunction, [undefined,$i]); 185 | } 186 | return $ret; 187 | } 188 | if($arrayLike instanceof JsObject && $arrayLike->offsetExists("length")){ 189 | for($i=0;$i<$arrayLike["length"];$i++){ 190 | $ret->data[] = call_user_func_array($mapFunction, [undefined,$i]); 191 | } 192 | return $ret; 193 | } 194 | if($arrayLike instanceof JsArray){ 195 | foreach ($arrayLike->data as $key=>$val) { 196 | $ret->data[] = call_user_func_array($mapFunction, [$val,$key]); 197 | } 198 | return $ret; 199 | } 200 | if(is_string($arrayLike)) { 201 | $chars = str_split($arrayLike); 202 | foreach ($chars as $char) { 203 | $ret->data[] = $char; 204 | } 205 | return $ret; 206 | } 207 | foreach ($arrayLike as $key=>$val) { 208 | $ret->data[] = call_user_func_array($mapFunction, [$val,$key]); 209 | } 210 | return $ret; 211 | }else{ 212 | if (gettype($arrayLike)=="array"){ 213 | if (array_values($arrayLike) === $arrayLike){ 214 | foreach ($arrayLike as $val){ 215 | $ret->data[]=$val; 216 | } 217 | return $ret; 218 | } 219 | if (array_key_exists("length",$arrayLike)) { 220 | for($i=0;$i<$arrayLike["length"];$i++){ 221 | $ret->data[] = call_user_func_array($mapFunction, [undefined,$i]); 222 | } 223 | return $ret; 224 | } 225 | return $ret; 226 | } 227 | if($arrayLike instanceof JsObject && $arrayLike->offsetExists("length")){ 228 | for($i=0;$i<$arrayLike["length"];$i++){ 229 | $ret->data[] = call_user_func_array($mapFunction, [undefined,$i]); 230 | } 231 | return $ret; 232 | } 233 | if ($arrayLike instanceof JsArray){ 234 | foreach ($arrayLike->data as $val){ 235 | $ret->data[]=$val; 236 | } 237 | return $ret; 238 | } 239 | if(is_string($arrayLike)){ 240 | $chars = str_split($arrayLike); 241 | foreach($chars as $char){ 242 | $ret->data[]=$char; 243 | } 244 | return $ret; 245 | } 246 | if ($arrayLike===null || $arrayLike===undefined){ 247 | throw new \Exception("Cannot convert undefined or null to object"); 248 | } 249 | return $ret; 250 | } 251 | } 252 | 253 | /** 254 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray 255 | * The Array::isArray() determines whether the passed value is an Array. 256 | * @param mixed $object The object to be checked. 257 | * @return bool If the object is an Array, true is returned, otherwise false is. 258 | */ 259 | public static function isArray($object){ 260 | if (gettype($object)=="array" && array_values($object) === $object){ 261 | return true; 262 | } 263 | if ($object instanceof JsArray){ 264 | return true; 265 | } 266 | return false; 267 | } 268 | 269 | /** 270 | * The Array.of() method creates a new Array instance with a variable number of arguments, regardless of number or type of the arguments. 271 | * 272 | * The difference between Array.of() and the Array constructor is in the handling of integer arguments: Array.of(42) creates an array with a single element, 42, whereas Array(42) creates an array with 42 elements, each of which is undefined. 273 | * @param mixed ...element Elements of which to create the array. 274 | * @return JsArray 275 | */ 276 | public static function of($element){ 277 | $ret = new JsArray(); 278 | foreach (func_get_args() as $val){ 279 | $ret->data[]=$val; 280 | } 281 | return $ret; 282 | } 283 | 284 | /** 285 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of 286 | * The concat() method returns a new array comprised of the array on which it is called joined with the array(s) and/or value(s) provided as arguments. 287 | * @param mixed|array ...$valueN Arrays and/or values to concatenate into a new array. See the description below for details. 288 | * @return JsArray 289 | */ 290 | public function concat($valueN){ 291 | $ret = new JsArray(); 292 | foreach ($this->data as $item) { 293 | $ret->data[]=$item; 294 | } 295 | $args=func_get_args(); 296 | foreach($args as $arg){ 297 | if (gettype($arg)=="array" && array_values($arg) === $arg){ 298 | foreach ($arg as $val){ 299 | $ret->data[]=$val; 300 | } 301 | }else if ($arg instanceof JsArray){ 302 | foreach ($arg->data as $value) { 303 | $ret->data[]=$value; 304 | } 305 | }else{ 306 | $ret->data[]=$arg; 307 | } 308 | } 309 | return $ret; 310 | } 311 | 312 | /** 313 | * The entries() method returns a new Array Iterator object that contains the key/value pairs for each index in the array. 314 | */ 315 | public function entries(){ 316 | return new JsArrayIterator($this); 317 | } 318 | 319 | /** 320 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries 321 | * The every() method tests whether all elements in the array pass the test implemented by the provided function. 322 | * @param callable $callback Function to test for each element. 323 | * @return bool 324 | * @throws \Exception 325 | */ 326 | public function every($callback){ 327 | if (!is_callable($callback)){ 328 | throw new \Exception("this is not a function"); 329 | } 330 | foreach($this->data as $key=>$value){ 331 | if (!call_user_func_array($callback,[$value,$key,$this])){ 332 | return false; 333 | } 334 | } 335 | return true; 336 | } 337 | 338 | /** 339 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill 340 | * The fill() method fills all the elements of an array from a start index to an end index with a static value. 341 | * @param mixed $value 342 | * @param int $start 343 | * @param int $end 344 | * @return JsArray 345 | */ 346 | public function fill($value,$start=null,$end=null){ 347 | $len = count($this->data); 348 | if ($start==null){ 349 | $start=0; 350 | } 351 | if ($end==null){ 352 | $end=$len; 353 | } 354 | if (((int)$start)!==$start || ((int)$end)!==$end){ 355 | return $this; 356 | } 357 | $start = $start < 0 ? 358 | max($len + $start, 0) : 359 | min($start, $len); 360 | $end = $end < 0 ? 361 | max($len + $end, 0) : 362 | min($end, $len); 363 | for($i=$start;$i<$end;$i++){ 364 | $this->data[$i]=$value; 365 | } 366 | return $this; 367 | } 368 | 369 | /** 370 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter 371 | * The filter() method creates a new array with all elements that pass the test implemented by the provided function. 372 | * @param callable $callback Function to test each element of the array. Invoked with arguments (element, index, array). Return true to keep the element, false otherwise. 373 | * @return JsArray 374 | * @throws \Exception 375 | */ 376 | public function filter($callback){ 377 | if (!is_callable($callback)){ 378 | throw new \Exception("this is not a function"); 379 | } 380 | $ret = new JsArray(); 381 | foreach($this->data as $key=>$value){ 382 | if (call_user_func_array($callback,[$value,$key,$this])){ 383 | $ret->data[]=$value; 384 | } 385 | } 386 | return $ret; 387 | } 388 | 389 | /** 390 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find 391 | * The find() method returns a value in the array, if an element in the array satisfies the provided testing function. Otherwise undefined is returned. 392 | * @param callable $callback 393 | * @throws \Exception 394 | */ 395 | public function find($callback){ 396 | if (!is_callable($callback)){ 397 | throw new \Exception("this is not a function"); 398 | } 399 | foreach($this->data as $key=>$value){ 400 | if (call_user_func_array($callback,[$value,$key,$this])){ 401 | return $value; 402 | } 403 | } 404 | return undefined; 405 | } 406 | 407 | /** 408 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex 409 | * The findIndex() method returns an index in the array, if an element in the array satisfies the provided testing function. Otherwise -1 is returned. 410 | * @param callable $callback 411 | * @return int 412 | * @throws \Exception 413 | */ 414 | public function findIndex($callback){ 415 | if (!is_callable($callback)){ 416 | throw new \Exception("this is not a function"); 417 | } 418 | foreach($this->data as $key=>$value){ 419 | if (call_user_func_array($callback,[$value,$key,$this])){ 420 | return $key; 421 | } 422 | } 423 | return -1; 424 | } 425 | 426 | /** 427 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes 428 | * The includes() method determines whether an array includes a certain element, returning true or false as appropriate. 429 | * @param mixed $searchElement The element to search for. 430 | * @param int $fromIndex Optional. The position in this array at which to begin searching for searchElement. A negative value searches from the index of array.length + fromIndex by asc. Defaults to 0. 431 | * @return bool 432 | */ 433 | public function includes($searchElement,$fromIndex=0){ 434 | $len=count($this->data); 435 | if ($len==0){ 436 | return false; 437 | } 438 | if ($fromIndex < 0) { 439 | $fromIndex = $len + $fromIndex; 440 | if ($fromIndex < 0) { 441 | $fromIndex = 0; 442 | } 443 | } 444 | while ($fromIndex < $len) { 445 | $currentElement = $this->data[$fromIndex]; 446 | if ($searchElement === $currentElement) { 447 | return true; 448 | } 449 | $fromIndex++; 450 | } 451 | return false; 452 | } 453 | 454 | /** 455 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf 456 | * The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present. 457 | * @param mixed $searchElement Element to locate in the array. 458 | * @param int $fromIndex The index to start the search at. If the index is greater than or equal to the array's length, -1 is returned, which means the array will not be searched. If the provided index value is a negative number, it is taken as the offset from the end of the array. Note: if the provided index is negative, the array is still searched from front to back. If the calculated index is less than 0, then the whole array will be searched. Default: 0 (entire array is searched). 459 | * @return int 460 | */ 461 | public function indexOf($searchElement,$fromIndex=0){ 462 | $len = count($this->data); 463 | if ($len==0){ 464 | return -1; 465 | } 466 | if ($fromIndex >= $len) { 467 | return -1; 468 | } 469 | $fromIndex = max($fromIndex >= 0 ? $fromIndex : $len - abs($fromIndex), 0); 470 | while ($fromIndex < $len) { 471 | if ($this->data[$fromIndex] === $searchElement) { 472 | return $fromIndex; 473 | } 474 | $fromIndex++; 475 | } 476 | return -1; 477 | } 478 | 479 | /** 480 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join 481 | * The join() method joins all elements of an array into a string. 482 | * @param string $separator 483 | * @return string 484 | */ 485 | public function join($separator=","){ 486 | return join($separator, $this->data); 487 | } 488 | 489 | /** 490 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/keys 491 | * The keys() method returns a new Array Iterator that contains the keys for each index in the array. 492 | * @return JsArrayIterator 493 | */ 494 | public function keys(){ 495 | return new JsArrayIterator($this,true); 496 | } 497 | 498 | /** 499 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf 500 | * The lastIndexOf() method returns the last index at which a given element can be found in the array, or -1 if it is not present. The array is searched backwards, starting at fromIndex. 501 | * @param mixed $searchElement Element to locate in the array. 502 | * @param int $fromIndex Optional. The index at which to start searching backwards. Defaults to the array's length minus one, i.e. the whole array will be searched. If the index is greater than or equal to the length of the array, the whole array will be searched. If negative, it is taken as the offset from the end of the array. Note that even when the index is negative, the array is still searched from back to front. If the calculated index is less than 0, -1 is returned, i.e. the array will not be searched. 503 | * @return int 504 | */ 505 | public function lastIndexOf($searchElement,$fromIndex=null){ 506 | $len=count($this->data); 507 | if ($len === 0) { 508 | return -1; 509 | } 510 | if ($fromIndex===null){ 511 | $fromIndex=$len-1; 512 | }else{ 513 | if (((int)$fromIndex)!==$fromIndex){ 514 | $fromIndex=0; 515 | } 516 | } 517 | 518 | for ($k = $fromIndex >= 0 ? min($fromIndex, $len - 1) : $len - abs($fromIndex); $k >= 0; $k--) { 519 | if ($this->data[$k] === $searchElement) { 520 | return $k; 521 | } 522 | } 523 | return -1; 524 | } 525 | 526 | /** 527 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map 528 | * The map() method creates a new array with the results of calling a provided function on every element in this array. 529 | * @param callable $callback Function that produces an element of the new Array 530 | * @return JsArray 531 | * @throws \Exception 532 | */ 533 | public function map($callback){ 534 | if (!is_callable($callback)){ 535 | throw new \Exception("this is not a function"); 536 | } 537 | $ret = new JsArray(); 538 | foreach ($this->data as $index=>$value) { 539 | $ret->data[$index]=call_user_func_array($callback,[$value,$index,$this]); 540 | } 541 | return $ret; 542 | } 543 | 544 | /** 545 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop 546 | * The pop() method removes the last element from an array and returns that element. 547 | */ 548 | public function pop(){ 549 | return array_pop($this->data); 550 | } 551 | 552 | /** 553 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push 554 | * The push() method adds one or more elements to the end of an array and returns the new length of the array. 555 | * @param mixed ...$value 556 | * @return int 557 | */ 558 | public function push($value){ 559 | foreach (func_get_args() as $arg) { 560 | array_push($this->data,$arg); 561 | } 562 | return count($this->data); 563 | } 564 | 565 | /** 566 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce 567 | * The reduce() method applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value. 568 | * @param callable $callback

Function to execute on each value in the array, taking four arguments: 569 | *
    570 | *
  • previousValue
    571 | * The value previously returned in the last invocation of the callback, or initialValue, if supplied. (See below.)
  • 572 | *
  • currentValue
    573 | * The current element being processed in the array.
  • 574 | *
  • currentIndex
    575 | * The index of the current element being processed in the array.
  • 576 | *
  • array
  • 577 | *
578 | * The array reduce was called upon. 579 | * @param int $initialValue 580 | * @return int 581 | * @throws \Exception 582 | */ 583 | public function reduce($callback, $initialValue=0){ 584 | if (!is_callable($callback)){ 585 | throw new \Exception("this is not a function"); 586 | } 587 | foreach ($this->data as $index=>$value) { 588 | $initialValue = call_user_func_array($callback,[$initialValue,$value,$index,$this]); 589 | } 590 | return $initialValue; 591 | } 592 | 593 | /** 594 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/ReduceRight 595 | * The reduceRight() method applies a function against an accumulator and each value of the array (from right-to-left) has to reduce it to a single value. 596 | * @param callable $callback
Function to execute on each value in the array, taking four arguments: 597 | *
    598 | *
  • previousValue
    599 | * The value previously returned in the last invocation of the callback, or initialValue, if supplied. (See below.)
  • 600 | *
  • currentValue
    601 | * The current element being processed in the array.
  • 602 | *
  • currentIndex
    603 | * The index of the current element being processed in the array.
  • 604 | *
  • array
    The array reduce was called upon.
  • 605 | *
606 | * @param int $initialValue 607 | * @return int 608 | * @throws \Exception 609 | */ 610 | public function reduceRight($callback, $initialValue=0){ 611 | if (!is_callable($callback)){ 612 | throw new \Exception("this is not a function"); 613 | } 614 | for ($i=count($this->data)-1;$i>0;$i--) { 615 | $initialValue = call_user_func_array($callback,[$initialValue, $this->data[$i],$i,$this]); 616 | } 617 | return $initialValue; 618 | } 619 | 620 | /** 621 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse 622 | * The reverse() method reverses an array in place. The first array element becomes the last and the last becomes the first. 623 | * @return JsArray 624 | */ 625 | public function reverse(){ 626 | $this->data = array_reverse($this->data,false); 627 | return $this; 628 | } 629 | 630 | /** 631 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift 632 | * The shift() method removes the first element from an array and returns that element. This method changes the length of the array. 633 | */ 634 | public function shift(){ 635 | return array_shift($this->data); 636 | } 637 | 638 | /** 639 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice 640 | * The slice() method returns a shallow copy of a portion of an array into a new array object. 641 | * @param int $begin
Zero-based index at which to begin extraction.
642 | * As a negative index, begin indicates an offset from the end of the sequence. slice(-2) extracts the last two elements in the sequence.
643 | * If begin is undefined, slice begins from index 0.
644 | * @param int $end
Zero-based index at which to end extraction. slice extracts up to but not including end.
645 | * slice(1,4) extracts the second element through the fourth element (elements indexed 1, 2, and 3).
646 | * As a negative index, end indicates an offset from the end of the sequence. slice(2,-1) extracts the third element through the second-to-last element in the sequence.
647 | * If end is omitted, slice extracts through the end of the sequence (arr.length).
648 | * @return JsArray 649 | */ 650 | public function slice($begin = 0, $end = null){ 651 | if ($end===null){ 652 | $end=count($this->data)-1; 653 | } 654 | $ret = new JsArray(); 655 | $ret->data = array_slice($this->data,$begin,$begin-$end,false); 656 | return $ret; 657 | } 658 | 659 | /** 660 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some 661 | * The some() method tests whether some element in the array passes the test implemented by the provided function. 662 | * @param callable $callback
Function to test for each element, taking three arguments: 663 | *
    664 | *
  • currentValue
    665 | * The current element being processed in the array.
  • 666 | *
  • index
    667 | * The index of the current element being processed in the array.
  • 668 | *
  • array
    The array reduce was called upon.
  • 669 | *
670 | * @return bool 671 | * @throws \Exception 672 | */ 673 | public function some($callback){ 674 | if (!is_callable($callback)){ 675 | throw new \Exception("this is not a function"); 676 | } 677 | foreach ($this->data as $index=>$value) { 678 | if (call_user_func_array($callback,[$value,$index,$this])==true){ 679 | return true; 680 | } 681 | } 682 | return false; 683 | } 684 | 685 | /** 686 | * The sort() method sorts the elements of an array in place and returns the array. The sort is not necessarily stable. The default sort order is according to string Unicode code points. 687 | * @param callable $callback Optional. Specifies a function that defines the sort order. If omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element. 688 | * @return $this 689 | * @throws \Exception 690 | */ 691 | public function sort($callback=null){ 692 | if ($callback!=null && !is_callable($callback)){ 693 | throw new \Exception("this is not a function"); 694 | } 695 | if ($callback!==null){ 696 | usort($this->data,$callback); 697 | }else{ 698 | usort($this->data,"strcoll"); 699 | } 700 | return $this; 701 | } 702 | 703 | /** 704 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice 705 | * The splice() method changes the content of an array by removing existing elements and/or adding new elements. 706 | * @param int $start Index at which to start changing the array (with origin 0). If greater than the length of the array, actual starting index will be set to the length of the array. If negative, will begin that many elements from the end. 707 | * @param int $deleteCount
An integer indicating the number of old array elements to remove. If deleteCount is 0, no elements are removed. In this case, you should specify at least one new element. If deleteCount is greater than the number of elements left in the array starting at start, then all of the elements through the end of the array will be deleted.
708 | * If deleteCount is omitted, deleteCount will be equal to (arr.length - start).
709 | * @param mixed [...$replacement] The elements to add to the array, beginning at the start index. If you don't specify any elements, splice() will only remove elements from the array. 710 | * @return JsArray 711 | */ 712 | public function splice($start,$deleteCount=null){ 713 | if ($deleteCount===null){ 714 | $deleteCount=count($this->data)-1; 715 | } 716 | $len = $deleteCount; 717 | $ret = new JsArray(); 718 | 719 | $args = func_get_args(); 720 | if (count($args)==3) { 721 | $ret->data = array_splice($this->data, $start, $len,$args[2]); 722 | }else if (count($args)>3){ 723 | $replacement = []; 724 | for($i=2;$idata = array_splice($this->data, $start, $len,$replacement); 728 | }else{ 729 | $ret->data = array_splice($this->data, $start, $len); 730 | } 731 | return $ret; 732 | } 733 | 734 | /** 735 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift 736 | * The unshift() method adds one or more elements to the beginning of an array and returns the new length of the array. 737 | * @param mixed [...$element] The elements to add to the front of the array. 738 | * @return int The new length property of the object upon which the method was called. 739 | */ 740 | public function unshift(){ 741 | $args = func_get_args(); 742 | for ($i=count($args)-1;$i>=0;$i--){ 743 | array_unshift($this->data,$args[$i]); 744 | } 745 | return count($this->data); 746 | } 747 | 748 | /** 749 | * @param mixed $offset 750 | * @internal 751 | * @return bool 752 | */ 753 | public function offsetExists($offset) { 754 | return isset($this->data[$offset]); 755 | } 756 | 757 | /** 758 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values 759 | * The values() method returns a new Array Iterator object that contains the values for each index in the array. 760 | */ 761 | public function values(){ 762 | return new JsArrayIterator($this,false,true); 763 | } 764 | 765 | /** 766 | * @param mixed $offset 767 | * @internal 768 | * @return mixed 769 | */ 770 | public function offsetGet($offset) { 771 | return $this->data[$offset]; 772 | } 773 | 774 | /** 775 | * @param mixed $offset 776 | * @param mixed $value 777 | * @internal 778 | * @return mixed 779 | */ 780 | public function offsetSet($offset, $value) { 781 | if (((int)$offset)!=$offset){ 782 | return $value; 783 | } 784 | if (count($this->data)>$offset){ 785 | while($offset++data)){ 786 | $this->data[]=undefined; 787 | } 788 | } 789 | $this->data[$offset]=$value; 790 | return $value; 791 | } 792 | 793 | /** 794 | * @param mixed $offset 795 | * @internal 796 | */ 797 | public function offsetUnset($offset) { 798 | unset($this->data[$offset]); 799 | } 800 | 801 | /** 802 | * @return mixed 803 | * @internal 804 | */ 805 | function jsonSerialize() { 806 | return $this->data; 807 | } 808 | 809 | /** 810 | * @param $name 811 | * @internal 812 | * @return int|null 813 | */ 814 | public function __get($name) { 815 | switch ($name){ 816 | case "length": return count($this->data); 817 | } 818 | 819 | return null; 820 | } 821 | } 822 | -------------------------------------------------------------------------------- /lib/phptojs/lib/php/JsObject.php: -------------------------------------------------------------------------------- 1 | data=$arg; 28 | $this->sortData(); 29 | }else if ($arg instanceof JsObject) { 30 | $this->data=$arg->data; 31 | $this->sortData(); 32 | }else{ 33 | throw new \Exception("Constructor on JsObject can get only array as parameter"); 34 | } 35 | } 36 | } 37 | 38 | public static function freeze(JsObject $target){ 39 | $target->isFreeze=true; 40 | return $target; 41 | } 42 | 43 | public static function isExtensible(JsObject $target){ 44 | return $target->isExtensible; 45 | } 46 | 47 | /** 48 | * @param array|JsObject $target 49 | * @return array 50 | * @throws \Exception 51 | */ 52 | public static function getOwnPropertyNames($target){ 53 | if ($target instanceof JsObject){ 54 | return array_keys($target->data); 55 | } 56 | if (is_array($target)){ 57 | return array_keys($target); 58 | } 59 | if (is_string($target)){ 60 | $chars = str_split($target); 61 | $chars[]="length"; 62 | return $chars; 63 | } 64 | throw new \Exception("Cannot convert target or null to object"); 65 | } 66 | 67 | /** 68 | * @param ...$target 69 | * @return JsObject 70 | * @throws \Exception 71 | */ 72 | public static function assign($target){ 73 | $args = func_get_args(); 74 | if (gettype($target)=="array"){ 75 | $target = new JsObject($target); 76 | }elseif ($target instanceof JsObject){ 77 | if ($target->isFreeze || !$target->isExtensible){ 78 | throw new \Exception("Can't add property, object is not extensible"); 79 | } 80 | }else if(gettype($target)=="object"){ 81 | }else if(get_class($target)=="Closure"){ 82 | return $target; 83 | }else{ 84 | throw new \Exception("This type is not implemented yet ".gettype($target)); 85 | } 86 | if (count($args)>1){ 87 | for($i=1;$i$char){ 90 | $target->data[$pos]=$char; 91 | } 92 | }elseif(is_array($args[$i]) || $args[$i] instanceof JsObject) { 93 | foreach ($args[$i] as $key => $val) { 94 | $target->data[$key] = $val; 95 | } 96 | }elseif (is_null($args[$i]) || $args[$i]===undefined || is_bool($args[$i]) || is_numeric($args[$i])) { 97 | continue; 98 | }else{ 99 | throw new \Exception("This type is not implemented yet ".gettype($args[$i])); 100 | } 101 | } 102 | } 103 | $target->sortData(); 104 | return $target; 105 | } 106 | 107 | private function sortData(){ 108 | uksort($this->data,function($a, $b){ 109 | if (gettype($a)=="string" && gettype($b)=="string"){ 110 | return 0; 111 | } 112 | if (gettype($a)=="integer" && gettype($b)=="string"){ 113 | return 0; 114 | } 115 | if (gettype($a)=="string" && gettype($b)=="integer"){ 116 | return 1; 117 | } 118 | if (gettype($a)=="integer" && gettype($b)=="integer"){ 119 | return $a>$b; 120 | } 121 | throw new \Exception("Unimplemented sort types ".gettype($a)."-".gettype($b)); 122 | }); 123 | } 124 | 125 | /** 126 | * Return the current element 127 | * @link http://php.net/manual/en/iterator.current.php 128 | * @return mixed Can return any type. 129 | * @since 5.0.0 130 | */ 131 | public function current() { 132 | return current($this->data); 133 | } 134 | 135 | /** 136 | * Move forward to next element 137 | * @link http://php.net/manual/en/iterator.next.php 138 | * @return void Any returned value is ignored. 139 | * @since 5.0.0 140 | */ 141 | public function next() { 142 | next($this->data); 143 | } 144 | 145 | /** 146 | * Return the key of the current element 147 | * @link http://php.net/manual/en/iterator.key.php 148 | * @return mixed scalar on success, or null on failure. 149 | * @since 5.0.0 150 | */ 151 | public function key() { 152 | return key($this->data); 153 | } 154 | 155 | /** 156 | * Checks if current position is valid 157 | * @link http://php.net/manual/en/iterator.valid.php 158 | * @return boolean The return value will be casted to boolean and then evaluated. 159 | * Returns true on success or false on failure. 160 | * @since 5.0.0 161 | */ 162 | public function valid() { 163 | return key($this->data)!==null; 164 | } 165 | 166 | /** 167 | * Rewind the Iterator to the first element 168 | * @link http://php.net/manual/en/iterator.rewind.php 169 | * @return void Any returned value is ignored. 170 | * @since 5.0.0 171 | */ 172 | public function rewind() { 173 | reset($this->data); 174 | } 175 | 176 | /** 177 | * Whether a offset exists 178 | * @link http://php.net/manual/en/arrayaccess.offsetexists.php 179 | * @param mixed $offset

180 | * An offset to check for. 181 | *

182 | * @return boolean true on success or false on failure. 183 | *

184 | *

185 | * The return value will be casted to boolean if non-boolean was returned. 186 | * @since 5.0.0 187 | */ 188 | public function offsetExists($offset) { 189 | return isset($this->data[$offset]); 190 | } 191 | 192 | /** 193 | * Offset to retrieve 194 | * @link http://php.net/manual/en/arrayaccess.offsetget.php 195 | * @param mixed $offset

196 | * The offset to retrieve. 197 | *

198 | * @return mixed Can return all value types. 199 | * @since 5.0.0 200 | */ 201 | public function offsetGet($offset) { 202 | return $this->data[$offset]; 203 | } 204 | 205 | /** 206 | * Offset to set 207 | * @link http://php.net/manual/en/arrayaccess.offsetset.php 208 | * @param mixed $offset

209 | * The offset to assign the value to. 210 | *

211 | * @param mixed $value

212 | * The value to set. 213 | *

214 | * @return mixed|void 215 | * @throws \Exception 216 | * @since 5.0.0 217 | */ 218 | public function offsetSet($offset, $value) { 219 | if ($this->isFreeze){ 220 | throw new \Exception("Can't set property {$offset}, object is not extensible"); 221 | } 222 | if (!isset($this->data[$offset]) && !$this->isExtensible){ 223 | return $value; 224 | } 225 | $this->data[$offset]=$value; 226 | $this->sortData(); 227 | return $value; 228 | } 229 | 230 | /** 231 | * Offset to unset 232 | * @link http://php.net/manual/en/arrayaccess.offsetunset.php 233 | * @param mixed $offset

234 | * The offset to unset. 235 | *

236 | * @throws \Exception 237 | * @since 5.0.0 238 | */ 239 | public function offsetUnset($offset) { 240 | if ($this->isFreeze){ 241 | throw new \Exception("Can't delete property {$offset}, object is not extensible"); 242 | } 243 | unset($this->data[$offset]); 244 | } 245 | 246 | /** 247 | * Count elements of an object 248 | * @link http://php.net/manual/en/countable.count.php 249 | * @return int The custom count as an integer. 250 | *

251 | *

252 | * The return value is cast to an integer. 253 | * @since 5.1.0 254 | */ 255 | public function count() { 256 | return count($this->data); 257 | } 258 | 259 | public function __get($name) { 260 | if (!isset($this->data)){ 261 | return undefined; 262 | }; 263 | return $this->data[$name]; 264 | } 265 | 266 | public function __set($name, $value) { 267 | if ($this->isFreeze){ 268 | throw new \Exception("Can't set property {$name}, object is not extensible"); 269 | } 270 | $this->offsetSet($name,$value); 271 | } 272 | } 273 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | 15 | ./test/ 16 | 17 | 18 | 19 | 20 | 21 | ./lib/PhpToJs/ 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /public_html/.htaccess: -------------------------------------------------------------------------------- 1 | AddHandler application/x-httpd-php7 .php -------------------------------------------------------------------------------- /public_html/convert.php: -------------------------------------------------------------------------------- 1 | "&", 18 | "__PLUS__" => "+", 19 | "__QUESTION_MARK__" => "?", 20 | "__ART__" => "alert", 21 | "__CA_SE__" => "case" 22 | ]; 23 | 24 | $code = str_replace(array_keys($change), array_values($change), $code); 25 | require_once __DIR__ . "/../vendor/autoload.php"; 26 | 27 | try { 28 | 29 | $parser = (new \PhpParser\ParserFactory())->create(\PhpParser\ParserFactory::PREFER_PHP7); 30 | $jsPrinter = new \phptojs\JsPrinter\JsPrinter(); 31 | 32 | $stmts = $parser->parse($code); 33 | ob_start(); 34 | $jsCode = $jsPrinter->jsPrint($stmts); 35 | $errors = ob_get_clean(); 36 | $errors = explode(PHP_EOL, $errors); 37 | foreach ($errors as $error) { 38 | if ($error != "") { 39 | echo "//" . $error; 40 | } 41 | echo PHP_EOL; 42 | } 43 | foreach ($jsPrinter->getErrors() as $error) { 44 | echo "//" . $error . PHP_EOL; 45 | } 46 | echo $jsCode; 47 | 48 | } catch (PhpParser\Error $e) { 49 | echo 'ERROR:', $e->getMessage(); 50 | } catch (Exception $e) { 51 | echo "ERROR:Some is wrong".PHP_EOL.$e->getMessage(); 52 | } -------------------------------------------------------------------------------- /public_html/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tito10047/PHP-to-Javascript/9de34316a5b0e088c8100759d468e123af0d875c/public_html/favicon.ico -------------------------------------------------------------------------------- /public_html/getTemplate.php: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | 14 | 15 | Php to Js converter 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 55 |

56 |
57 |

PHP to JavaScript converter

58 |

OOP, Inheritance, Exceptions, Namespaces and more

59 |

See more on github

60 |
61 | Watch 65 | Star 69 | Issue 72 |
73 |
74 | 75 | 76 | 100 | 105 | 114 | 115 |
77 |
78 | Write some PHP code
79 | 85 |

86 |
87 |
88 |
<?php
 91 | 
 92 | 
93 | 98 |
99 |
101 | 102 |

103 | 104 |
106 |
Converted JavaScript code

107 |
108 |
109 |                             
111 |                         
112 |
113 |
116 |
117 |
118 | 274 | 291 | 292 | -------------------------------------------------------------------------------- /public_html/scripts.php: -------------------------------------------------------------------------------- 1 | nodeJsPath = getenv('nodejs'); 37 | if (!$this->nodeJsPath){ 38 | throw new \Exception("define nodejs in env"); 39 | } 40 | if (!self::checkNodeJs()) { 41 | // exit; 42 | //TODO: replace this with warning 43 | throw new \Exception("nodejs not found in system path"); 44 | } 45 | $this->nodeJsExist = true; 46 | $s = DIRECTORY_SEPARATOR; 47 | $this->PATH_SRC_PHP = __DIR__ . "{$s}..{$s}code{$s}jsPrinter{$s}phpSrc{$s}"; 48 | $this->PATH_SRC_JS = __DIR__ . "{$s}..{$s}code{$s}jsPrinter{$s}jsSrc{$s}generated{$s}"; 49 | $this->PATH_TO_JS_TEST = __DIR__ . "{$s}..{$s}code{$s}jsPrinter{$s}jsSrc{$s}runTest.js"; 50 | $this->PATH_TO_PHP_TEST = __DIR__ . "{$s}..{$s}code{$s}jsPrinter{$s}phpSrc{$s}runTest.php"; 51 | $this->phpGlobalFiles = self::getFiles($this->PATH_SRC_PHP . 'global', "js.php"); 52 | JsPrinterAbstract::$throwErrors = false; 53 | JsPrinterAbstract::$enableVariadic = true; 54 | } 55 | 56 | /** 57 | * @dataProvider provideTestJsPrinter 58 | * @covers phptojs\JsPrinter\ 59 | */ 60 | public function testJsPrinter($class, $fileName, $filePath) { 61 | $this->doTestJsPrintClass($class, $fileName, $filePath); 62 | } 63 | 64 | public function provideTestJsPrinter() { 65 | return $this->getTests("JsPrinter"); 66 | } 67 | 68 | protected function doTestJsPrintClass($printerClassName, $fileName, $filePath) { 69 | $jsFilePath = $this->PATH_SRC_JS . $printerClassName . DIRECTORY_SEPARATOR . $fileName . '.js'; 70 | 71 | $className = '\phptojs\JsPrinter\\' . $printerClassName; 72 | /** @var JsPrinterAbstract $jsPrinter */ 73 | $jsPrinter = new $className(); 74 | if (!$jsPrinter->jsPrintFileTo($filePath, $jsFilePath)) { 75 | $this->throwException(new \Exception("cant write to '{$jsFilePath}'")); 76 | } 77 | 78 | foreach ($jsPrinter->getErrors() as $error) { 79 | echo $error . PHP_EOL; 80 | } 81 | if (file_exists(self::JS_FORMATTER)) { 82 | $source_file=$jsFilePath; 83 | // require self::JS_FORMATTER; 84 | } 85 | 86 | if ($this->onlyGenerate) { 87 | return; 88 | } 89 | 90 | $phpAsserts = $this->runPhpTest($filePath); 91 | foreach ($phpAsserts as $assert) { 92 | $this->assertEquals($assert->to, $assert->what, $fileName . ": " . $assert->message); 93 | } 94 | 95 | $jsAsserts = $this->runJsTest($jsFilePath); 96 | foreach ($jsAsserts as $assert) { 97 | if (!isset($assert->to) && !isset($assert->what)) continue; 98 | $this->assertEquals($assert->to, $assert->what, $fileName . ".js: " . $assert->message); 99 | } 100 | 101 | if (count($phpAsserts)!==count($jsAsserts)) { 102 | echo "messages PHP=>JS".PHP_EOL; 103 | $max = max(count($phpAsserts),count($jsAsserts)); 104 | for($i=0;$i<$max;$i++){ 105 | if (count($phpAsserts)>$i){ 106 | echo "php:".$phpAsserts[$i]->message; 107 | } 108 | echo "=>"; 109 | if (count($jsAsserts)>$i){ 110 | echo "JS:".$jsAsserts[$i]->message; 111 | } 112 | echo PHP_EOL; 113 | } 114 | } 115 | $this->assertEquals(count($phpAsserts), count($jsAsserts), "php VS js assertions count '{$fileName}'. JS:".count($jsAsserts)." vs PHP:".count($phpAsserts)); 116 | 117 | for ($i = 0; $i < count($phpAsserts); $i++) { 118 | if ((is_numeric($phpAsserts[$i]->to) && $phpAsserts[$i]->to==undefined) && !isset($jsAsserts[$i]->to)) continue; 119 | $this->assertEquals($phpAsserts[$i]->to, $jsAsserts[$i]->to, "php VS js '{$fileName}' '{$phpAsserts[$i]->message}'/'{$jsAsserts[$i]->message}''"); 120 | } 121 | } 122 | 123 | protected function runPhpTest($filePath) { 124 | $filePath = realpath($filePath); 125 | 126 | exec("php {$this->PATH_TO_PHP_TEST} {$filePath}", $output, $returnCode); 127 | if ($returnCode != false) { 128 | echo "================" . PHP_EOL; 129 | var_dump($output); 130 | $this->throwException(new NodeJsException('js error')); 131 | return array(); 132 | } 133 | 134 | if (count($output) != 1) { 135 | var_dump($output); 136 | $this->throwException(new NodeJsException('bad js result')); 137 | } 138 | return json_decode($output[0]); 139 | } 140 | 141 | protected function runJsTest($filePath) { 142 | $filePath = realpath($filePath); 143 | exec("{$this->nodeJsPath} {$this->PATH_TO_JS_TEST} {$filePath}", $output, $returnCode); 144 | if ($returnCode != false) { 145 | echo "================" . PHP_EOL; 146 | var_dump($output); 147 | $this->throwException(new NodeJsException('js error')); 148 | return array(); 149 | } 150 | if (count($output) != 1) { 151 | var_dump($output); 152 | $this->throwException(new NodeJsException('bad js result')); 153 | } 154 | return json_decode($output[0]); 155 | } 156 | 157 | 158 | protected function getTests($printerClassName) { 159 | if (!$this->nodeJsExist) { 160 | return array(); 161 | } 162 | if (file_exists($this->PATH_SRC_JS . $printerClassName)) { 163 | $this->rrmdir($this->PATH_SRC_JS . $printerClassName); 164 | mkdir($this->PATH_SRC_JS . $printerClassName, 0777, true); 165 | } 166 | $tests = array(); 167 | 168 | $phpLocalFiles = self::getFiles($this->PATH_SRC_PHP . $printerClassName, "js.php"); 169 | $phpLocalFiles = array_merge($this->phpGlobalFiles, $phpLocalFiles); 170 | foreach ($phpLocalFiles as $fileName => $filePath) { 171 | $tests[] = array($printerClassName, $fileName, $filePath); 172 | } 173 | return $tests; 174 | } 175 | 176 | protected function getFiles($directory, $fileExtension) { 177 | if (!file_exists($directory)) { 178 | $this->throwException(new \Exception("directory not exist '{$directory}'")); 179 | return array(); 180 | } 181 | $it = new \RecursiveDirectoryIterator($directory); 182 | $it = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::LEAVES_ONLY); 183 | $it = new \RegexIterator($it, '(\.' . preg_quote($fileExtension) . '$)'); 184 | $fileNames = array(); 185 | foreach ($it as $file) { 186 | /** @var \SplFileInfo $file */ 187 | $fileNames[$file->getFilename()] = realpath($file->getPathname()); 188 | } 189 | return $fileNames; 190 | } 191 | 192 | protected function checkNodeJs() { 193 | exec("{$this->nodeJsPath} -v", $output); 194 | return count($output) == 1; 195 | } 196 | 197 | function rrmdir($dir) { 198 | if (is_dir($dir)) { 199 | $objects = scandir($dir); 200 | foreach ($objects as $object) { 201 | if ($object != "." && $object != "..") { 202 | if (filetype($dir . "/" . $object) == "dir") $this->rrmdir($dir . "/" . $object); else unlink($dir . "/" . $object); 203 | } 204 | } 205 | reset($objects); 206 | rmdir($dir); 207 | } 208 | } 209 | 210 | } 211 | 212 | } -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/AssigningThis.js.php.js: -------------------------------------------------------------------------------- 1 | function paramTest(object, otherVar) { 2 | return object; 3 | } 4 | var TestClass = (function() { 5 | function TestClass() { 6 | window.__IS_INHERITANCE__ = false; 7 | this.five = 5; 8 | } 9 | TestClass.prototype.getThis = function() { 10 | return this; 11 | }; 12 | TestClass.prototype.getThis2 = function() { 13 | return paramTest(this, 'ignored var'); 14 | }; 15 | TestClass.prototype.getThis3 = function() { 16 | var returnValue; 17 | returnValue = this; 18 | return returnValue; 19 | }; 20 | TestClass.prototype.getClassName = function() { 21 | var className; 22 | className = get_class(this); 23 | return className; 24 | }; 25 | TestClass.prototype.getValue = function() { 26 | return this.five; 27 | }; 28 | return TestClass; 29 | })(); 30 | var testClass; 31 | testClass = new TestClass(); 32 | assert_(testClass.getThis(), testClass); 33 | assert_(testClass.getThis2(), testClass); 34 | assert_(testClass.getThis3(), testClass); 35 | assert_(testClass.getClassName(), 'TestClass'); 36 | assert_(testClass.getValue(), 5); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/JsArray.js.php.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by PhpStorm. 3 | * User: Jozef Môstka 4 | * Date: 4.6.2016 5 | * Time: 23:24 6 | */ 7 | /** @var {{testJsArray: {}}} N*/ 8 | N._INIT_('testJsArray'); 9 | (function() { 10 | var JsArray = N.jsphp.JsArray; 11 | var fruits; 12 | fruits = new JsArray('Apple', 'Banana'); 13 | assert_(fruits.length, 2, 'JsArray test 1'); 14 | assert_(fruits[0], 'Apple', 'JsArray test 2'); 15 | assert_(fruits[fruits.length - 1], 'Banana', 'JsArray test 3'); 16 | var values; 17 | values = { 18 | 0: 'Apple', 19 | 1: 'Banana' 20 | }; 21 | var indexPos; 22 | indexPos = 0; 23 | fruits.forEach(function(value, index, array) { 24 | assert_(value, values[indexPos], "JsArray test 4.1." + indexPos + ""); 25 | assert_(index, index, "JsArray test 4.2." + indexPos + ""); 26 | indexPos++; 27 | }); 28 | var oneTwoThree; 29 | oneTwoThree = new JsArray(1, 2, 3); 30 | var a; 31 | a = JsArray.from(oneTwoThree); 32 | assert_(a.length, 3, 'JsArray test 5'); 33 | assert_(a[2], 3, 'JsArray test 6'); 34 | a = JsArray.from('string'); 35 | assert_(a.length, 6, 'JsArray test 6'); 36 | assert_(a[2], 'r', 'JsArray test 7'); 37 | // Using an arrow function as the map function to 38 | // manipulate the elements 39 | a = JsArray.from(oneTwoThree, function(v) { 40 | return v + v; 41 | }); 42 | assert_(a.length, 3, 'JsArray test 8'); 43 | assert_(a[2], 6, 'JsArray test 9'); 44 | // Generate a sequence of numbers 45 | a = JsArray.from({ 46 | 'length': 5 47 | }, function(v, k) { 48 | return k; 49 | }); 50 | assert_(a.length, 5, 'JsArray test 10'); 51 | assert_(a[2], 2, 'JsArray test 11'); 52 | a = JsArray.of(1, 2, 3); 53 | assert_(a.length, 3, 'JsArray test 11.2'); 54 | assert_(a[2], 3, 'JsArray test 11.3'); 55 | var alpha; 56 | alpha = new JsArray('a', 'b', 'c'); 57 | var numeric; 58 | numeric = new JsArray(1, 2, 3); 59 | var alphaNumeric; 60 | alphaNumeric = alpha.concat(numeric); 61 | assert_(alphaNumeric.length, 6, 'JsArray test 12'); 62 | assert_(alphaNumeric[5], 3, 'JsArray test 13'); 63 | var oneTwo; 64 | oneTwo = new JsArray(2, 3); 65 | alphaNumeric = alpha.concat(1, oneTwo); 66 | assert_(alphaNumeric.length, 6, 'JsArray test 14'); 67 | assert_(alphaNumeric[5], 3, 'JsArray test 15'); 68 | var arr; 69 | arr = new JsArray('a', 'b', 'c'); 70 | var eArr; 71 | eArr = arr.entries(); 72 | assert_(eArr.next().value[1], 'a', 'JsArray test 16'); 73 | assert_(eArr.next().value[1], 'b', 'JsArray test 17'); 74 | assert_(eArr.next().value.length, 2, 'JsArray test 18'); 75 | // Not working in nodejs 76 | // $eArr = $arr->entries(); 77 | // foreach($eArr as $key=>$value){ 78 | // assert_($value,$arr[$key],"JsArray test 19.".$key); 79 | // } 80 | var isBigEnough; 81 | isBigEnough = function(element, index, array) { 82 | return element >= 10; 83 | }; 84 | var check; 85 | check = (new JsArray(12, 5, 8, 130, 44)).every(isBigEnough); 86 | assert_(check, false, 'JsArray test 20'); 87 | check = (new JsArray(12, 54, 18, 130, 44)).every(isBigEnough); 88 | assert_(check, true, 'JsArray test 21'); 89 | assert_(json_encode((new JsArray(1, 2, 3)).fill(4)), '[4,4,4]', 'JsArray test 22'); 90 | assert_(json_encode((new JsArray(1, 2, 3)).fill(4, 1)), '[1,4,4]', 'JsArray test 23'); 91 | assert_(json_encode((new JsArray(1, 2, 3)).fill(4, 1, 2)), '[1,4,3]', 'JsArray test 24'); 92 | assert_(json_encode((new JsArray(1, 2, 3)).fill(4, 1, 1)), '[1,2,3]', 'JsArray test 25'); 93 | assert_(json_encode((new JsArray(1, 2, 3)).fill(4, -3, -2)), '[4,2,3]', 'JsArray test 26'); 94 | assert_(json_encode((new JsArray(1, 2, 3)).fill(4, 'dsad', 'dasdas')), '[1,2,3]', 'JsArray test 27'); 95 | isBigEnough = function(value) { 96 | return value >= 10; 97 | }; 98 | var filtered; 99 | filtered = (new JsArray(12, 5, 8, 130, 44)).filter(isBigEnough); 100 | assert_(json_encode(filtered), '[12,130,44]', 'JsArray test 28'); 101 | var isPrime; 102 | isPrime = function(element, index, array) { 103 | var start; 104 | start = 2; 105 | while (start <= sqrt(element)) { 106 | if (element % start++ < 1) { 107 | return false; 108 | } 109 | } 110 | return element > 1; 111 | }; 112 | assert_((new JsArray(4, 6, 8, 12)).find(isPrime), undefined, 'JsArray test 29'); 113 | assert_((new JsArray(4, 5, 8, 12)).find(isPrime), 5, 'JsArray test 30'); 114 | assert_((new JsArray(4, 6, 8, 12)).findIndex(isPrime), -1, 'JsArray test 31'); 115 | assert_((new JsArray(4, 6, 7, 12)).findIndex(isPrime), 2, 'JsArray test 32'); 116 | assert_((new JsArray(1, 2, 3)).includes(2), true, 'JsArray test 33'); 117 | assert_((new JsArray(1, 2, 3)).includes(4), false, 'JsArray test 34'); 118 | assert_((new JsArray(1, 2, 3)).includes(3, 3), false, 'JsArray test 35'); 119 | assert_((new JsArray(1, 2, 3)).includes(3, -1), true, 'JsArray test 36'); 120 | var array; 121 | array = new JsArray(2, 9, 9); 122 | assert_(array.indexOf(2), 0, 'JsArray test 37'); 123 | assert_(array.indexOf(7), -1, 'JsArray test 38'); 124 | assert_(array.indexOf(9, 2), 2, 'JsArray test 39'); 125 | assert_(array.indexOf(2, -1), -1, 'JsArray test 40'); 126 | assert_(array.indexOf(2, -3), 0, 'JsArray test 41'); 127 | arr = new JsArray('a', 'b', 'c'); 128 | var iterator; 129 | iterator = arr.keys(); 130 | assert_(iterator.next().value, 0, 'JsArray test 42'); 131 | assert_(iterator.next().value, 1, 'JsArray test 43'); 132 | assert_(iterator.next().value, 2, 'JsArray test 44'); 133 | assert_(iterator.next().done, true, 'JsArray test 45'); 134 | array = new JsArray(2, 5, 9, 2); 135 | assert_(array.lastIndexOf(2), 3, 'JsArray test 46'); 136 | assert_(array.lastIndexOf(7), -1, 'JsArray test 47'); 137 | assert_(array.lastIndexOf(2, 3), 3, 'JsArray test 48'); 138 | assert_(array.lastIndexOf(2, 2), 0, 'JsArray test 49'); 139 | assert_(array.lastIndexOf(2, -2), 0, 'JsArray test 50'); 140 | assert_(array.lastIndexOf(2, -1), 3, 'JsArray test 51'); 141 | var numbers; 142 | numbers = new JsArray(1, 4, 9); 143 | var doubles; 144 | doubles = numbers.map(function(num) { 145 | return num * 2; 146 | }); 147 | assert_(json_encode(doubles), '[2,8,18]', 'JsArray test 52'); 148 | var myFish; 149 | myFish = new JsArray('angel', 'clown', 'mandarin', 'sturgeon'); 150 | var popped; 151 | popped = myFish.pop(); 152 | assert_(json_encode(myFish), '["angel","clown","mandarin"]', 'JsArray test 53'); 153 | assert_(popped, 'sturgeon', 'JsArray test 54'); 154 | var sports; 155 | sports = new JsArray('soccer', 'baseball'); 156 | var total; 157 | total = sports.push('football', 'swimming'); 158 | assert_(json_encode(sports), '["soccer","baseball","football","swimming"]', 'JsArray test 54'); 159 | assert_(total, 4, 'JsArray test 55'); 160 | var testArray; 161 | testArray = new JsArray(0, 1, 2, 3, 4); 162 | var mapFunc; 163 | mapFunc = function(previousValue, currentValue, currentIndex, array) { 164 | return previousValue + currentValue; 165 | }; 166 | var value; 167 | value = testArray.reduce(mapFunc); 168 | assert_(value, 10, 'JsArray test 56'); 169 | value = testArray.reduce(mapFunc, 10); 170 | assert_(value, 20, 'JsArray test 57'); 171 | value = testArray.reduceRight(mapFunc); 172 | assert_(value, 10, 'JsArray test 58'); 173 | value = testArray.reduceRight(mapFunc, 10); 174 | assert_(value, 20, 'JsArray test 59'); 175 | var myArray; 176 | myArray = new JsArray('one', 'two', 'three'); 177 | myArray.reverse(); 178 | assert_(json_encode(myArray), '["three","two","one"]', 'JsArray test 60'); 179 | myFish = new JsArray('angel', 'clown', 'mandarin', 'surgeon'); 180 | var shifted; 181 | shifted = myFish.shift(); 182 | assert_(json_encode(myFish), '["clown","mandarin","surgeon"]', 'JsArray test 61'); 183 | assert_(shifted, 'angel', 'JsArray test 62'); 184 | fruits = new JsArray('Banana', 'Orange', 'Lemon', 'Apple', 'Mango'); 185 | var citrus; 186 | citrus = fruits.slice(1, 3); 187 | assert_(json_encode(citrus), '["Orange","Lemon"]', 'JsArray test 62'); 188 | var isBiggerThan10; 189 | isBiggerThan10 = function(element, index, array) { 190 | return element > 10; 191 | }; 192 | assert_((new JsArray(2, 5, 8, 1, 4)).some(isBiggerThan10), false, 'JsArray test 63'); 193 | assert_((new JsArray(12, 5, 8, 1, 4)).some(isBiggerThan10), true, 'JsArray test 64'); 194 | var fruit; 195 | fruit = new JsArray('cherries', 'apples', 'bananas'); 196 | fruit.sort(); 197 | assert_(json_encode(fruit), '["apples","bananas","cherries"]', 'JsArray test 65'); 198 | var scores; 199 | scores = new JsArray(1, 10, 2, 21); 200 | scores.sort(); 201 | assert_(json_encode(scores), '[1,10,2,21]', 'JsArray test 66'); 202 | var things; 203 | things = new JsArray('word', 'Word', '1 Word', '2 Words'); 204 | things.sort(); 205 | assert_(json_encode(things), '["1 Word","2 Words","Word","word"]', 'JsArray test 67'); 206 | myFish = new JsArray('angel', 'clown', 'mandarin', 'surgeon'); 207 | var removed; 208 | removed = myFish.splice(2, 0, 'drum'); 209 | assert_(json_encode(myFish), '["angel","clown","drum","mandarin","surgeon"]', 'JsArray test 68'); 210 | assert_(json_encode(removed), '[]', 'JsArray test 69'); 211 | removed = myFish.splice(3, 1); 212 | assert_(json_encode(myFish), '["angel","clown","drum","surgeon"]', 'JsArray test 70'); 213 | assert_(json_encode(removed), '["mandarin"]', 'JsArray test 71'); 214 | removed = myFish.splice(2, 1, 'trumpet'); 215 | assert_(json_encode(myFish), '["angel","clown","trumpet","surgeon"]', 'JsArray test 72'); 216 | assert_(json_encode(removed), '["drum"]', 'JsArray test 73'); 217 | removed = myFish.splice(0, 2, 'parrot', 'anemone', 'blue'); 218 | assert_(json_encode(myFish), '["parrot","anemone","blue","trumpet","surgeon"]', 'JsArray test 74'); 219 | assert_(json_encode(removed), '["angel","clown"]', 'JsArray test 75'); 220 | removed = myFish.splice(myFish.length - 3, 2); 221 | assert_(json_encode(myFish), '["parrot","anemone","surgeon"]', 'JsArray test 76'); 222 | assert_(json_encode(removed), '["blue","trumpet"]', 'JsArray test 77'); 223 | arr = new JsArray(1, 2); 224 | assert_(arr.unshift(0), 3, 'JsArray test 78'); 225 | assert_(json_encode(arr), '[0,1,2]', 'JsArray test 79'); 226 | assert_(arr.unshift(-2, -1), '5', 'JsArray test 80'); 227 | assert_(json_encode(arr), '[-2,-1,0,1,2]', 'JsArray test 81'); 228 | // not working in nodejs 229 | // $arr = new JsArray('w', 'y', 'k', 'o', 'p'); 230 | // $eArr = $arr->values(); 231 | // assert_($eArr->next()->value,"w","JsArray test 82"); 232 | // assert_($eArr->next()->value,"y","JsArray test 83"); 233 | // assert_($eArr->next()->value,"k","JsArray test 84"); 234 | // assert_($eArr->next()->value,"o","JsArray test 85"); 235 | // assert_($eArr->next()->value,"p","JsArray test 86"); 236 | }).call(N.testJsArray); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/JsClass.js.php.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by PhpStorm. 3 | * User: Jozef Môstka 4 | * Date: 3.6.2016 5 | * Time: 19:19 6 | */ 7 | /** @var {{testJsClass: {}}} N*/ 8 | N._INIT_('testJsClass'); 9 | (function() { 10 | var JsObject = N.jsphp.JsObject; 11 | var jsClass; 12 | jsClass = new JsObject({ 13 | 0: 1, 14 | 1: 'ggg', 15 | 2: 5, 16 | 3: 2, 17 | 4: 'ff' 18 | }); 19 | var testIndexes; 20 | testIndexes = { 21 | 0: 1, 22 | 1: 'ggg', 23 | 2: 5, 24 | 3: 2, 25 | 4: 'ff' 26 | }; 27 | var index; 28 | index = 0; 29 | var _key_; 30 | for (_key_ in jsClass) { 31 | var property; 32 | property = jsClass[_key_]; 33 | assert_(property, testIndexes[index], "test JsClas unindexed index " + index + ""); 34 | index++; 35 | } 36 | jsClass = new JsObject(); 37 | jsClass.aaa = 1; 38 | jsClass.ccc = 2; 39 | jsClass.bbb = 3; 40 | jsClass['122'] = 4; 41 | jsClass['111'] = 5; 42 | jsClass['011'] = 6; 43 | jsClass['001'] = 7; 44 | testIndexes = { 45 | '111': 5, 46 | '122': 4, 47 | 'aaa': 1, 48 | 'ccc': 2, 49 | 'bbb': 3, 50 | '011': 6, 51 | '001': 7 52 | }; 53 | var testIndexesKeys; 54 | testIndexesKeys = { 55 | 0: '111', 56 | 1: '122', 57 | 2: 'aaa', 58 | 3: 'ccc', 59 | 4: 'bbb', 60 | 5: '011', 61 | 6: '001' 62 | }; 63 | index = 0; 64 | var key; 65 | for (key in jsClass) { 66 | property = jsClass[key]; 67 | assert_(property, testIndexes[testIndexesKeys[index]], "test JsClas indexed values index " + index + ""); 68 | assert_(key, testIndexesKeys[index], "test JsClas indexed keys index " + index + ""); 69 | index++; 70 | } 71 | var obj; 72 | obj = { 73 | 'a': 1 74 | }; 75 | var copy; 76 | copy = JsObject.assign({}, obj); 77 | assert_(copy.a, 1, 'JsArray::assign 1'); 78 | var o1; 79 | o1 = { 80 | 'a': 1 81 | }; 82 | var o2; 83 | o2 = { 84 | 'b': 2 85 | }; 86 | var o3; 87 | o3 = { 88 | 'c': 3 89 | }; 90 | obj = JsObject.assign(o1, o2, o3); 91 | assert_(obj.a, 1, 'JsArray::assign 2'); 92 | assert_(obj.b, 2, 'JsArray::assign 3'); 93 | assert_(obj.c, 3, 'JsArray::assign 4'); 94 | var v1; 95 | v1 = 'abc'; 96 | var v2; 97 | v2 = true; 98 | var v3; 99 | v3 = 10; 100 | var v4; 101 | v4 = 'fd'; 102 | obj = JsObject.assign({}, v1, null, v2, undefined, v3, v4); 103 | assert_(obj[0], 'f', 'JsArray::assign 5'); 104 | assert_(obj[1], 'd', 'JsArray::assign 6'); 105 | assert_(obj[2], 'c', 'JsArray::assign 7'); 106 | }).call(N.testJsClass); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/anonymousClass.js.php.js: -------------------------------------------------------------------------------- 1 | /** @var {{anonymusClass: {}}} N*/ 2 | N._INIT_('anonymusClass'); 3 | (function() { 4 | var AAA = this.AAA = (function() { 5 | function AAA() { 6 | window.__IS_INHERITANCE__ = false; 7 | } 8 | return AAA; 9 | })(); 10 | var BBB = this.BBB = (function() { 11 | function BBB() { 12 | window.__IS_INHERITANCE__ = false; 13 | __INTERFACE_NEW__(); 14 | } 15 | return BBB; 16 | })(); 17 | var CCC = this.CCC = (function() { 18 | function CCC() { 19 | window.__IS_INHERITANCE__ = false; 20 | __INTERFACE_NEW__(); 21 | } 22 | return CCC; 23 | })(); 24 | var a; 25 | a = new(function() { 26 | function __anonymous__() { 27 | window.__IS_INHERITANCE__ = false; 28 | } 29 | return __anonymous__; 30 | })(); 31 | var b; 32 | b = new(function(parent) { 33 | function __anonymous__() { 34 | window.__IS_INHERITANCE__ = true; 35 | parent.call(this); 36 | } 37 | __extends(__anonymous__, parent, arguments[1]); 38 | return __anonymous__; 39 | })(AAA, [BBB, CCC]); 40 | var c; 41 | c = new(function(parent, a) { 42 | var __private = __PRIVATIZE__(); 43 | 44 | function __anonymous__(a) { 45 | var __isInheritance = __IS_INHERITANCE__; 46 | window.__IS_INHERITANCE__ = true; 47 | parent.call(this); 48 | __private(this).a = null; 49 | if (__isInheritance == false) { 50 | this.__construct(a); 51 | } 52 | } 53 | __extends(__anonymous__, parent); 54 | __anonymous__.prototype.__construct = function(a) { 55 | __private(this).a = a; 56 | }; 57 | return __anonymous__; 58 | })(AAA, a); 59 | }).call(N.anonymusClass); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/array.js.php.js: -------------------------------------------------------------------------------- 1 | // count test 2 | var a; 3 | a = {}; 4 | assert_(count(a), 0, 'array count 0'); 5 | // Hash test 6 | a = new N.jsphp.HashArray(); 7 | a.set('dKey', 'item0'); 8 | a.push('item1'); 9 | a.set('3', 'item2'); 10 | a.set(5, 'item3'); 11 | a.push('item4'); 12 | a.set('bKey', 'item5'); 13 | a.set('aKey', 'item6'); 14 | var items; 15 | items = { 16 | 0: 'item0', 17 | 1: 'item1', 18 | 2: 'item2', 19 | 3: 'item3', 20 | 4: 'item4', 21 | 5: 'item5', 22 | 6: 'item6' 23 | }; 24 | var keys; 25 | keys = { 26 | 0: 'dKey', 27 | 1: 0, 28 | 2: 3, 29 | 3: 5, 30 | 4: 6, 31 | 5: 'bKey', 32 | 6: 'aKey' 33 | }; 34 | var i; 35 | for (i = 0; a.valid(); i++, a.next()) { 36 | if (i > 100) { 37 | throw new Exception('out of range'); 38 | } 39 | var val; 40 | val = a.current(); 41 | var key; 42 | key = a.key(); 43 | assert_(key, keys[i], 'key assert'); 44 | assert_(val, items[i], 'value assert'); 45 | } 46 | assert_(a.dKey, 'item0', 1); 47 | assert_(a['dKey'], 'item0', 2); 48 | assert_(a['dKey'], 'item0', 3); 49 | key = 'dKey'; 50 | assert_(a[key], 'item0', 4); 51 | assert_(a[key], 'item0', 5); 52 | assert_(a[key], 'item0', 6); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/class.js.php.js: -------------------------------------------------------------------------------- 1 | /** @var {{test: {}}} N*/ 2 | N._INIT_('test'); 3 | (function() { 4 | var Foo = this.Foo = (function() { 5 | function Foo() { 6 | window.__IS_INHERITANCE__ = false; 7 | } 8 | Foo.prototype.test = function() { 9 | return 6; 10 | }; 11 | return Foo; 12 | })(); 13 | }).call(N.test); 14 | var Foo = (function() { 15 | function Foo() { 16 | window.__IS_INHERITANCE__ = false; 17 | this.publicVar = 'publicVar'; 18 | } 19 | Foo.publicStaticVar = 'publicStaticVar'; 20 | Foo.prototype.publicFunc = function(publicVar) { 21 | this.publicVar = publicVar; 22 | }; 23 | Foo.publicStaticFunc = function() { 24 | return 5; 25 | }; 26 | Foo.CONSTANT = 'CONSTANT'; 27 | return Foo; 28 | })(); 29 | var foo1; 30 | foo1 = new Foo(); 31 | var foo2; 32 | foo2 = new Foo(); 33 | var testFoo; 34 | testFoo = 'test\\Foo'; 35 | var foo3; 36 | foo3 = new(N._GET_(testFoo))(); 37 | var foo4; 38 | foo4 = foo3 instanceof N.test.Foo; 39 | assert_(foo4, true, 'foo3 is not instanceof test\\Foo'); 40 | if (!foo3 instanceof N._GET_(testFoo)) { 41 | assert_(false, true, 'foo3 is not instanceod testFoo'); 42 | } 43 | foo1.publicFunc(5); 44 | assert_(foo1.publicVar, 5, 'foo1 publicvar'); 45 | assert_(foo2.publicVar, 'publicVar', 'foo1 publicvar'); 46 | assert_(Foo.publicStaticVar, 'publicStaticVar', 'publicStaticVar'); 47 | assert_(Foo.publicStaticFunc(), 5, 'publicStaticFunc'); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/closure.js.php.js: -------------------------------------------------------------------------------- 1 | var a; 2 | a = 5; 3 | var b, c, d; 4 | b = c = d = 6; 5 | var foo1; 6 | foo1 = function(b, c) { 7 | var d; 8 | d = 5; 9 | c = 6; 10 | return a + b + c + d; 11 | }; 12 | var foo2; 13 | var a_ = a; 14 | foo2 = function() { 15 | var a = a_; 16 | return a; 17 | }; 18 | var foo3; 19 | foo3 = function() { 20 | var a; 21 | a = 7; 22 | return a; 23 | }; 24 | var testAnonymusFunc; 25 | testAnonymusFunc = 5; 26 | (function() { 27 | testAnonymusFunc = 6; 28 | })(); 29 | assert_(testAnonymusFunc, 6, 'testAnonymusFunc'); 30 | var Foo = (function() { 31 | function Foo() { 32 | window.__IS_INHERITANCE__ = false; 33 | } 34 | Foo.prototype.foo1 = function() { 35 | var a; 36 | a = 8; 37 | return a; 38 | }; 39 | Foo.prototype.foo2 = function() { 40 | var a; 41 | a = 8; 42 | var foo; 43 | foo = function() { 44 | a = 9; 45 | }; 46 | foo(); 47 | return a; 48 | }; 49 | Foo.prototype.foo3 = function() { 50 | var a; 51 | a = 8; 52 | var foo; 53 | var a_ = a; 54 | foo = function() { 55 | var a = a_; 56 | return a; 57 | }; 58 | return foo(); 59 | }; 60 | return Foo; 61 | })(); 62 | a = 6; 63 | assert_(foo1(5), 6 + 16, 'anonymous function use by reference'); 64 | assert_(foo2(), 5, 'anonymous function use '); 65 | assert_(foo3(), 7, 'anonymous function'); 66 | var foo; 67 | foo = new Foo(); 68 | foo.foo1(); 69 | assert_(foo.foo2(), 9, 'anonymous function in class use by reference'); 70 | assert_(foo.foo3(), 8, 'anonymous function in class use '); 71 | assert_(a, 6, 'closure variable no changed'); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/continue.js.php.js: -------------------------------------------------------------------------------- 1 | var total; 2 | total = 0; 3 | var i; 4 | for (i = 0; i < 10; i++) { 5 | if (i % 2 == 0) { 6 | continue; 7 | } 8 | total++; 9 | } 10 | assert_(total, 5); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/defaultArg.js.php.js: -------------------------------------------------------------------------------- 1 | function getTotal(value1, value2) { 2 | if (typeof value2 == 'undefined') value2 = 5; 3 | return value1 + value2; 4 | } 5 | var mathTotal; 6 | mathTotal = getTotal(5); 7 | assert_(mathTotal, 10); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/function.js.php.js: -------------------------------------------------------------------------------- 1 | /** @var {{fooFunctions: {}}} N*/ 2 | N._INIT_('fooFunctions'); 3 | (function() { 4 | var B = this.B = (function() { 5 | function B() { 6 | window.__IS_INHERITANCE__ = false; 7 | } 8 | return B; 9 | })(); 10 | }).call(N.fooFunctions); 11 | /** @var {{functions: {}}} N*/ 12 | N._INIT_('functions'); 13 | (function() { 14 | var A = this.A = (function() { 15 | function A() { 16 | window.__IS_INHERITANCE__ = false; 17 | } 18 | A.prototype.f1 = function() {}; 19 | A.prototype.f2 = function(a, b) {}; 20 | A.prototype.f4 = function(a) { 21 | if (!a instanceof N.fooFunctions.B) throw new Error('bad param type'); 22 | }; 23 | A.prototype.f5 = function(a) { 24 | if (!isCallable(a)) throw new Error('bad param type'); 25 | }; 26 | A.prototype.f7 = function(...a) {}; 27 | A.prototype.f10 = function(...qq) { 28 | for (var __paraPos = 0; __paraPos < arguments.length; __paraPos++) { 29 | if (!arguments[__paraPos] instanceof A) throw new Error('bad param type'); 30 | } 31 | }; 32 | A.prototype.f11 = function(a, b, ...qq) { 33 | if (!a instanceof A) throw new Error('bad param type'); 34 | for (var __paraPos = 2; __paraPos < arguments.length; __paraPos++) { 35 | if (!arguments[__paraPos] instanceof A) throw new Error('bad param type'); 36 | } 37 | }; 38 | A.prototype.f13 = function(a) {}; 39 | A.prototype.f14 = function(a) {}; 40 | A.prototype.f15 = function(a) {}; 41 | A.prototype.f16 = function(a) { 42 | if (!isArray(a)) throw new Error('bad param type'); 43 | }; 44 | return A; 45 | })(); 46 | }).call(N.functions); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/include.js.php.js: -------------------------------------------------------------------------------- 1 | var foo; 2 | foo = 1; 3 | eval(include("includeIt.php.js")); 4 | assert_(foo, 2, 'foo=2'); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/includeIt.php.js: -------------------------------------------------------------------------------- 1 | var poo; 2 | poo = foo; 3 | assert_(poo, 1, 'foo=1'); 4 | foo = 2; 5 | -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/inheritance.js.php.js: -------------------------------------------------------------------------------- 1 | var FooInt = (function() { 2 | function FooInt() { 3 | window.__IS_INHERITANCE__ = false; 4 | __INTERFACE_NEW__(); 5 | } 6 | FooInt.prototype.fooIntFunc1 = function(a, b) { 7 | __INTERFACE_FUNC__(); 8 | }; 9 | return FooInt; 10 | })(); 11 | var FooAbs = (function() { 12 | function FooAbs() { 13 | window.__IS_INHERITANCE__ = false; 14 | } 15 | __extends(FooAbs, null, arguments[1]); 16 | FooAbs.prototype.__isAbstract__ = true; 17 | FooAbs.prototype.fooAbsFunc1 = function(a, b) { 18 | __ABSTRACT_FUNC__(); 19 | }; 20 | FooAbs.prototype.fooAbsFunc2 = function(a, b) { 21 | return a + b + 10; 22 | }; 23 | return FooAbs; 24 | })(null, [FooInt]); 25 | var FooParent = (function(parent) { 26 | function FooParent() { 27 | var __isInheritance = __IS_INHERITANCE__; 28 | window.__IS_INHERITANCE__ = true; 29 | parent.call(this); 30 | this.foo = 5; 31 | if (__isInheritance == false) { 32 | this.__construct(); 33 | } 34 | } 35 | __extends(FooParent, parent); 36 | FooParent.prototype.__construct = function() { 37 | this.foo = 5; 38 | }; 39 | FooParent.prototype.fooAbsFunc1 = function(a, b) { 40 | parent.prototype.fooAbsFunc2.call(this, 1, 5); 41 | return a + b; 42 | }; 43 | FooParent.prototype.fooIntFunc1 = function(a, b) { 44 | if (typeof b == 'undefined') b = 5; 45 | return a + b + 5; 46 | }; 47 | FooParent.fooStatic = function() { 48 | return 10; 49 | }; 50 | return FooParent; 51 | })(FooAbs); 52 | var FooChild = (function(parent) { 53 | function FooChild() { 54 | window.__IS_INHERITANCE__ = true; 55 | parent.call(this); 56 | this.foo = 6; 57 | } 58 | __extends(FooChild, parent); 59 | FooChild.prototype.fooIntFunc1 = function(a, b) { 60 | if (typeof b == 'undefined') b = 5; 61 | return a + b; 62 | }; 63 | FooChild.prototype.testParent = function() { 64 | assert_(this.fooIntFunc1(5, 5), 10, 'testParent 1'); 65 | assert_(parent.prototype.fooIntFunc1.call(this, 5, 5), 15, 'testParent 2'); 66 | }; 67 | return FooChild; 68 | })(FooParent); 69 | var fooParent; 70 | fooParent = new FooParent(); 71 | var fooChild; 72 | fooChild = new FooChild(); 73 | assert_(fooParent instanceof FooParent, true, 'fooParent instanceof FooParent'); 74 | assert_(fooParent instanceof FooInt, true, 'fooParent instanceof FooInt'); 75 | assert_(fooChild instanceof FooChild, true, 'fooChild instanceof FooChild'); 76 | assert_(fooChild instanceof FooParent, true, 'fooChild instanceof FooParent'); 77 | assert_(fooChild instanceof FooAbs, true, 'fooChild instanceof FooAbs'); 78 | assert_(fooChild instanceof FooInt, true, 'fooChild instanceof FooInt'); 79 | assert_(FooChild.fooStatic(), 10, 'FooChild::fooStatic()'); 80 | fooChild.testParent(); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/list.js.php.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by PhpStorm. 3 | * User: Jozef Môstka 4 | * Date: 28.5.2016 5 | * Time: 9:57 6 | */ 7 | var isNull, isFoo, isFive, __LIST_VALUES__; 8 | __LIST_VALUES__ = { 9 | 0: null, 10 | 1: 'foo', 11 | 2: 5 12 | }; 13 | isNull = __LIST_VALUES__[0]; 14 | isFoo = __LIST_VALUES__[1]; 15 | isFive = __LIST_VALUES__[2]; 16 | assert_(isNull, null, 'is null'); 17 | assert_(isFoo, 'foo', 'is foo'); 18 | assert_(isFive, 5, 'is five'); 19 | __LIST_VALUES__ = { 20 | 0: null, 21 | 1: 'foo', 22 | 2: 5 23 | }; 24 | isFive = __LIST_VALUES__[2]; 25 | assert_(isFive, 5, 'is five again'); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/loops.js.php.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by PhpStorm. 3 | * User: Jozef Môstka 4 | * Date: 28.5.2016 5 | * Time: 9:26 6 | */ 7 | var e; 8 | e = 5; 9 | var k; 10 | k = 0; 11 | var i; 12 | for (i = 0; i < e; i++) { 13 | k++; 14 | if (i < e - 2) { 15 | continue; 16 | } else { 17 | break; 18 | } 19 | } 20 | assert_(k, 4, 'for loop'); 21 | var y; 22 | y = { 23 | 0: 1, 24 | 1: 2, 25 | 2: 3, 26 | 3: 4, 27 | 4: 5 28 | }; 29 | k = 0; 30 | var key; 31 | for (key in y) { 32 | var val; 33 | val = y[key]; 34 | k += parseInt(key) + val; 35 | } 36 | assert_(k, 25, 'foreach loop'); 37 | k = 0; 38 | var _key_; 39 | for (_key_ in y) { 40 | var val2; 41 | val2 = y[_key_]; 42 | k += val2; 43 | } 44 | assert_(k, 15, 'foreach loop'); 45 | i = 0; 46 | e = 5; 47 | while (i < e) { 48 | i++; 49 | if (i < e - 1) { 50 | continue; 51 | } else { 52 | break; 53 | } 54 | } 55 | assert_(i, 4, 'while loop'); 56 | i = 0; 57 | e = 5; 58 | do { 59 | i++; 60 | if (i < e - 1) { 61 | continue; 62 | } else { 63 | break; 64 | } 65 | } while (i < e); 66 | assert_(i, 4, 'do while loop'); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/magicConstants.js.php.js: -------------------------------------------------------------------------------- 1 | var Foo = (function() { 2 | function Foo() { 3 | window.__IS_INHERITANCE__ = false; 4 | } 5 | Foo.prototype.getClassName = function() { 6 | return 'Foo'; 7 | }; 8 | Foo.prototype.getMethodName = function() { 9 | return 'Foo::getMethodName'; 10 | }; 11 | return Foo; 12 | })(); 13 | 14 | function getFunctionName() { 15 | return 'getFunctionName'; 16 | } 17 | var foo; 18 | foo = new Foo(); 19 | assert_(foo.getClassName(), 'Foo', '__CLASS__'); 20 | assert_(foo.getMethodName(), 'Foo::getMethodName', '__METHOS__'); 21 | assert_(getFunctionName(), 'getFunctionName', '__FUNCTION__'); 22 | /** @var {{testMagicConstants: {}}} N*/ 23 | N._INIT_('testMagicConstants'); 24 | (function() { 25 | var Foo = this.Foo = (function() { 26 | function Foo() { 27 | window.__IS_INHERITANCE__ = false; 28 | } 29 | Foo.prototype.getClassName = function() { 30 | return 'testMagicConstants\\Foo'; 31 | }; 32 | Foo.prototype.getMethodName = function() { 33 | return 'testMagicConstants\\Foo::getMethodName'; 34 | }; 35 | return Foo; 36 | })(); 37 | var getFunctionName = this.getFunctionName = function() { 38 | return 'testMagicConstants\\getFunctionName'; 39 | }; 40 | var getNamespace = this.getNamespace = function() { 41 | return 'testMagicConstants'; 42 | }; 43 | var foo; 44 | foo = new Foo(); 45 | assert_(foo.getClassName(), 'testMagicConstants\\Foo', '__CLASS__'); 46 | assert_(foo.getMethodName(), 'testMagicConstants\\Foo::getMethodName', '__METHOS__'); 47 | assert_(getFunctionName(), 'testMagicConstants\\getFunctionName', '__FUNCTION__'); 48 | assert_(getNamespace(), 'testMagicConstants', '__NAMESPACE__'); 49 | }).call(N.testMagicConstants); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/magicMethods.js.php.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by PhpStorm. 3 | * User: Jozef Môstka 4 | * Date: 29.5.2016 5 | * Time: 9:54 6 | */ 7 | /** @var {{testMagicMethods: {}}} N*/ 8 | N._INIT_('testMagicMethods'); 9 | (function() { 10 | /** 11 | * @property string test 12 | * @method testCall($test) 13 | */ 14 | var Foo = this.Foo = (function() { 15 | function Foo(test) { 16 | var __isInheritance = __IS_INHERITANCE__; 17 | window.__IS_INHERITANCE__ = false; 18 | this._test = null; 19 | if (__isInheritance == false) { 20 | this.__construct(test); 21 | } 22 | } 23 | Foo.prototype.__construct = function(test) { 24 | this._test = test; 25 | }; 26 | Foo.prototype.tetsFunc = function() { 27 | return 5; 28 | }; 29 | Foo.prototype.__get = function(name) { 30 | switch (name) { 31 | case 'test': 32 | return this._test; 33 | } 34 | return undefined; 35 | }; 36 | Foo.prototype.__set = function(name, value) { 37 | switch (name) { 38 | case 'test': 39 | this._test = value; 40 | } 41 | }; 42 | Foo.prototype.__call = function(name, arguments) { 43 | switch (name) { 44 | case 'testCall': 45 | return arguments[0]; 46 | } 47 | return null; 48 | }; 49 | var __handler = { 50 | construct: function(target, args) { 51 | var obj = Object.create(Foo.prototype); 52 | Foo.apply(obj, args); 53 | return new Proxy(obj, __PROXY_HANDLER); 54 | } 55 | }; 56 | return new Proxy(Foo, __handler); 57 | })(); 58 | var foo; 59 | foo = new Foo('12345'); 60 | assert_(foo._test, '12345', '12345'); 61 | foo._test = '6789'; 62 | assert_(foo._test, '6789', '6789'); 63 | assert_(foo.tetsFunc(), 5, 'testfunc'); 64 | assert_(foo.test, '6789', 'foo->test 1'); 65 | foo.test = '98765'; 66 | assert_(foo.test, '98765', '98765'); 67 | assert_(foo.testCall(5), 5, 'testCall(5)'); 68 | }).call(N.testMagicMethods); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/multiline.js.php.js: -------------------------------------------------------------------------------- 1 | var value1; 2 | value1 = 5; 3 | var value2; 4 | value2 = 10; 5 | var variableString; 6 | variableString = "" + value1 + "\n\ 7 | " + value2 + ""; 8 | assert_(variableString, '5\n\ 9 | 10'); 10 | var multiLineString; 11 | multiLineString = 'This is a string\n\ 12 | That spans two lines'; 13 | var testInlineString; 14 | testInlineString = "test JsClas indexed values index " + value2 + ""; 15 | assert_(testInlineString, 'test JsClas indexed values index 10'); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/namespaces.js.php.js: -------------------------------------------------------------------------------- 1 | window.FOO = 1; 2 | /** @var {{AAA: {}}} N*/ 3 | N._INIT_('AAA'); 4 | (function() { 5 | var FOO = 2; 6 | this.FOO = FOO; 7 | assert_(FOO, 2); 8 | var FooCls = this.FooCls = (function() { 9 | function FooCls() { 10 | window.__IS_INHERITANCE__ = false; 11 | this.foo2 = null; 12 | } 13 | FooCls.foo = 4; 14 | FooCls.fooStatic = function(foo) { 15 | if (typeof foo == 'undefined') foo = 5; 16 | var aa; 17 | aa = 5; 18 | return aa + foo; 19 | }; 20 | FooCls.prototype.fooFunc = function() { 21 | return this.foo2; 22 | }; 23 | return FooCls; 24 | })(); 25 | assert_(FooCls.foo, 4); 26 | assert_(FooCls.fooStatic(), 10); 27 | }).call(N.AAA); 28 | /** @var {{AAA: {BBB: {}}}} N*/ 29 | N._INIT_('AAA.BBB'); 30 | (function() { 31 | var FOO = 3; 32 | this.FOO = FOO; 33 | assert_(FOO, 3); 34 | }).call(N.AAA.BBB); 35 | /** @var {{AAA: {BBB: {CCC: {}}}}} N*/ 36 | N._INIT_('AAA.BBB.CCC'); 37 | (function() { 38 | var CCCFOO = 46; 39 | this.CCCFOO = CCCFOO; 40 | var testNamespaceFunc = this.testNamespaceFunc = function() { 41 | return 465; 42 | }; 43 | }).call(N.AAA.BBB.CCC); 44 | var PPP = N.AAA.BBB.CCC; 45 | assert_(FOO, 1); 46 | assert_(N.AAA.FOO, 2); 47 | assert_(N.AAA.BBB.FOO, 3); 48 | assert_(PPP.CCCFOO, 46); 49 | assert_(N.AAA.FooCls.foo, 4); 50 | assert_(N.AAA.FooCls.fooStatic(), 10); 51 | var foo; 52 | foo = new N.AAA.FooCls(); 53 | foo.foo2 = 6; 54 | assert_(foo.foo2, 6, 'foo2'); 55 | assert_(foo.fooFunc(), 6, 'fooFunc'); 56 | assert_(PPP.testNamespaceFunc(), 465, 'testNamespaceFunc'); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/operators.js.php.js: -------------------------------------------------------------------------------- 1 | var a; 2 | a = 0; 3 | var b; 4 | b = 1; 5 | var c; 6 | c = 2; 7 | var Foo = (function() { 8 | function Foo() { 9 | window.__IS_INHERITANCE__ = false; 10 | } 11 | return Foo; 12 | })(); 13 | ++a; 14 | --a; 15 | a++; 16 | a--; 17 | parseInt(a); 18 | parseInt(a); 19 | parseFloat(a); 20 | parseFloat(a); 21 | (a).toString(); 22 | a; 23 | a; 24 | a * b; 25 | a / b; 26 | a % b; 27 | a + b; 28 | a - b; 29 | a.b; 30 | a << b; 31 | a >> b; 32 | a < b; 33 | a <= b; 34 | a > b; 35 | a >= b; 36 | a == b; 37 | a != b; 38 | a != b; 39 | a === b; 40 | a !== b; 41 | a & b; 42 | a ^ b; 43 | a | b; 44 | a && b; 45 | a || b; 46 | a ? b : c; 47 | a = b; 48 | a *= b; 49 | a /= b; 50 | a %= b; 51 | a += b; 52 | a -= b; 53 | a += b; 54 | a <<= b; 55 | a >>= b; 56 | a &= b; 57 | a ^= b; 58 | a |= b; 59 | a && b; 60 | a ^ b; 61 | a || b; 62 | a instanceof Foo; -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/private.js.php.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by PhpStorm. 3 | * User: Jozef Môstka 4 | * Date: 31.5.2016 5 | * Time: 15:50 6 | */ 7 | /** @var {{privateTest: {}}} N*/ 8 | N._INIT_('privateTest'); 9 | (function() { 10 | var ParentClass = this.ParentClass = (function() { 11 | var __private = __PRIVATIZE__(); 12 | var __getPrivateFunc = function() { 13 | return __private(this).privateParent; 14 | }; 15 | 16 | function ParentClass() { 17 | window.__IS_INHERITANCE__ = false; 18 | __private(this).privateParent = 'privateParent'; 19 | this.publicParent = 'publicParent'; 20 | __private(this).overridePrivateParent = 'overridePrivateParent'; 21 | __private(this).getPrivateFunc = __getPrivateFunc; 22 | } 23 | ParentClass.prototype.getPublicFuncGetPrivate = function() { 24 | return __private(this).getPrivateFunc.call(this); 25 | }; 26 | ParentClass.prototype.getPublicFunc = function() { 27 | return this.publicParent; 28 | }; 29 | ParentClass.prototype.getOverridePrivateParent = function() { 30 | return __private(this).overridePrivateParent; 31 | }; 32 | return ParentClass; 33 | })(); 34 | var Children = this.Children = (function(parent) { 35 | var __private = __PRIVATIZE__(); 36 | var __getPrivateFunc = function() { 37 | return this.publicChildren; 38 | }; 39 | 40 | function Children() { 41 | window.__IS_INHERITANCE__ = true; 42 | parent.call(this); 43 | __private(this).privateChildren = 'privateChildren'; 44 | this.publicChildren = 'publicChildren'; 45 | __private(this).overridePrivateParent = 'overridePrivateParent in Children'; 46 | __private(this).getPrivateFunc = __getPrivateFunc; 47 | } 48 | __extends(Children, parent); 49 | Children.prototype.getPublicFunc = function() { 50 | return __private(this).privateChildren; 51 | }; 52 | Children.prototype.testParentPublicFuncGetPrivate = function() { 53 | return parent.prototype.getPublicFuncGetPrivate.call(this); 54 | }; 55 | Children.prototype.testParentPublicFunc = function() { 56 | return parent.prototype.getPublicFunc.call(this); 57 | }; 58 | Children.prototype.testOverridePrivateParent = function() { 59 | return parent.prototype.getOverridePrivateParent.call(this); 60 | }; 61 | return Children; 62 | })(ParentClass); 63 | var children; 64 | children = new Children(); 65 | assert_(children.testParentPublicFunc(), 'publicParent', 'testParentPublicFunc'); 66 | assert_(children.testParentPublicFuncGetPrivate(), 'privateParent', 'testParentPublicFunc'); 67 | assert_(children.getPublicFunc(), 'privateChildren', 'getPublicFunc'); 68 | assert_(children.testOverridePrivateParent(), 'overridePrivateParent', 'getPublicFunc'); 69 | }).call(N.privateTest); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/switchStatement.js.php.js: -------------------------------------------------------------------------------- 1 | function testSwitchFunction(name, value) { 2 | if (typeof value == 'undefined') value = false; 3 | var result; 4 | result = false; 5 | switch (name) { 6 | case 'output': 7 | result = 'output'; 8 | break; 9 | case 'silent': 10 | result = 'notloud'; 11 | break; 12 | case 'custom': 13 | result = value; 14 | break; 15 | default: 16 | result = 'Unknown'; 17 | } 18 | return result; 19 | } 20 | assert_(testSwitchFunction('output'), 'output'); 21 | assert_(testSwitchFunction('custom', 'bar'), 'bar'); 22 | assert_(testSwitchFunction('shamoan'), 'Unknown'); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/generated/JsPrinter/tryCatch.js.php.js: -------------------------------------------------------------------------------- 1 | var FooException_ = (function(parent) { 2 | function FooException_() { 3 | window.__IS_INHERITANCE__ = true; 4 | parent.call(this); 5 | } 6 | __extends(FooException_, parent); 7 | return FooException_; 8 | })(Exception); 9 | var Foo2Exception_ = (function(parent) { 10 | function Foo2Exception_() { 11 | window.__IS_INHERITANCE__ = true; 12 | parent.call(this); 13 | } 14 | __extends(Foo2Exception_, parent); 15 | return Foo2Exception_; 16 | })(FooException_); 17 | var BeeException_ = (function(parent) { 18 | function BeeException_() { 19 | window.__IS_INHERITANCE__ = true; 20 | parent.call(this); 21 | } 22 | __extends(BeeException_, parent); 23 | return BeeException_; 24 | })(Exception); 25 | var GooException_ = (function(parent) { 26 | function GooException_() { 27 | window.__IS_INHERITANCE__ = true; 28 | parent.call(this); 29 | } 30 | __extends(GooException_, parent); 31 | return GooException_; 32 | })(Exception); 33 | try { 34 | throw new GooException_(); 35 | } catch (__e__) { 36 | var e; 37 | if (__e__ instanceof GooException_) { 38 | e = __e__; 39 | assert_(true, true, 'GooException'); 40 | } else if (__e__ instanceof Exception) { 41 | e = __e__; 42 | assert_(true, false, 'GooException'); 43 | } 44 | } 45 | var finally_; 46 | finally_ = false; 47 | var Foo2Exception; 48 | Foo2Exception = false; 49 | try { 50 | throw new Foo2Exception_(); 51 | } catch (__e__) { 52 | var e; 53 | if (__e__ instanceof Foo2Exception_) { 54 | e = __e__; 55 | Foo2Exception = true; 56 | } else if (__e__ instanceof FooException_) { 57 | e = __e__; 58 | assert_(true, false, 'Foo2Exception'); 59 | } else if (__e__ instanceof Exception) { 60 | e = __e__; 61 | assert_(true, false, 'Foo2Exception'); 62 | var t; 63 | t = e.getLine(); 64 | } 65 | } finally { 66 | finally_ = true; 67 | } 68 | assert_(true, Foo2Exception, 'Foo2Exception'); 69 | assert_(true, finally_, 'finally'); 70 | var FooException; 71 | FooException = false; 72 | try { 73 | throw new FooException_(); 74 | } catch (__e__) { 75 | var e; 76 | if (__e__ instanceof Foo2Exception_) { 77 | e = __e__; 78 | assert_(true, false, 'FooException'); 79 | } else if (__e__ instanceof FooException_) { 80 | e = __e__; 81 | FooException = true; 82 | } else if (__e__ instanceof Exception) { 83 | e = __e__; 84 | assert_(true, false, 'FooException'); 85 | } 86 | } 87 | assert_(true, FooException, 'FooException'); -------------------------------------------------------------------------------- /test/code/jsPrinter/jsSrc/runTest.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'), 2 | path = require('path'); 3 | 4 | function sendError(message) { 5 | console.log(JSON.stringify({error: message})); 6 | process.exit(1); 7 | } 8 | if (process.argv.length != 3) { 9 | sendError("bad arguments"); 10 | } 11 | 12 | var asserts = []; 13 | global.assert_ = function (what, to, message) { 14 | if (typeof message == 'undefined') message = 'no message'; 15 | asserts.push({ 16 | 'what': what, 17 | to: to, 18 | message: message 19 | }); 20 | }; 21 | global.count = function (mixed_var, mode) { 22 | var key, cnt = 0; 23 | 24 | if (mode == 'COUNT_RECURSIVE') mode = 1; 25 | if (mode != 1) mode = 0; 26 | 27 | for (key in mixed_var) { 28 | cnt++; 29 | if (mode == 1 && mixed_var[key] && (mixed_var[key].constructor === Array || mixed_var[key].constructor === Object)) { 30 | cnt += count(mixed_var[key], 1); 31 | } 32 | } 33 | 34 | return cnt; 35 | }; 36 | global.get_class = function (obj) { 37 | if (obj && typeof obj === 'object' && 38 | Object.prototype.toString.call(obj) !== '[object Array]' && 39 | obj.constructor && obj !== this.window) { 40 | var arr = obj.constructor.toString().match(/function\s*(\w+)/); 41 | 42 | if (arr && arr.length === 2) { 43 | return arr[1]; 44 | } 45 | } 46 | return false; 47 | }; 48 | global.Exception = function (msg) { 49 | this.msg = msg; 50 | }; 51 | global.json_encode=function(value){ 52 | return JSON.stringify(value); 53 | }; 54 | global.sqrt=function(value){ 55 | return Math.sqrt(value); 56 | }; 57 | var include_ = function (fileName) { 58 | var ev = require(fileName); 59 | for (var prop in ev) { 60 | //console.log(prop); 61 | global[prop] = ev[prop]; 62 | } 63 | }; 64 | var __ROOT__ = path.dirname(process.argv[2]) + path.sep; 65 | global.include = function (path) { 66 | return fs.readFileSync(__ROOT__ + path) + ''; 67 | }; 68 | global.FALSE = false; 69 | 70 | 71 | include_("../../../../lib/phptojs/lib/js/classManager.js"); 72 | include_("../../../../lib/phptojs/lib/js/HashArray.js"); 73 | include_("../../../../lib/phptojs/lib/js/JsObject.js"); 74 | include_("../../../../lib/phptojs/lib/js/JsArray.js"); 75 | 76 | include_(process.argv[2]); 77 | 78 | console.log(JSON.stringify(asserts)); -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/JsPrinter/array.js.php: -------------------------------------------------------------------------------- 1 | set("dKey", "item0"); 9 | $a->push('item1'); 10 | $a->set("3", 'item2'); 11 | $a->set(5, 'item3'); 12 | $a->push('item4'); 13 | $a->set('bKey', 'item5'); 14 | $a->set('aKey', 'item6'); 15 | 16 | $items = ['item0', 'item1', 'item2', 'item3', 'item4', 'item5', "item6"]; 17 | $keys = ['dKey', 0, 3, 5, 6, "bKey", "aKey"]; 18 | 19 | for ($i = 0; $a->valid(); $i++, $a->next()) { 20 | if ($i > 100) throw new Exception('out of range'); 21 | $val = $a->current(); 22 | $key = $a->key(); 23 | assert_($key, $keys[$i], 'key assert'); 24 | assert_($val, $items[$i], 'value assert'); 25 | } 26 | 27 | assert_($a->dKey, "item0", 1); 28 | assert_($a->{'dKey'}, "item0", 2); 29 | assert_($a['dKey'], "item0", 3); 30 | 31 | $key = 'dKey'; 32 | assert_($a->$key, "item0", 4); 33 | assert_($a->{$key}, "item0", 5); 34 | assert_($a[$key], "item0", 6); 35 | 36 | -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/AssigningThis.js.php: -------------------------------------------------------------------------------- 1 | five; 39 | } 40 | 41 | 42 | } 43 | 44 | $testClass = new TestClass(); 45 | 46 | assert_($testClass->getThis(), $testClass); 47 | assert_($testClass->getThis2(), $testClass); 48 | assert_($testClass->getThis3(), $testClass); 49 | assert_($testClass->getClassName(), 'TestClass'); 50 | assert_($testClass->getValue(), 5); 51 | 52 | 53 | ?> -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/JsArray.js.php: -------------------------------------------------------------------------------- 1 | length,2,"JsArray test 1"); 15 | assert_($fruits[0],"Apple","JsArray test 2"); 16 | assert_($fruits[$fruits->length - 1],"Banana","JsArray test 3"); 17 | 18 | $values=["Apple", "Banana"]; 19 | $indexPos=0; 20 | 21 | $fruits->forEach(function($value,$index,$array) use(&$values,&$indexPos){ 22 | assert_($value,$values[$indexPos], "JsArray test 4.1.{$indexPos}"); 23 | assert_($index,$index, "JsArray test 4.2.{$indexPos}"); 24 | $indexPos++; 25 | }); 26 | 27 | $oneTwoThree=new JsArray(1,2,3); 28 | $a = JsArray::from($oneTwoThree); 29 | 30 | assert_($a->length,3,"JsArray test 5"); 31 | assert_($a[2],3,"JsArray test 6"); 32 | 33 | $a = JsArray::from("string"); 34 | 35 | assert_($a->length,6,"JsArray test 6"); 36 | assert_($a[2],"r","JsArray test 7"); 37 | 38 | // Using an arrow function as the map function to 39 | // manipulate the elements 40 | $a = JsArray::from($oneTwoThree, function($v){ 41 | return $v+$v; 42 | }); 43 | assert_($a->length,3,"JsArray test 8"); 44 | assert_($a[2],6,"JsArray test 9"); 45 | 46 | // Generate a sequence of numbers 47 | $a = JsArray::from(["length"=>5], function($v, $k){ 48 | return $k; 49 | }); 50 | assert_($a->length,5,"JsArray test 10"); 51 | assert_($a[2],2,"JsArray test 11"); 52 | 53 | $a = JsArray::of(1, 2, 3); 54 | assert_($a->length,3,"JsArray test 11.2"); 55 | assert_($a[2],3,"JsArray test 11.3"); 56 | 57 | $alpha = new JsArray('a', 'b', 'c'); 58 | $numeric = new JsArray(1, 2, 3); 59 | 60 | $alphaNumeric = $alpha->concat($numeric); 61 | assert_($alphaNumeric->length,6,"JsArray test 12"); 62 | assert_($alphaNumeric[5],3,"JsArray test 13"); 63 | 64 | $oneTwo = new JsArray(2,3); 65 | $alphaNumeric = $alpha->concat(1, $oneTwo); 66 | assert_($alphaNumeric->length,6,"JsArray test 14"); 67 | assert_($alphaNumeric[5],3,"JsArray test 15"); 68 | 69 | $arr = new JsArray('a', 'b', 'c'); 70 | $eArr = $arr->entries(); 71 | 72 | assert_($eArr->next()->value[1],'a',"JsArray test 16"); 73 | assert_($eArr->next()->value[1],'b',"JsArray test 17"); 74 | assert_($eArr->next()->value->length,2,"JsArray test 18"); 75 | 76 | // Not working in nodejs 77 | // $eArr = $arr->entries(); 78 | // foreach($eArr as $key=>$value){ 79 | // assert_($value,$arr[$key],"JsArray test 19.".$key); 80 | // } 81 | 82 | $isBigEnough = function($element, $index, $array) { 83 | return $element >= 10; 84 | }; 85 | $check = (new JsArray(12, 5, 8, 130, 44))->every($isBigEnough); 86 | assert_($check,false,"JsArray test 20"); 87 | $check = (new JsArray(12, 54, 18, 130, 44))->every($isBigEnough); 88 | assert_($check,true,"JsArray test 21"); 89 | 90 | assert_(json_encode((new JsArray(1, 2, 3))->fill(4)),"[4,4,4]","JsArray test 22"); 91 | assert_(json_encode((new JsArray(1, 2, 3))->fill(4,1)),"[1,4,4]","JsArray test 23"); 92 | assert_(json_encode((new JsArray(1, 2, 3))->fill(4,1,2)),"[1,4,3]","JsArray test 24"); 93 | assert_(json_encode((new JsArray(1, 2, 3))->fill(4,1,1)),"[1,2,3]","JsArray test 25"); 94 | assert_(json_encode((new JsArray(1, 2, 3))->fill(4,-3,-2)),"[4,2,3]","JsArray test 26"); 95 | assert_(json_encode((new JsArray(1, 2, 3))->fill(4,"dsad","dasdas")),"[1,2,3]","JsArray test 27"); 96 | 97 | $isBigEnough = function($value) { 98 | return $value >= 10; 99 | }; 100 | $filtered = (new JsArray(12, 5, 8, 130, 44))->filter($isBigEnough); 101 | assert_(json_encode($filtered),"[12,130,44]","JsArray test 28"); 102 | 103 | $isPrime = function($element, $index, $array){ 104 | $start = 2; 105 | while ($start <= sqrt($element)) { 106 | if ($element % $start++ < 1) { 107 | return false; 108 | } 109 | } 110 | return $element > 1; 111 | }; 112 | assert_((new JsArray(4, 6, 8, 12))->find($isPrime),undefined,"JsArray test 29"); 113 | assert_((new JsArray(4, 5, 8, 12))->find($isPrime),5,"JsArray test 30"); 114 | 115 | assert_((new JsArray(4, 6, 8, 12))->findIndex($isPrime),-1,"JsArray test 31"); 116 | assert_((new JsArray(4, 6, 7, 12))->findIndex($isPrime),2,"JsArray test 32"); 117 | 118 | assert_((new JsArray(1, 2, 3))->includes(2),true,"JsArray test 33"); 119 | assert_((new JsArray(1, 2, 3))->includes(4),false,"JsArray test 34"); 120 | assert_((new JsArray(1, 2, 3))->includes(3,3),false,"JsArray test 35"); 121 | assert_((new JsArray(1, 2, 3))->includes(3,-1),true,"JsArray test 36"); 122 | 123 | $array = new JsArray(2, 9, 9); 124 | assert_($array->indexOf(2),0,"JsArray test 37"); 125 | assert_($array->indexOf(7),-1,"JsArray test 38"); 126 | assert_($array->indexOf(9, 2),2,"JsArray test 39"); 127 | assert_($array->indexOf(2, -1),-1,"JsArray test 40"); 128 | assert_($array->indexOf(2, -3),0,"JsArray test 41"); 129 | 130 | $arr = new JsArray("a", "b", "c"); 131 | $iterator = $arr->keys(); 132 | 133 | assert_($iterator->next()->value,0,"JsArray test 42"); 134 | assert_($iterator->next()->value,1,"JsArray test 43"); 135 | assert_($iterator->next()->value,2,"JsArray test 44"); 136 | assert_($iterator->next()->done,true,"JsArray test 45"); 137 | 138 | $array = new JsArray(2, 5, 9, 2); 139 | assert_($array->lastIndexOf(2),3,"JsArray test 46"); 140 | assert_($array->lastIndexOf(7),-1,"JsArray test 47"); 141 | assert_($array->lastIndexOf(2, 3),3,"JsArray test 48"); 142 | assert_($array->lastIndexOf(2, 2),0,"JsArray test 49"); 143 | assert_($array->lastIndexOf(2, -2),0,"JsArray test 50"); 144 | assert_($array->lastIndexOf(2, -1),3,"JsArray test 51"); 145 | 146 | $numbers = new JsArray(1, 4, 9); 147 | $doubles = $numbers->map(function($num) { 148 | return $num * 2; 149 | }); 150 | assert_(json_encode($doubles),"[2,8,18]","JsArray test 52"); 151 | 152 | $myFish = new JsArray('angel', 'clown', 'mandarin', 'sturgeon'); 153 | $popped = $myFish->pop(); 154 | assert_(json_encode($myFish),'["angel","clown","mandarin"]',"JsArray test 53"); 155 | assert_($popped,"sturgeon","JsArray test 54"); 156 | 157 | $sports = new JsArray('soccer', 'baseball'); 158 | $total = $sports->push('football', 'swimming'); 159 | assert_(json_encode($sports),'["soccer","baseball","football","swimming"]',"JsArray test 54"); 160 | assert_($total,4,"JsArray test 55"); 161 | 162 | $testArray=new JsArray(0,1,2,3,4); 163 | $mapFunc = function($previousValue, $currentValue, $currentIndex, $array) { 164 | return $previousValue + $currentValue; 165 | }; 166 | $value = $testArray->reduce($mapFunc); 167 | assert_($value,10,"JsArray test 56"); 168 | $value = $testArray->reduce($mapFunc,10); 169 | assert_($value,20,"JsArray test 57"); 170 | 171 | $value = $testArray->reduceRight($mapFunc); 172 | assert_($value,10,"JsArray test 58"); 173 | $value = $testArray->reduceRight($mapFunc,10); 174 | assert_($value,20,"JsArray test 59"); 175 | 176 | $myArray = new JsArray('one', 'two', 'three'); 177 | $myArray->reverse(); 178 | assert_(json_encode($myArray),'["three","two","one"]',"JsArray test 60"); 179 | 180 | $myFish = new JsArray('angel', 'clown', 'mandarin', 'surgeon'); 181 | $shifted = $myFish->shift(); 182 | assert_(json_encode($myFish),'["clown","mandarin","surgeon"]',"JsArray test 61"); 183 | assert_($shifted,"angel","JsArray test 62"); 184 | 185 | $fruits = new JsArray('Banana', 'Orange', 'Lemon', 'Apple', 'Mango'); 186 | $citrus = $fruits->slice(1, 3); 187 | assert_(json_encode($citrus),'["Orange","Lemon"]',"JsArray test 62"); 188 | 189 | $isBiggerThan10 = function($element, $index, $array) { 190 | return $element > 10; 191 | }; 192 | assert_((new JsArray(2, 5, 8, 1, 4))->some($isBiggerThan10),false,"JsArray test 63"); 193 | assert_((new JsArray(12, 5, 8, 1, 4))->some($isBiggerThan10),true,"JsArray test 64"); 194 | 195 | 196 | $fruit = new JsArray('cherries', 'apples', 'bananas'); 197 | $fruit->sort(); 198 | assert_(json_encode($fruit),'["apples","bananas","cherries"]',"JsArray test 65"); 199 | 200 | $scores = new JsArray(1, 10, 2, 21); 201 | $scores->sort(); 202 | assert_(json_encode($scores),'[1,10,2,21]',"JsArray test 66"); 203 | 204 | $things = new JsArray('word', 'Word', '1 Word', '2 Words'); 205 | $things->sort(); 206 | assert_(json_encode($things),'["1 Word","2 Words","Word","word"]',"JsArray test 67"); 207 | 208 | $myFish = new JsArray('angel', 'clown', 'mandarin', 'surgeon'); 209 | $removed = $myFish->splice(2, 0, 'drum'); 210 | assert_(json_encode($myFish),'["angel","clown","drum","mandarin","surgeon"]',"JsArray test 68"); 211 | assert_(json_encode($removed),'[]',"JsArray test 69"); 212 | 213 | $removed = $myFish->splice(3, 1); 214 | assert_(json_encode($myFish),'["angel","clown","drum","surgeon"]',"JsArray test 70"); 215 | assert_(json_encode($removed),'["mandarin"]',"JsArray test 71"); 216 | 217 | $removed = $myFish->splice(2, 1, 'trumpet'); 218 | assert_(json_encode($myFish),'["angel","clown","trumpet","surgeon"]',"JsArray test 72"); 219 | assert_(json_encode($removed),'["drum"]',"JsArray test 73"); 220 | 221 | $removed = $myFish->splice(0, 2, 'parrot', 'anemone', 'blue'); 222 | assert_(json_encode($myFish),'["parrot","anemone","blue","trumpet","surgeon"]',"JsArray test 74"); 223 | assert_(json_encode($removed),'["angel","clown"]',"JsArray test 75"); 224 | 225 | $removed = $myFish->splice($myFish->length -3, 2); 226 | assert_(json_encode($myFish),'["parrot","anemone","surgeon"]',"JsArray test 76"); 227 | assert_(json_encode($removed),'["blue","trumpet"]',"JsArray test 77"); 228 | 229 | $arr = new JsArray(1, 2); 230 | 231 | assert_($arr->unshift(0),3,"JsArray test 78"); 232 | assert_(json_encode($arr),"[0,1,2]","JsArray test 79"); 233 | 234 | assert_($arr->unshift(-2, -1),"5","JsArray test 80"); 235 | assert_(json_encode($arr),"[-2,-1,0,1,2]","JsArray test 81"); 236 | 237 | // not working in nodejs 238 | // $arr = new JsArray('w', 'y', 'k', 'o', 'p'); 239 | // $eArr = $arr->values(); 240 | // assert_($eArr->next()->value,"w","JsArray test 82"); 241 | // assert_($eArr->next()->value,"y","JsArray test 83"); 242 | // assert_($eArr->next()->value,"k","JsArray test 84"); 243 | // assert_($eArr->next()->value,"o","JsArray test 85"); 244 | // assert_($eArr->next()->value,"p","JsArray test 86"); 245 | } -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/JsClass.js.php: -------------------------------------------------------------------------------- 1 | aaa=1; 24 | $jsClass->ccc=2; 25 | $jsClass->bbb=3; 26 | $jsClass['122'] = 4; 27 | $jsClass['111'] = 5; 28 | $jsClass['011'] = 6; 29 | $jsClass['001'] = 7; 30 | 31 | $testIndexes = [ 32 | "111"=>5, 33 | '122'=>4, 34 | "aaa"=>1, 35 | "ccc"=>2, 36 | "bbb"=>3, 37 | '011'=>6, 38 | '001'=>7 39 | ]; 40 | $testIndexesKeys=["111",'122',"aaa","ccc","bbb",'011','001']; 41 | 42 | $index = 0; 43 | foreach ($jsClass as $key=>$property) { 44 | assert_($property, $testIndexes[$testIndexesKeys[$index]], "test JsClas indexed values index {$index}"); 45 | assert_($key, $testIndexesKeys[$index], "test JsClas indexed keys index {$index}"); 46 | $index++; 47 | } 48 | 49 | $obj = ["a"=>1]; 50 | $copy = JsObject::assign([], $obj); 51 | assert_($copy->a,1, "JsArray::assign 1"); 52 | 53 | 54 | $o1 = ["a"=>1]; 55 | $o2 = ["b"=>2]; 56 | $o3 = ["c"=>3]; 57 | 58 | $obj = JsObject::assign($o1, $o2, $o3); 59 | 60 | assert_($obj->a,1, "JsArray::assign 2"); 61 | assert_($obj->b,2, "JsArray::assign 3"); 62 | assert_($obj->c,3, "JsArray::assign 4"); 63 | 64 | 65 | $v1 = 'abc'; 66 | $v2 = true; 67 | $v3 = 10; 68 | $v4 = "fd"; 69 | 70 | $obj = JsObject::assign([], $v1, null, $v2, undefined, $v3, $v4); 71 | 72 | assert_($obj[0],"f", "JsArray::assign 5"); 73 | assert_($obj[1],"d", "JsArray::assign 6"); 74 | assert_($obj[2],"c", "JsArray::assign 7"); 75 | } -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/anonymousClass.js.php: -------------------------------------------------------------------------------- 1 | a = $a; 22 | } 23 | }; 24 | } -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/array.js.php: -------------------------------------------------------------------------------- 1 | "item2", 13 | 5 => "item3", 14 | "item4", 15 | "bKey" => "item5", 16 | "aKey" => "item6", 17 | ); 18 | 19 | $items = ['item0', 'item1', 'item2', 'item3', 'item4', 'item5', "item6"]; 20 | $keys = ['dKey', 0, 3, 5, 6, "bKey", "aKey"]; 21 | $i = 0; 22 | foreach ($a as $key => $val) { 23 | assert_($key, $keys[$i], 'key assert'); 24 | assert_($val, $items[$i], 'value assert'); 25 | $i++; 26 | } 27 | 28 | assert_($a{'dKey'}, "item5"); 29 | assert_($a['dKey'], "item5"); 30 | 31 | $key = 'dKey'; 32 | assert_($a{$key}, "item5"); 33 | assert_($a[$key], "item5"); 34 | 35 | -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/class.js.php: -------------------------------------------------------------------------------- 1 | publicVar = $publicVar; 21 | } 22 | 23 | public static function publicStaticFunc() 24 | { 25 | return 5; 26 | } 27 | } 28 | 29 | $foo1 = new Foo(); 30 | $foo2 = new Foo(); 31 | $testFoo = 'test\Foo'; 32 | $foo3 = new $testFoo(); 33 | $foo4 = $foo3 instanceof test\Foo; 34 | assert_($foo4, true, "foo3 is not instanceof test\\Foo"); 35 | if (!$foo3 instanceof $testFoo) { 36 | assert_(false, true, "foo3 is not instanceod testFoo"); 37 | } 38 | $foo1->publicFunc(5); 39 | 40 | assert_($foo1->publicVar, 5, "foo1 publicvar"); 41 | assert_($foo2->publicVar, "publicVar", "foo1 publicvar"); 42 | 43 | assert_(Foo::$publicStaticVar, 'publicStaticVar', 'publicStaticVar'); 44 | 45 | assert_(Foo::publicStaticFunc(), 5, "publicStaticFunc"); 46 | } -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/closure.js.php: -------------------------------------------------------------------------------- 1 | foo1(); 59 | assert_($foo->foo2(), 9, 'anonymous function in class use by reference'); 60 | assert_($foo->foo3(), 8, 'anonymous function in class use '); 61 | 62 | assert_($a, 6, 'closure variable no changed'); 63 | -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/continue.js.php: -------------------------------------------------------------------------------- 1 | foo=5; 23 | } 24 | 25 | function fooAbsFunc1($a, $b) { 26 | parent::fooAbsFunc2(1, 5); 27 | return $a+$b; 28 | } 29 | 30 | function fooIntFunc1($a, $b=5) { 31 | return $a+$b+5; 32 | } 33 | 34 | public static function fooStatic() { 35 | return 10; 36 | } 37 | } 38 | 39 | class FooChild extends FooParent { 40 | public $foo=6; 41 | 42 | function fooIntFunc1($a, $b=5) { 43 | return $a+$b; 44 | } 45 | 46 | function testParent() { 47 | assert_($this->fooIntFunc1(5, 5), 10, 'testParent 1'); 48 | assert_(parent::fooIntFunc1(5, 5), 15, 'testParent 2'); 49 | } 50 | } 51 | } 52 | namespace inheritance3 { 53 | 54 | use inheritance1\FooAbs; 55 | use inheritance1\FooInt; 56 | use inheritance1\FooChild; 57 | use inheritance1\FooParent; 58 | 59 | $fooParent=new FooParent(); 60 | $fooChild=new FooChild(); 61 | 62 | assert_($fooParent instanceof FooParent, true, 'fooParent instanceof FooParent'); 63 | assert_($fooParent instanceof FooInt, true, 'fooParent instanceof FooInt'); 64 | 65 | assert_($fooChild instanceof FooChild, true, 'fooChild instanceof FooChild'); 66 | assert_($fooChild instanceof FooParent, true, 'fooChild instanceof FooParent'); 67 | assert_($fooChild instanceof FooAbs, true, 'fooChild instanceof FooAbs'); 68 | assert_($fooChild instanceof FooInt, true, 'fooChild instanceof FooInt'); 69 | 70 | assert_(FooChild::fooStatic(), 10, "FooChild::fooStatic()"); 71 | 72 | $fooChild->testParent(); 73 | } -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/list.js.php: -------------------------------------------------------------------------------- 1 | $val){ 23 | $k+=(int)$key+$val; 24 | } 25 | assert_($k,25,"foreach loop"); 26 | 27 | $k=0; 28 | foreach ($y as $val2){ 29 | $k+=$val2; 30 | } 31 | assert_($k,15,"foreach loop"); 32 | 33 | 34 | $i=0; 35 | $e=5; 36 | 37 | while($i<$e){ 38 | $i++; 39 | if ($i<$e-1){ 40 | continue; 41 | }else{ 42 | break; 43 | } 44 | } 45 | assert_($i,4,"while loop"); 46 | 47 | $i=0; 48 | $e=5; 49 | do{ 50 | $i++; 51 | if ($i<$e-1){ 52 | continue; 53 | }else{ 54 | break; 55 | } 56 | }while($i<$e); 57 | assert_($i,4,"do while loop"); -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/magicConstants.js.php: -------------------------------------------------------------------------------- 1 | getClassName(), "Foo", "__CLASS__"); 23 | assert_($foo->getMethodName(), "Foo::getMethodName", "__METHOS__"); 24 | assert_(getFunctionName(), "getFunctionName", "__FUNCTION__"); 25 | } 26 | namespace testMagicConstants { 27 | class Foo 28 | { 29 | public function getClassName() 30 | { 31 | return __CLASS__; 32 | } 33 | 34 | public function getMethodName() 35 | { 36 | return __METHOD__; 37 | } 38 | } 39 | 40 | function getFunctionName() 41 | { 42 | return __FUNCTION__; 43 | } 44 | 45 | function getNamespace() 46 | { 47 | return __NAMESPACE__; 48 | } 49 | 50 | $foo = new Foo(); 51 | assert_($foo->getClassName(), "testMagicConstants\\Foo", "__CLASS__"); 52 | assert_($foo->getMethodName(), "testMagicConstants\\Foo::getMethodName", "__METHOS__"); 53 | assert_(getFunctionName(), "testMagicConstants\\getFunctionName", "__FUNCTION__"); 54 | assert_(getNamespace(), "testMagicConstants", "__NAMESPACE__"); 55 | } -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/magicMethods.js.php: -------------------------------------------------------------------------------- 1 | _test=$test; 18 | } 19 | 20 | public function tetsFunc(){ 21 | return 5; 22 | } 23 | 24 | public function __get($name) { 25 | switch ($name) { 26 | case "test": 27 | return $this->_test; 28 | } 29 | return undefined; 30 | } 31 | 32 | public function __set($name, $value) { 33 | switch ($name) { 34 | case "test": 35 | $this->_test=$value; 36 | } 37 | } 38 | 39 | public function __call($name, $arguments) { 40 | switch ($name) { 41 | case "testCall": 42 | return $arguments[0]; 43 | } 44 | return null; 45 | } 46 | } 47 | 48 | $foo = new Foo("12345"); 49 | 50 | assert_($foo->_test,"12345","12345"); 51 | $foo->_test="6789"; 52 | assert_($foo->_test,"6789","6789"); 53 | assert_($foo->tetsFunc(),5,"testfunc"); 54 | assert_($foo->test,"6789","foo->test 1"); 55 | $foo->test="98765"; 56 | assert_($foo->test,"98765","98765"); 57 | assert_($foo->testCall(5),5,"testCall(5)"); 58 | } -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/multiline.js.php: -------------------------------------------------------------------------------- 1 | foo2; 25 | } 26 | } 27 | 28 | assert_(FooCls::$foo, 4); 29 | assert_(FooCls::fooStatic(), 10); 30 | } 31 | 32 | namespace AAA\BBB { 33 | const FOO = 3; 34 | assert_(FOO, 3); 35 | } 36 | 37 | namespace AAA\BBB\CCC { 38 | const CCCFOO = 46; 39 | 40 | function testNamespaceFunc(){ 41 | return 465; 42 | } 43 | } 44 | 45 | namespace { 46 | 47 | use AAA\BBB\CCC as PPP; 48 | 49 | assert_(FOO, 1); 50 | assert_(\AAA\FOO, 2); 51 | assert_(\AAA\BBB\FOO, 3); 52 | assert_(PPP\CCCFOO, 46); 53 | 54 | assert_(\AAA\FooCls::$foo, 4); 55 | assert_(\AAA\FooCls::fooStatic(), 10); 56 | 57 | $foo = new \AAA\FooCls(); 58 | $foo->foo2 = 6; 59 | assert_($foo->foo2, 6, 'foo2'); 60 | assert_($foo->fooFunc(), 6, 'fooFunc'); 61 | 62 | assert_(PPP\testNamespaceFunc(),465,"testNamespaceFunc"); 63 | } -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/operators.js.php: -------------------------------------------------------------------------------- 1 | > $b; 33 | $a < $b; 34 | $a <= $b; 35 | $a > $b; 36 | $a >= $b; 37 | $a == $b; 38 | $a != $b; 39 | $a <> $b; 40 | $a === $b; 41 | $a !== $b; 42 | $a & $b; 43 | $a ^ $b; 44 | $a | $b; 45 | $a && $b; 46 | $a || $b; 47 | $a ? $b : $c; 48 | 49 | $a = $b; 50 | $a *= $b; 51 | $a /= $b; 52 | $a %= $b; 53 | $a += $b; 54 | $a -= $b; 55 | $a .= $b; 56 | $a <<= $b; 57 | $a >>= $b; 58 | $a &= $b; 59 | $a ^= $b; 60 | $a |= $b; 61 | 62 | $a and $b; 63 | $a xor $b; 64 | $a or $b; 65 | $a instanceof Foo; 66 | -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/phpCore.js.php: -------------------------------------------------------------------------------- 1 | getArg1"); 20 | // not working with nodejs. method must be exported to global 21 | //assert_(call_user_func_array("getArg1",[1]),1,"getArg1"); -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/private.js.php: -------------------------------------------------------------------------------- 1 | privateParent; 17 | } 18 | 19 | public function getPublicFuncGetPrivate(){ 20 | return $this->getPrivateFunc(); 21 | } 22 | 23 | public function getPublicFunc(){ 24 | return $this->publicParent; 25 | } 26 | 27 | public function getOverridePrivateParent(){ 28 | return $this->overridePrivateParent; 29 | } 30 | } 31 | 32 | class Children extends ParentClass{ 33 | private $privateChildren="privateChildren"; 34 | public $publicChildren="publicChildren"; 35 | private $overridePrivateParent="overridePrivateParent in Children"; 36 | 37 | private function getPrivateFunc(){ 38 | return $this->publicChildren; 39 | } 40 | 41 | public function getPublicFunc(){ 42 | return $this->privateChildren; 43 | } 44 | 45 | public function testParentPublicFuncGetPrivate(){ 46 | return parent::getPublicFuncGetPrivate(); 47 | } 48 | 49 | public function testParentPublicFunc(){ 50 | return parent::getPublicFunc(); 51 | } 52 | 53 | public function testOverridePrivateParent(){ 54 | return parent::getOverridePrivateParent(); 55 | } 56 | } 57 | 58 | $children = new Children(); 59 | 60 | assert_($children->testParentPublicFunc(),"publicParent","testParentPublicFunc"); 61 | assert_($children->testParentPublicFuncGetPrivate(),"privateParent","testParentPublicFunc"); 62 | assert_($children->getPublicFunc(),"privateChildren","getPublicFunc"); 63 | assert_($children->testOverridePrivateParent(),"overridePrivateParent","getPublicFunc"); -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/global/switchStatement.js.php: -------------------------------------------------------------------------------- 1 | getLine(); 45 | } finally { 46 | $finally_ = true; 47 | } 48 | assert_(true, $Foo2Exception, "Foo2Exception"); 49 | assert_(true, $finally_, "finally"); 50 | 51 | $FooException = false; 52 | try { 53 | throw new FooException_(); 54 | } catch (Foo2Exception_ $e) { 55 | assert_(true, false, "FooException"); 56 | } catch (FooException_ $e) { 57 | $FooException = true; 58 | } catch (Exception $e) { 59 | assert_(true, false, "FooException"); 60 | } 61 | assert_(true, $FooException, "FooException"); -------------------------------------------------------------------------------- /test/code/jsPrinter/phpSrc/runTest.php: -------------------------------------------------------------------------------- 1 | $message, $errno, $errfile, $errline)); 16 | exit(1); 17 | } 18 | 19 | if (count($argv) != 2) { 20 | sendError("bad arguments"); 21 | exit(1); 22 | } 23 | global $asserts; 24 | $asserts = array(); 25 | function assert_($what, $to, $message = "no message") { 26 | global $asserts; 27 | $asserts[] = (object)array( 28 | 'what' => $what, 29 | 'to' => $to, 30 | 'message' => $message 31 | ); 32 | } 33 | 34 | ; 35 | include __DIR__ . "/../../../../lib/phptojs/lib/php/HashArray.php"; 36 | include __DIR__ . "/../../../../lib/phptojs/lib/php/JsObject.php"; 37 | include __DIR__ . "/../../../../lib/phptojs/lib/php/JsArray.php"; 38 | 39 | try { 40 | if (file_exists($argv[1])) { 41 | include $argv[1]; 42 | }else{ 43 | sendError("script not found '{$argv[1]}'"); 44 | } 45 | } catch (Exception $e) { 46 | sendError($e->getTraceAsString()); 47 | } 48 | 49 | echo json_encode($asserts); --------------------------------------------------------------------------------