feat(es/typescript): Support TS 4.9 (#5938)

**Description:**

This PR adds satisfaction expression to the AST and parser.
This commit is contained in:
Donny/강동윤 2022-09-23 16:41:56 +09:00 committed by GitHub
parent ae14211f04
commit 5cddb4c734
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 2962 additions and 2009 deletions

View File

@ -1,49 +1,26 @@
//// [typeSatisfaction.ts]
//!
//! x Expected a semicolon
//! ,----
//! 11 | const t1 = { a: 1 } satisfies I1; // Ok
//! : ^^^^^^^^^
//! `----
//!
//! x Expected a semicolon
//! ,----
//! 12 | const t2 = { a: 1, b: 1 } satisfies I1; // Error
//! : ^^^^^^^^^
//! `----
//!
//! x Expected a semicolon
//! ,----
//! 13 | const t3 = { } satisfies I1; // Error
//! : ^^^^^^^^^
//! `----
//!
//! x Expected a semicolon
//! ,----
//! 15 | const t4: T1 = { a: "a" } satisfies T1; // Ok
//! : ^^^^^^^^^
//! `----
//!
//! x Expected a semicolon
//! ,----
//! 16 | const t5 = (m => m.substring(0)) satisfies T2; // Ok
//! : ^^^^^^^^^
//! `----
//!
//! x Expected a semicolon
//! ,----
//! 18 | const t6 = [1, 2] satisfies [number, number];
//! : ^^^^^^^^^
//! `----
//!
//! x Expected a semicolon
//! ,----
//! 23 | let t7 = { a: 'test' } satisfies A;
//! : ^^^^^^^^^
//! `----
//!
//! x Expected a semicolon
//! ,----
//! 24 | let t8 = { a: 'test', b: 'test' } satisfies A;
//! : ^^^^^^^^^
//! `----
var t1 = {
a: 1
}; // Ok
var t2 = {
a: 1,
b: 1
}; // Error
var t3 = {}; // Error
var t4 = {
a: "a"
}; // Ok
var t5 = function(m) {
return m.substring(0);
}; // Ok
var t6 = [
1,
2
];
var t7 = {
a: "test"
};
var t8 = {
a: "test",
b: "test"
};

View File

@ -1,49 +1 @@
//// [typeSatisfaction.ts]
//!
//! x Expected a semicolon
//! ,----
//! 11 | const t1 = { a: 1 } satisfies I1; // Ok
//! : ^^^^^^^^^
//! `----
//!
//! x Expected a semicolon
//! ,----
//! 12 | const t2 = { a: 1, b: 1 } satisfies I1; // Error
//! : ^^^^^^^^^
//! `----
//!
//! x Expected a semicolon
//! ,----
//! 13 | const t3 = { } satisfies I1; // Error
//! : ^^^^^^^^^
//! `----
//!
//! x Expected a semicolon
//! ,----
//! 15 | const t4: T1 = { a: "a" } satisfies T1; // Ok
//! : ^^^^^^^^^
//! `----
//!
//! x Expected a semicolon
//! ,----
//! 16 | const t5 = (m => m.substring(0)) satisfies T2; // Ok
//! : ^^^^^^^^^
//! `----
//!
//! x Expected a semicolon
//! ,----
//! 18 | const t6 = [1, 2] satisfies [number, number];
//! : ^^^^^^^^^
//! `----
//!
//! x Expected a semicolon
//! ,----
//! 23 | let t7 = { a: 'test' } satisfies A;
//! : ^^^^^^^^^
//! `----
//!
//! x Expected a semicolon
//! ,----
//! 24 | let t8 = { a: 'test', b: 'test' } satisfies A;
//! : ^^^^^^^^^
//! `----

View File

@ -1,7 +1,9 @@
//// [typeSatisfaction_contextualTyping1.ts]
//!
//! x Expected a semicolon
//! ,----
//! 6 | } satisfies Predicates;
//! : ^^^^^^^^^
//! `----
var p = {
isEven: function(n) {
return n % 2 === 0;
},
isOdd: function(n) {
return n % 2 === 1;
}
};

View File

@ -1,7 +1 @@
//// [typeSatisfaction_contextualTyping1.ts]
//!
//! x Expected a semicolon
//! ,----
//! 6 | } satisfies Predicates;
//! : ^^^^^^^^^
//! `----

View File

@ -1,7 +1,8 @@
//// [typeSatisfaction_ensureInterfaceImpl.ts]
//!
//! x Expected a semicolon
//! ,----
//! 11 | } satisfies Movable & Record<string, unknown>;
//! : ^^^^^^^^^
//! `----
var car = {
start: function start() {},
move: function move(d) {
// d should be number
},
stop: function stop() {}
};

View File

@ -1,7 +1 @@
//// [typeSatisfaction_ensureInterfaceImpl.ts]
//!
//! x Expected a semicolon
//! ,----
//! 11 | } satisfies Movable & Record<string, unknown>;
//! : ^^^^^^^^^
//! `----

View File

@ -1,7 +1,2 @@
//// [/src/a.js]
//!
//! x Expected a semicolon
//! ,----
//! 2 | var v = undefined satisfies 1;
//! : ^^^^^^^^^
//! `----
var v = undefined;

View File

@ -1,7 +1 @@
//// [/src/a.js]
//!
//! x Expected a semicolon
//! ,----
//! 2 | var v = undefined satisfies 1;
//! : ^^^^^^^^^
//! `----

View File

@ -1,7 +1,9 @@
//// [typeSatisfaction_optionalMemberConformance.ts]
//!
//! x Expected a semicolon
//! ,----
//! 3 | const a = { x: 10 } satisfies Partial<Point2d>;
//! : ^^^^^^^^^
//! `----
// Undesirable behavior today with type annotation
var a = {
x: 10
};
// Should OK
console.log(a.x.toFixed());
// Should error
var p = a.y;

View File

@ -1,7 +1,5 @@
//// [typeSatisfaction_optionalMemberConformance.ts]
//!
//! x Expected a semicolon
//! ,----
//! 3 | const a = { x: 10 } satisfies Partial<Point2d>;
//! : ^^^^^^^^^
//! `----
var a = {
x: 10
};
console.log(a.x.toFixed()), a.y;

View File

@ -1,7 +1,11 @@
//// [typeSatisfaction_propNameConstraining.ts]
//!
//! x Expected a semicolon
//! ,----
//! 7 | } satisfies Partial<Record<Keys, unknown>>;
//! : ^^^^^^^^^
//! `----
var p = {
a: 0,
b: "hello",
x: 8 // Should error, 'x' isn't in 'Keys'
};
// Should be OK -- retain info that a is number and b is string
var a = p.a.toFixed();
var b = p.b.substring(1);
// Should error even though 'd' is in 'Keys'
var d = p.d;

View File

@ -1,7 +1,7 @@
//// [typeSatisfaction_propNameConstraining.ts]
//!
//! x Expected a semicolon
//! ,----
//! 7 | } satisfies Partial<Record<Keys, unknown>>;
//! : ^^^^^^^^^
//! `----
var p = {
a: 0,
b: "hello",
x: 8
};
p.a.toFixed(), p.b.substring(1), p.d;

View File

@ -1,7 +1,11 @@
//// [typeSatisfaction_propertyNameFulfillment.ts]
//!
//! x Expected a semicolon
//! ,----
//! 7 | } satisfies Record<Keys, unknown>;
//! : ^^^^^^^^^
//! `----
var p = {
a: 0,
b: "hello",
x: 8 // Should error, 'x' isn't in 'Keys'
};
// Should be OK -- retain info that a is number and b is string
var a = p.a.toFixed();
var b = p.b.substring(1);
// Should error even though 'd' is in 'Keys'
var d = p.d;

View File

@ -1,7 +1,7 @@
//// [typeSatisfaction_propertyNameFulfillment.ts]
//!
//! x Expected a semicolon
//! ,----
//! 7 | } satisfies Record<Keys, unknown>;
//! : ^^^^^^^^^
//! `----
var p = {
a: 0,
b: "hello",
x: 8
};
p.a.toFixed(), p.b.substring(1), p.d;

View File

@ -1,7 +1,16 @@
//// [typeSatisfaction_propertyValueConformance1.ts]
//!
//! x Expected a semicolon
//! ,----
//! 24 | } satisfies Facts;
//! : ^^^^^^^^^
//! `----
var x = {
m: true
};
// Should be OK
checkTruths(x);
// Should be OK
checkM(x);
// Should fail under --noPropertyAccessFromIndexSignature
console.log(x.z);
var m = x.m;
// Should be able to detect a failure here
var x2 = {
m: true,
s: "false"
};

View File

@ -1,7 +1,5 @@
//// [typeSatisfaction_propertyValueConformance1.ts]
//!
//! x Expected a semicolon
//! ,----
//! 24 | } satisfies Facts;
//! : ^^^^^^^^^
//! `----
var x = {
m: !0
};
checkTruths(x), checkM(x), console.log(x.z), x.m;

View File

@ -1,7 +1,16 @@
//// [typeSatisfaction_propertyValueConformance2.ts]
//!
//! x Expected a semicolon
//! ,----
//! 24 | } satisfies Facts;
//! : ^^^^^^^^^
//! `----
var x = {
m: true
};
// Should be OK
checkTruths(x);
// Should be OK
checkM(x);
console.log(x.z);
// Should be OK under --noUncheckedIndexedAccess
var m = x.m;
// Should be able to detect a failure here
var x2 = {
m: true,
s: "false"
};

View File

@ -1,7 +1,5 @@
//// [typeSatisfaction_propertyValueConformance2.ts]
//!
//! x Expected a semicolon
//! ,----
//! 24 | } satisfies Facts;
//! : ^^^^^^^^^
//! `----
var x = {
m: !0
};
checkTruths(x), checkM(x), console.log(x.z), x.m;

View File

@ -1,7 +1,19 @@
//// [typeSatisfaction_propertyValueConformance3.ts]
//!
//! x Expected a semicolon
//! ,----
//! 8 | } satisfies Record<string, Color>;
//! : ^^^^^^^^^
//! `----
// All of these should be Colors, but I only use some of them here.
export var Palette = {
white: {
r: 255,
g: 255,
b: 255
},
black: {
r: 0,
g: 0,
d: 0
},
blue: {
r: 0,
g: 0,
b: 255
}
};

View File

@ -1,7 +1,18 @@
//// [typeSatisfaction_propertyValueConformance3.ts]
//!
//! x Expected a semicolon
//! ,----
//! 8 | } satisfies Record<string, Color>;
//! : ^^^^^^^^^
//! `----
export var Palette = {
white: {
r: 255,
g: 255,
b: 255
},
black: {
r: 0,
g: 0,
d: 0
},
blue: {
r: 0,
g: 0,
b: 255
}
};

File diff suppressed because it is too large Load Diff

View File

@ -22,8 +22,8 @@ use crate::{
prop::Prop,
stmt::BlockStmt,
typescript::{
TsAsExpr, TsConstAssertion, TsInstantiation, TsNonNullExpr, TsTypeAnn, TsTypeAssertion,
TsTypeParamDecl, TsTypeParamInstantiation,
TsAsExpr, TsConstAssertion, TsInstantiation, TsNonNullExpr, TsSatisfactionExpr, TsTypeAnn,
TsTypeAssertion, TsTypeParamDecl, TsTypeParamInstantiation,
},
ComputedPropName, Id, Invalid,
};
@ -157,6 +157,9 @@ pub enum Expr {
#[tag("TsInstantiation")]
TsInstantiation(TsInstantiation),
#[tag("TsSatisfactionExpr")]
TsSatisfaction(TsSatisfactionExpr),
#[tag("PrivateName")]
PrivateName(PrivateName),
@ -257,6 +260,7 @@ impl Clone for Expr {
PrivateName(e) => PrivateName(e.clone()),
OptChain(e) => OptChain(e.clone()),
Invalid(e) => Invalid(e.clone()),
TsSatisfaction(e) => TsSatisfaction(e.clone()),
}
}
}

View File

@ -68,11 +68,12 @@ pub use self::{
TsKeywordType, TsKeywordTypeKind, TsLit, TsLitType, TsMappedType, TsMethodSignature,
TsModuleBlock, TsModuleDecl, TsModuleName, TsModuleRef, TsNamespaceBody, TsNamespaceDecl,
TsNamespaceExportDecl, TsNonNullExpr, TsOptionalType, TsParamProp, TsParamPropParam,
TsParenthesizedType, TsPropertySignature, TsQualifiedName, TsRestType, TsSetterSignature,
TsThisType, TsThisTypeOrIdent, TsTplLitType, TsTupleElement, TsTupleType, TsType,
TsTypeAliasDecl, TsTypeAnn, TsTypeAssertion, TsTypeElement, TsTypeLit, TsTypeOperator,
TsTypeOperatorOp, TsTypeParam, TsTypeParamDecl, TsTypeParamInstantiation, TsTypePredicate,
TsTypeQuery, TsTypeQueryExpr, TsTypeRef, TsUnionOrIntersectionType, TsUnionType,
TsParenthesizedType, TsPropertySignature, TsQualifiedName, TsRestType, TsSatisfactionExpr,
TsSetterSignature, TsThisType, TsThisTypeOrIdent, TsTplLitType, TsTupleElement,
TsTupleType, TsType, TsTypeAliasDecl, TsTypeAnn, TsTypeAssertion, TsTypeElement, TsTypeLit,
TsTypeOperator, TsTypeOperatorOp, TsTypeParam, TsTypeParamDecl, TsTypeParamInstantiation,
TsTypePredicate, TsTypeQuery, TsTypeQueryExpr, TsTypeRef, TsUnionOrIntersectionType,
TsUnionType,
},
};

View File

@ -1055,6 +1055,17 @@ pub struct TsNonNullExpr {
pub expr: Box<Expr>,
}
#[ast_node("TsSatisfactionExpr")]
#[derive(Eq, Hash, EqIgnoreSpan)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub struct TsSatisfactionExpr {
pub span: Span,
#[serde(rename = "expression")]
pub expr: Box<Expr>,
#[serde(rename = "typeAnnotation")]
pub type_ann: Box<TsType>,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Eq, Hash, EqIgnoreSpan)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(

View File

@ -746,7 +746,7 @@ where
#[emitter]
fn emit_expr(&mut self, node: &Expr) -> Result {
match *node {
match node {
Expr::Array(ref n) => emit!(n),
Expr::Arrow(ref n) => emit!(n),
Expr::Assign(ref n) => emit!(n),
@ -786,6 +786,9 @@ where
Expr::TsInstantiation(ref n) => emit!(n),
Expr::OptChain(ref n) => emit!(n),
Expr::Invalid(ref n) => emit!(n),
Expr::TsSatisfaction(n) => {
emit!(n)
}
}
if self.comments.is_some() {

View File

@ -39,6 +39,19 @@ where
emit!(n.type_ann);
}
#[emitter]
fn emit_ts_satisfaction_expr(&mut self, n: &TsSatisfactionExpr) -> Result {
self.emit_leading_comments_of_span(n.span(), false)?;
emit!(n.expr);
space!();
keyword!("satisfies");
space!();
emit!(n.type_ann);
}
#[emitter]
fn emit_ts_call_signature_decl(&mut self, n: &TsCallSignatureDecl) -> Result {
self.emit_leading_comments_of_span(n.span(), false)?;

View File

@ -141,7 +141,8 @@ impl StartsWithAlphaNum for Expr {
Expr::TsNonNull(TsNonNullExpr { ref expr, .. })
| Expr::TsAs(TsAsExpr { ref expr, .. })
| Expr::TsConstAssertion(TsConstAssertion { ref expr, .. })
| Expr::TsInstantiation(TsInstantiation { ref expr, .. }) => {
| Expr::TsInstantiation(TsInstantiation { ref expr, .. })
| Expr::TsSatisfaction(TsSatisfactionExpr { ref expr, .. }) => {
expr.starts_with_alpha_num()
}

View File

@ -197,6 +197,7 @@ impl SizeWithCtxt for Expr {
Expr::TsNonNull(_) => TODO,
Expr::TsAs(_) => TODO,
Expr::TsInstantiation(_) => TODO,
Expr::TsSatisfaction(_) => TODO,
}
}
}

View File

@ -332,6 +332,9 @@ macro_rules! tok {
("as") => {
crate::token::Token::Word(crate::token::Word::Ident(swc_atoms::js_word!("as")))
};
("satisfies") => {
crate::token::Token::Word(crate::token::Word::Ident(swc_atoms::js_word!("satisfies")))
};
("namespace") => {
crate::token::Token::Word(crate::token::Word::Ident(swc_atoms::js_word!("namespace")))
};

View File

@ -422,6 +422,7 @@ impl<I: Tokens> Parser<I> {
type_ann,
})));
}
// async a => body
let arg = Pat::from(ident);
let params = vec![arg];

View File

@ -114,6 +114,23 @@ impl<I: Tokens> Parser<I> {
return self.parse_bin_op_recursively_inner(node, min_prec);
}
if self.input.syntax().typescript()
&& !self.input.had_line_break_before_cur()
&& is!(self, "satisfies")
{
let start = left.span_lo();
let expr = left;
let node = {
let type_ann = self.next_then_parse_ts_type()?;
Box::new(Expr::TsAs(TsAsExpr {
span: span!(self, start),
expr,
type_ann,
}))
};
return self.parse_bin_op_recursively_inner(node, min_prec);
}
let ctx = self.ctx();
// Return left on eof

View File

@ -314,7 +314,8 @@ pub(super) trait ExprExt {
Expr::TsNonNull(TsNonNullExpr { ref expr, .. })
| Expr::TsTypeAssertion(TsTypeAssertion { ref expr, .. })
| Expr::TsAs(TsAsExpr { ref expr, .. })
| Expr::TsInstantiation(TsInstantiation { ref expr, .. }) => {
| Expr::TsInstantiation(TsInstantiation { ref expr, .. })
| Expr::TsSatisfaction(TsSatisfactionExpr { ref expr, .. }) => {
expr.is_valid_simple_assignment_target(strict)
}

View File

@ -275,7 +275,7 @@
"type": "VariableDeclarator",
"span": {
"start": 105,
"end": 118,
"end": 131,
"ctxt": 0
},
"id": {
@ -290,6 +290,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 110,
"end": 131,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 110,
@ -322,6 +329,26 @@
}
]
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 129,
"end": 131,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 129,
"end": 131,
"ctxt": 0
},
"value": "I1",
"optional": false
},
"typeParams": null
}
},
"definite": false
}
]
@ -340,7 +367,7 @@
"type": "VariableDeclarator",
"span": {
"start": 145,
"end": 164,
"end": 177,
"ctxt": 0
},
"id": {
@ -355,6 +382,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 150,
"end": 177,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 150,
@ -410,6 +444,26 @@
}
]
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 175,
"end": 177,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 175,
"end": 177,
"ctxt": 0
},
"value": "I1",
"optional": false
},
"typeParams": null
}
},
"definite": false
}
]
@ -428,7 +482,7 @@
"type": "VariableDeclarator",
"span": {
"start": 194,
"end": 202,
"end": 215,
"ctxt": 0
},
"id": {
@ -443,6 +497,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 199,
"end": 215,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 199,
@ -451,6 +512,26 @@
},
"properties": []
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 213,
"end": 215,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 213,
"end": 215,
"ctxt": 0
},
"value": "I1",
"optional": false
},
"typeParams": null
}
},
"definite": false
}
]
@ -469,7 +550,7 @@
"type": "VariableDeclarator",
"span": {
"start": 233,
"end": 252,
"end": 265,
"ctxt": 0
},
"id": {
@ -510,6 +591,13 @@
}
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 242,
"end": 265,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 242,
@ -542,6 +630,26 @@
}
]
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 263,
"end": 265,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 263,
"end": 265,
"ctxt": 0
},
"value": "T1",
"optional": false
},
"typeParams": null
}
},
"definite": false
}
]
@ -560,7 +668,7 @@
"type": "VariableDeclarator",
"span": {
"start": 279,
"end": 305,
"end": 318,
"ctxt": 0
},
"id": {
@ -575,6 +683,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 284,
"end": 318,
"ctxt": 0
},
"expression": {
"type": "ParenthesisExpression",
"span": {
"start": 284,
@ -659,6 +774,26 @@
"returnType": null
}
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 316,
"end": 318,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 316,
"end": 318,
"ctxt": 0
},
"value": "T2",
"optional": false
},
"typeParams": null
}
},
"definite": false
}
]
@ -677,7 +812,7 @@
"type": "VariableDeclarator",
"span": {
"start": 333,
"end": 344,
"end": 371,
"ctxt": 0
},
"id": {
@ -692,6 +827,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 338,
"end": 371,
"ctxt": 0
},
"expression": {
"type": "ArrayExpression",
"span": {
"start": 338,
@ -727,6 +869,53 @@
}
]
},
"typeAnnotation": {
"type": "TsTupleType",
"span": {
"start": 355,
"end": 371,
"ctxt": 0
},
"elemTypes": [
{
"type": "TsTupleElement",
"span": {
"start": 356,
"end": 362,
"ctxt": 0
},
"label": null,
"ty": {
"type": "TsKeywordType",
"span": {
"start": 356,
"end": 362,
"ctxt": 0
},
"kind": "number"
}
},
{
"type": "TsTupleElement",
"span": {
"start": 364,
"end": 370,
"ctxt": 0
},
"label": null,
"ty": {
"type": "TsKeywordType",
"span": {
"start": 364,
"end": 370,
"ctxt": 0
},
"kind": "number"
}
}
]
}
},
"definite": false
}
]
@ -817,7 +1006,7 @@
"type": "VariableDeclarator",
"span": {
"start": 408,
"end": 426,
"end": 438,
"ctxt": 0
},
"id": {
@ -832,6 +1021,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 413,
"end": 438,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 413,
@ -864,6 +1060,26 @@
}
]
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 437,
"end": 438,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 437,
"end": 438,
"ctxt": 0
},
"value": "A",
"optional": false
},
"typeParams": null
}
},
"definite": false
}
]
@ -882,7 +1098,7 @@
"type": "VariableDeclarator",
"span": {
"start": 444,
"end": 473,
"end": 485,
"ctxt": 0
},
"id": {
@ -897,6 +1113,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 449,
"end": 485,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 449,
@ -952,6 +1175,26 @@
}
]
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 484,
"end": 485,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 484,
"end": 485,
"ctxt": 0
},
"value": "A",
"optional": false
},
"typeParams": null
}
},
"definite": false
}
]

View File

@ -152,7 +152,7 @@
"type": "VariableDeclarator",
"span": {
"start": 67,
"end": 132,
"end": 153,
"ctxt": 0
},
"id": {
@ -167,6 +167,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 71,
"end": 153,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 71,
@ -348,6 +355,26 @@
}
]
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 143,
"end": 153,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 143,
"end": 153,
"ctxt": 0
},
"value": "Predicates",
"optional": false
},
"typeParams": null
}
},
"definite": false
}
]

View File

@ -118,7 +118,7 @@
"type": "VariableDeclarator",
"span": {
"start": 62,
"end": 154,
"end": 198,
"ctxt": 0
},
"id": {
@ -133,6 +133,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 68,
"end": 198,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 68,
@ -262,6 +269,82 @@
}
]
},
"typeAnnotation": {
"type": "TsIntersectionType",
"span": {
"start": 165,
"end": 198,
"ctxt": 0
},
"types": [
{
"type": "TsTypeReference",
"span": {
"start": 165,
"end": 172,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 165,
"end": 172,
"ctxt": 0
},
"value": "Movable",
"optional": false
},
"typeParams": null
},
{
"type": "TsTypeReference",
"span": {
"start": 175,
"end": 198,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 175,
"end": 181,
"ctxt": 0
},
"value": "Record",
"optional": false
},
"typeParams": {
"type": "TsTypeParameterInstantiation",
"span": {
"start": 181,
"end": 198,
"ctxt": 0
},
"params": [
{
"type": "TsKeywordType",
"span": {
"start": 182,
"end": 188,
"ctxt": 0
},
"kind": "string"
},
{
"type": "TsKeywordType",
"span": {
"start": 190,
"end": 197,
"ctxt": 0
},
"kind": "unknown"
}
]
}
}
]
}
},
"definite": false
}
]

View File

@ -20,7 +20,7 @@
"type": "VariableDeclarator",
"span": {
"start": 67,
"end": 80,
"end": 92,
"ctxt": 0
},
"id": {
@ -35,6 +35,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 71,
"end": 92,
"ctxt": 0
},
"expression": {
"type": "Identifier",
"span": {
"start": 71,
@ -44,6 +51,25 @@
"value": "undefined",
"optional": false
},
"typeAnnotation": {
"type": "TsLiteralType",
"span": {
"start": 91,
"end": 92,
"ctxt": 0
},
"literal": {
"type": "NumericLiteral",
"span": {
"start": 91,
"end": 92,
"ctxt": 0
},
"value": 1.0,
"raw": "1"
}
}
},
"definite": false
}
]

View File

@ -132,7 +132,7 @@
"type": "VariableDeclarator",
"span": {
"start": 99,
"end": 112,
"end": 139,
"ctxt": 0
},
"id": {
@ -147,6 +147,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 103,
"end": 139,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 103,
@ -179,6 +186,54 @@
}
]
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 123,
"end": 139,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 123,
"end": 130,
"ctxt": 0
},
"value": "Partial",
"optional": false
},
"typeParams": {
"type": "TsTypeParameterInstantiation",
"span": {
"start": 130,
"end": 139,
"ctxt": 0
},
"params": [
{
"type": "TsTypeReference",
"span": {
"start": 131,
"end": 138,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 131,
"end": 138,
"ctxt": 0
},
"value": "Point2d",
"optional": false
},
"typeParams": null
}
]
}
}
},
"definite": false
}
]

View File

@ -122,7 +122,7 @@
"type": "VariableDeclarator",
"span": {
"start": 43,
"end": 122,
"end": 163,
"ctxt": 0
},
"id": {
@ -137,6 +137,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 47,
"end": 163,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 47,
@ -215,6 +222,91 @@
}
]
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 133,
"end": 163,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 133,
"end": 140,
"ctxt": 0
},
"value": "Partial",
"optional": false
},
"typeParams": {
"type": "TsTypeParameterInstantiation",
"span": {
"start": 140,
"end": 163,
"ctxt": 0
},
"params": [
{
"type": "TsTypeReference",
"span": {
"start": 141,
"end": 162,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 141,
"end": 147,
"ctxt": 0
},
"value": "Record",
"optional": false
},
"typeParams": {
"type": "TsTypeParameterInstantiation",
"span": {
"start": 147,
"end": 162,
"ctxt": 0
},
"params": [
{
"type": "TsTypeReference",
"span": {
"start": 148,
"end": 152,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 148,
"end": 152,
"ctxt": 0
},
"value": "Keys",
"optional": false
},
"typeParams": null
},
{
"type": "TsKeywordType",
"span": {
"start": 154,
"end": 161,
"ctxt": 0
},
"kind": "unknown"
}
]
}
}
]
}
}
},
"definite": false
}
]

View File

@ -122,7 +122,7 @@
"type": "VariableDeclarator",
"span": {
"start": 43,
"end": 122,
"end": 154,
"ctxt": 0
},
"id": {
@ -137,6 +137,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 47,
"end": 154,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 47,
@ -215,6 +222,63 @@
}
]
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 133,
"end": 154,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 133,
"end": 139,
"ctxt": 0
},
"value": "Record",
"optional": false
},
"typeParams": {
"type": "TsTypeParameterInstantiation",
"span": {
"start": 139,
"end": 154,
"ctxt": 0
},
"params": [
{
"type": "TsTypeReference",
"span": {
"start": 140,
"end": 144,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 140,
"end": 144,
"ctxt": 0
},
"value": "Keys",
"optional": false
},
"typeParams": null
},
{
"type": "TsKeywordType",
"span": {
"start": 146,
"end": 153,
"ctxt": 0
},
"kind": "unknown"
}
]
}
}
},
"definite": false
}
]

View File

@ -666,7 +666,7 @@
"type": "VariableDeclarator",
"span": {
"start": 471,
"end": 507,
"end": 523,
"ctxt": 0
},
"id": {
@ -681,6 +681,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 476,
"end": 523,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 476,
@ -735,6 +742,26 @@
}
]
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 518,
"end": 523,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 518,
"end": 523,
"ctxt": 0
},
"value": "Facts",
"optional": false
},
"typeParams": null
}
},
"definite": false
}
]

View File

@ -666,7 +666,7 @@
"type": "VariableDeclarator",
"span": {
"start": 452,
"end": 488,
"end": 504,
"ctxt": 0
},
"id": {
@ -681,6 +681,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 457,
"end": 504,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 457,
@ -735,6 +742,26 @@
}
]
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 499,
"end": 504,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 499,
"end": 504,
"ctxt": 0
},
"value": "Facts",
"optional": false
},
"typeParams": null
}
},
"definite": false
}
]

View File

@ -188,7 +188,7 @@
"type": "VariableDeclarator",
"span": {
"start": 140,
"end": 291,
"end": 323,
"ctxt": 0
},
"id": {
@ -203,6 +203,13 @@
"typeAnnotation": null
},
"init": {
"type": "TsAsExpression",
"span": {
"start": 150,
"end": 323,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 150,
@ -488,6 +495,63 @@
}
]
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 302,
"end": 323,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 302,
"end": 308,
"ctxt": 0
},
"value": "Record",
"optional": false
},
"typeParams": {
"type": "TsTypeParameterInstantiation",
"span": {
"start": 308,
"end": 323,
"ctxt": 0
},
"params": [
{
"type": "TsKeywordType",
"span": {
"start": 309,
"end": 315,
"ctxt": 0
},
"kind": "string"
},
{
"type": "TsTypeReference",
"span": {
"start": 317,
"end": 322,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 317,
"end": 322,
"ctxt": 0
},
"value": "Color",
"optional": false
},
"typeParams": null
}
]
}
}
},
"definite": false
}
]

View File

@ -38,6 +38,7 @@ impl_enum!(
TsNonNull,
TsAs,
TsInstantiation,
TsSatisfaction,
PrivateName,
OptChain,
Invalid

View File

@ -19,3 +19,4 @@ fail_todo!(TsTypeParamDecl);
fail_todo!(TsExprWithTypeArgs);
fail_todo!(TsIndexSignature);
fail_todo!(TsParamProp);
fail_todo!(TsSatisfactionExpr);

View File

@ -1170,14 +1170,12 @@ fn can_be_null(e: &Expr) -> bool {
| Expr::Member(..)
| Expr::SuperProp(..)
| Expr::Call(..)
// an opt chain is either a member or a call
| Expr::OptChain(..)
| Expr::New(..)
| Expr::Yield(..)
| Expr::Await(..)
| Expr::MetaProp(..) => true,
// This does not include null
Expr::Lit(..) => false,
Expr::Array(..)
@ -1198,7 +1196,6 @@ fn can_be_null(e: &Expr) -> bool {
ref cons, ref alt, ..
}) => can_be_null(cons) || can_be_null(alt),
// TODO(kdy1): I'm not sure about this.
Expr::Unary(..) | Expr::Update(..) | Expr::Bin(..) => true,
Expr::JSXMember(..)
@ -1207,12 +1204,12 @@ fn can_be_null(e: &Expr) -> bool {
| Expr::JSXElement(..)
| Expr::JSXFragment(..) => unreachable!("destructuring jsx"),
// Trust user
Expr::TsNonNull(..) => false,
Expr::TsAs(TsAsExpr { ref expr, .. })
| Expr::TsTypeAssertion(TsTypeAssertion { ref expr, .. })
| Expr::TsConstAssertion(TsConstAssertion { ref expr, .. })
| Expr::TsInstantiation(TsInstantiation { ref expr, .. }) => can_be_null(expr),
| Expr::TsInstantiation(TsInstantiation { ref expr, .. })
| Expr::TsSatisfaction(TsSatisfactionExpr { ref expr, .. }) => can_be_null(expr),
Expr::Invalid(..) => unreachable!(),
}

View File

@ -436,7 +436,8 @@ where
| Expr::TsNonNull(TsNonNullExpr { expr, .. })
| Expr::TsTypeAssertion(TsTypeAssertion { expr, .. })
| Expr::TsConstAssertion(TsConstAssertion { expr, .. })
| Expr::TsInstantiation(TsInstantiation { expr, .. }) => {
| Expr::TsInstantiation(TsInstantiation { expr, .. })
| Expr::TsSatisfaction(TsSatisfactionExpr { expr, .. }) => {
expr.visit_mut_with(self);
let expr = *expr.take();
*n = expr;

View File

@ -1454,7 +1454,8 @@ pub trait ExprExt {
Expr::TsAs(TsAsExpr { ref expr, .. })
| Expr::TsNonNull(TsNonNullExpr { ref expr, .. })
| Expr::TsTypeAssertion(TsTypeAssertion { ref expr, .. })
| Expr::TsInstantiation(TsInstantiation { ref expr, .. }) => {
| Expr::TsInstantiation(TsInstantiation { ref expr, .. })
| Expr::TsSatisfaction(TsSatisfactionExpr { ref expr, .. }) => {
expr.may_have_side_effects(ctx)
}
@ -2422,7 +2423,8 @@ impl ExprCtx {
| Expr::TsNonNull(TsNonNullExpr { expr, .. })
| Expr::TsAs(TsAsExpr { expr, .. })
| Expr::TsConstAssertion(TsConstAssertion { expr, .. })
| Expr::TsInstantiation(TsInstantiation { expr, .. }) => {
| Expr::TsInstantiation(TsInstantiation { expr, .. })
| Expr::TsSatisfaction(TsSatisfactionExpr { expr, .. }) => {
self.extract_side_effects_to(to, *expr)
}
Expr::OptChain(OptChainExpr { base: child, .. }) => {

View File

@ -660,6 +660,7 @@ define!({
TsConstAssertion(TsConstAssertion),
TsNonNull(TsNonNullExpr),
TsAs(TsAsExpr),
TsSatisfaction(TsSatisfactionExpr),
TsInstantiation(TsInstantiation),
PrivateName(PrivateName),
OptChain(OptChainExpr),

View File

@ -157,6 +157,10 @@ impl Babelify for Expr {
"illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent",
&self
),
Expr::TsSatisfaction(_) => panic!(
"illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent",
&self
),
Expr::OptChain(_) => panic!(
"illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent",
&self

View File

@ -1 +1,227 @@
// This'll be generated by build process for the installation of the `@swc/core` package.
"use strict";
var __createBinding =
(this && this.__createBinding) ||
(Object.create
? function (o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (
!desc ||
("get" in desc
? !m.__esModule
: desc.writable || desc.configurable)
) {
desc = {
enumerable: true,
get: function () {
return m[k];
},
};
}
Object.defineProperty(o, k2, desc);
}
: function (o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
});
var __setModuleDefault =
(this && this.__setModuleDefault) ||
(Object.create
? function (o, v) {
Object.defineProperty(o, "default", {
enumerable: true,
value: v,
});
}
: function (o, v) {
o["default"] = v;
});
var __importStar =
(this && this.__importStar) ||
function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null)
for (var k in mod)
if (
k !== "default" &&
Object.prototype.hasOwnProperty.call(mod, k)
)
__createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter =
(this && this.__awaiter) ||
function (thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P
? value
: new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done
? resolve(result.value)
: adopt(result.value).then(fulfilled, rejected);
}
step(
(generator = generator.apply(thisArg, _arguments || [])).next()
);
});
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
* A postinstall script runs after `@swc/core` is installed.
*
* It checks if corresponding optional dependencies for native binary is installed and can be loaded properly.
* If it fails, it'll internally try to install `@swc/wasm` as fallback.
*/
const fs_1 = require("fs");
const assert = __importStar(require("assert"));
const path = __importStar(require("path"));
const child_process = __importStar(require("child_process"));
const fs = __importStar(require("fs"));
function removeRecursive(dir) {
for (const entry of fs.readdirSync(dir)) {
const entryPath = path.join(dir, entry);
let stats;
try {
stats = fs.lstatSync(entryPath);
} catch (_a) {
continue; // Guard against https://github.com/nodejs/node/issues/4760
}
if (stats.isDirectory()) removeRecursive(entryPath);
else fs.unlinkSync(entryPath);
}
fs.rmdirSync(dir);
}
/**
* Trying to validate @swc/core's native binary installation, then installs if it is not supported.
*/
const validateBinary = () =>
__awaiter(void 0, void 0, void 0, function* () {
var _a;
try {
const { name } = require(path.resolve(
process.env.INIT_CWD,
"package.json"
));
if (name === "@swc/core") {
return;
}
} catch (_) {
return;
}
// TODO: We do not take care of the case if user try to install with `--no-optional`.
// For now, it is considered as deliberate decision.
let binding;
try {
binding = require("./binding");
// Check if binding binary actually works.
// For the latest version, checks target triple. If it's old version doesn't have target triple, use parseSync instead.
const triple = binding.getTargetTriple
? binding.getTargetTriple()
: binding.parseSync(
"console.log()",
Buffer.from(JSON.stringify({ syntax: "ecmascript" }))
);
assert.ok(
triple,
"Failed to read target triple from native binary."
);
} catch (error) {
// if error is unsupported architecture, ignore to display.
if (
!((_a = error.message) === null || _a === void 0
? void 0
: _a.includes("Unsupported architecture"))
) {
console.warn(error);
}
console.warn(
`@swc/core was not able to resolve native bindings installation. It'll try to use @swc/wasm as fallback instead.`
);
}
if (!!binding) {
return;
}
// User choose to override the binary installation. Skip remanining validation.
if (!!process.env["SWC_BINARY_PATH"]) {
console.warn(
`@swc/core could not resolve native bindings installation, but found manual override config SWC_BINARY_PATH specified. Skipping remaning validation.`
);
return;
}
// Check if top-level package.json installs @swc/wasm separately already
let wasmBinding;
try {
wasmBinding = require.resolve(`@swc/wasm`);
} catch (_) {}
if (!!wasmBinding && (0, fs_1.existsSync)(wasmBinding)) {
return;
}
const env = Object.assign(Object.assign({}, process.env), {
npm_config_global: undefined,
});
const { version } = require(path.join(
path.dirname(require.resolve("@swc/core")),
"package.json"
));
// We want to place @swc/wasm next to the @swc/core as if normal installation was done,
// but can't directly set cwd to INIT_CWD as npm seems to acquire lock to the working dir.
// Instead, create a temporary inner and move it out.
const coreDir = path.dirname(require.resolve("@swc/core"));
const installDir = path.join(coreDir, "npm-install");
try {
fs.mkdirSync(installDir);
fs.writeFileSync(path.join(installDir, "package.json"), "{}");
// Instead of carrying over own dependencies to download & resolve package which increases installation sizes of `@swc/core`,
// assume & relies on system's npm installation.
child_process.execSync(
`npm install --no-save --loglevel=error --prefer-offline --no-audit --progress=false @swc/wasm@${version}`,
{ cwd: installDir, stdio: "pipe", env }
);
const installedBinPath = path.join(
installDir,
"node_modules",
`@swc/wasm`
);
// INIT_CWD is injected via npm. If it doesn't exists, can't proceed.
fs.renameSync(
installedBinPath,
path.resolve(process.env.INIT_CWD, "node_modules", `@swc/wasm`)
);
} catch (error) {
console.error(error);
console.error(`Failed to install fallback @swc/wasm@${version}. @swc/core will not properly.
Please install @swc/wasm manually, or retry whole installation.
If there are unexpected errors, please report at https://github.com/swc-project/swc/issues`);
} finally {
try {
removeRecursive(installDir);
} catch (_) {
// Gracefully ignore any failures. This'll make few leftover files but it shouldn't block installation.
}
}
});
validateBinary().catch((error) => {
// for now just throw the error as-is.
throw error;
});