From 7a4e995f018632044133b7c50f157276aac493bd Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 20 Oct 2015 15:14:18 -0700 Subject: [PATCH] feedback form pr --- Jakefile.js | 3 +- src/compiler/declarationEmitter.ts | 4 +- src/compiler/emitter.ts | 4 +- src/compiler/utilities.ts | 96 +++++++++++++++++------------- 4 files changed, 61 insertions(+), 46 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index 505ccf99384..be80edb0a67 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -247,7 +247,8 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOu if (!noOutFile) { options += " --out " + outFile; - } else { + } + else { options += " --module commonjs" } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index c3d611f131c..fb1ccf5714a 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -731,7 +731,7 @@ namespace ts { } let match: RegExpMatchArray; if ((!root) && node.moduleSpecifier.kind === SyntaxKind.StringLiteral && (match = getTextOfNode(node.moduleSpecifier).match(/('|")(\.\/|\.\.\/)/))) { - write(makeModulePathSemiabsolute(host, currentSourceFile, getTextOfNode(node.moduleSpecifier))); + write(makeModulePathSemiAbsolute(host, currentSourceFile, getTextOfNode(node.moduleSpecifier))); } else { writeTextOfNode(currentSourceFile, node.moduleSpecifier); @@ -773,7 +773,7 @@ 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))); + write(makeModulePathSemiAbsolute(host, currentSourceFile, getTextOfNode(node.moduleSpecifier))); } else { writeTextOfNode(currentSourceFile, node.moduleSpecifier); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 71c4f11e8c9..d62cec73bd9 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -6766,7 +6766,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } if (resolvePath) { - text = makeModulePathSemiabsolute(host, currentSourceFile, text); + text = makeModulePathSemiAbsolute(host, currentSourceFile, text); } write(text); } @@ -6813,7 +6813,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi let externalModuleName = getExternalModuleNameText(importNode); if (resolvePath) { - externalModuleName = makeModulePathSemiabsolute(host, currentSourceFile, externalModuleName); + externalModuleName = makeModulePathSemiAbsolute(host, currentSourceFile, externalModuleName); } // Find the name of the module alias, if there is one diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 7af0d0ea7e9..e3537ddffc9 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1608,42 +1608,34 @@ namespace ts { } } + let baseCharsMap: Map = { + "\0": "\\0", + "\t": "\\t", + "\v": "\\v", + "\f": "\\f", + "\b": "\\b", + "\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 = { - "\0": "\\0", - "\t": "\\t", - "\v": "\\v", - "\f": "\\f", - "\b": "\\b", - "\r": "\\r", - "\n": "\\n", - "\\": "\\\\", - "\"": "\\\"", - "\u2028": "\\u2028", // lineSeparator - "\u2029": "\\u2029", // paragraphSeparator - "\u0085": "\\u0085" // nextLine - }; + let escapedCharsMap: Map = extend(baseCharsMap, { + "\"": "\\\"" + }); let singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; - let singleQuoteEscapedCharsMap: Map = { - "\0": "\\0", - "\t": "\\t", - "\v": "\\v", - "\f": "\\f", - "\b": "\\b", - "\r": "\\r", - "\n": "\\n", - "\\": "\\\\", - "\'": "\\\'", - "\u2028": "\\u2028", // lineSeparator - "\u2029": "\\u2029", // paragraphSeparator - "\u0085": "\\u0085" // nextLine - }; + let singleQuoteEscapedCharsMap: Map = extend(baseCharsMap, { + "\'": "\\\'" + }); /** * Based heavily on the abstract 'Quote'/'QuoteJSONString' operation from ECMA-262 (24.3.2.2), @@ -1651,12 +1643,28 @@ namespace ts { * Note that this doesn't actually wrap the input in double quotes. */ export function escapeString(s: string): string { - return escapeStringByQuote(s, "\""); + return escapeStringByQuote(s, QuotationMark.Double); } - export function escapeStringByQuote(s: string, quotemark: string): string { - let regex = quotemark === "'" ? singleQuoteEscapedCharsRegExp : escapedCharsRegExp; - let replacementMap = quotemark === "'" ? singleQuoteEscapedCharsMap : escapedCharsMap; + export const enum QuotationMark { + Double, + Single + } + + export var QuotationMarkLookup: Map = { + [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, quoteMark: QuotationMark): string { + let regex = quoteMark === QuotationMark.Single ? singleQuoteEscapedCharsRegExp : escapedCharsRegExp; + let replacementMap = quoteMark === QuotationMark.Single ? singleQuoteEscapedCharsMap : escapedCharsMap; s = regex.test(s) ? s.replace(regex, getReplacement) : s; @@ -1667,8 +1675,12 @@ namespace ts { } } - export function quoteString(s: string, quotemark: string): string { - return quotemark + escapeStringByQuote(s, quotemark) + quotemark; + /** + * 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) { @@ -1784,22 +1796,24 @@ namespace ts { }; } - export function makeModulePathSemiabsolute(host: EmitHost, currentSourceFile: SourceFile, externalModuleName: string): string { - let quotemark = externalModuleName.charAt(0); + 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, quotemark); + 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 { let dir = host.getCurrentDirectory(); - return removeFileExtension( - getRelativePathToDirectoryOrUrl(dir, path, dir, f => host.getCanonicalFileName(f), /*isAbsolutePathAnUrl*/false) - ); + let relativePath = getRelativePathToDirectoryOrUrl(dir, path, dir, f => host.getCanonicalFileName(f), /*isAbsolutePathAnUrl*/ false); + return removeFileExtension(relativePath); } export function getOwnEmitOutputFilePath(sourceFile: SourceFile, host: EmitHost, extension: string) {