mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
feedback form pr
This commit is contained in:
@@ -14867,7 +14867,8 @@ namespace ts {
|
||||
collectLinkedAliases,
|
||||
getReferencedValueDeclaration,
|
||||
getTypeReferenceSerializationKind,
|
||||
isOptionalParameter
|
||||
isOptionalParameter,
|
||||
getSymbolAtLocation
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -729,17 +729,30 @@ namespace ts {
|
||||
}
|
||||
write(" from ");
|
||||
}
|
||||
let match: RegExpMatchArray;
|
||||
if ((!root) && node.moduleSpecifier.kind === SyntaxKind.StringLiteral && (match = getTextOfNode(node.moduleSpecifier).match(/('|")(\.\/|\.\.\/)/))) {
|
||||
write(makeModulePathSemiAbsolute(host, currentSourceFile, getTextOfNode(node.moduleSpecifier)));
|
||||
}
|
||||
else {
|
||||
writeTextOfNode(currentSourceFile, node.moduleSpecifier);
|
||||
}
|
||||
emitExternalModuleSpecifier(node.moduleSpecifier);
|
||||
write(";");
|
||||
writer.writeLine();
|
||||
}
|
||||
|
||||
function emitExternalModuleSpecifier(moduleSpecifier: Expression) {
|
||||
Debug.assert(moduleSpecifier.kind === SyntaxKind.StringLiteral);
|
||||
|
||||
if ((!root) && (compilerOptions.out || compilerOptions.outFile)) {
|
||||
let moduleSymbol = resolver.getSymbolAtLocation(moduleSpecifier);
|
||||
if (moduleSymbol && moduleSymbol.valueDeclaration &&
|
||||
moduleSymbol.valueDeclaration.kind === SyntaxKind.SourceFile &&
|
||||
!isDeclarationFile(<SourceFile>moduleSymbol.valueDeclaration)) {
|
||||
let nonRelativeModuleName = getExternalModuleNameFromPath(host, (moduleSymbol.valueDeclaration as SourceFile).fileName);
|
||||
write("\"");
|
||||
write(nonRelativeModuleName);
|
||||
write("\"");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
writeTextOfNode(currentSourceFile, moduleSpecifier);
|
||||
}
|
||||
|
||||
function emitImportOrExportSpecifier(node: ImportOrExportSpecifier) {
|
||||
if (node.propertyName) {
|
||||
writeTextOfNode(currentSourceFile, node.propertyName);
|
||||
@@ -771,13 +784,7 @@ namespace ts {
|
||||
}
|
||||
if (node.moduleSpecifier) {
|
||||
write(" from ");
|
||||
let match: RegExpMatchArray;
|
||||
if ((!root) && node.moduleSpecifier.kind === SyntaxKind.StringLiteral && (match = getTextOfNode(node.moduleSpecifier).match(/('|")(\.\/|\.\.\/)/))) {
|
||||
write(makeModulePathSemiAbsolute(host, currentSourceFile, getTextOfNode(node.moduleSpecifier)));
|
||||
}
|
||||
else {
|
||||
writeTextOfNode(currentSourceFile, node.moduleSpecifier);
|
||||
}
|
||||
emitExternalModuleSpecifier(node.moduleSpecifier);
|
||||
}
|
||||
write(";");
|
||||
writer.writeLine();
|
||||
|
||||
+15
-3
@@ -497,7 +497,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
function emitConcatenatedModule(sourceFile: SourceFile): void {
|
||||
currentSourceFile = sourceFile;
|
||||
exportFunctionForFile = undefined;
|
||||
let canonicalName = resolveToSemiabsolutePath(host, sourceFile.fileName);
|
||||
let canonicalName = getExternalModuleNameFromPath(host, sourceFile.fileName);
|
||||
sourceFile.moduleName = sourceFile.moduleName || canonicalName;
|
||||
emit(sourceFile);
|
||||
}
|
||||
@@ -6766,7 +6766,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
}
|
||||
|
||||
if (resolvePath) {
|
||||
text = makeModulePathSemiAbsolute(host, currentSourceFile, text);
|
||||
text = `"${lookupSpecifierName(externalImports[i])}"`;
|
||||
}
|
||||
write(text);
|
||||
}
|
||||
@@ -6782,6 +6782,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
write("});");
|
||||
}
|
||||
|
||||
function lookupSpecifierName(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration): string {
|
||||
let specifier: Node;
|
||||
if (declaration.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||
specifier = (declaration as ImportEqualsDeclaration).moduleReference;
|
||||
}
|
||||
else {
|
||||
specifier = (declaration as ImportDeclaration|ExportDeclaration).moduleSpecifier;
|
||||
}
|
||||
let moduleSymbol = resolver.getSymbolAtLocation(specifier);
|
||||
return getExternalModuleNameFromPath(host, (moduleSymbol.valueDeclaration as SourceFile).fileName);
|
||||
}
|
||||
|
||||
interface AMDDependencyNames {
|
||||
aliasedModuleNames: string[];
|
||||
unaliasedModuleNames: string[];
|
||||
@@ -6813,7 +6825,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
let externalModuleName = getExternalModuleNameText(importNode);
|
||||
|
||||
if (resolvePath) {
|
||||
externalModuleName = makeModulePathSemiAbsolute(host, currentSourceFile, externalModuleName);
|
||||
externalModuleName = `"${lookupSpecifierName(importNode)}"`;
|
||||
}
|
||||
|
||||
// Find the name of the module alias, if there is one
|
||||
|
||||
+23
-29
@@ -372,29 +372,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
if (options.rootDir && checkSourceFilesBelongToPath(files, options.rootDir)) {
|
||||
// If a rootDir is specified and is valid use it as the commonSourceDirectory
|
||||
commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, host.getCurrentDirectory());
|
||||
}
|
||||
else {
|
||||
// Compute the commonSourceDirectory from the input files
|
||||
commonSourceDirectory = computeCommonSourceDirectory(files);
|
||||
}
|
||||
|
||||
if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== directorySeparator) {
|
||||
// Make sure directory path ends with directory separator so this string can directly
|
||||
// used to replace with "" to get the relative path of the source file and the relative path doesn't
|
||||
// start with / making it rooted path
|
||||
commonSourceDirectory += directorySeparator;
|
||||
}
|
||||
}
|
||||
|
||||
verifyCompilerOptions();
|
||||
|
||||
// unconditionally set oldProgram to undefined to prevent it from being captured in closure
|
||||
@@ -540,12 +517,6 @@ namespace ts {
|
||||
getSourceFiles: program.getSourceFiles,
|
||||
writeFile: writeFileCallback || (
|
||||
(fileName, data, writeByteOrderMark, onError) => host.writeFile(fileName, data, writeByteOrderMark, onError)),
|
||||
resolveModuleName: (name: string, containingFile?: string) => {
|
||||
let resolvedModule = resolveModuleNamesWorker([name], containingFile || "dummy.ts")[0];
|
||||
if (!resolvedModule)
|
||||
return;
|
||||
return resolvedModule.resolvedFileName;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1063,6 +1034,29 @@ namespace ts {
|
||||
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
|
||||
|
||||
if (options.rootDir && checkSourceFilesBelongToPath(files, options.rootDir)) {
|
||||
// If a rootDir is specified and is valid use it as the commonSourceDirectory
|
||||
commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, host.getCurrentDirectory());
|
||||
}
|
||||
else {
|
||||
// Compute the commonSourceDirectory from the input files
|
||||
commonSourceDirectory = computeCommonSourceDirectory(files);
|
||||
}
|
||||
|
||||
if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== directorySeparator) {
|
||||
// Make sure directory path ends with directory separator so this string can directly
|
||||
// used to replace with "" to get the relative path of the source file and the relative path doesn't
|
||||
// start with / making it rooted path
|
||||
commonSourceDirectory += directorySeparator;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.noEmit) {
|
||||
if (options.out) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", "out"));
|
||||
|
||||
@@ -1611,6 +1611,7 @@ namespace ts {
|
||||
getReferencedValueDeclaration(reference: Identifier): Declaration;
|
||||
getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind;
|
||||
isOptionalParameter(node: ParameterDeclaration): boolean;
|
||||
getSymbolAtLocation(node: Node): Symbol;
|
||||
}
|
||||
|
||||
export const enum SymbolFlags {
|
||||
|
||||
+12
-62
@@ -40,7 +40,6 @@ namespace ts {
|
||||
getNewLine(): string;
|
||||
|
||||
writeFile: WriteFileCallback;
|
||||
resolveModuleName(path: string, containingFile?: string): string;
|
||||
}
|
||||
|
||||
// Pool writers to avoid needing to allocate them for every symbol we write.
|
||||
@@ -1608,7 +1607,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
let baseCharsMap: Map<string> = {
|
||||
// This consists of the first 19 unprintable ASCII characters, canonical escapes, lineSeparator,
|
||||
// paragraphSeparator, and nextLine. The latter three are just desirable to suppress new lines in
|
||||
// the language service. These characters should be escaped when printing, and if any characters are added,
|
||||
// the map below must be updated. Note that this regexp *does not* include the 'delete' character.
|
||||
// There is no reason for this other than that JSON.stringify does not handle it either.
|
||||
let escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
|
||||
let escapedCharsMap: Map<string> = {
|
||||
"\0": "\\0",
|
||||
"\t": "\\t",
|
||||
"\v": "\\v",
|
||||
@@ -1617,25 +1622,12 @@ namespace ts {
|
||||
"\r": "\\r",
|
||||
"\n": "\\n",
|
||||
"\\": "\\\\",
|
||||
"\"": "\\\"",
|
||||
"\u2028": "\\u2028", // lineSeparator
|
||||
"\u2029": "\\u2029", // paragraphSeparator
|
||||
"\u0085": "\\u0085" // nextLine
|
||||
};
|
||||
|
||||
// This consists of the first 19 unprintable ASCII characters, canonical escapes, lineSeparator,
|
||||
// paragraphSeparator, and nextLine. The latter three are just desirable to suppress new lines in
|
||||
// the language service. These characters should be escaped when printing, and if any characters are added,
|
||||
// the map below must be updated. Note that this regexp *does not* include the 'delete' character.
|
||||
// There is no reason for this other than that JSON.stringify does not handle it either.
|
||||
let escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
|
||||
let escapedCharsMap: Map<string> = extend(baseCharsMap, {
|
||||
"\"": "\\\""
|
||||
});
|
||||
|
||||
let singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
|
||||
let singleQuoteEscapedCharsMap: Map<string> = extend(baseCharsMap, {
|
||||
"\'": "\\\'"
|
||||
});
|
||||
|
||||
/**
|
||||
* Based heavily on the abstract 'Quote'/'QuoteJSONString' operation from ECMA-262 (24.3.2.2),
|
||||
@@ -1643,46 +1635,15 @@ namespace ts {
|
||||
* Note that this doesn't actually wrap the input in double quotes.
|
||||
*/
|
||||
export function escapeString(s: string): string {
|
||||
return escapeStringByQuote(s, QuotationMark.Double);
|
||||
}
|
||||
|
||||
export const enum QuotationMark {
|
||||
Double,
|
||||
Single
|
||||
}
|
||||
|
||||
export var QuotationMarkLookup: Map<string> = {
|
||||
[QuotationMark.Double]: "\"",
|
||||
[QuotationMark.Single]: "'",
|
||||
"\"": QuotationMark.Double.toString(),
|
||||
"'": QuotationMark.Single.toString(),
|
||||
};
|
||||
|
||||
/**
|
||||
* A generalization of the escape function described by escapeString configuable to handle
|
||||
* either single quotes or double quotes
|
||||
*/
|
||||
export function escapeStringByQuote(s: string, quotationMark: QuotationMark): string {
|
||||
let regex = quotationMark === QuotationMark.Single ? singleQuoteEscapedCharsRegExp : escapedCharsRegExp;
|
||||
let replacementMap = quotationMark === QuotationMark.Single ? singleQuoteEscapedCharsMap : escapedCharsMap;
|
||||
|
||||
s = regex.test(s) ? s.replace(regex, getReplacement) : s;
|
||||
s = escapedCharsRegExp.test(s) ? s.replace(escapedCharsRegExp, getReplacement) : s;
|
||||
|
||||
return s;
|
||||
|
||||
function getReplacement(c: string) {
|
||||
return replacementMap[c] || get16BitUnicodeEscapeSequence(c.charCodeAt(0));
|
||||
return escapedCharsMap[c] || get16BitUnicodeEscapeSequence(c.charCodeAt(0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quotes a given string akin to the abstract Quote operation from ECMA-262 (24.3.2.2)
|
||||
* with the specified quotation mark
|
||||
*/
|
||||
export function quoteString(s: string, quotemark: QuotationMark): string {
|
||||
return QuotationMarkLookup[quotemark] + escapeStringByQuote(s, quotemark) + QuotationMarkLookup[quotemark];
|
||||
}
|
||||
|
||||
export function isIntrinsicJsxName(name: string) {
|
||||
let ch = name.substr(0, 1);
|
||||
return ch.toLowerCase() === ch;
|
||||
@@ -1796,23 +1757,12 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function makeModulePathSemiAbsolute(host: EmitHost, currentSourceFile: SourceFile, externalModuleName: string): string {
|
||||
let quotationMark = externalModuleName.charAt(0);
|
||||
let unquotedModuleName = externalModuleName.substring(1, externalModuleName.length - 1);
|
||||
let resolvedFileName = host.resolveModuleName(unquotedModuleName, currentSourceFile.fileName);
|
||||
if (resolvedFileName) {
|
||||
let semiAbsoluteName = resolveToSemiabsolutePath(host, resolvedFileName);
|
||||
externalModuleName = quoteString(semiAbsoluteName, parseInt(QuotationMarkLookup[quotationMark]));
|
||||
}
|
||||
return externalModuleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a local path to a path which is absolute to the base of the emit
|
||||
*/
|
||||
export function resolveToSemiabsolutePath(host: EmitHost, path: string): string {
|
||||
export function getExternalModuleNameFromPath(host: EmitHost, fileName: string): string {
|
||||
let dir = host.getCurrentDirectory();
|
||||
let relativePath = getRelativePathToDirectoryOrUrl(dir, path, dir, f => host.getCanonicalFileName(f), /*isAbsolutePathAnUrl*/ false);
|
||||
let relativePath = getRelativePathToDirectoryOrUrl(dir, fileName, dir, f => host.getCanonicalFileName(f), /*isAbsolutePathAnUrl*/ false);
|
||||
return removeFileExtension(relativePath);
|
||||
}
|
||||
|
||||
|
||||
@@ -366,7 +366,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