Skip to content

Fix 'new' parsing & allow omitting parenthesis #966

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 31 additions & 29 deletions src/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,29 +114,6 @@ export function nodeIsConstantValue(kind: NodeKind): bool {
return false;
}

/** Checks if a node might be callable. */
export function nodeIsCallable(kind: NodeKind): bool {
switch (kind) {
case NodeKind.IDENTIFIER:
case NodeKind.ASSERTION: // if kind=NONNULL
case NodeKind.CALL:
case NodeKind.ELEMENTACCESS:
case NodeKind.PARENTHESIZED:
case NodeKind.PROPERTYACCESS:
case NodeKind.SUPER: return true;
}
return false;
}

/** Checks if a node might be callable with generic arguments. */
export function nodeIsGenericCallable(kind: NodeKind): bool {
switch (kind) {
case NodeKind.IDENTIFIER:
case NodeKind.PROPERTYACCESS: return true;
}
return false;
}

/** Base class of all nodes. */
export abstract class Node {

Expand Down Expand Up @@ -428,14 +405,14 @@ export abstract class Node {
}

static createNewExpression(
expression: Expression,
typeName: TypeName,
typeArgs: TypeNode[] | null,
args: Expression[],
range: Range
): NewExpression {
var expr = new NewExpression();
expr.range = range;
expr.expression = expression;
expr.typeName = typeName;
expr.typeArguments = typeArgs;
expr.arguments = args;
return expr;
Expand Down Expand Up @@ -1489,8 +1466,35 @@ export class IntegerLiteralExpression extends LiteralExpression {
}

/** Represents a `new` expression. Like a call but with its own kind. */
export class NewExpression extends CallExpression {
export class NewExpression extends Expression {
kind = NodeKind.NEW;

/** Type being constructed. */
typeName: TypeName;
/** Provided type arguments. */
typeArguments: TypeNode[] | null;
/** Provided arguments. */
arguments: Expression[];

/** Gets the type arguments range for reporting. */
get typeArgumentsRange(): Range {
var typeArguments = this.typeArguments;
var numTypeArguments: i32;
if (typeArguments && (numTypeArguments = typeArguments.length)) {
return Range.join(typeArguments[0].range, typeArguments[numTypeArguments - 1].range);
}
return this.typeName.range;
}

/** Gets the arguments range for reporting. */
get argumentsRange(): Range {
var args = this.arguments;
var numArguments = args.length;
if (numArguments) {
return Range.join(args[0].range, args[numArguments - 1].range);
}
return this.typeName.range;
}
}

/** Represents a `null` expression. */
Expand Down Expand Up @@ -1639,12 +1643,10 @@ export class Source extends Node {
statements: Statement[];
/** Full source text. */
text: string;
/** Tokenizer reference. */
tokenizer: Tokenizer | null = null;
/** Source map index. */
debugInfoIndex: i32 = -1;
/** Re-exported sources. */
exportPaths: Set<string> | null = null;
exportPaths: string[] | null = null;

/** Constructs a new source node. */
constructor(normalizedPath: string, text: string, kind: SourceKind) {
Expand Down
7 changes: 2 additions & 5 deletions src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7726,15 +7726,12 @@ export class Compiler extends DiagnosticEmitter {
var flow = this.currentFlow;

// obtain the class being instantiated
var target = this.resolver.lookupExpression( // reports
expression.expression,
flow
);
var target = this.resolver.resolveTypeName(expression.typeName, flow.actualFunction);
if (!target) return module.unreachable();
if (target.kind != ElementKind.CLASS_PROTOTYPE) {
this.error(
DiagnosticCode.This_expression_is_not_constructable,
expression.expression.range
expression.typeName.range
);
return this.module.unreachable();
}
Expand Down
11 changes: 7 additions & 4 deletions src/extra/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,12 @@ export class ASTBuilder {
}

visitCallExpression(node: CallExpression): void {
var sb = this.sb;
this.visitNode(node.expression);
var typeArguments = node.typeArguments;
this.visitArguments(node.typeArguments, node.arguments);
}

private visitArguments(typeArguments: TypeNode[] | null, args: Expression[]): void {
var sb = this.sb;
if (typeArguments) {
let numTypeArguments = typeArguments.length;
if (numTypeArguments) {
Expand All @@ -560,7 +563,6 @@ export class ASTBuilder {
} else {
sb.push("(");
}
var args = node.arguments;
var numArgs = args.length;
if (numArgs) {
this.visitNode(args[0]);
Expand Down Expand Up @@ -757,7 +759,8 @@ export class ASTBuilder {

visitNewExpression(node: NewExpression): void {
this.sb.push("new ");
this.visitCallExpression(node);
this.visitTypeName(node.typeName);
this.visitArguments(node.typeArguments, node.arguments);
}

visitParenthesizedExpression(node: ParenthesizedExpression): void {
Expand Down
Loading