diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2088fa8761e..8dcc7fc8961 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9244,7 +9244,7 @@ namespace ts { } function findFirstSuperCall(n: Node): Node { - if (isSuperCallExpression(n)) { + if (isSuperCall(n)) { return n; } else if (isFunctionLike(n)) { @@ -14407,7 +14407,7 @@ namespace ts { } function containsSuperCall(n: Node): boolean { - if (isSuperCallExpression(n)) { + if (isSuperCall(n)) { return true; } else if (isFunctionLike(n)) { @@ -14463,7 +14463,7 @@ namespace ts { let superCallStatement: ExpressionStatement; for (const statement of statements) { - if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((statement).expression)) { + if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((statement).expression)) { superCallStatement = statement; break; } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index b9a87e05457..97a36f46b13 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -105,6 +105,7 @@ namespace ts { export function createLiteral(textSource: StringLiteral | Identifier, location?: TextRange): StringLiteral; export function createLiteral(value: string, location?: TextRange): StringLiteral; export function createLiteral(value: number, location?: TextRange): NumericLiteral; + export function createLiteral(value: boolean, location?: TextRange): BooleanLiteral; export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression; export function createLiteral(value: string | number | boolean | StringLiteral | Identifier, location?: TextRange): PrimaryExpression { if (typeof value === "number") { @@ -120,7 +121,7 @@ namespace ts { node.text = value; return node; } - else { + else if (value) { const node = createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined); node.textSourceNode = value; node.text = value.text; @@ -497,14 +498,14 @@ namespace ts { return node; } - export function createTaggedTemplate(tag: Expression, template: Template, location?: TextRange) { + export function createTaggedTemplate(tag: Expression, template: TemplateLiteral, location?: TextRange) { const node = createNode(SyntaxKind.TaggedTemplateExpression, location); node.tag = parenthesizeForAccess(tag); node.template = template; return node; } - export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: Template) { + export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral) { if (node.tag !== tag || node.template !== template) { return updateNode(createTaggedTemplate(tag, template, node), node); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1d52ec9f648..2675f752752 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3930,7 +3930,7 @@ namespace ts { const tagExpression = createNode(SyntaxKind.TaggedTemplateExpression, expression.pos); tagExpression.tag = expression; tagExpression.template = token() === SyntaxKind.NoSubstitutionTemplateLiteral - ? parseLiteralNode() + ? parseLiteralNode() : parseTemplateExpression(); expression = finishNode(tagExpression); continue; diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index d8bf9ffa0f9..2f2beafbfdf 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -982,7 +982,7 @@ namespace ts { if (statementOffset < ctorStatements.length) { firstStatement = ctorStatements[statementOffset]; - if (firstStatement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((firstStatement as ExpressionStatement).expression)) { + if (firstStatement.kind === SyntaxKind.ExpressionStatement && isSuperCall((firstStatement as ExpressionStatement).expression)) { const superCall = (firstStatement as ExpressionStatement).expression as CallExpression; superCallExpression = setOriginalNode( saveStateAndInvoke(superCall, visitImmediateSuperCallInBody), diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 6d20f4b1e30..3b10f90e76a 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -657,12 +657,12 @@ namespace ts { } } - function isCompoundAssignment(kind: SyntaxKind) { + function isCompoundAssignment(kind: BinaryOperator): kind is CompoundAssignmentOperator { return kind >= SyntaxKind.FirstCompoundAssignment && kind <= SyntaxKind.LastCompoundAssignment; } - function getOperatorForCompoundAssignment(kind: SyntaxKind) { + function getOperatorForCompoundAssignment(kind: CompoundAssignmentOperator): BitwiseOperatorOrHigher { switch (kind) { case SyntaxKind.PlusEqualsToken: return SyntaxKind.PlusToken; case SyntaxKind.MinusEqualsToken: return SyntaxKind.MinusToken; diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 2b757619365..29f2d743172 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -989,7 +989,7 @@ namespace ts { } const statement = statements[index]; - if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((statement).expression)) { + if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((statement).expression)) { result.push(visitNode(statement, visitor, isStatement)); return index + 1; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 224c26a7263..d5ba0249317 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -523,7 +523,8 @@ namespace ts { | Token | Token | Token - | Token; + | Token + ; export type ModifiersArray = NodeArray; @@ -909,13 +910,16 @@ namespace ts { _incrementExpressionBrand: any; } + // see: https://tc39.github.io/ecma262/#prod-UpdateExpression + // see: https://tc39.github.io/ecma262/#prod-UnaryExpression export type PrefixUnaryOperator = SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken - | SyntaxKind.ExclamationToken; + | SyntaxKind.ExclamationToken + ; export interface PrefixUnaryExpression extends IncrementExpression { kind: SyntaxKind.PrefixUnaryExpression; @@ -923,9 +927,11 @@ namespace ts { operand: UnaryExpression; } + // see: https://tc39.github.io/ecma262/#prod-UpdateExpression export type PostfixUnaryOperator = SyntaxKind.PlusPlusToken - | SyntaxKind.MinusMinusToken; + | SyntaxKind.MinusMinusToken + ; export interface PostfixUnaryExpression extends IncrementExpression { kind: SyntaxKind.PostfixUnaryExpression; @@ -949,12 +955,20 @@ namespace ts { _primaryExpressionBrand: any; } - export interface KeywordExpression extends PrimaryExpression { - kind: SyntaxKind.TrueKeyword - | SyntaxKind.FalseKeyword - | SyntaxKind.NullKeyword - | SyntaxKind.ThisKeyword - | SyntaxKind.SuperKeyword; + export interface NullLiteral extends PrimaryExpression { + kind: SyntaxKind.NullKeyword; + } + + export interface BooleanLiteral extends PrimaryExpression { + kind: SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword; + } + + export interface ThisExpression extends PrimaryExpression { + kind: SyntaxKind.ThisKeyword; + } + + export interface SuperExpression extends PrimaryExpression { + kind: SyntaxKind.SuperKeyword; } export interface DeleteExpression extends UnaryExpression { @@ -983,45 +997,142 @@ namespace ts { expression?: Expression; } - export type BinaryOperator - = SyntaxKind.PlusToken - | SyntaxKind.PlusEqualsToken - | SyntaxKind.MinusToken - | SyntaxKind.MinusEqualsToken - | SyntaxKind.AsteriskToken - | SyntaxKind.AsteriskAsteriskToken - | SyntaxKind.AsteriskAsteriskEqualsToken - | SyntaxKind.AsteriskEqualsToken + // see: https://tc39.github.io/ecma262/#prod-ExponentiationExpression + export type ExponentiationOperator + = SyntaxKind.AsteriskAsteriskToken + ; + + // see: https://tc39.github.io/ecma262/#prod-MultiplicativeOperator + export type MultiplicativeOperator + = SyntaxKind.AsteriskToken | SyntaxKind.SlashToken - | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentToken - | SyntaxKind.PercentEqualsToken - | SyntaxKind.AmpersandToken - | SyntaxKind.AmpersandAmpersandToken - | SyntaxKind.AmpersandEqualsToken - | SyntaxKind.BarToken - | SyntaxKind.BarBarToken - | SyntaxKind.BarEqualsToken - | SyntaxKind.CaretToken - | SyntaxKind.CaretEqualsToken - | SyntaxKind.LessThanToken - | SyntaxKind.LessThanLessThanToken - | SyntaxKind.LessThanLessThanEqualsToken - | SyntaxKind.LessThanEqualsToken - | SyntaxKind.GreaterThanToken + ; + + // see: https://tc39.github.io/ecma262/#prod-MultiplicativeExpression + export type MultiplicativeOperatorOrHigher + = ExponentiationOperator + | MultiplicativeOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-AdditiveExpression + export type AdditiveOperator + = SyntaxKind.PlusToken + | SyntaxKind.MinusToken + ; + + // see: https://tc39.github.io/ecma262/#prod-AdditiveExpression + export type AdditiveOperatorOrHigher + = MultiplicativeOperatorOrHigher + | AdditiveOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-ShiftExpression + export type ShiftOperator + = SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken - | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken - | SyntaxKind.GreaterThanGreaterThanEqualsToken + ; + + // see: https://tc39.github.io/ecma262/#prod-ShiftExpression + export type ShiftOperatorOrHigher + = AdditiveOperatorOrHigher + | ShiftOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-RelationalExpression + export type RelationalOperator + = SyntaxKind.LessThanToken + | SyntaxKind.LessThanEqualsToken + | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken - | SyntaxKind.EqualsToken - | SyntaxKind.EqualsEqualsToken + | SyntaxKind.InstanceOfKeyword + | SyntaxKind.InKeyword + ; + + // see: https://tc39.github.io/ecma262/#prod-RelationalExpression + export type RelationalOperatorOrHigher + = ShiftOperatorOrHigher + | RelationalOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-EqualityExpression + export type EqualityOperator + = SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken - | SyntaxKind.InstanceOfKeyword - | SyntaxKind.InKeyword - | SyntaxKind.CommaToken; + ; + + // see: https://tc39.github.io/ecma262/#prod-EqualityExpression + export type EqualityOperatorOrHigher + = RelationalOperatorOrHigher + | EqualityOperator; + + // see: https://tc39.github.io/ecma262/#prod-BitwiseANDExpression + // see: https://tc39.github.io/ecma262/#prod-BitwiseXORExpression + // see: https://tc39.github.io/ecma262/#prod-BitwiseORExpression + export type BitwiseOperator + = SyntaxKind.AmpersandToken + | SyntaxKind.BarToken + | SyntaxKind.CaretToken + ; + + // see: https://tc39.github.io/ecma262/#prod-BitwiseANDExpression + // see: https://tc39.github.io/ecma262/#prod-BitwiseXORExpression + // see: https://tc39.github.io/ecma262/#prod-BitwiseORExpression + export type BitwiseOperatorOrHigher + = EqualityOperatorOrHigher + | BitwiseOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-LogicalANDExpression + // see: https://tc39.github.io/ecma262/#prod-LogicalORExpression + export type LogicalOperator + = SyntaxKind.AmpersandAmpersandToken + | SyntaxKind.BarBarToken + ; + + // see: https://tc39.github.io/ecma262/#prod-LogicalANDExpression + // see: https://tc39.github.io/ecma262/#prod-LogicalORExpression + export type LogicalOperatorOrHigher + = BitwiseOperatorOrHigher + | LogicalOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-AssignmentOperator + export type CompoundAssignmentOperator + = SyntaxKind.PlusEqualsToken + | SyntaxKind.MinusEqualsToken + | SyntaxKind.AsteriskAsteriskEqualsToken + | SyntaxKind.AsteriskEqualsToken + | SyntaxKind.SlashEqualsToken + | SyntaxKind.PercentEqualsToken + | SyntaxKind.AmpersandEqualsToken + | SyntaxKind.BarEqualsToken + | SyntaxKind.CaretEqualsToken + | SyntaxKind.LessThanLessThanEqualsToken + | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken + | SyntaxKind.GreaterThanGreaterThanEqualsToken + ; + + // see: https://tc39.github.io/ecma262/#prod-AssignmentExpression + export type AssignmentOperator + = SyntaxKind.EqualsToken + | CompoundAssignmentOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-AssignmentExpression + export type AssignmentOperatorOrHigher + = LogicalOperatorOrHigher + | AssignmentOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-Expression + export type BinaryOperator + = AssignmentOperatorOrHigher + | SyntaxKind.CommaToken + ; export type BinaryOperatorToken = Token; @@ -1057,6 +1168,9 @@ namespace ts { body: ConciseBody; } + // The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral, + // or any literal of a template, this means quotes have been removed and escapes have been converted to actual characters. + // For a NumericLiteral, the stored value is the toString() representation of the number. For example 1, 1.00, and 1e0 are all stored as just "1". export interface LiteralLikeNode extends Node { text: string; isUnterminated?: boolean; @@ -1097,7 +1211,7 @@ namespace ts { kind: SyntaxKind.TemplateTail; } - export type Template = TemplateExpression | LiteralExpression; + export type TemplateLiteral = TemplateExpression | NoSubstitutionTemplateLiteral; export interface TemplateExpression extends PrimaryExpression { kind: SyntaxKind.TemplateExpression; @@ -1156,6 +1270,10 @@ namespace ts { name: Identifier; } + export interface SuperPropertyAccessExpression extends PropertyAccessExpression { + expression: SuperExpression; + } + /** Brand for a PropertyAccessExpression which, like a QualifiedName, consists of a sequence of identifiers separated by dots. */ export interface PropertyAccessEntityNameExpression extends PropertyAccessExpression { _propertyAccessExpressionLikeQualifiedNameBrand?: any; @@ -1168,6 +1286,16 @@ namespace ts { argumentExpression?: Expression; } + export interface SuperElementAccessExpression extends ElementAccessExpression { + expression: SuperExpression; + } + + // see: https://tc39.github.io/ecma262/#prod-SuperProperty + export type SuperProperty + = SuperPropertyAccessExpression + | SuperElementAccessExpression + ; + export interface CallExpression extends LeftHandSideExpression, Declaration { kind: SyntaxKind.CallExpression; expression: LeftHandSideExpression; @@ -1175,6 +1303,11 @@ namespace ts { arguments: NodeArray; } + // see: https://tc39.github.io/ecma262/#prod-SuperCall + export interface SuperCall extends CallExpression { + expression: SuperExpression; + } + export interface ExpressionWithTypeArguments extends TypeNode { kind: SyntaxKind.ExpressionWithTypeArguments; expression: LeftHandSideExpression; @@ -1191,7 +1324,7 @@ namespace ts { export interface TaggedTemplateExpression extends MemberExpression { kind: SyntaxKind.TaggedTemplateExpression; tag: LeftHandSideExpression; - template: Template; + template: TemplateLiteral; } export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 89fc8d9a81d..938064dab4e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -609,7 +609,7 @@ namespace ts { return !!(getCombinedNodeFlags(node) & NodeFlags.Let); } - export function isSuperCallExpression(n: Node): boolean { + export function isSuperCall(n: Node): n is SuperCall { return n.kind === SyntaxKind.CallExpression && (n).expression.kind === SyntaxKind.SuperKeyword; } @@ -1047,7 +1047,7 @@ namespace ts { /** * Determines whether a node is a property or element access expression for super. */ - export function isSuperProperty(node: Node): node is (PropertyAccessExpression | ElementAccessExpression) { + export function isSuperProperty(node: Node): node is SuperProperty { const kind = node.kind; return (kind === SyntaxKind.PropertyAccessExpression || kind === SyntaxKind.ElementAccessExpression) && (node).expression.kind === SyntaxKind.SuperKeyword; @@ -3777,7 +3777,7 @@ namespace ts { return node.kind === SyntaxKind.CallExpression; } - export function isTemplate(node: Node): node is Template { + export function isTemplateLiteral(node: Node): node is TemplateLiteral { const kind = node.kind; return kind === SyntaxKind.TemplateExpression || kind === SyntaxKind.NoSubstitutionTemplateLiteral; diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index d16c038eeef..643c5c91eda 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -799,7 +799,7 @@ namespace ts { case SyntaxKind.TaggedTemplateExpression: return updateTaggedTemplate(node, visitNode((node).tag, visitor, isExpression), - visitNode((node).template, visitor, isTemplate)); + visitNode((node).template, visitor, isTemplateLiteral)); case SyntaxKind.ParenthesizedExpression: return updateParen(node,