Skip to content

Commit 2fdd9fa

Browse files
committed
add try/catch and call nodes
1 parent b7f1483 commit 2fdd9fa

File tree

13 files changed

+1626
-626
lines changed

13 files changed

+1626
-626
lines changed

dist/php-parser.js

Lines changed: 1350 additions & 504 deletions
Large diffs are not rendered by default.

dist/php-parser.min.js

Lines changed: 81 additions & 76 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/php-parser.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/AST.md

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,6 @@
22

33
# AST
44

5-
The AST builder class
6-
7-
**Parameters**
8-
9-
- `withPositions`
10-
- `withSource`
11-
12-
**Properties**
13-
14-
- `withPositions` **[Boolean](#boolean)** Should locate any node (by default false)
15-
- `withSource` **[Boolean](#boolean)** Should extract the node original code (by default false)
16-
17-
## prepare
18-
19-
Prepares an AST node
20-
21-
**Parameters**
22-
23-
- `kind` **([String](#string) | null)** Defines the node type
24-
(if null, the kind must be passed at the function call)
25-
- `parser` **Parser** The parser instance (use for extracting locations)
26-
27-
Returns **[Function](#function)**
28-
29-
# AST
30-
315
## Class hierarchy
326

337
- [Location](#location)
@@ -69,6 +43,9 @@ Returns **[Function](#function)**
6943
- [Foreach](#foreach)
7044
- [Switch](#switch)
7145
- [Goto](#goto)
46+
- [Try](#try)
47+
- [Catch](#catch)
48+
- [Call](#call)
7249
- [Block](#block)
7350
- [Program](#program)
7451
- [Namespace](#namespace)
@@ -109,6 +86,32 @@ Prepares an AST node
10986

11087
Returns **[Function](#function)**
11188

89+
# AST
90+
91+
The AST builder class
92+
93+
**Parameters**
94+
95+
- `withPositions`
96+
- `withSource`
97+
98+
**Properties**
99+
100+
- `withPositions` **[Boolean](#boolean)** Should locate any node (by default false)
101+
- `withSource` **[Boolean](#boolean)** Should extract the node original code (by default false)
102+
103+
## prepare
104+
105+
Prepares an AST node
106+
107+
**Parameters**
108+
109+
- `kind` **([String](#string) | null)** Defines the node type
110+
(if null, the kind must be passed at the function call)
111+
- `parser` **Parser** The parser instance (use for extracting locations)
112+
113+
Returns **[Function](#function)**
114+
112115
# Array
113116

114117
**Extends Expression**
@@ -154,6 +157,16 @@ Defines a boolean value (true/false)
154157

155158
A break statement
156159

160+
# Call
161+
162+
**Extends Statement**
163+
164+
Executes a call statement
165+
166+
**Properties**
167+
168+
- `arguments` **[Array](#array)<Arguments>**
169+
157170
# Case
158171

159172
**Extends Node**
@@ -165,6 +178,30 @@ A switch case statement
165178
- `test` **([Expression](#expression) | null)** if null, means that the default case
166179
- `body` **([Block](#block) | null)**
167180

181+
# Try
182+
183+
**Extends Statement**
184+
185+
Defines a catch statement
186+
187+
**Properties**
188+
189+
- `what` **[Array](#array)<[Identifier](#identifier)>**
190+
- `variable` **[Variable](#variable)**
191+
- `body` **[Statement](#statement)**
192+
193+
# Try
194+
195+
**Extends Statement**
196+
197+
Defines a try statement
198+
199+
**Properties**
200+
201+
- `body` **[Block](#block)**
202+
- `catches` **[Array](#array)<Catch>**
203+
- `allways` **[Block](#block)**
204+
168205
# Class
169206

170207
**Extends Declaration**

docs/parser.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,8 @@ Returns **Switch**
620620
(T_FINALLY '{' inner_statement* '}')?
621621
```
622622

623+
Returns **Try**
624+
623625
# read_short_form
624626

625627
Reads a short form of tokens

src/ast.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ var Position = require('./ast/position');
4949
* - [Foreach](#foreach)
5050
* - [Switch](#switch)
5151
* - [Goto](#goto)
52+
* - [Try](#try)
53+
* - [Catch](#catch)
54+
* - [Call](#call)
5255
* - [Block](#block)
5356
* - [Program](#program)
5457
* - [Namespace](#namespace)
@@ -146,7 +149,9 @@ AST.prototype.prepare = function(kind, parser) {
146149
require('./ast/block'),
147150
require('./ast/boolean'),
148151
require('./ast/break'),
152+
require('./ast/call'),
149153
require('./ast/case'),
154+
require('./ast/catch'),
150155
require('./ast/class'),
151156
require('./ast/classconstant'),
152157
require('./ast/clone'),
@@ -192,6 +197,7 @@ AST.prototype.prepare = function(kind, parser) {
192197
require('./ast/traitalias'),
193198
require('./ast/traitprecedence'),
194199
require('./ast/traituse'),
200+
require('./ast/try'),
195201
require('./ast/unset'),
196202
require('./ast/variable'),
197203
require('./ast/while')

src/ast/call.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*!
2+
* Copyright (C) 2017 Glayzzle (BSD3 License)
3+
* @authors https://github.com/glayzzle/php-parser/graphs/contributors
4+
* @url http://glayzzle.com
5+
*/
6+
"use strict";
7+
8+
var Statement = require('./statement');
9+
var KIND = 'call';
10+
11+
/**
12+
* Executes a call statement
13+
* @constructor Call
14+
* @extends {Statement}
15+
* @property {Identifier|Variable|??} what
16+
* @property {Arguments[]} arguments
17+
*/
18+
var Call = Statement.extends(function Call(what, args, location) {
19+
Statement.apply(this, [KIND, location]);
20+
this.what = what;
21+
this.arguments = args;
22+
});
23+
24+
module.exports = Call;

src/ast/catch.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*!
2+
* Copyright (C) 2017 Glayzzle (BSD3 License)
3+
* @authors https://github.com/glayzzle/php-parser/graphs/contributors
4+
* @url http://glayzzle.com
5+
*/
6+
"use strict";
7+
8+
var Statement = require('./statement');
9+
var KIND = 'catch';
10+
11+
/**
12+
* Defines a catch statement
13+
* @constructor Try
14+
* @extends {Statement}
15+
* @property {Identifier[]} what
16+
* @property {Variable} variable
17+
* @property {Statement} body
18+
* @see http://php.net/manual/en/language.exceptions.php
19+
*/
20+
var Catch = Statement.extends(function Catch(body, what, variable, location) {
21+
Statement.apply(this, [KIND, location]);
22+
this.body = body;
23+
this.what = what;
24+
this.variable = variable;
25+
});
26+
27+
module.exports = Catch;

src/ast/try.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*!
2+
* Copyright (C) 2017 Glayzzle (BSD3 License)
3+
* @authors https://github.com/glayzzle/php-parser/graphs/contributors
4+
* @url http://glayzzle.com
5+
*/
6+
"use strict";
7+
8+
var Statement = require('./statement');
9+
var KIND = 'try';
10+
11+
/**
12+
* Defines a try statement
13+
* @constructor Try
14+
* @extends {Statement}
15+
* @property {Block} body
16+
* @property {Catch[]} catches
17+
* @property {Block} allways
18+
*/
19+
var Try = Statement.extends(function Try(body, catches, always, location) {
20+
Statement.apply(this, [KIND, location]);
21+
this.body = body;
22+
this.catches = catches;
23+
this.always = always;
24+
});
25+
26+
module.exports = Try;

src/parser/namespace.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ module.exports = {
3636
} else if (this.token === '(') {
3737
// resolve ambuiguity between namespace & function call
3838
return this.node('call')(
39-
['ns', name.slice(1)]
39+
['ns', name.slice(1)] // @todo
4040
, this.read_function_argument_list()
4141
);
4242
} else {

src/parser/try.js

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,33 @@ module.exports = {
1212
* )*
1313
* (T_FINALLY '{' inner_statement* '}')?
1414
* ```
15+
* @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L448
16+
* @return {Try}
1517
*/
1618
read_try: function() {
17-
18-
// @todo implement the short form of declarations
1919
this.expect(this.tok.T_TRY);
20-
var result = this.node('try');
21-
var code = this.nextWithComments().read_statement();
22-
var allways = false;
23-
var catches = [];
24-
20+
var result = this.node('try'),
21+
always = null,
22+
body,
23+
catches = []
24+
;
25+
body = this.nextWithComments().read_statement();
2526
this.ignoreComments();
27+
// https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L455
2628
while(this.token === this.tok.T_CATCH) {
29+
var item = this.node('catch'), what = [], variable = null;
2730
this.next().expect('(') && this.next();
28-
var exName = this.read_namespace_name();
29-
var varName = this.read_variable(true, false, false);
30-
this.expect(')') && this.nextWithComments();
31-
catches.push({
32-
exception: exName,
33-
as: varName,
34-
body: this.read_statement()
35-
});
31+
what = this.read_list(
32+
this.read_namespace_name, '|', false
33+
);
34+
variable = this.read_variable(true, false, false);
35+
this.expect(')');
36+
catches.push(item(this.next().read_statement(), what, variable));
3637
this.ignoreComments();
3738
}
3839
if (this.token === this.tok.T_FINALLY) {
39-
allways = this.nextWithComments().read_statement();
40+
always = this.nextWithComments().read_statement();
4041
}
41-
return result(code, catches, allways);
42+
return result(body, catches, always);
4243
}
4344
};

src/parser/variable.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ module.exports = {
9797
if (read_only) {
9898
return result;
9999
} else {
100-
result = ['call', result, this.read_function_argument_list()];
100+
result = this.node('call')(
101+
result, this.read_function_argument_list()
102+
);
101103
}
102104
break;
103105
case '[':

test/statementTests.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,28 @@ describe('Test statements', function() {
1616
ast.children[2].kind.should.be.exactly('goto');
1717
ast.children[2].label.should.be.exactly('start');
1818
});
19+
it('test try', function() {
20+
var ast = parser.parseEval([
21+
'try {',
22+
' foo();',
23+
'} catch(FooError|BarError $err) {',
24+
' var_dump($err);',
25+
'} finally {',
26+
' clean();',
27+
'}'
28+
].join('\n'), {
29+
parser: { debug: false }
30+
});
31+
ast.children[0].kind.should.be.exactly('try');
32+
ast.children[0].body.kind.should.be.exactly('block');
33+
ast.children[0].body.children[0].kind.should.be.exactly('call');
34+
ast.children[0].body.children[0].what.name.should.be.exactly('foo');
35+
ast.children[0].catches[0].kind.should.be.exactly('catch');
36+
ast.children[0].catches[0].what.length.should.be.exactly(2);
37+
ast.children[0].catches[0].what[0].name.should.be.exactly('FooError');
38+
ast.children[0].catches[0].what[1].name.should.be.exactly('BarError');
39+
ast.children[0].catches[0].variable.kind.should.be.exactly('variable');
40+
ast.children[0].catches[0].variable.identifier.should.be.exactly('$err');
41+
ast.children[0].always.kind.should.be.exactly('block');
42+
});
1943
});

0 commit comments

Comments
 (0)