-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
As operator #3201
As operator #3201
Changes from all commits
20f5987
634cc0e
8f78848
8b03911
3aa1caa
e1e577d
1e6bd1c
d5bf689
c1e02c4
d127775
9e6e265
225e695
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -159,6 +159,9 @@ module ts { | |
return visitNode(cbNode, (<BinaryExpression>node).left) || | ||
visitNode(cbNode, (<BinaryExpression>node).operatorToken) || | ||
visitNode(cbNode, (<BinaryExpression>node).right); | ||
case SyntaxKind.AsExpression: | ||
return visitNode(cbNode, (<AsExpression>node).expression) || | ||
visitNode(cbNode, (<AsExpression>node).type); | ||
case SyntaxKind.ConditionalExpression: | ||
return visitNode(cbNode, (<ConditionalExpression>node).condition) || | ||
visitNode(cbNode, (<ConditionalExpression>node).questionToken) || | ||
|
@@ -2818,7 +2821,23 @@ module ts { | |
break; | ||
} | ||
|
||
leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence)); | ||
if (token === SyntaxKind.AsKeyword) { | ||
// Make sure we *do* perform ASI for constructs like this: | ||
// var x = foo | ||
// as (Bar) | ||
// This should be parsed as an initialized variable, followed | ||
// by a function call to 'as' with the argument 'Bar' | ||
if (canParseSemicolon()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just add a comment for this case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you just check scanner.hasPrecedingLineBreak instead? I don't really like canParseSemicolon that much. |
||
break; | ||
} | ||
else { | ||
nextToken(); | ||
leftOperand = makeAsExpression(leftOperand, parseType()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is an ambiguity with union types worth calling out here: x as Foo | Bar This is intended to be a type assertion to a union type, and not a bitwise OR where the first operand is a type assertion. Seems like you do the right thing here, but just wanted to bring it up. |
||
} | ||
} | ||
else { | ||
leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence)); | ||
} | ||
} | ||
|
||
return leftOperand; | ||
|
@@ -2855,6 +2874,7 @@ module ts { | |
case SyntaxKind.GreaterThanEqualsToken: | ||
case SyntaxKind.InstanceOfKeyword: | ||
case SyntaxKind.InKeyword: | ||
case SyntaxKind.AsKeyword: | ||
return 7; | ||
case SyntaxKind.LessThanLessThanToken: | ||
case SyntaxKind.GreaterThanGreaterThanToken: | ||
|
@@ -2882,6 +2902,13 @@ module ts { | |
return finishNode(node); | ||
} | ||
|
||
function makeAsExpression(left: Expression, right: TypeNode): AsExpression { | ||
let node = <AsExpression>createNode(SyntaxKind.AsExpression, left.pos); | ||
node.expression = left; | ||
node.type = right; | ||
return finishNode(node); | ||
} | ||
|
||
function parsePrefixUnaryExpression() { | ||
let node = <PrefixUnaryExpression>createNode(SyntaxKind.PrefixUnaryExpression); | ||
node.operator = token; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
//// [asOperator1.ts] | ||
var as = 43; | ||
var x = undefined as number; | ||
var y = (null as string).length; | ||
var z = Date as any as string; | ||
|
||
|
||
//// [asOperator1.js] | ||
var as = 43; | ||
var x = undefined; | ||
var y = null.length; | ||
var z = Date; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
=== tests/cases/conformance/expressions/asOperator/asOperator1.ts === | ||
var as = 43; | ||
>as : Symbol(as, Decl(asOperator1.ts, 0, 3)) | ||
|
||
var x = undefined as number; | ||
>x : Symbol(x, Decl(asOperator1.ts, 1, 3)) | ||
>undefined : Symbol(undefined) | ||
|
||
var y = (null as string).length; | ||
>y : Symbol(y, Decl(asOperator1.ts, 2, 3)) | ||
>(null as string).length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) | ||
>length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) | ||
|
||
var z = Date as any as string; | ||
>z : Symbol(z, Decl(asOperator1.ts, 3, 3)) | ||
>Date : Symbol(Date, Decl(lib.d.ts, 633, 23), Decl(lib.d.ts, 815, 11)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
=== tests/cases/conformance/expressions/asOperator/asOperator1.ts === | ||
var as = 43; | ||
>as : number | ||
>43 : number | ||
|
||
var x = undefined as number; | ||
>x : number | ||
>undefined as number : number | ||
>undefined : undefined | ||
|
||
var y = (null as string).length; | ||
>y : number | ||
>(null as string).length : number | ||
>(null as string) : string | ||
>null as string : string | ||
>null : null | ||
>length : number | ||
|
||
var z = Date as any as string; | ||
>z : string | ||
>Date as any as string : string | ||
>Date as any : any | ||
>Date : DateConstructor | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
tests/cases/conformance/expressions/asOperator/asOperator2.ts(1,9): error TS2352: Neither type 'number' nor type 'string' is assignable to the other. | ||
|
||
|
||
==== tests/cases/conformance/expressions/asOperator/asOperator2.ts (1 errors) ==== | ||
var x = 23 as string; | ||
~~~~~~~~~~~~ | ||
!!! error TS2352: Neither type 'number' nor type 'string' is assignable to the other. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
//// [asOperator2.ts] | ||
var x = 23 as string; | ||
|
||
|
||
//// [asOperator2.js] | ||
var x = 23; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//// [asOperator3.ts] | ||
declare function tag(...x: any[]): any; | ||
|
||
var a = `${123 + 456 as number}`; | ||
var b = `leading ${123 + 456 as number}`; | ||
var c = `${123 + 456 as number} trailing`; | ||
var d = `Hello ${123} World` as string; | ||
var e = `Hello` as string; | ||
var f = 1 + `${1} end of string` as string; | ||
var g = tag `Hello ${123} World` as string; | ||
var h = tag `Hello` as string; | ||
|
||
//// [asOperator3.js] | ||
var a = "" + 123 + 456; | ||
var b = "leading " + 123 + 456; | ||
var c = 123 + 456 + " trailing"; | ||
var d = ("Hello " + 123 + " World"); | ||
var e = "Hello"; | ||
var f = 1 + (1 + " end of string"); | ||
var g = (_a = ["Hello ", " World"], _a.raw = ["Hello ", " World"], tag(_a, 123)); | ||
var h = (_b = ["Hello"], _b.raw = ["Hello"], tag(_b)); | ||
var _a, _b; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
=== tests/cases/conformance/expressions/asOperator/asOperator3.ts === | ||
declare function tag(...x: any[]): any; | ||
>tag : Symbol(tag, Decl(asOperator3.ts, 0, 0)) | ||
>x : Symbol(x, Decl(asOperator3.ts, 0, 21)) | ||
|
||
var a = `${123 + 456 as number}`; | ||
>a : Symbol(a, Decl(asOperator3.ts, 2, 3)) | ||
|
||
var b = `leading ${123 + 456 as number}`; | ||
>b : Symbol(b, Decl(asOperator3.ts, 3, 3)) | ||
|
||
var c = `${123 + 456 as number} trailing`; | ||
>c : Symbol(c, Decl(asOperator3.ts, 4, 3)) | ||
|
||
var d = `Hello ${123} World` as string; | ||
>d : Symbol(d, Decl(asOperator3.ts, 5, 3)) | ||
|
||
var e = `Hello` as string; | ||
>e : Symbol(e, Decl(asOperator3.ts, 6, 3)) | ||
|
||
var f = 1 + `${1} end of string` as string; | ||
>f : Symbol(f, Decl(asOperator3.ts, 7, 3)) | ||
|
||
var g = tag `Hello ${123} World` as string; | ||
>g : Symbol(g, Decl(asOperator3.ts, 8, 3)) | ||
>tag : Symbol(tag, Decl(asOperator3.ts, 0, 0)) | ||
|
||
var h = tag `Hello` as string; | ||
>h : Symbol(h, Decl(asOperator3.ts, 9, 3)) | ||
>tag : Symbol(tag, Decl(asOperator3.ts, 0, 0)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to update parenthesizeForAccess as well.