mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-27 22:26:39 -05:00
Merge branch 'master' into sourceMapAndBreakpointDecorators
This commit is contained in:
@@ -1028,16 +1028,12 @@ namespace ts {
|
||||
|
||||
// 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.
|
||||
let moduleName = escapeIdentifier(moduleReferenceLiteral.text);
|
||||
const moduleName = escapeIdentifier(moduleReferenceLiteral.text);
|
||||
|
||||
if (moduleName === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (moduleName.indexOf("!") >= 0) {
|
||||
moduleName = moduleName.substr(0, moduleName.indexOf("!"));
|
||||
}
|
||||
|
||||
const isRelative = isExternalModuleNameRelative(moduleName);
|
||||
if (!isRelative) {
|
||||
const symbol = getSymbol(globals, "\"" + moduleName + "\"", SymbolFlags.ValueModule);
|
||||
@@ -5228,9 +5224,12 @@ namespace ts {
|
||||
const id = relation !== identityRelation || apparentSource.id < target.id ? apparentSource.id + "," + target.id : target.id + "," + apparentSource.id;
|
||||
const related = relation[id];
|
||||
if (related !== undefined) {
|
||||
// If we computed this relation already and it was failed and reported, or if we're not being asked to elaborate
|
||||
// errors, we can use the cached value. Otherwise, recompute the relation
|
||||
if (!elaborateErrors || (related === RelationComparisonResult.FailedAndReported)) {
|
||||
if (elaborateErrors && related === RelationComparisonResult.Failed) {
|
||||
// We are elaborating errors and the cached result is an unreported failure. Record the result as a reported
|
||||
// failure and continue computing the relation such that errors get reported.
|
||||
relation[id] = RelationComparisonResult.FailedAndReported;
|
||||
}
|
||||
else {
|
||||
return related === RelationComparisonResult.Succeeded ? Ternary.True : Ternary.False;
|
||||
}
|
||||
}
|
||||
@@ -6086,6 +6085,17 @@ namespace ts {
|
||||
}
|
||||
|
||||
function inferFromTypes(source: Type, target: Type) {
|
||||
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union ||
|
||||
source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
|
||||
// Source and target are both unions or both intersections. To improve the quality of
|
||||
// inferences we first reduce the types by removing constituents that are identically
|
||||
// matched by a constituent in the other type. For example, when inferring from
|
||||
// 'string | string[]' to 'string | T', we reduce the types to 'string[]' and 'T'.
|
||||
const reducedSource = reduceUnionOrIntersectionType(<UnionOrIntersectionType>source, <UnionOrIntersectionType>target);
|
||||
const reducedTarget = reduceUnionOrIntersectionType(<UnionOrIntersectionType>target, <UnionOrIntersectionType>source);
|
||||
source = reducedSource;
|
||||
target = reducedTarget;
|
||||
}
|
||||
if (target.flags & TypeFlags.TypeParameter) {
|
||||
// If target is a type parameter, make an inference, unless the source type contains
|
||||
// the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
|
||||
@@ -6096,7 +6106,6 @@ namespace ts {
|
||||
if (source.flags & TypeFlags.ContainsAnyFunctionType) {
|
||||
return;
|
||||
}
|
||||
|
||||
const typeParameters = context.typeParameters;
|
||||
for (let i = 0; i < typeParameters.length; i++) {
|
||||
if (target === typeParameters[i]) {
|
||||
@@ -6244,6 +6253,41 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function typeIdenticalToSomeType(source: Type, target: UnionOrIntersectionType): boolean {
|
||||
for (const t of target.types) {
|
||||
if (isTypeIdenticalTo(source, t)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the reduced form of the source type. This type is computed by by removing all source
|
||||
* constituents that have an identical match in the target type.
|
||||
*/
|
||||
function reduceUnionOrIntersectionType(source: UnionOrIntersectionType, target: UnionOrIntersectionType) {
|
||||
let sourceTypes = source.types;
|
||||
let sourceIndex = 0;
|
||||
let modified = false;
|
||||
while (sourceIndex < sourceTypes.length) {
|
||||
if (typeIdenticalToSomeType(sourceTypes[sourceIndex], target)) {
|
||||
if (!modified) {
|
||||
sourceTypes = sourceTypes.slice(0);
|
||||
modified = true;
|
||||
}
|
||||
sourceTypes.splice(sourceIndex, 1);
|
||||
}
|
||||
else {
|
||||
sourceIndex++;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
return source.flags & TypeFlags.Union ? getUnionType(sourceTypes, /*noSubtypeReduction*/ true) : getIntersectionType(sourceTypes);
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
function getInferenceCandidates(context: InferenceContext, index: number): Type[] {
|
||||
const inferences = context.inferences[index];
|
||||
return inferences.primary || inferences.secondary || emptyArray;
|
||||
|
||||
@@ -860,4 +860,4 @@ namespace ts {
|
||||
}
|
||||
return copiedList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1622,7 +1622,7 @@
|
||||
},
|
||||
"Cannot assign an abstract constructor type to a non-abstract constructor type.": {
|
||||
"category": "Error",
|
||||
"code":2517
|
||||
"code": 2517
|
||||
},
|
||||
"Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions.": {
|
||||
"category": "Error",
|
||||
@@ -2068,6 +2068,14 @@
|
||||
"category": "Error",
|
||||
"code": 5056
|
||||
},
|
||||
"Cannot find a tsconfig.json file at the specified directory: '{0}'": {
|
||||
"category": "Error",
|
||||
"code": 5057
|
||||
},
|
||||
"The specified path does not exist: '{0}'": {
|
||||
"category": "Error",
|
||||
"code": 5058
|
||||
},
|
||||
|
||||
"Concatenate and emit output to single file.": {
|
||||
"category": "Message",
|
||||
|
||||
@@ -402,6 +402,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
*/
|
||||
argumentsName?: string;
|
||||
|
||||
/*
|
||||
* alias for 'this' from the calling code stack frame in case if this was used inside the converted loop
|
||||
*/
|
||||
thisName?: string;
|
||||
|
||||
/*
|
||||
* list of non-block scoped variable declarations that appear inside converted loop
|
||||
* such variable declarations should be moved outside the loop body
|
||||
@@ -549,7 +554,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
[ModuleKind.CommonJS]() {},
|
||||
};
|
||||
|
||||
|
||||
|
||||
return doEmit;
|
||||
|
||||
function doEmit(jsFilePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
|
||||
@@ -1992,6 +1997,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.LexicalThis) {
|
||||
write("_this");
|
||||
}
|
||||
else if (convertedLoopState) {
|
||||
write(convertedLoopState.thisName || (convertedLoopState.thisName = makeUniqueName("this")));
|
||||
}
|
||||
else {
|
||||
write("this");
|
||||
}
|
||||
@@ -3322,6 +3330,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
convertedLoopState.argumentsName = convertedOuterLoopState.argumentsName;
|
||||
}
|
||||
|
||||
if (convertedOuterLoopState.thisName) {
|
||||
// outer loop has already used 'this' so we've already have some name to alias it
|
||||
// use the same name in all nested loops
|
||||
convertedLoopState.thisName = convertedOuterLoopState.thisName;
|
||||
}
|
||||
|
||||
if (convertedOuterLoopState.hoistedLocalVariables) {
|
||||
// we've already collected some non-block scoped variable declarations in enclosing loop
|
||||
// use the same storage in nested loop
|
||||
@@ -3351,6 +3365,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
writeLine();
|
||||
}
|
||||
}
|
||||
if (convertedLoopState.thisName) {
|
||||
// if alias for this is set
|
||||
if (convertedOuterLoopState) {
|
||||
// pass it to outer converted loop
|
||||
convertedOuterLoopState.thisName = convertedLoopState.thisName;
|
||||
}
|
||||
else {
|
||||
// this is top level converted loop so we need to create an alias for 'this' here
|
||||
// NOTE:
|
||||
// if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set.
|
||||
// If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'.
|
||||
write(`var ${convertedLoopState.thisName} = this;`);
|
||||
writeLine();
|
||||
}
|
||||
}
|
||||
|
||||
if (convertedLoopState.hoistedLocalVariables) {
|
||||
// if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later
|
||||
@@ -5987,9 +6016,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
}
|
||||
|
||||
// Clone the type name and parent it to a location outside of the current declaration.
|
||||
const typeName = cloneEntityName(node.typeName);
|
||||
typeName.parent = location;
|
||||
|
||||
const typeName = cloneEntityName(node.typeName, location);
|
||||
const result = resolver.getTypeReferenceSerializationKind(typeName);
|
||||
switch (result) {
|
||||
case TypeReferenceSerializationKind.Unknown:
|
||||
@@ -7352,7 +7379,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
write(`], function(${exportFunctionForFile}) {`);
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true);
|
||||
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true, /*ensureUseStrict*/ true);
|
||||
emitEmitHelpers(node);
|
||||
emitCaptureThisForNodeIfNecessary(node);
|
||||
emitSystemModuleBody(node, dependencyGroups, startIndex);
|
||||
@@ -7462,7 +7489,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
writeModuleName(node, emitRelativePathAsModuleName);
|
||||
emitAMDDependencies(node, /*includeNonAmdDependencies*/ true, emitRelativePathAsModuleName);
|
||||
increaseIndent();
|
||||
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true);
|
||||
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true, /*ensureUseStrict*/ true);
|
||||
emitExportStarHelper();
|
||||
emitCaptureThisForNodeIfNecessary(node);
|
||||
emitLinesStartingAt(node.statements, startIndex);
|
||||
@@ -7474,7 +7501,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
}
|
||||
|
||||
function emitCommonJSModule(node: SourceFile) {
|
||||
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false);
|
||||
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false, /*ensureUseStrict*/ true);
|
||||
emitEmitHelpers(node);
|
||||
collectExternalModuleInfo(node);
|
||||
emitExportStarHelper();
|
||||
@@ -7503,7 +7530,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
})(`);
|
||||
emitAMDFactoryHeader(dependencyNames);
|
||||
increaseIndent();
|
||||
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true);
|
||||
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true, /*ensureUseStrict*/ true);
|
||||
emitExportStarHelper();
|
||||
emitCaptureThisForNodeIfNecessary(node);
|
||||
emitLinesStartingAt(node.statements, startIndex);
|
||||
@@ -7645,19 +7672,38 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
}
|
||||
}
|
||||
|
||||
function emitDirectivePrologues(statements: Node[], startWithNewLine: boolean): number {
|
||||
function isUseStrictPrologue(node: ExpressionStatement): boolean {
|
||||
return !!(node.expression as StringLiteral).text.match(/use strict/);
|
||||
}
|
||||
|
||||
function ensureUseStrictPrologue(startWithNewLine: boolean, writeUseStrict: boolean) {
|
||||
if (writeUseStrict) {
|
||||
if (startWithNewLine) {
|
||||
writeLine();
|
||||
}
|
||||
write("\"use strict\";");
|
||||
}
|
||||
}
|
||||
|
||||
function emitDirectivePrologues(statements: Node[], startWithNewLine: boolean, ensureUseStrict?: boolean): number {
|
||||
let foundUseStrict = false;
|
||||
for (let i = 0; i < statements.length; ++i) {
|
||||
if (isPrologueDirective(statements[i])) {
|
||||
if (isUseStrictPrologue(statements[i] as ExpressionStatement)) {
|
||||
foundUseStrict = true;
|
||||
}
|
||||
if (startWithNewLine || i > 0) {
|
||||
writeLine();
|
||||
}
|
||||
emit(statements[i]);
|
||||
}
|
||||
else {
|
||||
ensureUseStrictPrologue(startWithNewLine || i > 0, !foundUseStrict && ensureUseStrict);
|
||||
// return index of the first non prologue directive
|
||||
return i;
|
||||
}
|
||||
}
|
||||
ensureUseStrictPrologue(startWithNewLine, !foundUseStrict && ensureUseStrict);
|
||||
return statements.length;
|
||||
}
|
||||
|
||||
|
||||
@@ -295,11 +295,26 @@ namespace ts {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--project"), /* compilerHost */ undefined);
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
configFileName = normalizePath(combinePaths(commandLine.options.project, "tsconfig.json"));
|
||||
if (commandLine.fileNames.length !== 0) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Option_project_cannot_be_mixed_with_source_files_on_a_command_line), /* compilerHost */ undefined);
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
|
||||
const fileOrDirectory = normalizePath(commandLine.options.project);
|
||||
if (!fileOrDirectory /* current directory "." */ || sys.directoryExists(fileOrDirectory)) {
|
||||
configFileName = combinePaths(fileOrDirectory, "tsconfig.json");
|
||||
if (!sys.fileExists(configFileName)) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0, commandLine.options.project), /* compilerHost */ undefined);
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
}
|
||||
else {
|
||||
configFileName = fileOrDirectory;
|
||||
if (!sys.fileExists(configFileName)) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_specified_path_does_not_exist_Colon_0, commandLine.options.project), /* compilerHost */ undefined);
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (commandLine.fileNames.length === 0 && isJSONSupported()) {
|
||||
const searchPath = normalizePath(sys.getCurrentDirectory());
|
||||
|
||||
@@ -1563,20 +1563,60 @@ namespace ts {
|
||||
return isFunctionLike(n) || n.kind === SyntaxKind.ModuleDeclaration || n.kind === SyntaxKind.SourceFile;
|
||||
}
|
||||
|
||||
export function cloneEntityName(node: EntityName): EntityName {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
const clone = <Identifier>createSynthesizedNode(SyntaxKind.Identifier);
|
||||
clone.text = (<Identifier>node).text;
|
||||
return clone;
|
||||
/**
|
||||
* Creates a shallow, memberwise clone of a node. The "kind", "pos", "end", "flags", and "parent"
|
||||
* properties are excluded by default, and can be provided via the "location", "flags", and
|
||||
* "parent" parameters.
|
||||
* @param node The node to clone.
|
||||
* @param location An optional TextRange to use to supply the new position.
|
||||
* @param flags The NodeFlags to use for the cloned node.
|
||||
* @param parent The parent for the new node.
|
||||
*/
|
||||
export function cloneNode<T extends Node>(node: T, location?: TextRange, flags?: NodeFlags, parent?: Node): T {
|
||||
// We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
|
||||
// the original node. We also need to exclude specific properties and only include own-
|
||||
// properties (to skip members already defined on the shared prototype).
|
||||
const clone = location !== undefined
|
||||
? <T>createNode(node.kind, location.pos, location.end)
|
||||
: <T>createSynthesizedNode(node.kind);
|
||||
|
||||
for (const key in node) {
|
||||
if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(<any>clone)[key] = (<any>node)[key];
|
||||
}
|
||||
else {
|
||||
const clone = <QualifiedName>createSynthesizedNode(SyntaxKind.QualifiedName);
|
||||
clone.left = cloneEntityName((<QualifiedName>node).left);
|
||||
clone.left.parent = clone;
|
||||
clone.right = <Identifier>cloneEntityName((<QualifiedName>node).right);
|
||||
clone.right.parent = clone;
|
||||
return clone;
|
||||
|
||||
if (flags !== undefined) {
|
||||
clone.flags = flags;
|
||||
}
|
||||
|
||||
if (parent !== undefined) {
|
||||
clone.parent = parent;
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep clone of an EntityName, with new parent pointers.
|
||||
* @param node The EntityName to clone.
|
||||
* @param parent The parent for the cloned node.
|
||||
*/
|
||||
export function cloneEntityName(node: EntityName, parent?: Node): EntityName {
|
||||
const clone = cloneNode(node, node, node.flags, parent);
|
||||
if (isQualifiedName(clone)) {
|
||||
const { left, right } = clone;
|
||||
clone.left = cloneEntityName(left, clone);
|
||||
clone.right = cloneNode(right, right, right.flags, parent);
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
export function isQualifiedName(node: Node): node is QualifiedName {
|
||||
return node.kind === SyntaxKind.QualifiedName;
|
||||
}
|
||||
|
||||
export function nodeIsSynthesized(node: Node): boolean {
|
||||
@@ -1919,7 +1959,7 @@ namespace ts {
|
||||
const bundledSources = filter(host.getSourceFiles(),
|
||||
sourceFile => !isDeclarationFile(sourceFile) && // Not a declaration file
|
||||
(!isExternalModule(sourceFile) || // non module file
|
||||
(getEmitModuleKind(options) && isExternalModule(sourceFile)))); // module that can emit - note falsy value from getEmitModuleKind means the module kind that shouldn't be emitted
|
||||
(getEmitModuleKind(options) && isExternalModule(sourceFile)))); // module that can emit - note falsy value from getEmitModuleKind means the module kind that shouldn't be emitted
|
||||
if (bundledSources.length) {
|
||||
const jsFilePath = options.outFile || options.out;
|
||||
const emitFileNames: EmitFileNames = {
|
||||
|
||||
Reference in New Issue
Block a user