Use lazy initializations for decorators and type parameters in parser (#554)

This commit is contained in:
Max Graey 2019-03-22 13:20:19 +02:00 committed by Daniel Wirtz
parent 858cca5a38
commit f9a8d2f1db

View File

@ -164,8 +164,8 @@ export class Parser extends DiagnosticEmitter {
this.skipStatement(tn); this.skipStatement(tn);
continue; continue;
} }
if (!decorators) decorators = []; if (!decorators) decorators = [decorator];
decorators.push(decorator); else decorators.push(decorator);
} }
// check modifiers // check modifiers
@ -454,7 +454,7 @@ export class Parser extends DiagnosticEmitter {
} else if (token == Token.IDENTIFIER) { } else if (token == Token.IDENTIFIER) {
let first = Node.createSimpleTypeName(tn.readIdentifier(), tn.range()); let first = Node.createSimpleTypeName(tn.readIdentifier(), tn.range());
let current = first; let current = first;
let parameters = new Array<TypeNode>(); let parameters: TypeNode[] | null = null;
let nullable = false; let nullable = false;
// Identifier ('.' Identifier)+ // Identifier ('.' Identifier)+
@ -477,7 +477,8 @@ export class Parser extends DiagnosticEmitter {
do { do {
let parameter = this.parseType(tn, true, suppressErrors); let parameter = this.parseType(tn, true, suppressErrors);
if (!parameter) return null; if (!parameter) return null;
parameters.push(<TypeNode>parameter); if (!parameters) parameters = [<TypeNode>parameter];
else parameters.push(<TypeNode>parameter);
} while (tn.skip(Token.COMMA)); } while (tn.skip(Token.COMMA));
if (!tn.skip(Token.GREATERTHAN)) { if (!tn.skip(Token.GREATERTHAN)) {
if (!suppressErrors) { if (!suppressErrors) {
@ -503,8 +504,7 @@ export class Parser extends DiagnosticEmitter {
return null; return null;
} }
} }
type = Node.createType(first, parameters, nullable, tn.range(startPos, tn.pos)); type = Node.createType(first, parameters || [], nullable, tn.range(startPos, tn.pos));
} else { } else {
if (!suppressErrors) { if (!suppressErrors) {
this.error( this.error(
@ -939,7 +939,7 @@ export class Parser extends DiagnosticEmitter {
// at '<': TypeParameter (',' TypeParameter)* '>' // at '<': TypeParameter (',' TypeParameter)* '>'
var typeParameters = new Array<TypeParameterNode>(); var typeParameters: TypeParameterNode[] | null = null;
var seenOptional = false; var seenOptional = false;
while (!tn.skip(Token.GREATERTHAN)) { while (!tn.skip(Token.GREATERTHAN)) {
let typeParameter = this.parseTypeParameter(tn); let typeParameter = this.parseTypeParameter(tn);
@ -953,7 +953,8 @@ export class Parser extends DiagnosticEmitter {
); );
typeParameter.defaultType = null; typeParameter.defaultType = null;
} }
typeParameters.push(<TypeParameterNode>typeParameter); if (!typeParameters) typeParameters = [ typeParameter ];
else typeParameters.push(typeParameter);
if (!tn.skip(Token.COMMA)) { if (!tn.skip(Token.COMMA)) {
if (tn.skip(Token.GREATERTHAN)) { if (tn.skip(Token.GREATERTHAN)) {
break; break;
@ -966,7 +967,7 @@ export class Parser extends DiagnosticEmitter {
} }
} }
} }
if (typeParameters.length === 0) { if (!(typeParameters && typeParameters.length)) {
this.error( this.error(
DiagnosticCode.Type_parameter_list_cannot_be_empty, DiagnosticCode.Type_parameter_list_cannot_be_empty,
tn.range() tn.range()
@ -1532,8 +1533,8 @@ export class Parser extends DiagnosticEmitter {
let type = this.parseType(tn); let type = this.parseType(tn);
if (!type) return null; if (!type) return null;
if (!isInterface) { if (!isInterface) {
if (!implementsTypes) implementsTypes = []; if (!implementsTypes) implementsTypes = [<TypeNode>type];
implementsTypes.push(<TypeNode>type); else implementsTypes.push(<TypeNode>type);
} }
} while (tn.skip(Token.COMMA)); } while (tn.skip(Token.COMMA));
} }
@ -1636,14 +1637,15 @@ export class Parser extends DiagnosticEmitter {
var startPos = tn.pos; var startPos = tn.pos;
var isInterface = parent.kind == NodeKind.INTERFACEDECLARATION; var isInterface = parent.kind == NodeKind.INTERFACEDECLARATION;
var decorators = new Array<DecoratorNode>(); var decorators: DecoratorNode[] | null = null;
if (tn.skip(Token.AT)) { if (tn.skip(Token.AT)) {
do { do {
let decorator = this.parseDecorator(tn); let decorator = this.parseDecorator(tn);
if (!decorator) break; if (!decorator) break;
decorators.push(<DecoratorNode>decorator); if (!decorators) decorators = [<DecoratorNode>decorator];
else decorators.push(<DecoratorNode>decorator);
} while (tn.skip(Token.AT)); } while (tn.skip(Token.AT));
if (isInterface) { if (decorators && isInterface) {
this.error( this.error(
DiagnosticCode.Decorators_are_not_valid_here, DiagnosticCode.Decorators_are_not_valid_here,
Range.join(decorators[0].range, decorators[decorators.length - 1].range) Range.join(decorators[0].range, decorators[decorators.length - 1].range)
@ -2064,11 +2066,11 @@ export class Parser extends DiagnosticEmitter {
return null; return null;
} }
parseIndexSignatureDeclaration(tn: Tokenizer, decorators: DecoratorNode[]): IndexSignatureDeclaration | null { parseIndexSignatureDeclaration(tn: Tokenizer, decorators: DecoratorNode[] | null): IndexSignatureDeclaration | null {
// at: '[': 'key' ':' Type ']' ':' Type // at: '[': 'key' ':' Type ']' ':' Type
if (decorators.length) { if (decorators && decorators.length) {
this.error( this.error(
DiagnosticCode.Decorators_are_not_valid_here, DiagnosticCode.Decorators_are_not_valid_here,
Range.join(decorators[0].range, decorators[decorators.length - 1].range) Range.join(decorators[0].range, decorators[decorators.length - 1].range)
@ -3410,7 +3412,7 @@ export class Parser extends DiagnosticEmitter {
var state = tn.mark(); var state = tn.mark();
if (!tn.skip(Token.LESSTHAN)) return null; if (!tn.skip(Token.LESSTHAN)) return null;
var typeArguments = new Array<CommonTypeNode>(); var typeArguments: CommonTypeNode[] | null = null;
do { do {
if (tn.peek() === Token.GREATERTHAN) { if (tn.peek() === Token.GREATERTHAN) {
break; break;
@ -3420,7 +3422,8 @@ export class Parser extends DiagnosticEmitter {
tn.reset(state); tn.reset(state);
return null; return null;
} }
typeArguments.push(type); if (!typeArguments) typeArguments = [ type ];
else typeArguments.push(type);
} while (tn.skip(Token.COMMA)); } while (tn.skip(Token.COMMA));
if (tn.skip(Token.GREATERTHAN) && tn.skip(Token.OPENPAREN)) { if (tn.skip(Token.GREATERTHAN) && tn.skip(Token.OPENPAREN)) {
return typeArguments; return typeArguments;