Merge branch 'master' into object-spread
This commit is contained in:
commit
f9fe01a6e3
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -41,6 +41,7 @@ tests/cases/**/*.js.map
|
|||
scripts/debug.bat
|
||||
scripts/run.bat
|
||||
scripts/word2md.js
|
||||
scripts/buildProtocol.js
|
||||
scripts/ior.js
|
||||
scripts/buildProtocol.js
|
||||
scripts/*.js.map
|
||||
|
|
|
@ -183,5 +183,3 @@ jake baseline-accept
|
|||
```
|
||||
|
||||
to establish the new baselines as the desired behavior. This will change the files in `tests\baselines\reference`, which should be included as part of your commit. It's important to carefully validate changes in the baselines.
|
||||
|
||||
**Note** that `baseline-accept` should only be run after a full test run! Accepting baselines after running a subset of tests will delete baseline files for the tests that didn't run.
|
||||
|
|
19
Jakefile.js
19
Jakefile.js
|
@ -70,14 +70,16 @@ var compilerSources = [
|
|||
"visitor.ts",
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/ts.ts",
|
||||
"transformers/module/es6.ts",
|
||||
"transformers/module/es2015.ts",
|
||||
"transformers/module/system.ts",
|
||||
"transformers/module/module.ts",
|
||||
"transformers/jsx.ts",
|
||||
"transformers/experimental.ts",
|
||||
"transformers/es7.ts",
|
||||
"transformers/es2017.ts",
|
||||
"transformers/es2016.ts",
|
||||
"transformers/es2015.ts",
|
||||
"transformers/generators.ts",
|
||||
"transformers/es6.ts",
|
||||
"transformers/es5.ts",
|
||||
"transformer.ts",
|
||||
"sourcemap.ts",
|
||||
"comments.ts",
|
||||
|
@ -105,14 +107,16 @@ var servicesSources = [
|
|||
"visitor.ts",
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/ts.ts",
|
||||
"transformers/module/es6.ts",
|
||||
"transformers/module/es2015.ts",
|
||||
"transformers/module/system.ts",
|
||||
"transformers/module/module.ts",
|
||||
"transformers/jsx.ts",
|
||||
"transformers/experimental.ts",
|
||||
"transformers/es7.ts",
|
||||
"transformers/es2017.ts",
|
||||
"transformers/es2016.ts",
|
||||
"transformers/es2015.ts",
|
||||
"transformers/generators.ts",
|
||||
"transformers/es6.ts",
|
||||
"transformers/es5.ts",
|
||||
"transformer.ts",
|
||||
"sourcemap.ts",
|
||||
"comments.ts",
|
||||
|
@ -355,6 +359,7 @@ function concatenateFiles(destinationFile, sourceFiles) {
|
|||
if (!fs.existsSync(sourceFiles[i])) {
|
||||
fail(sourceFiles[i] + " does not exist!");
|
||||
}
|
||||
fs.appendFileSync(temp, "\n\n");
|
||||
fs.appendFileSync(temp, fs.readFileSync(sourceFiles[i]));
|
||||
}
|
||||
// Move the file to the final destination
|
||||
|
@ -445,6 +450,8 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts
|
|||
options += " --stripInternal";
|
||||
}
|
||||
|
||||
options += " --target es5";
|
||||
|
||||
var cmd = host + " " + compilerPath + " " + options + " ";
|
||||
cmd = cmd + sources.join(" ");
|
||||
console.log(cmd + "\n");
|
||||
|
|
|
@ -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:** 1.8.0 / nightly (2.0.0-dev.201xxxxx)
|
||||
**TypeScript Version:** 2.0.3 / nightly (2.1.0-dev.201xxxxx)
|
||||
|
||||
**Code**
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ function endsWith(s: string, suffix: string) {
|
|||
class DeclarationsWalker {
|
||||
private visitedTypes: ts.Type[] = [];
|
||||
private text = "";
|
||||
private removedTypes: ts.Type[] = [];
|
||||
|
||||
private constructor(private typeChecker: ts.TypeChecker, private protocolFile: ts.SourceFile) {
|
||||
}
|
||||
|
||||
|
@ -17,9 +19,18 @@ class DeclarationsWalker {
|
|||
let text = "declare namespace ts.server.protocol {\n";
|
||||
var walker = new DeclarationsWalker(typeChecker, protocolFile);
|
||||
walker.visitTypeNodes(protocolFile);
|
||||
return walker.text
|
||||
text = walker.text
|
||||
? `declare namespace ts.server.protocol {\n${walker.text}}`
|
||||
: "";
|
||||
if (walker.removedTypes) {
|
||||
text += "\ndeclare namespace ts {\n";
|
||||
text += " // these types are empty stubs for types from services and should not be used directly\n"
|
||||
for (const type of walker.removedTypes) {
|
||||
text += ` export type ${type.symbol.name} = never;\n`;
|
||||
}
|
||||
text += "}"
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private processType(type: ts.Type): void {
|
||||
|
@ -41,12 +52,18 @@ class DeclarationsWalker {
|
|||
if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") {
|
||||
return;
|
||||
}
|
||||
// splice declaration in final d.ts file
|
||||
const text = decl.getFullText();
|
||||
this.text += `${text}\n`;
|
||||
if (decl.kind === ts.SyntaxKind.EnumDeclaration) {
|
||||
this.removedTypes.push(type);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// splice declaration in final d.ts file
|
||||
let text = decl.getFullText();
|
||||
this.text += `${text}\n`;
|
||||
// recursively pull all dependencies into result dts file
|
||||
|
||||
// recursively pull all dependencies into result dts file
|
||||
this.visitTypeNodes(decl);
|
||||
this.visitTypeNodes(decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,15 +79,37 @@ class DeclarationsWalker {
|
|||
case ts.SyntaxKind.Parameter:
|
||||
case ts.SyntaxKind.IndexSignature:
|
||||
if (((<ts.VariableDeclaration | ts.MethodDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration | ts.PropertySignature | ts.MethodSignature | ts.IndexSignatureDeclaration>node.parent).type) === node) {
|
||||
const type = this.typeChecker.getTypeAtLocation(node);
|
||||
if (type && !(type.flags & ts.TypeFlags.TypeParameter)) {
|
||||
this.processType(type);
|
||||
}
|
||||
this.processTypeOfNode(node);
|
||||
}
|
||||
break;
|
||||
case ts.SyntaxKind.InterfaceDeclaration:
|
||||
const heritageClauses = (<ts.InterfaceDeclaration>node.parent).heritageClauses;
|
||||
if (heritageClauses) {
|
||||
if (heritageClauses[0].token !== ts.SyntaxKind.ExtendsKeyword) {
|
||||
throw new Error(`Unexpected kind of heritage clause: ${ts.SyntaxKind[heritageClauses[0].kind]}`);
|
||||
}
|
||||
for (const type of heritageClauses[0].types) {
|
||||
this.processTypeOfNode(type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
ts.forEachChild(node, n => this.visitTypeNodes(n));
|
||||
}
|
||||
|
||||
private processTypeOfNode(node: ts.Node): void {
|
||||
if (node.kind === ts.SyntaxKind.UnionType) {
|
||||
for (const t of (<ts.UnionTypeNode>node).types) {
|
||||
this.processTypeOfNode(t);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const type = this.typeChecker.getTypeAtLocation(node);
|
||||
if (type && !(type.flags & (ts.TypeFlags.TypeParameter))) {
|
||||
this.processType(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,9 +160,12 @@ function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string)
|
|||
if (extraDeclarations) {
|
||||
protocolDts += extraDeclarations;
|
||||
}
|
||||
protocolDts += "\nimport protocol = ts.server.protocol;";
|
||||
protocolDts += "\nexport = protocol;";
|
||||
protocolDts += "\nexport as namespace protocol;";
|
||||
// do sanity check and try to compile generated text as standalone program
|
||||
const sanityCheckProgram = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ false);
|
||||
const diagnostics = [...program.getSyntacticDiagnostics(), ...program.getSemanticDiagnostics(), ...program.getGlobalDiagnostics()];
|
||||
const diagnostics = [...sanityCheckProgram.getSyntacticDiagnostics(), ...sanityCheckProgram.getSemanticDiagnostics(), ...sanityCheckProgram.getGlobalDiagnostics()];
|
||||
if (diagnostics.length) {
|
||||
const flattenedDiagnostics = diagnostics.map(d => ts.flattenDiagnosticMessageText(d.messageText, "\n")).join("\n");
|
||||
throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`);
|
||||
|
|
|
@ -785,6 +785,15 @@ namespace ts {
|
|||
};
|
||||
}
|
||||
|
||||
function createFlowArrayMutation(antecedent: FlowNode, node: CallExpression | BinaryExpression): FlowNode {
|
||||
setFlowNodeReferenced(antecedent);
|
||||
return <FlowArrayMutation>{
|
||||
flags: FlowFlags.ArrayMutation,
|
||||
antecedent,
|
||||
node
|
||||
};
|
||||
}
|
||||
|
||||
function finishFlowLabel(flow: FlowLabel): FlowNode {
|
||||
const antecedents = flow.antecedents;
|
||||
if (!antecedents) {
|
||||
|
@ -975,24 +984,44 @@ namespace ts {
|
|||
}
|
||||
|
||||
function bindTryStatement(node: TryStatement): void {
|
||||
const postFinallyLabel = createBranchLabel();
|
||||
const preFinallyLabel = createBranchLabel();
|
||||
const preTryFlow = currentFlow;
|
||||
// TODO: Every statement in try block is potentially an exit point!
|
||||
bind(node.tryBlock);
|
||||
addAntecedent(postFinallyLabel, currentFlow);
|
||||
addAntecedent(preFinallyLabel, currentFlow);
|
||||
|
||||
const flowAfterTry = currentFlow;
|
||||
let flowAfterCatch = unreachableFlow;
|
||||
|
||||
if (node.catchClause) {
|
||||
currentFlow = preTryFlow;
|
||||
bind(node.catchClause);
|
||||
addAntecedent(postFinallyLabel, currentFlow);
|
||||
addAntecedent(preFinallyLabel, currentFlow);
|
||||
|
||||
flowAfterCatch = currentFlow;
|
||||
}
|
||||
if (node.finallyBlock) {
|
||||
currentFlow = preTryFlow;
|
||||
// in finally flow is combined from pre-try/flow from try/flow from catch
|
||||
// pre-flow is necessary to make sure that finally is reachable even if finally flows in both try and finally blocks are unreachable
|
||||
addAntecedent(preFinallyLabel, preTryFlow);
|
||||
currentFlow = finishFlowLabel(preFinallyLabel);
|
||||
bind(node.finallyBlock);
|
||||
// if flow after finally is unreachable - keep it
|
||||
// otherwise check if flows after try and after catch are unreachable
|
||||
// if yes - convert current flow to unreachable
|
||||
// i.e.
|
||||
// try { return "1" } finally { console.log(1); }
|
||||
// console.log(2); // this line should be unreachable even if flow falls out of finally block
|
||||
if (!(currentFlow.flags & FlowFlags.Unreachable)) {
|
||||
if ((flowAfterTry.flags & FlowFlags.Unreachable) && (flowAfterCatch.flags & FlowFlags.Unreachable)) {
|
||||
currentFlow = flowAfterTry === reportedUnreachableFlow || flowAfterCatch === reportedUnreachableFlow
|
||||
? reportedUnreachableFlow
|
||||
: unreachableFlow;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if try statement has finally block and flow after finally block is unreachable - keep it
|
||||
// otherwise use whatever flow was accumulated at postFinallyLabel
|
||||
if (!node.finallyBlock || !(currentFlow.flags & FlowFlags.Unreachable)) {
|
||||
currentFlow = finishFlowLabel(postFinallyLabel);
|
||||
else {
|
||||
currentFlow = finishFlowLabel(preFinallyLabel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1168,6 +1197,12 @@ namespace ts {
|
|||
forEachChild(node, bind);
|
||||
if (operator === SyntaxKind.EqualsToken && !isAssignmentTarget(node)) {
|
||||
bindAssignmentTargetFlow(node.left);
|
||||
if (node.left.kind === SyntaxKind.ElementAccessExpression) {
|
||||
const elementAccess = <ElementAccessExpression>node.left;
|
||||
if (isNarrowableOperand(elementAccess.expression)) {
|
||||
currentFlow = createFlowArrayMutation(currentFlow, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1228,6 +1263,12 @@ namespace ts {
|
|||
else {
|
||||
forEachChild(node, bind);
|
||||
}
|
||||
if (node.expression.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
const propertyAccess = <PropertyAccessExpression>node.expression;
|
||||
if (isNarrowableOperand(propertyAccess.expression) && isPushOrUnshiftIdentifier(propertyAccess.name)) {
|
||||
currentFlow = createFlowArrayMutation(currentFlow, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getContainerFlags(node: Node): ContainerFlags {
|
||||
|
@ -1667,7 +1708,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkStrictModeFunctionDeclaration(node: FunctionDeclaration) {
|
||||
if (languageVersion < ScriptTarget.ES6) {
|
||||
if (languageVersion < ScriptTarget.ES2015) {
|
||||
// Report error if function is not top level function declaration
|
||||
if (blockScopeContainer.kind !== SyntaxKind.SourceFile &&
|
||||
blockScopeContainer.kind !== SyntaxKind.ModuleDeclaration &&
|
||||
|
@ -2035,7 +2076,9 @@ namespace ts {
|
|||
function setCommonJsModuleIndicator(node: Node) {
|
||||
if (!file.commonJsModuleIndicator) {
|
||||
file.commonJsModuleIndicator = node;
|
||||
bindSourceFileAsExternalModule();
|
||||
if (!file.externalModuleIndicator) {
|
||||
bindSourceFileAsExternalModule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2334,6 +2377,9 @@ namespace ts {
|
|||
case SyntaxKind.CallExpression:
|
||||
return computeCallExpression(<CallExpression>node, subtreeFlags);
|
||||
|
||||
case SyntaxKind.NewExpression:
|
||||
return computeNewExpression(<NewExpression>node, subtreeFlags);
|
||||
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return computeModuleDeclaration(<ModuleDeclaration>node, subtreeFlags);
|
||||
|
||||
|
@ -2411,11 +2457,15 @@ namespace ts {
|
|||
const expression = node.expression;
|
||||
const expressionKind = expression.kind;
|
||||
|
||||
if (node.typeArguments) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression
|
||||
|| isSuperOrSuperProperty(expression, expressionKind)) {
|
||||
// If the this node contains a SpreadExpression, or is a super call, then it is an ES6
|
||||
// node.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
|
@ -2437,6 +2487,21 @@ namespace ts {
|
|||
return false;
|
||||
}
|
||||
|
||||
function computeNewExpression(node: NewExpression, subtreeFlags: TransformFlags) {
|
||||
let transformFlags = subtreeFlags;
|
||||
if (node.typeArguments) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
// If the this node contains a SpreadElementExpression then it is an ES6
|
||||
// node.
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes;
|
||||
}
|
||||
|
||||
|
||||
function computeBinaryExpression(node: BinaryExpression, subtreeFlags: TransformFlags) {
|
||||
let transformFlags = subtreeFlags;
|
||||
const operatorTokenKind = node.operatorToken.kind;
|
||||
|
@ -2446,12 +2511,12 @@ namespace ts {
|
|||
&& (leftKind === SyntaxKind.ObjectLiteralExpression
|
||||
|| leftKind === SyntaxKind.ArrayLiteralExpression)) {
|
||||
// Destructuring assignments are ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES6 | TransformFlags.DestructuringAssignment;
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.DestructuringAssignment;
|
||||
}
|
||||
else if (operatorTokenKind === SyntaxKind.AsteriskAsteriskToken
|
||||
|| operatorTokenKind === SyntaxKind.AsteriskAsteriskEqualsToken) {
|
||||
// Exponentiation is ES7 syntax.
|
||||
transformFlags |= TransformFlags.AssertES7;
|
||||
// Exponentiation is ES2016 syntax.
|
||||
transformFlags |= TransformFlags.AssertES2016;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
|
@ -2465,13 +2530,12 @@ namespace ts {
|
|||
const initializer = node.initializer;
|
||||
const dotDotDotToken = node.dotDotDotToken;
|
||||
|
||||
// If the parameter has a question token, then it is TypeScript syntax.
|
||||
if (node.questionToken) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
// If the parameter's name is 'this', then it is TypeScript syntax.
|
||||
if (subtreeFlags & TransformFlags.ContainsDecorators || isThisIdentifier(name)) {
|
||||
// The '?' token, type annotations, decorators, and 'this' parameters are TypeSCript
|
||||
// syntax.
|
||||
if (node.questionToken
|
||||
|| node.type
|
||||
|| subtreeFlags & TransformFlags.ContainsDecorators
|
||||
|| isThisIdentifier(name)) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
|
@ -2483,7 +2547,7 @@ namespace ts {
|
|||
// If a parameter has an initializer, a binding pattern or a dotDotDot token, then
|
||||
// it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel.
|
||||
if (subtreeFlags & TransformFlags.ContainsBindingPattern || initializer || dotDotDotToken) {
|
||||
transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsDefaultValueAssignments;
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsDefaultValueAssignments;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
|
@ -2524,13 +2588,14 @@ namespace ts {
|
|||
}
|
||||
else {
|
||||
// A ClassDeclaration is ES6 syntax.
|
||||
transformFlags = subtreeFlags | TransformFlags.AssertES6;
|
||||
transformFlags = subtreeFlags | TransformFlags.AssertES2015;
|
||||
|
||||
// A class with a parameter property assignment, property initializer, or decorator is
|
||||
// TypeScript syntax.
|
||||
// An exported declaration may be TypeScript syntax.
|
||||
if ((subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask)
|
||||
|| (modifierFlags & ModifierFlags.Export)) {
|
||||
|| (modifierFlags & ModifierFlags.Export)
|
||||
|| node.typeParameters) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
|
@ -2547,11 +2612,12 @@ namespace ts {
|
|||
|
||||
function computeClassExpression(node: ClassExpression, subtreeFlags: TransformFlags) {
|
||||
// A ClassExpression is ES6 syntax.
|
||||
let transformFlags = subtreeFlags | TransformFlags.AssertES6;
|
||||
let transformFlags = subtreeFlags | TransformFlags.AssertES2015;
|
||||
|
||||
// A class with a parameter property assignment, property initializer, or decorator is
|
||||
// TypeScript syntax.
|
||||
if (subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask) {
|
||||
if (subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask
|
||||
|| node.typeParameters) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
|
@ -2571,7 +2637,7 @@ namespace ts {
|
|||
switch (node.token) {
|
||||
case SyntaxKind.ExtendsKeyword:
|
||||
// An `extends` HeritageClause is ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ImplementsKeyword:
|
||||
|
@ -2591,7 +2657,7 @@ namespace ts {
|
|||
function computeExpressionWithTypeArguments(node: ExpressionWithTypeArguments, subtreeFlags: TransformFlags) {
|
||||
// An ExpressionWithTypeArguments is ES6 syntax, as it is used in the
|
||||
// extends clause of a class.
|
||||
let transformFlags = subtreeFlags | TransformFlags.AssertES6;
|
||||
let transformFlags = subtreeFlags | TransformFlags.AssertES2015;
|
||||
|
||||
// If an ExpressionWithTypeArguments contains type arguments, then it
|
||||
// is TypeScript syntax.
|
||||
|
@ -2605,10 +2671,10 @@ namespace ts {
|
|||
|
||||
function computeConstructor(node: ConstructorDeclaration, subtreeFlags: TransformFlags) {
|
||||
let transformFlags = subtreeFlags;
|
||||
const body = node.body;
|
||||
|
||||
if (body === undefined) {
|
||||
// An overload constructor is TypeScript syntax.
|
||||
// TypeScript-specific modifiers and overloads are TypeScript syntax
|
||||
if (hasModifier(node, ModifierFlags.TypeScriptModifier)
|
||||
|| !node.body) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
|
@ -2618,23 +2684,25 @@ namespace ts {
|
|||
|
||||
function computeMethod(node: MethodDeclaration, subtreeFlags: TransformFlags) {
|
||||
// A MethodDeclaration is ES6 syntax.
|
||||
let transformFlags = subtreeFlags | TransformFlags.AssertES6;
|
||||
const modifierFlags = getModifierFlags(node);
|
||||
const body = node.body;
|
||||
const typeParameters = node.typeParameters;
|
||||
const asteriskToken = node.asteriskToken;
|
||||
let transformFlags = subtreeFlags | TransformFlags.AssertES2015;
|
||||
|
||||
// A MethodDeclaration is TypeScript syntax if it is either async, abstract, overloaded,
|
||||
// generic, or has a decorator.
|
||||
if (!body
|
||||
|| typeParameters
|
||||
|| (modifierFlags & (ModifierFlags.Async | ModifierFlags.Abstract))
|
||||
|| (subtreeFlags & TransformFlags.ContainsDecorators)) {
|
||||
// Decorators, TypeScript-specific modifiers, type parameters, type annotations, and
|
||||
// overloads are TypeScript syntax.
|
||||
if (node.decorators
|
||||
|| hasModifier(node, ModifierFlags.TypeScriptModifier)
|
||||
|| node.typeParameters
|
||||
|| node.type
|
||||
|| !node.body) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
// An async method declaration is ES2017 syntax.
|
||||
if (hasModifier(node, ModifierFlags.Async)) {
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
}
|
||||
|
||||
// Currently, we only support generators that were originally async function bodies.
|
||||
if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
transformFlags |= TransformFlags.AssertGenerator;
|
||||
}
|
||||
|
||||
|
@ -2644,14 +2712,13 @@ namespace ts {
|
|||
|
||||
function computeAccessor(node: AccessorDeclaration, subtreeFlags: TransformFlags) {
|
||||
let transformFlags = subtreeFlags;
|
||||
const modifierFlags = getModifierFlags(node);
|
||||
const body = node.body;
|
||||
|
||||
// A MethodDeclaration is TypeScript syntax if it is either async, abstract, overloaded,
|
||||
// generic, or has a decorator.
|
||||
if (!body
|
||||
|| (modifierFlags & (ModifierFlags.Async | ModifierFlags.Abstract))
|
||||
|| (subtreeFlags & TransformFlags.ContainsDecorators)) {
|
||||
// Decorators, TypeScript-specific modifiers, type annotations, and overloads are
|
||||
// TypeScript syntax.
|
||||
if (node.decorators
|
||||
|| hasModifier(node, ModifierFlags.TypeScriptModifier)
|
||||
|| node.type
|
||||
|| !node.body) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
|
@ -2677,7 +2744,6 @@ namespace ts {
|
|||
let transformFlags: TransformFlags;
|
||||
const modifierFlags = getModifierFlags(node);
|
||||
const body = node.body;
|
||||
const asteriskToken = node.asteriskToken;
|
||||
|
||||
if (!body || (modifierFlags & ModifierFlags.Ambient)) {
|
||||
// An ambient declaration is TypeScript syntax.
|
||||
|
@ -2689,19 +2755,27 @@ namespace ts {
|
|||
|
||||
// If a FunctionDeclaration is exported, then it is either ES6 or TypeScript syntax.
|
||||
if (modifierFlags & ModifierFlags.Export) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES6;
|
||||
transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
// If a FunctionDeclaration is async, then it is TypeScript syntax.
|
||||
if (modifierFlags & ModifierFlags.Async) {
|
||||
// TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
|
||||
// syntax.
|
||||
if (modifierFlags & ModifierFlags.TypeScriptModifier
|
||||
|| node.typeParameters
|
||||
|| node.type) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
// An async function declaration is ES2017 syntax.
|
||||
if (modifierFlags & ModifierFlags.Async) {
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
}
|
||||
|
||||
// If a FunctionDeclaration's subtree has marked the container as needing to capture the
|
||||
// lexical this, or the function contains parameters with initializers, then this node is
|
||||
// ES6 syntax.
|
||||
if (subtreeFlags & TransformFlags.ES6FunctionSyntaxMask) {
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
if (subtreeFlags & TransformFlags.ES2015FunctionSyntaxMask) {
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
// If a FunctionDeclaration is generator function and is the body of a
|
||||
|
@ -2709,7 +2783,7 @@ namespace ts {
|
|||
// down-level generator.
|
||||
// Currently we do not support transforming any other generator fucntions
|
||||
// down level.
|
||||
if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
transformFlags |= TransformFlags.AssertGenerator;
|
||||
}
|
||||
}
|
||||
|
@ -2720,19 +2794,25 @@ namespace ts {
|
|||
|
||||
function computeFunctionExpression(node: FunctionExpression, subtreeFlags: TransformFlags) {
|
||||
let transformFlags = subtreeFlags;
|
||||
const modifierFlags = getModifierFlags(node);
|
||||
const asteriskToken = node.asteriskToken;
|
||||
|
||||
// An async function expression is TypeScript syntax.
|
||||
if (modifierFlags & ModifierFlags.Async) {
|
||||
// TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
|
||||
// syntax.
|
||||
if (hasModifier(node, ModifierFlags.TypeScriptModifier)
|
||||
|| node.typeParameters
|
||||
|| node.type) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
// An async function expression is ES2017 syntax.
|
||||
if (hasModifier(node, ModifierFlags.Async)) {
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
}
|
||||
|
||||
// If a FunctionExpression's subtree has marked the container as needing to capture the
|
||||
// lexical this, or the function contains parameters with initializers, then this node is
|
||||
// ES6 syntax.
|
||||
if (subtreeFlags & TransformFlags.ES6FunctionSyntaxMask) {
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
if (subtreeFlags & TransformFlags.ES2015FunctionSyntaxMask) {
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
// If a FunctionExpression is generator function and is the body of a
|
||||
|
@ -2740,7 +2820,7 @@ namespace ts {
|
|||
// down-level generator.
|
||||
// Currently we do not support transforming any other generator fucntions
|
||||
// down level.
|
||||
if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
transformFlags |= TransformFlags.AssertGenerator;
|
||||
}
|
||||
|
||||
|
@ -2750,14 +2830,21 @@ namespace ts {
|
|||
|
||||
function computeArrowFunction(node: ArrowFunction, subtreeFlags: TransformFlags) {
|
||||
// An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction.
|
||||
let transformFlags = subtreeFlags | TransformFlags.AssertES6;
|
||||
const modifierFlags = getModifierFlags(node);
|
||||
let transformFlags = subtreeFlags | TransformFlags.AssertES2015;
|
||||
|
||||
// An async arrow function is TypeScript syntax.
|
||||
if (modifierFlags & ModifierFlags.Async) {
|
||||
// TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
|
||||
// syntax.
|
||||
if (hasModifier(node, ModifierFlags.TypeScriptModifier)
|
||||
|| node.typeParameters
|
||||
|| node.type) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
// An async arrow function is ES2017 syntax.
|
||||
if (hasModifier(node, ModifierFlags.Async)) {
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
}
|
||||
|
||||
// If an ArrowFunction contains a lexical this, its container must capture the lexical this.
|
||||
if (subtreeFlags & TransformFlags.ContainsLexicalThis) {
|
||||
transformFlags |= TransformFlags.ContainsCapturedLexicalThis;
|
||||
|
@ -2788,7 +2875,12 @@ namespace ts {
|
|||
|
||||
// A VariableDeclaration with a binding pattern is ES6 syntax.
|
||||
if (nameKind === SyntaxKind.ObjectBindingPattern || nameKind === SyntaxKind.ArrayBindingPattern) {
|
||||
transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsBindingPattern;
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
|
||||
}
|
||||
|
||||
// Type annotations are TypeScript syntax.
|
||||
if (node.type) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
|
@ -2809,11 +2901,11 @@ namespace ts {
|
|||
|
||||
// If a VariableStatement is exported, then it is either ES6 or TypeScript syntax.
|
||||
if (modifierFlags & ModifierFlags.Export) {
|
||||
transformFlags |= TransformFlags.AssertES6 | TransformFlags.AssertTypeScript;
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
if (declarationListTransformFlags & TransformFlags.ContainsBindingPattern) {
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2827,7 +2919,7 @@ namespace ts {
|
|||
// A labeled statement containing a block scoped binding *may* need to be transformed from ES6.
|
||||
if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding
|
||||
&& isIterationStatement(node, /*lookInLabeledStatements*/ true)) {
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
|
@ -2853,7 +2945,7 @@ namespace ts {
|
|||
// then we treat the statement as ES6 so that we can indicate that we do not
|
||||
// need to hold on to the right-hand side.
|
||||
if (node.expression.transformFlags & TransformFlags.DestructuringAssignment) {
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
|
@ -2876,12 +2968,12 @@ namespace ts {
|
|||
let transformFlags = subtreeFlags | TransformFlags.ContainsHoistedDeclarationOrCompletion;
|
||||
|
||||
if (subtreeFlags & TransformFlags.ContainsBindingPattern) {
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
// If a VariableDeclarationList is `let` or `const`, then it is ES6 syntax.
|
||||
if (node.flags & NodeFlags.BlockScoped) {
|
||||
transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsBlockScopedBinding;
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBlockScopedBinding;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
|
@ -2894,14 +2986,18 @@ namespace ts {
|
|||
let excludeFlags = TransformFlags.NodeExcludes;
|
||||
|
||||
switch (kind) {
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
case SyntaxKind.AwaitExpression:
|
||||
// async/await is ES2017 syntax
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
break;
|
||||
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.AwaitExpression:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.EnumMember:
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
|
@ -2926,7 +3022,7 @@ namespace ts {
|
|||
|
||||
case SyntaxKind.ExportKeyword:
|
||||
// This node is both ES6 and TypeScript syntax.
|
||||
transformFlags |= TransformFlags.AssertES6 | TransformFlags.AssertTypeScript;
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertTypeScript;
|
||||
break;
|
||||
|
||||
case SyntaxKind.DefaultKeyword:
|
||||
|
@ -2939,12 +3035,12 @@ namespace ts {
|
|||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
// These nodes are ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
break;
|
||||
|
||||
case SyntaxKind.YieldExpression:
|
||||
// This node is ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsYield;
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsYield;
|
||||
break;
|
||||
|
||||
case SyntaxKind.AnyKeyword:
|
||||
|
@ -3006,7 +3102,7 @@ namespace ts {
|
|||
|
||||
case SyntaxKind.SuperKeyword:
|
||||
// This node is ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ThisKeyword:
|
||||
|
@ -3017,7 +3113,7 @@ namespace ts {
|
|||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
// These nodes are ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsBindingPattern;
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
|
||||
break;
|
||||
|
||||
case SyntaxKind.Decorator:
|
||||
|
@ -3030,7 +3126,7 @@ namespace ts {
|
|||
if (subtreeFlags & TransformFlags.ContainsComputedPropertyName) {
|
||||
// If an ObjectLiteralExpression contains a ComputedPropertyName, then it
|
||||
// is an ES6 node.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) {
|
||||
|
@ -3053,7 +3149,7 @@ namespace ts {
|
|||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
// If the this node contains a SpreadExpression, then it is an ES6
|
||||
// node.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -3064,14 +3160,14 @@ namespace ts {
|
|||
case SyntaxKind.ForInStatement:
|
||||
// A loop containing a block scoped binding *may* need to be transformed from ES6.
|
||||
if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding) {
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.SourceFile:
|
||||
if (subtreeFlags & TransformFlags.ContainsCapturedLexicalThis) {
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -116,6 +116,7 @@ namespace ts {
|
|||
const spreadTypes = createMap<SpreadType>();
|
||||
const stringLiteralTypes = createMap<LiteralType>();
|
||||
const numericLiteralTypes = createMap<LiteralType>();
|
||||
const evolvingArrayTypes: AnonymousType[] = [];
|
||||
|
||||
const unknownSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "unknown");
|
||||
const resolvingSymbol = createSymbol(SymbolFlags.Transient, "__resolving__");
|
||||
|
@ -177,6 +178,7 @@ namespace ts {
|
|||
let globalBooleanType: ObjectType;
|
||||
let globalRegExpType: ObjectType;
|
||||
let anyArrayType: Type;
|
||||
let autoArrayType: Type;
|
||||
let anyReadonlyArrayType: Type;
|
||||
|
||||
// The library files are only loaded when the feature is used.
|
||||
|
@ -367,7 +369,7 @@ namespace ts {
|
|||
return emitResolver;
|
||||
}
|
||||
|
||||
function error(location: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void {
|
||||
function error(location: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): void {
|
||||
const diagnostic = location
|
||||
? createDiagnosticForNode(location, message, arg0, arg1, arg2)
|
||||
: createCompilerDiagnostic(message, arg0, arg1, arg2);
|
||||
|
@ -1053,7 +1055,7 @@ namespace ts {
|
|||
if (node.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
|
||||
return resolveExternalModuleSymbol(resolveExternalModuleName(node, getExternalModuleImportEqualsDeclarationExpression(node)));
|
||||
}
|
||||
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>node.moduleReference, node);
|
||||
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>node.moduleReference);
|
||||
}
|
||||
|
||||
function getTargetOfImportClause(node: ImportClause): Symbol {
|
||||
|
@ -1266,7 +1268,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
// This function is only for imports with entity names
|
||||
function getSymbolOfPartOfRightHandSideOfImportEquals(entityName: EntityName, importDeclaration: ImportEqualsDeclaration, dontResolveAlias?: boolean): Symbol {
|
||||
function getSymbolOfPartOfRightHandSideOfImportEquals(entityName: EntityName, dontResolveAlias?: boolean): Symbol {
|
||||
// There are three things we might try to look for. In the following examples,
|
||||
// the search term is enclosed in |...|:
|
||||
//
|
||||
|
@ -2204,7 +2206,7 @@ namespace ts {
|
|||
writeUnionOrIntersectionType(<UnionOrIntersectionType>type, nextFlags);
|
||||
}
|
||||
else if (type.flags & TypeFlags.Spread) {
|
||||
writeSpreadType(<SpreadType>type, nextFlags);
|
||||
writeSpreadType(<SpreadType>type);
|
||||
}
|
||||
else if (type.flags & TypeFlags.Anonymous) {
|
||||
writeAnonymousType(<ObjectType>type, nextFlags);
|
||||
|
@ -2310,7 +2312,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function writeSpreadType(type: SpreadType, flags: TypeFormatFlags) {
|
||||
function writeSpreadType(type: SpreadType) {
|
||||
writePunctuation(writer, SyntaxKind.OpenBraceToken);
|
||||
writer.writeLine();
|
||||
writer.increaseIndent();
|
||||
|
@ -2629,7 +2631,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: TypeParameter[], mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
|
||||
function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: TypeParameter[], mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node) {
|
||||
if (typeParameters && typeParameters.length) {
|
||||
writePunctuation(writer, SyntaxKind.LessThanToken);
|
||||
let flags = TypeFormatFlags.InFirstTypeArgument;
|
||||
|
@ -3109,9 +3111,14 @@ namespace ts {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
function isAutoVariableInitializer(initializer: Expression) {
|
||||
const expr = initializer && skipParentheses(initializer);
|
||||
return !expr || expr.kind === SyntaxKind.NullKeyword || expr.kind === SyntaxKind.Identifier && getResolvedSymbol(<Identifier>expr) === undefinedSymbol;
|
||||
function isNullOrUndefined(node: Expression) {
|
||||
const expr = skipParentheses(node);
|
||||
return expr.kind === SyntaxKind.NullKeyword || expr.kind === SyntaxKind.Identifier && getResolvedSymbol(<Identifier>expr) === undefinedSymbol;
|
||||
}
|
||||
|
||||
function isEmptyArrayLiteral(node: Expression) {
|
||||
const expr = skipParentheses(node);
|
||||
return expr.kind === SyntaxKind.ArrayLiteralExpression && (<ArrayLiteralExpression>expr).elements.length === 0;
|
||||
}
|
||||
|
||||
function addOptionality(type: Type, optional: boolean): Type {
|
||||
|
@ -3152,12 +3159,18 @@ namespace ts {
|
|||
return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality);
|
||||
}
|
||||
|
||||
// Use control flow type inference for non-ambient, non-exported var or let variables with no initializer
|
||||
// or a 'null' or 'undefined' initializer.
|
||||
if (declaration.kind === SyntaxKind.VariableDeclaration && !isBindingPattern(declaration.name) &&
|
||||
!(getCombinedNodeFlags(declaration) & NodeFlags.Const) && !(getCombinedModifierFlags(declaration) & ModifierFlags.Export) &&
|
||||
!isInAmbientContext(declaration) && isAutoVariableInitializer(declaration.initializer)) {
|
||||
return autoType;
|
||||
!(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && !isInAmbientContext(declaration)) {
|
||||
// Use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no
|
||||
// initializer or a 'null' or 'undefined' initializer.
|
||||
if (!(getCombinedNodeFlags(declaration) & NodeFlags.Const) && (!declaration.initializer || isNullOrUndefined(declaration.initializer))) {
|
||||
return autoType;
|
||||
}
|
||||
// Use control flow tracked 'any[]' type for non-ambient, non-exported variables with an empty array
|
||||
// literal initializer.
|
||||
if (declaration.initializer && isEmptyArrayLiteral(declaration.initializer)) {
|
||||
return autoArrayType;
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration.kind === SyntaxKind.Parameter) {
|
||||
|
@ -3179,8 +3192,7 @@ namespace ts {
|
|||
// Use contextual parameter type if one is available
|
||||
let type: Type;
|
||||
if (declaration.symbol.name === "this") {
|
||||
const thisParameter = getContextualThisParameter(func);
|
||||
type = thisParameter ? getTypeOfSymbol(thisParameter) : undefined;
|
||||
type = getContextualThisParameterType(func);
|
||||
}
|
||||
else {
|
||||
type = getContextuallyTypedParameterType(<ParameterDeclaration>declaration);
|
||||
|
@ -3260,7 +3272,7 @@ namespace ts {
|
|||
const elements = pattern.elements;
|
||||
const lastElement = lastOrUndefined(elements);
|
||||
if (elements.length === 0 || (!isOmittedExpression(lastElement) && lastElement.dotDotDotToken)) {
|
||||
return languageVersion >= ScriptTarget.ES6 ? createIterableType(anyType) : anyArrayType;
|
||||
return languageVersion >= ScriptTarget.ES2015 ? createIterableType(anyType) : anyArrayType;
|
||||
}
|
||||
// If the pattern has at least one element, and no rest element, then it should imply a tuple type.
|
||||
const elementTypes = map(elements, e => isOmittedExpression(e) ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors));
|
||||
|
@ -4856,9 +4868,6 @@ namespace ts {
|
|||
if (isJSConstructSignature) {
|
||||
minArgumentCount--;
|
||||
}
|
||||
if (!thisParameter && isObjectLiteralMethod(declaration)) {
|
||||
thisParameter = getContextualThisParameter(declaration);
|
||||
}
|
||||
|
||||
const classType = declaration.kind === SyntaxKind.Constructor ?
|
||||
getDeclaredTypeOfClassOrInterface(getMergedSymbol((<ClassDeclaration>declaration.parent).symbol))
|
||||
|
@ -4866,7 +4875,7 @@ namespace ts {
|
|||
const typeParameters = classType ? classType.localTypeParameters :
|
||||
declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) :
|
||||
getTypeParametersFromJSDocTemplate(declaration);
|
||||
const returnType = getSignatureReturnTypeFromDeclaration(declaration, minArgumentCount, isJSConstructSignature, classType);
|
||||
const returnType = getSignatureReturnTypeFromDeclaration(declaration, isJSConstructSignature, classType);
|
||||
const typePredicate = declaration.type && declaration.type.kind === SyntaxKind.TypePredicate ?
|
||||
createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode) :
|
||||
undefined;
|
||||
|
@ -4876,7 +4885,7 @@ namespace ts {
|
|||
return links.resolvedSignature;
|
||||
}
|
||||
|
||||
function getSignatureReturnTypeFromDeclaration(declaration: SignatureDeclaration, minArgumentCount: number, isJSConstructSignature: boolean, classType: Type) {
|
||||
function getSignatureReturnTypeFromDeclaration(declaration: SignatureDeclaration, isJSConstructSignature: boolean, classType: Type) {
|
||||
if (isJSConstructSignature) {
|
||||
return getTypeFromTypeNode(declaration.parameters[0].type);
|
||||
}
|
||||
|
@ -5241,10 +5250,7 @@ namespace ts {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
function resolveTypeReferenceName(
|
||||
node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference,
|
||||
typeReferenceName: EntityNameExpression | EntityName) {
|
||||
|
||||
function resolveTypeReferenceName(typeReferenceName: EntityNameExpression | EntityName) {
|
||||
if (!typeReferenceName) {
|
||||
return unknownSymbol;
|
||||
}
|
||||
|
@ -5282,7 +5288,7 @@ namespace ts {
|
|||
let type: Type;
|
||||
if (node.kind === SyntaxKind.JSDocTypeReference) {
|
||||
const typeReferenceName = getTypeReferenceName(node);
|
||||
symbol = resolveTypeReferenceName(node, typeReferenceName);
|
||||
symbol = resolveTypeReferenceName(typeReferenceName);
|
||||
type = getTypeReferenceType(node, symbol);
|
||||
}
|
||||
else {
|
||||
|
@ -6353,9 +6359,24 @@ namespace ts {
|
|||
}
|
||||
|
||||
function isContextSensitiveFunctionLikeDeclaration(node: FunctionLikeDeclaration) {
|
||||
const areAllParametersUntyped = !forEach(node.parameters, p => p.type);
|
||||
const isNullaryArrow = node.kind === SyntaxKind.ArrowFunction && !node.parameters.length;
|
||||
return !node.typeParameters && areAllParametersUntyped && !isNullaryArrow;
|
||||
// Functions with type parameters are not context sensitive.
|
||||
if (node.typeParameters) {
|
||||
return false;
|
||||
}
|
||||
// Functions with any parameters that lack type annotations are context sensitive.
|
||||
if (forEach(node.parameters, p => !p.type)) {
|
||||
return true;
|
||||
}
|
||||
// For arrow functions we now know we're not context sensitive.
|
||||
if (node.kind === SyntaxKind.ArrowFunction) {
|
||||
return false;
|
||||
}
|
||||
// If the first parameter is not an explicit 'this' parameter, then the function has
|
||||
// an implicit 'this' parameter which is subject to contextual typing. Otherwise we
|
||||
// know that all parameters (including 'this') have type annotations and nothing is
|
||||
// subject to contextual typing.
|
||||
const parameter = firstOrUndefined(node.parameters);
|
||||
return !(parameter && parameterIsThisKeyword(parameter));
|
||||
}
|
||||
|
||||
function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration {
|
||||
|
@ -6961,8 +6982,8 @@ namespace ts {
|
|||
}
|
||||
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union ||
|
||||
source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
|
||||
if (result = eachTypeRelatedToSomeType(<UnionOrIntersectionType>source, <UnionOrIntersectionType>target, /*reportErrors*/ false)) {
|
||||
if (result &= eachTypeRelatedToSomeType(<UnionOrIntersectionType>target, <UnionOrIntersectionType>source, /*reportErrors*/ false)) {
|
||||
if (result = eachTypeRelatedToSomeType(<UnionOrIntersectionType>source, <UnionOrIntersectionType>target)) {
|
||||
if (result &= eachTypeRelatedToSomeType(<UnionOrIntersectionType>target, <UnionOrIntersectionType>source)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -7023,7 +7044,7 @@ namespace ts {
|
|||
return false;
|
||||
}
|
||||
|
||||
function eachTypeRelatedToSomeType(source: UnionOrIntersectionType, target: UnionOrIntersectionType, reportErrors: boolean): Ternary {
|
||||
function eachTypeRelatedToSomeType(source: UnionOrIntersectionType, target: UnionOrIntersectionType): Ternary {
|
||||
let result = Ternary.True;
|
||||
const sourceTypes = source.types;
|
||||
for (const sourceType of sourceTypes) {
|
||||
|
@ -7735,7 +7756,7 @@ namespace ts {
|
|||
type.flags & TypeFlags.NumberLiteral ? numberType :
|
||||
type.flags & TypeFlags.BooleanLiteral ? booleanType :
|
||||
type.flags & TypeFlags.EnumLiteral ? (<EnumLiteralType>type).baseType :
|
||||
type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(map((<UnionType>type).types, getBaseTypeOfLiteralType)) :
|
||||
type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(sameMap((<UnionType>type).types, getBaseTypeOfLiteralType)) :
|
||||
type;
|
||||
}
|
||||
|
||||
|
@ -7744,7 +7765,7 @@ namespace ts {
|
|||
type.flags & TypeFlags.NumberLiteral && type.flags & TypeFlags.FreshLiteral ? numberType :
|
||||
type.flags & TypeFlags.BooleanLiteral ? booleanType :
|
||||
type.flags & TypeFlags.EnumLiteral ? (<EnumLiteralType>type).baseType :
|
||||
type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(map((<UnionType>type).types, getWidenedLiteralType)) :
|
||||
type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(sameMap((<UnionType>type).types, getWidenedLiteralType)) :
|
||||
type;
|
||||
}
|
||||
|
||||
|
@ -7883,10 +7904,10 @@ namespace ts {
|
|||
return getWidenedTypeOfObjectLiteral(type);
|
||||
}
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
return getUnionType(map((<UnionType>type).types, getWidenedConstituentType));
|
||||
return getUnionType(sameMap((<UnionType>type).types, getWidenedConstituentType));
|
||||
}
|
||||
if (isArrayType(type) || isTupleType(type)) {
|
||||
return createTypeReference((<TypeReference>type).target, map((<TypeReference>type).typeArguments, getWidenedType));
|
||||
return createTypeReference((<TypeReference>type).target, sameMap((<TypeReference>type).typeArguments, getWidenedType));
|
||||
}
|
||||
}
|
||||
return type;
|
||||
|
@ -8346,7 +8367,7 @@ namespace ts {
|
|||
const widenLiteralTypes = context.inferences[index].topLevel &&
|
||||
!hasPrimitiveConstraint(signature.typeParameters[index]) &&
|
||||
(context.inferences[index].isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), signature.typeParameters[index]));
|
||||
const baseInferences = widenLiteralTypes ? map(inferences, getWidenedLiteralType) : inferences;
|
||||
const baseInferences = widenLiteralTypes ? sameMap(inferences, getWidenedLiteralType) : inferences;
|
||||
// Infer widened union or supertype, or the unknown type for no common supertype
|
||||
const unionOrSuperType = context.inferUnionTypes ? getUnionType(baseInferences, /*subtypeReduction*/ true) : getCommonSupertype(baseInferences);
|
||||
inferredType = unionOrSuperType ? getWidenedType(unionOrSuperType) : unknownType;
|
||||
|
@ -8749,6 +8770,13 @@ namespace ts {
|
|||
getAssignedType(<Expression>node);
|
||||
}
|
||||
|
||||
function isEmptyArrayAssignment(node: VariableDeclaration | BindingElement | Expression) {
|
||||
return node.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>node).initializer &&
|
||||
isEmptyArrayLiteral((<VariableDeclaration>node).initializer) ||
|
||||
node.kind !== SyntaxKind.BindingElement && node.parent.kind === SyntaxKind.BinaryExpression &&
|
||||
isEmptyArrayLiteral((<BinaryExpression>node.parent).right);
|
||||
}
|
||||
|
||||
function getReferenceCandidate(node: Expression): Expression {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
|
@ -8764,6 +8792,14 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
function getReferenceRoot(node: Node): Node {
|
||||
const parent = node.parent;
|
||||
return parent.kind === SyntaxKind.ParenthesizedExpression ||
|
||||
parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>parent).operatorToken.kind === SyntaxKind.EqualsToken && (<BinaryExpression>parent).left === node ||
|
||||
parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>parent).operatorToken.kind === SyntaxKind.CommaToken && (<BinaryExpression>parent).right === node ?
|
||||
getReferenceRoot(parent) : node;
|
||||
}
|
||||
|
||||
function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) {
|
||||
if (clause.kind === SyntaxKind.CaseClause) {
|
||||
const caseType = getRegularTypeOfLiteralType(checkExpression((<CaseClause>clause).expression));
|
||||
|
@ -8849,21 +8885,113 @@ namespace ts {
|
|||
return incomplete ? { flags: 0, type } : type;
|
||||
}
|
||||
|
||||
// An evolving array type tracks the element types that have so far been seen in an
|
||||
// 'x.push(value)' or 'x[n] = value' operation along the control flow graph. Evolving
|
||||
// array types are ultimately converted into manifest array types (using getFinalArrayType)
|
||||
// and never escape the getFlowTypeOfReference function.
|
||||
function createEvolvingArrayType(elementType: Type): AnonymousType {
|
||||
const result = <AnonymousType>createObjectType(TypeFlags.Anonymous);
|
||||
result.elementType = elementType;
|
||||
return result;
|
||||
}
|
||||
|
||||
function getEvolvingArrayType(elementType: Type): AnonymousType {
|
||||
return evolvingArrayTypes[elementType.id] || (evolvingArrayTypes[elementType.id] = createEvolvingArrayType(elementType));
|
||||
}
|
||||
|
||||
// When adding evolving array element types we do not perform subtype reduction. Instead,
|
||||
// we defer subtype reduction until the evolving array type is finalized into a manifest
|
||||
// array type.
|
||||
function addEvolvingArrayElementType(evolvingArrayType: AnonymousType, node: Expression): AnonymousType {
|
||||
const elementType = getBaseTypeOfLiteralType(checkExpression(node));
|
||||
return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType]));
|
||||
}
|
||||
|
||||
function isEvolvingArrayType(type: Type) {
|
||||
return !!(type.flags & TypeFlags.Anonymous && (<AnonymousType>type).elementType);
|
||||
}
|
||||
|
||||
function createFinalArrayType(elementType: Type) {
|
||||
return elementType.flags & TypeFlags.Never ?
|
||||
autoArrayType :
|
||||
createArrayType(elementType.flags & TypeFlags.Union ?
|
||||
getUnionType((<UnionType>elementType).types, /*subtypeReduction*/ true) :
|
||||
elementType);
|
||||
}
|
||||
|
||||
// We perform subtype reduction upon obtaining the final array type from an evolving array type.
|
||||
function getFinalArrayType(evolvingArrayType: AnonymousType): Type {
|
||||
return evolvingArrayType.finalArrayType || (evolvingArrayType.finalArrayType = createFinalArrayType(evolvingArrayType.elementType));
|
||||
}
|
||||
|
||||
function finalizeEvolvingArrayType(type: Type): Type {
|
||||
return isEvolvingArrayType(type) ? getFinalArrayType(<AnonymousType>type) : type;
|
||||
}
|
||||
|
||||
function getElementTypeOfEvolvingArrayType(type: Type) {
|
||||
return isEvolvingArrayType(type) ? (<AnonymousType>type).elementType : neverType;
|
||||
}
|
||||
|
||||
function isEvolvingArrayTypeList(types: Type[]) {
|
||||
let hasEvolvingArrayType = false;
|
||||
for (const t of types) {
|
||||
if (!(t.flags & TypeFlags.Never)) {
|
||||
if (!isEvolvingArrayType(t)) {
|
||||
return false;
|
||||
}
|
||||
hasEvolvingArrayType = true;
|
||||
}
|
||||
}
|
||||
return hasEvolvingArrayType;
|
||||
}
|
||||
|
||||
// At flow control branch or loop junctions, if the type along every antecedent code path
|
||||
// is an evolving array type, we construct a combined evolving array type. Otherwise we
|
||||
// finalize all evolving array types.
|
||||
function getUnionOrEvolvingArrayType(types: Type[], subtypeReduction: boolean) {
|
||||
return isEvolvingArrayTypeList(types) ?
|
||||
getEvolvingArrayType(getUnionType(map(types, getElementTypeOfEvolvingArrayType))) :
|
||||
getUnionType(sameMap(types, finalizeEvolvingArrayType), subtypeReduction);
|
||||
}
|
||||
|
||||
// Return true if the given node is 'x' in an 'x.length', x.push(value)', 'x.unshift(value)' or
|
||||
// 'x[n] = value' operation, where 'n' is an expression of type any, undefined, or a number-like type.
|
||||
function isEvolvingArrayOperationTarget(node: Node) {
|
||||
const root = getReferenceRoot(node);
|
||||
const parent = root.parent;
|
||||
const isLengthPushOrUnshift = parent.kind === SyntaxKind.PropertyAccessExpression && (
|
||||
(<PropertyAccessExpression>parent).name.text === "length" ||
|
||||
parent.parent.kind === SyntaxKind.CallExpression && isPushOrUnshiftIdentifier((<PropertyAccessExpression>parent).name));
|
||||
const isElementAssignment = parent.kind === SyntaxKind.ElementAccessExpression &&
|
||||
(<ElementAccessExpression>parent).expression === root &&
|
||||
parent.parent.kind === SyntaxKind.BinaryExpression &&
|
||||
(<BinaryExpression>parent.parent).operatorToken.kind === SyntaxKind.EqualsToken &&
|
||||
(<BinaryExpression>parent.parent).left === parent &&
|
||||
!isAssignmentTarget(parent.parent) &&
|
||||
isTypeAnyOrAllConstituentTypesHaveKind(checkExpression((<ElementAccessExpression>parent).argumentExpression), TypeFlags.NumberLike | TypeFlags.Undefined);
|
||||
return isLengthPushOrUnshift || isElementAssignment;
|
||||
}
|
||||
|
||||
function getFlowTypeOfReference(reference: Node, declaredType: Type, assumeInitialized: boolean, flowContainer: Node) {
|
||||
let key: string;
|
||||
if (!reference.flowNode || assumeInitialized && !(declaredType.flags & TypeFlags.Narrowable)) {
|
||||
return declaredType;
|
||||
}
|
||||
const initialType = assumeInitialized ? declaredType :
|
||||
declaredType === autoType ? undefinedType :
|
||||
declaredType === autoType || declaredType === autoArrayType ? undefinedType :
|
||||
includeFalsyTypes(declaredType, TypeFlags.Undefined);
|
||||
const visitedFlowStart = visitedFlowCount;
|
||||
const result = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
|
||||
const evolvedType = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
|
||||
visitedFlowCount = visitedFlowStart;
|
||||
if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(result, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) {
|
||||
// When the reference is 'x' in an 'x.length', 'x.push(value)', 'x.unshift(value)' or x[n] = value' operation,
|
||||
// we give type 'any[]' to 'x' instead of using the type determined by control flow analysis such that operations
|
||||
// on empty arrays are possible without implicit any errors and new element types can be inferred without
|
||||
// type mismatch errors.
|
||||
const resultType = isEvolvingArrayType(evolvedType) && isEvolvingArrayOperationTarget(reference) ? anyArrayType : finalizeEvolvingArrayType(evolvedType);
|
||||
if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) {
|
||||
return declaredType;
|
||||
}
|
||||
return result;
|
||||
return resultType;
|
||||
|
||||
function getTypeAtFlowNode(flow: FlowNode): FlowType {
|
||||
while (true) {
|
||||
|
@ -8900,6 +9028,13 @@ namespace ts {
|
|||
getTypeAtFlowBranchLabel(<FlowLabel>flow) :
|
||||
getTypeAtFlowLoopLabel(<FlowLabel>flow);
|
||||
}
|
||||
else if (flow.flags & FlowFlags.ArrayMutation) {
|
||||
type = getTypeAtFlowArrayMutation(<FlowArrayMutation>flow);
|
||||
if (!type) {
|
||||
flow = (<FlowArrayMutation>flow).antecedent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (flow.flags & FlowFlags.Start) {
|
||||
// Check if we should continue with the control flow of the containing function.
|
||||
const container = (<FlowStart>flow).container;
|
||||
|
@ -8912,8 +9047,8 @@ namespace ts {
|
|||
}
|
||||
else {
|
||||
// Unreachable code errors are reported in the binding phase. Here we
|
||||
// simply return the declared type to reduce follow-on errors.
|
||||
type = declaredType;
|
||||
// simply return the non-auto declared type to reduce follow-on errors.
|
||||
type = convertAutoToAny(declaredType);
|
||||
}
|
||||
if (flow.flags & FlowFlags.Shared) {
|
||||
// Record visited node and the associated type in the cache.
|
||||
|
@ -8934,9 +9069,17 @@ namespace ts {
|
|||
const flowType = getTypeAtFlowNode(flow.antecedent);
|
||||
return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType));
|
||||
}
|
||||
return declaredType === autoType ? getBaseTypeOfLiteralType(getInitialOrAssignedType(node)) :
|
||||
declaredType.flags & TypeFlags.Union ? getAssignmentReducedType(<UnionType>declaredType, getInitialOrAssignedType(node)) :
|
||||
declaredType;
|
||||
if (declaredType === autoType || declaredType === autoArrayType) {
|
||||
if (isEmptyArrayAssignment(node)) {
|
||||
return getEvolvingArrayType(neverType);
|
||||
}
|
||||
const assignedType = getBaseTypeOfLiteralType(getInitialOrAssignedType(node));
|
||||
return isTypeAssignableTo(assignedType, declaredType) ? assignedType : anyArrayType;
|
||||
}
|
||||
if (declaredType.flags & TypeFlags.Union) {
|
||||
return getAssignmentReducedType(<UnionType>declaredType, getInitialOrAssignedType(node));
|
||||
}
|
||||
return declaredType;
|
||||
}
|
||||
// We didn't have a direct match. However, if the reference is a dotted name, this
|
||||
// may be an assignment to a left hand part of the reference. For example, for a
|
||||
|
@ -8949,24 +9092,56 @@ namespace ts {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
function getTypeAtFlowArrayMutation(flow: FlowArrayMutation): FlowType {
|
||||
const node = flow.node;
|
||||
const expr = node.kind === SyntaxKind.CallExpression ?
|
||||
(<PropertyAccessExpression>(<CallExpression>node).expression).expression :
|
||||
(<ElementAccessExpression>(<BinaryExpression>node).left).expression;
|
||||
if (isMatchingReference(reference, getReferenceCandidate(expr))) {
|
||||
const flowType = getTypeAtFlowNode(flow.antecedent);
|
||||
const type = getTypeFromFlowType(flowType);
|
||||
if (isEvolvingArrayType(type)) {
|
||||
let evolvedType = <AnonymousType>type;
|
||||
if (node.kind === SyntaxKind.CallExpression) {
|
||||
for (const arg of (<CallExpression>node).arguments) {
|
||||
evolvedType = addEvolvingArrayElementType(evolvedType, arg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const indexType = checkExpression((<ElementAccessExpression>(<BinaryExpression>node).left).argumentExpression);
|
||||
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike | TypeFlags.Undefined)) {
|
||||
evolvedType = addEvolvingArrayElementType(evolvedType, (<BinaryExpression>node).right);
|
||||
}
|
||||
}
|
||||
return evolvedType === type ? flowType : createFlowType(evolvedType, isIncomplete(flowType));
|
||||
}
|
||||
return flowType;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getTypeAtFlowCondition(flow: FlowCondition): FlowType {
|
||||
const flowType = getTypeAtFlowNode(flow.antecedent);
|
||||
let type = getTypeFromFlowType(flowType);
|
||||
if (!(type.flags & TypeFlags.Never)) {
|
||||
// If we have an antecedent type (meaning we're reachable in some way), we first
|
||||
// attempt to narrow the antecedent type. If that produces the never type, and if
|
||||
// the antecedent type is incomplete (i.e. a transient type in a loop), then we
|
||||
// take the type guard as an indication that control *could* reach here once we
|
||||
// have the complete type. We proceed by switching to the silent never type which
|
||||
// doesn't report errors when operators are applied to it. Note that this is the
|
||||
// *only* place a silent never type is ever generated.
|
||||
const assumeTrue = (flow.flags & FlowFlags.TrueCondition) !== 0;
|
||||
type = narrowType(type, flow.expression, assumeTrue);
|
||||
if (type.flags & TypeFlags.Never && isIncomplete(flowType)) {
|
||||
type = silentNeverType;
|
||||
}
|
||||
const type = getTypeFromFlowType(flowType);
|
||||
if (type.flags & TypeFlags.Never) {
|
||||
return flowType;
|
||||
}
|
||||
return createFlowType(type, isIncomplete(flowType));
|
||||
// If we have an antecedent type (meaning we're reachable in some way), we first
|
||||
// attempt to narrow the antecedent type. If that produces the never type, and if
|
||||
// the antecedent type is incomplete (i.e. a transient type in a loop), then we
|
||||
// take the type guard as an indication that control *could* reach here once we
|
||||
// have the complete type. We proceed by switching to the silent never type which
|
||||
// doesn't report errors when operators are applied to it. Note that this is the
|
||||
// *only* place a silent never type is ever generated.
|
||||
const assumeTrue = (flow.flags & FlowFlags.TrueCondition) !== 0;
|
||||
const nonEvolvingType = finalizeEvolvingArrayType(type);
|
||||
const narrowedType = narrowType(nonEvolvingType, flow.expression, assumeTrue);
|
||||
if (narrowedType === nonEvolvingType) {
|
||||
return flowType;
|
||||
}
|
||||
const incomplete = isIncomplete(flowType);
|
||||
const resultType = incomplete && narrowedType.flags & TypeFlags.Never ? silentNeverType : narrowedType;
|
||||
return createFlowType(resultType, incomplete);
|
||||
}
|
||||
|
||||
function getTypeAtSwitchClause(flow: FlowSwitchClause): FlowType {
|
||||
|
@ -9009,7 +9184,7 @@ namespace ts {
|
|||
seenIncomplete = true;
|
||||
}
|
||||
}
|
||||
return createFlowType(getUnionType(antecedentTypes, subtypeReduction), seenIncomplete);
|
||||
return createFlowType(getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction), seenIncomplete);
|
||||
}
|
||||
|
||||
function getTypeAtFlowLoopLabel(flow: FlowLabel): FlowType {
|
||||
|
@ -9025,11 +9200,15 @@ namespace ts {
|
|||
}
|
||||
// If this flow loop junction and reference are already being processed, return
|
||||
// the union of the types computed for each branch so far, marked as incomplete.
|
||||
// We should never see an empty array here because the first antecedent of a loop
|
||||
// junction is always the non-looping control flow path that leads to the top.
|
||||
// It is possible to see an empty array in cases where loops are nested and the
|
||||
// back edge of the outer loop reaches an inner loop that is already being analyzed.
|
||||
// In such cases we restart the analysis of the inner loop, which will then see
|
||||
// a non-empty in-process array for the outer loop and eventually terminate because
|
||||
// the first antecedent of a loop junction is always the non-looping control flow
|
||||
// path that leads to the top.
|
||||
for (let i = flowLoopStart; i < flowLoopCount; i++) {
|
||||
if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key) {
|
||||
return createFlowType(getUnionType(flowLoopTypes[i]), /*incomplete*/ true);
|
||||
if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key && flowLoopTypes[i].length) {
|
||||
return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], /*subtypeReduction*/ false), /*incomplete*/ true);
|
||||
}
|
||||
}
|
||||
// Add the flow loop junction and reference to the in-process stack and analyze
|
||||
|
@ -9072,7 +9251,7 @@ namespace ts {
|
|||
}
|
||||
// The result is incomplete if the first antecedent (the non-looping control flow path)
|
||||
// is incomplete.
|
||||
const result = getUnionType(antecedentTypes, subtypeReduction);
|
||||
const result = getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction);
|
||||
if (isIncomplete(firstAntecedentType)) {
|
||||
return createFlowType(result, /*incomplete*/ true);
|
||||
}
|
||||
|
@ -9454,6 +9633,10 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function isConstVariable(symbol: Symbol) {
|
||||
return symbol.flags & SymbolFlags.Variable && (getDeclarationNodeFlagsFromSymbol(symbol) & NodeFlags.Const) !== 0 && getTypeOfSymbol(symbol) !== autoArrayType;
|
||||
}
|
||||
|
||||
function checkIdentifier(node: Identifier): Type {
|
||||
const symbol = getResolvedSymbol(node);
|
||||
|
||||
|
@ -9465,7 +9648,7 @@ namespace ts {
|
|||
// can explicitly bound arguments objects
|
||||
if (symbol === argumentsSymbol) {
|
||||
const container = getContainingFunction(node);
|
||||
if (languageVersion < ScriptTarget.ES6) {
|
||||
if (languageVersion < ScriptTarget.ES2015) {
|
||||
if (container.kind === SyntaxKind.ArrowFunction) {
|
||||
error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression);
|
||||
}
|
||||
|
@ -9490,7 +9673,7 @@ namespace ts {
|
|||
// Due to the emit for class decorators, any reference to the class from inside of the class body
|
||||
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
|
||||
// behavior of class names in ES6.
|
||||
if (languageVersion === ScriptTarget.ES6
|
||||
if (languageVersion === ScriptTarget.ES2015
|
||||
&& declaration.kind === SyntaxKind.ClassDeclaration
|
||||
&& nodeIsDecorated(declaration)) {
|
||||
let container = getContainingClass(node);
|
||||
|
@ -9544,30 +9727,28 @@ namespace ts {
|
|||
// When the control flow originates in a function expression or arrow function and we are referencing
|
||||
// a const variable or parameter from an outer function, we extend the origin of the control flow
|
||||
// analysis to include the immediately enclosing function.
|
||||
while (flowContainer !== declarationContainer &&
|
||||
(flowContainer.kind === SyntaxKind.FunctionExpression ||
|
||||
flowContainer.kind === SyntaxKind.ArrowFunction ||
|
||||
isObjectLiteralOrClassExpressionMethod(flowContainer)) &&
|
||||
(isReadonlySymbol(localOrExportSymbol) || isParameter && !isParameterAssigned(localOrExportSymbol))) {
|
||||
while (flowContainer !== declarationContainer && (flowContainer.kind === SyntaxKind.FunctionExpression ||
|
||||
flowContainer.kind === SyntaxKind.ArrowFunction || isObjectLiteralOrClassExpressionMethod(flowContainer)) &&
|
||||
(isConstVariable(localOrExportSymbol) || isParameter && !isParameterAssigned(localOrExportSymbol))) {
|
||||
flowContainer = getControlFlowContainer(flowContainer);
|
||||
}
|
||||
// We only look for uninitialized variables in strict null checking mode, and only when we can analyze
|
||||
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
|
||||
// declaration container are the same).
|
||||
const assumeInitialized = isParameter || isOuterVariable ||
|
||||
type !== autoType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0) ||
|
||||
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0) ||
|
||||
isInAmbientContext(declaration);
|
||||
const flowType = getFlowTypeOfReference(node, type, assumeInitialized, flowContainer);
|
||||
// A variable is considered uninitialized when it is possible to analyze the entire control flow graph
|
||||
// from declaration to use, and when the variable's declared type doesn't include undefined but the
|
||||
// control flow based type does include undefined.
|
||||
if (type === autoType) {
|
||||
if (flowType === autoType) {
|
||||
if (type === autoType || type === autoArrayType) {
|
||||
if (flowType === autoType || flowType === autoArrayType) {
|
||||
if (compilerOptions.noImplicitAny) {
|
||||
error(declaration.name, Diagnostics.Variable_0_implicitly_has_type_any_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol));
|
||||
error(node, Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(anyType));
|
||||
error(declaration.name, Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(flowType));
|
||||
error(node, Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType));
|
||||
}
|
||||
return anyType;
|
||||
return convertAutoToAny(flowType);
|
||||
}
|
||||
}
|
||||
else if (!assumeInitialized && !(getFalsyFlags(type) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
|
||||
|
@ -9591,7 +9772,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkNestedBlockScopedBinding(node: Identifier, symbol: Symbol): void {
|
||||
if (languageVersion >= ScriptTarget.ES6 ||
|
||||
if (languageVersion >= ScriptTarget.ES2015 ||
|
||||
(symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.Class)) === 0 ||
|
||||
symbol.valueDeclaration.parent.kind === SyntaxKind.CatchClause) {
|
||||
return;
|
||||
|
@ -9757,7 +9938,7 @@ namespace ts {
|
|||
container = getThisContainer(container, /* includeArrowFunctions */ false);
|
||||
|
||||
// When targeting es6, arrow function lexically bind "this" so we do not need to do the work of binding "this" in emitted code
|
||||
needToCaptureLexicalThis = (languageVersion < ScriptTarget.ES6);
|
||||
needToCaptureLexicalThis = (languageVersion < ScriptTarget.ES2015);
|
||||
}
|
||||
|
||||
switch (container.kind) {
|
||||
|
@ -9810,7 +9991,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
const thisType = getThisTypeOfDeclaration(container);
|
||||
const thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container);
|
||||
if (thisType) {
|
||||
return thisType;
|
||||
}
|
||||
|
@ -9865,7 +10046,7 @@ namespace ts {
|
|||
if (!isCallExpression) {
|
||||
while (container && container.kind === SyntaxKind.ArrowFunction) {
|
||||
container = getSuperContainer(container, /*stopOnFunctions*/ true);
|
||||
needToCaptureLexicalThis = languageVersion < ScriptTarget.ES6;
|
||||
needToCaptureLexicalThis = languageVersion < ScriptTarget.ES2015;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9979,7 +10160,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
if (container.parent.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
if (languageVersion < ScriptTarget.ES6) {
|
||||
if (languageVersion < ScriptTarget.ES2015) {
|
||||
error(node, Diagnostics.super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher);
|
||||
return unknownType;
|
||||
}
|
||||
|
@ -10050,14 +10231,16 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function getContextualThisParameter(func: FunctionLikeDeclaration): Symbol {
|
||||
function getContextualThisParameterType(func: FunctionLikeDeclaration): Type {
|
||||
if (isContextSensitiveFunctionOrObjectLiteralMethod(func) && func.kind !== SyntaxKind.ArrowFunction) {
|
||||
const contextualSignature = getContextualSignature(func);
|
||||
if (contextualSignature) {
|
||||
return contextualSignature.thisParameter;
|
||||
const thisParameter = contextualSignature.thisParameter;
|
||||
if (thisParameter) {
|
||||
return getTypeOfSymbol(thisParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
@ -10347,7 +10530,7 @@ namespace ts {
|
|||
const index = indexOf(arrayLiteral.elements, node);
|
||||
return getTypeOfPropertyOfContextualType(type, "" + index)
|
||||
|| getIndexTypeOfContextualType(type, IndexKind.Number)
|
||||
|| (languageVersion >= ScriptTarget.ES6 ? getElementTypeOfIterable(type, /*errorNode*/ undefined) : undefined);
|
||||
|| (languageVersion >= ScriptTarget.ES2015 ? getElementTypeOfIterable(type, /*errorNode*/ undefined) : undefined);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
@ -10580,7 +10763,7 @@ namespace ts {
|
|||
// if there is no index type / iterated type.
|
||||
const restArrayType = checkExpression((<SpreadExpression>e).expression, contextualMapper);
|
||||
const restElementType = getIndexTypeOfType(restArrayType, IndexKind.Number) ||
|
||||
(languageVersion >= ScriptTarget.ES6 ? getElementTypeOfIterable(restArrayType, /*errorNode*/ undefined) : undefined);
|
||||
(languageVersion >= ScriptTarget.ES2015 ? getElementTypeOfIterable(restArrayType, /*errorNode*/ undefined) : undefined);
|
||||
if (restElementType) {
|
||||
elementTypes.push(restElementType);
|
||||
}
|
||||
|
@ -11038,7 +11221,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
return getUnionType(signatures.map(getReturnTypeOfSignature), /*subtypeReduction*/ true);
|
||||
return getUnionType(map(signatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
|
||||
}
|
||||
|
||||
/// e.g. "props" for React.d.ts,
|
||||
|
@ -11088,7 +11271,7 @@ namespace ts {
|
|||
}
|
||||
if (elemType.flags & TypeFlags.Union) {
|
||||
const types = (<UnionOrIntersectionType>elemType).types;
|
||||
return getUnionType(types.map(type => {
|
||||
return getUnionType(map(types, type => {
|
||||
return getResolvedJsxType(node, type, elemClassType);
|
||||
}), /*subtypeReduction*/ true);
|
||||
}
|
||||
|
@ -11354,7 +11537,7 @@ namespace ts {
|
|||
// - In a static member function or static member accessor
|
||||
// where this references the constructor function object of a derived class,
|
||||
// a super property access is permitted and must specify a public static member function of the base class.
|
||||
if (languageVersion < ScriptTarget.ES6 && getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) {
|
||||
if (languageVersion < ScriptTarget.ES2015 && getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) {
|
||||
// `prop` refers to a *property* declared in the super class
|
||||
// rather than a *method*, so it does not satisfy the above criteria.
|
||||
|
||||
|
@ -11967,7 +12150,7 @@ namespace ts {
|
|||
// If the effective argument is 'undefined', then it is an argument that is present but is synthetic.
|
||||
if (arg === undefined || arg.kind !== SyntaxKind.OmittedExpression) {
|
||||
const paramType = getTypeAtPosition(signature, i);
|
||||
let argType = getEffectiveArgumentType(node, i, arg);
|
||||
let argType = getEffectiveArgumentType(node, i);
|
||||
|
||||
// If the effective argument type is 'undefined', there is no synthetic type
|
||||
// for the argument. In that case, we should check the argument.
|
||||
|
@ -12053,7 +12236,7 @@ namespace ts {
|
|||
if (arg === undefined || arg.kind !== SyntaxKind.OmittedExpression) {
|
||||
// Check spread elements against rest type (from arity check we know spread argument corresponds to a rest parameter)
|
||||
const paramType = getTypeAtPosition(signature, i);
|
||||
let argType = getEffectiveArgumentType(node, i, arg);
|
||||
let argType = getEffectiveArgumentType(node, i);
|
||||
|
||||
// If the effective argument type is 'undefined', there is no synthetic type
|
||||
// for the argument. In that case, we should check the argument.
|
||||
|
@ -12346,7 +12529,7 @@ namespace ts {
|
|||
/**
|
||||
* Gets the effective argument type for an argument in a call expression.
|
||||
*/
|
||||
function getEffectiveArgumentType(node: CallLikeExpression, argIndex: number, arg: Expression): Type {
|
||||
function getEffectiveArgumentType(node: CallLikeExpression, argIndex: number): Type {
|
||||
// Decorators provide special arguments, a tagged template expression provides
|
||||
// a special first argument, and string literals get string literal types
|
||||
// unless we're reporting errors
|
||||
|
@ -12999,7 +13182,10 @@ namespace ts {
|
|||
}
|
||||
|
||||
// In JavaScript files, calls to any identifier 'require' are treated as external module imports
|
||||
if (isInJavaScriptFile(node) && isRequireCall(node, /*checkArgumentIsStringLiteral*/true)) {
|
||||
if (isInJavaScriptFile(node) &&
|
||||
isRequireCall(node, /*checkArgumentIsStringLiteral*/true) &&
|
||||
// Make sure require is not a local function
|
||||
!resolveName(node.expression, (<Identifier>node.expression).text, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined)) {
|
||||
return resolveExternalModuleTypeByLiteral(<StringLiteral>node.arguments[0]);
|
||||
}
|
||||
|
||||
|
@ -13048,21 +13234,36 @@ namespace ts {
|
|||
|
||||
function assignContextualParameterTypes(signature: Signature, context: Signature, mapper: TypeMapper) {
|
||||
const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
|
||||
if (context.thisParameter) {
|
||||
if (!signature.thisParameter) {
|
||||
signature.thisParameter = createTransientSymbol(context.thisParameter, undefined);
|
||||
if (isInferentialContext(mapper)) {
|
||||
for (let i = 0; i < len; i++) {
|
||||
const declaration = <ParameterDeclaration>signature.parameters[i].valueDeclaration;
|
||||
if (declaration.type) {
|
||||
inferTypes(mapper.context, getTypeFromTypeNode(declaration.type), getTypeAtPosition(context, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (context.thisParameter) {
|
||||
const parameter = signature.thisParameter;
|
||||
if (!parameter || parameter.valueDeclaration && !(<ParameterDeclaration>parameter.valueDeclaration).type) {
|
||||
if (!parameter) {
|
||||
signature.thisParameter = createTransientSymbol(context.thisParameter, undefined);
|
||||
}
|
||||
assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper);
|
||||
}
|
||||
assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper);
|
||||
}
|
||||
for (let i = 0; i < len; i++) {
|
||||
const parameter = signature.parameters[i];
|
||||
const contextualParameterType = getTypeAtPosition(context, i);
|
||||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper);
|
||||
if (!(<ParameterDeclaration>parameter.valueDeclaration).type) {
|
||||
const contextualParameterType = getTypeAtPosition(context, i);
|
||||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper);
|
||||
}
|
||||
}
|
||||
if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) {
|
||||
const parameter = lastOrUndefined(signature.parameters);
|
||||
const contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters));
|
||||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper);
|
||||
if (!(<ParameterDeclaration>parameter.valueDeclaration).type) {
|
||||
const contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters));
|
||||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13733,15 +13934,15 @@ namespace ts {
|
|||
return booleanType;
|
||||
}
|
||||
|
||||
function checkObjectLiteralAssignment(node: ObjectLiteralExpression, sourceType: Type, contextualMapper?: TypeMapper): Type {
|
||||
function checkObjectLiteralAssignment(node: ObjectLiteralExpression, sourceType: Type): Type {
|
||||
const properties = node.properties;
|
||||
for (const p of properties) {
|
||||
checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, contextualMapper);
|
||||
checkObjectLiteralDestructuringPropertyAssignment(sourceType, p);
|
||||
}
|
||||
return sourceType;
|
||||
}
|
||||
|
||||
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, contextualMapper?: TypeMapper) {
|
||||
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike) {
|
||||
if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
const name = <PropertyName>(<PropertyAssignment>property).name;
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
|
@ -13856,7 +14057,7 @@ namespace ts {
|
|||
target = (<BinaryExpression>target).left;
|
||||
}
|
||||
if (target.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
return checkObjectLiteralAssignment(<ObjectLiteralExpression>target, sourceType, contextualMapper);
|
||||
return checkObjectLiteralAssignment(<ObjectLiteralExpression>target, sourceType);
|
||||
}
|
||||
if (target.kind === SyntaxKind.ArrayLiteralExpression) {
|
||||
return checkArrayLiteralAssignment(<ArrayLiteralExpression>target, sourceType, contextualMapper);
|
||||
|
@ -14676,7 +14877,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
if (node.type) {
|
||||
if (languageVersion >= ScriptTarget.ES6 && isSyntacticallyValidGenerator(node)) {
|
||||
if (languageVersion >= ScriptTarget.ES2015 && isSyntacticallyValidGenerator(node)) {
|
||||
const returnType = getTypeFromTypeNode(node.type);
|
||||
if (returnType === voidType) {
|
||||
error(node.type, Diagnostics.A_generator_cannot_have_a_void_type_annotation);
|
||||
|
@ -15639,7 +15840,7 @@ namespace ts {
|
|||
* callable `then` signature.
|
||||
*/
|
||||
function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration): Type {
|
||||
if (languageVersion >= ScriptTarget.ES6) {
|
||||
if (languageVersion >= ScriptTarget.ES2015) {
|
||||
const returnType = getTypeFromTypeNode(node.type);
|
||||
return checkCorrectPromiseType(returnType, node.type, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type);
|
||||
}
|
||||
|
@ -16168,7 +16369,7 @@ namespace ts {
|
|||
|
||||
function checkCollisionWithRequireExportsInGeneratedCode(node: Node, name: Identifier) {
|
||||
// No need to check for require or exports for ES6 modules and later
|
||||
if (modulekind >= ModuleKind.ES6) {
|
||||
if (modulekind >= ModuleKind.ES2015) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -16349,7 +16550,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function convertAutoToAny(type: Type) {
|
||||
return type === autoType ? anyType : type;
|
||||
return type === autoType ? anyType : type === autoArrayType ? anyArrayType : type;
|
||||
}
|
||||
|
||||
// Check variable, parameter, or property declaration
|
||||
|
@ -16664,7 +16865,7 @@ namespace ts {
|
|||
if (isTypeAny(inputType)) {
|
||||
return inputType;
|
||||
}
|
||||
if (languageVersion >= ScriptTarget.ES6) {
|
||||
if (languageVersion >= ScriptTarget.ES2015) {
|
||||
return checkElementTypeOfIterable(inputType, errorNode);
|
||||
}
|
||||
if (allowStringInput) {
|
||||
|
@ -16842,7 +17043,7 @@ namespace ts {
|
|||
* 2. Some constituent is a string and target is less than ES5 (because in ES3 string is not indexable).
|
||||
*/
|
||||
function checkElementTypeOfArrayOrString(arrayOrStringType: Type, errorNode: Node): Type {
|
||||
Debug.assert(languageVersion < ScriptTarget.ES6);
|
||||
Debug.assert(languageVersion < ScriptTarget.ES2015);
|
||||
|
||||
// After we remove all types that are StringLike, we will know if there was a string constituent
|
||||
// based on whether the remaining type is the same as the initial type.
|
||||
|
@ -18155,7 +18356,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (modulekind === ModuleKind.ES6 && !isInAmbientContext(node)) {
|
||||
if (modulekind === ModuleKind.ES2015 && !isInAmbientContext(node)) {
|
||||
// Import equals declaration is deprecated in es6 or above
|
||||
grammarErrorOnNode(node, Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_2015_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead);
|
||||
}
|
||||
|
@ -18243,7 +18444,7 @@ namespace ts {
|
|||
checkExternalModuleExports(container);
|
||||
|
||||
if (node.isExportEquals && !isInAmbientContext(node)) {
|
||||
if (modulekind === ModuleKind.ES6) {
|
||||
if (modulekind === ModuleKind.ES2015) {
|
||||
// export assignment is not supported in es6 modules
|
||||
grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_2015_modules_Consider_using_export_default_or_another_module_format_instead);
|
||||
}
|
||||
|
@ -18769,7 +18970,7 @@ namespace ts {
|
|||
// Since we already checked for ExportAssignment, this really could only be an Import
|
||||
const importEqualsDeclaration = <ImportEqualsDeclaration>getAncestor(entityName, SyntaxKind.ImportEqualsDeclaration);
|
||||
Debug.assert(importEqualsDeclaration !== undefined);
|
||||
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>entityName, importEqualsDeclaration, /*dontResolveAlias*/ true);
|
||||
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>entityName, /*dontResolveAlias*/ true);
|
||||
}
|
||||
|
||||
if (isRightSideOfQualifiedNameOrPropertyAccess(entityName)) {
|
||||
|
@ -19761,7 +19962,7 @@ namespace ts {
|
|||
|
||||
getGlobalTemplateStringsArrayType = memoize(() => getGlobalType("TemplateStringsArray"));
|
||||
|
||||
if (languageVersion >= ScriptTarget.ES6) {
|
||||
if (languageVersion >= ScriptTarget.ES2015) {
|
||||
getGlobalESSymbolType = memoize(() => getGlobalType("Symbol"));
|
||||
getGlobalIterableType = memoize(() => <GenericType>getGlobalType("Iterable", /*arity*/ 1));
|
||||
getGlobalIteratorType = memoize(() => <GenericType>getGlobalType("Iterator", /*arity*/ 1));
|
||||
|
@ -19775,6 +19976,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
anyArrayType = createArrayType(anyType);
|
||||
autoArrayType = createArrayType(autoType);
|
||||
|
||||
const symbol = getGlobalSymbol("ReadonlyArray", SymbolFlags.Type, /*diagnostic*/ undefined);
|
||||
globalReadonlyArrayType = symbol && <GenericType>getTypeOfGlobalSymbol(symbol, /*arity*/ 1);
|
||||
|
@ -19794,7 +19996,7 @@ namespace ts {
|
|||
// If we found the module, report errors if it does not have the necessary exports.
|
||||
if (helpersModule) {
|
||||
const exports = helpersModule.exports;
|
||||
if (requestedExternalEmitHelpers & NodeFlags.HasClassExtends && languageVersion < ScriptTarget.ES6) {
|
||||
if (requestedExternalEmitHelpers & NodeFlags.HasClassExtends && languageVersion < ScriptTarget.ES2015) {
|
||||
verifyHelperSymbol(exports, "__extends", SymbolFlags.Value);
|
||||
}
|
||||
if (requestedExternalEmitHelpers & NodeFlags.HasSpreadAttribute && compilerOptions.jsx !== JsxEmit.Preserve) {
|
||||
|
@ -19811,7 +20013,7 @@ namespace ts {
|
|||
}
|
||||
if (requestedExternalEmitHelpers & NodeFlags.HasAsyncFunctions) {
|
||||
verifyHelperSymbol(exports, "__awaiter", SymbolFlags.Value);
|
||||
if (languageVersion < ScriptTarget.ES6) {
|
||||
if (languageVersion < ScriptTarget.ES2015) {
|
||||
verifyHelperSymbol(exports, "__generator", SymbolFlags.Value);
|
||||
}
|
||||
}
|
||||
|
@ -20157,7 +20359,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function checkGrammarTypeParameterList(node: FunctionLikeDeclaration, typeParameters: NodeArray<TypeParameterDeclaration>, file: SourceFile): boolean {
|
||||
function checkGrammarTypeParameterList(typeParameters: NodeArray<TypeParameterDeclaration>, file: SourceFile): boolean {
|
||||
if (checkGrammarForDisallowedTrailingComma(typeParameters)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -20208,7 +20410,7 @@ namespace ts {
|
|||
function checkGrammarFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean {
|
||||
// Prevent cascading error by short-circuit
|
||||
const file = getSourceFileOfNode(node);
|
||||
return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarTypeParameterList(node, node.typeParameters, file) ||
|
||||
return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) ||
|
||||
checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file);
|
||||
}
|
||||
|
||||
|
@ -20393,13 +20595,13 @@ namespace ts {
|
|||
if (!node.body) {
|
||||
return grammarErrorOnNode(node.asteriskToken, Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator);
|
||||
}
|
||||
if (languageVersion < ScriptTarget.ES6) {
|
||||
if (languageVersion < ScriptTarget.ES2015) {
|
||||
return grammarErrorOnNode(node.asteriskToken, Diagnostics.Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkGrammarForInvalidQuestionMark(node: Declaration, questionToken: Node, message: DiagnosticMessage): boolean {
|
||||
function checkGrammarForInvalidQuestionMark(questionToken: Node, message: DiagnosticMessage): boolean {
|
||||
if (questionToken) {
|
||||
return grammarErrorOnNode(questionToken, message);
|
||||
}
|
||||
|
@ -20448,7 +20650,7 @@ namespace ts {
|
|||
let currentKind: number;
|
||||
if (prop.kind === SyntaxKind.PropertyAssignment || prop.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
// Grammar checking for computedPropertyName and shorthandPropertyAssignment
|
||||
checkGrammarForInvalidQuestionMark(prop, (<PropertyAssignment>prop).questionToken, Diagnostics.An_object_member_cannot_be_declared_optional);
|
||||
checkGrammarForInvalidQuestionMark((<PropertyAssignment>prop).questionToken, Diagnostics.An_object_member_cannot_be_declared_optional);
|
||||
if (name.kind === SyntaxKind.NumericLiteral) {
|
||||
checkGrammarNumericLiteral(<NumericLiteral>name);
|
||||
}
|
||||
|
@ -20632,7 +20834,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
if (node.parent.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional)) {
|
||||
if (checkGrammarForInvalidQuestionMark(node.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional)) {
|
||||
return true;
|
||||
}
|
||||
else if (node.body === undefined) {
|
||||
|
|
|
@ -101,7 +101,7 @@ namespace ts {
|
|||
"amd": ModuleKind.AMD,
|
||||
"system": ModuleKind.System,
|
||||
"umd": ModuleKind.UMD,
|
||||
"es6": ModuleKind.ES6,
|
||||
"es6": ModuleKind.ES2015,
|
||||
"es2015": ModuleKind.ES2015,
|
||||
}),
|
||||
description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015,
|
||||
|
@ -261,8 +261,10 @@ namespace ts {
|
|||
type: createMap({
|
||||
"es3": ScriptTarget.ES3,
|
||||
"es5": ScriptTarget.ES5,
|
||||
"es6": ScriptTarget.ES6,
|
||||
"es6": ScriptTarget.ES2015,
|
||||
"es2015": ScriptTarget.ES2015,
|
||||
"es2016": ScriptTarget.ES2016,
|
||||
"es2017": ScriptTarget.ES2017,
|
||||
}),
|
||||
description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015,
|
||||
paramType: Diagnostics.VERSION,
|
||||
|
@ -513,10 +515,7 @@ namespace ts {
|
|||
|
||||
/* @internal */
|
||||
export function createCompilerDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType): Diagnostic {
|
||||
const namesOfType: string[] = [];
|
||||
for (const key in opt.type) {
|
||||
namesOfType.push(` '${key}'`);
|
||||
}
|
||||
const namesOfType = Object.keys(opt.type).map(key => `'${key}'`).join(", ");
|
||||
return createCompilerDiagnostic(Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, namesOfType);
|
||||
}
|
||||
|
||||
|
|
|
@ -188,7 +188,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function emitLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) {
|
||||
function emitLeadingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) {
|
||||
if (!hasWrittenComment) {
|
||||
emitNewLineBeforeLeadingCommentOfPosition(currentLineMap, writer, rangePos, commentPos);
|
||||
hasWrittenComment = true;
|
||||
|
@ -211,7 +211,7 @@ namespace ts {
|
|||
forEachTrailingCommentToEmit(pos, emitTrailingComment);
|
||||
}
|
||||
|
||||
function emitTrailingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean) {
|
||||
function emitTrailingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) {
|
||||
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/
|
||||
if (!writer.isAtStartOfLine()) {
|
||||
writer.write(" ");
|
||||
|
@ -242,7 +242,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean) {
|
||||
function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) {
|
||||
// trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
|
||||
|
||||
emitPos(commentPos);
|
||||
|
|
|
@ -20,6 +20,9 @@ namespace ts {
|
|||
|
||||
const createObject = Object.create;
|
||||
|
||||
// More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times.
|
||||
export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined;
|
||||
|
||||
export function createMap<T>(template?: MapLike<T>): Map<T> {
|
||||
const map: Map<T> = createObject(null); // tslint:disable-line:no-null-keyword
|
||||
|
||||
|
@ -265,13 +268,33 @@ namespace ts {
|
|||
if (array) {
|
||||
result = [];
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const v = array[i];
|
||||
result.push(f(v, i));
|
||||
result.push(f(array[i], i));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Maps from T to T and avoids allocation if all elements map to themselves
|
||||
export function sameMap<T>(array: T[], f: (x: T, i: number) => T): T[] {
|
||||
let result: T[];
|
||||
if (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (result) {
|
||||
result.push(f(array[i], i));
|
||||
}
|
||||
else {
|
||||
const item = array[i];
|
||||
const mapped = f(item, i);
|
||||
if (item !== mapped) {
|
||||
result = array.slice(0, i);
|
||||
result.push(mapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result || array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flattens an array containing a mix of array or non-array elements.
|
||||
*
|
||||
|
@ -399,6 +422,17 @@ namespace ts {
|
|||
return result;
|
||||
}
|
||||
|
||||
export function some<T>(array: T[], predicate?: (value: T) => boolean): boolean {
|
||||
if (array) {
|
||||
for (const v of array) {
|
||||
if (!predicate || predicate(v)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function concatenate<T>(array1: T[], array2: T[]): T[] {
|
||||
if (!array2 || !array2.length) return array1;
|
||||
if (!array1 || !array1.length) return array2;
|
||||
|
@ -869,7 +903,7 @@ namespace ts {
|
|||
return t => compose(a(t));
|
||||
}
|
||||
else {
|
||||
return t => u => u;
|
||||
return _ => u => u;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -906,10 +940,10 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function formatStringFromArgs(text: string, args: { [index: number]: any; }, baseIndex?: number): string {
|
||||
function formatStringFromArgs(text: string, args: { [index: number]: string; }, baseIndex?: number): string {
|
||||
baseIndex = baseIndex || 0;
|
||||
|
||||
return text.replace(/{(\d+)}/g, (match, index?) => args[+index + baseIndex]);
|
||||
return text.replace(/{(\d+)}/g, (_match, index?) => args[+index + baseIndex]);
|
||||
}
|
||||
|
||||
export let localizedDiagnosticMessages: Map<string> = undefined;
|
||||
|
@ -918,7 +952,7 @@ namespace ts {
|
|||
return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message;
|
||||
}
|
||||
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: any[]): Diagnostic;
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number)[]): Diagnostic;
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): Diagnostic {
|
||||
const end = start + length;
|
||||
|
||||
|
@ -948,7 +982,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
/* internal */
|
||||
export function formatMessage(dummy: any, message: DiagnosticMessage): string {
|
||||
export function formatMessage(_dummy: any, message: DiagnosticMessage): string {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
|
||||
if (arguments.length > 2) {
|
||||
|
@ -958,7 +992,7 @@ namespace ts {
|
|||
return text;
|
||||
}
|
||||
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: any[]): Diagnostic;
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: (string | number)[]): Diagnostic;
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
|
||||
|
@ -1016,7 +1050,8 @@ namespace ts {
|
|||
if (a === undefined) return Comparison.LessThan;
|
||||
if (b === undefined) return Comparison.GreaterThan;
|
||||
if (ignoreCase) {
|
||||
if (String.prototype.localeCompare) {
|
||||
if (collator && String.prototype.localeCompare) {
|
||||
// accent means a ≠ b, a ≠ á, a = A
|
||||
const result = a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" });
|
||||
return result < 0 ? Comparison.LessThan : result > 0 ? Comparison.GreaterThan : Comparison.EqualTo;
|
||||
}
|
||||
|
@ -1177,7 +1212,7 @@ namespace ts {
|
|||
|
||||
/**
|
||||
* Returns the path except for its basename. Eg:
|
||||
*
|
||||
*
|
||||
* /path/to/file.ext -> /path/to
|
||||
*/
|
||||
export function getDirectoryPath(path: Path): Path;
|
||||
|
@ -1203,7 +1238,7 @@ namespace ts {
|
|||
export function getEmitModuleKind(compilerOptions: CompilerOptions) {
|
||||
return typeof compilerOptions.module === "number" ?
|
||||
compilerOptions.module :
|
||||
getEmitScriptTarget(compilerOptions) === ScriptTarget.ES6 ? ModuleKind.ES6 : ModuleKind.CommonJS;
|
||||
getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2015 ? ModuleKind.ES2015 : ModuleKind.CommonJS;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
@ -1588,7 +1623,7 @@ namespace ts {
|
|||
basePaths: string[];
|
||||
}
|
||||
|
||||
export function getFileMatcherPatterns(path: string, extensions: string[], excludes: string[], includes: string[], useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns {
|
||||
export function getFileMatcherPatterns(path: string, excludes: string[], includes: string[], useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns {
|
||||
path = normalizePath(path);
|
||||
currentDirectory = normalizePath(currentDirectory);
|
||||
const absolutePath = combinePaths(currentDirectory, path);
|
||||
|
@ -1605,7 +1640,7 @@ namespace ts {
|
|||
path = normalizePath(path);
|
||||
currentDirectory = normalizePath(currentDirectory);
|
||||
|
||||
const patterns = getFileMatcherPatterns(path, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory);
|
||||
const patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory);
|
||||
|
||||
const regexFlag = useCaseSensitiveFileNames ? "" : "i";
|
||||
const includeFileRegex = patterns.includeFilePattern && new RegExp(patterns.includeFilePattern, regexFlag);
|
||||
|
@ -1839,11 +1874,11 @@ namespace ts {
|
|||
this.declarations = undefined;
|
||||
}
|
||||
|
||||
function Type(this: Type, checker: TypeChecker, flags: TypeFlags) {
|
||||
function Type(this: Type, _checker: TypeChecker, flags: TypeFlags) {
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
function Signature(checker: TypeChecker) {
|
||||
function Signature() {
|
||||
}
|
||||
|
||||
function Node(this: Node, kind: SyntaxKind, pos: number, end: number) {
|
||||
|
@ -1876,9 +1911,6 @@ namespace ts {
|
|||
}
|
||||
|
||||
export namespace Debug {
|
||||
declare var process: any;
|
||||
declare var require: any;
|
||||
|
||||
export let currentAssertionLevel = AssertionLevel.None;
|
||||
|
||||
export function shouldAssert(level: AssertionLevel): boolean {
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace ts {
|
|||
let isCurrentFileExternalModule: boolean;
|
||||
let reportedDeclarationError = false;
|
||||
let errorNameNode: DeclarationName;
|
||||
const emitJsDocComments = compilerOptions.removeComments ? function (declaration: Node) { } : writeJsDocComments;
|
||||
const emitJsDocComments = compilerOptions.removeComments ? () => {} : writeJsDocComments;
|
||||
const emit = compilerOptions.stripInternal ? stripInternal : emitNode;
|
||||
let noDeclare: boolean;
|
||||
|
||||
|
@ -580,7 +580,7 @@ namespace ts {
|
|||
writeAsynchronousModuleElements(nodes);
|
||||
}
|
||||
|
||||
function getDefaultExportAccessibilityDiagnostic(diagnostic: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
function getDefaultExportAccessibilityDiagnostic(): SymbolAccessibilityDiagnostic {
|
||||
return {
|
||||
diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
|
||||
errorNode: node
|
||||
|
@ -710,7 +710,7 @@ namespace ts {
|
|||
}
|
||||
writer.writeLine();
|
||||
|
||||
function getImportEntityNameVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
function getImportEntityNameVisibilityError(): SymbolAccessibilityDiagnostic {
|
||||
return {
|
||||
diagnosticMessage: Diagnostics.Import_declaration_0_is_using_private_name_1,
|
||||
errorNode: node,
|
||||
|
@ -888,7 +888,7 @@ namespace ts {
|
|||
writeLine();
|
||||
enclosingDeclaration = prevEnclosingDeclaration;
|
||||
|
||||
function getTypeAliasDeclarationVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
function getTypeAliasDeclarationVisibilityError(): SymbolAccessibilityDiagnostic {
|
||||
return {
|
||||
diagnosticMessage: Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1,
|
||||
errorNode: node.type,
|
||||
|
@ -955,7 +955,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function getTypeParameterConstraintVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
function getTypeParameterConstraintVisibilityError(): SymbolAccessibilityDiagnostic {
|
||||
// Type parameter constraints are named by user so we should always be able to name it
|
||||
let diagnosticMessage: DiagnosticMessage;
|
||||
switch (node.parent.kind) {
|
||||
|
@ -1029,7 +1029,7 @@ namespace ts {
|
|||
resolver.writeBaseConstructorTypeOfClass(<ClassLikeDeclaration>enclosingDeclaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer);
|
||||
}
|
||||
|
||||
function getHeritageClauseVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
function getHeritageClauseVisibilityError(): SymbolAccessibilityDiagnostic {
|
||||
let diagnosticMessage: DiagnosticMessage;
|
||||
// Heritage clause is written by user so it can always be named
|
||||
if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
|
||||
|
@ -1752,7 +1752,7 @@ namespace ts {
|
|||
}
|
||||
return addedBundledEmitReference;
|
||||
|
||||
function getDeclFileName(emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean) {
|
||||
function getDeclFileName(emitFileNames: EmitFileNames, _sourceFiles: SourceFile[], isBundledEmit: boolean) {
|
||||
// Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path
|
||||
if (isBundledEmit && !addBundledFileReference) {
|
||||
return;
|
||||
|
|
|
@ -2965,7 +2965,7 @@
|
|||
"category": "Error",
|
||||
"code": 7033
|
||||
},
|
||||
"Variable '{0}' implicitly has type 'any' in some locations where its type cannot be determined.": {
|
||||
"Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined.": {
|
||||
"category": "Error",
|
||||
"code": 7034
|
||||
},
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
const id = (s: SourceFile) => s;
|
||||
const nullTransformers: Transformer[] = [ctx => id];
|
||||
const nullTransformers: Transformer[] = [_ => id];
|
||||
|
||||
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean): EmitResult {
|
||||
|
@ -504,15 +504,29 @@ const _super = (function (geti, seti) {
|
|||
|
||||
// Contextual keywords
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
case SyntaxKind.AsKeyword:
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
case SyntaxKind.AwaitKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.ConstructorKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.GetKeyword:
|
||||
case SyntaxKind.IsKeyword:
|
||||
case SyntaxKind.ModuleKeyword:
|
||||
case SyntaxKind.NamespaceKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
case SyntaxKind.ReadonlyKeyword:
|
||||
case SyntaxKind.RequireKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.SetKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.TypeKeyword:
|
||||
case SyntaxKind.UndefinedKeyword:
|
||||
case SyntaxKind.FromKeyword:
|
||||
case SyntaxKind.GlobalKeyword:
|
||||
case SyntaxKind.OfKeyword:
|
||||
writeTokenText(kind);
|
||||
return;
|
||||
|
||||
|
@ -579,7 +593,7 @@ const _super = (function (geti, seti) {
|
|||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return emitExpressionWithTypeArguments(<ExpressionWithTypeArguments>node);
|
||||
case SyntaxKind.ThisType:
|
||||
return emitThisType(<ThisTypeNode>node);
|
||||
return emitThisType();
|
||||
case SyntaxKind.LiteralType:
|
||||
return emitLiteralType(<LiteralTypeNode>node);
|
||||
|
||||
|
@ -595,7 +609,7 @@ const _super = (function (geti, seti) {
|
|||
case SyntaxKind.TemplateSpan:
|
||||
return emitTemplateSpan(<TemplateSpan>node);
|
||||
case SyntaxKind.SemicolonClassElement:
|
||||
return emitSemicolonClassElement(<SemicolonClassElement>node);
|
||||
return emitSemicolonClassElement();
|
||||
|
||||
// Statements
|
||||
case SyntaxKind.Block:
|
||||
|
@ -603,7 +617,7 @@ const _super = (function (geti, seti) {
|
|||
case SyntaxKind.VariableStatement:
|
||||
return emitVariableStatement(<VariableStatement>node);
|
||||
case SyntaxKind.EmptyStatement:
|
||||
return emitEmptyStatement(<EmptyStatement>node);
|
||||
return emitEmptyStatement();
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
return emitExpressionStatement(<ExpressionStatement>node);
|
||||
case SyntaxKind.IfStatement:
|
||||
|
@ -1000,7 +1014,7 @@ const _super = (function (geti, seti) {
|
|||
write(";");
|
||||
}
|
||||
|
||||
function emitSemicolonClassElement(node: SemicolonClassElement) {
|
||||
function emitSemicolonClassElement() {
|
||||
write(";");
|
||||
}
|
||||
|
||||
|
@ -1070,7 +1084,7 @@ const _super = (function (geti, seti) {
|
|||
write(")");
|
||||
}
|
||||
|
||||
function emitThisType(node: ThisTypeNode) {
|
||||
function emitThisType() {
|
||||
write("this");
|
||||
}
|
||||
|
||||
|
@ -1198,12 +1212,14 @@ const _super = (function (geti, seti) {
|
|||
|
||||
function emitCallExpression(node: CallExpression) {
|
||||
emitExpression(node.expression);
|
||||
emitTypeArguments(node, node.typeArguments);
|
||||
emitExpressionList(node, node.arguments, ListFormat.CallExpressionArguments);
|
||||
}
|
||||
|
||||
function emitNewExpression(node: NewExpression) {
|
||||
write("new ");
|
||||
emitExpression(node.expression);
|
||||
emitTypeArguments(node, node.typeArguments);
|
||||
emitExpressionList(node, node.arguments, ListFormat.NewExpressionArguments);
|
||||
}
|
||||
|
||||
|
@ -1381,7 +1397,7 @@ const _super = (function (geti, seti) {
|
|||
// Statements
|
||||
//
|
||||
|
||||
function emitBlock(node: Block, format?: ListFormat) {
|
||||
function emitBlock(node: Block) {
|
||||
if (isSingleLineEmptyBlock(node)) {
|
||||
writeToken(SyntaxKind.OpenBraceToken, node.pos, /*contextNode*/ node);
|
||||
write(" ");
|
||||
|
@ -1409,7 +1425,7 @@ const _super = (function (geti, seti) {
|
|||
write(";");
|
||||
}
|
||||
|
||||
function emitEmptyStatement(node: EmptyStatement) {
|
||||
function emitEmptyStatement() {
|
||||
write(";");
|
||||
}
|
||||
|
||||
|
@ -1575,6 +1591,7 @@ const _super = (function (geti, seti) {
|
|||
|
||||
function emitVariableDeclaration(node: VariableDeclaration) {
|
||||
emit(node.name);
|
||||
emitWithPrefix(": ", node.type);
|
||||
emitExpressionWithPrefix(" = ", node.initializer);
|
||||
}
|
||||
|
||||
|
@ -1606,13 +1623,13 @@ const _super = (function (geti, seti) {
|
|||
|
||||
if (getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) {
|
||||
emitSignatureHead(node);
|
||||
emitBlockFunctionBody(node, body);
|
||||
emitBlockFunctionBody(body);
|
||||
}
|
||||
else {
|
||||
const savedTempFlags = tempFlags;
|
||||
tempFlags = 0;
|
||||
emitSignatureHead(node);
|
||||
emitBlockFunctionBody(node, body);
|
||||
emitBlockFunctionBody(body);
|
||||
tempFlags = savedTempFlags;
|
||||
}
|
||||
|
||||
|
@ -1639,7 +1656,7 @@ const _super = (function (geti, seti) {
|
|||
emitWithPrefix(": ", node.type);
|
||||
}
|
||||
|
||||
function shouldEmitBlockFunctionBodyOnSingleLine(parentNode: Node, body: Block) {
|
||||
function shouldEmitBlockFunctionBodyOnSingleLine(body: Block) {
|
||||
// We must emit a function body as a single-line body in the following case:
|
||||
// * The body has NodeEmitFlags.SingleLine specified.
|
||||
|
||||
|
@ -1677,12 +1694,12 @@ const _super = (function (geti, seti) {
|
|||
return true;
|
||||
}
|
||||
|
||||
function emitBlockFunctionBody(parentNode: Node, body: Block) {
|
||||
function emitBlockFunctionBody(body: Block) {
|
||||
write(" {");
|
||||
increaseIndent();
|
||||
|
||||
emitBodyWithDetachedComments(body, body.statements,
|
||||
shouldEmitBlockFunctionBodyOnSingleLine(parentNode, body)
|
||||
shouldEmitBlockFunctionBodyOnSingleLine(body)
|
||||
? emitBlockFunctionBodyOnSingleLine
|
||||
: emitBlockFunctionBodyWorker);
|
||||
|
||||
|
@ -2165,7 +2182,7 @@ const _super = (function (geti, seti) {
|
|||
|
||||
// Only Emit __extends function when target ES5.
|
||||
// For target ES6 and above, we can emit classDeclaration as is.
|
||||
if ((languageVersion < ScriptTarget.ES6) && (!extendsEmitted && node.flags & NodeFlags.HasClassExtends)) {
|
||||
if ((languageVersion < ScriptTarget.ES2015) && (!extendsEmitted && node.flags & NodeFlags.HasClassExtends)) {
|
||||
writeLines(extendsHelper);
|
||||
extendsEmitted = true;
|
||||
helpersEmitted = true;
|
||||
|
@ -2192,9 +2209,12 @@ const _super = (function (geti, seti) {
|
|||
helpersEmitted = true;
|
||||
}
|
||||
|
||||
if (!awaiterEmitted && node.flags & NodeFlags.HasAsyncFunctions) {
|
||||
// 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.ES6) {
|
||||
if (languageVersion < ScriptTarget.ES2015) {
|
||||
writeLines(generatorHelper);
|
||||
}
|
||||
|
||||
|
|
|
@ -525,9 +525,9 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function createFunctionExpression(asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
|
||||
export function createFunctionExpression(modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
|
||||
const node = <FunctionExpression>createNode(SyntaxKind.FunctionExpression, location, flags);
|
||||
node.modifiers = undefined;
|
||||
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
|
||||
node.asteriskToken = asteriskToken;
|
||||
node.name = typeof name === "string" ? createIdentifier(name) : name;
|
||||
node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined;
|
||||
|
@ -537,9 +537,9 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateFunctionExpression(node: FunctionExpression, name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
if (node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) {
|
||||
return updateNode(createFunctionExpression(node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node);
|
||||
export function updateFunctionExpression(node: FunctionExpression, modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
if (node.name !== name || node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) {
|
||||
return updateNode(createFunctionExpression(modifiers, node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
@ -1736,6 +1736,7 @@ namespace ts {
|
|||
|
||||
export function createAwaiterHelper(externalHelpersModuleName: Identifier | undefined, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) {
|
||||
const generatorFunc = createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
createToken(SyntaxKind.AsteriskToken),
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -1909,6 +1910,7 @@ namespace ts {
|
|||
createCall(
|
||||
createParen(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -1984,7 +1986,7 @@ namespace ts {
|
|||
}
|
||||
else if (callee.kind === SyntaxKind.SuperKeyword) {
|
||||
thisArg = createThis();
|
||||
target = languageVersion < ScriptTarget.ES6 ? createIdentifier("_super", /*location*/ callee) : <PrimaryExpression>callee;
|
||||
target = languageVersion < ScriptTarget.ES2015 ? createIdentifier("_super", /*location*/ callee) : <PrimaryExpression>callee;
|
||||
}
|
||||
else {
|
||||
switch (callee.kind) {
|
||||
|
@ -2090,6 +2092,7 @@ namespace ts {
|
|||
const properties: ObjectLiteralElementLike[] = [];
|
||||
if (getAccessor) {
|
||||
const getterFunction = createFunctionExpression(
|
||||
getAccessor.modifiers,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -2105,6 +2108,7 @@ namespace ts {
|
|||
|
||||
if (setAccessor) {
|
||||
const setterFunction = createFunctionExpression(
|
||||
setAccessor.modifiers,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -2171,6 +2175,7 @@ namespace ts {
|
|||
createMemberAccessForPropertyName(receiver, method.name, /*location*/ method.name),
|
||||
setOriginalNode(
|
||||
createFunctionExpression(
|
||||
method.modifiers,
|
||||
method.asteriskToken,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -2206,7 +2211,7 @@ namespace ts {
|
|||
* @param visitor: Optional callback used to visit any custom prologue directives.
|
||||
*/
|
||||
export function addPrologueDirectives(target: Statement[], source: Statement[], ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult<Node>): number {
|
||||
Debug.assert(target.length === 0, "PrologueDirectives should be at the first statement in the target statements array");
|
||||
Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array");
|
||||
let foundUseStrict = false;
|
||||
let statementOffset = 0;
|
||||
const numStatements = source.length;
|
||||
|
@ -2219,16 +2224,20 @@ namespace ts {
|
|||
target.push(statement);
|
||||
}
|
||||
else {
|
||||
if (ensureUseStrict && !foundUseStrict) {
|
||||
target.push(startOnNewLine(createStatement(createLiteral("use strict"))));
|
||||
foundUseStrict = true;
|
||||
}
|
||||
if (getEmitFlags(statement) & EmitFlags.CustomPrologue) {
|
||||
target.push(visitor ? visitNode(statement, visitor, isStatement) : statement);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
statementOffset++;
|
||||
}
|
||||
if (ensureUseStrict && !foundUseStrict) {
|
||||
target.push(startOnNewLine(createStatement(createLiteral("use strict"))));
|
||||
}
|
||||
while (statementOffset < numStatements) {
|
||||
const statement = source[statementOffset];
|
||||
if (getEmitFlags(statement) & EmitFlags.CustomPrologue) {
|
||||
target.push(visitor ? visitNode(statement, visitor, isStatement) : statement);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
statementOffset++;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace ts {
|
|||
|
||||
/* @internal */
|
||||
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
|
||||
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage): void {
|
||||
export function trace(host: ModuleResolutionHost): void {
|
||||
host.trace(formatMessage.apply(undefined, arguments));
|
||||
}
|
||||
|
||||
|
|
|
@ -576,10 +576,10 @@ namespace ts {
|
|||
// attached to the EOF token.
|
||||
let parseErrorBeforeNextFinishedNode = false;
|
||||
|
||||
export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, scriptKind?: ScriptKind): SourceFile {
|
||||
export function parseSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, scriptKind?: ScriptKind): SourceFile {
|
||||
scriptKind = ensureScriptKind(fileName, scriptKind);
|
||||
|
||||
initializeState(fileName, _sourceText, languageVersion, _syntaxCursor, scriptKind);
|
||||
initializeState(sourceText, languageVersion, syntaxCursor, scriptKind);
|
||||
|
||||
const result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind);
|
||||
|
||||
|
@ -593,7 +593,7 @@ namespace ts {
|
|||
return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS ? LanguageVariant.JSX : LanguageVariant.Standard;
|
||||
}
|
||||
|
||||
function initializeState(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) {
|
||||
function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) {
|
||||
NodeConstructor = objectAllocator.getNodeConstructor();
|
||||
TokenConstructor = objectAllocator.getTokenConstructor();
|
||||
IdentifierConstructor = objectAllocator.getIdentifierConstructor();
|
||||
|
@ -5284,7 +5284,7 @@ namespace ts {
|
|||
parseExpected(SyntaxKind.ClassKeyword);
|
||||
node.name = parseNameOfClassDeclarationOrExpression();
|
||||
node.typeParameters = parseTypeParameters();
|
||||
node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ true);
|
||||
node.heritageClauses = parseHeritageClauses();
|
||||
|
||||
if (parseExpected(SyntaxKind.OpenBraceToken)) {
|
||||
// ClassTail[Yield,Await] : (Modified) See 14.5
|
||||
|
@ -5314,7 +5314,7 @@ namespace ts {
|
|||
return token() === SyntaxKind.ImplementsKeyword && lookAhead(nextTokenIsIdentifierOrKeyword);
|
||||
}
|
||||
|
||||
function parseHeritageClauses(isClassHeritageClause: boolean): NodeArray<HeritageClause> {
|
||||
function parseHeritageClauses(): NodeArray<HeritageClause> {
|
||||
// ClassTail[Yield,Await] : (Modified) See 14.5
|
||||
// ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
|
||||
|
||||
|
@ -5362,7 +5362,7 @@ namespace ts {
|
|||
parseExpected(SyntaxKind.InterfaceKeyword);
|
||||
node.name = parseIdentifier();
|
||||
node.typeParameters = parseTypeParameters();
|
||||
node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ false);
|
||||
node.heritageClauses = parseHeritageClauses();
|
||||
node.members = parseObjectTypeMembers();
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
|
@ -5842,7 +5842,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number) {
|
||||
initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
|
||||
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
|
||||
sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS);
|
||||
scanner.setText(content, start, length);
|
||||
currentToken = scanner.scan();
|
||||
|
@ -6159,7 +6159,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
export function parseIsolatedJSDocComment(content: string, start: number, length: number) {
|
||||
initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
|
||||
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
|
||||
sourceFile = <SourceFile>{ languageVariant: LanguageVariant.Standard, text: content };
|
||||
const jsDoc = parseJSDocCommentWorker(start, length);
|
||||
const diagnostics = parseDiagnostics;
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace ts.performance {
|
|||
|
||||
const profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true
|
||||
? onProfilerEvent
|
||||
: (markName: string) => { };
|
||||
: (_markName: string) => { };
|
||||
|
||||
let enabled = false;
|
||||
let profilerStart = 0;
|
||||
|
|
|
@ -724,7 +724,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
|
||||
return sourceFile.parseDiagnostics;
|
||||
}
|
||||
|
||||
|
@ -761,16 +761,16 @@ namespace ts {
|
|||
// Instead, we just report errors for using TypeScript-only constructs from within a
|
||||
// JavaScript file.
|
||||
const checkDiagnostics = isSourceFileJavaScript(sourceFile) ?
|
||||
getJavaScriptSemanticDiagnosticsForFile(sourceFile, cancellationToken) :
|
||||
getJavaScriptSemanticDiagnosticsForFile(sourceFile) :
|
||||
typeChecker.getDiagnostics(sourceFile, cancellationToken);
|
||||
const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||
const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||
|
||||
return bindDiagnostics.concat(checkDiagnostics).concat(fileProcessingDiagnosticsInFile).concat(programDiagnosticsInFile);
|
||||
return bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
|
||||
});
|
||||
}
|
||||
|
||||
function getJavaScriptSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
function getJavaScriptSemanticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
|
||||
return runWithCancellationToken(() => {
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
walk(sourceFile);
|
||||
|
@ -977,7 +977,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function processRootFile(fileName: string, isDefaultLib: boolean) {
|
||||
processSourceFile(normalizePath(fileName), isDefaultLib, /*isReference*/ true);
|
||||
processSourceFile(normalizePath(fileName), isDefaultLib);
|
||||
}
|
||||
|
||||
function fileReferenceIsEqualTo(a: FileReference, b: FileReference): boolean {
|
||||
|
@ -1088,7 +1088,7 @@ namespace ts {
|
|||
/**
|
||||
* 'isReference' indicates whether the file was brought in via a reference directive (rather than an import declaration)
|
||||
*/
|
||||
function processSourceFile(fileName: string, isDefaultLib: boolean, isReference: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) {
|
||||
function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) {
|
||||
let diagnosticArgument: string[];
|
||||
let diagnostic: DiagnosticMessage;
|
||||
if (hasExtension(fileName)) {
|
||||
|
@ -1096,7 +1096,7 @@ namespace ts {
|
|||
diagnostic = Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1;
|
||||
diagnosticArgument = [fileName, "'" + supportedExtensions.join("', '") + "'"];
|
||||
}
|
||||
else if (!findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd)) {
|
||||
else if (!findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd)) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
diagnosticArgument = [fileName];
|
||||
}
|
||||
|
@ -1106,13 +1106,13 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
else {
|
||||
const nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd);
|
||||
const nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd);
|
||||
if (!nonTsFile) {
|
||||
if (options.allowNonTsExtensions) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
diagnosticArgument = [fileName];
|
||||
}
|
||||
else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, toPath(fileName + extension, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd))) {
|
||||
else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, toPath(fileName + extension, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd))) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
fileName += ".ts";
|
||||
diagnosticArgument = [fileName];
|
||||
|
@ -1141,7 +1141,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
// Get source file from normalized fileName
|
||||
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, isReference: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
|
||||
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
|
||||
if (filesByName.contains(path)) {
|
||||
const file = filesByName.get(path);
|
||||
// try to check if we've already seen this file but with a different casing in path
|
||||
|
@ -1155,18 +1155,18 @@ namespace ts {
|
|||
if (file && sourceFilesFoundSearchingNodeModules[file.path] && currentNodeModulesDepth == 0) {
|
||||
sourceFilesFoundSearchingNodeModules[file.path] = false;
|
||||
if (!options.noResolve) {
|
||||
processReferencedFiles(file, getDirectoryPath(fileName), isDefaultLib);
|
||||
processReferencedFiles(file, isDefaultLib);
|
||||
processTypeReferenceDirectives(file);
|
||||
}
|
||||
|
||||
modulesWithElidedImports[file.path] = false;
|
||||
processImportedModules(file, getDirectoryPath(fileName));
|
||||
processImportedModules(file);
|
||||
}
|
||||
// See if we need to reprocess the imports due to prior skipped imports
|
||||
else if (file && modulesWithElidedImports[file.path]) {
|
||||
if (currentNodeModulesDepth < maxNodeModulesJsDepth) {
|
||||
modulesWithElidedImports[file.path] = false;
|
||||
processImportedModules(file, getDirectoryPath(fileName));
|
||||
processImportedModules(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1202,14 +1202,13 @@ namespace ts {
|
|||
|
||||
skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
|
||||
|
||||
const basePath = getDirectoryPath(fileName);
|
||||
if (!options.noResolve) {
|
||||
processReferencedFiles(file, basePath, isDefaultLib);
|
||||
processReferencedFiles(file, isDefaultLib);
|
||||
processTypeReferenceDirectives(file);
|
||||
}
|
||||
|
||||
// always process imported modules to record module name resolutions
|
||||
processImportedModules(file, basePath);
|
||||
processImportedModules(file);
|
||||
|
||||
if (isDefaultLib) {
|
||||
files.unshift(file);
|
||||
|
@ -1222,10 +1221,10 @@ namespace ts {
|
|||
return file;
|
||||
}
|
||||
|
||||
function processReferencedFiles(file: SourceFile, basePath: string, isDefaultLib: boolean) {
|
||||
function processReferencedFiles(file: SourceFile, isDefaultLib: boolean) {
|
||||
forEach(file.referencedFiles, ref => {
|
||||
const referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
|
||||
processSourceFile(referencedFileName, isDefaultLib, /*isReference*/ true, file, ref.pos, ref.end);
|
||||
processSourceFile(referencedFileName, isDefaultLib, file, ref.pos, ref.end);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1256,7 +1255,7 @@ namespace ts {
|
|||
if (resolvedTypeReferenceDirective) {
|
||||
if (resolvedTypeReferenceDirective.primary) {
|
||||
// resolved from the primary path
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*isReference*/ true, refFile, refPos, refEnd);
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, refFile, refPos, refEnd);
|
||||
}
|
||||
else {
|
||||
// If we already resolved to this file, it must have been a secondary reference. Check file contents
|
||||
|
@ -1276,7 +1275,7 @@ namespace ts {
|
|||
}
|
||||
else {
|
||||
// First resolution of this library
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*isReference*/ true, refFile, refPos, refEnd);
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, refFile, refPos, refEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1302,7 +1301,7 @@ namespace ts {
|
|||
return host.getCanonicalFileName(fileName);
|
||||
}
|
||||
|
||||
function processImportedModules(file: SourceFile, basePath: string) {
|
||||
function processImportedModules(file: SourceFile) {
|
||||
collectExternalModuleReferences(file);
|
||||
if (file.imports.length || file.moduleAugmentations.length) {
|
||||
file.resolvedModules = createMap<ResolvedModule>();
|
||||
|
@ -1333,7 +1332,7 @@ namespace ts {
|
|||
else if (shouldAddFile) {
|
||||
findSourceFile(resolution.resolvedFileName,
|
||||
toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName),
|
||||
/*isDefaultLib*/ false, /*isReference*/ false,
|
||||
/*isDefaultLib*/ false,
|
||||
file,
|
||||
skipTrivia(file.text, file.imports[i].pos),
|
||||
file.imports[i].end);
|
||||
|
@ -1482,7 +1481,7 @@ namespace ts {
|
|||
|
||||
const firstNonAmbientExternalModuleSourceFile = forEach(files, f => isExternalModule(f) && !isDeclarationFile(f) ? f : undefined);
|
||||
if (options.isolatedModules) {
|
||||
if (options.module === ModuleKind.None && languageVersion < ScriptTarget.ES6) {
|
||||
if (options.module === ModuleKind.None && languageVersion < ScriptTarget.ES2015) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher));
|
||||
}
|
||||
|
||||
|
@ -1492,7 +1491,7 @@ namespace ts {
|
|||
programDiagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided));
|
||||
}
|
||||
}
|
||||
else if (firstNonAmbientExternalModuleSourceFile && languageVersion < ScriptTarget.ES6 && options.module === ModuleKind.None) {
|
||||
else if (firstNonAmbientExternalModuleSourceFile && languageVersion < ScriptTarget.ES2015 && options.module === ModuleKind.None) {
|
||||
// We cannot use createDiagnosticFromNode because nodes do not have parents yet
|
||||
const span = getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
|
||||
programDiagnostics.add(createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none));
|
||||
|
@ -1541,7 +1540,7 @@ namespace ts {
|
|||
if (!options.noEmit && !options.suppressOutputPathCheck) {
|
||||
const emitHost = getEmitHost();
|
||||
const emitFilesSeen = createFileMap<boolean>(!host.useCaseSensitiveFileNames() ? key => key.toLocaleLowerCase() : undefined);
|
||||
forEachExpectedEmitFile(emitHost, (emitFileNames, sourceFiles, isBundledEmit) => {
|
||||
forEachExpectedEmitFile(emitHost, (emitFileNames) => {
|
||||
verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen);
|
||||
verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen);
|
||||
});
|
||||
|
@ -1553,13 +1552,13 @@ namespace ts {
|
|||
const emitFilePath = toPath(emitFileName, currentDirectory, getCanonicalFileName);
|
||||
// Report error if the output overwrites input file
|
||||
if (filesByName.contains(emitFilePath)) {
|
||||
createEmitBlockingDiagnostics(emitFileName, emitFilePath, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file);
|
||||
createEmitBlockingDiagnostics(emitFileName, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file);
|
||||
}
|
||||
|
||||
// Report error if multiple files write into same file
|
||||
if (emitFilesSeen.contains(emitFilePath)) {
|
||||
// Already seen the same emit file - report error
|
||||
createEmitBlockingDiagnostics(emitFileName, emitFilePath, Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files);
|
||||
createEmitBlockingDiagnostics(emitFileName, Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files);
|
||||
}
|
||||
else {
|
||||
emitFilesSeen.set(emitFilePath, true);
|
||||
|
@ -1568,7 +1567,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function createEmitBlockingDiagnostics(emitFileName: string, emitFilePath: Path, message: DiagnosticMessage) {
|
||||
function createEmitBlockingDiagnostics(emitFileName: string, message: DiagnosticMessage) {
|
||||
hasEmitBlockingDiagnostics.set(toPath(emitFileName, currentDirectory, getCanonicalFileName), true);
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, emitFileName));
|
||||
}
|
||||
|
|
|
@ -723,7 +723,7 @@ namespace ts {
|
|||
return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial);
|
||||
}
|
||||
|
||||
function appendCommentRange(pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: any, comments: CommentRange[]) {
|
||||
function appendCommentRange(pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[]) {
|
||||
if (!comments) {
|
||||
comments = [];
|
||||
}
|
||||
|
|
|
@ -46,13 +46,9 @@ namespace ts {
|
|||
}
|
||||
|
||||
declare var require: any;
|
||||
declare var module: any;
|
||||
declare var process: any;
|
||||
declare var global: any;
|
||||
declare var __filename: string;
|
||||
declare var Buffer: {
|
||||
new (str: string, encoding?: string): any;
|
||||
};
|
||||
|
||||
declare class Enumerator {
|
||||
public atEnd(): boolean;
|
||||
|
@ -324,7 +320,7 @@ namespace ts {
|
|||
const platform: string = _os.platform();
|
||||
const useCaseSensitiveFileNames = isFileSystemCaseSensitive();
|
||||
|
||||
function readFile(fileName: string, encoding?: string): string {
|
||||
function readFile(fileName: string, _encoding?: string): string {
|
||||
if (!fileExists(fileName)) {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -576,7 +572,7 @@ namespace ts {
|
|||
args: ChakraHost.args,
|
||||
useCaseSensitiveFileNames: !!ChakraHost.useCaseSensitiveFileNames,
|
||||
write: ChakraHost.echo,
|
||||
readFile(path: string, encoding?: string) {
|
||||
readFile(path: string, _encoding?: string) {
|
||||
// encoding is automatically handled by the implementation in ChakraHost
|
||||
return ChakraHost.readFile(path);
|
||||
},
|
||||
|
@ -595,9 +591,9 @@ namespace ts {
|
|||
getExecutingFilePath: () => ChakraHost.executingFile,
|
||||
getCurrentDirectory: () => ChakraHost.currentDirectory,
|
||||
getDirectories: ChakraHost.getDirectories,
|
||||
getEnvironmentVariable: ChakraHost.getEnvironmentVariable || ((name: string) => ""),
|
||||
getEnvironmentVariable: ChakraHost.getEnvironmentVariable || (() => ""),
|
||||
readDirectory: (path: string, extensions?: string[], excludes?: string[], includes?: string[]) => {
|
||||
const pattern = getFileMatcherPatterns(path, extensions, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory);
|
||||
const pattern = getFileMatcherPatterns(path, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory);
|
||||
return ChakraHost.readDirectory(path, extensions, pattern.basePaths, pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern);
|
||||
},
|
||||
exit: ChakraHost.quit,
|
||||
|
|
|
@ -2,17 +2,19 @@
|
|||
/// <reference path="transformers/ts.ts" />
|
||||
/// <reference path="transformers/jsx.ts" />
|
||||
/// <reference path="transformers/experimental.ts" />
|
||||
/// <reference path="transformers/es7.ts" />
|
||||
/// <reference path="transformers/es6.ts" />
|
||||
/// <reference path="transformers/es2017.ts" />
|
||||
/// <reference path="transformers/es2016.ts" />
|
||||
/// <reference path="transformers/es2015.ts" />
|
||||
/// <reference path="transformers/generators.ts" />
|
||||
/// <reference path="transformers/es5.ts" />
|
||||
/// <reference path="transformers/module/module.ts" />
|
||||
/// <reference path="transformers/module/system.ts" />
|
||||
/// <reference path="transformers/module/es6.ts" />
|
||||
/// <reference path="transformers/module/es2015.ts" />
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
const moduleTransformerMap = createMap<Transformer>({
|
||||
[ModuleKind.ES6]: transformES6Module,
|
||||
[ModuleKind.ES2015]: transformES2015Module,
|
||||
[ModuleKind.System]: transformSystemModule,
|
||||
[ModuleKind.AMD]: transformModule,
|
||||
[ModuleKind.CommonJS]: transformModule,
|
||||
|
@ -117,13 +119,23 @@ namespace ts {
|
|||
}
|
||||
|
||||
transformers.push(transformExperimental);
|
||||
transformers.push(transformES7);
|
||||
if (languageVersion < ScriptTarget.ES2017) {
|
||||
transformers.push(transformES2017);
|
||||
}
|
||||
|
||||
if (languageVersion < ScriptTarget.ES6) {
|
||||
transformers.push(transformES6);
|
||||
if (languageVersion < ScriptTarget.ES2016) {
|
||||
transformers.push(transformES2016);
|
||||
}
|
||||
|
||||
if (languageVersion < ScriptTarget.ES2015) {
|
||||
transformers.push(transformES2015);
|
||||
transformers.push(transformGenerators);
|
||||
}
|
||||
|
||||
if (languageVersion < ScriptTarget.ES5) {
|
||||
transformers.push(transformES5);
|
||||
}
|
||||
|
||||
return transformers;
|
||||
}
|
||||
|
||||
|
@ -155,7 +167,7 @@ namespace ts {
|
|||
hoistFunctionDeclaration,
|
||||
startLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
onSubstituteNode: (emitContext, node) => node,
|
||||
onSubstituteNode: (_emitContext, node) => node,
|
||||
enableSubstitution,
|
||||
isSubstitutionEnabled,
|
||||
onEmitNode: (node, emitContext, emitCallback) => emitCallback(node, emitContext),
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace ts {
|
|||
location = value;
|
||||
}
|
||||
|
||||
flattenDestructuring(context, node, value, location, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
flattenDestructuring(node, value, location, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
|
||||
if (needsValue) {
|
||||
expressions.push(value);
|
||||
|
@ -87,13 +87,12 @@ namespace ts {
|
|||
* @param visitor An optional visitor to use to visit expressions.
|
||||
*/
|
||||
export function flattenParameterDestructuring(
|
||||
context: TransformationContext,
|
||||
node: ParameterDeclaration,
|
||||
value: Expression,
|
||||
visitor?: (node: Node) => VisitResult<Node>) {
|
||||
const declarations: VariableDeclaration[] = [];
|
||||
|
||||
flattenDestructuring(context, node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
|
||||
return declarations;
|
||||
|
||||
|
@ -123,7 +122,6 @@ namespace ts {
|
|||
* @param visitor An optional visitor to use to visit expressions.
|
||||
*/
|
||||
export function flattenVariableDestructuring(
|
||||
context: TransformationContext,
|
||||
node: VariableDeclaration,
|
||||
value?: Expression,
|
||||
visitor?: (node: Node) => VisitResult<Node>,
|
||||
|
@ -131,7 +129,7 @@ namespace ts {
|
|||
const declarations: VariableDeclaration[] = [];
|
||||
|
||||
let pendingAssignments: Expression[];
|
||||
flattenDestructuring(context, node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
|
||||
return declarations;
|
||||
|
||||
|
@ -180,7 +178,6 @@ namespace ts {
|
|||
* @param visitor An optional visitor to use to visit expressions.
|
||||
*/
|
||||
export function flattenVariableDestructuringToExpression(
|
||||
context: TransformationContext,
|
||||
node: VariableDeclaration,
|
||||
recordTempVariable: (name: Identifier) => void,
|
||||
nameSubstitution?: (name: Identifier) => Expression,
|
||||
|
@ -188,7 +185,7 @@ namespace ts {
|
|||
|
||||
const pendingAssignments: Expression[] = [];
|
||||
|
||||
flattenDestructuring(context, node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
flattenDestructuring(node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
|
||||
const expression = inlineExpressions(pendingAssignments);
|
||||
aggregateTransformFlags(expression);
|
||||
|
@ -219,7 +216,6 @@ namespace ts {
|
|||
}
|
||||
|
||||
function flattenDestructuring(
|
||||
context: TransformationContext,
|
||||
root: VariableDeclaration | ParameterDeclaration | BindingElement | BinaryExpression,
|
||||
value: Expression,
|
||||
location: TextRange,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/*@internal*/
|
||||
namespace ts {
|
||||
|
||||
const enum ES6SubstitutionFlags {
|
||||
const enum ES2015SubstitutionFlags {
|
||||
/** Enables substitutions for captured `this` */
|
||||
CapturedThis = 1 << 0,
|
||||
/** Enables substitutions for block-scoped bindings. */
|
||||
|
@ -163,7 +163,7 @@ namespace ts {
|
|||
ReplaceWithReturn,
|
||||
}
|
||||
|
||||
export function transformES6(context: TransformationContext) {
|
||||
export function transformES2015(context: TransformationContext) {
|
||||
const {
|
||||
startLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
|
@ -197,7 +197,7 @@ namespace ts {
|
|||
* They are persisted between each SourceFile transformation and should not
|
||||
* be reset.
|
||||
*/
|
||||
let enabledSubstitutions: ES6SubstitutionFlags;
|
||||
let enabledSubstitutions: ES2015SubstitutionFlags;
|
||||
|
||||
return transformSourceFile;
|
||||
|
||||
|
@ -252,7 +252,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function shouldCheckNode(node: Node): boolean {
|
||||
return (node.transformFlags & TransformFlags.ES6) !== 0 ||
|
||||
return (node.transformFlags & TransformFlags.ES2015) !== 0 ||
|
||||
node.kind === SyntaxKind.LabeledStatement ||
|
||||
(isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node));
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ namespace ts {
|
|||
if (shouldCheckNode(node)) {
|
||||
return visitJavaScript(node);
|
||||
}
|
||||
else if (node.transformFlags & TransformFlags.ContainsES6) {
|
||||
else if (node.transformFlags & TransformFlags.ContainsES2015) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
else {
|
||||
|
@ -396,7 +396,7 @@ namespace ts {
|
|||
return visitYieldExpression(<YieldExpression>node);
|
||||
|
||||
case SyntaxKind.SuperKeyword:
|
||||
return visitSuperKeyword(<PrimaryExpression>node);
|
||||
return visitSuperKeyword();
|
||||
|
||||
case SyntaxKind.YieldExpression:
|
||||
// `yield` will be handled by a generators transform.
|
||||
|
@ -681,6 +681,7 @@ namespace ts {
|
|||
|
||||
const extendsClauseElement = getClassExtendsHeritageClauseElement(node);
|
||||
const classFunction = createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -1117,7 +1118,7 @@ namespace ts {
|
|||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(
|
||||
flattenParameterDestructuring(context, parameter, temp, visitor)
|
||||
flattenParameterDestructuring(parameter, temp, visitor)
|
||||
)
|
||||
),
|
||||
EmitFlags.CustomPrologue
|
||||
|
@ -1416,6 +1417,7 @@ namespace ts {
|
|||
if (getAccessor) {
|
||||
const getterFunction = transformFunctionLikeToExpression(getAccessor, /*location*/ undefined, /*name*/ undefined);
|
||||
setSourceMapRange(getterFunction, getSourceMapRange(getAccessor));
|
||||
setEmitFlags(getterFunction, EmitFlags.NoLeadingComments);
|
||||
const getter = createPropertyAssignment("get", getterFunction);
|
||||
setCommentRange(getter, getCommentRange(getAccessor));
|
||||
properties.push(getter);
|
||||
|
@ -1424,6 +1426,7 @@ namespace ts {
|
|||
if (setAccessor) {
|
||||
const setterFunction = transformFunctionLikeToExpression(setAccessor, /*location*/ undefined, /*name*/ undefined);
|
||||
setSourceMapRange(setterFunction, getSourceMapRange(setAccessor));
|
||||
setEmitFlags(setterFunction, EmitFlags.NoLeadingComments);
|
||||
const setter = createPropertyAssignment("set", setterFunction);
|
||||
setCommentRange(setter, getCommentRange(setAccessor));
|
||||
properties.push(setter);
|
||||
|
@ -1509,6 +1512,7 @@ namespace ts {
|
|||
|
||||
const expression = setOriginalNode(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
node.asteriskToken,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -1686,7 +1690,7 @@ namespace ts {
|
|||
if (decl.initializer) {
|
||||
let assignment: Expression;
|
||||
if (isBindingPattern(decl.name)) {
|
||||
assignment = flattenVariableDestructuringToExpression(context, decl, hoistVariableDeclaration, /*nameSubstitution*/ undefined, visitor);
|
||||
assignment = flattenVariableDestructuringToExpression(decl, hoistVariableDeclaration, /*nameSubstitution*/ undefined, visitor);
|
||||
}
|
||||
else {
|
||||
assignment = createBinary(<Identifier>decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression));
|
||||
|
@ -1839,7 +1843,7 @@ namespace ts {
|
|||
if (isBindingPattern(node.name)) {
|
||||
const recordTempVariablesInLine = !enclosingVariableStatement
|
||||
|| !hasModifier(enclosingVariableStatement, ModifierFlags.Export);
|
||||
return flattenVariableDestructuring(context, node, /*value*/ undefined, visitor,
|
||||
return flattenVariableDestructuring(node, /*value*/ undefined, visitor,
|
||||
recordTempVariablesInLine ? undefined : hoistVariableDeclaration);
|
||||
}
|
||||
|
||||
|
@ -1942,7 +1946,6 @@ namespace ts {
|
|||
// This works whether the declaration is a var, let, or const.
|
||||
// It will use rhsIterationValue _a[_i] as the initializer.
|
||||
const declarations = flattenVariableDestructuring(
|
||||
context,
|
||||
firstOriginalDeclaration,
|
||||
createElementAccess(rhsReference, counter),
|
||||
visitor
|
||||
|
@ -2240,6 +2243,7 @@ namespace ts {
|
|||
/*type*/ undefined,
|
||||
setEmitFlags(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
isAsyncBlockContainingAwait ? createToken(SyntaxKind.AsteriskToken) : undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -2534,15 +2538,15 @@ namespace ts {
|
|||
break;
|
||||
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
expressions.push(transformPropertyAssignmentToExpression(node, <PropertyAssignment>property, receiver, node.multiLine));
|
||||
expressions.push(transformPropertyAssignmentToExpression(<PropertyAssignment>property, receiver, node.multiLine));
|
||||
break;
|
||||
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
expressions.push(transformShorthandPropertyAssignmentToExpression(node, <ShorthandPropertyAssignment>property, receiver, node.multiLine));
|
||||
expressions.push(transformShorthandPropertyAssignmentToExpression(<ShorthandPropertyAssignment>property, receiver, node.multiLine));
|
||||
break;
|
||||
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
expressions.push(transformObjectLiteralMethodDeclarationToExpression(node, <MethodDeclaration>property, receiver, node.multiLine));
|
||||
expressions.push(transformObjectLiteralMethodDeclarationToExpression(<MethodDeclaration>property, receiver, node.multiLine));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -2559,7 +2563,7 @@ namespace ts {
|
|||
* @param property The PropertyAssignment node.
|
||||
* @param receiver The receiver for the assignment.
|
||||
*/
|
||||
function transformPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: PropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
|
||||
function transformPropertyAssignmentToExpression(property: PropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
|
||||
const expression = createAssignment(
|
||||
createMemberAccessForPropertyName(
|
||||
receiver,
|
||||
|
@ -2581,7 +2585,7 @@ namespace ts {
|
|||
* @param property The ShorthandPropertyAssignment node.
|
||||
* @param receiver The receiver for the assignment.
|
||||
*/
|
||||
function transformShorthandPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: ShorthandPropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
|
||||
function transformShorthandPropertyAssignmentToExpression(property: ShorthandPropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
|
||||
const expression = createAssignment(
|
||||
createMemberAccessForPropertyName(
|
||||
receiver,
|
||||
|
@ -2603,7 +2607,7 @@ namespace ts {
|
|||
* @param method The MethodDeclaration node.
|
||||
* @param receiver The receiver for the assignment.
|
||||
*/
|
||||
function transformObjectLiteralMethodDeclarationToExpression(node: ObjectLiteralExpression, method: MethodDeclaration, receiver: Expression, startsOnNewLine: boolean) {
|
||||
function transformObjectLiteralMethodDeclarationToExpression(method: MethodDeclaration, receiver: Expression, startsOnNewLine: boolean) {
|
||||
const expression = createAssignment(
|
||||
createMemberAccessForPropertyName(
|
||||
receiver,
|
||||
|
@ -2793,7 +2797,7 @@ namespace ts {
|
|||
// expressions into an array literal.
|
||||
const numElements = elements.length;
|
||||
const segments = flatten(
|
||||
spanMap(elements, partitionSpread, (partition, visitPartition, start, end) =>
|
||||
spanMap(elements, partitionSpread, (partition, visitPartition, _start, end) =>
|
||||
visitPartition(partition, multiLine, hasTrailingComma && end === numElements)
|
||||
)
|
||||
);
|
||||
|
@ -2815,7 +2819,7 @@ namespace ts {
|
|||
: visitSpanOfNonSpreads;
|
||||
}
|
||||
|
||||
function visitSpanOfSpreads(chunk: Expression[], multiLine: boolean, hasTrailingComma: boolean): VisitResult<Expression> {
|
||||
function visitSpanOfSpreads(chunk: Expression[]): VisitResult<Expression> {
|
||||
return map(chunk, visitExpressionOfSpread);
|
||||
}
|
||||
|
||||
|
@ -3004,7 +3008,7 @@ namespace ts {
|
|||
/**
|
||||
* Visits the `super` keyword
|
||||
*/
|
||||
function visitSuperKeyword(node: PrimaryExpression): LeftHandSideExpression {
|
||||
function visitSuperKeyword(): LeftHandSideExpression {
|
||||
return enclosingNonAsyncFunctionBody
|
||||
&& isClassElement(enclosingNonAsyncFunctionBody)
|
||||
&& !hasModifier(enclosingNonAsyncFunctionBody, ModifierFlags.Static)
|
||||
|
@ -3034,7 +3038,7 @@ namespace ts {
|
|||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
|
||||
const savedEnclosingFunction = enclosingFunction;
|
||||
|
||||
if (enabledSubstitutions & ES6SubstitutionFlags.CapturedThis && isFunctionLike(node)) {
|
||||
if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis && isFunctionLike(node)) {
|
||||
// If we are tracking a captured `this`, keep track of the enclosing function.
|
||||
enclosingFunction = node;
|
||||
}
|
||||
|
@ -3049,8 +3053,8 @@ namespace ts {
|
|||
* contains block-scoped bindings (e.g. `let` or `const`).
|
||||
*/
|
||||
function enableSubstitutionsForBlockScopedBindings() {
|
||||
if ((enabledSubstitutions & ES6SubstitutionFlags.BlockScopedBindings) === 0) {
|
||||
enabledSubstitutions |= ES6SubstitutionFlags.BlockScopedBindings;
|
||||
if ((enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) === 0) {
|
||||
enabledSubstitutions |= ES2015SubstitutionFlags.BlockScopedBindings;
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
}
|
||||
}
|
||||
|
@ -3060,8 +3064,8 @@ namespace ts {
|
|||
* contains a captured `this`.
|
||||
*/
|
||||
function enableSubstitutionsForCapturedThis() {
|
||||
if ((enabledSubstitutions & ES6SubstitutionFlags.CapturedThis) === 0) {
|
||||
enabledSubstitutions |= ES6SubstitutionFlags.CapturedThis;
|
||||
if ((enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis) === 0) {
|
||||
enabledSubstitutions |= ES2015SubstitutionFlags.CapturedThis;
|
||||
context.enableSubstitution(SyntaxKind.ThisKeyword);
|
||||
context.enableEmitNotification(SyntaxKind.Constructor);
|
||||
context.enableEmitNotification(SyntaxKind.MethodDeclaration);
|
||||
|
@ -3100,7 +3104,7 @@ namespace ts {
|
|||
function substituteIdentifier(node: Identifier) {
|
||||
// Only substitute the identifier if we have enabled substitutions for block-scoped
|
||||
// bindings.
|
||||
if (enabledSubstitutions & ES6SubstitutionFlags.BlockScopedBindings) {
|
||||
if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) {
|
||||
const original = getParseTreeNode(node, isIdentifier);
|
||||
if (original && isNameOfDeclarationWithCollidingName(original)) {
|
||||
return getGeneratedNameForNode(original);
|
||||
|
@ -3153,7 +3157,7 @@ namespace ts {
|
|||
* @param node An Identifier node.
|
||||
*/
|
||||
function substituteExpressionIdentifier(node: Identifier): Identifier {
|
||||
if (enabledSubstitutions & ES6SubstitutionFlags.BlockScopedBindings) {
|
||||
if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) {
|
||||
const declaration = resolver.getReferencedDeclarationWithCollidingName(node);
|
||||
if (declaration) {
|
||||
return getGeneratedNameForNode(declaration.name);
|
||||
|
@ -3169,7 +3173,7 @@ namespace ts {
|
|||
* @param node The ThisKeyword node.
|
||||
*/
|
||||
function substituteThisKeyword(node: PrimaryExpression): PrimaryExpression {
|
||||
if (enabledSubstitutions & ES6SubstitutionFlags.CapturedThis
|
||||
if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis
|
||||
&& enclosingFunction
|
||||
&& getEmitFlags(enclosingFunction) & EmitFlags.CapturesThis) {
|
||||
return createIdentifier("_this", /*location*/ node);
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
export function transformES7(context: TransformationContext) {
|
||||
export function transformES2016(context: TransformationContext) {
|
||||
const { hoistVariableDeclaration } = context;
|
||||
|
||||
return transformSourceFile;
|
||||
|
@ -17,10 +17,10 @@ namespace ts {
|
|||
}
|
||||
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
if (node.transformFlags & TransformFlags.ES7) {
|
||||
if (node.transformFlags & TransformFlags.ES2016) {
|
||||
return visitorWorker(node);
|
||||
}
|
||||
else if (node.transformFlags & TransformFlags.ContainsES7) {
|
||||
else if (node.transformFlags & TransformFlags.ContainsES2016) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
else {
|
||||
|
@ -39,7 +39,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function visitBinaryExpression(node: BinaryExpression): Expression {
|
||||
// We are here because ES7 adds support for the exponentiation operator.
|
||||
// We are here because ES2016 adds support for the exponentiation operator.
|
||||
const left = visitNode(node.left, visitor, isExpression);
|
||||
const right = visitNode(node.right, visitor, isExpression);
|
||||
if (node.operatorToken.kind === SyntaxKind.AsteriskAsteriskEqualsToken) {
|
510
src/compiler/transformers/es2017.ts
Normal file
510
src/compiler/transformers/es2017.ts
Normal file
|
@ -0,0 +1,510 @@
|
|||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
type SuperContainer = ClassDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration;
|
||||
|
||||
export function transformES2017(context: TransformationContext) {
|
||||
|
||||
const enum ES2017SubstitutionFlags {
|
||||
/** Enables substitutions for async methods with `super` calls. */
|
||||
AsyncMethodsWithSuper = 1 << 0
|
||||
}
|
||||
|
||||
const {
|
||||
startLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
} = context;
|
||||
|
||||
const resolver = context.getEmitResolver();
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
|
||||
// These variables contain state that changes as we descend into the tree.
|
||||
let currentSourceFileExternalHelpersModuleName: Identifier;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
let currentSuperContainer: SuperContainer;
|
||||
|
||||
// Save the previous transformation hooks.
|
||||
const previousOnEmitNode = context.onEmitNode;
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
|
||||
// Set new transformation hooks.
|
||||
context.onEmitNode = onEmitNode;
|
||||
context.onSubstituteNode = onSubstituteNode;
|
||||
|
||||
let currentScope: SourceFile | Block | ModuleBlock | CaseBlock;
|
||||
|
||||
return transformSourceFile;
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
if (isDeclarationFile(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
currentSourceFileExternalHelpersModuleName = node.externalHelpersModuleName;
|
||||
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function visitorWorker(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
// ES2017 async modifier should be elided for targets < ES2017
|
||||
return undefined;
|
||||
|
||||
case SyntaxKind.AwaitExpression:
|
||||
// ES2017 'await' expressions must be transformed for targets < ES2017.
|
||||
return visitAwaitExpression(<AwaitExpression>node);
|
||||
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
// ES2017 method declarations may be 'async'
|
||||
return visitMethodDeclaration(<MethodDeclaration>node);
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
// ES2017 function declarations may be 'async'
|
||||
return visitFunctionDeclaration(<FunctionDeclaration>node);
|
||||
|
||||
case SyntaxKind.FunctionExpression:
|
||||
// ES2017 function expressions may be 'async'
|
||||
return visitFunctionExpression(<FunctionExpression>node);
|
||||
|
||||
case SyntaxKind.ArrowFunction:
|
||||
// ES2017 arrow functions may be 'async'
|
||||
return visitArrowFunction(<ArrowFunction>node);
|
||||
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an await expression.
|
||||
*
|
||||
* This function will be called any time a ES2017 await expression is encountered.
|
||||
*
|
||||
* @param node The await expression node.
|
||||
*/
|
||||
function visitAwaitExpression(node: AwaitExpression): Expression {
|
||||
return setOriginalNode(
|
||||
createYield(
|
||||
/*asteriskToken*/ undefined,
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
/*location*/ node
|
||||
),
|
||||
node
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a method declaration of a class.
|
||||
*
|
||||
* This function will be called when one of the following conditions are met:
|
||||
* - The node is marked as async
|
||||
*
|
||||
* @param node The method node.
|
||||
*/
|
||||
function visitMethodDeclaration(node: MethodDeclaration) {
|
||||
if (!isAsyncFunctionLike(node)) {
|
||||
return node;
|
||||
}
|
||||
const method = createMethod(
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node),
|
||||
/*location*/ 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(method, node);
|
||||
setSourceMapRange(method, moveRangePastDecorators(node));
|
||||
setOriginalNode(method, node);
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a function declaration.
|
||||
*
|
||||
* This function will be called when one of the following conditions are met:
|
||||
* - The node is marked async
|
||||
*
|
||||
* @param node The function node.
|
||||
*/
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult<Statement> {
|
||||
if (!isAsyncFunctionLike(node)) {
|
||||
return node;
|
||||
}
|
||||
const func = createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node),
|
||||
/*location*/ node
|
||||
);
|
||||
setOriginalNode(func, node);
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a function expression 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.
|
||||
*/
|
||||
function visitFunctionExpression(node: FunctionExpression): Expression {
|
||||
if (!isAsyncFunctionLike(node)) {
|
||||
return node;
|
||||
}
|
||||
if (nodeIsMissing(node.body)) {
|
||||
return createOmittedExpression();
|
||||
}
|
||||
|
||||
const func = createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node),
|
||||
/*location*/ node
|
||||
);
|
||||
|
||||
setOriginalNode(func, node);
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
/**
|
||||
* @remarks
|
||||
* This function will be called when one of the following conditions are met:
|
||||
* - The node is marked async
|
||||
*/
|
||||
function visitArrowFunction(node: ArrowFunction) {
|
||||
if (!isAsyncFunctionLike(node)) {
|
||||
return node;
|
||||
}
|
||||
const func = createArrowFunction(
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
/*type*/ undefined,
|
||||
node.equalsGreaterThanToken,
|
||||
transformConciseBody(node),
|
||||
/*location*/ node
|
||||
);
|
||||
|
||||
setOriginalNode(func, node);
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
function transformFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody {
|
||||
return <FunctionBody>transformAsyncFunctionBody(node);
|
||||
}
|
||||
|
||||
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 nodeType = node.original ? (<FunctionLikeDeclaration>node.original).type : node.type;
|
||||
const promiseConstructor = languageVersion < ScriptTarget.ES2015 ? getPromiseConstructor(nodeType) : undefined;
|
||||
const isArrowFunction = node.kind === SyntaxKind.ArrowFunction;
|
||||
const hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0;
|
||||
|
||||
// An async function is emit as an outer function that calls an inner
|
||||
// generator function. To preserve lexical bindings, we pass the current
|
||||
// `this` and `arguments` objects to `__awaiter`. The generator function
|
||||
// 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,
|
||||
hasLexicalArguments,
|
||||
promiseConstructor,
|
||||
transformFunctionBodyWorker(<Block>node.body, statementOffset)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const block = createBlock(statements, /*location*/ node.body, /*multiLine*/ true);
|
||||
|
||||
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
|
||||
// This step isn't needed if we eventually transform this to ES5.
|
||||
if (languageVersion >= ScriptTarget.ES2015) {
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
setEmitFlags(block, EmitFlags.EmitAdvancedSuperHelper);
|
||||
}
|
||||
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
setEmitFlags(block, EmitFlags.EmitSuperHelper);
|
||||
}
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
else {
|
||||
return createAwaiterHelper(
|
||||
currentSourceFileExternalHelpersModuleName,
|
||||
hasLexicalArguments,
|
||||
promiseConstructor,
|
||||
<Block>transformConciseBodyWorker(node.body, /*forceBlockFunctionBody*/ true)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getPromiseConstructor(type: TypeNode) {
|
||||
const typeName = getEntityNameFromTypeNode(type);
|
||||
if (typeName && isEntityName(typeName)) {
|
||||
const serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
|
||||
if (serializationKind === TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue
|
||||
|| serializationKind === TypeReferenceSerializationKind.Unknown) {
|
||||
return typeName;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function enableSubstitutionForAsyncMethodsWithSuper() {
|
||||
if ((enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper) === 0) {
|
||||
enabledSubstitutions |= ES2017SubstitutionFlags.AsyncMethodsWithSuper;
|
||||
|
||||
// We need to enable substitutions for call, property access, and element access
|
||||
// if we need to rewrite super calls.
|
||||
context.enableSubstitution(SyntaxKind.CallExpression);
|
||||
context.enableSubstitution(SyntaxKind.PropertyAccessExpression);
|
||||
context.enableSubstitution(SyntaxKind.ElementAccessExpression);
|
||||
|
||||
// We need to be notified when entering and exiting declarations that bind super.
|
||||
context.enableEmitNotification(SyntaxKind.ClassDeclaration);
|
||||
context.enableEmitNotification(SyntaxKind.MethodDeclaration);
|
||||
context.enableEmitNotification(SyntaxKind.GetAccessor);
|
||||
context.enableEmitNotification(SyntaxKind.SetAccessor);
|
||||
context.enableEmitNotification(SyntaxKind.Constructor);
|
||||
}
|
||||
}
|
||||
|
||||
function substituteExpression(node: Expression) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return substitutePropertyAccessExpression(<PropertyAccessExpression>node);
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
return substituteElementAccessExpression(<ElementAccessExpression>node);
|
||||
case SyntaxKind.CallExpression:
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper) {
|
||||
return substituteCallExpression(<CallExpression>node);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
const flags = getSuperContainerAsyncMethodFlags();
|
||||
if (flags) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
createLiteral(node.name.text),
|
||||
flags,
|
||||
node
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteElementAccessExpression(node: ElementAccessExpression) {
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
const flags = getSuperContainerAsyncMethodFlags();
|
||||
if (flags) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
node.argumentExpression,
|
||||
flags,
|
||||
node
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteCallExpression(node: CallExpression): Expression {
|
||||
const expression = node.expression;
|
||||
if (isSuperProperty(expression)) {
|
||||
const flags = getSuperContainerAsyncMethodFlags();
|
||||
if (flags) {
|
||||
const argumentExpression = isPropertyAccessExpression(expression)
|
||||
? substitutePropertyAccessExpression(expression)
|
||||
: substituteElementAccessExpression(expression);
|
||||
return createCall(
|
||||
createPropertyAccess(argumentExpression, "call"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createThis(),
|
||||
...node.arguments
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function isSuperContainer(node: Node): node is SuperContainer {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.ClassDeclaration
|
||||
|| kind === SyntaxKind.Constructor
|
||||
|| kind === SyntaxKind.MethodDeclaration
|
||||
|| kind === SyntaxKind.GetAccessor
|
||||
|| kind === SyntaxKind.SetAccessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for node emit.
|
||||
*
|
||||
* @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 {
|
||||
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)) {
|
||||
currentSuperContainer = node;
|
||||
}
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
|
||||
applicableSubstitutions = savedApplicableSubstitutions;
|
||||
currentSuperContainer = savedCurrentSuperContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param node The node to substitute.
|
||||
* @param isExpression A value indicating whether the node is to be used in an expression
|
||||
* position.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (emitContext === EmitContext.Expression) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function createSuperAccessInAsyncMethod(argumentExpression: Expression, flags: NodeCheckFlags, location: TextRange): LeftHandSideExpression {
|
||||
if (flags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
return createPropertyAccess(
|
||||
createCall(
|
||||
createIdentifier("_super"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
"value",
|
||||
location
|
||||
);
|
||||
}
|
||||
else {
|
||||
return createCall(
|
||||
createIdentifier("_super"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression],
|
||||
location
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getSuperContainerAsyncMethodFlags() {
|
||||
return currentSuperContainer !== undefined
|
||||
&& resolver.getNodeCheckFlags(currentSuperContainer) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding);
|
||||
}
|
||||
}
|
||||
}
|
83
src/compiler/transformers/es5.ts
Normal file
83
src/compiler/transformers/es5.ts
Normal file
|
@ -0,0 +1,83 @@
|
|||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
/**
|
||||
* Transforms ES5 syntax into ES3 syntax.
|
||||
*
|
||||
* @param context Context and state information for the transformation.
|
||||
*/
|
||||
export function transformES5(context: TransformationContext) {
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
context.onSubstituteNode = onSubstituteNode;
|
||||
context.enableSubstitution(SyntaxKind.PropertyAccessExpression);
|
||||
context.enableSubstitution(SyntaxKind.PropertyAssignment);
|
||||
return transformSourceFile;
|
||||
|
||||
/**
|
||||
* Transforms an ES5 source file to ES3.
|
||||
*
|
||||
* @param node A SourceFile
|
||||
*/
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext The context for the emitter.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (isPropertyAccessExpression(node)) {
|
||||
return substitutePropertyAccessExpression(node);
|
||||
}
|
||||
else if (isPropertyAssignment(node)) {
|
||||
return substitutePropertyAssignment(node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitutes a PropertyAccessExpression whose name is a reserved word.
|
||||
*
|
||||
* @param node A PropertyAccessExpression
|
||||
*/
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression): Expression {
|
||||
const literalName = trySubstituteReservedName(node.name);
|
||||
if (literalName) {
|
||||
return createElementAccess(node.expression, literalName, /*location*/ node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitutes a PropertyAssignment whose name is a reserved word.
|
||||
*
|
||||
* @param node A PropertyAssignment
|
||||
*/
|
||||
function substitutePropertyAssignment(node: PropertyAssignment): PropertyAssignment {
|
||||
const literalName = isIdentifier(node.name) && trySubstituteReservedName(node.name);
|
||||
if (literalName) {
|
||||
return updatePropertyAssignment(node, literalName, node.initializer);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* If an identifier name is a reserved word, returns a string literal for the name.
|
||||
*
|
||||
* @param name An Identifier
|
||||
*/
|
||||
function trySubstituteReservedName(name: Identifier) {
|
||||
const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(name.text) : undefined);
|
||||
if (token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) {
|
||||
return createLiteral(name, /*location*/ name);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -496,6 +496,7 @@ namespace ts {
|
|||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
node = setOriginalNode(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -955,7 +956,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>, _multiLine?: boolean) {
|
||||
// [source]
|
||||
// ar = [1, yield, 2];
|
||||
//
|
||||
|
@ -1101,7 +1102,7 @@ namespace ts {
|
|||
createFunctionApply(
|
||||
cacheExpression(visitNode(target, visitor, isLeftHandSideExpression)),
|
||||
thisArg,
|
||||
visitElements(node.arguments, /*multiLine*/ false),
|
||||
visitElements(node.arguments),
|
||||
/*location*/ node
|
||||
),
|
||||
node
|
||||
|
@ -1130,7 +1131,7 @@ namespace ts {
|
|||
createFunctionApply(
|
||||
cacheExpression(visitNode(target, visitor, isExpression)),
|
||||
thisArg,
|
||||
visitElements(node.arguments, /*multiLine*/ false)
|
||||
visitElements(node.arguments)
|
||||
),
|
||||
/*typeArguments*/ undefined,
|
||||
[],
|
||||
|
@ -2591,6 +2592,7 @@ namespace ts {
|
|||
createThis(),
|
||||
setEmitFlags(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -3080,4 +3082,4 @@ namespace ts {
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
39
src/compiler/transformers/module/es2015.ts
Normal file
39
src/compiler/transformers/module/es2015.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../visitor.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
export function transformES2015Module(context: TransformationContext) {
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
return transformSourceFile;
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
if (isDeclarationFile(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (isExternalModule(node) || compilerOptions.isolatedModules) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
// Elide `import=` as it is not legal with --module ES6
|
||||
return undefined;
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return visitExportAssignment(<ExportAssignment>node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function visitExportAssignment(node: ExportAssignment): VisitResult<ExportAssignment> {
|
||||
// Elide `export=` as it is not legal with --module ES6
|
||||
return node.isExportEquals ? undefined : node;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../visitor.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
export function transformES6Module(context: TransformationContext) {
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
const resolver = context.getEmitResolver();
|
||||
|
||||
let currentSourceFile: SourceFile;
|
||||
|
||||
return transformSourceFile;
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
if (isDeclarationFile(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (isExternalModule(node) || compilerOptions.isolatedModules) {
|
||||
currentSourceFile = node;
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return visitImportDeclaration(<ImportDeclaration>node);
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return visitImportEqualsDeclaration(<ImportEqualsDeclaration>node);
|
||||
case SyntaxKind.ImportClause:
|
||||
return visitImportClause(<ImportClause>node);
|
||||
case SyntaxKind.NamedImports:
|
||||
case SyntaxKind.NamespaceImport:
|
||||
return visitNamedBindings(<NamedImportBindings>node);
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
return visitImportSpecifier(<ImportSpecifier>node);
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return visitExportAssignment(<ExportAssignment>node);
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return visitExportDeclaration(<ExportDeclaration>node);
|
||||
case SyntaxKind.NamedExports:
|
||||
return visitNamedExports(<NamedExports>node);
|
||||
case SyntaxKind.ExportSpecifier:
|
||||
return visitExportSpecifier(<ExportSpecifier>node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function visitExportAssignment(node: ExportAssignment): ExportAssignment {
|
||||
if (node.isExportEquals) {
|
||||
return undefined; // do not emit export equals for ES6
|
||||
}
|
||||
const original = getOriginalNode(node);
|
||||
return nodeIsSynthesized(original) || resolver.isValueAliasDeclaration(original) ? node : undefined;
|
||||
}
|
||||
|
||||
function visitExportDeclaration(node: ExportDeclaration): ExportDeclaration {
|
||||
if (!node.exportClause) {
|
||||
return resolver.moduleExportsSomeValue(node.moduleSpecifier) ? node : undefined;
|
||||
}
|
||||
if (!resolver.isValueAliasDeclaration(node)) {
|
||||
return undefined;
|
||||
}
|
||||
const newExportClause = visitNode(node.exportClause, visitor, isNamedExports, /*optional*/ true);
|
||||
if (node.exportClause === newExportClause) {
|
||||
return node;
|
||||
}
|
||||
return newExportClause
|
||||
? createExportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
newExportClause,
|
||||
node.moduleSpecifier)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function visitNamedExports(node: NamedExports): NamedExports {
|
||||
const newExports = visitNodes(node.elements, visitor, isExportSpecifier);
|
||||
if (node.elements === newExports) {
|
||||
return node;
|
||||
}
|
||||
return newExports.length ? createNamedExports(newExports) : undefined;
|
||||
}
|
||||
|
||||
function visitExportSpecifier(node: ExportSpecifier): ExportSpecifier {
|
||||
return resolver.isValueAliasDeclaration(node) ? node : undefined;
|
||||
}
|
||||
|
||||
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): ImportEqualsDeclaration {
|
||||
return !isExternalModuleImportEqualsDeclaration(node) || resolver.isReferencedAliasDeclaration(node) ? node : undefined;
|
||||
}
|
||||
|
||||
function visitImportDeclaration(node: ImportDeclaration) {
|
||||
if (node.importClause) {
|
||||
const newImportClause = visitNode(node.importClause, visitor, isImportClause);
|
||||
if (!newImportClause.name && !newImportClause.namedBindings) {
|
||||
return undefined;
|
||||
}
|
||||
else if (newImportClause !== node.importClause) {
|
||||
return createImportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
newImportClause,
|
||||
node.moduleSpecifier);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function visitImportClause(node: ImportClause): ImportClause {
|
||||
let newDefaultImport = node.name;
|
||||
if (!resolver.isReferencedAliasDeclaration(node)) {
|
||||
newDefaultImport = undefined;
|
||||
}
|
||||
const newNamedBindings = visitNode(node.namedBindings, visitor, isNamedImportBindings, /*optional*/ true);
|
||||
return newDefaultImport !== node.name || newNamedBindings !== node.namedBindings
|
||||
? createImportClause(newDefaultImport, newNamedBindings)
|
||||
: node;
|
||||
}
|
||||
|
||||
function visitNamedBindings(node: NamedImportBindings): VisitResult<NamedImportBindings> {
|
||||
if (node.kind === SyntaxKind.NamespaceImport) {
|
||||
return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
|
||||
}
|
||||
else {
|
||||
const newNamedImportElements = visitNodes((<NamedImports>node).elements, visitor, isImportSpecifier);
|
||||
if (!newNamedImportElements || newNamedImportElements.length == 0) {
|
||||
return undefined;
|
||||
}
|
||||
if (newNamedImportElements === (<NamedImports>node).elements) {
|
||||
return node;
|
||||
}
|
||||
return createNamedImports(newNamedImportElements);
|
||||
}
|
||||
}
|
||||
|
||||
function visitImportSpecifier(node: ImportSpecifier) {
|
||||
return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -59,7 +59,7 @@ namespace ts {
|
|||
currentSourceFile = node;
|
||||
|
||||
// Collect information about the external module.
|
||||
({ externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues } = collectExternalModuleInfo(node, resolver));
|
||||
({ externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues } = collectExternalModuleInfo(node));
|
||||
|
||||
// Perform the transformation.
|
||||
const transformModule = transformModuleDelegates[moduleKind] || transformModuleDelegates[ModuleKind.None];
|
||||
|
@ -179,6 +179,7 @@ namespace ts {
|
|||
//
|
||||
// function (require, exports, module1, module2) ...
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -228,7 +229,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function addExportEqualsIfNeeded(statements: Statement[], emitAsReturn: boolean) {
|
||||
if (exportEquals && resolver.isValueAliasDeclaration(exportEquals)) {
|
||||
if (exportEquals) {
|
||||
if (emitAsReturn) {
|
||||
const statement = createReturn(
|
||||
exportEquals.expression,
|
||||
|
@ -415,7 +416,7 @@ namespace ts {
|
|||
)
|
||||
],
|
||||
/*location*/ undefined,
|
||||
/*flags*/ languageVersion >= ScriptTarget.ES6 ? NodeFlags.Const : NodeFlags.None),
|
||||
/*flags*/ languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None),
|
||||
/*location*/ node
|
||||
)
|
||||
);
|
||||
|
@ -461,23 +462,21 @@ namespace ts {
|
|||
);
|
||||
}
|
||||
for (const specifier of node.exportClause.elements) {
|
||||
if (resolver.isValueAliasDeclaration(specifier)) {
|
||||
const exportedValue = createPropertyAccess(
|
||||
generatedName,
|
||||
specifier.propertyName || specifier.name
|
||||
);
|
||||
statements.push(
|
||||
createStatement(
|
||||
createExportAssignment(specifier.name, exportedValue),
|
||||
/*location*/ specifier
|
||||
)
|
||||
);
|
||||
}
|
||||
const exportedValue = createPropertyAccess(
|
||||
generatedName,
|
||||
specifier.propertyName || specifier.name
|
||||
);
|
||||
statements.push(
|
||||
createStatement(
|
||||
createExportAssignment(specifier.name, exportedValue),
|
||||
/*location*/ specifier
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return singleOrMany(statements);
|
||||
}
|
||||
else if (resolver.moduleExportsSomeValue(node.moduleSpecifier)) {
|
||||
else {
|
||||
// export * from "mod";
|
||||
return createStatement(
|
||||
createCall(
|
||||
|
@ -495,15 +494,14 @@ namespace ts {
|
|||
}
|
||||
|
||||
function visitExportAssignment(node: ExportAssignment): VisitResult<Statement> {
|
||||
if (!node.isExportEquals) {
|
||||
if (nodeIsSynthesized(node) || resolver.isValueAliasDeclaration(node)) {
|
||||
const statements: Statement[] = [];
|
||||
addExportDefault(statements, node.expression, /*location*/ node);
|
||||
return statements;
|
||||
}
|
||||
if (node.isExportEquals) {
|
||||
// Elide as `export=` is handled in addExportEqualsIfNeeded
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
const statements: Statement[] = [];
|
||||
addExportDefault(statements, node.expression, /*location*/ node);
|
||||
return statements;
|
||||
}
|
||||
|
||||
function addExportDefault(statements: Statement[], expression: Expression, location: TextRange): void {
|
||||
|
@ -568,7 +566,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function collectExportMembers(names: Identifier[], node: Node): Identifier[] {
|
||||
if (isAliasSymbolDeclaration(node) && resolver.isValueAliasDeclaration(node) && isDeclaration(node)) {
|
||||
if (isAliasSymbolDeclaration(node) && isDeclaration(node)) {
|
||||
const name = node.name;
|
||||
if (isIdentifier(name)) {
|
||||
names.push(name);
|
||||
|
@ -682,7 +680,6 @@ namespace ts {
|
|||
const name = node.name;
|
||||
if (isBindingPattern(name)) {
|
||||
return flattenVariableDestructuringToExpression(
|
||||
context,
|
||||
node,
|
||||
hoistVariableDeclaration,
|
||||
getModuleMemberName,
|
||||
|
@ -701,11 +698,13 @@ namespace ts {
|
|||
const statements: Statement[] = [];
|
||||
const name = node.name || getGeneratedNameForNode(node);
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
// Keep async modifier for ES2017 transformer
|
||||
const isAsync = hasModifier(node, ModifierFlags.Async);
|
||||
statements.push(
|
||||
setOriginalNode(
|
||||
createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
isAsync ? [<Modifier>createNode(SyntaxKind.AsyncKeyword)] : undefined,
|
||||
node.asteriskToken,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -958,39 +957,19 @@ namespace ts {
|
|||
const declaration = resolver.getReferencedImportDeclaration(node);
|
||||
if (declaration) {
|
||||
if (isImportClause(declaration)) {
|
||||
if (languageVersion >= ScriptTarget.ES5) {
|
||||
return createPropertyAccess(
|
||||
getGeneratedNameForNode(declaration.parent),
|
||||
createIdentifier("default"),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
else {
|
||||
// TODO: ES3 transform to handle x.default -> x["default"]
|
||||
return createElementAccess(
|
||||
getGeneratedNameForNode(declaration.parent),
|
||||
createLiteral("default"),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
return createPropertyAccess(
|
||||
getGeneratedNameForNode(declaration.parent),
|
||||
createIdentifier("default"),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
else if (isImportSpecifier(declaration)) {
|
||||
const name = declaration.propertyName || declaration.name;
|
||||
if (name.originalKeywordKind === SyntaxKind.DefaultKeyword && languageVersion <= ScriptTarget.ES3) {
|
||||
// TODO: ES3 transform to handle x.default -> x["default"]
|
||||
return createElementAccess(
|
||||
getGeneratedNameForNode(declaration.parent.parent.parent),
|
||||
createLiteral(name.text),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
else {
|
||||
return createPropertyAccess(
|
||||
getGeneratedNameForNode(declaration.parent.parent.parent),
|
||||
getSynthesizedClone(name),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
return createPropertyAccess(
|
||||
getGeneratedNameForNode(declaration.parent.parent.parent),
|
||||
getSynthesizedClone(name),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1027,15 +1006,10 @@ namespace ts {
|
|||
|
||||
function createExportAssignment(name: Identifier, value: Expression) {
|
||||
return createAssignment(
|
||||
name.originalKeywordKind === SyntaxKind.DefaultKeyword && languageVersion === ScriptTarget.ES3
|
||||
? createElementAccess(
|
||||
createIdentifier("exports"),
|
||||
createLiteral(name.text)
|
||||
)
|
||||
: createPropertyAccess(
|
||||
createIdentifier("exports"),
|
||||
getSynthesizedClone(name)
|
||||
),
|
||||
createPropertyAccess(
|
||||
createIdentifier("exports"),
|
||||
getSynthesizedClone(name)
|
||||
),
|
||||
value
|
||||
);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ namespace ts {
|
|||
const compilerOptions = context.getCompilerOptions();
|
||||
const resolver = context.getEmitResolver();
|
||||
const host = context.getEmitHost();
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
const previousOnEmitNode = context.onEmitNode;
|
||||
context.onSubstituteNode = onSubstituteNode;
|
||||
|
@ -91,7 +90,7 @@ namespace ts {
|
|||
Debug.assert(!exportFunctionForFile);
|
||||
|
||||
// Collect information about the external module and dependency groups.
|
||||
({ externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues } = collectExternalModuleInfo(node, resolver));
|
||||
({ externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues } = collectExternalModuleInfo(node));
|
||||
|
||||
// Make sure that the name of the 'exports' function does not conflict with
|
||||
// existing identifiers.
|
||||
|
@ -110,6 +109,7 @@ namespace ts {
|
|||
const moduleName = tryGetModuleNameFromFile(node, host, compilerOptions);
|
||||
const dependencies = createArrayLiteral(map(dependencyGroups, getNameOfDependencyGroup));
|
||||
const body = createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -244,6 +244,7 @@ namespace ts {
|
|||
),
|
||||
createPropertyAssignment("execute",
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -430,6 +431,7 @@ namespace ts {
|
|||
|
||||
setters.push(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -573,28 +575,23 @@ namespace ts {
|
|||
}
|
||||
|
||||
function visitExportSpecifier(specifier: ExportSpecifier): Statement {
|
||||
if (resolver.getReferencedValueDeclaration(specifier.propertyName || specifier.name)
|
||||
|| resolver.isValueAliasDeclaration(specifier)) {
|
||||
recordExportName(specifier.name);
|
||||
return createExportStatement(
|
||||
specifier.name,
|
||||
specifier.propertyName || specifier.name
|
||||
);
|
||||
}
|
||||
return undefined;
|
||||
recordExportName(specifier.name);
|
||||
return createExportStatement(
|
||||
specifier.name,
|
||||
specifier.propertyName || specifier.name
|
||||
);
|
||||
}
|
||||
|
||||
function visitExportAssignment(node: ExportAssignment): Statement {
|
||||
if (!node.isExportEquals) {
|
||||
if (nodeIsSynthesized(node) || resolver.isValueAliasDeclaration(node)) {
|
||||
return createExportStatement(
|
||||
createLiteral("default"),
|
||||
node.expression
|
||||
);
|
||||
}
|
||||
if (node.isExportEquals) {
|
||||
// Elide `export=` as it is illegal in a SystemJS module.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return createExportStatement(
|
||||
createLiteral("default"),
|
||||
node.expression
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -649,7 +646,7 @@ namespace ts {
|
|||
}
|
||||
else {
|
||||
// If the variable has a BindingPattern, flatten the variable into multiple assignment expressions.
|
||||
return flattenVariableDestructuringToExpression(context, node, hoistVariableDeclaration);
|
||||
return flattenVariableDestructuringToExpression(node, hoistVariableDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -662,9 +659,11 @@ namespace ts {
|
|||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
// If the function is exported, ensure it has a name and rewrite the function without any export flags.
|
||||
const name = node.name || getGeneratedNameForNode(node);
|
||||
// Keep async modifier for ES2017 transformer
|
||||
const isAsync = hasModifier(node, ModifierFlags.Async);
|
||||
const newNode = createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
isAsync ? [<Modifier>createNode(SyntaxKind.AsyncKeyword)] : undefined,
|
||||
node.asteriskToken,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -796,7 +795,7 @@ namespace ts {
|
|||
const name = firstDeclaration.name;
|
||||
return isIdentifier(name)
|
||||
? name
|
||||
: flattenVariableDestructuringToExpression(context, firstDeclaration, hoistVariableDeclaration);
|
||||
: flattenVariableDestructuringToExpression(firstDeclaration, hoistVariableDeclaration);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1317,12 +1316,7 @@ namespace ts {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
if (name.originalKeywordKind && languageVersion === ScriptTarget.ES3) {
|
||||
return createElementAccess(importAlias, createLiteral(name.text));
|
||||
}
|
||||
else {
|
||||
return createPropertyAccess(importAlias, getSynthesizedClone(name));
|
||||
}
|
||||
return createPropertyAccess(importAlias, getSynthesizedClone(name));
|
||||
}
|
||||
|
||||
function collectDependencyGroups(externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]) {
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
type SuperContainer = ClassDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration;
|
||||
|
||||
/**
|
||||
* Indicates whether to emit type metadata in the new format.
|
||||
*/
|
||||
|
@ -16,8 +14,6 @@ namespace ts {
|
|||
ClassAliases = 1 << 0,
|
||||
/** Enables substitutions for namespace exports. */
|
||||
NamespaceExports = 1 << 1,
|
||||
/** Enables substitutions for async methods with `super` calls. */
|
||||
AsyncMethodsWithSuper = 1 << 2,
|
||||
/* Enables substitutions for unqualified enum members */
|
||||
NonQualifiedEnumMembers = 1 << 3
|
||||
}
|
||||
|
@ -72,12 +68,6 @@ namespace ts {
|
|||
*/
|
||||
let applicableSubstitutions: TypeScriptSubstitutionFlags;
|
||||
|
||||
/**
|
||||
* This keeps track of containers where `super` is valid, for use with
|
||||
* just-in-time substitution for `super` expressions inside of async methods.
|
||||
*/
|
||||
let currentSuperContainer: SuperContainer;
|
||||
|
||||
return transformSourceFile;
|
||||
|
||||
/**
|
||||
|
@ -147,6 +137,35 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialized visitor that visits the immediate children of a SourceFile.
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function sourceElementVisitor(node: Node): VisitResult<Node> {
|
||||
return saveStateAndInvoke(node, sourceElementVisitorWorker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialized visitor that visits the immediate children of a SourceFile.
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function sourceElementVisitorWorker(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return visitImportDeclaration(<ImportDeclaration>node);
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return visitImportEqualsDeclaration(<ImportEqualsDeclaration>node);
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return visitExportAssignment(<ExportAssignment>node);
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return visitExportDeclaration(<ExportDeclaration>node);
|
||||
default:
|
||||
return visitorWorker(node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialized visitor that visits the immediate children of a namespace.
|
||||
*
|
||||
|
@ -244,7 +263,6 @@ namespace ts {
|
|||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
case SyntaxKind.ReadonlyKeyword:
|
||||
|
@ -286,8 +304,7 @@ namespace ts {
|
|||
// TypeScript property declarations are elided.
|
||||
|
||||
case SyntaxKind.Constructor:
|
||||
// TypeScript constructors are transformed in `visitClassDeclaration`.
|
||||
return undefined;
|
||||
return visitConstructor(<ConstructorDeclaration>node);
|
||||
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
// TypeScript interfaces are elided, but some comments may be preserved.
|
||||
|
@ -304,7 +321,6 @@ namespace ts {
|
|||
// - property declarations
|
||||
// - index signatures
|
||||
// - method overload signatures
|
||||
// - async methods
|
||||
return visitClassDeclaration(<ClassDeclaration>node);
|
||||
|
||||
case SyntaxKind.ClassExpression:
|
||||
|
@ -317,7 +333,6 @@ namespace ts {
|
|||
// - property declarations
|
||||
// - index signatures
|
||||
// - method overload signatures
|
||||
// - async methods
|
||||
return visitClassExpression(<ClassExpression>node);
|
||||
|
||||
case SyntaxKind.HeritageClause:
|
||||
|
@ -332,7 +347,7 @@ namespace ts {
|
|||
return visitExpressionWithTypeArguments(<ExpressionWithTypeArguments>node);
|
||||
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
// TypeScript method declarations may be 'async', and may have decorators, modifiers
|
||||
// TypeScript method declarations may have decorators, modifiers
|
||||
// or type annotations.
|
||||
return visitMethodDeclaration(<MethodDeclaration>node);
|
||||
|
||||
|
@ -341,19 +356,19 @@ namespace ts {
|
|||
return visitGetAccessor(<GetAccessorDeclaration>node);
|
||||
|
||||
case SyntaxKind.SetAccessor:
|
||||
// Set Accessors can have TypeScript modifiers, decorators, and type annotations.
|
||||
// Set Accessors can have TypeScript modifiers and type annotations.
|
||||
return visitSetAccessor(<SetAccessorDeclaration>node);
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
// TypeScript function declarations may be 'async'
|
||||
// Typescript function declarations can have modifiers, decorators, and type annotations.
|
||||
return visitFunctionDeclaration(<FunctionDeclaration>node);
|
||||
|
||||
case SyntaxKind.FunctionExpression:
|
||||
// TypeScript function expressions may be 'async'
|
||||
// TypeScript function expressions can have modifiers and type annotations.
|
||||
return visitFunctionExpression(<FunctionExpression>node);
|
||||
|
||||
case SyntaxKind.ArrowFunction:
|
||||
// TypeScript arrow functions may be 'async'
|
||||
// TypeScript arrow functions can have modifiers and type annotations.
|
||||
return visitArrowFunction(<ArrowFunction>node);
|
||||
|
||||
case SyntaxKind.Parameter:
|
||||
|
@ -377,6 +392,12 @@ namespace ts {
|
|||
// TypeScript type assertions are removed, but their subtrees are preserved.
|
||||
return visitAssertionExpression(<AssertionExpression>node);
|
||||
|
||||
case SyntaxKind.CallExpression:
|
||||
return visitCallExpression(<CallExpression>node);
|
||||
|
||||
case SyntaxKind.NewExpression:
|
||||
return visitNewExpression(<NewExpression>node);
|
||||
|
||||
case SyntaxKind.NonNullExpression:
|
||||
// TypeScript non-null expressions are removed, but their subtrees are preserved.
|
||||
return visitNonNullExpression(<NonNullExpression>node);
|
||||
|
@ -385,14 +406,13 @@ namespace ts {
|
|||
// TypeScript enum declarations do not exist in ES6 and must be rewritten.
|
||||
return visitEnumDeclaration(<EnumDeclaration>node);
|
||||
|
||||
case SyntaxKind.AwaitExpression:
|
||||
// TypeScript 'await' expressions must be transformed.
|
||||
return visitAwaitExpression(<AwaitExpression>node);
|
||||
|
||||
case SyntaxKind.VariableStatement:
|
||||
// TypeScript namespace exports for variable statements must be transformed.
|
||||
return visitVariableStatement(<VariableStatement>node);
|
||||
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return visitVariableDeclaration(<VariableDeclaration>node);
|
||||
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
// TypeScript namespace declarations must be transformed.
|
||||
return visitModuleDeclaration(<ModuleDeclaration>node);
|
||||
|
@ -462,7 +482,7 @@ namespace ts {
|
|||
statements.push(externalHelpersModuleImport);
|
||||
|
||||
currentSourceFileExternalHelpersModuleName = externalHelpersModuleName;
|
||||
addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset));
|
||||
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
currentSourceFileExternalHelpersModuleName = undefined;
|
||||
|
||||
|
@ -470,7 +490,7 @@ namespace ts {
|
|||
node.externalHelpersModuleName = externalHelpersModuleName;
|
||||
}
|
||||
else {
|
||||
node = visitEachChild(node, visitor, context);
|
||||
node = visitEachChild(node, sourceElementVisitor, context);
|
||||
}
|
||||
|
||||
setEmitFlags(node, EmitFlags.EmitEmitHelpers | getEmitFlags(node));
|
||||
|
@ -560,7 +580,7 @@ namespace ts {
|
|||
// HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using
|
||||
// a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
|
||||
if (staticProperties.length) {
|
||||
addInitializedPropertyStatements(statements, node, staticProperties, getLocalName(node, /*noSourceMaps*/ true));
|
||||
addInitializedPropertyStatements(statements, staticProperties, getLocalName(node, /*noSourceMaps*/ true));
|
||||
}
|
||||
|
||||
// Write any decorators of the node.
|
||||
|
@ -775,7 +795,7 @@ namespace ts {
|
|||
function visitClassExpression(node: ClassExpression): Expression {
|
||||
const staticProperties = getInitializedProperties(node, /*isStatic*/ true);
|
||||
const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause);
|
||||
const members = transformClassMembers(node, heritageClauses !== undefined);
|
||||
const members = transformClassMembers(node, some(heritageClauses, c => c.token === SyntaxKind.ExtendsKeyword));
|
||||
|
||||
const classExpression = setOriginalNode(
|
||||
createClassExpression(
|
||||
|
@ -802,7 +822,7 @@ namespace ts {
|
|||
// the body of a class with static initializers.
|
||||
setEmitFlags(classExpression, EmitFlags.Indented | getEmitFlags(classExpression));
|
||||
expressions.push(startOnNewLine(createAssignment(temp, classExpression)));
|
||||
addRange(expressions, generateInitializedPropertyExpressions(node, staticProperties, temp));
|
||||
addRange(expressions, generateInitializedPropertyExpressions(staticProperties, temp));
|
||||
expressions.push(startOnNewLine(temp));
|
||||
return inlineExpressions(expressions);
|
||||
}
|
||||
|
@ -848,7 +868,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
const parameters = transformConstructorParameters(constructor);
|
||||
const body = transformConstructorBody(node, constructor, hasExtendsClause, parameters);
|
||||
const body = transformConstructorBody(node, constructor, hasExtendsClause);
|
||||
|
||||
// constructor(${parameters}) {
|
||||
// ${body}
|
||||
|
@ -902,9 +922,8 @@ namespace ts {
|
|||
* @param node The current class.
|
||||
* @param constructor The current class constructor.
|
||||
* @param hasExtendsClause A value indicating whether the class has an extends clause.
|
||||
* @param parameters The transformed parameters for the constructor.
|
||||
*/
|
||||
function transformConstructorBody(node: ClassExpression | ClassDeclaration, constructor: ConstructorDeclaration, hasExtendsClause: boolean, parameters: ParameterDeclaration[]) {
|
||||
function transformConstructorBody(node: ClassExpression | ClassDeclaration, constructor: ConstructorDeclaration, hasExtendsClause: boolean) {
|
||||
const statements: Statement[] = [];
|
||||
let indexOfFirstStatement = 0;
|
||||
|
||||
|
@ -956,7 +975,7 @@ namespace ts {
|
|||
// }
|
||||
//
|
||||
const properties = getInitializedProperties(node, /*isStatic*/ false);
|
||||
addInitializedPropertyStatements(statements, node, properties, createThis());
|
||||
addInitializedPropertyStatements(statements, properties, createThis());
|
||||
|
||||
if (constructor) {
|
||||
// The class already had a constructor, so we should add the existing statements, skipping the initial super call.
|
||||
|
@ -1096,13 +1115,12 @@ namespace ts {
|
|||
/**
|
||||
* Generates assignment statements for property initializers.
|
||||
*
|
||||
* @param node The class node.
|
||||
* @param properties An array of property declarations to transform.
|
||||
* @param receiver The receiver on which each property should be assigned.
|
||||
*/
|
||||
function addInitializedPropertyStatements(statements: Statement[], node: ClassExpression | ClassDeclaration, properties: PropertyDeclaration[], receiver: LeftHandSideExpression) {
|
||||
function addInitializedPropertyStatements(statements: Statement[], properties: PropertyDeclaration[], receiver: LeftHandSideExpression) {
|
||||
for (const property of properties) {
|
||||
const statement = createStatement(transformInitializedProperty(node, property, receiver));
|
||||
const statement = createStatement(transformInitializedProperty(property, receiver));
|
||||
setSourceMapRange(statement, moveRangePastModifiers(property));
|
||||
setCommentRange(statement, property);
|
||||
statements.push(statement);
|
||||
|
@ -1112,14 +1130,13 @@ namespace ts {
|
|||
/**
|
||||
* Generates assignment expressions for property initializers.
|
||||
*
|
||||
* @param node The class node.
|
||||
* @param properties An array of property declarations to transform.
|
||||
* @param receiver The receiver on which each property should be assigned.
|
||||
*/
|
||||
function generateInitializedPropertyExpressions(node: ClassExpression | ClassDeclaration, properties: PropertyDeclaration[], receiver: LeftHandSideExpression) {
|
||||
function generateInitializedPropertyExpressions(properties: PropertyDeclaration[], receiver: LeftHandSideExpression) {
|
||||
const expressions: Expression[] = [];
|
||||
for (const property of properties) {
|
||||
const expression = transformInitializedProperty(node, property, receiver);
|
||||
const expression = transformInitializedProperty(property, receiver);
|
||||
expression.startsOnNewLine = true;
|
||||
setSourceMapRange(expression, moveRangePastModifiers(property));
|
||||
setCommentRange(expression, property);
|
||||
|
@ -1132,11 +1149,10 @@ namespace ts {
|
|||
/**
|
||||
* Transforms a property initializer into an assignment statement.
|
||||
*
|
||||
* @param node The class containing the property.
|
||||
* @param property The property declaration.
|
||||
* @param receiver The object receiving the property assignment.
|
||||
*/
|
||||
function transformInitializedProperty(node: ClassExpression | ClassDeclaration, property: PropertyDeclaration, receiver: LeftHandSideExpression) {
|
||||
function transformInitializedProperty(property: PropertyDeclaration, receiver: LeftHandSideExpression) {
|
||||
const propertyName = visitPropertyNameOfClassElement(property);
|
||||
const initializer = visitNode(property.initializer, visitor, isExpression);
|
||||
const memberAccess = createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName);
|
||||
|
@ -1799,7 +1815,7 @@ namespace ts {
|
|||
return createIdentifier("Number");
|
||||
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
return languageVersion < ScriptTarget.ES6
|
||||
return languageVersion < ScriptTarget.ES2015
|
||||
? getGlobalSymbolNameWithFallback()
|
||||
: createIdentifier("Symbol");
|
||||
|
||||
|
@ -1896,7 +1912,7 @@ namespace ts {
|
|||
return createIdentifier("Array");
|
||||
|
||||
case TypeReferenceSerializationKind.ESSymbolType:
|
||||
return languageVersion < ScriptTarget.ES6
|
||||
return languageVersion < ScriptTarget.ES2015
|
||||
? getGlobalSymbolNameWithFallback()
|
||||
: createIdentifier("Symbol");
|
||||
|
||||
|
@ -2088,12 +2104,20 @@ namespace ts {
|
|||
return !nodeIsMissing(node.body);
|
||||
}
|
||||
|
||||
function visitConstructor(node: ConstructorDeclaration) {
|
||||
if (!shouldEmitFunctionLikeDeclaration(node)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a method declaration of a class.
|
||||
*
|
||||
* This function will be called when one of the following conditions are met:
|
||||
* - The node is an overload
|
||||
* - The node is marked as abstract, async, public, private, protected, or readonly
|
||||
* - The node is marked as abstract, public, private, protected, or readonly
|
||||
* - The node has both a decorator and a computed property name
|
||||
*
|
||||
* @param node The method node.
|
||||
|
@ -2204,8 +2228,8 @@ namespace ts {
|
|||
*
|
||||
* This function will be called when one of the following conditions are met:
|
||||
* - The node is an overload
|
||||
* - The node is marked async
|
||||
* - The node is exported from a TypeScript namespace
|
||||
* - The node has decorators
|
||||
*
|
||||
* @param node The function node.
|
||||
*/
|
||||
|
@ -2240,7 +2264,7 @@ namespace ts {
|
|||
* Visits a function expression node.
|
||||
*
|
||||
* This function will be called when one of the following conditions are met:
|
||||
* - The node is marked async
|
||||
* - The node has type annotations
|
||||
*
|
||||
* @param node The function expression node.
|
||||
*/
|
||||
|
@ -2250,6 +2274,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
const func = createFunctionExpression(
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -2267,11 +2292,11 @@ namespace ts {
|
|||
/**
|
||||
* @remarks
|
||||
* This function will be called when one of the following conditions are met:
|
||||
* - The node is marked async
|
||||
* - The node has type annotations
|
||||
*/
|
||||
function visitArrowFunction(node: ArrowFunction) {
|
||||
const func = createArrowFunction(
|
||||
/*modifiers*/ undefined,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
/*type*/ undefined,
|
||||
|
@ -2286,30 +2311,25 @@ namespace ts {
|
|||
}
|
||||
|
||||
function transformFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody {
|
||||
if (isAsyncFunctionLike(node)) {
|
||||
return <FunctionBody>transformAsyncFunctionBody(node);
|
||||
}
|
||||
|
||||
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 {
|
||||
if (isAsyncFunctionLike(node)) {
|
||||
return transformAsyncFunctionBody(node);
|
||||
}
|
||||
|
||||
return transformConciseBodyWorker(node.body, /*forceBlockFunctionBody*/ false);
|
||||
}
|
||||
|
||||
|
@ -2333,72 +2353,6 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function getPromiseConstructor(type: TypeNode) {
|
||||
const typeName = getEntityNameFromTypeNode(type);
|
||||
if (typeName && isEntityName(typeName)) {
|
||||
const serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
|
||||
if (serializationKind === TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue
|
||||
|| serializationKind === TypeReferenceSerializationKind.Unknown) {
|
||||
return typeName;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function transformAsyncFunctionBody(node: FunctionLikeDeclaration): ConciseBody | FunctionBody {
|
||||
const promiseConstructor = languageVersion < ScriptTarget.ES6 ? getPromiseConstructor(node.type) : undefined;
|
||||
const isArrowFunction = node.kind === SyntaxKind.ArrowFunction;
|
||||
const hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0;
|
||||
|
||||
// An async function is emit as an outer function that calls an inner
|
||||
// generator function. To preserve lexical bindings, we pass the current
|
||||
// `this` and `arguments` objects to `__awaiter`. The generator function
|
||||
// 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,
|
||||
hasLexicalArguments,
|
||||
promiseConstructor,
|
||||
transformFunctionBodyWorker(<Block>node.body, statementOffset)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const block = createBlock(statements, /*location*/ node.body, /*multiLine*/ true);
|
||||
|
||||
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
|
||||
// This step isn't needed if we eventually transform this to ES5.
|
||||
if (languageVersion >= ScriptTarget.ES6) {
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
setEmitFlags(block, EmitFlags.EmitAdvancedSuperHelper);
|
||||
}
|
||||
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
setEmitFlags(block, EmitFlags.EmitSuperHelper);
|
||||
}
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
else {
|
||||
return createAwaiterHelper(
|
||||
currentSourceFileExternalHelpersModuleName,
|
||||
hasLexicalArguments,
|
||||
promiseConstructor,
|
||||
<Block>transformConciseBodyWorker(node.body, /*forceBlockFunctionBody*/ true)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a parameter declaration node.
|
||||
*
|
||||
|
@ -2465,7 +2419,6 @@ namespace ts {
|
|||
const name = node.name;
|
||||
if (isBindingPattern(name)) {
|
||||
return flattenVariableDestructuringToExpression(
|
||||
context,
|
||||
node,
|
||||
hoistVariableDeclaration,
|
||||
getNamespaceMemberNameWithSourceMapsAndWithoutComments,
|
||||
|
@ -2481,22 +2434,12 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an await expression.
|
||||
*
|
||||
* This function will be called any time a TypeScript await expression is encountered.
|
||||
*
|
||||
* @param node The await expression node.
|
||||
*/
|
||||
function visitAwaitExpression(node: AwaitExpression): Expression {
|
||||
return setOriginalNode(
|
||||
createYield(
|
||||
/*asteriskToken*/ undefined,
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
/*location*/ node
|
||||
),
|
||||
node
|
||||
);
|
||||
function visitVariableDeclaration(node: VariableDeclaration) {
|
||||
return updateVariableDeclaration(
|
||||
node,
|
||||
visitNode(node.name, visitor, isBindingName),
|
||||
/*type*/ undefined,
|
||||
visitNode(node.initializer, visitor, isExpression));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2541,6 +2484,22 @@ namespace ts {
|
|||
return createPartiallyEmittedExpression(expression, node);
|
||||
}
|
||||
|
||||
function visitCallExpression(node: CallExpression) {
|
||||
return updateCall(
|
||||
node,
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
/*typeArguments*/ undefined,
|
||||
visitNodes(node.arguments, visitor, isExpression));
|
||||
}
|
||||
|
||||
function visitNewExpression(node: NewExpression) {
|
||||
return updateNew(
|
||||
node,
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
/*typeArguments*/ undefined,
|
||||
visitNodes(node.arguments, visitor, isExpression));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether to emit an enum declaration.
|
||||
*
|
||||
|
@ -2622,6 +2581,7 @@ namespace ts {
|
|||
const enumStatement = createStatement(
|
||||
createCall(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -2735,7 +2695,7 @@ namespace ts {
|
|||
|
||||
function isES6ExportedDeclaration(node: Node) {
|
||||
return isExternalModuleExport(node)
|
||||
&& moduleKind === ModuleKind.ES6;
|
||||
&& moduleKind === ModuleKind.ES2015;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2893,6 +2853,7 @@ namespace ts {
|
|||
const moduleStatement = createStatement(
|
||||
createCall(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
|
@ -2998,6 +2959,133 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an import declaration, eliding it if it is not referenced.
|
||||
*
|
||||
* @param node The import declaration node.
|
||||
*/
|
||||
function visitImportDeclaration(node: ImportDeclaration): VisitResult<Statement> {
|
||||
if (!node.importClause) {
|
||||
// Do not elide a side-effect only import declaration.
|
||||
// import "foo";
|
||||
return node;
|
||||
}
|
||||
|
||||
// Elide the declaration if the import clause was elided.
|
||||
const importClause = visitNode(node.importClause, visitImportClause, isImportClause, /*optional*/ true);
|
||||
return importClause
|
||||
? updateImportDeclaration(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
importClause,
|
||||
node.moduleSpecifier)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an import clause, eliding it if it is not referenced.
|
||||
*
|
||||
* @param node The import clause node.
|
||||
*/
|
||||
function visitImportClause(node: ImportClause): VisitResult<ImportClause> {
|
||||
// Elide the import clause if we elide both its name and its named bindings.
|
||||
const name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined;
|
||||
const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings, /*optional*/ true);
|
||||
return (name || namedBindings) ? updateImportClause(node, name, namedBindings) : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits named import bindings, eliding it if it is not referenced.
|
||||
*
|
||||
* @param node The named import bindings node.
|
||||
*/
|
||||
function visitNamedImportBindings(node: NamedImportBindings): VisitResult<NamedImportBindings> {
|
||||
if (node.kind === SyntaxKind.NamespaceImport) {
|
||||
// Elide a namespace import if it is not referenced.
|
||||
return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
|
||||
}
|
||||
else {
|
||||
// Elide named imports if all of its import specifiers are elided.
|
||||
const elements = visitNodes(node.elements, visitImportSpecifier, isImportSpecifier);
|
||||
return some(elements) ? updateNamedImports(node, elements) : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an import specifier, eliding it if it is not referenced.
|
||||
*
|
||||
* @param node The import specifier node.
|
||||
*/
|
||||
function visitImportSpecifier(node: ImportSpecifier): VisitResult<ImportSpecifier> {
|
||||
// Elide an import specifier if it is not referenced.
|
||||
return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an export assignment, eliding it if it does not contain a clause that resolves
|
||||
* to a value.
|
||||
*
|
||||
* @param node The export assignment node.
|
||||
*/
|
||||
function visitExportAssignment(node: ExportAssignment): VisitResult<Statement> {
|
||||
// Elide the export assignment if it does not reference a value.
|
||||
return resolver.isValueAliasDeclaration(node)
|
||||
? visitEachChild(node, visitor, context)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an export declaration, eliding it if it does not contain a clause that resolves
|
||||
* to a value.
|
||||
*
|
||||
* @param node The export declaration node.
|
||||
*/
|
||||
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement> {
|
||||
if (!node.exportClause) {
|
||||
// Elide a star export if the module it references does not export a value.
|
||||
return resolver.moduleExportsSomeValue(node.moduleSpecifier) ? node : undefined;
|
||||
}
|
||||
|
||||
if (!resolver.isValueAliasDeclaration(node)) {
|
||||
// Elide the export declaration if it does not export a value.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Elide the export declaration if all of its named exports are elided.
|
||||
const exportClause = visitNode(node.exportClause, visitNamedExports, isNamedExports, /*optional*/ true);
|
||||
return exportClause
|
||||
? updateExportDeclaration(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
exportClause,
|
||||
node.moduleSpecifier)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits named exports, eliding it if it does not contain an export specifier that
|
||||
* resolves to a value.
|
||||
*
|
||||
* @param node The named exports node.
|
||||
*/
|
||||
function visitNamedExports(node: NamedExports): VisitResult<NamedExports> {
|
||||
// Elide the named exports if all of its export specifiers were elided.
|
||||
const elements = visitNodes(node.elements, visitExportSpecifier, isExportSpecifier);
|
||||
return some(elements) ? updateNamedExports(node, elements) : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an export specifier, eliding it if it does not resolve to a value.
|
||||
*
|
||||
* @param node The export specifier node.
|
||||
*/
|
||||
function visitExportSpecifier(node: ExportSpecifier): VisitResult<ExportSpecifier> {
|
||||
// Elide an export specifier if it does not reference a value.
|
||||
return resolver.isValueAliasDeclaration(node) ? node : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether to emit an import equals declaration.
|
||||
*
|
||||
|
@ -3019,7 +3107,10 @@ namespace ts {
|
|||
*/
|
||||
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement> {
|
||||
if (isExternalModuleImportEqualsDeclaration(node)) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
// Elide external module `import=` if it is not referenced.
|
||||
return resolver.isReferencedAliasDeclaration(node)
|
||||
? visitEachChild(node, visitor, context)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
if (!shouldEmitImportEqualsDeclaration(node)) {
|
||||
|
@ -3253,25 +3344,6 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function enableSubstitutionForAsyncMethodsWithSuper() {
|
||||
if ((enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper) === 0) {
|
||||
enabledSubstitutions |= TypeScriptSubstitutionFlags.AsyncMethodsWithSuper;
|
||||
|
||||
// We need to enable substitutions for call, property access, and element access
|
||||
// if we need to rewrite super calls.
|
||||
context.enableSubstitution(SyntaxKind.CallExpression);
|
||||
context.enableSubstitution(SyntaxKind.PropertyAccessExpression);
|
||||
context.enableSubstitution(SyntaxKind.ElementAccessExpression);
|
||||
|
||||
// We need to be notified when entering and exiting declarations that bind super.
|
||||
context.enableEmitNotification(SyntaxKind.ClassDeclaration);
|
||||
context.enableEmitNotification(SyntaxKind.MethodDeclaration);
|
||||
context.enableEmitNotification(SyntaxKind.GetAccessor);
|
||||
context.enableEmitNotification(SyntaxKind.SetAccessor);
|
||||
context.enableEmitNotification(SyntaxKind.Constructor);
|
||||
}
|
||||
}
|
||||
|
||||
function enableSubstitutionForClassAliases() {
|
||||
if ((enabledSubstitutions & TypeScriptSubstitutionFlags.ClassAliases) === 0) {
|
||||
enabledSubstitutions |= TypeScriptSubstitutionFlags.ClassAliases;
|
||||
|
@ -3299,15 +3371,6 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function isSuperContainer(node: Node): node is SuperContainer {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.ClassDeclaration
|
||||
|| kind === SyntaxKind.Constructor
|
||||
|| kind === SyntaxKind.MethodDeclaration
|
||||
|| kind === SyntaxKind.GetAccessor
|
||||
|| kind === SyntaxKind.SetAccessor;
|
||||
}
|
||||
|
||||
function isTransformedModuleDeclaration(node: Node): boolean {
|
||||
return getOriginalNode(node).kind === SyntaxKind.ModuleDeclaration;
|
||||
}
|
||||
|
@ -3324,12 +3387,6 @@ namespace ts {
|
|||
*/
|
||||
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 & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
|
||||
currentSuperContainer = node;
|
||||
}
|
||||
|
||||
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && isTransformedModuleDeclaration(node)) {
|
||||
applicableSubstitutions |= TypeScriptSubstitutionFlags.NamespaceExports;
|
||||
|
@ -3342,7 +3399,6 @@ namespace ts {
|
|||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
|
||||
applicableSubstitutions = savedApplicableSubstitutions;
|
||||
currentSuperContainer = savedCurrentSuperContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3389,11 +3445,6 @@ namespace ts {
|
|||
return substitutePropertyAccessExpression(<PropertyAccessExpression>node);
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
return substituteElementAccessExpression(<ElementAccessExpression>node);
|
||||
case SyntaxKind.CallExpression:
|
||||
if (enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper) {
|
||||
return substituteCallExpression(<CallExpression>node);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return node;
|
||||
|
@ -3448,54 +3499,11 @@ namespace ts {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
function substituteCallExpression(node: CallExpression): Expression {
|
||||
const expression = node.expression;
|
||||
if (isSuperProperty(expression)) {
|
||||
const flags = getSuperContainerAsyncMethodFlags();
|
||||
if (flags) {
|
||||
const argumentExpression = isPropertyAccessExpression(expression)
|
||||
? substitutePropertyAccessExpression(expression)
|
||||
: substituteElementAccessExpression(expression);
|
||||
return createCall(
|
||||
createPropertyAccess(argumentExpression, "call"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createThis(),
|
||||
...node.arguments
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
if (enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
const flags = getSuperContainerAsyncMethodFlags();
|
||||
if (flags) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
createLiteral(node.name.text),
|
||||
flags,
|
||||
node
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return substituteConstantValue(node);
|
||||
}
|
||||
|
||||
function substituteElementAccessExpression(node: ElementAccessExpression) {
|
||||
if (enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
const flags = getSuperContainerAsyncMethodFlags();
|
||||
if (flags) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
node.argumentExpression,
|
||||
flags,
|
||||
node
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return substituteConstantValue(node);
|
||||
}
|
||||
|
||||
|
@ -3528,32 +3536,5 @@ namespace ts {
|
|||
? resolver.getConstantValue(<PropertyAccessExpression | ElementAccessExpression>node)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function createSuperAccessInAsyncMethod(argumentExpression: Expression, flags: NodeCheckFlags, location: TextRange): LeftHandSideExpression {
|
||||
if (flags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
return createPropertyAccess(
|
||||
createCall(
|
||||
createIdentifier("_super"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
"value",
|
||||
location
|
||||
);
|
||||
}
|
||||
else {
|
||||
return createCall(
|
||||
createIdentifier("_super"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression],
|
||||
location
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getSuperContainerAsyncMethodFlags() {
|
||||
return currentSuperContainer !== undefined
|
||||
&& resolver.getNodeCheckFlags(currentSuperContainer) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function reportEmittedFiles(files: string[], host: CompilerHost): void {
|
||||
function reportEmittedFiles(files: string[]): void {
|
||||
if (!files || files.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ namespace ts {
|
|||
return count;
|
||||
}
|
||||
|
||||
function getDiagnosticText(message: DiagnosticMessage, ...args: any[]): string {
|
||||
function getDiagnosticText(_message: DiagnosticMessage, ..._args: any[]): string {
|
||||
const diagnostic = createCompilerDiagnostic.apply(undefined, arguments);
|
||||
return <string>diagnostic.messageText;
|
||||
}
|
||||
|
@ -456,7 +456,7 @@ namespace ts {
|
|||
const sourceFile = hostGetSourceFile(fileName, languageVersion, onError);
|
||||
if (sourceFile && isWatchSet(compilerOptions) && sys.watchFile) {
|
||||
// Attach a file watcher
|
||||
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (fileName: string, removed?: boolean) => sourceFileChanged(sourceFile, removed));
|
||||
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (_fileName: string, removed?: boolean) => sourceFileChanged(sourceFile, removed));
|
||||
}
|
||||
return sourceFile;
|
||||
}
|
||||
|
@ -617,7 +617,7 @@ namespace ts {
|
|||
|
||||
reportDiagnostics(sortAndDeduplicateDiagnostics(diagnostics), compilerHost);
|
||||
|
||||
reportEmittedFiles(emitOutput.emittedFiles, compilerHost);
|
||||
reportEmittedFiles(emitOutput.emittedFiles);
|
||||
|
||||
if (emitOutput.emitSkipped && diagnostics.length > 0) {
|
||||
// If the emitter didn't emit anything, then pass that value along.
|
||||
|
|
|
@ -8,7 +8,10 @@
|
|||
"outFile": "../../built/local/tsc.js",
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"stripInternal": true
|
||||
"stripInternal": true,
|
||||
"target": "es5",
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true
|
||||
},
|
||||
"files": [
|
||||
"core.ts",
|
||||
|
@ -25,13 +28,15 @@
|
|||
"transformers/ts.ts",
|
||||
"transformers/jsx.ts",
|
||||
"transformers/experimental.ts",
|
||||
"transformers/es7.ts",
|
||||
"transformers/es6.ts",
|
||||
"transformers/es2017.ts",
|
||||
"transformers/es2016.ts",
|
||||
"transformers/es2015.ts",
|
||||
"transformers/generators.ts",
|
||||
"transformers/es5.ts",
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/module/module.ts",
|
||||
"transformers/module/system.ts",
|
||||
"transformers/module/es6.ts",
|
||||
"transformers/module/es2015.ts",
|
||||
"transformer.ts",
|
||||
"comments.ts",
|
||||
"sourcemap.ts",
|
||||
|
|
|
@ -45,6 +45,7 @@ namespace ts {
|
|||
// Literals
|
||||
NumericLiteral,
|
||||
StringLiteral,
|
||||
JsxText,
|
||||
RegularExpressionLiteral,
|
||||
NoSubstitutionTemplateLiteral,
|
||||
// Pseudo-literals
|
||||
|
@ -302,7 +303,6 @@ namespace ts {
|
|||
JsxElement,
|
||||
JsxSelfClosingElement,
|
||||
JsxOpeningElement,
|
||||
JsxText,
|
||||
JsxClosingElement,
|
||||
JsxAttribute,
|
||||
JsxSpreadAttribute,
|
||||
|
@ -458,6 +458,8 @@ namespace ts {
|
|||
// Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property.
|
||||
ParameterPropertyModifier = AccessibilityModifier | Readonly,
|
||||
NonPublicAccessibilityModifier = Private | Protected,
|
||||
|
||||
TypeScriptModifier = Ambient | Public | Private | Protected | Readonly | Abstract | Const
|
||||
}
|
||||
|
||||
export const enum JsxFlags {
|
||||
|
@ -1921,8 +1923,9 @@ namespace ts {
|
|||
TrueCondition = 1 << 5, // Condition known to be true
|
||||
FalseCondition = 1 << 6, // Condition known to be false
|
||||
SwitchClause = 1 << 7, // Switch statement clause
|
||||
Referenced = 1 << 8, // Referenced as antecedent once
|
||||
Shared = 1 << 9, // Referenced as antecedent more than once
|
||||
ArrayMutation = 1 << 8, // Potential array mutation
|
||||
Referenced = 1 << 9, // Referenced as antecedent once
|
||||
Shared = 1 << 10, // Referenced as antecedent more than once
|
||||
Label = BranchLabel | LoopLabel,
|
||||
Condition = TrueCondition | FalseCondition
|
||||
}
|
||||
|
@ -1965,6 +1968,13 @@ namespace ts {
|
|||
antecedent: FlowNode;
|
||||
}
|
||||
|
||||
// FlowArrayMutation represents a node potentially mutates an array, i.e. an
|
||||
// operation of the form 'x.push(value)', 'x.unshift(value)' or 'x[n] = value'.
|
||||
export interface FlowArrayMutation extends FlowNode {
|
||||
node: CallExpression | BinaryExpression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
|
||||
export type FlowType = Type | IncompleteType;
|
||||
|
||||
// Incomplete types occur during control flow analysis of loops. An IncompleteType
|
||||
|
@ -2778,6 +2788,8 @@ namespace ts {
|
|||
export interface AnonymousType extends ObjectType {
|
||||
target?: AnonymousType; // Instantiation target
|
||||
mapper?: TypeMapper; // Instantiation mapper
|
||||
elementType?: Type; // Element expressions of evolving array type
|
||||
finalArrayType?: Type; // Final array type of evolving array type
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
@ -3050,8 +3062,7 @@ namespace ts {
|
|||
AMD = 2,
|
||||
UMD = 3,
|
||||
System = 4,
|
||||
ES6 = 5,
|
||||
ES2015 = ES6,
|
||||
ES2015 = 5,
|
||||
}
|
||||
|
||||
export const enum JsxEmit {
|
||||
|
@ -3084,9 +3095,10 @@ namespace ts {
|
|||
export const enum ScriptTarget {
|
||||
ES3 = 0,
|
||||
ES5 = 1,
|
||||
ES6 = 2,
|
||||
ES2015 = ES6,
|
||||
Latest = ES6,
|
||||
ES2015 = 2,
|
||||
ES2016 = 3,
|
||||
ES2017 = 4,
|
||||
Latest = ES2017,
|
||||
}
|
||||
|
||||
export const enum LanguageVariant {
|
||||
|
@ -3373,29 +3385,31 @@ namespace ts {
|
|||
ContainsJsx = 1 << 3,
|
||||
Experimental = 1 << 4,
|
||||
ContainsExperimental = 1 << 5,
|
||||
ES7 = 1 << 6,
|
||||
ContainsES7 = 1 << 7,
|
||||
ES6 = 1 << 8,
|
||||
ContainsES6 = 1 << 9,
|
||||
DestructuringAssignment = 1 << 10,
|
||||
Generator = 1 << 11,
|
||||
ContainsGenerator = 1 << 12,
|
||||
ES2017 = 1 << 6,
|
||||
ContainsES2017 = 1 << 7,
|
||||
ES2016 = 1 << 8,
|
||||
ContainsES2016 = 1 << 9,
|
||||
ES2015 = 1 << 10,
|
||||
ContainsES2015 = 1 << 11,
|
||||
DestructuringAssignment = 1 << 12,
|
||||
Generator = 1 << 13,
|
||||
ContainsGenerator = 1 << 14,
|
||||
|
||||
// Markers
|
||||
// - Flags used to indicate that a subtree contains a specific transformation.
|
||||
ContainsDecorators = 1 << 13,
|
||||
ContainsPropertyInitializer = 1 << 14,
|
||||
ContainsLexicalThis = 1 << 15,
|
||||
ContainsCapturedLexicalThis = 1 << 16,
|
||||
ContainsLexicalThisInComputedPropertyName = 1 << 17,
|
||||
ContainsDefaultValueAssignments = 1 << 18,
|
||||
ContainsParameterPropertyAssignments = 1 << 19,
|
||||
ContainsSpreadExpression = 1 << 20,
|
||||
ContainsComputedPropertyName = 1 << 21,
|
||||
ContainsBlockScopedBinding = 1 << 22,
|
||||
ContainsBindingPattern = 1 << 23,
|
||||
ContainsYield = 1 << 24,
|
||||
ContainsHoistedDeclarationOrCompletion = 1 << 25,
|
||||
ContainsDecorators = 1 << 15,
|
||||
ContainsPropertyInitializer = 1 << 16,
|
||||
ContainsLexicalThis = 1 << 17,
|
||||
ContainsCapturedLexicalThis = 1 << 18,
|
||||
ContainsLexicalThisInComputedPropertyName = 1 << 19,
|
||||
ContainsDefaultValueAssignments = 1 << 20,
|
||||
ContainsParameterPropertyAssignments = 1 << 21,
|
||||
ContainsSpreadExpression = 1 << 22,
|
||||
ContainsComputedPropertyName = 1 << 23,
|
||||
ContainsBlockScopedBinding = 1 << 24,
|
||||
ContainsBindingPattern = 1 << 25,
|
||||
ContainsYield = 1 << 26,
|
||||
ContainsHoistedDeclarationOrCompletion = 1 << 27,
|
||||
|
||||
HasComputedFlags = 1 << 29, // Transform flags have been computed.
|
||||
|
||||
|
@ -3404,14 +3418,15 @@ namespace ts {
|
|||
AssertTypeScript = TypeScript | ContainsTypeScript,
|
||||
AssertJsx = Jsx | ContainsJsx,
|
||||
AssertExperimental = Experimental | ContainsExperimental,
|
||||
AssertES7 = ES7 | ContainsES7,
|
||||
AssertES6 = ES6 | ContainsES6,
|
||||
AssertES2017 = ES2017 | ContainsES2017,
|
||||
AssertES2016 = ES2016 | ContainsES2016,
|
||||
AssertES2015 = ES2015 | ContainsES2015,
|
||||
AssertGenerator = Generator | ContainsGenerator,
|
||||
|
||||
// Scope Exclusions
|
||||
// - Bitmasks that exclude flags from propagating out of a specific context
|
||||
// into the subtree flags of their container.
|
||||
NodeExcludes = TypeScript | Jsx | Experimental | ES7 | ES6 | DestructuringAssignment | Generator | HasComputedFlags,
|
||||
NodeExcludes = TypeScript | Jsx | Experimental | 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,
|
||||
|
@ -3427,7 +3442,7 @@ namespace ts {
|
|||
// Masks
|
||||
// - Additional bitmasks
|
||||
TypeScriptClassSyntaxMask = ContainsParameterPropertyAssignments | ContainsPropertyInitializer | ContainsDecorators,
|
||||
ES6FunctionSyntaxMask = ContainsCapturedLexicalThis | ContainsDefaultValueAssignments,
|
||||
ES2015FunctionSyntaxMask = ContainsCapturedLexicalThis | ContainsDefaultValueAssignments,
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
|
|
@ -337,7 +337,7 @@ namespace ts {
|
|||
export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile, languageVersion: ScriptTarget) {
|
||||
// Any template literal or string literal with an extended escape
|
||||
// (e.g. "\u{0067}") will need to be downleveled as a escaped string literal.
|
||||
if (languageVersion < ScriptTarget.ES6 && (isTemplateLiteralKind(node.kind) || node.hasExtendedUnicodeEscape)) {
|
||||
if (languageVersion < ScriptTarget.ES2015 && (isTemplateLiteralKind(node.kind) || node.hasExtendedUnicodeEscape)) {
|
||||
return getQuotedEscapedLiteralText('"', node.text, '"');
|
||||
}
|
||||
|
||||
|
@ -345,7 +345,7 @@ namespace ts {
|
|||
// the node's parent reference, then simply get the text as it was originally written.
|
||||
if (!nodeIsSynthesized(node) && node.parent) {
|
||||
const text = getSourceTextOfNodeFromSourceFile(sourceFile, node);
|
||||
if (languageVersion < ScriptTarget.ES6 && isBinaryOrOctalIntegerLiteral(node, text)) {
|
||||
if (languageVersion < ScriptTarget.ES2015 && isBinaryOrOctalIntegerLiteral(node, text)) {
|
||||
return node.text;
|
||||
}
|
||||
return text;
|
||||
|
@ -503,7 +503,7 @@ namespace ts {
|
|||
return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
|
||||
}
|
||||
|
||||
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): Diagnostic {
|
||||
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic {
|
||||
const sourceFile = getSourceFileOfNode(node);
|
||||
const span = getErrorSpanForNode(sourceFile, node);
|
||||
return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2);
|
||||
|
@ -1901,6 +1901,10 @@ namespace ts {
|
|||
return node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "Symbol";
|
||||
}
|
||||
|
||||
export function isPushOrUnshiftIdentifier(node: Identifier) {
|
||||
return node.text === "push" || node.text === "unshift";
|
||||
}
|
||||
|
||||
export function isModifierKind(token: SyntaxKind): boolean {
|
||||
switch (token) {
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
|
@ -2562,7 +2566,7 @@ namespace ts {
|
|||
const options = host.getCompilerOptions();
|
||||
// Emit on each source file
|
||||
if (options.outFile || options.out) {
|
||||
onBundledEmit(host, sourceFiles);
|
||||
onBundledEmit(sourceFiles);
|
||||
}
|
||||
else {
|
||||
for (const sourceFile of sourceFiles) {
|
||||
|
@ -2595,7 +2599,7 @@ namespace ts {
|
|||
action(jsFilePath, sourceMapFilePath, declarationFilePath, [sourceFile], /*isBundledEmit*/ false);
|
||||
}
|
||||
|
||||
function onBundledEmit(host: EmitHost, sourceFiles: SourceFile[]) {
|
||||
function onBundledEmit(sourceFiles: SourceFile[]) {
|
||||
if (sourceFiles.length) {
|
||||
const jsFilePath = options.outFile || options.out;
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
|
@ -3502,7 +3506,7 @@ namespace ts {
|
|||
return positionIsSynthesized(range.pos) ? -1 : skipTrivia(sourceFile.text, range.pos);
|
||||
}
|
||||
|
||||
export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver) {
|
||||
export function collectExternalModuleInfo(sourceFile: SourceFile) {
|
||||
const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = [];
|
||||
const exportSpecifiers = createMap<ExportSpecifier[]>();
|
||||
let exportEquals: ExportAssignment = undefined;
|
||||
|
@ -3510,19 +3514,16 @@ namespace ts {
|
|||
for (const node of sourceFile.statements) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
if (!(<ImportDeclaration>node).importClause ||
|
||||
resolver.isReferencedAliasDeclaration((<ImportDeclaration>node).importClause, /*checkChildren*/ true)) {
|
||||
// import "mod"
|
||||
// import x from "mod" where x is referenced
|
||||
// import * as x from "mod" where x is referenced
|
||||
// import { x, y } from "mod" where at least one import is referenced
|
||||
externalImports.push(<ImportDeclaration>node);
|
||||
}
|
||||
// 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 && resolver.isReferencedAliasDeclaration(node)) {
|
||||
// import x = require("mod") where x is referenced
|
||||
if ((<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference) {
|
||||
// import x = require("mod")
|
||||
externalImports.push(<ImportEqualsDeclaration>node);
|
||||
}
|
||||
break;
|
||||
|
@ -3531,13 +3532,11 @@ namespace ts {
|
|||
if ((<ExportDeclaration>node).moduleSpecifier) {
|
||||
if (!(<ExportDeclaration>node).exportClause) {
|
||||
// export * from "mod"
|
||||
if (resolver.moduleExportsSomeValue((<ExportDeclaration>node).moduleSpecifier)) {
|
||||
externalImports.push(<ExportDeclaration>node);
|
||||
hasExportStarsToExportValues = true;
|
||||
}
|
||||
externalImports.push(<ExportDeclaration>node);
|
||||
hasExportStarsToExportValues = true;
|
||||
}
|
||||
else if (resolver.isValueAliasDeclaration(node)) {
|
||||
// export { x, y } from "mod" where at least one export is a value symbol
|
||||
else {
|
||||
// export { x, y } from "mod"
|
||||
externalImports.push(<ExportDeclaration>node);
|
||||
}
|
||||
}
|
||||
|
@ -4168,7 +4167,17 @@ namespace ts {
|
|||
|
||||
namespace ts {
|
||||
export function getDefaultLibFileName(options: CompilerOptions): string {
|
||||
return options.target === ScriptTarget.ES6 ? "lib.es6.d.ts" : "lib.d.ts";
|
||||
switch (options.target) {
|
||||
case ScriptTarget.ES2017:
|
||||
return "lib.es2017.d.ts";
|
||||
case ScriptTarget.ES2016:
|
||||
return "lib.es2016.d.ts";
|
||||
case ScriptTarget.ES2015:
|
||||
return "lib.es6.d.ts";
|
||||
|
||||
default:
|
||||
return "lib.d.ts";
|
||||
}
|
||||
}
|
||||
|
||||
export function textSpanEnd(span: TextSpan) {
|
||||
|
|
|
@ -807,6 +807,7 @@ namespace ts {
|
|||
|
||||
case SyntaxKind.FunctionExpression:
|
||||
return updateFunctionExpression(<FunctionExpression>node,
|
||||
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)),
|
||||
|
@ -1330,18 +1331,18 @@ namespace ts {
|
|||
export namespace Debug {
|
||||
export const failNotOptional = shouldAssert(AssertionLevel.Normal)
|
||||
? (message?: string) => assert(false, message || "Node not optional.")
|
||||
: (message?: string) => {};
|
||||
: () => {};
|
||||
|
||||
export const failBadSyntaxKind = shouldAssert(AssertionLevel.Normal)
|
||||
? (node: Node, message?: string) => assert(false, message || "Unexpected node.", () => `Node ${formatSyntaxKind(node.kind)} was unexpected.`)
|
||||
: (node: Node, message?: string) => {};
|
||||
: () => {};
|
||||
|
||||
export const assertNode = shouldAssert(AssertionLevel.Normal)
|
||||
? (node: Node, test: (node: Node) => boolean, message?: string) => assert(
|
||||
test === undefined || test(node),
|
||||
message || "Unexpected node.",
|
||||
() => `Node ${formatSyntaxKind(node.kind)} did not pass test '${getFunctionName(test)}'.`)
|
||||
: (node: Node, test: (node: Node) => boolean, message?: string) => {};
|
||||
: () => {};
|
||||
|
||||
function getFunctionName(func: Function) {
|
||||
if (typeof func !== "function") {
|
||||
|
|
|
@ -941,7 +941,17 @@ namespace Harness {
|
|||
}
|
||||
|
||||
export function getDefaultLibFileName(options: ts.CompilerOptions): string {
|
||||
return options.target === ts.ScriptTarget.ES6 ? es2015DefaultLibFileName : defaultLibFileName;
|
||||
switch (options.target) {
|
||||
case ts.ScriptTarget.ES2017:
|
||||
return "lib.es2017.d.ts";
|
||||
case ts.ScriptTarget.ES2016:
|
||||
return "lib.es2016.d.ts";
|
||||
case ts.ScriptTarget.ES2015:
|
||||
return es2015DefaultLibFileName;
|
||||
|
||||
default:
|
||||
return defaultLibFileName;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache these between executions so we don't have to re-parse them for every test
|
||||
|
@ -1634,7 +1644,7 @@ namespace Harness {
|
|||
|
||||
export function collateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): string {
|
||||
// Collect, test, and sort the fileNames
|
||||
outputFiles.sort((a, b) => cleanName(a.fileName).localeCompare(cleanName(b.fileName)));
|
||||
outputFiles.sort((a, b) => ts.compareStrings(cleanName(a.fileName), cleanName(b.fileName)));
|
||||
|
||||
// Emit them
|
||||
let result = "";
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
"stripInternal": true,
|
||||
"types": [
|
||||
"node", "mocha", "chai"
|
||||
]
|
||||
],
|
||||
"target": "es5"
|
||||
},
|
||||
"files": [
|
||||
"../compiler/core.ts",
|
||||
|
@ -27,13 +28,15 @@
|
|||
"../compiler/transformers/ts.ts",
|
||||
"../compiler/transformers/jsx.ts",
|
||||
"../compiler/transformers/experimental.ts",
|
||||
"../compiler/transformers/es7.ts",
|
||||
"../compiler/transformers/es6.ts",
|
||||
"../compiler/transformers/es2017.ts",
|
||||
"../compiler/transformers/es2016.ts",
|
||||
"../compiler/transformers/es2015.ts",
|
||||
"../compiler/transformers/generators.ts",
|
||||
"../compiler/transformers/es5.ts",
|
||||
"../compiler/transformers/destructuring.ts",
|
||||
"../compiler/transformers/module/module.ts",
|
||||
"../compiler/transformers/module/system.ts",
|
||||
"../compiler/transformers/module/es6.ts",
|
||||
"../compiler/transformers/module/es2015.ts",
|
||||
"../compiler/transformer.ts",
|
||||
"../compiler/comments.ts",
|
||||
"../compiler/sourcemap.ts",
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace ts {
|
|||
assertParseResult(["--lib", "es5,invalidOption", "0.ts"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
|
@ -87,7 +87,7 @@ namespace ts {
|
|||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
|
@ -113,7 +113,7 @@ namespace ts {
|
|||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
|
@ -139,7 +139,7 @@ namespace ts {
|
|||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
|
@ -165,7 +165,7 @@ namespace ts {
|
|||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015'",
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
|
@ -191,7 +191,7 @@ namespace ts {
|
|||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
|
@ -263,7 +263,7 @@ namespace ts {
|
|||
assertParseResult(["--lib", "es5,", "es7", "0.ts"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
|
@ -283,7 +283,7 @@ namespace ts {
|
|||
assertParseResult(["--lib", "es5, ", "es7", "0.ts"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ namespace ts {
|
|||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
|
@ -122,7 +122,7 @@ namespace ts {
|
|||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
|
@ -150,7 +150,7 @@ namespace ts {
|
|||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
|
@ -176,7 +176,7 @@ namespace ts {
|
|||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015'",
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
|
@ -202,7 +202,7 @@ namespace ts {
|
|||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
|
@ -233,7 +233,7 @@ namespace ts {
|
|||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
|
@ -264,7 +264,7 @@ namespace ts {
|
|||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
|
@ -295,7 +295,7 @@ namespace ts {
|
|||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
|
@ -326,7 +326,7 @@ namespace ts {
|
|||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
|
|
|
@ -1017,7 +1017,7 @@ import b = require("./moduleB");
|
|||
const files = [f1, f2, f3, f4];
|
||||
|
||||
const names = map(files, f => f.name);
|
||||
const sourceFiles = arrayToMap(map(files, f => createSourceFile(f.name, f.content, ScriptTarget.ES6)), f => f.fileName);
|
||||
const sourceFiles = arrayToMap(map(files, f => createSourceFile(f.name, f.content, ScriptTarget.ES2015)), f => f.fileName);
|
||||
const compilerHost: CompilerHost = {
|
||||
fileExists : fileName => fileName in sourceFiles,
|
||||
getSourceFile: fileName => sourceFiles[fileName],
|
||||
|
|
|
@ -39,12 +39,18 @@ namespace ts.server {
|
|||
getLogFileName: (): string => undefined
|
||||
};
|
||||
|
||||
class TestSession extends Session {
|
||||
getProjectService() {
|
||||
return this.projectService;
|
||||
}
|
||||
}
|
||||
|
||||
describe("the Session class", () => {
|
||||
let session: Session;
|
||||
let session: TestSession;
|
||||
let lastSent: protocol.Message;
|
||||
|
||||
beforeEach(() => {
|
||||
session = new Session(mockHost, nullCancellationToken, /*useOneInferredProject*/ false, /*typingsInstaller*/ undefined, Utils.byteLength, process.hrtime, mockLogger, /*canUseEvents*/ true);
|
||||
session = new TestSession(mockHost, nullCancellationToken, /*useOneInferredProject*/ false, /*typingsInstaller*/ undefined, Utils.byteLength, process.hrtime, mockLogger, /*canUseEvents*/ true);
|
||||
session.send = (msg: protocol.Message) => {
|
||||
lastSent = msg;
|
||||
};
|
||||
|
@ -55,7 +61,7 @@ namespace ts.server {
|
|||
const req: protocol.FileRequest = {
|
||||
command: CommandNames.Open,
|
||||
seq: 0,
|
||||
type: "command",
|
||||
type: "request",
|
||||
arguments: {
|
||||
file: undefined
|
||||
}
|
||||
|
@ -67,7 +73,7 @@ namespace ts.server {
|
|||
const req: protocol.Request = {
|
||||
command: "foobar",
|
||||
seq: 0,
|
||||
type: "command"
|
||||
type: "request"
|
||||
};
|
||||
|
||||
session.executeCommand(req);
|
||||
|
@ -85,7 +91,7 @@ namespace ts.server {
|
|||
const req: protocol.ConfigureRequest = {
|
||||
command: CommandNames.Configure,
|
||||
seq: 0,
|
||||
type: "command",
|
||||
type: "request",
|
||||
arguments: {
|
||||
hostInfo: "unit test",
|
||||
formatOptions: {
|
||||
|
@ -106,6 +112,47 @@ namespace ts.server {
|
|||
body: undefined
|
||||
});
|
||||
});
|
||||
it ("should handle literal types in request", () => {
|
||||
const configureRequest: protocol.ConfigureRequest = {
|
||||
command: CommandNames.Configure,
|
||||
seq: 0,
|
||||
type: "request",
|
||||
arguments: {
|
||||
formatOptions: {
|
||||
indentStyle: "Block"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
session.onMessage(JSON.stringify(configureRequest));
|
||||
|
||||
assert.equal(session.getProjectService().getFormatCodeOptions().indentStyle, IndentStyle.Block);
|
||||
|
||||
const setOptionsRequest: protocol.SetCompilerOptionsForInferredProjectsRequest = {
|
||||
command: CommandNames.CompilerOptionsForInferredProjects,
|
||||
seq: 1,
|
||||
type: "request",
|
||||
arguments: {
|
||||
options: {
|
||||
module: "System",
|
||||
target: "ES5",
|
||||
jsx: "React",
|
||||
newLine: "Lf",
|
||||
moduleResolution: "Node"
|
||||
}
|
||||
}
|
||||
};
|
||||
session.onMessage(JSON.stringify(setOptionsRequest));
|
||||
assert.deepEqual(
|
||||
session.getProjectService().getCompilerOptionsForInferredProjects(),
|
||||
<CompilerOptions>{
|
||||
module: ModuleKind.System,
|
||||
target: ScriptTarget.ES5,
|
||||
jsx: JsxEmit.React,
|
||||
newLine: NewLineKind.LineFeed,
|
||||
moduleResolution: ModuleResolutionKind.NodeJs
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("onMessage", () => {
|
||||
|
@ -118,7 +165,7 @@ namespace ts.server {
|
|||
const req: protocol.Request = {
|
||||
command: name,
|
||||
seq: i,
|
||||
type: "command"
|
||||
type: "request"
|
||||
};
|
||||
i++;
|
||||
session.onMessage(JSON.stringify(req));
|
||||
|
@ -151,7 +198,7 @@ namespace ts.server {
|
|||
const req: protocol.ConfigureRequest = {
|
||||
command: CommandNames.Configure,
|
||||
seq: 0,
|
||||
type: "command",
|
||||
type: "request",
|
||||
arguments: {
|
||||
hostInfo: "unit test",
|
||||
formatOptions: {
|
||||
|
@ -175,7 +222,7 @@ namespace ts.server {
|
|||
|
||||
describe("send", () => {
|
||||
it("is an overrideable handle which sends protocol messages over the wire", () => {
|
||||
const msg = { seq: 0, type: "none" };
|
||||
const msg: server.protocol.Request = { seq: 0, type: "request", command: "" };
|
||||
const strmsg = JSON.stringify(msg);
|
||||
const len = 1 + Utils.byteLength(strmsg, "utf8");
|
||||
const resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`;
|
||||
|
@ -203,7 +250,7 @@ namespace ts.server {
|
|||
expect(session.executeCommand({
|
||||
command,
|
||||
seq: 0,
|
||||
type: "command"
|
||||
type: "request"
|
||||
})).to.deep.equal(result);
|
||||
});
|
||||
it("throws when a duplicate handler is passed", () => {
|
||||
|
@ -304,7 +351,7 @@ namespace ts.server {
|
|||
|
||||
expect(session.executeCommand({
|
||||
seq: 0,
|
||||
type: "command",
|
||||
type: "request",
|
||||
command: session.customHandler
|
||||
})).to.deep.equal({
|
||||
response: undefined,
|
||||
|
@ -405,7 +452,7 @@ namespace ts.server {
|
|||
this.seq++;
|
||||
this.server.enqueue({
|
||||
seq: this.seq,
|
||||
type: "command",
|
||||
type: "request",
|
||||
command,
|
||||
arguments: args
|
||||
});
|
||||
|
|
|
@ -135,7 +135,7 @@ namespace ts.projectSystem {
|
|||
}
|
||||
|
||||
export class TestServerEventManager {
|
||||
private events: server.ProjectServiceEvent[] = [];
|
||||
public events: server.ProjectServiceEvent[] = [];
|
||||
|
||||
handler: server.ProjectServiceEventHandler = (event: server.ProjectServiceEvent) => {
|
||||
this.events.push(event);
|
||||
|
@ -170,11 +170,18 @@ namespace ts.projectSystem {
|
|||
return host;
|
||||
}
|
||||
|
||||
class TestSession extends server.Session {
|
||||
getProjectService() {
|
||||
return this.projectService;
|
||||
}
|
||||
};
|
||||
|
||||
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler) {
|
||||
if (typingsInstaller === undefined) {
|
||||
typingsInstaller = new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
|
||||
}
|
||||
return new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler);
|
||||
|
||||
return new TestSession(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler);
|
||||
}
|
||||
|
||||
export interface CreateProjectServiceParameters {
|
||||
|
@ -515,11 +522,13 @@ namespace ts.projectSystem {
|
|||
this.reloadFS(filesOrFolders);
|
||||
}
|
||||
|
||||
write(s: string) {
|
||||
}
|
||||
|
||||
readonly readFile = (s: string) => (<File>this.fs.get(this.toPath(s))).content;
|
||||
readonly resolvePath = (s: string) => s;
|
||||
readonly getExecutingFilePath = () => this.executingFilePath;
|
||||
readonly getCurrentDirectory = () => this.currentDirectory;
|
||||
readonly write = (s: string) => notImplemented();
|
||||
readonly exit = () => notImplemented();
|
||||
readonly getEnvironmentVariable = (v: string) => notImplemented();
|
||||
}
|
||||
|
@ -2286,6 +2295,14 @@ namespace ts.projectSystem {
|
|||
const session = createSession(host, /*typingsInstaller*/ undefined, serverEventManager.handler);
|
||||
openFilesForSession([file], session);
|
||||
serverEventManager.checkEventCountOfType("configFileDiag", 1);
|
||||
|
||||
for (const event of serverEventManager.events) {
|
||||
if (event.eventName === "configFileDiag") {
|
||||
assert.equal(event.data.configFileName, configFile.path);
|
||||
assert.equal(event.data.triggerFile, file.path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("are generated when the config file doesn't have errors", () => {
|
||||
|
@ -2412,4 +2429,53 @@ namespace ts.projectSystem {
|
|||
assert.isTrue(inferredProject.containsFile(<server.NormalizedPath>file1.path));
|
||||
});
|
||||
});
|
||||
|
||||
describe("reload", () => {
|
||||
it("should work with temp file", () => {
|
||||
const f1 = {
|
||||
path: "/a/b/app.ts",
|
||||
content: "let x = 1"
|
||||
};
|
||||
const tmp = {
|
||||
path: "/a/b/app.tmp",
|
||||
content: "const y = 42"
|
||||
};
|
||||
const host = createServerHost([f1, tmp]);
|
||||
const session = createSession(host);
|
||||
|
||||
// send open request
|
||||
session.executeCommand(<server.protocol.OpenRequest>{
|
||||
type: "request",
|
||||
command: "open",
|
||||
seq: 1,
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
|
||||
// reload from tmp file
|
||||
session.executeCommand(<server.protocol.ReloadRequest>{
|
||||
type: "request",
|
||||
command: "reload",
|
||||
seq: 2,
|
||||
arguments: { file: f1.path, tmpfile: tmp.path }
|
||||
});
|
||||
|
||||
// verify content
|
||||
const projectServiice = session.getProjectService();
|
||||
const snap1 = projectServiice.getScriptInfo(f1.path).snap();
|
||||
assert.equal(snap1.getText(0, snap1.getLength()), tmp.content, "content should be equal to the content of temp file");
|
||||
|
||||
// reload from original file file
|
||||
session.executeCommand(<server.protocol.ReloadRequest>{
|
||||
type: "request",
|
||||
command: "reload",
|
||||
seq: 2,
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
|
||||
// verify content
|
||||
const snap2 = projectServiice.getScriptInfo(f1.path).snap();
|
||||
assert.equal(snap2.getText(0, snap2.getLength()), f1.content, "content should be equal to the content of original file");
|
||||
|
||||
});
|
||||
});
|
||||
}
|
|
@ -10,7 +10,8 @@
|
|||
"stripInternal": true,
|
||||
"types": [
|
||||
"node"
|
||||
]
|
||||
],
|
||||
"target": "es5"
|
||||
},
|
||||
"files": [
|
||||
"cancellationToken.ts"
|
||||
|
|
|
@ -424,33 +424,39 @@ namespace ts.server {
|
|||
}
|
||||
|
||||
getSyntacticDiagnostics(fileName: string): Diagnostic[] {
|
||||
const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file: fileName };
|
||||
const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file: fileName, includeLinePosition: true };
|
||||
|
||||
const request = this.processRequest<protocol.SyntacticDiagnosticsSyncRequest>(CommandNames.SyntacticDiagnosticsSync, args);
|
||||
const response = this.processResponse<protocol.SyntacticDiagnosticsSyncResponse>(request);
|
||||
|
||||
return (<protocol.Diagnostic[]>response.body).map(entry => this.convertDiagnostic(entry, fileName));
|
||||
return (<protocol.DiagnosticWithLinePosition[]>response.body).map(entry => this.convertDiagnostic(entry, fileName));
|
||||
}
|
||||
|
||||
getSemanticDiagnostics(fileName: string): Diagnostic[] {
|
||||
const args: protocol.SemanticDiagnosticsSyncRequestArgs = { file: fileName };
|
||||
const args: protocol.SemanticDiagnosticsSyncRequestArgs = { file: fileName, includeLinePosition: true };
|
||||
|
||||
const request = this.processRequest<protocol.SemanticDiagnosticsSyncRequest>(CommandNames.SemanticDiagnosticsSync, args);
|
||||
const response = this.processResponse<protocol.SemanticDiagnosticsSyncResponse>(request);
|
||||
|
||||
return (<protocol.Diagnostic[]>response.body).map(entry => this.convertDiagnostic(entry, fileName));
|
||||
return (<protocol.DiagnosticWithLinePosition[]>response.body).map(entry => this.convertDiagnostic(entry, fileName));
|
||||
}
|
||||
|
||||
convertDiagnostic(entry: protocol.Diagnostic, fileName: string): Diagnostic {
|
||||
const start = this.lineOffsetToPosition(fileName, entry.start);
|
||||
const end = this.lineOffsetToPosition(fileName, entry.end);
|
||||
convertDiagnostic(entry: protocol.DiagnosticWithLinePosition, fileName: string): Diagnostic {
|
||||
let category: DiagnosticCategory;
|
||||
for (const id in DiagnosticCategory) {
|
||||
if (typeof id === "string" && entry.category === id.toLowerCase()) {
|
||||
category = (<any>DiagnosticCategory)[id];
|
||||
}
|
||||
}
|
||||
|
||||
Debug.assert(category !== undefined, "convertDiagnostic: category should not be undefined");
|
||||
|
||||
return {
|
||||
file: undefined,
|
||||
start: start,
|
||||
length: end - start,
|
||||
messageText: entry.text,
|
||||
category: undefined,
|
||||
start: entry.start,
|
||||
length: entry.length,
|
||||
messageText: entry.message,
|
||||
category: category,
|
||||
code: entry.code
|
||||
};
|
||||
}
|
||||
|
|
|
@ -11,12 +11,74 @@ namespace ts.server {
|
|||
export const maxProgramSizeForNonTsFiles = 20 * 1024 * 1024;
|
||||
|
||||
export type ProjectServiceEvent =
|
||||
{ eventName: "context", data: { project: Project, fileName: NormalizedPath } } | { eventName: "configFileDiag", data: { triggerFile?: string, configFileName: string, diagnostics: Diagnostic[] } };
|
||||
{ eventName: "context", data: { project: Project, fileName: NormalizedPath } } | { eventName: "configFileDiag", data: { triggerFile: string, configFileName: string, diagnostics: Diagnostic[] } };
|
||||
|
||||
export interface ProjectServiceEventHandler {
|
||||
(event: ProjectServiceEvent): void;
|
||||
}
|
||||
|
||||
function prepareConvertersForEnumLikeCompilerOptions(commandLineOptions: CommandLineOption[]): Map<Map<number>> {
|
||||
const map: Map<Map<number>> = createMap<Map<number>>();
|
||||
for (const option of commandLineOptions) {
|
||||
if (typeof option.type === "object") {
|
||||
const optionMap = <Map<number>>option.type;
|
||||
// verify that map contains only numbers
|
||||
for (const id in optionMap) {
|
||||
Debug.assert(typeof optionMap[id] === "number");
|
||||
}
|
||||
map[option.name] = optionMap;
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
const compilerOptionConverters = prepareConvertersForEnumLikeCompilerOptions(optionDeclarations);
|
||||
const indentStyle = createMap({
|
||||
"none": IndentStyle.None,
|
||||
"block": IndentStyle.Block,
|
||||
"smart": IndentStyle.Smart
|
||||
});
|
||||
|
||||
export function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings {
|
||||
if (typeof protocolOptions.indentStyle === "string") {
|
||||
protocolOptions.indentStyle = indentStyle[protocolOptions.indentStyle.toLowerCase()];
|
||||
Debug.assert(protocolOptions.indentStyle !== undefined);
|
||||
}
|
||||
return <any>protocolOptions;
|
||||
}
|
||||
|
||||
export function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin {
|
||||
for (const id in compilerOptionConverters) {
|
||||
const propertyValue = protocolOptions[id];
|
||||
if (typeof propertyValue === "string") {
|
||||
const mappedValues = compilerOptionConverters[id];
|
||||
protocolOptions[id] = mappedValues[propertyValue.toLowerCase()];
|
||||
}
|
||||
}
|
||||
return <any>protocolOptions;
|
||||
}
|
||||
|
||||
export function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind {
|
||||
return typeof scriptKindName === "string"
|
||||
? convertScriptKindName(scriptKindName)
|
||||
: scriptKindName;
|
||||
}
|
||||
|
||||
export function convertScriptKindName(scriptKindName: protocol.ScriptKindName) {
|
||||
switch (scriptKindName) {
|
||||
case "JS":
|
||||
return ScriptKind.JS;
|
||||
case "JSX":
|
||||
return ScriptKind.JSX;
|
||||
case "TS":
|
||||
return ScriptKind.TS;
|
||||
case "TSX":
|
||||
return ScriptKind.TSX;
|
||||
default:
|
||||
return ScriptKind.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project.
|
||||
*/
|
||||
|
@ -63,7 +125,7 @@ namespace ts.server {
|
|||
|
||||
const externalFilePropertyReader: FilePropertyReader<protocol.ExternalFile> = {
|
||||
getFileName: x => x.fileName,
|
||||
getScriptKind: x => x.scriptKind,
|
||||
getScriptKind: x => tryConvertScriptKindName(x.scriptKind),
|
||||
hasMixedContent: x => x.hasMixedContent
|
||||
};
|
||||
|
||||
|
@ -214,6 +276,10 @@ namespace ts.server {
|
|||
this.ensureInferredProjectsUpToDate();
|
||||
}
|
||||
|
||||
getCompilerOptionsForInferredProjects() {
|
||||
return this.compilerOptionsForInferredProjects;
|
||||
}
|
||||
|
||||
updateTypingsForProject(response: SetTypings | InvalidateCachedTypings): void {
|
||||
const project = this.findProject(response.projectName);
|
||||
if (!project) {
|
||||
|
@ -231,10 +297,10 @@ namespace ts.server {
|
|||
}
|
||||
|
||||
setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.ExternalProjectCompilerOptions): void {
|
||||
this.compilerOptionsForInferredProjects = projectCompilerOptions;
|
||||
this.compilerOptionsForInferredProjects = convertCompilerOptions(projectCompilerOptions);
|
||||
this.compileOnSaveForInferredProjects = projectCompilerOptions.compileOnSave;
|
||||
for (const proj of this.inferredProjects) {
|
||||
proj.setCompilerOptions(projectCompilerOptions);
|
||||
proj.setCompilerOptions(this.compilerOptionsForInferredProjects);
|
||||
proj.compileOnSaveEnabled = projectCompilerOptions.compileOnSave;
|
||||
}
|
||||
this.updateProjectGraphs(this.inferredProjects);
|
||||
|
@ -392,12 +458,12 @@ namespace ts.server {
|
|||
this.throttledOperations.schedule(
|
||||
project.configFileName,
|
||||
/*delay*/250,
|
||||
() => this.handleChangeInSourceFileForConfiguredProject(project));
|
||||
() => this.handleChangeInSourceFileForConfiguredProject(project, fileName));
|
||||
}
|
||||
|
||||
private handleChangeInSourceFileForConfiguredProject(project: ConfiguredProject) {
|
||||
private handleChangeInSourceFileForConfiguredProject(project: ConfiguredProject, triggerFile: string) {
|
||||
const { projectOptions, configFileErrors } = this.convertConfigFileContentToProjectOptions(project.configFileName);
|
||||
this.reportConfigFileDiagnostics(project.getProjectName(), configFileErrors);
|
||||
this.reportConfigFileDiagnostics(project.getProjectName(), configFileErrors, triggerFile);
|
||||
|
||||
const newRootFiles = projectOptions.files.map((f => this.getCanonicalFileName(f)));
|
||||
const currentRootFiles = project.getRootFiles().map((f => this.getCanonicalFileName(f)));
|
||||
|
@ -434,7 +500,7 @@ namespace ts.server {
|
|||
}
|
||||
|
||||
const { configFileErrors } = this.convertConfigFileContentToProjectOptions(fileName);
|
||||
this.reportConfigFileDiagnostics(fileName, configFileErrors);
|
||||
this.reportConfigFileDiagnostics(fileName, configFileErrors, fileName);
|
||||
|
||||
this.logger.info(`Detected newly added tsconfig file: ${fileName}`);
|
||||
this.reloadProjects();
|
||||
|
@ -744,12 +810,13 @@ namespace ts.server {
|
|||
}
|
||||
|
||||
private createAndAddExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typingOptions: TypingOptions) {
|
||||
const compilerOptions = convertCompilerOptions(options);
|
||||
const project = new ExternalProject(
|
||||
projectFileName,
|
||||
this,
|
||||
this.documentRegistry,
|
||||
options,
|
||||
/*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(options, files, externalFilePropertyReader),
|
||||
compilerOptions,
|
||||
/*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, files, externalFilePropertyReader),
|
||||
options.compileOnSave === undefined ? true : options.compileOnSave);
|
||||
|
||||
this.addFilesToProjectAndUpdateGraph(project, files, externalFilePropertyReader, /*clientFileName*/ undefined, typingOptions, /*configFileErrors*/ undefined);
|
||||
|
@ -757,7 +824,7 @@ namespace ts.server {
|
|||
return project;
|
||||
}
|
||||
|
||||
private reportConfigFileDiagnostics(configFileName: string, diagnostics: Diagnostic[], triggerFile?: string) {
|
||||
private reportConfigFileDiagnostics(configFileName: string, diagnostics: Diagnostic[], triggerFile: string) {
|
||||
if (!this.eventHandler) {
|
||||
return;
|
||||
}
|
||||
|
@ -1018,7 +1085,7 @@ namespace ts.server {
|
|||
if (args.file) {
|
||||
const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(args.file));
|
||||
if (info) {
|
||||
info.setFormatOptions(args.formatOptions);
|
||||
info.setFormatOptions(convertFormatOptions(args.formatOptions));
|
||||
this.logger.info(`Host configuration update for file ${args.file}`);
|
||||
}
|
||||
}
|
||||
|
@ -1028,7 +1095,7 @@ namespace ts.server {
|
|||
this.logger.info(`Host information ${args.hostInfo}`);
|
||||
}
|
||||
if (args.formatOptions) {
|
||||
mergeMaps(this.hostConfiguration.formatCodeOptions, args.formatOptions);
|
||||
mergeMaps(this.hostConfiguration.formatCodeOptions, convertFormatOptions(args.formatOptions));
|
||||
this.logger.info("Format host information updated");
|
||||
}
|
||||
}
|
||||
|
@ -1142,7 +1209,7 @@ namespace ts.server {
|
|||
const scriptInfo = this.getScriptInfo(file.fileName);
|
||||
Debug.assert(!scriptInfo || !scriptInfo.isOpen);
|
||||
const normalizedPath = scriptInfo ? scriptInfo.fileName : toNormalizedPath(file.fileName);
|
||||
this.openClientFileWithNormalizedPath(normalizedPath, file.content, file.scriptKind, file.hasMixedContent);
|
||||
this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1235,7 +1302,7 @@ namespace ts.server {
|
|||
if (externalProject) {
|
||||
if (!tsConfigFiles) {
|
||||
// external project already exists and not config files were added - update the project and return;
|
||||
this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, proj.options, proj.typingOptions, proj.options.compileOnSave, /*configFileErrors*/ undefined);
|
||||
this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, convertCompilerOptions(proj.options), proj.typingOptions, proj.options.compileOnSave, /*configFileErrors*/ undefined);
|
||||
return;
|
||||
}
|
||||
// some config files were added to external project (that previously were not there)
|
||||
|
|
|
@ -437,11 +437,11 @@ namespace ts.server {
|
|||
}
|
||||
}
|
||||
|
||||
reloadScript(filename: NormalizedPath): boolean {
|
||||
reloadScript(filename: NormalizedPath, tempFileName?: NormalizedPath): boolean {
|
||||
const script = this.projectService.getScriptInfoForNormalizedPath(filename);
|
||||
if (script) {
|
||||
Debug.assert(script.isAttached(this));
|
||||
script.reloadFromFile();
|
||||
script.reloadFromFile(tempFileName);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -109,7 +109,7 @@ namespace ts.server.protocol {
|
|||
/**
|
||||
* One of "request", "response", or "event"
|
||||
*/
|
||||
type: string;
|
||||
type: "request" | "response" | "event";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -833,7 +833,7 @@ namespace ts.server.protocol {
|
|||
/**
|
||||
* Script kind of the file
|
||||
*/
|
||||
scriptKind?: ScriptKind;
|
||||
scriptKind?: ScriptKindName | ts.ScriptKind;
|
||||
/**
|
||||
* Whether file has mixed content (i.e. .cshtml file that combines html markup with C#/JavaScript)
|
||||
*/
|
||||
|
@ -866,20 +866,23 @@ namespace ts.server.protocol {
|
|||
typingOptions?: TypingOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* For external projects, some of the project settings are sent together with
|
||||
* compiler settings.
|
||||
*/
|
||||
export interface ExternalProjectCompilerOptions extends CompilerOptions {
|
||||
export interface CompileOnSaveMixin {
|
||||
/**
|
||||
* If compile on save is enabled for the project
|
||||
*/
|
||||
compileOnSave?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* For external projects, some of the project settings are sent together with
|
||||
* compiler settings.
|
||||
*/
|
||||
export type ExternalProjectCompilerOptions = CompilerOptions & CompileOnSaveMixin;
|
||||
|
||||
/**
|
||||
* Contains information about current project version
|
||||
*/
|
||||
/* @internal */
|
||||
export interface ProjectVersionInfo {
|
||||
/**
|
||||
* Project name
|
||||
|
@ -896,7 +899,7 @@ namespace ts.server.protocol {
|
|||
/**
|
||||
* Current set of compiler options for project
|
||||
*/
|
||||
options: CompilerOptions;
|
||||
options: ts.CompilerOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -920,6 +923,7 @@ namespace ts.server.protocol {
|
|||
* if changes is set - then this is the set of changes that should be applied to existing project
|
||||
* otherwise - assume that nothing is changed
|
||||
*/
|
||||
/* @internal */
|
||||
export interface ProjectFiles {
|
||||
/**
|
||||
* Information abount project verison
|
||||
|
@ -938,6 +942,7 @@ namespace ts.server.protocol {
|
|||
/**
|
||||
* Combines project information with project level errors.
|
||||
*/
|
||||
/* @internal */
|
||||
export interface ProjectFilesWithDiagnostics extends ProjectFiles {
|
||||
/**
|
||||
* List of errors in project
|
||||
|
@ -1012,9 +1017,11 @@ namespace ts.server.protocol {
|
|||
* Used to specify the script kind of the file explicitly. It could be one of the following:
|
||||
* "TS", "JS", "TSX", "JSX"
|
||||
*/
|
||||
scriptKindName?: "TS" | "JS" | "TSX" | "JSX";
|
||||
scriptKindName?: ScriptKindName;
|
||||
}
|
||||
|
||||
export type ScriptKindName = "TS" | "JS" | "TSX" | "JSX";
|
||||
|
||||
/**
|
||||
* Open request; value of command field is "open". Notify the
|
||||
* server that the client has file open. The server will not
|
||||
|
@ -1109,6 +1116,7 @@ namespace ts.server.protocol {
|
|||
/**
|
||||
* Arguments to SynchronizeProjectListRequest
|
||||
*/
|
||||
/* @internal */
|
||||
export interface SynchronizeProjectListRequestArgs {
|
||||
/**
|
||||
* List of last known projects
|
||||
|
@ -2056,4 +2064,141 @@ namespace ts.server.protocol {
|
|||
export interface NavTreeResponse extends Response {
|
||||
body?: NavigationTree;
|
||||
}
|
||||
|
||||
export namespace IndentStyle {
|
||||
export type None = "None";
|
||||
export type Block = "Block";
|
||||
export type Smart = "Smart";
|
||||
}
|
||||
|
||||
export type IndentStyle = IndentStyle.None | IndentStyle.Block | IndentStyle.Smart;
|
||||
|
||||
export interface EditorSettings {
|
||||
baseIndentSize?: number;
|
||||
indentSize?: number;
|
||||
tabSize?: number;
|
||||
newLineCharacter?: string;
|
||||
convertTabsToSpaces?: boolean;
|
||||
indentStyle?: IndentStyle | ts.IndentStyle;
|
||||
}
|
||||
|
||||
export interface FormatCodeSettings extends EditorSettings {
|
||||
insertSpaceAfterCommaDelimiter?: boolean;
|
||||
insertSpaceAfterSemicolonInForStatements?: boolean;
|
||||
insertSpaceBeforeAndAfterBinaryOperators?: boolean;
|
||||
insertSpaceAfterKeywordsInControlFlowStatements?: boolean;
|
||||
insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
|
||||
placeOpenBraceOnNewLineForFunctions?: boolean;
|
||||
placeOpenBraceOnNewLineForControlBlocks?: boolean;
|
||||
}
|
||||
|
||||
export interface CompilerOptions {
|
||||
allowJs?: boolean;
|
||||
allowSyntheticDefaultImports?: boolean;
|
||||
allowUnreachableCode?: boolean;
|
||||
allowUnusedLabels?: boolean;
|
||||
baseUrl?: string;
|
||||
charset?: string;
|
||||
declaration?: boolean;
|
||||
declarationDir?: string;
|
||||
disableSizeLimit?: boolean;
|
||||
emitBOM?: boolean;
|
||||
emitDecoratorMetadata?: boolean;
|
||||
experimentalDecorators?: boolean;
|
||||
forceConsistentCasingInFileNames?: boolean;
|
||||
inlineSourceMap?: boolean;
|
||||
inlineSources?: boolean;
|
||||
isolatedModules?: boolean;
|
||||
jsx?: JsxEmit | ts.JsxEmit;
|
||||
lib?: string[];
|
||||
locale?: string;
|
||||
mapRoot?: string;
|
||||
maxNodeModuleJsDepth?: number;
|
||||
module?: ModuleKind | ts.ModuleKind;
|
||||
moduleResolution?: ModuleResolutionKind | ts.ModuleResolutionKind;
|
||||
newLine?: NewLineKind | ts.NewLineKind;
|
||||
noEmit?: boolean;
|
||||
noEmitHelpers?: boolean;
|
||||
noEmitOnError?: boolean;
|
||||
noErrorTruncation?: boolean;
|
||||
noFallthroughCasesInSwitch?: boolean;
|
||||
noImplicitAny?: boolean;
|
||||
noImplicitReturns?: boolean;
|
||||
noImplicitThis?: boolean;
|
||||
noUnusedLocals?: boolean;
|
||||
noUnusedParameters?: boolean;
|
||||
noImplicitUseStrict?: boolean;
|
||||
noLib?: boolean;
|
||||
noResolve?: boolean;
|
||||
out?: string;
|
||||
outDir?: string;
|
||||
outFile?: string;
|
||||
paths?: MapLike<string[]>;
|
||||
preserveConstEnums?: boolean;
|
||||
project?: string;
|
||||
reactNamespace?: string;
|
||||
removeComments?: boolean;
|
||||
rootDir?: string;
|
||||
rootDirs?: string[];
|
||||
skipLibCheck?: boolean;
|
||||
skipDefaultLibCheck?: boolean;
|
||||
sourceMap?: boolean;
|
||||
sourceRoot?: string;
|
||||
strictNullChecks?: boolean;
|
||||
suppressExcessPropertyErrors?: boolean;
|
||||
suppressImplicitAnyIndexErrors?: boolean;
|
||||
target?: ScriptTarget | ts.ScriptTarget;
|
||||
traceResolution?: boolean;
|
||||
types?: string[];
|
||||
/** Paths used to used to compute primary types search locations */
|
||||
typeRoots?: string[];
|
||||
[option: string]: CompilerOptionsValue | undefined;
|
||||
}
|
||||
|
||||
export namespace JsxEmit {
|
||||
export type None = "None";
|
||||
export type Preserve = "Preserve";
|
||||
export type React = "React";
|
||||
}
|
||||
|
||||
export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React;
|
||||
|
||||
export namespace ModuleKind {
|
||||
export type None = "None";
|
||||
export type CommonJS = "CommonJS";
|
||||
export type AMD = "AMD";
|
||||
export type UMD = "UMD";
|
||||
export type System = "System";
|
||||
export type ES6 = "ES6";
|
||||
export type ES2015 = "ES2015";
|
||||
}
|
||||
|
||||
export type ModuleKind = ModuleKind.None | ModuleKind.CommonJS | ModuleKind.AMD | ModuleKind.UMD | ModuleKind.System | ModuleKind.ES6 | ModuleKind.ES2015;
|
||||
|
||||
export namespace ModuleResolutionKind {
|
||||
export type Classic = "Classic";
|
||||
export type Node = "Node";
|
||||
}
|
||||
|
||||
export type ModuleResolutionKind = ModuleResolutionKind.Classic | ModuleResolutionKind.Node;
|
||||
|
||||
export namespace NewLineKind {
|
||||
export type Crlf = "Crlf";
|
||||
export type Lf = "Lf";
|
||||
}
|
||||
|
||||
export type NewLineKind = NewLineKind.Crlf | NewLineKind.Lf;
|
||||
|
||||
export namespace ScriptTarget {
|
||||
export type ES3 = "ES3";
|
||||
export type ES5 = "ES5";
|
||||
export type ES6 = "ES6";
|
||||
export type ES2015 = "ES2015";
|
||||
}
|
||||
|
||||
export type ScriptTarget = ScriptTarget.ES3 | ScriptTarget.ES5 | ScriptTarget.ES6 | ScriptTarget.ES2015;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,6 @@ namespace ts.server {
|
|||
if (this.containingProjects.length === 0) {
|
||||
return Errors.ThrowNoProject();
|
||||
}
|
||||
Debug.assert(this.containingProjects.length !== 0);
|
||||
return this.containingProjects[0];
|
||||
}
|
||||
|
||||
|
@ -126,12 +125,12 @@ namespace ts.server {
|
|||
this.host.writeFile(fileName, snap.getText(0, snap.getLength()));
|
||||
}
|
||||
|
||||
reloadFromFile() {
|
||||
reloadFromFile(tempFileName?: NormalizedPath) {
|
||||
if (this.hasMixedContent) {
|
||||
this.reload("");
|
||||
}
|
||||
else {
|
||||
this.svc.reloadFromFile(this.fileName);
|
||||
this.svc.reloadFromFile(tempFileName || this.fileName);
|
||||
this.markContainingProjectsAsDirty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -389,9 +389,9 @@ namespace ts.server {
|
|||
});
|
||||
}
|
||||
|
||||
private getDiagnosticsWorker(args: protocol.FileRequestArgs, selector: (project: Project, file: string) => Diagnostic[], includeLinePosition: boolean) {
|
||||
private getDiagnosticsWorker(args: protocol.FileRequestArgs, isSemantic: boolean, selector: (project: Project, file: string) => Diagnostic[], includeLinePosition: boolean) {
|
||||
const { project, file } = this.getFileAndProject(args);
|
||||
if (shouldSkipSematicCheck(project)) {
|
||||
if (isSemantic && shouldSkipSematicCheck(project)) {
|
||||
return [];
|
||||
}
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
|
||||
|
@ -492,11 +492,11 @@ namespace ts.server {
|
|||
}
|
||||
|
||||
private getSyntacticDiagnosticsSync(args: protocol.SyntacticDiagnosticsSyncRequestArgs): protocol.Diagnostic[] | protocol.DiagnosticWithLinePosition[] {
|
||||
return this.getDiagnosticsWorker(args, (project, file) => project.getLanguageService().getSyntacticDiagnostics(file), args.includeLinePosition);
|
||||
return this.getDiagnosticsWorker(args, /*isSemantic*/ false, (project, file) => project.getLanguageService().getSyntacticDiagnostics(file), args.includeLinePosition);
|
||||
}
|
||||
|
||||
private getSemanticDiagnosticsSync(args: protocol.SemanticDiagnosticsSyncRequestArgs): protocol.Diagnostic[] | protocol.DiagnosticWithLinePosition[] {
|
||||
return this.getDiagnosticsWorker(args, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), args.includeLinePosition);
|
||||
return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), args.includeLinePosition);
|
||||
}
|
||||
|
||||
private getDocumentHighlights(args: protocol.DocumentHighlightsRequestArgs, simplifiedResult: boolean): protocol.DocumentHighlightsItem[] | DocumentHighlights[] {
|
||||
|
@ -761,7 +761,7 @@ namespace ts.server {
|
|||
if (this.eventHander) {
|
||||
this.eventHander({
|
||||
eventName: "configFileDiag",
|
||||
data: { fileName, configFileName, diagnostics: configFileErrors || [] }
|
||||
data: { triggerFile: fileName, configFileName, diagnostics: configFileErrors || [] }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -807,7 +807,7 @@ namespace ts.server {
|
|||
private getIndentation(args: protocol.IndentationRequestArgs) {
|
||||
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
|
||||
const position = this.getPosition(args, project.getScriptInfoForNormalizedPath(file));
|
||||
const options = args.options || this.projectService.getFormatCodeOptions(file);
|
||||
const options = args.options ? convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file);
|
||||
const indentation = project.getLanguageService(/*ensureSynchronized*/ false).getIndentationAtPosition(file, position, options);
|
||||
return { position, indentation };
|
||||
}
|
||||
|
@ -874,19 +874,19 @@ namespace ts.server {
|
|||
|
||||
private getFormattingEditsForRangeFull(args: protocol.FormatRequestArgs) {
|
||||
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
|
||||
const options = args.options || this.projectService.getFormatCodeOptions(file);
|
||||
const options = args.options ? convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file);
|
||||
return project.getLanguageService(/*ensureSynchronized*/ false).getFormattingEditsForRange(file, args.position, args.endPosition, options);
|
||||
}
|
||||
|
||||
private getFormattingEditsForDocumentFull(args: protocol.FormatRequestArgs) {
|
||||
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
|
||||
const options = args.options || this.projectService.getFormatCodeOptions(file);
|
||||
const options = args.options ? convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file);
|
||||
return project.getLanguageService(/*ensureSynchronized*/ false).getFormattingEditsForDocument(file, options);
|
||||
}
|
||||
|
||||
private getFormattingEditsAfterKeystrokeFull(args: protocol.FormatOnKeyRequestArgs) {
|
||||
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
|
||||
const options = args.options || this.projectService.getFormatCodeOptions(file);
|
||||
const options = args.options ? convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file);
|
||||
return project.getLanguageService(/*ensureSynchronized*/ false).getFormattingEditsAfterKeystroke(file, args.position, args.key, options);
|
||||
}
|
||||
|
||||
|
@ -967,7 +967,7 @@ namespace ts.server {
|
|||
result.push({ name, kind, kindModifiers, sortText, replacementSpan: convertedSpan });
|
||||
}
|
||||
return result;
|
||||
}, []).sort((a, b) => a.name.localeCompare(b.name));
|
||||
}, []).sort((a, b) => ts.compareStrings(a.name, b.name));
|
||||
}
|
||||
else {
|
||||
return completions;
|
||||
|
@ -1076,11 +1076,12 @@ namespace ts.server {
|
|||
|
||||
private reload(args: protocol.ReloadRequestArgs, reqSeq: number) {
|
||||
const file = toNormalizedPath(args.file);
|
||||
const tempFileName = args.tmpfile && toNormalizedPath(args.tmpfile);
|
||||
const project = this.projectService.getDefaultProjectForFile(file, /*refreshInferredProjects*/ true);
|
||||
if (project) {
|
||||
this.changeSeq++;
|
||||
// make sure no changes happen before this one is finished
|
||||
if (project.reloadScript(file)) {
|
||||
if (project.reloadScript(file, tempFileName)) {
|
||||
this.output(undefined, CommandNames.Reload, reqSeq);
|
||||
}
|
||||
}
|
||||
|
@ -1426,24 +1427,8 @@ namespace ts.server {
|
|||
[CommandNames.RenameInfoFull]: (request: protocol.FileLocationRequest) => {
|
||||
return this.requiredResponse(this.getRenameInfo(request.arguments));
|
||||
},
|
||||
[CommandNames.Open]: (request: protocol.Request) => {
|
||||
const openArgs = <protocol.OpenRequestArgs>request.arguments;
|
||||
let scriptKind: ScriptKind;
|
||||
switch (openArgs.scriptKindName) {
|
||||
case "TS":
|
||||
scriptKind = ScriptKind.TS;
|
||||
break;
|
||||
case "JS":
|
||||
scriptKind = ScriptKind.JS;
|
||||
break;
|
||||
case "TSX":
|
||||
scriptKind = ScriptKind.TSX;
|
||||
break;
|
||||
case "JSX":
|
||||
scriptKind = ScriptKind.JSX;
|
||||
break;
|
||||
}
|
||||
this.openClientFile(toNormalizedPath(openArgs.file), openArgs.fileContent, scriptKind);
|
||||
[CommandNames.Open]: (request: protocol.OpenRequest) => {
|
||||
this.openClientFile(toNormalizedPath(request.arguments.file), request.arguments.fileContent, convertScriptKindName(request.arguments.scriptKindName));
|
||||
return this.notRequired();
|
||||
},
|
||||
[CommandNames.Quickinfo]: (request: protocol.QuickInfoRequest) => {
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
"stripInternal": true,
|
||||
"types": [
|
||||
"node"
|
||||
]
|
||||
],
|
||||
"target": "es5"
|
||||
},
|
||||
"files": [
|
||||
"../services/shims.ts",
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
"sourceMap": true,
|
||||
"stripInternal": true,
|
||||
"declaration": true,
|
||||
"types": []
|
||||
"types": [],
|
||||
"target": "es5"
|
||||
},
|
||||
"files": [
|
||||
"../services/shims.ts",
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
"stripInternal": true,
|
||||
"types": [
|
||||
"node"
|
||||
]
|
||||
],
|
||||
"target": "es5"
|
||||
},
|
||||
"files": [
|
||||
"../types.d.ts",
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path='../compiler/utilities.ts' />
|
||||
|
||||
/* @internal */
|
||||
namespace ts.Completions {
|
||||
export function getCompletionsAtPosition(host: LanguageServiceHost, typeChecker: TypeChecker, log: (message: string) => void, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number): CompletionInfo {
|
||||
|
@ -951,7 +953,6 @@ namespace ts.Completions {
|
|||
if (!tryGetGlobalSymbols()) {
|
||||
return undefined;
|
||||
}
|
||||
isGlobalCompletion = true;
|
||||
}
|
||||
|
||||
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
|
||||
|
@ -1030,7 +1031,6 @@ namespace ts.Completions {
|
|||
if ((jsxContainer.kind === SyntaxKind.JsxSelfClosingElement) || (jsxContainer.kind === SyntaxKind.JsxOpeningElement)) {
|
||||
// Cursor is inside a JSX self-closing element or opening element
|
||||
attrsType = typeChecker.getJsxElementAttributesType(<JsxOpeningLikeElement>jsxContainer);
|
||||
isGlobalCompletion = false;
|
||||
|
||||
if (attrsType) {
|
||||
symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (<JsxOpeningLikeElement>jsxContainer).attributes);
|
||||
|
@ -1038,7 +1038,6 @@ namespace ts.Completions {
|
|||
isNewIdentifierLocation = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1079,6 +1078,13 @@ namespace ts.Completions {
|
|||
position;
|
||||
|
||||
const scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile;
|
||||
if (scopeNode) {
|
||||
isGlobalCompletion =
|
||||
scopeNode.kind === SyntaxKind.SourceFile ||
|
||||
scopeNode.kind === SyntaxKind.TemplateExpression ||
|
||||
scopeNode.kind === SyntaxKind.JsxExpression ||
|
||||
isStatement(scopeNode);
|
||||
}
|
||||
|
||||
/// TODO filter meaning based on the current context
|
||||
const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias;
|
||||
|
|
|
@ -624,10 +624,11 @@ namespace ts.formatting {
|
|||
return inheritedIndentation;
|
||||
}
|
||||
|
||||
if (isToken(child)) {
|
||||
// JSX text shouldn't affect indenting
|
||||
if (isToken(child) && child.kind !== SyntaxKind.JsxText) {
|
||||
// if child node is a token, it does not impact indentation, proceed it using parent indentation scope rules
|
||||
const tokenInfo = formattingScanner.readTokenInfo(child);
|
||||
Debug.assert(tokenInfo.token.end === child.end);
|
||||
Debug.assert(tokenInfo.token.end === child.end, "Token end is child end");
|
||||
consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, child);
|
||||
return inheritedIndentation;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace ts.formatting {
|
|||
}
|
||||
|
||||
export function getFormattingScanner(sourceFile: SourceFile, startPos: number, endPos: number): FormattingScanner {
|
||||
Debug.assert(scanner === undefined);
|
||||
Debug.assert(scanner === undefined, "Scanner should be undefined");
|
||||
scanner = sourceFile.languageVariant === LanguageVariant.JSX ? jsxScanner : standardScanner;
|
||||
|
||||
scanner.setText(sourceFile.text);
|
||||
|
@ -62,7 +62,7 @@ namespace ts.formatting {
|
|||
};
|
||||
|
||||
function advance(): void {
|
||||
Debug.assert(scanner !== undefined);
|
||||
Debug.assert(scanner !== undefined, "Scanner should be present");
|
||||
|
||||
lastTokenInfo = undefined;
|
||||
const isStarted = scanner.getStartPos() !== startPos;
|
||||
|
|
|
@ -35,8 +35,8 @@ namespace ts.formatting {
|
|||
}
|
||||
|
||||
private GetRuleBucketIndex(row: number, column: number): number {
|
||||
Debug.assert(row <= SyntaxKind.LastKeyword && column <= SyntaxKind.LastKeyword, "Must compute formatting context from tokens");
|
||||
const rulesBucketIndex = (row * this.mapRowLength) + column;
|
||||
// Debug.Assert(rulesBucketIndex < this.map.Length, "Trying to access an index outside the array.");
|
||||
return rulesBucketIndex;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,9 +6,6 @@ namespace ts.NavigateTo {
|
|||
const patternMatcher = createPatternMatcher(searchValue);
|
||||
let rawItems: RawNavigateToItem[] = [];
|
||||
|
||||
// This means "compare in a case insensitive manner."
|
||||
const baseSensitivity: Intl.CollatorOptions = { sensitivity: "base" };
|
||||
|
||||
// Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[]
|
||||
forEach(sourceFiles, sourceFile => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
@ -188,8 +185,8 @@ namespace ts.NavigateTo {
|
|||
// We first sort case insensitively. So "Aaa" will come before "bar".
|
||||
// Then we sort case sensitively, so "aaa" will come before "Aaa".
|
||||
return i1.matchKind - i2.matchKind ||
|
||||
i1.name.localeCompare(i2.name, undefined, baseSensitivity) ||
|
||||
i1.name.localeCompare(i2.name);
|
||||
ts.compareStringsCaseInsensitive(i1.name, i2.name) ||
|
||||
ts.compareStrings(i1.name, i2.name);
|
||||
}
|
||||
|
||||
function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem {
|
||||
|
|
|
@ -330,10 +330,8 @@ namespace ts.NavigationBar {
|
|||
}
|
||||
}
|
||||
|
||||
// More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times.
|
||||
const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined;
|
||||
// Intl is missing in Safari, and node 0.10 treats "a" as greater than "B".
|
||||
const localeCompareIsCorrect = collator && collator.compare("a", "B") < 0;
|
||||
const localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0;
|
||||
const localeCompareFix: (a: string, b: string) => number = localeCompareIsCorrect ? collator.compare : function(a, b) {
|
||||
// This isn't perfect, but it passes all of our tests.
|
||||
for (let i = 0; i < Math.min(a.length, b.length); i++) {
|
||||
|
@ -344,7 +342,7 @@ namespace ts.NavigationBar {
|
|||
if (chA === "'" && chB === "\"") {
|
||||
return -1;
|
||||
}
|
||||
const cmp = chA.toLocaleLowerCase().localeCompare(chB.toLocaleLowerCase());
|
||||
const cmp = ts.compareStrings(chA.toLocaleLowerCase(), chB.toLocaleLowerCase());
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
|
|
@ -444,7 +444,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
public readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[], depth?: number): string[] {
|
||||
const pattern = getFileMatcherPatterns(path, extensions, exclude, include,
|
||||
const pattern = getFileMatcherPatterns(path, exclude, include,
|
||||
this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory());
|
||||
return JSON.parse(this.shimHost.readDirectory(
|
||||
path,
|
||||
|
@ -509,7 +509,7 @@ namespace ts {
|
|||
// Wrap the API changes for 2.0 release. This try/catch
|
||||
// should be removed once TypeScript 2.0 has shipped.
|
||||
try {
|
||||
const pattern = getFileMatcherPatterns(rootDir, extensions, exclude, include,
|
||||
const pattern = getFileMatcherPatterns(rootDir, exclude, include,
|
||||
this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory());
|
||||
return JSON.parse(this.shimHost.readDirectory(
|
||||
rootDir,
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
"sourceMap": true,
|
||||
"stripInternal": true,
|
||||
"noResolve": false,
|
||||
"declaration": true
|
||||
"declaration": true,
|
||||
"target": "es5"
|
||||
},
|
||||
"files": [
|
||||
"../compiler/core.ts",
|
||||
|
@ -26,13 +27,15 @@
|
|||
"../compiler/transformers/ts.ts",
|
||||
"../compiler/transformers/jsx.ts",
|
||||
"../compiler/transformers/experimental.ts",
|
||||
"../compiler/transformers/es7.ts",
|
||||
"../compiler/transformers/es6.ts",
|
||||
"../compiler/transformers/es2017.ts",
|
||||
"../compiler/transformers/es2016.ts",
|
||||
"../compiler/transformers/es2015.ts",
|
||||
"../compiler/transformers/generators.ts",
|
||||
"../compiler/transformers/generators.ts",
|
||||
"../compiler/transformers/destructuring.ts",
|
||||
"../compiler/transformers/module/module.ts",
|
||||
"../compiler/transformers/module/system.ts",
|
||||
"../compiler/transformers/module/es6.ts",
|
||||
"../compiler/transformers/module/es2015.ts",
|
||||
"../compiler/transformer.ts",
|
||||
"../compiler/comments.ts",
|
||||
"../compiler/sourcemap.ts",
|
||||
|
|
|
@ -750,7 +750,7 @@ namespace ts {
|
|||
return find(startNode || sourceFile);
|
||||
|
||||
function findRightmostToken(n: Node): Node {
|
||||
if (isToken(n) || n.kind === SyntaxKind.JsxText) {
|
||||
if (isToken(n)) {
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -761,7 +761,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function find(n: Node): Node {
|
||||
if (isToken(n) || n.kind === SyntaxKind.JsxText) {
|
||||
if (isToken(n)) {
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -1339,7 +1339,7 @@ namespace ts {
|
|||
const options: TranspileOptions = {
|
||||
fileName: "config.js",
|
||||
compilerOptions: {
|
||||
target: ScriptTarget.ES6,
|
||||
target: ScriptTarget.ES2015,
|
||||
removeComments: true
|
||||
},
|
||||
reportDiagnostics: true
|
||||
|
|
|
@ -58,7 +58,7 @@ export function delint(sourceFile: ts.SourceFile) {
|
|||
const fileNames: string[] = process.argv.slice(2);
|
||||
fileNames.forEach(fileName => {
|
||||
// Parse a file
|
||||
let sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES6, /*setParentNodes */ true);
|
||||
let sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES2015, /*setParentNodes */ true);
|
||||
|
||||
// delint it
|
||||
delint(sourceFile);
|
||||
|
@ -113,7 +113,7 @@ exports.delint = delint;
|
|||
var fileNames = process.argv.slice(2);
|
||||
fileNames.forEach(function (fileName) {
|
||||
// Parse a file
|
||||
var sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES6, /*setParentNodes */ true);
|
||||
var sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES2015, /*setParentNodes */ true);
|
||||
// delint it
|
||||
delint(sourceFile);
|
||||
});
|
||||
|
|
|
@ -13,5 +13,5 @@ Foo.default.default.foo();
|
|||
//// [a.js]
|
||||
"use strict";
|
||||
var Foo = require("./b");
|
||||
Foo.default.bar();
|
||||
Foo.default.default.foo();
|
||||
Foo["default"].bar();
|
||||
Foo["default"]["default"].foo();
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
//// [arrowFunctionWithParameterNameAsync_es2017.ts]
|
||||
|
||||
const x = async => async;
|
||||
|
||||
//// [arrowFunctionWithParameterNameAsync_es2017.js]
|
||||
var x = function (async) { return async; };
|
|
@ -0,0 +1,7 @@
|
|||
=== tests/cases/conformance/async/es2017/asyncArrowFunction/arrowFunctionWithParameterNameAsync_es2017.ts ===
|
||||
|
||||
const x = async => async;
|
||||
>x : Symbol(x, Decl(arrowFunctionWithParameterNameAsync_es2017.ts, 1, 5))
|
||||
>async : Symbol(async, Decl(arrowFunctionWithParameterNameAsync_es2017.ts, 1, 9))
|
||||
>async : Symbol(async, Decl(arrowFunctionWithParameterNameAsync_es2017.ts, 1, 9))
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
=== tests/cases/conformance/async/es2017/asyncArrowFunction/arrowFunctionWithParameterNameAsync_es2017.ts ===
|
||||
|
||||
const x = async => async;
|
||||
>x : (async: any) => any
|
||||
>async => async : (async: any) => any
|
||||
>async : any
|
||||
>async : any
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction10_es2017.ts(4,11): error TS2304: Cannot find name 'await'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction10_es2017.ts (1 errors) ====
|
||||
|
||||
var foo = async (): Promise<void> => {
|
||||
// Legal to use 'await' in a type context.
|
||||
var v: await;
|
||||
~~~~~
|
||||
!!! error TS2304: Cannot find name 'await'.
|
||||
}
|
||||
|
13
tests/baselines/reference/asyncArrowFunction10_es2017.js
Normal file
13
tests/baselines/reference/asyncArrowFunction10_es2017.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
//// [asyncArrowFunction10_es2017.ts]
|
||||
|
||||
var foo = async (): Promise<void> => {
|
||||
// Legal to use 'await' in a type context.
|
||||
var v: await;
|
||||
}
|
||||
|
||||
|
||||
//// [asyncArrowFunction10_es2017.js]
|
||||
var foo = async () => {
|
||||
// Legal to use 'await' in a type context.
|
||||
var v;
|
||||
};
|
8
tests/baselines/reference/asyncArrowFunction1_es2017.js
Normal file
8
tests/baselines/reference/asyncArrowFunction1_es2017.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
//// [asyncArrowFunction1_es2017.ts]
|
||||
|
||||
var foo = async (): Promise<void> => {
|
||||
};
|
||||
|
||||
//// [asyncArrowFunction1_es2017.js]
|
||||
var foo = async () => {
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction1_es2017.ts ===
|
||||
|
||||
var foo = async (): Promise<void> => {
|
||||
>foo : Symbol(foo, Decl(asyncArrowFunction1_es2017.ts, 1, 3))
|
||||
>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --))
|
||||
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction1_es2017.ts ===
|
||||
|
||||
var foo = async (): Promise<void> => {
|
||||
>foo : () => Promise<void>
|
||||
>async (): Promise<void> => {} : () => Promise<void>
|
||||
>Promise : Promise<T>
|
||||
|
||||
};
|
7
tests/baselines/reference/asyncArrowFunction2_es2017.js
Normal file
7
tests/baselines/reference/asyncArrowFunction2_es2017.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
//// [asyncArrowFunction2_es2017.ts]
|
||||
var f = (await) => {
|
||||
}
|
||||
|
||||
//// [asyncArrowFunction2_es2017.js]
|
||||
var f = (await) => {
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction2_es2017.ts ===
|
||||
var f = (await) => {
|
||||
>f : Symbol(f, Decl(asyncArrowFunction2_es2017.ts, 0, 3))
|
||||
>await : Symbol(await, Decl(asyncArrowFunction2_es2017.ts, 0, 9))
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction2_es2017.ts ===
|
||||
var f = (await) => {
|
||||
>f : (await: any) => void
|
||||
>(await) => {} : (await: any) => void
|
||||
>await : any
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction3_es2017.ts(1,20): error TS2372: Parameter 'await' cannot be referenced in its initializer.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction3_es2017.ts (1 errors) ====
|
||||
function f(await = await) {
|
||||
~~~~~
|
||||
!!! error TS2372: Parameter 'await' cannot be referenced in its initializer.
|
||||
}
|
7
tests/baselines/reference/asyncArrowFunction3_es2017.js
Normal file
7
tests/baselines/reference/asyncArrowFunction3_es2017.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
//// [asyncArrowFunction3_es2017.ts]
|
||||
function f(await = await) {
|
||||
}
|
||||
|
||||
//// [asyncArrowFunction3_es2017.js]
|
||||
function f(await = await) {
|
||||
}
|
7
tests/baselines/reference/asyncArrowFunction4_es2017.js
Normal file
7
tests/baselines/reference/asyncArrowFunction4_es2017.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
//// [asyncArrowFunction4_es2017.ts]
|
||||
var await = () => {
|
||||
}
|
||||
|
||||
//// [asyncArrowFunction4_es2017.js]
|
||||
var await = () => {
|
||||
};
|
|
@ -0,0 +1,4 @@
|
|||
=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction4_es2017.ts ===
|
||||
var await = () => {
|
||||
>await : Symbol(await, Decl(asyncArrowFunction4_es2017.ts, 0, 3))
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction4_es2017.ts ===
|
||||
var await = () => {
|
||||
>await : () => void
|
||||
>() => {} : () => void
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts(2,11): error TS2304: Cannot find name 'async'.
|
||||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts(2,18): error TS2304: Cannot find name 'await'.
|
||||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts(2,24): error TS1005: ',' expected.
|
||||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts(2,26): error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'void'.
|
||||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts(2,33): error TS1005: '=' expected.
|
||||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts(2,40): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts (6 errors) ====
|
||||
|
||||
var foo = async (await): Promise<void> => {
|
||||
~~~~~
|
||||
!!! error TS2304: Cannot find name 'async'.
|
||||
~~~~~
|
||||
!!! error TS2304: Cannot find name 'await'.
|
||||
~
|
||||
!!! error TS1005: ',' expected.
|
||||
~~~~~~~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'void'.
|
||||
~
|
||||
!!! error TS1005: '=' expected.
|
||||
~~
|
||||
!!! error TS1109: Expression expected.
|
||||
}
|
9
tests/baselines/reference/asyncArrowFunction5_es2017.js
Normal file
9
tests/baselines/reference/asyncArrowFunction5_es2017.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
//// [asyncArrowFunction5_es2017.ts]
|
||||
|
||||
var foo = async (await): Promise<void> => {
|
||||
}
|
||||
|
||||
//// [asyncArrowFunction5_es2017.js]
|
||||
var foo = async(await), Promise = ;
|
||||
{
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction6_es2017.ts(2,22): error TS2524: 'await' expressions cannot be used in a parameter initializer.
|
||||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction6_es2017.ts(2,27): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction6_es2017.ts (2 errors) ====
|
||||
|
||||
var foo = async (a = await): Promise<void> => {
|
||||
~~~~~
|
||||
!!! error TS2524: 'await' expressions cannot be used in a parameter initializer.
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
}
|
8
tests/baselines/reference/asyncArrowFunction6_es2017.js
Normal file
8
tests/baselines/reference/asyncArrowFunction6_es2017.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
//// [asyncArrowFunction6_es2017.ts]
|
||||
|
||||
var foo = async (a = await): Promise<void> => {
|
||||
}
|
||||
|
||||
//// [asyncArrowFunction6_es2017.js]
|
||||
var foo = async (a = await ) => {
|
||||
};
|
|
@ -0,0 +1,15 @@
|
|||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction7_es2017.ts(4,24): error TS2524: 'await' expressions cannot be used in a parameter initializer.
|
||||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction7_es2017.ts(4,29): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction7_es2017.ts (2 errors) ====
|
||||
|
||||
var bar = async (): Promise<void> => {
|
||||
// 'await' here is an identifier, and not an await expression.
|
||||
var foo = async (a = await): Promise<void> => {
|
||||
~~~~~
|
||||
!!! error TS2524: 'await' expressions cannot be used in a parameter initializer.
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
}
|
||||
}
|
14
tests/baselines/reference/asyncArrowFunction7_es2017.js
Normal file
14
tests/baselines/reference/asyncArrowFunction7_es2017.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
//// [asyncArrowFunction7_es2017.ts]
|
||||
|
||||
var bar = async (): Promise<void> => {
|
||||
// 'await' here is an identifier, and not an await expression.
|
||||
var foo = async (a = await): Promise<void> => {
|
||||
}
|
||||
}
|
||||
|
||||
//// [asyncArrowFunction7_es2017.js]
|
||||
var bar = async () => {
|
||||
// 'await' here is an identifier, and not an await expression.
|
||||
var foo = async (a = await ) => {
|
||||
};
|
||||
};
|
|
@ -0,0 +1,10 @@
|
|||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction8_es2017.ts(3,19): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction8_es2017.ts (1 errors) ====
|
||||
|
||||
var foo = async (): Promise<void> => {
|
||||
var v = { [await]: foo }
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
}
|
10
tests/baselines/reference/asyncArrowFunction8_es2017.js
Normal file
10
tests/baselines/reference/asyncArrowFunction8_es2017.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
//// [asyncArrowFunction8_es2017.ts]
|
||||
|
||||
var foo = async (): Promise<void> => {
|
||||
var v = { [await]: foo }
|
||||
}
|
||||
|
||||
//// [asyncArrowFunction8_es2017.js]
|
||||
var foo = async () => {
|
||||
var v = { [await ]: foo };
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts(1,11): error TS2304: Cannot find name 'async'.
|
||||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts(1,18): error TS2304: Cannot find name 'a'.
|
||||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts(1,37): error TS1005: ',' expected.
|
||||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts(1,39): error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'void'.
|
||||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts(1,46): error TS1005: '=' expected.
|
||||
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts(1,53): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts (6 errors) ====
|
||||
var foo = async (a = await => await): Promise<void> => {
|
||||
~~~~~
|
||||
!!! error TS2304: Cannot find name 'async'.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'a'.
|
||||
~
|
||||
!!! error TS1005: ',' expected.
|
||||
~~~~~~~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'void'.
|
||||
~
|
||||
!!! error TS1005: '=' expected.
|
||||
~~
|
||||
!!! error TS1109: Expression expected.
|
||||
}
|
8
tests/baselines/reference/asyncArrowFunction9_es2017.js
Normal file
8
tests/baselines/reference/asyncArrowFunction9_es2017.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
//// [asyncArrowFunction9_es2017.ts]
|
||||
var foo = async (a = await => await): Promise<void> => {
|
||||
}
|
||||
|
||||
//// [asyncArrowFunction9_es2017.js]
|
||||
var foo = async(a = await => await), Promise = ;
|
||||
{
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
//// [asyncArrowFunctionCapturesArguments_es2017.ts]
|
||||
class C {
|
||||
method() {
|
||||
function other() {}
|
||||
var fn = async () => await other.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [asyncArrowFunctionCapturesArguments_es2017.js]
|
||||
class C {
|
||||
method() {
|
||||
function other() { }
|
||||
var fn = async () => await other.apply(this, arguments);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesArguments_es2017.ts ===
|
||||
class C {
|
||||
>C : Symbol(C, Decl(asyncArrowFunctionCapturesArguments_es2017.ts, 0, 0))
|
||||
|
||||
method() {
|
||||
>method : Symbol(C.method, Decl(asyncArrowFunctionCapturesArguments_es2017.ts, 0, 9))
|
||||
|
||||
function other() {}
|
||||
>other : Symbol(other, Decl(asyncArrowFunctionCapturesArguments_es2017.ts, 1, 13))
|
||||
|
||||
var fn = async () => await other.apply(this, arguments);
|
||||
>fn : Symbol(fn, Decl(asyncArrowFunctionCapturesArguments_es2017.ts, 3, 9))
|
||||
>other.apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --))
|
||||
>other : Symbol(other, Decl(asyncArrowFunctionCapturesArguments_es2017.ts, 1, 13))
|
||||
>apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --))
|
||||
>this : Symbol(C, Decl(asyncArrowFunctionCapturesArguments_es2017.ts, 0, 0))
|
||||
>arguments : Symbol(arguments)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesArguments_es2017.ts ===
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
method() {
|
||||
>method : () => void
|
||||
|
||||
function other() {}
|
||||
>other : () => void
|
||||
|
||||
var fn = async () => await other.apply(this, arguments);
|
||||
>fn : () => Promise<any>
|
||||
>async () => await other.apply(this, arguments) : () => Promise<any>
|
||||
>await other.apply(this, arguments) : any
|
||||
>other.apply(this, arguments) : any
|
||||
>other.apply : (this: Function, thisArg: any, argArray?: any) => any
|
||||
>other : () => void
|
||||
>apply : (this: Function, thisArg: any, argArray?: any) => any
|
||||
>this : this
|
||||
>arguments : IArguments
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
//// [asyncArrowFunctionCapturesThis_es2017.ts]
|
||||
class C {
|
||||
method() {
|
||||
var fn = async () => await this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [asyncArrowFunctionCapturesThis_es2017.js]
|
||||
class C {
|
||||
method() {
|
||||
var fn = async () => await this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesThis_es2017.ts ===
|
||||
class C {
|
||||
>C : Symbol(C, Decl(asyncArrowFunctionCapturesThis_es2017.ts, 0, 0))
|
||||
|
||||
method() {
|
||||
>method : Symbol(C.method, Decl(asyncArrowFunctionCapturesThis_es2017.ts, 0, 9))
|
||||
|
||||
var fn = async () => await this;
|
||||
>fn : Symbol(fn, Decl(asyncArrowFunctionCapturesThis_es2017.ts, 2, 9))
|
||||
>this : Symbol(C, Decl(asyncArrowFunctionCapturesThis_es2017.ts, 0, 0))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesThis_es2017.ts ===
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
method() {
|
||||
>method : () => void
|
||||
|
||||
var fn = async () => await this;
|
||||
>fn : () => Promise<this>
|
||||
>async () => await this : () => Promise<this>
|
||||
>await this : this
|
||||
>this : this
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
tests/cases/conformance/async/es2017/asyncAwaitIsolatedModules_es2017.ts(1,27): error TS2307: Cannot find module 'missing'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es2017/asyncAwaitIsolatedModules_es2017.ts (1 errors) ====
|
||||
import { MyPromise } from "missing";
|
||||
~~~~~~~~~
|
||||
!!! error TS2307: Cannot find module 'missing'.
|
||||
|
||||
declare var p: Promise<number>;
|
||||
declare var mp: MyPromise<number>;
|
||||
|
||||
async function f0() { }
|
||||
async function f1(): Promise<void> { }
|
||||
async function f3(): MyPromise<void> { }
|
||||
|
||||
let f4 = async function() { }
|
||||
let f5 = async function(): Promise<void> { }
|
||||
let f6 = async function(): MyPromise<void> { }
|
||||
|
||||
let f7 = async () => { };
|
||||
let f8 = async (): Promise<void> => { };
|
||||
let f9 = async (): MyPromise<void> => { };
|
||||
let f10 = async () => p;
|
||||
let f11 = async () => mp;
|
||||
let f12 = async (): Promise<number> => mp;
|
||||
let f13 = async (): MyPromise<number> => p;
|
||||
|
||||
let o = {
|
||||
async m1() { },
|
||||
async m2(): Promise<void> { },
|
||||
async m3(): MyPromise<void> { }
|
||||
};
|
||||
|
||||
class C {
|
||||
async m1() { }
|
||||
async m2(): Promise<void> { }
|
||||
async m3(): MyPromise<void> { }
|
||||
static async m4() { }
|
||||
static async m5(): Promise<void> { }
|
||||
static async m6(): MyPromise<void> { }
|
||||
}
|
||||
|
||||
module M {
|
||||
export async function f1() { }
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
//// [asyncAwaitIsolatedModules_es2017.ts]
|
||||
import { MyPromise } from "missing";
|
||||
|
||||
declare var p: Promise<number>;
|
||||
declare var mp: MyPromise<number>;
|
||||
|
||||
async function f0() { }
|
||||
async function f1(): Promise<void> { }
|
||||
async function f3(): MyPromise<void> { }
|
||||
|
||||
let f4 = async function() { }
|
||||
let f5 = async function(): Promise<void> { }
|
||||
let f6 = async function(): MyPromise<void> { }
|
||||
|
||||
let f7 = async () => { };
|
||||
let f8 = async (): Promise<void> => { };
|
||||
let f9 = async (): MyPromise<void> => { };
|
||||
let f10 = async () => p;
|
||||
let f11 = async () => mp;
|
||||
let f12 = async (): Promise<number> => mp;
|
||||
let f13 = async (): MyPromise<number> => p;
|
||||
|
||||
let o = {
|
||||
async m1() { },
|
||||
async m2(): Promise<void> { },
|
||||
async m3(): MyPromise<void> { }
|
||||
};
|
||||
|
||||
class C {
|
||||
async m1() { }
|
||||
async m2(): Promise<void> { }
|
||||
async m3(): MyPromise<void> { }
|
||||
static async m4() { }
|
||||
static async m5(): Promise<void> { }
|
||||
static async m6(): MyPromise<void> { }
|
||||
}
|
||||
|
||||
module M {
|
||||
export async function f1() { }
|
||||
}
|
||||
|
||||
//// [asyncAwaitIsolatedModules_es2017.js]
|
||||
async function f0() { }
|
||||
async function f1() { }
|
||||
async function f3() { }
|
||||
let f4 = async function () { };
|
||||
let f5 = async function () { };
|
||||
let f6 = async function () { };
|
||||
let f7 = async () => { };
|
||||
let f8 = async () => { };
|
||||
let f9 = async () => { };
|
||||
let f10 = async () => p;
|
||||
let f11 = async () => mp;
|
||||
let f12 = async () => mp;
|
||||
let f13 = async () => p;
|
||||
let o = {
|
||||
async m1() { },
|
||||
async m2() { },
|
||||
async m3() { }
|
||||
};
|
||||
class C {
|
||||
async m1() { }
|
||||
async m2() { }
|
||||
async m3() { }
|
||||
static async m4() { }
|
||||
static async m5() { }
|
||||
static async m6() { }
|
||||
}
|
||||
var M;
|
||||
(function (M) {
|
||||
async function f1() { }
|
||||
M.f1 = f1;
|
||||
})(M || (M = {}));
|
73
tests/baselines/reference/asyncAwait_es2017.js
Normal file
73
tests/baselines/reference/asyncAwait_es2017.js
Normal file
|
@ -0,0 +1,73 @@
|
|||
//// [asyncAwait_es2017.ts]
|
||||
type MyPromise<T> = Promise<T>;
|
||||
declare var MyPromise: typeof Promise;
|
||||
declare var p: Promise<number>;
|
||||
declare var mp: MyPromise<number>;
|
||||
|
||||
async function f0() { }
|
||||
async function f1(): Promise<void> { }
|
||||
async function f3(): MyPromise<void> { }
|
||||
|
||||
let f4 = async function() { }
|
||||
let f5 = async function(): Promise<void> { }
|
||||
let f6 = async function(): MyPromise<void> { }
|
||||
|
||||
let f7 = async () => { };
|
||||
let f8 = async (): Promise<void> => { };
|
||||
let f9 = async (): MyPromise<void> => { };
|
||||
let f10 = async () => p;
|
||||
let f11 = async () => mp;
|
||||
let f12 = async (): Promise<number> => mp;
|
||||
let f13 = async (): MyPromise<number> => p;
|
||||
|
||||
let o = {
|
||||
async m1() { },
|
||||
async m2(): Promise<void> { },
|
||||
async m3(): MyPromise<void> { }
|
||||
};
|
||||
|
||||
class C {
|
||||
async m1() { }
|
||||
async m2(): Promise<void> { }
|
||||
async m3(): MyPromise<void> { }
|
||||
static async m4() { }
|
||||
static async m5(): Promise<void> { }
|
||||
static async m6(): MyPromise<void> { }
|
||||
}
|
||||
|
||||
module M {
|
||||
export async function f1() { }
|
||||
}
|
||||
|
||||
//// [asyncAwait_es2017.js]
|
||||
async function f0() { }
|
||||
async function f1() { }
|
||||
async function f3() { }
|
||||
let f4 = async function () { };
|
||||
let f5 = async function () { };
|
||||
let f6 = async function () { };
|
||||
let f7 = async () => { };
|
||||
let f8 = async () => { };
|
||||
let f9 = async () => { };
|
||||
let f10 = async () => p;
|
||||
let f11 = async () => mp;
|
||||
let f12 = async () => mp;
|
||||
let f13 = async () => p;
|
||||
let o = {
|
||||
async m1() { },
|
||||
async m2() { },
|
||||
async m3() { }
|
||||
};
|
||||
class C {
|
||||
async m1() { }
|
||||
async m2() { }
|
||||
async m3() { }
|
||||
static async m4() { }
|
||||
static async m5() { }
|
||||
static async m6() { }
|
||||
}
|
||||
var M;
|
||||
(function (M) {
|
||||
async function f1() { }
|
||||
M.f1 = f1;
|
||||
})(M || (M = {}));
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue