diff --git a/.gitignore b/.gitignore index 0badfe0cf61..9173b12c328 100644 --- a/.gitignore +++ b/.gitignore @@ -9,12 +9,14 @@ test-args.txt \#*\# .\#* tests/baselines/local/* +tests/baselines/local.old/* tests/services/baselines/local/* tests/baselines/prototyping/local/* tests/baselines/rwc/* tests/baselines/test262/* tests/baselines/reference/projectOutput/* tests/baselines/local/projectOutput/* +tests/baselines/reference/testresults.tap tests/services/baselines/prototyping/local/* tests/services/browser/typescriptServices.js scripts/authors.js diff --git a/Jakefile.js b/Jakefile.js index 4c751945c87..40a0bb2ffa5 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -64,7 +64,20 @@ var compilerSources = [ "utilities.ts", "binder.ts", "checker.ts", + "factory.ts", + "visitor.ts", + "transformers/destructuring.ts", + "transformers/ts.ts", + "transformers/module/es6.ts", + "transformers/module/system.ts", + "transformers/module/module.ts", + "transformers/jsx.ts", + "transformers/es7.ts", + "transformers/generators.ts", + "transformers/es6.ts", + "transformer.ts", "sourcemap.ts", + "comments.ts", "declarationEmitter.ts", "emitter.ts", "program.ts", @@ -85,7 +98,20 @@ var servicesSources = [ "utilities.ts", "binder.ts", "checker.ts", + "factory.ts", + "visitor.ts", + "transformers/destructuring.ts", + "transformers/ts.ts", + "transformers/module/es6.ts", + "transformers/module/system.ts", + "transformers/module/module.ts", + "transformers/jsx.ts", + "transformers/es7.ts", + "transformers/generators.ts", + "transformers/es6.ts", + "transformer.ts", "sourcemap.ts", + "comments.ts", "declarationEmitter.ts", "emitter.ts", "program.ts", @@ -102,6 +128,7 @@ var servicesSources = [ "services.ts", "shims.ts", "signatureHelp.ts", + "types.ts", "utilities.ts", "formatting/formatting.ts", "formatting/formattingContext.ts", @@ -307,7 +334,10 @@ var builtLocalCompiler = path.join(builtLocalDirectory, compilerFilename); * @param callback: a function to execute after the compilation process ends */ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts, callback) { - file(outFile, prereqs, function () { + file(outFile, prereqs, function() { + if (process.env.USE_TRANSFORMS === "false") { + useBuiltCompiler = false; + } var startCompileTime = mark(); opts = opts || {}; var compilerPath = useBuiltCompiler ? builtLocalCompiler : LKGCompiler; @@ -745,8 +775,14 @@ function cleanTestDirs() { } // used to pass data from jake command line directly to run.js -function writeTestConfigFile(tests, light, taskConfigsFolder, workerCount) { - var testConfigContents = JSON.stringify({ test: tests ? [tests] : undefined, light: light, workerCount: workerCount, taskConfigsFolder: taskConfigsFolder }); +function writeTestConfigFile(tests, light, taskConfigsFolder, workerCount, stackTraceLimit) { + var testConfigContents = JSON.stringify({ + test: tests ? [tests] : undefined, + light: light, + workerCount: workerCount, + taskConfigsFolder: taskConfigsFolder, + stackTraceLimit: stackTraceLimit + }); fs.writeFileSync('test.config', testConfigContents); } @@ -757,10 +793,15 @@ function deleteTemporaryProjectOutput() { } function runConsoleTests(defaultReporter, runInParallel) { - cleanTestDirs(); + var dirty = process.env.dirty; + if (!dirty) { + cleanTestDirs(); + } + var debug = process.env.debug || process.env.d; tests = process.env.test || process.env.tests || process.env.t; var light = process.env.light || false; + var stackTraceLimit = process.env.stackTraceLimit; var testConfigFile = 'test.config'; if (fs.existsSync(testConfigFile)) { fs.unlinkSync(testConfigFile); @@ -780,7 +821,7 @@ function runConsoleTests(defaultReporter, runInParallel) { } if (tests || light || taskConfigsFolder) { - writeTestConfigFile(tests, light, taskConfigsFolder, workerCount); + writeTestConfigFile(tests, light, taskConfigsFolder, workerCount, stackTraceLimit); } if (tests && tests.toLocaleLowerCase() === "rwc") { @@ -849,7 +890,7 @@ function runConsoleTests(defaultReporter, runInParallel) { } } function runLinter() { - if (!lintFlag) { + if (!lintFlag || dirty) { return; } var lint = jake.Task['lint']; @@ -866,8 +907,8 @@ task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], functio runConsoleTests('min', /*runInParallel*/ true); }, { async: true }); -desc("Runs the tests using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|] d[ebug]=true color[s]=false lint=true bail=false."); -task("runtests", ["build-rules", "tests", builtLocalDirectory], function () { +desc("Runs the tests using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|] d[ebug]=true color[s]=false lint=true bail=false dirty=false."); +task("runtests", ["build-rules", "tests", builtLocalDirectory], function() { runConsoleTests('mocha-fivemat-progress-reporter', /*runInParallel*/ false); }, { async: true }); @@ -884,8 +925,8 @@ var nodeServerInFile = "tests/webTestServer.ts"; compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true }); desc("Runs browserify on run.js to produce a file suitable for running tests in the browser"); -task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function () { - var cmd = 'browserify built/local/run.js -d -o built/local/bundle.js'; +task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function() { + var cmd = 'browserify built/local/run.js -t ./scripts/browserify-optional -d -o built/local/bundle.js'; exec(cmd); }, { async: true }); diff --git a/lib/tsc.js b/lib/tsc.js index 05a903f9014..0e3d7285ac3 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -825,17 +825,10 @@ var ts; return true; } ts.containsPath = containsPath; - function startsWith(str, prefix) { - return str.lastIndexOf(prefix, 0) === 0; - } - ts.startsWith = startsWith; - function endsWith(str, suffix) { - var expectedPos = str.length - suffix.length; - return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos; - } - ts.endsWith = endsWith; function fileExtensionIs(path, extension) { - return path.length > extension.length && endsWith(path, extension); + var pathLen = path.length; + var extLen = extension.length; + return pathLen > extLen && path.substr(pathLen - extLen, extLen) === extension; } ts.fileExtensionIs = fileExtensionIs; function fileExtensionIsAny(path, extensions) { @@ -1100,8 +1093,6 @@ var ts; } ts.objectAllocator = { getNodeConstructor: function () { return Node; }, - getTokenConstructor: function () { return Node; }, - getIdentifierConstructor: function () { return Node; }, getSourceFileConstructor: function () { return Node; }, getSymbolConstructor: function () { return Symbol; }, getTypeConstructor: function () { return Type; }, @@ -1233,7 +1224,7 @@ var ts; function readDirectory(path, extensions, excludes, includes) { return ts.matchFiles(path, extensions, excludes, includes, false, shell.CurrentDirectory, getAccessibleFileSystemEntries); } - var wscriptSystem = { + return { args: args, newLine: "\r\n", useCaseSensitiveFileNames: false, @@ -1252,7 +1243,7 @@ var ts; return fso.FolderExists(path); }, createDirectory: function (directoryName) { - if (!wscriptSystem.directoryExists(directoryName)) { + if (!this.directoryExists(directoryName)) { fso.CreateFolder(directoryName); } }, @@ -1272,7 +1263,6 @@ var ts; } } }; - return wscriptSystem; } function getNodeSystem() { var _fs = require("fs"); @@ -1445,7 +1435,7 @@ var ts; function getDirectories(path) { return ts.filter(_fs.readdirSync(path), function (p) { return fileSystemEntryExists(ts.combinePaths(path, p), 1); }); } - var nodeSystem = { + return { args: process.argv.slice(2), newLine: _os.EOL, useCaseSensitiveFileNames: useCaseSensitiveFileNames, @@ -1495,7 +1485,7 @@ var ts; fileExists: fileExists, directoryExists: directoryExists, createDirectory: function (directoryName) { - if (!nodeSystem.directoryExists(directoryName)) { + if (!this.directoryExists(directoryName)) { _fs.mkdirSync(directoryName); } }, @@ -1543,7 +1533,6 @@ var ts; return _fs.realpathSync(path); } }; - return nodeSystem; } function getChakraSystem() { var realpath = ChakraHost.realpath && (function (path) { return ChakraHost.realpath(path); }); @@ -2293,8 +2282,8 @@ var ts; Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: { code: 6131, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", message: "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'." }, File_name_0_has_a_1_extension_stripping_it: { code: 6132, category: ts.DiagnosticCategory.Message, key: "File_name_0_has_a_1_extension_stripping_it_6132", message: "File name '{0}' has a '{1}' extension - stripping it" }, _0_is_declared_but_never_used: { code: 6133, category: ts.DiagnosticCategory.Error, key: "_0_is_declared_but_never_used_6133", message: "'{0}' is declared but never used." }, - Report_errors_on_unused_locals: { code: 6134, category: ts.DiagnosticCategory.Message, key: "Report_errors_on_unused_locals_6134", message: "Report errors on unused locals." }, - Report_errors_on_unused_parameters: { code: 6135, category: ts.DiagnosticCategory.Message, key: "Report_errors_on_unused_parameters_6135", message: "Report errors on unused parameters." }, + Report_Errors_on_Unused_Locals: { code: 6134, category: ts.DiagnosticCategory.Message, key: "Report_Errors_on_Unused_Locals_6134", message: "Report Errors on Unused Locals." }, + Report_Errors_on_Unused_Parameters: { code: 6135, category: ts.DiagnosticCategory.Message, key: "Report_Errors_on_Unused_Parameters_6135", message: "Report Errors on Unused Parameters." }, The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files: { code: 6136, category: ts.DiagnosticCategory.Message, key: "The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files_6136", message: "The maximum dependency depth to search under node_modules and load JavaScript files" }, No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0: { code: 6137, category: ts.DiagnosticCategory.Message, key: "No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0_6137", message: "No types specified in 'package.json' but 'allowJs' is set, so returning 'main' value of '{0}'" }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." }, @@ -4847,7 +4836,7 @@ var ts; } ts.isExpression = isExpression; function isExternalModuleNameRelative(moduleName) { - return /^\.\.?($|[\\/])/.test(moduleName); + return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\"; } ts.isExternalModuleNameRelative = isExternalModuleNameRelative; function isInstantiatedModule(node, preserveConstEnums) { @@ -6355,24 +6344,25 @@ var ts; return node.flags & 92 && node.parent.kind === 148 && ts.isClassLike(node.parent.parent); } ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration; + function startsWith(str, prefix) { + return str.lastIndexOf(prefix, 0) === 0; + } + ts.startsWith = startsWith; + function endsWith(str, suffix) { + var expectedPos = str.length - suffix.length; + return str.indexOf(suffix, expectedPos) === expectedPos; + } + ts.endsWith = endsWith; })(ts || (ts = {})); var ts; (function (ts) { ts.parseTime = 0; var NodeConstructor; - var TokenConstructor; - var IdentifierConstructor; var SourceFileConstructor; function createNode(kind, pos, end) { if (kind === 256) { return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end); } - else if (kind === 69) { - return new (IdentifierConstructor || (IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor()))(kind, pos, end); - } - else if (kind < 139) { - return new (TokenConstructor || (TokenConstructor = ts.objectAllocator.getTokenConstructor()))(kind, pos, end); - } else { return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end); } @@ -6795,8 +6785,6 @@ var ts; var scanner = ts.createScanner(2, true); var disallowInAndDecoratorContext = 4194304 | 16777216; var NodeConstructor; - var TokenConstructor; - var IdentifierConstructor; var SourceFileConstructor; var sourceFile; var parseDiagnostics; @@ -6822,8 +6810,6 @@ var ts; } function initializeState(fileName, _sourceText, languageVersion, _syntaxCursor, scriptKind) { NodeConstructor = ts.objectAllocator.getNodeConstructor(); - TokenConstructor = ts.objectAllocator.getTokenConstructor(); - IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor(); SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor(); sourceText = _sourceText; syntaxCursor = _syntaxCursor; @@ -7130,9 +7116,7 @@ var ts; if (!(pos >= 0)) { pos = scanner.getStartPos(); } - return kind >= 139 ? new NodeConstructor(kind, pos, pos) : - kind === 69 ? new IdentifierConstructor(kind, pos, pos) : - new TokenConstructor(kind, pos, pos); + return new NodeConstructor(kind, pos, pos); } function finishNode(node, end) { node.end = end === undefined ? scanner.getStartPos() : end; @@ -10908,9 +10892,6 @@ var ts; case 55: if (canParseTag) { parentTagTerminated = !tryParseChildTag(jsDocTypeLiteral); - if (!parentTagTerminated) { - resumePos = scanner.getStartPos(); - } } seenAsterisk = false; break; @@ -15437,18 +15418,17 @@ var ts; if (declaration.kind === 235) { return links.type = checkExpression(declaration.expression); } - if (declaration.flags & 134217728 && declaration.kind === 280 && declaration.typeExpression) { - return links.type = getTypeFromTypeNode(declaration.typeExpression.type); - } if (!pushTypeResolution(symbol, 0)) { return unknownType; } var type = undefined; - if (declaration.kind === 187 || - declaration.kind === 172 && declaration.parent.kind === 187) { - type = getUnionType(ts.map(symbol.declarations, function (decl) { return decl.kind === 187 ? - checkExpressionCached(decl.right) : - checkExpressionCached(decl.parent.right); })); + if (declaration.kind === 187) { + type = getUnionType(ts.map(symbol.declarations, function (decl) { return checkExpressionCached(decl.right); })); + } + else if (declaration.kind === 172) { + if (declaration.parent.kind === 187) { + type = checkExpressionCached(declaration.parent.right); + } } if (type === undefined) { type = getWidenedTypeForVariableLikeDeclaration(declaration, true); @@ -21955,7 +21935,7 @@ var ts; function getInferredClassType(symbol) { var links = getSymbolLinks(symbol); if (!links.inferredClassType) { - links.inferredClassType = createAnonymousType(symbol, symbol.members, emptyArray, emptyArray, undefined, undefined); + links.inferredClassType = createAnonymousType(undefined, symbol.members, emptyArray, emptyArray, undefined, undefined); } return links.inferredClassType; } @@ -23175,7 +23155,7 @@ var ts; checkAsyncFunctionReturnType(node); } } - if (noUnusedIdentifiers && !node.body) { + if (!node.body) { checkUnusedTypeParameters(node); } } @@ -24071,7 +24051,6 @@ var ts; var parameter = local_1.valueDeclaration; if (compilerOptions.noUnusedParameters && !ts.isParameterPropertyDeclaration(parameter) && - !parameterIsThisKeyword(parameter) && !parameterNameStartsWithUnderscore(parameter)) { error(local_1.valueDeclaration.name, ts.Diagnostics._0_is_declared_but_never_used, local_1.name); } @@ -24087,9 +24066,6 @@ var ts; } } } - function parameterIsThisKeyword(parameter) { - return parameter.name && parameter.name.originalKeywordKind === 97; - } function parameterNameStartsWithUnderscore(parameter) { return parameter.name && parameter.name.kind === 69 && parameter.name.text.charCodeAt(0) === 95; } @@ -24118,14 +24094,9 @@ var ts; function checkUnusedTypeParameters(node) { if (compilerOptions.noUnusedLocals && !ts.isInAmbientContext(node)) { if (node.typeParameters) { - var symbol = getSymbolOfNode(node); - var lastDeclaration = symbol && symbol.declarations && ts.lastOrUndefined(symbol.declarations); - if (lastDeclaration !== node) { - return; - } for (var _i = 0, _a = node.typeParameters; _i < _a.length; _i++) { var typeParameter = _a[_i]; - if (!getMergedSymbol(typeParameter.symbol).isReferenced) { + if (!typeParameter.symbol.isReferenced) { error(typeParameter.name, ts.Diagnostics._0_is_declared_but_never_used, typeParameter.symbol.name); } } @@ -25202,7 +25173,7 @@ var ts; ts.forEach(node.members, checkSourceElement); if (produceDiagnostics) { checkTypeForDuplicateIndexSignatures(node); - registerForUnusedIdentifiersCheck(node); + checkUnusedTypeParameters(node); } } function checkTypeAliasDeclaration(node) { @@ -29925,7 +29896,7 @@ var ts; writeLine(); var sourceMappingURL = sourceMap.getSourceMappingURL(); if (sourceMappingURL) { - write("//# " + "sourceMappingURL" + "=" + sourceMappingURL); + write("//# sourceMappingURL=" + sourceMappingURL); } writeEmittedFiles(writer.getText(), jsFilePath, sourceMapFilePath, compilerOptions.emitBOM, sourceFiles); sourceMap.reset(); @@ -33575,13 +33546,13 @@ var ts; if (isES6ExportedDeclaration(node) && !(node.flags & 512) && decoratedClassAlias === undefined) { write("export "); } + if (!isHoistedDeclarationInSystemModule) { + write("let "); + } if (decoratedClassAlias !== undefined) { - write("let " + decoratedClassAlias); + write("" + decoratedClassAlias); } else { - if (!isHoistedDeclarationInSystemModule) { - write("let "); - } emitDeclarationName(node); } write(" = "); @@ -35825,7 +35796,7 @@ var ts; ts.emitTime = 0; ts.ioReadTime = 0; ts.ioWriteTime = 0; - ts.version = "2.1.0"; + ts.version = "2.0.0"; var emptyArray = []; var defaultTypeRoots = ["node_modules/@types"]; function findConfigFile(searchPath, fileExists) { @@ -35905,7 +35876,12 @@ var ts; return { resolvedModule: resolvedFileName ? { resolvedFileName: resolvedFileName, isExternalLibraryImport: isExternalLibraryImport } : undefined, failedLookupLocations: failedLookupLocations }; } function moduleHasNonRelativeName(moduleName) { - return !(ts.isRootedDiskPath(moduleName) || ts.isExternalModuleNameRelative(moduleName)); + if (ts.isRootedDiskPath(moduleName)) { + return false; + } + var i = moduleName.lastIndexOf("./", 1); + var startsWithDotSlashOrDotDotSlash = i === 0 || (i === 1 && moduleName.charCodeAt(0) === 46); + return !startsWithDotSlashOrDotDotSlash; } function tryReadTypesSection(packageJsonPath, baseDirectory, state) { var jsonContent; @@ -36561,22 +36537,6 @@ var ts; return ts.sortAndDeduplicateDiagnostics(diagnostics); } ts.getPreEmitDiagnostics = getPreEmitDiagnostics; - function formatDiagnostics(diagnostics, host) { - var output = ""; - for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) { - var diagnostic = diagnostics_1[_i]; - if (diagnostic.file) { - var _a = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start), line = _a.line, character = _a.character; - var fileName = diagnostic.file.fileName; - var relativeFileName = ts.convertToRelativePath(fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }); - output += relativeFileName + "(" + (line + 1) + "," + (character + 1) + "): "; - } - var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase(); - output += category + " TS" + diagnostic.code + ": " + flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) + host.getNewLine(); - } - return output; - } - ts.formatDiagnostics = formatDiagnostics; function flattenDiagnosticMessageText(messageText, newLine) { if (typeof messageText === "string") { return messageText; @@ -36652,7 +36612,7 @@ var ts; var resolvedTypeReferenceDirectives = {}; var fileProcessingDiagnostics = ts.createDiagnosticCollection(); var maxNodeModulesJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 2; - var currentNodeModulesDepth = 0; + var currentNodeModulesJsDepth = 0; var modulesWithElidedImports = {}; var sourceFilesFoundSearchingNodeModules = {}; var start = new Date().getTime(); @@ -36876,7 +36836,8 @@ var ts; return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = ts.createTypeChecker(program, false)); } function emit(sourceFile, writeFileCallback, cancellationToken) { - return runWithCancellationToken(function () { return emitWorker(program, sourceFile, writeFileCallback, cancellationToken); }); + var _this = this; + return runWithCancellationToken(function () { return emitWorker(_this, sourceFile, writeFileCallback, cancellationToken); }); } function isEmitBlocked(emitFileName) { return hasEmitBlockingDiagnostics.contains(ts.toPath(emitFileName, currentDirectory, getCanonicalFileName)); @@ -37283,17 +37244,8 @@ var ts; if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) { reportFileNamesDifferOnlyInCasingError(fileName, file_1.fileName, refFile, refPos, refEnd); } - if (file_1 && ts.lookUp(sourceFilesFoundSearchingNodeModules, file_1.path) && currentNodeModulesDepth == 0) { - sourceFilesFoundSearchingNodeModules[file_1.path] = false; - if (!options.noResolve) { - processReferencedFiles(file_1, ts.getDirectoryPath(fileName), isDefaultLib); - processTypeReferenceDirectives(file_1); - } - modulesWithElidedImports[file_1.path] = false; - processImportedModules(file_1, ts.getDirectoryPath(fileName)); - } - else if (file_1 && ts.lookUp(modulesWithElidedImports, file_1.path)) { - if (currentNodeModulesDepth < maxNodeModulesJsDepth) { + if (file_1 && ts.lookUp(modulesWithElidedImports, file_1.path)) { + if (currentNodeModulesJsDepth < maxNodeModulesJsDepth) { modulesWithElidedImports[file_1.path] = false; processImportedModules(file_1, ts.getDirectoryPath(fileName)); } @@ -37310,7 +37262,6 @@ var ts; }); filesByName.set(path, file); if (file) { - sourceFilesFoundSearchingNodeModules[path] = (currentNodeModulesDepth > 0); file.path = path; if (host.useCaseSensitiveFileNames()) { var existingFile = filesByNameIgnoreCase.get(path); @@ -37411,9 +37362,12 @@ var ts; var isFromNodeModulesSearch = resolution && resolution.isExternalLibraryImport; var isJsFileFromNodeModules = isFromNodeModulesSearch && ts.hasJavaScriptFileExtension(resolution.resolvedFileName); if (isFromNodeModulesSearch) { - currentNodeModulesDepth++; + sourceFilesFoundSearchingNodeModules[resolvedPath] = true; } - var elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModulesJsDepth; + if (isJsFileFromNodeModules) { + currentNodeModulesJsDepth++; + } + var elideImport = isJsFileFromNodeModules && currentNodeModulesJsDepth > maxNodeModulesJsDepth; var shouldAddFile = resolution && !options.noResolve && i < file.imports.length && !elideImport; if (elideImport) { modulesWithElidedImports[file.path] = true; @@ -37421,8 +37375,8 @@ var ts; else if (shouldAddFile) { findSourceFile(resolution.resolvedFileName, resolvedPath, false, false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); } - if (isFromNodeModulesSearch) { - currentNodeModulesDepth--; + if (isJsFileFromNodeModules) { + currentNodeModulesJsDepth--; } } } @@ -37741,12 +37695,12 @@ var ts; { name: "noUnusedLocals", type: "boolean", - description: ts.Diagnostics.Report_errors_on_unused_locals + description: ts.Diagnostics.Report_Errors_on_Unused_Locals }, { name: "noUnusedParameters", type: "boolean", - description: ts.Diagnostics.Report_errors_on_unused_parameters + description: ts.Diagnostics.Report_Errors_on_Unused_Parameters }, { name: "noLib", @@ -38525,18 +38479,10 @@ var ts; })(ts || (ts = {})); var ts; (function (ts) { - var defaultFormatDiagnosticsHost = { - getCurrentDirectory: function () { return ts.sys.getCurrentDirectory(); }, - getNewLine: function () { return ts.sys.newLine; }, - getCanonicalFileName: ts.createGetCanonicalFileName(ts.sys.useCaseSensitiveFileNames) - }; - var reportDiagnosticWorker = reportDiagnosticSimply; - function reportDiagnostic(diagnostic, host) { - reportDiagnosticWorker(diagnostic, host || defaultFormatDiagnosticsHost); - } + var reportDiagnostic = reportDiagnosticSimply; function reportDiagnostics(diagnostics, host) { - for (var _i = 0, diagnostics_2 = diagnostics; _i < diagnostics_2.length; _i++) { - var diagnostic = diagnostics_2[_i]; + for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) { + var diagnostic = diagnostics_1[_i]; reportDiagnostic(diagnostic, host); } } @@ -38607,8 +38553,19 @@ var ts; var diagnostic = ts.createCompilerDiagnostic.apply(undefined, arguments); return diagnostic.messageText; } + function getRelativeFileName(fileName, host) { + return host ? ts.convertToRelativePath(fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }) : fileName; + } function reportDiagnosticSimply(diagnostic, host) { - ts.sys.write(ts.formatDiagnostics([diagnostic], host)); + var output = ""; + if (diagnostic.file) { + var _a = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start), line = _a.line, character = _a.character; + var relativeFileName = getRelativeFileName(diagnostic.file.fileName, host); + output += relativeFileName + "(" + (line + 1) + "," + (character + 1) + "): "; + } + var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase(); + output += category + " TS" + diagnostic.code + ": " + ts.flattenDiagnosticMessageText(diagnostic.messageText, ts.sys.newLine) + ts.sys.newLine; + ts.sys.write(output); } var redForegroundEscapeSequence = "\u001b[91m"; var yellowForegroundEscapeSequence = "\u001b[93m"; @@ -38633,7 +38590,7 @@ var ts; var _a = ts.getLineAndCharacterOfPosition(file, start), firstLine = _a.line, firstLineChar = _a.character; var _b = ts.getLineAndCharacterOfPosition(file, start + length_3), lastLine = _b.line, lastLineChar = _b.character; var lastLineInFile = ts.getLineAndCharacterOfPosition(file, file.text.length).line; - var relativeFileName = host ? ts.convertToRelativePath(file.fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }) : file.fileName; + var relativeFileName = getRelativeFileName(file.fileName, host); var hasMoreThanFiveLines = (lastLine - firstLine) >= 4; var gutterWidth = (lastLine + 1 + "").length; if (hasMoreThanFiveLines) { @@ -38822,8 +38779,7 @@ var ts; ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); return; } - var cwd = ts.sys.getCurrentDirectory(); - var configParseResult = ts.parseJsonConfigFileContent(configObject, ts.sys, ts.getNormalizedAbsolutePath(ts.getDirectoryPath(configFileName), cwd), commandLine.options, ts.getNormalizedAbsolutePath(configFileName, cwd)); + var configParseResult = ts.parseJsonConfigFileContent(configObject, ts.sys, ts.getNormalizedAbsolutePath(ts.getDirectoryPath(configFileName), ts.sys.getCurrentDirectory()), commandLine.options, configFileName); if (configParseResult.errors.length > 0) { reportDiagnostics(configParseResult.errors, undefined); ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); @@ -38860,7 +38816,7 @@ var ts; compilerHost.fileExists = cachedFileExists; } if (compilerOptions.pretty) { - reportDiagnosticWorker = reportDiagnosticWithColorAndContext; + reportDiagnostic = reportDiagnosticWithColorAndContext; } cachedExistingFiles = {}; var compileResult = compile(rootFileNames, compilerOptions, compilerHost); @@ -39023,7 +38979,7 @@ var ts; output += ts.sys.newLine + ts.sys.newLine; var padding = makePadding(marginLength); output += getDiagnosticText(ts.Diagnostics.Examples_Colon_0, makePadding(marginLength - examplesLength) + "tsc hello.ts") + ts.sys.newLine; - output += padding + "tsc --outFile file.js file.ts" + ts.sys.newLine; + output += padding + "tsc --out file.js file.ts" + ts.sys.newLine; output += padding + "tsc @args.txt" + ts.sys.newLine; output += ts.sys.newLine; output += getDiagnosticText(ts.Diagnostics.Options_Colon) + ts.sys.newLine; diff --git a/lib/tsserver.js b/lib/tsserver.js index 7e0dda1736e..af6ee897902 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -830,17 +830,10 @@ var ts; return true; } ts.containsPath = containsPath; - function startsWith(str, prefix) { - return str.lastIndexOf(prefix, 0) === 0; - } - ts.startsWith = startsWith; - function endsWith(str, suffix) { - var expectedPos = str.length - suffix.length; - return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos; - } - ts.endsWith = endsWith; function fileExtensionIs(path, extension) { - return path.length > extension.length && endsWith(path, extension); + var pathLen = path.length; + var extLen = extension.length; + return pathLen > extLen && path.substr(pathLen - extLen, extLen) === extension; } ts.fileExtensionIs = fileExtensionIs; function fileExtensionIsAny(path, extensions) { @@ -1105,8 +1098,6 @@ var ts; } ts.objectAllocator = { getNodeConstructor: function () { return Node; }, - getTokenConstructor: function () { return Node; }, - getIdentifierConstructor: function () { return Node; }, getSourceFileConstructor: function () { return Node; }, getSymbolConstructor: function () { return Symbol; }, getTypeConstructor: function () { return Type; }, @@ -1238,7 +1229,7 @@ var ts; function readDirectory(path, extensions, excludes, includes) { return ts.matchFiles(path, extensions, excludes, includes, false, shell.CurrentDirectory, getAccessibleFileSystemEntries); } - var wscriptSystem = { + return { args: args, newLine: "\r\n", useCaseSensitiveFileNames: false, @@ -1257,7 +1248,7 @@ var ts; return fso.FolderExists(path); }, createDirectory: function (directoryName) { - if (!wscriptSystem.directoryExists(directoryName)) { + if (!this.directoryExists(directoryName)) { fso.CreateFolder(directoryName); } }, @@ -1277,7 +1268,6 @@ var ts; } } }; - return wscriptSystem; } function getNodeSystem() { var _fs = require("fs"); @@ -1450,7 +1440,7 @@ var ts; function getDirectories(path) { return ts.filter(_fs.readdirSync(path), function (p) { return fileSystemEntryExists(ts.combinePaths(path, p), 1); }); } - var nodeSystem = { + return { args: process.argv.slice(2), newLine: _os.EOL, useCaseSensitiveFileNames: useCaseSensitiveFileNames, @@ -1500,7 +1490,7 @@ var ts; fileExists: fileExists, directoryExists: directoryExists, createDirectory: function (directoryName) { - if (!nodeSystem.directoryExists(directoryName)) { + if (!this.directoryExists(directoryName)) { _fs.mkdirSync(directoryName); } }, @@ -1548,7 +1538,6 @@ var ts; return _fs.realpathSync(path); } }; - return nodeSystem; } function getChakraSystem() { var realpath = ChakraHost.realpath && (function (path) { return ChakraHost.realpath(path); }); @@ -2298,8 +2287,8 @@ var ts; Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: { code: 6131, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", message: "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'." }, File_name_0_has_a_1_extension_stripping_it: { code: 6132, category: ts.DiagnosticCategory.Message, key: "File_name_0_has_a_1_extension_stripping_it_6132", message: "File name '{0}' has a '{1}' extension - stripping it" }, _0_is_declared_but_never_used: { code: 6133, category: ts.DiagnosticCategory.Error, key: "_0_is_declared_but_never_used_6133", message: "'{0}' is declared but never used." }, - Report_errors_on_unused_locals: { code: 6134, category: ts.DiagnosticCategory.Message, key: "Report_errors_on_unused_locals_6134", message: "Report errors on unused locals." }, - Report_errors_on_unused_parameters: { code: 6135, category: ts.DiagnosticCategory.Message, key: "Report_errors_on_unused_parameters_6135", message: "Report errors on unused parameters." }, + Report_Errors_on_Unused_Locals: { code: 6134, category: ts.DiagnosticCategory.Message, key: "Report_Errors_on_Unused_Locals_6134", message: "Report Errors on Unused Locals." }, + Report_Errors_on_Unused_Parameters: { code: 6135, category: ts.DiagnosticCategory.Message, key: "Report_Errors_on_Unused_Parameters_6135", message: "Report Errors on Unused Parameters." }, The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files: { code: 6136, category: ts.DiagnosticCategory.Message, key: "The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files_6136", message: "The maximum dependency depth to search under node_modules and load JavaScript files" }, No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0: { code: 6137, category: ts.DiagnosticCategory.Message, key: "No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0_6137", message: "No types specified in 'package.json' but 'allowJs' is set, so returning 'main' value of '{0}'" }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." }, @@ -3977,12 +3966,12 @@ var ts; { name: "noUnusedLocals", type: "boolean", - description: ts.Diagnostics.Report_errors_on_unused_locals + description: ts.Diagnostics.Report_Errors_on_Unused_Locals }, { name: "noUnusedParameters", type: "boolean", - description: ts.Diagnostics.Report_errors_on_unused_parameters + description: ts.Diagnostics.Report_Errors_on_Unused_Parameters }, { name: "noLib", @@ -5765,7 +5754,7 @@ var ts; } ts.isExpression = isExpression; function isExternalModuleNameRelative(moduleName) { - return /^\.\.?($|[\\/])/.test(moduleName); + return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\"; } ts.isExternalModuleNameRelative = isExternalModuleNameRelative; function isInstantiatedModule(node, preserveConstEnums) { @@ -7273,24 +7262,25 @@ var ts; return node.flags & 92 && node.parent.kind === 148 && ts.isClassLike(node.parent.parent); } ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration; + function startsWith(str, prefix) { + return str.lastIndexOf(prefix, 0) === 0; + } + ts.startsWith = startsWith; + function endsWith(str, suffix) { + var expectedPos = str.length - suffix.length; + return str.indexOf(suffix, expectedPos) === expectedPos; + } + ts.endsWith = endsWith; })(ts || (ts = {})); var ts; (function (ts) { ts.parseTime = 0; var NodeConstructor; - var TokenConstructor; - var IdentifierConstructor; var SourceFileConstructor; function createNode(kind, pos, end) { if (kind === 256) { return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end); } - else if (kind === 69) { - return new (IdentifierConstructor || (IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor()))(kind, pos, end); - } - else if (kind < 139) { - return new (TokenConstructor || (TokenConstructor = ts.objectAllocator.getTokenConstructor()))(kind, pos, end); - } else { return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end); } @@ -7713,8 +7703,6 @@ var ts; var scanner = ts.createScanner(2, true); var disallowInAndDecoratorContext = 4194304 | 16777216; var NodeConstructor; - var TokenConstructor; - var IdentifierConstructor; var SourceFileConstructor; var sourceFile; var parseDiagnostics; @@ -7740,8 +7728,6 @@ var ts; } function initializeState(fileName, _sourceText, languageVersion, _syntaxCursor, scriptKind) { NodeConstructor = ts.objectAllocator.getNodeConstructor(); - TokenConstructor = ts.objectAllocator.getTokenConstructor(); - IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor(); SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor(); sourceText = _sourceText; syntaxCursor = _syntaxCursor; @@ -8048,9 +8034,7 @@ var ts; if (!(pos >= 0)) { pos = scanner.getStartPos(); } - return kind >= 139 ? new NodeConstructor(kind, pos, pos) : - kind === 69 ? new IdentifierConstructor(kind, pos, pos) : - new TokenConstructor(kind, pos, pos); + return new NodeConstructor(kind, pos, pos); } function finishNode(node, end) { node.end = end === undefined ? scanner.getStartPos() : end; @@ -11826,9 +11810,6 @@ var ts; case 55: if (canParseTag) { parentTagTerminated = !tryParseChildTag(jsDocTypeLiteral); - if (!parentTagTerminated) { - resumePos = scanner.getStartPos(); - } } seenAsterisk = false; break; @@ -16355,18 +16336,17 @@ var ts; if (declaration.kind === 235) { return links.type = checkExpression(declaration.expression); } - if (declaration.flags & 134217728 && declaration.kind === 280 && declaration.typeExpression) { - return links.type = getTypeFromTypeNode(declaration.typeExpression.type); - } if (!pushTypeResolution(symbol, 0)) { return unknownType; } var type = undefined; - if (declaration.kind === 187 || - declaration.kind === 172 && declaration.parent.kind === 187) { - type = getUnionType(ts.map(symbol.declarations, function (decl) { return decl.kind === 187 ? - checkExpressionCached(decl.right) : - checkExpressionCached(decl.parent.right); })); + if (declaration.kind === 187) { + type = getUnionType(ts.map(symbol.declarations, function (decl) { return checkExpressionCached(decl.right); })); + } + else if (declaration.kind === 172) { + if (declaration.parent.kind === 187) { + type = checkExpressionCached(declaration.parent.right); + } } if (type === undefined) { type = getWidenedTypeForVariableLikeDeclaration(declaration, true); @@ -22873,7 +22853,7 @@ var ts; function getInferredClassType(symbol) { var links = getSymbolLinks(symbol); if (!links.inferredClassType) { - links.inferredClassType = createAnonymousType(symbol, symbol.members, emptyArray, emptyArray, undefined, undefined); + links.inferredClassType = createAnonymousType(undefined, symbol.members, emptyArray, emptyArray, undefined, undefined); } return links.inferredClassType; } @@ -24093,7 +24073,7 @@ var ts; checkAsyncFunctionReturnType(node); } } - if (noUnusedIdentifiers && !node.body) { + if (!node.body) { checkUnusedTypeParameters(node); } } @@ -24989,7 +24969,6 @@ var ts; var parameter = local_1.valueDeclaration; if (compilerOptions.noUnusedParameters && !ts.isParameterPropertyDeclaration(parameter) && - !parameterIsThisKeyword(parameter) && !parameterNameStartsWithUnderscore(parameter)) { error(local_1.valueDeclaration.name, ts.Diagnostics._0_is_declared_but_never_used, local_1.name); } @@ -25005,9 +24984,6 @@ var ts; } } } - function parameterIsThisKeyword(parameter) { - return parameter.name && parameter.name.originalKeywordKind === 97; - } function parameterNameStartsWithUnderscore(parameter) { return parameter.name && parameter.name.kind === 69 && parameter.name.text.charCodeAt(0) === 95; } @@ -25036,14 +25012,9 @@ var ts; function checkUnusedTypeParameters(node) { if (compilerOptions.noUnusedLocals && !ts.isInAmbientContext(node)) { if (node.typeParameters) { - var symbol = getSymbolOfNode(node); - var lastDeclaration = symbol && symbol.declarations && ts.lastOrUndefined(symbol.declarations); - if (lastDeclaration !== node) { - return; - } for (var _i = 0, _a = node.typeParameters; _i < _a.length; _i++) { var typeParameter = _a[_i]; - if (!getMergedSymbol(typeParameter.symbol).isReferenced) { + if (!typeParameter.symbol.isReferenced) { error(typeParameter.name, ts.Diagnostics._0_is_declared_but_never_used, typeParameter.symbol.name); } } @@ -26120,7 +26091,7 @@ var ts; ts.forEach(node.members, checkSourceElement); if (produceDiagnostics) { checkTypeForDuplicateIndexSignatures(node); - registerForUnusedIdentifiersCheck(node); + checkUnusedTypeParameters(node); } } function checkTypeAliasDeclaration(node) { @@ -30843,7 +30814,7 @@ var ts; writeLine(); var sourceMappingURL = sourceMap.getSourceMappingURL(); if (sourceMappingURL) { - write("//# " + "sourceMappingURL" + "=" + sourceMappingURL); + write("//# sourceMappingURL=" + sourceMappingURL); } writeEmittedFiles(writer.getText(), jsFilePath, sourceMapFilePath, compilerOptions.emitBOM, sourceFiles); sourceMap.reset(); @@ -34493,13 +34464,13 @@ var ts; if (isES6ExportedDeclaration(node) && !(node.flags & 512) && decoratedClassAlias === undefined) { write("export "); } + if (!isHoistedDeclarationInSystemModule) { + write("let "); + } if (decoratedClassAlias !== undefined) { - write("let " + decoratedClassAlias); + write("" + decoratedClassAlias); } else { - if (!isHoistedDeclarationInSystemModule) { - write("let "); - } emitDeclarationName(node); } write(" = "); @@ -36743,7 +36714,7 @@ var ts; ts.emitTime = 0; ts.ioReadTime = 0; ts.ioWriteTime = 0; - ts.version = "2.1.0"; + ts.version = "2.0.0"; var emptyArray = []; var defaultTypeRoots = ["node_modules/@types"]; function findConfigFile(searchPath, fileExists) { @@ -36823,7 +36794,12 @@ var ts; return { resolvedModule: resolvedFileName ? { resolvedFileName: resolvedFileName, isExternalLibraryImport: isExternalLibraryImport } : undefined, failedLookupLocations: failedLookupLocations }; } function moduleHasNonRelativeName(moduleName) { - return !(ts.isRootedDiskPath(moduleName) || ts.isExternalModuleNameRelative(moduleName)); + if (ts.isRootedDiskPath(moduleName)) { + return false; + } + var i = moduleName.lastIndexOf("./", 1); + var startsWithDotSlashOrDotDotSlash = i === 0 || (i === 1 && moduleName.charCodeAt(0) === 46); + return !startsWithDotSlashOrDotDotSlash; } function tryReadTypesSection(packageJsonPath, baseDirectory, state) { var jsonContent; @@ -37479,22 +37455,6 @@ var ts; return ts.sortAndDeduplicateDiagnostics(diagnostics); } ts.getPreEmitDiagnostics = getPreEmitDiagnostics; - function formatDiagnostics(diagnostics, host) { - var output = ""; - for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) { - var diagnostic = diagnostics_1[_i]; - if (diagnostic.file) { - var _a = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start), line = _a.line, character = _a.character; - var fileName = diagnostic.file.fileName; - var relativeFileName = ts.convertToRelativePath(fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }); - output += relativeFileName + "(" + (line + 1) + "," + (character + 1) + "): "; - } - var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase(); - output += category + " TS" + diagnostic.code + ": " + flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) + host.getNewLine(); - } - return output; - } - ts.formatDiagnostics = formatDiagnostics; function flattenDiagnosticMessageText(messageText, newLine) { if (typeof messageText === "string") { return messageText; @@ -37570,7 +37530,7 @@ var ts; var resolvedTypeReferenceDirectives = {}; var fileProcessingDiagnostics = ts.createDiagnosticCollection(); var maxNodeModulesJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 2; - var currentNodeModulesDepth = 0; + var currentNodeModulesJsDepth = 0; var modulesWithElidedImports = {}; var sourceFilesFoundSearchingNodeModules = {}; var start = new Date().getTime(); @@ -37794,7 +37754,8 @@ var ts; return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = ts.createTypeChecker(program, false)); } function emit(sourceFile, writeFileCallback, cancellationToken) { - return runWithCancellationToken(function () { return emitWorker(program, sourceFile, writeFileCallback, cancellationToken); }); + var _this = this; + return runWithCancellationToken(function () { return emitWorker(_this, sourceFile, writeFileCallback, cancellationToken); }); } function isEmitBlocked(emitFileName) { return hasEmitBlockingDiagnostics.contains(ts.toPath(emitFileName, currentDirectory, getCanonicalFileName)); @@ -38201,17 +38162,8 @@ var ts; if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) { reportFileNamesDifferOnlyInCasingError(fileName, file_1.fileName, refFile, refPos, refEnd); } - if (file_1 && ts.lookUp(sourceFilesFoundSearchingNodeModules, file_1.path) && currentNodeModulesDepth == 0) { - sourceFilesFoundSearchingNodeModules[file_1.path] = false; - if (!options.noResolve) { - processReferencedFiles(file_1, ts.getDirectoryPath(fileName), isDefaultLib); - processTypeReferenceDirectives(file_1); - } - modulesWithElidedImports[file_1.path] = false; - processImportedModules(file_1, ts.getDirectoryPath(fileName)); - } - else if (file_1 && ts.lookUp(modulesWithElidedImports, file_1.path)) { - if (currentNodeModulesDepth < maxNodeModulesJsDepth) { + if (file_1 && ts.lookUp(modulesWithElidedImports, file_1.path)) { + if (currentNodeModulesJsDepth < maxNodeModulesJsDepth) { modulesWithElidedImports[file_1.path] = false; processImportedModules(file_1, ts.getDirectoryPath(fileName)); } @@ -38228,7 +38180,6 @@ var ts; }); filesByName.set(path, file); if (file) { - sourceFilesFoundSearchingNodeModules[path] = (currentNodeModulesDepth > 0); file.path = path; if (host.useCaseSensitiveFileNames()) { var existingFile = filesByNameIgnoreCase.get(path); @@ -38329,9 +38280,12 @@ var ts; var isFromNodeModulesSearch = resolution && resolution.isExternalLibraryImport; var isJsFileFromNodeModules = isFromNodeModulesSearch && ts.hasJavaScriptFileExtension(resolution.resolvedFileName); if (isFromNodeModulesSearch) { - currentNodeModulesDepth++; + sourceFilesFoundSearchingNodeModules[resolvedPath] = true; } - var elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModulesJsDepth; + if (isJsFileFromNodeModules) { + currentNodeModulesJsDepth++; + } + var elideImport = isJsFileFromNodeModules && currentNodeModulesJsDepth > maxNodeModulesJsDepth; var shouldAddFile = resolution && !options.noResolve && i < file.imports.length && !elideImport; if (elideImport) { modulesWithElidedImports[file.path] = true; @@ -38339,8 +38293,8 @@ var ts; else if (shouldAddFile) { findSourceFile(resolution.resolvedFileName, resolvedPath, false, false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); } - if (isFromNodeModulesSearch) { - currentNodeModulesDepth--; + if (isJsFileFromNodeModules) { + currentNodeModulesJsDepth--; } } } @@ -39933,7 +39887,7 @@ var ts; return createPatternMatch(PatternMatchKind.exact, punctuationStripped, candidate === chunk.text); } else { - return createPatternMatch(PatternMatchKind.prefix, punctuationStripped, ts.startsWith(candidate, chunk.text)); + return createPatternMatch(PatternMatchKind.prefix, punctuationStripped, startsWith(candidate, chunk.text)); } } var isLowercase = chunk.isLowerCase; @@ -40105,6 +40059,14 @@ var ts; var str = String.fromCharCode(ch); return str === str.toLowerCase(); } + function startsWith(string, search) { + for (var i = 0, n = search.length; i < n; i++) { + if (string.charCodeAt(i) !== search.charCodeAt(i)) { + return false; + } + } + return true; + } function indexOfIgnoringCase(string, value) { for (var i = 0, n = string.length - value.length; i <= n; i++) { if (startsWithIgnoringCase(string, value, i)) { @@ -41589,9 +41551,6 @@ var ts; } return false; } - function shouldRescanJsxText(node) { - return node && node.kind === 244; - } function shouldRescanSlashToken(container) { return container.kind === 10; } @@ -41619,9 +41578,7 @@ var ts; ? 3 : shouldRescanJsxIdentifier(n) ? 4 - : shouldRescanJsxText(n) - ? 5 - : 0; + : 0; if (lastTokenInfo && expectedScanAction === lastScanAction) { return fixTokenKind(lastTokenInfo, n); } @@ -41649,10 +41606,6 @@ var ts; currentToken = scanner.scanJsxIdentifier(); lastScanAction = 4; } - else if (expectedScanAction === 5) { - currentToken = scanner.reScanJsxToken(); - lastScanAction = 5; - } else { lastScanAction = 0; } @@ -43901,20 +43854,19 @@ var ts; "version" ]; var jsDocCompletionEntries; - function createNode(kind, pos, end, parent) { - var node = kind >= 139 ? new NodeObject(kind, pos, end) : - kind === 69 ? new IdentifierObject(kind, pos, end) : - new TokenObject(kind, pos, end); + function createNode(kind, pos, end, flags, parent) { + var node = new NodeObject(kind, pos, end); + node.flags = flags; node.parent = parent; return node; } var NodeObject = (function () { function NodeObject(kind, pos, end) { + this.kind = kind; this.pos = pos; this.end = end; this.flags = 0; this.parent = undefined; - this.kind = kind; } NodeObject.prototype.getSourceFile = function () { return ts.getSourceFileOfNode(this); @@ -43949,14 +43901,14 @@ var ts; var token = useJSDocScanner ? scanner.scanJSDocToken() : scanner.scan(); var textPos = scanner.getTextPos(); if (textPos <= end) { - nodes.push(createNode(token, pos, textPos, this)); + nodes.push(createNode(token, pos, textPos, 0, this)); } pos = textPos; } return pos; }; NodeObject.prototype.createSyntaxList = function (nodes) { - var list = createNode(282, nodes.pos, nodes.end, this); + var list = createNode(282, nodes.pos, nodes.end, 0, this); list._children = []; var pos = nodes.pos; for (var _i = 0, nodes_4 = nodes; _i < nodes_4.length; _i++) { @@ -44041,73 +43993,6 @@ var ts; }; return NodeObject; }()); - var TokenOrIdentifierObject = (function () { - function TokenOrIdentifierObject(pos, end) { - this.pos = pos; - this.end = end; - this.flags = 0; - this.parent = undefined; - } - TokenOrIdentifierObject.prototype.getSourceFile = function () { - return ts.getSourceFileOfNode(this); - }; - TokenOrIdentifierObject.prototype.getStart = function (sourceFile, includeJsDocComment) { - return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment); - }; - TokenOrIdentifierObject.prototype.getFullStart = function () { - return this.pos; - }; - TokenOrIdentifierObject.prototype.getEnd = function () { - return this.end; - }; - TokenOrIdentifierObject.prototype.getWidth = function (sourceFile) { - return this.getEnd() - this.getStart(sourceFile); - }; - TokenOrIdentifierObject.prototype.getFullWidth = function () { - return this.end - this.pos; - }; - TokenOrIdentifierObject.prototype.getLeadingTriviaWidth = function (sourceFile) { - return this.getStart(sourceFile) - this.pos; - }; - TokenOrIdentifierObject.prototype.getFullText = function (sourceFile) { - return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end); - }; - TokenOrIdentifierObject.prototype.getText = function (sourceFile) { - return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd()); - }; - TokenOrIdentifierObject.prototype.getChildCount = function (sourceFile) { - return 0; - }; - TokenOrIdentifierObject.prototype.getChildAt = function (index, sourceFile) { - return undefined; - }; - TokenOrIdentifierObject.prototype.getChildren = function (sourceFile) { - return emptyArray; - }; - TokenOrIdentifierObject.prototype.getFirstToken = function (sourceFile) { - return undefined; - }; - TokenOrIdentifierObject.prototype.getLastToken = function (sourceFile) { - return undefined; - }; - return TokenOrIdentifierObject; - }()); - var TokenObject = (function (_super) { - __extends(TokenObject, _super); - function TokenObject(kind, pos, end) { - _super.call(this, pos, end); - this.kind = kind; - } - return TokenObject; - }(TokenOrIdentifierObject)); - var IdentifierObject = (function (_super) { - __extends(IdentifierObject, _super); - function IdentifierObject(kind, pos, end) { - _super.call(this, pos, end); - } - return IdentifierObject; - }(TokenOrIdentifierObject)); - IdentifierObject.prototype.kind = 69; var SymbolObject = (function () { function SymbolObject(flags, name) { this.flags = flags; @@ -49788,8 +49673,6 @@ var ts; function initializeServices() { ts.objectAllocator = { getNodeConstructor: function () { return NodeObject; }, - getTokenConstructor: function () { return TokenObject; }, - getIdentifierConstructor: function () { return IdentifierObject; }, getSourceFileConstructor: function () { return SourceFileObject; }, getSymbolConstructor: function () { return SymbolObject; }, getTypeConstructor: function () { return TypeObject; }, @@ -50910,6 +50793,7 @@ var ts; if (isOpen === void 0) { isOpen = false; } this.host = host; this.fileName = fileName; + this.content = content; this.isOpen = isOpen; this.children = []; this.formatCodeOptions = ts.clone(CompilerService.getDefaultFormatCodeOptions(this.host)); @@ -52535,7 +52419,7 @@ var ts; done: false, leaf: function (relativeStart, relativeLength, ll) { if (!f(ll, relativeStart, relativeLength)) { - walkFns.done = true; + this.done = true; } } }; @@ -53185,7 +53069,7 @@ var ts; ioSession.listen(); })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); -var debugObjectHost = new Function("return this")(); +var debugObjectHost = this; var ts; (function (ts) { function logInternalError(logger, err) { @@ -53313,7 +53197,7 @@ var ts; return this.shimHost.getCurrentDirectory(); }; LanguageServiceShimHostAdapter.prototype.getDirectories = function (path) { - return JSON.parse(this.shimHost.getDirectories(path)); + return this.shimHost.getDirectories(path); }; LanguageServiceShimHostAdapter.prototype.getDefaultLibFileName = function (options) { return this.shimHost.getDefaultLibFileName(JSON.stringify(options)); diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index 1821c212574..2c9fffcfcfb 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -405,10 +405,7 @@ declare namespace ts { interface ModifiersArray extends NodeArray { flags: NodeFlags; } - interface Token extends Node { - __tokenTag: any; - } - interface Modifier extends Token { + interface Modifier extends Node { } interface Identifier extends PrimaryExpression { text: string; @@ -2053,6 +2050,7 @@ declare namespace ts { getCancellationToken?(): CancellationToken; getDefaultLibFileName(options: CompilerOptions): string; getDefaultLibLocation?(): string; + getDefaultTypeDirectiveNames?(rootPath: string): string[]; writeFile: WriteFileCallback; getCurrentDirectory(): string; getDirectories(path: string): string[]; @@ -2158,8 +2156,6 @@ declare namespace ts { function ensureTrailingDirectorySeparator(path: string): string; function comparePaths(a: string, b: string, currentDirectory: string, ignoreCase?: boolean): Comparison; function containsPath(parent: string, child: string, currentDirectory: string, ignoreCase?: boolean): boolean; - function startsWith(str: string, prefix: string): boolean; - function endsWith(str: string, suffix: string): boolean; function fileExtensionIs(path: string, extension: string): boolean; function fileExtensionIsAny(path: string, extensions: string[]): boolean; function getRegularExpressionForWildcard(specs: string[], basePath: string, usage: "files" | "directories" | "exclude"): string; @@ -2197,8 +2193,6 @@ declare namespace ts { function changeExtension(path: T, newExtension: string): T; interface ObjectAllocator { getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node; - getTokenConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token; - getIdentifierConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token; getSourceFileConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => SourceFile; getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol; getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type; @@ -6462,13 +6456,13 @@ declare namespace ts { key: string; message: string; }; - Report_errors_on_unused_locals: { + Report_Errors_on_Unused_Locals: { code: number; category: DiagnosticCategory; key: string; message: string; }; - Report_errors_on_unused_parameters: { + Report_Errors_on_Unused_Parameters: { code: number; category: DiagnosticCategory; key: string; @@ -7149,6 +7143,8 @@ declare namespace ts { function collapseTextChangeRangesAcrossMultipleVersions(changes: TextChangeRange[]): TextChangeRange; function getTypeParameterOwner(d: Declaration): Declaration; function isParameterPropertyDeclaration(node: ParameterDeclaration): boolean; + function startsWith(str: string, prefix: string): boolean; + function endsWith(str: string, suffix: string): boolean; } declare namespace ts { let parseTime: number; @@ -7229,12 +7225,6 @@ declare namespace ts { const defaultInitCompilerOptions: CompilerOptions; function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; - interface FormatDiagnosticsHost { - getCurrentDirectory(): string; - getCanonicalFileName(fileName: string): string; - getNewLine(): string; - } - function formatDiagnostics(diagnostics: Diagnostic[], host: FormatDiagnosticsHost): string; function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string; function getAutomaticTypeDirectiveNames(options: CompilerOptions, rootFiles: string[], host: CompilerHost): string[]; function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program; @@ -8398,6 +8388,7 @@ declare namespace ts.server { class ScriptInfo { private host; fileName: string; + content: string; isOpen: boolean; svc: ScriptVersionCache; children: ScriptInfo[]; @@ -8738,7 +8729,7 @@ declare namespace ts { getLocalizedDiagnosticMessages(): string; getCancellationToken(): HostCancellationToken; getCurrentDirectory(): string; - getDirectories(path: string): string; + getDirectories(path: string): string[]; getDefaultLibFileName(options: string): string; getNewLine?(): string; getProjectVersion?(): string; diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 8823d9ce98b..5dafd5528a8 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -830,17 +830,10 @@ var ts; return true; } ts.containsPath = containsPath; - function startsWith(str, prefix) { - return str.lastIndexOf(prefix, 0) === 0; - } - ts.startsWith = startsWith; - function endsWith(str, suffix) { - var expectedPos = str.length - suffix.length; - return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos; - } - ts.endsWith = endsWith; function fileExtensionIs(path, extension) { - return path.length > extension.length && endsWith(path, extension); + var pathLen = path.length; + var extLen = extension.length; + return pathLen > extLen && path.substr(pathLen - extLen, extLen) === extension; } ts.fileExtensionIs = fileExtensionIs; function fileExtensionIsAny(path, extensions) { @@ -1105,8 +1098,6 @@ var ts; } ts.objectAllocator = { getNodeConstructor: function () { return Node; }, - getTokenConstructor: function () { return Node; }, - getIdentifierConstructor: function () { return Node; }, getSourceFileConstructor: function () { return Node; }, getSymbolConstructor: function () { return Symbol; }, getTypeConstructor: function () { return Type; }, @@ -1238,7 +1229,7 @@ var ts; function readDirectory(path, extensions, excludes, includes) { return ts.matchFiles(path, extensions, excludes, includes, false, shell.CurrentDirectory, getAccessibleFileSystemEntries); } - var wscriptSystem = { + return { args: args, newLine: "\r\n", useCaseSensitiveFileNames: false, @@ -1257,7 +1248,7 @@ var ts; return fso.FolderExists(path); }, createDirectory: function (directoryName) { - if (!wscriptSystem.directoryExists(directoryName)) { + if (!this.directoryExists(directoryName)) { fso.CreateFolder(directoryName); } }, @@ -1277,7 +1268,6 @@ var ts; } } }; - return wscriptSystem; } function getNodeSystem() { var _fs = require("fs"); @@ -1450,7 +1440,7 @@ var ts; function getDirectories(path) { return ts.filter(_fs.readdirSync(path), function (p) { return fileSystemEntryExists(ts.combinePaths(path, p), 1); }); } - var nodeSystem = { + return { args: process.argv.slice(2), newLine: _os.EOL, useCaseSensitiveFileNames: useCaseSensitiveFileNames, @@ -1500,7 +1490,7 @@ var ts; fileExists: fileExists, directoryExists: directoryExists, createDirectory: function (directoryName) { - if (!nodeSystem.directoryExists(directoryName)) { + if (!this.directoryExists(directoryName)) { _fs.mkdirSync(directoryName); } }, @@ -1548,7 +1538,6 @@ var ts; return _fs.realpathSync(path); } }; - return nodeSystem; } function getChakraSystem() { var realpath = ChakraHost.realpath && (function (path) { return ChakraHost.realpath(path); }); @@ -2298,8 +2287,8 @@ var ts; Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: { code: 6131, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", message: "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'." }, File_name_0_has_a_1_extension_stripping_it: { code: 6132, category: ts.DiagnosticCategory.Message, key: "File_name_0_has_a_1_extension_stripping_it_6132", message: "File name '{0}' has a '{1}' extension - stripping it" }, _0_is_declared_but_never_used: { code: 6133, category: ts.DiagnosticCategory.Error, key: "_0_is_declared_but_never_used_6133", message: "'{0}' is declared but never used." }, - Report_errors_on_unused_locals: { code: 6134, category: ts.DiagnosticCategory.Message, key: "Report_errors_on_unused_locals_6134", message: "Report errors on unused locals." }, - Report_errors_on_unused_parameters: { code: 6135, category: ts.DiagnosticCategory.Message, key: "Report_errors_on_unused_parameters_6135", message: "Report errors on unused parameters." }, + Report_Errors_on_Unused_Locals: { code: 6134, category: ts.DiagnosticCategory.Message, key: "Report_Errors_on_Unused_Locals_6134", message: "Report Errors on Unused Locals." }, + Report_Errors_on_Unused_Parameters: { code: 6135, category: ts.DiagnosticCategory.Message, key: "Report_Errors_on_Unused_Parameters_6135", message: "Report Errors on Unused Parameters." }, The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files: { code: 6136, category: ts.DiagnosticCategory.Message, key: "The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files_6136", message: "The maximum dependency depth to search under node_modules and load JavaScript files" }, No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0: { code: 6137, category: ts.DiagnosticCategory.Message, key: "No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0_6137", message: "No types specified in 'package.json' but 'allowJs' is set, so returning 'main' value of '{0}'" }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." }, @@ -3977,12 +3966,12 @@ var ts; { name: "noUnusedLocals", type: "boolean", - description: ts.Diagnostics.Report_errors_on_unused_locals + description: ts.Diagnostics.Report_Errors_on_Unused_Locals }, { name: "noUnusedParameters", type: "boolean", - description: ts.Diagnostics.Report_errors_on_unused_parameters + description: ts.Diagnostics.Report_Errors_on_Unused_Parameters }, { name: "noLib", @@ -5765,7 +5754,7 @@ var ts; } ts.isExpression = isExpression; function isExternalModuleNameRelative(moduleName) { - return /^\.\.?($|[\\/])/.test(moduleName); + return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\"; } ts.isExternalModuleNameRelative = isExternalModuleNameRelative; function isInstantiatedModule(node, preserveConstEnums) { @@ -7273,24 +7262,25 @@ var ts; return node.flags & 92 && node.parent.kind === 148 && ts.isClassLike(node.parent.parent); } ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration; + function startsWith(str, prefix) { + return str.lastIndexOf(prefix, 0) === 0; + } + ts.startsWith = startsWith; + function endsWith(str, suffix) { + var expectedPos = str.length - suffix.length; + return str.indexOf(suffix, expectedPos) === expectedPos; + } + ts.endsWith = endsWith; })(ts || (ts = {})); var ts; (function (ts) { ts.parseTime = 0; var NodeConstructor; - var TokenConstructor; - var IdentifierConstructor; var SourceFileConstructor; function createNode(kind, pos, end) { if (kind === 256) { return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end); } - else if (kind === 69) { - return new (IdentifierConstructor || (IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor()))(kind, pos, end); - } - else if (kind < 139) { - return new (TokenConstructor || (TokenConstructor = ts.objectAllocator.getTokenConstructor()))(kind, pos, end); - } else { return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end); } @@ -7713,8 +7703,6 @@ var ts; var scanner = ts.createScanner(2, true); var disallowInAndDecoratorContext = 4194304 | 16777216; var NodeConstructor; - var TokenConstructor; - var IdentifierConstructor; var SourceFileConstructor; var sourceFile; var parseDiagnostics; @@ -7740,8 +7728,6 @@ var ts; } function initializeState(fileName, _sourceText, languageVersion, _syntaxCursor, scriptKind) { NodeConstructor = ts.objectAllocator.getNodeConstructor(); - TokenConstructor = ts.objectAllocator.getTokenConstructor(); - IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor(); SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor(); sourceText = _sourceText; syntaxCursor = _syntaxCursor; @@ -8048,9 +8034,7 @@ var ts; if (!(pos >= 0)) { pos = scanner.getStartPos(); } - return kind >= 139 ? new NodeConstructor(kind, pos, pos) : - kind === 69 ? new IdentifierConstructor(kind, pos, pos) : - new TokenConstructor(kind, pos, pos); + return new NodeConstructor(kind, pos, pos); } function finishNode(node, end) { node.end = end === undefined ? scanner.getStartPos() : end; @@ -11826,9 +11810,6 @@ var ts; case 55: if (canParseTag) { parentTagTerminated = !tryParseChildTag(jsDocTypeLiteral); - if (!parentTagTerminated) { - resumePos = scanner.getStartPos(); - } } seenAsterisk = false; break; @@ -16355,18 +16336,17 @@ var ts; if (declaration.kind === 235) { return links.type = checkExpression(declaration.expression); } - if (declaration.flags & 134217728 && declaration.kind === 280 && declaration.typeExpression) { - return links.type = getTypeFromTypeNode(declaration.typeExpression.type); - } if (!pushTypeResolution(symbol, 0)) { return unknownType; } var type = undefined; - if (declaration.kind === 187 || - declaration.kind === 172 && declaration.parent.kind === 187) { - type = getUnionType(ts.map(symbol.declarations, function (decl) { return decl.kind === 187 ? - checkExpressionCached(decl.right) : - checkExpressionCached(decl.parent.right); })); + if (declaration.kind === 187) { + type = getUnionType(ts.map(symbol.declarations, function (decl) { return checkExpressionCached(decl.right); })); + } + else if (declaration.kind === 172) { + if (declaration.parent.kind === 187) { + type = checkExpressionCached(declaration.parent.right); + } } if (type === undefined) { type = getWidenedTypeForVariableLikeDeclaration(declaration, true); @@ -22873,7 +22853,7 @@ var ts; function getInferredClassType(symbol) { var links = getSymbolLinks(symbol); if (!links.inferredClassType) { - links.inferredClassType = createAnonymousType(symbol, symbol.members, emptyArray, emptyArray, undefined, undefined); + links.inferredClassType = createAnonymousType(undefined, symbol.members, emptyArray, emptyArray, undefined, undefined); } return links.inferredClassType; } @@ -24093,7 +24073,7 @@ var ts; checkAsyncFunctionReturnType(node); } } - if (noUnusedIdentifiers && !node.body) { + if (!node.body) { checkUnusedTypeParameters(node); } } @@ -24989,7 +24969,6 @@ var ts; var parameter = local_1.valueDeclaration; if (compilerOptions.noUnusedParameters && !ts.isParameterPropertyDeclaration(parameter) && - !parameterIsThisKeyword(parameter) && !parameterNameStartsWithUnderscore(parameter)) { error(local_1.valueDeclaration.name, ts.Diagnostics._0_is_declared_but_never_used, local_1.name); } @@ -25005,9 +24984,6 @@ var ts; } } } - function parameterIsThisKeyword(parameter) { - return parameter.name && parameter.name.originalKeywordKind === 97; - } function parameterNameStartsWithUnderscore(parameter) { return parameter.name && parameter.name.kind === 69 && parameter.name.text.charCodeAt(0) === 95; } @@ -25036,14 +25012,9 @@ var ts; function checkUnusedTypeParameters(node) { if (compilerOptions.noUnusedLocals && !ts.isInAmbientContext(node)) { if (node.typeParameters) { - var symbol = getSymbolOfNode(node); - var lastDeclaration = symbol && symbol.declarations && ts.lastOrUndefined(symbol.declarations); - if (lastDeclaration !== node) { - return; - } for (var _i = 0, _a = node.typeParameters; _i < _a.length; _i++) { var typeParameter = _a[_i]; - if (!getMergedSymbol(typeParameter.symbol).isReferenced) { + if (!typeParameter.symbol.isReferenced) { error(typeParameter.name, ts.Diagnostics._0_is_declared_but_never_used, typeParameter.symbol.name); } } @@ -26120,7 +26091,7 @@ var ts; ts.forEach(node.members, checkSourceElement); if (produceDiagnostics) { checkTypeForDuplicateIndexSignatures(node); - registerForUnusedIdentifiersCheck(node); + checkUnusedTypeParameters(node); } } function checkTypeAliasDeclaration(node) { @@ -30843,7 +30814,7 @@ var ts; writeLine(); var sourceMappingURL = sourceMap.getSourceMappingURL(); if (sourceMappingURL) { - write("//# " + "sourceMappingURL" + "=" + sourceMappingURL); + write("//# sourceMappingURL=" + sourceMappingURL); } writeEmittedFiles(writer.getText(), jsFilePath, sourceMapFilePath, compilerOptions.emitBOM, sourceFiles); sourceMap.reset(); @@ -34493,13 +34464,13 @@ var ts; if (isES6ExportedDeclaration(node) && !(node.flags & 512) && decoratedClassAlias === undefined) { write("export "); } + if (!isHoistedDeclarationInSystemModule) { + write("let "); + } if (decoratedClassAlias !== undefined) { - write("let " + decoratedClassAlias); + write("" + decoratedClassAlias); } else { - if (!isHoistedDeclarationInSystemModule) { - write("let "); - } emitDeclarationName(node); } write(" = "); @@ -36743,7 +36714,7 @@ var ts; ts.emitTime = 0; ts.ioReadTime = 0; ts.ioWriteTime = 0; - ts.version = "2.1.0"; + ts.version = "2.0.0"; var emptyArray = []; var defaultTypeRoots = ["node_modules/@types"]; function findConfigFile(searchPath, fileExists) { @@ -36823,7 +36794,12 @@ var ts; return { resolvedModule: resolvedFileName ? { resolvedFileName: resolvedFileName, isExternalLibraryImport: isExternalLibraryImport } : undefined, failedLookupLocations: failedLookupLocations }; } function moduleHasNonRelativeName(moduleName) { - return !(ts.isRootedDiskPath(moduleName) || ts.isExternalModuleNameRelative(moduleName)); + if (ts.isRootedDiskPath(moduleName)) { + return false; + } + var i = moduleName.lastIndexOf("./", 1); + var startsWithDotSlashOrDotDotSlash = i === 0 || (i === 1 && moduleName.charCodeAt(0) === 46); + return !startsWithDotSlashOrDotDotSlash; } function tryReadTypesSection(packageJsonPath, baseDirectory, state) { var jsonContent; @@ -37479,22 +37455,6 @@ var ts; return ts.sortAndDeduplicateDiagnostics(diagnostics); } ts.getPreEmitDiagnostics = getPreEmitDiagnostics; - function formatDiagnostics(diagnostics, host) { - var output = ""; - for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) { - var diagnostic = diagnostics_1[_i]; - if (diagnostic.file) { - var _a = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start), line = _a.line, character = _a.character; - var fileName = diagnostic.file.fileName; - var relativeFileName = ts.convertToRelativePath(fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }); - output += relativeFileName + "(" + (line + 1) + "," + (character + 1) + "): "; - } - var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase(); - output += category + " TS" + diagnostic.code + ": " + flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) + host.getNewLine(); - } - return output; - } - ts.formatDiagnostics = formatDiagnostics; function flattenDiagnosticMessageText(messageText, newLine) { if (typeof messageText === "string") { return messageText; @@ -37570,7 +37530,7 @@ var ts; var resolvedTypeReferenceDirectives = {}; var fileProcessingDiagnostics = ts.createDiagnosticCollection(); var maxNodeModulesJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 2; - var currentNodeModulesDepth = 0; + var currentNodeModulesJsDepth = 0; var modulesWithElidedImports = {}; var sourceFilesFoundSearchingNodeModules = {}; var start = new Date().getTime(); @@ -37794,7 +37754,8 @@ var ts; return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = ts.createTypeChecker(program, false)); } function emit(sourceFile, writeFileCallback, cancellationToken) { - return runWithCancellationToken(function () { return emitWorker(program, sourceFile, writeFileCallback, cancellationToken); }); + var _this = this; + return runWithCancellationToken(function () { return emitWorker(_this, sourceFile, writeFileCallback, cancellationToken); }); } function isEmitBlocked(emitFileName) { return hasEmitBlockingDiagnostics.contains(ts.toPath(emitFileName, currentDirectory, getCanonicalFileName)); @@ -38201,17 +38162,8 @@ var ts; if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) { reportFileNamesDifferOnlyInCasingError(fileName, file_1.fileName, refFile, refPos, refEnd); } - if (file_1 && ts.lookUp(sourceFilesFoundSearchingNodeModules, file_1.path) && currentNodeModulesDepth == 0) { - sourceFilesFoundSearchingNodeModules[file_1.path] = false; - if (!options.noResolve) { - processReferencedFiles(file_1, ts.getDirectoryPath(fileName), isDefaultLib); - processTypeReferenceDirectives(file_1); - } - modulesWithElidedImports[file_1.path] = false; - processImportedModules(file_1, ts.getDirectoryPath(fileName)); - } - else if (file_1 && ts.lookUp(modulesWithElidedImports, file_1.path)) { - if (currentNodeModulesDepth < maxNodeModulesJsDepth) { + if (file_1 && ts.lookUp(modulesWithElidedImports, file_1.path)) { + if (currentNodeModulesJsDepth < maxNodeModulesJsDepth) { modulesWithElidedImports[file_1.path] = false; processImportedModules(file_1, ts.getDirectoryPath(fileName)); } @@ -38228,7 +38180,6 @@ var ts; }); filesByName.set(path, file); if (file) { - sourceFilesFoundSearchingNodeModules[path] = (currentNodeModulesDepth > 0); file.path = path; if (host.useCaseSensitiveFileNames()) { var existingFile = filesByNameIgnoreCase.get(path); @@ -38329,9 +38280,12 @@ var ts; var isFromNodeModulesSearch = resolution && resolution.isExternalLibraryImport; var isJsFileFromNodeModules = isFromNodeModulesSearch && ts.hasJavaScriptFileExtension(resolution.resolvedFileName); if (isFromNodeModulesSearch) { - currentNodeModulesDepth++; + sourceFilesFoundSearchingNodeModules[resolvedPath] = true; } - var elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModulesJsDepth; + if (isJsFileFromNodeModules) { + currentNodeModulesJsDepth++; + } + var elideImport = isJsFileFromNodeModules && currentNodeModulesJsDepth > maxNodeModulesJsDepth; var shouldAddFile = resolution && !options.noResolve && i < file.imports.length && !elideImport; if (elideImport) { modulesWithElidedImports[file.path] = true; @@ -38339,8 +38293,8 @@ var ts; else if (shouldAddFile) { findSourceFile(resolution.resolvedFileName, resolvedPath, false, false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); } - if (isFromNodeModulesSearch) { - currentNodeModulesDepth--; + if (isJsFileFromNodeModules) { + currentNodeModulesJsDepth--; } } } @@ -39933,7 +39887,7 @@ var ts; return createPatternMatch(PatternMatchKind.exact, punctuationStripped, candidate === chunk.text); } else { - return createPatternMatch(PatternMatchKind.prefix, punctuationStripped, ts.startsWith(candidate, chunk.text)); + return createPatternMatch(PatternMatchKind.prefix, punctuationStripped, startsWith(candidate, chunk.text)); } } var isLowercase = chunk.isLowerCase; @@ -40105,6 +40059,14 @@ var ts; var str = String.fromCharCode(ch); return str === str.toLowerCase(); } + function startsWith(string, search) { + for (var i = 0, n = search.length; i < n; i++) { + if (string.charCodeAt(i) !== search.charCodeAt(i)) { + return false; + } + } + return true; + } function indexOfIgnoringCase(string, value) { for (var i = 0, n = string.length - value.length; i <= n; i++) { if (startsWithIgnoringCase(string, value, i)) { @@ -41589,9 +41551,6 @@ var ts; } return false; } - function shouldRescanJsxText(node) { - return node && node.kind === 244; - } function shouldRescanSlashToken(container) { return container.kind === 10; } @@ -41619,9 +41578,7 @@ var ts; ? 3 : shouldRescanJsxIdentifier(n) ? 4 - : shouldRescanJsxText(n) - ? 5 - : 0; + : 0; if (lastTokenInfo && expectedScanAction === lastScanAction) { return fixTokenKind(lastTokenInfo, n); } @@ -41649,10 +41606,6 @@ var ts; currentToken = scanner.scanJsxIdentifier(); lastScanAction = 4; } - else if (expectedScanAction === 5) { - currentToken = scanner.reScanJsxToken(); - lastScanAction = 5; - } else { lastScanAction = 0; } @@ -43901,20 +43854,19 @@ var ts; "version" ]; var jsDocCompletionEntries; - function createNode(kind, pos, end, parent) { - var node = kind >= 139 ? new NodeObject(kind, pos, end) : - kind === 69 ? new IdentifierObject(kind, pos, end) : - new TokenObject(kind, pos, end); + function createNode(kind, pos, end, flags, parent) { + var node = new NodeObject(kind, pos, end); + node.flags = flags; node.parent = parent; return node; } var NodeObject = (function () { function NodeObject(kind, pos, end) { + this.kind = kind; this.pos = pos; this.end = end; this.flags = 0; this.parent = undefined; - this.kind = kind; } NodeObject.prototype.getSourceFile = function () { return ts.getSourceFileOfNode(this); @@ -43949,14 +43901,14 @@ var ts; var token = useJSDocScanner ? scanner.scanJSDocToken() : scanner.scan(); var textPos = scanner.getTextPos(); if (textPos <= end) { - nodes.push(createNode(token, pos, textPos, this)); + nodes.push(createNode(token, pos, textPos, 0, this)); } pos = textPos; } return pos; }; NodeObject.prototype.createSyntaxList = function (nodes) { - var list = createNode(282, nodes.pos, nodes.end, this); + var list = createNode(282, nodes.pos, nodes.end, 0, this); list._children = []; var pos = nodes.pos; for (var _i = 0, nodes_4 = nodes; _i < nodes_4.length; _i++) { @@ -44041,73 +43993,6 @@ var ts; }; return NodeObject; }()); - var TokenOrIdentifierObject = (function () { - function TokenOrIdentifierObject(pos, end) { - this.pos = pos; - this.end = end; - this.flags = 0; - this.parent = undefined; - } - TokenOrIdentifierObject.prototype.getSourceFile = function () { - return ts.getSourceFileOfNode(this); - }; - TokenOrIdentifierObject.prototype.getStart = function (sourceFile, includeJsDocComment) { - return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment); - }; - TokenOrIdentifierObject.prototype.getFullStart = function () { - return this.pos; - }; - TokenOrIdentifierObject.prototype.getEnd = function () { - return this.end; - }; - TokenOrIdentifierObject.prototype.getWidth = function (sourceFile) { - return this.getEnd() - this.getStart(sourceFile); - }; - TokenOrIdentifierObject.prototype.getFullWidth = function () { - return this.end - this.pos; - }; - TokenOrIdentifierObject.prototype.getLeadingTriviaWidth = function (sourceFile) { - return this.getStart(sourceFile) - this.pos; - }; - TokenOrIdentifierObject.prototype.getFullText = function (sourceFile) { - return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end); - }; - TokenOrIdentifierObject.prototype.getText = function (sourceFile) { - return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd()); - }; - TokenOrIdentifierObject.prototype.getChildCount = function (sourceFile) { - return 0; - }; - TokenOrIdentifierObject.prototype.getChildAt = function (index, sourceFile) { - return undefined; - }; - TokenOrIdentifierObject.prototype.getChildren = function (sourceFile) { - return emptyArray; - }; - TokenOrIdentifierObject.prototype.getFirstToken = function (sourceFile) { - return undefined; - }; - TokenOrIdentifierObject.prototype.getLastToken = function (sourceFile) { - return undefined; - }; - return TokenOrIdentifierObject; - }()); - var TokenObject = (function (_super) { - __extends(TokenObject, _super); - function TokenObject(kind, pos, end) { - _super.call(this, pos, end); - this.kind = kind; - } - return TokenObject; - }(TokenOrIdentifierObject)); - var IdentifierObject = (function (_super) { - __extends(IdentifierObject, _super); - function IdentifierObject(kind, pos, end) { - _super.call(this, pos, end); - } - return IdentifierObject; - }(TokenOrIdentifierObject)); - IdentifierObject.prototype.kind = 69; var SymbolObject = (function () { function SymbolObject(flags, name) { this.flags = flags; @@ -49788,8 +49673,6 @@ var ts; function initializeServices() { ts.objectAllocator = { getNodeConstructor: function () { return NodeObject; }, - getTokenConstructor: function () { return TokenObject; }, - getIdentifierConstructor: function () { return IdentifierObject; }, getSourceFileConstructor: function () { return SourceFileObject; }, getSymbolConstructor: function () { return SymbolObject; }, getTypeConstructor: function () { return TypeObject; }, @@ -50910,6 +50793,7 @@ var ts; if (isOpen === void 0) { isOpen = false; } this.host = host; this.fileName = fileName; + this.content = content; this.isOpen = isOpen; this.children = []; this.formatCodeOptions = ts.clone(CompilerService.getDefaultFormatCodeOptions(this.host)); @@ -52535,7 +52419,7 @@ var ts; done: false, leaf: function (relativeStart, relativeLength, ll) { if (!f(ll, relativeStart, relativeLength)) { - walkFns.done = true; + this.done = true; } } }; @@ -52951,7 +52835,7 @@ var ts; server.LineLeaf = LineLeaf; })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); -var debugObjectHost = new Function("return this")(); +var debugObjectHost = this; var ts; (function (ts) { function logInternalError(logger, err) { @@ -53079,7 +52963,7 @@ var ts; return this.shimHost.getCurrentDirectory(); }; LanguageServiceShimHostAdapter.prototype.getDirectories = function (path) { - return JSON.parse(this.shimHost.getDirectories(path)); + return this.shimHost.getDirectories(path); }; LanguageServiceShimHostAdapter.prototype.getDefaultLibFileName = function (options) { return this.shimHost.getDefaultLibFileName(JSON.stringify(options)); diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index 92937fecf99..c322ba1dd0c 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -409,10 +409,7 @@ declare namespace ts { interface ModifiersArray extends NodeArray { flags: NodeFlags; } - interface Token extends Node { - __tokenTag: any; - } - interface Modifier extends Token { + interface Modifier extends Node { } interface Identifier extends PrimaryExpression { text: string; @@ -1699,6 +1696,7 @@ declare namespace ts { getCancellationToken?(): CancellationToken; getDefaultLibFileName(options: CompilerOptions): string; getDefaultLibLocation?(): string; + getDefaultTypeDirectiveNames?(rootPath: string): string[]; writeFile: WriteFileCallback; getCurrentDirectory(): string; getDirectories(path: string): string[]; @@ -1844,6 +1842,8 @@ declare namespace ts { function collapseTextChangeRangesAcrossMultipleVersions(changes: TextChangeRange[]): TextChangeRange; function getTypeParameterOwner(d: Declaration): Declaration; function isParameterPropertyDeclaration(node: ParameterDeclaration): boolean; + function startsWith(str: string, prefix: string): boolean; + function endsWith(str: string, suffix: string): boolean; } declare namespace ts { function createNode(kind: SyntaxKind, pos?: number, end?: number): Node; @@ -1868,12 +1868,6 @@ declare namespace ts { function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations; function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; - interface FormatDiagnosticsHost { - getCurrentDirectory(): string; - getCanonicalFileName(fileName: string): string; - getNewLine(): string; - } - function formatDiagnostics(diagnostics: Diagnostic[], host: FormatDiagnosticsHost): string; function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string; /** * Given a set of options and a set of root files, returns the set of type directive names diff --git a/lib/typescript.js b/lib/typescript.js index 41d3676a415..22cbe79129c 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -1756,19 +1756,10 @@ var ts; return true; } ts.containsPath = containsPath; - /* @internal */ - function startsWith(str, prefix) { - return str.lastIndexOf(prefix, 0) === 0; - } - ts.startsWith = startsWith; - /* @internal */ - function endsWith(str, suffix) { - var expectedPos = str.length - suffix.length; - return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos; - } - ts.endsWith = endsWith; function fileExtensionIs(path, extension) { - return path.length > extension.length && endsWith(path, extension); + var pathLen = path.length; + var extLen = extension.length; + return pathLen > extLen && path.substr(pathLen - extLen, extLen) === extension; } ts.fileExtensionIs = fileExtensionIs; function fileExtensionIsAny(path, extensions) { @@ -2079,8 +2070,6 @@ var ts; } ts.objectAllocator = { getNodeConstructor: function () { return Node; }, - getTokenConstructor: function () { return Node; }, - getIdentifierConstructor: function () { return Node; }, getSourceFileConstructor: function () { return Node; }, getSymbolConstructor: function () { return Symbol; }, getTypeConstructor: function () { return Type; }, @@ -2227,7 +2216,7 @@ var ts; function readDirectory(path, extensions, excludes, includes) { return ts.matchFiles(path, extensions, excludes, includes, /*useCaseSensitiveFileNames*/ false, shell.CurrentDirectory, getAccessibleFileSystemEntries); } - var wscriptSystem = { + return { args: args, newLine: "\r\n", useCaseSensitiveFileNames: false, @@ -2246,7 +2235,7 @@ var ts; return fso.FolderExists(path); }, createDirectory: function (directoryName) { - if (!wscriptSystem.directoryExists(directoryName)) { + if (!this.directoryExists(directoryName)) { fso.CreateFolder(directoryName); } }, @@ -2266,7 +2255,6 @@ var ts; } } }; - return wscriptSystem; } function getNodeSystem() { var _fs = require("fs"); @@ -2456,7 +2444,7 @@ var ts; function getDirectories(path) { return ts.filter(_fs.readdirSync(path), function (p) { return fileSystemEntryExists(ts.combinePaths(path, p), 1 /* Directory */); }); } - var nodeSystem = { + return { args: process.argv.slice(2), newLine: _os.EOL, useCaseSensitiveFileNames: useCaseSensitiveFileNames, @@ -2512,7 +2500,7 @@ var ts; fileExists: fileExists, directoryExists: directoryExists, createDirectory: function (directoryName) { - if (!nodeSystem.directoryExists(directoryName)) { + if (!this.directoryExists(directoryName)) { _fs.mkdirSync(directoryName); } }, @@ -2560,7 +2548,6 @@ var ts; return _fs.realpathSync(path); } }; - return nodeSystem; } function getChakraSystem() { var realpath = ChakraHost.realpath && (function (path) { return ChakraHost.realpath(path); }); @@ -3317,8 +3304,8 @@ var ts; Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: { code: 6131, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", message: "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'." }, File_name_0_has_a_1_extension_stripping_it: { code: 6132, category: ts.DiagnosticCategory.Message, key: "File_name_0_has_a_1_extension_stripping_it_6132", message: "File name '{0}' has a '{1}' extension - stripping it" }, _0_is_declared_but_never_used: { code: 6133, category: ts.DiagnosticCategory.Error, key: "_0_is_declared_but_never_used_6133", message: "'{0}' is declared but never used." }, - Report_errors_on_unused_locals: { code: 6134, category: ts.DiagnosticCategory.Message, key: "Report_errors_on_unused_locals_6134", message: "Report errors on unused locals." }, - Report_errors_on_unused_parameters: { code: 6135, category: ts.DiagnosticCategory.Message, key: "Report_errors_on_unused_parameters_6135", message: "Report errors on unused parameters." }, + Report_Errors_on_Unused_Locals: { code: 6134, category: ts.DiagnosticCategory.Message, key: "Report_Errors_on_Unused_Locals_6134", message: "Report Errors on Unused Locals." }, + Report_Errors_on_Unused_Parameters: { code: 6135, category: ts.DiagnosticCategory.Message, key: "Report_Errors_on_Unused_Parameters_6135", message: "Report Errors on Unused Parameters." }, The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files: { code: 6136, category: ts.DiagnosticCategory.Message, key: "The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files_6136", message: "The maximum dependency depth to search under node_modules and load JavaScript files" }, No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0: { code: 6137, category: ts.DiagnosticCategory.Message, key: "No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0_6137", message: "No types specified in 'package.json' but 'allowJs' is set, so returning 'main' value of '{0}'" }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." }, @@ -6166,7 +6153,7 @@ var ts; function isExternalModuleNameRelative(moduleName) { // TypeScript 1.0 spec (April 2014): 11.2.1 // An external module name is "relative" if the first term is "." or "..". - return /^\.\.?($|[\\/])/.test(moduleName); + return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\"; } ts.isExternalModuleNameRelative = isExternalModuleNameRelative; function isInstantiatedModule(node, preserveConstEnums) { @@ -7929,6 +7916,15 @@ var ts; return node.flags & 92 /* ParameterPropertyModifier */ && node.parent.kind === 148 /* Constructor */ && ts.isClassLike(node.parent.parent); } ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration; + function startsWith(str, prefix) { + return str.lastIndexOf(prefix, 0) === 0; + } + ts.startsWith = startsWith; + function endsWith(str, suffix) { + var expectedPos = str.length - suffix.length; + return str.indexOf(suffix, expectedPos) === expectedPos; + } + ts.endsWith = endsWith; })(ts || (ts = {})); /// /// @@ -7936,19 +7932,11 @@ var ts; (function (ts) { /* @internal */ ts.parseTime = 0; var NodeConstructor; - var TokenConstructor; - var IdentifierConstructor; var SourceFileConstructor; function createNode(kind, pos, end) { if (kind === 256 /* SourceFile */) { return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end); } - else if (kind === 69 /* Identifier */) { - return new (IdentifierConstructor || (IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor()))(kind, pos, end); - } - else if (kind < 139 /* FirstNode */) { - return new (TokenConstructor || (TokenConstructor = ts.objectAllocator.getTokenConstructor()))(kind, pos, end); - } else { return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end); } @@ -8398,8 +8386,6 @@ var ts; var disallowInAndDecoratorContext = 4194304 /* DisallowInContext */ | 16777216 /* DecoratorContext */; // capture constructors in 'initializeState' to avoid null checks var NodeConstructor; - var TokenConstructor; - var IdentifierConstructor; var SourceFileConstructor; var sourceFile; var parseDiagnostics; @@ -8499,8 +8485,6 @@ var ts; } function initializeState(fileName, _sourceText, languageVersion, _syntaxCursor, scriptKind) { NodeConstructor = ts.objectAllocator.getNodeConstructor(); - TokenConstructor = ts.objectAllocator.getTokenConstructor(); - IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor(); SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor(); sourceText = _sourceText; syntaxCursor = _syntaxCursor; @@ -8871,9 +8855,7 @@ var ts; if (!(pos >= 0)) { pos = scanner.getStartPos(); } - return kind >= 139 /* FirstNode */ ? new NodeConstructor(kind, pos, pos) : - kind === 69 /* Identifier */ ? new IdentifierConstructor(kind, pos, pos) : - new TokenConstructor(kind, pos, pos); + return new NodeConstructor(kind, pos, pos); } function finishNode(node, end) { node.end = end === undefined ? scanner.getStartPos() : end; @@ -13542,9 +13524,6 @@ var ts; case 55 /* AtToken */: if (canParseTag) { parentTagTerminated = !tryParseChildTag(jsDocTypeLiteral); - if (!parentTagTerminated) { - resumePos = scanner.getStartPos(); - } } seenAsterisk = false; break; @@ -19012,24 +18991,22 @@ var ts; if (declaration.kind === 235 /* ExportAssignment */) { return links.type = checkExpression(declaration.expression); } - if (declaration.flags & 134217728 /* JavaScriptFile */ && declaration.kind === 280 /* JSDocPropertyTag */ && declaration.typeExpression) { - return links.type = getTypeFromTypeNode(declaration.typeExpression.type); - } // Handle variable, parameter or property if (!pushTypeResolution(symbol, 0 /* Type */)) { return unknownType; } var type = undefined; - // Handle certain special assignment kinds, which happen to union across multiple declarations: - // * module.exports = expr - // * exports.p = expr - // * this.p = expr - // * className.prototype.method = expr - if (declaration.kind === 187 /* BinaryExpression */ || - declaration.kind === 172 /* PropertyAccessExpression */ && declaration.parent.kind === 187 /* BinaryExpression */) { - type = getUnionType(ts.map(symbol.declarations, function (decl) { return decl.kind === 187 /* BinaryExpression */ ? - checkExpressionCached(decl.right) : - checkExpressionCached(decl.parent.right); })); + // Handle module.exports = expr or this.p = expr + if (declaration.kind === 187 /* BinaryExpression */) { + type = getUnionType(ts.map(symbol.declarations, function (decl) { return checkExpressionCached(decl.right); })); + } + else if (declaration.kind === 172 /* PropertyAccessExpression */) { + // Declarations only exist for property access expressions for certain + // special assignment kinds + if (declaration.parent.kind === 187 /* BinaryExpression */) { + // Handle exports.p = expr or className.prototype.method = expr + type = checkExpressionCached(declaration.parent.right); + } } if (type === undefined) { type = getWidenedTypeForVariableLikeDeclaration(declaration, /*reportErrors*/ true); @@ -26784,7 +26761,7 @@ var ts; function getInferredClassType(symbol) { var links = getSymbolLinks(symbol); if (!links.inferredClassType) { - links.inferredClassType = createAnonymousType(symbol, symbol.members, emptyArray, emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined); + links.inferredClassType = createAnonymousType(undefined, symbol.members, emptyArray, emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined); } return links.inferredClassType; } @@ -28225,7 +28202,7 @@ var ts; checkAsyncFunctionReturnType(node); } } - if (noUnusedIdentifiers && !node.body) { + if (!node.body) { checkUnusedTypeParameters(node); } } @@ -29364,7 +29341,6 @@ var ts; var parameter = local_1.valueDeclaration; if (compilerOptions.noUnusedParameters && !ts.isParameterPropertyDeclaration(parameter) && - !parameterIsThisKeyword(parameter) && !parameterNameStartsWithUnderscore(parameter)) { error(local_1.valueDeclaration.name, ts.Diagnostics._0_is_declared_but_never_used, local_1.name); } @@ -29380,9 +29356,6 @@ var ts; } } } - function parameterIsThisKeyword(parameter) { - return parameter.name && parameter.name.originalKeywordKind === 97 /* ThisKeyword */; - } function parameterNameStartsWithUnderscore(parameter) { return parameter.name && parameter.name.kind === 69 /* Identifier */ && parameter.name.text.charCodeAt(0) === 95 /* _ */; } @@ -29411,16 +29384,9 @@ var ts; function checkUnusedTypeParameters(node) { if (compilerOptions.noUnusedLocals && !ts.isInAmbientContext(node)) { if (node.typeParameters) { - // Only report errors on the last declaration for the type parameter container; - // this ensures that all uses have been accounted for. - var symbol = getSymbolOfNode(node); - var lastDeclaration = symbol && symbol.declarations && ts.lastOrUndefined(symbol.declarations); - if (lastDeclaration !== node) { - return; - } for (var _i = 0, _a = node.typeParameters; _i < _a.length; _i++) { var typeParameter = _a[_i]; - if (!getMergedSymbol(typeParameter.symbol).isReferenced) { + if (!typeParameter.symbol.isReferenced) { error(typeParameter.name, ts.Diagnostics._0_is_declared_but_never_used, typeParameter.symbol.name); } } @@ -30753,7 +30719,7 @@ var ts; ts.forEach(node.members, checkSourceElement); if (produceDiagnostics) { checkTypeForDuplicateIndexSignatures(node); - registerForUnusedIdentifiersCheck(node); + checkUnusedTypeParameters(node); } } function checkTypeAliasDeclaration(node) { @@ -36017,7 +35983,7 @@ var ts; writeLine(); var sourceMappingURL = sourceMap.getSourceMappingURL(); if (sourceMappingURL) { - write("//# " + "sourceMappingURL" + "=" + sourceMappingURL); // Sometimes tools can sometimes see this line as a source mapping url comment + write("//# sourceMappingURL=" + sourceMappingURL); } writeEmittedFiles(writer.getText(), jsFilePath, sourceMapFilePath, /*writeByteOrderMark*/ compilerOptions.emitBOM, sourceFiles); // reset the state @@ -37914,7 +37880,7 @@ var ts; * if we should also export the value after its it changed * - check if node is a source level declaration to emit it differently, * i.e non-exported variable statement 'var x = 1' is hoisted so - * when we emit variable statement 'var' should be dropped. + * we we emit variable statement 'var' should be dropped. */ function isSourceFileLevelDeclarationInSystemJsModule(node, isExported) { if (!node || !isCurrentFileSystemExternalModule()) { @@ -40381,13 +40347,13 @@ var ts; if (isES6ExportedDeclaration(node) && !(node.flags & 512 /* Default */) && decoratedClassAlias === undefined) { write("export "); } + if (!isHoistedDeclarationInSystemModule) { + write("let "); + } if (decoratedClassAlias !== undefined) { - write("let " + decoratedClassAlias); + write("" + decoratedClassAlias); } else { - if (!isHoistedDeclarationInSystemModule) { - write("let "); - } emitDeclarationName(node); } write(" = "); @@ -40406,9 +40372,7 @@ var ts; // // We'll emit: // - // let C_1 = class C{}; - // C_1.a = 1; - // C_1.b = 2; // so forth and so on + // (_temp = class C { ... }, _temp.a = 1, _temp.b = 2, _temp) // // This keeps the expression as an expression, while ensuring that the static parts // of it have been initialized by the time it is used. @@ -42972,7 +42936,7 @@ var ts; /* @internal */ ts.ioReadTime = 0; /* @internal */ ts.ioWriteTime = 0; /** The version of the TypeScript compiler release */ - ts.version = "2.1.0"; + ts.version = "2.0.0"; var emptyArray = []; var defaultTypeRoots = ["node_modules/@types"]; function findConfigFile(searchPath, fileExists) { @@ -43061,7 +43025,12 @@ var ts; return { resolvedModule: resolvedFileName ? { resolvedFileName: resolvedFileName, isExternalLibraryImport: isExternalLibraryImport } : undefined, failedLookupLocations: failedLookupLocations }; } function moduleHasNonRelativeName(moduleName) { - return !(ts.isRootedDiskPath(moduleName) || ts.isExternalModuleNameRelative(moduleName)); + if (ts.isRootedDiskPath(moduleName)) { + return false; + } + var i = moduleName.lastIndexOf("./", 1); + var startsWithDotSlashOrDotDotSlash = i === 0 || (i === 1 && moduleName.charCodeAt(0) === 46 /* dot */); + return !startsWithDotSlashOrDotDotSlash; } function tryReadTypesSection(packageJsonPath, baseDirectory, state) { var jsonContent; @@ -43828,22 +43797,6 @@ var ts; return ts.sortAndDeduplicateDiagnostics(diagnostics); } ts.getPreEmitDiagnostics = getPreEmitDiagnostics; - function formatDiagnostics(diagnostics, host) { - var output = ""; - for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) { - var diagnostic = diagnostics_1[_i]; - if (diagnostic.file) { - var _a = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start), line = _a.line, character = _a.character; - var fileName = diagnostic.file.fileName; - var relativeFileName = ts.convertToRelativePath(fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }); - output += relativeFileName + "(" + (line + 1) + "," + (character + 1) + "): "; - } - var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase(); - output += category + " TS" + diagnostic.code + ": " + flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) + host.getNewLine(); - } - return output; - } - ts.formatDiagnostics = formatDiagnostics; function flattenDiagnosticMessageText(messageText, newLine) { if (typeof messageText === "string") { return messageText; @@ -43936,11 +43889,11 @@ var ts; // As all these operations happen - and are nested - within the createProgram call, they close over the below variables. // The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses. var maxNodeModulesJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 2; - var currentNodeModulesDepth = 0; + var currentNodeModulesJsDepth = 0; // If a module has some of its imports skipped due to being at the depth limit under node_modules, then track // this, as it may be imported at a shallower depth later, and then it will need its skipped imports processed. var modulesWithElidedImports = {}; - // Track source files that are source files found by searching under node_modules, as these shouldn't be compiled. + // Track source files that are JavaScript files found by searching under node_modules, as these shouldn't be compiled. var sourceFilesFoundSearchingNodeModules = {}; var start = new Date().getTime(); host = host || createCompilerHost(options); @@ -44197,7 +44150,8 @@ var ts; return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ false)); } function emit(sourceFile, writeFileCallback, cancellationToken) { - return runWithCancellationToken(function () { return emitWorker(program, sourceFile, writeFileCallback, cancellationToken); }); + var _this = this; + return runWithCancellationToken(function () { return emitWorker(_this, sourceFile, writeFileCallback, cancellationToken); }); } function isEmitBlocked(emitFileName) { return hasEmitBlockingDiagnostics.contains(ts.toPath(emitFileName, currentDirectory, getCanonicalFileName)); @@ -44649,19 +44603,9 @@ var ts; if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) { reportFileNamesDifferOnlyInCasingError(fileName, file_1.fileName, refFile, refPos, refEnd); } - // If the file was previously found via a node_modules search, but is now being processed as a root file, - // then everything it sucks in may also be marked incorrectly, and needs to be checked again. - if (file_1 && ts.lookUp(sourceFilesFoundSearchingNodeModules, file_1.path) && currentNodeModulesDepth == 0) { - sourceFilesFoundSearchingNodeModules[file_1.path] = false; - if (!options.noResolve) { - processReferencedFiles(file_1, ts.getDirectoryPath(fileName), isDefaultLib); - processTypeReferenceDirectives(file_1); - } - modulesWithElidedImports[file_1.path] = false; - processImportedModules(file_1, ts.getDirectoryPath(fileName)); - } - else if (file_1 && ts.lookUp(modulesWithElidedImports, file_1.path)) { - if (currentNodeModulesDepth < maxNodeModulesJsDepth) { + // See if we need to reprocess the imports due to prior skipped imports + if (file_1 && ts.lookUp(modulesWithElidedImports, file_1.path)) { + if (currentNodeModulesJsDepth < maxNodeModulesJsDepth) { modulesWithElidedImports[file_1.path] = false; processImportedModules(file_1, ts.getDirectoryPath(fileName)); } @@ -44679,7 +44623,6 @@ var ts; }); filesByName.set(path, file); if (file) { - sourceFilesFoundSearchingNodeModules[path] = (currentNodeModulesDepth > 0); file.path = path; if (host.useCaseSensitiveFileNames()) { // for case-sensitive file systems check if we've already seen some file with similar filename ignoring case @@ -44794,9 +44737,12 @@ var ts; var isFromNodeModulesSearch = resolution && resolution.isExternalLibraryImport; var isJsFileFromNodeModules = isFromNodeModulesSearch && ts.hasJavaScriptFileExtension(resolution.resolvedFileName); if (isFromNodeModulesSearch) { - currentNodeModulesDepth++; + sourceFilesFoundSearchingNodeModules[resolvedPath] = true; } - var elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModulesJsDepth; + if (isJsFileFromNodeModules) { + currentNodeModulesJsDepth++; + } + var elideImport = isJsFileFromNodeModules && currentNodeModulesJsDepth > maxNodeModulesJsDepth; var shouldAddFile = resolution && !options.noResolve && i < file.imports.length && !elideImport; if (elideImport) { modulesWithElidedImports[file.path] = true; @@ -44805,8 +44751,8 @@ var ts; findSourceFile(resolution.resolvedFileName, resolvedPath, /*isDefaultLib*/ false, /*isReference*/ false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); } - if (isFromNodeModulesSearch) { - currentNodeModulesDepth--; + if (isJsFileFromNodeModules) { + currentNodeModulesJsDepth--; } } } @@ -45144,12 +45090,12 @@ var ts; { name: "noUnusedLocals", type: "boolean", - description: ts.Diagnostics.Report_errors_on_unused_locals + description: ts.Diagnostics.Report_Errors_on_Unused_Locals }, { name: "noUnusedParameters", type: "boolean", - description: ts.Diagnostics.Report_errors_on_unused_parameters + description: ts.Diagnostics.Report_Errors_on_Unused_Parameters }, { name: "noLib", @@ -47141,7 +47087,7 @@ var ts; else { // b) Check if the part is a prefix of the candidate, in a case insensitive or sensitive // manner. If it does, return that there was a prefix match. - return createPatternMatch(PatternMatchKind.prefix, punctuationStripped, /*isCaseSensitive:*/ ts.startsWith(candidate, chunk.text)); + return createPatternMatch(PatternMatchKind.prefix, punctuationStripped, /*isCaseSensitive:*/ startsWith(candidate, chunk.text)); } } var isLowercase = chunk.isLowerCase; @@ -47407,6 +47353,14 @@ var ts; var str = String.fromCharCode(ch); return str === str.toLowerCase(); } + function startsWith(string, search) { + for (var i = 0, n = search.length; i < n; i++) { + if (string.charCodeAt(i) !== search.charCodeAt(i)) { + return false; + } + } + return true; + } // Assumes 'value' is already lowercase. function indexOfIgnoringCase(string, value) { for (var i = 0, n = string.length - value.length; i <= n; i++) { @@ -49251,7 +49205,6 @@ var ts; ScanAction[ScanAction["RescanSlashToken"] = 2] = "RescanSlashToken"; ScanAction[ScanAction["RescanTemplateToken"] = 3] = "RescanTemplateToken"; ScanAction[ScanAction["RescanJsxIdentifier"] = 4] = "RescanJsxIdentifier"; - ScanAction[ScanAction["RescanJsxText"] = 5] = "RescanJsxText"; })(ScanAction || (ScanAction = {})); function getFormattingScanner(sourceFile, startPos, endPos) { ts.Debug.assert(scanner === undefined); @@ -49343,9 +49296,6 @@ var ts; } return false; } - function shouldRescanJsxText(node) { - return node && node.kind === 244 /* JsxText */; - } function shouldRescanSlashToken(container) { return container.kind === 10 /* RegularExpressionLiteral */; } @@ -49376,9 +49326,7 @@ var ts; ? 3 /* RescanTemplateToken */ : shouldRescanJsxIdentifier(n) ? 4 /* RescanJsxIdentifier */ - : shouldRescanJsxText(n) - ? 5 /* RescanJsxText */ - : 0 /* Scan */; + : 0 /* Scan */; if (lastTokenInfo && expectedScanAction === lastScanAction) { // readTokenInfo was called before with the same expected scan action. // No need to re-scan text, return existing 'lastTokenInfo' @@ -49413,10 +49361,6 @@ var ts; currentToken = scanner.scanJsxIdentifier(); lastScanAction = 4 /* RescanJsxIdentifier */; } - else if (expectedScanAction === 5 /* RescanJsxText */) { - currentToken = scanner.reScanJsxToken(); - lastScanAction = 5 /* RescanJsxText */; - } else { lastScanAction = 0 /* Scan */; } @@ -52089,20 +52033,19 @@ var ts; "version" ]; var jsDocCompletionEntries; - function createNode(kind, pos, end, parent) { - var node = kind >= 139 /* FirstNode */ ? new NodeObject(kind, pos, end) : - kind === 69 /* Identifier */ ? new IdentifierObject(kind, pos, end) : - new TokenObject(kind, pos, end); + function createNode(kind, pos, end, flags, parent) { + var node = new NodeObject(kind, pos, end); + node.flags = flags; node.parent = parent; return node; } var NodeObject = (function () { function NodeObject(kind, pos, end) { + this.kind = kind; this.pos = pos; this.end = end; this.flags = 0 /* None */; this.parent = undefined; - this.kind = kind; } NodeObject.prototype.getSourceFile = function () { return ts.getSourceFileOfNode(this); @@ -52137,14 +52080,14 @@ var ts; var token = useJSDocScanner ? scanner.scanJSDocToken() : scanner.scan(); var textPos = scanner.getTextPos(); if (textPos <= end) { - nodes.push(createNode(token, pos, textPos, this)); + nodes.push(createNode(token, pos, textPos, 0, this)); } pos = textPos; } return pos; }; NodeObject.prototype.createSyntaxList = function (nodes) { - var list = createNode(282 /* SyntaxList */, nodes.pos, nodes.end, this); + var list = createNode(282 /* SyntaxList */, nodes.pos, nodes.end, 0, this); list._children = []; var pos = nodes.pos; for (var _i = 0, nodes_4 = nodes; _i < nodes_4.length; _i++) { @@ -52230,74 +52173,6 @@ var ts; }; return NodeObject; }()); - var TokenOrIdentifierObject = (function () { - function TokenOrIdentifierObject(pos, end) { - // Set properties in same order as NodeObject - this.pos = pos; - this.end = end; - this.flags = 0 /* None */; - this.parent = undefined; - } - TokenOrIdentifierObject.prototype.getSourceFile = function () { - return ts.getSourceFileOfNode(this); - }; - TokenOrIdentifierObject.prototype.getStart = function (sourceFile, includeJsDocComment) { - return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment); - }; - TokenOrIdentifierObject.prototype.getFullStart = function () { - return this.pos; - }; - TokenOrIdentifierObject.prototype.getEnd = function () { - return this.end; - }; - TokenOrIdentifierObject.prototype.getWidth = function (sourceFile) { - return this.getEnd() - this.getStart(sourceFile); - }; - TokenOrIdentifierObject.prototype.getFullWidth = function () { - return this.end - this.pos; - }; - TokenOrIdentifierObject.prototype.getLeadingTriviaWidth = function (sourceFile) { - return this.getStart(sourceFile) - this.pos; - }; - TokenOrIdentifierObject.prototype.getFullText = function (sourceFile) { - return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end); - }; - TokenOrIdentifierObject.prototype.getText = function (sourceFile) { - return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd()); - }; - TokenOrIdentifierObject.prototype.getChildCount = function (sourceFile) { - return 0; - }; - TokenOrIdentifierObject.prototype.getChildAt = function (index, sourceFile) { - return undefined; - }; - TokenOrIdentifierObject.prototype.getChildren = function (sourceFile) { - return emptyArray; - }; - TokenOrIdentifierObject.prototype.getFirstToken = function (sourceFile) { - return undefined; - }; - TokenOrIdentifierObject.prototype.getLastToken = function (sourceFile) { - return undefined; - }; - return TokenOrIdentifierObject; - }()); - var TokenObject = (function (_super) { - __extends(TokenObject, _super); - function TokenObject(kind, pos, end) { - _super.call(this, pos, end); - this.kind = kind; - } - return TokenObject; - }(TokenOrIdentifierObject)); - var IdentifierObject = (function (_super) { - __extends(IdentifierObject, _super); - function IdentifierObject(kind, pos, end) { - _super.call(this, pos, end); - } - return IdentifierObject; - }(TokenOrIdentifierObject)); - IdentifierObject.prototype.kind = 69 /* Identifier */; var SymbolObject = (function () { function SymbolObject(flags, name) { this.flags = flags; @@ -59062,8 +58937,6 @@ var ts; function initializeServices() { ts.objectAllocator = { getNodeConstructor: function () { return NodeObject; }, - getTokenConstructor: function () { return TokenObject; }, - getIdentifierConstructor: function () { return IdentifierObject; }, getSourceFileConstructor: function () { return SourceFileObject; }, getSymbolConstructor: function () { return SymbolObject; }, getTypeConstructor: function () { return TypeObject; }, @@ -59689,7 +59562,7 @@ var ts; // /// /* @internal */ -var debugObjectHost = new Function("return this")(); +var debugObjectHost = this; // We need to use 'null' to interface with the managed side. /* tslint:disable:no-null-keyword */ /* tslint:disable:no-in-operator */ @@ -59828,7 +59701,7 @@ var ts; return this.shimHost.getCurrentDirectory(); }; LanguageServiceShimHostAdapter.prototype.getDirectories = function (path) { - return JSON.parse(this.shimHost.getDirectories(path)); + return this.shimHost.getDirectories(path); }; LanguageServiceShimHostAdapter.prototype.getDefaultLibFileName = function (options) { return this.shimHost.getDefaultLibFileName(JSON.stringify(options)); diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index a14277d920b..4ffdd868f16 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -409,10 +409,7 @@ declare namespace ts { interface ModifiersArray extends NodeArray { flags: NodeFlags; } - interface Token extends Node { - __tokenTag: any; - } - interface Modifier extends Token { + interface Modifier extends Node { } interface Identifier extends PrimaryExpression { text: string; @@ -1699,6 +1696,7 @@ declare namespace ts { getCancellationToken?(): CancellationToken; getDefaultLibFileName(options: CompilerOptions): string; getDefaultLibLocation?(): string; + getDefaultTypeDirectiveNames?(rootPath: string): string[]; writeFile: WriteFileCallback; getCurrentDirectory(): string; getDirectories(path: string): string[]; @@ -1844,6 +1842,8 @@ declare namespace ts { function collapseTextChangeRangesAcrossMultipleVersions(changes: TextChangeRange[]): TextChangeRange; function getTypeParameterOwner(d: Declaration): Declaration; function isParameterPropertyDeclaration(node: ParameterDeclaration): boolean; + function startsWith(str: string, prefix: string): boolean; + function endsWith(str: string, suffix: string): boolean; } declare namespace ts { function createNode(kind: SyntaxKind, pos?: number, end?: number): Node; @@ -1868,12 +1868,6 @@ declare namespace ts { function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations; function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; - interface FormatDiagnosticsHost { - getCurrentDirectory(): string; - getCanonicalFileName(fileName: string): string; - getNewLine(): string; - } - function formatDiagnostics(diagnostics: Diagnostic[], host: FormatDiagnosticsHost): string; function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string; /** * Given a set of options and a set of root files, returns the set of type directive names diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 41d3676a415..22cbe79129c 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -1756,19 +1756,10 @@ var ts; return true; } ts.containsPath = containsPath; - /* @internal */ - function startsWith(str, prefix) { - return str.lastIndexOf(prefix, 0) === 0; - } - ts.startsWith = startsWith; - /* @internal */ - function endsWith(str, suffix) { - var expectedPos = str.length - suffix.length; - return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos; - } - ts.endsWith = endsWith; function fileExtensionIs(path, extension) { - return path.length > extension.length && endsWith(path, extension); + var pathLen = path.length; + var extLen = extension.length; + return pathLen > extLen && path.substr(pathLen - extLen, extLen) === extension; } ts.fileExtensionIs = fileExtensionIs; function fileExtensionIsAny(path, extensions) { @@ -2079,8 +2070,6 @@ var ts; } ts.objectAllocator = { getNodeConstructor: function () { return Node; }, - getTokenConstructor: function () { return Node; }, - getIdentifierConstructor: function () { return Node; }, getSourceFileConstructor: function () { return Node; }, getSymbolConstructor: function () { return Symbol; }, getTypeConstructor: function () { return Type; }, @@ -2227,7 +2216,7 @@ var ts; function readDirectory(path, extensions, excludes, includes) { return ts.matchFiles(path, extensions, excludes, includes, /*useCaseSensitiveFileNames*/ false, shell.CurrentDirectory, getAccessibleFileSystemEntries); } - var wscriptSystem = { + return { args: args, newLine: "\r\n", useCaseSensitiveFileNames: false, @@ -2246,7 +2235,7 @@ var ts; return fso.FolderExists(path); }, createDirectory: function (directoryName) { - if (!wscriptSystem.directoryExists(directoryName)) { + if (!this.directoryExists(directoryName)) { fso.CreateFolder(directoryName); } }, @@ -2266,7 +2255,6 @@ var ts; } } }; - return wscriptSystem; } function getNodeSystem() { var _fs = require("fs"); @@ -2456,7 +2444,7 @@ var ts; function getDirectories(path) { return ts.filter(_fs.readdirSync(path), function (p) { return fileSystemEntryExists(ts.combinePaths(path, p), 1 /* Directory */); }); } - var nodeSystem = { + return { args: process.argv.slice(2), newLine: _os.EOL, useCaseSensitiveFileNames: useCaseSensitiveFileNames, @@ -2512,7 +2500,7 @@ var ts; fileExists: fileExists, directoryExists: directoryExists, createDirectory: function (directoryName) { - if (!nodeSystem.directoryExists(directoryName)) { + if (!this.directoryExists(directoryName)) { _fs.mkdirSync(directoryName); } }, @@ -2560,7 +2548,6 @@ var ts; return _fs.realpathSync(path); } }; - return nodeSystem; } function getChakraSystem() { var realpath = ChakraHost.realpath && (function (path) { return ChakraHost.realpath(path); }); @@ -3317,8 +3304,8 @@ var ts; Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: { code: 6131, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", message: "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'." }, File_name_0_has_a_1_extension_stripping_it: { code: 6132, category: ts.DiagnosticCategory.Message, key: "File_name_0_has_a_1_extension_stripping_it_6132", message: "File name '{0}' has a '{1}' extension - stripping it" }, _0_is_declared_but_never_used: { code: 6133, category: ts.DiagnosticCategory.Error, key: "_0_is_declared_but_never_used_6133", message: "'{0}' is declared but never used." }, - Report_errors_on_unused_locals: { code: 6134, category: ts.DiagnosticCategory.Message, key: "Report_errors_on_unused_locals_6134", message: "Report errors on unused locals." }, - Report_errors_on_unused_parameters: { code: 6135, category: ts.DiagnosticCategory.Message, key: "Report_errors_on_unused_parameters_6135", message: "Report errors on unused parameters." }, + Report_Errors_on_Unused_Locals: { code: 6134, category: ts.DiagnosticCategory.Message, key: "Report_Errors_on_Unused_Locals_6134", message: "Report Errors on Unused Locals." }, + Report_Errors_on_Unused_Parameters: { code: 6135, category: ts.DiagnosticCategory.Message, key: "Report_Errors_on_Unused_Parameters_6135", message: "Report Errors on Unused Parameters." }, The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files: { code: 6136, category: ts.DiagnosticCategory.Message, key: "The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files_6136", message: "The maximum dependency depth to search under node_modules and load JavaScript files" }, No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0: { code: 6137, category: ts.DiagnosticCategory.Message, key: "No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0_6137", message: "No types specified in 'package.json' but 'allowJs' is set, so returning 'main' value of '{0}'" }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." }, @@ -6166,7 +6153,7 @@ var ts; function isExternalModuleNameRelative(moduleName) { // TypeScript 1.0 spec (April 2014): 11.2.1 // An external module name is "relative" if the first term is "." or "..". - return /^\.\.?($|[\\/])/.test(moduleName); + return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\"; } ts.isExternalModuleNameRelative = isExternalModuleNameRelative; function isInstantiatedModule(node, preserveConstEnums) { @@ -7929,6 +7916,15 @@ var ts; return node.flags & 92 /* ParameterPropertyModifier */ && node.parent.kind === 148 /* Constructor */ && ts.isClassLike(node.parent.parent); } ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration; + function startsWith(str, prefix) { + return str.lastIndexOf(prefix, 0) === 0; + } + ts.startsWith = startsWith; + function endsWith(str, suffix) { + var expectedPos = str.length - suffix.length; + return str.indexOf(suffix, expectedPos) === expectedPos; + } + ts.endsWith = endsWith; })(ts || (ts = {})); /// /// @@ -7936,19 +7932,11 @@ var ts; (function (ts) { /* @internal */ ts.parseTime = 0; var NodeConstructor; - var TokenConstructor; - var IdentifierConstructor; var SourceFileConstructor; function createNode(kind, pos, end) { if (kind === 256 /* SourceFile */) { return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end); } - else if (kind === 69 /* Identifier */) { - return new (IdentifierConstructor || (IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor()))(kind, pos, end); - } - else if (kind < 139 /* FirstNode */) { - return new (TokenConstructor || (TokenConstructor = ts.objectAllocator.getTokenConstructor()))(kind, pos, end); - } else { return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end); } @@ -8398,8 +8386,6 @@ var ts; var disallowInAndDecoratorContext = 4194304 /* DisallowInContext */ | 16777216 /* DecoratorContext */; // capture constructors in 'initializeState' to avoid null checks var NodeConstructor; - var TokenConstructor; - var IdentifierConstructor; var SourceFileConstructor; var sourceFile; var parseDiagnostics; @@ -8499,8 +8485,6 @@ var ts; } function initializeState(fileName, _sourceText, languageVersion, _syntaxCursor, scriptKind) { NodeConstructor = ts.objectAllocator.getNodeConstructor(); - TokenConstructor = ts.objectAllocator.getTokenConstructor(); - IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor(); SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor(); sourceText = _sourceText; syntaxCursor = _syntaxCursor; @@ -8871,9 +8855,7 @@ var ts; if (!(pos >= 0)) { pos = scanner.getStartPos(); } - return kind >= 139 /* FirstNode */ ? new NodeConstructor(kind, pos, pos) : - kind === 69 /* Identifier */ ? new IdentifierConstructor(kind, pos, pos) : - new TokenConstructor(kind, pos, pos); + return new NodeConstructor(kind, pos, pos); } function finishNode(node, end) { node.end = end === undefined ? scanner.getStartPos() : end; @@ -13542,9 +13524,6 @@ var ts; case 55 /* AtToken */: if (canParseTag) { parentTagTerminated = !tryParseChildTag(jsDocTypeLiteral); - if (!parentTagTerminated) { - resumePos = scanner.getStartPos(); - } } seenAsterisk = false; break; @@ -19012,24 +18991,22 @@ var ts; if (declaration.kind === 235 /* ExportAssignment */) { return links.type = checkExpression(declaration.expression); } - if (declaration.flags & 134217728 /* JavaScriptFile */ && declaration.kind === 280 /* JSDocPropertyTag */ && declaration.typeExpression) { - return links.type = getTypeFromTypeNode(declaration.typeExpression.type); - } // Handle variable, parameter or property if (!pushTypeResolution(symbol, 0 /* Type */)) { return unknownType; } var type = undefined; - // Handle certain special assignment kinds, which happen to union across multiple declarations: - // * module.exports = expr - // * exports.p = expr - // * this.p = expr - // * className.prototype.method = expr - if (declaration.kind === 187 /* BinaryExpression */ || - declaration.kind === 172 /* PropertyAccessExpression */ && declaration.parent.kind === 187 /* BinaryExpression */) { - type = getUnionType(ts.map(symbol.declarations, function (decl) { return decl.kind === 187 /* BinaryExpression */ ? - checkExpressionCached(decl.right) : - checkExpressionCached(decl.parent.right); })); + // Handle module.exports = expr or this.p = expr + if (declaration.kind === 187 /* BinaryExpression */) { + type = getUnionType(ts.map(symbol.declarations, function (decl) { return checkExpressionCached(decl.right); })); + } + else if (declaration.kind === 172 /* PropertyAccessExpression */) { + // Declarations only exist for property access expressions for certain + // special assignment kinds + if (declaration.parent.kind === 187 /* BinaryExpression */) { + // Handle exports.p = expr or className.prototype.method = expr + type = checkExpressionCached(declaration.parent.right); + } } if (type === undefined) { type = getWidenedTypeForVariableLikeDeclaration(declaration, /*reportErrors*/ true); @@ -26784,7 +26761,7 @@ var ts; function getInferredClassType(symbol) { var links = getSymbolLinks(symbol); if (!links.inferredClassType) { - links.inferredClassType = createAnonymousType(symbol, symbol.members, emptyArray, emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined); + links.inferredClassType = createAnonymousType(undefined, symbol.members, emptyArray, emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined); } return links.inferredClassType; } @@ -28225,7 +28202,7 @@ var ts; checkAsyncFunctionReturnType(node); } } - if (noUnusedIdentifiers && !node.body) { + if (!node.body) { checkUnusedTypeParameters(node); } } @@ -29364,7 +29341,6 @@ var ts; var parameter = local_1.valueDeclaration; if (compilerOptions.noUnusedParameters && !ts.isParameterPropertyDeclaration(parameter) && - !parameterIsThisKeyword(parameter) && !parameterNameStartsWithUnderscore(parameter)) { error(local_1.valueDeclaration.name, ts.Diagnostics._0_is_declared_but_never_used, local_1.name); } @@ -29380,9 +29356,6 @@ var ts; } } } - function parameterIsThisKeyword(parameter) { - return parameter.name && parameter.name.originalKeywordKind === 97 /* ThisKeyword */; - } function parameterNameStartsWithUnderscore(parameter) { return parameter.name && parameter.name.kind === 69 /* Identifier */ && parameter.name.text.charCodeAt(0) === 95 /* _ */; } @@ -29411,16 +29384,9 @@ var ts; function checkUnusedTypeParameters(node) { if (compilerOptions.noUnusedLocals && !ts.isInAmbientContext(node)) { if (node.typeParameters) { - // Only report errors on the last declaration for the type parameter container; - // this ensures that all uses have been accounted for. - var symbol = getSymbolOfNode(node); - var lastDeclaration = symbol && symbol.declarations && ts.lastOrUndefined(symbol.declarations); - if (lastDeclaration !== node) { - return; - } for (var _i = 0, _a = node.typeParameters; _i < _a.length; _i++) { var typeParameter = _a[_i]; - if (!getMergedSymbol(typeParameter.symbol).isReferenced) { + if (!typeParameter.symbol.isReferenced) { error(typeParameter.name, ts.Diagnostics._0_is_declared_but_never_used, typeParameter.symbol.name); } } @@ -30753,7 +30719,7 @@ var ts; ts.forEach(node.members, checkSourceElement); if (produceDiagnostics) { checkTypeForDuplicateIndexSignatures(node); - registerForUnusedIdentifiersCheck(node); + checkUnusedTypeParameters(node); } } function checkTypeAliasDeclaration(node) { @@ -36017,7 +35983,7 @@ var ts; writeLine(); var sourceMappingURL = sourceMap.getSourceMappingURL(); if (sourceMappingURL) { - write("//# " + "sourceMappingURL" + "=" + sourceMappingURL); // Sometimes tools can sometimes see this line as a source mapping url comment + write("//# sourceMappingURL=" + sourceMappingURL); } writeEmittedFiles(writer.getText(), jsFilePath, sourceMapFilePath, /*writeByteOrderMark*/ compilerOptions.emitBOM, sourceFiles); // reset the state @@ -37914,7 +37880,7 @@ var ts; * if we should also export the value after its it changed * - check if node is a source level declaration to emit it differently, * i.e non-exported variable statement 'var x = 1' is hoisted so - * when we emit variable statement 'var' should be dropped. + * we we emit variable statement 'var' should be dropped. */ function isSourceFileLevelDeclarationInSystemJsModule(node, isExported) { if (!node || !isCurrentFileSystemExternalModule()) { @@ -40381,13 +40347,13 @@ var ts; if (isES6ExportedDeclaration(node) && !(node.flags & 512 /* Default */) && decoratedClassAlias === undefined) { write("export "); } + if (!isHoistedDeclarationInSystemModule) { + write("let "); + } if (decoratedClassAlias !== undefined) { - write("let " + decoratedClassAlias); + write("" + decoratedClassAlias); } else { - if (!isHoistedDeclarationInSystemModule) { - write("let "); - } emitDeclarationName(node); } write(" = "); @@ -40406,9 +40372,7 @@ var ts; // // We'll emit: // - // let C_1 = class C{}; - // C_1.a = 1; - // C_1.b = 2; // so forth and so on + // (_temp = class C { ... }, _temp.a = 1, _temp.b = 2, _temp) // // This keeps the expression as an expression, while ensuring that the static parts // of it have been initialized by the time it is used. @@ -42972,7 +42936,7 @@ var ts; /* @internal */ ts.ioReadTime = 0; /* @internal */ ts.ioWriteTime = 0; /** The version of the TypeScript compiler release */ - ts.version = "2.1.0"; + ts.version = "2.0.0"; var emptyArray = []; var defaultTypeRoots = ["node_modules/@types"]; function findConfigFile(searchPath, fileExists) { @@ -43061,7 +43025,12 @@ var ts; return { resolvedModule: resolvedFileName ? { resolvedFileName: resolvedFileName, isExternalLibraryImport: isExternalLibraryImport } : undefined, failedLookupLocations: failedLookupLocations }; } function moduleHasNonRelativeName(moduleName) { - return !(ts.isRootedDiskPath(moduleName) || ts.isExternalModuleNameRelative(moduleName)); + if (ts.isRootedDiskPath(moduleName)) { + return false; + } + var i = moduleName.lastIndexOf("./", 1); + var startsWithDotSlashOrDotDotSlash = i === 0 || (i === 1 && moduleName.charCodeAt(0) === 46 /* dot */); + return !startsWithDotSlashOrDotDotSlash; } function tryReadTypesSection(packageJsonPath, baseDirectory, state) { var jsonContent; @@ -43828,22 +43797,6 @@ var ts; return ts.sortAndDeduplicateDiagnostics(diagnostics); } ts.getPreEmitDiagnostics = getPreEmitDiagnostics; - function formatDiagnostics(diagnostics, host) { - var output = ""; - for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) { - var diagnostic = diagnostics_1[_i]; - if (diagnostic.file) { - var _a = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start), line = _a.line, character = _a.character; - var fileName = diagnostic.file.fileName; - var relativeFileName = ts.convertToRelativePath(fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }); - output += relativeFileName + "(" + (line + 1) + "," + (character + 1) + "): "; - } - var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase(); - output += category + " TS" + diagnostic.code + ": " + flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) + host.getNewLine(); - } - return output; - } - ts.formatDiagnostics = formatDiagnostics; function flattenDiagnosticMessageText(messageText, newLine) { if (typeof messageText === "string") { return messageText; @@ -43936,11 +43889,11 @@ var ts; // As all these operations happen - and are nested - within the createProgram call, they close over the below variables. // The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses. var maxNodeModulesJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 2; - var currentNodeModulesDepth = 0; + var currentNodeModulesJsDepth = 0; // If a module has some of its imports skipped due to being at the depth limit under node_modules, then track // this, as it may be imported at a shallower depth later, and then it will need its skipped imports processed. var modulesWithElidedImports = {}; - // Track source files that are source files found by searching under node_modules, as these shouldn't be compiled. + // Track source files that are JavaScript files found by searching under node_modules, as these shouldn't be compiled. var sourceFilesFoundSearchingNodeModules = {}; var start = new Date().getTime(); host = host || createCompilerHost(options); @@ -44197,7 +44150,8 @@ var ts; return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ false)); } function emit(sourceFile, writeFileCallback, cancellationToken) { - return runWithCancellationToken(function () { return emitWorker(program, sourceFile, writeFileCallback, cancellationToken); }); + var _this = this; + return runWithCancellationToken(function () { return emitWorker(_this, sourceFile, writeFileCallback, cancellationToken); }); } function isEmitBlocked(emitFileName) { return hasEmitBlockingDiagnostics.contains(ts.toPath(emitFileName, currentDirectory, getCanonicalFileName)); @@ -44649,19 +44603,9 @@ var ts; if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) { reportFileNamesDifferOnlyInCasingError(fileName, file_1.fileName, refFile, refPos, refEnd); } - // If the file was previously found via a node_modules search, but is now being processed as a root file, - // then everything it sucks in may also be marked incorrectly, and needs to be checked again. - if (file_1 && ts.lookUp(sourceFilesFoundSearchingNodeModules, file_1.path) && currentNodeModulesDepth == 0) { - sourceFilesFoundSearchingNodeModules[file_1.path] = false; - if (!options.noResolve) { - processReferencedFiles(file_1, ts.getDirectoryPath(fileName), isDefaultLib); - processTypeReferenceDirectives(file_1); - } - modulesWithElidedImports[file_1.path] = false; - processImportedModules(file_1, ts.getDirectoryPath(fileName)); - } - else if (file_1 && ts.lookUp(modulesWithElidedImports, file_1.path)) { - if (currentNodeModulesDepth < maxNodeModulesJsDepth) { + // See if we need to reprocess the imports due to prior skipped imports + if (file_1 && ts.lookUp(modulesWithElidedImports, file_1.path)) { + if (currentNodeModulesJsDepth < maxNodeModulesJsDepth) { modulesWithElidedImports[file_1.path] = false; processImportedModules(file_1, ts.getDirectoryPath(fileName)); } @@ -44679,7 +44623,6 @@ var ts; }); filesByName.set(path, file); if (file) { - sourceFilesFoundSearchingNodeModules[path] = (currentNodeModulesDepth > 0); file.path = path; if (host.useCaseSensitiveFileNames()) { // for case-sensitive file systems check if we've already seen some file with similar filename ignoring case @@ -44794,9 +44737,12 @@ var ts; var isFromNodeModulesSearch = resolution && resolution.isExternalLibraryImport; var isJsFileFromNodeModules = isFromNodeModulesSearch && ts.hasJavaScriptFileExtension(resolution.resolvedFileName); if (isFromNodeModulesSearch) { - currentNodeModulesDepth++; + sourceFilesFoundSearchingNodeModules[resolvedPath] = true; } - var elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModulesJsDepth; + if (isJsFileFromNodeModules) { + currentNodeModulesJsDepth++; + } + var elideImport = isJsFileFromNodeModules && currentNodeModulesJsDepth > maxNodeModulesJsDepth; var shouldAddFile = resolution && !options.noResolve && i < file.imports.length && !elideImport; if (elideImport) { modulesWithElidedImports[file.path] = true; @@ -44805,8 +44751,8 @@ var ts; findSourceFile(resolution.resolvedFileName, resolvedPath, /*isDefaultLib*/ false, /*isReference*/ false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); } - if (isFromNodeModulesSearch) { - currentNodeModulesDepth--; + if (isJsFileFromNodeModules) { + currentNodeModulesJsDepth--; } } } @@ -45144,12 +45090,12 @@ var ts; { name: "noUnusedLocals", type: "boolean", - description: ts.Diagnostics.Report_errors_on_unused_locals + description: ts.Diagnostics.Report_Errors_on_Unused_Locals }, { name: "noUnusedParameters", type: "boolean", - description: ts.Diagnostics.Report_errors_on_unused_parameters + description: ts.Diagnostics.Report_Errors_on_Unused_Parameters }, { name: "noLib", @@ -47141,7 +47087,7 @@ var ts; else { // b) Check if the part is a prefix of the candidate, in a case insensitive or sensitive // manner. If it does, return that there was a prefix match. - return createPatternMatch(PatternMatchKind.prefix, punctuationStripped, /*isCaseSensitive:*/ ts.startsWith(candidate, chunk.text)); + return createPatternMatch(PatternMatchKind.prefix, punctuationStripped, /*isCaseSensitive:*/ startsWith(candidate, chunk.text)); } } var isLowercase = chunk.isLowerCase; @@ -47407,6 +47353,14 @@ var ts; var str = String.fromCharCode(ch); return str === str.toLowerCase(); } + function startsWith(string, search) { + for (var i = 0, n = search.length; i < n; i++) { + if (string.charCodeAt(i) !== search.charCodeAt(i)) { + return false; + } + } + return true; + } // Assumes 'value' is already lowercase. function indexOfIgnoringCase(string, value) { for (var i = 0, n = string.length - value.length; i <= n; i++) { @@ -49251,7 +49205,6 @@ var ts; ScanAction[ScanAction["RescanSlashToken"] = 2] = "RescanSlashToken"; ScanAction[ScanAction["RescanTemplateToken"] = 3] = "RescanTemplateToken"; ScanAction[ScanAction["RescanJsxIdentifier"] = 4] = "RescanJsxIdentifier"; - ScanAction[ScanAction["RescanJsxText"] = 5] = "RescanJsxText"; })(ScanAction || (ScanAction = {})); function getFormattingScanner(sourceFile, startPos, endPos) { ts.Debug.assert(scanner === undefined); @@ -49343,9 +49296,6 @@ var ts; } return false; } - function shouldRescanJsxText(node) { - return node && node.kind === 244 /* JsxText */; - } function shouldRescanSlashToken(container) { return container.kind === 10 /* RegularExpressionLiteral */; } @@ -49376,9 +49326,7 @@ var ts; ? 3 /* RescanTemplateToken */ : shouldRescanJsxIdentifier(n) ? 4 /* RescanJsxIdentifier */ - : shouldRescanJsxText(n) - ? 5 /* RescanJsxText */ - : 0 /* Scan */; + : 0 /* Scan */; if (lastTokenInfo && expectedScanAction === lastScanAction) { // readTokenInfo was called before with the same expected scan action. // No need to re-scan text, return existing 'lastTokenInfo' @@ -49413,10 +49361,6 @@ var ts; currentToken = scanner.scanJsxIdentifier(); lastScanAction = 4 /* RescanJsxIdentifier */; } - else if (expectedScanAction === 5 /* RescanJsxText */) { - currentToken = scanner.reScanJsxToken(); - lastScanAction = 5 /* RescanJsxText */; - } else { lastScanAction = 0 /* Scan */; } @@ -52089,20 +52033,19 @@ var ts; "version" ]; var jsDocCompletionEntries; - function createNode(kind, pos, end, parent) { - var node = kind >= 139 /* FirstNode */ ? new NodeObject(kind, pos, end) : - kind === 69 /* Identifier */ ? new IdentifierObject(kind, pos, end) : - new TokenObject(kind, pos, end); + function createNode(kind, pos, end, flags, parent) { + var node = new NodeObject(kind, pos, end); + node.flags = flags; node.parent = parent; return node; } var NodeObject = (function () { function NodeObject(kind, pos, end) { + this.kind = kind; this.pos = pos; this.end = end; this.flags = 0 /* None */; this.parent = undefined; - this.kind = kind; } NodeObject.prototype.getSourceFile = function () { return ts.getSourceFileOfNode(this); @@ -52137,14 +52080,14 @@ var ts; var token = useJSDocScanner ? scanner.scanJSDocToken() : scanner.scan(); var textPos = scanner.getTextPos(); if (textPos <= end) { - nodes.push(createNode(token, pos, textPos, this)); + nodes.push(createNode(token, pos, textPos, 0, this)); } pos = textPos; } return pos; }; NodeObject.prototype.createSyntaxList = function (nodes) { - var list = createNode(282 /* SyntaxList */, nodes.pos, nodes.end, this); + var list = createNode(282 /* SyntaxList */, nodes.pos, nodes.end, 0, this); list._children = []; var pos = nodes.pos; for (var _i = 0, nodes_4 = nodes; _i < nodes_4.length; _i++) { @@ -52230,74 +52173,6 @@ var ts; }; return NodeObject; }()); - var TokenOrIdentifierObject = (function () { - function TokenOrIdentifierObject(pos, end) { - // Set properties in same order as NodeObject - this.pos = pos; - this.end = end; - this.flags = 0 /* None */; - this.parent = undefined; - } - TokenOrIdentifierObject.prototype.getSourceFile = function () { - return ts.getSourceFileOfNode(this); - }; - TokenOrIdentifierObject.prototype.getStart = function (sourceFile, includeJsDocComment) { - return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment); - }; - TokenOrIdentifierObject.prototype.getFullStart = function () { - return this.pos; - }; - TokenOrIdentifierObject.prototype.getEnd = function () { - return this.end; - }; - TokenOrIdentifierObject.prototype.getWidth = function (sourceFile) { - return this.getEnd() - this.getStart(sourceFile); - }; - TokenOrIdentifierObject.prototype.getFullWidth = function () { - return this.end - this.pos; - }; - TokenOrIdentifierObject.prototype.getLeadingTriviaWidth = function (sourceFile) { - return this.getStart(sourceFile) - this.pos; - }; - TokenOrIdentifierObject.prototype.getFullText = function (sourceFile) { - return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end); - }; - TokenOrIdentifierObject.prototype.getText = function (sourceFile) { - return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd()); - }; - TokenOrIdentifierObject.prototype.getChildCount = function (sourceFile) { - return 0; - }; - TokenOrIdentifierObject.prototype.getChildAt = function (index, sourceFile) { - return undefined; - }; - TokenOrIdentifierObject.prototype.getChildren = function (sourceFile) { - return emptyArray; - }; - TokenOrIdentifierObject.prototype.getFirstToken = function (sourceFile) { - return undefined; - }; - TokenOrIdentifierObject.prototype.getLastToken = function (sourceFile) { - return undefined; - }; - return TokenOrIdentifierObject; - }()); - var TokenObject = (function (_super) { - __extends(TokenObject, _super); - function TokenObject(kind, pos, end) { - _super.call(this, pos, end); - this.kind = kind; - } - return TokenObject; - }(TokenOrIdentifierObject)); - var IdentifierObject = (function (_super) { - __extends(IdentifierObject, _super); - function IdentifierObject(kind, pos, end) { - _super.call(this, pos, end); - } - return IdentifierObject; - }(TokenOrIdentifierObject)); - IdentifierObject.prototype.kind = 69 /* Identifier */; var SymbolObject = (function () { function SymbolObject(flags, name) { this.flags = flags; @@ -59062,8 +58937,6 @@ var ts; function initializeServices() { ts.objectAllocator = { getNodeConstructor: function () { return NodeObject; }, - getTokenConstructor: function () { return TokenObject; }, - getIdentifierConstructor: function () { return IdentifierObject; }, getSourceFileConstructor: function () { return SourceFileObject; }, getSymbolConstructor: function () { return SymbolObject; }, getTypeConstructor: function () { return TypeObject; }, @@ -59689,7 +59562,7 @@ var ts; // /// /* @internal */ -var debugObjectHost = new Function("return this")(); +var debugObjectHost = this; // We need to use 'null' to interface with the managed side. /* tslint:disable:no-null-keyword */ /* tslint:disable:no-in-operator */ @@ -59828,7 +59701,7 @@ var ts; return this.shimHost.getCurrentDirectory(); }; LanguageServiceShimHostAdapter.prototype.getDirectories = function (path) { - return JSON.parse(this.shimHost.getDirectories(path)); + return this.shimHost.getDirectories(path); }; LanguageServiceShimHostAdapter.prototype.getDefaultLibFileName = function (options) { return this.shimHost.getDefaultLibFileName(JSON.stringify(options)); diff --git a/package.json b/package.json index eb34b6bffbb..1f943f89788 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "through2": "latest", "travis-fold": "latest", "ts-node": "latest", + "tsd": "latest", "tslint": "next", "typescript": "next" }, diff --git a/scripts/browserify-optional.js b/scripts/browserify-optional.js new file mode 100644 index 00000000000..43997c7803c --- /dev/null +++ b/scripts/browserify-optional.js @@ -0,0 +1,24 @@ +// simple script to optionally elide source-map-support (or other optional modules) when running browserify. + +var stream = require("stream"), + Transform = stream.Transform, + resolve = require("browser-resolve"); + +var requirePattern = /require\s*\(\s*['"](source-map-support)['"]\s*\)/; +module.exports = function (file) { + return new Transform({ + transform: function (data, encoding, cb) { + var text = encoding === "buffer" ? data.toString("utf8") : data; + this.push(new Buffer(text.replace(requirePattern, function (originalText, moduleName) { + try { + resolve.sync(moduleName, { filename: file }); + return originalText; + } + catch (e) { + return "(function () { throw new Error(\"module '" + moduleName + "' not found.\"); })()"; + } + }), "utf8")); + cb(); + } + }); +}; \ No newline at end of file diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index d8017d601ad..50c3adf1310 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -27,7 +27,7 @@ namespace ts { return ModuleInstanceState.ConstEnumOnly; } // 3. non-exported import declarations - else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && !(node.flags & NodeFlags.Export)) { + else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && !(hasModifier(node, ModifierFlags.Export))) { return ModuleInstanceState.NonInstantiated; } // 4. other uninstantiated module declarations. @@ -131,6 +131,10 @@ namespace ts { const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; const reportedUnreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; + // state used to aggregate transform flags during bind. + let subtreeTransformFlags: TransformFlags = TransformFlags.None; + let skipTransformFlagAggregation: boolean; + function bindSourceFile(f: SourceFile, opts: CompilerOptions) { file = f; options = opts; @@ -138,6 +142,7 @@ namespace ts { inStrictMode = !!file.externalModuleIndicator; classifiableNames = createMap(); symbolCount = 0; + skipTransformFlagAggregation = isDeclarationFile(file); Symbol = objectAllocator.getSymbolConstructor(); @@ -164,6 +169,7 @@ namespace ts { activeLabels = undefined; hasExplicitReturn = false; emitFlags = NodeFlags.None; + subtreeTransformFlags = TransformFlags.None; } return bindSourceFile; @@ -253,7 +259,7 @@ namespace ts { case SyntaxKind.FunctionDeclaration: case SyntaxKind.ClassDeclaration: - return node.flags & NodeFlags.Default ? "default" : undefined; + return hasModifier(node, ModifierFlags.Default) ? "default" : undefined; case SyntaxKind.JSDocFunctionType: return isJSDocConstructSignature(node) ? "__new" : "__call"; case SyntaxKind.Parameter: @@ -293,7 +299,7 @@ namespace ts { function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol { Debug.assert(!hasDynamicName(node)); - const isDefaultExport = node.flags & NodeFlags.Default; + const isDefaultExport = hasModifier(node, ModifierFlags.Default); // The exported symbol for an export default function/class node is always named "default" const name = isDefaultExport && parent ? "default" : getDeclarationName(node); @@ -350,7 +356,7 @@ namespace ts { : Diagnostics.Duplicate_identifier_0; forEach(symbol.declarations, declaration => { - if (declaration.flags & NodeFlags.Default) { + if (hasModifier(declaration, ModifierFlags.Default)) { message = Diagnostics.A_module_cannot_have_multiple_default_exports; } }); @@ -372,7 +378,7 @@ namespace ts { } function declareModuleMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { - const hasExportModifier = getCombinedNodeFlags(node) & NodeFlags.Export; + const hasExportModifier = getCombinedModifierFlags(node) & ModifierFlags.Export; if (symbolFlags & SymbolFlags.Alias) { if (node.kind === SyntaxKind.ExportSpecifier || (node.kind === SyntaxKind.ImportEqualsDeclaration && hasExportModifier)) { return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); @@ -513,6 +519,23 @@ namespace ts { } function bindChildren(node: Node): void { + if (skipTransformFlagAggregation) { + bindChildrenWorker(node); + } + else if (node.transformFlags & TransformFlags.HasComputedFlags) { + skipTransformFlagAggregation = true; + bindChildrenWorker(node); + skipTransformFlagAggregation = false; + } + else { + const savedSubtreeTransformFlags = subtreeTransformFlags; + subtreeTransformFlags = 0; + bindChildrenWorker(node); + subtreeTransformFlags = savedSubtreeTransformFlags | computeTransformFlagsForNode(node, subtreeTransformFlags); + } + } + + function bindChildrenWorker(node: Node): void { // Binding of JsDocComment should be done before the current block scope container changes. // because the scope of JsDocComment should not be affected by whether the current node is a // container or not. @@ -1308,7 +1331,7 @@ namespace ts { } function declareClassMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { - return node.flags & NodeFlags.Static + return hasModifier(node, ModifierFlags.Static) ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes) : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); } @@ -1345,7 +1368,7 @@ namespace ts { function bindModuleDeclaration(node: ModuleDeclaration) { setExportContextFlag(node); if (isAmbientModule(node)) { - if (node.flags & NodeFlags.Export) { + if (hasModifier(node, ModifierFlags.Export)) { errorOnFirstToken(node, Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible); } if (isExternalModuleAugmentation(node)) { @@ -1612,7 +1635,7 @@ namespace ts { } } - function checkStrictModeNumericLiteral(node: LiteralExpression) { + function checkStrictModeNumericLiteral(node: NumericLiteral) { if (inStrictMode && node.isOctalLiteral) { file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Octal_literals_are_not_allowed_in_strict_mode)); } @@ -1687,6 +1710,9 @@ namespace ts { } parent = saveParent; } + else if (!skipTransformFlagAggregation && (node.transformFlags & TransformFlags.HasComputedFlags) === 0) { + subtreeTransformFlags |= computeTransformFlagsForNode(node, 0); + } inStrictMode = saveInStrictMode; } @@ -1757,7 +1783,7 @@ namespace ts { case SyntaxKind.DeleteExpression: return checkStrictModeDeleteExpression(node); case SyntaxKind.NumericLiteral: - return checkStrictModeNumericLiteral(node); + return checkStrictModeNumericLiteral(node); case SyntaxKind.PostfixUnaryExpression: return checkStrictModePostfixUnaryExpression(node); case SyntaxKind.PrefixUnaryExpression: @@ -1789,7 +1815,7 @@ namespace ts { return bindPropertyOrMethodOrAccessor(node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes); case SyntaxKind.JsxSpreadAttribute: - emitFlags |= NodeFlags.HasJsxSpreadAttribute; + emitFlags |= NodeFlags.HasJsxSpreadAttributes; return; case SyntaxKind.CallSignature: @@ -2204,7 +2230,7 @@ namespace ts { if (currentFlow === unreachableFlow) { const reportError = // report error on all statements except empty ones - (isStatement(node) && node.kind !== SyntaxKind.EmptyStatement) || + (isStatementButNotDeclaration(node) && node.kind !== SyntaxKind.EmptyStatement) || // report error on class declarations node.kind === SyntaxKind.ClassDeclaration || // report error on instantiated modules or const-enums only modules if preserveConstEnums is set @@ -2241,4 +2267,763 @@ namespace ts { return true; } } + + /** + * Computes the transform flags for a node, given the transform flags of its subtree + * + * @param node The node to analyze + * @param subtreeFlags Transform flags computed for this node's subtree + */ + export function computeTransformFlagsForNode(node: Node, subtreeFlags: TransformFlags): TransformFlags { + const kind = node.kind; + switch (kind) { + case SyntaxKind.CallExpression: + return computeCallExpression(node, subtreeFlags); + + case SyntaxKind.ModuleDeclaration: + return computeModuleDeclaration(node, subtreeFlags); + + case SyntaxKind.ParenthesizedExpression: + return computeParenthesizedExpression(node, subtreeFlags); + + case SyntaxKind.BinaryExpression: + return computeBinaryExpression(node, subtreeFlags); + + case SyntaxKind.ExpressionStatement: + return computeExpressionStatement(node, subtreeFlags); + + case SyntaxKind.Parameter: + return computeParameter(node, subtreeFlags); + + case SyntaxKind.ArrowFunction: + return computeArrowFunction(node, subtreeFlags); + + case SyntaxKind.FunctionExpression: + return computeFunctionExpression(node, subtreeFlags); + + case SyntaxKind.FunctionDeclaration: + return computeFunctionDeclaration(node, subtreeFlags); + + case SyntaxKind.VariableDeclaration: + return computeVariableDeclaration(node, subtreeFlags); + + case SyntaxKind.VariableDeclarationList: + return computeVariableDeclarationList(node, subtreeFlags); + + case SyntaxKind.VariableStatement: + return computeVariableStatement(node, subtreeFlags); + + case SyntaxKind.LabeledStatement: + return computeLabeledStatement(node, subtreeFlags); + + case SyntaxKind.ClassDeclaration: + return computeClassDeclaration(node, subtreeFlags); + + case SyntaxKind.ClassExpression: + return computeClassExpression(node, subtreeFlags); + + case SyntaxKind.HeritageClause: + return computeHeritageClause(node, subtreeFlags); + + case SyntaxKind.ExpressionWithTypeArguments: + return computeExpressionWithTypeArguments(node, subtreeFlags); + + case SyntaxKind.Constructor: + return computeConstructor(node, subtreeFlags); + + case SyntaxKind.PropertyDeclaration: + return computePropertyDeclaration(node, subtreeFlags); + + case SyntaxKind.MethodDeclaration: + return computeMethod(node, subtreeFlags); + + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + return computeAccessor(node, subtreeFlags); + + case SyntaxKind.ImportEqualsDeclaration: + return computeImportEquals(node, subtreeFlags); + + case SyntaxKind.PropertyAccessExpression: + return computePropertyAccess(node, subtreeFlags); + + default: + return computeOther(node, kind, subtreeFlags); + } + } + + function computeCallExpression(node: CallExpression, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + const expression = node.expression; + const expressionKind = expression.kind; + + if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression + || isSuperOrSuperProperty(expression, expressionKind)) { + // If the this node contains a SpreadElementExpression, or is a super call, then it is an ES6 + // node. + transformFlags |= TransformFlags.AssertES6; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes; + } + + function isSuperOrSuperProperty(node: Node, kind: SyntaxKind) { + switch (kind) { + case SyntaxKind.SuperKeyword: + return true; + + case SyntaxKind.PropertyAccessExpression: + case SyntaxKind.ElementAccessExpression: + const expression = (node).expression; + const expressionKind = expression.kind; + return expressionKind === SyntaxKind.SuperKeyword; + } + + return false; + } + + function computeBinaryExpression(node: BinaryExpression, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + const operatorTokenKind = node.operatorToken.kind; + const leftKind = node.left.kind; + + if (operatorTokenKind === SyntaxKind.EqualsToken + && (leftKind === SyntaxKind.ObjectLiteralExpression + || leftKind === SyntaxKind.ArrayLiteralExpression)) { + // Destructuring assignments are ES6 syntax. + transformFlags |= TransformFlags.AssertES6 | TransformFlags.DestructuringAssignment; + } + else if (operatorTokenKind === SyntaxKind.AsteriskAsteriskToken + || operatorTokenKind === SyntaxKind.AsteriskAsteriskEqualsToken) { + // Exponentiation is ES7 syntax. + transformFlags |= TransformFlags.AssertES7; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.NodeExcludes; + } + + function computeParameter(node: ParameterDeclaration, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + const modifierFlags = getModifierFlags(node); + const name = node.name; + const initializer = node.initializer; + const dotDotDotToken = node.dotDotDotToken; + + // If the parameter has a question token, then it is TypeScript syntax. + if (node.questionToken) { + transformFlags |= TransformFlags.AssertTypeScript; + } + + // If the parameter's name is 'this', then it is TypeScript syntax. + if (subtreeFlags & TransformFlags.ContainsDecorators + || (name && isIdentifier(name) && name.originalKeywordKind === SyntaxKind.ThisKeyword)) { + transformFlags |= TransformFlags.AssertTypeScript; + } + + // If a parameter has an accessibility modifier, then it is TypeScript syntax. + if (modifierFlags & ModifierFlags.ParameterPropertyModifier) { + transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.ContainsParameterPropertyAssignments; + } + + // If a parameter has an initializer, a binding pattern or a dotDotDot token, then + // it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel. + if (subtreeFlags & TransformFlags.ContainsBindingPattern || initializer || dotDotDotToken) { + transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsDefaultValueAssignments; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.ParameterExcludes; + } + + function computeParenthesizedExpression(node: ParenthesizedExpression, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + const expression = node.expression; + const expressionKind = expression.kind; + const expressionTransformFlags = expression.transformFlags; + + // If the node is synthesized, it means the emitter put the parentheses there, + // not the user. If we didn't want them, the emitter would not have put them + // there. + if (expressionKind === SyntaxKind.AsExpression + || expressionKind === SyntaxKind.TypeAssertionExpression) { + transformFlags |= TransformFlags.AssertTypeScript; + } + + // If the expression of a ParenthesizedExpression is a destructuring assignment, + // then the ParenthesizedExpression is a destructuring assignment. + if (expressionTransformFlags & TransformFlags.DestructuringAssignment) { + transformFlags |= TransformFlags.DestructuringAssignment; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.NodeExcludes; + } + + function computeClassDeclaration(node: ClassDeclaration, subtreeFlags: TransformFlags) { + let transformFlags: TransformFlags; + const modifierFlags = getModifierFlags(node); + + if (modifierFlags & ModifierFlags.Ambient) { + // An ambient declaration is TypeScript syntax. + transformFlags = TransformFlags.AssertTypeScript; + } + else { + // A ClassDeclaration is ES6 syntax. + transformFlags = subtreeFlags | TransformFlags.AssertES6; + + // A class with a parameter property assignment, property initializer, or decorator is + // TypeScript syntax. + // An exported declaration may be TypeScript syntax. + if ((subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask) + || (modifierFlags & ModifierFlags.Export)) { + transformFlags |= TransformFlags.AssertTypeScript; + } + + if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) { + // A computed property name containing `this` might need to be rewritten, + // so propagate the ContainsLexicalThis flag upward. + transformFlags |= TransformFlags.ContainsLexicalThis; + } + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.ClassExcludes; + } + + function computeClassExpression(node: ClassExpression, subtreeFlags: TransformFlags) { + // A ClassExpression is ES6 syntax. + let transformFlags = subtreeFlags | TransformFlags.AssertES6; + + // A class with a parameter property assignment, property initializer, or decorator is + // TypeScript syntax. + if (subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask) { + transformFlags |= TransformFlags.AssertTypeScript; + } + + if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) { + // A computed property name containing `this` might need to be rewritten, + // so propagate the ContainsLexicalThis flag upward. + transformFlags |= TransformFlags.ContainsLexicalThis; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.ClassExcludes; + } + + function computeHeritageClause(node: HeritageClause, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + + switch (node.token) { + case SyntaxKind.ExtendsKeyword: + // An `extends` HeritageClause is ES6 syntax. + transformFlags |= TransformFlags.AssertES6; + break; + + case SyntaxKind.ImplementsKeyword: + // An `implements` HeritageClause is TypeScript syntax. + transformFlags |= TransformFlags.AssertTypeScript; + break; + + default: + Debug.fail("Unexpected token for heritage clause"); + break; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.NodeExcludes; + } + + function computeExpressionWithTypeArguments(node: ExpressionWithTypeArguments, subtreeFlags: TransformFlags) { + // An ExpressionWithTypeArguments is ES6 syntax, as it is used in the + // extends clause of a class. + let transformFlags = subtreeFlags | TransformFlags.AssertES6; + + // If an ExpressionWithTypeArguments contains type arguments, then it + // is TypeScript syntax. + if (node.typeArguments) { + transformFlags |= TransformFlags.AssertTypeScript; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.NodeExcludes; + } + + function computeConstructor(node: ConstructorDeclaration, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + const body = node.body; + + if (body === undefined) { + // An overload constructor is TypeScript syntax. + transformFlags |= TransformFlags.AssertTypeScript; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.ConstructorExcludes; + } + + function computeMethod(node: MethodDeclaration, subtreeFlags: TransformFlags) { + // A MethodDeclaration is ES6 syntax. + let transformFlags = subtreeFlags | TransformFlags.AssertES6; + const modifierFlags = getModifierFlags(node); + const body = node.body; + const typeParameters = node.typeParameters; + const asteriskToken = node.asteriskToken; + + // A MethodDeclaration is TypeScript syntax if it is either async, abstract, overloaded, + // generic, or has a decorator. + if (!body + || typeParameters + || (modifierFlags & (ModifierFlags.Async | ModifierFlags.Abstract)) + || (subtreeFlags & TransformFlags.ContainsDecorators)) { + transformFlags |= TransformFlags.AssertTypeScript; + } + + // Currently, we only support generators that were originally async function bodies. + if (asteriskToken && node.emitFlags & NodeEmitFlags.AsyncFunctionBody) { + transformFlags |= TransformFlags.AssertGenerator; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.MethodOrAccessorExcludes; + } + + function computeAccessor(node: AccessorDeclaration, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + const modifierFlags = getModifierFlags(node); + const body = node.body; + + // A MethodDeclaration is TypeScript syntax if it is either async, abstract, overloaded, + // generic, or has a decorator. + if (!body + || (modifierFlags & (ModifierFlags.Async | ModifierFlags.Abstract)) + || (subtreeFlags & TransformFlags.ContainsDecorators)) { + transformFlags |= TransformFlags.AssertTypeScript; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.MethodOrAccessorExcludes; + } + + function computePropertyDeclaration(node: PropertyDeclaration, subtreeFlags: TransformFlags) { + // A PropertyDeclaration is TypeScript syntax. + let transformFlags = subtreeFlags | TransformFlags.AssertTypeScript; + + // If the PropertyDeclaration has an initializer, we need to inform its ancestor + // so that it handle the transformation. + if (node.initializer) { + transformFlags |= TransformFlags.ContainsPropertyInitializer; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.NodeExcludes; + } + + function computeFunctionDeclaration(node: FunctionDeclaration, subtreeFlags: TransformFlags) { + let transformFlags: TransformFlags; + const modifierFlags = getModifierFlags(node); + const body = node.body; + const asteriskToken = node.asteriskToken; + + if (!body || (modifierFlags & ModifierFlags.Ambient)) { + // An ambient declaration is TypeScript syntax. + // A FunctionDeclaration without a body is an overload and is TypeScript syntax. + transformFlags = TransformFlags.AssertTypeScript; + } + else { + transformFlags = subtreeFlags | TransformFlags.ContainsHoistedDeclarationOrCompletion; + + // If a FunctionDeclaration is exported, then it is either ES6 or TypeScript syntax. + if (modifierFlags & ModifierFlags.Export) { + transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES6; + } + + // If a FunctionDeclaration is async, then it is TypeScript syntax. + if (modifierFlags & ModifierFlags.Async) { + transformFlags |= TransformFlags.AssertTypeScript; + } + + // If a FunctionDeclaration's subtree has marked the container as needing to capture the + // lexical this, or the function contains parameters with initializers, then this node is + // ES6 syntax. + if (subtreeFlags & TransformFlags.ES6FunctionSyntaxMask) { + transformFlags |= TransformFlags.AssertES6; + } + + // If a FunctionDeclaration is generator function and is the body of a + // transformed async function, then this node can be transformed to a + // down-level generator. + // Currently we do not support transforming any other generator fucntions + // down level. + if (asteriskToken && node.emitFlags & NodeEmitFlags.AsyncFunctionBody) { + transformFlags |= TransformFlags.AssertGenerator; + } + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.FunctionExcludes; + } + + function computeFunctionExpression(node: FunctionExpression, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + const modifierFlags = getModifierFlags(node); + const asteriskToken = node.asteriskToken; + + // An async function expression is TypeScript syntax. + if (modifierFlags & ModifierFlags.Async) { + transformFlags |= TransformFlags.AssertTypeScript; + } + + // If a FunctionExpression's subtree has marked the container as needing to capture the + // lexical this, or the function contains parameters with initializers, then this node is + // ES6 syntax. + if (subtreeFlags & TransformFlags.ES6FunctionSyntaxMask) { + transformFlags |= TransformFlags.AssertES6; + } + + // If a FunctionExpression is generator function and is the body of a + // transformed async function, then this node can be transformed to a + // down-level generator. + // Currently we do not support transforming any other generator fucntions + // down level. + if (asteriskToken && node.emitFlags & NodeEmitFlags.AsyncFunctionBody) { + transformFlags |= TransformFlags.AssertGenerator; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.FunctionExcludes; + } + + function computeArrowFunction(node: ArrowFunction, subtreeFlags: TransformFlags) { + // An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction. + let transformFlags = subtreeFlags | TransformFlags.AssertES6; + const modifierFlags = getModifierFlags(node); + + // An async arrow function is TypeScript syntax. + if (modifierFlags & ModifierFlags.Async) { + transformFlags |= TransformFlags.AssertTypeScript; + } + + // If an ArrowFunction contains a lexical this, its container must capture the lexical this. + if (subtreeFlags & TransformFlags.ContainsLexicalThis) { + transformFlags |= TransformFlags.ContainsCapturedLexicalThis; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.ArrowFunctionExcludes; + } + + function computePropertyAccess(node: PropertyAccessExpression, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + const expression = node.expression; + const expressionKind = expression.kind; + + // If a PropertyAccessExpression starts with a super keyword, then it is + // ES6 syntax, and requires a lexical `this` binding. + if (expressionKind === SyntaxKind.SuperKeyword) { + transformFlags |= TransformFlags.ContainsLexicalThis; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.NodeExcludes; + } + + function computeVariableDeclaration(node: VariableDeclaration, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + const nameKind = node.name.kind; + + // A VariableDeclaration with a binding pattern is ES6 syntax. + if (nameKind === SyntaxKind.ObjectBindingPattern || nameKind === SyntaxKind.ArrayBindingPattern) { + transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsBindingPattern; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.NodeExcludes; + } + + function computeVariableStatement(node: VariableStatement, subtreeFlags: TransformFlags) { + let transformFlags: TransformFlags; + const modifierFlags = getModifierFlags(node); + const declarationListTransformFlags = node.declarationList.transformFlags; + + // An ambient declaration is TypeScript syntax. + if (modifierFlags & ModifierFlags.Ambient) { + transformFlags = TransformFlags.AssertTypeScript; + } + else { + transformFlags = subtreeFlags; + + // If a VariableStatement is exported, then it is either ES6 or TypeScript syntax. + if (modifierFlags & ModifierFlags.Export) { + transformFlags |= TransformFlags.AssertES6 | TransformFlags.AssertTypeScript; + } + + if (declarationListTransformFlags & TransformFlags.ContainsBindingPattern) { + transformFlags |= TransformFlags.AssertES6; + } + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.NodeExcludes; + } + + function computeLabeledStatement(node: LabeledStatement, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + + // A labeled statement containing a block scoped binding *may* need to be transformed from ES6. + if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding + && isIterationStatement(node, /*lookInLabeledStatements*/ true)) { + transformFlags |= TransformFlags.AssertES6; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.NodeExcludes; + } + + function computeImportEquals(node: ImportEqualsDeclaration, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + + // An ImportEqualsDeclaration with a namespace reference is TypeScript. + if (!isExternalModuleImportEqualsDeclaration(node)) { + transformFlags |= TransformFlags.AssertTypeScript; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.NodeExcludes; + } + + function computeExpressionStatement(node: ExpressionStatement, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + + // If the expression of an expression statement is a destructuring assignment, + // then we treat the statement as ES6 so that we can indicate that we do not + // need to hold on to the right-hand side. + if (node.expression.transformFlags & TransformFlags.DestructuringAssignment) { + transformFlags |= TransformFlags.AssertES6; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.NodeExcludes; + } + + function computeModuleDeclaration(node: ModuleDeclaration, subtreeFlags: TransformFlags) { + let transformFlags = TransformFlags.AssertTypeScript; + const modifierFlags = getModifierFlags(node); + + if ((modifierFlags & ModifierFlags.Ambient) === 0) { + transformFlags |= subtreeFlags; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.ModuleExcludes; + } + + function computeVariableDeclarationList(node: VariableDeclarationList, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags | TransformFlags.ContainsHoistedDeclarationOrCompletion; + + if (subtreeFlags & TransformFlags.ContainsBindingPattern) { + transformFlags |= TransformFlags.AssertES6; + } + + // If a VariableDeclarationList is `let` or `const`, then it is ES6 syntax. + if (node.flags & NodeFlags.BlockScoped) { + transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsBlockScopedBinding; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.VariableDeclarationListExcludes; + } + + function computeOther(node: Node, kind: SyntaxKind, subtreeFlags: TransformFlags) { + // Mark transformations needed for each node + let transformFlags = subtreeFlags; + let excludeFlags = TransformFlags.NodeExcludes; + + switch (kind) { + case SyntaxKind.PublicKeyword: + case SyntaxKind.PrivateKeyword: + case SyntaxKind.ProtectedKeyword: + case SyntaxKind.AbstractKeyword: + case SyntaxKind.DeclareKeyword: + case SyntaxKind.AsyncKeyword: + case SyntaxKind.ConstKeyword: + case SyntaxKind.AwaitExpression: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.EnumMember: + case SyntaxKind.TypeAssertionExpression: + case SyntaxKind.AsExpression: + case SyntaxKind.NonNullExpression: + case SyntaxKind.ReadonlyKeyword: + // These nodes are TypeScript syntax. + transformFlags |= TransformFlags.AssertTypeScript; + break; + + case SyntaxKind.JsxElement: + case SyntaxKind.JsxSelfClosingElement: + case SyntaxKind.JsxOpeningElement: + case SyntaxKind.JsxText: + case SyntaxKind.JsxClosingElement: + case SyntaxKind.JsxAttribute: + case SyntaxKind.JsxSpreadAttribute: + case SyntaxKind.JsxExpression: + // These nodes are Jsx syntax. + transformFlags |= TransformFlags.AssertJsx; + break; + + case SyntaxKind.ExportKeyword: + // This node is both ES6 and TypeScript syntax. + transformFlags |= TransformFlags.AssertES6 | TransformFlags.AssertTypeScript; + break; + + case SyntaxKind.DefaultKeyword: + case SyntaxKind.NoSubstitutionTemplateLiteral: + case SyntaxKind.TemplateHead: + case SyntaxKind.TemplateMiddle: + case SyntaxKind.TemplateTail: + case SyntaxKind.TemplateExpression: + case SyntaxKind.TaggedTemplateExpression: + case SyntaxKind.ShorthandPropertyAssignment: + case SyntaxKind.ForOfStatement: + // These nodes are ES6 syntax. + transformFlags |= TransformFlags.AssertES6; + break; + + case SyntaxKind.YieldExpression: + // This node is ES6 syntax. + transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsYield; + break; + + case SyntaxKind.AnyKeyword: + case SyntaxKind.NumberKeyword: + case SyntaxKind.NeverKeyword: + case SyntaxKind.StringKeyword: + case SyntaxKind.BooleanKeyword: + case SyntaxKind.SymbolKeyword: + case SyntaxKind.VoidKeyword: + case SyntaxKind.TypeParameter: + case SyntaxKind.PropertySignature: + case SyntaxKind.MethodSignature: + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.IndexSignature: + case SyntaxKind.TypePredicate: + case SyntaxKind.TypeReference: + case SyntaxKind.FunctionType: + case SyntaxKind.ConstructorType: + case SyntaxKind.TypeQuery: + case SyntaxKind.TypeLiteral: + case SyntaxKind.ArrayType: + case SyntaxKind.TupleType: + case SyntaxKind.UnionType: + case SyntaxKind.IntersectionType: + case SyntaxKind.ParenthesizedType: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.TypeAliasDeclaration: + case SyntaxKind.ThisType: + case SyntaxKind.LiteralType: + // Types and signatures are TypeScript syntax, and exclude all other facts. + transformFlags = TransformFlags.AssertTypeScript; + excludeFlags = TransformFlags.TypeExcludes; + break; + + case SyntaxKind.ComputedPropertyName: + // Even though computed property names are ES6, we don't treat them as such. + // This is so that they can flow through PropertyName transforms unaffected. + // Instead, we mark the container as ES6, so that it can properly handle the transform. + transformFlags |= TransformFlags.ContainsComputedPropertyName; + if (subtreeFlags & TransformFlags.ContainsLexicalThis) { + // A computed method name like `[this.getName()](x: string) { ... }` needs to + // distinguish itself from the normal case of a method body containing `this`: + // `this` inside a method doesn't need to be rewritten (the method provides `this`), + // whereas `this` inside a computed name *might* need to be rewritten if the class/object + // is inside an arrow function: + // `_this = this; () => class K { [_this.getName()]() { ... } }` + // To make this distinction, use ContainsLexicalThisInComputedPropertyName + // instead of ContainsLexicalThis for computed property names + transformFlags |= TransformFlags.ContainsLexicalThisInComputedPropertyName; + } + break; + + case SyntaxKind.SpreadElementExpression: + // This node is ES6 syntax, but is handled by a containing node. + transformFlags |= TransformFlags.ContainsSpreadElementExpression; + break; + + case SyntaxKind.SuperKeyword: + // This node is ES6 syntax. + transformFlags |= TransformFlags.AssertES6; + break; + + case SyntaxKind.ThisKeyword: + // Mark this node and its ancestors as containing a lexical `this` keyword. + transformFlags |= TransformFlags.ContainsLexicalThis; + break; + + case SyntaxKind.ObjectBindingPattern: + case SyntaxKind.ArrayBindingPattern: + // These nodes are ES6 syntax. + transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsBindingPattern; + break; + + case SyntaxKind.Decorator: + // This node is TypeScript syntax, and marks its container as also being TypeScript syntax. + transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.ContainsDecorators; + break; + + case SyntaxKind.ObjectLiteralExpression: + excludeFlags = TransformFlags.ObjectLiteralExcludes; + if (subtreeFlags & TransformFlags.ContainsComputedPropertyName) { + // If an ObjectLiteralExpression contains a ComputedPropertyName, then it + // is an ES6 node. + transformFlags |= TransformFlags.AssertES6; + } + + if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) { + // A computed property name containing `this` might need to be rewritten, + // so propagate the ContainsLexicalThis flag upward. + transformFlags |= TransformFlags.ContainsLexicalThis; + } + + break; + + case SyntaxKind.ArrayLiteralExpression: + case SyntaxKind.NewExpression: + excludeFlags = TransformFlags.ArrayLiteralOrCallOrNewExcludes; + if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression) { + // If the this node contains a SpreadElementExpression, then it is an ES6 + // node. + transformFlags |= TransformFlags.AssertES6; + } + + break; + + case SyntaxKind.DoStatement: + case SyntaxKind.WhileStatement: + case SyntaxKind.ForStatement: + case SyntaxKind.ForInStatement: + // A loop containing a block scoped binding *may* need to be transformed from ES6. + if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding) { + transformFlags |= TransformFlags.AssertES6; + } + + break; + + case SyntaxKind.SourceFile: + if (subtreeFlags & TransformFlags.ContainsCapturedLexicalThis) { + transformFlags |= TransformFlags.AssertES6; + } + + break; + + case SyntaxKind.ReturnStatement: + case SyntaxKind.ContinueStatement: + case SyntaxKind.BreakStatement: + transformFlags |= TransformFlags.ContainsHoistedDeclarationOrCompletion; + break; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~excludeFlags; + } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 863c9e7c37a..da0b09cc781 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2,6 +2,8 @@ /* @internal */ namespace ts { + const ambientModuleSymbolRegex = /^".+"$/; + let nextSymbolId = 1; let nextNodeId = 1; let nextMergeId = 1; @@ -100,6 +102,7 @@ namespace ts { getAliasedSymbol: resolveAlias, getEmitResolver, getExportsOfModule: getExportsOfModuleAsArray, + getAmbientModules, getJsxElementAttributesType, getJsxIntrinsicTagNames, @@ -143,6 +146,7 @@ namespace ts { const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); + const resolvingSignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true); @@ -157,6 +161,7 @@ namespace ts { let getGlobalESSymbolConstructorSymbol: () => Symbol; let getGlobalPromiseConstructorSymbol: () => Symbol; + let tryGetGlobalPromiseConstructorSymbol: () => Symbol; let globalObjectType: ObjectType; let globalFunctionType: ObjectType; @@ -636,7 +641,7 @@ namespace ts { const initializerOfNonStaticProperty = current.parent && current.parent.kind === SyntaxKind.PropertyDeclaration && - (current.parent.flags & NodeFlags.Static) === 0 && + (getModifierFlags(current.parent) & ModifierFlags.Static) === 0 && (current.parent).initializer === current; if (initializerOfNonStaticProperty) { @@ -756,7 +761,7 @@ namespace ts { // local variables of the constructor. This effectively means that entities from outer scopes // by the same name as a constructor parameter or local variable are inaccessible // in initializer expressions for instance member variables. - if (isClassLike(location.parent) && !(location.flags & NodeFlags.Static)) { + if (isClassLike(location.parent) && !(getModifierFlags(location) & ModifierFlags.Static)) { const ctor = findConstructorDeclaration(location.parent); if (ctor && ctor.locals) { if (getSymbol(ctor.locals, name, meaning & SymbolFlags.Value)) { @@ -770,7 +775,7 @@ namespace ts { case SyntaxKind.ClassExpression: case SyntaxKind.InterfaceDeclaration: if (result = getSymbol(getSymbolOfNode(location).members, name, meaning & SymbolFlags.Type)) { - if (lastLocation && lastLocation.flags & NodeFlags.Static) { + if (lastLocation && getModifierFlags(lastLocation) & ModifierFlags.Static) { // TypeScript 1.0 spec (April 2014): 3.4.1 // The scope of a type parameter extends over the entire declaration with which the type // parameter list is associated, with the exception of static member declarations in classes. @@ -941,7 +946,7 @@ namespace ts { // No static member is present. // Check if we're in an instance method and look for a relevant instance member. - if (location === container && !(location.flags & NodeFlags.Static)) { + if (location === container && !(getModifierFlags(location) & ModifierFlags.Static)) { const instanceType = (getDeclaredTypeOfSymbol(classSymbol)).thisType; if (getPropertyOfType(instanceType, name)) { error(errorLocation, Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg)); @@ -1271,7 +1276,7 @@ namespace ts { } // Resolves a qualified name and any involved aliases - function resolveEntityName(name: EntityNameOrEntityNameExpression, meaning: SymbolFlags, ignoreErrors?: boolean, dontResolveAlias?: boolean): Symbol | undefined { + function resolveEntityName(name: EntityNameOrEntityNameExpression, meaning: SymbolFlags, ignoreErrors?: boolean, dontResolveAlias?: boolean, location?: Node): Symbol | undefined { if (nodeIsMissing(name)) { return undefined; } @@ -1280,7 +1285,7 @@ namespace ts { if (name.kind === SyntaxKind.Identifier) { const message = meaning === SymbolFlags.Namespace ? Diagnostics.Cannot_find_namespace_0 : Diagnostics.Cannot_find_name_0; - symbol = resolveName(name, (name).text, meaning, ignoreErrors ? undefined : message, name); + symbol = resolveName(location || name, (name).text, meaning, ignoreErrors ? undefined : message, name); if (!symbol) { return undefined; } @@ -1289,7 +1294,7 @@ namespace ts { const left = name.kind === SyntaxKind.QualifiedName ? (name).left : (name).expression; const right = name.kind === SyntaxKind.QualifiedName ? (name).right : (name).name; - const namespace = resolveEntityName(left, SymbolFlags.Namespace, ignoreErrors); + const namespace = resolveEntityName(left, SymbolFlags.Namespace, ignoreErrors, /*dontResolveAlias*/ false, location); if (!namespace || nodeIsMissing(right)) { return undefined; } @@ -1322,10 +1327,13 @@ namespace ts { } const moduleReferenceLiteral = moduleReferenceExpression; + return resolveExternalModule(location, moduleReferenceLiteral.text, moduleNotFoundError, moduleReferenceLiteral); + } + function resolveExternalModule(location: Node, moduleReference: string, moduleNotFoundError: DiagnosticMessage, errorNode: Node): Symbol { // Module names are escaped in our symbol table. However, string literal values aren't. // Escape the name in the "require(...)" clause to ensure we find the right symbol. - const moduleName = escapeIdentifier(moduleReferenceLiteral.text); + const moduleName = escapeIdentifier(moduleReference); if (moduleName === undefined) { return; @@ -1340,7 +1348,7 @@ namespace ts { } } - const resolvedModule = getResolvedModule(getSourceFileOfNode(location), moduleReferenceLiteral.text); + const resolvedModule = getResolvedModule(getSourceFileOfNode(location), moduleReference); const sourceFile = resolvedModule && host.getSourceFile(resolvedModule.resolvedFileName); if (sourceFile) { if (sourceFile.symbol) { @@ -1349,7 +1357,7 @@ namespace ts { } if (moduleNotFoundError) { // report errors only if it was requested - error(moduleReferenceLiteral, Diagnostics.File_0_is_not_a_module, sourceFile.fileName); + error(errorNode, Diagnostics.File_0_is_not_a_module, sourceFile.fileName); } return undefined; } @@ -1366,10 +1374,10 @@ namespace ts { const tsExtension = tryExtractTypeScriptExtension(moduleName); if (tsExtension) { const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; - error(moduleReferenceLiteral, diag, tsExtension, removeExtension(moduleName, tsExtension)); + error(errorNode, diag, tsExtension, removeExtension(moduleName, tsExtension)); } else { - error(moduleReferenceLiteral, moduleNotFoundError, moduleName); + error(errorNode, moduleNotFoundError, moduleName); } } return undefined; @@ -1825,7 +1833,7 @@ namespace ts { const anyImportSyntax = getAnyImportSyntax(declaration); if (anyImportSyntax && - !(anyImportSyntax.flags & NodeFlags.Export) && // import clause without export + !(getModifierFlags(anyImportSyntax) & ModifierFlags.Export) && // import clause without export isDeclarationVisible(anyImportSyntax.parent)) { getNodeLinks(declaration).isVisible = true; if (aliasesToMakeVisible) { @@ -1952,11 +1960,11 @@ namespace ts { return result || types; } - function visibilityToString(flags: NodeFlags) { - if (flags === NodeFlags.Private) { + function visibilityToString(flags: ModifierFlags) { + if (flags === ModifierFlags.Private) { return "private"; } - if (flags === NodeFlags.Protected) { + if (flags === ModifierFlags.Protected) { return "protected"; } return "public"; @@ -2301,7 +2309,7 @@ namespace ts { function shouldWriteTypeOfFunctionSymbol() { const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method && // typeof static method - forEach(symbol.declarations, declaration => declaration.flags & NodeFlags.Static)); + forEach(symbol.declarations, declaration => getModifierFlags(declaration) & ModifierFlags.Static)); const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && (symbol.parent || // is exported function symbol forEach(symbol.declarations, declaration => @@ -2668,7 +2676,7 @@ namespace ts { } const parent = getDeclarationContainer(node); // If the node is not exported or it is not ambient module element (except import declaration) - if (!(getCombinedNodeFlags(node) & NodeFlags.Export) && + if (!(getCombinedModifierFlags(node) & ModifierFlags.Export) && !(node.kind !== SyntaxKind.ImportEqualsDeclaration && parent.kind !== SyntaxKind.SourceFile && isInAmbientContext(parent))) { return isGlobalSourceFile(parent); } @@ -2681,7 +2689,7 @@ namespace ts { case SyntaxKind.SetAccessor: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - if (node.flags & (NodeFlags.Private | NodeFlags.Protected)) { + if (getModifierFlags(node) & (ModifierFlags.Private | ModifierFlags.Protected)) { // Private/protected properties/methods are not visible return false; } @@ -3533,7 +3541,7 @@ namespace ts { function getInstantiatedConstructorsForTypeArguments(type: ObjectType, typeArgumentNodes: TypeNode[]): Signature[] { let signatures = getConstructorsForTypeArguments(type, typeArgumentNodes); if (typeArgumentNodes) { - const typeArguments = map(typeArgumentNodes, getTypeFromTypeNode); + const typeArguments = map(typeArgumentNodes, getTypeFromTypeNodeNoAlias); signatures = map(signatures, sig => getSignatureInstantiation(sig, typeArguments)); } return signatures; @@ -4096,7 +4104,7 @@ namespace ts { return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)]; } const baseTypeNode = getBaseTypeNodeOfClass(classType); - const typeArguments = map(baseTypeNode.typeArguments, getTypeFromTypeNode); + const typeArguments = map(baseTypeNode.typeArguments, getTypeFromTypeNodeNoAlias); const typeArgCount = typeArguments ? typeArguments.length : 0; const result: Signature[] = []; for (const baseSig of baseSignatures) { @@ -4387,7 +4395,7 @@ namespace ts { const type = getApparentType(current); if (type !== unknownType) { const prop = getPropertyOfType(type, name); - if (prop && !(getDeclarationFlagsFromSymbol(prop) & (NodeFlags.Private | NodeFlags.Protected))) { + if (prop && !(getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected))) { commonFlags &= prop.flags; if (!props) { props = [prop]; @@ -4893,7 +4901,7 @@ namespace ts { const declaration = getIndexDeclarationOfSymbol(symbol, kind); if (declaration) { return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, - (declaration.flags & NodeFlags.Readonly) !== 0, declaration); + (getModifierFlags(declaration) & ModifierFlags.Readonly) !== 0, declaration); } return undefined; } @@ -5012,7 +5020,7 @@ namespace ts { // In a type reference, the outer type parameters of the referenced class or interface are automatically // supplied as type arguments and the type reference only specifies arguments for the local type parameters // of the class or interface. - return createTypeReference(type, concatenate(type.outerTypeParameters, map(node.typeArguments, getTypeFromTypeNode))); + return createTypeReference(type, concatenate(type.outerTypeParameters, map(node.typeArguments, getTypeFromTypeNodeNoAlias))); } if (node.typeArguments) { error(node, Diagnostics.Type_0_is_not_generic, typeToString(type)); @@ -5033,7 +5041,7 @@ namespace ts { error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, symbolToString(symbol), typeParameters.length); return unknownType; } - const typeArguments = map(node.typeArguments, getTypeFromTypeNode); + const typeArguments = map(node.typeArguments, getTypeFromTypeNodeNoAlias); const id = getTypeListId(typeArguments); return links.instantiations[id] || (links.instantiations[id] = instantiateType(type, createTypeMapper(typeParameters, typeArguments))); } @@ -5288,7 +5296,7 @@ namespace ts { function getTypeFromTupleTypeNode(node: TupleTypeNode): Type { const links = getNodeLinks(node); if (!links.resolvedType) { - links.resolvedType = createTupleType(map(node.elementTypes, getTypeFromTypeNode)); + links.resolvedType = createTupleType(map(node.elementTypes, getTypeFromTypeNodeNoAlias)); } return links.resolvedType; } @@ -5378,7 +5386,7 @@ namespace ts { while (i > 0) { i--; if (isSubtypeOfAny(types[i], types)) { - types.splice(i, 1); + orderedRemoveItemAt(types, i); } } } @@ -5436,7 +5444,7 @@ namespace ts { function getTypeFromUnionTypeNode(node: UnionTypeNode, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type { const links = getNodeLinks(node); if (!links.resolvedType) { - links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNode), /*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments); + links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNodeNoAlias), /*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments); } return links.resolvedType; } @@ -5493,7 +5501,7 @@ namespace ts { function getTypeFromIntersectionTypeNode(node: IntersectionTypeNode, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type { const links = getNodeLinks(node); if (!links.resolvedType) { - links.resolvedType = getIntersectionType(map(node.types, getTypeFromTypeNode), aliasSymbol, aliasTypeArguments); + links.resolvedType = getIntersectionType(map(node.types, getTypeFromTypeNodeNoAlias), aliasSymbol, aliasTypeArguments); } return links.resolvedType; } @@ -5541,7 +5549,7 @@ namespace ts { function getTypeFromJSDocTupleType(node: JSDocTupleType): Type { const links = getNodeLinks(node); if (!links.resolvedType) { - const types = map(node.types, getTypeFromTypeNode); + const types = map(node.types, getTypeFromTypeNodeNoAlias); links.resolvedType = createTupleType(types); } return links.resolvedType; @@ -5551,8 +5559,8 @@ namespace ts { const container = getThisContainer(node, /*includeArrowFunctions*/ false); const parent = container && container.parent; if (parent && (isClassLike(parent) || parent.kind === SyntaxKind.InterfaceDeclaration)) { - if (!(container.flags & NodeFlags.Static) && - (container.kind !== SyntaxKind.Constructor || isNodeDescendentOf(node, (container).body))) { + if (!(getModifierFlags(container) & ModifierFlags.Static) && + (container.kind !== SyntaxKind.Constructor || isNodeDescendantOf(node, (container).body))) { return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType; } } @@ -5568,6 +5576,10 @@ namespace ts { return links.resolvedType; } + function getTypeFromTypeNodeNoAlias(type: TypeNode) { + return getTypeFromTypeNode(type, /*aliasSymbol*/ undefined, /*aliasTypeArguments*/ undefined); + } + function getTypeFromTypeNode(node: TypeNode, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type { switch (node.kind) { case SyntaxKind.AnyKeyword: @@ -6714,24 +6726,24 @@ namespace ts { } } else if (!(targetProp.flags & SymbolFlags.Prototype)) { - const sourcePropFlags = getDeclarationFlagsFromSymbol(sourceProp); - const targetPropFlags = getDeclarationFlagsFromSymbol(targetProp); - if (sourcePropFlags & NodeFlags.Private || targetPropFlags & NodeFlags.Private) { + const sourcePropFlags = getDeclarationModifierFlagsFromSymbol(sourceProp); + const targetPropFlags = getDeclarationModifierFlagsFromSymbol(targetProp); + if (sourcePropFlags & ModifierFlags.Private || targetPropFlags & ModifierFlags.Private) { if (sourceProp.valueDeclaration !== targetProp.valueDeclaration) { if (reportErrors) { - if (sourcePropFlags & NodeFlags.Private && targetPropFlags & NodeFlags.Private) { + if (sourcePropFlags & ModifierFlags.Private && targetPropFlags & ModifierFlags.Private) { reportError(Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp)); } else { reportError(Diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, symbolToString(targetProp), - typeToString(sourcePropFlags & NodeFlags.Private ? source : target), - typeToString(sourcePropFlags & NodeFlags.Private ? target : source)); + typeToString(sourcePropFlags & ModifierFlags.Private ? source : target), + typeToString(sourcePropFlags & ModifierFlags.Private ? target : source)); } } return Ternary.False; } } - else if (targetPropFlags & NodeFlags.Protected) { + else if (targetPropFlags & ModifierFlags.Protected) { const sourceDeclaredInClass = sourceProp.parent && sourceProp.parent.flags & SymbolFlags.Class; const sourceClass = sourceDeclaredInClass ? getDeclaredTypeOfSymbol(getParentOfSymbol(sourceProp)) : undefined; const targetClass = getDeclaredTypeOfSymbol(getParentOfSymbol(targetProp)); @@ -6743,7 +6755,7 @@ namespace ts { return Ternary.False; } } - else if (sourcePropFlags & NodeFlags.Protected) { + else if (sourcePropFlags & ModifierFlags.Protected) { if (reportErrors) { reportError(Diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target)); @@ -6953,21 +6965,21 @@ namespace ts { return true; } - const sourceAccessibility = sourceSignature.declaration.flags & (NodeFlags.Private | NodeFlags.Protected); - const targetAccessibility = targetSignature.declaration.flags & (NodeFlags.Private | NodeFlags.Protected); + const sourceAccessibility = getModifierFlags(sourceSignature.declaration) & ModifierFlags.NonPublicAccessibilityModifier; + const targetAccessibility = getModifierFlags(targetSignature.declaration) & ModifierFlags.NonPublicAccessibilityModifier; // A public, protected and private signature is assignable to a private signature. - if (targetAccessibility === NodeFlags.Private) { + if (targetAccessibility === ModifierFlags.Private) { return true; } // A public and protected signature is assignable to a protected signature. - if (targetAccessibility === NodeFlags.Protected && sourceAccessibility !== NodeFlags.Private) { + if (targetAccessibility === ModifierFlags.Protected && sourceAccessibility !== ModifierFlags.Private) { return true; } // Only a public signature is assignable to public signature. - if (targetAccessibility !== NodeFlags.Protected && !sourceAccessibility) { + if (targetAccessibility !== ModifierFlags.Protected && !sourceAccessibility) { return true; } @@ -6985,7 +6997,7 @@ namespace ts { const symbol = type.symbol; if (symbol && symbol.flags & SymbolFlags.Class) { const declaration = getClassLikeDeclarationOfSymbol(symbol); - if (declaration && declaration.flags & NodeFlags.Abstract) { + if (declaration && getModifierFlags(declaration) & ModifierFlags.Abstract) { return true; } } @@ -7025,8 +7037,8 @@ namespace ts { if (sourceProp === targetProp) { return Ternary.True; } - const sourcePropAccessibility = getDeclarationFlagsFromSymbol(sourceProp) & (NodeFlags.Private | NodeFlags.Protected); - const targetPropAccessibility = getDeclarationFlagsFromSymbol(targetProp) & (NodeFlags.Private | NodeFlags.Protected); + const sourcePropAccessibility = getDeclarationModifierFlagsFromSymbol(sourceProp) & ModifierFlags.NonPublicAccessibilityModifier; + const targetPropAccessibility = getDeclarationModifierFlagsFromSymbol(targetProp) & ModifierFlags.NonPublicAccessibilityModifier; if (sourcePropAccessibility !== targetPropAccessibility) { return Ternary.False; } @@ -8758,7 +8770,7 @@ namespace ts { // The location isn't a reference to the given symbol, meaning we're being asked // a hypothetical question of what type the symbol would have if there was a reference // to it at the given location. Since we have no control flow information for the - // hypotherical reference (control flow information is created and attached by the + // hypothetical reference (control flow information is created and attached by the // binder), we simply return the declared type of the symbol. return getTypeOfSymbol(symbol); } @@ -8832,10 +8844,13 @@ namespace ts { // can explicitly bound arguments objects if (symbol === argumentsSymbol) { const container = getContainingFunction(node); - if (container.kind === SyntaxKind.ArrowFunction) { - if (languageVersion < ScriptTarget.ES6) { + if (languageVersion < ScriptTarget.ES6) { + if (container.kind === SyntaxKind.ArrowFunction) { error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression); } + else if (hasModifier(container, ModifierFlags.Async)) { + error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method); + } } if (node.flags & NodeFlags.AwaitContext) { @@ -8849,22 +8864,41 @@ namespace ts { const localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol); - // Due to the emit for class decorators, any reference to the class from inside of the class body - // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind - // behavior of class names in ES6. - if (languageVersion === ScriptTarget.ES6 - && localOrExportSymbol.flags & SymbolFlags.Class - && localOrExportSymbol.valueDeclaration.kind === SyntaxKind.ClassDeclaration - && nodeIsDecorated(localOrExportSymbol.valueDeclaration)) { - let container = getContainingClass(node); - while (container !== undefined) { - if (container === localOrExportSymbol.valueDeclaration && container.name !== node) { - getNodeLinks(container).flags |= NodeCheckFlags.ClassWithBodyScopedClassBinding; - getNodeLinks(node).flags |= NodeCheckFlags.BodyScopedClassBinding; - break; - } + if (localOrExportSymbol.flags & SymbolFlags.Class) { + const declaration = localOrExportSymbol.valueDeclaration; + // Due to the emit for class decorators, any reference to the class from inside of the class body + // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind + // behavior of class names in ES6. + if (languageVersion === ScriptTarget.ES6 + && declaration.kind === SyntaxKind.ClassDeclaration + && nodeIsDecorated(declaration)) { + let container = getContainingClass(node); + while (container !== undefined) { + if (container === declaration && container.name !== node) { + getNodeLinks(declaration).flags |= NodeCheckFlags.ClassWithConstructorReference; + getNodeLinks(node).flags |= NodeCheckFlags.ConstructorReferenceInClass; + break; + } - container = getContainingClass(container); + container = getContainingClass(container); + } + } + else if (declaration.kind === SyntaxKind.ClassExpression) { + // When we emit a class expression with static members that contain a reference + // to the constructor in the initializer, we will need to substitute that + // binding with an alias as the class name is not in scope. + let container = getThisContainer(node, /*includeArrowFunctions*/ false); + while (container !== undefined) { + if (container.parent === declaration) { + if (container.kind === SyntaxKind.PropertyDeclaration && hasModifier(container, ModifierFlags.Static)) { + getNodeLinks(declaration).flags |= NodeCheckFlags.ClassWithConstructorReference; + getNodeLinks(node).flags |= NodeCheckFlags.ConstructorReferenceInClass; + } + break; + } + + container = getThisContainer(container, /*includeArrowFunctions*/ false); + } } } @@ -9109,7 +9143,7 @@ namespace ts { break; case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: - if (container.flags & NodeFlags.Static) { + if (getModifierFlags(container) & ModifierFlags.Static) { error(node, Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer); // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks } @@ -9147,9 +9181,10 @@ namespace ts { return thisType; } } + if (isClassLike(container.parent)) { const symbol = getSymbolOfNode(container.parent); - const type = container.flags & NodeFlags.Static ? getTypeOfSymbol(symbol) : (getDeclaredTypeOfSymbol(symbol)).thisType; + const type = hasModifier(container, ModifierFlags.Static) ? getTypeOfSymbol(symbol) : (getDeclaredTypeOfSymbol(symbol)).thisType; return getFlowTypeOfReference(node, type, /*assumeInitialized*/ true, /*flowContainer*/ undefined); } @@ -9228,7 +9263,7 @@ namespace ts { return unknownType; } - if ((container.flags & NodeFlags.Static) || isCallExpression) { + if ((getModifierFlags(container) & ModifierFlags.Static) || isCallExpression) { nodeCheckFlag = NodeCheckFlags.SuperStatic; } else { @@ -9293,8 +9328,8 @@ namespace ts { // This helper creates an object with a "value" property that wraps the `super` property or indexed access for both get and set. // This is required for destructuring assignments, as a call expression cannot be used as the target of a destructuring assignment // while a property access can. - if (container.kind === SyntaxKind.MethodDeclaration && container.flags & NodeFlags.Async) { - if (isSuperPropertyOrElementAccess(node.parent) && isAssignmentTarget(node.parent)) { + if (container.kind === SyntaxKind.MethodDeclaration && getModifierFlags(container) & ModifierFlags.Async) { + if (isSuperProperty(node.parent) && isAssignmentTarget(node.parent)) { getNodeLinks(container).flags |= NodeCheckFlags.AsyncMethodWithSuperBinding; } else { @@ -9359,7 +9394,7 @@ namespace ts { // topmost container must be something that is directly nested in the class declaration\object literal expression if (isClassLike(container.parent) || container.parent.kind === SyntaxKind.ObjectLiteralExpression) { - if (container.flags & NodeFlags.Static) { + if (getModifierFlags(container) & ModifierFlags.Static) { return container.kind === SyntaxKind.MethodDeclaration || container.kind === SyntaxKind.MethodSignature || container.kind === SyntaxKind.GetAccessor || @@ -10644,8 +10679,12 @@ namespace ts { return s.valueDeclaration ? s.valueDeclaration.kind : SyntaxKind.PropertyDeclaration; } - function getDeclarationFlagsFromSymbol(s: Symbol): NodeFlags { - return s.valueDeclaration ? getCombinedNodeFlags(s.valueDeclaration) : s.flags & SymbolFlags.Prototype ? NodeFlags.Public | NodeFlags.Static : 0; + function getDeclarationModifierFlagsFromSymbol(s: Symbol): ModifierFlags { + return s.valueDeclaration ? getCombinedModifierFlags(s.valueDeclaration) : s.flags & SymbolFlags.Prototype ? ModifierFlags.Public | ModifierFlags.Static : 0; + } + + function getDeclarationNodeFlagsFromSymbol(s: Symbol): NodeFlags { + return s.valueDeclaration ? getCombinedNodeFlags(s.valueDeclaration) : 0; } /** @@ -10657,7 +10696,7 @@ namespace ts { * @param prop The symbol for the right hand side of the property access. */ function checkClassPropertyAccess(node: PropertyAccessExpression | QualifiedName | VariableLikeDeclaration, left: Expression | QualifiedName, type: Type, prop: Symbol): boolean { - const flags = getDeclarationFlagsFromSymbol(prop); + const flags = getDeclarationModifierFlagsFromSymbol(prop); const declaringClass = getDeclaredTypeOfSymbol(getParentOfSymbol(prop)); const errorNode = node.kind === SyntaxKind.PropertyAccessExpression || node.kind === SyntaxKind.VariableDeclaration ? (node).name : @@ -10678,7 +10717,7 @@ namespace ts { return false; } - if (flags & NodeFlags.Abstract) { + if (flags & ModifierFlags.Abstract) { // A method cannot be accessed in a super property access if the method is abstract. // This error could mask a private property access error. But, a member // cannot simultaneously be private and abstract, so this will trigger an @@ -10690,14 +10729,14 @@ namespace ts { } // Public properties are otherwise accessible. - if (!(flags & (NodeFlags.Private | NodeFlags.Protected))) { + if (!(flags & ModifierFlags.NonPublicAccessibilityModifier)) { return true; } // Property is known to be private or protected at this point // Private property is accessible if the property is within the declaring class - if (flags & NodeFlags.Private) { + if (flags & ModifierFlags.Private) { const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)); if (!isNodeWithinClass(node, declaringClassDeclaration)) { error(errorNode, Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(declaringClass)); @@ -10725,7 +10764,7 @@ namespace ts { return false; } // No further restrictions for static properties - if (flags & NodeFlags.Static) { + if (flags & ModifierFlags.Static) { return true; } // An instance property must be accessed through an instance of the enclosing class @@ -10786,7 +10825,7 @@ namespace ts { if (noUnusedIdentifiers && (prop.flags & SymbolFlags.ClassMember) && - prop.valueDeclaration && (prop.valueDeclaration.flags & NodeFlags.Private)) { + prop.valueDeclaration && (getModifierFlags(prop.valueDeclaration) & ModifierFlags.Private)) { if (prop.flags & SymbolFlags.Instantiated) { getSymbolLinks(prop).target.isReferenced = true; @@ -11820,7 +11859,7 @@ namespace ts { else if (candidateForTypeArgumentError) { if (!isTaggedTemplate && !isDecorator && typeArguments) { const typeArguments = (node).typeArguments; - checkTypeArguments(candidateForTypeArgumentError, typeArguments, map(typeArguments, getTypeFromTypeNode), /*reportErrors*/ true, headMessage); + checkTypeArguments(candidateForTypeArgumentError, typeArguments, map(typeArguments, getTypeFromTypeNodeNoAlias), /*reportErrors*/ true, headMessage); } else { Debug.assert(resultOfFailedInference.failedTypeParameterIndex >= 0); @@ -11851,7 +11890,7 @@ namespace ts { for (let candidate of candidates) { if (hasCorrectArity(node, args, candidate)) { if (candidate.typeParameters && typeArguments) { - candidate = getSignatureInstantiation(candidate, map(typeArguments, getTypeFromTypeNode)); + candidate = getSignatureInstantiation(candidate, map(typeArguments, getTypeFromTypeNodeNoAlias)); } return candidate; } @@ -11887,7 +11926,7 @@ namespace ts { if (candidate.typeParameters) { let typeArgumentTypes: Type[]; if (typeArguments) { - typeArgumentTypes = map(typeArguments, getTypeFromTypeNode); + typeArgumentTypes = map(typeArguments, getTypeFromTypeNodeNoAlias); typeArgumentsAreValid = checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false); } else { @@ -12043,7 +12082,7 @@ namespace ts { // In the case of a merged class-module or class-interface declaration, // only the class declaration node will have the Abstract flag set. const valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol); - if (valueDecl && valueDecl.flags & NodeFlags.Abstract) { + if (valueDecl && getModifierFlags(valueDecl) & ModifierFlags.Abstract) { error(node, Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, declarationNameToString(valueDecl.name)); return resolveErrorCall(node); } @@ -12096,10 +12135,10 @@ namespace ts { } const declaration = signature.declaration; - const flags = declaration.flags; + const modifiers = getModifierFlags(declaration); // Public constructor is accessible. - if (!(flags & (NodeFlags.Private | NodeFlags.Protected))) { + if (!(modifiers & ModifierFlags.NonPublicAccessibilityModifier)) { return true; } @@ -12114,16 +12153,16 @@ namespace ts { const baseTypes = getBaseTypes(containingType); if (baseTypes.length) { const baseType = baseTypes[0]; - if (flags & NodeFlags.Protected && + if (modifiers & ModifierFlags.Protected && baseType.symbol === declaration.parent.symbol) { return true; } } } - if (flags & NodeFlags.Private) { + if (modifiers & ModifierFlags.Private) { error(node, Diagnostics.Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration, typeToString(declaringClass)); } - if (flags & NodeFlags.Protected) { + if (modifiers & ModifierFlags.Protected) { error(node, Diagnostics.Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration, typeToString(declaringClass)); } return false; @@ -12229,10 +12268,10 @@ namespace ts { // or that a different candidatesOutArray was passed in. Therefore, we need to redo the work // to correctly fill the candidatesOutArray. const cached = links.resolvedSignature; - if (cached && cached !== anySignature && !candidatesOutArray) { + if (cached && cached !== resolvingSignature && !candidatesOutArray) { return cached; } - links.resolvedSignature = anySignature; + links.resolvedSignature = resolvingSignature; const result = resolveSignature(node, candidatesOutArray); // If signature resolution originated in control flow type analysis (for example to compute the // assigned type in a flow assignment) we don't cache the result as it may be based on temporary @@ -12244,7 +12283,7 @@ namespace ts { function getResolvedOrAnySignature(node: CallLikeExpression) { // If we're already in the process of resolving the given signature, don't resolve again as // that could cause infinite recursion. Instead, return anySignature. - return getNodeLinks(node).resolvedSignature === anySignature ? anySignature : getResolvedSignature(node); + return getNodeLinks(node).resolvedSignature === resolvingSignature ? resolvingSignature : getResolvedSignature(node); } function getInferredClassType(symbol: Symbol) { @@ -12792,8 +12831,8 @@ namespace ts { // Enum members // Unions and intersections of the above (unions and intersections eagerly set isReadonly on creation) return symbol.isReadonly || - symbol.flags & SymbolFlags.Property && (getDeclarationFlagsFromSymbol(symbol) & NodeFlags.Readonly) !== 0 || - symbol.flags & SymbolFlags.Variable && (getDeclarationFlagsFromSymbol(symbol) & NodeFlags.Const) !== 0 || + symbol.flags & SymbolFlags.Property && (getDeclarationModifierFlagsFromSymbol(symbol) & ModifierFlags.Readonly) !== 0 || + symbol.flags & SymbolFlags.Variable && (getDeclarationNodeFlagsFromSymbol(symbol) & NodeFlags.Const) !== 0 || symbol.flags & SymbolFlags.Accessor && !(symbol.flags & SymbolFlags.SetAccessor) || (symbol.flags & SymbolFlags.EnumMember) !== 0; } @@ -13498,7 +13537,7 @@ namespace ts { function checkLiteralExpression(node: Expression): Type { if (node.kind === SyntaxKind.NumericLiteral) { - checkGrammarNumericLiteral(node); + checkGrammarNumericLiteral(node); } switch (node.kind) { case SyntaxKind.StringLiteral: @@ -13729,7 +13768,7 @@ namespace ts { checkVariableLikeDeclaration(node); let func = getContainingFunction(node); - if (node.flags & NodeFlags.ParameterPropertyModifier) { + if (getModifierFlags(node) & ModifierFlags.ParameterPropertyModifier) { func = getContainingFunction(node); if (!(func.kind === SyntaxKind.Constructor && nodeIsPresent(func.body))) { error(node, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); @@ -14069,7 +14108,7 @@ namespace ts { // Abstract methods cannot have an implementation. // Extra checks are to avoid reporting multiple errors relating to the "abstractness" of the node. - if (node.flags & NodeFlags.Abstract && node.body) { + if (getModifierFlags(node) & ModifierFlags.Abstract && node.body) { error(node, Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, declarationNameToString(node.name)); } } @@ -14128,7 +14167,7 @@ namespace ts { function isInstancePropertyWithInitializer(n: Node): boolean { return n.kind === SyntaxKind.PropertyDeclaration && - !(n.flags & NodeFlags.Static) && + !(getModifierFlags(n) & ModifierFlags.Static) && !!(n).initializer; } @@ -14151,7 +14190,7 @@ namespace ts { // or the containing class declares instance member variables with initializers. const superCallShouldBeFirst = forEach((node.parent).members, isInstancePropertyWithInitializer) || - forEach(node.parameters, p => p.flags & NodeFlags.ParameterPropertyModifier); + forEach(node.parameters, p => getModifierFlags(p) & ModifierFlags.ParameterPropertyModifier); // Skip past any prologue directives to find the first statement // to ensure that it was a super call. @@ -14205,10 +14244,10 @@ namespace ts { const otherKind = node.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor; const otherAccessor = getDeclarationOfKind(node.symbol, otherKind); if (otherAccessor) { - if (((node.flags & NodeFlags.AccessibilityModifier) !== (otherAccessor.flags & NodeFlags.AccessibilityModifier))) { + if ((getModifierFlags(node) & ModifierFlags.AccessibilityModifier) !== (getModifierFlags(otherAccessor) & ModifierFlags.AccessibilityModifier)) { error(node.name, Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility); } - if (((node.flags & NodeFlags.Abstract) !== (otherAccessor.flags & NodeFlags.Abstract))) { + if (hasModifier(node, ModifierFlags.Abstract) !== hasModifier(otherAccessor, ModifierFlags.Abstract)) { error(node.name, Diagnostics.Accessors_must_both_be_abstract_or_non_abstract); } @@ -14257,7 +14296,7 @@ namespace ts { const constraint = getConstraintOfTypeParameter(typeParameters[i]); if (constraint) { if (!typeArguments) { - typeArguments = map(typeArgumentNodes, getTypeFromTypeNode); + typeArguments = map(typeArgumentNodes, getTypeFromTypeNodeNoAlias); mapper = createTypeMapper(typeParameters, typeArguments); } const typeArgument = typeArguments[i]; @@ -14323,11 +14362,11 @@ namespace ts { } function isPrivateWithinAmbient(node: Node): boolean { - return (node.flags & NodeFlags.Private) && isInAmbientContext(node); + return (getModifierFlags(node) & ModifierFlags.Private) && isInAmbientContext(node); } - function getEffectiveDeclarationFlags(n: Node, flagsToCheck: NodeFlags): NodeFlags { - let flags = getCombinedNodeFlags(n); + function getEffectiveDeclarationFlags(n: Node, flagsToCheck: ModifierFlags): ModifierFlags { + let flags = getCombinedModifierFlags(n); // children of classes (even ambient classes) should not be marked as ambient or export // because those flags have no useful semantics there. @@ -14335,11 +14374,11 @@ namespace ts { n.parent.kind !== SyntaxKind.ClassDeclaration && n.parent.kind !== SyntaxKind.ClassExpression && isInAmbientContext(n)) { - if (!(flags & NodeFlags.Ambient)) { + if (!(flags & ModifierFlags.Ambient)) { // It is nested in an ambient context, which means it is automatically exported - flags |= NodeFlags.Export; + flags |= ModifierFlags.Export; } - flags |= NodeFlags.Ambient; + flags |= ModifierFlags.Ambient; } return flags & flagsToCheck; @@ -14360,7 +14399,7 @@ namespace ts { return implementationSharesContainerWithFirstOverload ? implementation : overloads[0]; } - function checkFlagAgreementBetweenOverloads(overloads: Declaration[], implementation: FunctionLikeDeclaration, flagsToCheck: NodeFlags, someOverloadFlags: NodeFlags, allOverloadFlags: NodeFlags): void { + function checkFlagAgreementBetweenOverloads(overloads: Declaration[], implementation: FunctionLikeDeclaration, flagsToCheck: ModifierFlags, someOverloadFlags: ModifierFlags, allOverloadFlags: ModifierFlags): void { // Error if some overloads have a flag that is not shared by all overloads. To find the // deviations, we XOR someOverloadFlags with allOverloadFlags const someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags; @@ -14369,16 +14408,16 @@ namespace ts { forEach(overloads, o => { const deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags; - if (deviation & NodeFlags.Export) { + if (deviation & ModifierFlags.Export) { error(o.name, Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported); } - else if (deviation & NodeFlags.Ambient) { + else if (deviation & ModifierFlags.Ambient) { error(o.name, Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient); } - else if (deviation & (NodeFlags.Private | NodeFlags.Protected)) { + else if (deviation & (ModifierFlags.Private | ModifierFlags.Protected)) { error(o.name || o, Diagnostics.Overload_signatures_must_all_be_public_private_or_protected); } - else if (deviation & NodeFlags.Abstract) { + else if (deviation & ModifierFlags.Abstract) { error(o.name, Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract); } }); @@ -14397,8 +14436,8 @@ namespace ts { } } - const flagsToCheck: NodeFlags = NodeFlags.Export | NodeFlags.Ambient | NodeFlags.Private | NodeFlags.Protected | NodeFlags.Abstract; - let someNodeFlags: NodeFlags = 0; + const flagsToCheck: ModifierFlags = ModifierFlags.Export | ModifierFlags.Ambient | ModifierFlags.Private | ModifierFlags.Protected | ModifierFlags.Abstract; + let someNodeFlags: ModifierFlags = ModifierFlags.None; let allNodeFlags = flagsToCheck; let someHaveQuestionToken = false; let allHaveQuestionToken = true; @@ -14433,13 +14472,13 @@ namespace ts { if (node.name && (subsequentNode).name && (node.name).text === ((subsequentNode).name).text) { const reportError = (node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature) && - (node.flags & NodeFlags.Static) !== (subsequentNode.flags & NodeFlags.Static); + (getModifierFlags(node) & ModifierFlags.Static) !== (getModifierFlags(subsequentNode) & ModifierFlags.Static); // we can get here in two cases // 1. mixed static and instance class members // 2. something with the same name was defined before the set of overloads that prevents them from merging // here we'll report error only for the first case since for second we should already report error in binder if (reportError) { - const diagnostic = node.flags & NodeFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static; + const diagnostic = getModifierFlags(node) & ModifierFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static; error(errorNode, diagnostic); } return; @@ -14457,7 +14496,7 @@ namespace ts { else { // Report different errors regarding non-consecutive blocks of declarations depending on whether // the node in question is abstract. - if (node.flags & NodeFlags.Abstract) { + if (getModifierFlags(node) & ModifierFlags.Abstract) { error(errorNode, Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive); } else { @@ -14533,7 +14572,7 @@ namespace ts { // Abstract methods can't have an implementation -- in particular, they don't need one. if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body && - !(lastSeenNonAmbientDeclaration.flags & NodeFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) { + !(getModifierFlags(lastSeenNonAmbientDeclaration) & ModifierFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) { reportImplementationExpectedError(lastSeenNonAmbientDeclaration); } @@ -14583,10 +14622,10 @@ namespace ts { let defaultExportedDeclarationSpaces = SymbolFlags.None; for (const d of symbol.declarations) { const declarationSpaces = getDeclarationSpaces(d); - const effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, NodeFlags.Export | NodeFlags.Default); + const effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, ModifierFlags.Export | ModifierFlags.Default); - if (effectiveDeclarationFlags & NodeFlags.Export) { - if (effectiveDeclarationFlags & NodeFlags.Default) { + if (effectiveDeclarationFlags & ModifierFlags.Export) { + if (effectiveDeclarationFlags & ModifierFlags.Default) { defaultExportedDeclarationSpaces |= declarationSpaces; } else { @@ -14823,7 +14862,7 @@ namespace ts { * @param returnType The return type of a FunctionLikeDeclaration * @param location The node on which to report the error. */ - function checkCorrectPromiseType(returnType: Type, location: Node) { + function checkCorrectPromiseType(returnType: Type, location: Node, diagnostic: DiagnosticMessage, typeName?: string) { if (returnType === unknownType) { // The return type already had some other error, so we ignore and return // the unknown type. @@ -14842,7 +14881,7 @@ namespace ts { // The promise type was not a valid type reference to the global promise type, so we // report an error and return the unknown type. - error(location, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type); + error(location, diagnostic, typeName); return unknownType; } @@ -14862,7 +14901,7 @@ namespace ts { function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration): Type { if (languageVersion >= ScriptTarget.ES6) { const returnType = getTypeFromTypeNode(node.type); - return checkCorrectPromiseType(returnType, node.type); + return checkCorrectPromiseType(returnType, node.type, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type); } const globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType(); @@ -14908,11 +14947,11 @@ namespace ts { const promiseConstructor = getNodeLinks(node.type).resolvedSymbol; if (!promiseConstructor || !symbolIsValue(promiseConstructor)) { + // try to fall back to global promise type. const typeName = promiseConstructor ? symbolToString(promiseConstructor) : typeToString(promiseType); - error(node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type, typeName); - return unknownType; + return checkCorrectPromiseType(promiseType, node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type, typeName); } // If the Promise constructor, resolved locally, is an alias symbol we should mark it as referenced. @@ -14920,7 +14959,7 @@ namespace ts { // Validate the promise constructor type. const promiseConstructorType = getTypeOfSymbol(promiseConstructor); - if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type)) { + if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type)) { return unknownType; } @@ -15241,13 +15280,13 @@ namespace ts { if (node.members) { for (const member of node.members) { if (member.kind === SyntaxKind.MethodDeclaration || member.kind === SyntaxKind.PropertyDeclaration) { - if (!member.symbol.isReferenced && member.flags & NodeFlags.Private) { + if (!member.symbol.isReferenced && getModifierFlags(member) & ModifierFlags.Private) { error(member.name, Diagnostics._0_is_declared_but_never_used, member.symbol.name); } } else if (member.kind === SyntaxKind.Constructor) { for (const parameter of (member).parameters) { - if (!parameter.symbol.isReferenced && parameter.flags & NodeFlags.Private) { + if (!parameter.symbol.isReferenced && getModifierFlags(parameter) & ModifierFlags.Private) { error(parameter.name, Diagnostics.Property_0_is_declared_but_never_used, parameter.symbol.name); } } @@ -15473,7 +15512,7 @@ namespace ts { if (localDeclarationSymbol && localDeclarationSymbol !== symbol && localDeclarationSymbol.flags & SymbolFlags.BlockScopedVariable) { - if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.BlockScoped) { + if (getDeclarationNodeFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.BlockScoped) { const varDeclList = getAncestor(localDeclarationSymbol.valueDeclaration, SyntaxKind.VariableDeclarationList); const container = varDeclList.parent.kind === SyntaxKind.VariableStatement && varDeclList.parent.parent @@ -15551,7 +15590,7 @@ namespace ts { // computed property names/initializers in instance property declaration of class like entities // are executed in constructor and thus deferred if (current.parent.kind === SyntaxKind.PropertyDeclaration && - !(current.parent.flags & NodeFlags.Static) && + !(hasModifier(current.parent, ModifierFlags.Static)) && isClassLike(current.parent.parent)) { return; } @@ -15666,14 +15705,14 @@ namespace ts { return false; } - const interestingFlags = NodeFlags.Private | - NodeFlags.Protected | - NodeFlags.Async | - NodeFlags.Abstract | - NodeFlags.Readonly | - NodeFlags.Static; + const interestingFlags = ModifierFlags.Private | + ModifierFlags.Protected | + ModifierFlags.Async | + ModifierFlags.Abstract | + ModifierFlags.Readonly | + ModifierFlags.Static; - return (left.flags & interestingFlags) === (right.flags & interestingFlags); + return (getModifierFlags(left) & interestingFlags) === (getModifierFlags(right) & interestingFlags); } function checkVariableDeclaration(node: VariableDeclaration) { @@ -16329,7 +16368,7 @@ namespace ts { // Only process instance properties with computed names here. // Static properties cannot be in conflict with indexers, // and properties with literal names were already checked. - if (!(member.flags & NodeFlags.Static) && hasDynamicName(member)) { + if (!(getModifierFlags(member) & ModifierFlags.Static) && hasDynamicName(member)) { const propType = getTypeOfSymbol(member.symbol); checkIndexConstraintForProperty(member.symbol, propType, type, declaredStringIndexer, stringIndexType, IndexKind.String); checkIndexConstraintForProperty(member.symbol, propType, type, declaredNumberIndexer, numberIndexType, IndexKind.Number); @@ -16459,7 +16498,7 @@ namespace ts { } function checkClassDeclaration(node: ClassDeclaration) { - if (!node.name && !(node.flags & NodeFlags.Default)) { + if (!node.name && !(getModifierFlags(node) & ModifierFlags.Default)) { grammarErrorOnFirstToken(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } checkClassLikeDeclaration(node); @@ -16558,7 +16597,7 @@ namespace ts { const signatures = getSignaturesOfType(type, SignatureKind.Construct); if (signatures.length) { const declaration = signatures[0].declaration; - if (declaration && declaration.flags & NodeFlags.Private) { + if (declaration && getModifierFlags(declaration) & ModifierFlags.Private) { const typeClassDeclaration = getClassLikeDeclarationOfSymbol(type.symbol); if (!isNodeWithinClass(node, typeClassDeclaration)) { error(node, Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, (node.expression).text); @@ -16603,7 +16642,7 @@ namespace ts { } const derived = getTargetSymbol(getPropertyOfObjectType(type, base.name)); - const baseDeclarationFlags = getDeclarationFlagsFromSymbol(base); + const baseDeclarationFlags = getDeclarationModifierFlagsFromSymbol(base); Debug.assert(!!derived, "derived should point to something, even if it is the base class' declaration."); @@ -16619,7 +16658,7 @@ namespace ts { // It is an error to inherit an abstract member without implementing it or being declared abstract. // If there is no declaration for the derived class (as in the case of class expressions), // then the class cannot be declared abstract. - if (baseDeclarationFlags & NodeFlags.Abstract && (!derivedClassDecl || !(derivedClassDecl.flags & NodeFlags.Abstract))) { + if (baseDeclarationFlags & ModifierFlags.Abstract && (!derivedClassDecl || !(getModifierFlags(derivedClassDecl) & ModifierFlags.Abstract))) { if (derivedClassDecl.kind === SyntaxKind.ClassExpression) { error(derivedClassDecl, Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, symbolToString(baseProperty), typeToString(baseType)); @@ -16632,13 +16671,13 @@ namespace ts { } else { // derived overrides base. - const derivedDeclarationFlags = getDeclarationFlagsFromSymbol(derived); - if ((baseDeclarationFlags & NodeFlags.Private) || (derivedDeclarationFlags & NodeFlags.Private)) { + const derivedDeclarationFlags = getDeclarationModifierFlagsFromSymbol(derived); + if ((baseDeclarationFlags & ModifierFlags.Private) || (derivedDeclarationFlags & ModifierFlags.Private)) { // either base or derived property is private - not override, skip it continue; } - if ((baseDeclarationFlags & NodeFlags.Static) !== (derivedDeclarationFlags & NodeFlags.Static)) { + if ((baseDeclarationFlags & ModifierFlags.Static) !== (derivedDeclarationFlags & ModifierFlags.Static)) { // value of 'static' is not the same for properties - not override, skip it continue; } @@ -16910,7 +16949,7 @@ namespace ts { } return undefined; case SyntaxKind.NumericLiteral: - return +(e).text; + return +(e).text; case SyntaxKind.ParenthesizedExpression: return evalConstant((e).expression); case SyntaxKind.Identifier: @@ -17311,7 +17350,7 @@ namespace ts { // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && getModifierFlags(node) !== 0) { grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers); } if (checkExternalImportOrExportDeclaration(node)) { @@ -17341,7 +17380,7 @@ namespace ts { checkGrammarDecorators(node) || checkGrammarModifiers(node); if (isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { checkImportBinding(node); - if (node.flags & NodeFlags.Export) { + if (getModifierFlags(node) & ModifierFlags.Export) { markExportAsReferenced(node); } if (isInternalModuleImportEqualsDeclaration(node)) { @@ -17374,7 +17413,7 @@ namespace ts { return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && getModifierFlags(node) !== 0) { grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers); } @@ -17433,7 +17472,7 @@ namespace ts { return; } // Grammar checking - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && getModifierFlags(node) !== 0) { grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers); } if (node.expression.kind === SyntaxKind.Identifier) { @@ -17778,7 +17817,7 @@ namespace ts { function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] { const symbols = createMap(); - let memberFlags: NodeFlags = 0; + let memberFlags: ModifierFlags = ModifierFlags.None; if (isInsideWithStatementBody(location)) { // We cannot answer semantic questions within a with block, do not proceed any further @@ -17819,7 +17858,7 @@ namespace ts { // add the type parameters into the symbol table // (type parameters of classDeclaration/classExpression and interface are in member property of the symbol. // Note: that the memberFlags come from previous iteration. - if (!(memberFlags & NodeFlags.Static)) { + if (!(memberFlags & ModifierFlags.Static)) { copySymbols(getSymbolOfNode(location).members, meaning & SymbolFlags.Type); } break; @@ -17835,7 +17874,7 @@ namespace ts { copySymbol(argumentsSymbol, meaning); } - memberFlags = location.flags; + memberFlags = getModifierFlags(location); location = location.parent; } @@ -17997,7 +18036,7 @@ namespace ts { meaning |= SymbolFlags.Alias; return resolveEntityName(entityName, meaning); } - else if (isExpression(entityName)) { + else if (isPartOfExpression(entityName)) { if (nodeIsMissing(entityName)) { // Missing entity name. return undefined; @@ -18091,7 +18130,7 @@ namespace ts { // fallthrough case SyntaxKind.SuperKeyword: - const type = isExpression(node) ? checkExpression(node) : getTypeFromTypeNode(node); + const type = isPartOfExpression(node) ? checkExpression(node) : getTypeFromTypeNode(node); return type.symbol; case SyntaxKind.ThisType: @@ -18122,7 +18161,7 @@ namespace ts { if (objectType === unknownType) return undefined; const apparentType = getApparentType(objectType); if (apparentType === unknownType) return undefined; - return getPropertyOfType(apparentType, (node).text); + return getPropertyOfType(apparentType, (node).text); } break; } @@ -18152,11 +18191,11 @@ namespace ts { return unknownType; } - if (isTypeNode(node)) { + if (isPartOfTypeNode(node)) { return getTypeFromTypeNode(node); } - if (isExpression(node)) { + if (isPartOfExpression(node)) { return getTypeOfExpression(node); } @@ -18262,7 +18301,7 @@ namespace ts { */ function getParentTypeOfClassElement(node: ClassElement) { const classSymbol = getSymbolOfNode(node.parent); - return node.flags & NodeFlags.Static + return getModifierFlags(node) & ModifierFlags.Static ? getTypeOfSymbol(classSymbol) : getDeclaredTypeOfSymbol(classSymbol); } @@ -18310,7 +18349,14 @@ namespace ts { // Emitter support function isArgumentsLocalBinding(node: Identifier): boolean { - return getReferencedValueSymbol(node) === argumentsSymbol; + if (!isGeneratedIdentifier(node)) { + node = getParseTreeNode(node, isIdentifier); + if (node) { + return getReferencedValueSymbol(node) === argumentsSymbol; + } + } + + return false; } function moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean { @@ -18342,43 +18388,64 @@ namespace ts { } } + function isNameOfModuleOrEnumDeclaration(node: Identifier) { + const parent = node.parent; + return isModuleOrEnumDeclaration(parent) && node === parent.name; + } + // When resolved as an expression identifier, if the given node references an exported entity, return the declaration // node of the exported entity's container. Otherwise, return undefined. - function getReferencedExportContainer(node: Identifier): SourceFile | ModuleDeclaration | EnumDeclaration { - let symbol = getReferencedValueSymbol(node); - if (symbol) { - if (symbol.flags & SymbolFlags.ExportValue) { - // If we reference an exported entity within the same module declaration, then whether - // we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the - // kinds that we do NOT prefix. - const exportSymbol = getMergedSymbol(symbol.exportSymbol); - if (exportSymbol.flags & SymbolFlags.ExportHasLocal) { - return undefined; - } - symbol = exportSymbol; - } - const parentSymbol = getParentOfSymbol(symbol); - if (parentSymbol) { - if (parentSymbol.flags & SymbolFlags.ValueModule && parentSymbol.valueDeclaration.kind === SyntaxKind.SourceFile) { - // If `node` accesses an export and that export isn't in the same file, then symbol is a namespace export, so return undefined. - if (parentSymbol.valueDeclaration === getSourceFileOfNode(node)) { - return parentSymbol.valueDeclaration; + function getReferencedExportContainer(node: Identifier, prefixLocals?: boolean): SourceFile | ModuleDeclaration | EnumDeclaration { + node = getParseTreeNode(node, isIdentifier); + if (node) { + // When resolving the export container for the name of a module or enum + // declaration, we need to start resolution at the declaration's container. + // Otherwise, we could incorrectly resolve the export container as the + // declaration if it contains an exported member with the same name. + let symbol = getReferencedValueSymbol(node, /*startInDeclarationContainer*/ isNameOfModuleOrEnumDeclaration(node)); + if (symbol) { + if (symbol.flags & SymbolFlags.ExportValue) { + // If we reference an exported entity within the same module declaration, then whether + // we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the + // kinds that we do NOT prefix. + const exportSymbol = getMergedSymbol(symbol.exportSymbol); + if (!prefixLocals && exportSymbol.flags & SymbolFlags.ExportHasLocal) { + return undefined; } + symbol = exportSymbol; } - for (let n = node.parent; n; n = n.parent) { - if ((n.kind === SyntaxKind.ModuleDeclaration || n.kind === SyntaxKind.EnumDeclaration) && getSymbolOfNode(n) === parentSymbol) { - return n; + const parentSymbol = getParentOfSymbol(symbol); + if (parentSymbol) { + if (parentSymbol.flags & SymbolFlags.ValueModule && parentSymbol.valueDeclaration.kind === SyntaxKind.SourceFile) { + // If `node` accesses an export and that export isn't in the same file, then symbol is a namespace export, so return undefined. + if (parentSymbol.valueDeclaration === getSourceFileOfNode(node)) { + return parentSymbol.valueDeclaration; + } + } + for (let n = node.parent; n; n = n.parent) { + if (isModuleOrEnumDeclaration(n) && getSymbolOfNode(n) === parentSymbol) { + return n; + } } } } } + + return undefined; } // When resolved as an expression identifier, if the given node references an import, return the declaration of // that import. Otherwise, return undefined. function getReferencedImportDeclaration(node: Identifier): Declaration { - const symbol = getReferencedValueSymbol(node); - return symbol && symbol.flags & SymbolFlags.Alias ? getDeclarationOfAliasSymbol(symbol) : undefined; + node = getParseTreeNode(node, isIdentifier); + if (node) { + const symbol = getReferencedValueSymbol(node); + if (symbol && symbol.flags & SymbolFlags.Alias) { + return getDeclarationOfAliasSymbol(symbol); + } + } + + return undefined; } function isSymbolOfDeclarationWithCollidingName(symbol: Symbol): boolean { @@ -18428,35 +18495,62 @@ namespace ts { // a name that either hides an existing name or might hide it when compiled downlevel, // return the declaration of that entity. Otherwise, return undefined. function getReferencedDeclarationWithCollidingName(node: Identifier): Declaration { - const symbol = getReferencedValueSymbol(node); - return symbol && isSymbolOfDeclarationWithCollidingName(symbol) ? symbol.valueDeclaration : undefined; + if (!isGeneratedIdentifier(node)) { + node = getParseTreeNode(node, isIdentifier); + if (node) { + const symbol = getReferencedValueSymbol(node); + if (symbol && isSymbolOfDeclarationWithCollidingName(symbol)) { + return symbol.valueDeclaration; + } + } + } + + return undefined; } // Return true if the given node is a declaration of a nested block scoped entity with a name that either hides an // existing name or might hide a name when compiled downlevel function isDeclarationWithCollidingName(node: Declaration): boolean { - return isSymbolOfDeclarationWithCollidingName(getSymbolOfNode(node)); + node = getParseTreeNode(node, isDeclaration); + if (node) { + const symbol = getSymbolOfNode(node); + if (symbol) { + return isSymbolOfDeclarationWithCollidingName(symbol); + } + } + + return false; } function isValueAliasDeclaration(node: Node): boolean { + node = getParseTreeNode(node); + if (node === undefined) { + // A synthesized node comes from an emit transformation and is always a value. + return true; + } + switch (node.kind) { case SyntaxKind.ImportEqualsDeclaration: case SyntaxKind.ImportClause: case SyntaxKind.NamespaceImport: case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: - return isAliasResolvedToValue(getSymbolOfNode(node)); + return isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol); case SyntaxKind.ExportDeclaration: const exportClause = (node).exportClause; return exportClause && forEach(exportClause.elements, isValueAliasDeclaration); case SyntaxKind.ExportAssignment: - return (node).expression && (node).expression.kind === SyntaxKind.Identifier ? isAliasResolvedToValue(getSymbolOfNode(node)) : true; + return (node).expression + && (node).expression.kind === SyntaxKind.Identifier + ? isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol) + : true; } return false; } function isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): boolean { - if (node.parent.kind !== SyntaxKind.SourceFile || !isInternalModuleImportEqualsDeclaration(node)) { + node = getParseTreeNode(node, isImportEqualsDeclaration); + if (node === undefined || node.parent.kind !== SyntaxKind.SourceFile || !isInternalModuleImportEqualsDeclaration(node)) { // parent is not source file or it is not reference to internal module return false; } @@ -18481,9 +18575,15 @@ namespace ts { } function isReferencedAliasDeclaration(node: Node, checkChildren?: boolean): boolean { + node = getParseTreeNode(node); + // Purely synthesized nodes are always emitted. + if (node === undefined) { + return true; + } + if (isAliasSymbolDeclaration(node)) { const symbol = getSymbolOfNode(node); - if (getSymbolLinks(symbol).referenced) { + if (symbol && getSymbolLinks(symbol).referenced) { return true; } } @@ -18516,7 +18616,8 @@ namespace ts { } function getNodeCheckFlags(node: Node): NodeCheckFlags { - return getNodeLinks(node).flags; + node = getParseTreeNode(node); + return node ? getNodeLinks(node).flags : undefined; } function getEnumMemberValue(node: EnumMember): number { @@ -18544,16 +18645,21 @@ namespace ts { return type.flags & TypeFlags.ObjectType && getSignaturesOfType(type, SignatureKind.Call).length > 0; } - function getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind { + function getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind { // Resolve the symbol as a value to ensure the type can be reached at runtime during emit. - const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true); + const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); + const globalPromiseSymbol = tryGetGlobalPromiseConstructorSymbol(); + if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) { + return TypeReferenceSerializationKind.Promise; + } + const constructorType = valueSymbol ? getTypeOfSymbol(valueSymbol) : undefined; if (constructorType && isConstructorType(constructorType)) { return TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; } // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer. - const typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true); + const typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); // We might not be able to resolve type symbol so use unknown type in that case (eg error case) if (!typeSymbol) { return TypeReferenceSerializationKind.ObjectType; @@ -18565,8 +18671,8 @@ namespace ts { else if (type.flags & TypeFlags.Any) { return TypeReferenceSerializationKind.ObjectType; } - else if (isTypeOfKind(type, TypeFlags.Void)) { - return TypeReferenceSerializationKind.VoidType; + else if (isTypeOfKind(type, TypeFlags.Void | TypeFlags.Nullable | TypeFlags.Never)) { + return TypeReferenceSerializationKind.VoidNullableOrNeverType; } else if (isTypeOfKind(type, TypeFlags.BooleanLike)) { return TypeReferenceSerializationKind.BooleanType; @@ -18625,16 +18731,37 @@ namespace ts { return !!globals[name]; } - function getReferencedValueSymbol(reference: Identifier): Symbol { - return getNodeLinks(reference).resolvedSymbol || - resolveName(reference, reference.text, SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, - /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined); + function getReferencedValueSymbol(reference: Identifier, startInDeclarationContainer?: boolean): Symbol { + const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; + if (resolvedSymbol) { + return resolvedSymbol; + } + + let location: Node = reference; + if (startInDeclarationContainer) { + // When resolving the name of a declaration as a value, we need to start resolution + // at a point outside of the declaration. + const parent = reference.parent; + if (isDeclaration(parent) && reference === parent.name) { + location = getDeclarationContainer(parent); + } + } + + return resolveName(location, reference.text, SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined); } function getReferencedValueDeclaration(reference: Identifier): Declaration { - Debug.assert(!nodeIsSynthesized(reference)); - const symbol = getReferencedValueSymbol(reference); - return symbol && getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration; + if (!isGeneratedIdentifier(reference)) { + reference = getParseTreeNode(reference, isIdentifier); + if (reference) { + const symbol = getReferencedValueSymbol(reference); + if (symbol) { + return getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration; + } + } + } + + return undefined; } function createResolver(): EmitResolver { @@ -18770,20 +18897,21 @@ namespace ts { function initializeTypeChecker() { // Bind all source files and propagate errors - forEach(host.getSourceFiles(), file => { + for (const file of host.getSourceFiles()) { bindSourceFile(file, compilerOptions); - }); + } - let augmentations: LiteralExpression[][]; // Initialize global symbol table - forEach(host.getSourceFiles(), file => { + let augmentations: LiteralExpression[][]; + let requestedExternalEmitHelpers: NodeFlags = 0; + let firstFileRequestingExternalHelpers: SourceFile; + for (const file of host.getSourceFiles()) { if (!isExternalOrCommonJsModule(file)) { mergeSymbolTable(globals, file.locals); } if (file.patternAmbientModules && file.patternAmbientModules.length) { patternAmbientModules = concatenate(patternAmbientModules, file.patternAmbientModules); } - if (file.moduleAugmentations.length) { (augmentations || (augmentations = [])).push(file.moduleAugmentations); } @@ -18796,7 +18924,16 @@ namespace ts { } } } - }); + if ((compilerOptions.isolatedModules || isExternalModule(file)) && !file.isDeclarationFile) { + const fileRequestedExternalEmitHelpers = file.flags & NodeFlags.EmitHelperFlags; + if (fileRequestedExternalEmitHelpers) { + requestedExternalEmitHelpers |= fileRequestedExternalEmitHelpers; + if (firstFileRequestingExternalHelpers === undefined) { + firstFileRequestingExternalHelpers = file; + } + } + } + } if (augmentations) { // merge module augmentations. @@ -18836,6 +18973,7 @@ namespace ts { getGlobalPromiseLikeType = memoize(() => getGlobalType("PromiseLike", /*arity*/ 1)); getInstantiatedGlobalPromiseLikeType = memoize(createInstantiatedPromiseLikeType); getGlobalPromiseConstructorSymbol = memoize(() => getGlobalValueSymbol("Promise")); + tryGetGlobalPromiseConstructorSymbol = memoize(() => getGlobalSymbol("Promise", SymbolFlags.Value, /*diagnostic*/ undefined) && getGlobalPromiseConstructorSymbol()); getGlobalPromiseConstructorLikeType = memoize(() => getGlobalType("PromiseConstructorLike")); getGlobalThenableType = memoize(createThenableType); @@ -18859,6 +18997,51 @@ namespace ts { const symbol = getGlobalSymbol("ReadonlyArray", SymbolFlags.Type, /*diagnostic*/ undefined); globalReadonlyArrayType = symbol && getTypeOfGlobalSymbol(symbol, /*arity*/ 1); anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType; + + // If we have specified that we are importing helpers, we should report global + // errors if we cannot resolve the helpers external module, or if it does not have + // the necessary helpers exported. + if (compilerOptions.importHelpers && firstFileRequestingExternalHelpers) { + // Find the first reference to the helpers module. + const helpersModule = resolveExternalModule( + firstFileRequestingExternalHelpers, + externalHelpersModuleNameText, + Diagnostics.Cannot_find_module_0, + /*errorNode*/ undefined); + + // If we found the module, report errors if it does not have the necessary exports. + if (helpersModule) { + const exports = helpersModule.exports; + if (requestedExternalEmitHelpers & NodeFlags.HasClassExtends && languageVersion < ScriptTarget.ES6) { + verifyHelperSymbol(exports, "__extends", SymbolFlags.Value); + } + if (requestedExternalEmitHelpers & NodeFlags.HasJsxSpreadAttributes && compilerOptions.jsx !== JsxEmit.Preserve) { + verifyHelperSymbol(exports, "__assign", SymbolFlags.Value); + } + if (requestedExternalEmitHelpers & NodeFlags.HasDecorators) { + verifyHelperSymbol(exports, "__decorate", SymbolFlags.Value); + if (compilerOptions.emitDecoratorMetadata) { + verifyHelperSymbol(exports, "__metadata", SymbolFlags.Value); + } + } + if (requestedExternalEmitHelpers & NodeFlags.HasParamDecorators) { + verifyHelperSymbol(exports, "__param", SymbolFlags.Value); + } + if (requestedExternalEmitHelpers & NodeFlags.HasAsyncFunctions) { + verifyHelperSymbol(exports, "__awaiter", SymbolFlags.Value); + if (languageVersion < ScriptTarget.ES6) { + verifyHelperSymbol(exports, "__generator", SymbolFlags.Value); + } + } + } + } + } + + function verifyHelperSymbol(symbols: SymbolTable, name: string, meaning: SymbolFlags) { + const symbol = getSymbol(symbols, escapeIdentifier(name), meaning); + if (!symbol) { + error(/*location*/ undefined, Diagnostics.Module_0_has_no_exported_member_1, externalHelpersModuleNameText, name); + } } function createInstantiatedPromiseLikeType(): ObjectType { @@ -18912,7 +19095,7 @@ namespace ts { } let lastStatic: Node, lastPrivate: Node, lastProtected: Node, lastDeclare: Node, lastAsync: Node, lastReadonly: Node; - let flags = 0; + let flags = ModifierFlags.None; for (const modifier of node.modifiers) { if (modifier.kind !== SyntaxKind.ReadonlyKeyword) { if (node.kind === SyntaxKind.PropertySignature || node.kind === SyntaxKind.MethodSignature) { @@ -18940,22 +19123,22 @@ namespace ts { lastPrivate = modifier; } - if (flags & NodeFlags.AccessibilityModifier) { + if (flags & ModifierFlags.AccessibilityModifier) { return grammarErrorOnNode(modifier, Diagnostics.Accessibility_modifier_already_seen); } - else if (flags & NodeFlags.Static) { + else if (flags & ModifierFlags.Static) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "static"); } - else if (flags & NodeFlags.Readonly) { + else if (flags & ModifierFlags.Readonly) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "readonly"); } - else if (flags & NodeFlags.Async) { + else if (flags & ModifierFlags.Async) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "async"); } else if (node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.SourceFile) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, text); } - else if (flags & NodeFlags.Abstract) { + else if (flags & ModifierFlags.Abstract) { if (modifier.kind === SyntaxKind.PrivateKeyword) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, text, "abstract"); } @@ -18967,13 +19150,13 @@ namespace ts { break; case SyntaxKind.StaticKeyword: - if (flags & NodeFlags.Static) { + if (flags & ModifierFlags.Static) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "static"); } - else if (flags & NodeFlags.Readonly) { + else if (flags & ModifierFlags.Readonly) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "static", "readonly"); } - else if (flags & NodeFlags.Async) { + else if (flags & ModifierFlags.Async) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "static", "async"); } else if (node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.SourceFile) { @@ -18982,36 +19165,36 @@ namespace ts { else if (node.kind === SyntaxKind.Parameter) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "static"); } - else if (flags & NodeFlags.Abstract) { + else if (flags & ModifierFlags.Abstract) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract"); } - flags |= NodeFlags.Static; + flags |= ModifierFlags.Static; lastStatic = modifier; break; case SyntaxKind.ReadonlyKeyword: - if (flags & NodeFlags.Readonly) { + if (flags & ModifierFlags.Readonly) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "readonly"); } else if (node.kind !== SyntaxKind.PropertyDeclaration && node.kind !== SyntaxKind.PropertySignature && node.kind !== SyntaxKind.IndexSignature && node.kind !== SyntaxKind.Parameter) { // If node.kind === SyntaxKind.Parameter, checkParameter report an error if it's not a parameter property. return grammarErrorOnNode(modifier, Diagnostics.readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature); } - flags |= NodeFlags.Readonly; + flags |= ModifierFlags.Readonly; lastReadonly = modifier; break; case SyntaxKind.ExportKeyword: - if (flags & NodeFlags.Export) { + if (flags & ModifierFlags.Export) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "export"); } - else if (flags & NodeFlags.Ambient) { + else if (flags & ModifierFlags.Ambient) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "declare"); } - else if (flags & NodeFlags.Abstract) { + else if (flags & ModifierFlags.Abstract) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "abstract"); } - else if (flags & NodeFlags.Async) { + else if (flags & ModifierFlags.Async) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "async"); } else if (node.parent.kind === SyntaxKind.ClassDeclaration) { @@ -19020,14 +19203,14 @@ namespace ts { else if (node.kind === SyntaxKind.Parameter) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "export"); } - flags |= NodeFlags.Export; + flags |= ModifierFlags.Export; break; case SyntaxKind.DeclareKeyword: - if (flags & NodeFlags.Ambient) { + if (flags & ModifierFlags.Ambient) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "declare"); } - else if (flags & NodeFlags.Async) { + else if (flags & ModifierFlags.Async) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async"); } else if (node.parent.kind === SyntaxKind.ClassDeclaration) { @@ -19039,12 +19222,12 @@ namespace ts { else if (isInAmbientContext(node.parent) && node.parent.kind === SyntaxKind.ModuleBlock) { return grammarErrorOnNode(modifier, Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context); } - flags |= NodeFlags.Ambient; + flags |= ModifierFlags.Ambient; lastDeclare = modifier; break; case SyntaxKind.AbstractKeyword: - if (flags & NodeFlags.Abstract) { + if (flags & ModifierFlags.Abstract) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "abstract"); } if (node.kind !== SyntaxKind.ClassDeclaration) { @@ -19054,61 +19237,61 @@ namespace ts { node.kind !== SyntaxKind.SetAccessor) { return grammarErrorOnNode(modifier, Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration); } - if (!(node.parent.kind === SyntaxKind.ClassDeclaration && node.parent.flags & NodeFlags.Abstract)) { + if (!(node.parent.kind === SyntaxKind.ClassDeclaration && getModifierFlags(node.parent) & ModifierFlags.Abstract)) { return grammarErrorOnNode(modifier, Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class); } - if (flags & NodeFlags.Static) { + if (flags & ModifierFlags.Static) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract"); } - if (flags & NodeFlags.Private) { + if (flags & ModifierFlags.Private) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract"); } } - flags |= NodeFlags.Abstract; + flags |= ModifierFlags.Abstract; break; case SyntaxKind.AsyncKeyword: - if (flags & NodeFlags.Async) { + if (flags & ModifierFlags.Async) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "async"); } - else if (flags & NodeFlags.Ambient || isInAmbientContext(node.parent)) { + else if (flags & ModifierFlags.Ambient || isInAmbientContext(node.parent)) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async"); } else if (node.kind === SyntaxKind.Parameter) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "async"); } - flags |= NodeFlags.Async; + flags |= ModifierFlags.Async; lastAsync = modifier; break; } } if (node.kind === SyntaxKind.Constructor) { - if (flags & NodeFlags.Static) { + if (flags & ModifierFlags.Static) { return grammarErrorOnNode(lastStatic, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "static"); } - if (flags & NodeFlags.Abstract) { + if (flags & ModifierFlags.Abstract) { return grammarErrorOnNode(lastStatic, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "abstract"); } - else if (flags & NodeFlags.Async) { + else if (flags & ModifierFlags.Async) { return grammarErrorOnNode(lastAsync, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "async"); } - else if (flags & NodeFlags.Readonly) { + else if (flags & ModifierFlags.Readonly) { return grammarErrorOnNode(lastReadonly, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "readonly"); } return; } - else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && flags & NodeFlags.Ambient) { + else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && flags & ModifierFlags.Ambient) { return grammarErrorOnNode(lastDeclare, Diagnostics.A_0_modifier_cannot_be_used_with_an_import_declaration, "declare"); } - else if (node.kind === SyntaxKind.Parameter && (flags & NodeFlags.ParameterPropertyModifier) && isBindingPattern((node).name)) { + else if (node.kind === SyntaxKind.Parameter && (flags & ModifierFlags.ParameterPropertyModifier) && isBindingPattern((node).name)) { return grammarErrorOnNode(node, Diagnostics.A_parameter_property_may_not_be_declared_using_a_binding_pattern); } - else if (node.kind === SyntaxKind.Parameter && (flags & NodeFlags.ParameterPropertyModifier) && (node).dotDotDotToken) { + else if (node.kind === SyntaxKind.Parameter && (flags & ModifierFlags.ParameterPropertyModifier) && (node).dotDotDotToken) { return grammarErrorOnNode(node, Diagnostics.A_parameter_property_cannot_be_declared_using_a_rest_parameter); } - if (flags & NodeFlags.Async) { + if (flags & ModifierFlags.Async) { return checkGrammarAsyncModifier(node, lastAsync); } } @@ -19169,10 +19352,6 @@ namespace ts { } function checkGrammarAsyncModifier(node: Node, asyncModifier: Node): boolean { - if (languageVersion < ScriptTarget.ES6) { - return grammarErrorOnNode(asyncModifier, Diagnostics.Async_functions_are_only_available_when_targeting_ECMAScript_2015_or_higher); - } - switch (node.kind) { case SyntaxKind.MethodDeclaration: case SyntaxKind.FunctionDeclaration: @@ -19276,7 +19455,7 @@ namespace ts { if (parameter.dotDotDotToken) { return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.An_index_signature_cannot_have_a_rest_parameter); } - if (parameter.flags & NodeFlags.Modifier) { + if (getModifierFlags(parameter) !== 0) { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier); } if (parameter.questionToken) { @@ -19461,11 +19640,13 @@ namespace ts { } // Modifiers are never allowed on properties except for 'async' on a method declaration - forEach(prop.modifiers, mod => { - if (mod.kind !== SyntaxKind.AsyncKeyword || prop.kind !== SyntaxKind.MethodDeclaration) { - grammarErrorOnNode(mod, Diagnostics._0_modifier_cannot_be_used_here, getTextOfNode(mod)); + if (prop.modifiers) { + for (const mod of prop.modifiers) { + if (mod.kind !== SyntaxKind.AsyncKeyword || prop.kind !== SyntaxKind.MethodDeclaration) { + grammarErrorOnNode(mod, Diagnostics._0_modifier_cannot_be_used_here, getTextOfNode(mod)); + } } - }); + } // ECMA-262 11.1.5 Object Initializer // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true @@ -19480,7 +19661,7 @@ namespace ts { // Grammar checking for computedPropertyName and shorthandPropertyAssignment checkGrammarForInvalidQuestionMark(prop, (prop).questionToken, Diagnostics.An_object_member_cannot_be_declared_optional); if (name.kind === SyntaxKind.NumericLiteral) { - checkGrammarNumericLiteral(name); + checkGrammarNumericLiteral(name); } currentKind = Property; } @@ -19603,7 +19784,7 @@ namespace ts { else if (isInAmbientContext(accessor)) { return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context); } - else if (accessor.body === undefined && !(accessor.flags & NodeFlags.Abstract)) { + else if (accessor.body === undefined && !(getModifierFlags(accessor) & ModifierFlags.Abstract)) { return grammarErrorAtPos(getSourceFileOfNode(accessor), accessor.end - 1, ";".length, Diagnostics._0_expected, "{"); } else if (accessor.typeParameters) { @@ -19948,10 +20129,8 @@ namespace ts { node.kind === SyntaxKind.ExportDeclaration || node.kind === SyntaxKind.ExportAssignment || node.kind === SyntaxKind.NamespaceExportDeclaration || - (node.flags & NodeFlags.Ambient) || - (node.flags & (NodeFlags.Export | NodeFlags.Default))) { - - return false; + getModifierFlags(node) & (ModifierFlags.Ambient | ModifierFlags.Export | ModifierFlags.Default)) { + return false; } return grammarErrorOnFirstToken(node, Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file); @@ -20004,7 +20183,7 @@ namespace ts { } } - function checkGrammarNumericLiteral(node: LiteralExpression): boolean { + function checkGrammarNumericLiteral(node: NumericLiteral): boolean { // Grammar checking if (node.isOctalLiteral && languageVersion >= ScriptTarget.ES5) { return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher); @@ -20019,5 +20198,15 @@ namespace ts { return true; } } + + function getAmbientModules(): Symbol[] { + const result: Symbol[] = []; + for (const sym in globals) { + if (ambientModuleSymbolRegex.test(sym)) { + result.push(globals[sym]); + } + } + return result; + } } } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 3596233ed14..9a958f68b73 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -30,6 +30,7 @@ namespace ts { { name: "extendedDiagnostics", type: "boolean", + experimental: true }, { name: "emitBOM", @@ -433,6 +434,11 @@ namespace ts { name: "strictNullChecks", type: "boolean", description: Diagnostics.Enable_strict_null_checks + }, + { + name: "importHelpers", + type: "boolean", + description: Diagnostics.Import_emit_helpers_from_tslib } ]; diff --git a/src/compiler/comments.ts b/src/compiler/comments.ts new file mode 100644 index 00000000000..1bca13a4bdb --- /dev/null +++ b/src/compiler/comments.ts @@ -0,0 +1,352 @@ +/// + +/* @internal */ +namespace ts { + export interface CommentWriter { + reset(): void; + setSourceFile(sourceFile: SourceFile): void; + emitNodeWithComments(node: Node, emitCallback: (node: Node) => void): void; + emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void): void; + emitTrailingCommentsOfPosition(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; + + let containerPos = -1; + let containerEnd = -1; + let declarationListContainerEnd = -1; + let currentSourceFile: SourceFile; + let currentText: string; + let currentLineMap: number[]; + let detachedCommentsInfo: { nodePos: number, detachedCommentEndPos: number}[]; + let hasWrittenComment = false; + let disabled: boolean = compilerOptions.removeComments; + + return { + reset, + setSourceFile, + emitNodeWithComments, + emitBodyWithDetachedComments, + emitTrailingCommentsOfPosition, + }; + + function emitNodeWithComments(node: Node, emitCallback: (node: Node) => void) { + if (disabled) { + emitCallback(node); + return; + } + + if (node) { + const { pos, end } = node.commentRange || node; + const emitFlags = node.emitFlags; + if ((pos < 0 && end < 0) || (pos === end)) { + // Both pos and end are synthesized, so just emit the node without comments. + if (emitFlags & NodeEmitFlags.NoNestedComments) { + disableCommentsAndEmit(node, emitCallback); + } + else { + emitCallback(node); + } + } + else { + if (extendedDiagnostics) { + performance.mark("preEmitNodeWithComment"); + } + + const isEmittedNode = node.kind !== SyntaxKind.NotEmittedStatement; + const skipLeadingComments = pos < 0 || (emitFlags & NodeEmitFlags.NoLeadingComments) !== 0; + const skipTrailingComments = end < 0 || (emitFlags & NodeEmitFlags.NoTrailingComments) !== 0; + + // Emit leading comments if the position is not synthesized and the node + // has not opted out from emitting leading comments. + if (!skipLeadingComments) { + emitLeadingComments(pos, isEmittedNode); + } + + // Save current container state on the stack. + const savedContainerPos = containerPos; + const savedContainerEnd = containerEnd; + const savedDeclarationListContainerEnd = declarationListContainerEnd; + + if (!skipLeadingComments) { + containerPos = pos; + } + + if (!skipTrailingComments) { + containerEnd = end; + + // To avoid invalid comment emit in a down-level binding pattern, we + // keep track of the last declaration list container's end + if (node.kind === SyntaxKind.VariableDeclarationList) { + declarationListContainerEnd = end; + } + } + + if (extendedDiagnostics) { + performance.measure("commentTime", "preEmitNodeWithComment"); + } + + if (emitFlags & NodeEmitFlags.NoNestedComments) { + disableCommentsAndEmit(node, emitCallback); + } + else { + emitCallback(node); + } + + if (extendedDiagnostics) { + performance.mark("beginEmitNodeWithComment"); + } + + // Restore previous container state. + containerPos = savedContainerPos; + containerEnd = savedContainerEnd; + declarationListContainerEnd = savedDeclarationListContainerEnd; + + // Emit trailing comments if the position is not synthesized and the node + // has not opted out from emitting leading comments and is an emitted node. + if (!skipTrailingComments && isEmittedNode) { + emitTrailingComments(end); + } + + if (extendedDiagnostics) { + performance.measure("commentTime", "beginEmitNodeWithComment"); + } + } + } + } + + function emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void) { + if (extendedDiagnostics) { + performance.mark("preEmitBodyWithDetachedComments"); + } + + const { pos, end } = detachedRange; + const emitFlags = node.emitFlags; + const skipLeadingComments = pos < 0 || (emitFlags & NodeEmitFlags.NoLeadingComments) !== 0; + const skipTrailingComments = disabled || end < 0 || (emitFlags & NodeEmitFlags.NoTrailingComments) !== 0; + + if (!skipLeadingComments) { + emitDetachedCommentsAndUpdateCommentsInfo(detachedRange); + } + + if (extendedDiagnostics) { + performance.measure("commentTime", "preEmitBodyWithDetachedComments"); + } + + if (emitFlags & NodeEmitFlags.NoNestedComments) { + disableCommentsAndEmit(node, emitCallback); + } + else { + emitCallback(node); + } + + if (extendedDiagnostics) { + performance.mark("beginEmitBodyWithDetachedCommetns"); + } + + if (!skipTrailingComments) { + emitLeadingComments(detachedRange.end, /*isEmittedNode*/ true); + } + + if (extendedDiagnostics) { + performance.measure("commentTime", "beginEmitBodyWithDetachedCommetns"); + } + } + + function emitLeadingComments(pos: number, isEmittedNode: boolean) { + hasWrittenComment = false; + + if (isEmittedNode) { + forEachLeadingCommentToEmit(pos, emitLeadingComment); + } + else if (pos === 0) { + // If the node will not be emitted in JS, remove all the comments(normal, pinned and ///) associated with the node, + // unless it is a triple slash comment at the top of the file. + // For Example: + // /// + // declare var x; + // /// + // interface F {} + // The first /// will NOT be removed while the second one will be removed even though both node will not be emitted + forEachLeadingCommentToEmit(pos, emitTripleSlashLeadingComment); + } + } + + function emitTripleSlashLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { + if (isTripleSlashComment(commentPos, commentEnd)) { + emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos); + } + } + + function emitLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { + if (!hasWrittenComment) { + emitNewLineBeforeLeadingCommentOfPosition(currentLineMap, writer, rangePos, commentPos); + hasWrittenComment = true; + } + + // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space + emitPos(commentPos); + writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine); + emitPos(commentEnd); + + if (hasTrailingNewLine) { + writer.writeLine(); + } + else { + writer.write(" "); + } + } + + function emitTrailingComments(pos: number) { + forEachTrailingCommentToEmit(pos, emitTrailingComment); + } + + function emitTrailingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean) { + // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/ + if (!writer.isAtStartOfLine()) { + writer.write(" "); + } + + emitPos(commentPos); + writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine); + emitPos(commentEnd); + + if (hasTrailingNewLine) { + writer.writeLine(); + } + } + + function emitTrailingCommentsOfPosition(pos: number) { + if (disabled) { + return; + } + + if (extendedDiagnostics) { + performance.mark("beforeEmitTrailingCommentsOfPosition"); + } + + forEachTrailingCommentToEmit(pos, emitTrailingCommentOfPosition); + + if (extendedDiagnostics) { + performance.measure("commentTime", "beforeEmitTrailingCommentsOfPosition"); + } + } + + 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); + writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine); + emitPos(commentEnd); + + if (hasTrailingNewLine) { + writer.writeLine(); + } + else { + writer.write(" "); + } + } + + function forEachLeadingCommentToEmit(pos: number, cb: (commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) => void) { + // Emit the leading comments only if the container's pos doesn't match because the container should take care of emitting these comments + if (containerPos === -1 || pos !== containerPos) { + if (hasDetachedComments(pos)) { + forEachLeadingCommentWithoutDetachedComments(cb); + } + else { + forEachLeadingCommentRange(currentText, pos, cb, /*state*/ pos); + } + } + } + + function forEachTrailingCommentToEmit(end: number, cb: (commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean) => void) { + // Emit the trailing comments only if the container's end doesn't match because the container should take care of emitting these comments + if (containerEnd === -1 || (end !== containerEnd && end !== declarationListContainerEnd)) { + forEachTrailingCommentRange(currentText, end, cb); + } + } + + function reset() { + currentSourceFile = undefined; + currentText = undefined; + currentLineMap = undefined; + detachedCommentsInfo = undefined; + } + + function setSourceFile(sourceFile: SourceFile) { + currentSourceFile = sourceFile; + currentText = currentSourceFile.text; + currentLineMap = getLineStarts(currentSourceFile); + detachedCommentsInfo = undefined; + } + + function disableCommentsAndEmit(node: Node, emitCallback: (node: Node) => void): void { + if (disabled) { + emitCallback(node); + } + else { + disabled = true; + emitCallback(node); + disabled = false; + } + } + + function hasDetachedComments(pos: number) { + return detachedCommentsInfo !== undefined && lastOrUndefined(detachedCommentsInfo).nodePos === pos; + } + + function forEachLeadingCommentWithoutDetachedComments(cb: (commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) => void) { + // get the leading comments from detachedPos + const pos = lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos; + if (detachedCommentsInfo.length - 1) { + detachedCommentsInfo.pop(); + } + else { + detachedCommentsInfo = undefined; + } + + forEachLeadingCommentRange(currentText, pos, cb, /*state*/ pos); + } + + function emitDetachedCommentsAndUpdateCommentsInfo(range: TextRange) { + const currentDetachedCommentInfo = emitDetachedComments(currentText, currentLineMap, writer, writeComment, range, newLine, disabled); + if (currentDetachedCommentInfo) { + if (detachedCommentsInfo) { + detachedCommentsInfo.push(currentDetachedCommentInfo); + } + else { + detachedCommentsInfo = [currentDetachedCommentInfo]; + } + } + } + + function writeComment(text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) { + emitPos(commentPos); + writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine); + emitPos(commentEnd); + } + + /** + * Determine if the given comment is a triple-slash + * + * @return true if the comment is a triple-slash comment else false + **/ + function isTripleSlashComment(commentPos: number, commentEnd: number) { + // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text + // so that we don't end up computing comment string and doing match for all // comments + if (currentText.charCodeAt(commentPos + 1) === CharacterCodes.slash && + commentPos + 2 < commentEnd && + currentText.charCodeAt(commentPos + 2) === CharacterCodes.slash) { + const textSubStr = currentText.substring(commentPos, commentEnd); + return textSubStr.match(fullTripleSlashReferencePathRegEx) || + textSubStr.match(fullTripleSlashAMDReferencePathRegEx) ? + true : false; + } + return false; + } + } +} \ No newline at end of file diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 27b27bc6532..75a724e4fd8 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -113,6 +113,23 @@ namespace ts { return undefined; } + /** + * Iterates through `array` by index and performs the callback on each element of array until the callback + * returns a falsey value, then returns false. + * If no such value is found, the callback is applied to each element of array and `true` is returned. + */ + export function every(array: T[], callback: (element: T, index: number) => boolean): boolean { + if (array) { + for (let i = 0, len = array.length; i < len; i++) { + if (!callback(array[i], i)) { + return false; + } + } + } + + return true; + } + /** Works like Array.prototype.find, returning `undefined` if no element satisfying the predicate is found. */ export function find(array: T[], predicate: (element: T, index: number) => boolean): T | undefined { for (let i = 0, len = array.length; i < len; i++) { @@ -169,11 +186,12 @@ namespace ts { return -1; } - export function countWhere(array: T[], predicate: (x: T) => boolean): number { + export function countWhere(array: T[], predicate: (x: T, i: number) => boolean): number { let count = 0; if (array) { - for (const v of array) { - if (predicate(v)) { + for (let i = 0; i < array.length; i++) { + const v = array[i]; + if (predicate(v, i)) { count++; } } @@ -185,6 +203,8 @@ namespace ts { * Filters an array by a predicate function. Returns the same array instance if the predicate is * true for all elements, otherwise returns a new array instance containing the filtered subset. */ + export function filter(array: T[], f: (x: T) => x is U): U[]; + export function filter(array: T[], f: (x: T) => boolean): T[] export function filter(array: T[], f: (x: T) => boolean): T[] { if (array) { const len = array.length; @@ -232,22 +252,135 @@ namespace ts { array.length = outIndex; } - export function map(array: T[], f: (x: T) => U): U[] { + export function map(array: T[], f: (x: T, i: number) => U): U[] { let result: U[]; if (array) { result = []; - for (const v of array) { - result.push(f(v)); + for (let i = 0; i < array.length; i++) { + const v = array[i]; + result.push(f(v, i)); } } return result; } + /** + * Flattens an array containing a mix of array or non-array elements. + * + * @param array The array to flatten. + */ + export function flatten(array: (T | T[])[]): T[] { + let result: T[]; + if (array) { + result = []; + for (const v of array) { + if (v) { + if (isArray(v)) { + addRange(result, v); + } + else { + result.push(v); + } + } + } + } + + return result; + } + + /** + * Maps an array. If the mapped value is an array, it is spread into the result. + * + * @param array The array to map. + * @param mapfn The callback used to map the result into one or more values. + */ + export function flatMap(array: T[], mapfn: (x: T, i: number) => U | U[]): U[] { + let result: U[]; + if (array) { + result = []; + for (let i = 0; i < array.length; i++) { + const v = mapfn(array[i], i); + if (v) { + if (isArray(v)) { + addRange(result, v); + } + else { + result.push(v); + } + } + } + } + return result; + } + + /** + * Computes the first matching span of elements and returns a tuple of the first span + * and the remaining elements. + */ + export function span(array: T[], f: (x: T, i: number) => boolean): [T[], T[]] { + if (array) { + for (let i = 0; i < array.length; i++) { + if (!f(array[i], i)) { + return [array.slice(0, i), array.slice(i)]; + } + } + return [array.slice(0), []]; + } + + return undefined; + } + + /** + * Maps contiguous spans of values with the same key. + * + * @param array The array to map. + * @param keyfn A callback used to select the key for an element. + * @param mapfn A callback used to map a contiguous chunk of values to a single value. + */ + export function spanMap(array: T[], keyfn: (x: T, i: number) => K, mapfn: (chunk: T[], key: K, start: number, end: number) => U): U[] { + let result: U[]; + if (array) { + result = []; + const len = array.length; + let previousKey: K; + let key: K; + let start = 0; + let pos = 0; + while (start < len) { + while (pos < len) { + const value = array[pos]; + key = keyfn(value, pos); + if (pos === 0) { + previousKey = key; + } + else if (key !== previousKey) { + break; + } + + pos++; + } + + if (start < pos) { + const v = mapfn(array.slice(start, pos), previousKey, start, pos); + if (v) { + result.push(v); + } + + start = pos; + } + + previousKey = key; + pos++; + } + } + + return result; + } + export function concatenate(array1: T[], array2: T[]): T[] { if (!array2 || !array2.length) return array1; if (!array1 || !array1.length) return array2; - - return array1.concat(array2); + return [...array1, ...array2]; } export function deduplicate(array: T[], areEqual?: (a: T, b: T) => boolean): T[] { @@ -266,6 +399,27 @@ namespace ts { return result; } + /** + * Compacts an array, removing any falsey elements. + */ + export function compact(array: T[]): T[] { + let result: T[]; + if (array) { + for (let i = 0; i < array.length; i++) { + const v = array[i]; + if (result || !v) { + if (!result) { + result = array.slice(0, i); + } + if (v) { + result.push(v); + } + } + } + } + return result || array; + } + export function sum(array: any[], prop: string): number { let result = 0; for (const v of array) { @@ -277,7 +431,9 @@ namespace ts { export function addRange(to: T[], from: T[]): void { if (to && from) { for (const v of from) { - to.push(v); + if (v !== undefined) { + to.push(v); + } } } } @@ -292,15 +448,31 @@ namespace ts { return true; } + export function firstOrUndefined(array: T[]): T { + return array && array.length > 0 + ? array[0] + : undefined; + } + + export function singleOrUndefined(array: T[]): T { + return array && array.length === 1 + ? array[0] + : undefined; + } + + export function singleOrMany(array: T[]): T | T[] { + return array && array.length === 1 + ? array[0] + : array; + } + /** * Returns the last element of an array if non-empty, undefined otherwise. */ export function lastOrUndefined(array: T[]): T { - if (array.length === 0) { - return undefined; - } - - return array[array.length - 1]; + return array && array.length > 0 + ? array[array.length - 1] + : undefined; } /** @@ -332,14 +504,15 @@ namespace ts { return ~low; } - export function reduceLeft(array: T[], f: (a: T, x: T) => T): T; - export function reduceLeft(array: T[], f: (a: U, x: T) => U, initial: U): U; - export function reduceLeft(array: T[], f: (a: U, x: T) => U, initial?: U): U { - if (array) { - const count = array.length; - if (count > 0) { - let pos = 0; - let result: T | U; + export function reduceLeft(array: T[], f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U; + export function reduceLeft(array: T[], f: (memo: T, value: T, i: number) => T): T; + export function reduceLeft(array: T[], f: (memo: T, value: T, i: number) => T, initial?: T, start?: number, count?: number): T { + if (array && array.length > 0) { + const size = array.length; + if (size > 0) { + let pos = start === undefined || start < 0 ? 0 : start; + const end = count === undefined || pos + count > size - 1 ? size - 1 : pos + count; + let result: T; if (arguments.length <= 2) { result = array[pos]; pos++; @@ -347,23 +520,25 @@ namespace ts { else { result = initial; } - while (pos < count) { - result = f(result, array[pos]); + while (pos <= end) { + result = f(result, array[pos], pos); pos++; } - return result; + return result; } } return initial; } - export function reduceRight(array: T[], f: (a: T, x: T) => T): T; - export function reduceRight(array: T[], f: (a: U, x: T) => U, initial: U): U; - export function reduceRight(array: T[], f: (a: U, x: T) => U, initial?: U): U { + export function reduceRight(array: T[], f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U; + export function reduceRight(array: T[], f: (memo: T, value: T, i: number) => T): T; + export function reduceRight(array: T[], f: (memo: T, value: T, i: number) => T, initial?: T, start?: number, count?: number): T { if (array) { - let pos = array.length - 1; - if (pos >= 0) { - let result: T | U; + const size = array.length; + if (size > 0) { + let pos = start === undefined || start > size - 1 ? size - 1 : start; + const end = count === undefined || pos - count < 0 ? 0 : pos - count; + let result: T; if (arguments.length <= 2) { result = array[pos]; pos--; @@ -371,11 +546,11 @@ namespace ts { else { result = initial; } - while (pos >= 0) { - result = f(result, array[pos]); + while (pos >= end) { + result = f(result, array[pos], pos); pos--; } - return result; + return result; } } return initial; @@ -539,6 +714,15 @@ namespace ts { return result; } + export function isEmpty(map: Map) { + for (const id in map) { + if (hasProperty(map, id)) { + return false; + } + } + return true; + } + export function cloneMap(map: Map) { const clone = createMap(); copyProperties(map, clone); @@ -566,6 +750,36 @@ namespace ts { return result; } + /** + * Adds the value to an array of values associated with the key, and returns the array. + * Creates the array if it does not already exist. + */ + export function multiMapAdd(map: Map, key: string, value: V): V[] { + const values = map[key]; + if (values) { + values.push(value); + return values; + } + else { + return map[key] = [value]; + } + } + + /** + * Removes a value from an array of values associated with the key. + * Does not preserve the order of those values. + * Does nothing if `key` is not in `map`, or `value` is not in `map[key]`. + */ + export function multiMapRemove(map: Map, key: string, value: V): void { + const values = map[key]; + if (values) { + unorderedRemoveItem(values, value); + if (!values.length) { + delete map[key]; + } + } + } + /** * Tests whether a value is an array. */ @@ -1453,11 +1667,16 @@ namespace ts { } function Node(this: Node, kind: SyntaxKind, pos: number, end: number) { + this.id = 0; this.kind = kind; this.pos = pos; this.end = end; this.flags = NodeFlags.None; + this.modifierFlagsCache = ModifierFlags.None; + this.transformFlags = TransformFlags.None; this.parent = undefined; + this.original = undefined; + this.transformId = 0; } export let objectAllocator: ObjectAllocator = { @@ -1478,10 +1697,13 @@ namespace ts { } export namespace Debug { - const currentAssertionLevel = AssertionLevel.None; + declare var process: any; + declare var require: any; + + let currentAssertionLevel: AssertionLevel; export function shouldAssert(level: AssertionLevel): boolean { - return currentAssertionLevel >= level; + return getCurrentAssertionLevel() >= level; } export function assert(expression: boolean, message?: string, verboseDebugInfo?: () => string): void { @@ -1498,22 +1720,70 @@ namespace ts { export function fail(message?: string): void { Debug.assert(/*expression*/ false, message); } + + function getCurrentAssertionLevel() { + if (currentAssertionLevel !== undefined) { + return currentAssertionLevel; + } + + if (sys === undefined) { + return AssertionLevel.None; + } + + const developmentMode = /^development$/i.test(getEnvironmentVariable("NODE_ENV")); + currentAssertionLevel = developmentMode + ? AssertionLevel.Normal + : AssertionLevel.None; + + return currentAssertionLevel; + } } - export function copyListRemovingItem(item: T, list: T[]) { - const copiedList: T[] = []; - for (const e of list) { - if (e !== item) { - copiedList.push(e); + export function getEnvironmentVariable(name: string, host?: CompilerHost) { + if (host && host.getEnvironmentVariable) { + return host.getEnvironmentVariable(name); + } + + if (sys && sys.getEnvironmentVariable) { + return sys.getEnvironmentVariable(name); + } + + return ""; + } + + /** Remove an item from an array, moving everything to its right one space left. */ + export function orderedRemoveItemAt(array: T[], index: number): void { + // This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`. + for (let i = index; i < array.length - 1; i++) { + array[i] = array[i + 1]; + } + array.pop(); + } + + export function unorderedRemoveItemAt(array: T[], index: number): void { + // Fill in the "hole" left at `index`. + array[index] = array[array.length - 1]; + array.pop(); + } + + /** Remove the *first* occurrence of `item` from the array. */ + export function unorderedRemoveItem(array: T[], item: T): void { + unorderedRemoveFirstItemWhere(array, element => element === item); + } + + /** Remove the *first* element satisfying `predicate`. */ + function unorderedRemoveFirstItemWhere(array: T[], predicate: (element: T) => boolean): void { + for (let i = 0; i < array.length; i++) { + if (predicate(array[i])) { + unorderedRemoveItemAt(array, i); + break; } } - return copiedList; } - export function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string { - return useCaseSensitivefileNames + export function createGetCanonicalFileName(useCaseSensitiveFileNames: boolean): (fileName: string) => string { + return useCaseSensitiveFileNames ? ((fileName) => fileName) : ((fileName) => fileName.toLowerCase()); } - } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index ab1ca518256..68e488295e7 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -374,7 +374,7 @@ namespace ts { const jsDocComments = getJsDocCommentsFromText(declaration, currentText); emitNewLineBeforeLeadingComments(currentLineMap, writer, declaration, jsDocComments); // jsDoc comments are emitted at /*leading comment1 */space/*leading comment*/space - emitComments(currentText, currentLineMap, writer, jsDocComments, /*trailingSeparator*/ true, newLine, writeCommentRange); + emitComments(currentText, currentLineMap, writer, jsDocComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeCommentRange); } } @@ -655,12 +655,13 @@ namespace ts { function emitModuleElementDeclarationFlags(node: Node) { // If the node is parented in the current source file we need to emit export declare or just export if (node.parent.kind === SyntaxKind.SourceFile) { + const modifiers = getModifierFlags(node); // If the node is exported - if (node.flags & NodeFlags.Export) { + if (modifiers & ModifierFlags.Export) { write("export "); } - if (node.flags & NodeFlags.Default) { + if (modifiers & ModifierFlags.Default) { write("default "); } else if (node.kind !== SyntaxKind.InterfaceDeclaration && !noDeclare) { @@ -669,21 +670,21 @@ namespace ts { } } - function emitClassMemberDeclarationFlags(flags: NodeFlags) { - if (flags & NodeFlags.Private) { + function emitClassMemberDeclarationFlags(flags: ModifierFlags) { + if (flags & ModifierFlags.Private) { write("private "); } - else if (flags & NodeFlags.Protected) { + else if (flags & ModifierFlags.Protected) { write("protected "); } - if (flags & NodeFlags.Static) { + if (flags & ModifierFlags.Static) { write("static "); } - if (flags & NodeFlags.Readonly) { + if (flags & ModifierFlags.Readonly) { write("readonly "); } - if (flags & NodeFlags.Abstract) { + if (flags & ModifierFlags.Abstract) { write("abstract "); } } @@ -692,7 +693,7 @@ namespace ts { // note usage of writer. methods instead of aliases created, just to make sure we are using // correct writer especially to handle asynchronous alias writing emitJsDocComments(node); - if (node.flags & NodeFlags.Export) { + if (hasModifier(node, ModifierFlags.Export)) { write("export "); } write("import "); @@ -731,7 +732,7 @@ namespace ts { function writeImportDeclaration(node: ImportDeclaration) { emitJsDocComments(node); - if (node.flags & NodeFlags.Export) { + if (hasModifier(node, ModifierFlags.Export)) { write("export "); } write("import "); @@ -926,7 +927,7 @@ namespace ts { } function isPrivateMethodTypeParameter(node: TypeParameterDeclaration) { - return node.parent.kind === SyntaxKind.MethodDeclaration && (node.parent.flags & NodeFlags.Private); + return node.parent.kind === SyntaxKind.MethodDeclaration && hasModifier(node.parent, ModifierFlags.Private); } function emitTypeParameters(typeParameters: TypeParameterDeclaration[]) { @@ -976,7 +977,7 @@ namespace ts { case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - if (node.parent.flags & NodeFlags.Static) { + if (hasModifier(node.parent, ModifierFlags.Static)) { diagnosticMessage = Diagnostics.Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1; } else if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) { @@ -1055,7 +1056,7 @@ namespace ts { function emitParameterProperties(constructorDeclaration: ConstructorDeclaration) { if (constructorDeclaration) { forEach(constructorDeclaration.parameters, param => { - if (param.flags & NodeFlags.ParameterPropertyModifier) { + if (hasModifier(param, ModifierFlags.ParameterPropertyModifier)) { emitPropertyDeclaration(param); } }); @@ -1064,7 +1065,7 @@ namespace ts { emitJsDocComments(node); emitModuleElementDeclarationFlags(node); - if (node.flags & NodeFlags.Abstract) { + if (hasModifier(node, ModifierFlags.Abstract)) { write("abstract "); } @@ -1114,7 +1115,7 @@ namespace ts { } emitJsDocComments(node); - emitClassMemberDeclarationFlags(node.flags); + emitClassMemberDeclarationFlags(getModifierFlags(node)); emitVariableDeclaration(node); write(";"); writeLine(); @@ -1141,7 +1142,7 @@ namespace ts { if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) { emitTypeOfVariableDeclarationFromTypeLiteral(node); } - else if (!(node.flags & NodeFlags.Private)) { + else if (!hasModifier(node, ModifierFlags.Private)) { writeTypeOfDeclaration(node, node.type, getVariableDeclarationTypeVisibilityError); } } @@ -1158,7 +1159,7 @@ namespace ts { // This check is to ensure we don't report error on constructor parameter property as that error would be reported during parameter emit else if (node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) { // TODO(jfreeman): Deal with computed properties in error reporting. - if (node.flags & NodeFlags.Static) { + if (hasModifier(node, ModifierFlags.Static)) { return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : @@ -1269,9 +1270,9 @@ namespace ts { if (node === accessors.firstAccessor) { emitJsDocComments(accessors.getAccessor); emitJsDocComments(accessors.setAccessor); - emitClassMemberDeclarationFlags(node.flags | (accessors.setAccessor ? 0 : NodeFlags.Readonly)); + emitClassMemberDeclarationFlags(getModifierFlags(node) | (accessors.setAccessor ? 0 : ModifierFlags.Readonly)); writeTextOfNode(currentText, node.name); - if (!(node.flags & NodeFlags.Private)) { + if (!hasModifier(node, ModifierFlags.Private)) { accessorWithTypeAnnotation = node; let type = getTypeAnnotationFromAccessor(node); if (!type) { @@ -1302,7 +1303,7 @@ namespace ts { let diagnosticMessage: DiagnosticMessage; if (accessorWithTypeAnnotation.kind === SyntaxKind.SetAccessor) { // Setters have to have type named and cannot infer it so, the type should always be named - if (accessorWithTypeAnnotation.parent.flags & NodeFlags.Static) { + if (hasModifier(accessorWithTypeAnnotation.parent, ModifierFlags.Static)) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? Diagnostics.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1; @@ -1320,7 +1321,7 @@ namespace ts { }; } else { - if (accessorWithTypeAnnotation.flags & NodeFlags.Static) { + if (hasModifier(accessorWithTypeAnnotation, ModifierFlags.Static)) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : @@ -1356,7 +1357,7 @@ namespace ts { emitModuleElementDeclarationFlags(node); } else if (node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.Constructor) { - emitClassMemberDeclarationFlags(node.flags); + emitClassMemberDeclarationFlags(getModifierFlags(node)); } if (node.kind === SyntaxKind.FunctionDeclaration) { write("function "); @@ -1387,7 +1388,7 @@ namespace ts { if (node.kind === SyntaxKind.IndexSignature) { // Index signature can have readonly modifier - emitClassMemberDeclarationFlags(node.flags); + emitClassMemberDeclarationFlags(getModifierFlags(node)); write("["); } else { @@ -1428,7 +1429,7 @@ namespace ts { emitType(node.type); } } - else if (node.kind !== SyntaxKind.Constructor && !(node.flags & NodeFlags.Private)) { + else if (node.kind !== SyntaxKind.Constructor && !hasModifier(node, ModifierFlags.Private)) { writeReturnTypeAtSignature(node, getReturnTypeVisibilityError); } @@ -1468,7 +1469,7 @@ namespace ts { case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - if (node.flags & NodeFlags.Static) { + if (hasModifier(node, ModifierFlags.Static)) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : @@ -1534,7 +1535,7 @@ namespace ts { node.parent.parent.kind === SyntaxKind.TypeLiteral) { emitTypeOfVariableDeclarationFromTypeLiteral(node); } - else if (!(node.parent.flags & NodeFlags.Private)) { + else if (!hasModifier(node.parent, ModifierFlags.Private)) { writeTypeOfDeclaration(node, node.type, getParameterDeclarationTypeVisibilityError); } @@ -1570,7 +1571,7 @@ namespace ts { case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - if (node.parent.flags & NodeFlags.Static) { + if (hasModifier(node.parent, ModifierFlags.Static)) { return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e6bf1d5a170..cddb132f56c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -827,10 +827,6 @@ "category": "Error", "code": 1308 }, - "Async functions are only available when targeting ECMAScript 2015 or higher.": { - "category": "Error", - "code": 1311 - }, "'=' can only be used in an object literal property inside a destructuring assignment.": { "category": "Error", "code": 1312 @@ -1703,7 +1699,7 @@ "category": "Error", "code": 2521 }, - "The 'arguments' object cannot be referenced in an async arrow function. Consider using a standard async function expression.": { + "The 'arguments' object cannot be referenced in an async function or method in ES3 and ES5. Consider using a standard function or method.": { "category": "Error", "code": 2522 }, @@ -2840,6 +2836,10 @@ "category": "Error", "code": 6138 }, + "Import emit helpers from 'tslib'.": { + "category": "Message", + "code": 6139 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f02cf266744..680c446c0d5 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1,285 +1,11 @@ /// -/// +/// /// +/// +/// /* @internal */ namespace ts { - export function getResolvedExternalModuleName(host: EmitHost, file: SourceFile): string { - return file.moduleName || getExternalModuleNameFromPath(host, file.fileName); - } - - export function getExternalModuleNameFromDeclaration(host: EmitHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration): string { - const file = resolver.getExternalModuleFileFromDeclaration(declaration); - if (!file || isDeclarationFile(file)) { - return undefined; - } - return getResolvedExternalModuleName(host, file); - } - - type DependencyGroup = Array; - - const enum Jump { - Break = 1 << 1, - Continue = 1 << 2, - Return = 1 << 3 - } - - const entities = createMap({ - "quot": 0x0022, - "amp": 0x0026, - "apos": 0x0027, - "lt": 0x003C, - "gt": 0x003E, - "nbsp": 0x00A0, - "iexcl": 0x00A1, - "cent": 0x00A2, - "pound": 0x00A3, - "curren": 0x00A4, - "yen": 0x00A5, - "brvbar": 0x00A6, - "sect": 0x00A7, - "uml": 0x00A8, - "copy": 0x00A9, - "ordf": 0x00AA, - "laquo": 0x00AB, - "not": 0x00AC, - "shy": 0x00AD, - "reg": 0x00AE, - "macr": 0x00AF, - "deg": 0x00B0, - "plusmn": 0x00B1, - "sup2": 0x00B2, - "sup3": 0x00B3, - "acute": 0x00B4, - "micro": 0x00B5, - "para": 0x00B6, - "middot": 0x00B7, - "cedil": 0x00B8, - "sup1": 0x00B9, - "ordm": 0x00BA, - "raquo": 0x00BB, - "frac14": 0x00BC, - "frac12": 0x00BD, - "frac34": 0x00BE, - "iquest": 0x00BF, - "Agrave": 0x00C0, - "Aacute": 0x00C1, - "Acirc": 0x00C2, - "Atilde": 0x00C3, - "Auml": 0x00C4, - "Aring": 0x00C5, - "AElig": 0x00C6, - "Ccedil": 0x00C7, - "Egrave": 0x00C8, - "Eacute": 0x00C9, - "Ecirc": 0x00CA, - "Euml": 0x00CB, - "Igrave": 0x00CC, - "Iacute": 0x00CD, - "Icirc": 0x00CE, - "Iuml": 0x00CF, - "ETH": 0x00D0, - "Ntilde": 0x00D1, - "Ograve": 0x00D2, - "Oacute": 0x00D3, - "Ocirc": 0x00D4, - "Otilde": 0x00D5, - "Ouml": 0x00D6, - "times": 0x00D7, - "Oslash": 0x00D8, - "Ugrave": 0x00D9, - "Uacute": 0x00DA, - "Ucirc": 0x00DB, - "Uuml": 0x00DC, - "Yacute": 0x00DD, - "THORN": 0x00DE, - "szlig": 0x00DF, - "agrave": 0x00E0, - "aacute": 0x00E1, - "acirc": 0x00E2, - "atilde": 0x00E3, - "auml": 0x00E4, - "aring": 0x00E5, - "aelig": 0x00E6, - "ccedil": 0x00E7, - "egrave": 0x00E8, - "eacute": 0x00E9, - "ecirc": 0x00EA, - "euml": 0x00EB, - "igrave": 0x00EC, - "iacute": 0x00ED, - "icirc": 0x00EE, - "iuml": 0x00EF, - "eth": 0x00F0, - "ntilde": 0x00F1, - "ograve": 0x00F2, - "oacute": 0x00F3, - "ocirc": 0x00F4, - "otilde": 0x00F5, - "ouml": 0x00F6, - "divide": 0x00F7, - "oslash": 0x00F8, - "ugrave": 0x00F9, - "uacute": 0x00FA, - "ucirc": 0x00FB, - "uuml": 0x00FC, - "yacute": 0x00FD, - "thorn": 0x00FE, - "yuml": 0x00FF, - "OElig": 0x0152, - "oelig": 0x0153, - "Scaron": 0x0160, - "scaron": 0x0161, - "Yuml": 0x0178, - "fnof": 0x0192, - "circ": 0x02C6, - "tilde": 0x02DC, - "Alpha": 0x0391, - "Beta": 0x0392, - "Gamma": 0x0393, - "Delta": 0x0394, - "Epsilon": 0x0395, - "Zeta": 0x0396, - "Eta": 0x0397, - "Theta": 0x0398, - "Iota": 0x0399, - "Kappa": 0x039A, - "Lambda": 0x039B, - "Mu": 0x039C, - "Nu": 0x039D, - "Xi": 0x039E, - "Omicron": 0x039F, - "Pi": 0x03A0, - "Rho": 0x03A1, - "Sigma": 0x03A3, - "Tau": 0x03A4, - "Upsilon": 0x03A5, - "Phi": 0x03A6, - "Chi": 0x03A7, - "Psi": 0x03A8, - "Omega": 0x03A9, - "alpha": 0x03B1, - "beta": 0x03B2, - "gamma": 0x03B3, - "delta": 0x03B4, - "epsilon": 0x03B5, - "zeta": 0x03B6, - "eta": 0x03B7, - "theta": 0x03B8, - "iota": 0x03B9, - "kappa": 0x03BA, - "lambda": 0x03BB, - "mu": 0x03BC, - "nu": 0x03BD, - "xi": 0x03BE, - "omicron": 0x03BF, - "pi": 0x03C0, - "rho": 0x03C1, - "sigmaf": 0x03C2, - "sigma": 0x03C3, - "tau": 0x03C4, - "upsilon": 0x03C5, - "phi": 0x03C6, - "chi": 0x03C7, - "psi": 0x03C8, - "omega": 0x03C9, - "thetasym": 0x03D1, - "upsih": 0x03D2, - "piv": 0x03D6, - "ensp": 0x2002, - "emsp": 0x2003, - "thinsp": 0x2009, - "zwnj": 0x200C, - "zwj": 0x200D, - "lrm": 0x200E, - "rlm": 0x200F, - "ndash": 0x2013, - "mdash": 0x2014, - "lsquo": 0x2018, - "rsquo": 0x2019, - "sbquo": 0x201A, - "ldquo": 0x201C, - "rdquo": 0x201D, - "bdquo": 0x201E, - "dagger": 0x2020, - "Dagger": 0x2021, - "bull": 0x2022, - "hellip": 0x2026, - "permil": 0x2030, - "prime": 0x2032, - "Prime": 0x2033, - "lsaquo": 0x2039, - "rsaquo": 0x203A, - "oline": 0x203E, - "frasl": 0x2044, - "euro": 0x20AC, - "image": 0x2111, - "weierp": 0x2118, - "real": 0x211C, - "trade": 0x2122, - "alefsym": 0x2135, - "larr": 0x2190, - "uarr": 0x2191, - "rarr": 0x2192, - "darr": 0x2193, - "harr": 0x2194, - "crarr": 0x21B5, - "lArr": 0x21D0, - "uArr": 0x21D1, - "rArr": 0x21D2, - "dArr": 0x21D3, - "hArr": 0x21D4, - "forall": 0x2200, - "part": 0x2202, - "exist": 0x2203, - "empty": 0x2205, - "nabla": 0x2207, - "isin": 0x2208, - "notin": 0x2209, - "ni": 0x220B, - "prod": 0x220F, - "sum": 0x2211, - "minus": 0x2212, - "lowast": 0x2217, - "radic": 0x221A, - "prop": 0x221D, - "infin": 0x221E, - "ang": 0x2220, - "and": 0x2227, - "or": 0x2228, - "cap": 0x2229, - "cup": 0x222A, - "int": 0x222B, - "there4": 0x2234, - "sim": 0x223C, - "cong": 0x2245, - "asymp": 0x2248, - "ne": 0x2260, - "equiv": 0x2261, - "le": 0x2264, - "ge": 0x2265, - "sub": 0x2282, - "sup": 0x2283, - "nsub": 0x2284, - "sube": 0x2286, - "supe": 0x2287, - "oplus": 0x2295, - "otimes": 0x2297, - "perp": 0x22A5, - "sdot": 0x22C5, - "lceil": 0x2308, - "rceil": 0x2309, - "lfloor": 0x230A, - "rfloor": 0x230B, - "lang": 0x2329, - "rang": 0x232A, - "loz": 0x25CA, - "spades": 0x2660, - "clubs": 0x2663, - "hearts": 0x2665, - "diams": 0x2666 - }); - // Flags enum to track count of temp variables and a few dedicated names const enum TempFlags { Auto = 0x00000000, // No preferred name @@ -287,56 +13,11 @@ namespace ts { _i = 0x10000000, // Use/preference flag for '_i' } - const enum CopyDirection { - ToOriginal, - ToOutParameter - } - - /** - * If loop contains block scoped binding captured in some function then loop body is converted to a function. - * Lexical bindings declared in loop initializer will be passed into the loop body function as parameters, - * however if this binding is modified inside the body - this new value should be propagated back to the original binding. - * This is done by declaring new variable (out parameter holder) outside of the loop for every binding that is reassigned inside the body. - * On every iteration this variable is initialized with value of corresponding binding. - * At every point where control flow leaves the loop either explicitly (break/continue) or implicitly (at the end of loop body) - * we copy the value inside the loop to the out parameter holder. - * - * for (let x;;) { - * let a = 1; - * let b = () => a; - * x++ - * if (...) break; - * ... - * } - * - * will be converted to - * - * var out_x; - * var loop = function(x) { - * var a = 1; - * var b = function() { return a; } - * x++; - * if (...) return out_x = x, "break"; - * ... - * out_x = x; - * } - * for (var x;;) { - * out_x = x; - * var state = loop(x); - * x = out_x; - * if (state === "break") break; - * } - * - * NOTE: values to out parameters are not copies if loop is abrupted with 'return' - in this case this will end the entire enclosing function - * so nobody can observe this new value. - */ - interface LoopOutParameter { - originalName: Identifier; - outParamName: string; - } - // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile): EmitResult { + const delimiters = createDelimiterMap(); + const brackets = createBracketsMap(); + // emit output for the __extends helper function const extendsHelper = ` var __extends = (this && this.__extends) || function (d, b) { @@ -345,6 +26,9 @@ var __extends = (this && this.__extends) || function (d, b) { d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); };`; + // Emit output for the __assign helper function. + // This is typically used for JSX spread attributes, + // and can be used for object literal spread properties. const assignHelper = ` var __assign = (this && this.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { @@ -376,6 +60,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } };`; + // emit output for the __awaiter helper function const awaiterHelper = ` var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { @@ -386,17 +71,146 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); };`; + const generatorHelper = ` +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (sent[0] === 1) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent, f; + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (1) { + if (_.done) switch (op[0]) { + case 0: return { value: void 0, done: true }; + case 1: case 6: throw op[1]; + case 2: return { value: op[1], done: true }; + } + try { + switch (f = 1, op[0]) { + case 0: case 1: sent = op; break; + case 4: return _.label++, { value: op[1], done: false }; + case 7: op = _.stack.pop(), _.trys.pop(); continue; + default: + var r = _.trys.length > 0 && _.trys[_.trys.length - 1]; + if (!r && (op[0] === 6 || op[0] === 2)) { _.done = 1; continue; } + if (op[0] === 3 && (!r || (op[1] > r[0] && op[1] < r[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < r[1]) { _.label = r[1], sent = op; break; } + if (r && _.label < r[2]) { _.label = r[2], _.stack.push(op); break; } + if (r[2]) { _.stack.pop(); } + _.trys.pop(); + continue; + } + op = body.call(thisArg, _); + } + catch (e) { op = [6, e]; } + finally { f = 0, sent = void 0; } + } + } + return { + next: function (v) { return step([0, v]); }, + "throw": function (v) { return step([1, v]); }, + "return": function (v) { return step([2, v]); } + }; +};`; + + // emit output for the __export helper function + const exportStarHelper = ` +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +}`; + + // emit output for the UMD helper function. + const umdHelper = ` +(function (dependencies, factory) { + if (typeof module === 'object' && typeof module.exports === 'object') { + var v = factory(require, exports); if (v !== undefined) module.exports = v; + } + else if (typeof define === 'function' && define.amd) { + define(dependencies, factory); + } +})`; + + const superHelper = ` +const _super = name => super[name];`; + + const advancedSuperHelper = ` +const _super = (function (geti, seti) { + const cache = Object.create(null); + return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } }); +})(name => super[name], (name, value) => super[name] = value);`; + const compilerOptions = host.getCompilerOptions(); const languageVersion = getEmitScriptTarget(compilerOptions); - const modulekind = getEmitModuleKind(compilerOptions); + const moduleKind = getEmitModuleKind(compilerOptions); const sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined; const emittedFilesList: string[] = compilerOptions.listEmittedFiles ? [] : undefined; const emitterDiagnostics = createDiagnosticCollection(); - let emitSkipped = false; const newLine = host.getNewLine(); + const transformers = getTransformers(compilerOptions); + const writer = createTextWriter(newLine); + const { + write, + writeLine, + increaseIndent, + decreaseIndent + } = writer; - const emitJavaScript = createFileEmitter(); - forEachExpectedEmitFile(host, emitFile, targetSourceFile); + const sourceMap = createSourceMapWriter(host, writer); + const { + emitStart, + emitEnd, + emitTokenStart, + emitTokenEnd + } = sourceMap; + + const comments = createCommentWriter(host, writer, sourceMap); + const { + emitNodeWithComments, + emitBodyWithDetachedComments, + emitTrailingCommentsOfPosition + } = comments; + + let nodeIdToGeneratedName: string[]; + let autoGeneratedIdToGeneratedName: string[]; + let generatedNameSet: Map; + let tempFlags: TempFlags; + let currentSourceFile: SourceFile; + let currentText: string; + let currentFileIdentifiers: Map; + let extendsEmitted: boolean; + let assignEmitted: boolean; + let decorateEmitted: boolean; + let paramEmitted: boolean; + let awaiterEmitted: boolean; + let isOwnFileEmit: boolean; + let emitSkipped = false; + + performance.mark("beforeTransform"); + + // Transform the source files + const transformed = transformFiles( + resolver, + host, + getSourceFilesToEmit(host, targetSourceFile), + transformers); + + performance.measure("transformTime", "beforeTransform"); + + // Extract helpers from the result + const { + getTokenSourceMapRange, + isSubstitutionEnabled, + isEmitNotificationEnabled, + onSubstituteNode, + onEmitNode + } = transformed; + + performance.mark("beforePrint"); + + // Emit each output file + forEachTransformedEmitFile(host, transformed.getSourceFiles(), emitFile); + + // Clean up after transformation + transformed.dispose(); + + performance.measure("printTime", "beforePrint"); return { emitSkipped, @@ -405,7981 +219,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge sourceMaps: sourceMapDataList }; - function isUniqueLocalName(name: string, container: Node): boolean { - for (let node = container; isNodeDescendentOf(node, container); node = node.nextContainer) { - if (node.locals && name in node.locals) { - // We conservatively include alias symbols to cover cases where they're emitted as locals - if (node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) { - return false; - } - } - } - return true; - } - - interface ConvertedLoopState { - /* - * set of labels that occurred inside the converted loop - * used to determine if labeled jump can be emitted as is or it should be dispatched to calling code - */ - labels?: Map; - /* - * collection of labeled jumps that transfer control outside the converted loop. - * maps store association 'label -> labelMarker' where - * - label - value of label as it appear in code - * - label marker - return value that should be interpreted by calling code as 'jump to