This repository was archived by the owner on Feb 1, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathJNodeBase.php
More file actions
178 lines (152 loc) · 3.92 KB
/
JNodeBase.php
File metadata and controls
178 lines (152 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
<?php
/**
* File containing class JNodeBase
* @author Tim Whitlock
* @category PLUG
* @package JavaScript
* @subpackage JNodes
* @version $Id: JNodeBase.php,v 1.1 2009/03/22 12:51:08 twhitlock Exp $
*/
import('PLUG.parsing.LR.LRParseNode');
/**
* Default JavaScript node class
* @category PLUG
* @package JavaScript
* @subpackage JNodes
*/
class JNodeBase extends LRParseNode {
/**
* @override
*/
function push( ParseNode $Node, $recursion = true ){
//echo "<br />\n(",$Node->length,") ",j_token_name($Node->t)," pushed onto (",$this->length,") ", j_token_name($this->t);
if( $Node->is_transparent( $this ) ){
//while( $Child = $Node->remove_at(0) ){
// //echo " COLLAPSE to ", j_token_name( $Child->t );
// parent::push( $Child, $recursion );
// unset( $Child );
//}
parent::push_thru( $Node );
$Node->destroy();
return $this->length;
}
// else append this single node
return parent::push( $Node, $recursion );
}
/**
* Tests whether this node can be passed through when appending to given node
* @param JNodeBase
* @return bool
*/
function is_transparent( JNodeBase $Parent ){
return false;
}
/**
* Overloaded method ensures that minimal whitespace is appended where appropriate to maintain syntax
* @return string
*/
function __toString(){
if( $this->is_terminal() ){
return parent::__toString();
}
$src = '';
foreach( $this->children as $i => $Child ){
if( $Child->is_terminal() ){
$s = (string) $Child->value;
switch( $Child->t ){
// these terminals will may or may not be followed by an identifier
// but always by the next terminal in this node.
case J_FUNCTION:
case J_CONTINUE:
case J_BREAK;
$identFollows = isset($this->children[$i+1]) && $this->children[$i+1]->is_symbol(J_IDENTIFIER);
$identFollows and $s .= ' ';
break;
// these terminals will always be followed by an idenfifer
case J_VAR:
// these terminals are followed by a non terminal;
// adding a space to be on the safe side.
case J_DO:
case J_ELSE:
case J_RETURN:
case J_CASE:
case J_THROW:
case J_NEW:
case J_DELETE:
case J_VOID:
case J_TYPEOF:
$s .= ' ';
break;
// these terminals require a space on either side
case J_IN:
case J_INSTANCEOF:
$s = ' '.$s.' ';
break;
}
}
else {
// recursion into non-terminal
$s = $Child->__toString();
}
$src .= $s;
}
return $src;
}
/**
* Default obfuscation routine for non-terminal nodes
*/
function obfuscate( array &$names ){
// Obfuscate current scope, ignoring functions as their scopes are closed
// and are handled by JElementsNode::obfuscate
foreach( $this->children as $Node ){
if( $Node->is_terminal() ){
// identifiers are the only terminal symbol we want to call obfuscate on
if( $Node->is_symbol(J_IDENTIFIER) ){
$Node->obfuscate( $names );
}
}
else if( ! $Node->is_symbol(J_FUNC_DECL) && ! $Node->is_symbol(J_FUNC_EXPR) ){
$Node->obfuscate( $names );
}
}
}
/**
* Default formatting function
* @param string current line
* @param array all lines
*
*/
function format_lines( &$line, array &$lines ){
if( $this->is_terminal() ){
switch( $this->t ){
// semicolon always terminates line
case ';':
$line = rtrim( $line, ' ');
self::format_newline( $this->t, $line, $lines );
break;
// comma may hug previous element; adjust superfluous space.
case ',':
$line = rtrim( $line, ' ');
$line .= ', ';
break;
default:
// by default add trailing space
$line .= $this->__toString().' ';
}
}
else {
// default non-terminal method
foreach( $this->children as $Node ){
$line .= $Node->format_lines( $line, $lines );
}
}
}
/**
* @internal
*/
protected static function format_newline( $str, &$line, array &$lines ){
$line .= $str;
$lines[] = $line;
$line = '';
}
}