mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-19 20:37:00 -05:00
Properly support string-literal property names and escape external module names.
This commit is contained in:
@@ -535,6 +535,29 @@ module ts {
|
||||
return path;
|
||||
}
|
||||
|
||||
var escapedCharsRegExp = /[\t\v\f\b\0\r\n\"\\\u2028\u2029\u0085]/g;
|
||||
var escapedCharsMap: Map<string> = {
|
||||
"\t": "\\t",
|
||||
"\v": "\\v",
|
||||
"\f": "\\f",
|
||||
"\b": "\\b",
|
||||
"\0": "\\0",
|
||||
"\r": "\\r",
|
||||
"\n": "\\n",
|
||||
"\"": "\\\"",
|
||||
"\u2028": "\\u2028", // lineSeparator
|
||||
"\u2029": "\\u2029", // paragraphSeparator
|
||||
"\u0085": "\\u0085" // nextLine
|
||||
};
|
||||
|
||||
/** NOTE: This *does not* support the full escape characters, it only supports the subset that can be used in file names
|
||||
* or string literals. If the information encoded in the map changes, this needs to be revisited. */
|
||||
export function escapeString(s: string): string {
|
||||
return escapedCharsRegExp.test(s) ? s.replace(escapedCharsRegExp, c => {
|
||||
return escapedCharsMap[c] || c;
|
||||
}) : s;
|
||||
}
|
||||
|
||||
export interface ObjectAllocator {
|
||||
getNodeConstructor(kind: SyntaxKind): new () => Node;
|
||||
getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol;
|
||||
|
||||
@@ -591,21 +591,6 @@ module ts {
|
||||
recordSourceMapSpan(comment.end);
|
||||
}
|
||||
|
||||
var escapedCharsRegExp = /[\t\v\f\b\0\r\n\"\u2028\u2029\u0085]/g;
|
||||
var escapedCharsMap: Map<string> = {
|
||||
"\t": "\\t",
|
||||
"\v": "\\v",
|
||||
"\f": "\\f",
|
||||
"\b": "\\b",
|
||||
"\0": "\\0",
|
||||
"\r": "\\r",
|
||||
"\n": "\\n",
|
||||
"\"": "\\\"",
|
||||
"\u2028": "\\u2028", // lineSeparator
|
||||
"\u2029": "\\u2029", // paragraphSeparator
|
||||
"\u0085": "\\u0085" // nextLine
|
||||
};
|
||||
|
||||
function serializeSourceMapContents(version: number, file: string, sourceRoot: string, sources: string[], names: string[], mappings: string) {
|
||||
if (typeof JSON !== "undefined") {
|
||||
return JSON.stringify({
|
||||
@@ -620,14 +605,6 @@ module ts {
|
||||
|
||||
return "{\"version\":" + version + ",\"file\":\"" + escapeString(file) + "\",\"sourceRoot\":\"" + escapeString(sourceRoot) + "\",\"sources\":[" + serializeStringArray(sources) + "],\"names\":[" + serializeStringArray(names) + "],\"mappings\":\"" + escapeString(mappings) + "\"}";
|
||||
|
||||
/** This does not support the full escape characters, it only supports the subset that can be used in file names
|
||||
* or string literals. If the information encoded in the map changes, this needs to be revisited. */
|
||||
function escapeString(s: string): string {
|
||||
return escapedCharsRegExp.test(s) ? s.replace(escapedCharsRegExp, c => {
|
||||
return escapedCharsMap[c] || c;
|
||||
}) : s;
|
||||
}
|
||||
|
||||
function serializeStringArray(list: string[]): string {
|
||||
var output = "";
|
||||
for (var i = 0, n = list.length; i < n; i++) {
|
||||
|
||||
@@ -151,23 +151,23 @@ module ts {
|
||||
return basicChildItem(node, parameter.name.text, ts.ScriptElementKind.memberVariableElement);
|
||||
|
||||
case SyntaxKind.Method:
|
||||
var memberFunction = <MethodDeclaration>node;
|
||||
return basicChildItem(node, memberFunction.name.text, ts.ScriptElementKind.memberFunctionElement);
|
||||
var method = <MethodDeclaration>node;
|
||||
return basicChildItem(node, getPropertyText(method.name), ts.ScriptElementKind.memberFunctionElement);
|
||||
|
||||
case SyntaxKind.GetAccessor:
|
||||
var getAccessor = <AccessorDeclaration>node;
|
||||
return basicChildItem(node, getAccessor.name.text, ts.ScriptElementKind.memberGetAccessorElement);
|
||||
return basicChildItem(node, getPropertyText(getAccessor.name), ts.ScriptElementKind.memberGetAccessorElement);
|
||||
|
||||
case SyntaxKind.SetAccessor:
|
||||
var setAccessor = <AccessorDeclaration>node;
|
||||
return basicChildItem(node, setAccessor.name.text, ts.ScriptElementKind.memberSetAccessorElement);
|
||||
return basicChildItem(node, getPropertyText(setAccessor.name), ts.ScriptElementKind.memberSetAccessorElement);
|
||||
|
||||
case SyntaxKind.IndexSignature:
|
||||
return basicChildItem(node, "[]", ts.ScriptElementKind.indexSignatureElement);
|
||||
|
||||
case SyntaxKind.EnumMember:
|
||||
var enumElement = <EnumMember>node;
|
||||
return basicChildItem(node, enumElement.name.text, ts.ScriptElementKind.memberVariableElement);
|
||||
var enumMember = <EnumMember>node;
|
||||
return basicChildItem(node, getPropertyText(enumMember.name), ts.ScriptElementKind.memberVariableElement);
|
||||
|
||||
case SyntaxKind.CallSignature:
|
||||
return basicChildItem(node, "()", ts.ScriptElementKind.callSignatureElement);
|
||||
@@ -176,8 +176,8 @@ module ts {
|
||||
return basicChildItem(node, "new()", ts.ScriptElementKind.constructSignatureElement);
|
||||
|
||||
case SyntaxKind.Property:
|
||||
var propertySignature = <PropertyDeclaration>node;
|
||||
return basicChildItem(node, propertySignature.name.text, ts.ScriptElementKind.memberVariableElement);
|
||||
var property = <PropertyDeclaration>node;
|
||||
return basicChildItem(node, getPropertyText(property.name), ts.ScriptElementKind.memberVariableElement);
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
var functionDeclaration = <FunctionDeclaration>node;
|
||||
@@ -224,13 +224,13 @@ module ts {
|
||||
|
||||
return undefined;
|
||||
|
||||
function getModuleNames(moduleDeclaration: ModuleDeclaration): string[]{
|
||||
function getModuleName(moduleDeclaration: ModuleDeclaration): string {
|
||||
// We want to maintain quotation marks.
|
||||
if (moduleDeclaration.name.kind === SyntaxKind.StringLiteral) {
|
||||
return [getSourceTextOfNode(moduleDeclaration.name)];
|
||||
return getPropertyText(moduleDeclaration.name);
|
||||
}
|
||||
|
||||
// Otherwise, we need to aggregate each identifier of the qualified name.
|
||||
// Otherwise, we need to aggregate each identifier to build up the qualified name.
|
||||
var result: string[] = [];
|
||||
|
||||
result.push(moduleDeclaration.name.text);
|
||||
@@ -241,15 +241,15 @@ module ts {
|
||||
result.push(moduleDeclaration.name.text);
|
||||
}
|
||||
|
||||
return result;
|
||||
return result.join(".");
|
||||
}
|
||||
|
||||
function createModuleItem(node: ModuleDeclaration): NavigationBarItem {
|
||||
var moduleNames = getModuleNames(node);
|
||||
var moduleName = getModuleName(node);
|
||||
|
||||
var childItems = getItemsWorker(getChildNodes((<Block>getInnermostModule(node).body).statements), createChildItem);
|
||||
|
||||
return new ts.NavigationBarItem(moduleNames.join("."),
|
||||
return new ts.NavigationBarItem(moduleName,
|
||||
ts.ScriptElementKind.moduleElement,
|
||||
getNodeModifiers(node),
|
||||
[getNodeSpan(node)],
|
||||
@@ -281,7 +281,7 @@ module ts {
|
||||
|
||||
hasGlobalNode = true;
|
||||
var rootName = isExternalModule(node) ?
|
||||
"\"" + getBaseFilename(removeFileExtension(normalizePath(node.filename))) + "\"" :
|
||||
"\"" + escapeString(getBaseFilename(removeFileExtension(normalizePath(node.filename)))) + "\"" :
|
||||
"<global>"
|
||||
|
||||
return new ts.NavigationBarItem(rootName,
|
||||
@@ -340,7 +340,6 @@ module ts {
|
||||
}
|
||||
|
||||
function getInnermostModule(node: ModuleDeclaration): ModuleDeclaration {
|
||||
|
||||
while (node.body.kind === SyntaxKind.ModuleDeclaration) {
|
||||
node = <ModuleDeclaration>node.body;
|
||||
}
|
||||
@@ -351,5 +350,24 @@ module ts {
|
||||
function getNodeSpan(node: Node) {
|
||||
return TypeScript.TextSpan.fromBounds(node.getStart(), node.getEnd());
|
||||
}
|
||||
|
||||
function getPropertyText(node: Node): string {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
return (<Identifier>node).text;
|
||||
}
|
||||
|
||||
if (node.kind === SyntaxKind.StringLiteral) {
|
||||
// normalize the quotes and remove all '\{newline}'s from the original text.
|
||||
var text = getSourceTextOfNodeFromSourceText(sourceFile.text, node);
|
||||
text = text.substring(1, text.length - 1).replace(/\\\r?\n/g, "");
|
||||
return "\"" + text + "\"";
|
||||
}
|
||||
|
||||
if (node.kind === SyntaxKind.NumericLiteral) {
|
||||
return (<LiteralExpression>node).text;
|
||||
}
|
||||
|
||||
Debug.fail("getPropertyText given a property that is neither an identifier nor a literal expression.");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user