mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 11:35:42 -06:00
Merge branch 'master' into interfaceFixes
* resolved conflicts with 4/ interface for codefixes
This commit is contained in:
commit
69118cd3e4
@ -649,7 +649,7 @@ task("importDefinitelyTypedTests", [importDefinitelyTypedTestsJs], function () {
|
||||
|
||||
// Local target to build the compiler and services
|
||||
var tscFile = path.join(builtLocalDirectory, compilerFilename);
|
||||
compileFile(tscFile, compilerSources, [builtLocalDirectory, copyright].concat(compilerSources), [copyright], /*useBuiltCompiler:*/ false);
|
||||
compileFile(tscFile, compilerSources, [builtLocalDirectory, copyright].concat(compilerSources), [copyright], /*useBuiltCompiler:*/ false, { noMapRoot: true });
|
||||
|
||||
var servicesFile = path.join(builtLocalDirectory, "typescriptServices.js");
|
||||
var servicesFileInBrowserTest = path.join(builtLocalDirectory, "typescriptServicesInBrowserTest.js");
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<!-- QUESTIONS: This is not a general support forum! Ask Qs at http://stackoverflow.com/questions/tagged/typescript -->
|
||||
<!-- SUGGESTIONS: See https://github.com/Microsoft/TypeScript-wiki/blob/master/Writing-Good-Design-Proposals.md -->
|
||||
|
||||
**TypeScript Version:** 2.0.3 / nightly (2.1.0-dev.201xxxxx)
|
||||
**TypeScript Version:** 2.1.1 / nightly (2.2.0-dev.201xxxxx)
|
||||
|
||||
**Code**
|
||||
|
||||
@ -13,4 +13,4 @@
|
||||
|
||||
**Expected behavior:**
|
||||
|
||||
**Actual behavior:**
|
||||
**Actual behavior:**
|
||||
|
||||
@ -234,8 +234,8 @@ namespace ts {
|
||||
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const nameExpression = (<ComputedPropertyName>node.name).expression;
|
||||
// treat computed property names where expression is string/numeric literal as just string/numeric literal
|
||||
if (isStringOrNumericLiteral(nameExpression.kind)) {
|
||||
return (<LiteralExpression>nameExpression).text;
|
||||
if (isStringOrNumericLiteral(nameExpression)) {
|
||||
return nameExpression.text;
|
||||
}
|
||||
|
||||
Debug.assert(isWellKnownSymbolSyntactically(nameExpression));
|
||||
@ -570,6 +570,31 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function bindEach(nodes: NodeArray<Node>) {
|
||||
if (nodes === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (skipTransformFlagAggregation) {
|
||||
forEach(nodes, bind);
|
||||
}
|
||||
else {
|
||||
const savedSubtreeTransformFlags = subtreeTransformFlags;
|
||||
subtreeTransformFlags = TransformFlags.None;
|
||||
let nodeArrayFlags = TransformFlags.None;
|
||||
for (const node of nodes) {
|
||||
bind(node);
|
||||
nodeArrayFlags |= node.transformFlags & ~TransformFlags.HasComputedFlags;
|
||||
}
|
||||
nodes.transformFlags = nodeArrayFlags | TransformFlags.HasComputedFlags;
|
||||
subtreeTransformFlags |= savedSubtreeTransformFlags;
|
||||
}
|
||||
}
|
||||
|
||||
function bindEachChild(node: Node) {
|
||||
forEachChild(node, bind, bindEach);
|
||||
}
|
||||
|
||||
function bindChildrenWorker(node: Node): void {
|
||||
// Binding of JsDocComment should be done before the current block scope container changes.
|
||||
// because the scope of JsDocComment should not be affected by whether the current node is a
|
||||
@ -578,7 +603,7 @@ namespace ts {
|
||||
forEach(node.jsDocComments, bind);
|
||||
}
|
||||
if (checkUnreachable(node)) {
|
||||
forEachChild(node, bind);
|
||||
bindEachChild(node);
|
||||
return;
|
||||
}
|
||||
switch (node.kind) {
|
||||
@ -643,7 +668,7 @@ namespace ts {
|
||||
bindCallExpressionFlow(<CallExpression>node);
|
||||
break;
|
||||
default:
|
||||
forEachChild(node, bind);
|
||||
bindEachChild(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -976,7 +1001,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function bindbreakOrContinueFlow(node: BreakOrContinueStatement, breakTarget: FlowLabel, continueTarget: FlowLabel) {
|
||||
function bindBreakOrContinueFlow(node: BreakOrContinueStatement, breakTarget: FlowLabel, continueTarget: FlowLabel) {
|
||||
const flowLabel = node.kind === SyntaxKind.BreakStatement ? breakTarget : continueTarget;
|
||||
if (flowLabel) {
|
||||
addAntecedent(flowLabel, currentFlow);
|
||||
@ -990,11 +1015,11 @@ namespace ts {
|
||||
const activeLabel = findActiveLabel(node.label.text);
|
||||
if (activeLabel) {
|
||||
activeLabel.referenced = true;
|
||||
bindbreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget);
|
||||
bindBreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget);
|
||||
}
|
||||
}
|
||||
else {
|
||||
bindbreakOrContinueFlow(node, currentBreakTarget, currentContinueTarget);
|
||||
bindBreakOrContinueFlow(node, currentBreakTarget, currentContinueTarget);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1062,6 +1087,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindCaseBlock(node: CaseBlock): void {
|
||||
const savedSubtreeTransformFlags = subtreeTransformFlags;
|
||||
subtreeTransformFlags = 0;
|
||||
const clauses = node.clauses;
|
||||
let fallthroughFlow = unreachableFlow;
|
||||
for (let i = 0; i < clauses.length; i++) {
|
||||
@ -1081,6 +1108,8 @@ namespace ts {
|
||||
errorOnFirstToken(clause, Diagnostics.Fallthrough_case_in_switch);
|
||||
}
|
||||
}
|
||||
clauses.transformFlags = subtreeTransformFlags | TransformFlags.HasComputedFlags;
|
||||
subtreeTransformFlags |= savedSubtreeTransformFlags;
|
||||
}
|
||||
|
||||
function bindCaseClause(node: CaseClause): void {
|
||||
@ -1088,7 +1117,7 @@ namespace ts {
|
||||
currentFlow = preSwitchCaseFlow;
|
||||
bind(node.expression);
|
||||
currentFlow = saveCurrentFlow;
|
||||
forEach(node.statements, bind);
|
||||
bindEach(node.statements);
|
||||
}
|
||||
|
||||
function pushActiveLabel(name: string, breakTarget: FlowLabel, continueTarget: FlowLabel): ActiveLabel {
|
||||
@ -1180,12 +1209,12 @@ namespace ts {
|
||||
const saveTrueTarget = currentTrueTarget;
|
||||
currentTrueTarget = currentFalseTarget;
|
||||
currentFalseTarget = saveTrueTarget;
|
||||
forEachChild(node, bind);
|
||||
bindEachChild(node);
|
||||
currentFalseTarget = currentTrueTarget;
|
||||
currentTrueTarget = saveTrueTarget;
|
||||
}
|
||||
else {
|
||||
forEachChild(node, bind);
|
||||
bindEachChild(node);
|
||||
if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) {
|
||||
bindAssignmentTargetFlow(node.operand);
|
||||
}
|
||||
@ -1193,7 +1222,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindPostfixUnaryExpressionFlow(node: PostfixUnaryExpression) {
|
||||
forEachChild(node, bind);
|
||||
bindEachChild(node);
|
||||
if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) {
|
||||
bindAssignmentTargetFlow(node.operand);
|
||||
}
|
||||
@ -1212,7 +1241,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
forEachChild(node, bind);
|
||||
bindEachChild(node);
|
||||
if (isAssignmentOperator(operator) && !isAssignmentTarget(node)) {
|
||||
bindAssignmentTargetFlow(node.left);
|
||||
if (operator === SyntaxKind.EqualsToken && node.left.kind === SyntaxKind.ElementAccessExpression) {
|
||||
@ -1226,7 +1255,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindDeleteExpressionFlow(node: DeleteExpression) {
|
||||
forEachChild(node, bind);
|
||||
bindEachChild(node);
|
||||
if (node.expression.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
bindAssignmentTargetFlow(node.expression);
|
||||
}
|
||||
@ -1251,7 +1280,7 @@ namespace ts {
|
||||
function bindInitializedVariableFlow(node: VariableDeclaration | ArrayBindingElement) {
|
||||
const name = !isOmittedExpression(node) ? node.name : undefined;
|
||||
if (isBindingPattern(name)) {
|
||||
for (const child of name.elements) {
|
||||
for (const child of <ArrayBindingElement[]>name.elements) {
|
||||
bindInitializedVariableFlow(child);
|
||||
}
|
||||
}
|
||||
@ -1261,7 +1290,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindVariableDeclarationFlow(node: VariableDeclaration) {
|
||||
forEachChild(node, bind);
|
||||
bindEachChild(node);
|
||||
if (node.initializer || node.parent.parent.kind === SyntaxKind.ForInStatement || node.parent.parent.kind === SyntaxKind.ForOfStatement) {
|
||||
bindInitializedVariableFlow(node);
|
||||
}
|
||||
@ -1276,12 +1305,12 @@ namespace ts {
|
||||
expr = (<ParenthesizedExpression>expr).expression;
|
||||
}
|
||||
if (expr.kind === SyntaxKind.FunctionExpression || expr.kind === SyntaxKind.ArrowFunction) {
|
||||
forEach(node.typeArguments, bind);
|
||||
forEach(node.arguments, bind);
|
||||
bindEach(node.typeArguments);
|
||||
bindEach(node.arguments);
|
||||
bind(node.expression);
|
||||
}
|
||||
else {
|
||||
forEachChild(node, bind);
|
||||
bindEachChild(node);
|
||||
}
|
||||
if (node.expression.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
const propertyAccess = <PropertyAccessExpression>node.expression;
|
||||
@ -2517,7 +2546,7 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression
|
||||
if (subtreeFlags & TransformFlags.ContainsSpread
|
||||
|| isSuperOrSuperProperty(expression, expressionKind)) {
|
||||
// If the this node contains a SpreadExpression, or is a super call, then it is an ES6
|
||||
// node.
|
||||
@ -2548,7 +2577,7 @@ namespace ts {
|
||||
if (node.typeArguments) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
if (subtreeFlags & TransformFlags.ContainsSpread) {
|
||||
// If the this node contains a SpreadElementExpression then it is an ES6
|
||||
// node.
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
@ -2557,7 +2586,6 @@ namespace ts {
|
||||
return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes;
|
||||
}
|
||||
|
||||
|
||||
function computeBinaryExpression(node: BinaryExpression, subtreeFlags: TransformFlags) {
|
||||
let transformFlags = subtreeFlags;
|
||||
const operatorTokenKind = node.operatorToken.kind;
|
||||
@ -2604,7 +2632,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// parameters with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@ -2726,7 +2754,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
return transformFlags & ~TransformFlags.NodeExcludes;
|
||||
return transformFlags & ~TransformFlags.CatchClauseExcludes;
|
||||
}
|
||||
|
||||
function computeExpressionWithTypeArguments(node: ExpressionWithTypeArguments, subtreeFlags: TransformFlags) {
|
||||
@ -2753,6 +2781,11 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
return transformFlags & ~TransformFlags.ConstructorExcludes;
|
||||
}
|
||||
@ -2771,6 +2804,11 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
// An async method declaration is ES2017 syntax.
|
||||
if (hasModifier(node, ModifierFlags.Async)) {
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
@ -2797,6 +2835,11 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
return transformFlags & ~TransformFlags.MethodOrAccessorExcludes;
|
||||
}
|
||||
@ -2842,7 +2885,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@ -2884,7 +2927,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function expressions with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@ -2927,7 +2970,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// arrow functions with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@ -2957,16 +3000,11 @@ namespace ts {
|
||||
|
||||
function computeVariableDeclaration(node: VariableDeclaration, subtreeFlags: TransformFlags) {
|
||||
let transformFlags = subtreeFlags;
|
||||
const nameKind = node.name.kind;
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
|
||||
|
||||
// A VariableDeclaration with an object binding pattern is ES2015 syntax
|
||||
// and possibly ESNext syntax if it contains an object binding pattern
|
||||
if (nameKind === SyntaxKind.ObjectBindingPattern) {
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
|
||||
}
|
||||
// A VariableDeclaration with an object binding pattern is ES2015 syntax.
|
||||
else if (nameKind === SyntaxKind.ArrayBindingPattern) {
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
|
||||
// A VariableDeclaration containing ObjectRest is ESNext syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
// Type annotations are TypeScript syntax.
|
||||
@ -3182,16 +3220,12 @@ namespace ts {
|
||||
break;
|
||||
|
||||
case SyntaxKind.SpreadElement:
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
// This node is ES6 or ES next syntax, but is handled by a containing node.
|
||||
transformFlags |= TransformFlags.ContainsSpreadExpression;
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsSpread;
|
||||
break;
|
||||
|
||||
case SyntaxKind.BindingElement:
|
||||
if ((node as BindingElement).dotDotDotToken) {
|
||||
// this node is ES2015 or ES next syntax, but is handled by a containing node.
|
||||
transformFlags |= TransformFlags.ContainsSpreadExpression;
|
||||
}
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsObjectSpread;
|
||||
break;
|
||||
|
||||
case SyntaxKind.SuperKeyword:
|
||||
// This node is ES6 syntax.
|
||||
@ -3204,13 +3238,22 @@ namespace ts {
|
||||
break;
|
||||
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
// These nodes are ES2015 or ES Next syntax.
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsBindingPattern;
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
|
||||
if (subtreeFlags & TransformFlags.ContainsRest) {
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsObjectRest;
|
||||
}
|
||||
else {
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
|
||||
excludeFlags = TransformFlags.BindingPatternExcludes;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
|
||||
excludeFlags = TransformFlags.BindingPatternExcludes;
|
||||
break;
|
||||
|
||||
case SyntaxKind.BindingElement:
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
if ((<BindingElement>node).dotDotDotToken) {
|
||||
transformFlags |= TransformFlags.ContainsRest;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -3233,7 +3276,7 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.ContainsLexicalThis;
|
||||
}
|
||||
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectSpread) {
|
||||
// If an ObjectLiteralExpression contains a spread element, then it
|
||||
// is an ES next node.
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
@ -3244,7 +3287,7 @@ namespace ts {
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
excludeFlags = TransformFlags.ArrayLiteralOrCallOrNewExcludes;
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
if (subtreeFlags & TransformFlags.ContainsSpread) {
|
||||
// If the this node contains a SpreadExpression, then it is an ES6
|
||||
// node.
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
@ -3337,6 +3380,11 @@ namespace ts {
|
||||
return TransformFlags.TypeExcludes;
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return TransformFlags.ObjectLiteralExcludes;
|
||||
case SyntaxKind.CatchClause:
|
||||
return TransformFlags.CatchClauseExcludes;
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
return TransformFlags.BindingPatternExcludes;
|
||||
default:
|
||||
return TransformFlags.NodeExcludes;
|
||||
}
|
||||
|
||||
@ -108,10 +108,10 @@ namespace ts {
|
||||
getEmitResolver,
|
||||
getExportsOfModule: getExportsOfModuleAsArray,
|
||||
getAmbientModules,
|
||||
|
||||
getJsxElementAttributesType,
|
||||
getJsxIntrinsicTagNames,
|
||||
isOptionalParameter,
|
||||
tryGetMemberInModuleExports,
|
||||
tryFindAmbientModuleWithoutAugmentations: moduleName => {
|
||||
// we deliberately exclude augmentations
|
||||
// since we are only interested in declarations of the module itself
|
||||
@ -1489,6 +1489,13 @@ namespace ts {
|
||||
return symbolsToArray(getExportsOfModule(moduleSymbol));
|
||||
}
|
||||
|
||||
function tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined {
|
||||
const symbolTable = getExportsOfModule(moduleSymbol);
|
||||
if (symbolTable) {
|
||||
return symbolTable[memberName];
|
||||
}
|
||||
}
|
||||
|
||||
function getExportsOfSymbol(symbol: Symbol): SymbolTable {
|
||||
return symbol.flags & SymbolFlags.Module ? getExportsOfModule(symbol) : symbol.exports || emptySymbols;
|
||||
}
|
||||
@ -3040,7 +3047,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isComputedNonLiteralName(name: PropertyName): boolean {
|
||||
return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteral((<ComputedPropertyName>name).expression.kind);
|
||||
return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteral((<ComputedPropertyName>name).expression);
|
||||
}
|
||||
|
||||
function getRestType(source: Type, properties: PropertyName[], symbol: Symbol): Type {
|
||||
@ -3091,7 +3098,7 @@ namespace ts {
|
||||
}
|
||||
const literalMembers: PropertyName[] = [];
|
||||
for (const element of pattern.elements) {
|
||||
if (element.kind !== SyntaxKind.OmittedExpression && !(element as BindingElement).dotDotDotToken) {
|
||||
if (!(element as BindingElement).dotDotDotToken) {
|
||||
literalMembers.push(element.propertyName || element.name as Identifier);
|
||||
}
|
||||
}
|
||||
@ -4504,6 +4511,8 @@ namespace ts {
|
||||
const members: SymbolTable = createMap<Symbol>();
|
||||
let stringIndexInfo: IndexInfo;
|
||||
let numberIndexInfo: IndexInfo;
|
||||
// Resolve upfront such that recursive references see an empty object type.
|
||||
setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||
// In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type,
|
||||
// and T as the template type.
|
||||
const typeParameter = getTypeParameterFromMappedType(type);
|
||||
@ -8944,7 +8953,7 @@ namespace ts {
|
||||
return type;
|
||||
}
|
||||
|
||||
function getTypeOfDestructuredProperty(type: Type, name: Identifier | LiteralExpression | ComputedPropertyName) {
|
||||
function getTypeOfDestructuredProperty(type: Type, name: PropertyName) {
|
||||
const text = getTextOfPropertyName(name);
|
||||
return getTypeOfPropertyOfType(type, text) ||
|
||||
isNumericLiteralName(text) && getIndexTypeOfType(type, IndexKind.Number) ||
|
||||
@ -14238,9 +14247,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else if (property.kind === SyntaxKind.SpreadAssignment) {
|
||||
if (property.expression.kind !== SyntaxKind.Identifier) {
|
||||
error(property.expression, Diagnostics.An_object_rest_element_must_be_an_identifier);
|
||||
}
|
||||
checkReferenceExpression(property.expression, Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access);
|
||||
}
|
||||
else {
|
||||
error(property, Diagnostics.Property_assignment_expected);
|
||||
@ -14761,7 +14768,7 @@ namespace ts {
|
||||
function checkDeclarationInitializer(declaration: VariableLikeDeclaration) {
|
||||
const type = checkExpressionCached(declaration.initializer);
|
||||
return getCombinedNodeFlags(declaration) & NodeFlags.Const ||
|
||||
getCombinedModifierFlags(declaration) & ModifierFlags.Readonly ||
|
||||
getCombinedModifierFlags(declaration) & ModifierFlags.Readonly && !isParameterPropertyDeclaration(declaration) ||
|
||||
isTypeAssertion(declaration.initializer) ? type : getWidenedLiteralType(type);
|
||||
}
|
||||
|
||||
@ -19649,7 +19656,7 @@ namespace ts {
|
||||
|
||||
function isNameOfModuleOrEnumDeclaration(node: Identifier) {
|
||||
const parent = node.parent;
|
||||
return isModuleOrEnumDeclaration(parent) && node === parent.name;
|
||||
return parent && isModuleOrEnumDeclaration(parent) && node === parent.name;
|
||||
}
|
||||
|
||||
// When resolved as an expression identifier, if the given node references an exported entity, return the declaration
|
||||
|
||||
@ -884,7 +884,7 @@ namespace ts {
|
||||
function tryExtendsName(extendedConfig: string): [string[], string[], string[], CompilerOptions] {
|
||||
// If the path isn't a rooted or relative path, don't try to resolve it (we reserve the right to special case module-id like paths in the future)
|
||||
if (!(isRootedDiskPath(extendedConfig) || startsWith(normalizeSlashes(extendedConfig), "./") || startsWith(normalizeSlashes(extendedConfig), "../"))) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.The_path_in_an_extends_options_must_be_relative_or_rooted));
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not, extendedConfig));
|
||||
return;
|
||||
}
|
||||
let extendedConfigPath = toPath(extendedConfig, basePath, getCanonicalFileName);
|
||||
|
||||
@ -571,7 +571,7 @@ namespace ts {
|
||||
*/
|
||||
export function append<T>(to: T[] | undefined, value: T | undefined): T[] | undefined {
|
||||
if (value === undefined) return to;
|
||||
if (to === undefined) to = [];
|
||||
if (to === undefined) return [value];
|
||||
to.push(value);
|
||||
return to;
|
||||
}
|
||||
@ -592,6 +592,16 @@ namespace ts {
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stable sort of an array. Elements equal to each other maintain their relative position in the array.
|
||||
*/
|
||||
export function stableSort<T>(array: T[], comparer: (x: T, y: T) => Comparison = compareValues) {
|
||||
return array
|
||||
.map((_, i) => i) // create array of indices
|
||||
.sort((x, y) => comparer(array[x], array[y]) || compareValues(x, y)) // sort indices by value then position
|
||||
.map(i => array[i]); // get sorted array
|
||||
}
|
||||
|
||||
export function rangeEquals<T>(array1: T[], array2: T[], pos: number, end: number) {
|
||||
while (pos < end) {
|
||||
if (array1[pos] !== array2[pos]) {
|
||||
@ -816,6 +826,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function appendProperty<T>(map: Map<T>, key: string | number, value: T): Map<T> {
|
||||
if (key === undefined || value === undefined) return map;
|
||||
if (map === undefined) map = createMap<T>();
|
||||
map[key] = value;
|
||||
return map;
|
||||
}
|
||||
|
||||
export function assign<T1 extends MapLike<{}>, T2, T3>(t: T1, arg1: T2, arg2: T3): T1 & T2 & T3;
|
||||
export function assign<T1 extends MapLike<{}>, T2>(t: T1, arg1: T2): T1 & T2;
|
||||
export function assign<T1 extends MapLike<{}>>(t: T1, ...args: any[]): any;
|
||||
@ -1374,6 +1391,14 @@ namespace ts {
|
||||
getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2015 ? ModuleKind.ES2015 : ModuleKind.CommonJS;
|
||||
}
|
||||
|
||||
export function getEmitModuleResolutionKind(compilerOptions: CompilerOptions) {
|
||||
let moduleResolution = compilerOptions.moduleResolution;
|
||||
if (moduleResolution === undefined) {
|
||||
moduleResolution = getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS ? ModuleResolutionKind.NodeJs : ModuleResolutionKind.Classic;
|
||||
}
|
||||
return moduleResolution;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function hasZeroOrOneAsteriskCharacter(str: string): boolean {
|
||||
let seenAsterisk = false;
|
||||
@ -2092,6 +2117,17 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Remove an item from an array, moving everything to its right one space left. */
|
||||
export function orderedRemoveItem<T>(array: T[], item: T): boolean {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (array[i] === item) {
|
||||
orderedRemoveItemAt(array, i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Remove an item by index from an array, moving everything to its right one space left. */
|
||||
export function orderedRemoveItemAt<T>(array: T[], index: number): void {
|
||||
// This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`.
|
||||
for (let i = index; i < array.length - 1; i++) {
|
||||
|
||||
@ -1991,7 +1991,7 @@
|
||||
"category": "Error",
|
||||
"code": 2700
|
||||
},
|
||||
"An object rest element must be an identifier.": {
|
||||
"The target of an object rest assignment must be a variable or a property access.": {
|
||||
"category": "Error",
|
||||
"code": 2701
|
||||
},
|
||||
@ -3142,7 +3142,7 @@
|
||||
"category": "Error",
|
||||
"code": 18000
|
||||
},
|
||||
"The path in an 'extends' options must be relative or rooted.": {
|
||||
"A path in an 'extends' option must be relative or rooted, but '{0}' is not.": {
|
||||
"category": "Error",
|
||||
"code": 18001
|
||||
},
|
||||
@ -3190,5 +3190,17 @@
|
||||
"Type '{0}' is not assignable to type '{1}'. Two different types with this name exist, but they are unrelated.": {
|
||||
"category": "Error",
|
||||
"code": 90010
|
||||
},
|
||||
"Import {0} from {1}": {
|
||||
"category": "Message",
|
||||
"code": 90013
|
||||
},
|
||||
"Change {0} to {1}": {
|
||||
"category": "Message",
|
||||
"code": 90014
|
||||
},
|
||||
"Add {0} to existing import declaration from {1}": {
|
||||
"category": "Message",
|
||||
"code": 90015
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,188 +20,6 @@ namespace ts {
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean): EmitResult {
|
||||
const delimiters = createDelimiterMap();
|
||||
const brackets = createBracketsMap();
|
||||
|
||||
// emit output for the __extends helper function
|
||||
const extendsHelper = `
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};`;
|
||||
|
||||
// Emit output for the __assign helper function.
|
||||
// This is typically used for JSX spread attributes,
|
||||
// and can be used for object literal spread properties.
|
||||
const assignHelper = `
|
||||
var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};`;
|
||||
|
||||
const restHelper = `
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
|
||||
t[p[i]] = s[p[i]];
|
||||
return t;
|
||||
};`;
|
||||
|
||||
// emit output for the __decorate helper function
|
||||
const decorateHelper = `
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};`;
|
||||
|
||||
// emit output for the __metadata helper function
|
||||
const metadataHelper = `
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};`;
|
||||
|
||||
// emit output for the __param helper function
|
||||
const paramHelper = `
|
||||
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
return function (target, key) { decorator(target, key, paramIndex); }
|
||||
};`;
|
||||
|
||||
// emit output for the __awaiter helper function
|
||||
const awaiterHelper = `
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments)).next());
|
||||
});
|
||||
};`;
|
||||
|
||||
// The __generator helper is used by down-level transformations to emulate the runtime
|
||||
// semantics of an ES2015 generator function. When called, this helper returns an
|
||||
// object that implements the Iterator protocol, in that it has `next`, `return`, and
|
||||
// `throw` methods that step through the generator when invoked.
|
||||
//
|
||||
// parameters:
|
||||
// thisArg The value to use as the `this` binding for the transformed generator body.
|
||||
// body A function that acts as the transformed generator body.
|
||||
//
|
||||
// variables:
|
||||
// _ Persistent state for the generator that is shared between the helper and the
|
||||
// generator body. The state object has the following members:
|
||||
// sent() - A method that returns or throws the current completion value.
|
||||
// label - The next point at which to resume evaluation of the generator body.
|
||||
// trys - A stack of protected regions (try/catch/finally blocks).
|
||||
// ops - A stack of pending instructions when inside of a finally block.
|
||||
// f A value indicating whether the generator is executing.
|
||||
// y An iterator to delegate for a yield*.
|
||||
// t A temporary variable that holds one of the following values (note that these
|
||||
// cases do not overlap):
|
||||
// - The completion value when resuming from a `yield` or `yield*`.
|
||||
// - The error value for a catch block.
|
||||
// - The current protected region (array of try/catch/finally/end labels).
|
||||
// - The verb (`next`, `throw`, or `return` method) to delegate to the expression
|
||||
// of a `yield*`.
|
||||
// - The result of evaluating the verb delegated to the expression of a `yield*`.
|
||||
//
|
||||
// functions:
|
||||
// verb(n) Creates a bound callback to the `step` function for opcode `n`.
|
||||
// step(op) Evaluates opcodes in a generator body until execution is suspended or
|
||||
// completed.
|
||||
//
|
||||
// The __generator helper understands a limited set of instructions:
|
||||
// 0: next(value?) - Start or resume the generator with the specified value.
|
||||
// 1: throw(error) - Resume the generator with an exception. If the generator is
|
||||
// suspended inside of one or more protected regions, evaluates
|
||||
// any intervening finally blocks between the current label and
|
||||
// the nearest catch block or function boundary. If uncaught, the
|
||||
// exception is thrown to the caller.
|
||||
// 2: return(value?) - Resume the generator as if with a return. If the generator is
|
||||
// suspended inside of one or more protected regions, evaluates any
|
||||
// intervening finally blocks.
|
||||
// 3: break(label) - Jump to the specified label. If the label is outside of the
|
||||
// current protected region, evaluates any intervening finally
|
||||
// blocks.
|
||||
// 4: yield(value?) - Yield execution to the caller with an optional value. When
|
||||
// resumed, the generator will continue at the next label.
|
||||
// 5: yield*(value) - Delegates evaluation to the supplied iterator. When
|
||||
// delegation completes, the generator will continue at the next
|
||||
// label.
|
||||
// 6: catch(error) - Handles an exception thrown from within the generator body. If
|
||||
// the current label is inside of one or more protected regions,
|
||||
// evaluates any intervening finally blocks between the current
|
||||
// label and the nearest catch block or function boundary. If
|
||||
// uncaught, the exception is thrown to the caller.
|
||||
// 7: endfinally - Ends a finally block, resuming the last instruction prior to
|
||||
// entering a finally block.
|
||||
//
|
||||
// For examples of how these are used, see the comments in ./transformers/generators.ts
|
||||
const generatorHelper = `
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t;
|
||||
return { next: verb(0), "throw": verb(1), "return": verb(2) };
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [0, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};`;
|
||||
|
||||
// emit output for the __export helper function
|
||||
const exportStarHelper = `
|
||||
function __export(m) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}`;
|
||||
|
||||
// emit output for the UMD helper function.
|
||||
const umdHelper = `
|
||||
(function (dependencies, factory) {
|
||||
if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||
var v = factory(require, exports); if (v !== undefined) module.exports = v;
|
||||
}
|
||||
else if (typeof define === 'function' && define.amd) {
|
||||
define(dependencies, factory);
|
||||
}
|
||||
})`;
|
||||
|
||||
const superHelper = `
|
||||
const _super = name => super[name];`;
|
||||
|
||||
const advancedSuperHelper = `
|
||||
const _super = (function (geti, seti) {
|
||||
const cache = Object.create(null);
|
||||
return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
|
||||
})(name => super[name], (name, value) => super[name] = value);`;
|
||||
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
@ -238,12 +56,7 @@ const _super = (function (geti, seti) {
|
||||
let currentSourceFile: SourceFile;
|
||||
let currentText: string;
|
||||
let currentFileIdentifiers: Map<string>;
|
||||
let extendsEmitted: boolean;
|
||||
let assignEmitted: boolean;
|
||||
let restEmitted: boolean;
|
||||
let decorateEmitted: boolean;
|
||||
let paramEmitted: boolean;
|
||||
let awaiterEmitted: boolean;
|
||||
let bundledHelpers: Map<boolean>;
|
||||
let isOwnFileEmit: boolean;
|
||||
let emitSkipped = false;
|
||||
|
||||
@ -308,12 +121,13 @@ const _super = (function (geti, seti) {
|
||||
nodeIdToGeneratedName = [];
|
||||
autoGeneratedIdToGeneratedName = [];
|
||||
generatedNameSet = createMap<string>();
|
||||
bundledHelpers = isBundledEmit ? createMap<boolean>() : undefined;
|
||||
isOwnFileEmit = !isBundledEmit;
|
||||
|
||||
// Emit helpers from all the files
|
||||
if (isBundledEmit && moduleKind) {
|
||||
for (const sourceFile of sourceFiles) {
|
||||
emitEmitHelpers(sourceFile);
|
||||
emitHelpers(sourceFile, /*isBundle*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,11 +162,6 @@ const _super = (function (geti, seti) {
|
||||
tempFlags = TempFlags.Auto;
|
||||
currentSourceFile = undefined;
|
||||
currentText = undefined;
|
||||
extendsEmitted = false;
|
||||
assignEmitted = false;
|
||||
decorateEmitted = false;
|
||||
paramEmitted = false;
|
||||
awaiterEmitted = false;
|
||||
isOwnFileEmit = false;
|
||||
}
|
||||
|
||||
@ -861,6 +670,8 @@ const _super = (function (geti, seti) {
|
||||
// Transformation nodes
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
return emitPartiallyEmittedExpression(<PartiallyEmittedExpression>node);
|
||||
case SyntaxKind.RawExpression:
|
||||
return writeLines((<RawExpression>node).text);
|
||||
}
|
||||
}
|
||||
|
||||
@ -898,12 +709,7 @@ const _super = (function (geti, seti) {
|
||||
//
|
||||
|
||||
function emitIdentifier(node: Identifier) {
|
||||
if (getEmitFlags(node) & EmitFlags.UMDDefine) {
|
||||
writeLines(umdHelper);
|
||||
}
|
||||
else {
|
||||
write(getTextOfNode(node, /*includeTrivia*/ false));
|
||||
}
|
||||
write(getTextOfNode(node, /*includeTrivia*/ false));
|
||||
}
|
||||
|
||||
//
|
||||
@ -2207,93 +2013,39 @@ const _super = (function (geti, seti) {
|
||||
return statements.length;
|
||||
}
|
||||
|
||||
function emitHelpers(node: Node) {
|
||||
const emitFlags = getEmitFlags(node);
|
||||
let helpersEmitted = false;
|
||||
if (emitFlags & EmitFlags.EmitEmitHelpers) {
|
||||
helpersEmitted = emitEmitHelpers(currentSourceFile);
|
||||
}
|
||||
|
||||
if (emitFlags & EmitFlags.EmitExportStar) {
|
||||
writeLines(exportStarHelper);
|
||||
helpersEmitted = true;
|
||||
}
|
||||
|
||||
if (emitFlags & EmitFlags.EmitSuperHelper) {
|
||||
writeLines(superHelper);
|
||||
helpersEmitted = true;
|
||||
}
|
||||
|
||||
if (emitFlags & EmitFlags.EmitAdvancedSuperHelper) {
|
||||
writeLines(advancedSuperHelper);
|
||||
helpersEmitted = true;
|
||||
}
|
||||
|
||||
return helpersEmitted;
|
||||
}
|
||||
|
||||
function emitEmitHelpers(node: SourceFile) {
|
||||
// Only emit helpers if the user did not say otherwise.
|
||||
if (compilerOptions.noEmitHelpers) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't emit helpers if we can import them.
|
||||
if (compilerOptions.importHelpers
|
||||
&& (isExternalModule(node) || compilerOptions.isolatedModules)) {
|
||||
return false;
|
||||
}
|
||||
function emitHelpers(node: Node, isBundle?: boolean) {
|
||||
const sourceFile = isSourceFile(node) ? node : currentSourceFile;
|
||||
const shouldSkip = compilerOptions.noEmitHelpers || (sourceFile && getExternalHelpersModuleName(sourceFile) !== undefined);
|
||||
const shouldBundle = isSourceFile(node) && !isOwnFileEmit;
|
||||
|
||||
let helpersEmitted = false;
|
||||
const helpers = getEmitHelpers(node);
|
||||
if (helpers) {
|
||||
for (const helper of stableSort(helpers, compareEmitHelpers)) {
|
||||
if (!helper.scoped) {
|
||||
// Skip the helper if it can be skipped and the noEmitHelpers compiler
|
||||
// option is set, or if it can be imported and the importHelpers compiler
|
||||
// option is set.
|
||||
if (shouldSkip) continue;
|
||||
|
||||
// Only Emit __extends function when target ES5.
|
||||
// For target ES6 and above, we can emit classDeclaration as is.
|
||||
if ((languageVersion < ScriptTarget.ES2015) && (!extendsEmitted && node.flags & NodeFlags.HasClassExtends)) {
|
||||
writeLines(extendsHelper);
|
||||
extendsEmitted = true;
|
||||
helpersEmitted = true;
|
||||
}
|
||||
// Skip the helper if it can be bundled but hasn't already been emitted and we
|
||||
// are emitting a bundled module.
|
||||
if (shouldBundle) {
|
||||
if (bundledHelpers[helper.name]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((languageVersion < ScriptTarget.ESNext || currentSourceFile.scriptKind === ScriptKind.JSX || currentSourceFile.scriptKind === ScriptKind.TSX) &&
|
||||
compilerOptions.jsx !== JsxEmit.Preserve &&
|
||||
!assignEmitted &&
|
||||
node.flags & NodeFlags.HasSpreadAttribute) {
|
||||
writeLines(assignHelper);
|
||||
assignEmitted = true;
|
||||
}
|
||||
bundledHelpers[helper.name] = true;
|
||||
}
|
||||
}
|
||||
else if (isBundle) {
|
||||
// Skip the helper if it is scoped and we are emitting bundled helpers
|
||||
continue;
|
||||
}
|
||||
|
||||
if (languageVersion < ScriptTarget.ESNext && !restEmitted && node.flags & NodeFlags.HasRestAttribute) {
|
||||
writeLines(restHelper);
|
||||
restEmitted = true;
|
||||
}
|
||||
|
||||
if (!decorateEmitted && node.flags & NodeFlags.HasDecorators) {
|
||||
writeLines(decorateHelper);
|
||||
if (compilerOptions.emitDecoratorMetadata) {
|
||||
writeLines(metadataHelper);
|
||||
writeLines(helper.text);
|
||||
helpersEmitted = true;
|
||||
}
|
||||
|
||||
decorateEmitted = true;
|
||||
helpersEmitted = true;
|
||||
}
|
||||
|
||||
if (!paramEmitted && node.flags & NodeFlags.HasParamDecorators) {
|
||||
writeLines(paramHelper);
|
||||
paramEmitted = true;
|
||||
helpersEmitted = true;
|
||||
}
|
||||
|
||||
// Only emit __awaiter function when target ES5/ES6.
|
||||
// Only emit __generator function when target ES5.
|
||||
// For target ES2017 and above, we can emit async/await as is.
|
||||
if ((languageVersion < ScriptTarget.ES2017) && (!awaiterEmitted && node.flags & NodeFlags.HasAsyncFunctions)) {
|
||||
writeLines(awaiterHelper);
|
||||
if (languageVersion < ScriptTarget.ES2015) {
|
||||
writeLines(generatorHelper);
|
||||
}
|
||||
|
||||
awaiterEmitted = true;
|
||||
helpersEmitted = true;
|
||||
}
|
||||
|
||||
if (helpersEmitted) {
|
||||
@ -2304,9 +2056,10 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
|
||||
function writeLines(text: string): void {
|
||||
const lines = text.split(/\r\n|\r|\n/g);
|
||||
const lines = text.split(/\r\n?|\n/g);
|
||||
const indentation = guessIndentation(lines);
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
const line = indentation ? lines[i].slice(indentation) : lines[i];
|
||||
if (line.length) {
|
||||
if (i > 0) {
|
||||
writeLine();
|
||||
@ -2316,6 +2069,21 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
}
|
||||
|
||||
function guessIndentation(lines: string[]) {
|
||||
let indentation: number;
|
||||
for (const line of lines) {
|
||||
for (let i = 0; i < line.length && (indentation === undefined || i < indentation); i++) {
|
||||
if (!isWhiteSpace(line.charCodeAt(i))) {
|
||||
if (indentation === undefined || i < indentation) {
|
||||
indentation = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return indentation;
|
||||
}
|
||||
|
||||
//
|
||||
// Helpers
|
||||
//
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -61,7 +61,7 @@ namespace ts {
|
||||
return { resolvedModule: resolved && resolvedModuleFromResolved(resolved, isExternalLibraryImport), failedLookupLocations };
|
||||
}
|
||||
|
||||
function moduleHasNonRelativeName(moduleName: string): boolean {
|
||||
export function moduleHasNonRelativeName(moduleName: string): boolean {
|
||||
return !(isRootedDiskPath(moduleName) || isExternalModuleNameRelative(moduleName));
|
||||
}
|
||||
|
||||
|
||||
@ -1168,7 +1168,7 @@ namespace ts {
|
||||
|
||||
function parsePropertyNameWorker(allowComputedPropertyNames: boolean): PropertyName {
|
||||
if (token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NumericLiteral) {
|
||||
return parseLiteralNode(/*internName*/ true);
|
||||
return <StringLiteral | NumericLiteral>parseLiteralNode(/*internName*/ true);
|
||||
}
|
||||
if (allowComputedPropertyNames && token() === SyntaxKind.OpenBracketToken) {
|
||||
return parseComputedPropertyName();
|
||||
@ -5514,7 +5514,7 @@ namespace ts {
|
||||
node.flags |= NodeFlags.GlobalAugmentation;
|
||||
}
|
||||
else {
|
||||
node.name = parseLiteralNode(/*internName*/ true);
|
||||
node.name = <StringLiteral>parseLiteralNode(/*internName*/ true);
|
||||
}
|
||||
|
||||
if (token() === SyntaxKind.OpenBraceToken) {
|
||||
|
||||
@ -27,84 +27,6 @@ namespace ts {
|
||||
EmitNotifications = 1 << 1,
|
||||
}
|
||||
|
||||
export interface TransformationResult {
|
||||
/**
|
||||
* Gets the transformed source files.
|
||||
*/
|
||||
transformed: SourceFile[];
|
||||
|
||||
/**
|
||||
* Emits the substitute for a node, if one is available; otherwise, emits the node.
|
||||
*
|
||||
* @param emitContext The current emit context.
|
||||
* @param node The node to substitute.
|
||||
* @param emitCallback A callback used to emit the node or its substitute.
|
||||
*/
|
||||
emitNodeWithSubstitution(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
|
||||
|
||||
/**
|
||||
* Emits a node with possible notification.
|
||||
*
|
||||
* @param emitContext The current emit context.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback A callback used to emit the node.
|
||||
*/
|
||||
emitNodeWithNotification(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
|
||||
}
|
||||
|
||||
export interface TransformationContext extends LexicalEnvironment {
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getEmitResolver(): EmitResolver;
|
||||
getEmitHost(): EmitHost;
|
||||
|
||||
/**
|
||||
* Hoists a function declaration to the containing scope.
|
||||
*/
|
||||
hoistFunctionDeclaration(node: FunctionDeclaration): void;
|
||||
|
||||
/**
|
||||
* Hoists a variable declaration to the containing scope.
|
||||
*/
|
||||
hoistVariableDeclaration(node: Identifier): void;
|
||||
|
||||
/**
|
||||
* Enables expression substitutions in the pretty printer for the provided SyntaxKind.
|
||||
*/
|
||||
enableSubstitution(kind: SyntaxKind): void;
|
||||
|
||||
/**
|
||||
* Determines whether expression substitutions are enabled for the provided node.
|
||||
*/
|
||||
isSubstitutionEnabled(node: Node): boolean;
|
||||
|
||||
/**
|
||||
* Hook used by transformers to substitute expressions just before they
|
||||
* are emitted by the pretty printer.
|
||||
*/
|
||||
onSubstituteNode?: (emitContext: EmitContext, node: Node) => Node;
|
||||
|
||||
/**
|
||||
* Enables before/after emit notifications in the pretty printer for the provided
|
||||
* SyntaxKind.
|
||||
*/
|
||||
enableEmitNotification(kind: SyntaxKind): void;
|
||||
|
||||
/**
|
||||
* Determines whether before/after emit notifications should be raised in the pretty
|
||||
* printer when it emits a node.
|
||||
*/
|
||||
isEmitNotificationEnabled(node: Node): boolean;
|
||||
|
||||
/**
|
||||
* Hook used to allow transformers to capture state before or after
|
||||
* the printer emits a node.
|
||||
*/
|
||||
onEmitNode?: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type Transformer = (context: TransformationContext) => (node: SourceFile) => SourceFile;
|
||||
|
||||
export function getTransformers(compilerOptions: CompilerOptions) {
|
||||
const jsx = compilerOptions.jsx;
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
@ -154,14 +76,18 @@ namespace ts {
|
||||
* @param transforms An array of Transformers.
|
||||
*/
|
||||
export function transformFiles(resolver: EmitResolver, host: EmitHost, sourceFiles: SourceFile[], transformers: Transformer[]): TransformationResult {
|
||||
const lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = [];
|
||||
const lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = [];
|
||||
const enabledSyntaxKindFeatures = new Array<SyntaxKindFeatureFlags>(SyntaxKind.Count);
|
||||
|
||||
let lexicalEnvironmentDisabled = false;
|
||||
|
||||
let lexicalEnvironmentVariableDeclarations: VariableDeclaration[];
|
||||
let lexicalEnvironmentFunctionDeclarations: FunctionDeclaration[];
|
||||
let lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = [];
|
||||
let lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = [];
|
||||
let lexicalEnvironmentStackOffset = 0;
|
||||
let hoistedVariableDeclarations: VariableDeclaration[];
|
||||
let hoistedFunctionDeclarations: FunctionDeclaration[];
|
||||
let lexicalEnvironmentDisabled: boolean;
|
||||
let lexicalEnvironmentSuspended = false;
|
||||
|
||||
let emitHelpers: EmitHelper[];
|
||||
|
||||
// The transformation context is provided to each transformer as part of transformer
|
||||
// initialization.
|
||||
@ -169,10 +95,14 @@ namespace ts {
|
||||
getCompilerOptions: () => host.getCompilerOptions(),
|
||||
getEmitResolver: () => resolver,
|
||||
getEmitHost: () => host,
|
||||
startLexicalEnvironment,
|
||||
suspendLexicalEnvironment,
|
||||
resumeLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
hoistVariableDeclaration,
|
||||
hoistFunctionDeclaration,
|
||||
startLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
requestEmitHelper,
|
||||
readEmitHelpers,
|
||||
onSubstituteNode: (_emitContext, node) => node,
|
||||
enableSubstitution,
|
||||
isSubstitutionEnabled,
|
||||
@ -285,11 +215,11 @@ namespace ts {
|
||||
function hoistVariableDeclaration(name: Identifier): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
const decl = createVariableDeclaration(name);
|
||||
if (!hoistedVariableDeclarations) {
|
||||
hoistedVariableDeclarations = [decl];
|
||||
if (!lexicalEnvironmentVariableDeclarations) {
|
||||
lexicalEnvironmentVariableDeclarations = [decl];
|
||||
}
|
||||
else {
|
||||
hoistedVariableDeclarations.push(decl);
|
||||
lexicalEnvironmentVariableDeclarations.push(decl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -298,11 +228,11 @@ namespace ts {
|
||||
*/
|
||||
function hoistFunctionDeclaration(func: FunctionDeclaration): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
if (!hoistedFunctionDeclarations) {
|
||||
hoistedFunctionDeclarations = [func];
|
||||
if (!lexicalEnvironmentFunctionDeclarations) {
|
||||
lexicalEnvironmentFunctionDeclarations = [func];
|
||||
}
|
||||
else {
|
||||
hoistedFunctionDeclarations.push(func);
|
||||
lexicalEnvironmentFunctionDeclarations.push(func);
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,16 +242,31 @@ namespace ts {
|
||||
*/
|
||||
function startLexicalEnvironment(): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot start a lexical environment during the print phase.");
|
||||
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
|
||||
|
||||
// Save the current lexical environment. Rather than resizing the array we adjust the
|
||||
// stack size variable. This allows us to reuse existing array slots we've
|
||||
// already allocated between transformations to avoid allocation and GC overhead during
|
||||
// transformation.
|
||||
lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset] = hoistedVariableDeclarations;
|
||||
lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset] = hoistedFunctionDeclarations;
|
||||
lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentVariableDeclarations;
|
||||
lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentFunctionDeclarations;
|
||||
lexicalEnvironmentStackOffset++;
|
||||
hoistedVariableDeclarations = undefined;
|
||||
hoistedFunctionDeclarations = undefined;
|
||||
lexicalEnvironmentVariableDeclarations = undefined;
|
||||
lexicalEnvironmentFunctionDeclarations = undefined;
|
||||
}
|
||||
|
||||
/** Suspends the current lexical environment, usually after visiting a parameter list. */
|
||||
function suspendLexicalEnvironment(): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot suspend a lexical environment during the print phase.");
|
||||
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is already suspended.");
|
||||
lexicalEnvironmentSuspended = true;
|
||||
}
|
||||
|
||||
/** Resumes a suspended lexical environment, usually before visiting a function body. */
|
||||
function resumeLexicalEnvironment(): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot resume a lexical environment during the print phase.");
|
||||
Debug.assert(lexicalEnvironmentSuspended, "Lexical environment is not suspended.");
|
||||
lexicalEnvironmentSuspended = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -330,17 +275,18 @@ namespace ts {
|
||||
*/
|
||||
function endLexicalEnvironment(): Statement[] {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot end a lexical environment during the print phase.");
|
||||
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
|
||||
|
||||
let statements: Statement[];
|
||||
if (hoistedVariableDeclarations || hoistedFunctionDeclarations) {
|
||||
if (hoistedFunctionDeclarations) {
|
||||
statements = [...hoistedFunctionDeclarations];
|
||||
if (lexicalEnvironmentVariableDeclarations || lexicalEnvironmentFunctionDeclarations) {
|
||||
if (lexicalEnvironmentFunctionDeclarations) {
|
||||
statements = [...lexicalEnvironmentFunctionDeclarations];
|
||||
}
|
||||
|
||||
if (hoistedVariableDeclarations) {
|
||||
if (lexicalEnvironmentVariableDeclarations) {
|
||||
const statement = createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(hoistedVariableDeclarations)
|
||||
createVariableDeclarationList(lexicalEnvironmentVariableDeclarations)
|
||||
);
|
||||
|
||||
if (!statements) {
|
||||
@ -354,9 +300,26 @@ namespace ts {
|
||||
|
||||
// Restore the previous lexical environment.
|
||||
lexicalEnvironmentStackOffset--;
|
||||
hoistedVariableDeclarations = lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset];
|
||||
hoistedFunctionDeclarations = lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset];
|
||||
lexicalEnvironmentVariableDeclarations = lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset];
|
||||
lexicalEnvironmentFunctionDeclarations = lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset];
|
||||
if (lexicalEnvironmentStackOffset === 0) {
|
||||
lexicalEnvironmentVariableDeclarationsStack = [];
|
||||
lexicalEnvironmentFunctionDeclarationsStack = [];
|
||||
}
|
||||
return statements;
|
||||
}
|
||||
|
||||
function requestEmitHelper(helper: EmitHelper): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
Debug.assert(!helper.scoped, "Cannot request a scoped emit helper.");
|
||||
emitHelpers = append(emitHelpers, helper);
|
||||
}
|
||||
|
||||
function readEmitHelpers(): EmitHelper[] | undefined {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
const helpers = emitHelpers;
|
||||
emitHelpers = undefined;
|
||||
return helpers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -17,84 +17,75 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
if (node.transformFlags & TransformFlags.ES2016) {
|
||||
return visitorWorker(node);
|
||||
}
|
||||
else if (node.transformFlags & TransformFlags.ContainsES2016) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
else {
|
||||
if ((node.transformFlags & TransformFlags.ContainsES2016) === 0) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
function visitorWorker(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return visitBinaryExpression(<BinaryExpression>node);
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
}
|
||||
|
||||
function visitBinaryExpression(node: BinaryExpression): Expression {
|
||||
// We are here because ES2016 adds support for the exponentiation operator.
|
||||
switch (node.operatorToken.kind) {
|
||||
case SyntaxKind.AsteriskAsteriskEqualsToken:
|
||||
return visitExponentiationAssignmentExpression(node);
|
||||
case SyntaxKind.AsteriskAsteriskToken:
|
||||
return visitExponentiationExpression(node);
|
||||
default:
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
}
|
||||
|
||||
function visitExponentiationAssignmentExpression(node: BinaryExpression) {
|
||||
let target: Expression;
|
||||
let value: Expression;
|
||||
const left = visitNode(node.left, visitor, isExpression);
|
||||
const right = visitNode(node.right, visitor, isExpression);
|
||||
if (node.operatorToken.kind === SyntaxKind.AsteriskAsteriskEqualsToken) {
|
||||
let target: Expression;
|
||||
let value: Expression;
|
||||
if (isElementAccessExpression(left)) {
|
||||
// Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)`
|
||||
const expressionTemp = createTempVariable(hoistVariableDeclaration);
|
||||
|
||||
const argumentExpressionTemp = createTempVariable(hoistVariableDeclaration);
|
||||
|
||||
target = createElementAccess(
|
||||
createAssignment(expressionTemp, left.expression, /*location*/ left.expression),
|
||||
createAssignment(argumentExpressionTemp, left.argumentExpression, /*location*/ left.argumentExpression),
|
||||
/*location*/ left
|
||||
);
|
||||
|
||||
value = createElementAccess(
|
||||
expressionTemp,
|
||||
argumentExpressionTemp,
|
||||
/*location*/ left
|
||||
);
|
||||
}
|
||||
else if (isPropertyAccessExpression(left)) {
|
||||
// Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)`
|
||||
const expressionTemp = createTempVariable(hoistVariableDeclaration);
|
||||
|
||||
target = createPropertyAccess(
|
||||
createAssignment(expressionTemp, left.expression, /*location*/ left.expression),
|
||||
left.name,
|
||||
/*location*/ left
|
||||
);
|
||||
|
||||
value = createPropertyAccess(
|
||||
expressionTemp,
|
||||
left.name,
|
||||
/*location*/ left
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Transforms `a **= b` into `a = Math.pow(a, b)`
|
||||
target = left;
|
||||
value = left;
|
||||
}
|
||||
|
||||
return createAssignment(target, createMathPow(value, right, /*location*/ node), /*location*/ node);
|
||||
if (isElementAccessExpression(left)) {
|
||||
// Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)`
|
||||
const expressionTemp = createTempVariable(hoistVariableDeclaration);
|
||||
const argumentExpressionTemp = createTempVariable(hoistVariableDeclaration);
|
||||
target = createElementAccess(
|
||||
createAssignment(expressionTemp, left.expression, /*location*/ left.expression),
|
||||
createAssignment(argumentExpressionTemp, left.argumentExpression, /*location*/ left.argumentExpression),
|
||||
/*location*/ left
|
||||
);
|
||||
value = createElementAccess(
|
||||
expressionTemp,
|
||||
argumentExpressionTemp,
|
||||
/*location*/ left
|
||||
);
|
||||
}
|
||||
else if (node.operatorToken.kind === SyntaxKind.AsteriskAsteriskToken) {
|
||||
// Transforms `a ** b` into `Math.pow(a, b)`
|
||||
return createMathPow(left, right, /*location*/ node);
|
||||
else if (isPropertyAccessExpression(left)) {
|
||||
// Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)`
|
||||
const expressionTemp = createTempVariable(hoistVariableDeclaration);
|
||||
target = createPropertyAccess(
|
||||
createAssignment(expressionTemp, left.expression, /*location*/ left.expression),
|
||||
left.name,
|
||||
/*location*/ left
|
||||
);
|
||||
value = createPropertyAccess(
|
||||
expressionTemp,
|
||||
left.name,
|
||||
/*location*/ left
|
||||
);
|
||||
}
|
||||
else {
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return visitEachChild(node, visitor, context);
|
||||
// Transforms `a **= b` into `a = Math.pow(a, b)`
|
||||
target = left;
|
||||
value = left;
|
||||
}
|
||||
return createAssignment(target, createMathPow(value, right, /*location*/ node), /*location*/ node);
|
||||
}
|
||||
|
||||
function visitExponentiationExpression(node: BinaryExpression) {
|
||||
// Transforms `a ** b` into `Math.pow(a, b)`
|
||||
const left = visitNode(node.left, visitor, isExpression);
|
||||
const right = visitNode(node.right, visitor, isExpression);
|
||||
return createMathPow(left, right, /*location*/ node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,15 +5,15 @@
|
||||
namespace ts {
|
||||
type SuperContainer = ClassDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration;
|
||||
|
||||
const enum ES2017SubstitutionFlags {
|
||||
/** Enables substitutions for async methods with `super` calls. */
|
||||
AsyncMethodsWithSuper = 1 << 0
|
||||
}
|
||||
|
||||
export function transformES2017(context: TransformationContext) {
|
||||
|
||||
const enum ES2017SubstitutionFlags {
|
||||
/** Enables substitutions for async methods with `super` calls. */
|
||||
AsyncMethodsWithSuper = 1 << 0
|
||||
}
|
||||
|
||||
const {
|
||||
startLexicalEnvironment,
|
||||
resumeLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
} = context;
|
||||
|
||||
@ -22,19 +22,14 @@ namespace ts {
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
|
||||
// These variables contain state that changes as we descend into the tree.
|
||||
let currentSourceFileExternalHelpersModuleName: Identifier;
|
||||
let currentSourceFile: SourceFile;
|
||||
|
||||
/**
|
||||
* Keeps track of whether expression substitution has been enabled for specific edge cases.
|
||||
* They are persisted between each SourceFile transformation and should not be reset.
|
||||
*/
|
||||
let enabledSubstitutions: ES2017SubstitutionFlags;
|
||||
|
||||
/**
|
||||
* Keeps track of whether we are within any containing namespaces when performing
|
||||
* just-in-time substitution while printing an expression identifier.
|
||||
*/
|
||||
let applicableSubstitutions: ES2017SubstitutionFlags;
|
||||
|
||||
/**
|
||||
* This keeps track of containers where `super` is valid, for use with
|
||||
* just-in-time substitution for `super` expressions inside of async methods.
|
||||
@ -49,8 +44,6 @@ namespace ts {
|
||||
context.onEmitNode = onEmitNode;
|
||||
context.onSubstituteNode = onSubstituteNode;
|
||||
|
||||
let currentScope: SourceFile | Block | ModuleBlock | CaseBlock;
|
||||
|
||||
return transformSourceFile;
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
@ -58,23 +51,20 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
currentSourceFileExternalHelpersModuleName = node.externalHelpersModuleName;
|
||||
currentSourceFile = node;
|
||||
|
||||
return visitEachChild(node, visitor, context);
|
||||
const visited = visitEachChild(node, visitor, context);
|
||||
addEmitHelpers(visited, context.readEmitHelpers());
|
||||
|
||||
currentSourceFile = undefined;
|
||||
return visited;
|
||||
}
|
||||
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
if (node.transformFlags & TransformFlags.ES2017) {
|
||||
return visitorWorker(node);
|
||||
}
|
||||
else if (node.transformFlags & TransformFlags.ContainsES2017) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
if ((node.transformFlags & TransformFlags.ContainsES2017) === 0) {
|
||||
return node;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function visitorWorker(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
// ES2017 async modifier should be elided for targets < ES2017
|
||||
@ -101,17 +91,16 @@ namespace ts {
|
||||
return visitArrowFunction(<ArrowFunction>node);
|
||||
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return node;
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an await expression.
|
||||
* Visits an AwaitExpression node.
|
||||
*
|
||||
* This function will be called any time a ES2017 await expression is encountered.
|
||||
*
|
||||
* @param node The await expression node.
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitAwaitExpression(node: AwaitExpression): Expression {
|
||||
return setOriginalNode(
|
||||
@ -125,143 +114,102 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a method declaration of a class.
|
||||
* Visits a MethodDeclaration node.
|
||||
*
|
||||
* This function will be called when one of the following conditions are met:
|
||||
* - The node is marked as async
|
||||
*
|
||||
* @param node The method node.
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitMethodDeclaration(node: MethodDeclaration) {
|
||||
if (!isAsyncFunctionLike(node)) {
|
||||
return node;
|
||||
}
|
||||
const method = createMethod(
|
||||
return updateMethod(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node),
|
||||
/*location*/ node
|
||||
isAsyncFunctionLike(node)
|
||||
? transformAsyncFunctionBody(node)
|
||||
: visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
|
||||
// While we emit the source map for the node after skipping decorators and modifiers,
|
||||
// we need to emit the comments for the original range.
|
||||
setCommentRange(method, node);
|
||||
setSourceMapRange(method, moveRangePastDecorators(node));
|
||||
setOriginalNode(method, node);
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a function declaration.
|
||||
* Visits a FunctionDeclaration node.
|
||||
*
|
||||
* This function will be called when one of the following conditions are met:
|
||||
* - The node is marked async
|
||||
*
|
||||
* @param node The function node.
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult<Statement> {
|
||||
if (!isAsyncFunctionLike(node)) {
|
||||
return node;
|
||||
}
|
||||
const func = createFunctionDeclaration(
|
||||
return updateFunctionDeclaration(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node),
|
||||
/*location*/ node
|
||||
isAsyncFunctionLike(node)
|
||||
? transformAsyncFunctionBody(node)
|
||||
: visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
setOriginalNode(func, node);
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a function expression node.
|
||||
* Visits a FunctionExpression node.
|
||||
*
|
||||
* This function will be called when one of the following conditions are met:
|
||||
* - The node is marked async
|
||||
*
|
||||
* @param node The function expression node.
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitFunctionExpression(node: FunctionExpression): Expression {
|
||||
if (!isAsyncFunctionLike(node)) {
|
||||
return node;
|
||||
}
|
||||
if (nodeIsMissing(node.body)) {
|
||||
return createOmittedExpression();
|
||||
}
|
||||
|
||||
const func = createFunctionExpression(
|
||||
return updateFunctionExpression(
|
||||
node,
|
||||
/*modifiers*/ undefined,
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node),
|
||||
/*location*/ node
|
||||
isAsyncFunctionLike(node)
|
||||
? transformAsyncFunctionBody(node)
|
||||
: visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
|
||||
setOriginalNode(func, node);
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
/**
|
||||
* @remarks
|
||||
* Visits an ArrowFunction.
|
||||
*
|
||||
* This function will be called when one of the following conditions are met:
|
||||
* - The node is marked async
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitArrowFunction(node: ArrowFunction) {
|
||||
if (!isAsyncFunctionLike(node)) {
|
||||
return node;
|
||||
}
|
||||
const func = createArrowFunction(
|
||||
return updateArrowFunction(
|
||||
node,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
node.equalsGreaterThanToken,
|
||||
transformConciseBody(node),
|
||||
/*location*/ node
|
||||
isAsyncFunctionLike(node)
|
||||
? transformAsyncFunctionBody(node)
|
||||
: visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
|
||||
setOriginalNode(func, node);
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
function transformFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody {
|
||||
return <FunctionBody>transformAsyncFunctionBody(node);
|
||||
}
|
||||
function transformAsyncFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody;
|
||||
function transformAsyncFunctionBody(node: ArrowFunction): ConciseBody;
|
||||
function transformAsyncFunctionBody(node: FunctionLikeDeclaration): ConciseBody {
|
||||
resumeLexicalEnvironment();
|
||||
|
||||
function transformConciseBody(node: ArrowFunction): ConciseBody {
|
||||
return transformAsyncFunctionBody(node);
|
||||
}
|
||||
|
||||
function transformFunctionBodyWorker(body: Block, start = 0) {
|
||||
const savedCurrentScope = currentScope;
|
||||
currentScope = body;
|
||||
startLexicalEnvironment();
|
||||
|
||||
const statements = visitNodes(body.statements, visitor, isStatement, start);
|
||||
const visited = updateBlock(body, statements);
|
||||
const declarations = endLexicalEnvironment();
|
||||
currentScope = savedCurrentScope;
|
||||
return mergeFunctionBodyLexicalEnvironment(visited, declarations);
|
||||
}
|
||||
|
||||
function transformAsyncFunctionBody(node: FunctionLikeDeclaration): ConciseBody | FunctionBody {
|
||||
const original = getOriginalNode(node, isFunctionLike);
|
||||
const nodeType = original.type;
|
||||
const promiseConstructor = languageVersion < ScriptTarget.ES2015 ? getPromiseConstructor(nodeType) : undefined;
|
||||
@ -274,14 +222,13 @@ namespace ts {
|
||||
// passed to `__awaiter` is executed inside of the callback to the
|
||||
// promise constructor.
|
||||
|
||||
|
||||
if (!isArrowFunction) {
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologueDirectives(statements, (<Block>node.body).statements, /*ensureUseStrict*/ false, visitor);
|
||||
statements.push(
|
||||
createReturn(
|
||||
createAwaiterHelper(
|
||||
currentSourceFileExternalHelpersModuleName,
|
||||
context,
|
||||
hasLexicalArguments,
|
||||
promiseConstructor,
|
||||
transformFunctionBodyWorker(<Block>node.body, statementOffset)
|
||||
@ -289,6 +236,8 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
|
||||
const block = createBlock(statements, /*location*/ node.body, /*multiLine*/ true);
|
||||
|
||||
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
|
||||
@ -296,57 +245,56 @@ namespace ts {
|
||||
if (languageVersion >= ScriptTarget.ES2015) {
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
setEmitFlags(block, EmitFlags.EmitAdvancedSuperHelper);
|
||||
addEmitHelper(block, advancedAsyncSuperHelper);
|
||||
}
|
||||
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
setEmitFlags(block, EmitFlags.EmitSuperHelper);
|
||||
addEmitHelper(block, asyncSuperHelper);
|
||||
}
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
else {
|
||||
return createAwaiterHelper(
|
||||
currentSourceFileExternalHelpersModuleName,
|
||||
const expression = createAwaiterHelper(
|
||||
context,
|
||||
hasLexicalArguments,
|
||||
promiseConstructor,
|
||||
<Block>transformConciseBodyWorker(node.body, /*forceBlockFunctionBody*/ true)
|
||||
transformFunctionBodyWorker(node.body)
|
||||
);
|
||||
|
||||
const declarations = endLexicalEnvironment();
|
||||
if (some(declarations)) {
|
||||
const block = convertToFunctionBody(expression);
|
||||
return updateBlock(block, createNodeArray(concatenate(block.statements, declarations), block.statements));
|
||||
}
|
||||
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
|
||||
function transformConciseBodyWorker(body: Block | Expression, forceBlockFunctionBody: boolean) {
|
||||
function transformFunctionBodyWorker(body: ConciseBody, start?: number) {
|
||||
if (isBlock(body)) {
|
||||
return transformFunctionBodyWorker(body);
|
||||
return updateBlock(body, visitLexicalEnvironment(body.statements, visitor, context, start));
|
||||
}
|
||||
else {
|
||||
startLexicalEnvironment();
|
||||
const visited: Expression | Block = visitNode(body, visitor, isConciseBody);
|
||||
const visited = convertToFunctionBody(visitNode(body, visitor, isConciseBody));
|
||||
const declarations = endLexicalEnvironment();
|
||||
const merged = mergeFunctionBodyLexicalEnvironment(visited, declarations);
|
||||
if (forceBlockFunctionBody && !isBlock(merged)) {
|
||||
return createBlock([
|
||||
createReturn(<Expression>merged)
|
||||
]);
|
||||
}
|
||||
else {
|
||||
return merged;
|
||||
}
|
||||
return updateBlock(visited, createNodeArray(concatenate(visited.statements, declarations), visited.statements));
|
||||
}
|
||||
}
|
||||
|
||||
function getPromiseConstructor(type: TypeNode) {
|
||||
if (type) {
|
||||
const typeName = getEntityNameFromTypeNode(type);
|
||||
if (typeName && isEntityName(typeName)) {
|
||||
const serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
|
||||
if (serializationKind === TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue
|
||||
|| serializationKind === TypeReferenceSerializationKind.Unknown) {
|
||||
return typeName;
|
||||
}
|
||||
const typeName = type && getEntityNameFromTypeNode(type);
|
||||
if (typeName && isEntityName(typeName)) {
|
||||
const serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
|
||||
if (serializationKind === TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue
|
||||
|| serializationKind === TypeReferenceSerializationKind.Unknown) {
|
||||
return typeName;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@ -452,18 +400,17 @@ namespace ts {
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
|
||||
const savedApplicableSubstitutions = applicableSubstitutions;
|
||||
const savedCurrentSuperContainer = currentSuperContainer;
|
||||
// If we need to support substitutions for `super` in an async method,
|
||||
// we should track it here.
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
|
||||
const savedCurrentSuperContainer = currentSuperContainer;
|
||||
currentSuperContainer = node;
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
currentSuperContainer = savedCurrentSuperContainer;
|
||||
}
|
||||
else {
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
}
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
|
||||
applicableSubstitutions = savedApplicableSubstitutions;
|
||||
currentSuperContainer = savedCurrentSuperContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -509,4 +456,63 @@ namespace ts {
|
||||
&& resolver.getNodeCheckFlags(currentSuperContainer) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding);
|
||||
}
|
||||
}
|
||||
|
||||
function createAwaiterHelper(context: TransformationContext, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) {
|
||||
context.requestEmitHelper(awaiterHelper);
|
||||
const generatorFunc = createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
createToken(SyntaxKind.AsteriskToken),
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
/*parameters*/ [],
|
||||
/*type*/ undefined,
|
||||
body
|
||||
);
|
||||
|
||||
// Mark this node as originally an async function
|
||||
(generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= EmitFlags.AsyncFunctionBody;
|
||||
|
||||
return createCall(
|
||||
getHelperName("__awaiter"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createThis(),
|
||||
hasLexicalArguments ? createIdentifier("arguments") : createVoidZero(),
|
||||
promiseConstructor ? createExpressionFromEntityName(promiseConstructor) : createVoidZero(),
|
||||
generatorFunc
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
const awaiterHelper: EmitHelper = {
|
||||
name: "typescript:awaiter",
|
||||
scoped: false,
|
||||
priority: 5,
|
||||
text: `
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments)).next());
|
||||
});
|
||||
};`
|
||||
};
|
||||
|
||||
const asyncSuperHelper: EmitHelper = {
|
||||
name: "typescript:async-super",
|
||||
scoped: true,
|
||||
text: `
|
||||
const _super = name => super[name];`
|
||||
};
|
||||
|
||||
const advancedAsyncSuperHelper: EmitHelper = {
|
||||
name: "typescript:advanced-async-super",
|
||||
scoped: true,
|
||||
text: `
|
||||
const _super = (function (geti, seti) {
|
||||
const cache = Object.create(null);
|
||||
return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
|
||||
})(name => super[name], (name, value) => super[name] = value);`
|
||||
};
|
||||
}
|
||||
|
||||
@ -5,41 +5,55 @@
|
||||
namespace ts {
|
||||
export function transformESNext(context: TransformationContext) {
|
||||
const {
|
||||
hoistVariableDeclaration,
|
||||
resumeLexicalEnvironment,
|
||||
endLexicalEnvironment
|
||||
} = context;
|
||||
let currentSourceFile: SourceFile;
|
||||
return transformSourceFile;
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
currentSourceFile = node;
|
||||
return visitEachChild(node, visitor, context);
|
||||
if (isDeclarationFile(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
const visited = visitEachChild(node, visitor, context);
|
||||
addEmitHelpers(visited, context.readEmitHelpers());
|
||||
return visited;
|
||||
}
|
||||
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
if (node.transformFlags & TransformFlags.ESNext) {
|
||||
return visitorWorker(node);
|
||||
}
|
||||
else if (node.transformFlags & TransformFlags.ContainsESNext) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
else {
|
||||
return node;
|
||||
}
|
||||
return visitorWorker(node, /*noDestructuringValue*/ false);
|
||||
}
|
||||
|
||||
function visitorWorker(node: Node): VisitResult<Node> {
|
||||
function visitorNoDestructuringValue(node: Node): VisitResult<Node> {
|
||||
return visitorWorker(node, /*noDestructuringValue*/ true);
|
||||
}
|
||||
|
||||
function visitorWorker(node: Node, noDestructuringValue: boolean): VisitResult<Node> {
|
||||
if ((node.transformFlags & TransformFlags.ContainsESNext) === 0) {
|
||||
return node;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return visitObjectLiteralExpression(node as ObjectLiteralExpression);
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return visitBinaryExpression(node as BinaryExpression);
|
||||
return visitBinaryExpression(node as BinaryExpression, noDestructuringValue);
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return visitVariableDeclaration(node as VariableDeclaration);
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return visitForOfStatement(node as ForOfStatement);
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
return node;
|
||||
case SyntaxKind.ForStatement:
|
||||
return visitForStatement(node as ForStatement);
|
||||
case SyntaxKind.VoidExpression:
|
||||
return visitVoidExpression(node as VoidExpression);
|
||||
case SyntaxKind.Constructor:
|
||||
return visitConstructorDeclaration(node as ConstructorDeclaration);
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
return visitMethodDeclaration(node as MethodDeclaration);
|
||||
case SyntaxKind.GetAccessor:
|
||||
return visitGetAccessorDeclaration(node as GetAccessorDeclaration);
|
||||
case SyntaxKind.SetAccessor:
|
||||
return visitSetAccessorDeclaration(node as SetAccessorDeclaration);
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
return visitFunctionDeclaration(node as FunctionDeclaration);
|
||||
case SyntaxKind.FunctionExpression:
|
||||
@ -48,8 +62,11 @@ namespace ts {
|
||||
return visitArrowFunction(node as ArrowFunction);
|
||||
case SyntaxKind.Parameter:
|
||||
return visitParameter(node as ParameterDeclaration);
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
return visitExpressionStatement(node as ExpressionStatement);
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return visitParenthesizedExpression(node as ParenthesizedExpression, noDestructuringValue);
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
}
|
||||
@ -87,32 +104,51 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitObjectLiteralExpression(node: ObjectLiteralExpression): Expression {
|
||||
// spread elements emit like so:
|
||||
// non-spread elements are chunked together into object literals, and then all are passed to __assign:
|
||||
// { a, ...o, b } => __assign({a}, o, {b});
|
||||
// If the first element is a spread element, then the first argument to __assign is {}:
|
||||
// { ...o, a, b, ...o2 } => __assign({}, o, {a, b}, o2)
|
||||
if (forEach(node.properties, p => p.kind === SyntaxKind.SpreadAssignment)) {
|
||||
if (node.transformFlags & TransformFlags.ContainsObjectSpread) {
|
||||
// spread elements emit like so:
|
||||
// non-spread elements are chunked together into object literals, and then all are passed to __assign:
|
||||
// { a, ...o, b } => __assign({a}, o, {b});
|
||||
// If the first element is a spread element, then the first argument to __assign is {}:
|
||||
// { ...o, a, b, ...o2 } => __assign({}, o, {a, b}, o2)
|
||||
const objects = chunkObjectLiteralElements(node.properties);
|
||||
if (objects.length && objects[0].kind !== SyntaxKind.ObjectLiteralExpression) {
|
||||
objects.unshift(createObjectLiteral());
|
||||
}
|
||||
|
||||
return aggregateTransformFlags(createCall(createIdentifier("__assign"), undefined, objects));
|
||||
return createAssignHelper(context, objects);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitExpressionStatement(node: ExpressionStatement): ExpressionStatement {
|
||||
return visitEachChild(node, visitorNoDestructuringValue, context);
|
||||
}
|
||||
|
||||
function visitParenthesizedExpression(node: ParenthesizedExpression, noDestructuringValue: boolean): ParenthesizedExpression {
|
||||
return visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a BinaryExpression that contains a destructuring assignment.
|
||||
*
|
||||
* @param node A BinaryExpression node.
|
||||
*/
|
||||
function visitBinaryExpression(node: BinaryExpression): Expression {
|
||||
if (isDestructuringAssignment(node) && node.left.transformFlags & TransformFlags.AssertESNext) {
|
||||
return flattenDestructuringAssignment(context, node, /*needsDestructuringValue*/ true, hoistVariableDeclaration, visitor, /*transformRest*/ true);
|
||||
function visitBinaryExpression(node: BinaryExpression, noDestructuringValue: boolean): Expression {
|
||||
if (isDestructuringAssignment(node) && node.left.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
return flattenDestructuringAssignment(
|
||||
node,
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.ObjectRest,
|
||||
!noDestructuringValue
|
||||
);
|
||||
}
|
||||
else if (node.operatorToken.kind === SyntaxKind.CommaToken) {
|
||||
return updateBinary(
|
||||
node,
|
||||
visitNode(node.left, visitorNoDestructuringValue, isExpression),
|
||||
visitNode(node.right, noDestructuringValue ? visitorNoDestructuringValue : visitor, isExpression)
|
||||
);
|
||||
}
|
||||
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
@ -123,154 +159,254 @@ namespace ts {
|
||||
*/
|
||||
function visitVariableDeclaration(node: VariableDeclaration): VisitResult<VariableDeclaration> {
|
||||
// If we are here it is because the name contains a binding pattern with a rest somewhere in it.
|
||||
if (isBindingPattern(node.name) && node.name.transformFlags & TransformFlags.AssertESNext) {
|
||||
const result = flattenVariableDestructuring(node, /*value*/ undefined, visitor, /*recordTempVariable*/ undefined, /*transformRest*/ true);
|
||||
return result;
|
||||
if (isBindingPattern(node.name) && node.name.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
return flattenDestructuringBinding(
|
||||
node,
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.ObjectRest
|
||||
);
|
||||
}
|
||||
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitForStatement(node: ForStatement): VisitResult<Statement> {
|
||||
return updateFor(
|
||||
node,
|
||||
visitNode(node.initializer, visitorNoDestructuringValue, isForInitializer),
|
||||
visitNode(node.condition, visitor, isExpression),
|
||||
visitNode(node.incrementor, visitor, isExpression),
|
||||
visitNode(node.statement, visitor, isStatement)
|
||||
);
|
||||
}
|
||||
|
||||
function visitVoidExpression(node: VoidExpression) {
|
||||
return visitEachChild(node, visitorNoDestructuringValue, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a ForOfStatement and converts it into a ES2015-compatible ForOfStatement.
|
||||
*
|
||||
* @param node A ForOfStatement.
|
||||
*/
|
||||
function visitForOfStatement(node: ForOfStatement): VisitResult<Statement> {
|
||||
// The following ESNext code:
|
||||
//
|
||||
// for (let { x, y, ...rest } of expr) { }
|
||||
//
|
||||
// should be emitted as
|
||||
//
|
||||
// for (var _a of expr) {
|
||||
// let { x, y } = _a, rest = __rest(_a, ["x", "y"]);
|
||||
// }
|
||||
//
|
||||
// where _a is a temp emitted to capture the RHS.
|
||||
// When the left hand side is an expression instead of a let declaration,
|
||||
// the `let` before the `{ x, y }` is not emitted.
|
||||
// When the left hand side is a let/const, the v is renamed if there is
|
||||
// another v in scope.
|
||||
// Note that all assignments to the LHS are emitted in the body, including
|
||||
// all destructuring.
|
||||
// Note also that because an extra statement is needed to assign to the LHS,
|
||||
// for-of bodies are always emitted as blocks.
|
||||
|
||||
// for (<init> of <expression>) <statement>
|
||||
// where <init> is [let] variabledeclarationlist | expression
|
||||
const initializer = node.initializer;
|
||||
if (!isRestBindingPattern(initializer) && !isRestAssignment(initializer)) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
let leadingStatements: Statement[];
|
||||
let temp: Identifier;
|
||||
const initializer = skipParentheses(node.initializer);
|
||||
if (initializer.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (isVariableDeclarationList(initializer)) {
|
||||
temp = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const firstDeclaration = firstOrUndefined(initializer.declarations);
|
||||
const declarations = flattenDestructuringBinding(
|
||||
firstDeclaration,
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.ObjectRest,
|
||||
temp,
|
||||
/*doNotRecordTempVariablesInLine*/ false,
|
||||
/*skipInitializer*/ true,
|
||||
);
|
||||
if (some(declarations)) {
|
||||
const statement = createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
updateVariableDeclarationList(initializer, declarations),
|
||||
/*location*/ initializer
|
||||
);
|
||||
leadingStatements = append(leadingStatements, statement);
|
||||
}
|
||||
}
|
||||
else if (isAssignmentPattern(initializer)) {
|
||||
temp = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const expression = flattenDestructuringAssignment(
|
||||
aggregateTransformFlags(createAssignment(initializer, temp, /*location*/ node.initializer)),
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.ObjectRest
|
||||
);
|
||||
leadingStatements = append(leadingStatements, createStatement(expression, /*location*/ node.initializer));
|
||||
}
|
||||
}
|
||||
|
||||
return convertForOf(node, undefined, visitor, noop, context, /*transformRest*/ true);
|
||||
}
|
||||
|
||||
function isRestBindingPattern(initializer: ForInitializer) {
|
||||
if (isVariableDeclarationList(initializer)) {
|
||||
const declaration = firstOrUndefined(initializer.declarations);
|
||||
return declaration && declaration.name &&
|
||||
declaration.name.kind === SyntaxKind.ObjectBindingPattern &&
|
||||
!!(declaration.name.transformFlags & TransformFlags.ContainsSpreadExpression);
|
||||
if (temp) {
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
const statement = visitNode(node.statement, visitor, isStatement);
|
||||
const block = isBlock(statement)
|
||||
? updateBlock(statement, createNodeArray(concatenate(leadingStatements, statement.statements), statement.statements))
|
||||
: createBlock(append(leadingStatements, statement), statement, /*multiLine*/ true);
|
||||
return updateForOf(
|
||||
node,
|
||||
createVariableDeclarationList(
|
||||
[
|
||||
createVariableDeclaration(temp, /*type*/ undefined, /*initializer*/ undefined, node.initializer)
|
||||
],
|
||||
node.initializer,
|
||||
NodeFlags.Let
|
||||
),
|
||||
expression,
|
||||
block
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isRestAssignment(initializer: ForInitializer) {
|
||||
return initializer.kind === SyntaxKind.ObjectLiteralExpression &&
|
||||
initializer.transformFlags & TransformFlags.ContainsSpreadExpression;
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitParameter(node: ParameterDeclaration): ParameterDeclaration {
|
||||
if (isObjectRestParameter(node)) {
|
||||
if (node.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
// Binding patterns are converted into a generated name and are
|
||||
// evaluated inside the function body.
|
||||
return setOriginalNode(
|
||||
createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
getGeneratedNameForNode(node),
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
node.initializer,
|
||||
/*location*/ node
|
||||
),
|
||||
/*original*/ node
|
||||
return updateParameter(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
node.dotDotDotToken,
|
||||
getGeneratedNameForNode(node),
|
||||
/*type*/ undefined,
|
||||
visitNode(node.initializer, visitor, isExpression)
|
||||
);
|
||||
}
|
||||
else {
|
||||
return node;
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function isObjectRestParameter(node: ParameterDeclaration) {
|
||||
return node.name &&
|
||||
node.name.kind === SyntaxKind.ObjectBindingPattern &&
|
||||
!!(node.name.transformFlags & TransformFlags.ContainsSpreadExpression);
|
||||
function visitConstructorDeclaration(node: ConstructorDeclaration) {
|
||||
return updateConstructor(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
}
|
||||
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration): FunctionDeclaration {
|
||||
const hasRest = forEach(node.parameters, isObjectRestParameter);
|
||||
const body = hasRest ?
|
||||
transformFunctionBody(node, visitor, currentSourceFile, context, noop, /*convertObjectRest*/ true) as Block :
|
||||
visitEachChild(node.body, visitor, context);
|
||||
function visitGetAccessorDeclaration(node: GetAccessorDeclaration) {
|
||||
return updateGetAccessor(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
visitNode(node.name, visitor, isPropertyName),
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
}
|
||||
|
||||
return setOriginalNode(
|
||||
createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
/*type*/ undefined,
|
||||
body,
|
||||
/*location*/ node
|
||||
),
|
||||
/*original*/ node);
|
||||
function visitSetAccessorDeclaration(node: SetAccessorDeclaration) {
|
||||
return updateSetAccessor(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
visitNode(node.name, visitor, isPropertyName),
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
}
|
||||
|
||||
function visitMethodDeclaration(node: MethodDeclaration) {
|
||||
return updateMethod(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
visitNode(node.name, visitor, isPropertyName),
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
}
|
||||
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration) {
|
||||
return updateFunctionDeclaration(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
}
|
||||
|
||||
function visitArrowFunction(node: ArrowFunction) {
|
||||
const hasRest = forEach(node.parameters, isObjectRestParameter);
|
||||
const body = hasRest ?
|
||||
transformFunctionBody(node, visitor, currentSourceFile, context, noop, /*convertObjectRest*/ true) as Block :
|
||||
visitEachChild(node.body, visitor, context);
|
||||
const func = setOriginalNode(
|
||||
createArrowFunction(
|
||||
node.modifiers,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
/*type*/ undefined,
|
||||
node.equalsGreaterThanToken,
|
||||
body,
|
||||
/*location*/ node
|
||||
),
|
||||
/*original*/ node
|
||||
return updateArrowFunction(
|
||||
node,
|
||||
node.modifiers,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
setEmitFlags(func, EmitFlags.CapturesThis);
|
||||
return func;
|
||||
}
|
||||
|
||||
function visitFunctionExpression(node: FunctionExpression): Expression {
|
||||
const hasRest = forEach(node.parameters, isObjectRestParameter);
|
||||
const body = hasRest ?
|
||||
transformFunctionBody(node, visitor, currentSourceFile, context, noop, /*convertObjectRest*/ true) as Block :
|
||||
visitEachChild(node.body, visitor, context);
|
||||
return setOriginalNode(
|
||||
createFunctionExpression(
|
||||
node.modifiers,
|
||||
node.asteriskToken,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
/*type*/ undefined,
|
||||
body,
|
||||
/*location*/ node
|
||||
),
|
||||
/*original*/ node
|
||||
function visitFunctionExpression(node: FunctionExpression) {
|
||||
return updateFunctionExpression(
|
||||
node,
|
||||
node.modifiers,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
}
|
||||
|
||||
function transformFunctionBody(node: FunctionDeclaration | FunctionExpression | ConstructorDeclaration | MethodDeclaration | AccessorDeclaration): FunctionBody;
|
||||
function transformFunctionBody(node: ArrowFunction): ConciseBody;
|
||||
function transformFunctionBody(node: FunctionLikeDeclaration): ConciseBody {
|
||||
resumeLexicalEnvironment();
|
||||
let leadingStatements: Statement[];
|
||||
for (const parameter of node.parameters) {
|
||||
if (parameter.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
const temp = getGeneratedNameForNode(parameter);
|
||||
const declarations = flattenDestructuringBinding(
|
||||
parameter,
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.ObjectRest,
|
||||
temp,
|
||||
/*doNotRecordTempVariablesInLine*/ false,
|
||||
/*skipInitializer*/ true,
|
||||
);
|
||||
if (some(declarations)) {
|
||||
const statement = createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(
|
||||
declarations
|
||||
)
|
||||
);
|
||||
setEmitFlags(statement, EmitFlags.CustomPrologue);
|
||||
leadingStatements = append(leadingStatements, statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
const body = visitNode(node.body, visitor, isConciseBody);
|
||||
const trailingStatements = endLexicalEnvironment();
|
||||
if (some(leadingStatements) || some(trailingStatements)) {
|
||||
const block = convertToFunctionBody(body, /*multiLine*/ true);
|
||||
return updateBlock(block, createNodeArray(concatenate(concatenate(leadingStatements, block.statements), trailingStatements), block.statements));
|
||||
}
|
||||
return body;
|
||||
}
|
||||
}
|
||||
|
||||
const assignHelper: EmitHelper = {
|
||||
name: "typescript:assign",
|
||||
scoped: false,
|
||||
priority: 1,
|
||||
text: `
|
||||
var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};`
|
||||
};
|
||||
|
||||
export function createAssignHelper(context: TransformationContext, attributesSegments: Expression[]) {
|
||||
context.requestEmitHelper(assignHelper);
|
||||
return createCall(
|
||||
getHelperName("__assign"),
|
||||
/*typeArguments*/ undefined,
|
||||
attributesSegments
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -227,7 +227,7 @@ namespace ts {
|
||||
|
||||
export function transformGenerators(context: TransformationContext) {
|
||||
const {
|
||||
startLexicalEnvironment,
|
||||
resumeLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
hoistFunctionDeclaration,
|
||||
hoistVariableDeclaration,
|
||||
@ -291,17 +291,18 @@ namespace ts {
|
||||
return transformSourceFile;
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
if (isDeclarationFile(node)) {
|
||||
if (isDeclarationFile(node)
|
||||
|| (node.transformFlags & TransformFlags.ContainsGenerator) === 0) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (node.transformFlags & TransformFlags.ContainsGenerator) {
|
||||
currentSourceFile = node;
|
||||
node = visitEachChild(node, visitor, context);
|
||||
currentSourceFile = undefined;
|
||||
}
|
||||
currentSourceFile = node;
|
||||
|
||||
return node;
|
||||
const visited = visitEachChild(node, visitor, context);
|
||||
addEmitHelpers(visited, context.readEmitHelpers());
|
||||
|
||||
currentSourceFile = undefined;
|
||||
return visited;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -449,11 +450,11 @@ namespace ts {
|
||||
node = setOriginalNode(
|
||||
createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
node.modifiers,
|
||||
/*asteriskToken*/ undefined,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
node.parameters,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformGeneratorFunctionBody(node.body),
|
||||
/*location*/ node
|
||||
@ -500,7 +501,7 @@ namespace ts {
|
||||
/*asteriskToken*/ undefined,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
node.parameters,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformGeneratorFunctionBody(node.body),
|
||||
/*location*/ node
|
||||
@ -578,7 +579,7 @@ namespace ts {
|
||||
state = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
|
||||
// Build the generator
|
||||
startLexicalEnvironment();
|
||||
resumeLexicalEnvironment();
|
||||
|
||||
const statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor);
|
||||
|
||||
@ -946,7 +947,7 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitArrayLiteralExpression(node: ArrayLiteralExpression) {
|
||||
return visitElements(node.elements, node.multiLine);
|
||||
return visitElements(node.elements, /*leadingElement*/ undefined, /*location*/ undefined, node.multiLine);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -956,7 +957,7 @@ namespace ts {
|
||||
* @param elements The elements to visit.
|
||||
* @param multiLine Whether array literals created should be emitted on multiple lines.
|
||||
*/
|
||||
function visitElements(elements: NodeArray<Expression>, _multiLine?: boolean) {
|
||||
function visitElements(elements: NodeArray<Expression>, leadingElement?: Expression, location?: TextRange, multiLine?: boolean) {
|
||||
// [source]
|
||||
// ar = [1, yield, 2];
|
||||
//
|
||||
@ -971,18 +972,22 @@ namespace ts {
|
||||
const temp = declareLocal();
|
||||
let hasAssignedTemp = false;
|
||||
if (numInitialElements > 0) {
|
||||
const initialElements = visitNodes(elements, visitor, isExpression, 0, numInitialElements);
|
||||
emitAssignment(temp,
|
||||
createArrayLiteral(
|
||||
visitNodes(elements, visitor, isExpression, 0, numInitialElements)
|
||||
leadingElement
|
||||
? [leadingElement, ...initialElements]
|
||||
: initialElements
|
||||
)
|
||||
);
|
||||
leadingElement = undefined;
|
||||
hasAssignedTemp = true;
|
||||
}
|
||||
|
||||
const expressions = reduceLeft(elements, reduceElement, <Expression[]>[], numInitialElements);
|
||||
return hasAssignedTemp
|
||||
? createArrayConcat(temp, [createArrayLiteral(expressions)])
|
||||
: createArrayLiteral(expressions);
|
||||
? createArrayConcat(temp, [createArrayLiteral(expressions, /*location*/ undefined, multiLine)])
|
||||
: createArrayLiteral(leadingElement ? [leadingElement, ...expressions] : expressions, location, multiLine);
|
||||
|
||||
function reduceElement(expressions: Expression[], element: Expression) {
|
||||
if (containsYield(element) && expressions.length > 0) {
|
||||
@ -991,11 +996,16 @@ namespace ts {
|
||||
hasAssignedTemp
|
||||
? createArrayConcat(
|
||||
temp,
|
||||
[createArrayLiteral(expressions)]
|
||||
[createArrayLiteral(expressions, /*location*/ undefined, multiLine)]
|
||||
)
|
||||
: createArrayLiteral(
|
||||
leadingElement ? [leadingElement, ...expressions] : expressions,
|
||||
/*location*/ undefined,
|
||||
multiLine
|
||||
)
|
||||
: createArrayLiteral(expressions)
|
||||
);
|
||||
hasAssignedTemp = true;
|
||||
leadingElement = undefined;
|
||||
expressions = [];
|
||||
}
|
||||
|
||||
@ -1131,7 +1141,10 @@ namespace ts {
|
||||
createFunctionApply(
|
||||
cacheExpression(visitNode(target, visitor, isExpression)),
|
||||
thisArg,
|
||||
visitElements(node.arguments)
|
||||
visitElements(
|
||||
node.arguments,
|
||||
/*leadingElement*/ createVoidZero()
|
||||
)
|
||||
),
|
||||
/*typeArguments*/ undefined,
|
||||
[],
|
||||
@ -2585,28 +2598,24 @@ namespace ts {
|
||||
withBlockStack = undefined;
|
||||
|
||||
const buildResult = buildStatements();
|
||||
return createCall(
|
||||
createHelperName(currentSourceFile.externalHelpersModuleName, "__generator"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createThis(),
|
||||
setEmitFlags(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, state)],
|
||||
/*type*/ undefined,
|
||||
createBlock(
|
||||
buildResult,
|
||||
/*location*/ undefined,
|
||||
/*multiLine*/ buildResult.length > 0
|
||||
)
|
||||
),
|
||||
EmitFlags.ReuseTempVariableScope
|
||||
)
|
||||
]
|
||||
return createGeneratorHelper(
|
||||
context,
|
||||
setEmitFlags(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, state)],
|
||||
/*type*/ undefined,
|
||||
createBlock(
|
||||
buildResult,
|
||||
/*location*/ undefined,
|
||||
/*multiLine*/ buildResult.length > 0
|
||||
)
|
||||
),
|
||||
EmitFlags.ReuseTempVariableScope
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -3082,4 +3091,105 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function createGeneratorHelper(context: TransformationContext, body: FunctionExpression) {
|
||||
context.requestEmitHelper(generatorHelper);
|
||||
return createCall(
|
||||
getHelperName("__generator"),
|
||||
/*typeArguments*/ undefined,
|
||||
[createThis(), body]);
|
||||
}
|
||||
|
||||
// The __generator helper is used by down-level transformations to emulate the runtime
|
||||
// semantics of an ES2015 generator function. When called, this helper returns an
|
||||
// object that implements the Iterator protocol, in that it has `next`, `return`, and
|
||||
// `throw` methods that step through the generator when invoked.
|
||||
//
|
||||
// parameters:
|
||||
// thisArg The value to use as the `this` binding for the transformed generator body.
|
||||
// body A function that acts as the transformed generator body.
|
||||
//
|
||||
// variables:
|
||||
// _ Persistent state for the generator that is shared between the helper and the
|
||||
// generator body. The state object has the following members:
|
||||
// sent() - A method that returns or throws the current completion value.
|
||||
// label - The next point at which to resume evaluation of the generator body.
|
||||
// trys - A stack of protected regions (try/catch/finally blocks).
|
||||
// ops - A stack of pending instructions when inside of a finally block.
|
||||
// f A value indicating whether the generator is executing.
|
||||
// y An iterator to delegate for a yield*.
|
||||
// t A temporary variable that holds one of the following values (note that these
|
||||
// cases do not overlap):
|
||||
// - The completion value when resuming from a `yield` or `yield*`.
|
||||
// - The error value for a catch block.
|
||||
// - The current protected region (array of try/catch/finally/end labels).
|
||||
// - The verb (`next`, `throw`, or `return` method) to delegate to the expression
|
||||
// of a `yield*`.
|
||||
// - The result of evaluating the verb delegated to the expression of a `yield*`.
|
||||
//
|
||||
// functions:
|
||||
// verb(n) Creates a bound callback to the `step` function for opcode `n`.
|
||||
// step(op) Evaluates opcodes in a generator body until execution is suspended or
|
||||
// completed.
|
||||
//
|
||||
// The __generator helper understands a limited set of instructions:
|
||||
// 0: next(value?) - Start or resume the generator with the specified value.
|
||||
// 1: throw(error) - Resume the generator with an exception. If the generator is
|
||||
// suspended inside of one or more protected regions, evaluates
|
||||
// any intervening finally blocks between the current label and
|
||||
// the nearest catch block or function boundary. If uncaught, the
|
||||
// exception is thrown to the caller.
|
||||
// 2: return(value?) - Resume the generator as if with a return. If the generator is
|
||||
// suspended inside of one or more protected regions, evaluates any
|
||||
// intervening finally blocks.
|
||||
// 3: break(label) - Jump to the specified label. If the label is outside of the
|
||||
// current protected region, evaluates any intervening finally
|
||||
// blocks.
|
||||
// 4: yield(value?) - Yield execution to the caller with an optional value. When
|
||||
// resumed, the generator will continue at the next label.
|
||||
// 5: yield*(value) - Delegates evaluation to the supplied iterator. When
|
||||
// delegation completes, the generator will continue at the next
|
||||
// label.
|
||||
// 6: catch(error) - Handles an exception thrown from within the generator body. If
|
||||
// the current label is inside of one or more protected regions,
|
||||
// evaluates any intervening finally blocks between the current
|
||||
// label and the nearest catch block or function boundary. If
|
||||
// uncaught, the exception is thrown to the caller.
|
||||
// 7: endfinally - Ends a finally block, resuming the last instruction prior to
|
||||
// entering a finally block.
|
||||
//
|
||||
// For examples of how these are used, see the comments in ./transformers/generators.ts
|
||||
const generatorHelper: EmitHelper = {
|
||||
name: "typescript:generator",
|
||||
scoped: false,
|
||||
priority: 6,
|
||||
text: `
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t;
|
||||
return { next: verb(0), "throw": verb(1), "return": verb(2) };
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [0, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};`
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
/// <reference path="./esnext.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
const entities: Map<number> = createEntitiesMap();
|
||||
|
||||
export function transformJsx(context: TransformationContext) {
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
let currentSourceFile: SourceFile;
|
||||
|
||||
return transformSourceFile;
|
||||
|
||||
/**
|
||||
@ -21,18 +21,18 @@ namespace ts {
|
||||
}
|
||||
|
||||
currentSourceFile = node;
|
||||
node = visitEachChild(node, visitor, context);
|
||||
|
||||
const visited = visitEachChild(node, visitor, context);
|
||||
addEmitHelpers(visited, context.readEmitHelpers());
|
||||
|
||||
currentSourceFile = undefined;
|
||||
return node;
|
||||
return visited;
|
||||
}
|
||||
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
if (node.transformFlags & TransformFlags.Jsx) {
|
||||
if (node.transformFlags & TransformFlags.ContainsJsx) {
|
||||
return visitorWorker(node);
|
||||
}
|
||||
else if (node.transformFlags & TransformFlags.ContainsJsx) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
else {
|
||||
return node;
|
||||
}
|
||||
@ -50,8 +50,7 @@ namespace ts {
|
||||
return visitJsxExpression(<JsxExpression>node);
|
||||
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return undefined;
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,8 +108,10 @@ namespace ts {
|
||||
|
||||
// Either emit one big object literal (no spread attribs), or
|
||||
// a call to the __assign helper.
|
||||
objectProperties = singleOrUndefined(segments)
|
||||
|| createAssignHelper(currentSourceFile.externalHelpersModuleName, segments);
|
||||
objectProperties = singleOrUndefined(segments);
|
||||
if (!objectProperties) {
|
||||
objectProperties = createAssignHelper(context, segments);
|
||||
}
|
||||
}
|
||||
|
||||
const element = createExpressionForJsxElement(
|
||||
@ -276,261 +277,259 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createEntitiesMap(): Map<number> {
|
||||
return createMap<number>({
|
||||
"quot": 0x0022,
|
||||
"amp": 0x0026,
|
||||
"apos": 0x0027,
|
||||
"lt": 0x003C,
|
||||
"gt": 0x003E,
|
||||
"nbsp": 0x00A0,
|
||||
"iexcl": 0x00A1,
|
||||
"cent": 0x00A2,
|
||||
"pound": 0x00A3,
|
||||
"curren": 0x00A4,
|
||||
"yen": 0x00A5,
|
||||
"brvbar": 0x00A6,
|
||||
"sect": 0x00A7,
|
||||
"uml": 0x00A8,
|
||||
"copy": 0x00A9,
|
||||
"ordf": 0x00AA,
|
||||
"laquo": 0x00AB,
|
||||
"not": 0x00AC,
|
||||
"shy": 0x00AD,
|
||||
"reg": 0x00AE,
|
||||
"macr": 0x00AF,
|
||||
"deg": 0x00B0,
|
||||
"plusmn": 0x00B1,
|
||||
"sup2": 0x00B2,
|
||||
"sup3": 0x00B3,
|
||||
"acute": 0x00B4,
|
||||
"micro": 0x00B5,
|
||||
"para": 0x00B6,
|
||||
"middot": 0x00B7,
|
||||
"cedil": 0x00B8,
|
||||
"sup1": 0x00B9,
|
||||
"ordm": 0x00BA,
|
||||
"raquo": 0x00BB,
|
||||
"frac14": 0x00BC,
|
||||
"frac12": 0x00BD,
|
||||
"frac34": 0x00BE,
|
||||
"iquest": 0x00BF,
|
||||
"Agrave": 0x00C0,
|
||||
"Aacute": 0x00C1,
|
||||
"Acirc": 0x00C2,
|
||||
"Atilde": 0x00C3,
|
||||
"Auml": 0x00C4,
|
||||
"Aring": 0x00C5,
|
||||
"AElig": 0x00C6,
|
||||
"Ccedil": 0x00C7,
|
||||
"Egrave": 0x00C8,
|
||||
"Eacute": 0x00C9,
|
||||
"Ecirc": 0x00CA,
|
||||
"Euml": 0x00CB,
|
||||
"Igrave": 0x00CC,
|
||||
"Iacute": 0x00CD,
|
||||
"Icirc": 0x00CE,
|
||||
"Iuml": 0x00CF,
|
||||
"ETH": 0x00D0,
|
||||
"Ntilde": 0x00D1,
|
||||
"Ograve": 0x00D2,
|
||||
"Oacute": 0x00D3,
|
||||
"Ocirc": 0x00D4,
|
||||
"Otilde": 0x00D5,
|
||||
"Ouml": 0x00D6,
|
||||
"times": 0x00D7,
|
||||
"Oslash": 0x00D8,
|
||||
"Ugrave": 0x00D9,
|
||||
"Uacute": 0x00DA,
|
||||
"Ucirc": 0x00DB,
|
||||
"Uuml": 0x00DC,
|
||||
"Yacute": 0x00DD,
|
||||
"THORN": 0x00DE,
|
||||
"szlig": 0x00DF,
|
||||
"agrave": 0x00E0,
|
||||
"aacute": 0x00E1,
|
||||
"acirc": 0x00E2,
|
||||
"atilde": 0x00E3,
|
||||
"auml": 0x00E4,
|
||||
"aring": 0x00E5,
|
||||
"aelig": 0x00E6,
|
||||
"ccedil": 0x00E7,
|
||||
"egrave": 0x00E8,
|
||||
"eacute": 0x00E9,
|
||||
"ecirc": 0x00EA,
|
||||
"euml": 0x00EB,
|
||||
"igrave": 0x00EC,
|
||||
"iacute": 0x00ED,
|
||||
"icirc": 0x00EE,
|
||||
"iuml": 0x00EF,
|
||||
"eth": 0x00F0,
|
||||
"ntilde": 0x00F1,
|
||||
"ograve": 0x00F2,
|
||||
"oacute": 0x00F3,
|
||||
"ocirc": 0x00F4,
|
||||
"otilde": 0x00F5,
|
||||
"ouml": 0x00F6,
|
||||
"divide": 0x00F7,
|
||||
"oslash": 0x00F8,
|
||||
"ugrave": 0x00F9,
|
||||
"uacute": 0x00FA,
|
||||
"ucirc": 0x00FB,
|
||||
"uuml": 0x00FC,
|
||||
"yacute": 0x00FD,
|
||||
"thorn": 0x00FE,
|
||||
"yuml": 0x00FF,
|
||||
"OElig": 0x0152,
|
||||
"oelig": 0x0153,
|
||||
"Scaron": 0x0160,
|
||||
"scaron": 0x0161,
|
||||
"Yuml": 0x0178,
|
||||
"fnof": 0x0192,
|
||||
"circ": 0x02C6,
|
||||
"tilde": 0x02DC,
|
||||
"Alpha": 0x0391,
|
||||
"Beta": 0x0392,
|
||||
"Gamma": 0x0393,
|
||||
"Delta": 0x0394,
|
||||
"Epsilon": 0x0395,
|
||||
"Zeta": 0x0396,
|
||||
"Eta": 0x0397,
|
||||
"Theta": 0x0398,
|
||||
"Iota": 0x0399,
|
||||
"Kappa": 0x039A,
|
||||
"Lambda": 0x039B,
|
||||
"Mu": 0x039C,
|
||||
"Nu": 0x039D,
|
||||
"Xi": 0x039E,
|
||||
"Omicron": 0x039F,
|
||||
"Pi": 0x03A0,
|
||||
"Rho": 0x03A1,
|
||||
"Sigma": 0x03A3,
|
||||
"Tau": 0x03A4,
|
||||
"Upsilon": 0x03A5,
|
||||
"Phi": 0x03A6,
|
||||
"Chi": 0x03A7,
|
||||
"Psi": 0x03A8,
|
||||
"Omega": 0x03A9,
|
||||
"alpha": 0x03B1,
|
||||
"beta": 0x03B2,
|
||||
"gamma": 0x03B3,
|
||||
"delta": 0x03B4,
|
||||
"epsilon": 0x03B5,
|
||||
"zeta": 0x03B6,
|
||||
"eta": 0x03B7,
|
||||
"theta": 0x03B8,
|
||||
"iota": 0x03B9,
|
||||
"kappa": 0x03BA,
|
||||
"lambda": 0x03BB,
|
||||
"mu": 0x03BC,
|
||||
"nu": 0x03BD,
|
||||
"xi": 0x03BE,
|
||||
"omicron": 0x03BF,
|
||||
"pi": 0x03C0,
|
||||
"rho": 0x03C1,
|
||||
"sigmaf": 0x03C2,
|
||||
"sigma": 0x03C3,
|
||||
"tau": 0x03C4,
|
||||
"upsilon": 0x03C5,
|
||||
"phi": 0x03C6,
|
||||
"chi": 0x03C7,
|
||||
"psi": 0x03C8,
|
||||
"omega": 0x03C9,
|
||||
"thetasym": 0x03D1,
|
||||
"upsih": 0x03D2,
|
||||
"piv": 0x03D6,
|
||||
"ensp": 0x2002,
|
||||
"emsp": 0x2003,
|
||||
"thinsp": 0x2009,
|
||||
"zwnj": 0x200C,
|
||||
"zwj": 0x200D,
|
||||
"lrm": 0x200E,
|
||||
"rlm": 0x200F,
|
||||
"ndash": 0x2013,
|
||||
"mdash": 0x2014,
|
||||
"lsquo": 0x2018,
|
||||
"rsquo": 0x2019,
|
||||
"sbquo": 0x201A,
|
||||
"ldquo": 0x201C,
|
||||
"rdquo": 0x201D,
|
||||
"bdquo": 0x201E,
|
||||
"dagger": 0x2020,
|
||||
"Dagger": 0x2021,
|
||||
"bull": 0x2022,
|
||||
"hellip": 0x2026,
|
||||
"permil": 0x2030,
|
||||
"prime": 0x2032,
|
||||
"Prime": 0x2033,
|
||||
"lsaquo": 0x2039,
|
||||
"rsaquo": 0x203A,
|
||||
"oline": 0x203E,
|
||||
"frasl": 0x2044,
|
||||
"euro": 0x20AC,
|
||||
"image": 0x2111,
|
||||
"weierp": 0x2118,
|
||||
"real": 0x211C,
|
||||
"trade": 0x2122,
|
||||
"alefsym": 0x2135,
|
||||
"larr": 0x2190,
|
||||
"uarr": 0x2191,
|
||||
"rarr": 0x2192,
|
||||
"darr": 0x2193,
|
||||
"harr": 0x2194,
|
||||
"crarr": 0x21B5,
|
||||
"lArr": 0x21D0,
|
||||
"uArr": 0x21D1,
|
||||
"rArr": 0x21D2,
|
||||
"dArr": 0x21D3,
|
||||
"hArr": 0x21D4,
|
||||
"forall": 0x2200,
|
||||
"part": 0x2202,
|
||||
"exist": 0x2203,
|
||||
"empty": 0x2205,
|
||||
"nabla": 0x2207,
|
||||
"isin": 0x2208,
|
||||
"notin": 0x2209,
|
||||
"ni": 0x220B,
|
||||
"prod": 0x220F,
|
||||
"sum": 0x2211,
|
||||
"minus": 0x2212,
|
||||
"lowast": 0x2217,
|
||||
"radic": 0x221A,
|
||||
"prop": 0x221D,
|
||||
"infin": 0x221E,
|
||||
"ang": 0x2220,
|
||||
"and": 0x2227,
|
||||
"or": 0x2228,
|
||||
"cap": 0x2229,
|
||||
"cup": 0x222A,
|
||||
"int": 0x222B,
|
||||
"there4": 0x2234,
|
||||
"sim": 0x223C,
|
||||
"cong": 0x2245,
|
||||
"asymp": 0x2248,
|
||||
"ne": 0x2260,
|
||||
"equiv": 0x2261,
|
||||
"le": 0x2264,
|
||||
"ge": 0x2265,
|
||||
"sub": 0x2282,
|
||||
"sup": 0x2283,
|
||||
"nsub": 0x2284,
|
||||
"sube": 0x2286,
|
||||
"supe": 0x2287,
|
||||
"oplus": 0x2295,
|
||||
"otimes": 0x2297,
|
||||
"perp": 0x22A5,
|
||||
"sdot": 0x22C5,
|
||||
"lceil": 0x2308,
|
||||
"rceil": 0x2309,
|
||||
"lfloor": 0x230A,
|
||||
"rfloor": 0x230B,
|
||||
"lang": 0x2329,
|
||||
"rang": 0x232A,
|
||||
"loz": 0x25CA,
|
||||
"spades": 0x2660,
|
||||
"clubs": 0x2663,
|
||||
"hearts": 0x2665,
|
||||
"diams": 0x2666
|
||||
});
|
||||
}
|
||||
const entities = createMap<number>({
|
||||
"quot": 0x0022,
|
||||
"amp": 0x0026,
|
||||
"apos": 0x0027,
|
||||
"lt": 0x003C,
|
||||
"gt": 0x003E,
|
||||
"nbsp": 0x00A0,
|
||||
"iexcl": 0x00A1,
|
||||
"cent": 0x00A2,
|
||||
"pound": 0x00A3,
|
||||
"curren": 0x00A4,
|
||||
"yen": 0x00A5,
|
||||
"brvbar": 0x00A6,
|
||||
"sect": 0x00A7,
|
||||
"uml": 0x00A8,
|
||||
"copy": 0x00A9,
|
||||
"ordf": 0x00AA,
|
||||
"laquo": 0x00AB,
|
||||
"not": 0x00AC,
|
||||
"shy": 0x00AD,
|
||||
"reg": 0x00AE,
|
||||
"macr": 0x00AF,
|
||||
"deg": 0x00B0,
|
||||
"plusmn": 0x00B1,
|
||||
"sup2": 0x00B2,
|
||||
"sup3": 0x00B3,
|
||||
"acute": 0x00B4,
|
||||
"micro": 0x00B5,
|
||||
"para": 0x00B6,
|
||||
"middot": 0x00B7,
|
||||
"cedil": 0x00B8,
|
||||
"sup1": 0x00B9,
|
||||
"ordm": 0x00BA,
|
||||
"raquo": 0x00BB,
|
||||
"frac14": 0x00BC,
|
||||
"frac12": 0x00BD,
|
||||
"frac34": 0x00BE,
|
||||
"iquest": 0x00BF,
|
||||
"Agrave": 0x00C0,
|
||||
"Aacute": 0x00C1,
|
||||
"Acirc": 0x00C2,
|
||||
"Atilde": 0x00C3,
|
||||
"Auml": 0x00C4,
|
||||
"Aring": 0x00C5,
|
||||
"AElig": 0x00C6,
|
||||
"Ccedil": 0x00C7,
|
||||
"Egrave": 0x00C8,
|
||||
"Eacute": 0x00C9,
|
||||
"Ecirc": 0x00CA,
|
||||
"Euml": 0x00CB,
|
||||
"Igrave": 0x00CC,
|
||||
"Iacute": 0x00CD,
|
||||
"Icirc": 0x00CE,
|
||||
"Iuml": 0x00CF,
|
||||
"ETH": 0x00D0,
|
||||
"Ntilde": 0x00D1,
|
||||
"Ograve": 0x00D2,
|
||||
"Oacute": 0x00D3,
|
||||
"Ocirc": 0x00D4,
|
||||
"Otilde": 0x00D5,
|
||||
"Ouml": 0x00D6,
|
||||
"times": 0x00D7,
|
||||
"Oslash": 0x00D8,
|
||||
"Ugrave": 0x00D9,
|
||||
"Uacute": 0x00DA,
|
||||
"Ucirc": 0x00DB,
|
||||
"Uuml": 0x00DC,
|
||||
"Yacute": 0x00DD,
|
||||
"THORN": 0x00DE,
|
||||
"szlig": 0x00DF,
|
||||
"agrave": 0x00E0,
|
||||
"aacute": 0x00E1,
|
||||
"acirc": 0x00E2,
|
||||
"atilde": 0x00E3,
|
||||
"auml": 0x00E4,
|
||||
"aring": 0x00E5,
|
||||
"aelig": 0x00E6,
|
||||
"ccedil": 0x00E7,
|
||||
"egrave": 0x00E8,
|
||||
"eacute": 0x00E9,
|
||||
"ecirc": 0x00EA,
|
||||
"euml": 0x00EB,
|
||||
"igrave": 0x00EC,
|
||||
"iacute": 0x00ED,
|
||||
"icirc": 0x00EE,
|
||||
"iuml": 0x00EF,
|
||||
"eth": 0x00F0,
|
||||
"ntilde": 0x00F1,
|
||||
"ograve": 0x00F2,
|
||||
"oacute": 0x00F3,
|
||||
"ocirc": 0x00F4,
|
||||
"otilde": 0x00F5,
|
||||
"ouml": 0x00F6,
|
||||
"divide": 0x00F7,
|
||||
"oslash": 0x00F8,
|
||||
"ugrave": 0x00F9,
|
||||
"uacute": 0x00FA,
|
||||
"ucirc": 0x00FB,
|
||||
"uuml": 0x00FC,
|
||||
"yacute": 0x00FD,
|
||||
"thorn": 0x00FE,
|
||||
"yuml": 0x00FF,
|
||||
"OElig": 0x0152,
|
||||
"oelig": 0x0153,
|
||||
"Scaron": 0x0160,
|
||||
"scaron": 0x0161,
|
||||
"Yuml": 0x0178,
|
||||
"fnof": 0x0192,
|
||||
"circ": 0x02C6,
|
||||
"tilde": 0x02DC,
|
||||
"Alpha": 0x0391,
|
||||
"Beta": 0x0392,
|
||||
"Gamma": 0x0393,
|
||||
"Delta": 0x0394,
|
||||
"Epsilon": 0x0395,
|
||||
"Zeta": 0x0396,
|
||||
"Eta": 0x0397,
|
||||
"Theta": 0x0398,
|
||||
"Iota": 0x0399,
|
||||
"Kappa": 0x039A,
|
||||
"Lambda": 0x039B,
|
||||
"Mu": 0x039C,
|
||||
"Nu": 0x039D,
|
||||
"Xi": 0x039E,
|
||||
"Omicron": 0x039F,
|
||||
"Pi": 0x03A0,
|
||||
"Rho": 0x03A1,
|
||||
"Sigma": 0x03A3,
|
||||
"Tau": 0x03A4,
|
||||
"Upsilon": 0x03A5,
|
||||
"Phi": 0x03A6,
|
||||
"Chi": 0x03A7,
|
||||
"Psi": 0x03A8,
|
||||
"Omega": 0x03A9,
|
||||
"alpha": 0x03B1,
|
||||
"beta": 0x03B2,
|
||||
"gamma": 0x03B3,
|
||||
"delta": 0x03B4,
|
||||
"epsilon": 0x03B5,
|
||||
"zeta": 0x03B6,
|
||||
"eta": 0x03B7,
|
||||
"theta": 0x03B8,
|
||||
"iota": 0x03B9,
|
||||
"kappa": 0x03BA,
|
||||
"lambda": 0x03BB,
|
||||
"mu": 0x03BC,
|
||||
"nu": 0x03BD,
|
||||
"xi": 0x03BE,
|
||||
"omicron": 0x03BF,
|
||||
"pi": 0x03C0,
|
||||
"rho": 0x03C1,
|
||||
"sigmaf": 0x03C2,
|
||||
"sigma": 0x03C3,
|
||||
"tau": 0x03C4,
|
||||
"upsilon": 0x03C5,
|
||||
"phi": 0x03C6,
|
||||
"chi": 0x03C7,
|
||||
"psi": 0x03C8,
|
||||
"omega": 0x03C9,
|
||||
"thetasym": 0x03D1,
|
||||
"upsih": 0x03D2,
|
||||
"piv": 0x03D6,
|
||||
"ensp": 0x2002,
|
||||
"emsp": 0x2003,
|
||||
"thinsp": 0x2009,
|
||||
"zwnj": 0x200C,
|
||||
"zwj": 0x200D,
|
||||
"lrm": 0x200E,
|
||||
"rlm": 0x200F,
|
||||
"ndash": 0x2013,
|
||||
"mdash": 0x2014,
|
||||
"lsquo": 0x2018,
|
||||
"rsquo": 0x2019,
|
||||
"sbquo": 0x201A,
|
||||
"ldquo": 0x201C,
|
||||
"rdquo": 0x201D,
|
||||
"bdquo": 0x201E,
|
||||
"dagger": 0x2020,
|
||||
"Dagger": 0x2021,
|
||||
"bull": 0x2022,
|
||||
"hellip": 0x2026,
|
||||
"permil": 0x2030,
|
||||
"prime": 0x2032,
|
||||
"Prime": 0x2033,
|
||||
"lsaquo": 0x2039,
|
||||
"rsaquo": 0x203A,
|
||||
"oline": 0x203E,
|
||||
"frasl": 0x2044,
|
||||
"euro": 0x20AC,
|
||||
"image": 0x2111,
|
||||
"weierp": 0x2118,
|
||||
"real": 0x211C,
|
||||
"trade": 0x2122,
|
||||
"alefsym": 0x2135,
|
||||
"larr": 0x2190,
|
||||
"uarr": 0x2191,
|
||||
"rarr": 0x2192,
|
||||
"darr": 0x2193,
|
||||
"harr": 0x2194,
|
||||
"crarr": 0x21B5,
|
||||
"lArr": 0x21D0,
|
||||
"uArr": 0x21D1,
|
||||
"rArr": 0x21D2,
|
||||
"dArr": 0x21D3,
|
||||
"hArr": 0x21D4,
|
||||
"forall": 0x2200,
|
||||
"part": 0x2202,
|
||||
"exist": 0x2203,
|
||||
"empty": 0x2205,
|
||||
"nabla": 0x2207,
|
||||
"isin": 0x2208,
|
||||
"notin": 0x2209,
|
||||
"ni": 0x220B,
|
||||
"prod": 0x220F,
|
||||
"sum": 0x2211,
|
||||
"minus": 0x2212,
|
||||
"lowast": 0x2217,
|
||||
"radic": 0x221A,
|
||||
"prop": 0x221D,
|
||||
"infin": 0x221E,
|
||||
"ang": 0x2220,
|
||||
"and": 0x2227,
|
||||
"or": 0x2228,
|
||||
"cap": 0x2229,
|
||||
"cup": 0x222A,
|
||||
"int": 0x222B,
|
||||
"there4": 0x2234,
|
||||
"sim": 0x223C,
|
||||
"cong": 0x2245,
|
||||
"asymp": 0x2248,
|
||||
"ne": 0x2260,
|
||||
"equiv": 0x2261,
|
||||
"le": 0x2264,
|
||||
"ge": 0x2265,
|
||||
"sub": 0x2282,
|
||||
"sup": 0x2283,
|
||||
"nsub": 0x2284,
|
||||
"sube": 0x2286,
|
||||
"supe": 0x2287,
|
||||
"oplus": 0x2295,
|
||||
"otimes": 0x2297,
|
||||
"perp": 0x22A5,
|
||||
"sdot": 0x22C5,
|
||||
"lceil": 0x2308,
|
||||
"rceil": 0x2309,
|
||||
"lfloor": 0x230A,
|
||||
"rfloor": 0x230B,
|
||||
"lang": 0x2329,
|
||||
"rang": 0x232A,
|
||||
"loz": 0x25CA,
|
||||
"spades": 0x2660,
|
||||
"clubs": 0x2663,
|
||||
"hearts": 0x2665,
|
||||
"diams": 0x2666
|
||||
});
|
||||
}
|
||||
@ -5,6 +5,14 @@
|
||||
namespace ts {
|
||||
export function transformES2015Module(context: TransformationContext) {
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
const previousOnEmitNode = context.onEmitNode;
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
context.onEmitNode = onEmitNode;
|
||||
context.onSubstituteNode = onSubstituteNode;
|
||||
context.enableEmitNotification(SyntaxKind.SourceFile);
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
|
||||
let currentSourceFile: SourceFile;
|
||||
return transformSourceFile;
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
@ -13,7 +21,27 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (isExternalModule(node) || compilerOptions.isolatedModules) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(node, compilerOptions);
|
||||
if (externalHelpersModuleName) {
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologueDirectives(statements, node.statements);
|
||||
append(statements,
|
||||
createImportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
|
||||
createLiteral(externalHelpersModuleNameText)
|
||||
)
|
||||
);
|
||||
|
||||
addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset));
|
||||
return updateSourceFileNode(
|
||||
node,
|
||||
createNodeArray(statements, node.statements));
|
||||
}
|
||||
else {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
@ -35,5 +63,55 @@ namespace ts {
|
||||
// Elide `export=` as it is not legal with --module ES6
|
||||
return node.isExportEquals ? undefined : node;
|
||||
}
|
||||
|
||||
//
|
||||
// Emit Notification
|
||||
//
|
||||
|
||||
/**
|
||||
* Hook for node emit.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
|
||||
if (isSourceFile(node)) {
|
||||
currentSourceFile = node;
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
currentSourceFile = undefined;
|
||||
}
|
||||
else {
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Substitutions
|
||||
//
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (isIdentifier(node) && emitContext === EmitContext.Expression) {
|
||||
return substituteExpressionIdentifier(node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteExpressionIdentifier(node: Identifier): Expression {
|
||||
if (getEmitFlags(node) & EmitFlags.HelperName) {
|
||||
const externalHelpersModuleName = getExternalHelpersModuleName(currentSourceFile);
|
||||
if (externalHelpersModuleName) {
|
||||
return createPropertyAccess(externalHelpersModuleName, node);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,8 +19,7 @@ namespace ts {
|
||||
|
||||
const {
|
||||
startLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
hoistVariableDeclaration,
|
||||
endLexicalEnvironment
|
||||
} = context;
|
||||
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
@ -61,7 +60,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
currentSourceFile = node;
|
||||
currentModuleInfo = moduleInfoMap[getOriginalNodeId(node)] = collectExternalModuleInfo(node, resolver);
|
||||
currentModuleInfo = moduleInfoMap[getOriginalNodeId(node)] = collectExternalModuleInfo(node, resolver, compilerOptions);
|
||||
|
||||
// Perform the transformation.
|
||||
const transformModule = transformModuleDelegates[moduleKind] || transformModuleDelegates[ModuleKind.None];
|
||||
@ -82,13 +81,14 @@ namespace ts {
|
||||
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement, /*optional*/ true));
|
||||
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
|
||||
|
||||
const updated = updateSourceFileNode(node, createNodeArray(statements, node.statements));
|
||||
if (currentModuleInfo.hasExportStarsToExportValues) {
|
||||
setEmitFlags(updated, EmitFlags.EmitExportStar | getEmitFlags(node));
|
||||
addEmitHelper(updated, exportStarHelper);
|
||||
}
|
||||
|
||||
return updated;
|
||||
@ -111,8 +111,7 @@ namespace ts {
|
||||
* @param node The SourceFile node.
|
||||
*/
|
||||
function transformUMDModule(node: SourceFile) {
|
||||
const define = createIdentifier("define");
|
||||
setEmitFlags(define, EmitFlags.UMDDefine);
|
||||
const define = createRawExpression(umdHelper);
|
||||
return transformAsynchronousModule(node, define, /*moduleName*/ undefined, /*includeNonAmdDependencies*/ false);
|
||||
}
|
||||
|
||||
@ -257,6 +256,7 @@ namespace ts {
|
||||
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
|
||||
|
||||
// Visit each statement of the module body.
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement, /*optional*/ true));
|
||||
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
|
||||
|
||||
// End the lexical environment for the module body
|
||||
@ -270,7 +270,7 @@ namespace ts {
|
||||
if (currentModuleInfo.hasExportStarsToExportValues) {
|
||||
// If we have any `export * from ...` declarations
|
||||
// we need to inform the emitter to add the __export helper.
|
||||
setEmitFlags(body, EmitFlags.EmitExportStar);
|
||||
addEmitHelper(body, exportStarHelper);
|
||||
}
|
||||
|
||||
return body;
|
||||
@ -757,9 +757,12 @@ namespace ts {
|
||||
*/
|
||||
function transformInitializedVariable(node: VariableDeclaration): Expression {
|
||||
if (isBindingPattern(node.name)) {
|
||||
return flattenVariableDestructuringToExpression(
|
||||
return flattenDestructuringAssignment(
|
||||
node,
|
||||
hoistVariableDeclaration,
|
||||
/*visitor*/ undefined,
|
||||
context,
|
||||
FlattenLevel.All,
|
||||
/*needsValue*/ false,
|
||||
createExportExpression
|
||||
);
|
||||
}
|
||||
@ -1186,6 +1189,14 @@ namespace ts {
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function substituteExpressionIdentifier(node: Identifier): Expression {
|
||||
if (getEmitFlags(node) & EmitFlags.HelperName) {
|
||||
const externalHelpersModuleName = getExternalHelpersModuleName(currentSourceFile);
|
||||
if (externalHelpersModuleName) {
|
||||
return createPropertyAccess(externalHelpersModuleName, node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
if (!isGeneratedIdentifier(node) && !isLocalName(node)) {
|
||||
const exportContainer = resolver.getReferencedExportContainer(node, isExportName(node));
|
||||
if (exportContainer && exportContainer.kind === SyntaxKind.SourceFile) {
|
||||
@ -1312,4 +1323,25 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// emit output for the __export helper function
|
||||
const exportStarHelper: EmitHelper = {
|
||||
name: "typescript:export-star",
|
||||
scoped: true,
|
||||
text: `
|
||||
function __export(m) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}`
|
||||
};
|
||||
|
||||
// emit output for the UMD helper function.
|
||||
const umdHelper = `
|
||||
(function (dependencies, factory) {
|
||||
if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||
var v = factory(require, exports); if (v !== undefined) module.exports = v;
|
||||
}
|
||||
else if (typeof define === 'function' && define.amd) {
|
||||
define(dependencies, factory);
|
||||
}
|
||||
})`;
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ namespace ts {
|
||||
// see comment to 'substitutePostfixUnaryExpression' for more details
|
||||
|
||||
// Collect information about the external module and dependency groups.
|
||||
moduleInfo = moduleInfoMap[id] = collectExternalModuleInfo(node, resolver);
|
||||
moduleInfo = moduleInfoMap[id] = collectExternalModuleInfo(node, resolver, compilerOptions);
|
||||
|
||||
// Make sure that the name of the 'exports' function does not conflict with
|
||||
// existing identifiers.
|
||||
@ -82,6 +82,7 @@ namespace ts {
|
||||
|
||||
// Add the body of the module.
|
||||
const dependencyGroups = collectDependencyGroups(moduleInfo.externalImports);
|
||||
const moduleBodyBlock = createSystemModuleBody(node, dependencyGroups);
|
||||
const moduleBodyFunction = createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
@ -92,7 +93,7 @@ namespace ts {
|
||||
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, contextObject)
|
||||
],
|
||||
/*type*/ undefined,
|
||||
createSystemModuleBody(node, dependencyGroups)
|
||||
moduleBodyBlock
|
||||
);
|
||||
|
||||
// Write the call to `System.register`
|
||||
@ -115,7 +116,9 @@ namespace ts {
|
||||
], node.statements)
|
||||
);
|
||||
|
||||
setEmitFlags(updated, getEmitFlags(node) & ~EmitFlags.EmitEmitHelpers);
|
||||
if (!(compilerOptions.outFile || compilerOptions.out)) {
|
||||
moveEmitHelpers(updated, moduleBodyBlock, helper => !helper.scoped);
|
||||
}
|
||||
|
||||
if (noSubstitution) {
|
||||
noSubstitutionMap[id] = noSubstitution;
|
||||
@ -236,6 +239,9 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
|
||||
// Visit the synthetic external helpers import declaration if present
|
||||
visitNode(moduleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement, /*optional*/ true);
|
||||
|
||||
// Visit the statements of the source file, emitting any transformations into
|
||||
// the `executeStatements` array. We do this *before* we fill the `setters` array
|
||||
// as we both emit transformations as well as aggregate some data used when creating
|
||||
@ -280,9 +286,7 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
|
||||
const body = createBlock(statements, /*location*/ undefined, /*multiLine*/ true);
|
||||
setEmitFlags(body, EmitFlags.EmitEmitHelpers);
|
||||
return body;
|
||||
return createBlock(statements, /*location*/ undefined, /*multiLine*/ true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -394,7 +398,13 @@ namespace ts {
|
||||
if (localNames) {
|
||||
condition = createLogicalAnd(
|
||||
condition,
|
||||
createLogicalNot(createHasOwnProperty(localNames, n))
|
||||
createLogicalNot(
|
||||
createCall(
|
||||
createPropertyAccess(localNames, "hasOwnProperty"),
|
||||
/*typeArguments*/ undefined,
|
||||
[n]
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -808,7 +818,14 @@ namespace ts {
|
||||
function transformInitializedVariable(node: VariableDeclaration, isExportedDeclaration: boolean): Expression {
|
||||
const createAssignment = isExportedDeclaration ? createExportedVariableAssignment : createNonExportedVariableAssignment;
|
||||
return isBindingPattern(node.name)
|
||||
? flattenVariableDestructuringToExpression(node, hoistVariableDeclaration, createAssignment, destructuringVisitor)
|
||||
? flattenDestructuringAssignment(
|
||||
node,
|
||||
destructuringVisitor,
|
||||
context,
|
||||
FlattenLevel.All,
|
||||
/*needsValue*/ false,
|
||||
createAssignment
|
||||
)
|
||||
: createAssignment(node.name, visitNode(node.initializer, destructuringVisitor, isExpression));
|
||||
}
|
||||
|
||||
@ -1459,7 +1476,13 @@ namespace ts {
|
||||
*/
|
||||
function visitDestructuringAssignment(node: DestructuringAssignment): VisitResult<Expression> {
|
||||
if (hasExportedReferenceInDestructuringTarget(node.left)) {
|
||||
return flattenDestructuringAssignment(context, node, /*needsValue*/ true, hoistVariableDeclaration, destructuringVisitor);
|
||||
return flattenDestructuringAssignment(
|
||||
node,
|
||||
destructuringVisitor,
|
||||
context,
|
||||
FlattenLevel.All,
|
||||
/*needsValue*/ true
|
||||
);
|
||||
}
|
||||
|
||||
return visitEachChild(node, destructuringVisitor, context);
|
||||
@ -1599,6 +1622,14 @@ namespace ts {
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function substituteExpressionIdentifier(node: Identifier): Expression {
|
||||
if (getEmitFlags(node) & EmitFlags.HelperName) {
|
||||
const externalHelpersModuleName = getExternalHelpersModuleName(currentSourceFile);
|
||||
if (externalHelpersModuleName) {
|
||||
return createPropertyAccess(externalHelpersModuleName, node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// When we see an identifier in an expression position that
|
||||
// points to an imported symbol, we should substitute a qualified
|
||||
// reference to the imported symbol if one is needed.
|
||||
|
||||
@ -21,6 +21,7 @@ namespace ts {
|
||||
export function transformTypeScript(context: TransformationContext) {
|
||||
const {
|
||||
startLexicalEnvironment,
|
||||
resumeLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
hoistVariableDeclaration,
|
||||
} = context;
|
||||
@ -48,7 +49,6 @@ namespace ts {
|
||||
let currentNamespaceContainerName: Identifier;
|
||||
let currentScope: SourceFile | Block | ModuleBlock | CaseBlock;
|
||||
let currentScopeFirstDeclarationsOfName: Map<Node>;
|
||||
let currentExternalHelpersModuleName: Identifier;
|
||||
|
||||
/**
|
||||
* Keeps track of whether expression substitution has been enabled for specific edge cases.
|
||||
@ -80,7 +80,13 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
return visitNode(node, visitor, isSourceFile);
|
||||
currentSourceFile = node;
|
||||
|
||||
const visited = saveStateAndInvoke(node, visitSourceFile);
|
||||
addEmitHelpers(visited, context.readEmitHelpers());
|
||||
|
||||
currentSourceFile = undefined;
|
||||
return visited;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,6 +113,32 @@ namespace ts {
|
||||
return visited;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs actions that should always occur immediately before visiting a node.
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function onBeforeVisitNode(node: Node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.CaseBlock:
|
||||
case SyntaxKind.ModuleBlock:
|
||||
case SyntaxKind.Block:
|
||||
currentScope = <SourceFile | CaseBlock | ModuleBlock | Block>node;
|
||||
currentScopeFirstDeclarationsOfName = undefined;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
if (hasModifier(node, ModifierFlags.Ambient)) {
|
||||
break;
|
||||
}
|
||||
|
||||
recordEmittedDeclarationInScope(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* General-purpose node visitor.
|
||||
*
|
||||
@ -122,10 +154,7 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitorWorker(node: Node): VisitResult<Node> {
|
||||
if (node.kind === SyntaxKind.SourceFile) {
|
||||
return visitSourceFile(<SourceFile>node);
|
||||
}
|
||||
else if (node.transformFlags & TransformFlags.TypeScript) {
|
||||
if (node.transformFlags & TransformFlags.TypeScript) {
|
||||
// This node is explicitly marked as TypeScript, so we should transform the node.
|
||||
return visitTypeScript(node);
|
||||
}
|
||||
@ -252,7 +281,6 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Branching visitor, visits a TypeScript syntax node.
|
||||
*
|
||||
@ -442,78 +470,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs actions that should always occur immediately before visiting a node.
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function onBeforeVisitNode(node: Node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.CaseBlock:
|
||||
case SyntaxKind.ModuleBlock:
|
||||
case SyntaxKind.Block:
|
||||
currentScope = <SourceFile | CaseBlock | ModuleBlock | Block>node;
|
||||
currentScopeFirstDeclarationsOfName = undefined;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
if (hasModifier(node, ModifierFlags.Ambient)) {
|
||||
break;
|
||||
}
|
||||
|
||||
recordEmittedDeclarationInScope(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function visitSourceFile(node: SourceFile) {
|
||||
currentSourceFile = node;
|
||||
|
||||
// ensure "use strict" is emitted in all scenarios in alwaysStrict mode
|
||||
// There is no need to emit "use strict" in the following cases:
|
||||
// 1. The file is an external module and target is es2015 or higher
|
||||
// or 2. The file is an external module and module-kind is es6 or es2015 as such value is not allowed when targeting es5 or lower
|
||||
if (compilerOptions.alwaysStrict &&
|
||||
!(isExternalModule(node) && (compilerOptions.target >= ScriptTarget.ES2015 || compilerOptions.module === ModuleKind.ES2015))) {
|
||||
node = ensureUseStrict(node);
|
||||
}
|
||||
|
||||
// If the source file requires any helpers and is an external module, and
|
||||
// the importHelpers compiler option is enabled, emit a synthesized import
|
||||
// statement for the helpers library.
|
||||
if (node.flags & NodeFlags.EmitHelperFlags
|
||||
&& compilerOptions.importHelpers
|
||||
&& (isExternalModule(node) || compilerOptions.isolatedModules)) {
|
||||
startLexicalEnvironment();
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ false, visitor);
|
||||
const externalHelpersModuleName = createUniqueName(externalHelpersModuleNameText);
|
||||
const externalHelpersModuleImport = createImportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
|
||||
createLiteral(externalHelpersModuleNameText));
|
||||
|
||||
externalHelpersModuleImport.parent = node;
|
||||
externalHelpersModuleImport.flags &= ~NodeFlags.Synthesized;
|
||||
statements.push(externalHelpersModuleImport);
|
||||
|
||||
currentExternalHelpersModuleName = externalHelpersModuleName;
|
||||
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
currentExternalHelpersModuleName = undefined;
|
||||
|
||||
node = updateSourceFileNode(node, createNodeArray(statements, node.statements));
|
||||
node.externalHelpersModuleName = externalHelpersModuleName;
|
||||
}
|
||||
else {
|
||||
node = visitEachChild(node, sourceElementVisitor, context);
|
||||
}
|
||||
|
||||
setEmitFlags(node, EmitFlags.EmitEmitHelpers | getEmitFlags(node));
|
||||
return node;
|
||||
const alwaysStrict = compilerOptions.alwaysStrict && !(isExternalModule(node) && moduleKind === ModuleKind.ES2015);
|
||||
return updateSourceFileNode(
|
||||
node,
|
||||
visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -885,9 +846,8 @@ namespace ts {
|
||||
// downlevel the '...args' portion less efficiently by naively copying the contents of 'arguments' to an array.
|
||||
// Instead, we'll avoid using a rest parameter and spread into the super call as
|
||||
// 'super(...arguments)' instead of 'super(...args)', as you can see in "transformConstructorBody".
|
||||
return constructor
|
||||
? visitNodes(constructor.parameters, visitor, isParameter)
|
||||
: <ParameterDeclaration[]>[];
|
||||
return visitParameterList(constructor && constructor.parameters, visitor, context)
|
||||
|| <ParameterDeclaration[]>[];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -902,8 +862,7 @@ namespace ts {
|
||||
const statements: Statement[] = [];
|
||||
let indexOfFirstStatement = 0;
|
||||
|
||||
// The body of a constructor is a new lexical environment
|
||||
startLexicalEnvironment();
|
||||
resumeLexicalEnvironment();
|
||||
|
||||
if (constructor) {
|
||||
indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(constructor, statements);
|
||||
@ -959,15 +918,13 @@ namespace ts {
|
||||
|
||||
// End the lexical environment.
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
return setMultiLine(
|
||||
createBlock(
|
||||
createNodeArray(
|
||||
statements,
|
||||
/*location*/ constructor ? constructor.body.statements : node.members
|
||||
),
|
||||
/*location*/ constructor ? constructor.body : /*location*/ undefined
|
||||
return createBlock(
|
||||
createNodeArray(
|
||||
statements,
|
||||
/*location*/ constructor ? constructor.body.statements : node.members
|
||||
),
|
||||
true
|
||||
/*location*/ constructor ? constructor.body : /*location*/ undefined,
|
||||
/*multiLine*/ true
|
||||
);
|
||||
}
|
||||
|
||||
@ -1425,7 +1382,7 @@ namespace ts {
|
||||
: undefined;
|
||||
|
||||
const helper = createDecorateHelper(
|
||||
currentExternalHelpersModuleName,
|
||||
context,
|
||||
decoratorExpressions,
|
||||
prefix,
|
||||
memberName,
|
||||
@ -1463,7 +1420,7 @@ namespace ts {
|
||||
|
||||
const classAlias = classAliases && classAliases[getOriginalNodeId(node)];
|
||||
const localName = getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
|
||||
const decorate = createDecorateHelper(currentExternalHelpersModuleName, decoratorExpressions, localName);
|
||||
const decorate = createDecorateHelper(context, decoratorExpressions, localName);
|
||||
const expression = createAssignment(localName, classAlias ? createAssignment(classAlias, decorate) : decorate);
|
||||
setEmitFlags(expression, EmitFlags.NoComments);
|
||||
setSourceMapRange(expression, moveRangePastDecorators(node));
|
||||
@ -1491,7 +1448,7 @@ namespace ts {
|
||||
expressions = [];
|
||||
for (const decorator of decorators) {
|
||||
const helper = createParamHelper(
|
||||
currentExternalHelpersModuleName,
|
||||
context,
|
||||
transformDecorator(decorator),
|
||||
parameterOffset,
|
||||
/*location*/ decorator.expression);
|
||||
@ -1521,13 +1478,13 @@ namespace ts {
|
||||
function addOldTypeMetadata(node: Declaration, decoratorExpressions: Expression[]) {
|
||||
if (compilerOptions.emitDecoratorMetadata) {
|
||||
if (shouldAddTypeMetadata(node)) {
|
||||
decoratorExpressions.push(createMetadataHelper(currentExternalHelpersModuleName, "design:type", serializeTypeOfNode(node)));
|
||||
decoratorExpressions.push(createMetadataHelper(context, "design:type", serializeTypeOfNode(node)));
|
||||
}
|
||||
if (shouldAddParamTypesMetadata(node)) {
|
||||
decoratorExpressions.push(createMetadataHelper(currentExternalHelpersModuleName, "design:paramtypes", serializeParameterTypesOfNode(node)));
|
||||
decoratorExpressions.push(createMetadataHelper(context, "design:paramtypes", serializeParameterTypesOfNode(node)));
|
||||
}
|
||||
if (shouldAddReturnTypeMetadata(node)) {
|
||||
decoratorExpressions.push(createMetadataHelper(currentExternalHelpersModuleName, "design:returntype", serializeReturnTypeOfNode(node)));
|
||||
decoratorExpressions.push(createMetadataHelper(context, "design:returntype", serializeReturnTypeOfNode(node)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1545,7 +1502,7 @@ namespace ts {
|
||||
(properties || (properties = [])).push(createPropertyAssignment("returnType", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeReturnTypeOfNode(node))));
|
||||
}
|
||||
if (properties) {
|
||||
decoratorExpressions.push(createMetadataHelper(currentExternalHelpersModuleName, "design:typeinfo", createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true)));
|
||||
decoratorExpressions.push(createMetadataHelper(context, "design:typeinfo", createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1819,12 +1776,7 @@ namespace ts {
|
||||
const temp = createTempVariable(hoistVariableDeclaration);
|
||||
return createLogicalOr(
|
||||
createLogicalAnd(
|
||||
createStrictEquality(
|
||||
createTypeOf(
|
||||
createAssignment(temp, serialized)
|
||||
),
|
||||
createLiteral("function")
|
||||
),
|
||||
createTypeCheck(createAssignment(temp, serialized), "function"),
|
||||
temp
|
||||
),
|
||||
createIdentifier("Object")
|
||||
@ -1933,13 +1885,8 @@ namespace ts {
|
||||
*/
|
||||
function getGlobalSymbolNameWithFallback(): Expression {
|
||||
return createConditional(
|
||||
createStrictEquality(
|
||||
createTypeOf(createIdentifier("Symbol")),
|
||||
createLiteral("function")
|
||||
),
|
||||
createToken(SyntaxKind.QuestionToken),
|
||||
createTypeCheck(createIdentifier("Symbol"), "function"),
|
||||
createIdentifier("Symbol"),
|
||||
createToken(SyntaxKind.ColonToken),
|
||||
createIdentifier("Object")
|
||||
);
|
||||
}
|
||||
@ -2063,26 +2010,23 @@ namespace ts {
|
||||
if (!shouldEmitFunctionLikeDeclaration(node)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const method = createMethod(
|
||||
const updated = updateMethod(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
node.asteriskToken,
|
||||
visitPropertyNameOfClassElement(node),
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node),
|
||||
/*location*/ node
|
||||
visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
|
||||
// While we emit the source map for the node after skipping decorators and modifiers,
|
||||
// we need to emit the comments for the original range.
|
||||
setCommentRange(method, node);
|
||||
setSourceMapRange(method, moveRangePastDecorators(node));
|
||||
setOriginalNode(method, node);
|
||||
|
||||
return method;
|
||||
if (updated !== node) {
|
||||
// While we emit the source map for the node after skipping decorators and modifiers,
|
||||
// we need to emit the comments for the original range.
|
||||
setCommentRange(updated, node);
|
||||
setSourceMapRange(updated, moveRangePastDecorators(node));
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2108,24 +2052,22 @@ namespace ts {
|
||||
if (!shouldEmitAccessorDeclaration(node)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const accessor = createGetAccessor(
|
||||
const updated = updateGetAccessor(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
visitPropertyNameOfClassElement(node),
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
node.body ? visitEachChild(node.body, visitor, context) : createBlock([]),
|
||||
/*location*/ node
|
||||
visitFunctionBody(node.body, visitor, context) || createBlock([])
|
||||
);
|
||||
|
||||
// While we emit the source map for the node after skipping decorators and modifiers,
|
||||
// we need to emit the comments for the original range.
|
||||
setOriginalNode(accessor, node);
|
||||
setCommentRange(accessor, node);
|
||||
setSourceMapRange(accessor, moveRangePastDecorators(node));
|
||||
|
||||
return accessor;
|
||||
if (updated !== node) {
|
||||
// While we emit the source map for the node after skipping decorators and modifiers,
|
||||
// we need to emit the comments for the original range.
|
||||
setCommentRange(updated, node);
|
||||
setSourceMapRange(updated, moveRangePastDecorators(node));
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2141,23 +2083,21 @@ namespace ts {
|
||||
if (!shouldEmitAccessorDeclaration(node)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const accessor = createSetAccessor(
|
||||
const updated = updateSetAccessor(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
visitPropertyNameOfClassElement(node),
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
node.body ? visitEachChild(node.body, visitor, context) : createBlock([]),
|
||||
/*location*/ node
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
visitFunctionBody(node.body, visitor, context) || createBlock([])
|
||||
);
|
||||
|
||||
// While we emit the source map for the node after skipping decorators and modifiers,
|
||||
// we need to emit the comments for the original range.
|
||||
setOriginalNode(accessor, node);
|
||||
setCommentRange(accessor, node);
|
||||
setSourceMapRange(accessor, moveRangePastDecorators(node));
|
||||
|
||||
return accessor;
|
||||
if (updated !== node) {
|
||||
// While we emit the source map for the node after skipping decorators and modifiers,
|
||||
// we need to emit the comments for the original range.
|
||||
setCommentRange(updated, node);
|
||||
setSourceMapRange(updated, moveRangePastDecorators(node));
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2174,27 +2114,22 @@ namespace ts {
|
||||
if (!shouldEmitFunctionLikeDeclaration(node)) {
|
||||
return createNotEmittedStatement(node);
|
||||
}
|
||||
|
||||
const func = createFunctionDeclaration(
|
||||
const updated = updateFunctionDeclaration(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node),
|
||||
/*location*/ node
|
||||
visitFunctionBody(node.body, visitor, context) || createBlock([])
|
||||
);
|
||||
setOriginalNode(func, node);
|
||||
|
||||
if (isNamespaceExport(node)) {
|
||||
const statements: Statement[] = [func];
|
||||
const statements: Statement[] = [updated];
|
||||
addExportMemberAssignment(statements, node);
|
||||
return statements;
|
||||
}
|
||||
|
||||
return func;
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2209,21 +2144,16 @@ namespace ts {
|
||||
if (nodeIsMissing(node.body)) {
|
||||
return createOmittedExpression();
|
||||
}
|
||||
|
||||
const func = createFunctionExpression(
|
||||
const updated = updateFunctionExpression(
|
||||
node,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node),
|
||||
/*location*/ node
|
||||
visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
|
||||
setOriginalNode(func, node);
|
||||
|
||||
return func;
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2232,62 +2162,15 @@ namespace ts {
|
||||
* - The node has type annotations
|
||||
*/
|
||||
function visitArrowFunction(node: ArrowFunction) {
|
||||
const func = createArrowFunction(
|
||||
const updated = updateArrowFunction(
|
||||
node,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
node.equalsGreaterThanToken,
|
||||
transformConciseBody(node),
|
||||
/*location*/ node
|
||||
visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
|
||||
setOriginalNode(func, node);
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
function transformFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody {
|
||||
return transformFunctionBodyWorker(node.body);
|
||||
}
|
||||
|
||||
function transformFunctionBodyWorker(body: Block, start = 0) {
|
||||
const savedCurrentScope = currentScope;
|
||||
const savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
|
||||
currentScope = body;
|
||||
currentScopeFirstDeclarationsOfName = createMap<Node>();
|
||||
startLexicalEnvironment();
|
||||
|
||||
const statements = visitNodes(body.statements, visitor, isStatement, start);
|
||||
const visited = updateBlock(body, statements);
|
||||
const declarations = endLexicalEnvironment();
|
||||
currentScope = savedCurrentScope;
|
||||
currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
|
||||
return mergeFunctionBodyLexicalEnvironment(visited, declarations);
|
||||
}
|
||||
|
||||
function transformConciseBody(node: ArrowFunction): ConciseBody {
|
||||
return transformConciseBodyWorker(node.body, /*forceBlockFunctionBody*/ false);
|
||||
}
|
||||
|
||||
function transformConciseBodyWorker(body: Block | Expression, forceBlockFunctionBody: boolean) {
|
||||
if (isBlock(body)) {
|
||||
return transformFunctionBodyWorker(body);
|
||||
}
|
||||
else {
|
||||
startLexicalEnvironment();
|
||||
const visited: Expression | Block = visitNode(body, visitor, isConciseBody);
|
||||
const declarations = endLexicalEnvironment();
|
||||
const merged = mergeFunctionBodyLexicalEnvironment(visited, declarations);
|
||||
if (forceBlockFunctionBody && !isBlock(merged)) {
|
||||
return createBlock([
|
||||
createReturn(<Expression>merged)
|
||||
]);
|
||||
}
|
||||
else {
|
||||
return merged;
|
||||
}
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2355,11 +2238,13 @@ namespace ts {
|
||||
function transformInitializedVariable(node: VariableDeclaration): Expression {
|
||||
const name = node.name;
|
||||
if (isBindingPattern(name)) {
|
||||
return flattenVariableDestructuringToExpression(
|
||||
return flattenDestructuringAssignment(
|
||||
node,
|
||||
hoistVariableDeclaration,
|
||||
createNamespaceExportExpression,
|
||||
visitor
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.All,
|
||||
/*needsValue*/ false,
|
||||
createNamespaceExportExpression
|
||||
);
|
||||
}
|
||||
else {
|
||||
@ -3359,7 +3244,7 @@ namespace ts {
|
||||
|
||||
function trySubstituteNamespaceExportedName(node: Identifier): Expression {
|
||||
// If this is explicitly a local name, do not substitute.
|
||||
if (enabledSubstitutions & applicableSubstitutions && !isLocalName(node)) {
|
||||
if (enabledSubstitutions & applicableSubstitutions && !isGeneratedIdentifier(node) && !isLocalName(node)) {
|
||||
// If we are nested within a namespace declaration, we may need to qualifiy
|
||||
// an identifier that is exported from a merged namespace.
|
||||
const container = resolver.getReferencedExportContainer(node, /*prefixLocals*/ false);
|
||||
@ -3414,4 +3299,77 @@ namespace ts {
|
||||
: undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const paramHelper: EmitHelper = {
|
||||
name: "typescript:param",
|
||||
scoped: false,
|
||||
priority: 4,
|
||||
text: `
|
||||
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
return function (target, key) { decorator(target, key, paramIndex); }
|
||||
};`
|
||||
};
|
||||
|
||||
function createParamHelper(context: TransformationContext, expression: Expression, parameterOffset: number, location?: TextRange) {
|
||||
context.requestEmitHelper(paramHelper);
|
||||
return createCall(
|
||||
getHelperName("__param"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createLiteral(parameterOffset),
|
||||
expression
|
||||
],
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
const metadataHelper: EmitHelper = {
|
||||
name: "typescript:metadata",
|
||||
scoped: false,
|
||||
priority: 3,
|
||||
text: `
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};`
|
||||
};
|
||||
|
||||
function createMetadataHelper(context: TransformationContext, metadataKey: string, metadataValue: Expression) {
|
||||
context.requestEmitHelper(metadataHelper);
|
||||
return createCall(
|
||||
getHelperName("__metadata"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createLiteral(metadataKey),
|
||||
metadataValue
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
const decorateHelper: EmitHelper = {
|
||||
name: "typescript:decorate",
|
||||
scoped: false,
|
||||
priority: 2,
|
||||
text: `
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};`
|
||||
};
|
||||
|
||||
function createDecorateHelper(context: TransformationContext, decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression, location?: TextRange) {
|
||||
context.requestEmitHelper(decorateHelper);
|
||||
const argumentsArray: Expression[] = [];
|
||||
argumentsArray.push(createArrayLiteral(decoratorExpressions, /*location*/ undefined, /*multiLine*/ true));
|
||||
argumentsArray.push(target);
|
||||
if (memberName) {
|
||||
argumentsArray.push(memberName);
|
||||
if (descriptor) {
|
||||
argumentsArray.push(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
return createCall(getHelperName("__decorate"), /*typeArguments*/ undefined, argumentsArray, location);
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,6 +369,7 @@ namespace ts {
|
||||
PartiallyEmittedExpression,
|
||||
MergeDeclarationMarker,
|
||||
EndOfDeclarationMarker,
|
||||
RawExpression,
|
||||
|
||||
// Enum value count
|
||||
Count,
|
||||
@ -507,6 +508,7 @@ namespace ts {
|
||||
|
||||
export interface NodeArray<T extends Node> extends Array<T>, TextRange {
|
||||
hasTrailingComma?: boolean;
|
||||
/* @internal */ transformFlags?: TransformFlags;
|
||||
}
|
||||
|
||||
export interface Token<TKind extends SyntaxKind> extends Node {
|
||||
@ -578,9 +580,9 @@ namespace ts {
|
||||
|
||||
export type EntityName = Identifier | QualifiedName;
|
||||
|
||||
export type PropertyName = Identifier | LiteralExpression | ComputedPropertyName;
|
||||
export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName;
|
||||
|
||||
export type DeclarationName = Identifier | LiteralExpression | ComputedPropertyName | BindingPattern;
|
||||
export type DeclarationName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | BindingPattern;
|
||||
|
||||
export interface Declaration extends Node {
|
||||
_declarationBrand: any;
|
||||
@ -588,7 +590,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface DeclarationStatement extends Declaration, Statement {
|
||||
name?: Identifier | LiteralExpression;
|
||||
name?: Identifier | StringLiteral | NumericLiteral;
|
||||
}
|
||||
|
||||
export interface ComputedPropertyName extends Node {
|
||||
@ -723,22 +725,20 @@ namespace ts {
|
||||
name: PropertyName;
|
||||
}
|
||||
|
||||
export interface BindingPattern extends Node {
|
||||
elements: NodeArray<BindingElement | ArrayBindingElement>;
|
||||
}
|
||||
|
||||
export interface ObjectBindingPattern extends BindingPattern {
|
||||
export interface ObjectBindingPattern extends Node {
|
||||
kind: SyntaxKind.ObjectBindingPattern;
|
||||
elements: NodeArray<BindingElement>;
|
||||
}
|
||||
|
||||
export type ArrayBindingElement = BindingElement | OmittedExpression;
|
||||
|
||||
export interface ArrayBindingPattern extends BindingPattern {
|
||||
export interface ArrayBindingPattern extends Node {
|
||||
kind: SyntaxKind.ArrayBindingPattern;
|
||||
elements: NodeArray<ArrayBindingElement>;
|
||||
}
|
||||
|
||||
export type BindingPattern = ObjectBindingPattern | ArrayBindingPattern;
|
||||
|
||||
export type ArrayBindingElement = BindingElement | OmittedExpression;
|
||||
|
||||
/**
|
||||
* Several node kinds share function-like features such as a signature,
|
||||
* a name, and a body. These nodes should extend FunctionLikeDeclaration.
|
||||
@ -920,7 +920,7 @@ namespace ts {
|
||||
|
||||
export interface StringLiteral extends LiteralExpression {
|
||||
kind: SyntaxKind.StringLiteral;
|
||||
/* @internal */ textSourceNode?: Identifier | StringLiteral; // Allows a StringLiteral to get its text from another node (used by transforms).
|
||||
/* @internal */ textSourceNode?: Identifier | StringLiteral | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms).
|
||||
}
|
||||
|
||||
// Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing.
|
||||
@ -1185,20 +1185,64 @@ namespace ts {
|
||||
right: Expression;
|
||||
}
|
||||
|
||||
export interface AssignmentExpression extends BinaryExpression {
|
||||
export type AssignmentOperatorToken = Token<AssignmentOperator>;
|
||||
|
||||
export interface AssignmentExpression<TOperator extends AssignmentOperatorToken> extends BinaryExpression {
|
||||
left: LeftHandSideExpression;
|
||||
operatorToken: Token<SyntaxKind.EqualsToken>;
|
||||
operatorToken: TOperator;
|
||||
}
|
||||
|
||||
export interface ObjectDestructuringAssignment extends AssignmentExpression {
|
||||
export interface ObjectDestructuringAssignment extends AssignmentExpression<EqualsToken> {
|
||||
left: ObjectLiteralExpression;
|
||||
}
|
||||
|
||||
export interface ArrayDestructuringAssignment extends AssignmentExpression {
|
||||
export interface ArrayDestructuringAssignment extends AssignmentExpression<EqualsToken> {
|
||||
left: ArrayLiteralExpression;
|
||||
}
|
||||
|
||||
export type DestructuringAssignment = ObjectDestructuringAssignment | ArrayDestructuringAssignment;
|
||||
export type DestructuringAssignment
|
||||
= ObjectDestructuringAssignment
|
||||
| ArrayDestructuringAssignment
|
||||
;
|
||||
|
||||
export type BindingOrAssignmentElement
|
||||
= VariableDeclaration
|
||||
| ParameterDeclaration
|
||||
| BindingElement
|
||||
| PropertyAssignment // AssignmentProperty
|
||||
| ShorthandPropertyAssignment // AssignmentProperty
|
||||
| SpreadAssignment // AssignmentRestProperty
|
||||
| OmittedExpression // Elision
|
||||
| SpreadElement // AssignmentRestElement
|
||||
| ArrayLiteralExpression // ArrayAssignmentPattern
|
||||
| ObjectLiteralExpression // ObjectAssignmentPattern
|
||||
| AssignmentExpression<EqualsToken> // AssignmentElement
|
||||
| Identifier // DestructuringAssignmentTarget
|
||||
| PropertyAccessExpression // DestructuringAssignmentTarget
|
||||
| ElementAccessExpression // DestructuringAssignmentTarget
|
||||
;
|
||||
|
||||
export type BindingOrAssignmentElementRestIndicator
|
||||
= DotDotDotToken // from BindingElement
|
||||
| SpreadElement // AssignmentRestElement
|
||||
| SpreadAssignment // AssignmentRestProperty
|
||||
;
|
||||
|
||||
export type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Expression;
|
||||
|
||||
export type ObjectBindingOrAssignmentPattern
|
||||
= ObjectBindingPattern
|
||||
| ObjectLiteralExpression // ObjectAssignmentPattern
|
||||
;
|
||||
|
||||
export type ArrayBindingOrAssignmentPattern
|
||||
= ArrayBindingPattern
|
||||
| ArrayLiteralExpression // ArrayAssignmentPattern
|
||||
;
|
||||
|
||||
export type AssignmentPattern = ObjectLiteralExpression | ArrayLiteralExpression;
|
||||
|
||||
export type BindingOrAssignmentPattern = ObjectBindingOrAssignmentPattern | ArrayBindingOrAssignmentPattern;
|
||||
|
||||
export interface ConditionalExpression extends Expression {
|
||||
kind: SyntaxKind.ConditionalExpression;
|
||||
@ -1480,6 +1524,16 @@ namespace ts {
|
||||
kind: SyntaxKind.EndOfDeclarationMarker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits a string of raw text in an expression position. Raw text is never transformed, should
|
||||
* be ES3 compliant, and should have the same precedence as PrimaryExpression.
|
||||
*/
|
||||
/* @internal */
|
||||
export interface RawExpression extends PrimaryExpression {
|
||||
kind: SyntaxKind.RawExpression;
|
||||
text: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the beginning of a merged transformed declaration.
|
||||
*/
|
||||
@ -1519,6 +1573,11 @@ namespace ts {
|
||||
expression: Expression;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface PrologueDirective extends ExpressionStatement {
|
||||
expression: StringLiteral;
|
||||
}
|
||||
|
||||
export interface IfStatement extends Statement {
|
||||
kind: SyntaxKind.IfStatement;
|
||||
expression: Expression;
|
||||
@ -1703,7 +1762,7 @@ namespace ts {
|
||||
|
||||
export interface ModuleDeclaration extends DeclarationStatement {
|
||||
kind: SyntaxKind.ModuleDeclaration;
|
||||
name: Identifier | LiteralExpression;
|
||||
name: Identifier | StringLiteral;
|
||||
body?: ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | Identifier;
|
||||
}
|
||||
|
||||
@ -1909,7 +1968,7 @@ namespace ts {
|
||||
|
||||
export interface JSDocRecordMember extends PropertySignature {
|
||||
kind: SyntaxKind.JSDocRecordMember;
|
||||
name: Identifier | LiteralExpression;
|
||||
name: Identifier | StringLiteral | NumericLiteral;
|
||||
type?: JSDocType;
|
||||
}
|
||||
|
||||
@ -2119,8 +2178,6 @@ namespace ts {
|
||||
/* @internal */ moduleAugmentations: LiteralExpression[];
|
||||
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
|
||||
/* @internal */ ambientModuleNames: string[];
|
||||
// The synthesized identifier for an imported external helpers module.
|
||||
/* @internal */ externalHelpersModuleName?: Identifier;
|
||||
}
|
||||
|
||||
export interface ScriptReferenceHost {
|
||||
@ -2318,6 +2375,8 @@ namespace ts {
|
||||
isOptionalParameter(node: ParameterDeclaration): boolean;
|
||||
getAmbientModules(): Symbol[];
|
||||
|
||||
tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
|
||||
|
||||
/* @internal */ tryFindAmbientModuleWithoutAugmentations(moduleName: string): Symbol;
|
||||
|
||||
// Should not be called directly. Should only be accessed through the Program instance.
|
||||
@ -2683,7 +2742,7 @@ namespace ts {
|
||||
resolvedSignature?: Signature; // Cached signature of signature node or call expression
|
||||
resolvedSymbol?: Symbol; // Cached name resolution result
|
||||
resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result
|
||||
maybeTypePredicate?: boolean; // Cached check whether call expression might reference a type predicate
|
||||
maybeTypePredicate?: boolean; // Cached check whether call expression might reference a type predicate
|
||||
enumMemberValue?: number; // Constant value of enum member
|
||||
isVisible?: boolean; // Is this node visible
|
||||
hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context
|
||||
@ -3140,7 +3199,7 @@ namespace ts {
|
||||
target?: ScriptTarget;
|
||||
traceResolution?: boolean;
|
||||
types?: string[];
|
||||
/** Paths used to used to compute primary types search locations */
|
||||
/** Paths used to compute primary types search locations */
|
||||
typeRoots?: string[];
|
||||
/*@internal*/ version?: boolean;
|
||||
/*@internal*/ watch?: boolean;
|
||||
@ -3521,46 +3580,45 @@ namespace ts {
|
||||
// - Flags used to indicate that a node or subtree contains syntax that requires transformation.
|
||||
TypeScript = 1 << 0,
|
||||
ContainsTypeScript = 1 << 1,
|
||||
Jsx = 1 << 2,
|
||||
ContainsJsx = 1 << 3,
|
||||
ESNext = 1 << 4,
|
||||
ContainsESNext = 1 << 5,
|
||||
ES2017 = 1 << 6,
|
||||
ContainsES2017 = 1 << 7,
|
||||
ES2016 = 1 << 8,
|
||||
ContainsES2016 = 1 << 9,
|
||||
ES2015 = 1 << 10,
|
||||
ContainsES2015 = 1 << 11,
|
||||
Generator = 1 << 12,
|
||||
ContainsGenerator = 1 << 13,
|
||||
DestructuringAssignment = 1 << 14,
|
||||
ContainsDestructuringAssignment = 1 << 15,
|
||||
ContainsJsx = 1 << 2,
|
||||
ContainsESNext = 1 << 3,
|
||||
ContainsES2017 = 1 << 4,
|
||||
ContainsES2016 = 1 << 5,
|
||||
ES2015 = 1 << 6,
|
||||
ContainsES2015 = 1 << 7,
|
||||
Generator = 1 << 8,
|
||||
ContainsGenerator = 1 << 9,
|
||||
DestructuringAssignment = 1 << 10,
|
||||
ContainsDestructuringAssignment = 1 << 11,
|
||||
|
||||
// Markers
|
||||
// - Flags used to indicate that a subtree contains a specific transformation.
|
||||
ContainsDecorators = 1 << 16,
|
||||
ContainsPropertyInitializer = 1 << 17,
|
||||
ContainsLexicalThis = 1 << 18,
|
||||
ContainsCapturedLexicalThis = 1 << 19,
|
||||
ContainsLexicalThisInComputedPropertyName = 1 << 20,
|
||||
ContainsDefaultValueAssignments = 1 << 21,
|
||||
ContainsParameterPropertyAssignments = 1 << 22,
|
||||
ContainsSpreadExpression = 1 << 23,
|
||||
ContainsComputedPropertyName = 1 << 24,
|
||||
ContainsBlockScopedBinding = 1 << 25,
|
||||
ContainsBindingPattern = 1 << 26,
|
||||
ContainsYield = 1 << 27,
|
||||
ContainsHoistedDeclarationOrCompletion = 1 << 28,
|
||||
ContainsDecorators = 1 << 12,
|
||||
ContainsPropertyInitializer = 1 << 13,
|
||||
ContainsLexicalThis = 1 << 14,
|
||||
ContainsCapturedLexicalThis = 1 << 15,
|
||||
ContainsLexicalThisInComputedPropertyName = 1 << 16,
|
||||
ContainsDefaultValueAssignments = 1 << 17,
|
||||
ContainsParameterPropertyAssignments = 1 << 18,
|
||||
ContainsSpread = 1 << 19,
|
||||
ContainsObjectSpread = 1 << 20,
|
||||
ContainsRest = ContainsSpread,
|
||||
ContainsObjectRest = ContainsObjectSpread,
|
||||
ContainsComputedPropertyName = 1 << 21,
|
||||
ContainsBlockScopedBinding = 1 << 22,
|
||||
ContainsBindingPattern = 1 << 23,
|
||||
ContainsYield = 1 << 24,
|
||||
ContainsHoistedDeclarationOrCompletion = 1 << 25,
|
||||
|
||||
HasComputedFlags = 1 << 29, // Transform flags have been computed.
|
||||
|
||||
// Assertions
|
||||
// - Bitmasks that are used to assert facts about the syntax of a node and its subtree.
|
||||
AssertTypeScript = TypeScript | ContainsTypeScript,
|
||||
AssertJsx = Jsx | ContainsJsx,
|
||||
AssertESNext = ESNext | ContainsESNext,
|
||||
AssertES2017 = ES2017 | ContainsES2017,
|
||||
AssertES2016 = ES2016 | ContainsES2016,
|
||||
AssertJsx = ContainsJsx,
|
||||
AssertESNext = ContainsESNext,
|
||||
AssertES2017 = ContainsES2017,
|
||||
AssertES2016 = ContainsES2016,
|
||||
AssertES2015 = ES2015 | ContainsES2015,
|
||||
AssertGenerator = Generator | ContainsGenerator,
|
||||
AssertDestructuringAssignment = DestructuringAssignment | ContainsDestructuringAssignment,
|
||||
@ -3568,18 +3626,20 @@ namespace ts {
|
||||
// Scope Exclusions
|
||||
// - Bitmasks that exclude flags from propagating out of a specific context
|
||||
// into the subtree flags of their container.
|
||||
NodeExcludes = TypeScript | Jsx | ESNext | ES2017 | ES2016 | ES2015 | DestructuringAssignment | Generator | HasComputedFlags,
|
||||
ArrowFunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion,
|
||||
FunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion,
|
||||
ConstructorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion,
|
||||
MethodOrAccessorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion,
|
||||
NodeExcludes = TypeScript | ES2015 | DestructuringAssignment | Generator | HasComputedFlags,
|
||||
ArrowFunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest,
|
||||
FunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest,
|
||||
ConstructorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest,
|
||||
MethodOrAccessorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest,
|
||||
ClassExcludes = NodeExcludes | ContainsDecorators | ContainsPropertyInitializer | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsComputedPropertyName | ContainsParameterPropertyAssignments | ContainsLexicalThisInComputedPropertyName,
|
||||
ModuleExcludes = NodeExcludes | ContainsDecorators | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsHoistedDeclarationOrCompletion,
|
||||
TypeExcludes = ~ContainsTypeScript,
|
||||
ObjectLiteralExcludes = NodeExcludes | ContainsDecorators | ContainsComputedPropertyName | ContainsLexicalThisInComputedPropertyName,
|
||||
ArrayLiteralOrCallOrNewExcludes = NodeExcludes | ContainsSpreadExpression,
|
||||
VariableDeclarationListExcludes = NodeExcludes | ContainsBindingPattern,
|
||||
ParameterExcludes = NodeExcludes | ContainsBindingPattern,
|
||||
ObjectLiteralExcludes = NodeExcludes | ContainsDecorators | ContainsComputedPropertyName | ContainsLexicalThisInComputedPropertyName | ContainsObjectSpread,
|
||||
ArrayLiteralOrCallOrNewExcludes = NodeExcludes | ContainsSpread,
|
||||
VariableDeclarationListExcludes = NodeExcludes | ContainsBindingPattern | ContainsObjectRest,
|
||||
ParameterExcludes = NodeExcludes,
|
||||
CatchClauseExcludes = NodeExcludes | ContainsObjectRest,
|
||||
BindingPatternExcludes = NodeExcludes | ContainsRest,
|
||||
|
||||
// Masks
|
||||
// - Additional bitmasks
|
||||
@ -3589,45 +3649,51 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export interface EmitNode {
|
||||
flags?: EmitFlags;
|
||||
commentRange?: TextRange;
|
||||
sourceMapRange?: TextRange;
|
||||
tokenSourceMapRanges?: Map<TextRange>;
|
||||
annotatedNodes?: Node[]; // Tracks Parse-tree nodes with EmitNodes for eventual cleanup.
|
||||
constantValue?: number;
|
||||
flags?: EmitFlags; // Flags that customize emit
|
||||
commentRange?: TextRange; // The text range to use when emitting leading or trailing comments
|
||||
sourceMapRange?: TextRange; // The text range to use when emitting leading or trailing source mappings
|
||||
tokenSourceMapRanges?: Map<TextRange>; // The text range to use when emitting source mappings for tokens
|
||||
constantValue?: number; // The constant value of an expression
|
||||
externalHelpersModuleName?: Identifier; // The local name for an imported helpers module
|
||||
helpers?: EmitHelper[]; // Emit helpers for the node
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const enum EmitFlags {
|
||||
EmitEmitHelpers = 1 << 0, // Any emit helpers should be written to this node.
|
||||
EmitExportStar = 1 << 1, // The export * helper should be written to this node.
|
||||
EmitSuperHelper = 1 << 2, // Emit the basic _super helper for async methods.
|
||||
EmitAdvancedSuperHelper = 1 << 3, // Emit the advanced _super helper for async methods.
|
||||
UMDDefine = 1 << 4, // This node should be replaced with the UMD define helper.
|
||||
SingleLine = 1 << 5, // The contents of this node should be emitted on a single line.
|
||||
AdviseOnEmitNode = 1 << 6, // The printer should invoke the onEmitNode callback when printing this node.
|
||||
NoSubstitution = 1 << 7, // Disables further substitution of an expression.
|
||||
CapturesThis = 1 << 8, // The function captures a lexical `this`
|
||||
NoLeadingSourceMap = 1 << 9, // Do not emit a leading source map location for this node.
|
||||
NoTrailingSourceMap = 1 << 10, // Do not emit a trailing source map location for this node.
|
||||
SingleLine = 1 << 0, // The contents of this node should be emitted on a single line.
|
||||
AdviseOnEmitNode = 1 << 1, // The printer should invoke the onEmitNode callback when printing this node.
|
||||
NoSubstitution = 1 << 2, // Disables further substitution of an expression.
|
||||
CapturesThis = 1 << 3, // The function captures a lexical `this`
|
||||
NoLeadingSourceMap = 1 << 4, // Do not emit a leading source map location for this node.
|
||||
NoTrailingSourceMap = 1 << 5, // Do not emit a trailing source map location for this node.
|
||||
NoSourceMap = NoLeadingSourceMap | NoTrailingSourceMap, // Do not emit a source map location for this node.
|
||||
NoNestedSourceMaps = 1 << 11, // Do not emit source map locations for children of this node.
|
||||
NoTokenLeadingSourceMaps = 1 << 12, // Do not emit leading source map location for token nodes.
|
||||
NoTokenTrailingSourceMaps = 1 << 13, // Do not emit trailing source map location for token nodes.
|
||||
NoNestedSourceMaps = 1 << 6, // Do not emit source map locations for children of this node.
|
||||
NoTokenLeadingSourceMaps = 1 << 7, // Do not emit leading source map location for token nodes.
|
||||
NoTokenTrailingSourceMaps = 1 << 8, // Do not emit trailing source map location for token nodes.
|
||||
NoTokenSourceMaps = NoTokenLeadingSourceMaps | NoTokenTrailingSourceMaps, // Do not emit source map locations for tokens of this node.
|
||||
NoLeadingComments = 1 << 14, // Do not emit leading comments for this node.
|
||||
NoTrailingComments = 1 << 15, // Do not emit trailing comments for this node.
|
||||
NoLeadingComments = 1 << 9, // Do not emit leading comments for this node.
|
||||
NoTrailingComments = 1 << 10, // Do not emit trailing comments for this node.
|
||||
NoComments = NoLeadingComments | NoTrailingComments, // Do not emit comments for this node.
|
||||
NoNestedComments = 1 << 16,
|
||||
ExportName = 1 << 17, // Ensure an export prefix is added for an identifier that points to an exported declaration with a local name (see SymbolFlags.ExportHasLocal).
|
||||
LocalName = 1 << 18, // Ensure an export prefix is not added for an identifier that points to an exported declaration.
|
||||
Indented = 1 << 19, // Adds an explicit extra indentation level for class and function bodies when printing (used to match old emitter).
|
||||
NoIndentation = 1 << 20, // Do not indent the node.
|
||||
AsyncFunctionBody = 1 << 21,
|
||||
ReuseTempVariableScope = 1 << 22, // Reuse the existing temp variable scope during emit.
|
||||
CustomPrologue = 1 << 23, // Treat the statement as if it were a prologue directive (NOTE: Prologue directives are *not* transformed).
|
||||
NoHoisting = 1 << 24, // Do not hoist this declaration in --module system
|
||||
HasEndOfDeclarationMarker = 1 << 25, // Declaration has an associated NotEmittedStatement to mark the end of the declaration
|
||||
NoNestedComments = 1 << 11,
|
||||
HelperName = 1 << 12,
|
||||
ExportName = 1 << 13, // Ensure an export prefix is added for an identifier that points to an exported declaration with a local name (see SymbolFlags.ExportHasLocal).
|
||||
LocalName = 1 << 14, // Ensure an export prefix is not added for an identifier that points to an exported declaration.
|
||||
Indented = 1 << 15, // Adds an explicit extra indentation level for class and function bodies when printing (used to match old emitter).
|
||||
NoIndentation = 1 << 16, // Do not indent the node.
|
||||
AsyncFunctionBody = 1 << 17,
|
||||
ReuseTempVariableScope = 1 << 18, // Reuse the existing temp variable scope during emit.
|
||||
CustomPrologue = 1 << 19, // Treat the statement as if it were a prologue directive (NOTE: Prologue directives are *not* transformed).
|
||||
NoHoisting = 1 << 20, // Do not hoist this declaration in --module system
|
||||
HasEndOfDeclarationMarker = 1 << 21, // Declaration has an associated NotEmittedStatement to mark the end of the declaration
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface EmitHelper {
|
||||
readonly name: string; // A unique name for this helper.
|
||||
readonly scoped: boolean; // Indicates whether ther helper MUST be emitted in the current scope.
|
||||
readonly text: string; // ES3-compatible raw script text.
|
||||
readonly priority?: number; // Helpers with a higher priority are emitted earlier than other helpers on the node.
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@ -3638,16 +3704,123 @@ namespace ts {
|
||||
Unspecified, // Emitting an otherwise unspecified node
|
||||
}
|
||||
|
||||
/** Additional context provided to `visitEachChild` */
|
||||
/* @internal */
|
||||
export interface LexicalEnvironment {
|
||||
export interface EmitHost extends ScriptReferenceHost {
|
||||
getSourceFiles(): SourceFile[];
|
||||
|
||||
/* @internal */
|
||||
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
|
||||
getCommonSourceDirectory(): string;
|
||||
getCanonicalFileName(fileName: string): string;
|
||||
getNewLine(): string;
|
||||
|
||||
isEmitBlocked(emitFileName: string): boolean;
|
||||
|
||||
writeFile: WriteFileCallback;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TransformationContext {
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getEmitResolver(): EmitResolver;
|
||||
getEmitHost(): EmitHost;
|
||||
|
||||
/** Starts a new lexical environment. */
|
||||
startLexicalEnvironment(): void;
|
||||
|
||||
/** Suspends the current lexical environment, usually after visiting a parameter list. */
|
||||
suspendLexicalEnvironment(): void;
|
||||
|
||||
/** Resumes a suspended lexical environment, usually before visiting a function body. */
|
||||
resumeLexicalEnvironment(): void;
|
||||
|
||||
/** Ends a lexical environment, returning any declarations. */
|
||||
endLexicalEnvironment(): Statement[];
|
||||
|
||||
/**
|
||||
* Hoists a function declaration to the containing scope.
|
||||
*/
|
||||
hoistFunctionDeclaration(node: FunctionDeclaration): void;
|
||||
|
||||
/**
|
||||
* Hoists a variable declaration to the containing scope.
|
||||
*/
|
||||
hoistVariableDeclaration(node: Identifier): void;
|
||||
|
||||
/**
|
||||
* Records a request for a non-scoped emit helper in the current context.
|
||||
*/
|
||||
requestEmitHelper(helper: EmitHelper): void;
|
||||
|
||||
/**
|
||||
* Gets and resets the requested non-scoped emit helpers.
|
||||
*/
|
||||
readEmitHelpers(): EmitHelper[] | undefined;
|
||||
|
||||
/**
|
||||
* Enables expression substitutions in the pretty printer for the provided SyntaxKind.
|
||||
*/
|
||||
enableSubstitution(kind: SyntaxKind): void;
|
||||
|
||||
/**
|
||||
* Determines whether expression substitutions are enabled for the provided node.
|
||||
*/
|
||||
isSubstitutionEnabled(node: Node): boolean;
|
||||
|
||||
/**
|
||||
* Hook used by transformers to substitute expressions just before they
|
||||
* are emitted by the pretty printer.
|
||||
*/
|
||||
onSubstituteNode?: (emitContext: EmitContext, node: Node) => Node;
|
||||
|
||||
/**
|
||||
* Enables before/after emit notifications in the pretty printer for the provided
|
||||
* SyntaxKind.
|
||||
*/
|
||||
enableEmitNotification(kind: SyntaxKind): void;
|
||||
|
||||
/**
|
||||
* Determines whether before/after emit notifications should be raised in the pretty
|
||||
* printer when it emits a node.
|
||||
*/
|
||||
isEmitNotificationEnabled(node: Node): boolean;
|
||||
|
||||
/**
|
||||
* Hook used to allow transformers to capture state before or after
|
||||
* the printer emits a node.
|
||||
*/
|
||||
onEmitNode?: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TransformationResult {
|
||||
/**
|
||||
* Gets the transformed source files.
|
||||
*/
|
||||
transformed: SourceFile[];
|
||||
|
||||
/**
|
||||
* Emits the substitute for a node, if one is available; otherwise, emits the node.
|
||||
*
|
||||
* @param emitContext The current emit context.
|
||||
* @param node The node to substitute.
|
||||
* @param emitCallback A callback used to emit the node or its substitute.
|
||||
*/
|
||||
emitNodeWithSubstitution(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
|
||||
|
||||
/**
|
||||
* Emits a node with possible notification.
|
||||
*
|
||||
* @param emitContext The current emit context.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback A callback used to emit the node.
|
||||
*/
|
||||
emitNodeWithNotification(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type Transformer = (context: TransformationContext) => (node: SourceFile) => SourceFile;
|
||||
|
||||
export interface TextSpan {
|
||||
start: number;
|
||||
|
||||
@ -28,21 +28,6 @@ namespace ts {
|
||||
string(): string;
|
||||
}
|
||||
|
||||
export interface EmitHost extends ScriptReferenceHost {
|
||||
getSourceFiles(): SourceFile[];
|
||||
|
||||
/* @internal */
|
||||
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
|
||||
getCommonSourceDirectory(): string;
|
||||
getCanonicalFileName(fileName: string): string;
|
||||
getNewLine(): string;
|
||||
|
||||
isEmitBlocked(emitFileName: string): boolean;
|
||||
|
||||
writeFile: WriteFileCallback;
|
||||
}
|
||||
|
||||
// Pool writers to avoid needing to allocate them for every symbol we write.
|
||||
const stringWriters: StringSymbolWriter[] = [];
|
||||
export function getSingleLineStringWriter(): StringSymbolWriter {
|
||||
@ -493,7 +478,7 @@ namespace ts {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return (<LiteralExpression>name).text;
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
if (isStringOrNumericLiteral((<ComputedPropertyName>name).expression.kind)) {
|
||||
if (isStringOrNumericLiteral((<ComputedPropertyName>name).expression)) {
|
||||
return (<LiteralExpression>(<ComputedPropertyName>name).expression).text;
|
||||
}
|
||||
}
|
||||
@ -626,8 +611,9 @@ namespace ts {
|
||||
return n.kind === SyntaxKind.CallExpression && (<CallExpression>n).expression.kind === SyntaxKind.SuperKeyword;
|
||||
}
|
||||
|
||||
export function isPrologueDirective(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.ExpressionStatement && (<ExpressionStatement>node).expression.kind === SyntaxKind.StringLiteral;
|
||||
export function isPrologueDirective(node: Node): node is PrologueDirective {
|
||||
return node.kind === SyntaxKind.ExpressionStatement
|
||||
&& (<ExpressionStatement>node).expression.kind === SyntaxKind.StringLiteral;
|
||||
}
|
||||
|
||||
export function getLeadingCommentRangesOfNode(node: Node, sourceFileOfNode: SourceFile) {
|
||||
@ -1880,8 +1866,10 @@ namespace ts {
|
||||
return isFunctionLike(node) && hasModifier(node, ModifierFlags.Async) && !isAccessor(node);
|
||||
}
|
||||
|
||||
export function isStringOrNumericLiteral(kind: SyntaxKind): boolean {
|
||||
return kind === SyntaxKind.StringLiteral || kind === SyntaxKind.NumericLiteral;
|
||||
export function isStringOrNumericLiteral(node: Node): node is StringLiteral | NumericLiteral {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.StringLiteral
|
||||
|| kind === SyntaxKind.NumericLiteral;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1897,7 +1885,7 @@ namespace ts {
|
||||
|
||||
export function isDynamicName(name: DeclarationName): boolean {
|
||||
return name.kind === SyntaxKind.ComputedPropertyName &&
|
||||
!isStringOrNumericLiteral((<ComputedPropertyName>name).expression.kind) &&
|
||||
!isStringOrNumericLiteral((<ComputedPropertyName>name).expression) &&
|
||||
!isWellKnownSymbolSyntactically((<ComputedPropertyName>name).expression);
|
||||
}
|
||||
|
||||
@ -1910,7 +1898,7 @@ namespace ts {
|
||||
return isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
|
||||
}
|
||||
|
||||
export function getPropertyNameForPropertyNameNode(name: DeclarationName): string {
|
||||
export function getPropertyNameForPropertyNameNode(name: DeclarationName | ParameterDeclaration): string {
|
||||
if (name.kind === SyntaxKind.Identifier || name.kind === SyntaxKind.StringLiteral || name.kind === SyntaxKind.NumericLiteral || name.kind === SyntaxKind.Parameter) {
|
||||
return (<Identifier | LiteralExpression>name).text;
|
||||
}
|
||||
@ -2146,6 +2134,7 @@ namespace ts {
|
||||
case SyntaxKind.TemplateExpression:
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.OmittedExpression:
|
||||
case SyntaxKind.RawExpression:
|
||||
return 19;
|
||||
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
@ -3138,19 +3127,21 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function isAssignmentExpression(node: Node): node is AssignmentExpression {
|
||||
export function isAssignmentExpression(node: Node, excludeCompoundAssignment: true): node is AssignmentExpression<EqualsToken>;
|
||||
export function isAssignmentExpression(node: Node, excludeCompoundAssignment?: false): node is AssignmentExpression<AssignmentOperatorToken>;
|
||||
export function isAssignmentExpression(node: Node, excludeCompoundAssignment?: boolean): node is AssignmentExpression<AssignmentOperatorToken> {
|
||||
return isBinaryExpression(node)
|
||||
&& isAssignmentOperator(node.operatorToken.kind)
|
||||
&& (excludeCompoundAssignment
|
||||
? node.operatorToken.kind === SyntaxKind.EqualsToken
|
||||
: isAssignmentOperator(node.operatorToken.kind))
|
||||
&& isLeftHandSideExpression(node.left);
|
||||
}
|
||||
|
||||
export function isDestructuringAssignment(node: Node): node is DestructuringAssignment {
|
||||
if (isBinaryExpression(node)) {
|
||||
if (node.operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
const kind = node.left.kind;
|
||||
return kind === SyntaxKind.ObjectLiteralExpression
|
||||
|| kind === SyntaxKind.ArrayLiteralExpression;
|
||||
}
|
||||
if (isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) {
|
||||
const kind = node.left.kind;
|
||||
return kind === SyntaxKind.ObjectLiteralExpression
|
||||
|| kind === SyntaxKind.ArrayLiteralExpression;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -3568,153 +3559,6 @@ namespace ts {
|
||||
return positionIsSynthesized(range.pos) ? -1 : skipTrivia(sourceFile.text, range.pos);
|
||||
}
|
||||
|
||||
export interface ExternalModuleInfo {
|
||||
externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]; // imports of other external modules
|
||||
exportSpecifiers: Map<ExportSpecifier[]>; // export specifiers by name
|
||||
exportedBindings: Map<Identifier[]>; // exported names of local declarations
|
||||
exportedNames: Identifier[]; // all exported names local to module
|
||||
exportEquals: ExportAssignment | undefined; // an export= declaration if one was present
|
||||
hasExportStarsToExportValues: boolean; // whether this module contains export*
|
||||
}
|
||||
|
||||
export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver): ExternalModuleInfo {
|
||||
const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = [];
|
||||
const exportSpecifiers = createMap<ExportSpecifier[]>();
|
||||
const exportedBindings = createMap<Identifier[]>();
|
||||
const uniqueExports = createMap<Identifier>();
|
||||
let hasExportDefault = false;
|
||||
let exportEquals: ExportAssignment = undefined;
|
||||
let hasExportStarsToExportValues = false;
|
||||
for (const node of sourceFile.statements) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
// import "mod"
|
||||
// import x from "mod"
|
||||
// import * as x from "mod"
|
||||
// import { x, y } from "mod"
|
||||
externalImports.push(<ImportDeclaration>node);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
if ((<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference) {
|
||||
// import x = require("mod")
|
||||
externalImports.push(<ImportEqualsDeclaration>node);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
if ((<ExportDeclaration>node).moduleSpecifier) {
|
||||
if (!(<ExportDeclaration>node).exportClause) {
|
||||
// export * from "mod"
|
||||
externalImports.push(<ExportDeclaration>node);
|
||||
hasExportStarsToExportValues = true;
|
||||
}
|
||||
else {
|
||||
// export { x, y } from "mod"
|
||||
externalImports.push(<ExportDeclaration>node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export { x, y }
|
||||
for (const specifier of (<ExportDeclaration>node).exportClause.elements) {
|
||||
if (!uniqueExports[specifier.name.text]) {
|
||||
const name = specifier.propertyName || specifier.name;
|
||||
multiMapAdd(exportSpecifiers, name.text, specifier);
|
||||
|
||||
const decl = resolver.getReferencedImportDeclaration(name)
|
||||
|| resolver.getReferencedValueDeclaration(name);
|
||||
|
||||
if (decl) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
|
||||
}
|
||||
|
||||
uniqueExports[specifier.name.text] = specifier.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportAssignment:
|
||||
if ((<ExportAssignment>node).isExportEquals && !exportEquals) {
|
||||
// export = x
|
||||
exportEquals = <ExportAssignment>node;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.VariableStatement:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
for (const decl of (<VariableStatement>node).declarationList.declarations) {
|
||||
collectExportedVariableInfo(decl, uniqueExports);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
if (hasModifier(node, ModifierFlags.Default)) {
|
||||
// export default function() { }
|
||||
if (!hasExportDefault) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<FunctionDeclaration>node));
|
||||
hasExportDefault = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export function x() { }
|
||||
const name = (<FunctionDeclaration>node).name;
|
||||
if (!uniqueExports[name.text]) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports[name.text] = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
if (hasModifier(node, ModifierFlags.Default)) {
|
||||
// export default class { }
|
||||
if (!hasExportDefault) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<ClassDeclaration>node));
|
||||
hasExportDefault = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export class x { }
|
||||
const name = (<ClassDeclaration>node).name;
|
||||
if (!uniqueExports[name.text]) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports[name.text] = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let exportedNames: Identifier[];
|
||||
for (const key in uniqueExports) {
|
||||
exportedNames = ts.append(exportedNames, uniqueExports[key]);
|
||||
}
|
||||
|
||||
return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues, exportedBindings, exportedNames };
|
||||
}
|
||||
|
||||
function collectExportedVariableInfo(decl: VariableDeclaration | BindingElement, uniqueExports: Map<Identifier>) {
|
||||
if (isBindingPattern(decl.name)) {
|
||||
for (const element of decl.name.elements) {
|
||||
if (!isOmittedExpression(element)) {
|
||||
collectExportedVariableInfo(element, uniqueExports);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!isGeneratedIdentifier(decl.name)) {
|
||||
if (!uniqueExports[decl.name.text]) {
|
||||
uniqueExports[decl.name.text] = decl.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a name was originally the declaration name of an enum or namespace
|
||||
* declaration.
|
||||
@ -3931,6 +3775,14 @@ namespace ts {
|
||||
|
||||
// Binding patterns
|
||||
|
||||
export function isArrayBindingPattern(node: Node): node is ArrayBindingPattern {
|
||||
return node.kind === SyntaxKind.ArrayBindingPattern;
|
||||
}
|
||||
|
||||
export function isObjectBindingPattern(node: Node): node is ObjectBindingPattern {
|
||||
return node.kind === SyntaxKind.ObjectBindingPattern;
|
||||
}
|
||||
|
||||
export function isBindingPattern(node: Node): node is BindingPattern {
|
||||
if (node) {
|
||||
const kind = node.kind;
|
||||
@ -3941,6 +3793,12 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isAssignmentPattern(node: Node): node is AssignmentPattern {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.ArrayLiteralExpression
|
||||
|| kind === SyntaxKind.ObjectLiteralExpression;
|
||||
}
|
||||
|
||||
export function isBindingElement(node: Node): node is BindingElement {
|
||||
return node.kind === SyntaxKind.BindingElement;
|
||||
}
|
||||
@ -3951,6 +3809,55 @@ namespace ts {
|
||||
|| kind === SyntaxKind.OmittedExpression;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines whether the BindingOrAssignmentElement is a BindingElement-like declaration
|
||||
*/
|
||||
export function isDeclarationBindingElement(bindingElement: BindingOrAssignmentElement): bindingElement is VariableDeclaration | ParameterDeclaration | BindingElement {
|
||||
switch (bindingElement.kind) {
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.BindingElement:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a node is a BindingOrAssignmentPattern
|
||||
*/
|
||||
export function isBindingOrAssignmentPattern(node: BindingOrAssignmentElementTarget): node is BindingOrAssignmentPattern {
|
||||
return isObjectBindingOrAssignmentPattern(node)
|
||||
|| isArrayBindingOrAssignmentPattern(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a node is an ObjectBindingOrAssignmentPattern
|
||||
*/
|
||||
export function isObjectBindingOrAssignmentPattern(node: BindingOrAssignmentElementTarget): node is ObjectBindingOrAssignmentPattern {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a node is an ArrayBindingOrAssignmentPattern
|
||||
*/
|
||||
export function isArrayBindingOrAssignmentPattern(node: BindingOrAssignmentElementTarget): node is ArrayBindingOrAssignmentPattern {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Expression
|
||||
|
||||
export function isArrayLiteralExpression(node: Node): node is ArrayLiteralExpression {
|
||||
@ -4019,7 +3926,8 @@ namespace ts {
|
||||
|| kind === SyntaxKind.ThisKeyword
|
||||
|| kind === SyntaxKind.TrueKeyword
|
||||
|| kind === SyntaxKind.SuperKeyword
|
||||
|| kind === SyntaxKind.NonNullExpression;
|
||||
|| kind === SyntaxKind.NonNullExpression
|
||||
|| kind === SyntaxKind.RawExpression;
|
||||
}
|
||||
|
||||
export function isLeftHandSideExpression(node: Node): node is LeftHandSideExpression {
|
||||
@ -4049,6 +3957,7 @@ namespace ts {
|
||||
|| kind === SyntaxKind.SpreadElement
|
||||
|| kind === SyntaxKind.AsExpression
|
||||
|| kind === SyntaxKind.OmittedExpression
|
||||
|| kind === SyntaxKind.RawExpression
|
||||
|| isUnaryExpressionKind(kind);
|
||||
}
|
||||
|
||||
@ -4588,7 +4497,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function isParameterPropertyDeclaration(node: ParameterDeclaration): boolean {
|
||||
export function isParameterPropertyDeclaration(node: Node): boolean {
|
||||
return hasModifier(node, ModifierFlags.ParameterPropertyModifier) && node.parent.kind === SyntaxKind.Constructor && isClassLike(node.parent.parent);
|
||||
}
|
||||
|
||||
|
||||
@ -99,20 +99,26 @@ namespace ts {
|
||||
return node ? f(initial, node) : initial;
|
||||
}
|
||||
|
||||
function reduceNodeArray<T>(nodes: Node[], f: (memo: T, nodes: Node[]) => T, initial: T) {
|
||||
return nodes ? f(initial, nodes) : initial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to `reduceLeft`, performs a reduction against each child of a node.
|
||||
* NOTE: Unlike `forEachChild`, this does *not* visit every node. Only nodes added to the
|
||||
* `nodeEdgeTraversalMap` above will be visited.
|
||||
*
|
||||
* @param node The node containing the children to reduce.
|
||||
* @param f The callback function
|
||||
* @param initial The initial value to supply to the reduction.
|
||||
* @param f The callback function
|
||||
*/
|
||||
export function reduceEachChild<T>(node: Node, f: (memo: T, node: Node) => T, initial: T): T {
|
||||
export function reduceEachChild<T>(node: Node, initial: T, cbNode: (memo: T, node: Node) => T, cbNodeArray?: (memo: T, nodes: Node[]) => T): T {
|
||||
if (node === undefined) {
|
||||
return initial;
|
||||
}
|
||||
|
||||
const reduceNodes: (nodes: Node[], f: (memo: T, node: Node | Node[]) => T, initial: T) => T = cbNodeArray ? reduceNodeArray : reduceLeft;
|
||||
const cbNodes = cbNodeArray || cbNode;
|
||||
const kind = node.kind;
|
||||
|
||||
// No need to visit nodes with no children.
|
||||
@ -138,127 +144,127 @@ namespace ts {
|
||||
|
||||
// Names
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
result = reduceNode((<ComputedPropertyName>node).expression, f, result);
|
||||
result = reduceNode((<ComputedPropertyName>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
// Signature elements
|
||||
case SyntaxKind.Parameter:
|
||||
result = reduceLeft((<ParameterDeclaration>node).decorators, f, result);
|
||||
result = reduceLeft((<ParameterDeclaration>node).modifiers, f, result);
|
||||
result = reduceNode((<ParameterDeclaration>node).name, f, result);
|
||||
result = reduceNode((<ParameterDeclaration>node).type, f, result);
|
||||
result = reduceNode((<ParameterDeclaration>node).initializer, f, result);
|
||||
result = reduceNodes((<ParameterDeclaration>node).decorators, cbNodes, result);
|
||||
result = reduceNodes((<ParameterDeclaration>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<ParameterDeclaration>node).name, cbNode, result);
|
||||
result = reduceNode((<ParameterDeclaration>node).type, cbNode, result);
|
||||
result = reduceNode((<ParameterDeclaration>node).initializer, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.Decorator:
|
||||
result = reduceNode((<Decorator>node).expression, f, result);
|
||||
result = reduceNode((<Decorator>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
// Type member
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
result = reduceLeft((<PropertyDeclaration>node).decorators, f, result);
|
||||
result = reduceLeft((<PropertyDeclaration>node).modifiers, f, result);
|
||||
result = reduceNode((<PropertyDeclaration>node).name, f, result);
|
||||
result = reduceNode((<PropertyDeclaration>node).type, f, result);
|
||||
result = reduceNode((<PropertyDeclaration>node).initializer, f, result);
|
||||
result = reduceNodes((<PropertyDeclaration>node).decorators, cbNodes, result);
|
||||
result = reduceNodes((<PropertyDeclaration>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<PropertyDeclaration>node).name, cbNode, result);
|
||||
result = reduceNode((<PropertyDeclaration>node).type, cbNode, result);
|
||||
result = reduceNode((<PropertyDeclaration>node).initializer, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
result = reduceLeft((<MethodDeclaration>node).decorators, f, result);
|
||||
result = reduceLeft((<MethodDeclaration>node).modifiers, f, result);
|
||||
result = reduceNode((<MethodDeclaration>node).name, f, result);
|
||||
result = reduceLeft((<MethodDeclaration>node).typeParameters, f, result);
|
||||
result = reduceLeft((<MethodDeclaration>node).parameters, f, result);
|
||||
result = reduceNode((<MethodDeclaration>node).type, f, result);
|
||||
result = reduceNode((<MethodDeclaration>node).body, f, result);
|
||||
result = reduceNodes((<MethodDeclaration>node).decorators, cbNodes, result);
|
||||
result = reduceNodes((<MethodDeclaration>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<MethodDeclaration>node).name, cbNode, result);
|
||||
result = reduceNodes((<MethodDeclaration>node).typeParameters, cbNodes, result);
|
||||
result = reduceNodes((<MethodDeclaration>node).parameters, cbNodes, result);
|
||||
result = reduceNode((<MethodDeclaration>node).type, cbNode, result);
|
||||
result = reduceNode((<MethodDeclaration>node).body, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.Constructor:
|
||||
result = reduceLeft((<ConstructorDeclaration>node).modifiers, f, result);
|
||||
result = reduceLeft((<ConstructorDeclaration>node).parameters, f, result);
|
||||
result = reduceNode((<ConstructorDeclaration>node).body, f, result);
|
||||
result = reduceNodes((<ConstructorDeclaration>node).modifiers, cbNodes, result);
|
||||
result = reduceNodes((<ConstructorDeclaration>node).parameters, cbNodes, result);
|
||||
result = reduceNode((<ConstructorDeclaration>node).body, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.GetAccessor:
|
||||
result = reduceLeft((<GetAccessorDeclaration>node).decorators, f, result);
|
||||
result = reduceLeft((<GetAccessorDeclaration>node).modifiers, f, result);
|
||||
result = reduceNode((<GetAccessorDeclaration>node).name, f, result);
|
||||
result = reduceLeft((<GetAccessorDeclaration>node).parameters, f, result);
|
||||
result = reduceNode((<GetAccessorDeclaration>node).type, f, result);
|
||||
result = reduceNode((<GetAccessorDeclaration>node).body, f, result);
|
||||
result = reduceNodes((<GetAccessorDeclaration>node).decorators, cbNodes, result);
|
||||
result = reduceNodes((<GetAccessorDeclaration>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<GetAccessorDeclaration>node).name, cbNode, result);
|
||||
result = reduceNodes((<GetAccessorDeclaration>node).parameters, cbNodes, result);
|
||||
result = reduceNode((<GetAccessorDeclaration>node).type, cbNode, result);
|
||||
result = reduceNode((<GetAccessorDeclaration>node).body, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.SetAccessor:
|
||||
result = reduceLeft((<GetAccessorDeclaration>node).decorators, f, result);
|
||||
result = reduceLeft((<GetAccessorDeclaration>node).modifiers, f, result);
|
||||
result = reduceNode((<GetAccessorDeclaration>node).name, f, result);
|
||||
result = reduceLeft((<GetAccessorDeclaration>node).parameters, f, result);
|
||||
result = reduceNode((<GetAccessorDeclaration>node).body, f, result);
|
||||
result = reduceNodes((<GetAccessorDeclaration>node).decorators, cbNodes, result);
|
||||
result = reduceNodes((<GetAccessorDeclaration>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<GetAccessorDeclaration>node).name, cbNode, result);
|
||||
result = reduceNodes((<GetAccessorDeclaration>node).parameters, cbNodes, result);
|
||||
result = reduceNode((<GetAccessorDeclaration>node).body, cbNode, result);
|
||||
break;
|
||||
|
||||
// Binding patterns
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
result = reduceLeft((<BindingPattern>node).elements, f, result);
|
||||
result = reduceNodes((<BindingPattern>node).elements, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.BindingElement:
|
||||
result = reduceNode((<BindingElement>node).propertyName, f, result);
|
||||
result = reduceNode((<BindingElement>node).name, f, result);
|
||||
result = reduceNode((<BindingElement>node).initializer, f, result);
|
||||
result = reduceNode((<BindingElement>node).propertyName, cbNode, result);
|
||||
result = reduceNode((<BindingElement>node).name, cbNode, result);
|
||||
result = reduceNode((<BindingElement>node).initializer, cbNode, result);
|
||||
break;
|
||||
|
||||
// Expression
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
result = reduceLeft((<ArrayLiteralExpression>node).elements, f, result);
|
||||
result = reduceNodes((<ArrayLiteralExpression>node).elements, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
result = reduceLeft((<ObjectLiteralExpression>node).properties, f, result);
|
||||
result = reduceNodes((<ObjectLiteralExpression>node).properties, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
result = reduceNode((<PropertyAccessExpression>node).expression, f, result);
|
||||
result = reduceNode((<PropertyAccessExpression>node).name, f, result);
|
||||
result = reduceNode((<PropertyAccessExpression>node).expression, cbNode, result);
|
||||
result = reduceNode((<PropertyAccessExpression>node).name, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
result = reduceNode((<ElementAccessExpression>node).expression, f, result);
|
||||
result = reduceNode((<ElementAccessExpression>node).argumentExpression, f, result);
|
||||
result = reduceNode((<ElementAccessExpression>node).expression, cbNode, result);
|
||||
result = reduceNode((<ElementAccessExpression>node).argumentExpression, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.CallExpression:
|
||||
result = reduceNode((<CallExpression>node).expression, f, result);
|
||||
result = reduceLeft((<CallExpression>node).typeArguments, f, result);
|
||||
result = reduceLeft((<CallExpression>node).arguments, f, result);
|
||||
result = reduceNode((<CallExpression>node).expression, cbNode, result);
|
||||
result = reduceNodes((<CallExpression>node).typeArguments, cbNodes, result);
|
||||
result = reduceNodes((<CallExpression>node).arguments, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.NewExpression:
|
||||
result = reduceNode((<NewExpression>node).expression, f, result);
|
||||
result = reduceLeft((<NewExpression>node).typeArguments, f, result);
|
||||
result = reduceLeft((<NewExpression>node).arguments, f, result);
|
||||
result = reduceNode((<NewExpression>node).expression, cbNode, result);
|
||||
result = reduceNodes((<NewExpression>node).typeArguments, cbNodes, result);
|
||||
result = reduceNodes((<NewExpression>node).arguments, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
result = reduceNode((<TaggedTemplateExpression>node).tag, f, result);
|
||||
result = reduceNode((<TaggedTemplateExpression>node).template, f, result);
|
||||
result = reduceNode((<TaggedTemplateExpression>node).tag, cbNode, result);
|
||||
result = reduceNode((<TaggedTemplateExpression>node).template, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.FunctionExpression:
|
||||
result = reduceLeft((<FunctionExpression>node).modifiers, f, result);
|
||||
result = reduceNode((<FunctionExpression>node).name, f, result);
|
||||
result = reduceLeft((<FunctionExpression>node).typeParameters, f, result);
|
||||
result = reduceLeft((<FunctionExpression>node).parameters, f, result);
|
||||
result = reduceNode((<FunctionExpression>node).type, f, result);
|
||||
result = reduceNode((<FunctionExpression>node).body, f, result);
|
||||
result = reduceNodes((<FunctionExpression>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<FunctionExpression>node).name, cbNode, result);
|
||||
result = reduceNodes((<FunctionExpression>node).typeParameters, cbNodes, result);
|
||||
result = reduceNodes((<FunctionExpression>node).parameters, cbNodes, result);
|
||||
result = reduceNode((<FunctionExpression>node).type, cbNode, result);
|
||||
result = reduceNode((<FunctionExpression>node).body, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ArrowFunction:
|
||||
result = reduceLeft((<ArrowFunction>node).modifiers, f, result);
|
||||
result = reduceLeft((<ArrowFunction>node).typeParameters, f, result);
|
||||
result = reduceLeft((<ArrowFunction>node).parameters, f, result);
|
||||
result = reduceNode((<ArrowFunction>node).type, f, result);
|
||||
result = reduceNode((<ArrowFunction>node).body, f, result);
|
||||
result = reduceNodes((<ArrowFunction>node).modifiers, cbNodes, result);
|
||||
result = reduceNodes((<ArrowFunction>node).typeParameters, cbNodes, result);
|
||||
result = reduceNodes((<ArrowFunction>node).parameters, cbNodes, result);
|
||||
result = reduceNode((<ArrowFunction>node).type, cbNode, result);
|
||||
result = reduceNode((<ArrowFunction>node).body, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
@ -269,258 +275,258 @@ namespace ts {
|
||||
case SyntaxKind.YieldExpression:
|
||||
case SyntaxKind.SpreadElement:
|
||||
case SyntaxKind.NonNullExpression:
|
||||
result = reduceNode((<ParenthesizedExpression | DeleteExpression | TypeOfExpression | VoidExpression | AwaitExpression | YieldExpression | SpreadElement | NonNullExpression>node).expression, f, result);
|
||||
result = reduceNode((<ParenthesizedExpression | DeleteExpression | TypeOfExpression | VoidExpression | AwaitExpression | YieldExpression | SpreadElement | NonNullExpression>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
case SyntaxKind.PostfixUnaryExpression:
|
||||
result = reduceNode((<PrefixUnaryExpression | PostfixUnaryExpression>node).operand, f, result);
|
||||
result = reduceNode((<PrefixUnaryExpression | PostfixUnaryExpression>node).operand, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.BinaryExpression:
|
||||
result = reduceNode((<BinaryExpression>node).left, f, result);
|
||||
result = reduceNode((<BinaryExpression>node).right, f, result);
|
||||
result = reduceNode((<BinaryExpression>node).left, cbNode, result);
|
||||
result = reduceNode((<BinaryExpression>node).right, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
result = reduceNode((<ConditionalExpression>node).condition, f, result);
|
||||
result = reduceNode((<ConditionalExpression>node).whenTrue, f, result);
|
||||
result = reduceNode((<ConditionalExpression>node).whenFalse, f, result);
|
||||
result = reduceNode((<ConditionalExpression>node).condition, cbNode, result);
|
||||
result = reduceNode((<ConditionalExpression>node).whenTrue, cbNode, result);
|
||||
result = reduceNode((<ConditionalExpression>node).whenFalse, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.TemplateExpression:
|
||||
result = reduceNode((<TemplateExpression>node).head, f, result);
|
||||
result = reduceLeft((<TemplateExpression>node).templateSpans, f, result);
|
||||
result = reduceNode((<TemplateExpression>node).head, cbNode, result);
|
||||
result = reduceNodes((<TemplateExpression>node).templateSpans, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ClassExpression:
|
||||
result = reduceLeft((<ClassExpression>node).modifiers, f, result);
|
||||
result = reduceNode((<ClassExpression>node).name, f, result);
|
||||
result = reduceLeft((<ClassExpression>node).typeParameters, f, result);
|
||||
result = reduceLeft((<ClassExpression>node).heritageClauses, f, result);
|
||||
result = reduceLeft((<ClassExpression>node).members, f, result);
|
||||
result = reduceNodes((<ClassExpression>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<ClassExpression>node).name, cbNode, result);
|
||||
result = reduceNodes((<ClassExpression>node).typeParameters, cbNodes, result);
|
||||
result = reduceNodes((<ClassExpression>node).heritageClauses, cbNodes, result);
|
||||
result = reduceNodes((<ClassExpression>node).members, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
result = reduceNode((<ExpressionWithTypeArguments>node).expression, f, result);
|
||||
result = reduceLeft((<ExpressionWithTypeArguments>node).typeArguments, f, result);
|
||||
result = reduceNode((<ExpressionWithTypeArguments>node).expression, cbNode, result);
|
||||
result = reduceNodes((<ExpressionWithTypeArguments>node).typeArguments, cbNodes, result);
|
||||
break;
|
||||
|
||||
// Misc
|
||||
case SyntaxKind.TemplateSpan:
|
||||
result = reduceNode((<TemplateSpan>node).expression, f, result);
|
||||
result = reduceNode((<TemplateSpan>node).literal, f, result);
|
||||
result = reduceNode((<TemplateSpan>node).expression, cbNode, result);
|
||||
result = reduceNode((<TemplateSpan>node).literal, cbNode, result);
|
||||
break;
|
||||
|
||||
// Element
|
||||
case SyntaxKind.Block:
|
||||
result = reduceLeft((<Block>node).statements, f, result);
|
||||
result = reduceNodes((<Block>node).statements, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.VariableStatement:
|
||||
result = reduceLeft((<VariableStatement>node).modifiers, f, result);
|
||||
result = reduceNode((<VariableStatement>node).declarationList, f, result);
|
||||
result = reduceNodes((<VariableStatement>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<VariableStatement>node).declarationList, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
result = reduceNode((<ExpressionStatement>node).expression, f, result);
|
||||
result = reduceNode((<ExpressionStatement>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.IfStatement:
|
||||
result = reduceNode((<IfStatement>node).expression, f, result);
|
||||
result = reduceNode((<IfStatement>node).thenStatement, f, result);
|
||||
result = reduceNode((<IfStatement>node).elseStatement, f, result);
|
||||
result = reduceNode((<IfStatement>node).expression, cbNode, result);
|
||||
result = reduceNode((<IfStatement>node).thenStatement, cbNode, result);
|
||||
result = reduceNode((<IfStatement>node).elseStatement, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.DoStatement:
|
||||
result = reduceNode((<DoStatement>node).statement, f, result);
|
||||
result = reduceNode((<DoStatement>node).expression, f, result);
|
||||
result = reduceNode((<DoStatement>node).statement, cbNode, result);
|
||||
result = reduceNode((<DoStatement>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.WithStatement:
|
||||
result = reduceNode((<WhileStatement | WithStatement>node).expression, f, result);
|
||||
result = reduceNode((<WhileStatement | WithStatement>node).statement, f, result);
|
||||
result = reduceNode((<WhileStatement | WithStatement>node).expression, cbNode, result);
|
||||
result = reduceNode((<WhileStatement | WithStatement>node).statement, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ForStatement:
|
||||
result = reduceNode((<ForStatement>node).initializer, f, result);
|
||||
result = reduceNode((<ForStatement>node).condition, f, result);
|
||||
result = reduceNode((<ForStatement>node).incrementor, f, result);
|
||||
result = reduceNode((<ForStatement>node).statement, f, result);
|
||||
result = reduceNode((<ForStatement>node).initializer, cbNode, result);
|
||||
result = reduceNode((<ForStatement>node).condition, cbNode, result);
|
||||
result = reduceNode((<ForStatement>node).incrementor, cbNode, result);
|
||||
result = reduceNode((<ForStatement>node).statement, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
result = reduceNode((<ForInStatement | ForOfStatement>node).initializer, f, result);
|
||||
result = reduceNode((<ForInStatement | ForOfStatement>node).expression, f, result);
|
||||
result = reduceNode((<ForInStatement | ForOfStatement>node).statement, f, result);
|
||||
result = reduceNode((<ForInStatement | ForOfStatement>node).initializer, cbNode, result);
|
||||
result = reduceNode((<ForInStatement | ForOfStatement>node).expression, cbNode, result);
|
||||
result = reduceNode((<ForInStatement | ForOfStatement>node).statement, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ReturnStatement:
|
||||
case SyntaxKind.ThrowStatement:
|
||||
result = reduceNode((<ReturnStatement>node).expression, f, result);
|
||||
result = reduceNode((<ReturnStatement>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.SwitchStatement:
|
||||
result = reduceNode((<SwitchStatement>node).expression, f, result);
|
||||
result = reduceNode((<SwitchStatement>node).caseBlock, f, result);
|
||||
result = reduceNode((<SwitchStatement>node).expression, cbNode, result);
|
||||
result = reduceNode((<SwitchStatement>node).caseBlock, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.LabeledStatement:
|
||||
result = reduceNode((<LabeledStatement>node).label, f, result);
|
||||
result = reduceNode((<LabeledStatement>node).statement, f, result);
|
||||
result = reduceNode((<LabeledStatement>node).label, cbNode, result);
|
||||
result = reduceNode((<LabeledStatement>node).statement, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.TryStatement:
|
||||
result = reduceNode((<TryStatement>node).tryBlock, f, result);
|
||||
result = reduceNode((<TryStatement>node).catchClause, f, result);
|
||||
result = reduceNode((<TryStatement>node).finallyBlock, f, result);
|
||||
result = reduceNode((<TryStatement>node).tryBlock, cbNode, result);
|
||||
result = reduceNode((<TryStatement>node).catchClause, cbNode, result);
|
||||
result = reduceNode((<TryStatement>node).finallyBlock, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
result = reduceNode((<VariableDeclaration>node).name, f, result);
|
||||
result = reduceNode((<VariableDeclaration>node).type, f, result);
|
||||
result = reduceNode((<VariableDeclaration>node).initializer, f, result);
|
||||
result = reduceNode((<VariableDeclaration>node).name, cbNode, result);
|
||||
result = reduceNode((<VariableDeclaration>node).type, cbNode, result);
|
||||
result = reduceNode((<VariableDeclaration>node).initializer, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.VariableDeclarationList:
|
||||
result = reduceLeft((<VariableDeclarationList>node).declarations, f, result);
|
||||
result = reduceNodes((<VariableDeclarationList>node).declarations, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
result = reduceLeft((<FunctionDeclaration>node).decorators, f, result);
|
||||
result = reduceLeft((<FunctionDeclaration>node).modifiers, f, result);
|
||||
result = reduceNode((<FunctionDeclaration>node).name, f, result);
|
||||
result = reduceLeft((<FunctionDeclaration>node).typeParameters, f, result);
|
||||
result = reduceLeft((<FunctionDeclaration>node).parameters, f, result);
|
||||
result = reduceNode((<FunctionDeclaration>node).type, f, result);
|
||||
result = reduceNode((<FunctionDeclaration>node).body, f, result);
|
||||
result = reduceNodes((<FunctionDeclaration>node).decorators, cbNodes, result);
|
||||
result = reduceNodes((<FunctionDeclaration>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<FunctionDeclaration>node).name, cbNode, result);
|
||||
result = reduceNodes((<FunctionDeclaration>node).typeParameters, cbNodes, result);
|
||||
result = reduceNodes((<FunctionDeclaration>node).parameters, cbNodes, result);
|
||||
result = reduceNode((<FunctionDeclaration>node).type, cbNode, result);
|
||||
result = reduceNode((<FunctionDeclaration>node).body, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
result = reduceLeft((<ClassDeclaration>node).decorators, f, result);
|
||||
result = reduceLeft((<ClassDeclaration>node).modifiers, f, result);
|
||||
result = reduceNode((<ClassDeclaration>node).name, f, result);
|
||||
result = reduceLeft((<ClassDeclaration>node).typeParameters, f, result);
|
||||
result = reduceLeft((<ClassDeclaration>node).heritageClauses, f, result);
|
||||
result = reduceLeft((<ClassDeclaration>node).members, f, result);
|
||||
result = reduceNodes((<ClassDeclaration>node).decorators, cbNodes, result);
|
||||
result = reduceNodes((<ClassDeclaration>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<ClassDeclaration>node).name, cbNode, result);
|
||||
result = reduceNodes((<ClassDeclaration>node).typeParameters, cbNodes, result);
|
||||
result = reduceNodes((<ClassDeclaration>node).heritageClauses, cbNodes, result);
|
||||
result = reduceNodes((<ClassDeclaration>node).members, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.CaseBlock:
|
||||
result = reduceLeft((<CaseBlock>node).clauses, f, result);
|
||||
result = reduceNodes((<CaseBlock>node).clauses, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
result = reduceLeft((<ImportDeclaration>node).decorators, f, result);
|
||||
result = reduceLeft((<ImportDeclaration>node).modifiers, f, result);
|
||||
result = reduceNode((<ImportDeclaration>node).importClause, f, result);
|
||||
result = reduceNode((<ImportDeclaration>node).moduleSpecifier, f, result);
|
||||
result = reduceNodes((<ImportDeclaration>node).decorators, cbNodes, result);
|
||||
result = reduceNodes((<ImportDeclaration>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<ImportDeclaration>node).importClause, cbNode, result);
|
||||
result = reduceNode((<ImportDeclaration>node).moduleSpecifier, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ImportClause:
|
||||
result = reduceNode((<ImportClause>node).name, f, result);
|
||||
result = reduceNode((<ImportClause>node).namedBindings, f, result);
|
||||
result = reduceNode((<ImportClause>node).name, cbNode, result);
|
||||
result = reduceNode((<ImportClause>node).namedBindings, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.NamespaceImport:
|
||||
result = reduceNode((<NamespaceImport>node).name, f, result);
|
||||
result = reduceNode((<NamespaceImport>node).name, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.NamedImports:
|
||||
case SyntaxKind.NamedExports:
|
||||
result = reduceLeft((<NamedImports | NamedExports>node).elements, f, result);
|
||||
result = reduceNodes((<NamedImports | NamedExports>node).elements, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
case SyntaxKind.ExportSpecifier:
|
||||
result = reduceNode((<ImportSpecifier | ExportSpecifier>node).propertyName, f, result);
|
||||
result = reduceNode((<ImportSpecifier | ExportSpecifier>node).name, f, result);
|
||||
result = reduceNode((<ImportSpecifier | ExportSpecifier>node).propertyName, cbNode, result);
|
||||
result = reduceNode((<ImportSpecifier | ExportSpecifier>node).name, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportAssignment:
|
||||
result = reduceLeft((<ExportAssignment>node).decorators, f, result);
|
||||
result = reduceLeft((<ExportAssignment>node).modifiers, f, result);
|
||||
result = reduceNode((<ExportAssignment>node).expression, f, result);
|
||||
result = reduceLeft((<ExportAssignment>node).decorators, cbNode, result);
|
||||
result = reduceLeft((<ExportAssignment>node).modifiers, cbNode, result);
|
||||
result = reduceNode((<ExportAssignment>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
result = reduceLeft((<ExportDeclaration>node).decorators, f, result);
|
||||
result = reduceLeft((<ExportDeclaration>node).modifiers, f, result);
|
||||
result = reduceNode((<ExportDeclaration>node).exportClause, f, result);
|
||||
result = reduceNode((<ExportDeclaration>node).moduleSpecifier, f, result);
|
||||
result = reduceLeft((<ExportDeclaration>node).decorators, cbNode, result);
|
||||
result = reduceLeft((<ExportDeclaration>node).modifiers, cbNode, result);
|
||||
result = reduceNode((<ExportDeclaration>node).exportClause, cbNode, result);
|
||||
result = reduceNode((<ExportDeclaration>node).moduleSpecifier, cbNode, result);
|
||||
break;
|
||||
|
||||
// JSX
|
||||
case SyntaxKind.JsxElement:
|
||||
result = reduceNode((<JsxElement>node).openingElement, f, result);
|
||||
result = reduceLeft((<JsxElement>node).children, f, result);
|
||||
result = reduceNode((<JsxElement>node).closingElement, f, result);
|
||||
result = reduceNode((<JsxElement>node).openingElement, cbNode, result);
|
||||
result = reduceLeft((<JsxElement>node).children, cbNode, result);
|
||||
result = reduceNode((<JsxElement>node).closingElement, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
result = reduceNode((<JsxSelfClosingElement | JsxOpeningElement>node).tagName, f, result);
|
||||
result = reduceLeft((<JsxSelfClosingElement | JsxOpeningElement>node).attributes, f, result);
|
||||
result = reduceNode((<JsxSelfClosingElement | JsxOpeningElement>node).tagName, cbNode, result);
|
||||
result = reduceNodes((<JsxSelfClosingElement | JsxOpeningElement>node).attributes, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
result = reduceNode((<JsxClosingElement>node).tagName, f, result);
|
||||
result = reduceNode((<JsxClosingElement>node).tagName, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.JsxAttribute:
|
||||
result = reduceNode((<JsxAttribute>node).name, f, result);
|
||||
result = reduceNode((<JsxAttribute>node).initializer, f, result);
|
||||
result = reduceNode((<JsxAttribute>node).name, cbNode, result);
|
||||
result = reduceNode((<JsxAttribute>node).initializer, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
result = reduceNode((<JsxSpreadAttribute>node).expression, f, result);
|
||||
result = reduceNode((<JsxSpreadAttribute>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.JsxExpression:
|
||||
result = reduceNode((<JsxExpression>node).expression, f, result);
|
||||
result = reduceNode((<JsxExpression>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
// Clauses
|
||||
case SyntaxKind.CaseClause:
|
||||
result = reduceNode((<CaseClause>node).expression, f, result);
|
||||
result = reduceNode((<CaseClause>node).expression, cbNode, result);
|
||||
// fall-through
|
||||
|
||||
case SyntaxKind.DefaultClause:
|
||||
result = reduceLeft((<CaseClause | DefaultClause>node).statements, f, result);
|
||||
result = reduceNodes((<CaseClause | DefaultClause>node).statements, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.HeritageClause:
|
||||
result = reduceLeft((<HeritageClause>node).types, f, result);
|
||||
result = reduceNodes((<HeritageClause>node).types, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.CatchClause:
|
||||
result = reduceNode((<CatchClause>node).variableDeclaration, f, result);
|
||||
result = reduceNode((<CatchClause>node).block, f, result);
|
||||
result = reduceNode((<CatchClause>node).variableDeclaration, cbNode, result);
|
||||
result = reduceNode((<CatchClause>node).block, cbNode, result);
|
||||
break;
|
||||
|
||||
// Property assignments
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
result = reduceNode((<PropertyAssignment>node).name, f, result);
|
||||
result = reduceNode((<PropertyAssignment>node).initializer, f, result);
|
||||
result = reduceNode((<PropertyAssignment>node).name, cbNode, result);
|
||||
result = reduceNode((<PropertyAssignment>node).initializer, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
result = reduceNode((<ShorthandPropertyAssignment>node).name, f, result);
|
||||
result = reduceNode((<ShorthandPropertyAssignment>node).objectAssignmentInitializer, f, result);
|
||||
result = reduceNode((<ShorthandPropertyAssignment>node).name, cbNode, result);
|
||||
result = reduceNode((<ShorthandPropertyAssignment>node).objectAssignmentInitializer, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
result = reduceNode((node as SpreadAssignment).expression, f, result);
|
||||
result = reduceNode((node as SpreadAssignment).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
// Top-level nodes
|
||||
case SyntaxKind.SourceFile:
|
||||
result = reduceLeft((<SourceFile>node).statements, f, result);
|
||||
result = reduceNodes((<SourceFile>node).statements, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
result = reduceNode((<PartiallyEmittedExpression>node).expression, f, result);
|
||||
result = reduceNode((<PartiallyEmittedExpression>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -530,8 +536,8 @@ namespace ts {
|
||||
const value = (<MapLike<any>>node)[edge.name];
|
||||
if (value !== undefined) {
|
||||
result = isArray(value)
|
||||
? reduceLeft(<NodeArray<Node>>value, f, result)
|
||||
: f(result, <Node>value);
|
||||
? reduceNodes(<NodeArray<Node>>value, cbNodes, result)
|
||||
: cbNode(result, <Node>value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -553,8 +559,8 @@ namespace ts {
|
||||
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional?: boolean, lift?: (node: NodeArray<Node>) => T): T;
|
||||
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional: boolean, lift: (node: NodeArray<Node>) => T, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node): T;
|
||||
export function visitNode(node: Node, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional?: boolean, lift?: (node: Node[]) => Node, parenthesize?: (node: Node, parentNode: Node) => Node, parentNode?: Node): Node {
|
||||
if (node === undefined) {
|
||||
return undefined;
|
||||
if (node === undefined || visitor === undefined) {
|
||||
return node;
|
||||
}
|
||||
|
||||
aggregateTransformFlags(node);
|
||||
@ -659,6 +665,53 @@ namespace ts {
|
||||
return updated || nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new lexical environment and visits a statement list, ending the lexical environment
|
||||
* and merging hoisted declarations upon completion.
|
||||
*/
|
||||
export function visitLexicalEnvironment(statements: NodeArray<Statement>, visitor: (node: Node) => VisitResult<Node>, context: TransformationContext, start?: number, ensureUseStrict?: boolean) {
|
||||
context.startLexicalEnvironment();
|
||||
statements = visitNodes(statements, visitor, isStatement, start);
|
||||
if (ensureUseStrict && !startsWithUseStrict(statements)) {
|
||||
statements = createNodeArray([createStatement(createLiteral("use strict")), ...statements], statements);
|
||||
}
|
||||
const declarations = context.endLexicalEnvironment();
|
||||
return createNodeArray(concatenate(statements, declarations), statements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new lexical environment and visits a parameter list, suspending the lexical
|
||||
* environment upon completion.
|
||||
*/
|
||||
export function visitParameterList(nodes: NodeArray<ParameterDeclaration>, visitor: (node: Node) => VisitResult<Node>, context: TransformationContext) {
|
||||
context.startLexicalEnvironment();
|
||||
const updated = visitNodes(nodes, visitor, isParameterDeclaration);
|
||||
context.suspendLexicalEnvironment();
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes a suspended lexical environment and visits a function body, ending the lexical
|
||||
* environment and merging hoisted declarations upon completion.
|
||||
*/
|
||||
export function visitFunctionBody(node: FunctionBody, visitor: (node: Node) => VisitResult<Node>, context: TransformationContext): FunctionBody;
|
||||
/**
|
||||
* Resumes a suspended lexical environment and visits a concise body, ending the lexical
|
||||
* environment and merging hoisted declarations upon completion.
|
||||
*/
|
||||
export function visitFunctionBody(node: ConciseBody, visitor: (node: Node) => VisitResult<Node>, context: TransformationContext): ConciseBody;
|
||||
export function visitFunctionBody(node: ConciseBody, visitor: (node: Node) => VisitResult<Node>, context: TransformationContext): ConciseBody {
|
||||
context.resumeLexicalEnvironment();
|
||||
const updated = visitNode(node, visitor, isConciseBody);
|
||||
const declarations = context.endLexicalEnvironment();
|
||||
if (some(declarations)) {
|
||||
const block = convertToFunctionBody(updated);
|
||||
const statements = mergeLexicalEnvironment(block.statements, declarations);
|
||||
return updateBlock(block, statements);
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place.
|
||||
*
|
||||
@ -666,8 +719,8 @@ namespace ts {
|
||||
* @param visitor The callback used to visit each child.
|
||||
* @param context A lexical environment context for the visitor.
|
||||
*/
|
||||
export function visitEachChild<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment): T;
|
||||
export function visitEachChild(node: Node, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment): Node {
|
||||
export function visitEachChild<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, context: TransformationContext): T;
|
||||
export function visitEachChild(node: Node, visitor: (node: Node) => VisitResult<Node>, context: TransformationContext): Node {
|
||||
if (node === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
@ -701,6 +754,7 @@ namespace ts {
|
||||
return updateParameter(<ParameterDeclaration>node,
|
||||
visitNodes((<ParameterDeclaration>node).decorators, visitor, isDecorator),
|
||||
visitNodes((<ParameterDeclaration>node).modifiers, visitor, isModifier),
|
||||
(<ParameterDeclaration>node).dotDotDotToken,
|
||||
visitNode((<ParameterDeclaration>node).name, visitor, isBindingName),
|
||||
visitNode((<ParameterDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
|
||||
visitNode((<ParameterDeclaration>node).initializer, visitor, isExpression, /*optional*/ true));
|
||||
@ -720,41 +774,33 @@ namespace ts {
|
||||
visitNodes((<MethodDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<MethodDeclaration>node).name, visitor, isPropertyName),
|
||||
visitNodes((<MethodDeclaration>node).typeParameters, visitor, isTypeParameter),
|
||||
(context.startLexicalEnvironment(), visitNodes((<MethodDeclaration>node).parameters, visitor, isParameter)),
|
||||
visitParameterList((<MethodDeclaration>node).parameters, visitor, context),
|
||||
visitNode((<MethodDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
|
||||
mergeFunctionBodyLexicalEnvironment(
|
||||
visitNode((<MethodDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
|
||||
context.endLexicalEnvironment()));
|
||||
visitFunctionBody((<MethodDeclaration>node).body, visitor, context));
|
||||
|
||||
case SyntaxKind.Constructor:
|
||||
return updateConstructor(<ConstructorDeclaration>node,
|
||||
visitNodes((<ConstructorDeclaration>node).decorators, visitor, isDecorator),
|
||||
visitNodes((<ConstructorDeclaration>node).modifiers, visitor, isModifier),
|
||||
(context.startLexicalEnvironment(), visitNodes((<ConstructorDeclaration>node).parameters, visitor, isParameter)),
|
||||
mergeFunctionBodyLexicalEnvironment(
|
||||
visitNode((<ConstructorDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
|
||||
context.endLexicalEnvironment()));
|
||||
visitParameterList((<ConstructorDeclaration>node).parameters, visitor, context),
|
||||
visitFunctionBody((<ConstructorDeclaration>node).body, visitor, context));
|
||||
|
||||
case SyntaxKind.GetAccessor:
|
||||
return updateGetAccessor(<GetAccessorDeclaration>node,
|
||||
visitNodes((<GetAccessorDeclaration>node).decorators, visitor, isDecorator),
|
||||
visitNodes((<GetAccessorDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<GetAccessorDeclaration>node).name, visitor, isPropertyName),
|
||||
(context.startLexicalEnvironment(), visitNodes((<GetAccessorDeclaration>node).parameters, visitor, isParameter)),
|
||||
visitParameterList((<GetAccessorDeclaration>node).parameters, visitor, context),
|
||||
visitNode((<GetAccessorDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
|
||||
mergeFunctionBodyLexicalEnvironment(
|
||||
visitNode((<GetAccessorDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
|
||||
context.endLexicalEnvironment()));
|
||||
visitFunctionBody((<GetAccessorDeclaration>node).body, visitor, context));
|
||||
|
||||
case SyntaxKind.SetAccessor:
|
||||
return updateSetAccessor(<SetAccessorDeclaration>node,
|
||||
visitNodes((<SetAccessorDeclaration>node).decorators, visitor, isDecorator),
|
||||
visitNodes((<SetAccessorDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<SetAccessorDeclaration>node).name, visitor, isPropertyName),
|
||||
(context.startLexicalEnvironment(), visitNodes((<SetAccessorDeclaration>node).parameters, visitor, isParameter)),
|
||||
mergeFunctionBodyLexicalEnvironment(
|
||||
visitNode((<SetAccessorDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
|
||||
context.endLexicalEnvironment()));
|
||||
visitParameterList((<SetAccessorDeclaration>node).parameters, visitor, context),
|
||||
visitFunctionBody((<SetAccessorDeclaration>node).body, visitor, context));
|
||||
|
||||
// Binding patterns
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
@ -767,6 +813,7 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.BindingElement:
|
||||
return updateBindingElement(<BindingElement>node,
|
||||
(<BindingElement>node).dotDotDotToken,
|
||||
visitNode((<BindingElement>node).propertyName, visitor, isPropertyName, /*optional*/ true),
|
||||
visitNode((<BindingElement>node).name, visitor, isBindingName),
|
||||
visitNode((<BindingElement>node).initializer, visitor, isExpression, /*optional*/ true));
|
||||
@ -816,21 +863,17 @@ namespace ts {
|
||||
visitNodes((<FunctionExpression>node).modifiers, visitor, isModifier),
|
||||
visitNode((<FunctionExpression>node).name, visitor, isPropertyName),
|
||||
visitNodes((<FunctionExpression>node).typeParameters, visitor, isTypeParameter),
|
||||
(context.startLexicalEnvironment(), visitNodes((<FunctionExpression>node).parameters, visitor, isParameter)),
|
||||
visitParameterList((<FunctionExpression>node).parameters, visitor, context),
|
||||
visitNode((<FunctionExpression>node).type, visitor, isTypeNode, /*optional*/ true),
|
||||
mergeFunctionBodyLexicalEnvironment(
|
||||
visitNode((<FunctionExpression>node).body, visitor, isFunctionBody, /*optional*/ true),
|
||||
context.endLexicalEnvironment()));
|
||||
visitFunctionBody((<FunctionExpression>node).body, visitor, context));
|
||||
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return updateArrowFunction(<ArrowFunction>node,
|
||||
visitNodes((<ArrowFunction>node).modifiers, visitor, isModifier),
|
||||
visitNodes((<ArrowFunction>node).typeParameters, visitor, isTypeParameter),
|
||||
(context.startLexicalEnvironment(), visitNodes((<ArrowFunction>node).parameters, visitor, isParameter)),
|
||||
visitParameterList((<ArrowFunction>node).parameters, visitor, context),
|
||||
visitNode((<ArrowFunction>node).type, visitor, isTypeNode, /*optional*/ true),
|
||||
mergeFunctionBodyLexicalEnvironment(
|
||||
visitNode((<ArrowFunction>node).body, visitor, isConciseBody, /*optional*/ true),
|
||||
context.endLexicalEnvironment()));
|
||||
visitFunctionBody((<ArrowFunction>node).body, visitor, context));
|
||||
|
||||
case SyntaxKind.DeleteExpression:
|
||||
return updateDelete(<DeleteExpression>node,
|
||||
@ -1001,11 +1044,9 @@ namespace ts {
|
||||
visitNodes((<FunctionDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<FunctionDeclaration>node).name, visitor, isPropertyName),
|
||||
visitNodes((<FunctionDeclaration>node).typeParameters, visitor, isTypeParameter),
|
||||
(context.startLexicalEnvironment(), visitNodes((<FunctionDeclaration>node).parameters, visitor, isParameter)),
|
||||
visitParameterList((<FunctionDeclaration>node).parameters, visitor, context),
|
||||
visitNode((<FunctionDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
|
||||
mergeFunctionBodyLexicalEnvironment(
|
||||
visitNode((<FunctionDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
|
||||
context.endLexicalEnvironment()));
|
||||
visitFunctionBody((<FunctionExpression>node).body, visitor, context));
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return updateClassDeclaration(<ClassDeclaration>node,
|
||||
@ -1137,13 +1178,8 @@ namespace ts {
|
||||
|
||||
// Top-level nodes
|
||||
case SyntaxKind.SourceFile:
|
||||
context.startLexicalEnvironment();
|
||||
return updateSourceFileNode(<SourceFile>node,
|
||||
createNodeArray(
|
||||
concatenate(
|
||||
visitNodes((<SourceFile>node).statements, visitor, isStatement),
|
||||
context.endLexicalEnvironment()),
|
||||
(<SourceFile>node).statements));
|
||||
visitLexicalEnvironment((<SourceFile>node).statements, visitor, context));
|
||||
|
||||
// Transformation nodes
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
@ -1177,6 +1213,24 @@ namespace ts {
|
||||
// return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges generated lexical declarations into a new statement list.
|
||||
*/
|
||||
export function mergeLexicalEnvironment(statements: NodeArray<Statement>, declarations: Statement[]): NodeArray<Statement>;
|
||||
/**
|
||||
* Appends generated lexical declarations to an array of statements.
|
||||
*/
|
||||
export function mergeLexicalEnvironment(statements: Statement[], declarations: Statement[]): Statement[];
|
||||
export function mergeLexicalEnvironment(statements: Statement[], declarations: Statement[]) {
|
||||
if (!some(declarations)) {
|
||||
return statements;
|
||||
}
|
||||
return isNodeArray(statements)
|
||||
? createNodeArray(concatenate(statements, declarations), statements)
|
||||
: addRange(statements, declarations);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Merges generated lexical declarations into the FunctionBody of a non-arrow function-like declaration.
|
||||
*
|
||||
@ -1247,13 +1301,25 @@ namespace ts {
|
||||
if (node === undefined) {
|
||||
return TransformFlags.None;
|
||||
}
|
||||
else if (node.transformFlags & TransformFlags.HasComputedFlags) {
|
||||
if (node.transformFlags & TransformFlags.HasComputedFlags) {
|
||||
return node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind);
|
||||
}
|
||||
else {
|
||||
const subtreeFlags = aggregateTransformFlagsForSubtree(node);
|
||||
return computeTransformFlagsForNode(node, subtreeFlags);
|
||||
const subtreeFlags = aggregateTransformFlagsForSubtree(node);
|
||||
return computeTransformFlagsForNode(node, subtreeFlags);
|
||||
}
|
||||
|
||||
function aggregateTransformFlagsForNodeArray(nodes: NodeArray<Node>): TransformFlags {
|
||||
if (nodes === undefined) {
|
||||
return TransformFlags.None;
|
||||
}
|
||||
let subtreeFlags = TransformFlags.None;
|
||||
let nodeArrayFlags = TransformFlags.None;
|
||||
for (const node of nodes) {
|
||||
subtreeFlags |= aggregateTransformFlagsForNode(node);
|
||||
nodeArrayFlags |= node.transformFlags & ~TransformFlags.HasComputedFlags;
|
||||
}
|
||||
nodes.transformFlags = nodeArrayFlags | TransformFlags.HasComputedFlags;
|
||||
return subtreeFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1267,15 +1333,19 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Aggregate the transform flags of each child.
|
||||
return reduceEachChild(node, aggregateTransformFlagsForChildNode, TransformFlags.None);
|
||||
return reduceEachChild(node, TransformFlags.None, aggregateTransformFlagsForChildNode, aggregateTransformFlagsForChildNodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Aggregates the TransformFlags of a child node with the TransformFlags of its
|
||||
* siblings.
|
||||
*/
|
||||
function aggregateTransformFlagsForChildNode(transformFlags: TransformFlags, child: Node): TransformFlags {
|
||||
return transformFlags | aggregateTransformFlagsForNode(child);
|
||||
function aggregateTransformFlagsForChildNode(transformFlags: TransformFlags, node: Node): TransformFlags {
|
||||
return transformFlags | aggregateTransformFlagsForNode(node);
|
||||
}
|
||||
|
||||
function aggregateTransformFlagsForChildNodes(transformFlags: TransformFlags, nodes: NodeArray<Node>): TransformFlags {
|
||||
return transformFlags | aggregateTransformFlagsForNodeArray(nodes);
|
||||
}
|
||||
|
||||
export namespace Debug {
|
||||
@ -1287,6 +1357,13 @@ namespace ts {
|
||||
? (node: Node, message?: string) => assert(false, message || "Unexpected node.", () => `Node ${formatSyntaxKind(node.kind)} was unexpected.`)
|
||||
: noop;
|
||||
|
||||
export const assertEachNode = shouldAssert(AssertionLevel.Normal)
|
||||
? (nodes: Node[], test: (node: Node) => boolean, message?: string) => assert(
|
||||
test === undefined || every(nodes, test),
|
||||
message || "Unexpected node.",
|
||||
() => `Node array did not pass test '${getFunctionName(test)}'.`)
|
||||
: noop;
|
||||
|
||||
export const assertNode = shouldAssert(AssertionLevel.Normal)
|
||||
? (node: Node, test: (node: Node) => boolean, message?: string) => assert(
|
||||
test === undefined || test(node),
|
||||
@ -1294,6 +1371,27 @@ namespace ts {
|
||||
() => `Node ${formatSyntaxKind(node.kind)} did not pass test '${getFunctionName(test)}'.`)
|
||||
: noop;
|
||||
|
||||
export const assertOptionalNode = shouldAssert(AssertionLevel.Normal)
|
||||
? (node: Node, test: (node: Node) => boolean, message?: string) => assert(
|
||||
test === undefined || node === undefined || test(node),
|
||||
message || "Unexpected node.",
|
||||
() => `Node ${formatSyntaxKind(node.kind)} did not pass test '${getFunctionName(test)}'.`)
|
||||
: noop;
|
||||
|
||||
export const assertOptionalToken = shouldAssert(AssertionLevel.Normal)
|
||||
? (node: Node, kind: SyntaxKind, message?: string) => assert(
|
||||
kind === undefined || node === undefined || node.kind === kind,
|
||||
message || "Unexpected node.",
|
||||
() => `Node ${formatSyntaxKind(node.kind)} was not a '${formatSyntaxKind(kind)}' token.`)
|
||||
: noop;
|
||||
|
||||
export const assertMissingNode = shouldAssert(AssertionLevel.Normal)
|
||||
? (node: Node, message?: string) => assert(
|
||||
node === undefined,
|
||||
message || "Unexpected node.",
|
||||
() => `Node ${formatSyntaxKind(node.kind)} was unexpected'.`)
|
||||
: noop;
|
||||
|
||||
function getFunctionName(func: Function) {
|
||||
if (typeof func !== "function") {
|
||||
return "";
|
||||
|
||||
@ -2094,6 +2094,34 @@ namespace FourSlash {
|
||||
this.applyEdits(fileChanges.fileName, fileChanges.textChanges, /*isFormattingEdit*/ false);
|
||||
}
|
||||
|
||||
public verifyImportFixAtPosition(expectedTextArray: string[], errorCode?: number) {
|
||||
const ranges = this.getRanges();
|
||||
if (ranges.length == 0) {
|
||||
this.raiseError("At least one range should be specified in the testfile.");
|
||||
}
|
||||
|
||||
const codeFixes = this.getCodeFixActions(this.activeFile.fileName, errorCode);
|
||||
|
||||
if (!codeFixes || codeFixes.length == 0) {
|
||||
this.raiseError("No codefixes returned.");
|
||||
}
|
||||
|
||||
const actualTextArray: string[] = [];
|
||||
const scriptInfo = this.languageServiceAdapterHost.getScriptInfo(codeFixes[0].changes[0].fileName);
|
||||
const originalContent = scriptInfo.content;
|
||||
for (const codeFix of codeFixes) {
|
||||
this.applyEdits(codeFix.changes[0].fileName, codeFix.changes[0].textChanges, /*isFormattingEdit*/ false);
|
||||
actualTextArray.push(this.normalizeNewlines(this.rangeText(ranges[0])));
|
||||
scriptInfo.updateContent(originalContent);
|
||||
}
|
||||
const sortedExpectedArray = ts.map(expectedTextArray, str => this.normalizeNewlines(str)).sort();
|
||||
const sortedActualArray = actualTextArray.sort();
|
||||
if (!ts.arrayIsEqualTo(sortedExpectedArray, sortedActualArray)) {
|
||||
this.raiseError(
|
||||
`Actual text array doesn't match expected text array. \nActual: \n"${sortedActualArray.join("\n\n")}"\n---\nExpected: \n'${sortedExpectedArray.join("\n\n")}'`);
|
||||
}
|
||||
}
|
||||
|
||||
public verifyDocCommentTemplate(expected?: ts.TextInsertion) {
|
||||
const name = "verifyDocCommentTemplate";
|
||||
const actual = this.languageService.getDocCommentTemplateAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
@ -2127,6 +2155,10 @@ namespace FourSlash {
|
||||
});
|
||||
}
|
||||
|
||||
private normalizeNewlines(str: string) {
|
||||
return str.replace(/\r?\n/g, "\n");
|
||||
}
|
||||
|
||||
public verifyBraceCompletionAtPosition(negative: boolean, openingBrace: string) {
|
||||
|
||||
const openBraceMap = ts.createMap<ts.CharacterCodes>({
|
||||
@ -2654,7 +2686,7 @@ ${code}
|
||||
resetLocalData();
|
||||
}
|
||||
|
||||
currentFileName = basePath + "/" + value;
|
||||
currentFileName = ts.isRootedDiskPath(value) ? value : basePath + "/" + value;
|
||||
currentFileOptions[key] = value;
|
||||
}
|
||||
else {
|
||||
@ -3351,6 +3383,10 @@ namespace FourSlashInterface {
|
||||
this.state.verifyRangeAfterCodeFix(expectedText, errorCode);
|
||||
}
|
||||
|
||||
public importFixAtPosition(expectedTextArray: string[], errorCode?: number): void {
|
||||
this.state.verifyImportFixAtPosition(expectedTextArray, errorCode);
|
||||
}
|
||||
|
||||
public navigationBar(json: any) {
|
||||
this.state.verifyNavigationBar(json);
|
||||
}
|
||||
|
||||
@ -61,6 +61,10 @@ function createRunner(kind: TestRunnerKind): RunnerBase {
|
||||
}
|
||||
}
|
||||
|
||||
if (Harness.IO.tryEnableSourceMapsForHost && /^development$/i.test(Harness.IO.getEnvironmentVariable("NODE_ENV"))) {
|
||||
Harness.IO.tryEnableSourceMapsForHost();
|
||||
}
|
||||
|
||||
// users can define tests to run in mytest.config that will override cmd line args, otherwise use cmd line args (test.config), otherwise no options
|
||||
|
||||
const mytestconfigFileName = "mytest.config";
|
||||
|
||||
@ -179,7 +179,7 @@ namespace ts {
|
||||
testFailure("can error when 'extends' is neither relative nor rooted.", "extends2.json", [{
|
||||
code: 18001,
|
||||
category: DiagnosticCategory.Error,
|
||||
messageText: `The path in an 'extends' options must be relative or rooted.`
|
||||
messageText: `A path in an 'extends' option must be relative or rooted, but 'configs/base' is not.`
|
||||
}]);
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* @internal */
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export interface CodeFix {
|
||||
errorCodes: number[];
|
||||
@ -11,6 +11,8 @@ namespace ts {
|
||||
span: TextSpan;
|
||||
program: Program;
|
||||
newLineCharacter: string;
|
||||
host: LanguageServiceHost;
|
||||
cancellationToken: CancellationToken;
|
||||
}
|
||||
|
||||
export namespace codefix {
|
||||
|
||||
@ -3,4 +3,6 @@
|
||||
/// <reference path="fixClassSuperMustPrecedeThisAccess.ts" />
|
||||
/// <reference path="fixConstructorForDerivedNeedSuperCall.ts" />
|
||||
/// <reference path="fixExtendsInterfaceBecomesImplements.ts" />
|
||||
///<reference path='unusedIdentifierFixes.ts' />
|
||||
///<reference path='unusedIdentifierFixes.ts' />
|
||||
///<reference path='importFixes.ts' />
|
||||
|
||||
|
||||
591
src/services/codefixes/importFixes.ts
Normal file
591
src/services/codefixes/importFixes.ts
Normal file
@ -0,0 +1,591 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
|
||||
type ImportCodeActionKind = "CodeChange" | "InsertingIntoExistingImport" | "NewImport";
|
||||
interface ImportCodeAction extends CodeAction {
|
||||
kind: ImportCodeActionKind,
|
||||
moduleSpecifier?: string
|
||||
}
|
||||
|
||||
enum ModuleSpecifierComparison {
|
||||
Better,
|
||||
Equal,
|
||||
Worse
|
||||
}
|
||||
|
||||
class ImportCodeActionMap {
|
||||
private symbolIdToActionMap = createMap<ImportCodeAction[]>();
|
||||
|
||||
addAction(symbolId: number, newAction: ImportCodeAction) {
|
||||
if (!newAction) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.symbolIdToActionMap[symbolId]) {
|
||||
this.symbolIdToActionMap[symbolId] = [newAction];
|
||||
return;
|
||||
}
|
||||
|
||||
if (newAction.kind === "CodeChange") {
|
||||
this.symbolIdToActionMap[symbolId].push(newAction);
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedNewImports: ImportCodeAction[] = [];
|
||||
for (const existingAction of this.symbolIdToActionMap[symbolId]) {
|
||||
if (existingAction.kind === "CodeChange") {
|
||||
// only import actions should compare
|
||||
updatedNewImports.push(existingAction);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (this.compareModuleSpecifiers(existingAction.moduleSpecifier, newAction.moduleSpecifier)) {
|
||||
case ModuleSpecifierComparison.Better:
|
||||
// the new one is not worth considering if it is a new improt.
|
||||
// However if it is instead a insertion into existing import, the user might want to use
|
||||
// the module specifier even it is worse by our standards. So keep it.
|
||||
if (newAction.kind === "NewImport") {
|
||||
return;
|
||||
}
|
||||
case ModuleSpecifierComparison.Equal:
|
||||
// the current one is safe. But it is still possible that the new one is worse
|
||||
// than another existing one. For example, you may have new imports from "./foo/bar"
|
||||
// and "bar", when the new one is "bar/bar2" and the current one is "./foo/bar". The new
|
||||
// one and the current one are not comparable (one relative path and one absolute path),
|
||||
// but the new one is worse than the other one, so should not add to the list.
|
||||
updatedNewImports.push(existingAction);
|
||||
break;
|
||||
case ModuleSpecifierComparison.Worse:
|
||||
// the existing one is worse, remove from the list.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// if we reach here, it means the new one is better or equal to all of the existing ones.
|
||||
updatedNewImports.push(newAction);
|
||||
this.symbolIdToActionMap[symbolId] = updatedNewImports;
|
||||
}
|
||||
|
||||
addActions(symbolId: number, newActions: ImportCodeAction[]) {
|
||||
for (const newAction of newActions) {
|
||||
this.addAction(symbolId, newAction);
|
||||
}
|
||||
}
|
||||
|
||||
getAllActions() {
|
||||
let result: ImportCodeAction[] = [];
|
||||
for (const symbolId in this.symbolIdToActionMap) {
|
||||
result = concatenate(result, this.symbolIdToActionMap[symbolId]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private compareModuleSpecifiers(moduleSpecifier1: string, moduleSpecifier2: string): ModuleSpecifierComparison {
|
||||
if (moduleSpecifier1 === moduleSpecifier2) {
|
||||
return ModuleSpecifierComparison.Equal;
|
||||
}
|
||||
|
||||
// if moduleSpecifier1 (ms1) is a substring of ms2, then it is better
|
||||
if (moduleSpecifier2.indexOf(moduleSpecifier1) === 0) {
|
||||
return ModuleSpecifierComparison.Better;
|
||||
}
|
||||
|
||||
if (moduleSpecifier1.indexOf(moduleSpecifier2) === 0) {
|
||||
return ModuleSpecifierComparison.Worse;
|
||||
}
|
||||
|
||||
// if both are relative paths, and ms1 has fewer levels, then it is better
|
||||
if (isExternalModuleNameRelative(moduleSpecifier1) && isExternalModuleNameRelative(moduleSpecifier2)) {
|
||||
const regex = new RegExp(directorySeparator, "g");
|
||||
const moduleSpecifier1LevelCount = (moduleSpecifier1.match(regex) || []).length;
|
||||
const moduleSpecifier2LevelCount = (moduleSpecifier2.match(regex) || []).length;
|
||||
|
||||
return moduleSpecifier1LevelCount < moduleSpecifier2LevelCount
|
||||
? ModuleSpecifierComparison.Better
|
||||
: moduleSpecifier1LevelCount === moduleSpecifier2LevelCount
|
||||
? ModuleSpecifierComparison.Equal
|
||||
: ModuleSpecifierComparison.Worse;
|
||||
}
|
||||
|
||||
// the equal cases include when the two specifiers are not comparable.
|
||||
return ModuleSpecifierComparison.Equal;
|
||||
}
|
||||
}
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.Cannot_find_name_0.code],
|
||||
getCodeActions: (context: CodeFixContext) => {
|
||||
const sourceFile = context.sourceFile;
|
||||
const checker = context.program.getTypeChecker();
|
||||
const allSourceFiles = context.program.getSourceFiles();
|
||||
const useCaseSensitiveFileNames = context.host.useCaseSensitiveFileNames ? context.host.useCaseSensitiveFileNames() : false;
|
||||
|
||||
const token = getTokenAtPosition(sourceFile, context.span.start);
|
||||
const name = token.getText();
|
||||
const symbolIdActionMap = new ImportCodeActionMap();
|
||||
|
||||
// this is a module id -> module import declaration map
|
||||
const cachedImportDeclarations = createMap<(ImportDeclaration | ImportEqualsDeclaration)[]>();
|
||||
let cachedNewImportInsertPosition: number;
|
||||
|
||||
const allPotentialModules = checker.getAmbientModules();
|
||||
for (const otherSourceFile of allSourceFiles) {
|
||||
if (otherSourceFile !== sourceFile && isExternalOrCommonJsModule(otherSourceFile)) {
|
||||
allPotentialModules.push(otherSourceFile.symbol);
|
||||
}
|
||||
}
|
||||
|
||||
const currentTokenMeaning = getMeaningFromLocation(token);
|
||||
for (const moduleSymbol of allPotentialModules) {
|
||||
context.cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
// check the default export
|
||||
const defaultExport = checker.tryGetMemberInModuleExports("default", moduleSymbol);
|
||||
if (defaultExport) {
|
||||
const localSymbol = getLocalSymbolForExportDefault(defaultExport);
|
||||
if (localSymbol && localSymbol.name === name && checkSymbolHasMeaning(localSymbol, currentTokenMeaning)) {
|
||||
// check if this symbol is already used
|
||||
const symbolId = getUniqueSymbolId(localSymbol);
|
||||
symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, /*isDefaultExport*/ true));
|
||||
}
|
||||
}
|
||||
|
||||
// check exports with the same name
|
||||
const exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExports(name, moduleSymbol);
|
||||
if (exportSymbolWithIdenticalName && checkSymbolHasMeaning(exportSymbolWithIdenticalName, currentTokenMeaning)) {
|
||||
const symbolId = getUniqueSymbolId(exportSymbolWithIdenticalName);
|
||||
symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol));
|
||||
}
|
||||
}
|
||||
|
||||
return symbolIdActionMap.getAllActions();
|
||||
|
||||
function getImportDeclarations(moduleSymbol: Symbol) {
|
||||
const moduleSymbolId = getUniqueSymbolId(moduleSymbol);
|
||||
|
||||
if (cachedImportDeclarations[moduleSymbolId]) {
|
||||
return cachedImportDeclarations[moduleSymbolId];
|
||||
}
|
||||
|
||||
const existingDeclarations: (ImportDeclaration | ImportEqualsDeclaration)[] = [];
|
||||
for (const importModuleSpecifier of sourceFile.imports) {
|
||||
const importSymbol = checker.getSymbolAtLocation(importModuleSpecifier);
|
||||
if (importSymbol === moduleSymbol) {
|
||||
existingDeclarations.push(getImportDeclaration(importModuleSpecifier));
|
||||
}
|
||||
}
|
||||
cachedImportDeclarations[moduleSymbolId] = existingDeclarations;
|
||||
return existingDeclarations;
|
||||
|
||||
function getImportDeclaration(moduleSpecifier: LiteralExpression) {
|
||||
let node: Node = moduleSpecifier;
|
||||
while (node) {
|
||||
if (node.kind === SyntaxKind.ImportDeclaration) {
|
||||
return <ImportDeclaration>node;
|
||||
}
|
||||
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||
return <ImportEqualsDeclaration>node;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function getUniqueSymbolId(symbol: Symbol) {
|
||||
if (symbol.flags & SymbolFlags.Alias) {
|
||||
return getSymbolId(checker.getAliasedSymbol(symbol));
|
||||
}
|
||||
return getSymbolId(symbol);
|
||||
}
|
||||
|
||||
function checkSymbolHasMeaning(symbol: Symbol, meaning: SemanticMeaning) {
|
||||
const declarations = symbol.getDeclarations();
|
||||
return declarations ? some(symbol.declarations, decl => !!(getMeaningFromDeclaration(decl) & meaning)) : false;
|
||||
}
|
||||
|
||||
function getCodeActionForImport(moduleSymbol: Symbol, isDefault?: boolean): ImportCodeAction[] {
|
||||
const existingDeclarations = getImportDeclarations(moduleSymbol);
|
||||
if (existingDeclarations.length > 0) {
|
||||
// With an existing import statement, there are more than one actions the user can do.
|
||||
return getCodeActionsForExistingImport(existingDeclarations);
|
||||
}
|
||||
else {
|
||||
return [getCodeActionForNewImport()];
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getCodeActionsForExistingImport(declarations: (ImportDeclaration | ImportEqualsDeclaration)[]): ImportCodeAction[] {
|
||||
const actions: ImportCodeAction[] = [];
|
||||
|
||||
// It is possible that multiple import statements with the same specifier exist in the file.
|
||||
// e.g.
|
||||
//
|
||||
// import * as ns from "foo";
|
||||
// import { member1, member2 } from "foo";
|
||||
//
|
||||
// member3/**/ <-- cusor here
|
||||
//
|
||||
// in this case we should provie 2 actions:
|
||||
// 1. change "member3" to "ns.member3"
|
||||
// 2. add "member3" to the second import statement's import list
|
||||
// and it is up to the user to decide which one fits best.
|
||||
let namespaceImportDeclaration: ImportDeclaration | ImportEqualsDeclaration;
|
||||
let namedImportDeclaration: ImportDeclaration;
|
||||
let existingModuleSpecifier: string;
|
||||
for (const declaration of declarations) {
|
||||
if (declaration.kind === SyntaxKind.ImportDeclaration) {
|
||||
const namedBindings = declaration.importClause && declaration.importClause.namedBindings;
|
||||
if (namedBindings && namedBindings.kind === SyntaxKind.NamespaceImport) {
|
||||
// case:
|
||||
// import * as ns from "foo"
|
||||
namespaceImportDeclaration = declaration;
|
||||
}
|
||||
else {
|
||||
// cases:
|
||||
// import default from "foo"
|
||||
// import { bar } from "foo" or combination with the first one
|
||||
// import "foo"
|
||||
namedImportDeclaration = declaration;
|
||||
}
|
||||
existingModuleSpecifier = declaration.moduleSpecifier.getText();
|
||||
}
|
||||
else {
|
||||
// case:
|
||||
// import foo = require("foo")
|
||||
namespaceImportDeclaration = declaration;
|
||||
existingModuleSpecifier = getModuleSpecifierFromImportEqualsDeclaration(declaration);
|
||||
}
|
||||
}
|
||||
|
||||
if (namespaceImportDeclaration) {
|
||||
actions.push(getCodeActionForNamespaceImport(namespaceImportDeclaration));
|
||||
}
|
||||
|
||||
if (namedImportDeclaration && namedImportDeclaration.importClause &&
|
||||
(namedImportDeclaration.importClause.name || namedImportDeclaration.importClause.namedBindings)) {
|
||||
/**
|
||||
* If the existing import declaration already has a named import list, just
|
||||
* insert the identifier into that list.
|
||||
*/
|
||||
const textChange = getTextChangeForImportClause(namedImportDeclaration.importClause);
|
||||
const moduleSpecifierWithoutQuotes = stripQuotes(namedImportDeclaration.moduleSpecifier.getText());
|
||||
actions.push(createCodeAction(
|
||||
Diagnostics.Add_0_to_existing_import_declaration_from_1,
|
||||
[name, moduleSpecifierWithoutQuotes],
|
||||
textChange.newText,
|
||||
textChange.span,
|
||||
sourceFile.fileName,
|
||||
"InsertingIntoExistingImport",
|
||||
moduleSpecifierWithoutQuotes
|
||||
));
|
||||
}
|
||||
else {
|
||||
// we need to create a new import statement, but the existing module specifier can be reused.
|
||||
actions.push(getCodeActionForNewImport(existingModuleSpecifier));
|
||||
}
|
||||
return actions;
|
||||
|
||||
function getModuleSpecifierFromImportEqualsDeclaration(declaration: ImportEqualsDeclaration) {
|
||||
if (declaration.moduleReference && declaration.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
|
||||
return declaration.moduleReference.expression.getText();
|
||||
}
|
||||
return declaration.moduleReference.getText();
|
||||
}
|
||||
|
||||
function getTextChangeForImportClause(importClause: ImportClause): TextChange {
|
||||
const newImportText = isDefault ? `default as ${name}` : name;
|
||||
const importList = <NamedImports>importClause.namedBindings;
|
||||
// case 1:
|
||||
// original text: import default from "module"
|
||||
// change to: import default, { name } from "module"
|
||||
if (!importList && importClause.name) {
|
||||
const start = importClause.name.getEnd();
|
||||
return {
|
||||
newText: `, { ${newImportText} }`,
|
||||
span: { start, length: 0 }
|
||||
};
|
||||
}
|
||||
|
||||
// case 2:
|
||||
// original text: import {} from "module"
|
||||
// change to: import { name } from "module"
|
||||
if (importList.elements.length === 0) {
|
||||
const start = importList.getStart();
|
||||
return {
|
||||
newText: `{ ${newImportText} }`,
|
||||
span: { start, length: importList.getEnd() - start }
|
||||
};
|
||||
}
|
||||
|
||||
// case 3:
|
||||
// original text: import { foo, bar } from "module"
|
||||
// change to: import { foo, bar, name } from "module"
|
||||
const insertPoint = importList.elements[importList.elements.length - 1].getEnd();
|
||||
/**
|
||||
* If the import list has one import per line, preserve that. Otherwise, insert on same line as last element
|
||||
* import {
|
||||
* foo
|
||||
* } from "./module";
|
||||
*/
|
||||
const startLine = getLineOfLocalPosition(sourceFile, importList.getStart());
|
||||
const endLine = getLineOfLocalPosition(sourceFile, importList.getEnd());
|
||||
const oneImportPerLine = endLine - startLine > importList.elements.length;
|
||||
|
||||
return {
|
||||
newText: `,${oneImportPerLine ? context.newLineCharacter : " "}${newImportText}`,
|
||||
span: { start: insertPoint, length: 0 }
|
||||
};
|
||||
}
|
||||
|
||||
function getCodeActionForNamespaceImport(declaration: ImportDeclaration | ImportEqualsDeclaration): ImportCodeAction {
|
||||
let namespacePrefix: string;
|
||||
if (declaration.kind === SyntaxKind.ImportDeclaration) {
|
||||
namespacePrefix = (<NamespaceImport>declaration.importClause.namedBindings).name.getText();
|
||||
}
|
||||
else {
|
||||
namespacePrefix = declaration.name.getText();
|
||||
}
|
||||
namespacePrefix = stripQuotes(namespacePrefix);
|
||||
|
||||
/**
|
||||
* Cases:
|
||||
* import * as ns from "mod"
|
||||
* import default, * as ns from "mod"
|
||||
* import ns = require("mod")
|
||||
*
|
||||
* Because there is no import list, we alter the reference to include the
|
||||
* namespace instead of altering the import declaration. For example, "foo" would
|
||||
* become "ns.foo"
|
||||
*/
|
||||
return createCodeAction(
|
||||
Diagnostics.Change_0_to_1,
|
||||
[name, `${namespacePrefix}.${name}`],
|
||||
`${namespacePrefix}.`,
|
||||
{ start: token.getStart(), length: 0 },
|
||||
sourceFile.fileName,
|
||||
"CodeChange"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getCodeActionForNewImport(moduleSpecifier?: string): ImportCodeAction {
|
||||
if (!cachedNewImportInsertPosition) {
|
||||
// insert after any existing imports
|
||||
let lastModuleSpecifierEnd = -1;
|
||||
for (const moduleSpecifier of sourceFile.imports) {
|
||||
const end = moduleSpecifier.getEnd();
|
||||
if (!lastModuleSpecifierEnd || end > lastModuleSpecifierEnd) {
|
||||
lastModuleSpecifierEnd = end;
|
||||
}
|
||||
}
|
||||
cachedNewImportInsertPosition = lastModuleSpecifierEnd > 0 ? sourceFile.getLineEndOfPosition(lastModuleSpecifierEnd) : sourceFile.getStart();
|
||||
}
|
||||
|
||||
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier || getModuleSpecifierForNewImport());
|
||||
const importStatementText = isDefault
|
||||
? `import ${name} from "${moduleSpecifierWithoutQuotes}"`
|
||||
: `import { ${name} } from "${moduleSpecifierWithoutQuotes}"`;
|
||||
|
||||
// if this file doesn't have any import statements, insert an import statement and then insert a new line
|
||||
// between the only import statement and user code. Otherwise just insert the statement because chances
|
||||
// are there are already a new line seperating code and import statements.
|
||||
const newText = cachedNewImportInsertPosition === sourceFile.getStart()
|
||||
? `${importStatementText};${context.newLineCharacter}${context.newLineCharacter}`
|
||||
: `${context.newLineCharacter}${importStatementText};`;
|
||||
|
||||
return createCodeAction(
|
||||
Diagnostics.Import_0_from_1,
|
||||
[name, `"${moduleSpecifierWithoutQuotes}"`],
|
||||
newText,
|
||||
{ start: cachedNewImportInsertPosition, length: 0 },
|
||||
sourceFile.fileName,
|
||||
"NewImport",
|
||||
moduleSpecifierWithoutQuotes
|
||||
);
|
||||
|
||||
function getModuleSpecifierForNewImport() {
|
||||
const fileName = sourceFile.path;
|
||||
const moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().path;
|
||||
const sourceDirectory = getDirectoryPath(fileName);
|
||||
const options = context.program.getCompilerOptions();
|
||||
|
||||
return tryGetModuleNameFromAmbientModule() ||
|
||||
tryGetModuleNameFromBaseUrl() ||
|
||||
tryGetModuleNameFromRootDirs() ||
|
||||
tryGetModuleNameFromTypeRoots() ||
|
||||
tryGetModuleNameAsNodeModule() ||
|
||||
removeFileExtension(getRelativePath(moduleFileName, sourceDirectory));
|
||||
|
||||
function tryGetModuleNameFromAmbientModule(): string {
|
||||
if (moduleSymbol.valueDeclaration.kind !== SyntaxKind.SourceFile) {
|
||||
return moduleSymbol.name;
|
||||
}
|
||||
}
|
||||
|
||||
function tryGetModuleNameFromBaseUrl() {
|
||||
if (!options.baseUrl) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const normalizedBaseUrl = toPath(options.baseUrl, getDirectoryPath(options.baseUrl), getCanonicalFileName);
|
||||
let relativeName = tryRemoveParentDirectoryName(moduleFileName, normalizedBaseUrl);
|
||||
if (!relativeName) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
relativeName = removeExtensionAndIndexPostFix(relativeName);
|
||||
|
||||
if (options.paths) {
|
||||
for (const key in options.paths) {
|
||||
for (const pattern of options.paths[key]) {
|
||||
const indexOfStar = pattern.indexOf("*");
|
||||
if (indexOfStar === 0 && pattern.length === 1) {
|
||||
continue;
|
||||
}
|
||||
else if (indexOfStar !== -1) {
|
||||
const prefix = pattern.substr(0, indexOfStar);
|
||||
const suffix = pattern.substr(indexOfStar + 1);
|
||||
if (relativeName.length >= prefix.length + suffix.length &&
|
||||
startsWith(relativeName, prefix) &&
|
||||
endsWith(relativeName, suffix)) {
|
||||
const matchedStar = relativeName.substr(prefix.length, relativeName.length - suffix.length);
|
||||
return key.replace("\*", matchedStar);
|
||||
}
|
||||
}
|
||||
else if (pattern === relativeName) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return relativeName;
|
||||
}
|
||||
|
||||
function tryGetModuleNameFromRootDirs() {
|
||||
if (options.rootDirs) {
|
||||
const normalizedRootDirs = map(options.rootDirs, rootDir => toPath(rootDir, /*basePath*/ undefined, getCanonicalFileName));
|
||||
const normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, normalizedRootDirs);
|
||||
const normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, normalizedRootDirs);
|
||||
if (normalizedTargetPath !== undefined) {
|
||||
const relativePath = normalizedSourcePath !== undefined ? getRelativePath(normalizedTargetPath, normalizedSourcePath) : normalizedTargetPath;
|
||||
return removeFileExtension(relativePath);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function tryGetModuleNameFromTypeRoots() {
|
||||
const typeRoots = getEffectiveTypeRoots(options, context.host);
|
||||
if (typeRoots) {
|
||||
const normalizedTypeRoots = map(typeRoots, typeRoot => toPath(typeRoot, /*basePath*/ undefined, getCanonicalFileName));
|
||||
for (const typeRoot of normalizedTypeRoots) {
|
||||
if (startsWith(moduleFileName, typeRoot)) {
|
||||
let relativeFileName = moduleFileName.substring(typeRoot.length + 1);
|
||||
return removeExtensionAndIndexPostFix(relativeFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function tryGetModuleNameAsNodeModule() {
|
||||
if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs) {
|
||||
// nothing to do here
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const indexOfNodeModules = moduleFileName.indexOf("node_modules");
|
||||
if (indexOfNodeModules < 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let relativeFileName: string;
|
||||
if (sourceDirectory.indexOf(moduleFileName.substring(0, indexOfNodeModules - 1)) === 0) {
|
||||
// if node_modules folder is in this folder or any of its parent folder, no need to keep it.
|
||||
relativeFileName = moduleFileName.substring(indexOfNodeModules + 13 /* "node_modules\".length */);
|
||||
}
|
||||
else {
|
||||
relativeFileName = getRelativePath(moduleFileName, sourceDirectory);
|
||||
}
|
||||
|
||||
relativeFileName = removeFileExtension(relativeFileName);
|
||||
if (endsWith(relativeFileName, "/index")) {
|
||||
relativeFileName = getDirectoryPath(relativeFileName);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
const moduleDirectory = getDirectoryPath(moduleFileName);
|
||||
const packageJsonContent = JSON.parse(context.host.readFile(combinePaths(moduleDirectory, "package.json")));
|
||||
if (packageJsonContent) {
|
||||
const mainFile = packageJsonContent.main || packageJsonContent.typings;
|
||||
if (mainFile) {
|
||||
const mainExportFile = toPath(mainFile, moduleDirectory, getCanonicalFileName);
|
||||
if (removeFileExtension(mainExportFile) === removeFileExtension(moduleFileName)) {
|
||||
relativeFileName = getDirectoryPath(relativeFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
|
||||
return relativeFileName;
|
||||
}
|
||||
}
|
||||
|
||||
function getPathRelativeToRootDirs(path: Path, rootDirs: Path[]) {
|
||||
for (const rootDir of rootDirs) {
|
||||
const relativeName = tryRemoveParentDirectoryName(path, rootDir);
|
||||
if (relativeName !== undefined) {
|
||||
return relativeName;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function removeExtensionAndIndexPostFix(fileName: string) {
|
||||
fileName = removeFileExtension(fileName);
|
||||
if (endsWith(fileName, "/index")) {
|
||||
fileName = fileName.substr(0, fileName.length - 6/* "/index".length */);
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
function getRelativePath(path: string, directoryPath: string) {
|
||||
const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, false);
|
||||
return moduleHasNonRelativeName(relativePath) ? "./" + relativePath : relativePath;
|
||||
}
|
||||
|
||||
function tryRemoveParentDirectoryName(path: Path, parentDirectory: Path) {
|
||||
const index = path.indexOf(parentDirectory);
|
||||
if (index === 0) {
|
||||
return endsWith(parentDirectory, directorySeparator)
|
||||
? path.substring(parentDirectory.length)
|
||||
: path.substring(parentDirectory.length + 1);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function createCodeAction(
|
||||
description: DiagnosticMessage,
|
||||
diagnosticArgs: string[],
|
||||
newText: string,
|
||||
span: TextSpan,
|
||||
fileName: string,
|
||||
kind: ImportCodeActionKind,
|
||||
moduleSpecifier?: string): ImportCodeAction {
|
||||
return {
|
||||
description: formatMessage.apply(undefined, [undefined, description].concat(<any[]>diagnosticArgs)),
|
||||
changes: [{ fileName, textChanges: [{ newText, span }] }],
|
||||
kind,
|
||||
moduleSpecifier
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1188,7 +1188,7 @@ namespace ts.FindAllReferences {
|
||||
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const nameExpression = (<ComputedPropertyName>node.name).expression;
|
||||
// treat computed property names where expression is string/numeric literal as just string/numeric literal
|
||||
if (isStringOrNumericLiteral(nameExpression.kind)) {
|
||||
if (isStringOrNumericLiteral(nameExpression)) {
|
||||
return (<LiteralExpression>nameExpression).text;
|
||||
}
|
||||
return undefined;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path="..\compiler\program.ts"/>
|
||||
/// <reference path="..\compiler\program.ts"/>
|
||||
/// <reference path="..\compiler\commandLineParser.ts"/>
|
||||
|
||||
/// <reference path='types.ts' />
|
||||
@ -492,6 +492,23 @@ namespace ts {
|
||||
return ts.getPositionOfLineAndCharacter(this, line, character);
|
||||
}
|
||||
|
||||
public getLineEndOfPosition(pos: number): number {
|
||||
const { line } = this.getLineAndCharacterOfPosition(pos);
|
||||
const lineStarts = this.getLineStarts();
|
||||
|
||||
let lastCharPos: number;
|
||||
if (line + 1 >= lineStarts.length) {
|
||||
lastCharPos = this.getEnd();
|
||||
}
|
||||
if (!lastCharPos) {
|
||||
lastCharPos = lineStarts[line + 1] - 1;
|
||||
}
|
||||
|
||||
const fullText = this.getFullText();
|
||||
// if the new line is "\r\n", we should return the last non-new-line-character position
|
||||
return fullText[lastCharPos] === "\n" && fullText[lastCharPos - 1] === "\r" ? lastCharPos - 1 : lastCharPos;
|
||||
}
|
||||
|
||||
public getNamedDeclarations(): Map<Declaration[]> {
|
||||
if (!this.namedDeclarations) {
|
||||
this.namedDeclarations = this.computeNamedDeclarations();
|
||||
@ -1676,7 +1693,9 @@ namespace ts {
|
||||
sourceFile: sourceFile,
|
||||
span: span,
|
||||
program: program,
|
||||
newLineCharacter: newLineChar
|
||||
newLineCharacter: newLineChar,
|
||||
host: host,
|
||||
cancellationToken: cancellationToken
|
||||
};
|
||||
|
||||
const fixes = codefix.getFixes(context);
|
||||
|
||||
@ -53,6 +53,7 @@ namespace ts {
|
||||
/* @internal */ getNamedDeclarations(): Map<Declaration[]>;
|
||||
|
||||
getLineAndCharacterOfPosition(pos: number): LineAndCharacter;
|
||||
getLineEndOfPosition(pos: number): number;
|
||||
getLineStarts(): number[];
|
||||
getPositionOfLineAndCharacter(line: number, character: number): number;
|
||||
update(newText: string, textChangeRange: TextChangeRange): SourceFile;
|
||||
|
||||
@ -1282,7 +1282,7 @@ namespace ts {
|
||||
if (isImportOrExportSpecifierName(location)) {
|
||||
return location.getText();
|
||||
}
|
||||
else if (isStringOrNumericLiteral(location.kind) &&
|
||||
else if (isStringOrNumericLiteral(location) &&
|
||||
location.parent.kind === SyntaxKind.ComputedPropertyName) {
|
||||
return (<LiteralExpression>location).text;
|
||||
}
|
||||
|
||||
@ -37,17 +37,17 @@ x = [true][0];
|
||||
x; // boolean
|
||||
_a = [1][0], x = _a === void 0 ? "" : _a;
|
||||
x; // string | number
|
||||
(_b = { x: true }, x = _b.x, _b);
|
||||
(x = { x: true }.x);
|
||||
x; // boolean
|
||||
(_c = { y: 1 }, x = _c.y, _c);
|
||||
(x = { y: 1 }.y);
|
||||
x; // number
|
||||
(_d = { x: true }, _e = _d.x, x = _e === void 0 ? "" : _e, _d);
|
||||
(_b = { x: true }.x, x = _b === void 0 ? "" : _b);
|
||||
x; // string | boolean
|
||||
(_f = { y: 1 }, _g = _f.y, x = _g === void 0 ? /a/ : _g, _f);
|
||||
(_c = { y: 1 }.y, x = _c === void 0 ? /a/ : _c);
|
||||
x; // number | RegExp
|
||||
var a;
|
||||
for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
|
||||
x = a_1[_i];
|
||||
x; // string
|
||||
}
|
||||
var _a, _b, _c, _d, _e, _f, _g;
|
||||
var _a, _b, _c;
|
||||
|
||||
@ -81,8 +81,8 @@ var B = (function (_super) {
|
||||
// async method with assignment/destructuring on 'super' requires a binding
|
||||
B.prototype.advanced = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var f, a, b, _a, _b;
|
||||
return __generator(this, function (_c) {
|
||||
var f, a, b;
|
||||
return __generator(this, function (_a) {
|
||||
f = function () { };
|
||||
// call with property access
|
||||
_super.prototype.x.call(this);
|
||||
@ -95,9 +95,9 @@ var B = (function (_super) {
|
||||
// element access (assign)
|
||||
_super.prototype["x"] = f;
|
||||
// destructuring assign with property access
|
||||
(_a = { f: f }, super.x = _a.f, _a);
|
||||
(_super.prototype.x = { f: f }.f);
|
||||
// destructuring assign with element access
|
||||
(_b = { f: f }, super["x"] = _b.f, _b);
|
||||
(_super.prototype["x"] = { f: f }.f);
|
||||
return [2 /*return*/];
|
||||
});
|
||||
});
|
||||
|
||||
@ -41,13 +41,13 @@ let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}];
|
||||
// destructuring in variable declarations
|
||||
var foo = "bar";
|
||||
var _a = foo, bar = { bar: "bar" }[_a];
|
||||
var _b = "bar", bar2 = { bar: "bar" }[_b];
|
||||
var bar2 = { bar: "bar" }["bar"];
|
||||
var foo2 = function () { return "bar"; };
|
||||
var _c = foo2(), bar3 = { bar: "bar" }[_c];
|
||||
var _d = foo, bar4 = [{ bar: "bar" }][0][_d];
|
||||
var _e = foo2(), bar5 = [{ bar: "bar" }][0][_e];
|
||||
var _b = foo2(), bar3 = { bar: "bar" }[_b];
|
||||
var _c = foo, bar4 = [{ bar: "bar" }][0][_c];
|
||||
var _d = foo2(), bar5 = [{ bar: "bar" }][0][_d];
|
||||
function f1(_a) {
|
||||
var _b = "bar", x = _a[_b];
|
||||
var x = _a["bar"];
|
||||
}
|
||||
function f2(_a) {
|
||||
var _b = foo, x = _a[_b];
|
||||
@ -62,14 +62,14 @@ function f5(_a) {
|
||||
var _b = foo2(), x = _a[0][_b];
|
||||
}
|
||||
// report errors on type errors in computed properties used in destructuring
|
||||
var _f = foo(), bar6 = [{ bar: "bar" }][0][_f];
|
||||
var _g = foo.toExponential(), bar7 = [{ bar: "bar" }][0][_g];
|
||||
var _e = foo(), bar6 = [{ bar: "bar" }][0][_e];
|
||||
var _f = foo.toExponential(), bar7 = [{ bar: "bar" }][0][_f];
|
||||
// destructuring assignment
|
||||
(_h = { bar: "bar" }, _j = foo, bar = _h[_j], _h);
|
||||
(_k = { bar: "bar" }, _l = "bar", bar2 = _k[_l], _k);
|
||||
(_m = { bar: "bar" }, _o = foo2(), bar3 = _m[_o], _m);
|
||||
_p = foo, bar4 = [{ bar: "bar" }][0][_p];
|
||||
_q = foo2(), bar5 = [{ bar: "bar" }][0][_q];
|
||||
_r = foo(), bar4 = [{ bar: "bar" }][0][_r];
|
||||
_s = (1 + {}), bar4 = [{ bar: "bar" }][0][_s];
|
||||
var _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
||||
(_g = foo, bar = { bar: "bar" }[_g]);
|
||||
(bar2 = { bar: "bar" }["bar"]);
|
||||
(_h = foo2(), bar3 = { bar: "bar" }[_h]);
|
||||
_j = foo, bar4 = [{ bar: "bar" }][0][_j];
|
||||
_k = foo2(), bar5 = [{ bar: "bar" }][0][_k];
|
||||
_l = foo(), bar4 = [{ bar: "bar" }][0][_l];
|
||||
_m = (1 + {}), bar4 = [{ bar: "bar" }][0][_m];
|
||||
var _g, _h, _j, _k, _l, _m;
|
||||
|
||||
@ -37,7 +37,7 @@ function f2(_a) {
|
||||
var _b = _a["show"], showRename = _b === void 0 ? function (v) { return v.toString(); } : _b;
|
||||
}
|
||||
function f3(_a) {
|
||||
var _b = "show", _c = _a[_b], showRename = _c === void 0 ? function (v) { return v.toString(); } : _c;
|
||||
var _b = _a["show"], showRename = _b === void 0 ? function (v) { return v.toString(); } : _b;
|
||||
}
|
||||
function ff(_a) {
|
||||
var _b = _a.nested, nested = _b === void 0 ? { show: function (v) { return v.toString(); } } : _b;
|
||||
|
||||
@ -35,7 +35,7 @@ function f2(_a) {
|
||||
var _b = _a["show"], showRename = _b === void 0 ? function (v) { return v; } : _b;
|
||||
}
|
||||
function f3(_a) {
|
||||
var _b = "show", _c = _a[_b], showRename = _c === void 0 ? function (v) { return v; } : _c;
|
||||
var _b = _a["show"], showRename = _b === void 0 ? function (v) { return v; } : _b;
|
||||
}
|
||||
function ff(_a) {
|
||||
var _b = _a.nested, nestedRename = _b === void 0 ? { show: function (v) { return v; } } : _b;
|
||||
|
||||
@ -300,8 +300,8 @@ function f18() {
|
||||
var a;
|
||||
var b;
|
||||
var aa;
|
||||
(_a = { a: a, b: b }, a = _a.a, b = _a.b, _a);
|
||||
(_b = { b: b, a: a }, a = _b.a, b = _b.b, _b);
|
||||
(_a = { a: a, b: b }, a = _a.a, b = _a.b);
|
||||
(_b = { b: b, a: a }, a = _b.a, b = _b.b);
|
||||
_c = [a, b], aa[0] = _c[0], b = _c[1];
|
||||
_d = [b, a], a = _d[0], b = _d[1]; // Error
|
||||
_e = [2, "def"], _f = _e[0], a = _f === void 0 ? 1 : _f, _g = _e[1], b = _g === void 0 ? "abc" : _g;
|
||||
@ -311,7 +311,7 @@ function f19() {
|
||||
var a, b;
|
||||
_a = [1, 2], a = _a[0], b = _a[1];
|
||||
_b = [b, a], a = _b[0], b = _b[1];
|
||||
(_c = { b: b, a: a }, a = _c.a, b = _c.b, _c);
|
||||
(_c = { b: b, a: a }, a = _c.a, b = _c.b);
|
||||
_d = [[2, 3]][0], _e = _d === void 0 ? [1, 2] : _d, a = _e[0], b = _e[1];
|
||||
var x = (_f = [1, 2], a = _f[0], b = _f[1], _f);
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
|
||||
@ -7,5 +7,5 @@ let x = 0;
|
||||
//// [destructuringAssignmentWithDefault.js]
|
||||
var a = {};
|
||||
var x = 0;
|
||||
(_a = a.x, x = _a === void 0 ? 1 : _a, a);
|
||||
(_a = a.x, x = _a === void 0 ? 1 : _a);
|
||||
var _a;
|
||||
|
||||
@ -9,8 +9,8 @@ let x, y, z, a1, a2, a3;
|
||||
//// [emptyAssignmentPatterns02_ES5.js]
|
||||
var a;
|
||||
var x, y, z, a1, a2, a3;
|
||||
(x = a.x, y = a.y, z = a.z, a);
|
||||
(a1 = a[0], a2 = a[1], a3 = a[2], a);
|
||||
(x = a.x, y = a.y, z = a.z);
|
||||
(a1 = a[0], a2 = a[1], a3 = a[2]);
|
||||
|
||||
|
||||
//// [emptyAssignmentPatterns02_ES5.d.ts]
|
||||
|
||||
@ -9,9 +9,8 @@ let x, y, z, a1, a2, a3;
|
||||
//// [emptyAssignmentPatterns04_ES5.js]
|
||||
var a;
|
||||
var x, y, z, a1, a2, a3;
|
||||
(_a = a, x = _a.x, y = _a.y, z = _a.z, _a);
|
||||
(_b = a, a1 = _b[0], a2 = _b[1], a3 = _b[2], _b);
|
||||
var _a, _b;
|
||||
(x = a.x, y = a.y, z = a.z);
|
||||
(a1 = a[0], a2 = a[1], a3 = a[2]);
|
||||
|
||||
|
||||
//// [emptyAssignmentPatterns04_ES5.d.ts]
|
||||
|
||||
@ -119,7 +119,7 @@ function newExpression2() {
|
||||
_a = x.bind;
|
||||
return [4 /*yield*/, y];
|
||||
case 1:
|
||||
new (_a.apply(x, [_c.sent(), z]))();
|
||||
new (_a.apply(x, [void 0, _c.sent(), z]))();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
@ -132,7 +132,7 @@ function newExpression3() {
|
||||
switch (_c.label) {
|
||||
case 0:
|
||||
_a = x.bind;
|
||||
_b = [y];
|
||||
_b = [void 0, y];
|
||||
return [4 /*yield*/, z];
|
||||
case 1:
|
||||
new (_a.apply(x, _b.concat([_c.sent()])))();
|
||||
@ -280,7 +280,7 @@ function newExpression13() {
|
||||
_b = (_a = x.a).bind;
|
||||
return [4 /*yield*/, y];
|
||||
case 1:
|
||||
new (_b.apply(_a, [_d.sent(), z]))();
|
||||
new (_b.apply(_a, [void 0, _d.sent(), z]))();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
@ -293,7 +293,7 @@ function newExpression14() {
|
||||
switch (_d.label) {
|
||||
case 0:
|
||||
_b = (_a = x.a).bind;
|
||||
_c = [y];
|
||||
_c = [void 0, y];
|
||||
return [4 /*yield*/, z];
|
||||
case 1:
|
||||
new (_b.apply(_a, _c.concat([_d.sent()])))();
|
||||
@ -362,7 +362,7 @@ function newExpression19() {
|
||||
_b = (_a = x[a]).bind;
|
||||
return [4 /*yield*/, y];
|
||||
case 1:
|
||||
new (_b.apply(_a, [_d.sent(), z]))();
|
||||
new (_b.apply(_a, [void 0, _d.sent(), z]))();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
@ -375,7 +375,7 @@ function newExpression20() {
|
||||
switch (_d.label) {
|
||||
case 0:
|
||||
_b = (_a = x[a]).bind;
|
||||
_c = [y];
|
||||
_c = [void 0, y];
|
||||
return [4 /*yield*/, z];
|
||||
case 1:
|
||||
new (_b.apply(_a, _c.concat([_d.sent()])))();
|
||||
|
||||
@ -29,9 +29,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
@ -67,8 +67,8 @@ C = tslib_1.__decorate([
|
||||
tslib_1.__metadata("design:paramtypes", [])
|
||||
], C);
|
||||
var o = { a: 1 };
|
||||
var y = __assign({}, o);
|
||||
var x = __rest(y, []);
|
||||
var y = tslib_1.__assign({}, o);
|
||||
var x = tslib_1.__rest(y, []);
|
||||
//// [script.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
|
||||
@ -28,7 +28,6 @@ if (true) {
|
||||
var x_1 = { x: 0 }.x;
|
||||
var y_1 = { y: 0 }.y;
|
||||
var z_1;
|
||||
(_a = { z: 0 }, z_1 = _a.z, _a);
|
||||
(_b = { z: 0 }, z_1 = _b.z, _b);
|
||||
(z_1 = { z: 0 }.z);
|
||||
(z_1 = { z: 0 }.z);
|
||||
}
|
||||
var _a, _b;
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
tests/cases/conformance/types/literal/literalTypesWidenInParameterPosition.ts(4,9): error TS2322: Type '5' is not assignable to type '1'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/literal/literalTypesWidenInParameterPosition.ts (1 errors) ====
|
||||
class D {
|
||||
readonly noWiden = 1
|
||||
constructor(readonly widen = 2) {
|
||||
this.noWiden = 5; // error
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '5' is not assignable to type '1'.
|
||||
this.widen = 6; // ok
|
||||
}
|
||||
}
|
||||
new D(7); // ok
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
//// [literalTypesWidenInParameterPosition.ts]
|
||||
class D {
|
||||
readonly noWiden = 1
|
||||
constructor(readonly widen = 2) {
|
||||
this.noWiden = 5; // error
|
||||
this.widen = 6; // ok
|
||||
}
|
||||
}
|
||||
new D(7); // ok
|
||||
|
||||
|
||||
//// [literalTypesWidenInParameterPosition.js]
|
||||
var D = (function () {
|
||||
function D(widen) {
|
||||
if (widen === void 0) { widen = 2; }
|
||||
this.widen = widen;
|
||||
this.noWiden = 1;
|
||||
this.noWiden = 5; // error
|
||||
this.widen = 6; // ok
|
||||
}
|
||||
return D;
|
||||
}());
|
||||
new D(7); // ok
|
||||
@ -45,10 +45,10 @@ function f1() {
|
||||
// Missing properties
|
||||
function f2() {
|
||||
var x, y;
|
||||
(_a = {}, x = _a.x, y = _a.y, _a);
|
||||
(_b = {}, _c = _b.x, x = _c === void 0 ? 1 : _c, y = _b.y, _b);
|
||||
(_d = {}, x = _d.x, _e = _d.y, y = _e === void 0 ? 1 : _e, _d);
|
||||
(_f = {}, _g = _f.x, x = _g === void 0 ? 1 : _g, _h = _f.y, y = _h === void 0 ? 1 : _h, _f);
|
||||
(_a = {}, x = _a.x, y = _a.y);
|
||||
(_b = {}, _c = _b.x, x = _c === void 0 ? 1 : _c, y = _b.y);
|
||||
(_d = {}, x = _d.x, _e = _d.y, y = _e === void 0 ? 1 : _e);
|
||||
(_f = {}, _g = _f.x, x = _g === void 0 ? 1 : _g, _h = _f.y, y = _h === void 0 ? 1 : _h);
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h;
|
||||
}
|
||||
// Excess properties
|
||||
@ -62,8 +62,8 @@ function f3() {
|
||||
function f4() {
|
||||
var x, y;
|
||||
({ x: 0, y: 0 });
|
||||
(_a = { x: 0, y: 0 }, x = _a.x, _a);
|
||||
(_b = { x: 0, y: 0 }, y = _b.y, _b);
|
||||
(_c = { x: 0, y: 0 }, x = _c.x, y = _c.y, _c);
|
||||
var _a, _b, _c;
|
||||
(x = { x: 0, y: 0 }.x);
|
||||
(y = { x: 0, y: 0 }.y);
|
||||
(_a = { x: 0, y: 0 }, x = _a.x, y = _a.y);
|
||||
var _a;
|
||||
}
|
||||
|
||||
@ -52,18 +52,18 @@ var o = { a: 1, b: 'no' };
|
||||
var clone = __rest(o, []);
|
||||
var { a } = o, justB = __rest(o, ["a"]);
|
||||
var { a, b: renamed } = o, empty = __rest(o, ["a", "b"]);
|
||||
var _a = 'b', renamed = o[_a], justA = __rest(o, [typeof _a === "symbol" ? _a : _a + ""]);
|
||||
var { 'b': renamed } = o, justA = __rest(o, ["b"]);
|
||||
var { ['b']: renamed } = o, justA = __rest(o, ['b']);
|
||||
var { 'b': renamed } = o, justA = __rest(o, ['b']);
|
||||
var { b: { '0': n, '1': oooo } } = o, justA = __rest(o, ["b"]);
|
||||
let o2 = { c: 'terrible idea?', d: 'yes' };
|
||||
var { d: renamed } = o2, d = __rest(o2, ["d"]);
|
||||
let nestedrest;
|
||||
var { x } = nestedrest, _b = nestedrest.n1, { y } = _b, _c = _b.n2, { z } = _c, nr = __rest(_c.n3, []), restrest = __rest(nestedrest, ["x", "n1"]);
|
||||
var { x } = nestedrest, _a = nestedrest.n1, { y } = _a, _b = _a.n2, { z } = _b, nr = __rest(_b.n3, []), restrest = __rest(nestedrest, ["x", "n1"]);
|
||||
let complex;
|
||||
var _d = complex.x, { ka } = _d, nested = __rest(_d, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]);
|
||||
(_e = complex.x, { ka } = _e, nested = __rest(_e, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]), complex);
|
||||
var _f = { x: 1, y: 2 }, { x } = _f, fresh = __rest(_f, ["x"]);
|
||||
(_g = { x: 1, y: 2 }, { x } = _g, fresh = __rest(_g, ["x"]), _g);
|
||||
var _c = complex.x, { ka } = _c, nested = __rest(_c, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]);
|
||||
(_d = complex.x, { ka } = _d, nested = __rest(_d, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]));
|
||||
var _e = { x: 1, y: 2 }, { x } = _e, fresh = __rest(_e, ["x"]);
|
||||
(_f = { x: 1, y: 2 }, { x } = _f, fresh = __rest(_f, ["x"]));
|
||||
class Removable {
|
||||
set z(value) { }
|
||||
get both() { return 12; }
|
||||
@ -74,6 +74,6 @@ var removable = new Removable();
|
||||
var { removed } = removable, removableRest = __rest(removable, ["removed"]);
|
||||
let computed = 'b';
|
||||
let computed2 = 'a';
|
||||
var _h = computed, stillNotGreat = o[_h], _j = computed2, soSo = o[_j], o = __rest(o, [typeof _h === "symbol" ? _h : _h + "", typeof _j === "symbol" ? _j : _j + ""]);
|
||||
(_k = computed, stillNotGreat = o[_k], _l = computed2, soSo = o[_l], o = __rest(o, [typeof _k === "symbol" ? _k : _k + "", typeof _l === "symbol" ? _l : _l + ""]), o);
|
||||
var _e, _g, _k, _l;
|
||||
var _g = computed, stillNotGreat = o[_g], _h = computed2, soSo = o[_h], o = __rest(o, [typeof _g === "symbol" ? _g : _g + "", typeof _h === "symbol" ? _h : _h + ""]);
|
||||
(_j = computed, stillNotGreat = o[_j], _k = computed2, soSo = o[_k], o = __rest(o, [typeof _j === "symbol" ? _j : _j + "", typeof _k === "symbol" ? _k : _k + ""]));
|
||||
var _d, _f, _j, _k;
|
||||
|
||||
@ -20,9 +20,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
@ -29,10 +29,10 @@ let nested;
|
||||
let other;
|
||||
let rest;
|
||||
let complex;
|
||||
(_a = complex.x, { ka } = _a, nested = __rest(_a, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]), complex);
|
||||
(_a = complex.x, { ka } = _a, nested = __rest(_a, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]));
|
||||
// should be:
|
||||
let overEmit;
|
||||
// var _g = overEmit.a, [_h, ...y] = _g, nested2 = __rest(_h, []), _j = overEmit.b, { z } = _j, c = __rest(_j, ["z"]), rest2 = __rest(overEmit, ["a", "b"]);
|
||||
var _b = overEmit.a, [_c, ...y] = _b, nested2 = __rest(_c, []), _d = overEmit.b, { z } = _d, c = __rest(_d, ["z"]), rest2 = __rest(overEmit, ["a", "b"]);
|
||||
(_e = overEmit.a, [_f, ...y] = _e, nested2 = __rest(_f, []), _g = overEmit.b, { z } = _g, c = __rest(_g, ["z"]), rest2 = __rest(overEmit, ["a", "b"]), overEmit);
|
||||
var _a, _e, _f, _g;
|
||||
var [_b, ...y] = overEmit.a, nested2 = __rest(_b, []), _c = overEmit.b, { z } = _c, c = __rest(_c, ["z"]), rest2 = __rest(overEmit, ["a", "b"]);
|
||||
([_d, ...y] = overEmit.a, nested2 = __rest(_d, []), _e = overEmit.b, { z } = _e, c = __rest(_e, ["z"]), rest2 = __rest(overEmit, ["a", "b"]));
|
||||
var _a, _d, _e;
|
||||
|
||||
@ -20,9 +20,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
@ -36,14 +33,14 @@ var __rest = (this && this.__rest) || function (s, e) {
|
||||
return t;
|
||||
};
|
||||
let array;
|
||||
for (var array_1 of array) {
|
||||
var { x } = array_1, restOf = __rest(array_1, ["x"]);
|
||||
for (let _a of array) {
|
||||
let { x } = _a, restOf = __rest(_a, ["x"]);
|
||||
[x, restOf];
|
||||
}
|
||||
let xx;
|
||||
let rrestOff;
|
||||
for (var array_2 of array) {
|
||||
({ x: xx } = array_2, rrestOff = __rest(array_2, ["x"]));
|
||||
for (let _b of array) {
|
||||
({ x: xx } = _b, rrestOff = __rest(_b, ["x"]));
|
||||
[xx, rrestOff];
|
||||
}
|
||||
for (const norest of array.map(a => (__assign({}, a, { x: 'a string' })))) {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(2,10): error TS2462: A rest element must be last in a destructuring pattern
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(3,31): error TS2462: A rest element must be last in a destructuring pattern
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(6,17): error TS2700: Rest types may only be created from object types.
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(11,9): error TS2701: An object rest element must be an identifier.
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(11,9): error TS2701: The target of an object rest assignment must be a variable or a property access.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/rest/objectRestNegative.ts (4 errors) ====
|
||||
@ -23,5 +23,5 @@ tests/cases/conformance/types/rest/objectRestNegative.ts(11,9): error TS2701: An
|
||||
let rest: { b: string }
|
||||
({a, ...rest.b + rest.b} = o);
|
||||
~~~~~~~~~~~~~~~
|
||||
!!! error TS2701: An object rest element must be an identifier.
|
||||
!!! error TS2701: The target of an object rest assignment must be a variable or a property access.
|
||||
|
||||
@ -23,13 +23,13 @@ var __rest = (this && this.__rest) || function (s, e) {
|
||||
return t;
|
||||
};
|
||||
var o = { a: 1, b: 'no' };
|
||||
var mustBeLast = o.mustBeLast, a = o.a;
|
||||
var a = o.a;
|
||||
function stillMustBeLast(_a) {
|
||||
var mustBeLast = _a.mustBeLast, a = _a.a;
|
||||
var a = _a.a;
|
||||
}
|
||||
function generic(t) {
|
||||
var x = t.x, rest = __rest(t, ["x"]);
|
||||
return rest;
|
||||
}
|
||||
var rest;
|
||||
(a = o.a, o, o);
|
||||
(a = o.a, o, rest.b + rest.b = __rest(o, ["a"]));
|
||||
|
||||
@ -6,6 +6,15 @@ declare function suddenly(f: (a: { x: { z, ka }, y: string }) => void);
|
||||
suddenly(({ x: a, ...rest }) => rest.y);
|
||||
suddenly(({ x: { z = 12, ...nested }, ...rest } = { x: { z: 1, ka: 1 }, y: 'noo' }) => rest.y + nested.ka);
|
||||
|
||||
class C {
|
||||
m({ a, ...clone }: { a: number, b: string}): void {
|
||||
// actually, never mind, don't clone
|
||||
}
|
||||
set p({ a, ...clone }: { a: number, b: string}) {
|
||||
// actually, never mind, don't clone
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//// [objectRestParameter.js]
|
||||
@ -29,3 +38,13 @@ suddenly((_a = { x: { z: 1, ka: 1 }, y: 'noo' }) => {
|
||||
var _b = _a.x, { z = 12 } = _b, nested = __rest(_b, ["z"]), rest = __rest(_a, ["x"]);
|
||||
return rest.y + nested.ka;
|
||||
});
|
||||
class C {
|
||||
m(_a) {
|
||||
var { a } = _a, clone = __rest(_a, ["a"]);
|
||||
// actually, never mind, don't clone
|
||||
}
|
||||
set p(_a) {
|
||||
var { a } = _a, clone = __rest(_a, ["a"]);
|
||||
// actually, never mind, don't clone
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,4 +42,27 @@ suddenly(({ x: { z = 12, ...nested }, ...rest } = { x: { z: 1, ka: 1 }, y: 'noo'
|
||||
>nested : Symbol(nested, Decl(objectRestParameter.ts, 5, 24))
|
||||
>ka : Symbol(ka, Decl(objectRestParameter.ts, 3, 42))
|
||||
|
||||
class C {
|
||||
>C : Symbol(C, Decl(objectRestParameter.ts, 5, 107))
|
||||
|
||||
m({ a, ...clone }: { a: number, b: string}): void {
|
||||
>m : Symbol(C.m, Decl(objectRestParameter.ts, 7, 9))
|
||||
>a : Symbol(a, Decl(objectRestParameter.ts, 8, 7))
|
||||
>clone : Symbol(clone, Decl(objectRestParameter.ts, 8, 10))
|
||||
>a : Symbol(a, Decl(objectRestParameter.ts, 8, 24))
|
||||
>b : Symbol(b, Decl(objectRestParameter.ts, 8, 35))
|
||||
|
||||
// actually, never mind, don't clone
|
||||
}
|
||||
set p({ a, ...clone }: { a: number, b: string}) {
|
||||
>p : Symbol(C.p, Decl(objectRestParameter.ts, 10, 5))
|
||||
>a : Symbol(a, Decl(objectRestParameter.ts, 11, 11))
|
||||
>clone : Symbol(clone, Decl(objectRestParameter.ts, 11, 14))
|
||||
>a : Symbol(a, Decl(objectRestParameter.ts, 11, 28))
|
||||
>b : Symbol(b, Decl(objectRestParameter.ts, 11, 39))
|
||||
|
||||
// actually, never mind, don't clone
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -53,4 +53,27 @@ suddenly(({ x: { z = 12, ...nested }, ...rest } = { x: { z: 1, ka: 1 }, y: 'noo'
|
||||
>nested : { ka: any; }
|
||||
>ka : any
|
||||
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
m({ a, ...clone }: { a: number, b: string}): void {
|
||||
>m : ({a, ...clone}: { a: number; b: string; }) => void
|
||||
>a : number
|
||||
>clone : { b: string; }
|
||||
>a : number
|
||||
>b : string
|
||||
|
||||
// actually, never mind, don't clone
|
||||
}
|
||||
set p({ a, ...clone }: { a: number, b: string}) {
|
||||
>p : { a: number; b: string; }
|
||||
>a : number
|
||||
>clone : { b: string; }
|
||||
>a : number
|
||||
>b : string
|
||||
|
||||
// actually, never mind, don't clone
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -87,9 +87,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
@ -16,9 +16,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
@ -23,9 +23,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
@ -77,9 +77,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
@ -11,9 +11,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
@ -27,9 +27,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
@ -18,9 +18,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
30
tests/baselines/reference/recursiveMappedTypes.js
Normal file
30
tests/baselines/reference/recursiveMappedTypes.js
Normal file
@ -0,0 +1,30 @@
|
||||
//// [recursiveMappedTypes.ts]
|
||||
|
||||
// Recursive mapped types simply appear empty
|
||||
|
||||
type Recurse = {
|
||||
[K in keyof Recurse]: Recurse[K]
|
||||
}
|
||||
|
||||
type Recurse1 = {
|
||||
[K in keyof Recurse2]: Recurse2[K]
|
||||
}
|
||||
|
||||
type Recurse2 = {
|
||||
[K in keyof Recurse1]: Recurse1[K]
|
||||
}
|
||||
|
||||
//// [recursiveMappedTypes.js]
|
||||
// Recursive mapped types simply appear empty
|
||||
|
||||
|
||||
//// [recursiveMappedTypes.d.ts]
|
||||
declare type Recurse = {
|
||||
[K in keyof Recurse]: Recurse[K];
|
||||
};
|
||||
declare type Recurse1 = {
|
||||
[K in keyof Recurse2]: Recurse2[K];
|
||||
};
|
||||
declare type Recurse2 = {
|
||||
[K in keyof Recurse1]: Recurse1[K];
|
||||
};
|
||||
33
tests/baselines/reference/recursiveMappedTypes.symbols
Normal file
33
tests/baselines/reference/recursiveMappedTypes.symbols
Normal file
@ -0,0 +1,33 @@
|
||||
=== tests/cases/conformance/types/mapped/recursiveMappedTypes.ts ===
|
||||
|
||||
// Recursive mapped types simply appear empty
|
||||
|
||||
type Recurse = {
|
||||
>Recurse : Symbol(Recurse, Decl(recursiveMappedTypes.ts, 0, 0))
|
||||
|
||||
[K in keyof Recurse]: Recurse[K]
|
||||
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 4, 5))
|
||||
>Recurse : Symbol(Recurse, Decl(recursiveMappedTypes.ts, 0, 0))
|
||||
>Recurse : Symbol(Recurse, Decl(recursiveMappedTypes.ts, 0, 0))
|
||||
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 4, 5))
|
||||
}
|
||||
|
||||
type Recurse1 = {
|
||||
>Recurse1 : Symbol(Recurse1, Decl(recursiveMappedTypes.ts, 5, 1))
|
||||
|
||||
[K in keyof Recurse2]: Recurse2[K]
|
||||
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 8, 5))
|
||||
>Recurse2 : Symbol(Recurse2, Decl(recursiveMappedTypes.ts, 9, 1))
|
||||
>Recurse2 : Symbol(Recurse2, Decl(recursiveMappedTypes.ts, 9, 1))
|
||||
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 8, 5))
|
||||
}
|
||||
|
||||
type Recurse2 = {
|
||||
>Recurse2 : Symbol(Recurse2, Decl(recursiveMappedTypes.ts, 9, 1))
|
||||
|
||||
[K in keyof Recurse1]: Recurse1[K]
|
||||
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 12, 5))
|
||||
>Recurse1 : Symbol(Recurse1, Decl(recursiveMappedTypes.ts, 5, 1))
|
||||
>Recurse1 : Symbol(Recurse1, Decl(recursiveMappedTypes.ts, 5, 1))
|
||||
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 12, 5))
|
||||
}
|
||||
33
tests/baselines/reference/recursiveMappedTypes.types
Normal file
33
tests/baselines/reference/recursiveMappedTypes.types
Normal file
@ -0,0 +1,33 @@
|
||||
=== tests/cases/conformance/types/mapped/recursiveMappedTypes.ts ===
|
||||
|
||||
// Recursive mapped types simply appear empty
|
||||
|
||||
type Recurse = {
|
||||
>Recurse : Recurse
|
||||
|
||||
[K in keyof Recurse]: Recurse[K]
|
||||
>K : K
|
||||
>Recurse : Recurse
|
||||
>Recurse : Recurse
|
||||
>K : K
|
||||
}
|
||||
|
||||
type Recurse1 = {
|
||||
>Recurse1 : Recurse1
|
||||
|
||||
[K in keyof Recurse2]: Recurse2[K]
|
||||
>K : K
|
||||
>Recurse2 : Recurse2
|
||||
>Recurse2 : Recurse2
|
||||
>K : K
|
||||
}
|
||||
|
||||
type Recurse2 = {
|
||||
>Recurse2 : Recurse2
|
||||
|
||||
[K in keyof Recurse1]: Recurse1[K]
|
||||
>K : K
|
||||
>Recurse1 : Recurse1
|
||||
>Recurse1 : Recurse1
|
||||
>K : K
|
||||
}
|
||||
@ -176,63 +176,63 @@ function foo({a = 4, b = { x: 5 }}) {
|
||||
});
|
||||
(function () {
|
||||
var y;
|
||||
(_a = { y: 1 }, _b = _a.y, y = _b === void 0 ? 5 : _b, _a);
|
||||
var _a, _b;
|
||||
(_a = { y: 1 }.y, y = _a === void 0 ? 5 : _a);
|
||||
var _a;
|
||||
});
|
||||
(function () {
|
||||
var y;
|
||||
(_a = { y: 1 }, _b = _a.y, y = _b === void 0 ? 5 : _b, _a);
|
||||
var _a, _b;
|
||||
(_a = { y: 1 }.y, y = _a === void 0 ? 5 : _a);
|
||||
var _a;
|
||||
});
|
||||
(function () {
|
||||
var y0;
|
||||
(_a = { y0: 1 }, _b = _a.y0, y0 = _b === void 0 ? 5 : _b, _a);
|
||||
var _a, _b;
|
||||
(_a = { y0: 1 }.y0, y0 = _a === void 0 ? 5 : _a);
|
||||
var _a;
|
||||
});
|
||||
(function () {
|
||||
var y0;
|
||||
(_a = { y0: 1 }, _b = _a.y0, y0 = _b === void 0 ? 5 : _b, _a);
|
||||
var _a, _b;
|
||||
(_a = { y0: 1 }.y0, y0 = _a === void 0 ? 5 : _a);
|
||||
var _a;
|
||||
});
|
||||
(function () {
|
||||
var y1;
|
||||
(_a = {}, _b = _a.y1, y1 = _b === void 0 ? 5 : _b, _a);
|
||||
var _a, _b;
|
||||
(_a = {}.y1, y1 = _a === void 0 ? 5 : _a);
|
||||
var _a;
|
||||
});
|
||||
(function () {
|
||||
var y1;
|
||||
(_a = {}, _b = _a.y1, y1 = _b === void 0 ? 5 : _b, _a);
|
||||
var _a, _b;
|
||||
(_a = {}.y1, y1 = _a === void 0 ? 5 : _a);
|
||||
var _a;
|
||||
});
|
||||
(function () {
|
||||
var y2, y3;
|
||||
(_a = {}, _b = _a.y2, y2 = _b === void 0 ? 5 : _b, _c = _a.y3, y3 = _c === void 0 ? { x: 1 } : _c, _a);
|
||||
(_a = {}, _b = _a.y2, y2 = _b === void 0 ? 5 : _b, _c = _a.y3, y3 = _c === void 0 ? { x: 1 } : _c);
|
||||
var _a, _b, _c;
|
||||
});
|
||||
(function () {
|
||||
var y2, y3;
|
||||
(_a = {}, _b = _a.y2, y2 = _b === void 0 ? 5 : _b, _c = _a.y3, y3 = _c === void 0 ? { x: 1 } : _c, _a);
|
||||
(_a = {}, _b = _a.y2, y2 = _b === void 0 ? 5 : _b, _c = _a.y3, y3 = _c === void 0 ? { x: 1 } : _c);
|
||||
var _a, _b, _c;
|
||||
});
|
||||
(function () {
|
||||
var y4, y5;
|
||||
(_a = {}, _b = _a.y4, y4 = _b === void 0 ? 5 : _b, _c = _a.y5, y5 = _c === void 0 ? { x: 1 } : _c, _a);
|
||||
(_a = {}, _b = _a.y4, y4 = _b === void 0 ? 5 : _b, _c = _a.y5, y5 = _c === void 0 ? { x: 1 } : _c);
|
||||
var _a, _b, _c;
|
||||
});
|
||||
(function () {
|
||||
var y4, y5;
|
||||
(_a = {}, _b = _a.y4, y4 = _b === void 0 ? 5 : _b, _c = _a.y5, y5 = _c === void 0 ? { x: 1 } : _c, _a);
|
||||
(_a = {}, _b = _a.y4, y4 = _b === void 0 ? 5 : _b, _c = _a.y5, y5 = _c === void 0 ? { x: 1 } : _c);
|
||||
var _a, _b, _c;
|
||||
});
|
||||
(function () {
|
||||
var z;
|
||||
(_a = { z: { x: 1 } }, _b = _a.z, z = _b === void 0 ? { x: 5 } : _b, _a);
|
||||
var _a, _b;
|
||||
(_a = { z: { x: 1 } }.z, z = _a === void 0 ? { x: 5 } : _a);
|
||||
var _a;
|
||||
});
|
||||
(function () {
|
||||
var z;
|
||||
(_a = { z: { x: 1 } }, _b = _a.z, z = _b === void 0 ? { x: 5 } : _b, _a);
|
||||
var _a, _b;
|
||||
(_a = { z: { x: 1 } }.z, z = _a === void 0 ? { x: 5 } : _a);
|
||||
var _a;
|
||||
});
|
||||
(function () {
|
||||
var a = { s: s };
|
||||
|
||||
@ -194,13 +194,13 @@ for (_b = getRobot(), _c = _b.name, nameA = _c === void 0 ? "noName" : _c, _b, i
|
||||
for (_d = { name: "trimmer", skill: "trimming" }, _e = _d.name, nameA = _e === void 0 ? "noName" : _e, _d, i = 0; i < 1; i++) {
|
||||
console.log(nameA);
|
||||
}
|
||||
for (_f = multiRobot.skills, _g = _f === void 0 ? { primary: "none", secondary: "none" } : _f, _h = _g.primary, primaryA = _h === void 0 ? "primary" : _h, _j = _g.secondary, secondaryA = _j === void 0 ? "secondary" : _j, multiRobot, multiRobot, i = 0; i < 1; i++) {
|
||||
for (_f = multiRobot.skills, _g = _f === void 0 ? { primary: "none", secondary: "none" } : _f, _h = _g.primary, primaryA = _h === void 0 ? "primary" : _h, _j = _g.secondary, secondaryA = _j === void 0 ? "secondary" : _j, multiRobot, i = 0; i < 1; i++) {
|
||||
console.log(primaryA);
|
||||
}
|
||||
for (_k = getMultiRobot(), (_l = _k.skills, _m = _l === void 0 ? { primary: "none", secondary: "none" } : _l, _o = _m.primary, primaryA = _o === void 0 ? "primary" : _o, _p = _m.secondary, secondaryA = _p === void 0 ? "secondary" : _p, _k), _k, i = 0; i < 1; i++) {
|
||||
for (_k = getMultiRobot(), _l = _k.skills, _m = _l === void 0 ? { primary: "none", secondary: "none" } : _l, _o = _m.primary, primaryA = _o === void 0 ? "primary" : _o, _p = _m.secondary, secondaryA = _p === void 0 ? "secondary" : _p, _k, i = 0; i < 1; i++) {
|
||||
console.log(primaryA);
|
||||
}
|
||||
for (_q = { name: "trimmer", skills: { primary: "trimming", secondary: "edging" } }, (_r = _q.skills, _s = _r === void 0 ? { primary: "none", secondary: "none" } : _r, _t = _s.primary, primaryA = _t === void 0 ? "primary" : _t, _u = _s.secondary, secondaryA = _u === void 0 ? "secondary" : _u, _q), _q,
|
||||
for (_q = { name: "trimmer", skills: { primary: "trimming", secondary: "edging" } }, _r = _q.skills, _s = _r === void 0 ? { primary: "none", secondary: "none" } : _r, _t = _s.primary, primaryA = _t === void 0 ? "primary" : _t, _u = _s.secondary, secondaryA = _u === void 0 ? "secondary" : _u, _q,
|
||||
i = 0; i < 1; i++) {
|
||||
console.log(primaryA);
|
||||
}
|
||||
@ -213,13 +213,13 @@ for (_w = getRobot(), _x = _w.name, name = _x === void 0 ? "noName" : _x, _w, i
|
||||
for (_y = { name: "trimmer", skill: "trimming" }, _z = _y.name, name = _z === void 0 ? "noName" : _z, _y, i = 0; i < 1; i++) {
|
||||
console.log(nameA);
|
||||
}
|
||||
for (_0 = multiRobot.skills, _1 = _0 === void 0 ? { primary: "none", secondary: "none" } : _0, _2 = _1.primary, primary = _2 === void 0 ? "primary" : _2, _3 = _1.secondary, secondary = _3 === void 0 ? "secondary" : _3, multiRobot, multiRobot, i = 0; i < 1; i++) {
|
||||
for (_0 = multiRobot.skills, _1 = _0 === void 0 ? { primary: "none", secondary: "none" } : _0, _2 = _1.primary, primary = _2 === void 0 ? "primary" : _2, _3 = _1.secondary, secondary = _3 === void 0 ? "secondary" : _3, multiRobot, i = 0; i < 1; i++) {
|
||||
console.log(primaryA);
|
||||
}
|
||||
for (_4 = getMultiRobot(), (_5 = _4.skills, _6 = _5 === void 0 ? { primary: "none", secondary: "none" } : _5, _7 = _6.primary, primary = _7 === void 0 ? "primary" : _7, _8 = _6.secondary, secondary = _8 === void 0 ? "secondary" : _8, _4), _4, i = 0; i < 1; i++) {
|
||||
for (_4 = getMultiRobot(), _5 = _4.skills, _6 = _5 === void 0 ? { primary: "none", secondary: "none" } : _5, _7 = _6.primary, primary = _7 === void 0 ? "primary" : _7, _8 = _6.secondary, secondary = _8 === void 0 ? "secondary" : _8, _4, i = 0; i < 1; i++) {
|
||||
console.log(primaryA);
|
||||
}
|
||||
for (_9 = { name: "trimmer", skills: { primary: "trimming", secondary: "edging" } }, (_10 = _9.skills, _11 = _10 === void 0 ? { primary: "none", secondary: "none" } : _10, _12 = _11.primary, primary = _12 === void 0 ? "primary" : _12, _13 = _11.secondary, secondary = _13 === void 0 ? "secondary" : _13, _9), _9,
|
||||
for (_9 = { name: "trimmer", skills: { primary: "trimming", secondary: "edging" } }, _10 = _9.skills, _11 = _10 === void 0 ? { primary: "none", secondary: "none" } : _10, _12 = _11.primary, primary = _12 === void 0 ? "primary" : _12, _13 = _11.secondary, secondary = _13 === void 0 ? "secondary" : _13, _9,
|
||||
i = 0; i < 1; i++) {
|
||||
console.log(primaryA);
|
||||
}
|
||||
@ -232,13 +232,13 @@ for (_16 = getRobot(), _17 = _16.name, nameA = _17 === void 0 ? "noName" : _17,
|
||||
for (_19 = { name: "trimmer", skill: "trimming" }, _20 = _19.name, nameA = _20 === void 0 ? "noName" : _20, _21 = _19.skill, skillA = _21 === void 0 ? "skill" : _21, _19, i = 0; i < 1; i++) {
|
||||
console.log(nameA);
|
||||
}
|
||||
for (_22 = multiRobot.name, nameA = _22 === void 0 ? "noName" : _22, _23 = multiRobot.skills, _24 = _23 === void 0 ? { primary: "none", secondary: "none" } : _23, _25 = _24.primary, primaryA = _25 === void 0 ? "primary" : _25, _26 = _24.secondary, secondaryA = _26 === void 0 ? "secondary" : _26, multiRobot, multiRobot, i = 0; i < 1; i++) {
|
||||
for (_22 = multiRobot.name, nameA = _22 === void 0 ? "noName" : _22, _23 = multiRobot.skills, _24 = _23 === void 0 ? { primary: "none", secondary: "none" } : _23, _25 = _24.primary, primaryA = _25 === void 0 ? "primary" : _25, _26 = _24.secondary, secondaryA = _26 === void 0 ? "secondary" : _26, multiRobot, i = 0; i < 1; i++) {
|
||||
console.log(primaryA);
|
||||
}
|
||||
for (_27 = getMultiRobot(), (_28 = _27.name, nameA = _28 === void 0 ? "noName" : _28, _29 = _27.skills, _30 = _29 === void 0 ? { primary: "none", secondary: "none" } : _29, _31 = _30.primary, primaryA = _31 === void 0 ? "primary" : _31, _32 = _30.secondary, secondaryA = _32 === void 0 ? "secondary" : _32, _27), _27, i = 0; i < 1; i++) {
|
||||
for (_27 = getMultiRobot(), _28 = _27.name, nameA = _28 === void 0 ? "noName" : _28, _29 = _27.skills, _30 = _29 === void 0 ? { primary: "none", secondary: "none" } : _29, _31 = _30.primary, primaryA = _31 === void 0 ? "primary" : _31, _32 = _30.secondary, secondaryA = _32 === void 0 ? "secondary" : _32, _27, i = 0; i < 1; i++) {
|
||||
console.log(primaryA);
|
||||
}
|
||||
for (_33 = { name: "trimmer", skills: { primary: "trimming", secondary: "edging" } }, (_34 = _33.name, nameA = _34 === void 0 ? "noName" : _34, _35 = _33.skills, _36 = _35 === void 0 ? { primary: "none", secondary: "none" } : _35, _37 = _36.primary, primaryA = _37 === void 0 ? "primary" : _37, _38 = _36.secondary, secondaryA = _38 === void 0 ? "secondary" : _38, _33), _33,
|
||||
for (_33 = { name: "trimmer", skills: { primary: "trimming", secondary: "edging" } }, _34 = _33.name, nameA = _34 === void 0 ? "noName" : _34, _35 = _33.skills, _36 = _35 === void 0 ? { primary: "none", secondary: "none" } : _35, _37 = _36.primary, primaryA = _37 === void 0 ? "primary" : _37, _38 = _36.secondary, secondaryA = _38 === void 0 ? "secondary" : _38, _33,
|
||||
i = 0; i < 1; i++) {
|
||||
console.log(primaryA);
|
||||
}
|
||||
@ -251,16 +251,15 @@ for (_41 = getRobot(), _42 = _41.name, name = _42 === void 0 ? "noName" : _42, _
|
||||
for (_44 = { name: "trimmer", skill: "trimming" }, _45 = _44.name, name = _45 === void 0 ? "noName" : _45, _46 = _44.skill, skill = _46 === void 0 ? "skill" : _46, _44, i = 0; i < 1; i++) {
|
||||
console.log(nameA);
|
||||
}
|
||||
for (_47 = multiRobot.name, name = _47 === void 0 ? "noName" : _47, _48 = multiRobot.skills, _49 = _48 === void 0 ? { primary: "none", secondary: "none" } : _48, _50 = _49.primary, primary = _50 === void 0 ? "primary" : _50, _51 = _49.secondary, secondary = _51 === void 0 ? "secondary" : _51, multiRobot, multiRobot, i = 0; i < 1; i++) {
|
||||
for (_47 = multiRobot.name, name = _47 === void 0 ? "noName" : _47, _48 = multiRobot.skills, _49 = _48 === void 0 ? { primary: "none", secondary: "none" } : _48, _50 = _49.primary, primary = _50 === void 0 ? "primary" : _50, _51 = _49.secondary, secondary = _51 === void 0 ? "secondary" : _51, multiRobot, i = 0; i < 1; i++) {
|
||||
console.log(primaryA);
|
||||
}
|
||||
for (_52 = getMultiRobot(), (_53 = _52.name, name = _53 === void 0 ? "noName" : _53, _54 = _52.skills, _55 = _54 === void 0 ? { primary: "none", secondary: "none" } : _54, _56 = _55.primary, primary = _56 === void 0 ? "primary" : _56, _57 = _55.secondary, secondary = _57 === void 0 ? "secondary" : _57, _52), _52, i = 0; i < 1; i++) {
|
||||
for (_52 = getMultiRobot(), _53 = _52.name, name = _53 === void 0 ? "noName" : _53, _54 = _52.skills, _55 = _54 === void 0 ? { primary: "none", secondary: "none" } : _54, _56 = _55.primary, primary = _56 === void 0 ? "primary" : _56, _57 = _55.secondary, secondary = _57 === void 0 ? "secondary" : _57, _52, i = 0; i < 1; i++) {
|
||||
console.log(primaryA);
|
||||
}
|
||||
for (_58 = { name: "trimmer", skills: { primary: "trimming", secondary: "edging" } }, (_59 = _58.name, name = _59 === void 0 ? "noName" : _59, _60 = _58.skills, _61 = _60 === void 0 ? { primary: "none", secondary: "none" } : _60, _62 = _61.primary, primary = _62 === void 0 ? "primary" : _62, _63 = _61.secondary, secondary = _63 === void 0 ? "secondary" : _63, _58), _58,
|
||||
for (_58 = { name: "trimmer", skills: { primary: "trimming", secondary: "edging" } }, _59 = _58.name, name = _59 === void 0 ? "noName" : _59, _60 = _58.skills, _61 = _60 === void 0 ? { primary: "none", secondary: "none" } : _60, _62 = _61.primary, primary = _62 === void 0 ? "primary" : _62, _63 = _61.secondary, secondary = _63 === void 0 ? "secondary" : _63, _58,
|
||||
i = 0; i < 1; i++) {
|
||||
console.log(primaryA);
|
||||
}
|
||||
var _k, _q, _4, _9, _27, _33, _52, _58;
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _l, _m, _o, _p, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _5, _6, _7, _8, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _28, _29, _30, _31, _32, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _53, _54, _55, _56, _57, _59, _60, _61, _62, _63;
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63;
|
||||
//# sourceMappingURL=sourceMapValidationDestructuringForObjectBindingPatternDefaultValues2.js.map
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -24,9 +24,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
@ -21,9 +21,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
@ -23,9 +23,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
@ -28,9 +28,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
@ -33,9 +33,6 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
if (typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
class D {
|
||||
readonly noWiden = 1
|
||||
constructor(readonly widen = 2) {
|
||||
this.noWiden = 5; // error
|
||||
this.widen = 6; // ok
|
||||
}
|
||||
}
|
||||
new D(7); // ok
|
||||
15
tests/cases/conformance/types/mapped/recursiveMappedTypes.ts
Normal file
15
tests/cases/conformance/types/mapped/recursiveMappedTypes.ts
Normal file
@ -0,0 +1,15 @@
|
||||
// @declaration: true
|
||||
|
||||
// Recursive mapped types simply appear empty
|
||||
|
||||
type Recurse = {
|
||||
[K in keyof Recurse]: Recurse[K]
|
||||
}
|
||||
|
||||
type Recurse1 = {
|
||||
[K in keyof Recurse2]: Recurse2[K]
|
||||
}
|
||||
|
||||
type Recurse2 = {
|
||||
[K in keyof Recurse1]: Recurse1[K]
|
||||
}
|
||||
@ -6,3 +6,12 @@ declare function suddenly(f: (a: { x: { z, ka }, y: string }) => void);
|
||||
suddenly(({ x: a, ...rest }) => rest.y);
|
||||
suddenly(({ x: { z = 12, ...nested }, ...rest } = { x: { z: 1, ka: 1 }, y: 'noo' }) => rest.y + nested.ka);
|
||||
|
||||
class C {
|
||||
m({ a, ...clone }: { a: number, b: string}): void {
|
||||
// actually, never mind, don't clone
|
||||
}
|
||||
set p({ a, ...clone }: { a: number, b: string}) {
|
||||
// actually, never mind, don't clone
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
/// <reference path='../fourslash.ts' />
|
||||
|
||||
////class Base{
|
||||
////}
|
||||
|
||||
@ -211,6 +211,7 @@ declare namespace FourSlashInterface {
|
||||
DocCommentTemplate(expectedText: string, expectedOffset: number, empty?: boolean): void;
|
||||
noDocCommentTemplate(): void;
|
||||
rangeAfterCodeFix(expectedText: string, errorCode?: number): void;
|
||||
importFixAtPosition(expectedTextArray: string[], errorCode?: number): void;
|
||||
|
||||
navigationBar(json: any): void;
|
||||
navigationTree(json: any): void;
|
||||
|
||||
10
tests/cases/fourslash/importNameCodeFixExistingImport0.ts
Normal file
10
tests/cases/fourslash/importNameCodeFixExistingImport0.ts
Normal file
@ -0,0 +1,10 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// import [|{ v1 }|] from "./module";
|
||||
//// f1/*0*/();
|
||||
|
||||
// @Filename: module.ts
|
||||
//// export function f1() {}
|
||||
//// export var v1 = 5;
|
||||
|
||||
verify.importFixAtPosition([`{ v1, f1 }`]);
|
||||
11
tests/cases/fourslash/importNameCodeFixExistingImport1.ts
Normal file
11
tests/cases/fourslash/importNameCodeFixExistingImport1.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// import d, [|{ v1 }|] from "./module";
|
||||
//// f1/*0*/();
|
||||
|
||||
// @Filename: module.ts
|
||||
//// export function f1() {}
|
||||
//// export var v1 = 5;
|
||||
//// export default var d1 = 6;
|
||||
|
||||
verify.importFixAtPosition([`{ v1, f1 }`]);
|
||||
21
tests/cases/fourslash/importNameCodeFixExistingImport10.ts
Normal file
21
tests/cases/fourslash/importNameCodeFixExistingImport10.ts
Normal file
@ -0,0 +1,21 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// import [|{
|
||||
//// v1,
|
||||
//// v2
|
||||
//// }|] from "./module";
|
||||
//// f1/*0*/();
|
||||
|
||||
// @Filename: module.ts
|
||||
//// export function f1() {}
|
||||
//// export var v1 = 5;
|
||||
//// export var v2 = 5;
|
||||
//// export var v3 = 5;
|
||||
|
||||
verify.importFixAtPosition([
|
||||
`{
|
||||
v1,
|
||||
v2,
|
||||
f1
|
||||
}`
|
||||
]);
|
||||
20
tests/cases/fourslash/importNameCodeFixExistingImport11.ts
Normal file
20
tests/cases/fourslash/importNameCodeFixExistingImport11.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////import [|{
|
||||
//// v1, v2,
|
||||
//// v3
|
||||
////}|] from "./module";
|
||||
////f1/*0*/();
|
||||
|
||||
// @Filename: module.ts
|
||||
//// export function f1() {}
|
||||
//// export var v1 = 5;
|
||||
//// export var v2 = 5;
|
||||
//// export var v3 = 5;
|
||||
|
||||
verify.importFixAtPosition([
|
||||
`{
|
||||
v1, v2,
|
||||
v3, f1
|
||||
}`
|
||||
]);
|
||||
12
tests/cases/fourslash/importNameCodeFixExistingImport12.ts
Normal file
12
tests/cases/fourslash/importNameCodeFixExistingImport12.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// import [|{}|] from "./module";
|
||||
//// f1/*0*/();
|
||||
|
||||
// @Filename: module.ts
|
||||
//// export function f1() {}
|
||||
//// export var v1 = 5;
|
||||
//// export var v2 = 5;
|
||||
//// export var v3 = 5;
|
||||
|
||||
verify.importFixAtPosition([`{ f1 }`]);
|
||||
16
tests/cases/fourslash/importNameCodeFixExistingImport2.ts
Normal file
16
tests/cases/fourslash/importNameCodeFixExistingImport2.ts
Normal file
@ -0,0 +1,16 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// [|import * as ns from "./module";
|
||||
//// f1/*0*/();|]
|
||||
|
||||
// @Filename: module.ts
|
||||
//// export function f1() {}
|
||||
//// export var v1 = 5;
|
||||
|
||||
verify.importFixAtPosition([
|
||||
`import * as ns from "./module";
|
||||
import { f1 } from "./module";
|
||||
f1();`,
|
||||
`import * as ns from "./module";
|
||||
ns.f1();`
|
||||
]);
|
||||
18
tests/cases/fourslash/importNameCodeFixExistingImport3.ts
Normal file
18
tests/cases/fourslash/importNameCodeFixExistingImport3.ts
Normal file
@ -0,0 +1,18 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// [|import d, * as ns from "./module" ;
|
||||
//// f1/*0*/();|]
|
||||
|
||||
// @Filename: module.ts
|
||||
//// export function f1() {}
|
||||
//// export var v1 = 5;
|
||||
//// export default var d1 = 6;
|
||||
|
||||
// Test with some extra spaces before the semicolon
|
||||
verify.importFixAtPosition([
|
||||
`import d, * as ns from "./module" ;
|
||||
ns.f1();`,
|
||||
`import d, * as ns from "./module" ;
|
||||
import { f1 } from "./module";
|
||||
f1();`,
|
||||
]);
|
||||
14
tests/cases/fourslash/importNameCodeFixExistingImport4.ts
Normal file
14
tests/cases/fourslash/importNameCodeFixExistingImport4.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// [|import d from "./module";
|
||||
//// f1/*0*/();|]
|
||||
|
||||
// @Filename: module.ts
|
||||
//// export function f1() {}
|
||||
//// export var v1 = 5;
|
||||
//// export default var d1 = 6;
|
||||
|
||||
verify.importFixAtPosition([
|
||||
`import d, { f1 } from "./module";
|
||||
f1();`
|
||||
]);
|
||||
12
tests/cases/fourslash/importNameCodeFixExistingImport5.ts
Normal file
12
tests/cases/fourslash/importNameCodeFixExistingImport5.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// [|import "./module";
|
||||
//// f1/*0*/();|]
|
||||
|
||||
// @Filename: module.ts
|
||||
//// export function f1() {}
|
||||
//// export var v1 = 5;
|
||||
|
||||
verify.importFixAtPosition([`import "./module";
|
||||
import { f1 } from "./module";
|
||||
f1();`]);
|
||||
13
tests/cases/fourslash/importNameCodeFixExistingImport6.ts
Normal file
13
tests/cases/fourslash/importNameCodeFixExistingImport6.ts
Normal file
@ -0,0 +1,13 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// import [|{ v1 }|] from "fake-module";
|
||||
//// f1/*0*/();
|
||||
|
||||
// @Filename: ../package.json
|
||||
//// { "dependencies": { "fake-module": "latest" } }
|
||||
|
||||
// @Filename: ../node_modules/fake-module/index.ts
|
||||
//// export var v1 = 5;
|
||||
//// export function f1();
|
||||
|
||||
verify.importFixAtPosition([`{ v1, f1 }`]);
|
||||
10
tests/cases/fourslash/importNameCodeFixExistingImport7.ts
Normal file
10
tests/cases/fourslash/importNameCodeFixExistingImport7.ts
Normal file
@ -0,0 +1,10 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// import [|{ v1 }|] from "../other_dir/module";
|
||||
//// f1/*0*/();
|
||||
|
||||
// @Filename: ../other_dir/module.ts
|
||||
//// export var v1 = 5;
|
||||
//// export function f1();
|
||||
|
||||
verify.importFixAtPosition([`{ v1, f1 }`]);
|
||||
12
tests/cases/fourslash/importNameCodeFixExistingImport8.ts
Normal file
12
tests/cases/fourslash/importNameCodeFixExistingImport8.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// import [|{v1, v2, v3,}|] from "./module";
|
||||
//// f1/*0*/();
|
||||
|
||||
// @Filename: module.ts
|
||||
//// export function f1() {}
|
||||
//// export var v1 = 5;
|
||||
//// export var v2 = 5;
|
||||
//// export var v3 = 5;
|
||||
|
||||
verify.importFixAtPosition([`{v1, v2, v3, f1,}`]);
|
||||
17
tests/cases/fourslash/importNameCodeFixExistingImport9.ts
Normal file
17
tests/cases/fourslash/importNameCodeFixExistingImport9.ts
Normal file
@ -0,0 +1,17 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// import [|{
|
||||
//// v1
|
||||
//// }|] from "./module";
|
||||
//// f1/*0*/();
|
||||
|
||||
// @Filename: module.ts
|
||||
//// export function f1() {}
|
||||
//// export var v1 = 5;
|
||||
|
||||
verify.importFixAtPosition([
|
||||
`{
|
||||
v1,
|
||||
f1
|
||||
}`
|
||||
]);
|
||||
@ -0,0 +1,18 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// [|import ns = require("ambient-module");
|
||||
//// var x = v1/*0*/ + 5;|]
|
||||
|
||||
// @Filename: ambientModule.ts
|
||||
//// declare module "ambient-module" {
|
||||
//// export function f1();
|
||||
//// export var v1;
|
||||
//// }
|
||||
|
||||
verify.importFixAtPosition([
|
||||
`import ns = require("ambient-module");
|
||||
var x = ns.v1 + 5;`,
|
||||
`import ns = require("ambient-module");
|
||||
import { v1 } from "ambient-module";
|
||||
var x = v1 + 5;`,
|
||||
]);
|
||||
15
tests/cases/fourslash/importNameCodeFixNewImportAmbient0.ts
Normal file
15
tests/cases/fourslash/importNameCodeFixNewImportAmbient0.ts
Normal file
@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// [|f1/*0*/();|]
|
||||
|
||||
// @Filename: ambientModule.ts
|
||||
//// declare module "ambient-module" {
|
||||
//// export function f1();
|
||||
//// export var v1;
|
||||
//// }
|
||||
|
||||
verify.importFixAtPosition([
|
||||
`import { f1 } from "ambient-module";
|
||||
|
||||
f1();`
|
||||
]);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user