@rightcapital/phpdoc-parser 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +10 -1
- package/dist/index.js +22 -4
- package/dist/phpdoc-parser/ast/comment.d.ts +7 -0
- package/dist/phpdoc-parser/ast/comment.js +14 -0
- package/dist/phpdoc-parser/ast/const-expr/const-expr-node.d.ts +0 -2
- package/dist/phpdoc-parser/ast/const-expr/const-expr-node.js +0 -3
- package/dist/phpdoc-parser/ast/const-expr/const-expr-string-node.d.ts +5 -1
- package/dist/phpdoc-parser/ast/const-expr/const-expr-string-node.js +33 -2
- package/dist/phpdoc-parser/ast/php-doc/param-closure-this-tag-value-node.d.ts +10 -0
- package/dist/phpdoc-parser/ast/php-doc/param-closure-this-tag-value-node.js +19 -0
- package/dist/phpdoc-parser/ast/php-doc/param-immediately-invoked-callable-tag-value-node.d.ts +8 -0
- package/dist/phpdoc-parser/ast/php-doc/param-immediately-invoked-callable-tag-value-node.js +18 -0
- package/dist/phpdoc-parser/ast/php-doc/param-later-invoked-callable-tag-value-node.d.ts +8 -0
- package/dist/phpdoc-parser/ast/php-doc/param-later-invoked-callable-tag-value-node.js +18 -0
- package/dist/phpdoc-parser/ast/php-doc/php-doc-node.d.ts +2 -0
- package/dist/phpdoc-parser/ast/php-doc/php-doc-node.js +6 -0
- package/dist/phpdoc-parser/ast/php-doc/pure-unless-callable-is-impure-tag-value-node.d.ts +8 -0
- package/dist/phpdoc-parser/ast/php-doc/pure-unless-callable-is-impure-tag-value-node.js +18 -0
- package/dist/phpdoc-parser/ast/php-doc/require-extends-tag-value-node.d.ts +9 -0
- package/dist/phpdoc-parser/ast/php-doc/require-extends-tag-value-node.js +18 -0
- package/dist/phpdoc-parser/ast/php-doc/require-implements-tag-value-node.d.ts +9 -0
- package/dist/phpdoc-parser/ast/php-doc/require-implements-tag-value-node.js +18 -0
- package/dist/phpdoc-parser/ast/php-doc/sealed-tag-value-node.d.ts +9 -0
- package/dist/phpdoc-parser/ast/php-doc/sealed-tag-value-node.js +18 -0
- package/dist/phpdoc-parser/ast/php-doc/template-tag-value-node.d.ts +2 -1
- package/dist/phpdoc-parser/ast/php-doc/template-tag-value-node.js +4 -2
- package/dist/phpdoc-parser/ast/type/array-shape-item-node.d.ts +3 -2
- package/dist/phpdoc-parser/ast/type/array-shape-node.d.ts +8 -2
- package/dist/phpdoc-parser/ast/type/array-shape-node.js +13 -3
- package/dist/phpdoc-parser/ast/type/array-shape-unsealed-type-node.d.ts +8 -0
- package/dist/phpdoc-parser/ast/type/array-shape-unsealed-type-node.js +21 -0
- package/dist/phpdoc-parser/ast/type/callable-type-node.d.ts +3 -1
- package/dist/phpdoc-parser/ast/type/callable-type-node.js +4 -2
- package/dist/phpdoc-parser/ast/types.d.ts +2 -1
- package/dist/phpdoc-parser/ast/types.js +1 -0
- package/dist/phpdoc-parser/lexer/lexer.d.ts +2 -0
- package/dist/phpdoc-parser/lexer/lexer.js +3 -0
- package/dist/phpdoc-parser/parser/const-expr-parser.d.ts +2 -4
- package/dist/phpdoc-parser/parser/const-expr-parser.js +6 -20
- package/dist/phpdoc-parser/parser/php-doc-parser.d.ts +11 -9
- package/dist/phpdoc-parser/parser/php-doc-parser.js +112 -66
- package/dist/phpdoc-parser/parser/string-unescaper.js +2 -2
- package/dist/phpdoc-parser/parser/token-iterator.d.ts +4 -0
- package/dist/phpdoc-parser/parser/token-iterator.js +31 -3
- package/dist/phpdoc-parser/parser/type-parser.d.ts +8 -2
- package/dist/phpdoc-parser/parser/type-parser.js +205 -76
- package/dist/phpdoc-parser/parser-config.d.ts +10 -0
- package/dist/phpdoc-parser/parser-config.js +12 -0
- package/dist/phpdoc-parser/transpiler/php-doc-to-typescript-type-transpiler.js +9 -2
- package/package.json +8 -5
- package/dist/phpdoc-parser/ast/const-expr/quote-aware-const-expr-string-node.d.ts +0 -10
- package/dist/phpdoc-parser/ast/const-expr/quote-aware-const-expr-string-node.js +0 -47
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ArrayShapeUnsealedTypeNode = void 0;
|
|
4
|
+
const type_node_1 = require("./type-node");
|
|
5
|
+
class ArrayShapeUnsealedTypeNode extends type_node_1.TypeNode {
|
|
6
|
+
constructor(valueType, keyType) {
|
|
7
|
+
super();
|
|
8
|
+
this.valueType = valueType;
|
|
9
|
+
this.keyType = keyType;
|
|
10
|
+
}
|
|
11
|
+
toString() {
|
|
12
|
+
if (this.keyType !== null) {
|
|
13
|
+
return `<${this.keyType.toString()}, ${this.valueType.toString()}>`;
|
|
14
|
+
}
|
|
15
|
+
return `<${this.valueType.toString()}>`;
|
|
16
|
+
}
|
|
17
|
+
getNodeType() {
|
|
18
|
+
return 'ArrayShapeUnsealedTypeNode';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.ArrayShapeUnsealedTypeNode = ArrayShapeUnsealedTypeNode;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TemplateTagValueNode } from '../php-doc/template-tag-value-node';
|
|
1
2
|
import type { CallableTypeParameterNode } from './callable-type-parameter-node';
|
|
2
3
|
import type { IdentifierTypeNode } from './identifier-type-node';
|
|
3
4
|
import { TypeNode } from './type-node';
|
|
@@ -5,7 +6,8 @@ export declare class CallableTypeNode extends TypeNode {
|
|
|
5
6
|
identifier: IdentifierTypeNode;
|
|
6
7
|
parameters: CallableTypeParameterNode[];
|
|
7
8
|
returnType: TypeNode;
|
|
8
|
-
|
|
9
|
+
templateTypes: TemplateTagValueNode[];
|
|
10
|
+
constructor(identifier: IdentifierTypeNode, parameters: CallableTypeParameterNode[], returnType: TypeNode, templateTypes?: TemplateTagValueNode[]);
|
|
9
11
|
toString(): string;
|
|
10
12
|
getNodeType(): string;
|
|
11
13
|
}
|
|
@@ -3,19 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CallableTypeNode = void 0;
|
|
4
4
|
const type_node_1 = require("./type-node");
|
|
5
5
|
class CallableTypeNode extends type_node_1.TypeNode {
|
|
6
|
-
constructor(identifier, parameters, returnType) {
|
|
6
|
+
constructor(identifier, parameters, returnType, templateTypes = []) {
|
|
7
7
|
super();
|
|
8
8
|
this.identifier = identifier;
|
|
9
9
|
this.parameters = parameters;
|
|
10
10
|
this.returnType = returnType;
|
|
11
|
+
this.templateTypes = templateTypes;
|
|
11
12
|
}
|
|
12
13
|
toString() {
|
|
13
14
|
let { returnType } = this;
|
|
14
15
|
if (returnType instanceof CallableTypeNode) {
|
|
15
16
|
returnType = `(${returnType.toString()})`;
|
|
16
17
|
}
|
|
18
|
+
const template = this.templateTypes.length > 0 ? `<${this.templateTypes.join(', ')}>` : '';
|
|
17
19
|
const parameters = this.parameters.join(', ');
|
|
18
|
-
return `${this.identifier.toString()}(${parameters}): ${returnType.toString()}`;
|
|
20
|
+
return `${this.identifier.toString()}${template}(${parameters}): ${returnType.toString()}`;
|
|
19
21
|
}
|
|
20
22
|
getNodeType() {
|
|
21
23
|
return 'CallableTypeNode';
|
|
@@ -34,6 +34,7 @@ export declare class Lexer {
|
|
|
34
34
|
static TOKEN_CLOSE_CURLY_BRACKET: string;
|
|
35
35
|
static TOKEN_NEGATED: string;
|
|
36
36
|
static TOKEN_ARROW: string;
|
|
37
|
+
static TOKEN_COMMENT: string;
|
|
37
38
|
static TOKEN_LABELS: {
|
|
38
39
|
[Lexer.TOKEN_REFERENCE]: string;
|
|
39
40
|
[Lexer.TOKEN_UNION]: string;
|
|
@@ -49,6 +50,7 @@ export declare class Lexer {
|
|
|
49
50
|
[Lexer.TOKEN_OPEN_CURLY_BRACKET]: string;
|
|
50
51
|
[Lexer.TOKEN_CLOSE_CURLY_BRACKET]: string;
|
|
51
52
|
[Lexer.TOKEN_COMMA]: string;
|
|
53
|
+
[Lexer.TOKEN_COMMENT]: string;
|
|
52
54
|
[Lexer.TOKEN_COLON]: string;
|
|
53
55
|
[Lexer.TOKEN_VARIADIC]: string;
|
|
54
56
|
[Lexer.TOKEN_DOUBLE_COLON]: string;
|
|
@@ -40,6 +40,7 @@ class Lexer {
|
|
|
40
40
|
[Lexer.TOKEN_OPEN_CURLY_BRACKET]: '\\{',
|
|
41
41
|
[Lexer.TOKEN_CLOSE_CURLY_BRACKET]: '\\}',
|
|
42
42
|
[Lexer.TOKEN_COMMA]: ',',
|
|
43
|
+
[Lexer.TOKEN_COMMENT]: '\\/\\/[^\\r\\n]*(?=\\n|\\r|\\*\\/)',
|
|
43
44
|
[Lexer.TOKEN_VARIADIC]: '\\.\\.\\.',
|
|
44
45
|
[Lexer.TOKEN_DOUBLE_COLON]: '::',
|
|
45
46
|
[Lexer.TOKEN_DOUBLE_ARROW]: '=>',
|
|
@@ -101,6 +102,7 @@ Lexer.TOKEN_OPEN_CURLY_BRACKET = 'TOKEN_OPEN_CURLY_BRACKET';
|
|
|
101
102
|
Lexer.TOKEN_CLOSE_CURLY_BRACKET = 'TOKEN_CLOSE_CURLY_BRACKET';
|
|
102
103
|
Lexer.TOKEN_NEGATED = 'TOKEN_NEGATED';
|
|
103
104
|
Lexer.TOKEN_ARROW = 'TOKEN_ARROW';
|
|
105
|
+
Lexer.TOKEN_COMMENT = 'TOKEN_COMMENT';
|
|
104
106
|
Lexer.TOKEN_LABELS = {
|
|
105
107
|
[Lexer.TOKEN_REFERENCE]: '&',
|
|
106
108
|
[Lexer.TOKEN_UNION]: '|',
|
|
@@ -116,6 +118,7 @@ Lexer.TOKEN_LABELS = {
|
|
|
116
118
|
[Lexer.TOKEN_OPEN_CURLY_BRACKET]: '{',
|
|
117
119
|
[Lexer.TOKEN_CLOSE_CURLY_BRACKET]: '}',
|
|
118
120
|
[Lexer.TOKEN_COMMA]: ',',
|
|
121
|
+
[Lexer.TOKEN_COMMENT]: '//',
|
|
119
122
|
[Lexer.TOKEN_COLON]: ':',
|
|
120
123
|
[Lexer.TOKEN_VARIADIC]: '...',
|
|
121
124
|
[Lexer.TOKEN_DOUBLE_COLON]: '::',
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import type { ConstExprNode } from '../ast/const-expr/const-expr-node';
|
|
2
2
|
import type { TokenIterator } from './token-iterator';
|
|
3
3
|
export declare class ConstExprParser {
|
|
4
|
-
private unescapeStrings;
|
|
5
|
-
private quoteAwareConstExprString;
|
|
6
4
|
private useLinesAttributes;
|
|
7
5
|
private useIndexAttributes;
|
|
8
|
-
constructor(
|
|
6
|
+
constructor(usedAttributes?: {
|
|
9
7
|
lines?: boolean;
|
|
10
8
|
indexes?: boolean;
|
|
11
9
|
});
|
|
12
|
-
parse(tokens: TokenIterator
|
|
10
|
+
parse(tokens: TokenIterator): ConstExprNode;
|
|
13
11
|
private parseArray;
|
|
14
12
|
private parseArrayItem;
|
|
15
13
|
private enrichWithAttributes;
|
|
@@ -10,20 +10,17 @@ const const_expr_null_node_1 = require("../ast/const-expr/const-expr-null-node")
|
|
|
10
10
|
const const_expr_string_node_1 = require("../ast/const-expr/const-expr-string-node");
|
|
11
11
|
const const_expr_true_node_1 = require("../ast/const-expr/const-expr-true-node");
|
|
12
12
|
const const_fetch_node_1 = require("../ast/const-expr/const-fetch-node");
|
|
13
|
-
const quote_aware_const_expr_string_node_1 = require("../ast/const-expr/quote-aware-const-expr-string-node");
|
|
14
13
|
const types_1 = require("../ast/types");
|
|
15
14
|
const lexer_1 = require("../lexer/lexer");
|
|
16
15
|
const parser_exception_1 = require("./parser-exception");
|
|
17
16
|
const string_unescaper_1 = require("./string-unescaper");
|
|
18
17
|
class ConstExprParser {
|
|
19
|
-
constructor(
|
|
18
|
+
constructor(usedAttributes = {}) {
|
|
20
19
|
var _a, _b;
|
|
21
|
-
this.unescapeStrings = unescapeStrings;
|
|
22
|
-
this.quoteAwareConstExprString = quoteAwareConstExprString;
|
|
23
20
|
this.useLinesAttributes = (_a = usedAttributes.lines) !== null && _a !== void 0 ? _a : false;
|
|
24
21
|
this.useIndexAttributes = (_b = usedAttributes.indexes) !== null && _b !== void 0 ? _b : false;
|
|
25
22
|
}
|
|
26
|
-
parse(tokens
|
|
23
|
+
parse(tokens) {
|
|
27
24
|
const startLine = tokens.currentTokenLine();
|
|
28
25
|
const startIndex = tokens.currentTokenIndex();
|
|
29
26
|
if (tokens.isCurrentTokenType(lexer_1.Lexer.TOKEN_FLOAT)) {
|
|
@@ -37,23 +34,12 @@ class ConstExprParser {
|
|
|
37
34
|
return this.enrichWithAttributes(tokens, new const_expr_integer_node_1.ConstExprIntegerNode(value.replaceAll('_', '')), startLine, startIndex);
|
|
38
35
|
}
|
|
39
36
|
if (tokens.isCurrentTokenType(lexer_1.Lexer.TOKEN_SINGLE_QUOTED_STRING, lexer_1.Lexer.TOKEN_DOUBLE_QUOTED_STRING)) {
|
|
40
|
-
|
|
37
|
+
const value = string_unescaper_1.StringUnescaper.unescapeString(tokens.currentTokenValue());
|
|
41
38
|
const type = tokens.currentTokenType();
|
|
42
|
-
if (trimStrings) {
|
|
43
|
-
if (this.unescapeStrings) {
|
|
44
|
-
value = string_unescaper_1.StringUnescaper.unescapeString(value);
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
value = value.substring(1, value.length - 1);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
39
|
tokens.next();
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
: quote_aware_const_expr_string_node_1.QuoteAwareConstExprStringNode.DOUBLE_QUOTED), startLine, startIndex);
|
|
55
|
-
}
|
|
56
|
-
return this.enrichWithAttributes(tokens, new const_expr_string_node_1.ConstExprStringNode(value), startLine, startIndex);
|
|
40
|
+
return this.enrichWithAttributes(tokens, new const_expr_string_node_1.ConstExprStringNode(value, type === lexer_1.Lexer.TOKEN_SINGLE_QUOTED_STRING
|
|
41
|
+
? const_expr_string_node_1.ConstExprStringNode.SINGLE_QUOTED
|
|
42
|
+
: const_expr_string_node_1.ConstExprStringNode.DOUBLE_QUOTED), startLine, startIndex);
|
|
57
43
|
}
|
|
58
44
|
if (tokens.isCurrentTokenType(lexer_1.Lexer.TOKEN_IDENTIFIER)) {
|
|
59
45
|
const identifier = tokens.currentTokenValue();
|
|
@@ -7,17 +7,13 @@ import type { TypeParser } from './type-parser';
|
|
|
7
7
|
export declare class PhpDocParser {
|
|
8
8
|
typeParser: TypeParser;
|
|
9
9
|
constantExprParser: ConstExprParser;
|
|
10
|
-
requireWhitespaceBeforeDescription: boolean;
|
|
11
|
-
preserveTypeAliasesWithInvalidTypes: boolean;
|
|
12
|
-
parseDoctrineAnnotations: boolean;
|
|
13
|
-
private textBetweenTagsBelongsToDescription;
|
|
14
10
|
private useLinesAttributes;
|
|
15
11
|
private useIndexAttributes;
|
|
16
12
|
private static readonly DISALLOWED_DESCRIPTION_START_TOKENS;
|
|
17
|
-
constructor(typeParser: TypeParser, constantExprParser: ConstExprParser,
|
|
18
|
-
lines
|
|
19
|
-
indexes
|
|
20
|
-
}
|
|
13
|
+
constructor(typeParser: TypeParser, constantExprParser: ConstExprParser, usedAttributes?: {
|
|
14
|
+
lines?: boolean;
|
|
15
|
+
indexes?: boolean;
|
|
16
|
+
});
|
|
21
17
|
parse(tokens: TokenIterator): PhpDocNode;
|
|
22
18
|
private parseChild;
|
|
23
19
|
private enrichWithAttributes;
|
|
@@ -30,10 +26,16 @@ export declare class PhpDocParser {
|
|
|
30
26
|
private parseThrowsTagValue;
|
|
31
27
|
private parseMixinTagValue;
|
|
32
28
|
private parseDeprecatedTagValue;
|
|
29
|
+
private parseParamImmediatelyInvokedCallableTagValue;
|
|
30
|
+
private parseParamLaterInvokedCallableTagValue;
|
|
31
|
+
private parseParamClosureThisTagValue;
|
|
32
|
+
private parsePureUnlessCallableIsImpureTagValue;
|
|
33
|
+
private parseRequireExtendsTagValue;
|
|
34
|
+
private parseRequireImplementsTagValue;
|
|
35
|
+
private parseSealedTagValue;
|
|
33
36
|
private parsePropertyTagValue;
|
|
34
37
|
private parseMethodTagValue;
|
|
35
38
|
private parseMethodTagValueParameter;
|
|
36
|
-
private parseTemplateTagValue;
|
|
37
39
|
private parseExtendsTagValue;
|
|
38
40
|
private parseTypeAliasTagValue;
|
|
39
41
|
private parseTypeAliasImportTagValue;
|
|
@@ -12,15 +12,21 @@ const invalid_tag_value_node_1 = require("../ast/php-doc/invalid-tag-value-node"
|
|
|
12
12
|
const method_tag_value_node_1 = require("../ast/php-doc/method-tag-value-node");
|
|
13
13
|
const method_tag_value_parameter_node_1 = require("../ast/php-doc/method-tag-value-parameter-node");
|
|
14
14
|
const mixin_tag_value_node_1 = require("../ast/php-doc/mixin-tag-value-node");
|
|
15
|
+
const param_closure_this_tag_value_node_1 = require("../ast/php-doc/param-closure-this-tag-value-node");
|
|
16
|
+
const param_immediately_invoked_callable_tag_value_node_1 = require("../ast/php-doc/param-immediately-invoked-callable-tag-value-node");
|
|
17
|
+
const param_later_invoked_callable_tag_value_node_1 = require("../ast/php-doc/param-later-invoked-callable-tag-value-node");
|
|
15
18
|
const param_out_tag_value_node_1 = require("../ast/php-doc/param-out-tag-value-node");
|
|
16
19
|
const param_tag_value_node_1 = require("../ast/php-doc/param-tag-value-node");
|
|
17
20
|
const php_doc_node_1 = require("../ast/php-doc/php-doc-node");
|
|
18
21
|
const php_doc_tag_node_1 = require("../ast/php-doc/php-doc-tag-node");
|
|
19
22
|
const php_doc_text_node_1 = require("../ast/php-doc/php-doc-text-node");
|
|
20
23
|
const property_tag_value_node_1 = require("../ast/php-doc/property-tag-value-node");
|
|
24
|
+
const pure_unless_callable_is_impure_tag_value_node_1 = require("../ast/php-doc/pure-unless-callable-is-impure-tag-value-node");
|
|
25
|
+
const require_extends_tag_value_node_1 = require("../ast/php-doc/require-extends-tag-value-node");
|
|
26
|
+
const require_implements_tag_value_node_1 = require("../ast/php-doc/require-implements-tag-value-node");
|
|
21
27
|
const return_tag_value_node_1 = require("../ast/php-doc/return-tag-value-node");
|
|
28
|
+
const sealed_tag_value_node_1 = require("../ast/php-doc/sealed-tag-value-node");
|
|
22
29
|
const self_out_tag_value_node_1 = require("../ast/php-doc/self-out-tag-value-node");
|
|
23
|
-
const template_tag_value_node_1 = require("../ast/php-doc/template-tag-value-node");
|
|
24
30
|
const throws_tag_value_node_1 = require("../ast/php-doc/throws-tag-value-node");
|
|
25
31
|
const type_alias_import_tag_value_node_1 = require("../ast/php-doc/type-alias-import-tag-value-node");
|
|
26
32
|
const type_alias_tag_value_node_1 = require("../ast/php-doc/type-alias-tag-value-node");
|
|
@@ -36,17 +42,10 @@ const DISALLOWED_DESCRIPTION_START_TOKENS = [
|
|
|
36
42
|
lexer_1.Lexer.TOKEN_INTERSECTION,
|
|
37
43
|
];
|
|
38
44
|
class PhpDocParser {
|
|
39
|
-
constructor(typeParser, constantExprParser,
|
|
40
|
-
lines: false,
|
|
41
|
-
indexes: false,
|
|
42
|
-
}, parseDoctrineAnnotations = false, textBetweenTagsBelongsToDescription = false) {
|
|
45
|
+
constructor(typeParser, constantExprParser, usedAttributes = {}) {
|
|
43
46
|
var _a, _b;
|
|
44
47
|
this.typeParser = typeParser;
|
|
45
48
|
this.constantExprParser = constantExprParser;
|
|
46
|
-
this.requireWhitespaceBeforeDescription = requireWhitespaceBeforeDescription;
|
|
47
|
-
this.preserveTypeAliasesWithInvalidTypes = preserveTypeAliasesWithInvalidTypes;
|
|
48
|
-
this.parseDoctrineAnnotations = parseDoctrineAnnotations;
|
|
49
|
-
this.textBetweenTagsBelongsToDescription = textBetweenTagsBelongsToDescription;
|
|
50
49
|
this.useLinesAttributes = (_a = usedAttributes.lines) !== null && _a !== void 0 ? _a : false;
|
|
51
50
|
this.useIndexAttributes = (_b = usedAttributes.indexes) !== null && _b !== void 0 ? _b : false;
|
|
52
51
|
}
|
|
@@ -109,32 +108,22 @@ class PhpDocParser {
|
|
|
109
108
|
parseText(tokens) {
|
|
110
109
|
var _a, _b;
|
|
111
110
|
let text = '';
|
|
112
|
-
|
|
113
|
-
lexer_1.Lexer.TOKEN_PHPDOC_EOL,
|
|
114
|
-
lexer_1.Lexer.TOKEN_CLOSE_PHPDOC,
|
|
115
|
-
lexer_1.Lexer.TOKEN_END,
|
|
116
|
-
];
|
|
117
|
-
if (this.textBetweenTagsBelongsToDescription) {
|
|
118
|
-
endTokens = [lexer_1.Lexer.TOKEN_CLOSE_PHPDOC, lexer_1.Lexer.TOKEN_END];
|
|
119
|
-
}
|
|
111
|
+
const endTokens = [lexer_1.Lexer.TOKEN_CLOSE_PHPDOC, lexer_1.Lexer.TOKEN_END];
|
|
120
112
|
let savepoint = false;
|
|
121
|
-
while (
|
|
122
|
-
!tokens.isCurrentTokenType(lexer_1.Lexer.TOKEN_PHPDOC_EOL)) {
|
|
113
|
+
while (true) {
|
|
123
114
|
const tmpText = tokens.getSkippedHorizontalWhiteSpaceIfAny() +
|
|
124
115
|
tokens.joinUntil(lexer_1.Lexer.TOKEN_PHPDOC_EOL, ...endTokens);
|
|
125
116
|
text += tmpText;
|
|
126
117
|
if (!tokens.isCurrentTokenType(lexer_1.Lexer.TOKEN_PHPDOC_EOL)) {
|
|
127
118
|
break;
|
|
128
119
|
}
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
tokens.pushSavePoint();
|
|
137
|
-
}
|
|
120
|
+
if (!savepoint) {
|
|
121
|
+
tokens.pushSavePoint();
|
|
122
|
+
savepoint = true;
|
|
123
|
+
}
|
|
124
|
+
else if (tmpText !== '') {
|
|
125
|
+
tokens.dropSavePoint();
|
|
126
|
+
tokens.pushSavePoint();
|
|
138
127
|
}
|
|
139
128
|
tokens.pushSavePoint();
|
|
140
129
|
tokens.next();
|
|
@@ -167,16 +156,36 @@ class PhpDocParser {
|
|
|
167
156
|
case '@param':
|
|
168
157
|
case '@phpstan-param':
|
|
169
158
|
case '@psalm-param':
|
|
159
|
+
case '@phan-param':
|
|
170
160
|
tagValue = this.parseParamTagValue(tokens);
|
|
171
161
|
break;
|
|
162
|
+
case '@param-immediately-invoked-callable':
|
|
163
|
+
case '@phpstan-param-immediately-invoked-callable':
|
|
164
|
+
tagValue = this.parseParamImmediatelyInvokedCallableTagValue(tokens);
|
|
165
|
+
break;
|
|
166
|
+
case '@param-later-invoked-callable':
|
|
167
|
+
case '@phpstan-param-later-invoked-callable':
|
|
168
|
+
tagValue = this.parseParamLaterInvokedCallableTagValue(tokens);
|
|
169
|
+
break;
|
|
170
|
+
case '@param-closure-this':
|
|
171
|
+
case '@phpstan-param-closure-this':
|
|
172
|
+
tagValue = this.parseParamClosureThisTagValue(tokens);
|
|
173
|
+
break;
|
|
174
|
+
case '@pure-unless-callable-is-impure':
|
|
175
|
+
case '@phpstan-pure-unless-callable-is-impure':
|
|
176
|
+
tagValue = this.parsePureUnlessCallableIsImpureTagValue(tokens);
|
|
177
|
+
break;
|
|
172
178
|
case '@var':
|
|
173
179
|
case '@phpstan-var':
|
|
174
180
|
case '@psalm-var':
|
|
181
|
+
case '@phan-var':
|
|
175
182
|
tagValue = this.parseVarTagValue(tokens);
|
|
176
183
|
break;
|
|
177
184
|
case '@return':
|
|
178
185
|
case '@phpstan-return':
|
|
179
186
|
case '@psalm-return':
|
|
187
|
+
case '@phan-return':
|
|
188
|
+
case '@phan-real-return':
|
|
180
189
|
tagValue = this.parseReturnTagValue(tokens);
|
|
181
190
|
break;
|
|
182
191
|
case '@throws':
|
|
@@ -184,8 +193,21 @@ class PhpDocParser {
|
|
|
184
193
|
tagValue = this.parseThrowsTagValue(tokens);
|
|
185
194
|
break;
|
|
186
195
|
case '@mixin':
|
|
196
|
+
case '@phan-mixin':
|
|
187
197
|
tagValue = this.parseMixinTagValue(tokens);
|
|
188
198
|
break;
|
|
199
|
+
case '@psalm-require-extends':
|
|
200
|
+
case '@phpstan-require-extends':
|
|
201
|
+
tagValue = this.parseRequireExtendsTagValue(tokens);
|
|
202
|
+
break;
|
|
203
|
+
case '@psalm-require-implements':
|
|
204
|
+
case '@phpstan-require-implements':
|
|
205
|
+
tagValue = this.parseRequireImplementsTagValue(tokens);
|
|
206
|
+
break;
|
|
207
|
+
case '@psalm-inheritors':
|
|
208
|
+
case '@phpstan-sealed':
|
|
209
|
+
tagValue = this.parseSealedTagValue(tokens);
|
|
210
|
+
break;
|
|
189
211
|
case '@deprecated':
|
|
190
212
|
tagValue = this.parseDeprecatedTagValue(tokens);
|
|
191
213
|
break;
|
|
@@ -198,26 +220,33 @@ class PhpDocParser {
|
|
|
198
220
|
case '@psalm-property':
|
|
199
221
|
case '@psalm-property-read':
|
|
200
222
|
case '@psalm-property-write':
|
|
223
|
+
case '@phan-property':
|
|
224
|
+
case '@phan-property-read':
|
|
225
|
+
case '@phan-property-write':
|
|
201
226
|
tagValue = this.parsePropertyTagValue(tokens);
|
|
202
227
|
break;
|
|
203
228
|
case '@method':
|
|
204
229
|
case '@phpstan-method':
|
|
205
230
|
case '@psalm-method':
|
|
231
|
+
case '@phan-method':
|
|
206
232
|
tagValue = this.parseMethodTagValue(tokens);
|
|
207
233
|
break;
|
|
208
234
|
case '@template':
|
|
209
235
|
case '@phpstan-template':
|
|
210
236
|
case '@psalm-template':
|
|
237
|
+
case '@phan-template':
|
|
211
238
|
case '@template-covariant':
|
|
212
239
|
case '@phpstan-template-covariant':
|
|
213
240
|
case '@psalm-template-covariant':
|
|
214
241
|
case '@template-contravariant':
|
|
215
242
|
case '@phpstan-template-contravariant':
|
|
216
243
|
case '@psalm-template-contravariant':
|
|
217
|
-
tagValue = this.parseTemplateTagValue(tokens, true);
|
|
244
|
+
tagValue = this.typeParser.parseTemplateTagValue(tokens, (t) => this.parseOptionalDescription(t, true));
|
|
218
245
|
break;
|
|
219
246
|
case '@extends':
|
|
220
247
|
case '@phpstan-extends':
|
|
248
|
+
case '@phan-extends':
|
|
249
|
+
case '@phan-inherits':
|
|
221
250
|
case '@template-extends':
|
|
222
251
|
tagValue = this.parseExtendsTagValue('@extends', tokens);
|
|
223
252
|
break;
|
|
@@ -233,6 +262,7 @@ class PhpDocParser {
|
|
|
233
262
|
break;
|
|
234
263
|
case '@phpstan-type':
|
|
235
264
|
case '@psalm-type':
|
|
265
|
+
case '@phan-type':
|
|
236
266
|
tagValue = this.parseTypeAliasTagValue(tokens);
|
|
237
267
|
break;
|
|
238
268
|
case '@phpstan-import-type':
|
|
@@ -245,6 +275,9 @@ class PhpDocParser {
|
|
|
245
275
|
case '@psalm-assert':
|
|
246
276
|
case '@psalm-assert-if-true':
|
|
247
277
|
case '@psalm-assert-if-false':
|
|
278
|
+
case '@phan-assert':
|
|
279
|
+
case '@phan-assert-if-true':
|
|
280
|
+
case '@phan-assert-if-false':
|
|
248
281
|
tagValue = this.parseAssertTagValue(tokens);
|
|
249
282
|
break;
|
|
250
283
|
case '@phpstan-this-out':
|
|
@@ -309,6 +342,42 @@ class PhpDocParser {
|
|
|
309
342
|
const description = this.parseOptionalDescription(tokens);
|
|
310
343
|
return new deprecated_tag_value_node_1.DeprecatedTagValueNode(description);
|
|
311
344
|
}
|
|
345
|
+
parseParamImmediatelyInvokedCallableTagValue(tokens) {
|
|
346
|
+
const parameterName = this.parseRequiredVariableName(tokens);
|
|
347
|
+
const description = this.parseOptionalDescription(tokens);
|
|
348
|
+
return new param_immediately_invoked_callable_tag_value_node_1.ParamImmediatelyInvokedCallableTagValueNode(parameterName, description);
|
|
349
|
+
}
|
|
350
|
+
parseParamLaterInvokedCallableTagValue(tokens) {
|
|
351
|
+
const parameterName = this.parseRequiredVariableName(tokens);
|
|
352
|
+
const description = this.parseOptionalDescription(tokens);
|
|
353
|
+
return new param_later_invoked_callable_tag_value_node_1.ParamLaterInvokedCallableTagValueNode(parameterName, description);
|
|
354
|
+
}
|
|
355
|
+
parseParamClosureThisTagValue(tokens) {
|
|
356
|
+
const type = this.typeParser.parse(tokens);
|
|
357
|
+
const parameterName = this.parseRequiredVariableName(tokens);
|
|
358
|
+
const description = this.parseOptionalDescription(tokens);
|
|
359
|
+
return new param_closure_this_tag_value_node_1.ParamClosureThisTagValueNode(type, parameterName, description);
|
|
360
|
+
}
|
|
361
|
+
parsePureUnlessCallableIsImpureTagValue(tokens) {
|
|
362
|
+
const parameterName = this.parseRequiredVariableName(tokens);
|
|
363
|
+
const description = this.parseOptionalDescription(tokens);
|
|
364
|
+
return new pure_unless_callable_is_impure_tag_value_node_1.PureUnlessCallableIsImpureTagValueNode(parameterName, description);
|
|
365
|
+
}
|
|
366
|
+
parseRequireExtendsTagValue(tokens) {
|
|
367
|
+
const type = this.typeParser.parse(tokens);
|
|
368
|
+
const description = this.parseOptionalDescription(tokens, true);
|
|
369
|
+
return new require_extends_tag_value_node_1.RequireExtendsTagValueNode(type, description);
|
|
370
|
+
}
|
|
371
|
+
parseRequireImplementsTagValue(tokens) {
|
|
372
|
+
const type = this.typeParser.parse(tokens);
|
|
373
|
+
const description = this.parseOptionalDescription(tokens, true);
|
|
374
|
+
return new require_implements_tag_value_node_1.RequireImplementsTagValueNode(type, description);
|
|
375
|
+
}
|
|
376
|
+
parseSealedTagValue(tokens) {
|
|
377
|
+
const type = this.typeParser.parse(tokens);
|
|
378
|
+
const description = this.parseOptionalDescription(tokens, true);
|
|
379
|
+
return new sealed_tag_value_node_1.SealedTagValueNode(type, description);
|
|
380
|
+
}
|
|
312
381
|
parsePropertyTagValue(tokens) {
|
|
313
382
|
const type = this.typeParser.parse(tokens);
|
|
314
383
|
const name = this.parseRequiredVariableName(tokens);
|
|
@@ -342,7 +411,7 @@ class PhpDocParser {
|
|
|
342
411
|
do {
|
|
343
412
|
startLine = tokens.currentTokenLine();
|
|
344
413
|
startIndex = tokens.currentTokenIndex();
|
|
345
|
-
const templateType = this.parseTemplateTagValue(tokens
|
|
414
|
+
const templateType = this.typeParser.parseTemplateTagValue(tokens);
|
|
346
415
|
templateTypes.push(this.enrichWithAttributes(tokens, templateType, startLine, startIndex));
|
|
347
416
|
} while (tokens.tryConsumeTokenType(lexer_1.Lexer.TOKEN_COMMA));
|
|
348
417
|
tokens.consumeTokenType(lexer_1.Lexer.TOKEN_CLOSE_ANGLE_BRACKET);
|
|
@@ -383,24 +452,6 @@ class PhpDocParser {
|
|
|
383
452
|
}
|
|
384
453
|
return this.enrichWithAttributes(tokens, new method_tag_value_parameter_node_1.MethodTagValueParameterNode(type, isReference, isVariadic, name, defaultValue), startLine, startIndex);
|
|
385
454
|
}
|
|
386
|
-
parseTemplateTagValue(tokens, parseDescription) {
|
|
387
|
-
const name = tokens.currentTokenValue();
|
|
388
|
-
tokens.consumeTokenType(lexer_1.Lexer.TOKEN_IDENTIFIER);
|
|
389
|
-
let bound = null;
|
|
390
|
-
if (tokens.tryConsumeTokenValue('of') ||
|
|
391
|
-
tokens.tryConsumeTokenValue('as')) {
|
|
392
|
-
bound = this.typeParser.parse(tokens);
|
|
393
|
-
}
|
|
394
|
-
let defaultValue = null;
|
|
395
|
-
if (tokens.tryConsumeTokenValue('=')) {
|
|
396
|
-
defaultValue = this.typeParser.parse(tokens);
|
|
397
|
-
}
|
|
398
|
-
let description = '';
|
|
399
|
-
if (parseDescription) {
|
|
400
|
-
description = this.parseOptionalDescription(tokens);
|
|
401
|
-
}
|
|
402
|
-
return new template_tag_value_node_1.TemplateTagValueNode(name, bound, description, defaultValue);
|
|
403
|
-
}
|
|
404
455
|
parseExtendsTagValue(tagName, tokens) {
|
|
405
456
|
const startLine = tokens.currentTokenLine();
|
|
406
457
|
const startIndex = tokens.currentTokenIndex();
|
|
@@ -423,25 +474,21 @@ class PhpDocParser {
|
|
|
423
474
|
const alias = tokens.currentTokenValue();
|
|
424
475
|
tokens.consumeTokenType(lexer_1.Lexer.TOKEN_IDENTIFIER);
|
|
425
476
|
tokens.tryConsumeTokenType(lexer_1.Lexer.TOKEN_EQUAL);
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
if (!tokens.isCurrentTokenType(lexer_1.Lexer.
|
|
432
|
-
|
|
433
|
-
throw new Error('Expected end of line');
|
|
434
|
-
}
|
|
477
|
+
const startLine = tokens.currentTokenLine();
|
|
478
|
+
const startIndex = tokens.currentTokenIndex();
|
|
479
|
+
try {
|
|
480
|
+
const type = this.typeParser.parse(tokens);
|
|
481
|
+
if (!tokens.isCurrentTokenType(lexer_1.Lexer.TOKEN_CLOSE_PHPDOC)) {
|
|
482
|
+
if (!tokens.isCurrentTokenType(lexer_1.Lexer.TOKEN_PHPDOC_EOL)) {
|
|
483
|
+
throw new Error('Expected end of line');
|
|
435
484
|
}
|
|
436
|
-
return new type_alias_tag_value_node_1.TypeAliasTagValueNode(alias, type);
|
|
437
|
-
}
|
|
438
|
-
catch (e) {
|
|
439
|
-
this.parseOptionalDescription(tokens);
|
|
440
|
-
return new type_alias_tag_value_node_1.TypeAliasTagValueNode(alias, this.enrichWithAttributes(tokens, new invalid_type_node_1.InvalidTypeNode(e), startLine, startIndex));
|
|
441
485
|
}
|
|
486
|
+
return new type_alias_tag_value_node_1.TypeAliasTagValueNode(alias, type);
|
|
487
|
+
}
|
|
488
|
+
catch (e) {
|
|
489
|
+
this.parseOptionalDescription(tokens);
|
|
490
|
+
return new type_alias_tag_value_node_1.TypeAliasTagValueNode(alias, this.enrichWithAttributes(tokens, new invalid_type_node_1.InvalidTypeNode(e), startLine, startIndex));
|
|
442
491
|
}
|
|
443
|
-
const type = this.typeParser.parse(tokens);
|
|
444
|
-
return new type_alias_tag_value_node_1.TypeAliasTagValueNode(alias, type);
|
|
445
492
|
}
|
|
446
493
|
parseTypeAliasImportTagValue(tokens) {
|
|
447
494
|
const importedAlias = tokens.currentTokenValue();
|
|
@@ -542,8 +589,7 @@ class PhpDocParser {
|
|
|
542
589
|
}
|
|
543
590
|
tokens.consumeTokenType(lexer_1.Lexer.TOKEN_OTHER);
|
|
544
591
|
}
|
|
545
|
-
if (
|
|
546
|
-
!tokens.isCurrentTokenType(lexer_1.Lexer.TOKEN_PHPDOC_EOL, lexer_1.Lexer.TOKEN_CLOSE_PHPDOC, lexer_1.Lexer.TOKEN_END) &&
|
|
592
|
+
if (!tokens.isCurrentTokenType(lexer_1.Lexer.TOKEN_PHPDOC_EOL, lexer_1.Lexer.TOKEN_CLOSE_PHPDOC, lexer_1.Lexer.TOKEN_END) &&
|
|
547
593
|
!tokens.isPrecededByHorizontalWhitespace()) {
|
|
548
594
|
tokens.consumeTokenType(lexer_1.Lexer.TOKEN_HORIZONTAL_WS);
|
|
549
595
|
}
|
|
@@ -5,12 +5,12 @@ class StringUnescaper {
|
|
|
5
5
|
static unescapeString(input) {
|
|
6
6
|
const quote = input[0];
|
|
7
7
|
if (quote === "'") {
|
|
8
|
-
return input.slice(1, input.length - 1).replaceAll(/\\([
|
|
8
|
+
return input.slice(1, input.length - 1).replaceAll(/\\([\\'])/g, '$1');
|
|
9
9
|
}
|
|
10
10
|
return this.parseEscapeSequences(input.slice(1, input.length - 1), '"');
|
|
11
11
|
}
|
|
12
12
|
static parseEscapeSequences(input, quote) {
|
|
13
|
-
input = input.replaceAll(new RegExp(
|
|
13
|
+
input = input.replaceAll(new RegExp(`\\\\${quote}`, 'g'), quote);
|
|
14
14
|
return input.replaceAll(/\\([\\nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3}|u\{([0-9a-fA-F]+)\})/g, (substring, ...matches) => {
|
|
15
15
|
const firstCaptureGroup = matches[0];
|
|
16
16
|
if (this.REPLACEMENTS[firstCaptureGroup]) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { Comment } from '../ast/comment';
|
|
1
2
|
export declare class TokenIterator {
|
|
2
3
|
private tokens;
|
|
3
4
|
private index;
|
|
5
|
+
private comments;
|
|
4
6
|
private savePoints;
|
|
5
7
|
private skippedTokenTypes;
|
|
6
8
|
private newline;
|
|
@@ -21,6 +23,8 @@ export declare class TokenIterator {
|
|
|
21
23
|
consumeTokenValue(tokenType: string, tokenValue: string): void;
|
|
22
24
|
tryConsumeTokenValue(tokenValue: string): boolean;
|
|
23
25
|
tryConsumeTokenType(tokenType: string): boolean;
|
|
26
|
+
flushComments(): Comment[];
|
|
27
|
+
skipNewLineTokensAndConsumeComments(): void;
|
|
24
28
|
private detectNewline;
|
|
25
29
|
getSkippedHorizontalWhiteSpaceIfAny(): string;
|
|
26
30
|
joinUntil(...tokenType: string[]): string;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TokenIterator = void 0;
|
|
4
|
+
const comment_1 = require("../ast/comment");
|
|
4
5
|
const lexer_1 = require("../lexer/lexer");
|
|
5
6
|
const parser_exception_1 = require("./parser-exception");
|
|
6
7
|
class TokenIterator {
|
|
7
8
|
constructor(tokens, index = 0) {
|
|
9
|
+
this.comments = [];
|
|
8
10
|
this.savePoints = [];
|
|
9
11
|
this.skippedTokenTypes = [lexer_1.Lexer.TOKEN_HORIZONTAL_WS];
|
|
10
12
|
this.newline = null;
|
|
@@ -110,6 +112,29 @@ class TokenIterator {
|
|
|
110
112
|
this.skipIrrelevantTokens();
|
|
111
113
|
return true;
|
|
112
114
|
}
|
|
115
|
+
flushComments() {
|
|
116
|
+
const res = this.comments;
|
|
117
|
+
this.comments = [];
|
|
118
|
+
return res;
|
|
119
|
+
}
|
|
120
|
+
skipNewLineTokensAndConsumeComments() {
|
|
121
|
+
if (this.currentTokenType() === lexer_1.Lexer.TOKEN_COMMENT) {
|
|
122
|
+
this.comments.push(new comment_1.Comment(this.currentTokenValue(), this.currentTokenLine(), this.currentTokenIndex()));
|
|
123
|
+
this.next();
|
|
124
|
+
}
|
|
125
|
+
if (!this.isCurrentTokenType(lexer_1.Lexer.TOKEN_PHPDOC_EOL)) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
let foundNewLine;
|
|
129
|
+
do {
|
|
130
|
+
foundNewLine = this.tryConsumeTokenType(lexer_1.Lexer.TOKEN_PHPDOC_EOL);
|
|
131
|
+
if (this.currentTokenType() !== lexer_1.Lexer.TOKEN_COMMENT) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
this.comments.push(new comment_1.Comment(this.currentTokenValue(), this.currentTokenLine(), this.currentTokenIndex()));
|
|
135
|
+
this.next();
|
|
136
|
+
} while (foundNewLine);
|
|
137
|
+
}
|
|
113
138
|
detectNewline() {
|
|
114
139
|
const value = this.currentTokenValue();
|
|
115
140
|
if (value.substring(0, 2) === '\r\n') {
|
|
@@ -162,14 +187,17 @@ class TokenIterator {
|
|
|
162
187
|
this.index = lastToken;
|
|
163
188
|
}
|
|
164
189
|
pushSavePoint() {
|
|
165
|
-
this.savePoints.push(this.index);
|
|
190
|
+
this.savePoints.push([this.index, [...this.comments]]);
|
|
166
191
|
}
|
|
167
192
|
dropSavePoint() {
|
|
168
193
|
this.savePoints.pop();
|
|
169
194
|
}
|
|
170
195
|
rollback() {
|
|
171
|
-
const
|
|
172
|
-
|
|
196
|
+
const savepoint = this.savePoints.pop();
|
|
197
|
+
if (savepoint === undefined) {
|
|
198
|
+
throw new Error('No save point to rollback to');
|
|
199
|
+
}
|
|
200
|
+
[this.index, this.comments] = savepoint;
|
|
173
201
|
}
|
|
174
202
|
throwError(expectedTokenType, expectedTokenValue = null) {
|
|
175
203
|
throw new parser_exception_1.ParserException(this.currentTokenValue(), this.currentTokenType(), this.currentTokenOffset(), expectedTokenType, expectedTokenValue, this.currentTokenLine());
|