Merge branch 'master' into functionAndClassProperties

This commit is contained in:
Mohamed Hegazy
2017-02-09 15:28:31 -08:00
375 changed files with 9172 additions and 4993 deletions
+13 -1
View File
@@ -8,11 +8,14 @@ Alexander Rusakov <a_s_rusakov@mail.ru>
Alex Eagle <alexeagle@google.com>
Anatoly Ressin <anatoly.ressin@icloud.com>
Anders Hejlsberg <andersh@microsoft.com> unknown <andersh@AndersX1.NOE.Nokia.com> unknown <andersh@andersh-yoga.redmond.corp.microsoft.com>
about-code <about-code@users.noreply.github.com> # Andreas Martin
Andrej Baran <andrej.baran@gmail.com>
Andrew Ochsner <andrew.ochsner@wipro.com>
Andrew Z Allen <me@andrewzallen.com>
Andy Hanson <anhans@microsoft.com> Andy <anhans@microsoft.com>
Anil Anar <anilanar@hotmail.com>
Anton Tolmachev <myste@mail.ru>
Anubha Mathur <anubmat@microsoft.com> anubmat <anubmat@microsoft.com>
Arnavion <arnavion@gmail.com> # Arnav Singh
Arthur Ozga <aozgaa@umich.edu> Arthur Ozga <t-arthoz@microsoft.com> Arthur Ozga <aozgaa-ms@outlook.com> Arthur Ozga <aozgaa@users.noreply.github.com> Arthur Ozga <arozga@microsoft.com>
Asad Saeeduddin <masaeedu@gmail.com>
@@ -37,6 +40,7 @@ Dan Corder <dev@dancorder.com>
Dan Quirk <danquirk@microsoft.com> Dan Quirk <danquirk@users.noreply.github.com> nknown <danquirk@DANQUIRK1.redmond.corp.microsoft.com>
Daniel Rosenwasser <drosen@microsoft.com> Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com> Daniel Rosenwasser <DanielRosenwasser@gmail.com> Daniel Rosenwasser <Daniel.Rosenwasser@microsoft.com> Daniel Rosenwasser <DanielRosenwasser@microsoft.com>
David Li <jiawei.davidli@gmail.com>
David Sheldrick <david@futurice.com>
David Souther <davidsouther@gmail.com>
Denis Nedelyaev <denvned@gmail.com>
Dick van den Brink <d_vandenbrink@outlook.com> unknown <d_vandenbrink@outlook.com> unknown <d_vandenbrink@live.com>
@@ -52,6 +56,7 @@ Evan Sebastian <evanlhoini@gmail.com>
Eyas <eyas.sharaiha@gmail.com> # Eyas Sharaiha
Fabian Cook <faybecook@gmail.com>
falsandtru <falsandtru@users.noreply.github.com> # @falsandtru
flowmemo <flowmemo@outlook.com> # @flowmemo
Frank Wallis <fwallis@outlook.com>
František Žiacik <fziacik@gratex.com> František Žiacik <ziacik@gmail.com>
Gabe Moothart <gmoothart@gmail.com>
@@ -62,6 +67,7 @@ Graeme Wicksted <graeme.wicksted@gmail.com>
Guillaume Salles <guillaume.salles@me.com>
Guy Bedford <guybedford@gmail.com> guybedford <guybedford@gmail.com>
Harald Niesche <harald@niesche.de>
Homa Wong <homawong@gmail.com>
Iain Monro <iain.monro@softwire.com>
Ingvar Stepanyan <me@rreverser.com>
impinball <impinball@gmail.com> # Isiah Meadows
@@ -81,6 +87,7 @@ Jonathan Park <jpark@daptiv.com>
Jonathan Turner <jont@microsoft.com> Jonathan Turner <probata@hotmail.com>
Jonathan Toland <toland@dnalot.com>
Jesse Schalken <me@jesseschalken.com>
Joel Day <joelday@gmail.com>
Josh Abernathy <joshaber@gmail.com> joshaber <joshaber@gmail.com>
Josh Kalderimis <josh.kalderimis@gmail.com>
Josh Soref <jsoref@users.noreply.github.com>
@@ -95,10 +102,12 @@ Kanchalai Tanglertsampan <yuisu@microsoft.com> Yui T <yuisu@microsoft.com>
Kanchalai Tanglertsampan <yuisu@microsoft.com> Yui <yuit@users.noreply.github.com>
Kanchalai Tanglertsampan <yuisu@microsoft.com> Yui <yuisu@microsoft.com>
Kanchalai Tanglertsampan <yuisu@microsoft.com> yui T <yuisu@microsoft.com>
Kārlis Gaņģis <Knagis@users.noreply.github.com>
Keith Mashinter <kmashint@yahoo.com> kmashint <kmashint@yahoo.com>
Ken Howard <ken@simplicatedweb.com>
Kevin Lang <klang2012@gmail.com>
kimamula <kenji.imamula@gmail.com> # Kenji Imamula
Klaus Meinhardt <klaus.meinhardt1@gmail.com>
Kyle Kelley <rgbkrk@gmail.com>
Lorant Pinter <lorant.pinter@prezi.com>
Lucien Greathouse <me@lpghatguy.com>
@@ -107,6 +116,7 @@ Martin Vseticka <vseticka.martin@gmail.com> Martin Všeticka <vseticka.martin@gm
gcnew <gcnew@abv.bg> # Marin Marinov
vvakame <vvakame+dev@gmail.com> # Masahiro Wakame
Matt McCutchen <rmccutch@mit.edu>
MANISH-GIRI <manish.giri.me@gmail.com> # Manish Giri
Max Deepfield <maxdeepfield@absolutefreakout.com>
Micah Zoltu <micah@zoltu.net>
Michael <maykelchiche@gmail.com>
@@ -213,4 +223,6 @@ Tim Perry <tim.perry@softwire.com>
Vidar Tonaas Fauske <vidartf@gmail.com>
Viktor Zozulyak <zozulyakviktor@gmail.com>
rix <rix@rixs-MacBook-Pro.local> # Richard Sentino
rohitverma007 <rohitverma@live.ca> # Rohit Verma
rohitverma007 <rohitverma@live.ca> # Rohit Verma
rdosanjh <me@rajdeep.io> # Raj Dosanjh
gdh1995 <gdh1995@qq.com> # Dahan Gong
+12
View File
@@ -12,13 +12,16 @@ TypeScript is authored by:
* Aliaksandr Radzivanovich
* Anatoly Ressin
* Anders Hejlsberg
* Andreas Martin
* Andrej Baran
* Andrew Ochsner
* Andrew Z Allen
* András Parditka
* Andy Hanson
* Anil Anar
* Anton Khlynovskiy
* Anton Tolmachev
* Anubha Mathur
* Arnav Singh
* Arthur Ozga
* Asad Saeeduddin
@@ -42,12 +45,14 @@ TypeScript is authored by:
* Cotton Hou
* Cyrus Najmabadi
* Dafrok Zhang
* Dahan Gong
* Dan Corder
* Dan Quirk
* Daniel Hollocher
* Daniel Rosenwasser
* David Kmenta
* David Li
* David Sheldrick
* David Souther
* Denis Nedelyaev
* Dick van den Brink
@@ -66,6 +71,7 @@ TypeScript is authored by:
* Eyas Sharaiha
* Fabian Cook
* @falsandtru
* @flowmemo
* Frank Wallis
* Franklin Tse
* František Žiacik
@@ -79,6 +85,7 @@ TypeScript is authored by:
* Guy Bedford
* Harald Niesche
* Herrington Darkholme
* Homa Wong
* Iain Monro
* Ingvar Stepanyan
* Isiah Meadows
@@ -93,6 +100,7 @@ TypeScript is authored by:
* Jeffrey Morlan
* Jesse Schalken
* Jiri Tobisek
* Joel Day
* Joey Wilson
* Johannes Rieken
* John Vilk
@@ -114,10 +122,13 @@ TypeScript is authored by:
* Ken Howard
* Kenji Imamula
* Kevin Lang
* Klaus Meinhardt
* Kyle Kelley
* Kārlis Gaņģis
* Lorant Pinter
* Lucien Greathouse
* Lukas Elmer
* Manish Giri
* Marin Marinov
* Marius Schulz
* Martin Vseticka
@@ -155,6 +166,7 @@ TypeScript is authored by:
* @progre
* Punya Biswal
* Rado Kirov
* Raj Dosanjh
* Richard Knoll
* Richard Sentino
* Robert Coie
+32 -169
View File
@@ -6,6 +6,8 @@ var path = require("path");
var child_process = require("child_process");
var fold = require("travis-fold");
var runTestsInParallel = require("./scripts/mocha-parallel").runTestsInParallel;
var ts = require("./lib/typescript");
// Variables
var compilerDirectory = "src/compiler/";
@@ -34,6 +36,24 @@ if (process.env.path !== undefined) {
process.env.PATH = nodeModulesPathPrefix + process.env.PATH;
}
function filesFromConfig(configPath) {
var configText = fs.readFileSync(configPath).toString();
var config = ts.parseConfigFileTextToJson(configPath, configText, /*stripComments*/ true);
if (config.error) {
throw new Error(diagnosticsToString([config.error]));
}
const configFileContent = ts.parseJsonConfigFileContent(config.config, ts.sys, path.dirname(configPath));
if (configFileContent.errors && configFileContent.errors.length) {
throw new Error(diagnosticsToString(configFileContent.errors));
}
return configFileContent.fileNames;
function diagnosticsToString(s) {
return s.map(function(e) { return ts.flattenDiagnosticMessageText(e.messageText, ts.sys.newLine); }).join(ts.sys.newLine);
}
}
function toNs(diff) {
return diff[0] * 1e9 + diff[1];
}
@@ -56,173 +76,12 @@ function measure(marker) {
console.log("travis_time:end:" + marker.id + ":start=" + toNs(marker.stamp) + ",finish=" + toNs(total) + ",duration=" + toNs(diff) + "\r");
}
var compilerSources = [
"core.ts",
"performance.ts",
"sys.ts",
"types.ts",
"scanner.ts",
"parser.ts",
"utilities.ts",
"binder.ts",
"checker.ts",
"factory.ts",
"visitor.ts",
"transformers/destructuring.ts",
"transformers/ts.ts",
"transformers/jsx.ts",
"transformers/esnext.ts",
"transformers/es2017.ts",
"transformers/es2016.ts",
"transformers/es2015.ts",
"transformers/generators.ts",
"transformers/es5.ts",
"transformers/module/es2015.ts",
"transformers/module/system.ts",
"transformers/module/module.ts",
"transformer.ts",
"sourcemap.ts",
"comments.ts",
"declarationEmitter.ts",
"emitter.ts",
"program.ts",
"commandLineParser.ts",
"tsc.ts",
"diagnosticInformationMap.generated.ts"
].map(function (f) {
return path.join(compilerDirectory, f);
});
var servicesSources = [
"core.ts",
"performance.ts",
"sys.ts",
"types.ts",
"scanner.ts",
"parser.ts",
"utilities.ts",
"binder.ts",
"checker.ts",
"factory.ts",
"visitor.ts",
"transformers/destructuring.ts",
"transformers/ts.ts",
"transformers/jsx.ts",
"transformers/esnext.ts",
"transformers/es2017.ts",
"transformers/es2016.ts",
"transformers/es2015.ts",
"transformers/generators.ts",
"transformers/es5.ts",
"transformers/module/es2015.ts",
"transformers/module/system.ts",
"transformers/module/module.ts",
"transformer.ts",
"sourcemap.ts",
"comments.ts",
"declarationEmitter.ts",
"emitter.ts",
"program.ts",
"commandLineParser.ts",
"diagnosticInformationMap.generated.ts"
].map(function (f) {
return path.join(compilerDirectory, f);
}).concat([
"types.ts",
"utilities.ts",
"breakpoints.ts",
"classifier.ts",
"completions.ts",
"documentHighlights.ts",
"documentRegistry.ts",
"findAllReferences.ts",
"goToDefinition.ts",
"goToImplementation.ts",
"jsDoc.ts",
"jsTyping.ts",
"navigateTo.ts",
"navigationBar.ts",
"outliningElementsCollector.ts",
"patternMatcher.ts",
"preProcess.ts",
"rename.ts",
"services.ts",
"shims.ts",
"signatureHelp.ts",
"symbolDisplay.ts",
"transpile.ts",
// Formatting
"formatting/formatting.ts",
"formatting/formattingContext.ts",
"formatting/formattingRequestKind.ts",
"formatting/formattingScanner.ts",
"formatting/references.ts",
"formatting/rule.ts",
"formatting/ruleAction.ts",
"formatting/ruleDescriptor.ts",
"formatting/ruleFlag.ts",
"formatting/ruleOperation.ts",
"formatting/ruleOperationContext.ts",
"formatting/rules.ts",
"formatting/rulesMap.ts",
"formatting/rulesProvider.ts",
"formatting/smartIndenter.ts",
"formatting/tokenRange.ts",
// CodeFixes
"codeFixProvider.ts",
"codefixes/fixes.ts",
"codefixes/fixExtendsInterfaceBecomesImplements.ts",
"codefixes/fixClassIncorrectlyImplementsInterface.ts",
"codefixes/fixClassDoesntImplementInheritedAbstractMember.ts",
"codefixes/fixClassSuperMustPrecedeThisAccess.ts",
"codefixes/fixConstructorForDerivedNeedSuperCall.ts",
"codefixes/helpers.ts",
"codefixes/importFixes.ts",
"codefixes/unusedIdentifierFixes.ts"
].map(function (f) {
return path.join(servicesDirectory, f);
}));
var baseServerCoreSources = [
"builder.ts",
"editorServices.ts",
"lsHost.ts",
"project.ts",
"protocol.ts",
"scriptInfo.ts",
"scriptVersionCache.ts",
"session.ts",
"shared.ts",
"types.ts",
"typingsCache.ts",
"utilities.ts",
].map(function (f) {
return path.join(serverDirectory, f);
});
var serverCoreSources = [
"server.ts"
].map(function (f) {
return path.join(serverDirectory, f);
}).concat(baseServerCoreSources);
var cancellationTokenSources = [
"cancellationToken.ts"
].map(function (f) {
return path.join(cancellationTokenDirectory, f);
});
var typingsInstallerSources = [
"../types.ts",
"../shared.ts",
"typingsInstaller.ts",
"nodeTypingsInstaller.ts"
].map(function (f) {
return path.join(typingsInstallerDirectory, f);
});
var serverSources = serverCoreSources.concat(servicesSources);
var languageServiceLibrarySources = baseServerCoreSources.concat(servicesSources);
var compilerSources = filesFromConfig("./src/compiler/tsconfig.json");
var servicesSources = filesFromConfig("./src/services/tsconfig.json");
var cancellationTokenSources = filesFromConfig(path.join(serverDirectory, "cancellationToken/tsconfig.json"));
var typingsInstallerSources = filesFromConfig(path.join(serverDirectory, "typingsInstaller/tsconfig.json"));
var serverSources = filesFromConfig(path.join(serverDirectory, "tsconfig.json"))
var languageServiceLibrarySources = filesFromConfig(path.join(serverDirectory, "tsconfig.library.json"));
var harnessCoreSources = [
"harness.ts",
@@ -269,6 +128,7 @@ var harnessSources = harnessCoreSources.concat([
"projectErrors.ts",
"matchFiles.ts",
"initializeTSConfig.ts",
"printer.ts",
].map(function (f) {
return path.join(unittestsDirectory, f);
})).concat([
@@ -1229,13 +1089,16 @@ var lintTargets = compilerSources
.concat(harnessSources)
// Other harness sources
.concat(["instrumenter.ts"].map(function (f) { return path.join(harnessDirectory, f) }))
.concat(serverCoreSources)
.concat(serverSources)
.concat(tslintRulesFiles)
.concat(servicesSources)
.concat(typingsInstallerSources)
.concat(cancellationTokenSources)
.concat(["Gulpfile.ts"])
.concat([nodeServerInFile, perftscPath, "tests/perfsys.ts", webhostPath]);
.concat([nodeServerInFile, perftscPath, "tests/perfsys.ts", webhostPath])
.map(function (p) { return path.resolve(p) });
// keep only unique items
lintTargets = Array.from(new Set(lintTargets));
function sendNextFile(files, child, callback, failures) {
var file = files.pop();
+58 -22
View File
@@ -326,7 +326,6 @@ namespace ts {
"object": TypeFacts.TypeofEQObject,
"function": TypeFacts.TypeofEQFunction
});
const typeofNEFacts = createMapFromTemplate({
"string": TypeFacts.TypeofNEString,
"number": TypeFacts.TypeofNENumber,
@@ -336,7 +335,6 @@ namespace ts {
"object": TypeFacts.TypeofNEObject,
"function": TypeFacts.TypeofNEFunction
});
const typeofTypesByName = createMapFromTemplate<Type>({
"string": stringType,
"number": numberType,
@@ -344,6 +342,7 @@ namespace ts {
"symbol": esSymbolType,
"undefined": undefinedType
});
const typeofType = createTypeofType();
let jsxElementType: Type;
let _jsxNamespace: string;
@@ -641,7 +640,7 @@ namespace ts {
}
// declaration is after usage
// can be legal if usage is deferred (i.e. inside function or in initializer of instance property)
if (isUsedInFunctionOrNonStaticProperty(usage)) {
if (isUsedInFunctionOrInstanceProperty(usage)) {
return true;
}
const sourceFiles = host.getSourceFiles();
@@ -668,10 +667,12 @@ namespace ts {
}
// declaration is after usage
// can be legal if usage is deferred (i.e. inside function or in initializer of instance property)
// declaration is after usage, but it can still be legal if usage is deferred:
// 1. inside a function
// 2. inside an instance property initializer, a reference to a non-instance property
const container = getEnclosingBlockScopeContainer(declaration);
return isUsedInFunctionOrNonStaticProperty(usage, container);
const isInstanceProperty = declaration.kind === SyntaxKind.PropertyDeclaration && !(getModifierFlags(declaration) & ModifierFlags.Static);
return isUsedInFunctionOrInstanceProperty(usage, isInstanceProperty, container);
function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration: VariableDeclaration, usage: Node): boolean {
const container = getEnclosingBlockScopeContainer(declaration);
@@ -700,7 +701,7 @@ namespace ts {
return false;
}
function isUsedInFunctionOrNonStaticProperty(usage: Node, container?: Node): boolean {
function isUsedInFunctionOrInstanceProperty(usage: Node, isDeclarationInstanceProperty?: boolean, container?: Node): boolean {
let current = usage;
while (current) {
if (current === container) {
@@ -711,13 +712,13 @@ namespace ts {
return true;
}
const initializerOfNonStaticProperty = current.parent &&
const initializerOfInstanceProperty = current.parent &&
current.parent.kind === SyntaxKind.PropertyDeclaration &&
(getModifierFlags(current.parent) & ModifierFlags.Static) === 0 &&
(<PropertyDeclaration>current.parent).initializer === current;
if (initializerOfNonStaticProperty) {
return true;
if (initializerOfInstanceProperty) {
return !isDeclarationInstanceProperty;
}
current = current.parent;
@@ -986,10 +987,10 @@ namespace ts {
// interface bar {}
// }
// const foo/*1*/: foo/*2*/.bar;
// The foo at /*1*/ and /*2*/ will share same symbol with two meaning
// block - scope variable and namespace module. However, only when we
// The foo at /*1*/ and /*2*/ will share same symbol with two meanings:
// block-scoped variable and namespace module. However, only when we
// try to resolve name in /*1*/ which is used in variable position,
// we want to check for block- scoped
// we want to check for block-scoped
if (meaning & SymbolFlags.BlockScopedVariable) {
const exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result);
if (exportOrLocalSymbol.flags & SymbolFlags.BlockScopedVariable) {
@@ -1013,7 +1014,7 @@ namespace ts {
return false;
}
const container = getThisContainer(errorLocation, /* includeArrowFunctions */ true);
const container = getThisContainer(errorLocation, /*includeArrowFunctions*/ true);
let location = container;
while (location) {
if (isClassLike(location.parent)) {
@@ -1725,6 +1726,10 @@ namespace ts {
return type;
}
function createTypeofType() {
return getUnionType(convertToArray(typeofEQFacts.keys(), s => getLiteralTypeForText(TypeFlags.StringLiteral, s)));
}
// A reserved member name starts with two underscores, but the third character cannot be an underscore
// or the @ symbol. A third underscore indicates an escaped form of an identifer that started
// with at least two underscores. The @ character indicates that the name is denoted by a well known ES
@@ -3993,7 +3998,7 @@ namespace ts {
// A valid base type is any non-generic object type or intersection of non-generic
// object types.
function isValidBaseType(type: Type): boolean {
return type.flags & TypeFlags.Object && !isGenericMappedType(type) ||
return type.flags & (TypeFlags.Object | TypeFlags.NonPrimitive) && !isGenericMappedType(type) ||
type.flags & TypeFlags.Intersection && !forEach((<IntersectionType>type).types, t => !isValidBaseType(t));
}
@@ -4931,7 +4936,7 @@ namespace ts {
}
function getApparentTypeOfIntersectionType(type: IntersectionType) {
return type.resolvedIndexType || (type.resolvedApparentType = getTypeWithThisArgument(type, type));
return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type));
}
/**
@@ -4946,7 +4951,7 @@ namespace ts {
t.flags & TypeFlags.NumberLike ? globalNumberType :
t.flags & TypeFlags.BooleanLike ? globalBooleanType :
t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType() :
t.flags & TypeFlags.NonPrimitive ? globalObjectType :
t.flags & TypeFlags.NonPrimitive ? emptyObjectType :
t;
}
@@ -7689,7 +7694,7 @@ namespace ts {
function isKnownProperty(type: Type, name: string): boolean {
if (type.flags & TypeFlags.Object) {
const resolved = resolveStructuredTypeMembers(<ObjectType>type);
if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyObjectType(resolved)) ||
if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyResolvedType(resolved)) ||
resolved.stringIndexInfo ||
(resolved.numberIndexInfo && isNumericLiteralName(name)) ||
getPropertyOfType(type, name)) {
@@ -7706,7 +7711,7 @@ namespace ts {
return false;
}
function isEmptyObjectType(t: ResolvedType) {
function isEmptyResolvedType(t: ResolvedType) {
return t.properties.length === 0 &&
t.callSignatures.length === 0 &&
t.constructSignatures.length === 0 &&
@@ -7714,6 +7719,10 @@ namespace ts {
!t.numberIndexInfo;
}
function isEmptyObjectType(type: Type) {
return type.flags & TypeFlags.Object && isEmptyResolvedType(resolveStructuredTypeMembers(<ObjectType>type));
}
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
if (maybeTypeOfKind(target, TypeFlags.Object) && !(getObjectFlags(target) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) {
for (const prop of getPropertiesOfObjectType(source)) {
@@ -7927,10 +7936,14 @@ namespace ts {
}
}
}
else if ((<MappedType>target).declaration.questionToken && isEmptyObjectType(source)) {
return Ternary.True;
}
}
else if (relation !== identityRelation) {
const resolved = resolveStructuredTypeMembers(<ObjectType>target);
if (isEmptyObjectType(resolved) || resolved.stringIndexInfo && resolved.stringIndexInfo.type.flags & TypeFlags.Any) {
if (isEmptyResolvedType(resolved) || resolved.stringIndexInfo && resolved.stringIndexInfo.type.flags & TypeFlags.Any) {
return Ternary.True;
}
}
@@ -9461,11 +9474,19 @@ namespace ts {
}
function getAssignedTypeOfBinaryExpression(node: BinaryExpression): Type {
return node.parent.kind === SyntaxKind.ArrayLiteralExpression || node.parent.kind === SyntaxKind.PropertyAssignment ?
const isDestructuringDefaultAssignment =
node.parent.kind === SyntaxKind.ArrayLiteralExpression && isDestructuringAssignmentTarget(node.parent) ||
node.parent.kind === SyntaxKind.PropertyAssignment && isDestructuringAssignmentTarget(node.parent.parent);
return isDestructuringDefaultAssignment ?
getTypeWithDefault(getAssignedType(node), node.right) :
getTypeOfExpression(node.right);
}
function isDestructuringAssignmentTarget(parent: Node) {
return parent.parent.kind === SyntaxKind.BinaryExpression && (parent.parent as BinaryExpression).left === parent ||
parent.parent.kind === SyntaxKind.ForOfStatement && (parent.parent as ForOfStatement).initializer === parent;
}
function getAssignedTypeOfArrayLiteralElement(node: ArrayLiteralExpression, element: Expression): Type {
return getTypeOfDestructuredArrayElement(getAssignedType(node), indexOf(node.elements, element));
}
@@ -12537,6 +12558,16 @@ namespace ts {
}
}
function isInPropertyInitializer(node: Node): boolean {
while (node) {
if (node.parent && node.parent.kind === SyntaxKind.PropertyDeclaration && (node.parent as PropertyDeclaration).initializer === node) {
return true;
}
node = node.parent;
}
return false;
}
function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) {
const type = checkNonNullExpression(left);
if (isTypeAny(type) || type === silentNeverType) {
@@ -12559,6 +12590,11 @@ namespace ts {
}
return unknownType;
}
if (prop.valueDeclaration &&
isInPropertyInitializer(node) &&
!isBlockScopedNameDeclaredBeforeUse(prop.valueDeclaration, right)) {
error(right, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, right.text);
}
markPropertyAsReferenced(prop);
@@ -14606,7 +14642,7 @@ namespace ts {
function checkTypeOfExpression(node: TypeOfExpression): Type {
checkExpression(node.expression);
return stringType;
return typeofType;
}
function checkVoidExpression(node: VoidExpression): Type {
+36 -22
View File
@@ -5,17 +5,17 @@ namespace ts {
export interface CommentWriter {
reset(): void;
setSourceFile(sourceFile: SourceFile): void;
emitNodeWithComments(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
setWriter(writer: EmitTextWriter): void;
emitNodeWithComments(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void): void;
emitTrailingCommentsOfPosition(pos: number): void;
emitLeadingCommentsOfPosition(pos: number): void;
}
export function createCommentWriter(host: EmitHost, writer: EmitTextWriter, sourceMap: SourceMapWriter): CommentWriter {
const compilerOptions = host.getCompilerOptions();
const extendedDiagnostics = compilerOptions.extendedDiagnostics;
const newLine = host.getNewLine();
const { emitPos } = sourceMap;
export function createCommentWriter(printerOptions: PrinterOptions, emitPos: ((pos: number) => void) | undefined): CommentWriter {
const extendedDiagnostics = printerOptions.extendedDiagnostics;
const newLine = getNewLineCharacter(printerOptions);
let writer: EmitTextWriter;
let containerPos = -1;
let containerEnd = -1;
let declarationListContainerEnd = -1;
@@ -24,19 +24,21 @@ namespace ts {
let currentLineMap: number[];
let detachedCommentsInfo: { nodePos: number, detachedCommentEndPos: number}[];
let hasWrittenComment = false;
let disabled: boolean = compilerOptions.removeComments;
let disabled: boolean = printerOptions.removeComments;
return {
reset,
setWriter,
setSourceFile,
emitNodeWithComments,
emitBodyWithDetachedComments,
emitTrailingCommentsOfPosition,
emitLeadingCommentsOfPosition,
};
function emitNodeWithComments(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
function emitNodeWithComments(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
if (disabled) {
emitCallback(emitContext, node);
emitCallback(hint, node);
return;
}
@@ -47,11 +49,11 @@ namespace ts {
// Both pos and end are synthesized, so just emit the node without comments.
if (emitFlags & EmitFlags.NoNestedComments) {
disabled = true;
emitCallback(emitContext, node);
emitCallback(hint, node);
disabled = false;
}
else {
emitCallback(emitContext, node);
emitCallback(hint, node);
}
}
else {
@@ -94,11 +96,11 @@ namespace ts {
if (emitFlags & EmitFlags.NoNestedComments) {
disabled = true;
emitCallback(emitContext, node);
emitCallback(hint, node);
disabled = false;
}
else {
emitCallback(emitContext, node);
emitCallback(hint, node);
}
if (extendedDiagnostics) {
@@ -198,9 +200,9 @@ namespace ts {
}
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
emitPos(commentPos);
if (emitPos) emitPos(commentPos);
writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
emitPos(commentEnd);
if (emitPos) emitPos(commentEnd);
if (hasTrailingNewLine) {
writer.writeLine();
@@ -210,6 +212,14 @@ namespace ts {
}
}
function emitLeadingCommentsOfPosition(pos: number) {
if (disabled || pos === -1) {
return;
}
emitLeadingComments(pos, /*isEmittedNode*/ true);
}
function emitTrailingComments(pos: number) {
forEachTrailingCommentToEmit(pos, emitTrailingComment);
}
@@ -220,9 +230,9 @@ namespace ts {
writer.write(" ");
}
emitPos(commentPos);
if (emitPos) emitPos(commentPos);
writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
emitPos(commentEnd);
if (emitPos) emitPos(commentEnd);
if (hasTrailingNewLine) {
writer.writeLine();
@@ -248,9 +258,9 @@ namespace ts {
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);
if (emitPos) emitPos(commentPos);
writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
emitPos(commentEnd);
if (emitPos) emitPos(commentEnd);
if (hasTrailingNewLine) {
writer.writeLine();
@@ -286,6 +296,10 @@ namespace ts {
detachedCommentsInfo = undefined;
}
function setWriter(output: EmitTextWriter): void {
writer = output;
}
function setSourceFile(sourceFile: SourceFile) {
currentSourceFile = sourceFile;
currentText = currentSourceFile.text;
@@ -323,9 +337,9 @@ namespace ts {
}
function writeComment(text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) {
emitPos(commentPos);
if (emitPos) emitPos(commentPos);
writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine);
emitPos(commentEnd);
if (emitPos) emitPos(commentEnd);
}
/**
+9 -1
View File
@@ -895,6 +895,14 @@ namespace ts {
return result;
}
export function convertToArray<T, U>(iterator: Iterator<T>, f: (value: T) => U) {
const result: U[] = [];
for (let { value, done } = iterator.next(); !done; { value, done } = iterator.next()) {
result.push(f(value));
}
return result;
}
/**
* Calls `callback` for each entry in the map, returning the first truthy result.
* Use `map.forEach` instead for normal iteration.
@@ -1447,7 +1455,7 @@ namespace ts {
return /^\.\.?($|[\\/])/.test(moduleName);
}
export function getEmitScriptTarget(compilerOptions: CompilerOptions) {
export function getEmitScriptTarget(compilerOptions: CompilerOptions | PrinterOptions) {
return compilerOptions.target || ScriptTarget.ES3;
}
+10 -6
View File
@@ -35,13 +35,15 @@ namespace ts {
forEachEmittedFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile);
return declarationDiagnostics.getDiagnostics(targetSourceFile ? targetSourceFile.fileName : undefined);
function getDeclarationDiagnosticsFromFile({ declarationFilePath }: EmitFileNames, sources: SourceFile[], isBundledEmit: boolean) {
emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sources, isBundledEmit, /*emitOnlyDtsFiles*/ false);
function getDeclarationDiagnosticsFromFile({ declarationFilePath }: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sourceFileOrBundle, /*emitOnlyDtsFiles*/ false);
}
}
function emitDeclarations(host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, declarationFilePath: string,
sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean): DeclarationEmit {
sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean): DeclarationEmit {
const sourceFiles = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle];
const isBundledEmit = sourceFileOrBundle.kind === SyntaxKind.Bundle;
const newLine = host.getNewLine();
const compilerOptions = host.getCompilerOptions();
@@ -1803,8 +1805,9 @@ namespace ts {
}
return addedBundledEmitReference;
function getDeclFileName(emitFileNames: EmitFileNames, _sourceFiles: SourceFile[], isBundledEmit: boolean) {
function getDeclFileName(emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
// Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path
const isBundledEmit = sourceFileOrBundle.kind === SyntaxKind.Bundle;
if (isBundledEmit && !addBundledFileReference) {
return;
}
@@ -1817,10 +1820,11 @@ namespace ts {
}
/* @internal */
export function writeDeclarationFile(declarationFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean, host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, emitOnlyDtsFiles: boolean) {
const emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFiles, isBundledEmit, emitOnlyDtsFiles);
export function writeDeclarationFile(declarationFilePath: string, sourceFileOrBundle: SourceFile | Bundle, host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, emitOnlyDtsFiles: boolean) {
const emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFileOrBundle, emitOnlyDtsFiles);
const emitSkipped = emitDeclarationResult.reportedDeclarationError || host.isEmitBlocked(declarationFilePath) || host.getCompilerOptions().noEmit;
if (!emitSkipped) {
const sourceFiles = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle];
const declarationOutput = emitDeclarationResult.referencesOutput
+ getDeclarationOutput(emitDeclarationResult.synchronousDeclarationOutput, emitDeclarationResult.moduleElementDeclarationEmitInfo);
writeFile(host, emitterDiagnostics, declarationFilePath, declarationOutput, host.getCompilerOptions().emitBOM, sourceFiles);
+553 -459
View File
File diff suppressed because it is too large Load Diff
+1288 -1080
View File
File diff suppressed because it is too large Load Diff
+3 -6
View File
@@ -1152,13 +1152,10 @@ namespace ts {
&& (options.isolatedModules || isExternalModuleFile)
&& !file.isDeclarationFile) {
// synthesize 'import "tslib"' declaration
const externalHelpersModuleReference = <StringLiteral>createSynthesizedNode(SyntaxKind.StringLiteral);
externalHelpersModuleReference.text = externalHelpersModuleNameText;
const importDecl = createSynthesizedNode(SyntaxKind.ImportDeclaration);
importDecl.parent = file;
const externalHelpersModuleReference = createLiteral(externalHelpersModuleNameText);
const importDecl = createImportDeclaration(undefined, undefined, undefined);
externalHelpersModuleReference.parent = importDecl;
importDecl.parent = file;
imports = [externalHelpersModuleReference];
}
+13 -15
View File
@@ -8,10 +8,9 @@ namespace ts {
*
* @param filePath The path to the generated output file.
* @param sourceMapFilePath The path to the output source map file.
* @param sourceFiles The input source files for the program.
* @param isBundledEmit A value indicating whether the generated output file is a bundle.
* @param sourceFileOrBundle The input source file or bundle for the program.
*/
initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean): void;
initialize(filePath: string, sourceMapFilePath: string, sourceFileOrBundle: SourceFile | Bundle): void;
/**
* Reset the SourceMapWriter to an empty state.
@@ -38,11 +37,11 @@ namespace ts {
/**
* Emits a node with possible leading and trailing source maps.
*
* @param emitContext The current emit context
* @param hint The current emit context
* @param node The node to emit.
* @param emitCallback The callback used to emit the node.
*/
emitNodeWithSourceMap(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
emitNodeWithSourceMap(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
/**
* Emits a token of a node node with possible leading and trailing source maps.
@@ -115,10 +114,9 @@ namespace ts {
*
* @param filePath The path to the generated output file.
* @param sourceMapFilePath The path to the output source map file.
* @param sourceFiles The input source files for the program.
* @param isBundledEmit A value indicating whether the generated output file is a bundle.
* @param sourceFileOrBundle The input source file or bundle for the program.
*/
function initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
function initialize(filePath: string, sourceMapFilePath: string, sourceFileOrBundle: SourceFile | Bundle) {
if (disabled) {
return;
}
@@ -161,11 +159,10 @@ namespace ts {
if (compilerOptions.mapRoot) {
sourceMapDir = normalizeSlashes(compilerOptions.mapRoot);
if (!isBundledEmit) { // emitting single module file
Debug.assert(sourceFiles.length === 1);
if (sourceFileOrBundle.kind === SyntaxKind.SourceFile) { // emitting single module file
// For modules or multiple emit files the mapRoot will have directory structure like the sources
// So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFiles[0], host, sourceMapDir));
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFileOrBundle, host, sourceMapDir));
}
if (!isRootedDiskPath(sourceMapDir) && !isUrl(sourceMapDir)) {
@@ -311,12 +308,13 @@ namespace ts {
/**
* Emits a node with possible leading and trailing source maps.
*
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emitCallback The callback used to emit the node.
*/
function emitNodeWithSourceMap(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
function emitNodeWithSourceMap(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
if (disabled) {
return emitCallback(emitContext, node);
return emitCallback(hint, node);
}
if (node) {
@@ -332,11 +330,11 @@ namespace ts {
if (emitFlags & EmitFlags.NoNestedSourceMaps) {
disabled = true;
emitCallback(emitContext, node);
emitCallback(hint, node);
disabled = false;
}
else {
emitCallback(emitContext, node);
emitCallback(hint, node);
}
if (node.kind !== SyntaxKind.NotEmittedStatement
+8 -1
View File
@@ -485,7 +485,10 @@ namespace ts {
// Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
// (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
let options: any;
if (!directoryExists(directoryName)) {
if (!directoryExists(directoryName) || (isUNCPath(directoryName) && process.platform === "win32")) {
// do nothing if either
// - target folder does not exist
// - this is UNC path on Windows (https://github.com/Microsoft/TypeScript/issues/13874)
return noOpFileWatcher;
}
@@ -509,6 +512,10 @@ namespace ts {
};
}
);
function isUNCPath(s: string): boolean {
return s.length > 2 && s.charCodeAt(0) === CharacterCodes.slash && s.charCodeAt(1) === CharacterCodes.slash;
}
},
resolvePath: function(path: string): string {
return _path.resolve(path);
+15 -15
View File
@@ -105,14 +105,16 @@ namespace ts {
hoistFunctionDeclaration,
requestEmitHelper,
readEmitHelpers,
onSubstituteNode: (_emitContext, node) => node,
onSubstituteNode: (_, node) => node,
enableSubstitution,
isSubstitutionEnabled,
onEmitNode: (node, emitContext, emitCallback) => emitCallback(node, emitContext),
onEmitNode: (hint, node, callback) => callback(hint, node),
enableEmitNotification,
isEmitNotificationEnabled
};
performance.mark("beforeTransform");
// Chain together and initialize each transformer.
const transformation = chain(...transformers)(context);
@@ -122,6 +124,9 @@ namespace ts {
// Disable modification of the lexical environment.
lexicalEnvironmentDisabled = true;
performance.mark("afterTransform");
performance.measure("transformTime", "beforeTransform", "afterTransform");
return {
transformed,
emitNodeWithSubstitution,
@@ -159,21 +164,16 @@ namespace ts {
/**
* Emits a node with possible substitution.
*
* @param emitContext The current emit context.
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emitCallback The callback used to emit the node or its substitute.
*/
function emitNodeWithSubstitution(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
function emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
if (node) {
if (isSubstitutionEnabled(node)) {
const substitute = context.onSubstituteNode(emitContext, node);
if (substitute && substitute !== node) {
emitCallback(emitContext, substitute);
return;
}
node = context.onSubstituteNode(hint, node) || node;
}
emitCallback(emitContext, node);
emitCallback(hint, node);
}
}
@@ -196,17 +196,17 @@ namespace ts {
/**
* Emits a node with possible emit notification.
*
* @param emitContext The current emit context.
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emitCallback The callback used to emit the node.
*/
function emitNodeWithNotification(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
function emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
if (node) {
if (isEmitNotificationEnabled(node)) {
context.onEmitNode(emitContext, node, emitCallback);
context.onEmitNode(hint, node, emitCallback);
}
else {
emitCallback(emitContext, node);
emitCallback(hint, node);
}
}
}
+18 -5
View File
@@ -112,7 +112,10 @@ namespace ts {
Debug.assertNode(target, createAssignmentCallback ? isIdentifier : isExpression);
const expression = createAssignmentCallback
? createAssignmentCallback(<Identifier>target, value, location)
: createAssignment(visitNode(<Expression>target, visitor, isExpression), value, location);
: setTextRange(
createAssignment(visitNode(<Expression>target, visitor, isExpression), value),
location
);
expression.original = original;
emitExpression(expression);
}
@@ -174,9 +177,10 @@ namespace ts {
const variable = createVariableDeclaration(
name,
/*type*/ undefined,
pendingExpressions ? inlineExpressions(append(pendingExpressions, value)) : value,
location);
pendingExpressions ? inlineExpressions(append(pendingExpressions, value)) : value
);
variable.original = original;
setTextRange(variable, location);
if (isIdentifier(name)) {
setEmitFlags(variable, EmitFlags.NoNestedSourceMaps);
}
@@ -416,7 +420,7 @@ namespace ts {
const temp = createTempVariable(/*recordTempVariable*/ undefined);
if (flattenContext.hoistTempVariables) {
flattenContext.context.hoistVariableDeclaration(temp);
flattenContext.emitExpression(createAssignment(temp, value, location));
flattenContext.emitExpression(setTextRange(createAssignment(temp, value), location));
}
else {
flattenContext.emitBindingOrAssignment(temp, value, location, /*original*/ undefined);
@@ -492,6 +496,15 @@ namespace ts {
}
}
}
return createCall(getHelperName("__rest"), undefined, [value, createArrayLiteral(propertyNames, location)]);
return createCall(
getHelperName("__rest"),
undefined,
[
value,
setTextRange(
createArrayLiteral(propertyNames),
location
)
]);
}
}
+211 -172
View File
@@ -514,7 +514,7 @@ namespace ts {
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
return updateSourceFileNode(
node,
createNodeArray(statements, node.statements)
setTextRange(createNodeArray(statements), node.statements)
);
}
@@ -671,9 +671,10 @@ namespace ts {
setOriginalNode(variable, node);
const statements: Statement[] = [];
const statement = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([variable]), /*location*/ node);
const statement = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([variable]));
setOriginalNode(statement, node);
setTextRange(statement, node);
startOnNewLine(statement);
statements.push(statement);
@@ -818,7 +819,7 @@ namespace ts {
addRange(statements, endLexicalEnvironment());
const block = createBlock(createNodeArray(statements, /*location*/ node.members), /*location*/ undefined, /*multiLine*/ true);
const block = createBlock(setTextRange(createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true);
setEmitFlags(block, EmitFlags.NoComments);
return block;
}
@@ -833,8 +834,10 @@ namespace ts {
function addExtendsHelperIfNeeded(statements: Statement[], node: ClassExpression | ClassDeclaration, extendsClauseElement: ExpressionWithTypeArguments): void {
if (extendsClauseElement) {
statements.push(
createStatement(
createExtendsHelper(context, getLocalName(node)),
setTextRange(
createStatement(
createExtendsHelper(context, getLocalName(node))
),
/*location*/ extendsClauseElement
)
);
@@ -854,19 +857,18 @@ namespace ts {
const ancestorFacts = enterSubtree(HierarchyFacts.ConstructorExcludes, HierarchyFacts.ConstructorIncludes);
const constructor = getFirstConstructorWithBody(node);
const hasSynthesizedSuper = hasSynthesizedDefaultSuperCall(constructor, extendsClauseElement !== undefined);
const constructorFunction =
createFunctionDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
getDeclarationName(node),
/*typeParameters*/ undefined,
transformConstructorParameters(constructor, hasSynthesizedSuper),
/*type*/ undefined,
transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper),
/*location*/ constructor || node
);
const constructorFunction = createFunctionDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
getDeclarationName(node),
/*typeParameters*/ undefined,
transformConstructorParameters(constructor, hasSynthesizedSuper),
/*type*/ undefined,
transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper)
);
setTextRange(constructorFunction, constructor || node);
if (extendsClauseElement) {
setEmitFlags(constructorFunction, EmitFlags.CapturesThis);
}
@@ -962,14 +964,16 @@ namespace ts {
}
const block = createBlock(
createNodeArray(
statements,
setTextRange(
createNodeArray(
statements
),
/*location*/ constructor ? constructor.body.statements : node.members
),
/*location*/ constructor ? constructor.body : node,
/*multiLine*/ true
);
setTextRange(block, constructor ? constructor.body : node);
if (!constructor) {
setEmitFlags(block, EmitFlags.NoComments);
}
@@ -1139,14 +1143,16 @@ namespace ts {
// Binding patterns are converted into a generated name and are
// evaluated inside the function body.
return setOriginalNode(
createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
getGeneratedNameForNode(node),
/*questionToken*/ undefined,
/*type*/ undefined,
/*initializer*/ undefined,
setTextRange(
createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
getGeneratedNameForNode(node),
/*questionToken*/ undefined,
/*type*/ undefined,
/*initializer*/ undefined
),
/*location*/ node
),
/*original*/ node
@@ -1155,14 +1161,16 @@ namespace ts {
else if (node.initializer) {
// Initializers are elided
return setOriginalNode(
createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
node.name,
/*questionToken*/ undefined,
/*type*/ undefined,
/*initializer*/ undefined,
setTextRange(
createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
node.name,
/*questionToken*/ undefined,
/*type*/ undefined,
/*initializer*/ undefined
),
/*location*/ node
),
/*original*/ node
@@ -1274,21 +1282,25 @@ namespace ts {
const statement = createIf(
createTypeCheck(getSynthesizedClone(name), "undefined"),
setEmitFlags(
createBlock([
createStatement(
createAssignment(
setEmitFlags(getMutableClone(name), EmitFlags.NoSourceMap),
setEmitFlags(initializer, EmitFlags.NoSourceMap | getEmitFlags(initializer)),
/*location*/ parameter
setTextRange(
createBlock([
createStatement(
setTextRange(
createAssignment(
setEmitFlags(getMutableClone(name), EmitFlags.NoSourceMap),
setEmitFlags(initializer, EmitFlags.NoSourceMap | getEmitFlags(initializer))
),
parameter
)
)
)
], /*location*/ parameter),
]),
parameter
),
EmitFlags.SingleLine | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTokenSourceMaps
),
/*elseStatement*/ undefined,
/*location*/ parameter
)
);
statement.startsOnNewLine = true;
setTextRange(statement, parameter);
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.CustomPrologue);
statements.push(statement);
}
@@ -1332,15 +1344,17 @@ namespace ts {
// var param = [];
statements.push(
setEmitFlags(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
declarationName,
/*type*/ undefined,
createArrayLiteral([])
)
]),
setTextRange(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
declarationName,
/*type*/ undefined,
createArrayLiteral([])
)
])
),
/*location*/ parameter
),
EmitFlags.CustomPrologue
@@ -1351,26 +1365,33 @@ namespace ts {
// param[_i - restIndex] = arguments[_i];
// }
const forStatement = createFor(
createVariableDeclarationList([
createVariableDeclaration(temp, /*type*/ undefined, createLiteral(restIndex))
], /*location*/ parameter),
createLessThan(
temp,
createPropertyAccess(createIdentifier("arguments"), "length"),
/*location*/ parameter
setTextRange(
createVariableDeclarationList([
createVariableDeclaration(temp, /*type*/ undefined, createLiteral(restIndex))
]),
parameter
),
createPostfixIncrement(temp, /*location*/ parameter),
setTextRange(
createLessThan(
temp,
createPropertyAccess(createIdentifier("arguments"), "length")
),
parameter
),
setTextRange(createPostfixIncrement(temp), parameter),
createBlock([
startOnNewLine(
createStatement(
createAssignment(
createElementAccess(
expressionName,
restIndex === 0
? temp
: createSubtract(temp, createLiteral(restIndex))
),
createElementAccess(createIdentifier("arguments"), temp)
setTextRange(
createStatement(
createAssignment(
createElementAccess(
expressionName,
restIndex === 0
? temp
: createSubtract(temp, createLiteral(restIndex))
),
createElementAccess(createIdentifier("arguments"), temp)
)
),
/*location*/ parameter
)
@@ -1405,11 +1426,10 @@ namespace ts {
/*type*/ undefined,
initializer
)
]),
originalStatement
])
);
setEmitFlags(captureThisStatement, EmitFlags.NoComments | EmitFlags.CustomPrologue);
setTextRange(captureThisStatement, originalStatement);
setSourceMapRange(captureThisStatement, node);
statements.push(captureThisStatement);
}
@@ -1529,7 +1549,7 @@ namespace ts {
* @param member The SemicolonClassElement node.
*/
function transformSemicolonClassElementToStatement(member: SemicolonClassElement) {
return createEmptyStatement(/*location*/ member);
return setTextRange(createEmptyStatement(), member);
}
/**
@@ -1547,8 +1567,10 @@ namespace ts {
setEmitFlags(memberFunction, EmitFlags.NoComments);
setSourceMapRange(memberFunction, sourceMapRange);
const statement = createStatement(
createAssignment(memberName, memberFunction),
const statement = setTextRange(
createStatement(
createAssignment(memberName, memberFunction)
),
/*location*/ member
);
@@ -1571,15 +1593,12 @@ namespace ts {
* @param accessors The set of related get/set accessors.
*/
function transformAccessorsToStatement(receiver: LeftHandSideExpression, accessors: AllAccessorDeclarations, container: Node): Statement {
const statement = createStatement(
transformAccessorsToExpression(receiver, accessors, container, /*startsOnNewLine*/ false),
/*location*/ getSourceMapRange(accessors.firstAccessor)
);
const statement = createStatement(transformAccessorsToExpression(receiver, accessors, container, /*startsOnNewLine*/ false));
// The location for the statement is used to emit source maps only.
// No comments should be emitted for this statement to align with the
// old emitter.
setEmitFlags(statement, EmitFlags.NoComments);
setSourceMapRange(statement, getSourceMapRange(accessors.firstAccessor));
return statement;
}
@@ -1622,8 +1641,8 @@ namespace ts {
}
properties.push(
createPropertyAssignment("enumerable", createLiteral(true)),
createPropertyAssignment("configurable", createLiteral(true))
createPropertyAssignment("enumerable", createTrue()),
createPropertyAssignment("configurable", createTrue())
);
const call = createCall(
@@ -1632,7 +1651,7 @@ namespace ts {
[
target,
propertyName,
createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true)
createObjectLiteral(properties, /*multiLine*/ true)
]
);
if (startsOnNewLine) {
@@ -1662,9 +1681,9 @@ namespace ts {
/*typeParameters*/ undefined,
visitParameterList(node.parameters, visitor, context),
/*type*/ undefined,
transformFunctionBody(node),
node
transformFunctionBody(node)
);
setTextRange(func, node);
setOriginalNode(func, node);
setEmitFlags(func, EmitFlags.CapturesThis);
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
@@ -1758,14 +1777,16 @@ namespace ts {
exitSubtree(ancestorFacts, HierarchyFacts.PropagateNewTargetMask, HierarchyFacts.None);
convertedLoopState = savedConvertedLoopState;
return setOriginalNode(
createFunctionExpression(
/*modifiers*/ undefined,
node.asteriskToken,
name,
/*typeParameters*/ undefined,
parameters,
/*type*/ undefined,
body,
setTextRange(
createFunctionExpression(
/*modifiers*/ undefined,
node.asteriskToken,
name,
/*typeParameters*/ undefined,
parameters,
/*type*/ undefined,
body
),
location
),
/*original*/ node
@@ -1832,7 +1853,8 @@ namespace ts {
}
const expression = visitNode(body, visitor, isExpression);
const returnStatement = createReturn(expression, /*location*/ body);
const returnStatement = createReturn(expression);
setTextRange(returnStatement, body);
setEmitFlags(returnStatement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTrailingComments);
statements.push(returnStatement);
@@ -1851,7 +1873,8 @@ namespace ts {
multiLine = true;
}
const block = createBlock(createNodeArray(statements, statementsLocation), node.body, multiLine);
const block = createBlock(setTextRange(createNodeArray(statements), statementsLocation), multiLine);
setTextRange(block, node.body);
if (!multiLine && singleLine) {
setEmitFlags(block, EmitFlags.SingleLine);
}
@@ -1868,8 +1891,10 @@ namespace ts {
const updated = visitFunctionBody(node.body, functionBodyVisitor, context);
return updateBlock(
updated,
createNodeArray(
prependCaptureNewTargetIfNeeded(updated.statements, node, /*copyOnWrite*/ true),
setTextRange(
createNodeArray(
prependCaptureNewTargetIfNeeded(updated.statements, node, /*copyOnWrite*/ true)
),
/*location*/ updated.statements
)
);
@@ -1969,7 +1994,7 @@ namespace ts {
}
}
if (assignments) {
updated = createStatement(reduceLeft(assignments, (acc, v) => createBinary(v, SyntaxKind.CommaToken, acc)), node);
updated = setTextRange(createStatement(reduceLeft(assignments, (acc, v) => createBinary(v, SyntaxKind.CommaToken, acc))), node);
}
else {
// none of declarations has initializer - the entire variable statement can be deleted
@@ -1999,8 +2024,9 @@ namespace ts {
? visitVariableDeclarationInLetDeclarationList
: visitVariableDeclaration));
const declarationList = createVariableDeclarationList(declarations, /*location*/ node);
const declarationList = createVariableDeclarationList(declarations);
setOriginalNode(declarationList, node);
setTextRange(declarationList, node);
setCommentRange(declarationList, node);
if (node.transformFlags & TransformFlags.ContainsBindingPattern
@@ -2225,7 +2251,7 @@ namespace ts {
// we don't want to emit a temporary variable for the RHS, just use it directly.
const counter = createLoopVariable();
const rhsReference = expression.kind === SyntaxKind.Identifier
? createUniqueName((<Identifier>expression).text)
? createUniqueName(unescapeIdentifier((<Identifier>expression).text))
: createTempVariable(/*recordTempVariable*/ undefined);
const elementAccess = createElementAccess(rhsReference, counter);
@@ -2248,8 +2274,9 @@ namespace ts {
elementAccess
);
const declarationList = createVariableDeclarationList(declarations, /*location*/ initializer);
const declarationList = createVariableDeclarationList(declarations);
setOriginalNode(declarationList, initializer);
setTextRange(declarationList, initializer);
// Adjust the source map range for the first declaration to align with the old
// emitter.
@@ -2268,19 +2295,24 @@ namespace ts {
// The following call does not include the initializer, so we have
// to emit it separately.
statements.push(
createVariableStatement(
/*modifiers*/ undefined,
setOriginalNode(
createVariableDeclarationList([
createVariableDeclaration(
firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
/*type*/ undefined,
createElementAccess(rhsReference, counter)
)
], /*location*/ moveRangePos(initializer, -1)),
initializer
setTextRange(
createVariableStatement(
/*modifiers*/ undefined,
setOriginalNode(
setTextRange(
createVariableDeclarationList([
createVariableDeclaration(
firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
/*type*/ undefined,
createElementAccess(rhsReference, counter)
)
]),
moveRangePos(initializer, -1)
),
initializer
)
),
/*location*/ moveRangeEnd(initializer, -1)
moveRangeEnd(initializer, -1)
)
);
}
@@ -2306,7 +2338,7 @@ namespace ts {
// Currently there is not way to check that assignment is binary expression of destructing assignment
// so we have to cast never type to binaryExpression
(<BinaryExpression>assignment).end = initializer.end;
statements.push(createStatement(assignment, /*location*/ moveRangeEnd(initializer, -1)));
statements.push(setTextRange(createStatement(assignment), moveRangeEnd(initializer, -1)));
}
}
@@ -2332,33 +2364,38 @@ namespace ts {
// The old emitter does not emit source maps for the block.
// We add the location to preserve comments.
const body = createBlock(
createNodeArray(statements, /*location*/ statementsLocation),
/*location*/ bodyLocation
);
const body = createBlock(setTextRange(createNodeArray(statements), /*location*/ statementsLocation));
setTextRange(body, bodyLocation);
setEmitFlags(body, EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps);
const forStatement = createFor(
setEmitFlags(
createVariableDeclarationList([
createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0), /*location*/ moveRangePos(node.expression, -1)),
createVariableDeclaration(rhsReference, /*type*/ undefined, expression, /*location*/ node.expression)
], /*location*/ node.expression),
setTextRange(
createVariableDeclarationList([
setTextRange(createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0)), moveRangePos(node.expression, -1)),
setTextRange(createVariableDeclaration(rhsReference, /*type*/ undefined, expression), node.expression)
]),
node.expression
),
EmitFlags.NoHoisting
),
createLessThan(
counter,
createPropertyAccess(rhsReference, "length"),
/*location*/ node.expression
setTextRange(
createLessThan(
counter,
createPropertyAccess(rhsReference, "length")
),
node.expression
),
createPostfixIncrement(counter, /*location*/ node.expression),
body,
/*location*/ node
setTextRange(
createPostfixIncrement(counter),
node.expression
),
body
);
// Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter.
setEmitFlags(forStatement, EmitFlags.NoTokenTrailingSourceMaps);
setTextRange(forStatement, node);
return restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel);
}
@@ -2418,7 +2455,6 @@ namespace ts {
setEmitFlags(
createObjectLiteral(
visitNodes(properties, visitor, isObjectLiteralElementLike, 0, numInitialProperties),
/*location*/ undefined,
node.multiLine
),
EmitFlags.Indented
@@ -2546,14 +2582,14 @@ namespace ts {
copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements);
}
addRange(statements, lexicalEnvironment)
loopBody = createBlock(statements, /*location*/ undefined, /*multiline*/ true);
loopBody = createBlock(statements, /*multiline*/ true);
}
if (isBlock(loopBody)) {
loopBody.multiLine = true;
}
else {
loopBody = createBlock([loopBody], /*location*/ undefined, /*multiline*/ true);
loopBody = createBlock([loopBody], /*multiline*/ true);
}
const isAsyncBlockContainingAwait =
@@ -2687,12 +2723,7 @@ namespace ts {
// visit childnodes to transform initializer/condition/incrementor parts
clone = visitEachChild(clone, visitor, context);
// set loop statement
clone.statement = createBlock(
convertedLoopBodyStatements,
/*location*/ undefined,
/*multiline*/ true
);
clone.statement = createBlock(convertedLoopBodyStatements, /*multiline*/ true);
// reset and re-aggregate the transform flags
clone.transformFlags = 0;
aggregateTransformFlags(clone);
@@ -2841,7 +2872,7 @@ namespace ts {
else {
loopParameters.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
if (resolver.getNodeCheckFlags(decl) & NodeCheckFlags.NeedsLoopOutParameter) {
const outParamName = createUniqueName("out_" + name.text);
const outParamName = createUniqueName("out_" + unescapeIdentifier(name.text));
loopOutParameters.push({ originalName: name, outParamName });
}
}
@@ -2903,9 +2934,9 @@ namespace ts {
receiver,
visitNode(property.name, visitor, isPropertyName)
),
visitNode(property.initializer, visitor, isExpression),
/*location*/ property
visitNode(property.initializer, visitor, isExpression)
);
setTextRange(expression, property);
if (startsOnNewLine) {
expression.startsOnNewLine = true;
}
@@ -2925,9 +2956,9 @@ namespace ts {
receiver,
visitNode(property.name, visitor, isPropertyName)
),
getSynthesizedClone(property.name),
/*location*/ property
getSynthesizedClone(property.name)
);
setTextRange(expression, property);
if (startsOnNewLine) {
expression.startsOnNewLine = true;
}
@@ -2948,9 +2979,9 @@ namespace ts {
receiver,
visitNode(method.name, visitor, isPropertyName)
),
transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined, container),
/*location*/ method
transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined, container)
);
setTextRange(expression, method);
if (startsOnNewLine) {
expression.startsOnNewLine = true;
}
@@ -2963,7 +2994,8 @@ namespace ts {
let updated: CatchClause;
if (isBindingPattern(node.variableDeclaration.name)) {
const temp = createTempVariable(undefined);
const newVariableDeclaration = createVariableDeclaration(temp, undefined, undefined, node.variableDeclaration);
const newVariableDeclaration = createVariableDeclaration(temp);
setTextRange(newVariableDeclaration, node.variableDeclaration);
const vars = flattenDestructuringBinding(
node.variableDeclaration,
visitor,
@@ -2971,8 +3003,9 @@ namespace ts {
FlattenLevel.All,
temp
);
const list = createVariableDeclarationList(vars, /*location*/node.variableDeclaration, /*flags*/node.variableDeclaration.flags);
const destructure = createVariableStatement(undefined, list);
const list = createVariableDeclarationList(vars);
setTextRange(list, node.variableDeclaration);
const destructure = createVariableStatement(/*modifiers*/ undefined, list);
updated = updateCatchClause(node, newVariableDeclaration, addStatementToStartOfBlock(node.block, destructure));
}
else {
@@ -3001,9 +3034,11 @@ namespace ts {
Debug.assert(!isComputedPropertyName(node.name));
const functionExpression = transformFunctionLikeToExpression(node, /*location*/ moveRangePos(node, -1), /*name*/ undefined, /*container*/ undefined);
setEmitFlags(functionExpression, EmitFlags.NoLeadingComments | getEmitFlags(functionExpression));
return createPropertyAssignment(
node.name,
functionExpression,
return setTextRange(
createPropertyAssignment(
node.name,
functionExpression
),
/*location*/ node
);
}
@@ -3030,9 +3065,11 @@ namespace ts {
* @param node A ShorthandPropertyAssignment node.
*/
function visitShorthandPropertyAssignment(node: ShorthandPropertyAssignment): ObjectLiteralElementLike {
return createPropertyAssignment(
node.name,
getSynthesizedClone(node.name),
return setTextRange(
createPropertyAssignment(
node.name,
getSynthesizedClone(node.name)
),
/*location*/ node
);
}
@@ -3225,8 +3262,7 @@ namespace ts {
function visitSpanOfNonSpreads(chunk: Expression[], multiLine: boolean, hasTrailingComma: boolean): VisitResult<Expression> {
return createArrayLiteral(
visitNodes(createNodeArray(chunk, /*location*/ undefined, hasTrailingComma), visitor, isExpression),
/*location*/ undefined,
visitNodes(createNodeArray(chunk, hasTrailingComma), visitor, isExpression),
multiLine
);
}
@@ -3250,7 +3286,7 @@ namespace ts {
* @param node A template literal.
*/
function visitTemplateLiteral(node: LiteralExpression): LeftHandSideExpression {
return createLiteral(node.text, /*location*/ node);
return setTextRange(createLiteral(node.text), node);
}
/**
@@ -3318,7 +3354,7 @@ namespace ts {
// ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's
// <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for both TV and TRV.
text = text.replace(/\r\n?/g, "\n");
return createLiteral(text, /*location*/ node);
return setTextRange(createLiteral(text), node);
}
/**
@@ -3342,7 +3378,8 @@ namespace ts {
// "abc" + (1 << 2) + ""
const expression = reduceLeft(expressions, createAdd);
if (nodeIsSynthesized(expression)) {
setTextRange(expression, node);
expression.pos = node.pos;
expression.end = node.end;
}
return expression;
@@ -3435,9 +3472,11 @@ namespace ts {
/**
* Called by the printer just before a node is printed.
*
* @param hint A hint as to the intended usage of the node.
* @param node The node to be printed.
* @param emitCallback The callback used to emit the node.
*/
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis && isFunctionLike(node)) {
// If we are tracking a captured `this`, keep track of the enclosing function.
const ancestorFacts = enterSubtree(
@@ -3445,11 +3484,11 @@ namespace ts {
getEmitFlags(node) & EmitFlags.CapturesThis
? HierarchyFacts.FunctionIncludes | HierarchyFacts.CapturesThis
: HierarchyFacts.FunctionIncludes);
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
return;
}
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
}
/**
@@ -3484,13 +3523,13 @@ namespace ts {
/**
* Hooks node substitutions.
*
* @param emitContext The context for the emitter.
* @param hint The context for the emitter.
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
function onSubstituteNode(hint: EmitHint, node: Node) {
node = previousOnSubstituteNode(hint, node);
if (emitContext === EmitContext.Expression) {
if (hint === EmitHint.Expression) {
return substituteExpression(node);
}
@@ -3578,7 +3617,7 @@ namespace ts {
function substituteThisKeyword(node: PrimaryExpression): PrimaryExpression {
if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis
&& hierarchyFacts & HierarchyFacts.CapturesThis) {
return createIdentifier("_this", /*location*/ node);
return setTextRange(createIdentifier("_this"), node);
}
return node;
}
+31 -17
View File
@@ -48,29 +48,37 @@ namespace ts {
// Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)`
const expressionTemp = createTempVariable(hoistVariableDeclaration);
const argumentExpressionTemp = createTempVariable(hoistVariableDeclaration);
target = createElementAccess(
createAssignment(expressionTemp, left.expression, /*location*/ left.expression),
createAssignment(argumentExpressionTemp, left.argumentExpression, /*location*/ left.argumentExpression),
/*location*/ left
target = setTextRange(
createElementAccess(
setTextRange(createAssignment(expressionTemp, left.expression), left.expression),
setTextRange(createAssignment(argumentExpressionTemp, left.argumentExpression), left.argumentExpression)
),
left
);
value = createElementAccess(
expressionTemp,
argumentExpressionTemp,
/*location*/ left
value = setTextRange(
createElementAccess(
expressionTemp,
argumentExpressionTemp
),
left
);
}
else if (isPropertyAccessExpression(left)) {
// Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)`
const expressionTemp = createTempVariable(hoistVariableDeclaration);
target = createPropertyAccess(
createAssignment(expressionTemp, left.expression, /*location*/ left.expression),
left.name,
/*location*/ left
target = setTextRange(
createPropertyAccess(
setTextRange(createAssignment(expressionTemp, left.expression), left.expression),
left.name
),
left
);
value = createPropertyAccess(
expressionTemp,
left.name,
/*location*/ left
value = setTextRange(
createPropertyAccess(
expressionTemp,
left.name
),
left
);
}
else {
@@ -78,7 +86,13 @@ namespace ts {
target = left;
value = left;
}
return createAssignment(target, createMathPow(value, right, /*location*/ node), /*location*/ node);
return setTextRange(
createAssignment(
target,
createMathPow(value, right, /*location*/ node)
),
node
);
}
function visitExponentiationExpression(node: BinaryExpression) {
+32 -25
View File
@@ -104,10 +104,12 @@ namespace ts {
*/
function visitAwaitExpression(node: AwaitExpression): Expression {
return setOriginalNode(
createYield(
/*asteriskToken*/ undefined,
visitNode(node.expression, visitor, isExpression),
/*location*/ node
setTextRange(
createYield(
/*asteriskToken*/ undefined,
visitNode(node.expression, visitor, isExpression)
),
node
),
node
);
@@ -238,7 +240,8 @@ namespace ts {
addRange(statements, endLexicalEnvironment());
const block = createBlock(statements, /*location*/ node.body, /*multiLine*/ true);
const block = createBlock(statements, /*multiLine*/ true);
setTextRange(block, node.body);
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
// This step isn't needed if we eventually transform this to ES5.
@@ -266,7 +269,7 @@ namespace ts {
const declarations = endLexicalEnvironment();
if (some(declarations)) {
const block = convertToFunctionBody(expression);
return updateBlock(block, createNodeArray(concatenate(block.statements, declarations), block.statements));
return updateBlock(block, setTextRange(createNodeArray(concatenate(block.statements, declarations)), block.statements));
}
return expression;
@@ -281,7 +284,7 @@ namespace ts {
startLexicalEnvironment();
const visited = convertToFunctionBody(visitNode(body, visitor, isConciseBody));
const declarations = endLexicalEnvironment();
return updateBlock(visited, createNodeArray(concatenate(visited.statements, declarations), visited.statements));
return updateBlock(visited, setTextRange(createNodeArray(concatenate(visited.statements, declarations)), visited.statements));
}
}
@@ -396,33 +399,33 @@ namespace ts {
/**
* Hook for node emit.
*
* @param hint A hint as to the intended usage of the node.
* @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 {
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
// If we need to support substitutions for `super` in an async method,
// we should track it here.
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
const savedCurrentSuperContainer = currentSuperContainer;
currentSuperContainer = node;
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
currentSuperContainer = savedCurrentSuperContainer;
}
else {
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
}
}
/**
* Hooks node substitutions.
*
* @param hint A hint as to the intended usage of the node.
* @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) {
function onSubstituteNode(hint: EmitHint, node: Node) {
node = previousOnSubstituteNode(hint, node);
if (hint === EmitHint.Expression) {
return substituteExpression(<Expression>node);
}
@@ -431,21 +434,25 @@ namespace ts {
function createSuperAccessInAsyncMethod(argumentExpression: Expression, flags: NodeCheckFlags, location: TextRange): LeftHandSideExpression {
if (flags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
return createPropertyAccess(
return setTextRange(
createPropertyAccess(
createCall(
createIdentifier("_super"),
/*typeArguments*/ undefined,
[argumentExpression]
),
"value"
),
location
);
}
else {
return setTextRange(
createCall(
createIdentifier("_super"),
/*typeArguments*/ undefined,
[argumentExpression]
),
"value",
location
);
}
else {
return createCall(
createIdentifier("_super"),
/*typeArguments*/ undefined,
[argumentExpression],
location
);
}
+12 -10
View File
@@ -12,7 +12,7 @@ namespace ts {
const compilerOptions = context.getCompilerOptions();
// enable emit notification only if using --jsx preserve or react-native
let previousOnEmitNode: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void;
let previousOnEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
let noSubstitution: boolean[];
if (compilerOptions.jsx === JsxEmit.Preserve || compilerOptions.jsx === JsxEmit.ReactNative) {
previousOnEmitNode = context.onEmitNode;
@@ -41,9 +41,11 @@ namespace ts {
/**
* Called by the printer just before a node is printed.
*
* @param node The node to be printed.
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emitCallback A callback used to emit the node.
*/
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (emitContext: EmitHint, node: Node) => void) {
switch (node.kind) {
case SyntaxKind.JsxOpeningElement:
case SyntaxKind.JsxClosingElement:
@@ -53,21 +55,21 @@ namespace ts {
break;
}
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
}
/**
* Hooks node substitutions.
*
* @param emitContext The context for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
function onSubstituteNode(hint: EmitHint, node: Node) {
if (node.id && noSubstitution && noSubstitution[node.id]) {
return previousOnSubstituteNode(emitContext, node);
return previousOnSubstituteNode(hint, node);
}
node = previousOnSubstituteNode(emitContext, node);
node = previousOnSubstituteNode(hint, node);
if (isPropertyAccessExpression(node)) {
return substitutePropertyAccessExpression(node);
}
@@ -85,7 +87,7 @@ namespace ts {
function substitutePropertyAccessExpression(node: PropertyAccessExpression): Expression {
const literalName = trySubstituteReservedName(node.name);
if (literalName) {
return createElementAccess(node.expression, literalName, /*location*/ node);
return setTextRange(createElementAccess(node.expression, literalName), node);
}
return node;
}
@@ -111,7 +113,7 @@ namespace ts {
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 setTextRange(createLiteral(name), name);
}
return undefined;
}
+16 -12
View File
@@ -210,36 +210,40 @@ namespace ts {
const statement = createVariableStatement(
/*modifiers*/ undefined,
updateVariableDeclarationList(initializer, declarations),
/*location*/ initializer
);
setTextRange(statement, initializer);
leadingStatements = append(leadingStatements, statement);
}
}
else if (isAssignmentPattern(initializer)) {
temp = createTempVariable(/*recordTempVariable*/ undefined);
const expression = flattenDestructuringAssignment(
aggregateTransformFlags(createAssignment(initializer, temp, /*location*/ node.initializer)),
aggregateTransformFlags(
setTextRange(
createAssignment(initializer, temp),
node.initializer
)
),
visitor,
context,
FlattenLevel.ObjectRest
);
leadingStatements = append(leadingStatements, createStatement(expression, /*location*/ node.initializer));
leadingStatements = append(leadingStatements, setTextRange(createStatement(expression), node.initializer));
}
}
if (temp) {
const expression = visitNode(node.expression, visitor, isExpression);
const statement = visitNode(node.statement, visitor, isStatement);
const block = isBlock(statement)
? updateBlock(statement, createNodeArray(concatenate(leadingStatements, statement.statements), statement.statements))
: createBlock(append(leadingStatements, statement), statement, /*multiLine*/ true);
? updateBlock(statement, setTextRange(createNodeArray(concatenate(leadingStatements, statement.statements)), statement.statements))
: setTextRange(createBlock(append(leadingStatements, statement), /*multiLine*/ true), statement);
return updateForOf(
node,
createVariableDeclarationList(
[
createVariableDeclaration(temp, /*type*/ undefined, /*initializer*/ undefined, node.initializer)
],
node.initializer,
NodeFlags.Let
setTextRange(
createVariableDeclarationList([
setTextRange(createVariableDeclaration(temp), node.initializer)
], NodeFlags.Let),
node.initializer
),
expression,
block
@@ -380,7 +384,7 @@ namespace ts {
const trailingStatements = endLexicalEnvironment();
if (some(leadingStatements) || some(trailingStatements)) {
const block = convertToFunctionBody(body, /*multiLine*/ true);
return updateBlock(block, createNodeArray(concatenate(concatenate(leadingStatements, block.statements), trailingStatements), block.statements));
return updateBlock(block, setTextRange(createNodeArray(concatenate(concatenate(leadingStatements, block.statements), trailingStatements)), block.statements));
}
return body;
}
+129 -93
View File
@@ -450,15 +450,17 @@ namespace ts {
// Currently, we only support generators that were originally async functions.
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
node = setOriginalNode(
createFunctionDeclaration(
/*decorators*/ undefined,
node.modifiers,
/*asteriskToken*/ undefined,
node.name,
/*typeParameters*/ undefined,
visitParameterList(node.parameters, visitor, context),
/*type*/ undefined,
transformGeneratorFunctionBody(node.body),
setTextRange(
createFunctionDeclaration(
/*decorators*/ undefined,
node.modifiers,
/*asteriskToken*/ undefined,
node.name,
/*typeParameters*/ undefined,
visitParameterList(node.parameters, visitor, context),
/*type*/ undefined,
transformGeneratorFunctionBody(node.body)
),
/*location*/ node
),
node
@@ -498,14 +500,16 @@ namespace ts {
// Currently, we only support generators that were originally async functions.
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
node = setOriginalNode(
createFunctionExpression(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
node.name,
/*typeParameters*/ undefined,
visitParameterList(node.parameters, visitor, context),
/*type*/ undefined,
transformGeneratorFunctionBody(node.body),
setTextRange(
createFunctionExpression(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
node.name,
/*typeParameters*/ undefined,
visitParameterList(node.parameters, visitor, context),
/*type*/ undefined,
transformGeneratorFunctionBody(node.body)
),
/*location*/ node
),
node
@@ -606,7 +610,7 @@ namespace ts {
operationLocations = savedOperationLocations;
state = savedState;
return createBlock(statements, /*location*/ body, body.multiLine);
return setTextRange(createBlock(statements, body.multiLine), body);
}
/**
@@ -739,14 +743,17 @@ namespace ts {
const operator = node.operatorToken.kind;
if (isCompoundAssignment(operator)) {
return createBinary(
target,
SyntaxKind.EqualsToken,
createBinary(
cacheExpression(target),
getOperatorForCompoundAssignment(operator),
visitNode(right, visitor, isExpression),
node
return setTextRange(
createAssignment(
target,
setTextRange(
createBinary(
cacheExpression(target),
getOperatorForCompoundAssignment(operator),
visitNode(right, visitor, isExpression)
),
node
)
),
node
);
@@ -988,8 +995,11 @@ namespace ts {
const expressions = reduceLeft(elements, reduceElement, <Expression[]>[], numInitialElements);
return hasAssignedTemp
? createArrayConcat(temp, [createArrayLiteral(expressions, /*location*/ undefined, multiLine)])
: createArrayLiteral(leadingElement ? [leadingElement, ...expressions] : expressions, location, multiLine);
? createArrayConcat(temp, [createArrayLiteral(expressions, multiLine)])
: setTextRange(
createArrayLiteral(leadingElement ? [leadingElement, ...expressions] : expressions, multiLine),
location
);
function reduceElement(expressions: Expression[], element: Expression) {
if (containsYield(element) && expressions.length > 0) {
@@ -998,11 +1008,10 @@ namespace ts {
hasAssignedTemp
? createArrayConcat(
temp,
[createArrayLiteral(expressions, /*location*/ undefined, multiLine)]
[createArrayLiteral(expressions, multiLine)]
)
: createArrayLiteral(
leadingElement ? [leadingElement, ...expressions] : expressions,
/*location*/ undefined,
multiLine
)
);
@@ -1043,7 +1052,6 @@ namespace ts {
emitAssignment(temp,
createObjectLiteral(
visitNodes(properties, visitor, isObjectLiteralElementLike, 0, numInitialProperties),
/*location*/ undefined,
multiLine
)
);
@@ -1139,18 +1147,20 @@ namespace ts {
const { target, thisArg } = createCallBinding(createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration);
return setOriginalNode(
createNew(
createFunctionApply(
cacheExpression(visitNode(target, visitor, isExpression)),
thisArg,
visitElements(
node.arguments,
/*leadingElement*/ createVoidZero()
)
setTextRange(
createNew(
createFunctionApply(
cacheExpression(visitNode(target, visitor, isExpression)),
thisArg,
visitElements(
node.arguments,
/*leadingElement*/ createVoidZero()
)
),
/*typeArguments*/ undefined,
[]
),
/*typeArguments*/ undefined,
[],
/*location*/ node
node
),
node
);
@@ -1423,9 +1433,11 @@ namespace ts {
}
else {
emitStatement(
createStatement(
visitNode(initializer, visitor, isExpression),
/*location*/ initializer
setTextRange(
createStatement(
visitNode(initializer, visitor, isExpression)
),
initializer
)
);
}
@@ -1441,9 +1453,11 @@ namespace ts {
markLabel(incrementLabel);
if (node.incrementor) {
emitStatement(
createStatement(
visitNode(node.incrementor, visitor, isExpression),
/*location*/ node.incrementor
setTextRange(
createStatement(
visitNode(node.incrementor, visitor, isExpression)
),
node.incrementor
)
);
}
@@ -1909,9 +1923,9 @@ namespace ts {
return -1;
}
function onSubstituteNode(emitContext: EmitContext, node: Node): Node {
node = previousOnSubstituteNode(emitContext, node);
if (emitContext === EmitContext.Expression) {
function onSubstituteNode(hint: EmitHint, node: Node): Node {
node = previousOnSubstituteNode(hint, node);
if (hint === EmitHint.Expression) {
return substituteExpression(<Expression>node);
}
return node;
@@ -2417,11 +2431,13 @@ namespace ts {
*/
function createInlineBreak(label: Label, location?: TextRange): ReturnStatement {
Debug.assert(label > 0, `Invalid label: ${label}`);
return createReturn(
createArrayLiteral([
createInstruction(Instruction.Break),
createLabel(label)
]),
return setTextRange(
createReturn(
createArrayLiteral([
createInstruction(Instruction.Break),
createLabel(label)
])
),
location
);
}
@@ -2433,10 +2449,12 @@ namespace ts {
* @param location An optional source map location for the statement.
*/
function createInlineReturn(expression?: Expression, location?: TextRange): ReturnStatement {
return createReturn(
createArrayLiteral(expression
? [createInstruction(Instruction.Return), expression]
: [createInstruction(Instruction.Return)]
return setTextRange(
createReturn(
createArrayLiteral(expression
? [createInstruction(Instruction.Return), expression]
: [createInstruction(Instruction.Return)]
)
),
location
);
@@ -2446,7 +2464,14 @@ namespace ts {
* Creates an expression that can be used to resume from a Yield operation.
*/
function createGeneratorResume(location?: TextRange): LeftHandSideExpression {
return createCall(createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, [], location);
return setTextRange(
createCall(
createPropertyAccess(state, "sent"),
/*typeArguments*/ undefined,
[]
),
location
);
}
/**
@@ -2614,7 +2639,6 @@ namespace ts {
/*type*/ undefined,
createBlock(
buildResult,
/*location*/ undefined,
/*multiLine*/ buildResult.length > 0
)
),
@@ -2944,7 +2968,7 @@ namespace ts {
* @param operationLocation The source map location for the operation.
*/
function writeAssign(left: Expression, right: Expression, operationLocation: TextRange): void {
writeStatement(createStatement(createAssignment(left, right), operationLocation));
writeStatement(setTextRange(createStatement(createAssignment(left, right)), operationLocation));
}
/**
@@ -2956,7 +2980,7 @@ namespace ts {
function writeThrow(expression: Expression, operationLocation: TextRange): void {
lastOperationWasAbrupt = true;
lastOperationWasCompletion = true;
writeStatement(createThrow(expression, operationLocation));
writeStatement(setTextRange(createThrow(expression), operationLocation));
}
/**
@@ -2970,10 +2994,12 @@ namespace ts {
lastOperationWasCompletion = true;
writeStatement(
setEmitFlags(
createReturn(
createArrayLiteral(expression
? [createInstruction(Instruction.Return), expression]
: [createInstruction(Instruction.Return)]
setTextRange(
createReturn(
createArrayLiteral(expression
? [createInstruction(Instruction.Return), expression]
: [createInstruction(Instruction.Return)]
)
),
operationLocation
),
@@ -2992,11 +3018,13 @@ namespace ts {
lastOperationWasAbrupt = true;
writeStatement(
setEmitFlags(
createReturn(
createArrayLiteral([
createInstruction(Instruction.Break),
createLabel(label)
]),
setTextRange(
createReturn(
createArrayLiteral([
createInstruction(Instruction.Break),
createLabel(label)
])
),
operationLocation
),
EmitFlags.NoTokenSourceMaps
@@ -3017,11 +3045,13 @@ namespace ts {
createIf(
condition,
setEmitFlags(
createReturn(
createArrayLiteral([
createInstruction(Instruction.Break),
createLabel(label)
]),
setTextRange(
createReturn(
createArrayLiteral([
createInstruction(Instruction.Break),
createLabel(label)
])
),
operationLocation
),
EmitFlags.NoTokenSourceMaps
@@ -3045,11 +3075,13 @@ namespace ts {
createIf(
createLogicalNot(condition),
setEmitFlags(
createReturn(
createArrayLiteral([
createInstruction(Instruction.Break),
createLabel(label)
]),
setTextRange(
createReturn(
createArrayLiteral([
createInstruction(Instruction.Break),
createLabel(label)
])
),
operationLocation
),
EmitFlags.NoTokenSourceMaps
@@ -3070,11 +3102,13 @@ namespace ts {
lastOperationWasAbrupt = true;
writeStatement(
setEmitFlags(
createReturn(
createArrayLiteral(
expression
? [createInstruction(Instruction.Yield), expression]
: [createInstruction(Instruction.Yield)]
setTextRange(
createReturn(
createArrayLiteral(
expression
? [createInstruction(Instruction.Yield), expression]
: [createInstruction(Instruction.Yield)]
)
),
operationLocation
),
@@ -3093,11 +3127,13 @@ namespace ts {
lastOperationWasAbrupt = true;
writeStatement(
setEmitFlags(
createReturn(
createArrayLiteral([
createInstruction(Instruction.YieldStar),
expression
]),
setTextRange(
createReturn(
createArrayLiteral([
createInstruction(Instruction.YieldStar),
expression
])
),
operationLocation
),
EmitFlags.NoTokenSourceMaps
+3 -3
View File
@@ -143,15 +143,15 @@ namespace ts {
function transformJsxAttributeInitializer(node: StringLiteral | JsxExpression) {
if (node === undefined) {
return createLiteral(true);
return createTrue();
}
else if (node.kind === SyntaxKind.StringLiteral) {
const decoded = tryDecodeEntities((<StringLiteral>node).text);
return decoded ? createLiteral(decoded, /*location*/ node) : node;
return decoded ? setTextRange(createLiteral(decoded), node) : node;
}
else if (node.kind === SyntaxKind.JsxExpression) {
if (node.expression === undefined) {
return createLiteral(true);
return createTrue();
}
return visitJsxExpression(<JsxExpression>node);
}
+9 -9
View File
@@ -37,7 +37,7 @@ namespace ts {
addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset));
return updateSourceFileNode(
node,
createNodeArray(statements, node.statements));
setTextRange(createNodeArray(statements), node.statements));
}
else {
return visitEachChild(node, visitor, context);
@@ -71,18 +71,18 @@ namespace ts {
/**
* Hook for node emit.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @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 {
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
if (isSourceFile(node)) {
currentSourceFile = node;
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
currentSourceFile = undefined;
}
else {
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
}
}
@@ -93,12 +93,12 @@ namespace ts {
/**
* Hooks node substitutions.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
if (isIdentifier(node) && emitContext === EmitContext.Expression) {
function onSubstituteNode(hint: EmitHint, node: Node) {
node = previousOnSubstituteNode(hint, node);
if (isIdentifier(node) && hint === EmitHint.Expression) {
return substituteExpressionIdentifier(node);
}
return node;
+248 -218
View File
@@ -88,7 +88,7 @@ namespace ts {
addRange(statements, endLexicalEnvironment());
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
const updated = updateSourceFileNode(node, createNodeArray(statements, node.statements));
const updated = updateSourceFileNode(node, setTextRange(createNodeArray(statements), node.statements));
if (currentModuleInfo.hasExportStarsToExportValues) {
addEmitHelper(updated, exportStarHelper);
}
@@ -131,47 +131,49 @@ namespace ts {
// Create an updated SourceFile:
//
// define(moduleName?, ["module1", "module2"], function ...
return updateSourceFileNode(node, createNodeArray(
[
createStatement(
createCall(
define,
/*typeArguments*/ undefined,
[
// Add the module name (if provided).
...(moduleName ? [moduleName] : []),
return updateSourceFileNode(node,
setTextRange(
createNodeArray([
createStatement(
createCall(
define,
/*typeArguments*/ undefined,
[
// Add the module name (if provided).
...(moduleName ? [moduleName] : []),
// Add the dependency array argument:
//
// ["require", "exports", module1", "module2", ...]
createArrayLiteral([
createLiteral("require"),
createLiteral("exports"),
...aliasedModuleNames,
...unaliasedModuleNames
]),
// Add the dependency array argument:
//
// ["require", "exports", module1", "module2", ...]
createArrayLiteral([
createLiteral("require"),
createLiteral("exports"),
...aliasedModuleNames,
...unaliasedModuleNames
]),
// Add the module body function argument:
//
// function (require, exports, module1, module2) ...
createFunctionExpression(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
[
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"),
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports"),
...importAliasNames
],
/*type*/ undefined,
transformAsynchronousModuleBody(node)
)
]
// Add the module body function argument:
//
// function (require, exports, module1, module2) ...
createFunctionExpression(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
[
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"),
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports"),
...importAliasNames
],
/*type*/ undefined,
transformAsynchronousModuleBody(node)
)
]
)
)
)
],
/*location*/ node.statements)
]),
/*location*/ node.statements
)
);
}
@@ -189,74 +191,76 @@ namespace ts {
/*typeParameters*/ undefined,
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "factory")],
/*type*/ undefined,
createBlock(
[
createIf(
createLogicalAnd(
createTypeCheck(createIdentifier("module"), "object"),
createTypeCheck(createPropertyAccess(createIdentifier("module"), "exports"), "object")
),
createBlock([
createVariableStatement(
/*modifiers*/ undefined,
[
createVariableDeclaration(
"v",
/*type*/ undefined,
setTextRange(
createBlock(
[
createIf(
createLogicalAnd(
createTypeCheck(createIdentifier("module"), "object"),
createTypeCheck(createPropertyAccess(createIdentifier("module"), "exports"), "object")
),
createBlock([
createVariableStatement(
/*modifiers*/ undefined,
[
createVariableDeclaration(
"v",
/*type*/ undefined,
createCall(
createIdentifier("factory"),
/*typeArguments*/ undefined,
[
createIdentifier("require"),
createIdentifier("exports")
]
)
)
]
),
setEmitFlags(
createIf(
createStrictInequality(
createIdentifier("v"),
createIdentifier("undefined")
),
createStatement(
createAssignment(
createPropertyAccess(createIdentifier("module"), "exports"),
createIdentifier("v")
)
)
),
EmitFlags.SingleLine
)
]),
createIf(
createLogicalAnd(
createTypeCheck(createIdentifier("define"), "function"),
createPropertyAccess(createIdentifier("define"), "amd")
),
createBlock([
createStatement(
createCall(
createIdentifier("factory"),
createIdentifier("define"),
/*typeArguments*/ undefined,
[
createIdentifier("require"),
createIdentifier("exports")
createArrayLiteral([
createLiteral("require"),
createLiteral("exports"),
...aliasedModuleNames,
...unaliasedModuleNames
]),
createIdentifier("factory")
]
)
)
]
),
setEmitFlags(
createIf(
createStrictInequality(
createIdentifier("v"),
createIdentifier("undefined")
),
createStatement(
createAssignment(
createPropertyAccess(createIdentifier("module"), "exports"),
createIdentifier("v")
)
)
),
EmitFlags.SingleLine
])
)
]),
createIf(
createLogicalAnd(
createTypeCheck(createIdentifier("define"), "function"),
createPropertyAccess(createIdentifier("define"), "amd")
),
createBlock([
createStatement(
createCall(
createIdentifier("define"),
/*typeArguments*/ undefined,
[
createArrayLiteral([
createLiteral("require"),
createLiteral("exports"),
...aliasedModuleNames,
...unaliasedModuleNames
]),
createIdentifier("factory")
]
)
)
])
)
)
],
/*location*/ undefined,
/*multiLine*/ true
],
/*multiLine*/ true
),
/*location*/ undefined
)
);
@@ -274,8 +278,8 @@ namespace ts {
return updateSourceFileNode(
node,
createNodeArray(
[
setTextRange(
createNodeArray([
createStatement(
createCall(
umdHeader,
@@ -300,7 +304,7 @@ namespace ts {
]
)
)
],
]),
/*location*/ node.statements
)
);
@@ -378,7 +382,7 @@ namespace ts {
// Append the 'export =' statement if provided.
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true);
const body = createBlock(statements, /*location*/ undefined, /*multiLine*/ true);
const body = createBlock(statements, /*multiLine*/ true);
if (currentModuleInfo.hasExportStarsToExportValues) {
// If we have any `export * from ...` declarations
// we need to inform the emitter to add the __export helper.
@@ -399,11 +403,8 @@ namespace ts {
function addExportEqualsIfNeeded(statements: Statement[], emitAsReturn: boolean) {
if (currentModuleInfo.exportEquals) {
if (emitAsReturn) {
const statement = createReturn(
currentModuleInfo.exportEquals.expression,
/*location*/ currentModuleInfo.exportEquals
);
const statement = createReturn(currentModuleInfo.exportEquals.expression);
setTextRange(statement, currentModuleInfo.exportEquals);
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments);
statements.push(statement);
}
@@ -415,10 +416,10 @@ namespace ts {
"exports"
),
currentModuleInfo.exportEquals.expression
),
/*location*/ currentModuleInfo.exportEquals
)
);
setTextRange(statement, currentModuleInfo.exportEquals);
setEmitFlags(statement, EmitFlags.NoComments);
statements.push(statement);
}
@@ -481,7 +482,7 @@ namespace ts {
if (moduleKind !== ModuleKind.AMD) {
if (!node.importClause) {
// import "mod";
return createStatement(createRequireCall(node), /*location*/ node);
return setTextRange(createStatement(createRequireCall(node)), node);
}
else {
const variables: VariableDeclaration[] = [];
@@ -520,12 +521,13 @@ namespace ts {
}
statements = append(statements,
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
variables,
/*location*/ undefined,
languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None
setTextRange(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
variables,
languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None
)
),
/*location*/ node
)
@@ -539,14 +541,15 @@ namespace ts {
/*modifiers*/ undefined,
createVariableDeclarationList(
[
createVariableDeclaration(
getSynthesizedClone(namespaceDeclaration.name),
/*type*/ undefined,
getGeneratedNameForNode(node),
setTextRange(
createVariableDeclaration(
getSynthesizedClone(namespaceDeclaration.name),
/*type*/ undefined,
getGeneratedNameForNode(node)
),
/*location*/ node
)
],
/*location*/ undefined,
languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None
)
)
@@ -592,31 +595,34 @@ namespace ts {
if (moduleKind !== ModuleKind.AMD) {
if (hasModifier(node, ModifierFlags.Export)) {
statements = append(statements,
createStatement(
createExportExpression(
node.name,
createRequireCall(node)
setTextRange(
createStatement(
createExportExpression(
node.name,
createRequireCall(node)
)
),
/*location*/ node
node
)
);
}
else {
statements = append(statements,
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
[
createVariableDeclaration(
getSynthesizedClone(node.name),
/*type*/ undefined,
createRequireCall(node)
)
],
/*location*/ undefined,
/*flags*/ languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None
setTextRange(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
[
createVariableDeclaration(
getSynthesizedClone(node.name),
/*type*/ undefined,
createRequireCall(node)
)
],
/*flags*/ languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None
)
),
/*location*/ node
node
)
);
}
@@ -624,9 +630,11 @@ namespace ts {
else {
if (hasModifier(node, ModifierFlags.Export)) {
statements = append(statements,
createStatement(
createExportExpression(getExportName(node), getLocalName(node)),
/*location*/ node
setTextRange(
createStatement(
createExportExpression(getExportName(node), getLocalName(node))
),
node
)
);
}
@@ -662,15 +670,17 @@ namespace ts {
// export { x, y } from "mod";
if (moduleKind !== ModuleKind.AMD) {
statements.push(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
generatedName,
/*type*/ undefined,
createRequireCall(node)
)
]),
setTextRange(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
generatedName,
/*type*/ undefined,
createRequireCall(node)
)
])
),
/*location*/ node
)
);
@@ -681,9 +691,11 @@ namespace ts {
specifier.propertyName || specifier.name
);
statements.push(
createStatement(
createExportExpression(getExportName(specifier), exportedValue),
/*location*/ specifier
setTextRange(
createStatement(
createExportExpression(getExportName(specifier), exportedValue)
),
specifier
)
);
}
@@ -692,17 +704,19 @@ namespace ts {
}
else {
// export * from "mod";
return createStatement(
createCall(
createIdentifier("__export"),
/*typeArguments*/ undefined,
[
moduleKind !== ModuleKind.AMD
? createRequireCall(node)
: generatedName
]
return setTextRange(
createStatement(
createCall(
createIdentifier("__export"),
/*typeArguments*/ undefined,
[
moduleKind !== ModuleKind.AMD
? createRequireCall(node)
: generatedName
]
)
),
/*location*/ node
node
);
}
}
@@ -741,15 +755,17 @@ namespace ts {
if (hasModifier(node, ModifierFlags.Export)) {
statements = append(statements,
setOriginalNode(
createFunctionDeclaration(
/*decorators*/ undefined,
visitNodes(node.modifiers, modifierVisitor, isModifier),
node.asteriskToken,
getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
/*typeParameters*/ undefined,
node.parameters,
/*type*/ undefined,
node.body,
setTextRange(
createFunctionDeclaration(
/*decorators*/ undefined,
visitNodes(node.modifiers, modifierVisitor, isModifier),
node.asteriskToken,
getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
/*typeParameters*/ undefined,
node.parameters,
/*type*/ undefined,
node.body
),
/*location*/ node
),
/*original*/ node
@@ -782,16 +798,18 @@ namespace ts {
if (hasModifier(node, ModifierFlags.Export)) {
statements = append(statements,
setOriginalNode(
createClassDeclaration(
/*decorators*/ undefined,
visitNodes(node.modifiers, modifierVisitor, isModifier),
getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
/*typeParameters*/ undefined,
node.heritageClauses,
node.members,
/*location*/ node
setTextRange(
createClassDeclaration(
/*decorators*/ undefined,
visitNodes(node.modifiers, modifierVisitor, isModifier),
getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
/*typeParameters*/ undefined,
node.heritageClauses,
node.members
),
node
),
/*original*/ node
node
)
);
}
@@ -843,7 +861,7 @@ namespace ts {
}
if (expressions) {
statements = append(statements, createStatement(inlineExpressions(expressions), /*location*/ node));
statements = append(statements, setTextRange(createStatement(inlineExpressions(expressions)), node));
}
}
else {
@@ -880,9 +898,11 @@ namespace ts {
}
else {
return createAssignment(
createPropertyAccess(
createIdentifier("exports"),
node.name,
setTextRange(
createPropertyAccess(
createIdentifier("exports"),
node.name
),
/*location*/ node.name
),
node.initializer
@@ -1115,7 +1135,7 @@ namespace ts {
createStatement(
createExportExpression(
createIdentifier("__esModule"),
createLiteral(true)
createTrue()
)
)
);
@@ -1130,7 +1150,7 @@ namespace ts {
createIdentifier("exports"),
createLiteral("__esModule"),
createObjectLiteral([
createPropertyAssignment("value", createLiteral(true))
createPropertyAssignment("value", createTrue())
])
]
)
@@ -1153,7 +1173,7 @@ namespace ts {
* @param allowComments An optional value indicating whether to emit comments for the statement.
*/
function createExportStatement(name: Identifier, value: Expression, location?: TextRange, allowComments?: boolean) {
const statement = createStatement(createExportExpression(name, value), location);
const statement = setTextRange(createStatement(createExportExpression(name, value)), location);
startOnNewLine(statement);
if (!allowComments) {
setEmitFlags(statement, EmitFlags.NoComments);
@@ -1170,12 +1190,14 @@ namespace ts {
* @param location The location to use for source maps and comments for the export.
*/
function createExportExpression(name: Identifier, value: Expression, location?: TextRange) {
return createAssignment(
createPropertyAccess(
createIdentifier("exports"),
getSynthesizedClone(name)
return setTextRange(
createAssignment(
createPropertyAccess(
createIdentifier("exports"),
getSynthesizedClone(name)
),
value
),
value,
location
);
}
@@ -1207,24 +1229,24 @@ namespace ts {
/**
* Hook for node emit notifications.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @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 {
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
if (node.kind === SyntaxKind.SourceFile) {
currentSourceFile = <SourceFile>node;
currentModuleInfo = moduleInfoMap[getOriginalNodeId(currentSourceFile)];
noSubstitution = [];
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
currentSourceFile = undefined;
currentModuleInfo = undefined;
noSubstitution = undefined;
}
else {
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
}
}
@@ -1235,16 +1257,16 @@ namespace ts {
/**
* Hooks node substitutions.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
function onSubstituteNode(hint: EmitHint, node: Node) {
node = previousOnSubstituteNode(hint, node);
if (node.id && noSubstitution[node.id]) {
return node;
}
if (emitContext === EmitContext.Expression) {
if (hint === EmitHint.Expression) {
return substituteExpression(<Expression>node);
}
else if (isShorthandPropertyAssignment(node)) {
@@ -1268,9 +1290,9 @@ namespace ts {
// destructuring assignment
if (node.objectAssignmentInitializer) {
const initializer = createAssignment(exportedOrImportedName, node.objectAssignmentInitializer);
return createPropertyAssignment(name, initializer, /*location*/ node);
return setTextRange(createPropertyAssignment(name, initializer), node);
}
return createPropertyAssignment(name, exportedOrImportedName, /*location*/ node);
return setTextRange(createPropertyAssignment(name, exportedOrImportedName), node);
}
return node;
}
@@ -1312,9 +1334,11 @@ namespace ts {
if (!isGeneratedIdentifier(node) && !isLocalName(node)) {
const exportContainer = resolver.getReferencedExportContainer(node, isExportName(node));
if (exportContainer && exportContainer.kind === SyntaxKind.SourceFile) {
return createPropertyAccess(
createIdentifier("exports"),
getSynthesizedClone(node),
return setTextRange(
createPropertyAccess(
createIdentifier("exports"),
getSynthesizedClone(node)
),
/*location*/ node
);
}
@@ -1322,17 +1346,21 @@ namespace ts {
const importDeclaration = resolver.getReferencedImportDeclaration(node);
if (importDeclaration) {
if (isImportClause(importDeclaration)) {
return createPropertyAccess(
getGeneratedNameForNode(importDeclaration.parent),
createIdentifier("default"),
return setTextRange(
createPropertyAccess(
getGeneratedNameForNode(importDeclaration.parent),
createIdentifier("default")
),
/*location*/ node
);
}
else if (isImportSpecifier(importDeclaration)) {
const name = importDeclaration.propertyName || importDeclaration.name;
return createPropertyAccess(
getGeneratedNameForNode(importDeclaration.parent.parent.parent),
getSynthesizedClone(name),
return setTextRange(
createPropertyAccess(
getGeneratedNameForNode(importDeclaration.parent.parent.parent),
getSynthesizedClone(name)
),
/*location*/ node
);
}
@@ -1400,10 +1428,12 @@ namespace ts {
const exportedNames = getExports(node.operand);
if (exportedNames) {
let expression: Expression = node.kind === SyntaxKind.PostfixUnaryExpression
? createBinary(
node.operand,
createToken(node.operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken),
createLiteral(1),
? setTextRange(
createBinary(
node.operand,
createToken(node.operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken),
createLiteral(1)
),
/*location*/ node)
: node;
for (const exportName of exportedNames) {
+81 -78
View File
@@ -105,17 +105,20 @@ namespace ts {
const updated = setEmitFlags(
updateSourceFileNode(
node,
createNodeArray([
createStatement(
createCall(
createPropertyAccess(createIdentifier("System"), "register"),
/*typeArguments*/ undefined,
moduleName
? [moduleName, dependencies, moduleBodyFunction]
: [dependencies, moduleBodyFunction]
setTextRange(
createNodeArray([
createStatement(
createCall(
createPropertyAccess(createIdentifier("System"), "register"),
/*typeArguments*/ undefined,
moduleName
? [moduleName, dependencies, moduleBodyFunction]
: [dependencies, moduleBodyFunction]
)
)
)
], node.statements)
]),
node.statements
)
), EmitFlags.NoTrailingComments);
if (!(compilerOptions.outFile || compilerOptions.out)) {
@@ -260,35 +263,26 @@ namespace ts {
addRange(statements, endLexicalEnvironment());
const exportStarFunction = addExportStarIfNeeded(statements);
statements.push(
createReturn(
setMultiLine(
createObjectLiteral([
createPropertyAssignment("setters",
createSettersArray(exportStarFunction, dependencyGroups)
),
createPropertyAssignment("execute",
createFunctionExpression(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
/*parameters*/ [],
/*type*/ undefined,
createBlock(
executeStatements,
/*location*/ undefined,
/*multiLine*/ true
)
)
)
]),
/*multiLine*/ true
const moduleObject = createObjectLiteral([
createPropertyAssignment("setters",
createSettersArray(exportStarFunction, dependencyGroups)
),
createPropertyAssignment("execute",
createFunctionExpression(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
/*parameters*/ [],
/*type*/ undefined,
createBlock(executeStatements, /*multiLine*/ true)
)
)
);
]);
return createBlock(statements, /*location*/ undefined, /*multiLine*/ true);
moduleObject.multiLine = true;
statements.push(createReturn(moduleObject));
return createBlock(statements, /*multiLine*/ true);
}
/**
@@ -337,7 +331,7 @@ namespace ts {
exportedNames.push(
createPropertyAssignment(
createLiteral(exportedLocalName),
createLiteral(true)
createTrue()
)
);
}
@@ -359,7 +353,7 @@ namespace ts {
exportedNames.push(
createPropertyAssignment(
createLiteral((element.name || element.propertyName).text),
createLiteral(true)
createTrue()
)
);
}
@@ -373,7 +367,7 @@ namespace ts {
createVariableDeclaration(
exportedNamesStorageRef,
/*type*/ undefined,
createObjectLiteral(exportedNames, /*location*/ undefined, /*multiline*/ true)
createObjectLiteral(exportedNames, /*multiline*/ true)
)
])
)
@@ -456,9 +450,7 @@ namespace ts {
[exports]
)
)
],
/*location*/ undefined,
/*multiline*/ true)
], /*multiline*/ true)
);
}
@@ -525,7 +517,7 @@ namespace ts {
createCall(
exportFunction,
/*typeArguments*/ undefined,
[createObjectLiteral(properties, /*location*/ undefined, /*multiline*/ true)]
[createObjectLiteral(properties, /*multiline*/ true)]
)
)
);
@@ -558,12 +550,12 @@ namespace ts {
/*typeParameters*/ undefined,
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)],
/*type*/ undefined,
createBlock(statements, /*location*/ undefined, /*multiLine*/ true)
createBlock(statements, /*multiLine*/ true)
)
);
}
return createArrayLiteral(setters, /*location*/ undefined, /*multiLine*/ true);
return createArrayLiteral(setters, /*multiLine*/ true);
}
//
@@ -713,19 +705,23 @@ namespace ts {
// Rewrite the class declaration into an assignment of a class expression.
statements = append(statements,
createStatement(
createAssignment(
name,
createClassExpression(
/*modifiers*/ undefined,
node.name,
/*typeParameters*/ undefined,
visitNodes(node.heritageClauses, destructuringVisitor, isHeritageClause),
visitNodes(node.members, destructuringVisitor, isClassElement),
/*location*/ node
setTextRange(
createStatement(
createAssignment(
name,
setTextRange(
createClassExpression(
/*modifiers*/ undefined,
node.name,
/*typeParameters*/ undefined,
visitNodes(node.heritageClauses, destructuringVisitor, isHeritageClause),
visitNodes(node.members, destructuringVisitor, isClassElement)
),
node
)
)
),
/*location*/ node
node
)
);
@@ -766,7 +762,7 @@ namespace ts {
let statements: Statement[];
if (expressions) {
statements = append(statements, createStatement(inlineExpressions(expressions), /*location*/ node));
statements = append(statements, setTextRange(createStatement(inlineExpressions(expressions)), node));
}
if (isMarkedDeclaration) {
@@ -864,8 +860,8 @@ namespace ts {
function createVariableAssignment(name: Identifier, value: Expression, location: TextRange, isExportedDeclaration: boolean) {
hoistVariableDeclaration(getSynthesizedClone(name));
return isExportedDeclaration
? createExportExpression(name, preventSubstitution(createAssignment(name, value, location)))
: preventSubstitution(createAssignment(name, value, location));
? createExportExpression(name, preventSubstitution(setTextRange(createAssignment(name, value), location)))
: preventSubstitution(setTextRange(createAssignment(name, value), location));
}
/**
@@ -1548,11 +1544,11 @@ namespace ts {
/**
* Hook for node emit notifications.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emit A callback used to emit the node in the printer.
* @param emitCallback A callback used to emit the node in the printer.
*/
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
if (node.kind === SyntaxKind.SourceFile) {
const id = getOriginalNodeId(node);
currentSourceFile = <SourceFile>node;
@@ -1564,7 +1560,7 @@ namespace ts {
delete noSubstitutionMap[id];
}
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
currentSourceFile = undefined;
moduleInfo = undefined;
@@ -1572,7 +1568,7 @@ namespace ts {
noSubstitution = undefined;
}
else {
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
}
}
@@ -1583,16 +1579,16 @@ namespace ts {
/**
* Hooks node substitutions.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
function onSubstituteNode(hint: EmitHint, node: Node) {
node = previousOnSubstituteNode(hint, node);
if (isSubstitutionPrevented(node)) {
return node;
}
if (emitContext === EmitContext.Expression) {
if (hint === EmitHint.Expression) {
return substituteExpression(<Expression>node);
}
@@ -1642,16 +1638,20 @@ namespace ts {
const importDeclaration = resolver.getReferencedImportDeclaration(node);
if (importDeclaration) {
if (isImportClause(importDeclaration)) {
return createPropertyAccess(
getGeneratedNameForNode(importDeclaration.parent),
createIdentifier("default"),
return setTextRange(
createPropertyAccess(
getGeneratedNameForNode(importDeclaration.parent),
createIdentifier("default")
),
/*location*/ node
);
}
else if (isImportSpecifier(importDeclaration)) {
return createPropertyAccess(
getGeneratedNameForNode(importDeclaration.parent.parent.parent),
getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name),
return setTextRange(
createPropertyAccess(
getGeneratedNameForNode(importDeclaration.parent.parent.parent),
getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name)
),
/*location*/ node
);
}
@@ -1718,10 +1718,13 @@ namespace ts {
const exportedNames = getExports(node.operand);
if (exportedNames) {
let expression: Expression = node.kind === SyntaxKind.PostfixUnaryExpression
? createPrefix(
node.operator,
node.operand,
/*location*/ node)
? setTextRange(
createPrefix(
node.operator,
node.operand
),
node
)
: node;
for (const exportName of exportedNames) {
+156 -117
View File
@@ -588,17 +588,17 @@ namespace ts {
name,
/*typeParameters*/ undefined,
visitNodes(node.heritageClauses, visitor, isHeritageClause),
transformClassMembers(node, hasExtendsClause),
node);
let emitFlags = getEmitFlags(node);
transformClassMembers(node, hasExtendsClause)
);
// To better align with the old emitter, we should not emit a trailing source map
// entry if the class has static properties.
let emitFlags = getEmitFlags(node);
if (hasStaticProperties) {
emitFlags |= EmitFlags.NoTrailingSourceMap;
}
setTextRange(classDeclaration, node);
setOriginalNode(classDeclaration, node);
setEmitFlags(classDeclaration, emitFlags);
return classDeclaration;
@@ -709,13 +709,24 @@ namespace ts {
// }
const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause);
const members = transformClassMembers(node, hasExtendsClause);
const classExpression = createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members, location);
const classExpression = createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members);
setOriginalNode(classExpression, node);
setTextRange(classExpression, location);
// let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference
// or decoratedClassAlias if the class contain self-reference.
const statement = createLetStatement(declName, classAlias ? createAssignment(classAlias, classExpression) : classExpression, location);
const statement = createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
declName,
/*type*/ undefined,
classAlias ? createAssignment(classAlias, classExpression) : classExpression
)
], NodeFlags.Let)
);
setOriginalNode(statement, node);
setTextRange(statement, location);
setCommentRange(statement, node);
return statement;
}
@@ -734,18 +745,17 @@ namespace ts {
const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause);
const members = transformClassMembers(node, some(heritageClauses, c => c.token === SyntaxKind.ExtendsKeyword));
const classExpression = setOriginalNode(
createClassExpression(
/*modifiers*/ undefined,
node.name,
/*typeParameters*/ undefined,
heritageClauses,
members,
/*location*/ node
),
node
const classExpression = createClassExpression(
/*modifiers*/ undefined,
node.name,
/*typeParameters*/ undefined,
heritageClauses,
members
);
setOriginalNode(classExpression, node);
setTextRange(classExpression, node);
if (staticProperties.length > 0) {
const expressions: Expression[] = [];
const temp = createTempVariable(hoistVariableDeclaration);
@@ -781,7 +791,7 @@ namespace ts {
}
addRange(members, visitNodes(node.members, classElementVisitor, isClassElement));
return createNodeArray(members, /*location*/ node.members);
return setTextRange(createNodeArray(members), /*location*/ node.members);
}
/**
@@ -812,12 +822,14 @@ namespace ts {
// }
return startOnNewLine(
setOriginalNode(
createConstructor(
/*decorators*/ undefined,
/*modifiers*/ undefined,
parameters,
body,
/*location*/ constructor || node
setTextRange(
createConstructor(
/*decorators*/ undefined,
/*modifiers*/ undefined,
parameters,
body
),
constructor || node
),
constructor
)
@@ -919,13 +931,15 @@ namespace ts {
// End the lexical environment.
addRange(statements, endLexicalEnvironment());
return createBlock(
createNodeArray(
statements,
/*location*/ constructor ? constructor.body.statements : node.members
return setTextRange(
createBlock(
setTextRange(
createNodeArray(statements),
/*location*/ constructor ? constructor.body.statements : node.members
),
/*multiLine*/ true
),
/*location*/ constructor ? constructor.body : /*location*/ undefined,
/*multiLine*/ true
/*location*/ constructor ? constructor.body : undefined
);
}
@@ -991,16 +1005,20 @@ namespace ts {
setEmitFlags(localName, EmitFlags.NoComments);
return startOnNewLine(
createStatement(
createAssignment(
createPropertyAccess(
createThis(),
propertyName,
/*location*/ node.name
),
localName
setTextRange(
createStatement(
createAssignment(
setTextRange(
createPropertyAccess(
createThis(),
propertyName
),
node.name
),
localName
)
),
/*location*/ moveRangePos(node, -1)
moveRangePos(node, -1)
)
);
}
@@ -1504,7 +1522,7 @@ namespace ts {
(properties || (properties = [])).push(createPropertyAssignment("returnType", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeReturnTypeOfNode(node))));
}
if (properties) {
decoratorExpressions.push(createMetadataHelper(context, "design:typeinfo", createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true)));
decoratorExpressions.push(createMetadataHelper(context, "design:typeinfo", createObjectLiteral(properties, /*multiLine*/ true)));
}
}
}
@@ -1939,10 +1957,7 @@ namespace ts {
expression = createAssignment(generatedName, expression);
}
return setOriginalNode(
createComputedPropertyName(expression, /*location*/ name),
name
);
return updateComputedPropertyName(name, expression);
}
else {
return name;
@@ -1961,9 +1976,11 @@ namespace ts {
function visitHeritageClause(node: HeritageClause): HeritageClause {
if (node.token === SyntaxKind.ExtendsKeyword) {
const types = visitNodes(node.types, visitor, isExpressionWithTypeArguments, 0, 1);
return createHeritageClause(
SyntaxKind.ExtendsKeyword,
types,
return setTextRange(
createHeritageClause(
SyntaxKind.ExtendsKeyword,
types
),
node
);
}
@@ -1980,11 +1997,10 @@ namespace ts {
* @param node The ExpressionWithTypeArguments to transform.
*/
function visitExpressionWithTypeArguments(node: ExpressionWithTypeArguments): ExpressionWithTypeArguments {
const expression = visitNode(node.expression, visitor, isLeftHandSideExpression);
return createExpressionWithTypeArguments(
return updateExpressionWithTypeArguments(
node,
/*typeArguments*/ undefined,
expression,
node
visitNode(node.expression, visitor, isLeftHandSideExpression)
);
}
@@ -2205,13 +2221,13 @@ namespace ts {
visitNode(node.name, visitor, isBindingName),
/*questionToken*/ undefined,
/*type*/ undefined,
visitNode(node.initializer, visitor, isExpression),
/*location*/ moveRangePastModifiers(node)
visitNode(node.initializer, visitor, isExpression)
);
// While we emit the source map for the node after skipping decorators and modifiers,
// we need to emit the comments for the original range.
setOriginalNode(parameter, node);
setTextRange(parameter, moveRangePastModifiers(node));
setCommentRange(parameter, node);
setSourceMapRange(parameter, moveRangePastModifiers(node));
setEmitFlags(parameter.name, EmitFlags.NoTrailingSourceMap);
@@ -2233,11 +2249,13 @@ namespace ts {
return undefined;
}
return createStatement(
inlineExpressions(
map(variables, transformInitializedVariable)
return setTextRange(
createStatement(
inlineExpressions(
map(variables, transformInitializedVariable)
)
),
/*location*/ node
node
);
}
else {
@@ -2258,9 +2276,11 @@ namespace ts {
);
}
else {
return createAssignment(
getNamespaceMemberNameWithSourceMapsAndWithoutComments(name),
visitNode(node.initializer, visitor, isExpression),
return setTextRange(
createAssignment(
getNamespaceMemberNameWithSourceMapsAndWithoutComments(name),
visitNode(node.initializer, visitor, isExpression)
),
/*location*/ node
);
}
@@ -2418,11 +2438,11 @@ namespace ts {
),
/*typeArguments*/ undefined,
[moduleArg]
),
/*location*/ node
)
);
setOriginalNode(enumStatement, node);
setTextRange(enumStatement, node);
setEmitFlags(enumStatement, emitFlags);
statements.push(enumStatement);
@@ -2448,8 +2468,7 @@ namespace ts {
currentNamespaceContainerName = savedCurrentNamespaceLocalName;
return createBlock(
createNodeArray(statements, /*location*/ node.members),
/*location*/ undefined,
setTextRange(createNodeArray(statements), /*location*/ node.members),
/*multiLine*/ true
);
}
@@ -2464,22 +2483,26 @@ namespace ts {
// we pass false as 'generateNameForComputedPropertyName' for a backward compatibility purposes
// old emitter always generate 'expression' part of the name as-is.
const name = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ false);
return createStatement(
createAssignment(
createElementAccess(
currentNamespaceContainerName,
return setTextRange(
createStatement(
setTextRange(
createAssignment(
createElementAccess(
currentNamespaceContainerName,
name
createAssignment(
createElementAccess(
currentNamespaceContainerName,
name
),
transformEnumMemberDeclarationValue(member)
)
),
transformEnumMemberDeclarationValue(member)
)
),
name,
/*location*/ member
name
),
member
)
),
/*location*/ member
member
);
}
@@ -2697,11 +2720,11 @@ namespace ts {
),
/*typeArguments*/ undefined,
[moduleArg]
),
/*location*/ node
)
);
setOriginalNode(moduleStatement, node);
setTextRange(moduleStatement, node);
setEmitFlags(moduleStatement, emitFlags);
statements.push(moduleStatement);
@@ -2756,13 +2779,13 @@ namespace ts {
currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
const block = createBlock(
createNodeArray(
statements,
setTextRange(
createNodeArray(statements),
/*location*/ statementsLocation
),
/*location*/ blockLocation,
/*multiLine*/ true
);
setTextRange(block, blockLocation);
// namespace hello.hi.world {
// function foo() {}
@@ -2962,18 +2985,20 @@ namespace ts {
// export var ${name} = ${moduleReference};
// var ${name} = ${moduleReference};
return setOriginalNode(
createVariableStatement(
visitNodes(node.modifiers, modifierVisitor, isModifier),
createVariableDeclarationList([
setOriginalNode(
createVariableDeclaration(
node.name,
/*type*/ undefined,
moduleReference
),
node
)
]),
setTextRange(
createVariableStatement(
visitNodes(node.modifiers, modifierVisitor, isModifier),
createVariableDeclarationList([
setOriginalNode(
createVariableDeclaration(
node.name,
/*type*/ undefined,
moduleReference
),
node
)
])
),
node
),
node
@@ -3034,7 +3059,7 @@ namespace ts {
* Creates a statement for the provided expression. This is used in calls to `map`.
*/
function expressionToStatement(expression: Expression) {
return createStatement(expression, /*location*/ undefined);
return createStatement(expression);
}
function addExportMemberAssignment(statements: Statement[], node: ClassDeclaration | FunctionDeclaration) {
@@ -3050,17 +3075,19 @@ namespace ts {
}
function createNamespaceExport(exportName: Identifier, exportValue: Expression, location?: TextRange) {
return createStatement(
createAssignment(
getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true),
exportValue
return setTextRange(
createStatement(
createAssignment(
getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true),
exportValue
)
),
location
);
}
function createNamespaceExportExpression(exportName: Identifier, exportValue: Expression, location?: TextRange) {
return createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue, location);
return setTextRange(createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue), location);
}
function getNamespaceMemberNameWithSourceMapsAndWithoutComments(name: Identifier) {
@@ -3092,7 +3119,7 @@ namespace ts {
function getClassAliasIfNeeded(node: ClassDeclaration) {
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) {
enableSubstitutionForClassAliases();
const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? node.name.text : "default");
const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? unescapeIdentifier(node.name.text) : "default");
classAliases[getOriginalNodeId(node)] = classAlias;
hoistVariableDeclaration(classAlias);
return classAlias;
@@ -3154,11 +3181,11 @@ namespace ts {
/**
* Hook for node emit.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @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 {
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
const savedApplicableSubstitutions = applicableSubstitutions;
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && isTransformedModuleDeclaration(node)) {
@@ -3169,7 +3196,7 @@ namespace ts {
applicableSubstitutions |= TypeScriptSubstitutionFlags.NonQualifiedEnumMembers;
}
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
applicableSubstitutions = savedApplicableSubstitutions;
}
@@ -3177,12 +3204,12 @@ namespace ts {
/**
* Hooks node substitutions.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
if (emitContext === EmitContext.Expression) {
function onSubstituteNode(hint: EmitHint, node: Node) {
node = previousOnSubstituteNode(hint, node);
if (hint === EmitHint.Expression) {
return substituteExpression(<Expression>node);
}
else if (isShorthandPropertyAssignment(node)) {
@@ -3201,9 +3228,9 @@ namespace ts {
// destructuring assignment
if (node.objectAssignmentInitializer) {
const initializer = createAssignment(exportedName, node.objectAssignmentInitializer);
return createPropertyAssignment(name, initializer, /*location*/ node);
return setTextRange(createPropertyAssignment(name, initializer), node);
}
return createPropertyAssignment(name, exportedName, /*location*/ node);
return setTextRange(createPropertyAssignment(name, exportedName), node);
}
}
return node;
@@ -3263,7 +3290,10 @@ namespace ts {
(applicableSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && container.kind === SyntaxKind.ModuleDeclaration) ||
(applicableSubstitutions & TypeScriptSubstitutionFlags.NonQualifiedEnumMembers && container.kind === SyntaxKind.EnumDeclaration);
if (substitute) {
return createPropertyAccess(getGeneratedNameForNode(container), node, /*location*/ node);
return setTextRange(
createPropertyAccess(getGeneratedNameForNode(container), node),
/*location*/ node
);
}
}
}
@@ -3322,13 +3352,15 @@ namespace ts {
function createParamHelper(context: TransformationContext, expression: Expression, parameterOffset: number, location?: TextRange) {
context.requestEmitHelper(paramHelper);
return createCall(
getHelperName("__param"),
/*typeArguments*/ undefined,
[
createLiteral(parameterOffset),
expression
],
return setTextRange(
createCall(
getHelperName("__param"),
/*typeArguments*/ undefined,
[
createLiteral(parameterOffset),
expression
]
),
location
);
}
@@ -3371,7 +3403,7 @@ namespace ts {
function createDecorateHelper(context: TransformationContext, decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression, location?: TextRange) {
context.requestEmitHelper(decorateHelper);
const argumentsArray: Expression[] = [];
argumentsArray.push(createArrayLiteral(decoratorExpressions, /*location*/ undefined, /*multiLine*/ true));
argumentsArray.push(createArrayLiteral(decoratorExpressions, /*multiLine*/ true));
argumentsArray.push(target);
if (memberName) {
argumentsArray.push(memberName);
@@ -3380,6 +3412,13 @@ namespace ts {
}
}
return createCall(getHelperName("__decorate"), /*typeArguments*/ undefined, argumentsArray, location);
return setTextRange(
createCall(
getHelperName("__decorate"),
/*typeArguments*/ undefined,
argumentsArray
),
location
);
}
}
+130 -18
View File
@@ -348,6 +348,7 @@
EnumMember,
// Top-level nodes
SourceFile,
Bundle,
// JSDoc nodes
JSDocTypeExpression,
@@ -957,8 +958,7 @@
}
// Represents an expression that is elided as part of a transformation to emit comments on a
// not-emitted node. The 'expression' property of a NotEmittedExpression should be emitted.
// @internal
// not-emitted node. The 'expression' property of a PartiallyEmittedExpression should be emitted.
export interface PartiallyEmittedExpression extends LeftHandSideExpression {
kind: SyntaxKind.PartiallyEmittedExpression;
expression: Expression;
@@ -1537,7 +1537,6 @@
// Represents a statement that is elided as part of a transformation to emit comments on a
// not-emitted node.
// @internal
export interface NotEmittedStatement extends Statement {
kind: SyntaxKind.NotEmittedStatement;
}
@@ -1772,24 +1771,28 @@
members: NodeArray<EnumMember>;
}
export type ModuleBody = ModuleBlock | ModuleDeclaration;
export type ModuleName = Identifier | StringLiteral;
export type ModuleBody = NamespaceBody | JSDocNamespaceBody;
export interface ModuleDeclaration extends DeclarationStatement {
kind: SyntaxKind.ModuleDeclaration;
name: Identifier | StringLiteral;
body?: ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | Identifier;
body?: ModuleBody | JSDocNamespaceDeclaration | Identifier;
}
export type NamespaceBody = ModuleBlock | NamespaceDeclaration;
export interface NamespaceDeclaration extends ModuleDeclaration {
name: Identifier;
body: ModuleBlock | NamespaceDeclaration;
body: NamespaceBody;
}
export type JSDocNamespaceBody = Identifier | JSDocNamespaceDeclaration;
export interface JSDocNamespaceDeclaration extends ModuleDeclaration {
name: Identifier;
body: JSDocNamespaceDeclaration | Identifier;
body: JSDocNamespaceBody;
}
export interface ModuleBlock extends Node, Statement {
@@ -2201,6 +2204,11 @@
/* @internal */ ambientModuleNames: string[];
}
export interface Bundle extends Node {
kind: SyntaxKind.Bundle;
sourceFiles: SourceFile[];
}
export interface ScriptReferenceHost {
getCompilerOptions(): CompilerOptions;
getSourceFile(fileName: string): SourceFile;
@@ -3726,7 +3734,6 @@
helpers?: EmitHelper[]; // Emit helpers for the node
}
/* @internal */
export const enum EmitFlags {
SingleLine = 1 << 0, // The contents of this node should be emitted on a single line.
AdviseOnEmitNode = 1 << 1, // The printer should invoke the onEmitNode callback when printing this node.
@@ -3755,7 +3762,6 @@
HasEndOfDeclarationMarker = 1 << 21, // Declaration has an associated NotEmittedStatement to mark the end of the declaration
}
/* @internal */
export interface EmitHelper {
readonly name: string; // A unique name for this helper.
readonly scoped: boolean; // Indicates whether ther helper MUST be emitted in the current scope.
@@ -3782,8 +3788,7 @@
LastEmitHelper = Generator
}
/* @internal */
export const enum EmitContext {
export const enum EmitHint {
SourceFile, // Emitting a SourceFile
Expression, // Emitting an Expression
IdentifierName, // Emitting an IdentifierName
@@ -3858,7 +3863,7 @@
* Hook used by transformers to substitute expressions just before they
* are emitted by the pretty printer.
*/
onSubstituteNode?: (emitContext: EmitContext, node: Node) => Node;
onSubstituteNode?: (hint: EmitHint, node: Node) => Node;
/**
* Enables before/after emit notifications in the pretty printer for the provided
@@ -3876,7 +3881,7 @@
* Hook used to allow transformers to capture state before or after
* the printer emits a node.
*/
onEmitNode?: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void;
onEmitNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
}
/* @internal */
@@ -3889,25 +3894,132 @@
/**
* Emits the substitute for a node, if one is available; otherwise, emits the node.
*
* @param emitContext The current emit context.
* @param hint A hint as to the intended usage of the node.
* @param node The node to substitute.
* @param emitCallback A callback used to emit the node or its substitute.
*/
emitNodeWithSubstitution(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
/**
* Emits a node with possible notification.
*
* @param emitContext The current emit context.
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emitCallback A callback used to emit the node.
*/
emitNodeWithNotification(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
}
/* @internal */
export type Transformer = (context: TransformationContext) => (node: SourceFile) => SourceFile;
export interface Printer {
/**
* Print a node and its subtree as-is, without any emit transformations.
* @param hint A value indicating the purpose of a node. This is primarily used to
* distinguish between an `Identifier` used in an expression position, versus an
* `Identifier` used as an `IdentifierName` as part of a declaration. For most nodes you
* should just pass `Unspecified`.
* @param node The node to print. The node and its subtree are printed as-is, without any
* emit transformations.
* @param sourceFile A source file that provides context for the node. The source text of
* the file is used to emit the original source content for literals and identifiers, while
* the identifiers of the source file are used when generating unique names to avoid
* collisions.
*/
printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string;
/**
* Prints a source file as-is, without any emit transformations.
*/
printFile(sourceFile: SourceFile): string;
/**
* Prints a bundle of source files as-is, without any emit transformations.
*/
printBundle(bundle: Bundle): string;
/*@internal*/ writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile, writer: EmitTextWriter): void;
/*@internal*/ writeFile(sourceFile: SourceFile, writer: EmitTextWriter): void;
/*@internal*/ writeBundle(bundle: Bundle, writer: EmitTextWriter): void;
}
export interface PrintHandlers {
/**
* A hook used by the Printer when generating unique names to avoid collisions with
* globally defined names that exist outside of the current source file.
*/
hasGlobalName?(name: string): boolean;
/**
* A hook used by the Printer to provide notifications prior to emitting a node. A
* compatible implementation **must** invoke `emitCallback` with the provided `hint` and
* `node` values.
* @param hint A hint indicating the intended purpose of the node.
* @param node The node to emit.
* @param emitCallback A callback that, when invoked, will emit the node.
* @example
* ```ts
* var printer = createPrinter(printerOptions, {
* onEmitNode(hint, node, emitCallback) {
* // set up or track state prior to emitting the node...
* emitCallback(hint, node);
* // restore state after emitting the node...
* }
* });
* ```
*/
onEmitNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
/**
* A hook used by the Printer to perform just-in-time substitution of a node. This is
* primarily used by node transformations that need to substitute one node for another,
* such as replacing `myExportedVar` with `exports.myExportedVar`. A compatible
* implementation **must** invoke `emitCallback` eith the provided `hint` and either
* the provided `node`, or its substitute.
* @param hint A hint indicating the intended purpose of the node.
* @param node The node to emit.
* @param emitCallback A callback that, when invoked, will emit the node.
* @example
* ```ts
* var printer = createPrinter(printerOptions, {
* onSubstituteNode(hint, node, emitCallback) {
* // perform substitution if necessary...
* emitCallback(hint, node);
* }
* });
* ```
*/
onSubstituteNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
/*@internal*/ onEmitSourceMapOfNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
/*@internal*/ onEmitSourceMapOfToken?: (node: Node, token: SyntaxKind, pos: number, emitCallback: (token: SyntaxKind, pos: number) => number) => number;
/*@internal*/ onEmitSourceMapOfPosition?: (pos: number) => void;
/*@internal*/ onEmitHelpers?: (node: Node, writeLines: (text: string) => void) => void;
/*@internal*/ onSetSourceFile?: (node: SourceFile) => void;
}
export interface PrinterOptions {
target?: ScriptTarget;
removeComments?: boolean;
newLine?: NewLineKind;
/*@internal*/ sourceMap?: boolean;
/*@internal*/ inlineSourceMap?: boolean;
/*@internal*/ extendedDiagnostics?: boolean;
}
/*@internal*/
export interface EmitTextWriter {
write(s: string): void;
writeTextOfNode(text: string, node: Node): void;
writeLine(): void;
increaseIndent(): void;
decreaseIndent(): void;
getText(): string;
rawWrite(s: string): void;
writeLiteral(s: string): void;
getTextPos(): number;
getLine(): number;
getColumn(): number;
getIndent(): number;
isAtStartOfLine(): boolean;
reset(): void;
}
export interface TextSpan {
start: number;
length: number;
+83 -76
View File
@@ -2047,67 +2047,19 @@ namespace ts {
|| positionIsSynthesized(node.end);
}
export function getOriginalNode(node: Node): Node;
export function getOriginalNode<T extends Node>(node: Node, nodeTest: (node: Node) => node is T): T;
export function getOriginalNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
if (node) {
while (node.original !== undefined) {
node = node.original;
}
export function getOriginalSourceFileOrBundle(sourceFileOrBundle: SourceFile | Bundle) {
if (sourceFileOrBundle.kind === SyntaxKind.Bundle) {
return updateBundle(sourceFileOrBundle, sameMap(sourceFileOrBundle.sourceFiles, getOriginalSourceFile));
}
return !nodeTest || nodeTest(node) ? node : undefined;
return getOriginalSourceFile(sourceFileOrBundle);
}
/**
* Gets a value indicating whether a node originated in the parse tree.
*
* @param node The node to test.
*/
export function isParseTreeNode(node: Node): boolean {
return (node.flags & NodeFlags.Synthesized) === 0;
}
/**
* Gets the original parse tree node for a node.
*
* @param node The original node.
* @returns The original parse tree node if found; otherwise, undefined.
*/
export function getParseTreeNode(node: Node): Node;
/**
* Gets the original parse tree node for a node.
*
* @param node The original node.
* @param nodeTest A callback used to ensure the correct type of parse tree node is returned.
* @returns The original parse tree node if found; otherwise, undefined.
*/
export function getParseTreeNode<T extends Node>(node: Node, nodeTest?: (node: Node) => node is T): T;
export function getParseTreeNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
if (isParseTreeNode(node)) {
return node;
}
node = getOriginalNode(node);
if (isParseTreeNode(node) && (!nodeTest || nodeTest(node))) {
return node;
}
return undefined;
function getOriginalSourceFile(sourceFile: SourceFile) {
return getParseTreeNode(sourceFile, isSourceFile) || sourceFile;
}
export function getOriginalSourceFiles(sourceFiles: SourceFile[]) {
const originalSourceFiles: SourceFile[] = [];
for (const sourceFile of sourceFiles) {
const originalSourceFile = getParseTreeNode(sourceFile, isSourceFile);
if (originalSourceFile) {
originalSourceFiles.push(originalSourceFile);
}
}
return originalSourceFiles;
return sameMap(sourceFiles, getOriginalSourceFile);
}
export function getOriginalNodeId(node: Node) {
@@ -2446,23 +2398,6 @@ namespace ts {
s;
}
export interface EmitTextWriter {
write(s: string): void;
writeTextOfNode(text: string, node: Node): void;
writeLine(): void;
increaseIndent(): void;
decreaseIndent(): void;
getText(): string;
rawWrite(s: string): void;
writeLiteral(s: string): void;
getTextPos(): number;
getLine(): number;
getColumn(): number;
getIndent(): number;
isAtStartOfLine(): boolean;
reset(): void;
}
const indentStrings: string[] = ["", " "];
export function getIndentString(level: number) {
if (indentStrings[level] === undefined) {
@@ -2645,7 +2580,7 @@ namespace ts {
* Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit.
*/
export function forEachEmittedFile(
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean) => void,
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => void,
sourceFilesOrTargetSourceFile?: SourceFile[] | SourceFile,
emitOnlyDtsFiles?: boolean) {
@@ -2656,7 +2591,7 @@ namespace ts {
const jsFilePath = options.outFile || options.out;
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined;
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFiles, /*isBundledEmit*/true, emitOnlyDtsFiles);
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles);
}
}
else {
@@ -2664,7 +2599,7 @@ namespace ts {
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options));
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, [sourceFile], /*isBundledEmit*/false, emitOnlyDtsFiles);
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFile, emitOnlyDtsFiles);
}
}
}
@@ -3239,7 +3174,7 @@ namespace ts {
const carriageReturnLineFeed = "\r\n";
const lineFeed = "\n";
export function getNewLineCharacter(options: CompilerOptions): string {
export function getNewLineCharacter(options: CompilerOptions | PrinterOptions): string {
if (options.newLine === NewLineKind.CarriageReturnLineFeed) {
return carriageReturnLineFeed;
}
@@ -3350,6 +3285,14 @@ namespace ts {
}
}
export function getRangePos(range: TextRange | undefined) {
return range ? range.pos : -1;
}
export function getRangeEnd(range: TextRange | undefined) {
return range ? range.end : -1;
}
/**
* Increases (or decreases) a position by the provided amount.
*
@@ -3949,6 +3892,19 @@ namespace ts {
export function isModuleBody(node: Node): node is ModuleBody {
const kind = node.kind;
return kind === SyntaxKind.ModuleBlock
|| kind === SyntaxKind.ModuleDeclaration
|| kind === SyntaxKind.Identifier;
}
export function isNamespaceBody(node: Node): node is NamespaceBody {
const kind = node.kind;
return kind === SyntaxKind.ModuleBlock
|| kind === SyntaxKind.ModuleDeclaration;
}
export function isJSDocNamespaceBody(node: Node): node is JSDocNamespaceBody {
const kind = node.kind;
return kind === SyntaxKind.Identifier
|| kind === SyntaxKind.ModuleDeclaration;
}
@@ -4541,4 +4497,55 @@ namespace ts {
return true;
}
}
export function getOriginalNode(node: Node): Node;
export function getOriginalNode<T extends Node>(node: Node, nodeTest: (node: Node) => node is T): T;
export function getOriginalNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
if (node) {
while (node.original !== undefined) {
node = node.original;
}
}
return !nodeTest || nodeTest(node) ? node : undefined;
}
/**
* Gets a value indicating whether a node originated in the parse tree.
*
* @param node The node to test.
*/
export function isParseTreeNode(node: Node): boolean {
return (node.flags & NodeFlags.Synthesized) === 0;
}
/**
* Gets the original parse tree node for a node.
*
* @param node The original node.
* @returns The original parse tree node if found; otherwise, undefined.
*/
export function getParseTreeNode(node: Node): Node;
/**
* Gets the original parse tree node for a node.
*
* @param node The original node.
* @param nodeTest A callback used to ensure the correct type of parse tree node is returned.
* @returns The original parse tree node if found; otherwise, undefined.
*/
export function getParseTreeNode<T extends Node>(node: Node, nodeTest?: (node: Node) => node is T): T;
export function getParseTreeNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
if (isParseTreeNode(node)) {
return node;
}
node = getOriginalNode(node);
if (isParseTreeNode(node) && (!nodeTest || nodeTest(node))) {
return node;
}
return undefined;
}
}
+147 -166
View File
@@ -6,97 +6,6 @@
namespace ts {
export type VisitResult<T extends Node> = T | T[];
/**
* Describes an edge of a Node, used when traversing a syntax tree.
*/
interface NodeEdge {
/** The property name for the edge. */
name: string;
/** Indicates that the result is optional. */
optional?: boolean;
/** A callback used to test whether a node is valid. */
test?: (node: Node) => node is Node;
/** A callback used to lift a NodeArrayNode into a valid node. */
lift?: (nodes: NodeArray<Node>) => Node;
/** A callback used to parenthesize a node to preserve the intended order of operations. */
parenthesize?: (value: Node, parentNode: Node) => Node;
};
/**
* Describes the shape of a Node.
*/
type NodeTraversalPath = NodeEdge[];
/**
* This map contains information about the shape of each Node in "types.ts" pertaining to how
* each node should be traversed during a transformation.
*
* Each edge corresponds to a property in a Node subtype that should be traversed when visiting
* each child. The properties are assigned in the order in which traversal should occur.
*
* We only add entries for nodes that do not have a create/update pair defined in factory.ts
*
* NOTE: This needs to be kept up to date with changes to nodes in "types.ts". Currently, this
* map is not comprehensive. Only node edges relevant to tree transformation are
* currently defined. We may extend this to be more comprehensive, and eventually
* supplant the existing `forEachChild` implementation if performance is not
* significantly impacted.
*/
function getNodeEdgeTraversal(kind: SyntaxKind): NodeTraversalPath {
switch (kind) {
case SyntaxKind.QualifiedName: return [
{ name: "left", test: isEntityName },
{ name: "right", test: isIdentifier }
];
case SyntaxKind.Decorator: return [
{ name: "expression", test: isLeftHandSideExpression }
];
case SyntaxKind.TypeAssertionExpression: return [
{ name: "type", test: isTypeNode },
{ name: "expression", test: isUnaryExpression }
];
case SyntaxKind.AsExpression: return [
{ name: "expression", test: isExpression },
{ name: "type", test: isTypeNode }
];
case SyntaxKind.NonNullExpression: return [
{ name: "expression", test: isLeftHandSideExpression }
];
case SyntaxKind.EnumDeclaration: return [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isIdentifier },
{ name: "members", test: isEnumMember }
];
case SyntaxKind.ModuleDeclaration: return [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isModuleName },
{ name: "body", test: isModuleBody }
];
case SyntaxKind.ModuleBlock: return [
{ name: "statements", test: isStatement }
];
case SyntaxKind.ImportEqualsDeclaration: return [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isIdentifier },
{ name: "moduleReference", test: isModuleReference }
];
case SyntaxKind.ExternalModuleReference: return [
{ name: "expression", test: isExpression, optional: true }
];
case SyntaxKind.EnumMember: return [
{ name: "name", test: isPropertyName },
{ name: "initializer", test: isExpression, optional: true, parenthesize: parenthesizeExpressionForList }
];
}
}
function reduceNode<T>(node: Node, f: (memo: T, node: Node) => T, initial: T) {
return node ? f(initial, node) : initial;
}
@@ -107,8 +16,7 @@ namespace ts {
/**
* Similar to `reduceLeft`, performs a reduction against each child of a node.
* NOTE: Unlike `forEachChild`, this does *not* visit every node. Only nodes added to the
* `nodeEdgeTraversalMap` above will be visited.
* NOTE: Unlike `forEachChild`, this does *not* visit every node.
*
* @param node The node containing the children to reduce.
* @param initial The initial value to supply to the reduction.
@@ -145,6 +53,11 @@ namespace ts {
break;
// Names
case SyntaxKind.QualifiedName:
result = reduceNode((<QualifiedName>node).left, cbNode, result);
result = reduceNode((<QualifiedName>node).right, cbNode, result);
break;
case SyntaxKind.ComputedPropertyName:
result = reduceNode((<ComputedPropertyName>node).expression, cbNode, result);
break;
@@ -252,6 +165,11 @@ namespace ts {
result = reduceNode((<TaggedTemplateExpression>node).template, cbNode, result);
break;
case SyntaxKind.TypeAssertionExpression:
result = reduceNode((<TypeAssertion>node).type, cbNode, result);
result = reduceNode((<TypeAssertion>node).expression, cbNode, result);
break;
case SyntaxKind.FunctionExpression:
result = reduceNodes((<FunctionExpression>node).modifiers, cbNodes, result);
result = reduceNode((<FunctionExpression>node).name, cbNode, result);
@@ -314,6 +232,15 @@ namespace ts {
result = reduceNodes((<ExpressionWithTypeArguments>node).typeArguments, cbNodes, result);
break;
case SyntaxKind.AsExpression:
result = reduceNode((<AsExpression>node).expression, cbNode, result);
result = reduceNode((<AsExpression>node).type, cbNode, result);
break;
case SyntaxKind.NonNullExpression:
result = reduceNode((<NonNullExpression>node).expression, cbNode, result);
break;
// Misc
case SyntaxKind.TemplateSpan:
result = reduceNode((<TemplateSpan>node).expression, cbNode, result);
@@ -415,10 +342,35 @@ namespace ts {
result = reduceNodes((<ClassDeclaration>node).members, cbNodes, result);
break;
case SyntaxKind.EnumDeclaration:
result = reduceNodes((<EnumDeclaration>node).decorators, cbNodes, result);
result = reduceNodes((<EnumDeclaration>node).modifiers, cbNodes, result);
result = reduceNode((<EnumDeclaration>node).name, cbNode, result);
result = reduceNodes((<EnumDeclaration>node).members, cbNodes, result);
break;
case SyntaxKind.ModuleDeclaration:
result = reduceNodes((<ModuleDeclaration>node).decorators, cbNodes, result);
result = reduceNodes((<ModuleDeclaration>node).modifiers, cbNodes, result);
result = reduceNode((<ModuleDeclaration>node).name, cbNode, result);
result = reduceNode((<ModuleDeclaration>node).body, cbNode, result);
break;
case SyntaxKind.ModuleBlock:
result = reduceNodes((<ModuleBlock>node).statements, cbNodes, result);
break;
case SyntaxKind.CaseBlock:
result = reduceNodes((<CaseBlock>node).clauses, cbNodes, result);
break;
case SyntaxKind.ImportEqualsDeclaration:
result = reduceNodes((<ImportEqualsDeclaration>node).decorators, cbNodes, result);
result = reduceNodes((<ImportEqualsDeclaration>node).modifiers, cbNodes, result);
result = reduceNode((<ImportEqualsDeclaration>node).name, cbNode, result);
result = reduceNode((<ImportEqualsDeclaration>node).moduleReference, cbNode, result);
break;
case SyntaxKind.ImportDeclaration:
result = reduceNodes((<ImportDeclaration>node).decorators, cbNodes, result);
result = reduceNodes((<ImportDeclaration>node).modifiers, cbNodes, result);
@@ -459,6 +411,11 @@ namespace ts {
result = reduceNode((<ExportDeclaration>node).moduleSpecifier, cbNode, result);
break;
// Module references
case SyntaxKind.ExternalModuleReference:
result = reduceNode((<ExternalModuleReference>node).expression, cbNode, result);
break;
// JSX
case SyntaxKind.JsxElement:
result = reduceNode((<JsxElement>node).openingElement, cbNode, result);
@@ -519,30 +476,25 @@ namespace ts {
break;
case SyntaxKind.SpreadAssignment:
result = reduceNode((node as SpreadAssignment).expression, cbNode, result);
result = reduceNode((<SpreadAssignment>node).expression, cbNode, result);
break;
// Enum
case SyntaxKind.EnumMember:
result = reduceNode((<EnumMember>node).name, cbNode, result);
result = reduceNode((<EnumMember>node).initializer, cbNode, result);
// Top-level nodes
case SyntaxKind.SourceFile:
result = reduceNodes((<SourceFile>node).statements, cbNodes, result);
break;
// Transformation nodes
case SyntaxKind.PartiallyEmittedExpression:
result = reduceNode((<PartiallyEmittedExpression>node).expression, cbNode, result);
break;
default:
const edgeTraversalPath = getNodeEdgeTraversal(kind);
if (edgeTraversalPath) {
for (const edge of edgeTraversalPath) {
const value = (<MapLike<any>>node)[edge.name];
if (value !== undefined) {
result = isArray(value)
? reduceNodes(<NodeArray<Node>>value, cbNodes, result)
: cbNode(result, <Node>value);
}
}
}
break;
}
@@ -556,11 +508,9 @@ namespace ts {
* @param visitor The callback used to visit the Node.
* @param test A callback to execute to verify the Node is valid.
* @param optional An optional value indicating whether the Node is itself optional.
* @param lift An optional callback to execute to lift a NodeArrayNode into a valid Node.
* @param lift An optional callback to execute to lift a NodeArray into a valid Node.
*/
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional?: boolean, lift?: (node: NodeArray<Node>) => T): T;
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional: boolean, lift: (node: NodeArray<Node>) => T, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node): T;
export function visitNode(node: Node, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional?: boolean, lift?: (node: Node[]) => Node, parenthesize?: (node: Node, parentNode: Node) => Node, parentNode?: Node): Node {
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional?: boolean, lift?: (node: NodeArray<Node>) => T): T {
if (node === undefined || visitor === undefined) {
return node;
}
@@ -586,13 +536,9 @@ namespace ts {
visitedNode = visited;
}
if (parenthesize !== undefined) {
visitedNode = parenthesize(visitedNode, parentNode);
}
Debug.assertNode(visitedNode, test);
aggregateTransformFlags(visitedNode);
return visitedNode;
return <T>visitedNode;
}
/**
@@ -604,14 +550,12 @@ namespace ts {
* @param start An optional value indicating the starting offset at which to start visiting.
* @param count An optional value indicating the maximum number of nodes to visit.
*/
export function visitNodes<T extends Node>(nodes: NodeArray<T>, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, start?: number, count?: number): NodeArray<T>;
export function visitNodes<T extends Node>(nodes: NodeArray<T>, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, start: number, count: number, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node): NodeArray<T>;
export function visitNodes(nodes: NodeArray<Node>, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, start?: number, count?: number, parenthesize?: (node: Node, parentNode: Node) => Node, parentNode?: Node): NodeArray<Node> {
export function visitNodes<T extends Node>(nodes: NodeArray<T>, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, start?: number, count?: number): NodeArray<T> {
if (nodes === undefined) {
return undefined;
}
let updated: NodeArray<Node>;
let updated: NodeArray<T>;
// Ensure start and count have valid values
const length = nodes.length;
@@ -627,8 +571,7 @@ namespace ts {
// If we are not visiting all of the original nodes, we must always create a new array.
// Since this is a fragment of a node array, we do not copy over the previous location
// and will only copy over `hasTrailingComma` if we are including the last element.
updated = createNodeArray<Node>([], /*location*/ undefined,
/*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length);
updated = createNodeArray<T>([], /*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length);
}
// Visit each original node.
@@ -639,26 +582,21 @@ namespace ts {
if (updated !== undefined || visited === undefined || visited !== node) {
if (updated === undefined) {
// Ensure we have a copy of `nodes`, up to the current index.
updated = createNodeArray(nodes.slice(0, i), /*location*/ nodes, nodes.hasTrailingComma);
updated = createNodeArray(nodes.slice(0, i), nodes.hasTrailingComma);
setTextRange(updated, nodes);
}
if (visited) {
if (isArray(visited)) {
for (let visitedNode of visited) {
visitedNode = parenthesize
? parenthesize(visitedNode, parentNode)
: visitedNode;
for (const visitedNode of visited) {
Debug.assertNode(visitedNode, test);
aggregateTransformFlags(visitedNode);
updated.push(visitedNode);
updated.push(<T>visitedNode);
}
}
else {
const visitedNode = parenthesize
? parenthesize(visited, parentNode)
: visited;
Debug.assertNode(visitedNode, test);
aggregateTransformFlags(visitedNode);
updated.push(visitedNode);
Debug.assertNode(visited, test);
aggregateTransformFlags(visited);
updated.push(<T>visited);
}
}
}
@@ -675,10 +613,10 @@ namespace ts {
context.startLexicalEnvironment();
statements = visitNodes(statements, visitor, isStatement, start);
if (ensureUseStrict && !startsWithUseStrict(statements)) {
statements = createNodeArray([createStatement(createLiteral("use strict")), ...statements], statements);
statements = setTextRange(createNodeArray([createStatement(createLiteral("use strict")), ...statements]), statements);
}
const declarations = context.endLexicalEnvironment();
return createNodeArray(concatenate(statements, declarations), statements);
return setTextRange(createNodeArray(concatenate(statements, declarations)), statements);
}
/**
@@ -747,6 +685,11 @@ namespace ts {
return node;
// Names
case SyntaxKind.QualifiedName:
return updateQualifiedName(<QualifiedName>node,
visitNode((<QualifiedName>node).left, visitor, isEntityName),
visitNode((<QualifiedName>node).right, visitor, isIdentifier));
case SyntaxKind.ComputedPropertyName:
return updateComputedPropertyName(<ComputedPropertyName>node,
visitNode((<ComputedPropertyName>node).expression, visitor, isExpression));
@@ -761,6 +704,10 @@ namespace ts {
visitNode((<ParameterDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
visitNode((<ParameterDeclaration>node).initializer, visitor, isExpression, /*optional*/ true));
case SyntaxKind.Decorator:
return updateDecorator(<Decorator>node,
visitNode((<Decorator>node).expression, visitor, isExpression));
// Type member
case SyntaxKind.PropertyDeclaration:
return updateProperty(<PropertyDeclaration>node,
@@ -856,6 +803,11 @@ namespace ts {
visitNode((<TaggedTemplateExpression>node).tag, visitor, isExpression),
visitNode((<TaggedTemplateExpression>node).template, visitor, isTemplateLiteral));
case SyntaxKind.TypeAssertionExpression:
return updateTypeAssertion(<TypeAssertion>node,
visitNode((<TypeAssertion>node).type, visitor, isTypeNode),
visitNode((<TypeAssertion>node).expression, visitor, isExpression));
case SyntaxKind.ParenthesizedExpression:
return updateParen(<ParenthesizedExpression>node,
visitNode((<ParenthesizedExpression>node).expression, visitor, isExpression));
@@ -938,6 +890,15 @@ namespace ts {
visitNodes((<ExpressionWithTypeArguments>node).typeArguments, visitor, isTypeNode),
visitNode((<ExpressionWithTypeArguments>node).expression, visitor, isExpression));
case SyntaxKind.AsExpression:
return updateAsExpression(<AsExpression>node,
visitNode((<AsExpression>node).expression, visitor, isExpression),
visitNode((<AsExpression>node).type, visitor, isTypeNode));
case SyntaxKind.NonNullExpression:
return updateNonNullExpression(<NonNullExpression>node,
visitNode((<NonNullExpression>node).expression, visitor, isExpression));
// Misc
case SyntaxKind.TemplateSpan:
return updateTemplateSpan(<TemplateSpan>node,
@@ -1059,10 +1020,35 @@ namespace ts {
visitNodes((<ClassDeclaration>node).heritageClauses, visitor, isHeritageClause),
visitNodes((<ClassDeclaration>node).members, visitor, isClassElement));
case SyntaxKind.EnumDeclaration:
return updateEnumDeclaration(<EnumDeclaration>node,
visitNodes((<EnumDeclaration>node).decorators, visitor, isDecorator),
visitNodes((<EnumDeclaration>node).modifiers, visitor, isModifier),
visitNode((<EnumDeclaration>node).name, visitor, isIdentifier),
visitNodes((<EnumDeclaration>node).members, visitor, isEnumMember));
case SyntaxKind.ModuleDeclaration:
return updateModuleDeclaration(<ModuleDeclaration>node,
visitNodes((<ModuleDeclaration>node).decorators, visitor, isDecorator),
visitNodes((<ModuleDeclaration>node).modifiers, visitor, isModifier),
visitNode((<ModuleDeclaration>node).name, visitor, isIdentifier),
visitNode((<ModuleDeclaration>node).body, visitor, isModuleBody));
case SyntaxKind.ModuleBlock:
return updateModuleBlock(<ModuleBlock>node,
visitNodes((<ModuleBlock>node).statements, visitor, isStatement));
case SyntaxKind.CaseBlock:
return updateCaseBlock(<CaseBlock>node,
visitNodes((<CaseBlock>node).clauses, visitor, isCaseOrDefaultClause));
case SyntaxKind.ImportEqualsDeclaration:
return updateImportEqualsDeclaration(<ImportEqualsDeclaration>node,
visitNodes((<ImportEqualsDeclaration>node).decorators, visitor, isDecorator),
visitNodes((<ImportEqualsDeclaration>node).modifiers, visitor, isModifier),
visitNode((<ImportEqualsDeclaration>node).name, visitor, isIdentifier),
visitNode((<ImportEqualsDeclaration>node).moduleReference, visitor, isModuleReference));
case SyntaxKind.ImportDeclaration:
return updateImportDeclaration(<ImportDeclaration>node,
visitNodes((<ImportDeclaration>node).decorators, visitor, isDecorator),
@@ -1110,6 +1096,11 @@ namespace ts {
visitNode((<ExportSpecifier>node).propertyName, visitor, isIdentifier, /*optional*/ true),
visitNode((<ExportSpecifier>node).name, visitor, isIdentifier));
// Module references
case SyntaxKind.ExternalModuleReference:
return updateExternalModuleReference(<ExternalModuleReference>node,
visitNode((<ExternalModuleReference>node).expression, visitor, isExpression));
// JSX
case SyntaxKind.JsxElement:
return updateJsxElement(<JsxElement>node,
@@ -1175,10 +1166,16 @@ namespace ts {
visitNode((<ShorthandPropertyAssignment>node).objectAssignmentInitializer, visitor, isExpression));
case SyntaxKind.SpreadAssignment:
return updateSpreadAssignment(node as SpreadAssignment,
visitNode((node as SpreadAssignment).expression, visitor, isExpression));
return updateSpreadAssignment(<SpreadAssignment>node,
visitNode((<SpreadAssignment>node).expression, visitor, isExpression));
// Top-level nodes
// Enum
case SyntaxKind.EnumMember:
return updateEnumMember(<EnumMember>node,
visitNode((<EnumMember>node).name, visitor, isPropertyName),
visitNode((<EnumMember>node).initializer, visitor, isExpression, /*optional*/ true));
// Top-level nodes
case SyntaxKind.SourceFile:
return updateSourceFileNode(<SourceFile>node,
visitLexicalEnvironment((<SourceFile>node).statements, visitor, context));
@@ -1189,30 +1186,8 @@ namespace ts {
visitNode((<PartiallyEmittedExpression>node).expression, visitor, isExpression));
default:
let updated: Node & MapLike<any>;
const edgeTraversalPath = getNodeEdgeTraversal(kind);
if (edgeTraversalPath) {
for (const edge of edgeTraversalPath) {
const value = <Node | NodeArray<Node>>(<Node & MapLike<any>>node)[edge.name];
if (value !== undefined) {
const visited = isArray(value)
? visitNodes(value, visitor, edge.test, 0, value.length, edge.parenthesize, node)
: visitNode(value, visitor, edge.test, edge.optional, edge.lift, edge.parenthesize, node);
if (updated !== undefined || visited !== value) {
if (updated === undefined) {
updated = getMutableClone(node);
}
if (visited !== value) {
updated[edge.name] = visited;
}
}
}
}
}
return updated ? updateNode(updated, node) : node;
return node;
}
// return node;
}
/**
@@ -1228,7 +1203,7 @@ namespace ts {
return statements;
}
return isNodeArray(statements)
? createNodeArray(concatenate(statements, declarations), statements)
? setTextRange(createNodeArray(concatenate(statements, declarations)), statements)
: addRange(statements, declarations);
}
@@ -1252,13 +1227,19 @@ namespace ts {
export function mergeFunctionBodyLexicalEnvironment(body: ConciseBody, declarations: Statement[]): ConciseBody {
if (body && declarations !== undefined && declarations.length > 0) {
if (isBlock(body)) {
return updateBlock(body, createNodeArray(concatenate(body.statements, declarations), body.statements));
return updateBlock(body, setTextRange(createNodeArray(concatenate(body.statements, declarations)), body.statements));
}
else {
return createBlock(
createNodeArray([createReturn(body, /*location*/ body), ...declarations], body),
/*location*/ body,
/*multiLine*/ true);
return setTextRange(
createBlock(
setTextRange(
createNodeArray([setTextRange(createReturn(body), body), ...declarations]),
body
),
/*multiLine*/ true
),
/*location*/ body
);
}
}
return body;
+93 -30
View File
@@ -183,7 +183,7 @@ namespace FourSlash {
// The current caret position in the active file
public currentCaretPosition = 0;
public lastKnownMarker: string = "";
public lastKnownMarker = "";
// The file that's currently 'opened'
public activeFile: FourSlashFile;
@@ -452,7 +452,8 @@ namespace FourSlash {
}
private messageAtLastKnownMarker(message: string) {
return "Marker: " + this.lastKnownMarker + "\n" + message;
const locationDescription = this.lastKnownMarker ? this.lastKnownMarker : this.getLineColStringAtPosition(this.currentCaretPosition);
return `At ${locationDescription}: ${message}`;
}
private assertionMessageAtLastKnownMarker(msg: string) {
@@ -562,7 +563,7 @@ namespace FourSlash {
}
public verifyGoToDefinitionIs(endMarker: string | string[]) {
this.verifyGoToXWorker(endMarker instanceof Array ? endMarker : [endMarker], () => this.getGoToDefinition());
this.verifyGoToXWorker(toArray(endMarker), () => this.getGoToDefinition());
}
public verifyGoToDefinition(arg0: any, endMarkerNames?: string | string[]) {
@@ -582,7 +583,7 @@ namespace FourSlash {
if (endMarkerNames) {
this.verifyGoToXPlain(arg0, endMarkerNames, getDefs);
}
else if (arg0 instanceof Array) {
else if (ts.isArray(arg0)) {
const pairs: [string | string[], string | string[]][] = arg0;
for (const [start, end] of pairs) {
this.verifyGoToXPlain(start, end, getDefs);
@@ -599,13 +600,8 @@ namespace FourSlash {
}
private verifyGoToXPlain(startMarkerNames: string | string[], endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
if (startMarkerNames instanceof Array) {
for (const start of startMarkerNames) {
this.verifyGoToXSingle(start, endMarkerNames, getDefs);
}
}
else {
this.verifyGoToXSingle(startMarkerNames, endMarkerNames, getDefs);
for (const start of toArray(startMarkerNames)) {
this.verifyGoToXSingle(start, endMarkerNames, getDefs);
}
}
@@ -617,7 +613,7 @@ namespace FourSlash {
private verifyGoToXSingle(startMarkerName: string, endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
this.goToMarker(startMarkerName);
this.verifyGoToXWorker(endMarkerNames instanceof Array ? endMarkerNames : [endMarkerNames], getDefs);
this.verifyGoToXWorker(toArray(endMarkerNames), getDefs);
}
private verifyGoToXWorker(endMarkers: string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
@@ -899,8 +895,74 @@ namespace FourSlash {
}
}
public verifyRangesWithSameTextReferenceEachOther() {
this.rangesByText().forEach(ranges => this.verifyRangesReferenceEachOther(ranges));
public verifyReferenceGroups(startRanges: Range | Range[], parts: Array<{ definition: string, ranges: Range[] }>): void {
interface ReferenceJson { definition: string; ranges: ts.ReferenceEntry[]; }
type ReferencesJson = ReferenceJson[];
const fullExpected = parts.map<ReferenceJson>(({ definition, ranges }) => ({ definition, ranges: ranges.map(rangeToReferenceEntry) }));
for (const startRange of toArray(startRanges)) {
this.goToRangeStart(startRange);
const fullActual = this.findReferencesAtCaret().map<ReferenceJson>(({ definition, references }) => ({
definition: definition.displayParts.map(d => d.text).join(""),
ranges: references
}));
this.assertObjectsEqual<ReferencesJson>(fullActual, fullExpected);
}
function rangeToReferenceEntry(r: Range) {
let { isWriteAccess, isDefinition } = (r.marker && r.marker.data) || { isWriteAccess: false, isDefinition: false };
isWriteAccess = !!isWriteAccess; isDefinition = !!isDefinition;
return { fileName: r.fileName, textSpan: { start: r.start, length: r.end - r.start }, isWriteAccess, isDefinition }
}
}
public verifyNoReferences(markerNameOrRange?: string | Range) {
if (markerNameOrRange) {
if (typeof markerNameOrRange === "string") {
this.goToMarker(markerNameOrRange);
}
else {
this.goToRangeStart(markerNameOrRange);
}
}
const refs = this.getReferencesAtCaret();
if (refs && refs.length) {
console.log(refs);
this.raiseError("Expected getReferences to fail");
}
}
public verifySingleReferenceGroup(definition: string, ranges?: Range[]) {
ranges = ranges || this.getRanges();
this.verifyReferenceGroups(ranges, [{ definition, ranges }]);
}
private assertObjectsEqual<T>(fullActual: T, fullExpected: T, msgPrefix = ""): void {
const recur = <U>(actual: U, expected: U, path: string) => {
const fail = (msg: string) => {
console.log("Expected:", stringify(fullExpected));
console.log("Actual: ", stringify(fullActual));
this.raiseError(`${msgPrefix}At ${path}: ${msg}`);
};
for (const key in actual) if (ts.hasProperty(actual as any, key)) {
const ak = actual[key], ek = expected[key];
if (typeof ak === "object" && typeof ek === "object") {
recur(ak, ek, path ? path + "." + key : key);
}
else if (ak !== ek) {
fail(`Expected '${key}' to be '${ek}', got '${ak}'`);
}
}
for (const key in expected) if (ts.hasProperty(expected as any, key)) {
if (!ts.hasProperty(actual as any, key)) {
fail(`${msgPrefix}Missing property '${key}'`);
}
}
};
recur(fullActual, fullExpected, "");
}
public verifyDisplayPartsOfReferencedSymbol(expected: ts.SymbolDisplayPart[]) {
@@ -974,7 +1036,7 @@ namespace FourSlash {
public verifyQuickInfos(namesAndTexts: { [name: string]: string | [string, string] }) {
for (const name in namesAndTexts) if (ts.hasProperty(namesAndTexts, name)) {
const text = namesAndTexts[name];
if (text instanceof Array) {
if (ts.isArray(text)) {
assert(text.length === 2);
const [expectedText, expectedDocumentation] = text;
this.verifyQuickInfoAt(name, expectedText, expectedDocumentation);
@@ -1411,13 +1473,6 @@ namespace FourSlash {
Harness.IO.log(membersString);
}
public printReferences() {
const references = this.getReferencesAtCaret();
ts.forEach(references, entry => {
Harness.IO.log(stringify(entry));
});
}
public printContext() {
ts.forEach(this.languageServiceAdapterHost.getFilenames(), Harness.IO.log);
}
@@ -3082,6 +3137,10 @@ ${code}
}
return ts.arrayFrom(set.keys());
}
function toArray<T>(x: T | T[]): T[] {
return ts.isArray(x) ? x : [x];
}
}
namespace FourSlashInterface {
@@ -3346,6 +3405,18 @@ namespace FourSlashInterface {
this.state.verifyReferencesOf(start, references);
}
public referenceGroups(startRanges: FourSlash.Range[], parts: Array<{ definition: string, ranges: FourSlash.Range[] }>) {
this.state.verifyReferenceGroups(startRanges, parts);
}
public noReferences(markerNameOrRange?: string | FourSlash.Range) {
this.state.verifyNoReferences(markerNameOrRange);
}
public singleReferenceGroup(definition: string, ranges?: FourSlash.Range[]) {
this.state.verifySingleReferenceGroup(definition, ranges);
}
public rangesReferenceEachOther(ranges?: FourSlash.Range[]) {
this.state.verifyRangesReferenceEachOther(ranges);
}
@@ -3354,10 +3425,6 @@ namespace FourSlashInterface {
this.state.verifyDisplayPartsOfReferencedSymbol(expected);
}
public rangesWithSameTextReferenceEachOther() {
this.state.verifyRangesWithSameTextReferenceEachOther();
}
public currentParameterHelpArgumentNameIs(name: string) {
this.state.verifyCurrentParameterHelpName(name);
}
@@ -3660,10 +3727,6 @@ namespace FourSlashInterface {
this.state.printNavigationBar();
}
public printReferences() {
this.state.printReferences();
}
public printContext() {
this.state.printContext();
}
+2 -2
View File
@@ -5,7 +5,7 @@
namespace Harness.LanguageService {
export class ScriptInfo {
public version: number = 1;
public version = 1;
public editRanges: { length: number; textChangeRange: ts.TextChangeRange; }[] = [];
private lineMap: number[] = undefined;
@@ -594,7 +594,7 @@ namespace Harness.LanguageService {
class SessionServerHost implements ts.server.ServerHost, ts.server.Logger {
args: string[] = [];
newLine: string;
useCaseSensitiveFileNames: boolean = false;
useCaseSensitiveFileNames = false;
constructor(private host: NativeLanguageServiceHost) {
this.newLine = this.host.getNewLine();
+2 -1
View File
@@ -118,6 +118,7 @@
"./unittests/initializeTSConfig.ts",
"./unittests/compileOnSave.ts",
"./unittests/typingsInstaller.ts",
"./unittests/projectErrors.ts"
"./unittests/projectErrors.ts",
"./unittests/printer.ts"
]
}
+97
View File
@@ -0,0 +1,97 @@
/// <reference path="..\..\compiler\emitter.ts" />
/// <reference path="..\harness.ts" />
namespace ts {
describe("PrinterAPI", () => {
function makePrintsCorrectly(prefix: string) {
return function printsCorrectly(name: string, options: PrinterOptions, printCallback: (printer: Printer) => string) {
it(name, () => {
Harness.Baseline.runBaseline(`printerApi/${prefix}.${name}.js`, () =>
printCallback(createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed, ...options })));
});
}
}
describe("printFile", () => {
const printsCorrectly = makePrintsCorrectly("printsFileCorrectly");
const sourceFile = createSourceFile("source.ts", `
interface A<T> {
// comment1
readonly prop?: T;
// comment2
method(): void;
// comment3
new <T>(): A<T>;
// comment4
<T>(): A<T>;
}
// comment5
type B = number | string | object;
type C = A<number> & { x: string; }; // comment6
// comment7
enum E1 {
// comment8
first
}
const enum E2 {
second
}
// comment9
console.log(1 + 2);
`, ScriptTarget.ES2015);
printsCorrectly("default", {}, printer => printer.printFile(sourceFile));
printsCorrectly("removeComments", { removeComments: true }, printer => printer.printFile(sourceFile));
});
describe("printBundle", () => {
const printsCorrectly = makePrintsCorrectly("printsBundleCorrectly");
const bundle = createBundle([
createSourceFile("a.ts", `
/*! [a.ts] */
// comment0
const a = 1;
`, ScriptTarget.ES2015),
createSourceFile("b.ts", `
/*! [b.ts] */
// comment1
const b = 2;
`, ScriptTarget.ES2015)
]);
printsCorrectly("default", {}, printer => printer.printBundle(bundle));
printsCorrectly("removeComments", { removeComments: true }, printer => printer.printBundle(bundle));
});
describe("printNode", () => {
const printsCorrectly = makePrintsCorrectly("printsNodeCorrectly");
const sourceFile = createSourceFile("source.ts", "", ScriptTarget.ES2015);
const syntheticNode = createClassDeclaration(
undefined,
undefined,
/*name*/ createIdentifier("C"),
undefined,
undefined,
createNodeArray([
createProperty(
undefined,
createNodeArray([createToken(SyntaxKind.PublicKeyword)]),
createIdentifier("prop"),
undefined,
undefined,
undefined
)
])
);
printsCorrectly("class", {}, printer => printer.printNode(EmitHint.Unspecified, syntheticNode, sourceFile));
});
});
}
+49 -1
View File
@@ -3031,6 +3031,54 @@ namespace ts.projectSystem {
});
});
describe("emit with outFile or out setting", () => {
function test(opts: CompilerOptions, expectedUsesOutFile: boolean) {
const f1 = {
path: "/a/a.ts",
content: "let x = 1"
};
const f2 = {
path: "/a/b.ts",
content: "let y = 1"
};
const config = {
path: "/a/tsconfig.json",
content: JSON.stringify({
compilerOptions: opts,
compileOnSave: true
})
};
const host = createServerHost([f1, f2, config]);
const session = createSession(host);
session.executeCommand(<protocol.OpenRequest>{
seq: 1,
type: "request",
command: "open",
arguments: { file: f1.path }
});
checkNumberOfProjects(session.getProjectService(), { configuredProjects: 1 });
const { response } = session.executeCommand(<protocol.CompileOnSaveAffectedFileListRequest>{
seq: 2,
type: "request",
command: "compileOnSaveAffectedFileList",
arguments: { file: f1.path }
});
assert.equal((<protocol.CompileOnSaveAffectedFileListSingleProject[]>response).length, 1, "expected output for 1 project");
assert.equal((<protocol.CompileOnSaveAffectedFileListSingleProject[]>response)[0].fileNames.length, 2, "expected output for 1 project");
assert.equal((<protocol.CompileOnSaveAffectedFileListSingleProject[]>response)[0].projectUsesOutFile, expectedUsesOutFile, "usesOutFile");
}
it ("projectUsesOutFile should not be returned if not set", () => {
test({}, /*expectedUsesOutFile*/ false);
});
it ("projectUsesOutFile should be true if outFile is set", () => {
test({ outFile: "/a/out.js" }, /*expectedUsesOutFile*/ true);
});
it ("projectUsesOutFile should be true if out is set", () => {
test({ out: "/a/out.js" }, /*expectedUsesOutFile*/ true);
});
});
describe("import helpers", () => {
it("should not crash in tsserver", () => {
const f1 = {
@@ -3067,7 +3115,7 @@ namespace ts.projectSystem {
let options = project.getCompilerOptions();
assert.isTrue(options.maxNodeModuleJsDepth === 2);
// Assert the option sticks
// Assert the option sticks
projectService.setCompilerOptionsForInferredProjects({ target: ScriptTarget.ES2016 });
project = projectService.inferredProjects[0];
options = project.getCompilerOptions();
+49 -8
View File
@@ -44,6 +44,47 @@ namespace ts.projectSystem {
});
}
import typingsName = server.typingsInstaller.typingsName;
describe("local module", () => {
it("should not be picked up", () => {
const f1 = {
path: "/a/app.js",
content: "const c = require('./config');"
};
const f2 = {
path: "/a/config.js",
content: "export let x = 1"
};
const typesCache = "/cache"
const typesConfig = {
path: typesCache + "/node_modules/@types/config/index.d.ts",
content: "export let y: number;"
};
const config = {
path: "/a/jsconfig.json",
content: JSON.stringify({
compilerOptions: { moduleResolution: "commonjs" },
typeAcquisition: { enable: true }
})
};
const host = createServerHost([f1, f2, config, typesConfig]);
const installer = new (class extends Installer {
constructor() {
super(host, { typesRegistry: createTypesRegistry("config"), globalTypingsCacheLocation: typesCache });
}
installWorker(_requestId: number, _args: string[], _cwd: string, _cb: server.typingsInstaller.RequestCompletedAction) {
assert(false, "should not be called")
}
})();
const service = createProjectService(host, { typingsInstaller: installer });
service.openClientFile(f1.path);
service.checkNumberOfProjects({ configuredProjects: 1 });
checkProjectActualFiles(service.configuredProjects[0], [f1.path, f2.path]);
installer.installAll(0);
});
});
describe("typingsInstaller", () => {
it("configured projects (typings installed) 1", () => {
const file1 = {
@@ -519,32 +560,32 @@ namespace ts.projectSystem {
const commander = {
path: "/a/data/node_modules/@types/commander/index.d.ts",
content: "declare const commander: { x: number }",
typings: "@types/commander"
typings: typingsName("commander")
};
const jquery = {
path: "/a/data/node_modules/@types/jquery/index.d.ts",
content: "declare const jquery: { x: number }",
typings: "@types/jquery"
typings: typingsName("jquery")
};
const lodash = {
path: "/a/data/node_modules/@types/lodash/index.d.ts",
content: "declare const lodash: { x: number }",
typings: "@types/lodash"
typings: typingsName("lodash")
};
const cordova = {
path: "/a/data/node_modules/@types/cordova/index.d.ts",
content: "declare const cordova: { x: number }",
typings: "@types/cordova"
typings: typingsName("cordova")
};
const grunt = {
path: "/a/data/node_modules/@types/grunt/index.d.ts",
content: "declare const grunt: { x: number }",
typings: "@types/grunt"
typings: typingsName("grunt")
};
const gulp = {
path: "/a/data/node_modules/@types/gulp/index.d.ts",
content: "declare const gulp: { x: number }",
typings: "@types/gulp"
typings: typingsName("gulp")
};
const host = createServerHost([lodashJs, commanderJs, file3]);
@@ -554,7 +595,7 @@ namespace ts.projectSystem {
}
installWorker(_requestId: number, args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
let typingFiles: (FileOrFolder & { typings: string })[] = [];
if (args.indexOf("@types/commander") >= 0) {
if (args.indexOf(typingsName("commander")) >= 0) {
typingFiles = [commander, jquery, lodash, cordova];
}
else {
@@ -982,7 +1023,7 @@ namespace ts.projectSystem {
return;
}
if (response.kind === server.EventEndInstallTypes) {
assert.deepEqual(response.packagesToInstall, ["@types/commander"]);
assert.deepEqual(response.packagesToInstall, [typingsName("commander")]);
seenTelemetryEvent = true;
return;
}
+1564 -365
View File
File diff suppressed because it is too large Load Diff
+636 -161
View File
File diff suppressed because it is too large Load Diff
@@ -1,7 +1,7 @@
/// <reference types="node" />
// TODO: extract services types
// TODO: extract services types
interface HostCancellationToken {
isCancellationRequested(): boolean;
}
+1 -1
View File
@@ -28,7 +28,7 @@ namespace ts.server {
: undefined;
const primaryResult = resolveModuleName(moduleName, containingFile, compilerOptions, host);
// return result immediately only if it is .ts, .tsx or .d.ts
if (!(primaryResult.resolvedModule && extensionIsTypeScript(primaryResult.resolvedModule.extension)) && globalCache !== undefined) {
if (moduleHasNonRelativeName(moduleName) && !(primaryResult.resolvedModule && extensionIsTypeScript(primaryResult.resolvedModule.extension)) && globalCache !== undefined) {
// otherwise try to load typings from @types
// create different collection of failed lookup locations for second pass
+5
View File
@@ -1239,6 +1239,11 @@ namespace ts.server.protocol {
* List of files names that should be recompiled
*/
fileNames: string[];
/**
* true if project uses outFile or out compiler option
*/
projectUsesOutFile: boolean;
}
/**
+2 -1
View File
@@ -1040,7 +1040,8 @@ namespace ts.server {
if (project.compileOnSaveEnabled && project.languageServiceEnabled) {
result.push({
projectFileName: project.getProjectName(),
fileNames: project.getCompileOnSaveAffectedFileList(info)
fileNames: project.getCompileOnSaveAffectedFileList(info),
projectUsesOutFile: !!project.getCompilerOptions().outFile || !!project.getCompilerOptions().out
});
}
}
@@ -295,8 +295,7 @@ namespace ts.server.typingsInstaller {
this.log.writeLine(`Installing typings ${JSON.stringify(typingsToInstall)}`);
}
const filteredTypings = this.filterTypings(typingsToInstall);
const scopedTypings = filteredTypings.map(x => `@types/${x}`);
if (scopedTypings.length === 0) {
if (filteredTypings.length === 0) {
if (this.log.isEnabled()) {
this.log.writeLine(`All typings are known to be missing or invalid - no need to go any further`);
}
@@ -316,6 +315,7 @@ namespace ts.server.typingsInstaller {
projectName: req.projectName
});
const scopedTypings = filteredTypings.map(typingsName);
this.installTypingsAsync(requestId, scopedTypings, cachePath, ok => {
try {
if (!ok) {
@@ -429,4 +429,10 @@ namespace ts.server.typingsInstaller {
protected abstract installWorker(requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void;
protected abstract sendResponse(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes): void;
}
/* @internal */
export function typingsName(packageName: string): string {
return `@types/${packageName}@ts${versionMajorMinor}`;
}
const versionMajorMinor = version.split(".").slice(0, 2).join(".");
}
+13 -19
View File
@@ -115,6 +115,7 @@ namespace ts.codefix {
registerCodeFix({
errorCodes: [
Diagnostics.Cannot_find_name_0.code,
Diagnostics.Cannot_find_namespace_0.code,
Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code
],
getCodeActions: (context: CodeFixContext) => {
@@ -416,8 +417,8 @@ namespace ts.codefix {
);
function getModuleSpecifierForNewImport() {
const fileName = sourceFile.path;
const moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().path;
const fileName = sourceFile.fileName;
const moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().fileName;
const sourceDirectory = getDirectoryPath(fileName);
const options = context.program.getCompilerOptions();
@@ -439,8 +440,7 @@ namespace ts.codefix {
return undefined;
}
const normalizedBaseUrl = toPath(options.baseUrl, getDirectoryPath(options.baseUrl), getCanonicalFileName);
let relativeName = tryRemoveParentDirectoryName(moduleFileName, normalizedBaseUrl);
let relativeName = getRelativePathIfInDirectory(moduleFileName, options.baseUrl);
if (!relativeName) {
return undefined;
}
@@ -477,9 +477,8 @@ namespace ts.codefix {
function tryGetModuleNameFromRootDirs() {
if (options.rootDirs) {
const normalizedRootDirs = map(options.rootDirs, rootDir => toPath(rootDir, /*basePath*/ undefined, getCanonicalFileName));
const normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, normalizedRootDirs);
const normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, normalizedRootDirs);
const normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, options.rootDirs);
const normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, options.rootDirs);
if (normalizedTargetPath !== undefined) {
const relativePath = normalizedSourcePath !== undefined ? getRelativePath(normalizedTargetPath, normalizedSourcePath) : normalizedTargetPath;
return removeFileExtension(relativePath);
@@ -546,9 +545,9 @@ namespace ts.codefix {
}
}
function getPathRelativeToRootDirs(path: Path, rootDirs: Path[]) {
function getPathRelativeToRootDirs(path: string, rootDirs: string[]) {
for (const rootDir of rootDirs) {
const relativeName = tryRemoveParentDirectoryName(path, rootDir);
const relativeName = getRelativePathIfInDirectory(path, rootDir);
if (relativeName !== undefined) {
return relativeName;
}
@@ -564,20 +563,15 @@ namespace ts.codefix {
return fileName;
}
function getRelativePathIfInDirectory(path: string, directoryPath: string) {
const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, false);
return isRootedDiskPath(relativePath) || startsWith(relativePath, "..") ? undefined : relativePath;
}
function getRelativePath(path: string, directoryPath: string) {
const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, false);
return moduleHasNonRelativeName(relativePath) ? "./" + relativePath : relativePath;
}
function tryRemoveParentDirectoryName(path: Path, parentDirectory: Path) {
const index = path.indexOf(parentDirectory);
if (index === 0) {
return endsWith(parentDirectory, directorySeparator)
? path.substring(parentDirectory.length)
: path.substring(parentDirectory.length + 1);
}
return undefined;
}
}
}
+34 -18
View File
@@ -25,7 +25,7 @@ namespace ts.codefix {
const forStatement = <ForStatement>token.parent.parent.parent;
const forInitializer = <VariableDeclarationList>forStatement.initializer;
if (forInitializer.declarations.length === 1) {
return createCodeFix("", forInitializer.pos, forInitializer.end - forInitializer.pos);
return createCodeFixToRemoveNode(forInitializer);
}
else {
return removeSingleItem(forInitializer.declarations, token);
@@ -35,7 +35,7 @@ namespace ts.codefix {
const forOfStatement = <ForOfStatement>token.parent.parent.parent;
if (forOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList) {
const forOfInitializer = <VariableDeclarationList>forOfStatement.initializer;
return createCodeFix("{}", forOfInitializer.declarations[0].pos, forOfInitializer.declarations[0].end - forOfInitializer.declarations[0].pos);
return createCodeFix("{}", forOfInitializer.declarations[0].getStart(), forOfInitializer.declarations[0].getWidth());
}
break;
@@ -47,12 +47,12 @@ namespace ts.codefix {
case SyntaxKind.CatchClause:
const catchClause = <CatchClause>token.parent.parent;
const parameter = catchClause.variableDeclaration.getChildren()[0];
return createCodeFix("", parameter.pos, parameter.end - parameter.pos);
return createCodeFixToRemoveNode(parameter);
default:
const variableStatement = <VariableStatement>token.parent.parent.parent;
if (variableStatement.declarationList.declarations.length === 1) {
return createCodeFix("", variableStatement.pos, variableStatement.end - variableStatement.pos);
return createCodeFixToRemoveNode(variableStatement);
}
else {
const declarations = variableStatement.declarationList.declarations;
@@ -72,7 +72,7 @@ namespace ts.codefix {
case ts.SyntaxKind.Parameter:
const functionDeclaration = <FunctionDeclaration>token.parent.parent;
if (functionDeclaration.parameters.length === 1) {
return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos);
return createCodeFixToRemoveNode(token.parent);
}
else {
return removeSingleItem(functionDeclaration.parameters, token);
@@ -81,36 +81,43 @@ namespace ts.codefix {
// handle case where 'import a = A;'
case SyntaxKind.ImportEqualsDeclaration:
const importEquals = findImportDeclaration(token);
return createCodeFix("", importEquals.pos, importEquals.end - importEquals.pos);
return createCodeFixToRemoveNode(importEquals);
case SyntaxKind.ImportSpecifier:
const namedImports = <NamedImports>token.parent.parent;
if (namedImports.elements.length === 1) {
// Only 1 import and it is unused. So the entire declaration should be removed.
const importSpec = findImportDeclaration(token);
return createCodeFix("", importSpec.pos, importSpec.end - importSpec.pos);
return createCodeFixToRemoveNode(importSpec);
}
else {
return removeSingleItem(namedImports.elements, token);
}
// handle case where "import d, * as ns from './file'"
// handle case where "import d, * as ns from './file'"
// or "'import {a, b as ns} from './file'"
case SyntaxKind.ImportClause: // this covers both 'import |d|' and 'import |d,| *'
case SyntaxKind.ImportClause: // this covers both 'import |d|' and 'import |d,| *'
const importClause = <ImportClause>token.parent;
if (!importClause.namedBindings) { // |import d from './file'| or |import * as ns from './file'|
const importDecl = findImportDeclaration(importClause);
return createCodeFix("", importDecl.pos, importDecl.end - importDecl.pos);
return createCodeFixToRemoveNode(importDecl);
}
else { // import |d,| * as ns from './file'
return createCodeFix("", importClause.name.pos, importClause.namedBindings.pos - importClause.name.pos);
else {
// import |d,| * as ns from './file'
const start = importClause.name.getStart();
let end = findFirstNonSpaceCharPosStarting(importClause.name.end);
if (sourceFile.text.charCodeAt(end) === CharacterCodes.comma) {
end = findFirstNonSpaceCharPosStarting(end + 1);
}
return createCodeFix("", start, end - start);
}
case SyntaxKind.NamespaceImport:
const namespaceImport = <NamespaceImport>token.parent;
if (namespaceImport.name == token && !(<ImportClause>namespaceImport.parent).name) {
const importDecl = findImportDeclaration(namespaceImport);
return createCodeFix("", importDecl.pos, importDecl.end - importDecl.pos);
return createCodeFixToRemoveNode(importDecl);
}
else {
const start = (<ImportClause>namespaceImport.parent).name.end;
@@ -120,16 +127,14 @@ namespace ts.codefix {
break;
case SyntaxKind.PropertyDeclaration:
return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos);
case SyntaxKind.NamespaceImport:
return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos);
return createCodeFixToRemoveNode(token.parent);
}
if (isDeclarationName(token)) {
return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos);
return createCodeFixToRemoveNode(token.parent);
}
else if (isLiteralComputedPropertyDeclarationName(token)) {
return createCodeFix("", token.parent.parent.pos, token.parent.parent.end - token.parent.parent.pos);
return createCodeFixToRemoveNode(token.parent.parent);
}
else {
return undefined;
@@ -144,6 +149,17 @@ namespace ts.codefix {
return importDecl;
}
function createCodeFixToRemoveNode(node: Node) {
return createCodeFix("", node.getStart(), node.getWidth());
}
function findFirstNonSpaceCharPosStarting(start: number) {
while (isWhiteSpace(sourceFile.text.charCodeAt(start))) {
start += 1;
}
return start;
}
function createCodeFix(newText: string, start: number, length: number): CodeAction[] {
return [{
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Remove_declaration_for_Colon_0), { 0: token.getText() }),
+25 -3
View File
@@ -173,6 +173,18 @@ namespace ts.Completions {
// var y = require("/*completion position*/");
return getStringLiteralCompletionEntriesFromModuleNames(<StringLiteral>node, compilerOptions, host, typeChecker);
}
else if (isEqualityExpression(node.parent)) {
// Get completions from the type of the other operand
// i.e. switch (a) {
// case '/*completion position*/'
// }
return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation(node.parent.left === node ? node.parent.right : node.parent.left), typeChecker);
}
else if (isCaseOrDefaultClause(node.parent)) {
// Get completions from the type of the switch expression
// i.e. x === '/*completion position'
return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation((<SwitchStatement>node.parent.parent.parent).expression), typeChecker);
}
else {
const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile);
if (argumentInfo) {
@@ -184,7 +196,7 @@ namespace ts.Completions {
// Get completion for string literal from string literal type
// i.e. var x: "hi" | "hello" = "/*completion position*/"
return getStringLiteralCompletionEntriesFromContextualType(<StringLiteral>node, typeChecker);
return getStringLiteralCompletionEntriesFromType(typeChecker.getContextualType(<StringLiteral>node), typeChecker);
}
}
@@ -228,8 +240,7 @@ namespace ts.Completions {
return undefined;
}
function getStringLiteralCompletionEntriesFromContextualType(node: StringLiteral, typeChecker: TypeChecker): CompletionInfo | undefined {
const type = typeChecker.getContextualType(node);
function getStringLiteralCompletionEntriesFromType(type: Type, typeChecker: TypeChecker): CompletionInfo | undefined {
if (type) {
const entries: CompletionEntry[] = [];
addStringLiteralCompletionsFromType(type, entries, typeChecker);
@@ -1756,4 +1767,15 @@ namespace ts.Completions {
catch (e) {}
return undefined;
}
function isEqualityExpression(node: Node): node is BinaryExpression {
return isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind);
}
function isEqualityOperatorKind(kind: SyntaxKind) {
return kind == SyntaxKind.EqualsEqualsToken ||
kind === SyntaxKind.ExclamationEqualsToken ||
kind === SyntaxKind.EqualsEqualsEqualsToken ||
kind === SyntaxKind.ExclamationEqualsEqualsToken;
}
}
+4 -15
View File
@@ -5,6 +5,10 @@ namespace ts.FindAllReferences {
return getReferencedSymbolsForNode(typeChecker, cancellationToken, node, sourceFiles, findInStrings, findInComments, isForRename);
}
export function convertReferences(referenceSymbols: ReferencedSymbol[]): ReferenceEntry[] {
return referenceSymbols && flatMap(referenceSymbols, r => r.references);
}
export function getReferencedSymbolsForNode(typeChecker: TypeChecker, cancellationToken: CancellationToken, node: Node, sourceFiles: SourceFile[], findInStrings?: boolean, findInComments?: boolean, isForRename?: boolean, implementations?: boolean): ReferencedSymbol[] | undefined {
if (!implementations) {
const special = getReferencedSymbolsSpecial(node, sourceFiles, typeChecker, cancellationToken);
@@ -411,7 +415,6 @@ namespace ts.FindAllReferences {
textSpan: createTextSpan(0, 1),
displayParts: [{ text: name, kind: ScriptElementKind.keyword }]
}
const references: ReferenceEntry[] = [];
for (const sourceFile of sourceFiles) {
cancellationToken.throwIfCancellationRequested();
@@ -1316,20 +1319,6 @@ namespace ts.FindAllReferences {
return meaning;
}
export function convertReferences(referenceSymbols: ReferencedSymbol[]): ReferenceEntry[] {
if (!referenceSymbols) {
return undefined;
}
const referenceEntries: ReferenceEntry[] = [];
for (const referenceSymbol of referenceSymbols) {
addRange(referenceEntries, referenceSymbol.references);
}
return referenceEntries;
}
function isImplementation(node: Node): boolean {
if (!node) {
return false;
+1 -6
View File
@@ -1415,7 +1415,6 @@ namespace ts {
function findReferences(fileName: string, position: number): ReferencedSymbol[] {
const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false, /*isForRename*/false);
// Only include referenced symbols that have a valid definition.
return filter(referencedSymbols, rs => !!rs.definition);
}
@@ -2015,9 +2014,5 @@ namespace ts {
throw new Error("getDefaultLibFilePath is only supported when consumed as a node module. ");
}
function initializeServices() {
objectAllocator = getServicesObjectAllocator();
}
initializeServices();
objectAllocator = getServicesObjectAllocator();
}
@@ -12,7 +12,7 @@ function f1(x: Color | string) {
if (typeof x === "number") {
>typeof x === "number" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | Color
>"number" : "number"
@@ -41,7 +41,7 @@ function f2(x: Color | string | string[]) {
if (typeof x === "object") {
>typeof x === "object" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | Color | string[]
>"object" : "object"
@@ -54,7 +54,7 @@ function f2(x: Color | string | string[]) {
}
if (typeof x === "number") {
>typeof x === "number" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | Color | string[]
>"number" : "number"
@@ -76,7 +76,7 @@ function f2(x: Color | string | string[]) {
}
if (typeof x === "string") {
>typeof x === "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | Color | string[]
>"string" : "string"
@@ -26,5 +26,6 @@ define(["require", "exports"], function (require, exports) {
define(["require", "exports", "./foo_0"], function (require, exports, foo) {
"use strict";
if (foo.E1.A === 0) {
// Should cause runtime import - interesting optimization possibility, as gets inlined to 0.
}
});
@@ -4,7 +4,7 @@ function f() {
return typeof class {} === "function";
>typeof class {} === "function" : boolean
>typeof class {} : string
>typeof class {} : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>class {} : typeof (Anonymous class)
>"function" : "function"
}
+1
View File
@@ -17,6 +17,7 @@ var C = (function () {
}
C.prototype.P = function (ii, j, k) {
for (var i = 0; i < arguments.length; i++) {
// WScript.Echo("param: " + arguments[i]);
}
};
return C;
@@ -83,7 +83,9 @@ f(// comment 1
// comment 2
function () {
// comment 4
});
}
// comment 5
);
// body is not a block
f(function (_) { return 1 +
2; });
@@ -0,0 +1,21 @@
//// [assignmentNestedInLiterals.ts]
var target, x, y;
target = [x = 1, y = x];
var aegis, a, b;
aegis = { x: a = 1, y: b = a };
var kowloona, c, d;
for (kowloona of [c = 1, d = c]) {
}
//// [assignmentNestedInLiterals.js]
var target, x, y;
target = [x = 1, y = x];
var aegis, a, b;
aegis = { x: a = 1, y: b = a };
var kowloona, c, d;
for (var _i = 0, _a = [c = 1, d = c]; _i < _a.length; _i++) {
kowloona = _a[_i];
}
@@ -0,0 +1,37 @@
=== tests/cases/compiler/assignmentNestedInLiterals.ts ===
var target, x, y;
>target : Symbol(target, Decl(assignmentNestedInLiterals.ts, 0, 3))
>x : Symbol(x, Decl(assignmentNestedInLiterals.ts, 0, 11))
>y : Symbol(y, Decl(assignmentNestedInLiterals.ts, 0, 14))
target = [x = 1, y = x];
>target : Symbol(target, Decl(assignmentNestedInLiterals.ts, 0, 3))
>x : Symbol(x, Decl(assignmentNestedInLiterals.ts, 0, 11))
>y : Symbol(y, Decl(assignmentNestedInLiterals.ts, 0, 14))
>x : Symbol(x, Decl(assignmentNestedInLiterals.ts, 0, 11))
var aegis, a, b;
>aegis : Symbol(aegis, Decl(assignmentNestedInLiterals.ts, 3, 3))
>a : Symbol(a, Decl(assignmentNestedInLiterals.ts, 3, 10))
>b : Symbol(b, Decl(assignmentNestedInLiterals.ts, 3, 13))
aegis = { x: a = 1, y: b = a };
>aegis : Symbol(aegis, Decl(assignmentNestedInLiterals.ts, 3, 3))
>x : Symbol(x, Decl(assignmentNestedInLiterals.ts, 4, 9))
>a : Symbol(a, Decl(assignmentNestedInLiterals.ts, 3, 10))
>y : Symbol(y, Decl(assignmentNestedInLiterals.ts, 4, 19))
>b : Symbol(b, Decl(assignmentNestedInLiterals.ts, 3, 13))
>a : Symbol(a, Decl(assignmentNestedInLiterals.ts, 3, 10))
var kowloona, c, d;
>kowloona : Symbol(kowloona, Decl(assignmentNestedInLiterals.ts, 6, 3))
>c : Symbol(c, Decl(assignmentNestedInLiterals.ts, 6, 13))
>d : Symbol(d, Decl(assignmentNestedInLiterals.ts, 6, 16))
for (kowloona of [c = 1, d = c]) {
>kowloona : Symbol(kowloona, Decl(assignmentNestedInLiterals.ts, 6, 3))
>c : Symbol(c, Decl(assignmentNestedInLiterals.ts, 6, 13))
>d : Symbol(d, Decl(assignmentNestedInLiterals.ts, 6, 16))
>c : Symbol(c, Decl(assignmentNestedInLiterals.ts, 6, 13))
}
@@ -0,0 +1,51 @@
=== tests/cases/compiler/assignmentNestedInLiterals.ts ===
var target, x, y;
>target : any
>x : any
>y : any
target = [x = 1, y = x];
>target = [x = 1, y = x] : number[]
>target : any
>[x = 1, y = x] : number[]
>x = 1 : 1
>x : any
>1 : 1
>y = x : number
>y : any
>x : number
var aegis, a, b;
>aegis : any
>a : any
>b : any
aegis = { x: a = 1, y: b = a };
>aegis = { x: a = 1, y: b = a } : { x: number; y: number; }
>aegis : any
>{ x: a = 1, y: b = a } : { x: number; y: number; }
>x : number
>a = 1 : 1
>a : any
>1 : 1
>y : number
>b = a : number
>b : any
>a : number
var kowloona, c, d;
>kowloona : any
>c : any
>d : any
for (kowloona of [c = 1, d = c]) {
>kowloona : any
>[c = 1, d = c] : number[]
>c = 1 : 1
>c : any
>1 : 1
>d = c : number
>d : any
>c : number
}
@@ -103,17 +103,17 @@ var r6 = foo6(1);
>1 : 1
function foo7(x) {
>foo7 : (x: any) => string
>foo7 : (x: any) => "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : any
return typeof x;
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : any
}
var r7 = foo7(1);
>r7 : string
>foo7(1) : string
>foo7 : (x: any) => string
>r7 : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>foo7(1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>foo7 : (x: any) => "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>1 : 1
// object types
@@ -0,0 +1,52 @@
//// [capturedLetConstInLoop13.ts]
class Main {
constructor() {
this.register("a", "b", "c");
}
private register(...names: string[]): void {
for (let name of names) {
this.bar({
[name + ".a"]: () => { this.foo(name); },
});
}
}
private bar(a: any): void { }
private foo(name: string): void { }
}
new Main();
//// [capturedLetConstInLoop13.js]
var Main = (function () {
function Main() {
this.register("a", "b", "c");
}
Main.prototype.register = function () {
var _this = this;
var names = [];
for (var _i = 0; _i < arguments.length; _i++) {
names[_i] = arguments[_i];
}
var _loop_1 = function (name) {
this_1.bar((_a = {},
_a[name + ".a"] = function () { _this.foo(name); },
_a));
var _a;
};
var this_1 = this;
for (var _a = 0, names_1 = names; _a < names_1.length; _a++) {
var name = names_1[_a];
_loop_1(name);
}
};
Main.prototype.bar = function (a) { };
Main.prototype.foo = function (name) { };
return Main;
}());
new Main();
@@ -0,0 +1,48 @@
=== tests/cases/compiler/capturedLetConstInLoop13.ts ===
class Main {
>Main : Symbol(Main, Decl(capturedLetConstInLoop13.ts, 0, 0))
constructor() {
this.register("a", "b", "c");
>this.register : Symbol(Main.register, Decl(capturedLetConstInLoop13.ts, 4, 5))
>this : Symbol(Main, Decl(capturedLetConstInLoop13.ts, 0, 0))
>register : Symbol(Main.register, Decl(capturedLetConstInLoop13.ts, 4, 5))
}
private register(...names: string[]): void {
>register : Symbol(Main.register, Decl(capturedLetConstInLoop13.ts, 4, 5))
>names : Symbol(names, Decl(capturedLetConstInLoop13.ts, 6, 21))
for (let name of names) {
>name : Symbol(name, Decl(capturedLetConstInLoop13.ts, 7, 16))
>names : Symbol(names, Decl(capturedLetConstInLoop13.ts, 6, 21))
this.bar({
>this.bar : Symbol(Main.bar, Decl(capturedLetConstInLoop13.ts, 13, 5))
>this : Symbol(Main, Decl(capturedLetConstInLoop13.ts, 0, 0))
>bar : Symbol(Main.bar, Decl(capturedLetConstInLoop13.ts, 13, 5))
[name + ".a"]: () => { this.foo(name); },
>name : Symbol(name, Decl(capturedLetConstInLoop13.ts, 7, 16))
>this.foo : Symbol(Main.foo, Decl(capturedLetConstInLoop13.ts, 15, 33))
>this : Symbol(Main, Decl(capturedLetConstInLoop13.ts, 0, 0))
>foo : Symbol(Main.foo, Decl(capturedLetConstInLoop13.ts, 15, 33))
>name : Symbol(name, Decl(capturedLetConstInLoop13.ts, 7, 16))
});
}
}
private bar(a: any): void { }
>bar : Symbol(Main.bar, Decl(capturedLetConstInLoop13.ts, 13, 5))
>a : Symbol(a, Decl(capturedLetConstInLoop13.ts, 15, 16))
private foo(name: string): void { }
>foo : Symbol(Main.foo, Decl(capturedLetConstInLoop13.ts, 15, 33))
>name : Symbol(name, Decl(capturedLetConstInLoop13.ts, 17, 16))
}
new Main();
>Main : Symbol(Main, Decl(capturedLetConstInLoop13.ts, 0, 0))
@@ -0,0 +1,59 @@
=== tests/cases/compiler/capturedLetConstInLoop13.ts ===
class Main {
>Main : Main
constructor() {
this.register("a", "b", "c");
>this.register("a", "b", "c") : void
>this.register : (...names: string[]) => void
>this : this
>register : (...names: string[]) => void
>"a" : "a"
>"b" : "b"
>"c" : "c"
}
private register(...names: string[]): void {
>register : (...names: string[]) => void
>names : string[]
for (let name of names) {
>name : string
>names : string[]
this.bar({
>this.bar({ [name + ".a"]: () => { this.foo(name); }, }) : void
>this.bar : (a: any) => void
>this : this
>bar : (a: any) => void
>{ [name + ".a"]: () => { this.foo(name); }, } : { [x: string]: () => void; }
[name + ".a"]: () => { this.foo(name); },
>name + ".a" : string
>name : string
>".a" : ".a"
>() => { this.foo(name); } : () => void
>this.foo(name) : void
>this.foo : (name: string) => void
>this : this
>foo : (name: string) => void
>name : string
});
}
}
private bar(a: any): void { }
>bar : (a: any) => void
>a : any
private foo(name: string): void { }
>foo : (name: string) => void
>name : string
}
new Main();
>new Main() : Main
>Main : typeof Main
@@ -182,7 +182,7 @@ declare var A;
>(<any>typeof A).x : any
>(<any>typeof A) : any
><any>typeof A : any
>typeof A : string
>typeof A : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>A : any
>x : any
+2 -2
View File
@@ -8,7 +8,7 @@ async function f() {
>0 : 0
typeof await 0;
>typeof await 0 : string
>typeof await 0 : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>await 0 : 0
>0 : 0
@@ -21,7 +21,7 @@ async function f() {
>await void <string> typeof <number> void await 0 : any
>void <string> typeof <number> void await 0 : undefined
><string> typeof <number> void await 0 : string
>typeof <number> void await 0 : string
>typeof <number> void await 0 : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
><number> void await 0 : number
>void await 0 : undefined
>await 0 : 0
@@ -5,7 +5,7 @@ var x: StringTree;
if (typeof x !== "string") {
>typeof x !== "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : StringTree
>"string" : "string"
@@ -0,0 +1,24 @@
//// [commentLeadingCloseBrace.ts]
declare function commentedParameters(...args): any;
function ifelse() {
if (commentedParameters(1, 2)) {
/*comment1*/
commentedParameters(3, 4);
/*comment2*/
} else {
commentedParameters(5, 6);
}
}
//// [commentLeadingCloseBrace.js]
function ifelse() {
if (commentedParameters(1, 2)) {
/*comment1*/
commentedParameters(3, 4);
/*comment2*/
}
else {
commentedParameters(5, 6);
}
}
@@ -0,0 +1,21 @@
=== tests/cases/compiler/commentLeadingCloseBrace.ts ===
declare function commentedParameters(...args): any;
>commentedParameters : Symbol(commentedParameters, Decl(commentLeadingCloseBrace.ts, 0, 0))
>args : Symbol(args, Decl(commentLeadingCloseBrace.ts, 0, 37))
function ifelse() {
>ifelse : Symbol(ifelse, Decl(commentLeadingCloseBrace.ts, 0, 51))
if (commentedParameters(1, 2)) {
>commentedParameters : Symbol(commentedParameters, Decl(commentLeadingCloseBrace.ts, 0, 0))
/*comment1*/
commentedParameters(3, 4);
>commentedParameters : Symbol(commentedParameters, Decl(commentLeadingCloseBrace.ts, 0, 0))
/*comment2*/
} else {
commentedParameters(5, 6);
>commentedParameters : Symbol(commentedParameters, Decl(commentLeadingCloseBrace.ts, 0, 0))
}
}
@@ -0,0 +1,30 @@
=== tests/cases/compiler/commentLeadingCloseBrace.ts ===
declare function commentedParameters(...args): any;
>commentedParameters : (...args: any[]) => any
>args : any[]
function ifelse() {
>ifelse : () => void
if (commentedParameters(1, 2)) {
>commentedParameters(1, 2) : any
>commentedParameters : (...args: any[]) => any
>1 : 1
>2 : 2
/*comment1*/
commentedParameters(3, 4);
>commentedParameters(3, 4) : any
>commentedParameters : (...args: any[]) => any
>3 : 3
>4 : 4
/*comment2*/
} else {
commentedParameters(5, 6);
>commentedParameters(5, 6) : any
>commentedParameters : (...args: any[]) => any
>5 : 5
>6 : 6
}
}
@@ -0,0 +1,17 @@
//// [commentOnArrayElement1.ts]
var array = [
/* element 1*/
1
/* end of element 1 */,
2
/* end of element 2 */
];
//// [commentOnArrayElement1.js]
var array = [
/* element 1*/
1
/* end of element 1 */ ,
2
/* end of element 2 */
];
@@ -0,0 +1,10 @@
=== tests/cases/compiler/commentOnArrayElement1.ts ===
var array = [
>array : Symbol(array, Decl(commentOnArrayElement1.ts, 0, 3))
/* element 1*/
1
/* end of element 1 */,
2
/* end of element 2 */
];
@@ -0,0 +1,15 @@
=== tests/cases/compiler/commentOnArrayElement1.ts ===
var array = [
>array : number[]
>[ /* element 1*/ 1 /* end of element 1 */, 2 /* end of element 2 */] : number[]
/* element 1*/
1
>1 : 1
/* end of element 1 */,
2
>2 : 2
/* end of element 2 */
];
@@ -0,0 +1,15 @@
//// [commentOnArrayElement2.ts]
var array = [
/* element 1*/
1 /* end of element 1 */,
2
/* end of element 2 */
];
//// [commentOnArrayElement2.js]
var array = [
/* element 1*/
1 /* end of element 1 */,
2
/* end of element 2 */
];
@@ -0,0 +1,9 @@
=== tests/cases/compiler/commentOnArrayElement2.ts ===
var array = [
>array : Symbol(array, Decl(commentOnArrayElement2.ts, 0, 3))
/* element 1*/
1 /* end of element 1 */,
2
/* end of element 2 */
];
@@ -0,0 +1,14 @@
=== tests/cases/compiler/commentOnArrayElement2.ts ===
var array = [
>array : number[]
>[ /* element 1*/ 1 /* end of element 1 */, 2 /* end of element 2 */] : number[]
/* element 1*/
1 /* end of element 1 */,
>1 : 1
2
>2 : 2
/* end of element 2 */
];
@@ -0,0 +1,19 @@
//// [commentOnArrayElement3.ts]
var array = [
/* element 1*/
1
/* end of element 1 */,
2
/* end of element 2 */, ,
/* extra comment */
];
//// [commentOnArrayElement3.js]
var array = [
/* element 1*/
1
/* end of element 1 */ ,
2
/* end of element 2 */ ,
,
];
@@ -0,0 +1,11 @@
=== tests/cases/compiler/commentOnArrayElement3.ts ===
var array = [
>array : Symbol(array, Decl(commentOnArrayElement3.ts, 0, 3))
/* element 1*/
1
/* end of element 1 */,
2
/* end of element 2 */, ,
/* extra comment */
];
@@ -0,0 +1,18 @@
=== tests/cases/compiler/commentOnArrayElement3.ts ===
var array = [
>array : number[]
>[ /* element 1*/ 1 /* end of element 1 */, 2 /* end of element 2 */, , /* extra comment */] : number[]
/* element 1*/
1
>1 : 1
/* end of element 1 */,
2
>2 : 2
/* end of element 2 */, ,
> : undefined
/* extra comment */
];
@@ -0,0 +1,20 @@
//// [commentOnParameter1.ts]
function commentedParameters(
/* Parameter a */
a
/* End of parameter a */
/* Parameter b */
,
b
/* End of parameter b */
){}
//// [commentOnParameter1.js]
function commentedParameters(
/* Parameter a */
a
/* End of parameter a */
/* Parameter b */
, b
/* End of parameter b */
) { }
@@ -0,0 +1,16 @@
=== tests/cases/compiler/commentOnParameter1.ts ===
function commentedParameters(
>commentedParameters : Symbol(commentedParameters, Decl(commentOnParameter1.ts, 0, 0))
/* Parameter a */
a
>a : Symbol(a, Decl(commentOnParameter1.ts, 0, 29))
/* End of parameter a */
/* Parameter b */
,
b
>b : Symbol(b, Decl(commentOnParameter1.ts, 5, 1))
/* End of parameter b */
){}
@@ -0,0 +1,16 @@
=== tests/cases/compiler/commentOnParameter1.ts ===
function commentedParameters(
>commentedParameters : (a: any, b: any) => void
/* Parameter a */
a
>a : any
/* End of parameter a */
/* Parameter b */
,
b
>b : any
/* End of parameter b */
){}
@@ -0,0 +1,18 @@
//// [commentOnParameter2.ts]
function commentedParameters(
/* Parameter a */
a /* End of parameter a */
/* Parameter b */
,
b
/* End of parameter b */
){}
//// [commentOnParameter2.js]
function commentedParameters(
/* Parameter a */
a /* End of parameter a */
/* Parameter b */
, b
/* End of parameter b */
) { }
@@ -0,0 +1,15 @@
=== tests/cases/compiler/commentOnParameter2.ts ===
function commentedParameters(
>commentedParameters : Symbol(commentedParameters, Decl(commentOnParameter2.ts, 0, 0))
/* Parameter a */
a /* End of parameter a */
>a : Symbol(a, Decl(commentOnParameter2.ts, 0, 29))
/* Parameter b */
,
b
>b : Symbol(b, Decl(commentOnParameter2.ts, 4, 1))
/* End of parameter b */
){}
@@ -0,0 +1,15 @@
=== tests/cases/compiler/commentOnParameter2.ts ===
function commentedParameters(
>commentedParameters : (a: any, b: any) => void
/* Parameter a */
a /* End of parameter a */
>a : any
/* Parameter b */
,
b
>b : any
/* End of parameter b */
){}
@@ -0,0 +1,9 @@
//// [commentOnParameter3.ts]
function commentedParameters(
a /* parameter a */,
b /* parameter b */,
/* extra comment */
) { }
//// [commentOnParameter3.js]
function commentedParameters(a /* parameter a */, b /* parameter b */) { }
@@ -0,0 +1,12 @@
=== tests/cases/compiler/commentOnParameter3.ts ===
function commentedParameters(
>commentedParameters : Symbol(commentedParameters, Decl(commentOnParameter3.ts, 0, 0))
a /* parameter a */,
>a : Symbol(a, Decl(commentOnParameter3.ts, 0, 29))
b /* parameter b */,
>b : Symbol(b, Decl(commentOnParameter3.ts, 1, 20))
/* extra comment */
) { }
@@ -0,0 +1,12 @@
=== tests/cases/compiler/commentOnParameter3.ts ===
function commentedParameters(
>commentedParameters : (a: any, b: any) => void
a /* parameter a */,
>a : any
b /* parameter b */,
>b : any
/* extra comment */
) { }
@@ -27,4 +27,5 @@ exports.C1 = C1;
"use strict";
var foo = require("./foo_0");
if (foo.C1.s1) {
// Should cause runtime import
}
@@ -120,7 +120,7 @@ true ? exprString1 : exprBoolean1; // union
typeof "123" == "string" ? exprBoolean1 : exprBoolean2;
>typeof "123" == "string" ? exprBoolean1 : exprBoolean2 : boolean
>typeof "123" == "string" : boolean
>typeof "123" : string
>typeof "123" : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>"123" : "123"
>"string" : "string"
>exprBoolean1 : boolean
@@ -262,7 +262,7 @@ var resultIsBoolean3 = typeof "123" == "string" ? exprBoolean1 : exprBoolean2;
>resultIsBoolean3 : boolean
>typeof "123" == "string" ? exprBoolean1 : exprBoolean2 : boolean
>typeof "123" == "string" : boolean
>typeof "123" : string
>typeof "123" : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>"123" : "123"
>"string" : "string"
>exprBoolean1 : boolean
@@ -299,7 +299,7 @@ var resultIsStringOrBoolean4 = typeof "123" === "string" ? exprString1 : exprBoo
>resultIsStringOrBoolean4 : string | boolean
>typeof "123" === "string" ? exprString1 : exprBoolean1 : string | boolean
>typeof "123" === "string" : boolean
>typeof "123" : string
>typeof "123" : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>"123" : "123"
>"string" : "string"
>exprString1 : string
@@ -123,7 +123,7 @@ var array = ["1", "2", "3"];
typeof condString ? exprAny1 : exprAny2;
>typeof condString ? exprAny1 : exprAny2 : any
>typeof condString : string
>typeof condString : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>condString : string
>exprAny1 : any
>exprAny2 : any
@@ -254,7 +254,7 @@ var resultIsStringOrBoolean2 = "hello" ? exprString1 : exprBoolean1; // union
var resultIsAny3 = typeof condString ? exprAny1 : exprAny2;
>resultIsAny3 : any
>typeof condString ? exprAny1 : exprAny2 : any
>typeof condString : string
>typeof condString : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>condString : string
>exprAny1 : any
>exprAny2 : any
@@ -297,7 +297,7 @@ var resultIsObject3 = array[1] ? exprIsObject1 : exprIsObject2;
var resultIsStringOrBoolean3 = typeof condString ? exprString1 : exprBoolean1; // union
>resultIsStringOrBoolean3 : string | boolean
>typeof condString ? exprString1 : exprBoolean1 : string | boolean
>typeof condString : string
>typeof condString : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>condString : string
>exprString1 : string
>exprBoolean1 : boolean
@@ -12,7 +12,7 @@ function f1() {
if (typeof x === "string") {
>typeof x === "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number
>"string" : "string"
@@ -35,7 +35,7 @@ function f2() {
if (typeof x !== "string") {
>typeof x !== "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number
>"string" : "string"
@@ -59,7 +59,7 @@ function f3() {
if (typeof x === "string") {
>typeof x === "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number
>"string" : "string"
@@ -82,7 +82,7 @@ function f4() {
if (typeof x !== "string") {
>typeof x !== "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number
>"string" : "string"
@@ -106,7 +106,7 @@ function f5() {
if (typeof x === "string") {
>typeof x === "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number
>"string" : "string"
@@ -17,7 +17,7 @@ function f(x: string | number | boolean) {
>y : string | number | boolean
>"" : ""
>typeof x === "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number | boolean
>"string" : "string"
@@ -36,7 +36,7 @@ function f(x: string | number | boolean) {
>z : string | number | boolean
>1 : 1
>typeof x === "number" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : number | boolean
>"number" : "number"
@@ -66,7 +66,7 @@ function c() {
if (typeof x === "string") continue;
>typeof x === "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number
>"string" : "string"
@@ -82,7 +82,7 @@ function d() {
>x : string | number | boolean
>"" : ""
>typeof x === "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number
>"string" : "string"
>x = 5 : 5
@@ -107,7 +107,7 @@ function e() {
>"" : ""
>0 : 0
>typeof x !== "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : number | true
>"string" : "string"
>x = "" || true : true
@@ -128,7 +128,7 @@ function f() {
for (; typeof x !== "string";) {
>typeof x !== "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number | boolean
>"string" : "string"
@@ -137,7 +137,7 @@ function f() {
if (typeof x === "number") break;
>typeof x === "number" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : number | boolean
>"number" : "number"
@@ -13,7 +13,7 @@ function f1() {
if (typeof x === "string") {
>typeof x === "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number
>"string" : "string"
@@ -41,7 +41,7 @@ function f2() {
if (typeof x === "string") {
>typeof x === "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number
>"string" : "string"
@@ -73,7 +73,7 @@ function f3() {
if (typeof x === "string") {
>typeof x === "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number
>"string" : "string"
@@ -100,7 +100,7 @@ function c<T>(data: string | T): T {
if (typeof data === 'string') {
>typeof data === 'string' : boolean
>typeof data : string
>typeof data : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>data : string | T
>'string' : "string"
@@ -124,7 +124,7 @@ function d<T extends string>(data: string | T): never {
if (typeof data === 'string') {
>typeof data === 'string' : boolean
>typeof data : string
>typeof data : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>data : string | T
>'string' : "string"
@@ -69,7 +69,7 @@ function c() {
if (typeof x === "string") continue;
>typeof x === "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number
>"string" : "string"
@@ -16,7 +16,7 @@ function foo1() {
if (typeof x === "string") {
>typeof x === "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number
>"string" : "string"
@@ -49,7 +49,7 @@ function foo2() {
if (typeof x === "number") {
>typeof x === "number" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number
>"number" : "number"
@@ -7,7 +7,7 @@ export function f(x: any): x is number {
return typeof x === "number";
>typeof x === "number" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : any
>"number" : "number"
}
@@ -30,7 +30,7 @@ function f1(x: Foo | Bar | string) {
if (typeof x !== 'string') {
>typeof x !== 'string' : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | Foo | Bar
>'string' : "string"
@@ -58,7 +58,7 @@ function f2(x: Foo | Bar | string | undefined) {
if (typeof x === "object") {
>typeof x === "object" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | Foo | Bar | undefined
>"object" : "object"
@@ -89,7 +89,7 @@ function f3(x: Foo | Bar | string | null) {
>x && typeof x !== "string" : boolean | "" | null
>x : string | Foo | Bar | null
>typeof x !== "string" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | Foo | Bar
>"string" : "string"
@@ -120,7 +120,7 @@ function f4(x: Foo | Bar | string | number | null) {
>x && typeof x === "object" : boolean | "" | 0 | null
>x : string | number | Foo | Bar | null
>typeof x === "object" : boolean
>typeof x : string
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : string | number | Foo | Bar
>"object" : "object"
@@ -391,6 +391,7 @@ var TestRunner = (function () {
}
}
if (testResult === false) {
//console.log(e.message);
}
}
if ((testcase.errorMessageRegEx !== undefined) && !exception) {
@@ -64,7 +64,7 @@ var s;
`${typeof (t1 ** t2 ** t1) } world`;
>`${typeof (t1 ** t2 ** t1) } world` : string
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
@@ -162,14 +162,14 @@ var s;
`${typeof (t1 ** t2 ** t1)} hello world ${typeof (t1 ** t2 ** t1)}`;
>`${typeof (t1 ** t2 ** t1)} hello world ${typeof (t1 ** t2 ** t1)}` : string
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
>t2 ** t1 : number
>t2 : number
>t1 : number
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
@@ -223,7 +223,7 @@ var s;
`hello ${typeof (t1 ** t2 ** t1)}`;
>`hello ${typeof (t1 ** t2 ** t1)}` : string
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
@@ -64,7 +64,7 @@ var s;
`${typeof (t1 ** t2 ** t1) } world`;
>`${typeof (t1 ** t2 ** t1) } world` : string
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
@@ -162,14 +162,14 @@ var s;
`${typeof (t1 ** t2 ** t1)} hello world ${typeof (t1 ** t2 ** t1)}`;
>`${typeof (t1 ** t2 ** t1)} hello world ${typeof (t1 ** t2 ** t1)}` : string
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
>t2 ** t1 : number
>t2 : number
>t1 : number
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
@@ -223,7 +223,7 @@ var s;
`hello ${typeof (t1 ** t2 ** t1)}`;
>`hello ${typeof (t1 ** t2 ** t1)}` : string
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
@@ -54,7 +54,7 @@ var s;
`${typeof (t1 ** t2 ** t1) }`;
>`${typeof (t1 ** t2 ** t1) }` : string
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
@@ -66,7 +66,7 @@ var s;
>`${1 + typeof (t1 ** t2 ** t1) }` : string
>1 + typeof (t1 ** t2 ** t1) : string
>1 : 1
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
@@ -141,14 +141,14 @@ var s;
`${typeof (t1 ** t2 ** t1)}${typeof (t1 ** t2 ** t1)}`;
>`${typeof (t1 ** t2 ** t1)}${typeof (t1 ** t2 ** t1)}` : string
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
>t2 ** t1 : number
>t2 : number
>t1 : number
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
@@ -223,14 +223,14 @@ var s;
`${typeof (t1 ** t2 ** t1) } hello world ${typeof (t1 ** t2 ** t1) }`;
>`${typeof (t1 ** t2 ** t1) } hello world ${typeof (t1 ** t2 ** t1) }` : string
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
>t2 ** t1 : number
>t2 : number
>t1 : number
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
@@ -54,7 +54,7 @@ var s;
`${typeof (t1 ** t2 ** t1) }`;
>`${typeof (t1 ** t2 ** t1) }` : string
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
@@ -66,7 +66,7 @@ var s;
>`${1 + typeof (t1 ** t2 ** t1) }` : string
>1 + typeof (t1 ** t2 ** t1) : string
>1 : 1
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
@@ -141,14 +141,14 @@ var s;
`${typeof (t1 ** t2 ** t1)}${typeof (t1 ** t2 ** t1)}`;
>`${typeof (t1 ** t2 ** t1)}${typeof (t1 ** t2 ** t1)}` : string
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
>t2 ** t1 : number
>t2 : number
>t1 : number
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
@@ -223,14 +223,14 @@ var s;
`${typeof (t1 ** t2 ** t1) } hello world ${typeof (t1 ** t2 ** t1) }`;
>`${typeof (t1 ** t2 ** t1) } hello world ${typeof (t1 ** t2 ** t1) }` : string
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number
>t2 ** t1 : number
>t2 : number
>t1 : number
>typeof (t1 ** t2 ** t1) : string
>typeof (t1 ** t2 ** t1) : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(t1 ** t2 ** t1) : number
>t1 ** t2 ** t1 : number
>t1 : number

Some files were not shown because too many files have changed in this diff Show More