mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
merge with master
This commit is contained in:
+81
-25
@@ -81,7 +81,7 @@ namespace ts {
|
||||
symbolToString,
|
||||
getAugmentedPropertiesOfType,
|
||||
getRootSymbols,
|
||||
getContextualType,
|
||||
getContextualType: getApparentTypeOfContextualType,
|
||||
getFullyQualifiedName,
|
||||
getResolvedSignature,
|
||||
getConstantValue,
|
||||
@@ -1653,7 +1653,7 @@ namespace ts {
|
||||
writeAnonymousType(<ObjectType>type, flags);
|
||||
}
|
||||
else if (type.flags & TypeFlags.StringLiteral) {
|
||||
writer.writeStringLiteral((<StringLiteralType>type).text);
|
||||
writer.writeStringLiteral(`"${escapeString((<StringLiteralType>type).text)}"`);
|
||||
}
|
||||
else {
|
||||
// Should never get here
|
||||
@@ -4411,12 +4411,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getStringLiteralType(node: StringLiteral): StringLiteralType {
|
||||
if (hasProperty(stringLiteralTypes, node.text)) {
|
||||
return stringLiteralTypes[node.text];
|
||||
const text = node.text;
|
||||
if (hasProperty(stringLiteralTypes, text)) {
|
||||
return stringLiteralTypes[text];
|
||||
}
|
||||
|
||||
const type = stringLiteralTypes[node.text] = <StringLiteralType>createType(TypeFlags.StringLiteral);
|
||||
type.text = getTextOfNode(node);
|
||||
const type = stringLiteralTypes[text] = <StringLiteralType>createType(TypeFlags.StringLiteral);
|
||||
type.text = text;
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -5084,9 +5085,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
function typeParameterIdenticalTo(source: TypeParameter, target: TypeParameter): Ternary {
|
||||
if (source.symbol.name !== target.symbol.name) {
|
||||
return Ternary.False;
|
||||
}
|
||||
// covers case when both type parameters does not have constraint (both equal to noConstraintType)
|
||||
if (source.constraint === target.constraint) {
|
||||
return Ternary.True;
|
||||
@@ -5747,6 +5745,10 @@ namespace ts {
|
||||
return !!getPropertyOfType(type, "0");
|
||||
}
|
||||
|
||||
function isStringLiteralType(type: Type) {
|
||||
return type.flags & TypeFlags.StringLiteral;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a Type was written as a tuple type literal.
|
||||
* Prefer using isTupleLikeType() unless the use of `elementTypes` is required.
|
||||
@@ -6979,7 +6981,7 @@ namespace ts {
|
||||
else if (operator === SyntaxKind.BarBarToken) {
|
||||
// When an || expression has a contextual type, the operands are contextually typed by that type. When an ||
|
||||
// expression has no contextual type, the right operand is contextually typed by the type of the left operand.
|
||||
let type = getContextualType(binaryExpression);
|
||||
let type = getApparentTypeOfContextualType(binaryExpression);
|
||||
if (!type && node === binaryExpression.right) {
|
||||
type = checkExpression(binaryExpression.left);
|
||||
}
|
||||
@@ -7026,6 +7028,10 @@ namespace ts {
|
||||
return applyToContextualType(type, t => getIndexTypeOfStructuredType(t, kind));
|
||||
}
|
||||
|
||||
function contextualTypeIsStringLiteralType(type: Type): boolean {
|
||||
return !!(type.flags & TypeFlags.Union ? forEach((<UnionType>type).types, isStringLiteralType) : isStringLiteralType(type));
|
||||
}
|
||||
|
||||
// Return true if the given contextual type is a tuple-like type
|
||||
function contextualTypeIsTupleLikeType(type: Type): boolean {
|
||||
return !!(type.flags & TypeFlags.Union ? forEach((<UnionType>type).types, isTupleLikeType) : isTupleLikeType(type));
|
||||
@@ -7051,7 +7057,7 @@ namespace ts {
|
||||
|
||||
function getContextualTypeForObjectLiteralElement(element: ObjectLiteralElement) {
|
||||
const objectLiteral = <ObjectLiteralExpression>element.parent;
|
||||
const type = getContextualType(objectLiteral);
|
||||
const type = getApparentTypeOfContextualType(objectLiteral);
|
||||
if (type) {
|
||||
if (!hasDynamicName(element)) {
|
||||
// For a (non-symbol) computed property, there is no reason to look up the name
|
||||
@@ -7077,7 +7083,7 @@ namespace ts {
|
||||
// type of T.
|
||||
function getContextualTypeForElementExpression(node: Expression): Type {
|
||||
const arrayLiteral = <ArrayLiteralExpression>node.parent;
|
||||
const type = getContextualType(arrayLiteral);
|
||||
const type = getApparentTypeOfContextualType(arrayLiteral);
|
||||
if (type) {
|
||||
const index = indexOf(arrayLiteral.elements, node);
|
||||
return getTypeOfPropertyOfContextualType(type, "" + index)
|
||||
@@ -7090,7 +7096,7 @@ namespace ts {
|
||||
// In a contextually typed conditional expression, the true/false expressions are contextually typed by the same type.
|
||||
function getContextualTypeForConditionalOperand(node: Expression): Type {
|
||||
const conditional = <ConditionalExpression>node.parent;
|
||||
return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined;
|
||||
return node === conditional.whenTrue || node === conditional.whenFalse ? getApparentTypeOfContextualType(conditional) : undefined;
|
||||
}
|
||||
|
||||
function getContextualTypeForJsxExpression(expr: JsxExpression | JsxSpreadAttribute): Type {
|
||||
@@ -7115,12 +7121,22 @@ namespace ts {
|
||||
|
||||
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
|
||||
// be "pushed" onto a node using the contextualType property.
|
||||
function getContextualType(node: Expression): Type {
|
||||
const type = getContextualTypeWorker(node);
|
||||
function getApparentTypeOfContextualType(node: Expression): Type {
|
||||
const type = getContextualType(node);
|
||||
return type && getApparentType(type);
|
||||
}
|
||||
|
||||
function getContextualTypeWorker(node: Expression): Type {
|
||||
/**
|
||||
* Woah! Do you really want to use this function?
|
||||
*
|
||||
* Unless you're trying to get the *non-apparent* type for a value-literal type,
|
||||
* you probably meant to use 'getApparentTypeOfContextualType'.
|
||||
* Otherwise this is slightly less useful.
|
||||
*
|
||||
* @param node the expression whose contextual type will be returned.
|
||||
* @returns the contextual type of an expression.
|
||||
*/
|
||||
function getContextualType(node: Expression): Type {
|
||||
if (isInsideWithStatementBody(node)) {
|
||||
// We cannot answer semantic questions within a with block, do not proceed any further
|
||||
return undefined;
|
||||
@@ -7159,7 +7175,7 @@ namespace ts {
|
||||
Debug.assert(parent.parent.kind === SyntaxKind.TemplateExpression);
|
||||
return getContextualTypeForSubstitutionExpression(<TemplateExpression>parent.parent, node);
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return getContextualType(<ParenthesizedExpression>parent);
|
||||
return getApparentTypeOfContextualType(<ParenthesizedExpression>parent);
|
||||
case SyntaxKind.JsxExpression:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
return getContextualTypeForJsxExpression(<JsxExpression>parent);
|
||||
@@ -7199,7 +7215,7 @@ namespace ts {
|
||||
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
|
||||
const type = isObjectLiteralMethod(node)
|
||||
? getContextualTypeForObjectLiteralMethod(node)
|
||||
: getContextualType(node);
|
||||
: getApparentTypeOfContextualType(node);
|
||||
if (!type) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -7329,7 +7345,7 @@ namespace ts {
|
||||
type.pattern = node;
|
||||
return type;
|
||||
}
|
||||
const contextualType = getContextualType(node);
|
||||
const contextualType = getApparentTypeOfContextualType(node);
|
||||
if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
|
||||
const pattern = contextualType.pattern;
|
||||
// If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
|
||||
@@ -7421,7 +7437,7 @@ namespace ts {
|
||||
|
||||
const propertiesTable: SymbolTable = {};
|
||||
const propertiesArray: Symbol[] = [];
|
||||
const contextualType = getContextualType(node);
|
||||
const contextualType = getApparentTypeOfContextualType(node);
|
||||
const contextualTypeHasPattern = contextualType && contextualType.pattern &&
|
||||
(contextualType.pattern.kind === SyntaxKind.ObjectBindingPattern || contextualType.pattern.kind === SyntaxKind.ObjectLiteralExpression);
|
||||
let typeFlags: TypeFlags = 0;
|
||||
@@ -9422,7 +9438,12 @@ namespace ts {
|
||||
const targetType = getTypeFromTypeNode(node.type);
|
||||
if (produceDiagnostics && targetType !== unknownType) {
|
||||
const widenedType = getWidenedType(exprType);
|
||||
if (!(isTypeAssignableTo(targetType, widenedType))) {
|
||||
|
||||
// Permit 'number[] | "foo"' to be asserted to 'string'.
|
||||
const bothAreStringLike =
|
||||
someConstituentTypeHasKind(targetType, TypeFlags.StringLike) &&
|
||||
someConstituentTypeHasKind(widenedType, TypeFlags.StringLike);
|
||||
if (!bothAreStringLike && !(isTypeAssignableTo(targetType, widenedType))) {
|
||||
checkTypeAssignableTo(exprType, targetType, node, Diagnostics.Neither_type_0_nor_type_1_is_assignable_to_the_other);
|
||||
}
|
||||
}
|
||||
@@ -10252,6 +10273,10 @@ namespace ts {
|
||||
case SyntaxKind.ExclamationEqualsToken:
|
||||
case SyntaxKind.EqualsEqualsEqualsToken:
|
||||
case SyntaxKind.ExclamationEqualsEqualsToken:
|
||||
// Permit 'number[] | "foo"' to be asserted to 'string'.
|
||||
if (someConstituentTypeHasKind(leftType, TypeFlags.StringLike) && someConstituentTypeHasKind(rightType, TypeFlags.StringLike)) {
|
||||
return booleanType;
|
||||
}
|
||||
if (!isTypeAssignableTo(leftType, rightType) && !isTypeAssignableTo(rightType, leftType)) {
|
||||
reportOperatorError();
|
||||
}
|
||||
@@ -10390,6 +10415,15 @@ namespace ts {
|
||||
return getUnionType([type1, type2]);
|
||||
}
|
||||
|
||||
function checkStringLiteralExpression(node: StringLiteral): Type {
|
||||
const contextualType = getContextualType(node);
|
||||
if (contextualType && contextualTypeIsStringLiteralType(contextualType)) {
|
||||
return getStringLiteralType(node);
|
||||
}
|
||||
|
||||
return stringType;
|
||||
}
|
||||
|
||||
function checkTemplateExpression(node: TemplateExpression): Type {
|
||||
// We just want to check each expressions, but we are unconcerned with
|
||||
// the type of each expression, as any value may be coerced into a string.
|
||||
@@ -10449,7 +10483,7 @@ namespace ts {
|
||||
if (isInferentialContext(contextualMapper)) {
|
||||
const signature = getSingleCallSignature(type);
|
||||
if (signature && signature.typeParameters) {
|
||||
const contextualType = getContextualType(<Expression>node);
|
||||
const contextualType = getApparentTypeOfContextualType(<Expression>node);
|
||||
if (contextualType) {
|
||||
const contextualSignature = getSingleCallSignature(contextualType);
|
||||
if (contextualSignature && !contextualSignature.typeParameters) {
|
||||
@@ -10520,6 +10554,7 @@ namespace ts {
|
||||
case SyntaxKind.TemplateExpression:
|
||||
return checkTemplateExpression(<TemplateExpression>node);
|
||||
case SyntaxKind.StringLiteral:
|
||||
return checkStringLiteralExpression(<StringLiteral>node);
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
return stringType;
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
@@ -12714,6 +12749,7 @@ namespace ts {
|
||||
let hasDuplicateDefaultClause = false;
|
||||
|
||||
const expressionType = checkExpression(node.expression);
|
||||
const expressionTypeIsStringLike = someConstituentTypeHasKind(expressionType, TypeFlags.StringLike);
|
||||
forEach(node.caseBlock.clauses, clause => {
|
||||
// Grammar check for duplicate default clauses, skip if we already report duplicate default clause
|
||||
if (clause.kind === SyntaxKind.DefaultClause && !hasDuplicateDefaultClause) {
|
||||
@@ -12734,6 +12770,12 @@ namespace ts {
|
||||
// TypeScript 1.0 spec (April 2014):5.9
|
||||
// In a 'switch' statement, each 'case' expression must be of a type that is assignable to or from the type of the 'switch' expression.
|
||||
const caseType = checkExpression(caseClause.expression);
|
||||
|
||||
// Permit 'number[] | "foo"' to be asserted to 'string'.
|
||||
if (expressionTypeIsStringLike && someConstituentTypeHasKind(caseType, TypeFlags.StringLike)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isTypeAssignableTo(expressionType, caseType)) {
|
||||
// check 'expressionType isAssignableTo caseType' failed, try the reversed check and report errors if it fails
|
||||
checkTypeAssignableTo(caseType, expressionType, caseClause.expression, /*headMessage*/ undefined);
|
||||
@@ -14089,8 +14131,12 @@ namespace ts {
|
||||
if (!(links.flags & NodeCheckFlags.TypeChecked)) {
|
||||
// Check whether the file has declared it is the default lib,
|
||||
// and whether the user has specifically chosen to avoid checking it.
|
||||
if (node.isDefaultLib && compilerOptions.skipDefaultLibCheck) {
|
||||
return;
|
||||
if (compilerOptions.skipDefaultLibCheck) {
|
||||
// If the user specified '--noLib' and a file has a '/// <reference no-default-lib="true"/>',
|
||||
// then we should treat that file as a default lib.
|
||||
if (node.hasNoDefaultLib) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Grammar checking
|
||||
@@ -14959,10 +15005,20 @@ namespace ts {
|
||||
getTypeReferenceSerializationKind,
|
||||
isOptionalParameter,
|
||||
moduleExportsSomeValue,
|
||||
isArgumentsLocalBinding
|
||||
isArgumentsLocalBinding,
|
||||
getExternalModuleFileFromDeclaration
|
||||
};
|
||||
}
|
||||
|
||||
function getExternalModuleFileFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration): SourceFile {
|
||||
const specifier = getExternalModuleName(declaration);
|
||||
const moduleSymbol = getSymbolAtLocation(specifier);
|
||||
if (!moduleSymbol) {
|
||||
return undefined;
|
||||
}
|
||||
return getDeclarationOfKind(moduleSymbol, SyntaxKind.SourceFile) as SourceFile;
|
||||
}
|
||||
|
||||
function initializeTypeChecker() {
|
||||
// Bind all source files and propagate errors
|
||||
forEach(host.getSourceFiles(), file => {
|
||||
|
||||
@@ -58,8 +58,9 @@ namespace ts {
|
||||
let errorNameNode: DeclarationName;
|
||||
const emitJsDocComments = compilerOptions.removeComments ? function (declaration: Node) { } : writeJsDocComments;
|
||||
const emit = compilerOptions.stripInternal ? stripInternal : emitNode;
|
||||
let noDeclare = !root;
|
||||
|
||||
const moduleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = [];
|
||||
let moduleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = [];
|
||||
let asynchronousSubModuleDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[];
|
||||
|
||||
// Contains the reference paths that needs to go in the declaration file.
|
||||
@@ -107,15 +108,16 @@ namespace ts {
|
||||
else {
|
||||
// Emit references corresponding to this file
|
||||
const emittedReferencedFiles: SourceFile[] = [];
|
||||
let prevModuleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = [];
|
||||
forEach(host.getSourceFiles(), sourceFile => {
|
||||
if (!isExternalModuleOrDeclarationFile(sourceFile)) {
|
||||
if (!isDeclarationFile(sourceFile)) {
|
||||
// Check what references need to be added
|
||||
if (!compilerOptions.noResolve) {
|
||||
forEach(sourceFile.referencedFiles, fileReference => {
|
||||
const referencedFile = tryResolveScriptReference(host, sourceFile, fileReference);
|
||||
|
||||
// If the reference file is a declaration file or an external module, emit that reference
|
||||
if (referencedFile && (isExternalModuleOrDeclarationFile(referencedFile) &&
|
||||
// If the reference file is a declaration file, emit that reference
|
||||
if (referencedFile && (isDeclarationFile(referencedFile) &&
|
||||
!contains(emittedReferencedFiles, referencedFile))) { // If the file reference was not already emitted
|
||||
|
||||
writeReferencePath(referencedFile);
|
||||
@@ -123,10 +125,43 @@ namespace ts {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!isExternalModuleOrDeclarationFile(sourceFile)) {
|
||||
noDeclare = false;
|
||||
emitSourceFile(sourceFile);
|
||||
}
|
||||
else if (isExternalModule(sourceFile)) {
|
||||
noDeclare = true;
|
||||
write(`declare module "${getResolvedExternalModuleName(host, sourceFile)}" {`);
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
emitSourceFile(sourceFile);
|
||||
decreaseIndent();
|
||||
write("}");
|
||||
writeLine();
|
||||
|
||||
// create asynchronous output for the importDeclarations
|
||||
if (moduleElementDeclarationEmitInfo.length) {
|
||||
const oldWriter = writer;
|
||||
forEach(moduleElementDeclarationEmitInfo, aliasEmitInfo => {
|
||||
if (aliasEmitInfo.isVisible && !aliasEmitInfo.asynchronousOutput) {
|
||||
Debug.assert(aliasEmitInfo.node.kind === SyntaxKind.ImportDeclaration);
|
||||
createAndSetNewTextWriterWithSymbolWriter();
|
||||
Debug.assert(aliasEmitInfo.indent === 1);
|
||||
increaseIndent();
|
||||
writeImportDeclaration(<ImportDeclaration>aliasEmitInfo.node);
|
||||
aliasEmitInfo.asynchronousOutput = writer.getText();
|
||||
decreaseIndent();
|
||||
}
|
||||
});
|
||||
setWriter(oldWriter);
|
||||
}
|
||||
prevModuleElementDeclarationEmitInfo = prevModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo);
|
||||
moduleElementDeclarationEmitInfo = [];
|
||||
}
|
||||
});
|
||||
moduleElementDeclarationEmitInfo = moduleElementDeclarationEmitInfo.concat(prevModuleElementDeclarationEmitInfo);
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -607,7 +642,7 @@ namespace ts {
|
||||
if (node.flags & NodeFlags.Default) {
|
||||
write("default ");
|
||||
}
|
||||
else if (node.kind !== SyntaxKind.InterfaceDeclaration) {
|
||||
else if (node.kind !== SyntaxKind.InterfaceDeclaration && !noDeclare) {
|
||||
write("declare ");
|
||||
}
|
||||
}
|
||||
@@ -702,11 +737,25 @@ namespace ts {
|
||||
}
|
||||
write(" from ");
|
||||
}
|
||||
writeTextOfNode(currentText, node.moduleSpecifier);
|
||||
emitExternalModuleSpecifier(node.moduleSpecifier);
|
||||
write(";");
|
||||
writer.writeLine();
|
||||
}
|
||||
|
||||
function emitExternalModuleSpecifier(moduleSpecifier: Expression) {
|
||||
if (moduleSpecifier.kind === SyntaxKind.StringLiteral && (!root) && (compilerOptions.out || compilerOptions.outFile)) {
|
||||
const moduleName = getExternalModuleNameFromDeclaration(host, resolver, moduleSpecifier.parent as (ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration));
|
||||
if (moduleName) {
|
||||
write("\"");
|
||||
write(moduleName);
|
||||
write("\"");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
writeTextOfNode(currentText, moduleSpecifier);
|
||||
}
|
||||
|
||||
function emitImportOrExportSpecifier(node: ImportOrExportSpecifier) {
|
||||
if (node.propertyName) {
|
||||
writeTextOfNode(currentText, node.propertyName);
|
||||
@@ -738,7 +787,7 @@ namespace ts {
|
||||
}
|
||||
if (node.moduleSpecifier) {
|
||||
write(" from ");
|
||||
writeTextOfNode(currentText, node.moduleSpecifier);
|
||||
emitExternalModuleSpecifier(node.moduleSpecifier);
|
||||
}
|
||||
write(";");
|
||||
writer.writeLine();
|
||||
|
||||
@@ -2310,7 +2310,6 @@
|
||||
"category": "Message",
|
||||
"code": 6078
|
||||
},
|
||||
|
||||
"Specify JSX code generation: 'preserve' or 'react'": {
|
||||
"category": "Message",
|
||||
"code": 6080
|
||||
@@ -2319,7 +2318,10 @@
|
||||
"category": "Message",
|
||||
"code": 6081
|
||||
},
|
||||
|
||||
"Only 'amd' and 'system' modules are supported alongside --{0}.": {
|
||||
"category": "Error",
|
||||
"code": 6082
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
|
||||
+81
-31
@@ -7,6 +7,18 @@ namespace ts {
|
||||
return isExternalModule(sourceFile) || isDeclarationFile(sourceFile);
|
||||
}
|
||||
|
||||
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<ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration>;
|
||||
|
||||
const enum Jump {
|
||||
@@ -332,19 +344,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
const newLine = host.getNewLine();
|
||||
const jsxDesugaring = host.getCompilerOptions().jsx !== JsxEmit.Preserve;
|
||||
const shouldEmitJsx = (s: SourceFile) => (s.languageVariant === LanguageVariant.JSX && !jsxDesugaring);
|
||||
const outFile = compilerOptions.outFile || compilerOptions.out;
|
||||
|
||||
const emitJavaScript = createFileEmitter();
|
||||
|
||||
if (targetSourceFile === undefined) {
|
||||
forEach(host.getSourceFiles(), sourceFile => {
|
||||
if (shouldEmitToOwnFile(sourceFile, compilerOptions)) {
|
||||
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, shouldEmitJsx(sourceFile) ? ".jsx" : ".js");
|
||||
emitFile(jsFilePath, sourceFile);
|
||||
}
|
||||
});
|
||||
|
||||
if (compilerOptions.outFile || compilerOptions.out) {
|
||||
emitFile(compilerOptions.outFile || compilerOptions.out);
|
||||
if (outFile) {
|
||||
emitFile(outFile);
|
||||
}
|
||||
else {
|
||||
forEach(host.getSourceFiles(), sourceFile => {
|
||||
if (shouldEmitToOwnFile(sourceFile, compilerOptions)) {
|
||||
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, shouldEmitJsx(sourceFile) ? ".jsx" : ".js");
|
||||
emitFile(jsFilePath, sourceFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -353,8 +367,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
const jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, host, shouldEmitJsx(targetSourceFile) ? ".jsx" : ".js");
|
||||
emitFile(jsFilePath, targetSourceFile);
|
||||
}
|
||||
else if (!isDeclarationFile(targetSourceFile) && (compilerOptions.outFile || compilerOptions.out)) {
|
||||
emitFile(compilerOptions.outFile || compilerOptions.out);
|
||||
else if (!isDeclarationFile(targetSourceFile) && outFile) {
|
||||
emitFile(outFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,10 +559,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
/** Sourcemap data that will get encoded */
|
||||
let sourceMapData: SourceMapData;
|
||||
|
||||
/** The root file passed to the emit function (if present) */
|
||||
let root: SourceFile;
|
||||
|
||||
/** If removeComments is true, no leading-comments needed to be emitted **/
|
||||
const emitLeadingCommentsOfPosition = compilerOptions.removeComments ? function (pos: number) { } : emitLeadingCommentsOfPositionWorker;
|
||||
|
||||
const moduleEmitDelegates: Map<(node: SourceFile) => void> = {
|
||||
const moduleEmitDelegates: Map<(node: SourceFile, emitRelativePathAsModuleName?: boolean) => void> = {
|
||||
[ModuleKind.ES6]: emitES6Module,
|
||||
[ModuleKind.AMD]: emitAMDModule,
|
||||
[ModuleKind.System]: emitSystemModule,
|
||||
@@ -556,9 +573,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
[ModuleKind.CommonJS]: emitCommonJSModule,
|
||||
};
|
||||
|
||||
const bundleEmitDelegates: Map<(node: SourceFile, emitRelativePathAsModuleName?: boolean) => void> = {
|
||||
[ModuleKind.ES6]() {},
|
||||
[ModuleKind.AMD]: emitAMDModule,
|
||||
[ModuleKind.System]: emitSystemModule,
|
||||
[ModuleKind.UMD]() {},
|
||||
[ModuleKind.CommonJS]() {},
|
||||
};
|
||||
|
||||
return doEmit;
|
||||
|
||||
function doEmit(jsFilePath: string, root?: SourceFile) {
|
||||
function doEmit(jsFilePath: string, rootFile?: SourceFile) {
|
||||
// reset the state
|
||||
writer.reset();
|
||||
currentSourceFile = undefined;
|
||||
@@ -586,6 +611,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
isEs6Module = false;
|
||||
renamedDependencies = undefined;
|
||||
isCurrentFileExternalModule = false;
|
||||
root = rootFile;
|
||||
|
||||
if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) {
|
||||
initializeEmitterWithSourceMaps(jsFilePath, root);
|
||||
@@ -596,8 +622,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
emitSourceFile(root);
|
||||
}
|
||||
else {
|
||||
if (modulekind) {
|
||||
forEach(host.getSourceFiles(), emitEmitHelpers);
|
||||
}
|
||||
forEach(host.getSourceFiles(), sourceFile => {
|
||||
if (!isExternalModuleOrDeclarationFile(sourceFile)) {
|
||||
if ((!isExternalModuleOrDeclarationFile(sourceFile)) || (modulekind && isExternalModule(sourceFile))) {
|
||||
emitSourceFile(sourceFile);
|
||||
}
|
||||
});
|
||||
@@ -2461,7 +2490,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
// let obj = { y };
|
||||
// }
|
||||
// Here we need to emit obj = { y : m.y } regardless of the output target.
|
||||
if (languageVersion < ScriptTarget.ES6 || isNamespaceExportReference(node.name)) {
|
||||
if (modulekind !== ModuleKind.ES6 || isNamespaceExportReference(node.name)) {
|
||||
// Emit identifier as an identifier
|
||||
write(": ");
|
||||
emit(node.name);
|
||||
@@ -7303,7 +7332,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
write("}"); // execute
|
||||
}
|
||||
|
||||
function emitSystemModule(node: SourceFile): void {
|
||||
function writeModuleName(node: SourceFile, emitRelativePathAsModuleName?: boolean): void {
|
||||
let moduleName = node.moduleName;
|
||||
if (moduleName || (emitRelativePathAsModuleName && (moduleName = getResolvedExternalModuleName(host, node)))) {
|
||||
write(`"${moduleName}", `);
|
||||
}
|
||||
}
|
||||
|
||||
function emitSystemModule(node: SourceFile, emitRelativePathAsModuleName?: boolean): void {
|
||||
collectExternalModuleInfo(node);
|
||||
// System modules has the following shape
|
||||
// System.register(['dep-1', ... 'dep-n'], function(exports) {/* module body function */})
|
||||
@@ -7318,16 +7354,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
exportFunctionForFile = makeUniqueName("exports");
|
||||
writeLine();
|
||||
write("System.register(");
|
||||
if (node.moduleName) {
|
||||
write(`"${node.moduleName}", `);
|
||||
}
|
||||
writeModuleName(node, emitRelativePathAsModuleName);
|
||||
write("[");
|
||||
|
||||
const groupIndices: Map<number> = {};
|
||||
const dependencyGroups: DependencyGroup[] = [];
|
||||
|
||||
for (let i = 0; i < externalImports.length; ++i) {
|
||||
const text = getExternalModuleNameText(externalImports[i]);
|
||||
let text = getExternalModuleNameText(externalImports[i]);
|
||||
if (hasProperty(groupIndices, text)) {
|
||||
// deduplicate/group entries in dependency list by the dependency name
|
||||
const groupIndex = groupIndices[text];
|
||||
@@ -7343,6 +7377,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
write(", ");
|
||||
}
|
||||
|
||||
if (emitRelativePathAsModuleName) {
|
||||
const name = getExternalModuleNameFromDeclaration(host, resolver, externalImports[i]);
|
||||
if (name) {
|
||||
text = `"${name}"`;
|
||||
}
|
||||
}
|
||||
write(text);
|
||||
}
|
||||
write(`], function(${exportFunctionForFile}) {`);
|
||||
@@ -7363,7 +7403,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
importAliasNames: string[];
|
||||
}
|
||||
|
||||
function getAMDDependencyNames(node: SourceFile, includeNonAmdDependencies: boolean): AMDDependencyNames {
|
||||
function getAMDDependencyNames(node: SourceFile, includeNonAmdDependencies: boolean, emitRelativePathAsModuleName?: boolean): AMDDependencyNames {
|
||||
// names of modules with corresponding parameter in the factory function
|
||||
const aliasedModuleNames: string[] = [];
|
||||
// names of modules with no corresponding parameters in factory function
|
||||
@@ -7385,7 +7425,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
|
||||
for (const importNode of externalImports) {
|
||||
// Find the name of the external module
|
||||
const externalModuleName = getExternalModuleNameText(importNode);
|
||||
let externalModuleName = getExternalModuleNameText(importNode);
|
||||
|
||||
if (emitRelativePathAsModuleName) {
|
||||
const name = getExternalModuleNameFromDeclaration(host, resolver, importNode);
|
||||
if (name) {
|
||||
externalModuleName = `"${name}"`;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the name of the module alias, if there is one
|
||||
const importAliasName = getLocalNameForExternalImport(importNode);
|
||||
@@ -7401,7 +7448,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
return { aliasedModuleNames, unaliasedModuleNames, importAliasNames };
|
||||
}
|
||||
|
||||
function emitAMDDependencies(node: SourceFile, includeNonAmdDependencies: boolean) {
|
||||
function emitAMDDependencies(node: SourceFile, includeNonAmdDependencies: boolean, emitRelativePathAsModuleName?: boolean) {
|
||||
// An AMD define function has the following shape:
|
||||
// define(id?, dependencies?, factory);
|
||||
//
|
||||
@@ -7414,7 +7461,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
// `import "module"` or `<amd-dependency path= "a.css" />`
|
||||
// we need to add modules without alias names to the end of the dependencies list
|
||||
|
||||
const dependencyNames = getAMDDependencyNames(node, includeNonAmdDependencies);
|
||||
const dependencyNames = getAMDDependencyNames(node, includeNonAmdDependencies, emitRelativePathAsModuleName);
|
||||
emitAMDDependencyList(dependencyNames);
|
||||
write(", ");
|
||||
emitAMDFactoryHeader(dependencyNames);
|
||||
@@ -7442,16 +7489,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
write(") {");
|
||||
}
|
||||
|
||||
function emitAMDModule(node: SourceFile) {
|
||||
function emitAMDModule(node: SourceFile, emitRelativePathAsModuleName?: boolean) {
|
||||
emitEmitHelpers(node);
|
||||
collectExternalModuleInfo(node);
|
||||
|
||||
writeLine();
|
||||
write("define(");
|
||||
if (node.moduleName) {
|
||||
write("\"" + node.moduleName + "\", ");
|
||||
}
|
||||
emitAMDDependencies(node, /*includeNonAmdDependencies*/ true);
|
||||
writeModuleName(node, emitRelativePathAsModuleName);
|
||||
emitAMDDependencies(node, /*includeNonAmdDependencies*/ true, emitRelativePathAsModuleName);
|
||||
increaseIndent();
|
||||
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true);
|
||||
emitExportStarHelper();
|
||||
@@ -7700,8 +7745,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
emitDetachedCommentsAndUpdateCommentsInfo(node);
|
||||
|
||||
if (isExternalModule(node) || compilerOptions.isolatedModules) {
|
||||
const emitModule = moduleEmitDelegates[modulekind] || moduleEmitDelegates[ModuleKind.CommonJS];
|
||||
emitModule(node);
|
||||
if (root || (!isExternalModule(node) && compilerOptions.isolatedModules)) {
|
||||
const emitModule = moduleEmitDelegates[modulekind] || moduleEmitDelegates[ModuleKind.CommonJS];
|
||||
emitModule(node);
|
||||
}
|
||||
else {
|
||||
bundleEmitDelegates[modulekind](node, /*emitRelativePathAsModuleName*/true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// emit prologue directives prior to __extends
|
||||
|
||||
@@ -1992,9 +1992,7 @@ namespace ts {
|
||||
|
||||
function parseParameterType(): TypeNode {
|
||||
if (parseOptional(SyntaxKind.ColonToken)) {
|
||||
return token === SyntaxKind.StringLiteral
|
||||
? <StringLiteral>parseLiteralNode(/*internName*/ true)
|
||||
: parseType();
|
||||
return parseType();
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@@ -2382,6 +2380,8 @@ namespace ts {
|
||||
// If these are followed by a dot, then parse these out as a dotted type reference instead.
|
||||
const node = tryParse(parseKeywordAndNoDot);
|
||||
return node || parseTypeReferenceOrTypePredicate();
|
||||
case SyntaxKind.StringLiteral:
|
||||
return <StringLiteral>parseLiteralNode(/*internName*/ true);
|
||||
case SyntaxKind.VoidKeyword:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
return parseTokenNode<TypeNode>();
|
||||
@@ -2412,6 +2412,7 @@ namespace ts {
|
||||
case SyntaxKind.OpenBracketToken:
|
||||
case SyntaxKind.LessThanToken:
|
||||
case SyntaxKind.NewKeyword:
|
||||
case SyntaxKind.StringLiteral:
|
||||
return true;
|
||||
case SyntaxKind.OpenParenToken:
|
||||
// Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
|
||||
@@ -5629,6 +5630,7 @@ namespace ts {
|
||||
return parseTokenNode<JSDocType>();
|
||||
}
|
||||
|
||||
// TODO (drosen): Parse string literal types in JSDoc as well.
|
||||
return parseJSDocTypeReference();
|
||||
}
|
||||
|
||||
|
||||
+10
-3
@@ -833,7 +833,6 @@ namespace ts {
|
||||
processImportedModules(file, basePath);
|
||||
|
||||
if (isDefaultLib) {
|
||||
file.isDefaultLib = true;
|
||||
files.unshift(file);
|
||||
}
|
||||
else {
|
||||
@@ -923,6 +922,10 @@ namespace ts {
|
||||
}
|
||||
});
|
||||
|
||||
if (!commonPathComponents) { // Can happen when all input files are .d.ts files
|
||||
return currentDirectory;
|
||||
}
|
||||
|
||||
return getNormalizedPathFromPathComponents(commonPathComponents);
|
||||
}
|
||||
|
||||
@@ -1024,12 +1027,16 @@ namespace ts {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_modules_into_es2015_when_targeting_ES5_or_lower));
|
||||
}
|
||||
|
||||
// Cannot specify module gen that isn't amd or system with --out
|
||||
if (outFile && options.module && !(options.module === ModuleKind.AMD || options.module === ModuleKind.System)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile"));
|
||||
}
|
||||
|
||||
// there has to be common source directory if user specified --outdir || --sourceRoot
|
||||
// if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted
|
||||
if (options.outDir || // there is --outDir specified
|
||||
options.sourceRoot || // there is --sourceRoot specified
|
||||
(options.mapRoot && // there is --mapRoot specified and there would be multiple js files generated
|
||||
(!outFile || firstExternalModuleSourceFile !== undefined))) {
|
||||
options.mapRoot) { // there is --mapRoot specified
|
||||
|
||||
if (options.rootDir && checkSourceFilesBelongToPath(files, options.rootDir)) {
|
||||
// If a rootDir is specified and is valid use it as the commonSourceDirectory
|
||||
|
||||
@@ -701,7 +701,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Note that a StringLiteral AST node is both an Expression and a TypeNode. The latter is
|
||||
// because string literals can appear in the type annotation of a parameter node.
|
||||
// because string literals can appear in type annotations as well.
|
||||
export interface StringLiteral extends LiteralExpression, TypeNode {
|
||||
_stringLiteralBrand: any;
|
||||
}
|
||||
@@ -1285,7 +1285,6 @@ namespace ts {
|
||||
// The first node that causes this file to be an external module
|
||||
/* @internal */ externalModuleIndicator: Node;
|
||||
|
||||
/* @internal */ isDefaultLib: boolean;
|
||||
/* @internal */ identifiers: Map<string>;
|
||||
/* @internal */ nodeCount: number;
|
||||
/* @internal */ identifierCount: number;
|
||||
@@ -1623,6 +1622,7 @@ namespace ts {
|
||||
isOptionalParameter(node: ParameterDeclaration): boolean;
|
||||
moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean;
|
||||
isArgumentsLocalBinding(node: Identifier): boolean;
|
||||
getExternalModuleFileFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration): SourceFile;
|
||||
}
|
||||
|
||||
export const enum SymbolFlags {
|
||||
|
||||
@@ -1660,6 +1660,7 @@ namespace ts {
|
||||
"\u0085": "\\u0085" // nextLine
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Based heavily on the abstract 'Quote'/'QuoteJSONString' operation from ECMA-262 (24.3.2.2),
|
||||
* but augmented for a few select characters (e.g. lineSeparator, paragraphSeparator, nextLine)
|
||||
@@ -1800,6 +1801,15 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a local path to a path which is absolute to the base of the emit
|
||||
*/
|
||||
export function getExternalModuleNameFromPath(host: EmitHost, fileName: string): string {
|
||||
const dir = host.getCurrentDirectory();
|
||||
const relativePath = getRelativePathToDirectoryOrUrl(dir, fileName, dir, f => host.getCanonicalFileName(f), /*isAbsolutePathAnUrl*/ false);
|
||||
return removeFileExtension(relativePath);
|
||||
}
|
||||
|
||||
export function getOwnEmitOutputFilePath(sourceFile: SourceFile, host: EmitHost, extension: string) {
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
let emitOutputFilePathWithoutExtension: string;
|
||||
|
||||
@@ -1169,7 +1169,7 @@ namespace Harness {
|
||||
}
|
||||
else if (isTS(file.unitName)) {
|
||||
const declFile = findResultCodeFile(file.unitName);
|
||||
if (!findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) {
|
||||
if (declFile && !findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) {
|
||||
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,7 +306,10 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
const outputDtsFileName = emitOutputFilePathWithoutExtension + ".d.ts";
|
||||
allInputFiles.unshift(findOutpuDtsFile(outputDtsFileName));
|
||||
const file = findOutpuDtsFile(outputDtsFileName);
|
||||
if (file) {
|
||||
allInputFiles.unshift(file);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile || compilerOptions.out) + ".d.ts";
|
||||
@@ -346,7 +349,7 @@ class ProjectRunner extends RunnerBase {
|
||||
const inputFiles = ts.map(ts.filter(compilerResult.program.getSourceFiles(),
|
||||
sourceFile => sourceFile.fileName !== "lib.d.ts"),
|
||||
sourceFile => {
|
||||
return { unitName: sourceFile.fileName, content: sourceFile.text };
|
||||
return { unitName: RunnerBase.removeFullPaths(sourceFile.fileName), content: sourceFile.text };
|
||||
});
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors);
|
||||
@@ -387,7 +390,7 @@ class ProjectRunner extends RunnerBase {
|
||||
return resolutionInfo;
|
||||
}
|
||||
|
||||
it(name + ": " + moduleNameToString(moduleKind) , () => {
|
||||
it(name + ": " + moduleNameToString(moduleKind), () => {
|
||||
// Compile using node
|
||||
compilerResult = batchCompilerProjectTestCase(moduleKind);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user