Skip to content

Commit 92a768f

Browse files
authored
Fix 'new' parsing & allow omitting parenthesis (#966)
1 parent ec12908 commit 92a768f

File tree

9 files changed

+694
-217
lines changed

9 files changed

+694
-217
lines changed

src/ast.ts

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -114,29 +114,6 @@ export function nodeIsConstantValue(kind: NodeKind): bool {
114114
return false;
115115
}
116116

117-
/** Checks if a node might be callable. */
118-
export function nodeIsCallable(kind: NodeKind): bool {
119-
switch (kind) {
120-
case NodeKind.IDENTIFIER:
121-
case NodeKind.ASSERTION: // if kind=NONNULL
122-
case NodeKind.CALL:
123-
case NodeKind.ELEMENTACCESS:
124-
case NodeKind.PARENTHESIZED:
125-
case NodeKind.PROPERTYACCESS:
126-
case NodeKind.SUPER: return true;
127-
}
128-
return false;
129-
}
130-
131-
/** Checks if a node might be callable with generic arguments. */
132-
export function nodeIsGenericCallable(kind: NodeKind): bool {
133-
switch (kind) {
134-
case NodeKind.IDENTIFIER:
135-
case NodeKind.PROPERTYACCESS: return true;
136-
}
137-
return false;
138-
}
139-
140117
/** Base class of all nodes. */
141118
export abstract class Node {
142119

@@ -428,14 +405,14 @@ export abstract class Node {
428405
}
429406

430407
static createNewExpression(
431-
expression: Expression,
408+
typeName: TypeName,
432409
typeArgs: TypeNode[] | null,
433410
args: Expression[],
434411
range: Range
435412
): NewExpression {
436413
var expr = new NewExpression();
437414
expr.range = range;
438-
expr.expression = expression;
415+
expr.typeName = typeName;
439416
expr.typeArguments = typeArgs;
440417
expr.arguments = args;
441418
return expr;
@@ -1489,8 +1466,35 @@ export class IntegerLiteralExpression extends LiteralExpression {
14891466
}
14901467

14911468
/** Represents a `new` expression. Like a call but with its own kind. */
1492-
export class NewExpression extends CallExpression {
1469+
export class NewExpression extends Expression {
14931470
kind = NodeKind.NEW;
1471+
1472+
/** Type being constructed. */
1473+
typeName: TypeName;
1474+
/** Provided type arguments. */
1475+
typeArguments: TypeNode[] | null;
1476+
/** Provided arguments. */
1477+
arguments: Expression[];
1478+
1479+
/** Gets the type arguments range for reporting. */
1480+
get typeArgumentsRange(): Range {
1481+
var typeArguments = this.typeArguments;
1482+
var numTypeArguments: i32;
1483+
if (typeArguments && (numTypeArguments = typeArguments.length)) {
1484+
return Range.join(typeArguments[0].range, typeArguments[numTypeArguments - 1].range);
1485+
}
1486+
return this.typeName.range;
1487+
}
1488+
1489+
/** Gets the arguments range for reporting. */
1490+
get argumentsRange(): Range {
1491+
var args = this.arguments;
1492+
var numArguments = args.length;
1493+
if (numArguments) {
1494+
return Range.join(args[0].range, args[numArguments - 1].range);
1495+
}
1496+
return this.typeName.range;
1497+
}
14941498
}
14951499

14961500
/** Represents a `null` expression. */
@@ -1639,12 +1643,10 @@ export class Source extends Node {
16391643
statements: Statement[];
16401644
/** Full source text. */
16411645
text: string;
1642-
/** Tokenizer reference. */
1643-
tokenizer: Tokenizer | null = null;
16441646
/** Source map index. */
16451647
debugInfoIndex: i32 = -1;
16461648
/** Re-exported sources. */
1647-
exportPaths: Set<string> | null = null;
1649+
exportPaths: string[] | null = null;
16481650

16491651
/** Constructs a new source node. */
16501652
constructor(normalizedPath: string, text: string, kind: SourceKind) {

src/compiler.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7726,15 +7726,12 @@ export class Compiler extends DiagnosticEmitter {
77267726
var flow = this.currentFlow;
77277727

77287728
// obtain the class being instantiated
7729-
var target = this.resolver.lookupExpression( // reports
7730-
expression.expression,
7731-
flow
7732-
);
7729+
var target = this.resolver.resolveTypeName(expression.typeName, flow.actualFunction);
77337730
if (!target) return module.unreachable();
77347731
if (target.kind != ElementKind.CLASS_PROTOTYPE) {
77357732
this.error(
77367733
DiagnosticCode.This_expression_is_not_constructable,
7737-
expression.expression.range
7734+
expression.typeName.range
77387735
);
77397736
return this.module.unreachable();
77407737
}

src/extra/ast.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -543,9 +543,12 @@ export class ASTBuilder {
543543
}
544544

545545
visitCallExpression(node: CallExpression): void {
546-
var sb = this.sb;
547546
this.visitNode(node.expression);
548-
var typeArguments = node.typeArguments;
547+
this.visitArguments(node.typeArguments, node.arguments);
548+
}
549+
550+
private visitArguments(typeArguments: TypeNode[] | null, args: Expression[]): void {
551+
var sb = this.sb;
549552
if (typeArguments) {
550553
let numTypeArguments = typeArguments.length;
551554
if (numTypeArguments) {
@@ -560,7 +563,6 @@ export class ASTBuilder {
560563
} else {
561564
sb.push("(");
562565
}
563-
var args = node.arguments;
564566
var numArgs = args.length;
565567
if (numArgs) {
566568
this.visitNode(args[0]);
@@ -757,7 +759,8 @@ export class ASTBuilder {
757759

758760
visitNewExpression(node: NewExpression): void {
759761
this.sb.push("new ");
760-
this.visitCallExpression(node);
762+
this.visitTypeName(node.typeName);
763+
this.visitArguments(node.typeArguments, node.arguments);
761764
}
762765

763766
visitParenthesizedExpression(node: ParenthesizedExpression): void {

0 commit comments

Comments
 (0)