projecte_ionic/node_modules/jsdoctypeparser/peg_src/jsdoctype.pegjs
2022-02-09 18:30:03 +01:00

1217 lines
41 KiB
JavaScript
Executable file

{
const meta = require('../lib/SyntaxType.js');
const {
GenericTypeSyntax,
VariadicTypeSyntax, OptionalTypeSyntax,
NullableTypeSyntax, NotNullableTypeSyntax,
} = meta;
const NodeType = require('../lib/NodeType.js');
const NamepathOperatorType = {
MEMBER: 'MEMBER',
INNER_MEMBER: 'INNER_MEMBER',
INSTANCE_MEMBER: 'INSTANCE_MEMBER',
};
}
TopTypeExpr = _ expr:( VariadicTypeExpr
/ UnionTypeExpr
/ IntersectionTypeExpr // no-jsdoc, no-closure
/ UnaryUnionTypeExpr
/ ArrayTypeExpr // no-closure
/ GenericTypeExpr
/ RecordTypeExpr
/ TupleTypeExpr // no-jsdoc, no-closure
/ ArrowTypeExpr // no-jsdoc, no-closure
/ FunctionTypeExpr
/ TypeQueryExpr // no-jsdoc
/ KeyQueryExpr // no-jsdoc, no-closure
/ BroadNamepathExpr
/ ParenthesizedExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr
) _ {
return expr;
}
/*
* White spaces.
*/
WS = [ \t] / [\r]? [\n]
_ = WS*
__ = WS+
/*
* JavaScript identifier names.
*
* NOTE: We do not support UnicodeIDStart and \UnicodeEscapeSequence yet.
*
* Spec:
* - http://www.ecma-international.org/ecma-262/6.0/index.html#sec-names-and-keywords
* - http://unicode.org/reports/tr31/#Table_Lexical_Classes_for_Identifiers
*/
JsIdentifier = $([a-zA-Z_$][a-zA-Z0-9_$]*)
// It is transformed to remove left recursion.
// See https://en.wikipedia.org/wiki/Left_recursion#Removing_left_recursion
NamepathExpr = rootOwner:(
ParenthesizedExpr /
ImportTypeExpr / // no-jsdoc, no-closure
TypeNameExpr
) memberPartWithOperators:(_ InfixNamepathOperator _ "event:"? _ MemberName)* {
return memberPartWithOperators.reduce(function(owner, tokens) {
const operatorType = tokens[1];
const eventNamespace = tokens[3];
const MemberName = tokens[5];
const {quoteStyle, name: memberName} = MemberName;
switch (operatorType) {
case NamepathOperatorType.MEMBER:
return {
type: NodeType.MEMBER,
owner,
name: memberName,
quoteStyle,
hasEventPrefix: Boolean(eventNamespace),
};
case NamepathOperatorType.INSTANCE_MEMBER:
return {
type: NodeType.INSTANCE_MEMBER,
owner,
name: memberName,
quoteStyle,
hasEventPrefix: Boolean(eventNamespace),
};
case NamepathOperatorType.INNER_MEMBER:
return {
type: NodeType.INNER_MEMBER,
owner,
name: memberName,
quoteStyle,
hasEventPrefix: Boolean(eventNamespace),
};
/* istanbul ignore next */
default:
throw new Error('Unexpected operator type: "' + operatorType + '"');
}
}, rootOwner);
}
/*
* Type name expressions.
*
* Examples:
* - string
* - null
* - Error
* - $
* - _
* - custom-type (JSDoc compatible)
*
* Spec:
* - https://developers.google.com/closure/compiler/docs/js-for-compiler#types
*/
TypeNameExpr = TypeNameExprJsDocFlavored
// JSDoc allows using hyphens in identifier contexts.
// See https://github.com/jsdoctypeparser/jsdoctypeparser/issues/15
TypeNameExprJsDocFlavored = name:$([a-zA-Z_$][a-zA-Z0-9_$-]*) {
return {
type: NodeType.NAME,
name
};
}
MemberName = "'" name:$([^\\'] / "\\".)* "'" {
return {
quoteStyle: 'single',
name: name.replace(/\\'/g, "'")
.replace(/\\\\/gu, '\\')
};
}
/ '"' name:$([^\\"] / "\\".)* '"' {
return {
quoteStyle: 'double',
name: name.replace(/\\"/gu, '"')
.replace(/\\\\/gu, '\\')
};
}
/ name:JsIdentifier {
return {
quoteStyle: 'none',
name
};
};
InfixNamepathOperator = MemberTypeOperator
/ InstanceMemberTypeOperator
/ InnerMemberTypeOperator
QualifiedMemberName = rootOwner:TypeNameExpr memberPart:(_ "." _ TypeNameExpr)* {
return memberPart.reduce(function(owner, tokens) {
return {
type: NodeType.MEMBER,
owner,
name: tokens[3]
}
}, rootOwner);
}
/*
* Member type expressions.
*
* Examples:
* - owner.member
* - superOwner.owner.member
*/
MemberTypeOperator = "." {
return NamepathOperatorType.MEMBER;
}
/*
* Inner member type expressions.
*
* Examples:
* - owner~innerMember
* - superOwner~owner~innerMember
*/
InnerMemberTypeOperator = "~" {
return NamepathOperatorType.INNER_MEMBER;
}
/*
* Instance member type expressions.
*
* Examples:
* - owner#instanceMember
* - superOwner#owner#instanceMember
*/
InstanceMemberTypeOperator = "#" {
return NamepathOperatorType.INSTANCE_MEMBER;
}
BroadNamepathExpr =
ExternalNameExpr / // no-typescript
ModuleNameExpr / // no-typescript
NamepathExpr
// no-typescript-begin
/*
* External name expressions.
*
* Examples:
* - external:classNamespaceOrModuleName
* - external:path/to/file
* - external:path/to/file.js
*
* Spec:
* - https://jsdoc.app/tags-external.html
*/
ExternalNameExpr = "external" _ ":" _ external:(MemberName) memberPartWithOperators:(_ InfixNamepathOperator _ "event:"? _ MemberName)* {
return memberPartWithOperators.reduce(function(owner, tokens) {
const operatorType = tokens[1];
const eventNamespace = tokens[3];
const MemberName = tokens[5];
const {quoteStyle, name: memberName} = MemberName;
switch (operatorType) {
case NamepathOperatorType.MEMBER:
return {
type: NodeType.MEMBER,
owner,
name: memberName,
quoteStyle,
hasEventPrefix: Boolean(eventNamespace),
};
case NamepathOperatorType.INSTANCE_MEMBER:
return {
type: NodeType.INSTANCE_MEMBER,
owner,
name: memberName,
quoteStyle,
hasEventPrefix: Boolean(eventNamespace),
};
case NamepathOperatorType.INNER_MEMBER:
return {
type: NodeType.INNER_MEMBER,
owner,
name: memberName,
quoteStyle,
hasEventPrefix: Boolean(eventNamespace),
};
/* istanbul ignore next */
default:
throw new Error('Unexpected operator type: "' + operatorType + '"');
}
}, Object.assign({
type: NodeType.EXTERNAL
}, external));
}
// no-typescript-end
// no-typescript-begin
/*
* Module name expressions.
*
* Examples:
* - module:path/to/file
* - module:path/to/file.MyModule~Foo
*
* Spec:
* - https://jsdoc.app/tags-module.html
* - https://jsdoc.app/howto-commonjs-modules.html
*/
ModuleNameExpr = "module" _ ":" _ value:ModulePathExpr {
return {
type: NodeType.MODULE,
value,
};
}
// It is transformed to remove left recursion
ModulePathExpr = rootOwner:(FilePathExpr) memberPartWithOperators:(_ InfixNamepathOperator _ "event:"? _ MemberName)* {
return memberPartWithOperators.reduce(function(owner, tokens) {
const operatorType = tokens[1];
const eventNamespace = tokens[3];
const MemberName = tokens[5];
const {quoteStyle, name: memberName} = MemberName;
switch (operatorType) {
case NamepathOperatorType.MEMBER:
return {
type: NodeType.MEMBER,
owner,
name: memberName,
quoteStyle,
hasEventPrefix: Boolean(eventNamespace),
};
case NamepathOperatorType.INSTANCE_MEMBER:
return {
type: NodeType.INSTANCE_MEMBER,
owner,
name: memberName,
quoteStyle,
hasEventPrefix: Boolean(eventNamespace),
};
case NamepathOperatorType.INNER_MEMBER:
return {
type: NodeType.INNER_MEMBER,
owner,
name: memberName,
quoteStyle,
hasEventPrefix: Boolean(eventNamespace),
};
/* istanbul ignore next */
default:
throw new Error('Unexpected operator type: "' + operatorType + '"');
}
}, rootOwner);
}
FilePathExpr = "'" path:$([^\\'] / "\\".)* "'" {
return {
quoteStyle: 'single',
type: NodeType.FILE_PATH,
path: path.replace(/\\'/g, "'")
.replace(/\\\\/gu, '\\')
};
}
/ '"' path:$([^\\"] / "\\".)* '"' {
return {
quoteStyle: 'double',
type: NodeType.FILE_PATH,
path: path.replace(/\\"/gu, '"')
.replace(/\\\\/gu, '\\')
};
}
/ path:$([a-zA-Z0-9_$/-]+) {
return {
quoteStyle: 'none',
type: NodeType.FILE_PATH,
path,
};
}
// no-typescript-end
/*
* Any type expressions.
*
* Examples:
* - *
*
* Spec:
* - https://developers.google.com/closure/compiler/docs/js-for-compiler#types
*/
AnyTypeExpr = "*" {
return { type: NodeType.ANY };
}
/*
* Unknown type expressions.
*
* Examples:
* - ?
*
* Spec:
* - https://developers.google.com/closure/compiler/docs/js-for-compiler#types
*/
UnknownTypeExpr = "?" {
return { type: NodeType.UNKNOWN };
}
/*
* Value type expressions.
*
* Example:
* - 123
* - 0.0
* - -123
* - 0b11
* - 0o77
* - 0cff
* - "foo"
* - "foo\"bar\nbuz"
*
*/
ValueExpr = StringLiteralExpr / NumberLiteralExpr
StringLiteralExpr = '"' value:$([^\\"] / "\\".)* '"' {
return {
type: NodeType.STRING_VALUE,
quoteStyle: 'double',
string: value.replace(/\\"/gu, '"')
.replace(/\\\\/gu, '\\')
};
}
/ "'" value:$([^\\'] / "\\".)* "'" {
return {
type: NodeType.STRING_VALUE,
quoteStyle: 'single',
string: value.replace(/\\'/g, "'")
.replace(/\\\\/gu, '\\')
};
}
NumberLiteralExpr = value:(BinNumberLiteralExpr / OctNumberLiteralExpr / HexNumberLiteralExpr / DecimalNumberLiteralExpr) {
return {
type: NodeType.NUMBER_VALUE,
number: value
};
}
DecimalNumberLiteralExpr = $(("+" / "-")? UnsignedDecimalNumberLiteralExpr)
UnsignedDecimalNumberLiteralExpr = $((([0-9]+ ("." [0-9]+)?) / ("." [0-9]+)) ("e" ("+" / "-")? [0-9]+)?)
BinNumberLiteralExpr = $("-"? "0b"[01]+)
OctNumberLiteralExpr = $("-"? "0o"[0-7]+)
HexNumberLiteralExpr = $("-"? "0x"[0-9a-fA-F]+)
// no-jsdoc-begin, no-closure-begin
/*
* Intersection type expressions.
*
* Examples:
* - A & B
* - Person & Serializable & Loggable
* Spec:
* - https://www.typescriptlang.org/v2/docs/handbook/unions-and-intersections.html
* Issues to support:
* - https://github.com/jsdoc/jsdoc/issues/1285
*/
IntersectionTypeExpr = left:IntersectionTypeExprOperand _ "&" _ right:(IntersectionTypeExpr / IntersectionTypeExprOperand) {
return {
type: NodeType.INTERSECTION,
left,
right,
};
}
IntersectionTypeExprOperand = UnaryUnionTypeExpr
/ RecordTypeExpr
/ TupleTypeExpr // no-jsdoc, no-closure
/ ArrowTypeExpr // no-jsdoc, no-closure
/ FunctionTypeExpr
/ ParenthesizedExpr
/ TypeQueryExpr // no-jsdoc
/ KeyQueryExpr // no-jsdoc, no-closure
/ GenericTypeExpr
/ ArrayTypeExpr // no-closure
/ BroadNamepathExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr
// no-jsdoc-end, no-closure-end
/*
* Union type expressions.
*
* Examples:
* - number|undefined
* - Foo|Bar|Baz
*/
UnionTypeExpr = left:UnionTypeExprOperand _ "|" _ right:(UnionTypeExpr / UnionTypeExprOperand) {
return {
type: NodeType.UNION,
left,
right,
};
}
UnionTypeExprOperand = UnaryUnionTypeExpr
/ RecordTypeExpr
/ TupleTypeExpr // no-jsdoc, no-closure
/ ArrowTypeExpr // no-jsdoc, no-closure
/ FunctionTypeExpr
/ ParenthesizedExpr
/ TypeQueryExpr // no-jsdoc
/ KeyQueryExpr // no-jsdoc, no-closure
/ GenericTypeExpr
/ ArrayTypeExpr // no-closure
/ BroadNamepathExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr
UnaryUnionTypeExpr = SuffixUnaryUnionTypeExpr
/ PrefixUnaryUnionTypeExpr
PrefixUnaryUnionTypeExpr = PrefixOptionalTypeExpr
/ PrefixNotNullableTypeExpr
/ PrefixNullableTypeExpr
PrefixUnaryUnionTypeExprOperand = GenericTypeExpr
/ RecordTypeExpr
/ TupleTypeExpr // no-jsdoc, no-closure
/ ArrowTypeExpr // no-jsdoc, no-closure
/ FunctionTypeExpr
/ ParenthesizedExpr
/ BroadNamepathExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr
// While the following is supported in Closure per https://github.com/google/closure-compiler/wiki/Types-in-the-Closure-Type-System#user-content-the-javascript-type-language
// ...the statement at https://jsdoc.app/tags-type.html :
// > Full support for Google Closure Compiler-style type expressions is
// > available in JSDoc 3.2 and later.
// ... is apparently outdated as the catharsis parser on which jsdoc depends,
// does not contain reference to `typeof` as an expression, so preventing
// from jsdoc mode for now.
// no-jsdoc-begin
TypeQueryExpr = operator:"typeof" __ name:QualifiedMemberName {
return {
type: NodeType.TYPE_QUERY,
name,
};
}
// no-jsdoc-end
// no-jsdoc-begin, no-closure-begin
KeyQueryExpr = operator:"keyof" __ operand:KeyQueryExprOperand {
return {
type: NodeType.KEY_QUERY,
value: operand,
}
}
/ operator:"keyof" operand:ParenthesizedExpr {
return {
type: NodeType.KEY_QUERY,
value: operand,
}
}
KeyQueryExprOperand = UnionTypeExpr
/ IntersectionTypeExpr // no-jsdoc, no-closure
/ UnaryUnionTypeExpr
/ RecordTypeExpr
/ TupleTypeExpr // no-jsdoc, no-closure
/ FunctionTypeExpr
/ ParenthesizedExpr
/ TypeQueryExpr // no-jsdoc
/ KeyQueryExpr
/ ArrayTypeExpr // no-closure
/ GenericTypeExpr
/ BroadNamepathExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr
// no-jsdoc-end, no-closure-end
// no-jsdoc-begin, no-closure-begin
ImportTypeExpr = operator:"import" _ "(" _ path:StringLiteralExpr _ ")" {
return { type: NodeType.IMPORT, path };
}
// no-jsdoc-end, no-closure-end
/*
* Prefix nullable type expressions.
*
* Examples:
* - ?string
*
* Spec:
* - https://developers.google.com/closure/compiler/docs/js-for-compiler#types
*/
PrefixNullableTypeExpr = operator:"?" _ operand:PrefixUnaryUnionTypeExprOperand {
return {
type: NodeType.NULLABLE,
value: operand,
meta: { syntax: NullableTypeSyntax.PREFIX_QUESTION_MARK },
};
}
/*
* Prefix not nullable type expressions.
*
* Examples:
* - !Object
*
* Spec:
* - https://developers.google.com/closure/compiler/docs/js-for-compiler#types
*/
PrefixNotNullableTypeExpr = operator:"!" _ operand:PrefixUnaryUnionTypeExprOperand {
return {
type: NodeType.NOT_NULLABLE,
value: operand,
meta: { syntax: NotNullableTypeSyntax.PREFIX_BANG },
};
}
/*
* Prefix optional type expressions.
* This expression is deprecated.
*
* Examples:
* - =string (deprecated)
*/
PrefixOptionalTypeExpr = operator:"=" _ operand:PrefixUnaryUnionTypeExprOperand {
return {
type: NodeType.OPTIONAL,
value: operand,
meta: { syntax: OptionalTypeSyntax.PREFIX_EQUALS_SIGN },
};
}
SuffixUnaryUnionTypeExpr = SuffixOptionalTypeExpr
/ SuffixNullableTypeExpr
/ SuffixNotNullableTypeExpr
SuffixUnaryUnionTypeExprOperand = PrefixUnaryUnionTypeExpr
/ GenericTypeExpr
/ RecordTypeExpr
/ TupleTypeExpr // no-jsdoc, no-closure
/ ArrowTypeExpr // no-jsdoc, no-closure
/ FunctionTypeExpr
/ ParenthesizedExpr
/ BroadNamepathExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr
/*
* Suffix nullable type expressions.
* This expression is deprecated.
*
* Examples:
* - string? (deprecated)
*
* Note:
* Deprecated optional type operators can be placed before optional operators.
* See https://github.com/google/closure-library/blob/47f9c92bb4c7de9a3d46f9921a427402910073fb/closure/goog/net/tmpnetwork.js#L50
*/
SuffixNullableTypeExpr = operand:SuffixUnaryUnionTypeExprOperand _ operator:"?" {
return {
type: NodeType.NULLABLE,
value: operand,
meta: { syntax: NullableTypeSyntax.SUFFIX_QUESTION_MARK },
};
}
/*
* Suffix not nullable type expressions.
* This expression is deprecated.
*
* Examples:
* - Object! (deprecated)
*/
SuffixNotNullableTypeExpr = operand:SuffixUnaryUnionTypeExprOperand _ operator:"!" {
return {
type: NodeType.NOT_NULLABLE,
value: operand,
meta: { syntax: NotNullableTypeSyntax.SUFFIX_BANG },
};
}
/*
* Suffix optional type expressions.
*
* Examples:
* - string=
*
* Spec:
* - https://developers.google.com/closure/compiler/docs/js-for-compiler#types
*/
SuffixOptionalTypeExpr = operand:( SuffixNullableTypeExpr
/ SuffixNotNullableTypeExpr
/ SuffixUnaryUnionTypeExprOperand
) _ operator:"=" {
return {
type: NodeType.OPTIONAL,
value: operand,
meta: { syntax: OptionalTypeSyntax.SUFFIX_EQUALS_SIGN },
};
}
/*
* Generic type expressions.
*
* Examples:
* - Function<T>
* - Array.<string> (Legacy Closure Library style and JSDoc3 style)
*
* Spec:
* - https://developers.google.com/closure/compiler/docs/js-for-compiler#types
* - https://jsdoc.app/tags-type.html
*/
GenericTypeExpr = operand:GenericTypeExprOperand _ syntax:GenericTypeStartToken _
params:GenericTypeExprTypeParamList _ GenericTypeEndToken {
return {
type: NodeType.GENERIC,
subject: operand,
objects: params,
meta: { syntax },
};
}
GenericTypeExprOperand = ParenthesizedExpr
/ BroadNamepathExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr
GenericTypeExprTypeParamOperand = UnionTypeExpr
/ IntersectionTypeExpr // no-jsdoc, no-closure
/ UnaryUnionTypeExpr
/ RecordTypeExpr
/ TupleTypeExpr // no-jsdoc, no-closure
/ ArrowTypeExpr // no-jsdoc, no-closure
/ FunctionTypeExpr
/ ParenthesizedExpr
/ ArrayTypeExpr // no-closure
/ GenericTypeExpr
/ TypeQueryExpr // no-jsdoc
/ KeyQueryExpr // no-jsdoc, no-closure
/ BroadNamepathExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr
GenericTypeExprTypeParamList = first:GenericTypeExprTypeParamOperand
restsWithComma:(_ "," _ GenericTypeExprTypeParamOperand)* {
return restsWithComma.reduce(function(params, tokens) {
return params.concat([tokens[3]]);
}, [first]);
}
GenericTypeStartToken = GenericTypeEcmaScriptFlavoredStartToken
/ GenericTypeTypeScriptFlavoredStartToken
GenericTypeEcmaScriptFlavoredStartToken = ".<" {
return GenericTypeSyntax.ANGLE_BRACKET_WITH_DOT;
}
GenericTypeTypeScriptFlavoredStartToken = "<" {
return GenericTypeSyntax.ANGLE_BRACKET;
}
GenericTypeEndToken = ">"
// no-closure-begin
/*
* JSDoc style array of generic type expressions.
*
* Examples:
* - string[]
* - number[][]
*
* Spec:
* - https://jsdoc.app/tags-type.html
*/
// TODO: We should support complex type expressions like "Some[]![]"
ArrayTypeExpr = operand:ArrayTypeExprOperand brackets:(_ "[" _ "]")+ {
return brackets.reduce(function(operand) {
return {
type: NodeType.GENERIC,
subject: {
type: NodeType.NAME,
name: 'Array'
},
objects: [ operand ],
meta: { syntax: GenericTypeSyntax.SQUARE_BRACKET },
};
}, operand);
}
ArrayTypeExprOperand = UnaryUnionTypeExpr
/ RecordTypeExpr
/ TupleTypeExpr // no-jsdoc, no-closure
/ ArrowTypeExpr // no-jsdoc, no-closure
/ FunctionTypeExpr
/ ParenthesizedExpr
/ GenericTypeExpr
/ TypeQueryExpr // no-jsdoc
/ KeyQueryExpr // no-jsdoc, no-closure
/ BroadNamepathExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr
// no-closure-end
// no-jsdoc-begin, no-closure-begin
ArrowTypeExpr = newModifier:"new"? _ paramsPart:ArrowTypeExprParamsList _ "=>" _ returnedTypeNode:FunctionTypeExprReturnableOperand {
return {
type: NodeType.ARROW,
params: paramsPart,
returns: returnedTypeNode,
new: newModifier
};
}
ArrowTypeExprParamsList = "(" _ ")" {
return [];
} /
"(" _ params:ArrowTypeExprParams _ ")" {
return params;
}
ArrowTypeExprParams = paramsWithComma:(JsIdentifier _ ":" _ FunctionTypeExprParamOperand? _ "," _)* lastParam:VariadicNameExpr? {
return paramsWithComma.reduceRight(function(params, tokens) {
const param = { type: NodeType.NAMED_PARAMETER, name: tokens[0], typeName: tokens[4] };
return [param].concat(params);
}, lastParam ? [lastParam] : []);
}
VariadicNameExpr = spread:"..."? _ id:JsIdentifier _ ":" _ type:FunctionTypeExprParamOperand? {
const operand = { type: NodeType.NAMED_PARAMETER, name: id, typeName: type };
if (spread) {
return {
type: NodeType.VARIADIC,
value: operand,
meta: { syntax: VariadicTypeSyntax.PREFIX_DOTS },
};
}
else {
return operand;
}
}
// no-jsdoc-end, no-closure-end
/*
* Function type expressions.
*
* Examples:
* - function(string)
* - function(string, ...string)
* - function():number
* - function(this:jQuery):jQuery
* - function(new:Error)
*
* Spec:
* - https://developers.google.com/closure/compiler/docs/js-for-compiler#types
*/
FunctionTypeExpr = "function" _ paramsPart:FunctionTypeExprParamsList _
returnedTypePart:(":" _ FunctionTypeExprReturnableOperand)? {
const returnedTypeNode = returnedTypePart ? returnedTypePart[2] : null;
return {
type: NodeType.FUNCTION,
params: paramsPart.params,
returns: returnedTypeNode,
this: paramsPart.modifier.nodeThis,
new: paramsPart.modifier.nodeNew,
};
}
FunctionTypeExprParamsList = "(" _ modifier:FunctionTypeExprModifier _ "," _ params: FunctionTypeExprParams _ ")" {
return { params, modifier };
}
/ "(" _ modifier:FunctionTypeExprModifier _ ")" {
return { params: [], modifier };
}
/ "(" _ ")" {
return { params: [], modifier: { nodeThis: null, nodeNew: null } };
}
/ "(" _ params:FunctionTypeExprParams _ ")" {
return { params, modifier: { nodeThis: null, nodeNew: null } };
}
// We can specify either "this:" or "new:".
// See https://github.com/google/closure-compiler/blob/
// 91cf3603d5b0b0dc289ba73adcd0f2741aa90d89/src/
// com/google/javascript/jscomp/parsing/JsDocInfoParser.java#L2158-L2171
FunctionTypeExprModifier = modifierThis:("this" _ ":" _ FunctionTypeExprParamOperand) {
return { nodeThis: modifierThis[4], nodeNew: null };
}
/ modifierNew:("new" _ ":" _ FunctionTypeExprParamOperand) {
return { nodeThis: null, nodeNew: modifierNew[4] };
}
FunctionTypeExprParams = paramsWithComma:(FunctionTypeExprParamOperand _ "," _)*
// Variadic type is only allowed on the last parameter.
lastParam:(VariadicTypeExpr / VariadicTypeExprOperand)? {
return paramsWithComma.reduceRight(function(params, tokens) {
const [param] = tokens;
return [param].concat(params);
}, lastParam ? [lastParam] : []);
}
FunctionTypeExprParamOperand = UnionTypeExpr
/ IntersectionTypeExpr // no-jsdoc, no-closure
/ TypeQueryExpr // no-jsdoc
/ KeyQueryExpr // no-jsdoc, no-closure
/ UnaryUnionTypeExpr
/ RecordTypeExpr
/ TupleTypeExpr // no-jsdoc, no-closure
/ ArrowTypeExpr // no-jsdoc, no-closure
/ FunctionTypeExpr
/ ParenthesizedExpr
/ ArrayTypeExpr // no-closure
/ GenericTypeExpr
/ BroadNamepathExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr
FunctionTypeExprReturnableOperand = PrefixUnaryUnionTypeExpr
// Suffix unary union type operators should not be
// placed here to keep operator precedence. For example,
// "Foo|function():Returned=" should be parsed as
// "(Foo|function():Returned)=" instead of
// "Foo|(function():Returned=)". This result was expected
// by Closure Library.
//
// See https://github.com/google/closure-library/blob/
// 47f9c92bb4c7de9a3d46f9921a427402910073fb/
// closure/goog/ui/zippy.js#L47
/ RecordTypeExpr
/ TupleTypeExpr // no-jsdoc, no-closure
/ ArrowTypeExpr // no-jsdoc, no-closure
/ FunctionTypeExpr
/ ParenthesizedExpr
/ ArrayTypeExpr // no-closure
/ TypeQueryExpr // no-jsdoc
/ KeyQueryExpr // no-jsdoc, no-closure
/ GenericTypeExpr
/ BroadNamepathExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr
/*
* Record type expressions.
*
* Examples:
* - {}
* - {length}
* - {length:number}
* - {toString:Function,valueOf:Function}
* - {'foo':*}
* - {a:string,b?:number} // TypeScript syntax
*
* Spec:
* - https://developers.google.com/closure/compiler/docs/js-for-compiler#types
* - https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html#patterns-that-are-known-not-to-be-supported
*/
RecordTypeExpr = "{" _ entries:RecordTypeExprEntries? _ "}" {
return {
type: NodeType.RECORD,
entries: entries || [],
};
}
RecordTypeExprEntries = first:RecordTypeExprEntry restWithComma:((_ "," /_ ";" / [ \t]* [\r]? [\n]) _ RecordTypeExprEntry)* (_ "," / _ ";" / [ \t]* [\r]? [\n])? {
return restWithComma.reduce(function(entries, tokens) {
const entry = tokens[2];
return entries.concat([entry]);
}, [first]);
}
RecordTypeExprEntry = readonly:("readonly" __)? keyInfo:RecordTypeExprEntryKey _
optional:"?"?
_ ":" _ value:RecordTypeExprEntryOperand {
const {quoteStyle, key} = keyInfo;
return {
type: NodeType.RECORD_ENTRY,
key,
quoteStyle,
value:
optional === '?' ? {
type: NodeType.OPTIONAL,
value,
meta: { syntax: OptionalTypeSyntax.SUFFIX_KEY_QUESTION_MARK },
} :
value,
readonly: Boolean(readonly)
};
}
/ readonly:("readonly" __)? keyInfo:RecordTypeExprEntryKey {
const {quoteStyle, key} = keyInfo;
return {
type: NodeType.RECORD_ENTRY,
key,
quoteStyle,
value: null,
readonly: Boolean(readonly)
};
}
RecordTypeExprEntryKey = '"' key:$([^\\"] / "\\".)* '"' {
return {
quoteStyle: 'double',
key: key.replace(/\\"/gu, '"')
.replace(/\\\\/gu, '\\')
};
}
/ "'" key:$([^\\'] / "\\".)* "'" {
return {
quoteStyle: 'single',
key: key.replace(/\\'/g, "'")
.replace(/\\\\/gu, '\\')
};
}
/ key:$(JsIdentifier / UnsignedDecimalNumberLiteralExpr) {
return {
quoteStyle: 'none',
key
};
}
RecordTypeExprEntryOperand = UnionTypeExpr
/ IntersectionTypeExpr // no-jsdoc, no-closure
/ UnaryUnionTypeExpr
/ RecordTypeExpr
/ TupleTypeExpr // no-jsdoc, no-closure
/ ArrowTypeExpr // no-jsdoc, no-closure
/ FunctionTypeExpr
/ ParenthesizedExpr
/ ArrayTypeExpr // no-closure
/ GenericTypeExpr
/ BroadNamepathExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr
// no-jsdoc-begin, no-closure-begin
/**
* TypeScript style tuple type.
*
* Examples:
* - []
* - [string]
* - [number]
* - [string, number]
*
* Spec:
* - https://www.typescriptlang.org/docs/handbook/basic-types.html#tuple
*/
TupleTypeExpr = "[" _ entries:TupleTypeExprEntries _ "]" {
return {
type: NodeType.TUPLE,
entries,
}
}
TupleTypeExprEntries = restWithComma:(TupleTypeExprOperand _ "," _)*
// Variadic type is only allowed on the last entry.
last:(VariadicTypeExpr / VariadicTypeExprOperand)? {
return restWithComma.reduceRight((entries, tokens) => {
let [entry] = tokens;
return [entry].concat(entries);
}, last ? [last] : []);
}
TupleTypeExprOperand = UnionTypeExpr
/ IntersectionTypeExpr // no-jsdoc, no-closure
/ UnaryUnionTypeExpr
/ RecordTypeExpr
/ TupleTypeExpr // no-jsdoc, no-closure
/ ArrowTypeExpr // no-jsdoc, no-closure
/ FunctionTypeExpr
/ ParenthesizedExpr
/ TypeQueryExpr // no-jsdoc
/ KeyQueryExpr // no-jsdoc, no-closure
/ ArrayTypeExpr // no-closure
/ GenericTypeExpr
/ BroadNamepathExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr
// no-jsdoc-end, no-closure-end
/*
* Parenthesis expressions.
*
* Examples:
* - (Foo|Bar)
* - (module: path/to/file).Module
*
* Spec:
* - https://developers.google.com/closure/compiler/docs/js-for-compiler#types
*/
ParenthesizedExpr = "(" _ wrapped:ParenthesizedExprOperand _ ")" {
return {
type: NodeType.PARENTHESIS,
value: wrapped,
};
}
ParenthesizedExprOperand = UnionTypeExpr
/ IntersectionTypeExpr // no-jsdoc, no-closure
/ UnaryUnionTypeExpr
/ RecordTypeExpr
/ TupleTypeExpr // no-jsdoc, no-closure
/ ArrowTypeExpr // no-jsdoc, no-closure
/ FunctionTypeExpr
/ ArrayTypeExpr // no-closure
/ TypeQueryExpr // no-jsdoc
/ KeyQueryExpr // no-jsdoc, no-closure
/ GenericTypeExpr
/ BroadNamepathExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr
/*
* Variadic type expressions.
*
* Examples:
* - ...string (only allow on the top level or the last function parameter)
* - string... (only allow on the top level)
* - ...
*
* Note:
* It seems that we can omit the operand.
* See https://github.com/google/closure-library/blob/
* 47f9c92bb4c7de9a3d46f9921a427402910073fb/
* closure/goog/base.js#L1847
*
* Spec:
* - https://developers.google.com/closure/compiler/docs/js-for-compiler#types
*/
VariadicTypeExpr = PrefixVariadicTypeExpr
/ SuffixVariadicTypeExpr
/ AnyVariadicTypeExpr
PrefixVariadicTypeExpr = "..." operand:VariadicTypeExprOperand {
return {
type: NodeType.VARIADIC,
value: operand,
meta: { syntax: VariadicTypeSyntax.PREFIX_DOTS },
};
}
SuffixVariadicTypeExpr = operand:VariadicTypeExprOperand "..." {
return {
type: NodeType.VARIADIC,
value: operand,
meta: { syntax: VariadicTypeSyntax.SUFFIX_DOTS },
};
}
AnyVariadicTypeExpr = "..." {
return {
type: NodeType.VARIADIC,
value: { type: NodeType.ANY },
meta: { syntax: VariadicTypeSyntax.ONLY_DOTS },
};
}
VariadicTypeExprOperand = UnionTypeExpr
/ IntersectionTypeExpr // no-jsdoc, no-closure
/ UnaryUnionTypeExpr
/ RecordTypeExpr
/ TupleTypeExpr // no-jsdoc, no-closure
/ ArrowTypeExpr // no-jsdoc, no-closure
/ FunctionTypeExpr
/ ParenthesizedExpr
/ TypeQueryExpr // no-jsdoc
/ KeyQueryExpr // no-jsdoc, no-closure
/ ArrayTypeExpr // no-closure
/ GenericTypeExpr
/ BroadNamepathExpr
/ ValueExpr
/ AnyTypeExpr
/ UnknownTypeExpr