Merge branch 'master' into watchImprovements

This commit is contained in:
Sheetal Nandi
2017-08-07 11:04:11 -07:00
431 changed files with 235021 additions and 212978 deletions
+61 -37
View File
@@ -28,7 +28,6 @@ import minimist = require("minimist");
import browserify = require("browserify");
import through2 = require("through2");
import merge2 = require("merge2");
import intoStream = require("into-stream");
import * as os from "os";
import fold = require("travis-fold");
const gulp = helpMaker(originalGulp);
@@ -294,7 +293,7 @@ gulp.task("configure-nightly", "Runs scripts/configureNightly.ts to prepare a bu
exec(host, [configureNightlyJs, packageJson, versionFile], done, done);
});
gulp.task("publish-nightly", "Runs `npm publish --tag next` to create a new nightly build on npm", ["LKG"], () => {
return runSequence("clean", "useDebugMode", "runtests", (done) => {
return runSequence("clean", "useDebugMode", "runtests-parallel", (done) => {
exec("npm", ["publish", "--tag", "next"], done, done);
});
});
@@ -737,50 +736,75 @@ gulp.task(nodeServerOutFile, /*help*/ false, [servicesFile], () => {
import convertMap = require("convert-source-map");
import sorcery = require("sorcery");
declare module "convert-source-map" {
export function fromSource(source: string, largeSource?: boolean): SourceMapConverter;
}
import Vinyl = require("vinyl");
gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile, run], (done) => {
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "../../built/local/bundle.js" }, /*useBuiltCompiler*/ true));
return testProject.src()
.pipe(newer("built/local/bundle.js"))
const bundlePath = path.resolve("built/local/bundle.js");
gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile], (done) => {
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: bundlePath, inlineSourceMap: true }, /*useBuiltCompiler*/ true));
let originalMap: any;
let prebundledContent: string;
browserify(testProject.src()
.pipe(newer(bundlePath))
.pipe(sourcemaps.init())
.pipe(testProject())
.pipe(through2.obj((file, enc, next) => {
const originalMap = file.sourceMap;
const prebundledContent = file.contents.toString();
if (originalMap) {
throw new Error("Should only recieve one file!");
}
console.log(`Saving sourcemaps for ${file.path}`);
originalMap = file.sourceMap;
prebundledContent = file.contents.toString();
// Make paths absolute to help sorcery deal with all the terrible paths being thrown around
originalMap.sources = originalMap.sources.map(s => path.resolve(path.join("src/harness", s)));
// intoStream (below) makes browserify think the input file is named this, so this is what it puts in the sourcemap
// browserify names input files this when they are streamed in, so this is what it puts in the sourcemap
originalMap.file = "built/local/_stream_0.js";
browserify(intoStream(file.contents), { debug: true })
.bundle((err, res) => {
// assumes file.contents is a Buffer
const maps = JSON.parse(convertMap.fromSource(res.toString(), /*largeSource*/ true).toJSON());
delete maps.sourceRoot;
maps.sources = maps.sources.map(s => path.resolve(s === "_stream_0.js" ? "built/local/_stream_0.js" : s));
// Strip browserify's inline comments away (could probably just let sorcery do this, but then we couldn't fix the paths)
file.contents = new Buffer(convertMap.removeComments(res.toString()));
const chain = sorcery.loadSync("built/local/bundle.js", {
content: {
"built/local/_stream_0.js": prebundledContent,
"built/local/bundle.js": file.contents.toString()
},
sourcemaps: {
"built/local/_stream_0.js": originalMap,
"built/local/bundle.js": maps,
"node_modules/source-map-support/source-map-support.js": undefined,
}
});
const finalMap = chain.apply();
file.sourceMap = finalMap;
next(/*err*/ undefined, file);
});
next(/*err*/ undefined, file.contents);
}))
.pipe(sourcemaps.write(".", { includeContent: false }))
.pipe(gulp.dest("src/harness"));
.on("error", err => {
return done(err);
}), { debug: true, basedir: __dirname }) // Attach error handler to inner stream
.bundle((err, contents) => {
if (err) {
if (err.message.match(/Cannot find module '.*_stream_0.js'/)) {
return done(); // Browserify errors when we pass in no files when `newer` filters the input, we should count that as a success, though
}
return done(err);
}
const stringContent = contents.toString();
const file = new Vinyl({ contents, path: bundlePath });
console.log(`Fixing sourcemaps for ${file.path}`);
// assumes contents is a Buffer, since that's what browserify yields
const maps = convertMap.fromSource(stringContent, /*largeSource*/ true).toObject();
delete maps.sourceRoot;
maps.sources = maps.sources.map(s => path.resolve(s === "_stream_0.js" ? "built/local/_stream_0.js" : s));
// Strip browserify's inline comments away (could probably just let sorcery do this, but then we couldn't fix the paths)
file.contents = new Buffer(convertMap.removeComments(stringContent));
const chain = sorcery.loadSync(bundlePath, {
content: {
"built/local/_stream_0.js": prebundledContent,
[bundlePath]: stringContent
},
sourcemaps: {
"built/local/_stream_0.js": originalMap,
[bundlePath]: maps,
"node_modules/source-map-support/source-map-support.js": undefined,
}
});
const finalMap = chain.apply();
file.sourceMap = finalMap;
const stream = through2.obj((file, enc, callback) => {
return callback(/*err*/ undefined, file);
});
stream.pipe(sourcemaps.write(".", { includeContent: false }))
.pipe(gulp.dest("."))
.on("end", done)
.on("error", done);
stream.write(file);
stream.end();
});
});
+3 -2
View File
@@ -505,7 +505,7 @@ task("configure-nightly", [configureNightlyJs], function () {
}, { async: true });
desc("Configure, build, test, and publish the nightly release.");
task("publish-nightly", ["configure-nightly", "LKG", "clean", "setDebugMode", "runtests"], function () {
task("publish-nightly", ["configure-nightly", "LKG", "clean", "setDebugMode", "runtests-parallel"], function () {
var cmd = "npm publish --tag next";
console.log(cmd);
exec(cmd);
@@ -840,7 +840,8 @@ function runConsoleTests(defaultReporter, runInParallel) {
testTimeout = 800000;
}
var colors = process.env.colors || process.env.color || true;
var colorsFlag = process.env.color || process.env.colors;
var colors = colorsFlag !== "false" && colorsFlag !== "0";
var reporter = process.env.reporter || process.env.r || defaultReporter;
var bail = process.env.bail || process.env.b;
var lintFlag = process.env.lint !== 'false';
-2
View File
@@ -69,5 +69,3 @@ function createCancellationToken(args) {
}
}
module.exports = createCancellationToken;
//# sourceMappingURL=cancellationToken.js.map
+4346 -4803
View File
File diff suppressed because it is too large Load Diff
+4200 -4452
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -21,8 +21,8 @@ and limitations under the License.
/// <reference path="lib.es2015.core.d.ts" />
/// <reference path="lib.es2015.collection.d.ts" />
/// <reference path="lib.es2015.generator.d.ts" />
/// <reference path="lib.es2015.iterable.d.ts" />
/// <reference path="lib.es2015.promise.d.ts" />
/// <reference path="lib.es2015.iterable.d.ts" />
/// <reference path="lib.es2015.proxy.d.ts" />
/// <reference path="lib.es2015.reflect.d.ts" />
/// <reference path="lib.es2015.symbol.d.ts" />
+4200 -6276
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -22,4 +22,4 @@ and limitations under the License.
/// <reference path="lib.es2017.object.d.ts" />
/// <reference path="lib.es2017.sharedmemory.d.ts" />
/// <reference path="lib.es2017.string.d.ts" />
/// <reference path="lib.es2017.intl.d.ts" />
/// <reference path="lib.es2017.intl.d.ts" />
+4200 -6275
View File
File diff suppressed because it is too large Load Diff
+30
View File
@@ -0,0 +1,30 @@
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
type DateTimeFormatPartTypes = "day" | "dayPeriod" | "era" | "hour" | "literal" | "minute" | "month" | "second" | "timeZoneName" | "weekday" | "year";
interface DateTimeFormatPart {
type: DateTimeFormatPartTypes;
value: string;
}
interface DateTimeFormat {
formatToParts(date?: Date | number): DateTimeFormatPart[];
}
+146 -351
View File
File diff suppressed because it is too large Load Diff
+4346 -4803
View File
File diff suppressed because it is too large Load Diff
+4200 -6276
View File
File diff suppressed because it is too large Load Diff
+145 -134
View File
@@ -20,7 +20,7 @@ and limitations under the License.
/////////////////////////////
/// IE Worker APIs
/// Worker APIs
/////////////////////////////
interface Algorithm {
@@ -28,16 +28,16 @@ interface Algorithm {
}
interface CacheQueryOptions {
ignoreSearch?: boolean;
ignoreMethod?: boolean;
ignoreVary?: boolean;
cacheName?: string;
ignoreMethod?: boolean;
ignoreSearch?: boolean;
ignoreVary?: boolean;
}
interface CloseEventInit extends EventInit {
wasClean?: boolean;
code?: number;
reason?: string;
wasClean?: boolean;
}
interface EventInit {
@@ -69,16 +69,16 @@ interface MessageEventInit extends EventInit {
channel?: string;
data?: any;
origin?: string;
source?: any;
ports?: MessagePort[];
source?: any;
}
interface NotificationOptions {
dir?: NotificationDirection;
lang?: string;
body?: string;
tag?: string;
dir?: NotificationDirection;
icon?: string;
lang?: string;
tag?: string;
}
interface ObjectURLOptions {
@@ -86,29 +86,29 @@ interface ObjectURLOptions {
}
interface PushSubscriptionOptionsInit {
userVisibleOnly?: boolean;
applicationServerKey?: any;
userVisibleOnly?: boolean;
}
interface RequestInit {
method?: string;
headers?: any;
body?: any;
referrer?: string;
referrerPolicy?: ReferrerPolicy;
mode?: RequestMode;
credentials?: RequestCredentials;
cache?: RequestCache;
redirect?: RequestRedirect;
credentials?: RequestCredentials;
headers?: any;
integrity?: string;
keepalive?: boolean;
method?: string;
mode?: RequestMode;
redirect?: RequestRedirect;
referrer?: string;
referrerPolicy?: ReferrerPolicy;
window?: any;
}
interface ResponseInit {
headers?: any;
status?: number;
statusText?: string;
headers?: any;
}
interface ClientQueryOptions {
@@ -176,7 +176,7 @@ interface AudioBuffer {
declare var AudioBuffer: {
prototype: AudioBuffer;
new(): AudioBuffer;
}
};
interface Blob {
readonly size: number;
@@ -189,7 +189,7 @@ interface Blob {
declare var Blob: {
prototype: Blob;
new (blobParts?: any[], options?: BlobPropertyBag): Blob;
}
};
interface Cache {
add(request: RequestInfo): Promise<void>;
@@ -204,7 +204,7 @@ interface Cache {
declare var Cache: {
prototype: Cache;
new(): Cache;
}
};
interface CacheStorage {
delete(cacheName: string): Promise<boolean>;
@@ -217,7 +217,7 @@ interface CacheStorage {
declare var CacheStorage: {
prototype: CacheStorage;
new(): CacheStorage;
}
};
interface CloseEvent extends Event {
readonly code: number;
@@ -229,7 +229,7 @@ interface CloseEvent extends Event {
declare var CloseEvent: {
prototype: CloseEvent;
new(typeArg: string, eventInitDict?: CloseEventInit): CloseEvent;
}
};
interface Console {
assert(test?: boolean, message?: string, ...optionalParams: any[]): void;
@@ -240,8 +240,8 @@ interface Console {
dirxml(value: any): void;
error(message?: any, ...optionalParams: any[]): void;
exception(message?: string, ...optionalParams: any[]): void;
group(groupTitle?: string): void;
groupCollapsed(groupTitle?: string): void;
group(groupTitle?: string, ...optionalParams: any[]): void;
groupCollapsed(groupTitle?: string, ...optionalParams: any[]): void;
groupEnd(): void;
info(message?: any, ...optionalParams: any[]): void;
log(message?: any, ...optionalParams: any[]): void;
@@ -259,7 +259,7 @@ interface Console {
declare var Console: {
prototype: Console;
new(): Console;
}
};
interface Coordinates {
readonly accuracy: number;
@@ -274,7 +274,7 @@ interface Coordinates {
declare var Coordinates: {
prototype: Coordinates;
new(): Coordinates;
}
};
interface CryptoKey {
readonly algorithm: KeyAlgorithm;
@@ -286,7 +286,7 @@ interface CryptoKey {
declare var CryptoKey: {
prototype: CryptoKey;
new(): CryptoKey;
}
};
interface DOMError {
readonly name: string;
@@ -296,7 +296,7 @@ interface DOMError {
declare var DOMError: {
prototype: DOMError;
new(): DOMError;
}
};
interface DOMException {
readonly code: number;
@@ -316,10 +316,10 @@ interface DOMException {
readonly INVALID_STATE_ERR: number;
readonly NAMESPACE_ERR: number;
readonly NETWORK_ERR: number;
readonly NOT_FOUND_ERR: number;
readonly NOT_SUPPORTED_ERR: number;
readonly NO_DATA_ALLOWED_ERR: number;
readonly NO_MODIFICATION_ALLOWED_ERR: number;
readonly NOT_FOUND_ERR: number;
readonly NOT_SUPPORTED_ERR: number;
readonly PARSE_ERR: number;
readonly QUOTA_EXCEEDED_ERR: number;
readonly SECURITY_ERR: number;
@@ -348,10 +348,10 @@ declare var DOMException: {
readonly INVALID_STATE_ERR: number;
readonly NAMESPACE_ERR: number;
readonly NETWORK_ERR: number;
readonly NOT_FOUND_ERR: number;
readonly NOT_SUPPORTED_ERR: number;
readonly NO_DATA_ALLOWED_ERR: number;
readonly NO_MODIFICATION_ALLOWED_ERR: number;
readonly NOT_FOUND_ERR: number;
readonly NOT_SUPPORTED_ERR: number;
readonly PARSE_ERR: number;
readonly QUOTA_EXCEEDED_ERR: number;
readonly SECURITY_ERR: number;
@@ -362,7 +362,7 @@ declare var DOMException: {
readonly URL_MISMATCH_ERR: number;
readonly VALIDATION_ERR: number;
readonly WRONG_DOCUMENT_ERR: number;
}
};
interface DOMStringList {
readonly length: number;
@@ -374,7 +374,7 @@ interface DOMStringList {
declare var DOMStringList: {
prototype: DOMStringList;
new(): DOMStringList;
}
};
interface ErrorEvent extends Event {
readonly colno: number;
@@ -388,12 +388,12 @@ interface ErrorEvent extends Event {
declare var ErrorEvent: {
prototype: ErrorEvent;
new(type: string, errorEventInitDict?: ErrorEventInit): ErrorEvent;
}
};
interface Event {
readonly bubbles: boolean;
cancelBubble: boolean;
readonly cancelable: boolean;
cancelBubble: boolean;
readonly currentTarget: EventTarget;
readonly defaultPrevented: boolean;
readonly eventPhase: number;
@@ -420,7 +420,7 @@ declare var Event: {
readonly AT_TARGET: number;
readonly BUBBLING_PHASE: number;
readonly CAPTURING_PHASE: number;
}
};
interface EventTarget {
addEventListener(type: string, listener?: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
@@ -431,7 +431,7 @@ interface EventTarget {
declare var EventTarget: {
prototype: EventTarget;
new(): EventTarget;
}
};
interface File extends Blob {
readonly lastModifiedDate: any;
@@ -442,7 +442,7 @@ interface File extends Blob {
declare var File: {
prototype: File;
new (parts: (ArrayBuffer | ArrayBufferView | Blob | string)[], filename: string, properties?: FilePropertyBag): File;
}
};
interface FileList {
readonly length: number;
@@ -453,7 +453,7 @@ interface FileList {
declare var FileList: {
prototype: FileList;
new(): FileList;
}
};
interface FileReader extends EventTarget, MSBaseReader {
readonly error: DOMError;
@@ -468,8 +468,17 @@ interface FileReader extends EventTarget, MSBaseReader {
declare var FileReader: {
prototype: FileReader;
new(): FileReader;
};
interface FormData {
append(name: string, value: string | Blob, fileName?: string): void;
}
declare var FormData: {
prototype: FormData;
new(): FormData;
};
interface Headers {
append(name: string, value: string): void;
delete(name: string): void;
@@ -482,7 +491,7 @@ interface Headers {
declare var Headers: {
prototype: Headers;
new(init?: any): Headers;
}
};
interface IDBCursor {
readonly direction: IDBCursorDirection;
@@ -506,7 +515,7 @@ declare var IDBCursor: {
readonly NEXT_NO_DUPLICATE: string;
readonly PREV: string;
readonly PREV_NO_DUPLICATE: string;
}
};
interface IDBCursorWithValue extends IDBCursor {
readonly value: any;
@@ -515,7 +524,7 @@ interface IDBCursorWithValue extends IDBCursor {
declare var IDBCursorWithValue: {
prototype: IDBCursorWithValue;
new(): IDBCursorWithValue;
}
};
interface IDBDatabaseEventMap {
"abort": Event;
@@ -532,7 +541,7 @@ interface IDBDatabase extends EventTarget {
close(): void;
createObjectStore(name: string, optionalParameters?: IDBObjectStoreParameters): IDBObjectStore;
deleteObjectStore(name: string): void;
transaction(storeNames: string | string[], mode?: string): IDBTransaction;
transaction(storeNames: string | string[], mode?: IDBTransactionMode): IDBTransaction;
addEventListener(type: "versionchange", listener: (ev: IDBVersionChangeEvent) => any, useCapture?: boolean): void;
addEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
@@ -541,7 +550,7 @@ interface IDBDatabase extends EventTarget {
declare var IDBDatabase: {
prototype: IDBDatabase;
new(): IDBDatabase;
}
};
interface IDBFactory {
cmp(first: any, second: any): number;
@@ -552,7 +561,7 @@ interface IDBFactory {
declare var IDBFactory: {
prototype: IDBFactory;
new(): IDBFactory;
}
};
interface IDBIndex {
keyPath: string | string[];
@@ -563,14 +572,14 @@ interface IDBIndex {
count(key?: IDBKeyRange | IDBValidKey): IDBRequest;
get(key: IDBKeyRange | IDBValidKey): IDBRequest;
getKey(key: IDBKeyRange | IDBValidKey): IDBRequest;
openCursor(range?: IDBKeyRange | IDBValidKey, direction?: string): IDBRequest;
openKeyCursor(range?: IDBKeyRange | IDBValidKey, direction?: string): IDBRequest;
openCursor(range?: IDBKeyRange | IDBValidKey, direction?: IDBCursorDirection): IDBRequest;
openKeyCursor(range?: IDBKeyRange | IDBValidKey, direction?: IDBCursorDirection): IDBRequest;
}
declare var IDBIndex: {
prototype: IDBIndex;
new(): IDBIndex;
}
};
interface IDBKeyRange {
readonly lower: any;
@@ -586,7 +595,7 @@ declare var IDBKeyRange: {
lowerBound(lower: any, open?: boolean): IDBKeyRange;
only(value: any): IDBKeyRange;
upperBound(upper: any, open?: boolean): IDBKeyRange;
}
};
interface IDBObjectStore {
readonly indexNames: DOMStringList;
@@ -602,14 +611,14 @@ interface IDBObjectStore {
deleteIndex(indexName: string): void;
get(key: any): IDBRequest;
index(name: string): IDBIndex;
openCursor(range?: IDBKeyRange | IDBValidKey, direction?: string): IDBRequest;
openCursor(range?: IDBKeyRange | IDBValidKey, direction?: IDBCursorDirection): IDBRequest;
put(value: any, key?: IDBKeyRange | IDBValidKey): IDBRequest;
}
declare var IDBObjectStore: {
prototype: IDBObjectStore;
new(): IDBObjectStore;
}
};
interface IDBOpenDBRequestEventMap extends IDBRequestEventMap {
"blocked": Event;
@@ -626,7 +635,7 @@ interface IDBOpenDBRequest extends IDBRequest {
declare var IDBOpenDBRequest: {
prototype: IDBOpenDBRequest;
new(): IDBOpenDBRequest;
}
};
interface IDBRequestEventMap {
"error": Event;
@@ -634,7 +643,7 @@ interface IDBRequestEventMap {
}
interface IDBRequest extends EventTarget {
readonly error: DOMError;
readonly error: DOMException;
onerror: (this: IDBRequest, ev: Event) => any;
onsuccess: (this: IDBRequest, ev: Event) => any;
readonly readyState: IDBRequestReadyState;
@@ -648,7 +657,7 @@ interface IDBRequest extends EventTarget {
declare var IDBRequest: {
prototype: IDBRequest;
new(): IDBRequest;
}
};
interface IDBTransactionEventMap {
"abort": Event;
@@ -658,7 +667,7 @@ interface IDBTransactionEventMap {
interface IDBTransaction extends EventTarget {
readonly db: IDBDatabase;
readonly error: DOMError;
readonly error: DOMException;
readonly mode: IDBTransactionMode;
onabort: (this: IDBTransaction, ev: Event) => any;
oncomplete: (this: IDBTransaction, ev: Event) => any;
@@ -678,7 +687,7 @@ declare var IDBTransaction: {
readonly READ_ONLY: string;
readonly READ_WRITE: string;
readonly VERSION_CHANGE: string;
}
};
interface IDBVersionChangeEvent extends Event {
readonly newVersion: number | null;
@@ -688,7 +697,7 @@ interface IDBVersionChangeEvent extends Event {
declare var IDBVersionChangeEvent: {
prototype: IDBVersionChangeEvent;
new(): IDBVersionChangeEvent;
}
};
interface ImageData {
data: Uint8ClampedArray;
@@ -700,7 +709,7 @@ declare var ImageData: {
prototype: ImageData;
new(width: number, height: number): ImageData;
new(array: Uint8ClampedArray, width: number, height: number): ImageData;
}
};
interface MessageChannel {
readonly port1: MessagePort;
@@ -710,7 +719,7 @@ interface MessageChannel {
declare var MessageChannel: {
prototype: MessageChannel;
new(): MessageChannel;
}
};
interface MessageEvent extends Event {
readonly data: any;
@@ -723,7 +732,7 @@ interface MessageEvent extends Event {
declare var MessageEvent: {
prototype: MessageEvent;
new(type: string, eventInitDict?: MessageEventInit): MessageEvent;
}
};
interface MessagePortEventMap {
"message": MessageEvent;
@@ -741,7 +750,7 @@ interface MessagePort extends EventTarget {
declare var MessagePort: {
prototype: MessagePort;
new(): MessagePort;
}
};
interface NotificationEventMap {
"click": Event;
@@ -771,7 +780,7 @@ declare var Notification: {
prototype: Notification;
new(title: string, options?: NotificationOptions): Notification;
requestPermission(callback?: NotificationPermissionCallback): Promise<NotificationPermission>;
}
};
interface Performance {
readonly navigation: PerformanceNavigation;
@@ -794,7 +803,7 @@ interface Performance {
declare var Performance: {
prototype: Performance;
new(): Performance;
}
};
interface PerformanceNavigation {
readonly redirectCount: number;
@@ -813,18 +822,18 @@ declare var PerformanceNavigation: {
readonly TYPE_NAVIGATE: number;
readonly TYPE_RELOAD: number;
readonly TYPE_RESERVED: number;
}
};
interface PerformanceTiming {
readonly connectEnd: number;
readonly connectStart: number;
readonly domainLookupEnd: number;
readonly domainLookupStart: number;
readonly domComplete: number;
readonly domContentLoadedEventEnd: number;
readonly domContentLoadedEventStart: number;
readonly domInteractive: number;
readonly domLoading: number;
readonly domainLookupEnd: number;
readonly domainLookupStart: number;
readonly fetchStart: number;
readonly loadEventEnd: number;
readonly loadEventStart: number;
@@ -844,7 +853,7 @@ interface PerformanceTiming {
declare var PerformanceTiming: {
prototype: PerformanceTiming;
new(): PerformanceTiming;
}
};
interface Position {
readonly coords: Coordinates;
@@ -854,7 +863,7 @@ interface Position {
declare var Position: {
prototype: Position;
new(): Position;
}
};
interface PositionError {
readonly code: number;
@@ -871,7 +880,7 @@ declare var PositionError: {
readonly PERMISSION_DENIED: number;
readonly POSITION_UNAVAILABLE: number;
readonly TIMEOUT: number;
}
};
interface ProgressEvent extends Event {
readonly lengthComputable: boolean;
@@ -883,7 +892,7 @@ interface ProgressEvent extends Event {
declare var ProgressEvent: {
prototype: ProgressEvent;
new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent;
}
};
interface PushManager {
getSubscription(): Promise<PushSubscription>;
@@ -894,7 +903,7 @@ interface PushManager {
declare var PushManager: {
prototype: PushManager;
new(): PushManager;
}
};
interface PushSubscription {
readonly endpoint: USVString;
@@ -907,7 +916,7 @@ interface PushSubscription {
declare var PushSubscription: {
prototype: PushSubscription;
new(): PushSubscription;
}
};
interface PushSubscriptionOptions {
readonly applicationServerKey: ArrayBuffer | null;
@@ -917,7 +926,7 @@ interface PushSubscriptionOptions {
declare var PushSubscriptionOptions: {
prototype: PushSubscriptionOptions;
new(): PushSubscriptionOptions;
}
};
interface ReadableStream {
readonly locked: boolean;
@@ -928,7 +937,7 @@ interface ReadableStream {
declare var ReadableStream: {
prototype: ReadableStream;
new(): ReadableStream;
}
};
interface ReadableStreamReader {
cancel(): Promise<void>;
@@ -939,7 +948,7 @@ interface ReadableStreamReader {
declare var ReadableStreamReader: {
prototype: ReadableStreamReader;
new(): ReadableStreamReader;
}
};
interface Request extends Object, Body {
readonly cache: RequestCache;
@@ -961,7 +970,7 @@ interface Request extends Object, Body {
declare var Request: {
prototype: Request;
new(input: Request | string, init?: RequestInit): Request;
}
};
interface Response extends Object, Body {
readonly body: ReadableStream | null;
@@ -977,7 +986,9 @@ interface Response extends Object, Body {
declare var Response: {
prototype: Response;
new(body?: any, init?: ResponseInit): Response;
}
error: () => Response;
redirect: (url: string, status?: number) => Response;
};
interface ServiceWorkerEventMap extends AbstractWorkerEventMap {
"statechange": Event;
@@ -995,7 +1006,7 @@ interface ServiceWorker extends EventTarget, AbstractWorker {
declare var ServiceWorker: {
prototype: ServiceWorker;
new(): ServiceWorker;
}
};
interface ServiceWorkerRegistrationEventMap {
"updatefound": Event;
@@ -1020,7 +1031,7 @@ interface ServiceWorkerRegistration extends EventTarget {
declare var ServiceWorkerRegistration: {
prototype: ServiceWorkerRegistration;
new(): ServiceWorkerRegistration;
}
};
interface SyncManager {
getTags(): any;
@@ -1030,7 +1041,7 @@ interface SyncManager {
declare var SyncManager: {
prototype: SyncManager;
new(): SyncManager;
}
};
interface URL {
hash: string;
@@ -1053,7 +1064,7 @@ declare var URL: {
new(url: string, base?: string): URL;
createObjectURL(object: any, options?: ObjectURLOptions): string;
revokeObjectURL(url: string): void;
}
};
interface WebSocketEventMap {
"close": CloseEvent;
@@ -1090,7 +1101,7 @@ declare var WebSocket: {
readonly CLOSING: number;
readonly CONNECTING: number;
readonly OPEN: number;
}
};
interface WorkerEventMap extends AbstractWorkerEventMap {
"message": MessageEvent;
@@ -1107,7 +1118,7 @@ interface Worker extends EventTarget, AbstractWorker {
declare var Worker: {
prototype: Worker;
new(stringUrl: string): Worker;
}
};
interface XMLHttpRequestEventMap extends XMLHttpRequestEventTargetEventMap {
"readystatechange": Event;
@@ -1153,7 +1164,7 @@ declare var XMLHttpRequest: {
readonly LOADING: number;
readonly OPENED: number;
readonly UNSENT: number;
}
};
interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget {
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
@@ -1163,7 +1174,7 @@ interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget {
declare var XMLHttpRequestUpload: {
prototype: XMLHttpRequestUpload;
new(): XMLHttpRequestUpload;
}
};
interface AbstractWorkerEventMap {
"error": ErrorEvent;
@@ -1278,7 +1289,7 @@ interface Client {
declare var Client: {
prototype: Client;
new(): Client;
}
};
interface Clients {
claim(): Promise<void>;
@@ -1290,7 +1301,7 @@ interface Clients {
declare var Clients: {
prototype: Clients;
new(): Clients;
}
};
interface DedicatedWorkerGlobalScopeEventMap extends WorkerGlobalScopeEventMap {
"message": MessageEvent;
@@ -1307,7 +1318,7 @@ interface DedicatedWorkerGlobalScope extends WorkerGlobalScope {
declare var DedicatedWorkerGlobalScope: {
prototype: DedicatedWorkerGlobalScope;
new(): DedicatedWorkerGlobalScope;
}
};
interface ExtendableEvent extends Event {
waitUntil(f: Promise<any>): void;
@@ -1316,7 +1327,7 @@ interface ExtendableEvent extends Event {
declare var ExtendableEvent: {
prototype: ExtendableEvent;
new(type: string, eventInitDict?: ExtendableEventInit): ExtendableEvent;
}
};
interface ExtendableMessageEvent extends ExtendableEvent {
readonly data: any;
@@ -1329,7 +1340,7 @@ interface ExtendableMessageEvent extends ExtendableEvent {
declare var ExtendableMessageEvent: {
prototype: ExtendableMessageEvent;
new(type: string, eventInitDict?: ExtendableMessageEventInit): ExtendableMessageEvent;
}
};
interface FetchEvent extends ExtendableEvent {
readonly clientId: string | null;
@@ -1341,7 +1352,7 @@ interface FetchEvent extends ExtendableEvent {
declare var FetchEvent: {
prototype: FetchEvent;
new(type: string, eventInitDict: FetchEventInit): FetchEvent;
}
};
interface FileReaderSync {
readAsArrayBuffer(blob: Blob): any;
@@ -1353,7 +1364,7 @@ interface FileReaderSync {
declare var FileReaderSync: {
prototype: FileReaderSync;
new(): FileReaderSync;
}
};
interface NotificationEvent extends ExtendableEvent {
readonly action: string;
@@ -1363,7 +1374,7 @@ interface NotificationEvent extends ExtendableEvent {
declare var NotificationEvent: {
prototype: NotificationEvent;
new(type: string, eventInitDict: NotificationEventInit): NotificationEvent;
}
};
interface PushEvent extends ExtendableEvent {
readonly data: PushMessageData | null;
@@ -1372,7 +1383,7 @@ interface PushEvent extends ExtendableEvent {
declare var PushEvent: {
prototype: PushEvent;
new(type: string, eventInitDict?: PushEventInit): PushEvent;
}
};
interface PushMessageData {
arrayBuffer(): ArrayBuffer;
@@ -1384,7 +1395,7 @@ interface PushMessageData {
declare var PushMessageData: {
prototype: PushMessageData;
new(): PushMessageData;
}
};
interface ServiceWorkerGlobalScopeEventMap extends WorkerGlobalScopeEventMap {
"activate": ExtendableEvent;
@@ -1418,7 +1429,7 @@ interface ServiceWorkerGlobalScope extends WorkerGlobalScope {
declare var ServiceWorkerGlobalScope: {
prototype: ServiceWorkerGlobalScope;
new(): ServiceWorkerGlobalScope;
}
};
interface SyncEvent extends ExtendableEvent {
readonly lastChance: boolean;
@@ -1428,7 +1439,7 @@ interface SyncEvent extends ExtendableEvent {
declare var SyncEvent: {
prototype: SyncEvent;
new(type: string, init: SyncEventInit): SyncEvent;
}
};
interface WindowClient extends Client {
readonly focused: boolean;
@@ -1440,7 +1451,7 @@ interface WindowClient extends Client {
declare var WindowClient: {
prototype: WindowClient;
new(): WindowClient;
}
};
interface WorkerGlobalScopeEventMap {
"error": ErrorEvent;
@@ -1463,7 +1474,7 @@ interface WorkerGlobalScope extends EventTarget, WorkerUtils, WindowConsole, Glo
declare var WorkerGlobalScope: {
prototype: WorkerGlobalScope;
new(): WorkerGlobalScope;
}
};
interface WorkerLocation {
readonly hash: string;
@@ -1481,7 +1492,7 @@ interface WorkerLocation {
declare var WorkerLocation: {
prototype: WorkerLocation;
new(): WorkerLocation;
}
};
interface WorkerNavigator extends Object, NavigatorID, NavigatorOnLine, NavigatorBeacon, NavigatorConcurrentHardware {
readonly hardwareConcurrency: number;
@@ -1490,7 +1501,7 @@ interface WorkerNavigator extends Object, NavigatorID, NavigatorOnLine, Navigato
declare var WorkerNavigator: {
prototype: WorkerNavigator;
new(): WorkerNavigator;
}
};
interface WorkerUtils extends Object, WindowBase64 {
readonly indexedDB: IDBFactory;
@@ -1533,38 +1544,38 @@ interface ImageBitmap {
interface URLSearchParams {
/**
* Appends a specified key/value pair as a new search parameter.
*/
* Appends a specified key/value pair as a new search parameter.
*/
append(name: string, value: string): void;
/**
* Deletes the given search parameter, and its associated value, from the list of all search parameters.
*/
* Deletes the given search parameter, and its associated value, from the list of all search parameters.
*/
delete(name: string): void;
/**
* Returns the first value associated to the given search parameter.
*/
* Returns the first value associated to the given search parameter.
*/
get(name: string): string | null;
/**
* Returns all the values association with a given search parameter.
*/
* Returns all the values association with a given search parameter.
*/
getAll(name: string): string[];
/**
* Returns a Boolean indicating if such a search parameter exists.
*/
* Returns a Boolean indicating if such a search parameter exists.
*/
has(name: string): boolean;
/**
* Sets the value associated to a given search parameter to the given value. If there were several values, delete the others.
*/
* Sets the value associated to a given search parameter to the given value. If there were several values, delete the others.
*/
set(name: string, value: string): void;
}
declare var URLSearchParams: {
prototype: URLSearchParams;
/**
* Constructor returning a URLSearchParams object.
*/
* Constructor returning a URLSearchParams object.
*/
new (init?: string | URLSearchParams): URLSearchParams;
}
};
interface BlobPropertyBag {
type?: string;
@@ -1771,8 +1782,23 @@ interface AddEventListenerOptions extends EventListenerOptions {
declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
interface DecodeErrorCallback {
(error: DOMException): void;
}
interface DecodeSuccessCallback {
(decodedData: AudioBuffer): void;
}
interface ErrorEventHandler {
(message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void;
(message: string, filename?: string, lineno?: number, colno?: number, error?: Error): void;
}
interface ForEachCallback {
(keyId: any, status: MediaKeyStatus): void;
}
interface FunctionStringCallback {
(data: string): void;
}
interface NotificationPermissionCallback {
(permission: NotificationPermission): void;
}
interface PositionCallback {
(position: Position): void;
@@ -1780,21 +1806,6 @@ interface PositionCallback {
interface PositionErrorCallback {
(error: PositionError): void;
}
interface DecodeSuccessCallback {
(decodedData: AudioBuffer): void;
}
interface DecodeErrorCallback {
(error: DOMException): void;
}
interface FunctionStringCallback {
(data: string): void;
}
interface ForEachCallback {
(keyId: any, status: MediaKeyStatus): void;
}
interface NotificationPermissionCallback {
(permission: NotificationPermission): void;
}
declare var onmessage: (this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any;
declare function close(): void;
declare function postMessage(message: any, transfer?: any[]): void;
+180 -95
View File
@@ -2,51 +2,53 @@
* Declaration module describing the TypeScript Server protocol
*/
declare namespace ts.server.protocol {
namespace CommandTypes {
type Brace = "brace";
type BraceCompletion = "braceCompletion";
type Change = "change";
type Close = "close";
type Completions = "completions";
type CompletionDetails = "completionEntryDetails";
type CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList";
type CompileOnSaveEmitFile = "compileOnSaveEmitFile";
type Configure = "configure";
type Definition = "definition";
type Implementation = "implementation";
type Exit = "exit";
type Format = "format";
type Formatonkey = "formatonkey";
type Geterr = "geterr";
type GeterrForProject = "geterrForProject";
type SemanticDiagnosticsSync = "semanticDiagnosticsSync";
type SyntacticDiagnosticsSync = "syntacticDiagnosticsSync";
type NavBar = "navbar";
type Navto = "navto";
type NavTree = "navtree";
type NavTreeFull = "navtree-full";
type Occurrences = "occurrences";
type DocumentHighlights = "documentHighlights";
type Open = "open";
type Quickinfo = "quickinfo";
type References = "references";
type Reload = "reload";
type Rename = "rename";
type Saveto = "saveto";
type SignatureHelp = "signatureHelp";
type TypeDefinition = "typeDefinition";
type ProjectInfo = "projectInfo";
type ReloadProjects = "reloadProjects";
type Unknown = "unknown";
type OpenExternalProject = "openExternalProject";
type OpenExternalProjects = "openExternalProjects";
type CloseExternalProject = "closeExternalProject";
type TodoComments = "todoComments";
type Indentation = "indentation";
type DocCommentTemplate = "docCommentTemplate";
type CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects";
type GetCodeFixes = "getCodeFixes";
type GetSupportedCodeFixes = "getSupportedCodeFixes";
const enum CommandTypes {
Brace = "brace",
BraceCompletion = "braceCompletion",
Change = "change",
Close = "close",
Completions = "completions",
CompletionDetails = "completionEntryDetails",
CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList",
CompileOnSaveEmitFile = "compileOnSaveEmitFile",
Configure = "configure",
Definition = "definition",
Implementation = "implementation",
Exit = "exit",
Format = "format",
Formatonkey = "formatonkey",
Geterr = "geterr",
GeterrForProject = "geterrForProject",
SemanticDiagnosticsSync = "semanticDiagnosticsSync",
SyntacticDiagnosticsSync = "syntacticDiagnosticsSync",
NavBar = "navbar",
Navto = "navto",
NavTree = "navtree",
NavTreeFull = "navtree-full",
Occurrences = "occurrences",
DocumentHighlights = "documentHighlights",
Open = "open",
Quickinfo = "quickinfo",
References = "references",
Reload = "reload",
Rename = "rename",
Saveto = "saveto",
SignatureHelp = "signatureHelp",
TypeDefinition = "typeDefinition",
ProjectInfo = "projectInfo",
ReloadProjects = "reloadProjects",
Unknown = "unknown",
OpenExternalProject = "openExternalProject",
OpenExternalProjects = "openExternalProjects",
CloseExternalProject = "closeExternalProject",
TodoComments = "todoComments",
Indentation = "indentation",
DocCommentTemplate = "docCommentTemplate",
CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects",
GetCodeFixes = "getCodeFixes",
GetSupportedCodeFixes = "getSupportedCodeFixes",
GetApplicableRefactors = "getApplicableRefactors",
GetEditsForRefactor = "getEditsForRefactor",
}
/**
* A TypeScript Server message
@@ -287,6 +289,85 @@ declare namespace ts.server.protocol {
*/
offset: number;
}
type FileLocationOrRangeRequestArgs = FileLocationRequestArgs | FileRangeRequestArgs;
/**
* Request refactorings at a given position or selection area.
*/
interface GetApplicableRefactorsRequest extends Request {
command: CommandTypes.GetApplicableRefactors;
arguments: GetApplicableRefactorsRequestArgs;
}
type GetApplicableRefactorsRequestArgs = FileLocationOrRangeRequestArgs;
/**
* Response is a list of available refactorings.
* Each refactoring exposes one or more "Actions"; a user selects one action to invoke a refactoring
*/
interface GetApplicableRefactorsResponse extends Response {
body?: ApplicableRefactorInfo[];
}
/**
* A set of one or more available refactoring actions, grouped under a parent refactoring.
*/
interface ApplicableRefactorInfo {
/**
* The programmatic name of the refactoring
*/
name: string;
/**
* A description of this refactoring category to show to the user.
* If the refactoring gets inlined (see below), this text will not be visible.
*/
description: string;
/**
* Inlineable refactorings can have their actions hoisted out to the top level
* of a context menu. Non-inlineanable refactorings should always be shown inside
* their parent grouping.
*
* If not specified, this value is assumed to be 'true'
*/
inlineable?: boolean;
actions: RefactorActionInfo[];
}
/**
* Represents a single refactoring action - for example, the "Extract Method..." refactor might
* offer several actions, each corresponding to a surround class or closure to extract into.
*/
type RefactorActionInfo = {
/**
* The programmatic name of the refactoring action
*/
name: string;
/**
* A description of this refactoring action to show to the user.
* If the parent refactoring is inlined away, this will be the only text shown,
* so this description should make sense by itself if the parent is inlineable=true
*/
description: string;
};
interface GetEditsForRefactorRequest extends Request {
command: CommandTypes.GetEditsForRefactor;
arguments: GetEditsForRefactorRequestArgs;
}
/**
* Request the edits that a particular refactoring action produces.
* Callers must specify the name of the refactor and the name of the action.
*/
type GetEditsForRefactorRequestArgs = FileLocationOrRangeRequestArgs & {
refactor: string;
action: string;
};
interface GetEditsForRefactorResponse extends Response {
body?: RefactorEditInfo;
}
type RefactorEditInfo = {
edits: FileCodeEdits[];
/**
* An optional location where the editor should start a rename operation once
* the refactoring edits have been applied
*/
renameLocation?: Location;
renameFilename?: string;
};
/**
* Request for the available codefixes at a specific position.
*/
@@ -294,10 +375,7 @@ declare namespace ts.server.protocol {
command: CommandTypes.GetCodeFixes;
arguments: CodeFixRequestArgs;
}
/**
* Instances of this interface specify errorcodes on a specific location in a sourcefile.
*/
interface CodeFixRequestArgs extends FileRequestArgs {
interface FileRangeRequestArgs extends FileRequestArgs {
/**
* The line number for the request (1-based).
*/
@@ -314,6 +392,11 @@ declare namespace ts.server.protocol {
* The character offset (on the line) for the request (1-based).
*/
endOffset: number;
}
/**
* Instances of this interface specify errorcodes on a specific location in a sourcefile.
*/
interface CodeFixRequestArgs extends FileRangeRequestArgs {
/**
* Errorcodes we want to get the fixes for.
*/
@@ -394,7 +477,7 @@ declare namespace ts.server.protocol {
command: CommandTypes.Implementation;
}
/**
* Location in source code expressed as (one-based) line and character offset.
* Location in source code expressed as (one-based) line and (one-based) column offset.
*/
interface Location {
line: number;
@@ -488,10 +571,9 @@ declare namespace ts.server.protocol {
}
/**
* Span augmented with extra information that denotes the kind of the highlighting to be used for span.
* Kind is taken from HighlightSpanKind type.
*/
interface HighlightSpan extends TextSpan {
kind: string;
kind: HighlightSpanKind;
}
/**
* Represents a set of highligh spans for a give name
@@ -609,7 +691,7 @@ declare namespace ts.server.protocol {
/**
* The items's kind (such as 'className' or 'parameterName' or plain 'text').
*/
kind: string;
kind: ScriptElementKind;
/**
* Optional modifiers for the kind (such as 'public').
*/
@@ -957,7 +1039,7 @@ declare namespace ts.server.protocol {
/**
* The symbol's kind (such as 'className' or 'parameterName' or plain 'text').
*/
kind: string;
kind: ScriptElementKind;
/**
* Optional modifiers for the kind (such as 'public').
*/
@@ -1143,7 +1225,7 @@ declare namespace ts.server.protocol {
/**
* The symbol's kind (such as 'className' or 'parameterName').
*/
kind: string;
kind: ScriptElementKind;
/**
* Optional modifiers for the kind (such as 'public').
*/
@@ -1170,7 +1252,7 @@ declare namespace ts.server.protocol {
/**
* The symbol's kind (such as 'className' or 'parameterName').
*/
kind: string;
kind: ScriptElementKind;
/**
* Optional modifiers for the kind (such as 'public').
*/
@@ -1417,6 +1499,12 @@ declare namespace ts.server.protocol {
*/
source?: string;
}
interface DiagnosticWithFileName extends Diagnostic {
/**
* Name of the file the diagnostic is in
*/
fileName: string;
}
interface DiagnosticEventBody {
/**
* The file for which diagnostic information is reported.
@@ -1446,7 +1534,7 @@ declare namespace ts.server.protocol {
/**
* An arry of diagnostic information items for the found config file.
*/
diagnostics: Diagnostic[];
diagnostics: DiagnosticWithFileName[];
}
/**
* Event message for "configFileDiag" event type.
@@ -1563,7 +1651,7 @@ declare namespace ts.server.protocol {
/**
* The symbol's kind (such as 'className' or 'parameterName').
*/
kind: string;
kind: ScriptElementKind;
/**
* exact, substring, or prefix.
*/
@@ -1596,7 +1684,7 @@ declare namespace ts.server.protocol {
/**
* Kind of symbol's container symbol (if any).
*/
containerKind?: string;
containerKind?: ScriptElementKind;
}
/**
* Navto response message. Body is an array of navto items. Each
@@ -1660,7 +1748,7 @@ declare namespace ts.server.protocol {
/**
* The symbol's kind (such as 'className' or 'parameterName').
*/
kind: string;
kind: ScriptElementKind;
/**
* Optional modifiers for the kind (such as 'public').
*/
@@ -1681,7 +1769,7 @@ declare namespace ts.server.protocol {
/** protocol.NavigationTree is identical to ts.NavigationTree, except using protocol.TextSpan instead of ts.TextSpan */
interface NavigationTree {
text: string;
kind: string;
kind: ScriptElementKind;
kindModifiers: string;
spans: TextSpan[];
childItems?: NavigationTree[];
@@ -1756,12 +1844,11 @@ declare namespace ts.server.protocol {
interface NavTreeResponse extends Response {
body?: NavigationTree;
}
namespace IndentStyle {
type None = "None";
type Block = "Block";
type Smart = "Smart";
const enum IndentStyle {
None = "None",
Block = "Block",
Smart = "Smart",
}
type IndentStyle = IndentStyle.None | IndentStyle.Block | IndentStyle.Smart;
interface EditorSettings {
baseIndentSize?: number;
indentSize?: number;
@@ -1782,6 +1869,7 @@ declare namespace ts.server.protocol {
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces?: boolean;
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
insertSpaceAfterTypeAssertion?: boolean;
insertSpaceBeforeFunctionParenthesis?: boolean;
placeOpenBraceOnNewLineForFunctions?: boolean;
placeOpenBraceOnNewLineForControlBlocks?: boolean;
@@ -1854,40 +1942,35 @@ declare namespace ts.server.protocol {
typeRoots?: string[];
[option: string]: CompilerOptionsValue | undefined;
}
namespace JsxEmit {
type None = "None";
type Preserve = "Preserve";
type ReactNative = "ReactNative";
type React = "React";
const enum JsxEmit {
None = "None",
Preserve = "Preserve",
ReactNative = "ReactNative",
React = "React",
}
type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.ReactNative;
namespace ModuleKind {
type None = "None";
type CommonJS = "CommonJS";
type AMD = "AMD";
type UMD = "UMD";
type System = "System";
type ES6 = "ES6";
type ES2015 = "ES2015";
const enum ModuleKind {
None = "None",
CommonJS = "CommonJS",
AMD = "AMD",
UMD = "UMD",
System = "System",
ES6 = "ES6",
ES2015 = "ES2015",
}
type ModuleKind = ModuleKind.None | ModuleKind.CommonJS | ModuleKind.AMD | ModuleKind.UMD | ModuleKind.System | ModuleKind.ES6 | ModuleKind.ES2015;
namespace ModuleResolutionKind {
type Classic = "Classic";
type Node = "Node";
const enum ModuleResolutionKind {
Classic = "Classic",
Node = "Node",
}
type ModuleResolutionKind = ModuleResolutionKind.Classic | ModuleResolutionKind.Node;
namespace NewLineKind {
type Crlf = "Crlf";
type Lf = "Lf";
const enum NewLineKind {
Crlf = "Crlf",
Lf = "Lf",
}
type NewLineKind = NewLineKind.Crlf | NewLineKind.Lf;
namespace ScriptTarget {
type ES3 = "ES3";
type ES5 = "ES5";
type ES6 = "ES6";
type ES2015 = "ES2015";
const enum ScriptTarget {
ES3 = "ES3",
ES5 = "ES5",
ES6 = "ES6",
ES2015 = "ES2015",
}
type ScriptTarget = ScriptTarget.ES3 | ScriptTarget.ES5 | ScriptTarget.ES6 | ScriptTarget.ES2015;
}
declare namespace ts.server.protocol {
@@ -1943,6 +2026,8 @@ declare namespace ts.server.protocol {
}
declare namespace ts {
// these types are empty stubs for types from services and should not be used directly
export type HighlightSpanKind = never;
export type ScriptElementKind = never;
export type ScriptKind = never;
export type IndentStyle = never;
export type JsxEmit = never;
+32264 -31871
View File
File diff suppressed because it is too large Load Diff
+34381 -32033
View File
File diff suppressed because it is too large Load Diff
+939 -685
View File
File diff suppressed because it is too large Load Diff
+37069 -34736
View File
File diff suppressed because it is too large Load Diff
+803 -446
View File
File diff suppressed because it is too large Load Diff
+40242 -37611
View File
File diff suppressed because it is too large Load Diff
+803 -446
View File
File diff suppressed because it is too large Load Diff
+40242 -37611
View File
File diff suppressed because it is too large Load Diff
+11502 -2323
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -13,6 +13,7 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
"use strict";
if (process.argv.length < 3) {
process.exit(1);
}
-1
View File
@@ -60,7 +60,6 @@
"gulp-newer": "latest",
"gulp-sourcemaps": "latest",
"gulp-typescript": "latest",
"into-stream": "latest",
"istanbul": "latest",
"jake": "latest",
"merge2": "latest",
+38 -165
View File
@@ -6,9 +6,7 @@ interface DiagnosticDetails {
isEarly?: boolean;
}
interface InputDiagnosticMessageTable {
[msg: string]: DiagnosticDetails;
}
type InputDiagnosticMessageTable = ts.Map<DiagnosticDetails>;
function main(): void {
var sys = ts.sys;
@@ -28,101 +26,66 @@ function main(): void {
var inputFilePath = sys.args[0].replace(/\\/g, "/");
var inputStr = sys.readFile(inputFilePath);
var diagnosticMessages: InputDiagnosticMessageTable = JSON.parse(inputStr);
var diagnosticMessagesJson: { [key: string]: DiagnosticDetails } = JSON.parse(inputStr);
// Check that there are no duplicates.
const seenNames = ts.createMap<true>();
for (const name of Object.keys(diagnosticMessagesJson)) {
if (seenNames.has(name))
throw new Error(`Name ${name} appears twice`);
seenNames.set(name, true);
}
var names = Utilities.getObjectKeys(diagnosticMessages);
var nameMap = buildUniqueNameMap(names);
const diagnosticMessages: InputDiagnosticMessageTable = ts.createMapFromTemplate(diagnosticMessagesJson);
var infoFileOutput = buildInfoFileOutput(diagnosticMessages, nameMap);
checkForUniqueCodes(names, diagnosticMessages);
var infoFileOutput = buildInfoFileOutput(diagnosticMessages);
checkForUniqueCodes(diagnosticMessages);
writeFile("diagnosticInformationMap.generated.ts", infoFileOutput);
var messageOutput = buildDiagnosticMessageOutput(diagnosticMessages, nameMap);
var messageOutput = buildDiagnosticMessageOutput(diagnosticMessages);
writeFile("diagnosticMessages.generated.json", messageOutput);
}
function checkForUniqueCodes(messages: string[], diagnosticTable: InputDiagnosticMessageTable) {
const originalMessageForCode: string[] = [];
let numConflicts = 0;
for (const currentMessage of messages) {
const code = diagnosticTable[currentMessage].code;
if (code in originalMessageForCode) {
const originalMessage = originalMessageForCode[code];
ts.sys.write("\x1b[91m"); // High intensity red.
ts.sys.write("Error");
ts.sys.write("\x1b[0m"); // Reset formatting.
ts.sys.write(`: Diagnostic code '${code}' conflicts between "${originalMessage}" and "${currentMessage}".`);
ts.sys.write(ts.sys.newLine + ts.sys.newLine);
numConflicts++;
}
else {
originalMessageForCode[code] = currentMessage;
}
}
if (numConflicts > 0) {
throw new Error(`Found ${numConflicts} conflict(s) in diagnostic codes.`);
}
function checkForUniqueCodes(diagnosticTable: InputDiagnosticMessageTable) {
const allCodes: { [key: number]: true | undefined } = [];
diagnosticTable.forEach(({ code }) => {
if (allCodes[code])
throw new Error(`Diagnostic code ${code} appears more than once.`);
allCodes[code] = true;
});
}
function buildUniqueNameMap(names: string[]): ts.Map<string> {
var nameMap = ts.createMap<string>();
var uniqueNames = NameGenerator.ensureUniqueness(names, /* isCaseSensitive */ false, /* isFixed */ undefined);
for (var i = 0; i < names.length; i++) {
nameMap.set(names[i], uniqueNames[i]);
}
return nameMap;
}
function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap: ts.Map<string>): string {
function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable): string {
var result =
'// <auto-generated />\r\n' +
'/// <reference path="types.ts" />\r\n' +
'/* @internal */\r\n' +
'namespace ts {\r\n' +
" function diag(code: number, category: DiagnosticCategory, key: string, message: string): DiagnosticMessage {\r\n" +
" return { code, category, key, message };\r\n" +
" }\r\n" +
' export const Diagnostics = {\r\n';
var names = Utilities.getObjectKeys(messageTable);
for (var i = 0; i < names.length; i++) {
var name = names[i];
var diagnosticDetails = messageTable[name];
var propName = convertPropertyName(nameMap.get(name));
result +=
' ' + propName +
': { code: ' + diagnosticDetails.code +
', category: DiagnosticCategory.' + diagnosticDetails.category +
', key: "' + createKey(propName, diagnosticDetails.code) + '"' +
', message: "' + name.replace(/[\"]/g, '\\"') + '"' +
' },\r\n';
}
messageTable.forEach(({ code, category }, name) => {
const propName = convertPropertyName(name);
result += ` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}),\r\n`;
});
result += ' };\r\n}';
return result;
}
function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable, nameMap: ts.Map<string>): string {
var result =
'{';
var names = Utilities.getObjectKeys(messageTable);
for (var i = 0; i < names.length; i++) {
var name = names[i];
var diagnosticDetails = messageTable[name];
var propName = convertPropertyName(nameMap.get(name));
function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable): string {
let result = '{';
messageTable.forEach(({ code }, name) => {
const propName = convertPropertyName(name);
result += `\r\n "${createKey(propName, code)}" : "${name.replace(/[\"]/g, '\\"')}",`;
});
result += '\r\n "' + createKey(propName, diagnosticDetails.code) + '"' + ' : "' + name.replace(/[\"]/g, '\\"') + '"';
if (i !== names.length - 1) {
result += ',';
}
}
// Shave trailing comma, then add newline and ending brace
result = result.slice(0, result.length - 1) + '\r\n}';
result += '\r\n}';
// Assert that we generated valid JSON
JSON.parse(result);
return result;
}
@@ -139,7 +102,6 @@ function convertPropertyName(origName: string): string {
return /\w/.test(char) ? char : "_";
}).join("");
// get rid of all multi-underscores
result = result.replace(/_+/g, "_");
@@ -152,93 +114,4 @@ function convertPropertyName(origName: string): string {
return result;
}
module NameGenerator {
export function ensureUniqueness(names: string[], isCaseSensitive: boolean, isFixed?: boolean[]): string[]{
if (!isFixed) {
isFixed = names.map(() => false)
}
var names = names.slice();
ensureUniquenessInPlace(names, isCaseSensitive, isFixed);
return names;
}
function ensureUniquenessInPlace(names: string[], isCaseSensitive: boolean, isFixed: boolean[]): void {
for (var i = 0; i < names.length; i++) {
var name = names[i];
var collisionIndices = Utilities.collectMatchingIndices(name, names, isCaseSensitive);
// We will always have one "collision" because getCollisionIndices returns the index of name itself as well;
// so if we only have one collision, then there are no issues.
if (collisionIndices.length < 2) {
continue;
}
handleCollisions(name, names, isFixed, collisionIndices, isCaseSensitive);
}
}
function handleCollisions(name: string, proposedNames: string[], isFixed: boolean[], collisionIndices: number[], isCaseSensitive: boolean): void {
var suffix = 1;
for (var i = 0; i < collisionIndices.length; i++) {
var collisionIndex = collisionIndices[i];
if (isFixed[collisionIndex]) {
// can't do anything about this name.
continue;
}
while (true) {
var newName = name + suffix;
suffix++;
// Check if we've synthesized a unique name, and if so
// replace the conflicting name with the new one.
if (!proposedNames.some(name => Utilities.stringEquals(name, newName, isCaseSensitive))) {
proposedNames[collisionIndex] = newName;
break;
}
}
}
}
}
module Utilities {
/// Return a list of all indices where a string occurs.
export function collectMatchingIndices(name: string, proposedNames: string[], isCaseSensitive: boolean): number[] {
var matchingIndices: number[] = [];
for (var i = 0; i < proposedNames.length; i++) {
if (stringEquals(name, proposedNames[i], isCaseSensitive)) {
matchingIndices.push(i);
}
}
return matchingIndices;
}
export function stringEquals(s1: string, s2: string, caseSensitive: boolean): boolean {
if (caseSensitive) {
s1 = s1.toLowerCase();
s2 = s2.toLowerCase();
}
return s1 == s2;
}
// Like Object.keys
export function getObjectKeys(obj: any): string[] {
var result: string[] = [];
for (var name in obj) {
if (obj.hasOwnProperty(name)) {
result.push(name);
}
}
return result;
}
}
main();
-8
View File
@@ -13,13 +13,5 @@ declare module "gulp-insert" {
export function transform(cb: (contents: string, file: {path: string, relative: string}) => string): NodeJS.ReadWriteStream; // file is a vinyl file
}
declare module "into-stream" {
function IntoStream(content: string | Buffer | (string | Buffer)[]): NodeJS.ReadableStream;
namespace IntoStream {
export function obj(content: any): NodeJS.ReadableStream
}
export = IntoStream;
}
declare module "sorcery";
declare module "travis-fold";
+35 -35
View File
@@ -242,7 +242,7 @@ namespace ts {
}
Debug.assert(isWellKnownSymbolSyntactically(nameExpression));
return getPropertyNameForKnownSymbolName(unescapeLeadingUnderscores((<PropertyAccessExpression>nameExpression).name.text));
return getPropertyNameForKnownSymbolName(unescapeLeadingUnderscores((<PropertyAccessExpression>nameExpression).name.escapedText));
}
return getEscapedTextOfIdentifierOrLiteral(<Identifier | LiteralExpression>name);
}
@@ -287,8 +287,8 @@ namespace ts {
if (parentNode && parentNode.kind === SyntaxKind.VariableStatement) {
if ((<VariableStatement>parentNode).declarationList.declarations.length > 0) {
const nameIdentifier = (<VariableStatement>parentNode).declarationList.declarations[0].name;
if (nameIdentifier.kind === SyntaxKind.Identifier) {
nameFromParentNode = (<Identifier>nameIdentifier).text;
if (isIdentifier(nameIdentifier)) {
nameFromParentNode = nameIdentifier.escapedText;
}
}
}
@@ -1031,7 +1031,7 @@ namespace ts {
function bindBreakOrContinueStatement(node: BreakOrContinueStatement): void {
bind(node.label);
if (node.label) {
const activeLabel = findActiveLabel(node.label.text);
const activeLabel = findActiveLabel(node.label.escapedText);
if (activeLabel) {
activeLabel.referenced = true;
bindBreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget);
@@ -1192,7 +1192,7 @@ namespace ts {
const postStatementLabel = createBranchLabel();
bind(node.label);
addAntecedent(preStatementLabel, currentFlow);
const activeLabel = pushActiveLabel(node.label.text, postStatementLabel, preStatementLabel);
const activeLabel = pushActiveLabel(node.label.escapedText, postStatementLabel, preStatementLabel);
bind(node.statement);
popActiveLabel();
if (!activeLabel.referenced && !options.allowUnusedLabels) {
@@ -1504,9 +1504,9 @@ namespace ts {
return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
case SyntaxKind.TypeLiteral:
case SyntaxKind.JSDocTypeLiteral:
case SyntaxKind.ObjectLiteralExpression:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.JSDocTypeLiteral:
case SyntaxKind.JsxAttributes:
// Interface/Object-types always have their children added to the 'members' of
// their container. They are only accessible through an instance of their
@@ -1649,7 +1649,7 @@ namespace ts {
const typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type);
addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral);
typeLiteralSymbol.members = createSymbolTable();
typeLiteralSymbol.members.set(symbol.name, symbol);
typeLiteralSymbol.members.set(symbol.escapedName, symbol);
}
function bindObjectLiteralExpression(node: ObjectLiteralExpression) {
@@ -1680,9 +1680,9 @@ namespace ts {
? ElementKind.Property
: ElementKind.Accessor;
const existingKind = seen.get(identifier.text);
const existingKind = seen.get(identifier.escapedText);
if (!existingKind) {
seen.set(identifier.text, currentKind);
seen.set(identifier.escapedText, currentKind);
continue;
}
@@ -1792,8 +1792,7 @@ namespace ts {
}
function isEvalOrArgumentsIdentifier(node: Node): boolean {
return node.kind === SyntaxKind.Identifier &&
((<Identifier>node).text === "eval" || (<Identifier>node).text === "arguments");
return isIdentifier(node) && (node.escapedText === "eval" || node.escapedText === "arguments");
}
function checkStrictModeEvalOrArguments(contextNode: Node, name: Node) {
@@ -1804,7 +1803,7 @@ namespace ts {
// otherwise report generic error message.
const span = getErrorSpanForNode(file, name);
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length,
getStrictModeEvalOrArgumentsMessage(contextNode), unescapeLeadingUnderscores(identifier.text)));
getStrictModeEvalOrArgumentsMessage(contextNode), unescapeLeadingUnderscores(identifier.escapedText)));
}
}
}
@@ -2104,8 +2103,9 @@ namespace ts {
case SyntaxKind.ConstructorType:
return bindFunctionOrConstructorType(<SignatureDeclaration>node);
case SyntaxKind.TypeLiteral:
case SyntaxKind.JSDocTypeLiteral:
case SyntaxKind.MappedType:
return bindAnonymousTypeWorker(node as TypeLiteralNode | MappedTypeNode);
return bindAnonymousTypeWorker(node as TypeLiteralNode | MappedTypeNode | JSDocTypeLiteral);
case SyntaxKind.ObjectLiteralExpression:
return bindObjectLiteralExpression(<ObjectLiteralExpression>node);
case SyntaxKind.FunctionExpression:
@@ -2163,13 +2163,17 @@ namespace ts {
case SyntaxKind.ModuleBlock:
return updateStrictModeStatementList((<Block | ModuleBlock>node).statements);
case SyntaxKind.JSDocParameterTag:
if (node.parent.kind !== SyntaxKind.JSDocTypeLiteral) {
break;
}
// falls through
case SyntaxKind.JSDocPropertyTag:
return declareSymbolAndAddToSymbolTable(node as JSDocPropertyTag,
(node as JSDocPropertyTag).isBracketed || ((node as JSDocPropertyTag).typeExpression && (node as JSDocPropertyTag).typeExpression.type.kind === SyntaxKind.JSDocOptionalType) ?
SymbolFlags.Property | SymbolFlags.Optional : SymbolFlags.Property,
SymbolFlags.PropertyExcludes);
case SyntaxKind.JSDocTypeLiteral:
return bindAnonymousTypeWorker(node as JSDocTypeLiteral);
const propTag = node as JSDocPropertyLikeTag;
const flags = propTag.isBracketed || propTag.typeExpression.type.kind === SyntaxKind.JSDocOptionalType ?
SymbolFlags.Property | SymbolFlags.Optional :
SymbolFlags.Property;
return declareSymbolAndAddToSymbolTable(propTag, flags, SymbolFlags.PropertyExcludes);
case SyntaxKind.JSDocTypedefTag: {
const { fullName } = node as JSDocTypedefTag;
if (!fullName || fullName.kind === SyntaxKind.Identifier) {
@@ -2295,14 +2299,10 @@ namespace ts {
}
function isNameOfExportsOrModuleExportsAliasDeclaration(node: Node) {
if (node.kind === SyntaxKind.Identifier) {
const symbol = lookupSymbolForName((<Identifier>node).text);
if (symbol && symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.VariableDeclaration) {
const declaration = symbol.valueDeclaration as VariableDeclaration;
if (declaration.initializer) {
return isExportsOrModuleExportsOrAliasOrAssignment(declaration.initializer);
}
}
if (isIdentifier(node)) {
const symbol = lookupSymbolForName(node.escapedText);
return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) &&
symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(symbol.valueDeclaration.initializer);
}
return false;
}
@@ -2369,7 +2369,7 @@ namespace ts {
constructorFunction.parent = classPrototype;
classPrototype.parent = leftSideOfAssignment;
bindPropertyAssignment(constructorFunction.text, leftSideOfAssignment, /*isPrototypeProperty*/ true);
bindPropertyAssignment(constructorFunction.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ true);
}
function bindStaticPropertyAssignment(node: BinaryExpression) {
@@ -2391,7 +2391,7 @@ namespace ts {
bindExportsPropertyAssignment(node);
}
else {
bindPropertyAssignment(target.text, leftSideOfAssignment, /*isPrototypeProperty*/ false);
bindPropertyAssignment(target.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ false);
}
}
@@ -2432,11 +2432,11 @@ namespace ts {
bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
}
else {
const bindingName = node.name ? node.name.text : InternalSymbolName.Class;
const bindingName = node.name ? node.name.escapedText : InternalSymbolName.Class;
bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName);
// Add name of class expression into the map for semantic classifier
if (node.name) {
classifiableNames.set(node.name.text, true);
classifiableNames.set(node.name.escapedText, true);
}
}
@@ -2452,14 +2452,14 @@ namespace ts {
// module might have an exported variable called 'prototype'. We can't allow that as
// that would clash with the built-in 'prototype' for the class.
const prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype" as __String);
const symbolExport = symbol.exports.get(prototypeSymbol.name);
const symbolExport = symbol.exports.get(prototypeSymbol.escapedName);
if (symbolExport) {
if (node.name) {
node.name.parent = node;
}
file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], Diagnostics.Duplicate_identifier_0, unescapeLeadingUnderscores(prototypeSymbol.name)));
file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], Diagnostics.Duplicate_identifier_0, unescapeLeadingUnderscores(prototypeSymbol.escapedName)));
}
symbol.exports.set(prototypeSymbol.name, prototypeSymbol);
symbol.exports.set(prototypeSymbol.escapedName, prototypeSymbol);
prototypeSymbol.parent = symbol;
}
@@ -2545,7 +2545,7 @@ namespace ts {
node.flowNode = currentFlow;
}
checkStrictModeFunctionName(node);
const bindingName = node.name ? node.name.text : InternalSymbolName.Function;
const bindingName = node.name ? node.name.escapedText : InternalSymbolName.Function;
return bindAnonymousDeclaration(node, SymbolFlags.Function, bindingName);
}
+465 -328
View File
File diff suppressed because it is too large Load Diff
+73 -81
View File
@@ -728,12 +728,12 @@ namespace ts {
}
/* @internal */
export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) {
export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string, errors: Push<Diagnostic>) {
return convertJsonOptionOfCustomType(opt, trimString(value || ""), errors);
}
/* @internal */
export function parseListTypeOption(opt: CommandLineOptionOfListType, value = "", errors: Diagnostic[]): (string | number)[] | undefined {
export function parseListTypeOption(opt: CommandLineOptionOfListType, value = "", errors: Push<Diagnostic>): (string | number)[] | undefined {
value = trimString(value);
if (startsWith(value, "-")) {
return undefined;
@@ -752,7 +752,7 @@ namespace ts {
}
}
export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string | undefined): ParsedCommandLine {
export function parseCommandLine(commandLine: ReadonlyArray<string>, readFile?: (path: string) => string | undefined): ParsedCommandLine {
const options: CompilerOptions = {};
const fileNames: string[] = [];
const errors: Diagnostic[] = [];
@@ -764,7 +764,7 @@ namespace ts {
errors
};
function parseStrings(args: string[]) {
function parseStrings(args: ReadonlyArray<string>) {
let i = 0;
while (i < args.length) {
const s = args[i];
@@ -916,7 +916,7 @@ namespace ts {
return text === undefined ? createCompilerDiagnostic(Diagnostics.The_specified_path_does_not_exist_Colon_0, fileName) : text;
}
function commandLineOptionsToMap(options: CommandLineOption[]) {
function commandLineOptionsToMap(options: ReadonlyArray<CommandLineOption>) {
return arrayToMap(options, option => option.name);
}
@@ -1007,7 +1007,7 @@ namespace ts {
/**
* Convert the json syntax tree into the json value
*/
export function convertToObject(sourceFile: JsonSourceFile, errors: Diagnostic[]): any {
export function convertToObject(sourceFile: JsonSourceFile, errors: Push<Diagnostic>): any {
return convertToObjectWorker(sourceFile, errors, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
}
@@ -1016,7 +1016,7 @@ namespace ts {
*/
function convertToObjectWorker(
sourceFile: JsonSourceFile,
errors: Diagnostic[],
errors: Push<Diagnostic>,
knownRootOptions: Map<CommandLineOption> | undefined,
jsonConversionNotifier: JsonConversionNotifier | undefined): any {
if (!sourceFile.jsonObject) {
@@ -1085,11 +1085,7 @@ namespace ts {
elements: NodeArray<Expression>,
elementOption: CommandLineOption | undefined
): any[] {
const result: any[] = [];
for (const element of elements) {
result.push(convertPropertyValueToJson(element, elementOption));
}
return result;
return elements.map(element => convertPropertyValueToJson(element, elementOption));
}
function convertPropertyValueToJson(valueExpression: Expression, option: CommandLineOption): any {
@@ -1202,17 +1198,9 @@ namespace ts {
* @param fileNames array of filenames to be generated into tsconfig.json
*/
/* @internal */
export function generateTSConfig(options: CompilerOptions, fileNames: string[], newLine: string): string {
export function generateTSConfig(options: CompilerOptions, fileNames: ReadonlyArray<string>, newLine: string): string {
const compilerOptions = extend(options, defaultInitCompilerOptions);
const configurations: { compilerOptions: MapLike<CompilerOptionsValue>; files?: string[] } = {
compilerOptions: serializeCompilerOptions(compilerOptions)
};
if (fileNames && fileNames.length) {
// only set the files property if we have at least one file
configurations.files = fileNames;
}
const compilerOptionsMap = serializeCompilerOptions(compilerOptions);
return writeConfigurations();
function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): Map<string | number> | undefined {
@@ -1237,8 +1225,8 @@ namespace ts {
});
}
function serializeCompilerOptions(options: CompilerOptions): MapLike<CompilerOptionsValue> {
const result: ts.MapLike<CompilerOptionsValue> = {};
function serializeCompilerOptions(options: CompilerOptions): Map<CompilerOptionsValue> {
const result = createMap<CompilerOptionsValue>();
const optionsNameMap = getOptionNameMap().optionNameMap;
for (const name in options) {
@@ -1255,19 +1243,15 @@ namespace ts {
if (!customTypeMap) {
// There is no map associated with this compiler option then use the value as-is
// This is the case if the value is expect to be string, number, boolean or list of string
result[name] = value;
result.set(name, value);
}
else {
if (optionDefinition.type === "list") {
const convertedValue: string[] = [];
for (const element of value as (string | number)[]) {
convertedValue.push(getNameOfCompilerOptionValue(element, customTypeMap));
}
result[name] = convertedValue;
result.set(name, (value as ReadonlyArray<string | number>).map(element => getNameOfCompilerOptionValue(element, customTypeMap)));
}
else {
// There is a typeMap associated with this command-line option so use it to map value back to its name
result[name] = getNameOfCompilerOptionValue(value, customTypeMap);
result.set(name, getNameOfCompilerOptionValue(value, customTypeMap));
}
}
}
@@ -1299,33 +1283,30 @@ namespace ts {
function writeConfigurations() {
// Filter applicable options to place in the file
const categorizedOptions = reduceLeft(
filter(optionDeclarations, o => o.category !== Diagnostics.Command_line_Options && o.category !== Diagnostics.Advanced_Options),
(memo, value) => {
if (value.category) {
const name = getLocaleSpecificMessage(value.category);
(memo[name] || (memo[name] = [])).push(value);
}
return memo;
}, <MapLike<CommandLineOption[]>>{});
const categorizedOptions = createMultiMap<CommandLineOption>();
for (const option of optionDeclarations) {
const { category } = option;
if (category !== undefined && category !== Diagnostics.Command_line_Options && category !== Diagnostics.Advanced_Options) {
categorizedOptions.add(getLocaleSpecificMessage(category), option);
}
}
// Serialize all options and thier descriptions
// Serialize all options and their descriptions
let marginLength = 0;
let seenKnownKeys = 0;
const nameColumn: string[] = [];
const descriptionColumn: string[] = [];
const knownKeysCount = getOwnKeys(configurations.compilerOptions).length;
for (const category in categorizedOptions) {
categorizedOptions.forEach((options, category) => {
if (nameColumn.length !== 0) {
nameColumn.push("");
descriptionColumn.push("");
}
nameColumn.push(`/* ${category} */`);
descriptionColumn.push("");
for (const option of categorizedOptions[category]) {
for (const option of options) {
let optionName;
if (hasProperty(configurations.compilerOptions, option.name)) {
optionName = `"${option.name}": ${JSON.stringify(configurations.compilerOptions[option.name])}${(seenKnownKeys += 1) === knownKeysCount ? "" : ","}`;
if (compilerOptionsMap.has(option.name)) {
optionName = `"${option.name}": ${JSON.stringify(compilerOptionsMap.get(option.name))}${(seenKnownKeys += 1) === compilerOptionsMap.size ? "" : ","}`;
}
else {
optionName = `// "${option.name}": ${JSON.stringify(getDefaultValueForOption(option))},`;
@@ -1334,7 +1315,7 @@ namespace ts {
descriptionColumn.push(`/* ${option.description && getLocaleSpecificMessage(option.description) || option.name} */`);
marginLength = Math.max(optionName.length, marginLength);
}
}
});
// Write the output
const tab = makePadding(2);
@@ -1347,11 +1328,11 @@ namespace ts {
const description = descriptionColumn[i];
result.push(optionName && `${tab}${tab}${optionName}${ description && (makePadding(marginLength - optionName.length + 2) + description)}`);
}
if (configurations.files && configurations.files.length) {
if (fileNames.length) {
result.push(`${tab}},`);
result.push(`${tab}"files": [`);
for (let i = 0; i < configurations.files.length; i++) {
result.push(`${tab}${tab}${JSON.stringify(configurations.files[i])}${i === configurations.files.length - 1 ? "" : ","}`);
for (let i = 0; i < fileNames.length; i++) {
result.push(`${tab}${tab}${JSON.stringify(fileNames[i])}${i === fileNames.length - 1 ? "" : ","}`);
}
result.push(`${tab}]`);
}
@@ -1371,7 +1352,7 @@ namespace ts {
* @param basePath A root directory to resolve relative path entries in the config
* file to. e.g. outDir
*/
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: JsFileExtensionInfo[]): ParsedCommandLine {
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: ReadonlyArray<JsFileExtensionInfo>): ParsedCommandLine {
return parseJsonConfigFileContentWorker(json, /*sourceFile*/ undefined, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions);
}
@@ -1382,7 +1363,7 @@ namespace ts {
* @param basePath A root directory to resolve relative path entries in the config
* file to. e.g. outDir
*/
export function parseJsonSourceFileConfigFileContent(sourceFile: JsonSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: JsFileExtensionInfo[]): ParsedCommandLine {
export function parseJsonSourceFileConfigFileContent(sourceFile: JsonSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: ReadonlyArray<JsFileExtensionInfo>): ParsedCommandLine {
return parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions);
}
@@ -1410,7 +1391,7 @@ namespace ts {
existingOptions: CompilerOptions = {},
configFileName?: string,
resolutionStack: Path[] = [],
extraFileExtensions: JsFileExtensionInfo[] = [],
extraFileExtensions: ReadonlyArray<JsFileExtensionInfo> = [],
): ParsedCommandLine {
Debug.assert((json === undefined && sourceFile !== undefined) || (json !== undefined && sourceFile === undefined));
const errors: Diagnostic[] = [];
@@ -1434,10 +1415,10 @@ namespace ts {
};
function getFileNames(): ExpandResult {
let filesSpecs: string[];
let filesSpecs: ReadonlyArray<string>;
if (hasProperty(raw, "files")) {
if (isArray(raw["files"])) {
filesSpecs = <string[]>raw["files"];
filesSpecs = <ReadonlyArray<string>>raw["files"];
if (filesSpecs.length === 0) {
createCompilerDiagnosticOnlyIfJson(Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json");
}
@@ -1447,20 +1428,20 @@ namespace ts {
}
}
let includeSpecs: string[];
let includeSpecs: ReadonlyArray<string>;
if (hasProperty(raw, "include")) {
if (isArray(raw["include"])) {
includeSpecs = <string[]>raw["include"];
includeSpecs = <ReadonlyArray<string>>raw["include"];
}
else {
createCompilerDiagnosticOnlyIfJson(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "include", "Array");
}
}
let excludeSpecs: string[];
let excludeSpecs: ReadonlyArray<string>;
if (hasProperty(raw, "exclude")) {
if (isArray(raw["exclude"])) {
excludeSpecs = <string[]>raw["exclude"];
excludeSpecs = <ReadonlyArray<string>>raw["exclude"];
}
else {
createCompilerDiagnosticOnlyIfJson(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "exclude", "Array");
@@ -1468,12 +1449,13 @@ namespace ts {
}
else {
// If no includes were specified, exclude common package folders and the outDir
excludeSpecs = includeSpecs ? [] : ["node_modules", "bower_components", "jspm_packages"];
const specs = includeSpecs ? [] : ["node_modules", "bower_components", "jspm_packages"];
const outDir = raw["compilerOptions"] && raw["compilerOptions"]["outDir"];
if (outDir) {
excludeSpecs.push(outDir);
specs.push(outDir);
}
excludeSpecs = specs;
}
if (filesSpecs === undefined && includeSpecs === undefined) {
@@ -1527,7 +1509,7 @@ namespace ts {
configFileName: string,
getCanonicalFileName: (fileName: string) => string,
resolutionStack: Path[],
errors: Diagnostic[],
errors: Push<Diagnostic>,
): ParsedTsconfig {
basePath = normalizeSlashes(basePath);
const resolvedPath = toPath(configFileName || "", basePath, getCanonicalFileName);
@@ -1575,7 +1557,7 @@ namespace ts {
basePath: string,
getCanonicalFileName: (fileName: string) => string,
configFileName: string,
errors: Diagnostic[]
errors: Push<Diagnostic>
): ParsedTsconfig {
if (hasProperty(json, "excludes")) {
errors.push(createCompilerDiagnostic(Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
@@ -1605,7 +1587,7 @@ namespace ts {
basePath: string,
getCanonicalFileName: (fileName: string) => string,
configFileName: string,
errors: Diagnostic[]
errors: Push<Diagnostic>
): ParsedTsconfig {
const options = getDefaultCompilerOptions(configFileName);
let typeAcquisition: TypeAcquisition, typingOptionstypeAcquisition: TypeAcquisition;
@@ -1636,7 +1618,7 @@ namespace ts {
);
return;
case "files":
if ((<string[]>value).length === 0) {
if ((<ReadonlyArray<string>>value).length === 0) {
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, valueNode, Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json"));
}
return;
@@ -1672,7 +1654,7 @@ namespace ts {
host: ParseConfigHost,
basePath: string,
getCanonicalFileName: (fileName: string) => string,
errors: Diagnostic[],
errors: Push<Diagnostic>,
createDiagnostic: (message: DiagnosticMessage, arg1?: string) => Diagnostic) {
extendedConfig = normalizeSlashes(extendedConfig);
// If the path isn't a rooted or relative path, don't try to resolve it (we reserve the right to special case module-id like paths in the future)
@@ -1698,7 +1680,7 @@ namespace ts {
basePath: string,
getCanonicalFileName: (fileName: string) => string,
resolutionStack: Path[],
errors: Diagnostic[],
errors: Push<Diagnostic>,
): ParsedTsconfig | undefined {
const extendedResult = readJsonConfigFile(extendedConfigPath, path => host.readFile(path));
if (sourceFile) {
@@ -1735,7 +1717,7 @@ namespace ts {
return extendedConfig;
}
function convertCompileOnSaveOptionFromJson(jsonOption: any, basePath: string, errors: Diagnostic[]): boolean {
function convertCompileOnSaveOptionFromJson(jsonOption: any, basePath: string, errors: Push<Diagnostic>): boolean {
if (!hasProperty(jsonOption, compileOnSaveCommandLineOption.name)) {
return undefined;
}
@@ -1766,7 +1748,7 @@ namespace ts {
}
function convertCompilerOptionsFromJsonWorker(jsonOptions: any,
basePath: string, errors: Diagnostic[], configFileName?: string): CompilerOptions {
basePath: string, errors: Push<Diagnostic>, configFileName?: string): CompilerOptions {
const options = getDefaultCompilerOptions(configFileName);
convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_compiler_option_0, errors);
@@ -1779,7 +1761,7 @@ namespace ts {
}
function convertTypeAcquisitionFromJsonWorker(jsonOptions: any,
basePath: string, errors: Diagnostic[], configFileName?: string): TypeAcquisition {
basePath: string, errors: Push<Diagnostic>, configFileName?: string): TypeAcquisition {
const options = getDefaultTypeAcquisition(configFileName);
const typeAcquisition = convertEnableAutoDiscoveryToEnable(jsonOptions);
@@ -1788,8 +1770,8 @@ namespace ts {
return options;
}
function convertOptionsFromJson(optionDeclarations: CommandLineOption[], jsonOptions: any, basePath: string,
defaultOptions: CompilerOptions | TypeAcquisition, diagnosticMessage: DiagnosticMessage, errors: Diagnostic[]) {
function convertOptionsFromJson(optionDeclarations: ReadonlyArray<CommandLineOption>, jsonOptions: any, basePath: string,
defaultOptions: CompilerOptions | TypeAcquisition, diagnosticMessage: DiagnosticMessage, errors: Push<Diagnostic>) {
if (!jsonOptions) {
return;
@@ -1808,7 +1790,7 @@ namespace ts {
}
}
function convertJsonOption(opt: CommandLineOption, value: any, basePath: string, errors: Diagnostic[]): CompilerOptionsValue {
function convertJsonOption(opt: CommandLineOption, value: any, basePath: string, errors: Push<Diagnostic>): CompilerOptionsValue {
if (isCompilerOptionsValue(opt, value)) {
const optType = opt.type;
if (optType === "list" && isArray(value)) {
@@ -1848,7 +1830,7 @@ namespace ts {
return value;
}
function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) {
function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value: string, errors: Push<Diagnostic>) {
const key = value.toLowerCase();
const val = opt.type.get(key);
if (val !== undefined) {
@@ -1859,7 +1841,7 @@ namespace ts {
}
}
function convertJsonOptionOfListType(option: CommandLineOptionOfListType, values: any[], basePath: string, errors: Diagnostic[]): any[] {
function convertJsonOptionOfListType(option: CommandLineOptionOfListType, values: ReadonlyArray<any>, basePath: string, errors: Push<Diagnostic>): any[] {
return filter(map(values, v => convertJsonOption(option.element, v, basePath, errors)), v => !!v);
}
@@ -1950,9 +1932,19 @@ namespace ts {
* @param host The host used to resolve files and directories.
* @param errors An array for diagnostic reporting.
*/
function matchFileNames(filesSpecs: string[], includeSpecs: string[], excludeSpecs: string[], basePath: string, options: CompilerOptions, host: ParseConfigHost, errors: Diagnostic[], extraFileExtensions: JsFileExtensionInfo[], jsonSourceFile: JsonSourceFile): ExpandResult {
function matchFileNames(
filesSpecs: ReadonlyArray<string>,
includeSpecs: ReadonlyArray<string>,
excludeSpecs: ReadonlyArray<string>,
basePath: string,
options: CompilerOptions,
host: ParseConfigHost,
errors: Push<Diagnostic>,
extraFileExtensions: ReadonlyArray<JsFileExtensionInfo>,
jsonSourceFile: JsonSourceFile
): ExpandResult {
basePath = normalizePath(basePath);
let validatedIncludeSpecs: string[], validatedExcludeSpecs: string[];
let validatedIncludeSpecs: ReadonlyArray<string>, validatedExcludeSpecs: ReadonlyArray<string>;
// The exclude spec list is converted into a regular expression, which allows us to quickly
// test whether a file or directory should be excluded before recursively traversing the
@@ -1987,7 +1979,7 @@ namespace ts {
* @param host The host used to resolve files and directories.
* @param errors An array for diagnostic reporting.
*/
export function getFileNamesFromConfigSpecs(spec: ConfigFileSpecs, basePath: string, options: CompilerOptions, host: ParseConfigHost, extraFileExtensions: JsFileExtensionInfo[]): ExpandResult {
export function getFileNamesFromConfigSpecs(spec: ConfigFileSpecs, basePath: string, options: CompilerOptions, host: ParseConfigHost, extraFileExtensions: ReadonlyArray<JsFileExtensionInfo>): ExpandResult {
basePath = normalizePath(basePath);
const keyMapper = host.useCaseSensitiveFileNames ? caseSensitiveKeyMapper : caseInsensitiveKeyMapper;
@@ -2051,7 +2043,7 @@ namespace ts {
};
}
function validateSpecs(specs: string[], errors: Diagnostic[], allowTrailingRecursion: boolean, jsonSourceFile: JsonSourceFile, specKey: string) {
function validateSpecs(specs: ReadonlyArray<string>, errors: Push<Diagnostic>, allowTrailingRecursion: boolean, jsonSourceFile: JsonSourceFile, specKey: string): ReadonlyArray<string> {
const validSpecs: string[] = [];
for (const spec of specs) {
if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) {
@@ -2075,7 +2067,7 @@ namespace ts {
for (const property of getPropertyAssignment(jsonSourceFile.jsonObject, specKey)) {
if (isArrayLiteralExpression(property.initializer)) {
for (const element of property.initializer.elements) {
if (element.kind === SyntaxKind.StringLiteral && (<StringLiteral>element).text === spec) {
if (isStringLiteral(element) && element.text === spec) {
return createDiagnosticForNodeInSourceFile(jsonSourceFile, element, message, spec);
}
}
@@ -2089,7 +2081,7 @@ namespace ts {
/**
* Gets directories in a set of include patterns that should be watched for changes.
*/
function getWildcardDirectories(include: string[], exclude: string[], path: string, useCaseSensitiveFileNames: boolean): MapLike<WatchDirectoryFlags> {
function getWildcardDirectories(include: ReadonlyArray<string>, exclude: ReadonlyArray<string>, path: string, useCaseSensitiveFileNames: boolean): MapLike<WatchDirectoryFlags> {
// We watch a directory recursively if it contains a wildcard anywhere in a directory segment
// of the pattern:
//
+3 -3
View File
@@ -59,7 +59,7 @@ namespace ts {
const result = createMap<Symbol>() as SymbolTable;
if (symbols) {
for (const symbol of symbols) {
result.set(symbol.name, symbol);
result.set(symbol.escapedName, symbol);
}
}
return result;
@@ -718,7 +718,7 @@ namespace ts {
* are not present in `arrayA` but are present in `arrayB`. Assumes both arrays are sorted
* based on the provided comparer.
*/
export function relativeComplement<T>(arrayA: T[] | undefined, arrayB: T[] | undefined, comparer: (x: T, y: T) => Comparison = compareValues, offsetA = 0, offsetB = 0): T[] | undefined {
export function relativeComplement<T>(arrayA: T[] | undefined, arrayB: T[] | undefined, comparer: Comparer<T> = compareValues, offsetA = 0, offsetB = 0): T[] | undefined {
if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0) return arrayB;
const result: T[] = [];
outer: for (; offsetB < arrayB.length; offsetB++) {
@@ -2313,7 +2313,7 @@ namespace ts {
function Symbol(this: Symbol, flags: SymbolFlags, name: __String) {
this.flags = flags;
this.name = name;
this.escapedName = name;
this.declarations = undefined;
}
+1 -1
View File
@@ -1164,7 +1164,7 @@ namespace ts {
if (baseTypeNode && !isEntityNameExpression(baseTypeNode.expression)) {
tempVarName = baseTypeNode.expression.kind === SyntaxKind.NullKeyword ?
"null" :
emitTempVariableDeclaration(baseTypeNode.expression, `${node.name.text}_base`, {
emitTempVariableDeclaration(baseTypeNode.expression, `${node.name.escapedText}_base`, {
diagnosticMessage: Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1,
errorNode: baseTypeNode,
typeName: node.name
+12
View File
@@ -2192,6 +2192,10 @@
"category": "Error",
"code": 2712
},
"Cannot access '{0}.{1}' because '{0}' is a type, but not a namespace. Did you mean to retrieve the type of the property '{1}' in '{0}' with '{0}[\"{1}\"]'?": {
"category": "Error",
"code": 2713
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
@@ -3451,6 +3455,10 @@
"category": "Error",
"code": 8012
},
"'non-null assertions' can only be used in a .ts file.": {
"category": "Error",
"code": 8013
},
"'enum declarations' can only be used in a .ts file.": {
"category": "Error",
"code": 8015
@@ -3649,6 +3657,10 @@
"category": "Message",
"code": 90025
},
"Rewrite as the indexed access type '{0}'.": {
"category": "Message",
"code": 90026
},
"Convert function to an ES2015 class": {
"category": "Message",
+6 -4
View File
@@ -1346,7 +1346,9 @@ namespace ts {
emitExpression(node.left);
increaseIndentIf(indentBeforeOperator, isCommaOperator ? " " : undefined);
emitLeadingCommentsOfPosition(node.operatorToken.pos);
writeTokenNode(node.operatorToken);
emitTrailingCommentsOfPosition(node.operatorToken.end);
increaseIndentIf(indentAfterOperator, " ");
emitExpression(node.right);
decreaseIndentIf(indentBeforeOperator, indentAfterOperator);
@@ -2761,7 +2763,7 @@ namespace ts {
return generateName(node);
}
else if (isIdentifier(node) && (nodeIsSynthesized(node) || !node.parent)) {
return unescapeLeadingUnderscores(node.text);
return unescapeLeadingUnderscores(node.escapedText);
}
else if (node.kind === SyntaxKind.StringLiteral && (<StringLiteral>node).textSourceNode) {
return getTextOfNode((<StringLiteral>node).textSourceNode, includeTrivia);
@@ -2917,8 +2919,8 @@ namespace ts {
*/
function generateNameForImportOrExportDeclaration(node: ImportDeclaration | ExportDeclaration) {
const expr = getExternalModuleName(node);
const baseName = expr.kind === SyntaxKind.StringLiteral ?
makeIdentifierFromModuleName((<LiteralExpression>expr).text) : "module";
const baseName = isStringLiteral(expr) ?
makeIdentifierFromModuleName(expr.text) : "module";
return makeUniqueName(baseName);
}
@@ -2981,7 +2983,7 @@ namespace ts {
case GeneratedIdentifierKind.Loop:
return makeTempVariableName(TempFlags._i);
case GeneratedIdentifierKind.Unique:
return makeUniqueName(unescapeLeadingUnderscores(name.text));
return makeUniqueName(unescapeLeadingUnderscores(name.escapedText));
}
Debug.fail("Unsupported GeneratedIdentifierKind.");
+6 -6
View File
@@ -114,7 +114,7 @@ namespace ts {
export function createIdentifier(text: string, typeArguments: ReadonlyArray<TypeNode>): Identifier;
export function createIdentifier(text: string, typeArguments?: ReadonlyArray<TypeNode>): Identifier {
const node = <Identifier>createSynthesizedNode(SyntaxKind.Identifier);
node.text = escapeLeadingUnderscores(text);
node.escapedText = escapeLeadingUnderscores(text);
node.originalKeywordKind = text ? stringToToken(text) : SyntaxKind.Unknown;
node.autoGenerateKind = GeneratedIdentifierKind.None;
node.autoGenerateId = 0;
@@ -126,7 +126,7 @@ namespace ts {
export function updateIdentifier(node: Identifier, typeArguments: NodeArray<TypeNode> | undefined): Identifier {
return node.typeArguments !== typeArguments
? updateNode(createIdentifier(unescapeLeadingUnderscores(node.text), typeArguments), node)
? updateNode(createIdentifier(unescapeLeadingUnderscores(node.escapedText), typeArguments), node)
: node;
}
@@ -2863,12 +2863,12 @@ namespace ts {
function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement): Expression {
if (isQualifiedName(jsxFactory)) {
const left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent);
const right = createIdentifier(unescapeLeadingUnderscores(jsxFactory.right.text));
right.text = jsxFactory.right.text;
const right = createIdentifier(unescapeLeadingUnderscores(jsxFactory.right.escapedText));
right.escapedText = jsxFactory.right.escapedText;
return createPropertyAccess(left, right);
}
else {
return createReactNamespace(unescapeLeadingUnderscores(jsxFactory.text), parent);
return createReactNamespace(unescapeLeadingUnderscores(jsxFactory.escapedText), parent);
}
}
@@ -3477,7 +3477,7 @@ namespace ts {
}
function isUseStrictPrologue(node: ExpressionStatement): boolean {
return (node.expression as StringLiteral).text === "use strict";
return isStringLiteral(node.expression) && node.expression.text === "use strict";
}
/**
+2 -6
View File
@@ -13,12 +13,6 @@ namespace ts {
return compilerOptions.traceResolution && host.trace !== undefined;
}
/** Array that is only intended to be pushed to, never read. */
/* @internal */
export interface Push<T> {
push(value: T): void;
}
/**
* Result of trying to resolve a module.
* At least one of `ts` and `js` should be defined, or the whole thing should be `undefined`.
@@ -262,6 +256,8 @@ namespace ts {
for (const typeDirectivePath of host.getDirectories(root)) {
const normalized = normalizePath(typeDirectivePath);
const packageJsonPath = pathToPackageJson(combinePaths(root, normalized));
// `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types.
// See `createNotNeededPackageJSON` in the types-publisher` repo.
// tslint:disable-next-line:no-null-keyword
const isNotNeededPackage = host.fileExists(packageJsonPath) && readJson(packageJsonPath, host).typings === null;
if (!isNotNeededPackage) {
+271 -151
View File
@@ -59,6 +59,9 @@ namespace ts {
* @param node a given node to visit its children
* @param cbNode a callback to be invoked for all child nodes
* @param cbNodes a callback to be invoked for embedded array
*
* @remarks `forEachChild` must visit the children of a node in the order
* that they appear in the source code. The language service depends on this property to locate nodes by position.
*/
export function forEachChild<T>(node: Node, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray<Node>) => T | undefined): T | undefined {
if (!node || node.kind <= SyntaxKind.LastToken) {
@@ -407,9 +410,15 @@ namespace ts {
case SyntaxKind.JSDocComment:
return visitNodes(cbNode, cbNodes, (<JSDoc>node).tags);
case SyntaxKind.JSDocParameterTag:
return visitNode(cbNode, (<JSDocParameterTag>node).preParameterName) ||
visitNode(cbNode, (<JSDocParameterTag>node).typeExpression) ||
visitNode(cbNode, (<JSDocParameterTag>node).postParameterName);
case SyntaxKind.JSDocPropertyTag:
if ((node as JSDocPropertyLikeTag).isNameFirst) {
return visitNode(cbNode, (<JSDocPropertyLikeTag>node).name) ||
visitNode(cbNode, (<JSDocPropertyLikeTag>node).typeExpression);
}
else {
return visitNode(cbNode, (<JSDocPropertyLikeTag>node).typeExpression) ||
visitNode(cbNode, (<JSDocPropertyLikeTag>node).name);
}
case SyntaxKind.JSDocReturnTag:
return visitNode(cbNode, (<JSDocReturnTag>node).typeExpression);
case SyntaxKind.JSDocTypeTag:
@@ -419,15 +428,20 @@ namespace ts {
case SyntaxKind.JSDocTemplateTag:
return visitNodes(cbNode, cbNodes, (<JSDocTemplateTag>node).typeParameters);
case SyntaxKind.JSDocTypedefTag:
return visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression) ||
visitNode(cbNode, (<JSDocTypedefTag>node).fullName) ||
visitNode(cbNode, (<JSDocTypedefTag>node).name) ||
visitNode(cbNode, (<JSDocTypedefTag>node).jsDocTypeLiteral);
if ((node as JSDocTypedefTag).typeExpression &&
(node as JSDocTypedefTag).typeExpression.kind === SyntaxKind.JSDocTypeExpression) {
return visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression) ||
visitNode(cbNode, (<JSDocTypedefTag>node).fullName);
}
else {
return visitNode(cbNode, (<JSDocTypedefTag>node).fullName) ||
visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression);
}
case SyntaxKind.JSDocTypeLiteral:
return visitNodes(cbNode, cbNodes, (<JSDocTypeLiteral>node).jsDocPropertyTags);
case SyntaxKind.JSDocPropertyTag:
return visitNode(cbNode, (<JSDocPropertyTag>node).typeExpression) ||
visitNode(cbNode, (<JSDocPropertyTag>node).name);
for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags) {
visitNode(cbNode, tag);
}
return;
case SyntaxKind.PartiallyEmittedExpression:
return visitNode(cbNode, (<PartiallyEmittedExpression>node).expression);
}
@@ -1149,7 +1163,7 @@ namespace ts {
return node;
}
function createMissingNode(kind: SyntaxKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Node {
function createMissingNode<T extends Node>(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): T {
if (reportAtCurrentPosition) {
parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0);
}
@@ -1158,8 +1172,15 @@ namespace ts {
}
const result = createNode(kind, scanner.getStartPos());
(<Identifier>result).text = "" as __String;
return finishNode(result);
if (kind === SyntaxKind.Identifier) {
(result as Identifier).escapedText = "" as __String;
}
else if (isLiteralKind(kind) || isTemplateLiteralKind(kind)) {
(result as LiteralLikeNode).text = "";
}
return finishNode(result) as T;
}
function internIdentifier(text: string): string {
@@ -1182,12 +1203,12 @@ namespace ts {
if (token() !== SyntaxKind.Identifier) {
node.originalKeywordKind = token();
}
node.text = escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue()));
node.escapedText = escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue()));
nextToken();
return finishNode(node);
}
return <Identifier>createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, diagnosticMessage || Diagnostics.Identifier_expected);
return createMissingNode<Identifier>(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, diagnosticMessage || Diagnostics.Identifier_expected);
}
function parseIdentifier(diagnosticMessage?: DiagnosticMessage): Identifier {
@@ -1858,9 +1879,12 @@ namespace ts {
let commaStart = -1; // Meaning the previous token was not a comma
while (true) {
if (isListElement(kind, /*inErrorRecovery*/ false)) {
const startPos = scanner.getStartPos();
result.push(parseListElement(kind, parseElement));
commaStart = scanner.getTokenPos();
if (parseOptional(SyntaxKind.CommaToken)) {
// No need to check for a zero length node since we know we parsed a comma
continue;
}
@@ -1881,6 +1905,13 @@ namespace ts {
if (considerSemicolonAsDelimiter && token() === SyntaxKind.SemicolonToken && !scanner.hasPrecedingLineBreak()) {
nextToken();
}
if (startPos === scanner.getStartPos()) {
// What we're parsing isn't actually remotely recognizable as a element and we've consumed no tokens whatsoever
// Consume a token to advance the parser in some way and avoid an infinite loop
// This can happen when we're speculatively parsing parenthesized expressions which we think may be arrow functions,
// or when a modifier keyword which is disallowed as a parameter name (ie, `static` in strict mode) is supplied
nextToken();
}
continue;
}
@@ -1932,14 +1963,18 @@ namespace ts {
break;
}
dotPos = scanner.getStartPos();
const node: QualifiedName = <QualifiedName>createNode(SyntaxKind.QualifiedName, entity.pos);
node.left = entity;
node.right = parseRightSideOfDot(allowReservedWords);
entity = finishNode(node);
entity = createQualifiedName(entity, parseRightSideOfDot(allowReservedWords));
}
return entity;
}
function createQualifiedName(entity: EntityName, name: Identifier): QualifiedName {
const node = createNode(SyntaxKind.QualifiedName, entity.pos) as QualifiedName;
node.left = entity;
node.right = name;
return finishNode(node);
}
function parseRightSideOfDot(allowIdentifierNames: boolean): Identifier {
// Technically a keyword is valid here as all identifiers and keywords are identifier names.
// However, often we'll encounter this in error situations when the identifier or keyword
@@ -1967,7 +2002,7 @@ namespace ts {
// Report that we need an identifier. However, report it right after the dot,
// and not on the next token. This is because the next token might actually
// be an identifier and the error would be quite confusing.
return <Identifier>createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected);
return createMissingNode<Identifier>(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected);
}
}
@@ -2026,7 +2061,7 @@ namespace ts {
return <TemplateMiddle | TemplateTail>fragment;
}
function parseLiteralLikeNode(kind: SyntaxKind): LiteralLikeNode {
function parseLiteralLikeNode(kind: SyntaxKind): LiteralExpression | LiteralLikeNode {
const node = <LiteralExpression>createNode(kind);
const text = scanner.getTokenValue();
node.text = text;
@@ -2202,8 +2237,7 @@ namespace ts {
return token() === SyntaxKind.DotDotDotToken ||
isIdentifierOrPattern() ||
isModifierKind(token()) ||
token() === SyntaxKind.AtToken || token() === SyntaxKind.ThisKeyword || token() === SyntaxKind.NewKeyword ||
token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NumericLiteral;
token() === SyntaxKind.AtToken || isStartOfType();
}
function parseParameter(): ParameterDeclaration {
@@ -2237,15 +2271,6 @@ namespace ts {
node.type = parseParameterType();
node.initializer = parseBindingElementInitializer(/*inParameter*/ true);
// Do not check for initializers in an ambient context for parameters. This is not
// a grammar error because the grammar allows arbitrary call signatures in
// an ambient context.
// It is actually not necessary for this to be an error at all. The reason is that
// function/constructor implementations are syntactically disallowed in ambient
// contexts. In addition, parameter initializers are semantically disallowed in
// overload signatures. So parameter initializers are transitively disallowed in
// ambient contexts.
return addJSDocComment(finishNode(node));
}
@@ -2586,11 +2611,31 @@ namespace ts {
return token() === SyntaxKind.DotToken ? undefined : node;
}
function parseLiteralTypeNode(): LiteralTypeNode {
const node = <LiteralTypeNode>createNode(SyntaxKind.LiteralType);
node.literal = parseSimpleUnaryExpression();
finishNode(node);
return node;
function parseLiteralTypeNode(negative?: boolean): LiteralTypeNode {
const node = createNode(SyntaxKind.LiteralType) as LiteralTypeNode;
let unaryMinusExpression: PrefixUnaryExpression;
if (negative) {
unaryMinusExpression = createNode(SyntaxKind.PrefixUnaryExpression) as PrefixUnaryExpression;
unaryMinusExpression.operator = SyntaxKind.MinusToken;
nextToken();
}
let expression: UnaryExpression;
switch (token()) {
case SyntaxKind.StringLiteral:
case SyntaxKind.NumericLiteral:
expression = parseLiteralLikeNode(token()) as LiteralExpression;
break;
case SyntaxKind.TrueKeyword:
case SyntaxKind.FalseKeyword:
expression = parseTokenNode();
}
if (negative) {
unaryMinusExpression.operand = expression;
finishNode(unaryMinusExpression);
expression = unaryMinusExpression;
}
node.literal = expression;
return finishNode(node);
}
function nextTokenIsNumericLiteral() {
@@ -2625,7 +2670,7 @@ namespace ts {
case SyntaxKind.FalseKeyword:
return parseLiteralTypeNode();
case SyntaxKind.MinusToken:
return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode() : parseTypeReference();
return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference();
case SyntaxKind.VoidKeyword:
case SyntaxKind.NullKeyword:
return parseTokenNode<TypeNode>();
@@ -2675,6 +2720,7 @@ namespace ts {
case SyntaxKind.TrueKeyword:
case SyntaxKind.FalseKeyword:
case SyntaxKind.ObjectKeyword:
case SyntaxKind.AsteriskToken:
return true;
case SyntaxKind.MinusToken:
return lookAhead(nextTokenIsNumericLiteral);
@@ -3136,7 +3182,7 @@ namespace ts {
return addJSDocComment(finishNode(node));
}
function tryParseParenthesizedArrowFunctionExpression(): Expression {
function tryParseParenthesizedArrowFunctionExpression(): Expression | undefined {
const triState = isParenthesizedArrowFunctionExpression();
if (triState === Tristate.False) {
// It's definitely not a parenthesized arrow function expression.
@@ -3299,7 +3345,7 @@ namespace ts {
return parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ false);
}
function tryParseAsyncSimpleArrowFunctionExpression(): ArrowFunction {
function tryParseAsyncSimpleArrowFunctionExpression(): ArrowFunction | undefined {
// We do a check here so that we won't be doing unnecessarily call to "lookAhead"
if (token() === SyntaxKind.AsyncKeyword) {
const isUnParenthesizedAsyncArrowFunction = lookAhead(isUnParenthesizedAsyncArrowFunctionWorker);
@@ -3896,7 +3942,7 @@ namespace ts {
}
if (lhs.kind === SyntaxKind.Identifier) {
return (<Identifier>lhs).text === (<Identifier>rhs).text;
return (<Identifier>lhs).escapedText === (<Identifier>rhs).escapedText;
}
if (lhs.kind === SyntaxKind.ThisKeyword) {
@@ -3906,7 +3952,7 @@ namespace ts {
// If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only
// take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression
// it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element
return (<PropertyAccessExpression>lhs).name.text === (<PropertyAccessExpression>rhs).name.text &&
return (<PropertyAccessExpression>lhs).name.escapedText === (<PropertyAccessExpression>rhs).name.escapedText &&
tagNamesAreEquivalent((<PropertyAccessExpression>lhs).expression as JsxTagNameExpression, (<PropertyAccessExpression>rhs).expression as JsxTagNameExpression);
}
@@ -4373,7 +4419,7 @@ namespace ts {
return finishNode(node);
}
function tryParseAccessorDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): AccessorDeclaration {
function tryParseAccessorDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): AccessorDeclaration | undefined {
if (parseContextualModifier(SyntaxKind.GetKeyword)) {
return parseAccessorDeclaration(SyntaxKind.GetAccessor, fullStart, decorators, modifiers);
}
@@ -4486,7 +4532,7 @@ namespace ts {
return addJSDocComment(finishNode(node));
}
function parseOptionalIdentifier() {
function parseOptionalIdentifier(): Identifier | undefined {
return isIdentifier() ? parseIdentifier() : undefined;
}
@@ -5509,7 +5555,7 @@ namespace ts {
if (decorators || modifiers) {
// treat this as a property declaration with a missing name.
const name = <Identifier>createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected);
const name = createMissingNode<Identifier>(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected);
return parsePropertyDeclaration(fullStart, decorators, modifiers, name, /*questionToken*/ undefined);
}
@@ -5551,7 +5597,7 @@ namespace ts {
return addJSDocComment(finishNode(node));
}
function parseNameOfClassDeclarationOrExpression(): Identifier {
function parseNameOfClassDeclarationOrExpression(): Identifier | undefined {
// implements is a future reserved word so
// 'class implements' might mean either
// - class expression with omitted name, 'implements' starts heritage clause
@@ -6091,7 +6137,7 @@ namespace ts {
}
export namespace JSDocParser {
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number) {
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number): { jsDocTypeExpression: JSDocTypeExpression, diagnostics: Diagnostic[] } | undefined {
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS);
scanner.setText(content, start, length);
@@ -6116,7 +6162,7 @@ namespace ts {
return finishNode(result);
}
export function parseIsolatedJSDocComment(content: string, start: number, length: number) {
export function parseIsolatedJSDocComment(content: string, start: number, length: number): { jsDoc: JSDoc, diagnostics: Diagnostic[] } | undefined {
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
sourceFile = <SourceFile>{ languageVariant: LanguageVariant.Standard, text: content };
const jsDoc = parseJSDocCommentWorker(start, length);
@@ -6155,6 +6201,11 @@ namespace ts {
SavingComments,
}
const enum PropertyLikeParse {
Property,
Parameter,
}
export function parseJSDocCommentWorker(start: number, length: number): JSDoc {
const content = sourceText;
start = start || 0;
@@ -6323,7 +6374,7 @@ namespace ts {
let tag: JSDocTag;
if (tagName) {
switch (tagName.text) {
switch (tagName.escapedText) {
case "augments":
tag = parseAugmentsTag(atToken, tagName);
break;
@@ -6334,7 +6385,7 @@ namespace ts {
case "arg":
case "argument":
case "param":
tag = parseParameterOrPropertyTag(atToken, tagName, /*shouldParseParamTag*/ true);
tag = parseParameterOrPropertyTag(atToken, tagName, PropertyLikeParse.Parameter);
break;
case "return":
case "returns":
@@ -6446,7 +6497,7 @@ namespace ts {
tags.end = tag.end;
}
function tryParseTypeExpression(): JSDocTypeExpression {
function tryParseTypeExpression(): JSDocTypeExpression | undefined {
return tryParse(() => {
skipWhitespace();
if (token() !== SyntaxKind.OpenBraceToken) {
@@ -6457,10 +6508,10 @@ namespace ts {
});
}
function parseBracketNameInPropertyAndParamTag(): { name: Identifier, isBracketed: boolean } {
// Looking for something like '[foo]' or 'foo'
function parseBracketNameInPropertyAndParamTag(): { name: EntityName, isBracketed: boolean } {
// Looking for something like '[foo]', 'foo', '[foo.bar]' or 'foo.bar'
const isBracketed = parseOptional(SyntaxKind.OpenBracketToken);
const name = parseJSDocIdentifierName(/*createIfMissing*/ true);
const name = parseJSDocEntityName();
if (isBracketed) {
skipWhitespace();
@@ -6475,38 +6526,77 @@ namespace ts {
return { name, isBracketed };
}
function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, shouldParseParamTag: boolean): JSDocPropertyTag | JSDocParameterTag {
function isObjectOrObjectArrayTypeReference(node: TypeNode): boolean {
switch (node.kind) {
case SyntaxKind.ObjectKeyword:
return true;
case SyntaxKind.ArrayType:
return isObjectOrObjectArrayTypeReference((node as ArrayTypeNode).elementType);
default:
return isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "Object";
}
}
function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse.Parameter): JSDocParameterTag;
function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse.Property): JSDocPropertyTag;
function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse): JSDocPropertyLikeTag {
let typeExpression = tryParseTypeExpression();
let isNameFirst = !typeExpression;
skipWhitespace();
const { name, isBracketed } = parseBracketNameInPropertyAndParamTag();
skipWhitespace();
let preName: Identifier, postName: Identifier;
if (typeExpression) {
postName = name;
}
else {
preName = name;
if (isNameFirst) {
typeExpression = tryParseTypeExpression();
}
const result = shouldParseParamTag ?
const result: JSDocPropertyLikeTag = target === PropertyLikeParse.Parameter ?
<JSDocParameterTag>createNode(SyntaxKind.JSDocParameterTag, atToken.pos) :
<JSDocPropertyTag>createNode(SyntaxKind.JSDocPropertyTag, atToken.pos);
const nestedTypeLiteral = parseNestedTypeLiteral(typeExpression, name);
if (nestedTypeLiteral) {
typeExpression = nestedTypeLiteral;
isNameFirst = true;
}
result.atToken = atToken;
result.tagName = tagName;
result.preParameterName = preName;
result.typeExpression = typeExpression;
result.postParameterName = postName;
result.name = postName || preName;
result.name = name;
result.isNameFirst = isNameFirst;
result.isBracketed = isBracketed;
return finishNode(result);
}
function parseNestedTypeLiteral(typeExpression: JSDocTypeExpression, name: EntityName) {
if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) {
const typeLiteralExpression = <JSDocTypeExpression>createNode(SyntaxKind.JSDocTypeExpression, scanner.getTokenPos());
let child: JSDocParameterTag | false;
let jsdocTypeLiteral: JSDocTypeLiteral;
const start = scanner.getStartPos();
let children: JSDocParameterTag[];
while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.Parameter, name))) {
if (!children) {
children = [];
}
children.push(child);
}
if (children) {
jsdocTypeLiteral = <JSDocTypeLiteral>createNode(SyntaxKind.JSDocTypeLiteral, start);
jsdocTypeLiteral.jsDocPropertyTags = children;
if (typeExpression.type.kind === SyntaxKind.ArrayType) {
jsdocTypeLiteral.isArrayType = true;
}
typeLiteralExpression.type = finishNode(jsdocTypeLiteral);
return finishNode(typeLiteralExpression);
}
}
}
function parseReturnTag(atToken: AtToken, tagName: Identifier): JSDocReturnTag {
if (forEach(tags, t => t.kind === SyntaxKind.JSDocReturnTag)) {
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.escapedText);
}
const result = <JSDocReturnTag>createNode(SyntaxKind.JSDocReturnTag, atToken.pos);
@@ -6518,7 +6608,7 @@ namespace ts {
function parseTypeTag(atToken: AtToken, tagName: Identifier): JSDocTypeTag {
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTypeTag)) {
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.escapedText);
}
const result = <JSDocTypeTag>createNode(SyntaxKind.JSDocTypeTag, atToken.pos);
@@ -6565,69 +6655,44 @@ namespace ts {
rightNode = rightNode.body;
}
}
typedefTag.typeExpression = typeExpression;
skipWhitespace();
if (typeExpression) {
if (isObjectTypeReference(typeExpression.type)) {
typedefTag.jsDocTypeLiteral = scanChildTags();
typedefTag.typeExpression = typeExpression;
if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) {
let child: JSDocTypeTag | JSDocPropertyTag | false;
let jsdocTypeLiteral: JSDocTypeLiteral;
let alreadyHasTypeTag = false;
const start = scanner.getStartPos();
while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.Property))) {
if (!jsdocTypeLiteral) {
jsdocTypeLiteral = <JSDocTypeLiteral>createNode(SyntaxKind.JSDocTypeLiteral, start);
}
if (child.kind === SyntaxKind.JSDocTypeTag) {
if (alreadyHasTypeTag) {
break;
}
else {
jsdocTypeLiteral.jsDocTypeTag = child;
alreadyHasTypeTag = true;
}
}
else {
if (!jsdocTypeLiteral.jsDocPropertyTags) {
jsdocTypeLiteral.jsDocPropertyTags = [] as MutableNodeArray<JSDocPropertyTag>;
}
(jsdocTypeLiteral.jsDocPropertyTags as MutableNodeArray<JSDocPropertyTag>).push(child);
}
}
if (!typedefTag.jsDocTypeLiteral) {
typedefTag.jsDocTypeLiteral = <JSDocTypeLiteral>typeExpression.type;
if (jsdocTypeLiteral) {
if (typeExpression && typeExpression.type.kind === SyntaxKind.ArrayType) {
jsdocTypeLiteral.isArrayType = true;
}
typedefTag.typeExpression = finishNode(jsdocTypeLiteral);
}
}
else {
typedefTag.jsDocTypeLiteral = scanChildTags();
}
return finishNode(typedefTag);
function isObjectTypeReference(node: TypeNode) {
return node.kind === SyntaxKind.ObjectKeyword ||
isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.text === "Object";
}
function scanChildTags(): JSDocTypeLiteral {
const jsDocTypeLiteral = <JSDocTypeLiteral>createNode(SyntaxKind.JSDocTypeLiteral, scanner.getStartPos());
let resumePos = scanner.getStartPos();
let canParseTag = true;
let seenAsterisk = false;
let parentTagTerminated = false;
while (token() !== SyntaxKind.EndOfFileToken && !parentTagTerminated) {
nextJSDocToken();
switch (token()) {
case SyntaxKind.AtToken:
if (canParseTag) {
parentTagTerminated = !tryParseChildTag(jsDocTypeLiteral);
if (!parentTagTerminated) {
resumePos = scanner.getStartPos();
}
}
seenAsterisk = false;
break;
case SyntaxKind.NewLineTrivia:
resumePos = scanner.getStartPos() - 1;
canParseTag = true;
seenAsterisk = false;
break;
case SyntaxKind.AsteriskToken:
if (seenAsterisk) {
canParseTag = false;
}
seenAsterisk = true;
break;
case SyntaxKind.Identifier:
canParseTag = false;
break;
case SyntaxKind.EndOfFileToken:
break;
}
}
scanner.setTextPos(resumePos);
return finishNode(jsDocTypeLiteral);
}
function parseJSDocTypeNameWithNamespace(flags: NodeFlags) {
const pos = scanner.getTokenPos();
const typeNameOrNamespaceName = parseJSDocIdentifierName();
@@ -6647,8 +6712,58 @@ namespace ts {
}
}
function escapedTextsEqual(a: EntityName, b: EntityName): boolean {
while (!ts.isIdentifier(a) || !ts.isIdentifier(b)) {
if (!ts.isIdentifier(a) && !ts.isIdentifier(b) && a.right.escapedText === b.right.escapedText) {
a = a.left;
b = b.left;
}
else {
return false;
}
}
return a.escapedText === b.escapedText;
}
function tryParseChildTag(parentTag: JSDocTypeLiteral): boolean {
function parseChildParameterOrPropertyTag(target: PropertyLikeParse.Property): JSDocTypeTag | JSDocPropertyTag | false;
function parseChildParameterOrPropertyTag(target: PropertyLikeParse.Parameter, name: EntityName): JSDocParameterTag | false;
function parseChildParameterOrPropertyTag(target: PropertyLikeParse, name?: EntityName): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | false {
let canParseTag = true;
let seenAsterisk = false;
while (true) {
nextJSDocToken();
switch (token()) {
case SyntaxKind.AtToken:
if (canParseTag) {
const child = tryParseChildTag(target);
if (child && child.kind === SyntaxKind.JSDocParameterTag &&
(ts.isIdentifier(child.name) || !escapedTextsEqual(name, child.name.left))) {
return false;
}
return child;
}
seenAsterisk = false;
break;
case SyntaxKind.NewLineTrivia:
canParseTag = true;
seenAsterisk = false;
break;
case SyntaxKind.AsteriskToken:
if (seenAsterisk) {
canParseTag = false;
}
seenAsterisk = true;
break;
case SyntaxKind.Identifier:
canParseTag = false;
break;
case SyntaxKind.EndOfFileToken:
return false;
}
}
}
function tryParseChildTag(target: PropertyLikeParse): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | false {
Debug.assert(token() === SyntaxKind.AtToken);
const atToken = <AtToken>createNode(SyntaxKind.AtToken, scanner.getStartPos());
atToken.end = scanner.getTextPos();
@@ -6659,34 +6774,23 @@ namespace ts {
if (!tagName) {
return false;
}
switch (tagName.text) {
switch (tagName.escapedText) {
case "type":
if (parentTag.jsDocTypeTag) {
// already has a @type tag, terminate the parent tag now.
return false;
}
parentTag.jsDocTypeTag = parseTypeTag(atToken, tagName);
return true;
return target === PropertyLikeParse.Property && parseTypeTag(atToken, tagName);
case "prop":
case "property":
const propertyTag = parseParameterOrPropertyTag(atToken, tagName, /*shouldParseParamTag*/ false) as JSDocPropertyTag;
if (propertyTag) {
if (!parentTag.jsDocPropertyTags) {
parentTag.jsDocPropertyTags = <MutableNodeArray<JSDocPropertyTag>>[];
}
(parentTag.jsDocPropertyTags as MutableNodeArray<JSDocPropertyTag>).push(propertyTag);
return true;
}
// Error parsing property tag
return false;
return target === PropertyLikeParse.Property && parseParameterOrPropertyTag(atToken, tagName, target);
case "arg":
case "argument":
case "param":
return target === PropertyLikeParse.Parameter && parseParameterOrPropertyTag(atToken, tagName, target);
}
return false;
}
function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag {
function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag | undefined {
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTemplateTag)) {
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.escapedText);
}
// Type parameter list looks like '@template T,U,V'
@@ -6728,14 +6832,30 @@ namespace ts {
return currentToken = scanner.scanJSDocToken();
}
function parseJSDocIdentifierName(createIfMissing = false): Identifier {
return createJSDocIdentifier(tokenIsIdentifierOrKeyword(token()), createIfMissing);
function parseJSDocEntityName(): EntityName {
let entity: EntityName = parseJSDocIdentifierName(/*createIfMissing*/ true);
if (parseOptional(SyntaxKind.OpenBracketToken)) {
parseExpected(SyntaxKind.CloseBracketToken);
// Note that y[] is accepted as an entity name, but the postfix brackets are not saved for checking.
// Technically usejsdoc.org requires them for specifying a property of a type equivalent to Array<{ x: ...}>
// but it's not worth it to enforce that restriction.
}
while (parseOptional(SyntaxKind.DotToken)) {
const name = parseJSDocIdentifierName(/*createIfMissing*/ true);
if (parseOptional(SyntaxKind.OpenBracketToken)) {
parseExpected(SyntaxKind.CloseBracketToken);
}
entity = createQualifiedName(entity, name);
}
return entity;
}
function createJSDocIdentifier(isIdentifier: boolean, createIfMissing: boolean): Identifier {
if (!isIdentifier) {
function parseJSDocIdentifierName(): Identifier | undefined;
function parseJSDocIdentifierName(createIfMissing: true): Identifier;
function parseJSDocIdentifierName(createIfMissing = false): Identifier | undefined {
if (!tokenIsIdentifierOrKeyword(token())) {
if (createIfMissing) {
return <Identifier>createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected);
return createMissingNode<Identifier>(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected);
}
else {
parseErrorAtCurrentToken(Diagnostics.Identifier_expected);
@@ -6746,7 +6866,7 @@ namespace ts {
const pos = scanner.getTokenPos();
const end = scanner.getTextPos();
const result = <Identifier>createNode(SyntaxKind.Identifier, pos);
result.text = escapeLeadingUnderscores(content.substring(pos, end));
result.escapedText = escapeLeadingUnderscores(content.substring(pos, end));
finishNode(result, end);
nextJSDocToken();
@@ -7114,7 +7234,7 @@ namespace ts {
}
}
function getLastChildWorker(node: Node): Node {
function getLastChildWorker(node: Node): Node | undefined {
let last: Node = undefined;
forEachChild(node, child => {
if (nodeIsPresent(child)) {
+11 -6
View File
@@ -1196,10 +1196,14 @@ namespace ts {
case SyntaxKind.EnumDeclaration:
diagnostics.push(createDiagnosticForNode(node, Diagnostics.enum_declarations_can_only_be_used_in_a_ts_file));
return;
case SyntaxKind.TypeAssertionExpression:
const typeAssertionExpression = <TypeAssertion>node;
diagnostics.push(createDiagnosticForNode(typeAssertionExpression.type, Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file));
case SyntaxKind.NonNullExpression:
diagnostics.push(createDiagnosticForNode(node, Diagnostics.non_null_assertions_can_only_be_used_in_a_ts_file));
return;
case SyntaxKind.AsExpression:
diagnostics.push(createDiagnosticForNode((node as AsExpression).type, Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file));
return;
case SyntaxKind.TypeAssertionExpression:
Debug.fail(); // Won't parse these in a JS file anyway, as they are interpreted as JSX.
}
const prevParent = parent;
@@ -1441,19 +1445,20 @@ namespace ts {
break;
case SyntaxKind.ModuleDeclaration:
if (isAmbientModule(<ModuleDeclaration>node) && (inAmbientModule || hasModifier(node, ModifierFlags.Ambient) || file.isDeclarationFile)) {
const moduleName = <StringLiteral>(<ModuleDeclaration>node).name;
const moduleName = <StringLiteral>(<ModuleDeclaration>node).name; // TODO: GH#17347
const nameText = ts.getTextOfIdentifierOrLiteral(moduleName);
// Ambient module declarations can be interpreted as augmentations for some existing external modules.
// This will happen in two cases:
// - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope
// - if current file is not external module then module augmentation is an ambient module declaration with non-relative module name
// immediately nested in top level ambient module declaration .
if (isExternalModuleFile || (inAmbientModule && !isExternalModuleNameRelative(moduleName.text))) {
if (isExternalModuleFile || (inAmbientModule && !isExternalModuleNameRelative(nameText))) {
(moduleAugmentations || (moduleAugmentations = [])).push(moduleName);
}
else if (!inAmbientModule) {
if (file.isDeclarationFile) {
// for global .d.ts files record name of ambient module
(ambientModules || (ambientModules = [])).push(moduleName.text);
(ambientModules || (ambientModules = [])).push(nameText);
}
// An AmbientExternalModuleDeclaration declares an external module.
// This type of declaration is permitted only in the global module.
File diff suppressed because one or more lines are too long
+22 -3
View File
@@ -4,6 +4,18 @@ declare function setTimeout(handler: (...args: any[]) => void, timeout: number):
declare function clearTimeout(handle: any): void;
namespace ts {
/**
* Set a high stack trace limit to provide more information in case of an error.
* Called for command-line and server use cases.
* Not called if TypeScript is used as a library.
*/
/* @internal */
export function setStackTraceLimit() {
if ((Error as any).stackTraceLimit < 100) { // Also tests that we won't set the property if it doesn't exist.
(Error as any).stackTraceLimit = 100;
}
}
export enum FileWatcherEventKind {
Created,
Changed,
@@ -196,9 +208,16 @@ namespace ts {
if (platform === "win32" || platform === "win64") {
return false;
}
// convert current file name to upper case / lower case and check if file exists
// (guards against cases when name is already all uppercase or lowercase)
return !fileExists(__filename.toUpperCase()) || !fileExists(__filename.toLowerCase());
// If this file exists under a different case, we must be case-insensitve.
return !fileExists(swapCase(__filename));
}
/** Convert all lowercase chars to uppercase, and vice-versa */
function swapCase(s: string): string {
return s.replace(/\w/g, (ch) => {
const up = ch.toUpperCase();
return ch === up ? ch.toLowerCase() : up;
});
}
const platform: string = _os.platform();
+1 -1
View File
@@ -415,7 +415,7 @@ namespace ts {
return createElementAccess(value, argumentExpression);
}
else {
const name = createIdentifier(unescapeLeadingUnderscores(propertyName.text));
const name = createIdentifier(unescapeLeadingUnderscores(propertyName.escapedText));
return createPropertyAccess(value, name);
}
}
+12 -12
View File
@@ -647,7 +647,7 @@ namespace ts {
if (isGeneratedIdentifier(node)) {
return node;
}
if (node.text !== "arguments" || !resolver.isArgumentsLocalBinding(node)) {
if (node.escapedText !== "arguments" || !resolver.isArgumentsLocalBinding(node)) {
return node;
}
return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = createUniqueName("arguments"));
@@ -661,7 +661,7 @@ namespace ts {
// - break/continue is non-labeled and located in non-converted loop/switch statement
const jump = node.kind === SyntaxKind.BreakStatement ? Jump.Break : Jump.Continue;
const canUseBreakOrContinue =
(node.label && convertedLoopState.labels && convertedLoopState.labels.get(unescapeLeadingUnderscores(node.label.text))) ||
(node.label && convertedLoopState.labels && convertedLoopState.labels.get(unescapeLeadingUnderscores(node.label.escapedText))) ||
(!node.label && (convertedLoopState.allowedNonLabeledJumps & jump));
if (!canUseBreakOrContinue) {
@@ -679,12 +679,12 @@ namespace ts {
}
else {
if (node.kind === SyntaxKind.BreakStatement) {
labelMarker = `break-${node.label.text}`;
setLabeledJump(convertedLoopState, /*isBreak*/ true, unescapeLeadingUnderscores(node.label.text), labelMarker);
labelMarker = `break-${node.label.escapedText}`;
setLabeledJump(convertedLoopState, /*isBreak*/ true, unescapeLeadingUnderscores(node.label.escapedText), labelMarker);
}
else {
labelMarker = `continue-${node.label.text}`;
setLabeledJump(convertedLoopState, /*isBreak*/ false, unescapeLeadingUnderscores(node.label.text), labelMarker);
labelMarker = `continue-${node.label.escapedText}`;
setLabeledJump(convertedLoopState, /*isBreak*/ false, unescapeLeadingUnderscores(node.label.escapedText), labelMarker);
}
}
let returnExpression: Expression = createLiteral(labelMarker);
@@ -2236,11 +2236,11 @@ namespace ts {
}
function recordLabel(node: LabeledStatement) {
convertedLoopState.labels.set(unescapeLeadingUnderscores(node.label.text), true);
convertedLoopState.labels.set(unescapeLeadingUnderscores(node.label.escapedText), true);
}
function resetLabel(node: LabeledStatement) {
convertedLoopState.labels.set(unescapeLeadingUnderscores(node.label.text), false);
convertedLoopState.labels.set(unescapeLeadingUnderscores(node.label.escapedText), false);
}
function visitLabeledStatement(node: LabeledStatement): VisitResult<Statement> {
@@ -3053,7 +3053,7 @@ namespace ts {
else {
loopParameters.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
if (resolver.getNodeCheckFlags(decl) & NodeCheckFlags.NeedsLoopOutParameter) {
const outParamName = createUniqueName("out_" + unescapeLeadingUnderscores(name.text));
const outParamName = createUniqueName("out_" + unescapeLeadingUnderscores(name.escapedText));
loopOutParameters.push({ originalName: name, outParamName });
}
}
@@ -3591,7 +3591,7 @@ namespace ts {
if (isCallExpression(firstSegment)
&& isIdentifier(firstSegment.expression)
&& (getEmitFlags(firstSegment.expression) & EmitFlags.HelperName)
&& firstSegment.expression.text === "___spread") {
&& firstSegment.expression.escapedText === "___spread") {
return segments[0];
}
}
@@ -3842,7 +3842,7 @@ namespace ts {
}
function visitMetaProperty(node: MetaProperty) {
if (node.keywordToken === SyntaxKind.NewKeyword && node.name.text === "target") {
if (node.keywordToken === SyntaxKind.NewKeyword && node.name.escapedText === "target") {
if (hierarchyFacts & HierarchyFacts.ComputedPropertyName) {
hierarchyFacts |= HierarchyFacts.NewTargetInComputedPropertyName;
}
@@ -4067,7 +4067,7 @@ namespace ts {
}
const expression = (<SpreadElement>callArgument).expression;
return isIdentifier(expression) && expression.text === "arguments";
return isIdentifier(expression) && expression.escapedText === "arguments";
}
}
+1 -1
View File
@@ -369,7 +369,7 @@ namespace ts {
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
if (node.expression.kind === SyntaxKind.SuperKeyword) {
return createSuperAccessInAsyncMethod(
createLiteral(unescapeLeadingUnderscores(node.name.text)),
createLiteral(unescapeLeadingUnderscores(node.name.escapedText)),
node
);
}
+1 -1
View File
@@ -111,7 +111,7 @@ namespace ts {
* @param name An Identifier
*/
function trySubstituteReservedName(name: Identifier) {
const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(unescapeLeadingUnderscores(name.text)) : undefined);
const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(unescapeLeadingUnderscores(name.escapedText)) : undefined);
if (token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) {
return setTextRange(createLiteral(name), name);
}
+1 -1
View File
@@ -776,7 +776,7 @@ namespace ts {
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
if (node.expression.kind === SyntaxKind.SuperKeyword) {
return createSuperAccessInAsyncMethod(
createLiteral(unescapeLeadingUnderscores(node.name.text)),
createLiteral(unescapeLeadingUnderscores(node.name.escapedText)),
node
);
}
+8 -8
View File
@@ -1635,14 +1635,14 @@ namespace ts {
}
function transformAndEmitContinueStatement(node: ContinueStatement): void {
const label = findContinueTarget(node.label ? unescapeLeadingUnderscores(node.label.text) : undefined);
const label = findContinueTarget(node.label ? unescapeLeadingUnderscores(node.label.escapedText) : undefined);
Debug.assert(label > 0, "Expected continue statment to point to a valid Label.");
emitBreak(label, /*location*/ node);
}
function visitContinueStatement(node: ContinueStatement): Statement {
if (inStatementContainingYield) {
const label = findContinueTarget(node.label && unescapeLeadingUnderscores(node.label.text));
const label = findContinueTarget(node.label && unescapeLeadingUnderscores(node.label.escapedText));
if (label > 0) {
return createInlineBreak(label, /*location*/ node);
}
@@ -1652,14 +1652,14 @@ namespace ts {
}
function transformAndEmitBreakStatement(node: BreakStatement): void {
const label = findBreakTarget(node.label ? unescapeLeadingUnderscores(node.label.text) : undefined);
const label = findBreakTarget(node.label ? unescapeLeadingUnderscores(node.label.escapedText) : undefined);
Debug.assert(label > 0, "Expected break statment to point to a valid Label.");
emitBreak(label, /*location*/ node);
}
function visitBreakStatement(node: BreakStatement): Statement {
if (inStatementContainingYield) {
const label = findBreakTarget(node.label && unescapeLeadingUnderscores(node.label.text));
const label = findBreakTarget(node.label && unescapeLeadingUnderscores(node.label.escapedText));
if (label > 0) {
return createInlineBreak(label, /*location*/ node);
}
@@ -1838,7 +1838,7 @@ namespace ts {
// /*body*/
// .endlabeled
// .mark endLabel
beginLabeledBlock(unescapeLeadingUnderscores(node.label.text));
beginLabeledBlock(unescapeLeadingUnderscores(node.label.escapedText));
transformAndEmitEmbeddedStatement(node.statement);
endLabeledBlock();
}
@@ -1849,7 +1849,7 @@ namespace ts {
function visitLabeledStatement(node: LabeledStatement) {
if (inStatementContainingYield) {
beginScriptLabeledBlock(unescapeLeadingUnderscores(node.label.text));
beginScriptLabeledBlock(unescapeLeadingUnderscores(node.label.escapedText));
}
node = visitEachChild(node, visitor, context);
@@ -1950,7 +1950,7 @@ namespace ts {
}
function substituteExpressionIdentifier(node: Identifier) {
if (!isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(unescapeLeadingUnderscores(node.text))) {
if (!isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(unescapeLeadingUnderscores(node.escapedText))) {
const original = getOriginalNode(node);
if (isIdentifier(original) && original.parent) {
const declaration = resolver.getReferencedValueDeclaration(original);
@@ -2123,7 +2123,7 @@ namespace ts {
hoistVariableDeclaration(variable.name);
}
else {
const text = unescapeLeadingUnderscores((<Identifier>variable.name).text);
const text = unescapeLeadingUnderscores((<Identifier>variable.name).escapedText);
name = declareLocal(text);
if (!renamedCatchVariables) {
renamedCatchVariables = createMap<boolean>();
+4 -4
View File
@@ -252,8 +252,8 @@ namespace ts {
}
else {
const name = (<JsxOpeningLikeElement>node).tagName;
if (isIdentifier(name) && isIntrinsicJsxName(name.text)) {
return createLiteral(unescapeLeadingUnderscores(name.text));
if (isIdentifier(name) && isIntrinsicJsxName(name.escapedText)) {
return createLiteral(unescapeLeadingUnderscores(name.escapedText));
}
else {
return createExpressionFromEntityName(name);
@@ -268,11 +268,11 @@ namespace ts {
*/
function getAttributeName(node: JsxAttribute): StringLiteral | Identifier {
const name = node.name;
if (/^[A-Za-z_]\w*$/.test(unescapeLeadingUnderscores(name.text))) {
if (/^[A-Za-z_]\w*$/.test(unescapeLeadingUnderscores(name.escapedText))) {
return name;
}
else {
return createLiteral(unescapeLeadingUnderscores(name.text));
return createLiteral(unescapeLeadingUnderscores(name.escapedText));
}
}
+2 -2
View File
@@ -924,7 +924,7 @@ namespace ts {
getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
/*typeParameters*/ undefined,
visitNodes(node.heritageClauses, importCallExpressionVisitor),
node.members
visitNodes(node.members, importCallExpressionVisitor)
),
node
),
@@ -1225,7 +1225,7 @@ namespace ts {
*/
function appendExportsOfDeclaration(statements: Statement[] | undefined, decl: Declaration): Statement[] | undefined {
const name = getDeclarationName(decl);
const exportSpecifiers = currentModuleInfo.exportSpecifiers.get(unescapeLeadingUnderscores(name.text));
const exportSpecifiers = currentModuleInfo.exportSpecifiers.get(unescapeLeadingUnderscores(name.escapedText));
if (exportSpecifiers) {
for (const exportSpecifier of exportSpecifiers) {
statements = appendExportStatement(statements, exportSpecifier.name, name, /*location*/ exportSpecifier.name);
+7 -7
View File
@@ -324,7 +324,7 @@ namespace ts {
const exportedNames: ObjectLiteralElementLike[] = [];
if (moduleInfo.exportedNames) {
for (const exportedLocalName of moduleInfo.exportedNames) {
if (exportedLocalName.text === "default") {
if (exportedLocalName.escapedText === "default") {
continue;
}
@@ -353,7 +353,7 @@ namespace ts {
// write name of indirectly exported entry, i.e. 'export {x} from ...'
exportedNames.push(
createPropertyAssignment(
createLiteral(unescapeLeadingUnderscores((element.name || element.propertyName).text)),
createLiteral(unescapeLeadingUnderscores((element.name || element.propertyName).escapedText)),
createTrue()
)
);
@@ -504,10 +504,10 @@ namespace ts {
for (const e of (<ExportDeclaration>entry).exportClause.elements) {
properties.push(
createPropertyAssignment(
createLiteral(unescapeLeadingUnderscores(e.name.text)),
createLiteral(unescapeLeadingUnderscores(e.name.escapedText)),
createElementAccess(
parameterName,
createLiteral(unescapeLeadingUnderscores((e.propertyName || e.name).text))
createLiteral(unescapeLeadingUnderscores((e.propertyName || e.name).escapedText))
)
)
);
@@ -1028,7 +1028,7 @@ namespace ts {
let excludeName: string;
if (exportSelf) {
statements = appendExportStatement(statements, decl.name, getLocalName(decl));
excludeName = unescapeLeadingUnderscores(decl.name.text);
excludeName = unescapeLeadingUnderscores(decl.name.escapedText);
}
statements = appendExportsOfDeclaration(statements, decl, excludeName);
@@ -1080,10 +1080,10 @@ namespace ts {
}
const name = getDeclarationName(decl);
const exportSpecifiers = moduleInfo.exportSpecifiers.get(unescapeLeadingUnderscores(name.text));
const exportSpecifiers = moduleInfo.exportSpecifiers.get(unescapeLeadingUnderscores(name.escapedText));
if (exportSpecifiers) {
for (const exportSpecifier of exportSpecifiers) {
if (exportSpecifier.name.text !== excludeName) {
if (exportSpecifier.name.escapedText !== excludeName) {
statements = appendExportStatement(statements, exportSpecifier.name, name);
}
}
+7 -7
View File
@@ -1692,7 +1692,7 @@ namespace ts {
const numParameters = parameters.length;
for (let i = 0; i < numParameters; i++) {
const parameter = parameters[i];
if (i === 0 && isIdentifier(parameter.name) && parameter.name.text === "this") {
if (i === 0 && isIdentifier(parameter.name) && parameter.name.escapedText === "this") {
continue;
}
if (parameter.dotDotDotToken) {
@@ -1841,7 +1841,7 @@ namespace ts {
for (const typeNode of node.types) {
const serializedIndividual = serializeTypeNode(typeNode);
if (isIdentifier(serializedIndividual) && serializedIndividual.text === "Object") {
if (isIdentifier(serializedIndividual) && serializedIndividual.escapedText === "Object") {
// One of the individual is global object, return immediately
return serializedIndividual;
}
@@ -1851,7 +1851,7 @@ namespace ts {
// Different types
if (!isIdentifier(serializedUnion) ||
!isIdentifier(serializedIndividual) ||
serializedUnion.text !== serializedIndividual.text) {
serializedUnion.escapedText !== serializedIndividual.escapedText) {
return createIdentifier("Object");
}
}
@@ -2007,7 +2007,7 @@ namespace ts {
: (<ComputedPropertyName>name).expression;
}
else if (isIdentifier(name)) {
return createLiteral(unescapeLeadingUnderscores(name.text));
return createLiteral(unescapeLeadingUnderscores(name.escapedText));
}
else {
return getSynthesizedClone(name);
@@ -2644,7 +2644,7 @@ namespace ts {
* on symbol names.
*/
function recordEmittedDeclarationInScope(node: Node) {
const name = node.symbol && node.symbol.name;
const name = node.symbol && node.symbol.escapedName;
if (name) {
if (!currentScopeFirstDeclarationsOfName) {
currentScopeFirstDeclarationsOfName = createUnderscoreEscapedMap<Node>();
@@ -2662,7 +2662,7 @@ namespace ts {
*/
function isFirstEmittedDeclarationInScope(node: Node) {
if (currentScopeFirstDeclarationsOfName) {
const name = node.symbol && node.symbol.name;
const name = node.symbol && node.symbol.escapedName;
if (name) {
return currentScopeFirstDeclarationsOfName.get(name) === node;
}
@@ -3210,7 +3210,7 @@ namespace ts {
function getClassAliasIfNeeded(node: ClassDeclaration) {
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) {
enableSubstitutionForClassAliases();
const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? unescapeLeadingUnderscores(node.name.text) : "default");
const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? unescapeLeadingUnderscores(node.name.escapedText) : "default");
classAliases[getOriginalNodeId(node)] = classAlias;
hoistVariableDeclaration(classAlias);
return classAlias;
+9 -9
View File
@@ -58,9 +58,9 @@ namespace ts {
else {
// export { x, y }
for (const specifier of (<ExportDeclaration>node).exportClause.elements) {
if (!uniqueExports.get(unescapeLeadingUnderscores(specifier.name.text))) {
if (!uniqueExports.get(unescapeLeadingUnderscores(specifier.name.escapedText))) {
const name = specifier.propertyName || specifier.name;
exportSpecifiers.add(unescapeLeadingUnderscores(name.text), specifier);
exportSpecifiers.add(unescapeLeadingUnderscores(name.escapedText), specifier);
const decl = resolver.getReferencedImportDeclaration(name)
|| resolver.getReferencedValueDeclaration(name);
@@ -69,7 +69,7 @@ namespace ts {
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
}
uniqueExports.set(unescapeLeadingUnderscores(specifier.name.text), true);
uniqueExports.set(unescapeLeadingUnderscores(specifier.name.escapedText), true);
exportedNames = append(exportedNames, specifier.name);
}
}
@@ -103,9 +103,9 @@ namespace ts {
else {
// export function x() { }
const name = (<FunctionDeclaration>node).name;
if (!uniqueExports.get(unescapeLeadingUnderscores(name.text))) {
if (!uniqueExports.get(unescapeLeadingUnderscores(name.escapedText))) {
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
uniqueExports.set(unescapeLeadingUnderscores(name.text), true);
uniqueExports.set(unescapeLeadingUnderscores(name.escapedText), true);
exportedNames = append(exportedNames, name);
}
}
@@ -124,9 +124,9 @@ namespace ts {
else {
// export class x { }
const name = (<ClassDeclaration>node).name;
if (!uniqueExports.get(unescapeLeadingUnderscores(name.text))) {
if (!uniqueExports.get(unescapeLeadingUnderscores(name.escapedText))) {
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
uniqueExports.set(unescapeLeadingUnderscores(name.text), true);
uniqueExports.set(unescapeLeadingUnderscores(name.escapedText), true);
exportedNames = append(exportedNames, name);
}
}
@@ -158,8 +158,8 @@ namespace ts {
}
}
else if (!isGeneratedIdentifier(decl.name)) {
if (!uniqueExports.get(unescapeLeadingUnderscores(decl.name.text))) {
uniqueExports.set(unescapeLeadingUnderscores(decl.name.text), true);
if (!uniqueExports.get(unescapeLeadingUnderscores(decl.name.escapedText))) {
uniqueExports.set(unescapeLeadingUnderscores(decl.name.escapedText), true);
exportedNames = append(exportedNames, decl.name);
}
}
+2
View File
@@ -665,6 +665,8 @@ namespace ts {
}
}
ts.setStackTraceLimit();
if (ts.Debug.isDebugging) {
ts.Debug.enableDebugInfo();
}
+52 -50
View File
@@ -31,6 +31,11 @@ namespace ts {
next(): { value: T, done: false } | { value: never, done: true };
}
/** Array that is only intended to be pushed to, never read. */
export interface Push<T> {
push(...values: T[]): void;
}
// branded string type used to store absolute, normalized and canonicalized paths
// arbitrary file name can be converted to Path via toPath function
export type Path = string & { __pathBrand: any };
@@ -505,22 +510,22 @@ namespace ts {
flags: NodeFlags;
/* @internal */ modifierFlagsCache?: ModifierFlags;
/* @internal */ transformFlags?: TransformFlags;
decorators?: NodeArray<Decorator>; // Array of decorators (in document order)
modifiers?: ModifiersArray; // Array of modifiers
/* @internal */ id?: number; // Unique id (used to look up NodeLinks)
parent?: Node; // Parent node (initialized by binding)
/* @internal */ original?: Node; // The original node if this is an updated node.
/* @internal */ startsOnNewLine?: boolean; // Whether a synthesized node should start on a new line (used by transforms).
/* @internal */ jsDoc?: JSDoc[]; // JSDoc that directly precedes this node
/* @internal */ jsDocCache?: JSDocTag[]; // Cache for getJSDocTags
/* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding)
/* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding)
/* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding)
/* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
/* @internal */ flowNode?: FlowNode; // Associated FlowNode (initialized by binding)
/* @internal */ emitNode?: EmitNode; // Associated EmitNode (initialized by transforms)
/* @internal */ contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution
/* @internal */ contextualMapper?: TypeMapper; // Mapper for contextual type
decorators?: NodeArray<Decorator>; // Array of decorators (in document order)
modifiers?: ModifiersArray; // Array of modifiers
/* @internal */ id?: number; // Unique id (used to look up NodeLinks)
parent?: Node; // Parent node (initialized by binding)
/* @internal */ original?: Node; // The original node if this is an updated node.
/* @internal */ startsOnNewLine?: boolean; // Whether a synthesized node should start on a new line (used by transforms).
/* @internal */ jsDoc?: JSDoc[]; // JSDoc that directly precedes this node
/* @internal */ jsDocCache?: ReadonlyArray<JSDocTag>; // Cache for getJSDocTags
/* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding)
/* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding)
/* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding)
/* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
/* @internal */ flowNode?: FlowNode; // Associated FlowNode (initialized by binding)
/* @internal */ emitNode?: EmitNode; // Associated EmitNode (initialized by transforms)
/* @internal */ contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution
/* @internal */ contextualMapper?: TypeMapper; // Mapper for contextual type
}
/* @internal */
@@ -574,10 +579,10 @@ namespace ts {
export interface Identifier extends PrimaryExpression {
kind: SyntaxKind.Identifier;
/**
* Text of identifier (with escapes converted to characters).
* If the identifier begins with two underscores, this will begin with three.
* Prefer to use `id.unescapedText`. (Note: This is available only in services, not internally to the TypeScript compiler.)
* Text of identifier, but if the identifier begins with two underscores, this will begin with three.
*/
text: __String;
escapedText: __String;
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
/*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier.
/*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name.
@@ -680,7 +685,7 @@ namespace ts {
kind: SyntaxKind.Parameter;
parent?: SignatureDeclaration;
dotDotDotToken?: DotDotDotToken; // Present on rest parameter
name?: BindingName; // Declared parameter name. Missing if this is a parameter in a JSDocFunctionType.
name: BindingName; // Declared parameter name.
questionToken?: QuestionToken; // Present on optional parameter
type?: TypeNode; // Optional type annotation
initializer?: Expression; // Optional initializer
@@ -755,6 +760,7 @@ namespace ts {
// SyntaxKind.ShorthandPropertyAssignment
// SyntaxKind.EnumMember
// SyntaxKind.JSDocPropertyTag
// SyntaxKind.JSDocParameterTag
export interface VariableLikeDeclaration extends NamedDeclaration {
propertyName?: PropertyName;
dotDotDotToken?: DotDotDotToken;
@@ -2031,7 +2037,7 @@ namespace ts {
}
// represents a top level: { type } expression in a JSDoc comment.
export interface JSDocTypeExpression extends Node {
export interface JSDocTypeExpression extends TypeNode {
kind: SyntaxKind.JSDocTypeExpression;
type: TypeNode;
}
@@ -2120,38 +2126,32 @@ namespace ts {
kind: SyntaxKind.JSDocTypedefTag;
fullName?: JSDocNamespaceDeclaration | Identifier;
name?: Identifier;
typeExpression?: JSDocTypeExpression;
jsDocTypeLiteral?: JSDocTypeLiteral;
typeExpression?: JSDocTypeExpression | JSDocTypeLiteral;
}
export interface JSDocPropertyTag extends JSDocTag, TypeElement {
export interface JSDocPropertyLikeTag extends JSDocTag, Declaration {
parent: JSDoc;
kind: SyntaxKind.JSDocPropertyTag;
name: Identifier;
/** the parameter name, if provided *before* the type (TypeScript-style) */
preParameterName?: Identifier;
/** the parameter name, if provided *after* the type (JSDoc-standard) */
postParameterName?: Identifier;
name: EntityName;
typeExpression: JSDocTypeExpression;
/** Whether the property name came before the type -- non-standard for JSDoc, but Typescript-like */
isNameFirst: boolean;
isBracketed: boolean;
}
export interface JSDocPropertyTag extends JSDocPropertyLikeTag {
kind: SyntaxKind.JSDocPropertyTag;
}
export interface JSDocParameterTag extends JSDocPropertyLikeTag {
kind: SyntaxKind.JSDocParameterTag;
}
export interface JSDocTypeLiteral extends JSDocType {
kind: SyntaxKind.JSDocTypeLiteral;
jsDocPropertyTags?: NodeArray<JSDocPropertyTag>;
jsDocPropertyTags?: ReadonlyArray<JSDocPropertyLikeTag>;
jsDocTypeTag?: JSDocTypeTag;
}
export interface JSDocParameterTag extends JSDocTag {
kind: SyntaxKind.JSDocParameterTag;
/** the parameter name, if provided *before* the type (TypeScript-style) */
preParameterName?: Identifier;
typeExpression?: JSDocTypeExpression;
/** the parameter name, if provided *after* the type (JSDoc-standard) */
postParameterName?: Identifier;
/** the parameter name, regardless of the location it was provided */
name: Identifier;
isBracketed: boolean;
/** If true, then this type literal represents an *array* of its type. */
isArrayType?: boolean;
}
export const enum FlowFlags {
@@ -2360,7 +2360,7 @@ namespace ts {
}
export interface WriteFileCallback {
(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void, sourceFiles?: SourceFile[]): void;
(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void, sourceFiles?: ReadonlyArray<SourceFile>): void;
}
export class OperationCanceledException { }
@@ -2581,6 +2581,8 @@ namespace ts {
getAmbientModules(): Symbol[];
tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
/** Unlike `tryGetMemberInModuleExports`, this includes properties of an `export =` value. */
/* @internal */ tryGetMemberInModuleExportsAndProperties(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
getApparentType(type: Type): Type;
getSuggestionForNonexistentProperty(node: Identifier, containingType: Type): string | undefined;
getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;
@@ -2894,7 +2896,7 @@ namespace ts {
export interface Symbol {
flags: SymbolFlags; // Symbol flags
name: __String; // Name of symbol
escapedName: __String; // Name of symbol
declarations?: Declaration[]; // Declarations associated with this symbol
valueDeclaration?: Declaration; // First value declaration of the symbol
members?: SymbolTable; // Class, interface or literal instance members
@@ -3685,11 +3687,11 @@ namespace ts {
}
export interface ConfigFileSpecs {
filesSpecs: string[];
includeSpecs: string[];
excludeSpecs: string[];
validatedIncludeSpecs: string[];
validatedExcludeSpecs: string[];
filesSpecs: ReadonlyArray<string>;
includeSpecs: ReadonlyArray<string>;
excludeSpecs: ReadonlyArray<string>;
validatedIncludeSpecs: ReadonlyArray<string>;
validatedExcludeSpecs: ReadonlyArray<string>;
wildcardDirectories: MapLike<WatchDirectoryFlags>;
}
+88 -73
View File
@@ -3,6 +3,7 @@
/* @internal */
namespace ts {
export const emptyArray: never[] = [] as never[];
export const emptyMap: ReadonlyMap<never> = createMap<never>();
export const externalHelpersModuleNameText = "tslib";
@@ -91,12 +92,8 @@ namespace ts {
return node.end - node.pos;
}
export function hasResolvedModule(sourceFile: SourceFile, moduleNameText: string): boolean {
return !!(sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules.get(moduleNameText));
}
export function getResolvedModule(sourceFile: SourceFile, moduleNameText: string): ResolvedModuleFull {
return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules.get(moduleNameText) : undefined;
export function getResolvedModule(sourceFile: SourceFile, moduleNameText: string): ResolvedModuleFull | undefined {
return sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules.get(moduleNameText);
}
export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModuleFull): void {
@@ -128,7 +125,11 @@ namespace ts {
}
/* @internal */
export function hasChangesInResolutions<T>(names: string[], newResolutions: T[], oldResolutions: Map<T>, comparer: (oldResolution: T, newResolution: T) => boolean): boolean {
export function hasChangesInResolutions<T>(
names: ReadonlyArray<string>,
newResolutions: ReadonlyArray<T>,
oldResolutions: ReadonlyMap<T>,
comparer: (oldResolution: T, newResolution: T) => boolean): boolean {
Debug.assert(names.length === newResolutions.length);
for (let i = 0; i < names.length; i++) {
@@ -363,11 +364,11 @@ namespace ts {
}
/**
* @deprecated
* @deprecated Use `id.escapedText` to get the escaped text of an Identifier.
* @param identifier The identifier to escape
*/
export function escapeIdentifier(identifier: string): string {
return escapeLeadingUnderscores(identifier) as string;
return identifier;
}
// Make an identifier from an external module name by extracting the string after the last "/" and replacing
@@ -391,6 +392,11 @@ namespace ts {
((<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral || isGlobalScopeAugmentation(<ModuleDeclaration>node));
}
/* @internal */
export function isNonGlobalAmbientModule(node: Node): node is ModuleDeclaration & { name: StringLiteral } {
return isModuleDeclaration(node) && isStringLiteral(node.name);
}
/** Given a symbol for a module, checks that it is a shorthand ambient module. */
export function isShorthandAmbientModuleSymbol(moduleSymbol: Symbol): boolean {
return isShorthandAmbientModule(moduleSymbol.valueDeclaration);
@@ -485,7 +491,7 @@ namespace ts {
export function getTextOfPropertyName(name: PropertyName): __String {
switch (name.kind) {
case SyntaxKind.Identifier:
return (<Identifier>name).text;
return (<Identifier>name).escapedText;
case SyntaxKind.StringLiteral:
case SyntaxKind.NumericLiteral:
return escapeLeadingUnderscores((<LiteralExpression>name).text);
@@ -501,7 +507,7 @@ namespace ts {
export function entityNameToString(name: EntityNameOrEntityNameExpression): string {
switch (name.kind) {
case SyntaxKind.Identifier:
return getFullWidth(name) === 0 ? unescapeLeadingUnderscores(name.text) : getTextOfNode(name);
return getFullWidth(name) === 0 ? unescapeLeadingUnderscores(name.escapedText) : getTextOfNode(name);
case SyntaxKind.QualifiedName:
return entityNameToString(name.left) + "." + entityNameToString(name.right);
case SyntaxKind.PropertyAccessExpression:
@@ -906,8 +912,8 @@ namespace ts {
return predicate && predicate.kind === TypePredicateKind.This;
}
export function getPropertyAssignment(objectLiteral: ObjectLiteralExpression, key: string, key2?: string) {
return <PropertyAssignment[]>filter(objectLiteral.properties, property => {
export function getPropertyAssignment(objectLiteral: ObjectLiteralExpression, key: string, key2?: string): ReadonlyArray<PropertyAssignment> {
return filter(objectLiteral.properties, (property): property is PropertyAssignment => {
if (property.kind === SyntaxKind.PropertyAssignment) {
const propName = getTextOfPropertyName(property.name);
return key === propName || (key2 && key2 === propName);
@@ -916,21 +922,11 @@ namespace ts {
}
export function getContainingFunction(node: Node): FunctionLike {
while (true) {
node = node.parent;
if (!node || isFunctionLike(node)) {
return <FunctionLike>node;
}
}
return findAncestor(node.parent, isFunctionLike);
}
export function getContainingClass(node: Node): ClassLikeDeclaration {
while (true) {
node = node.parent;
if (!node || isClassLike(node)) {
return <ClassLikeDeclaration>node;
}
}
return findAncestor(node.parent, isClassLike);
}
export function getThisContainer(node: Node, includeArrowFunctions: boolean): Node {
@@ -1308,7 +1304,7 @@ namespace ts {
}
const { expression, arguments: args } = callExpression as CallExpression;
if (expression.kind !== SyntaxKind.Identifier || (expression as Identifier).text !== "require") {
if (expression.kind !== SyntaxKind.Identifier || (expression as Identifier).escapedText !== "require") {
return false;
}
@@ -1343,11 +1339,11 @@ namespace ts {
}
export function isExportsIdentifier(node: Node) {
return isIdentifier(node) && node.text === "exports";
return isIdentifier(node) && node.escapedText === "exports";
}
export function isModuleExportsPropertyAccessExpression(node: Node) {
return isPropertyAccessExpression(node) && isIdentifier(node.expression) && node.expression.text === "module" && node.name.text === "exports";
return isPropertyAccessExpression(node) && isIdentifier(node.expression) && node.expression.escapedText === "module" && node.name.escapedText === "exports";
}
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
@@ -1363,11 +1359,11 @@ namespace ts {
const lhs = <PropertyAccessExpression>expr.left;
if (lhs.expression.kind === SyntaxKind.Identifier) {
const lhsId = <Identifier>lhs.expression;
if (lhsId.text === "exports") {
if (lhsId.escapedText === "exports") {
// exports.name = expr
return SpecialPropertyAssignmentKind.ExportsProperty;
}
else if (lhsId.text === "module" && lhs.name.text === "exports") {
else if (lhsId.escapedText === "module" && lhs.name.escapedText === "exports") {
// module.exports = expr
return SpecialPropertyAssignmentKind.ModuleExports;
}
@@ -1385,10 +1381,10 @@ namespace ts {
if (innerPropertyAccess.expression.kind === SyntaxKind.Identifier) {
// module.exports.name = expr
const innerPropertyAccessIdentifier = <Identifier>innerPropertyAccess.expression;
if (innerPropertyAccessIdentifier.text === "module" && innerPropertyAccess.name.text === "exports") {
if (innerPropertyAccessIdentifier.escapedText === "module" && innerPropertyAccess.name.escapedText === "exports") {
return SpecialPropertyAssignmentKind.ExportsProperty;
}
if (innerPropertyAccess.name.text === "prototype") {
if (innerPropertyAccess.name.escapedText === "prototype") {
return SpecialPropertyAssignmentKind.PrototypeProperty;
}
}
@@ -1454,7 +1450,7 @@ namespace ts {
return node.kind === SyntaxKind.JSDocFunctionType &&
(node as JSDocFunctionType).parameters.length > 0 &&
(node as JSDocFunctionType).parameters[0].name &&
((node as JSDocFunctionType).parameters[0].name as Identifier).text === "new";
((node as JSDocFunctionType).parameters[0].name as Identifier).escapedText === "new";
}
export function hasJSDocParameterTags(node: FunctionLikeDeclaration | SignatureDeclaration): boolean {
@@ -1473,7 +1469,7 @@ namespace ts {
return getJSDocCommentsAndTags(node);
}
export function getJSDocTags(node: Node): JSDocTag[] | undefined {
export function getJSDocTags(node: Node): ReadonlyArray<JSDocTag> | undefined {
let tags = node.jsDocCache;
// If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing.
if (tags === undefined) {
@@ -1541,32 +1537,36 @@ namespace ts {
export function getJSDocParameterTags(param: ParameterDeclaration): JSDocParameterTag[] | undefined {
if (param.name && isIdentifier(param.name)) {
const name = param.name.text;
return getJSDocTags(param.parent).filter((tag): tag is JSDocParameterTag => isJSDocParameterTag(tag) && tag.name.text === name) as JSDocParameterTag[];
}
else {
// TODO: it's a destructured parameter, so it should look up an "object type" series of multiple lines
// But multi-line object types aren't supported yet either
return undefined;
const name = param.name.escapedText;
return getJSDocTags(param.parent).filter((tag): tag is JSDocParameterTag => isJSDocParameterTag(tag) && isIdentifier(tag.name) && tag.name.escapedText === name) as JSDocParameterTag[];
}
// a binding pattern doesn't have a name, so it's not possible to match it a jsdoc parameter, which is identified by name
return undefined;
}
/** Does the opposite of `getJSDocParameterTags`: given a JSDoc parameter, finds the parameter corresponding to it. */
export function getParameterFromJSDoc(node: JSDocParameterTag): ParameterDeclaration | undefined {
const name = node.name.text;
const grandParent = node.parent!.parent!;
Debug.assert(node.parent!.kind === SyntaxKind.JSDocComment);
if (!isFunctionLike(grandParent)) {
export function getParameterSymbolFromJSDoc(node: JSDocParameterTag): Symbol | undefined {
if (node.symbol) {
return node.symbol;
}
if (!isIdentifier(node.name)) {
return undefined;
}
return find(grandParent.parameters, p =>
p.name.kind === SyntaxKind.Identifier && p.name.text === name);
const name = node.name.escapedText;
Debug.assert(node.parent!.kind === SyntaxKind.JSDocComment);
const func = node.parent!.parent!;
if (!isFunctionLike(func)) {
return undefined;
}
const parameter = find(func.parameters, p =>
p.name.kind === SyntaxKind.Identifier && p.name.escapedText === name);
return parameter && parameter.symbol;
}
export function getTypeParameterFromJsDoc(node: TypeParameterDeclaration & { parent: JSDocTemplateTag }): TypeParameterDeclaration | undefined {
const name = node.name.text;
const name = node.name.escapedText;
const { typeParameters } = (node.parent.parent.parent as ts.SignatureDeclaration | ts.InterfaceDeclaration | ts.ClassDeclaration);
return find(typeParameters, p => p.name.text === name);
return find(typeParameters, p => p.name.escapedText === name);
}
export function getJSDocType(node: Node): TypeNode {
@@ -1771,7 +1771,8 @@ namespace ts {
// Property name in binding element or import specifier
return (<BindingElement | ImportSpecifier>parent).propertyName === node;
case SyntaxKind.ExportSpecifier:
// Any name in an export specifier
case SyntaxKind.JsxAttribute:
// Any name in an export specifier or JSX Attribute
return true;
}
return false;
@@ -1969,7 +1970,7 @@ namespace ts {
export function getPropertyNameForPropertyNameNode(name: DeclarationName): __String {
if (name.kind === SyntaxKind.Identifier) {
return name.text;
return name.escapedText;
}
if (name.kind === SyntaxKind.StringLiteral || name.kind === SyntaxKind.NumericLiteral) {
return escapeLeadingUnderscores(name.text);
@@ -1977,7 +1978,7 @@ namespace ts {
if (name.kind === SyntaxKind.ComputedPropertyName) {
const nameExpression = name.expression;
if (isWellKnownSymbolSyntactically(nameExpression)) {
const rightHandSideName = (<PropertyAccessExpression>nameExpression).name.text;
const rightHandSideName = (<PropertyAccessExpression>nameExpression).name.escapedText;
return getPropertyNameForKnownSymbolName(unescapeLeadingUnderscores(rightHandSideName));
}
else if (nameExpression.kind === SyntaxKind.StringLiteral || nameExpression.kind === SyntaxKind.NumericLiteral) {
@@ -1991,7 +1992,7 @@ namespace ts {
export function getTextOfIdentifierOrLiteral(node: Identifier | LiteralLikeNode) {
if (node) {
if (node.kind === SyntaxKind.Identifier) {
return unescapeLeadingUnderscores((node as Identifier).text);
return unescapeLeadingUnderscores((node as Identifier).escapedText);
}
if (node.kind === SyntaxKind.StringLiteral ||
node.kind === SyntaxKind.NumericLiteral) {
@@ -2006,7 +2007,7 @@ namespace ts {
export function getEscapedTextOfIdentifierOrLiteral(node: Identifier | LiteralLikeNode) {
if (node) {
if (node.kind === SyntaxKind.Identifier) {
return (node as Identifier).text;
return (node as Identifier).escapedText;
}
if (node.kind === SyntaxKind.StringLiteral ||
node.kind === SyntaxKind.NumericLiteral) {
@@ -2026,11 +2027,11 @@ namespace ts {
* Includes the word "Symbol" with unicode escapes
*/
export function isESSymbolIdentifier(node: Node): boolean {
return node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "Symbol";
return node.kind === SyntaxKind.Identifier && (<Identifier>node).escapedText === "Symbol";
}
export function isPushOrUnshiftIdentifier(node: Identifier) {
return node.text === "push" || node.text === "unshift";
return node.escapedText === "push" || node.escapedText === "unshift";
}
export function isParameterDeclaration(node: VariableLikeDeclaration) {
@@ -2067,7 +2068,7 @@ namespace ts {
return getParseTreeNode(sourceFile, isSourceFile) || sourceFile;
}
export function getOriginalSourceFiles(sourceFiles: SourceFile[]) {
export function getOriginalSourceFiles(sourceFiles: ReadonlyArray<SourceFile>) {
return sameMap(sourceFiles, getOriginalSourceFile);
}
@@ -2588,7 +2589,7 @@ namespace ts {
return combinePaths(newDirPath, sourceFilePath);
}
export function writeFile(host: EmitHost, diagnostics: DiagnosticCollection, fileName: string, data: string, writeByteOrderMark: boolean, sourceFiles?: SourceFile[]) {
export function writeFile(host: EmitHost, diagnostics: DiagnosticCollection, fileName: string, data: string, writeByteOrderMark: boolean, sourceFiles?: ReadonlyArray<SourceFile>) {
host.writeFile(fileName, data, writeByteOrderMark, hostErrorMessage => {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage));
}, sourceFiles);
@@ -2598,7 +2599,7 @@ namespace ts {
return getLineAndCharacterOfPosition(currentSourceFile, pos).line;
}
export function getLineOfLocalPositionFromLineMap(lineMap: number[], pos: number) {
export function getLineOfLocalPositionFromLineMap(lineMap: ReadonlyArray<number>, pos: number) {
return computeLineAndCharacterOfPosition(lineMap, pos).line;
}
@@ -2750,11 +2751,11 @@ namespace ts {
return parameter && getEffectiveTypeAnnotationNode(parameter);
}
export function emitNewLineBeforeLeadingComments(lineMap: number[], writer: EmitTextWriter, node: TextRange, leadingComments: CommentRange[]) {
export function emitNewLineBeforeLeadingComments(lineMap: ReadonlyArray<number>, writer: EmitTextWriter, node: TextRange, leadingComments: ReadonlyArray<CommentRange>) {
emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, node.pos, leadingComments);
}
export function emitNewLineBeforeLeadingCommentsOfPosition(lineMap: number[], writer: EmitTextWriter, pos: number, leadingComments: CommentRange[]) {
export function emitNewLineBeforeLeadingCommentsOfPosition(lineMap: ReadonlyArray<number>, writer: EmitTextWriter, pos: number, leadingComments: ReadonlyArray<CommentRange>) {
// If the leading comments start on different line than the start of node, write new line
if (leadingComments && leadingComments.length && pos !== leadingComments[0].pos &&
getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, leadingComments[0].pos)) {
@@ -2762,7 +2763,7 @@ namespace ts {
}
}
export function emitNewLineBeforeLeadingCommentOfPosition(lineMap: number[], writer: EmitTextWriter, pos: number, commentPos: number) {
export function emitNewLineBeforeLeadingCommentOfPosition(lineMap: ReadonlyArray<number>, writer: EmitTextWriter, pos: number, commentPos: number) {
// If the leading comments start on different line than the start of node, write new line
if (pos !== commentPos &&
getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, commentPos)) {
@@ -2770,8 +2771,15 @@ namespace ts {
}
}
export function emitComments(text: string, lineMap: number[], writer: EmitTextWriter, comments: CommentRange[], leadingSeparator: boolean, trailingSeparator: boolean, newLine: string,
writeComment: (text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) => void) {
export function emitComments(
text: string,
lineMap: ReadonlyArray<number>,
writer: EmitTextWriter,
comments: ReadonlyArray<CommentRange>,
leadingSeparator: boolean,
trailingSeparator: boolean,
newLine: string,
writeComment: (text: string, lineMap: ReadonlyArray<number>, writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) => void) {
if (comments && comments.length > 0) {
if (leadingSeparator) {
writer.write(" ");
@@ -2803,8 +2811,8 @@ namespace ts {
* Detached comment is a comment at the top of file or function body that is separated from
* the next statement by space.
*/
export function emitDetachedComments(text: string, lineMap: number[], writer: EmitTextWriter,
writeComment: (text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) => void,
export function emitDetachedComments(text: string, lineMap: ReadonlyArray<number>, writer: EmitTextWriter,
writeComment: (text: string, lineMap: ReadonlyArray<number>, writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) => void,
node: TextRange, newLine: string, removeComments: boolean) {
let leadingComments: CommentRange[];
let currentDetachedCommentInfo: { nodePos: number, detachedCommentEndPos: number };
@@ -2868,7 +2876,7 @@ namespace ts {
}
export function writeCommentRange(text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) {
export function writeCommentRange(text: string, lineMap: ReadonlyArray<number>, writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) {
if (text.charCodeAt(commentPos + 1) === CharacterCodes.asterisk) {
const firstCommentLineAndCharacter = computeLineAndCharacterOfPosition(lineMap, commentPos);
const lineCount = lineMap.length;
@@ -3718,7 +3726,7 @@ namespace ts {
* This function will then merge those changes into a single change range valid between V1 and
* Vn.
*/
export function collapseTextChangeRangesAcrossMultipleVersions(changes: TextChangeRange[]): TextChangeRange {
export function collapseTextChangeRangesAcrossMultipleVersions(changes: ReadonlyArray<TextChangeRange>): TextChangeRange {
if (changes.length === 0) {
return unchangedTextChangeRange;
}
@@ -3909,7 +3917,7 @@ namespace ts {
export function validateLocaleAndSetLanguage(
locale: string,
sys: { getExecutingFilePath(): string, resolvePath(path: string): string, fileExists(fileName: string): boolean, readFile(fileName: string): string | undefined },
errors?: Diagnostic[]) {
errors?: Push<Diagnostic>) {
const matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase());
if (!matchResult) {
@@ -3928,7 +3936,7 @@ namespace ts {
trySetLanguageAndTerritory(language, /*territory*/ undefined, errors);
}
function trySetLanguageAndTerritory(language: string, territory: string, errors?: Diagnostic[]): boolean {
function trySetLanguageAndTerritory(language: string, territory: string, errors?: Push<Diagnostic>): boolean {
const compilerFilePath = normalizePath(sys.getExecutingFilePath());
const containingDirectoryPath = getDirectoryPath(compilerFilePath);
@@ -4033,18 +4041,21 @@ namespace ts {
/**
* Remove extra underscore from escaped identifier text content.
* @deprecated
* @deprecated Use `id.text` for the unescaped text.
* @param identifier The escaped identifier text.
* @returns The unescaped identifier text.
*/
export function unescapeIdentifier(id: string): string {
return unescapeLeadingUnderscores(id as __String);
return id;
}
export function getNameOfDeclaration(declaration: Declaration): DeclarationName | undefined {
if (!declaration) {
return undefined;
}
if (isJSDocPropertyLikeTag(declaration) && declaration.name.kind === SyntaxKind.QualifiedName) {
return declaration.name.right;
}
if (declaration.kind === SyntaxKind.BinaryExpression) {
const expr = declaration as BinaryExpression;
switch (getSpecialPropertyAssignmentKind(expr)) {
@@ -4703,6 +4714,10 @@ namespace ts {
return node.kind === SyntaxKind.JSDocPropertyTag;
}
export function isJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag {
return node.kind === SyntaxKind.JSDocPropertyTag || node.kind === SyntaxKind.JSDocParameterTag;
}
export function isJSDocTypeLiteral(node: Node): node is JSDocTypeLiteral {
return node.kind === SyntaxKind.JSDocTypeLiteral;
}
+1 -1
View File
@@ -2405,7 +2405,7 @@ namespace FourSlash {
const sortedActualArray = actualTextArray.sort();
if (!ts.arrayIsEqualTo(sortedExpectedArray, sortedActualArray)) {
this.raiseError(
`Actual text array doesn't match expected text array. \nActual: \n"${sortedActualArray.join("\n\n")}"\n---\nExpected: \n'${sortedExpectedArray.join("\n\n")}'`);
`Actual text array doesn't match expected text array. \nActual: \n'${sortedActualArray.join("\n\n")}'\n---\nExpected: \n'${sortedExpectedArray.join("\n\n")}'`);
}
}
+2 -1
View File
@@ -54,7 +54,8 @@ namespace RWC {
useCustomLibraryFile = undefined;
});
it("can compile", () => {
it("can compile", function(this: Mocha.ITestCallbackContext) {
this.timeout(800000); // Allow long timeouts for RWC compilations
let opts: ts.ParsedCommandLine;
const ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
-5
View File
@@ -74,11 +74,6 @@
"../services/formatting/tokenRange.ts",
"../services/codeFixProvider.ts",
"../services/codefixes/fixes.ts",
"../services/codefixes/fixExtendsInterfaceBecomesImplements.ts",
"../services/codefixes/fixClassIncorrectlyImplementsInterface.ts",
"../services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts",
"../services/codefixes/fixClassSuperMustPrecedeThisAccess.ts",
"../services/codefixes/fixConstructorForDerivedNeedSuperCall.ts",
"../services/codefixes/helpers.ts",
"../services/codefixes/importFixes.ts",
"../services/codefixes/fixUnusedIdentifier.ts",
+1 -1
View File
@@ -11,7 +11,7 @@ namespace ts {
return find(n);
function find(node: Node): Node {
if (isDeclaration(node) && node.name && isIdentifier(node.name) && node.name.text === name) {
if (isDeclaration(node) && node.name && isIdentifier(node.name) && node.name.escapedText === name) {
return node;
}
else {
+2 -2
View File
@@ -8,7 +8,7 @@ namespace ts {
context.enableSubstitution(SyntaxKind.Identifier);
context.onSubstituteNode = (hint, node) => {
node = previousOnSubstituteNode(hint, node);
if (hint === EmitHint.Expression && node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "undefined") {
if (hint === EmitHint.Expression && isIdentifier(node) && node.escapedText === "undefined") {
node = createPartiallyEmittedExpression(
addSyntheticTrailingComment(
setTextRange(
@@ -26,7 +26,7 @@ namespace ts {
context.enableSubstitution(SyntaxKind.Identifier);
context.onSubstituteNode = (hint, node) => {
node = previousOnSubstituteNode(hint, node);
if (node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "oldName") {
if (isIdentifier(node) && node.escapedText === "oldName") {
node = setTextRange(createIdentifier("newName"), node);
}
return node;
@@ -2509,6 +2509,50 @@ namespace ts.projectSystem {
const navbar = projectService.externalProjects[0].getLanguageService(/*ensureSynchronized*/ false).getNavigationBarItems(f1.path);
assert.equal(navbar[0].spans[0].length, f1.content.length);
});
it("deleting config file opened from the external project works", () => {
const site = {
path: "/user/someuser/project/js/site.js",
content: ""
};
const configFile = {
path: "/user/someuser/project/tsconfig.json",
content: "{}"
};
const projectFileName = "/user/someuser/project/WebApplication6.csproj";
const host = createServerHost([libFile, site, configFile]);
const projectService = createProjectService(host);
const externalProject: protocol.ExternalProject = {
projectFileName,
rootFiles: [toExternalFile(site.path), toExternalFile(configFile.path)],
options: { allowJs: false },
typeAcquisition: { "include": [] }
};
projectService.openExternalProjects([externalProject]);
let knownProjects = projectService.synchronizeProjectList([]);
checkNumberOfProjects(projectService, { configuredProjects: 1, externalProjects: 0, inferredProjects: 0 });
const configProject = configuredProjectAt(projectService, 0);
checkProjectActualFiles(configProject, [libFile.path, configFile.path]);
const diagnostics = configProject.getAllProjectErrors();
assert.equal(diagnostics[0].code, Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
host.reloadFS([libFile, site]);
host.checkTimeoutQueueLengthAndRun(1);
knownProjects = projectService.synchronizeProjectList(map(knownProjects, proj => proj.info));
checkNumberOfProjects(projectService, { configuredProjects: 0, externalProjects: 0, inferredProjects: 0 });
externalProject.rootFiles.length = 1;
projectService.openExternalProjects([externalProject]);
checkNumberOfProjects(projectService, { configuredProjects: 0, externalProjects: 1, inferredProjects: 0 });
checkProjectActualFiles(projectService.externalProjects[0], [site.path, libFile.path]);
});
});
describe("Proper errors", () => {
+11 -5
View File
@@ -1034,6 +1034,8 @@ namespace ts.projectSystem {
});
describe("discover typings", () => {
const emptySafeList = emptyMap;
it("should use mappings from safe list", () => {
const app = {
path: "/a/b/app.js",
@@ -1047,13 +1049,15 @@ namespace ts.projectSystem {
path: "/a/b/chroma.min.js",
content: ""
};
const cache = createMap<string>();
const safeList = createMapFromTemplate({ jquery: "jquery", chroma: "chroma-js" });
const host = createServerHost([app, jquery, chroma]);
const logger = trackingLogger();
const result = JsTyping.discoverTypings(host, logger.log, [app.path, jquery.path, chroma.path], getDirectoryPath(<Path>app.path), /*safeListPath*/ undefined, cache, { enable: true }, []);
const result = JsTyping.discoverTypings(host, logger.log, [app.path, jquery.path, chroma.path], getDirectoryPath(<Path>app.path), safeList, emptyMap, { enable: true }, emptyArray);
assert.deepEqual(logger.finish(), [
'Inferred typings from file names: ["jquery","chroma-js"]',
"Inferred typings from unresolved imports: []",
'Result: {"cachedTypingPaths":[],"newTypingNames":["jquery","chroma-js"],"filesToWatch":["/a/b/bower_components","/a/b/node_modules"]}',
]);
assert.deepEqual(result.newTypingNames, ["jquery", "chroma-js"]);
@@ -1069,7 +1073,7 @@ namespace ts.projectSystem {
for (const name of JsTyping.nodeCoreModuleList) {
const logger = trackingLogger();
const result = JsTyping.discoverTypings(host, logger.log, [f.path], getDirectoryPath(<Path>f.path), /*safeListPath*/ undefined, cache, { enable: true }, [name, "somename"]);
const result = JsTyping.discoverTypings(host, logger.log, [f.path], getDirectoryPath(<Path>f.path), emptySafeList, cache, { enable: true }, [name, "somename"]);
assert.deepEqual(logger.finish(), [
'Inferred typings from unresolved imports: ["node","somename"]',
'Result: {"cachedTypingPaths":[],"newTypingNames":["node","somename"],"filesToWatch":["/a/b/bower_components","/a/b/node_modules"]}',
@@ -1090,7 +1094,7 @@ namespace ts.projectSystem {
const host = createServerHost([f, node]);
const cache = createMapFromTemplate<string>({ "node": node.path });
const logger = trackingLogger();
const result = JsTyping.discoverTypings(host, logger.log, [f.path], getDirectoryPath(<Path>f.path), /*safeListPath*/ undefined, cache, { enable: true }, ["fs", "bar"]);
const result = JsTyping.discoverTypings(host, logger.log, [f.path], getDirectoryPath(<Path>f.path), emptySafeList, cache, { enable: true }, ["fs", "bar"]);
assert.deepEqual(logger.finish(), [
'Inferred typings from unresolved imports: ["node","bar"]',
'Result: {"cachedTypingPaths":["/a/b/node.d.ts"],"newTypingNames":["bar"],"filesToWatch":["/a/b/bower_components","/a/b/node_modules"]}',
@@ -1115,9 +1119,11 @@ namespace ts.projectSystem {
const host = createServerHost([app, a, b]);
const cache = createMap<string>();
const logger = trackingLogger();
const result = JsTyping.discoverTypings(host, logger.log, [app.path], getDirectoryPath(<Path>app.path), /*safeListPath*/ undefined, cache, { enable: true }, /*unresolvedImports*/ []);
const result = JsTyping.discoverTypings(host, logger.log, [app.path], getDirectoryPath(<Path>app.path), emptySafeList, cache, { enable: true }, /*unresolvedImports*/ []);
assert.deepEqual(logger.finish(), [
'Searching for typing names in /node_modules; all files: ["/node_modules/a/package.json"]',
' Found package names: ["a"]',
"Inferred typings from unresolved imports: []",
'Result: {"cachedTypingPaths":[],"newTypingNames":["a"],"filesToWatch":["/bower_components","/node_modules"]}',
]);
assert.deepEqual(result, {
+6 -6
View File
@@ -349,7 +349,7 @@ namespace ts.server {
private readonly throttledOperations: ThrottledOperations;
private readonly hostConfiguration: HostConfiguration;
private static safelist: SafeList = defaultTypeSafeList;
private safelist: SafeList = defaultTypeSafeList;
private changedFiles: ScriptInfo[];
private pendingProjectUpdates = createMap<Project>();
@@ -1148,7 +1148,7 @@ namespace ts.server {
this.logger.info("Open files: ");
for (const rootFile of this.openFiles) {
this.logger.info(rootFile.fileName);
this.logger.info(`\t${rootFile.fileName}`);
}
this.logger.endGroup();
@@ -1899,7 +1899,7 @@ namespace ts.server {
}
resetSafeList(): void {
ProjectService.safelist = defaultTypeSafeList;
this.safelist = defaultTypeSafeList;
}
loadSafeList(fileName: string): void {
@@ -1909,7 +1909,7 @@ namespace ts.server {
raw[k].match = new RegExp(raw[k].match as {} as string, "i");
}
// raw is now fixed and ready
ProjectService.safelist = raw;
this.safelist = raw;
}
applySafeList(proj: protocol.ExternalProject): void {
@@ -1920,8 +1920,8 @@ namespace ts.server {
const normalizedNames = rootFiles.map(f => normalizeSlashes(f.fileName));
for (const name of Object.keys(ProjectService.safelist)) {
const rule = ProjectService.safelist[name];
for (const name of Object.keys(this.safelist)) {
const rule = this.safelist[name];
for (const root of normalizedNames) {
if (rule.match.test(root)) {
this.logger.info(`Excluding files based on rule ${name}`);
+2 -2
View File
@@ -981,8 +981,8 @@ namespace ts.server {
private typeAcquisition: TypeAcquisition;
/* @internal */
configFileWatcher: FileWatcher;
private directoriesWatchedForWildcards: Map<WildCardDirectoryWatchers>;
private typeRootsWatchers: Map<FileWatcher>;
private directoriesWatchedForWildcards: Map<WildCardDirectoryWatchers> | undefined;
private typeRootsWatchers: Map<FileWatcher> | undefined;
readonly canonicalConfigFilePath: NormalizedPath;
/* @internal */
+9 -1
View File
@@ -200,7 +200,7 @@ namespace ts.server {
msg(s: string, type: Msg.Types = Msg.Err) {
if (this.fd >= 0 || this.traceToConsole) {
s = s + "\n";
s = `[${nowString()}] ${s}\n`;
const prefix = Logger.padStringRight(type + " " + this.seq.toString(), " ");
if (this.firstInGroup) {
s = prefix + s;
@@ -222,6 +222,12 @@ namespace ts.server {
}
}
// E.g. "12:34:56.789"
function nowString() {
const d = new Date();
return `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}.${d.getMilliseconds()}`;
}
class NodeTypingsInstaller implements ITypingsInstaller {
private installer: NodeChildProcess;
private installerPidReported = false;
@@ -751,6 +757,8 @@ namespace ts.server {
validateLocaleAndSetLanguage(localeStr, sys);
}
setStackTraceLimit();
const typingSafeListLocation = findArgument(Arguments.TypingSafeListLocation);
const npmLocation = findArgument(Arguments.NpmLocation);
@@ -85,6 +85,7 @@ namespace ts.server.typingsInstaller {
private readonly missingTypingsSet: Map<true> = createMap<true>();
private readonly knownCachesSet: Map<true> = createMap<true>();
private readonly projectWatchers: Map<FileWatcher[]> = createMap<FileWatcher[]>();
private safeList: JsTyping.SafeList | undefined;
readonly pendingRunRequests: PendingRequest[] = [];
private installRunCount = 1;
@@ -143,12 +144,15 @@ namespace ts.server.typingsInstaller {
this.processCacheLocation(req.cachePath);
}
if (this.safeList === undefined) {
this.safeList = JsTyping.loadSafeList(this.installTypingHost, this.safeListPath);
}
const discoverTypingsResult = JsTyping.discoverTypings(
this.installTypingHost,
this.log.isEnabled() ? this.log.writeLine : undefined,
req.fileNames,
req.projectRootPath,
this.safeListPath,
this.safeList,
this.packageNameToTypingLocation,
req.typeAcquisition,
req.unresolvedImports);
+79 -76
View File
@@ -176,6 +176,85 @@ namespace ts.server {
return [] as SortedArray<T>;
}
export class ThrottledOperations {
private pendingTimeouts: Map<any> = createMap<any>();
constructor(private readonly host: ServerHost) {
}
public schedule(operationId: string, delay: number, cb: () => void) {
const pendingTimeout = this.pendingTimeouts.get(operationId);
if (pendingTimeout) {
// another operation was already scheduled for this id - cancel it
this.host.clearTimeout(pendingTimeout);
}
// schedule new operation, pass arguments
this.pendingTimeouts.set(operationId, this.host.setTimeout(ThrottledOperations.run, delay, this, operationId, cb));
}
private static run(self: ThrottledOperations, operationId: string, cb: () => void) {
self.pendingTimeouts.delete(operationId);
cb();
}
}
export class GcTimer {
private timerId: any;
constructor(private readonly host: ServerHost, private readonly delay: number, private readonly logger: Logger) {
}
public scheduleCollect() {
if (!this.host.gc || this.timerId !== undefined) {
// no global.gc or collection was already scheduled - skip this request
return;
}
this.timerId = this.host.setTimeout(GcTimer.run, this.delay, this);
}
private static run(self: GcTimer) {
self.timerId = undefined;
const log = self.logger.hasLevel(LogLevel.requestTime);
const before = log && self.host.getMemoryUsage();
self.host.gc();
if (log) {
const after = self.host.getMemoryUsage();
self.logger.perftrc(`GC::before ${before}, after ${after}`);
}
}
}
}
/* @internal */
namespace ts.server {
export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Comparer<T>): void {
if (array.length === 0) {
array.push(insert);
return;
}
const insertIndex = binarySearch(array, insert, compare);
if (insertIndex < 0) {
array.splice(~insertIndex, 0, insert);
}
}
export function removeSorted<T>(array: SortedArray<T>, remove: T, compare: Comparer<T>): void {
if (!array || array.length === 0) {
return;
}
if (array[0] === remove) {
array.splice(0, 1);
return;
}
const removeIndex = binarySearch(array, remove, compare);
if (removeIndex >= 0) {
array.splice(removeIndex, 1);
}
}
export function toSortedArray(arr: string[]): SortedArray<string>;
export function toSortedArray<T>(arr: T[], comparer: Comparer<T>): SortedArray<T>;
export function toSortedArray<T>(arr: T[], comparer?: Comparer<T>): SortedArray<T> {
@@ -286,80 +365,4 @@ namespace ts.server {
cleanExistingMap(existingMap, onDeleteExistingValue);
return undefined;
}
export class ThrottledOperations {
private pendingTimeouts: Map<any> = createMap<any>();
constructor(private readonly host: ServerHost) {
}
public schedule(operationId: string, delay: number, cb: () => void) {
const pendingTimeout = this.pendingTimeouts.get(operationId);
if (pendingTimeout) {
// another operation was already scheduled for this id - cancel it
this.host.clearTimeout(pendingTimeout);
}
// schedule new operation, pass arguments
this.pendingTimeouts.set(operationId, this.host.setTimeout(ThrottledOperations.run, delay, this, operationId, cb));
}
private static run(self: ThrottledOperations, operationId: string, cb: () => void) {
self.pendingTimeouts.delete(operationId);
cb();
}
}
export class GcTimer {
private timerId: any;
constructor(private readonly host: ServerHost, private readonly delay: number, private readonly logger: Logger) {
}
public scheduleCollect() {
if (!this.host.gc || this.timerId !== undefined) {
// no global.gc or collection was already scheduled - skip this request
return;
}
this.timerId = this.host.setTimeout(GcTimer.run, this.delay, this);
}
private static run(self: GcTimer) {
self.timerId = undefined;
const log = self.logger.hasLevel(LogLevel.requestTime);
const before = log && self.host.getMemoryUsage();
self.host.gc();
if (log) {
const after = self.host.getMemoryUsage();
self.logger.perftrc(`GC::before ${before}, after ${after}`);
}
}
}
export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Comparer<T>): void {
if (array.length === 0) {
array.push(insert);
return;
}
const insertIndex = binarySearch(array, insert, compare);
if (insertIndex < 0) {
array.splice(~insertIndex, 0, insert);
}
}
export function removeSorted<T>(array: SortedArray<T>, remove: T, compare: Comparer<T>): void {
if (!array || array.length === 0) {
return;
}
if (array[0] === remove) {
array.splice(0, 1);
return;
}
const removeIndex = binarySearch(array, remove, compare);
if (removeIndex >= 0) {
array.splice(removeIndex, 1);
}
}
}
+9 -9
View File
@@ -557,7 +557,7 @@ namespace ts {
// Only bother calling into the typechecker if this is an identifier that
// could possibly resolve to a type name. This makes classification run
// in a third of the time it would normally take.
if (classifiableNames.has(identifier.text)) {
if (classifiableNames.has(identifier.escapedText)) {
const symbol = typeChecker.getSymbolAtLocation(node);
if (symbol) {
const type = classifySymbol(symbol, getMeaningFromLocation(node));
@@ -755,10 +755,10 @@ namespace ts {
return;
function processJSDocParameterTag(tag: JSDocParameterTag) {
if (tag.preParameterName) {
pushCommentRange(pos, tag.preParameterName.pos - pos);
pushClassification(tag.preParameterName.pos, tag.preParameterName.end - tag.preParameterName.pos, ClassificationType.parameterName);
pos = tag.preParameterName.end;
if (tag.isNameFirst) {
pushCommentRange(pos, tag.name.pos - pos);
pushClassification(tag.name.pos, tag.name.end - tag.name.pos, ClassificationType.parameterName);
pos = tag.name.end;
}
if (tag.typeExpression) {
@@ -767,10 +767,10 @@ namespace ts {
pos = tag.typeExpression.end;
}
if (tag.postParameterName) {
pushCommentRange(pos, tag.postParameterName.pos - pos);
pushClassification(tag.postParameterName.pos, tag.postParameterName.end - tag.postParameterName.pos, ClassificationType.parameterName);
pos = tag.postParameterName.end;
if (!tag.isNameFirst) {
pushCommentRange(pos, tag.name.pos - pos);
pushClassification(tag.name.pos, tag.name.end - tag.name.pos, ClassificationType.parameterName);
pos = tag.name.end;
}
}
}
@@ -0,0 +1,27 @@
/* @internal */
namespace ts.codefix {
registerCodeFix({
errorCodes: [Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1.code],
getCodeActions: (context: CodeFixContext) => {
const sourceFile = context.sourceFile;
const token = getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
const qualifiedName = getAncestor(token, SyntaxKind.QualifiedName) as QualifiedName;
Debug.assert(!!qualifiedName, "Expected position to be owned by a qualified name.");
if (!isIdentifier(qualifiedName.left)) {
return undefined;
}
const leftText = qualifiedName.left.getText(sourceFile);
const rightText = qualifiedName.right.getText(sourceFile);
const replacement = createIndexedAccessTypeNode(
createTypeReferenceNode(qualifiedName.left, /*typeArguments*/ undefined),
createLiteralTypeNode(createLiteral(rightText)));
const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
changeTracker.replaceNode(sourceFile, qualifiedName, replacement);
return [{
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Rewrite_as_the_indexed_access_type_0), [`${leftText}["${rightText}"]`]),
changes: changeTracker.getChanges()
}];
}
});
}
+2 -1
View File
@@ -15,7 +15,8 @@ namespace ts.codefix {
const node = getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false); // TODO: GH#15852
const checker = context.program.getTypeChecker();
let suggestion: string;
if (node.kind === SyntaxKind.Identifier && isPropertyAccessExpression(node.parent)) {
if (isPropertyAccessExpression(node.parent) && node.parent.name === node) {
Debug.assert(node.kind === SyntaxKind.Identifier);
const containingType = checker.getTypeAtLocation(node.parent.expression);
suggestion = checker.getSuggestionForNonexistentProperty(node as Identifier, containingType);
}
+1
View File
@@ -1,3 +1,4 @@
/// <reference path="correctQualifiedNameToIndexedAccessType.ts" />
/// <reference path="fixClassIncorrectlyImplementsInterface.ts" />
/// <reference path="fixAddMissingMember.ts" />
/// <reference path="fixSpelling.ts" />
+2 -2
View File
@@ -35,7 +35,7 @@ namespace ts.codefix {
*/
export function createMissingMemberNodes(classDeclaration: ClassLikeDeclaration, possiblyMissingSymbols: Symbol[], checker: TypeChecker): Node[] {
const classMembers = classDeclaration.symbol.members;
const missingMembers = possiblyMissingSymbols.filter(symbol => !classMembers.has(symbol.name));
const missingMembers = possiblyMissingSymbols.filter(symbol => !classMembers.has(symbol.escapedName));
let newNodes: Node[] = [];
for (const symbol of missingMembers) {
@@ -205,7 +205,7 @@ namespace ts.codefix {
}
}
const maxNonRestArgs = maxArgsSignature.parameters.length - (maxArgsSignature.hasRestParameter ? 1 : 0);
const maxArgsParameterSymbolNames = maxArgsSignature.parameters.map(symbol => symbol.getUnescapedName());
const maxArgsParameterSymbolNames = maxArgsSignature.parameters.map(symbol => symbol.name);
const parameters = createDummyParameters(maxNonRestArgs, maxArgsParameterSymbolNames, minArgumentCount, /*addAnyType*/ true);
+107 -29
View File
@@ -148,7 +148,7 @@ namespace ts.codefix {
else if (isJsxOpeningLikeElement(token.parent) && token.parent.tagName === token) {
// The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`.
symbol = checker.getAliasedSymbol(checker.resolveNameAtLocation(token, checker.getJsxNamespace(), SymbolFlags.Value));
symbolName = symbol.getUnescapedName();
symbolName = symbol.name;
}
else {
Debug.fail("Either the symbol or the JSX namespace should be a UMD global if we got here");
@@ -171,15 +171,18 @@ namespace ts.codefix {
const defaultExport = checker.tryGetMemberInModuleExports("default", moduleSymbol);
if (defaultExport) {
const localSymbol = getLocalSymbolForExportDefault(defaultExport);
if (localSymbol && localSymbol.name === name && checkSymbolHasMeaning(localSymbol, currentTokenMeaning)) {
if (localSymbol && localSymbol.escapedName === name && checkSymbolHasMeaning(localSymbol, currentTokenMeaning)) {
// check if this symbol is already used
const symbolId = getUniqueSymbolId(localSymbol);
symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, name, /*isDefault*/ true));
symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, name, /*isNamespaceImport*/ true));
}
}
// "default" is a keyword and not a legal identifier for the import, so we don't expect it here
Debug.assert(name !== "default");
// check exports with the same name
const exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExports(name, moduleSymbol);
const exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExportsAndProperties(name, moduleSymbol);
if (exportSymbolWithIdenticalName && checkSymbolHasMeaning(exportSymbolWithIdenticalName, currentTokenMeaning)) {
const symbolId = getUniqueSymbolId(exportSymbolWithIdenticalName);
symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, name));
@@ -501,45 +504,120 @@ namespace ts.codefix {
return undefined;
}
const indexOfNodeModules = moduleFileName.indexOf("node_modules");
if (indexOfNodeModules < 0) {
const parts = getNodeModulePathParts(moduleFileName);
if (!parts) {
return undefined;
}
let relativeFileName: string;
if (sourceDirectory.indexOf(moduleFileName.substring(0, indexOfNodeModules - 1)) === 0) {
// if node_modules folder is in this folder or any of its parent folder, no need to keep it.
relativeFileName = moduleFileName.substring(indexOfNodeModules + 13 /* "node_modules\".length */);
}
else {
relativeFileName = getRelativePath(moduleFileName, sourceDirectory);
}
// Simplify the full file path to something that can be resolved by Node.
relativeFileName = removeFileExtension(relativeFileName);
if (endsWith(relativeFileName, "/index")) {
relativeFileName = getDirectoryPath(relativeFileName);
}
else {
try {
const moduleDirectory = getDirectoryPath(moduleFileName);
const packageJsonContent = JSON.parse(context.host.readFile(combinePaths(moduleDirectory, "package.json")));
// If the module could be imported by a directory name, use that directory's name
let moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName);
// Get a path that's relative to node_modules or the importing file's path
moduleSpecifier = getNodeResolvablePath(moduleSpecifier);
// If the module was found in @types, get the actual Node package name
return getPackageNameFromAtTypesDirectory(moduleSpecifier);
function getDirectoryOrExtensionlessFileName(path: string): string {
// If the file is the main module, it can be imported by the package name
const packageRootPath = path.substring(0, parts.packageRootIndex);
const packageJsonPath = combinePaths(packageRootPath, "package.json");
if (context.host.fileExists(packageJsonPath)) {
const packageJsonContent = JSON.parse(context.host.readFile(packageJsonPath));
if (packageJsonContent) {
const mainFile = packageJsonContent.main || packageJsonContent.typings;
if (mainFile) {
const mainExportFile = toPath(mainFile, moduleDirectory, getCanonicalFileName);
if (removeFileExtension(mainExportFile) === removeFileExtension(moduleFileName)) {
relativeFileName = getDirectoryPath(relativeFileName);
const mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main;
if (mainFileRelative) {
const mainExportFile = toPath(mainFileRelative, packageRootPath, getCanonicalFileName);
if (mainExportFile === getCanonicalFileName(path)) {
return packageRootPath;
}
}
}
}
catch (e) { }
// We still have a file name - remove the extension
const fullModulePathWithoutExtension = removeFileExtension(path);
// If the file is /index, it can be imported by its directory name
if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index") {
return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex);
}
return fullModulePathWithoutExtension;
}
return getPackageNameFromAtTypesDirectory(relativeFileName);
function getNodeResolvablePath(path: string): string {
const basePath = path.substring(0, parts.topLevelNodeModulesIndex);
if (sourceDirectory.indexOf(basePath) === 0) {
// if node_modules folder is in this folder or any of its parent folders, no need to keep it.
return path.substring(parts.topLevelPackageNameIndex + 1);
}
else {
return getRelativePath(path, sourceDirectory);
}
}
}
}
function getNodeModulePathParts(fullPath: string) {
// If fullPath can't be valid module file within node_modules, returns undefined.
// Example of expected pattern: /base/path/node_modules/[@scope/otherpackage/@otherscope/node_modules/]package/[subdirectory/]file.js
// Returns indices: ^ ^ ^ ^
let topLevelNodeModulesIndex = 0;
let topLevelPackageNameIndex = 0;
let packageRootIndex = 0;
let fileNameIndex = 0;
const enum States {
BeforeNodeModules,
NodeModules,
Scope,
PackageContent
}
let partStart = 0;
let partEnd = 0;
let state = States.BeforeNodeModules;
while (partEnd >= 0) {
partStart = partEnd;
partEnd = fullPath.indexOf("/", partStart + 1);
switch (state) {
case States.BeforeNodeModules:
if (fullPath.indexOf("/node_modules/", partStart) === partStart) {
topLevelNodeModulesIndex = partStart;
topLevelPackageNameIndex = partEnd;
state = States.NodeModules;
}
break;
case States.NodeModules:
case States.Scope:
if (state === States.NodeModules && fullPath.charAt(partStart + 1) === "@") {
state = States.Scope;
}
else {
packageRootIndex = partEnd;
state = States.PackageContent;
}
break;
case States.PackageContent:
if (fullPath.indexOf("/node_modules/", partStart) === partStart) {
state = States.NodeModules;
}
else {
state = States.PackageContent;
}
break;
}
}
fileNameIndex = partStart;
return state > States.NodeModules ? { topLevelNodeModulesIndex, topLevelPackageNameIndex, packageRootIndex, fileNameIndex } : undefined;
}
function getPathRelativeToRootDirs(path: string, rootDirs: string[]) {
for (const rootDir of rootDirs) {
const relativeName = getRelativePathIfInDirectory(path, rootDir);
+12 -12
View File
@@ -420,7 +420,7 @@ namespace ts.Completions {
if (tag.tagName.pos <= position && position <= tag.tagName.end) {
request = { kind: "JsDocTagName" };
}
if (isTagWithTypeExpression(tag) && tag.typeExpression) {
if (isTagWithTypeExpression(tag) && tag.typeExpression && tag.typeExpression.kind === SyntaxKind.JSDocTypeExpression) {
currentToken = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ true);
if (!currentToken ||
(!isDeclarationName(currentToken) &&
@@ -606,7 +606,7 @@ namespace ts.Completions {
if (symbol.flags & (SymbolFlags.Module | SymbolFlags.Enum)) {
// Extract module or enum members
const exportedSymbols = typeChecker.getExportsOfModule(symbol);
const isValidValueAccess = (symbol: Symbol) => typeChecker.isValidPropertyAccess(<PropertyAccessExpression>(node.parent), symbol.getUnescapedName());
const isValidValueAccess = (symbol: Symbol) => typeChecker.isValidPropertyAccess(<PropertyAccessExpression>(node.parent), symbol.name);
const isValidTypeAccess = (symbol: Symbol) => symbolCanBeReferencedAtTypeLocation(symbol);
const isValidAccess = isRhsOfImportDeclaration ?
// Any kind is allowed when dotting off namespace in internal import equals declaration
@@ -636,7 +636,7 @@ namespace ts.Completions {
function addTypeProperties(type: Type) {
// Filter private properties
for (const symbol of type.getApparentProperties()) {
if (typeChecker.isValidPropertyAccess(<PropertyAccessExpression>(node.parent), symbol.getUnescapedName())) {
if (typeChecker.isValidPropertyAccess(<PropertyAccessExpression>(node.parent), symbol.name)) {
symbols.push(symbol);
}
}
@@ -1453,14 +1453,14 @@ namespace ts.Completions {
}
const name = element.propertyName || element.name;
existingImportsOrExports.set(name.text, true);
existingImportsOrExports.set(name.escapedText, true);
}
if (existingImportsOrExports.size === 0) {
return filter(exportsOfModule, e => e.name !== "default");
return filter(exportsOfModule, e => e.escapedName !== "default");
}
return filter(exportsOfModule, e => e.name !== "default" && !existingImportsOrExports.get(e.name));
return filter(exportsOfModule, e => e.escapedName !== "default" && !existingImportsOrExports.get(e.escapedName));
}
/**
@@ -1496,7 +1496,7 @@ namespace ts.Completions {
if (m.kind === SyntaxKind.BindingElement && (<BindingElement>m).propertyName) {
// include only identifiers in completion list
if ((<BindingElement>m).propertyName.kind === SyntaxKind.Identifier) {
existingName = (<Identifier>(<BindingElement>m).propertyName).text;
existingName = (<Identifier>(<BindingElement>m).propertyName).escapedText;
}
}
else {
@@ -1510,7 +1510,7 @@ namespace ts.Completions {
existingMemberNames.set(existingName, true);
}
return filter(contextualMemberSymbols, m => !existingMemberNames.get(m.name));
return filter(contextualMemberSymbols, m => !existingMemberNames.get(m.escapedName));
}
/**
@@ -1571,7 +1571,7 @@ namespace ts.Completions {
}
function isValidProperty(propertySymbol: Symbol, inValidModifierFlags: ModifierFlags) {
return !existingMemberNames.get(propertySymbol.name) &&
return !existingMemberNames.get(propertySymbol.escapedName) &&
propertySymbol.getDeclarations() &&
!(getDeclarationModifierFlagsFromSymbol(propertySymbol) & inValidModifierFlags);
}
@@ -1592,11 +1592,11 @@ namespace ts.Completions {
}
if (attr.kind === SyntaxKind.JsxAttribute) {
seenNames.set((<JsxAttribute>attr).name.text, true);
seenNames.set((<JsxAttribute>attr).name.escapedText, true);
}
}
return filter(symbols, a => !seenNames.get(a.name));
return filter(symbols, a => !seenNames.get(a.escapedName));
}
function isCurrentlyEditingNode(node: Node): boolean {
@@ -1610,7 +1610,7 @@ namespace ts.Completions {
* @return undefined if the name is of external module
*/
function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean): string | undefined {
const name = symbol.getUnescapedName();
const name = symbol.name;
if (!name) return undefined;
// First check of the displayName is not external module; if it is an external module, it is not valid entry
+2 -2
View File
@@ -248,7 +248,7 @@ namespace ts.DocumentHighlights {
case SyntaxKind.ForOfStatement:
case SyntaxKind.WhileStatement:
case SyntaxKind.DoStatement:
if (!statement.label || isLabeledBy(node, unescapeLeadingUnderscores(statement.label.text))) {
if (!statement.label || isLabeledBy(node, statement.label.text)) {
return node;
}
break;
@@ -606,7 +606,7 @@ namespace ts.DocumentHighlights {
*/
function isLabeledBy(node: Node, labelName: string) {
for (let owner = node.parent; owner.kind === SyntaxKind.LabeledStatement; owner = owner.parent) {
if ((<LabeledStatement>owner).label.text === labelName) {
if ((<LabeledStatement>owner).label.escapedText === labelName) {
return true;
}
}
+18 -13
View File
@@ -122,7 +122,7 @@ namespace ts.FindAllReferences {
}
case "label": {
const { node } = def;
return { node, name: unescapeLeadingUnderscores(node.text), kind: ScriptElementKind.label, displayParts: [displayPart(unescapeLeadingUnderscores(node.text), SymbolDisplayPartKind.text)] };
return { node, name: node.text, kind: ScriptElementKind.label, displayParts: [displayPart(node.text, SymbolDisplayPartKind.text)] };
}
case "keyword": {
const { node } = def;
@@ -357,7 +357,7 @@ namespace ts.FindAllReferences.Core {
// Labels
if (isLabelName(node)) {
if (isJumpStatementTarget(node)) {
const labelDefinition = getTargetLabel((<BreakOrContinueStatement>node.parent), unescapeLeadingUnderscores((<Identifier>node).text));
const labelDefinition = getTargetLabel((<BreakOrContinueStatement>node.parent), (<Identifier>node).text);
// if we have a label definition, look within its statement for references, if not, then
// the label is undefined and we have no results..
return labelDefinition && getLabelReferencesInNode(labelDefinition.parent, labelDefinition);
@@ -604,11 +604,16 @@ namespace ts.FindAllReferences.Core {
function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol: Symbol, checker: TypeChecker): Symbol | undefined {
const bindingElement = getObjectBindingElementWithoutPropertyName(symbol);
if (bindingElement) {
const typeOfPattern = checker.getTypeAtLocation(bindingElement.parent);
return typeOfPattern && checker.getPropertyOfType(typeOfPattern, unescapeLeadingUnderscores((<Identifier>bindingElement.name).text));
if (!bindingElement) return undefined;
const typeOfPattern = checker.getTypeAtLocation(bindingElement.parent);
const propSymbol = typeOfPattern && checker.getPropertyOfType(typeOfPattern, (<Identifier>bindingElement.name).text);
if (propSymbol && propSymbol.flags & SymbolFlags.Accessor) {
// See GH#16922
Debug.assert(!!(propSymbol.flags & SymbolFlags.Transient));
return (propSymbol as TransientSymbol).target;
}
return undefined;
return propSymbol;
}
/**
@@ -718,7 +723,7 @@ namespace ts.FindAllReferences.Core {
function getLabelReferencesInNode(container: Node, targetLabel: Identifier): SymbolAndEntries[] {
const references: Entry[] = [];
const sourceFile = container.getSourceFile();
const labelName = unescapeLeadingUnderscores(targetLabel.text);
const labelName = targetLabel.text;
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container);
for (const position of possiblePositions) {
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false);
@@ -735,7 +740,7 @@ namespace ts.FindAllReferences.Core {
// Compare the length so we filter out strict superstrings of the symbol we are looking for
switch (node && node.kind) {
case SyntaxKind.Identifier:
return unescapeLeadingUnderscores((node as Identifier).text).length === searchSymbolName.length;
return (node as Identifier).text.length === searchSymbolName.length;
case SyntaxKind.StringLiteral:
return (isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) &&
@@ -1417,7 +1422,7 @@ namespace ts.FindAllReferences.Core {
// Property Declaration symbol is a member of the class, so the symbol is stored in its class Declaration.symbol.members
if (symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.Parameter &&
isParameterPropertyDeclaration(<ParameterDeclaration>symbol.valueDeclaration)) {
addRange(result, checker.getSymbolsOfParameterPropertyDeclaration(<ParameterDeclaration>symbol.valueDeclaration, symbol.getUnescapedName()));
addRange(result, checker.getSymbolsOfParameterPropertyDeclaration(<ParameterDeclaration>symbol.valueDeclaration, symbol.name));
}
// If this is symbol of binding element without propertyName declaration in Object binding pattern
@@ -1436,7 +1441,7 @@ namespace ts.FindAllReferences.Core {
// Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getUnescapedName(), result, /*previousIterationSymbolsCache*/ createSymbolTable(), checker);
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), checker);
}
}
@@ -1467,7 +1472,7 @@ namespace ts.FindAllReferences.Core {
// the function will add any found symbol of the property-name, then its sub-routine will call
// getPropertySymbolsFromBaseTypes again to walk up any base types to prevent revisiting already
// visited symbol, interface "C", the sub-routine will pass the current symbol as previousIterationSymbol.
if (previousIterationSymbolsCache.has(symbol.name)) {
if (previousIterationSymbolsCache.has(symbol.escapedName)) {
return;
}
@@ -1494,7 +1499,7 @@ namespace ts.FindAllReferences.Core {
}
// Visit the typeReference as well to see if it directly or indirectly use that property
previousIterationSymbolsCache.set(symbol.name, symbol);
previousIterationSymbolsCache.set(symbol.escapedName, symbol);
getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result, previousIterationSymbolsCache, checker);
}
}
@@ -1554,7 +1559,7 @@ namespace ts.FindAllReferences.Core {
}
const result: Symbol[] = [];
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getUnescapedName(), result, /*previousIterationSymbolsCache*/ createSymbolTable(), state.checker);
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), state.checker);
return find(result, search.includes);
}
+1 -1
View File
@@ -26,7 +26,7 @@ namespace ts.GoToDefinition {
// Labels
if (isJumpStatementTarget(node)) {
const labelName = unescapeLeadingUnderscores((<Identifier>node).text);
const labelName = (<Identifier>node).text;
const label = getTargetLabel((<BreakOrContinueStatement>node.parent), labelName);
return label ? [createDefinitionInfoFromName(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined;
}
+10 -10
View File
@@ -180,7 +180,7 @@ namespace ts.FindAllReferences {
* But re-exports will be placed in 'singleReferences' since they cannot be locally referenced.
*/
function getSearchesFromDirectImports(directImports: Importer[], exportSymbol: Symbol, exportKind: ExportKind, checker: TypeChecker, isForRename: boolean): Pick<ImportsResult, "importSearches" | "singleReferences"> {
const exportName = exportSymbol.name;
const exportName = exportSymbol.escapedName;
const importSearches: Array<[Identifier, Symbol]> = [];
const singleReferences: Identifier[] = [];
function addSearch(location: Identifier, symbol: Symbol): void {
@@ -238,7 +238,7 @@ namespace ts.FindAllReferences {
const { name } = importClause;
// If a default import has the same name as the default export, allow to rename it.
// Given `import f` and `export default function f`, we will rename both, but for `import g` we will rename just that.
if (name && (!isForRename || name.text === symbolName(exportSymbol))) {
if (name && (!isForRename || name.escapedText === symbolName(exportSymbol))) {
const defaultImportAlias = checker.getSymbolAtLocation(name);
addSearch(name, defaultImportAlias);
}
@@ -258,7 +258,7 @@ namespace ts.FindAllReferences {
*/
function handleNamespaceImportLike(importName: Identifier): void {
// Don't rename an import that already has a different name than the export.
if (exportKind === ExportKind.ExportEquals && (!isForRename || importName.text === exportName)) {
if (exportKind === ExportKind.ExportEquals && (!isForRename || importName.escapedText === exportName)) {
addSearch(importName, checker.getSymbolAtLocation(importName));
}
}
@@ -267,7 +267,7 @@ namespace ts.FindAllReferences {
if (namedBindings) {
for (const element of namedBindings.elements) {
const { name, propertyName } = element;
if ((propertyName || name).text !== exportName) {
if ((propertyName || name).escapedText !== exportName) {
continue;
}
@@ -521,11 +521,11 @@ namespace ts.FindAllReferences {
// Search on the local symbol in the exporting module, not the exported symbol.
importedSymbol = skipExportSpecifierSymbol(importedSymbol, checker);
// Similarly, skip past the symbol for 'export ='
if (importedSymbol.name === "export=") {
if (importedSymbol.escapedName === "export=") {
importedSymbol = getExportEqualsLocalSymbol(importedSymbol, checker);
}
if (symbolName(importedSymbol) === symbol.name) { // If this is a rename import, do not continue searching.
if (symbolName(importedSymbol) === symbol.escapedName) { // If this is a rename import, do not continue searching.
return { kind: ImportExport.Import, symbol: importedSymbol, ...isImport };
}
}
@@ -595,16 +595,16 @@ namespace ts.FindAllReferences {
}
function symbolName(symbol: Symbol): __String | undefined {
if (symbol.name !== "default") {
return symbol.getName();
if (symbol.escapedName !== "default") {
return symbol.escapedName;
}
return forEach(symbol.declarations, decl => {
if (isExportAssignment(decl)) {
return isIdentifier(decl.expression) ? decl.expression.text : undefined;
return isIdentifier(decl.expression) ? decl.expression.escapedText : undefined;
}
const name = getNameOfDeclaration(decl);
return name && name.kind === SyntaxKind.Identifier && name.text;
return name && name.kind === SyntaxKind.Identifier && name.escapedText;
});
}
+8 -5
View File
@@ -71,7 +71,7 @@ namespace ts.JsDoc {
forEachUnique(declarations, declaration => {
for (const tag of getJSDocTags(declaration)) {
if (tag.kind === SyntaxKind.JSDocTag) {
tags.push({ name: unescapeLeadingUnderscores(tag.tagName.text), text: tag.comment });
tags.push({ name: tag.tagName.text, text: tag.comment });
}
}
});
@@ -120,7 +120,10 @@ namespace ts.JsDoc {
}
export function getJSDocParameterNameCompletions(tag: JSDocParameterTag): CompletionEntry[] {
const nameThusFar = unescapeLeadingUnderscores(tag.name.text);
if (!isIdentifier(tag.name)) {
return emptyArray;
}
const nameThusFar = tag.name.text;
const jsdoc = tag.parent;
const fn = jsdoc.parent;
if (!ts.isFunctionLike(fn)) return [];
@@ -128,8 +131,8 @@ namespace ts.JsDoc {
return mapDefined(fn.parameters, param => {
if (!isIdentifier(param.name)) return undefined;
const name = unescapeLeadingUnderscores(param.name.text);
if (jsdoc.tags.some(t => t !== tag && isJSDocParameterTag(t) && t.name.text === name)
const name = param.name.text;
if (jsdoc.tags.some(t => t !== tag && isJSDocParameterTag(t) && isIdentifier(t.name) && t.name.escapedText === name)
|| nameThusFar !== undefined && !startsWith(name, nameThusFar)) {
return undefined;
}
@@ -213,7 +216,7 @@ namespace ts.JsDoc {
for (let i = 0; i < parameters.length; i++) {
const currentName = parameters[i].name;
const paramName = currentName.kind === SyntaxKind.Identifier ?
(<Identifier>currentName).text :
(<Identifier>currentName).escapedText :
"param" + i;
if (isJavaScriptFile) {
docParams += `${indentationStr} * @param {any} ${paramName}${newLine}`;
+34 -45
View File
@@ -22,13 +22,10 @@ namespace ts.JsTyping {
name?: string;
optionalDependencies?: MapLike<string>;
peerDependencies?: MapLike<string>;
types?: string;
typings?: string;
}
// A map of loose file names to library names
// that we are confident require typings
let safeList: Map<string>;
/* @internal */
export const nodeCoreModuleList: ReadonlyArray<string> = [
"buffer", "querystring", "events", "http", "cluster",
@@ -40,6 +37,16 @@ namespace ts.JsTyping {
const nodeCoreModules = arrayToMap(<string[]>nodeCoreModuleList, x => x);
/**
* A map of loose file names to library names that we are confident require typings
*/
export type SafeList = ReadonlyMap<string>;
export function loadSafeList(host: TypingResolutionHost, safeListPath: Path): SafeList {
const result = readConfigFile(safeListPath, path => host.readFile(path));
return createMapFromTemplate<string>(result.config);
}
/**
* @param host is the object providing I/O related operations.
* @param fileNames are the file names that belong to the same project
@@ -54,8 +61,8 @@ namespace ts.JsTyping {
log: ((message: string) => void) | undefined,
fileNames: string[],
projectRootPath: Path,
safeListPath: Path,
packageNameToTypingLocation: Map<string>,
safeList: SafeList,
packageNameToTypingLocation: ReadonlyMap<string>,
typeAcquisition: TypeAcquisition,
unresolvedImports: ReadonlyArray<string>):
{ cachedTypingPaths: string[], newTypingNames: string[], filesToWatch: string[] } {
@@ -75,21 +82,13 @@ namespace ts.JsTyping {
}
});
if (!safeList) {
const result = readConfigFile(safeListPath, (path: string) => host.readFile(path));
safeList = createMapFromTemplate<string>(result.config);
}
const filesToWatch: string[] = [];
forEach(typeAcquisition.include, addInferredTyping);
if (typeAcquisition.include) addInferredTypings(typeAcquisition.include, "Explicitly included types");
const exclude = typeAcquisition.exclude || [];
// Directories to search for package.json, bower.json and other typing information
const possibleSearchDirs = createMap<true>();
for (const f of fileNames) {
possibleSearchDirs.set(getDirectoryPath(f), true);
}
const possibleSearchDirs = arrayToSet(fileNames, getDirectoryPath);
possibleSearchDirs.set(projectRootPath, true);
possibleSearchDirs.forEach((_true, searchDir) => {
const packageJsonPath = combinePaths(searchDir, "package.json");
@@ -108,13 +107,8 @@ namespace ts.JsTyping {
// add typings for unresolved imports
if (unresolvedImports) {
const x = unresolvedImports.map(moduleId => nodeCoreModules.has(moduleId) ? "node" : moduleId);
if (x.length && log) log(`Inferred typings from unresolved imports: ${JSON.stringify(x)}`);
for (const typingName of x) {
if (!inferredTypings.has(typingName)) {
inferredTypings.set(typingName, undefined);
}
}
const module = deduplicate(unresolvedImports.map(moduleId => nodeCoreModules.has(moduleId) ? "node" : moduleId));
addInferredTypings(module, "Inferred typings from unresolved imports");
}
// Add the cached typing locations for inferred typings that are already installed
packageNameToTypingLocation.forEach((typingLocation, name) => {
@@ -125,7 +119,8 @@ namespace ts.JsTyping {
// Remove typings that the user has added to the exclude list
for (const excludeTypingName of exclude) {
inferredTypings.delete(excludeTypingName);
const didDelete = inferredTypings.delete(excludeTypingName);
if (didDelete && log) log(`Typing for ${excludeTypingName} is in exclude list, will be ignored.`);
}
const newTypingNames: string[] = [];
@@ -147,6 +142,10 @@ namespace ts.JsTyping {
inferredTypings.set(typingName, undefined);
}
}
function addInferredTypings(typingNames: ReadonlyArray<string>, message: string) {
if (log) log(`${message}: ${JSON.stringify(typingNames)}`);
forEach(typingNames, addInferredTyping);
}
/**
* Get the typing info from common package manager json files like package.json or bower.json
@@ -157,20 +156,9 @@ namespace ts.JsTyping {
}
filesToWatch.push(jsonPath);
if (log) log(`Searching for typing names in '${jsonPath}' dependencies`);
const jsonConfig: PackageJson = readConfigFile(jsonPath, (path: string) => host.readFile(path)).config;
addInferredTypingsFromKeys(jsonConfig.dependencies);
addInferredTypingsFromKeys(jsonConfig.devDependencies);
addInferredTypingsFromKeys(jsonConfig.optionalDependencies);
addInferredTypingsFromKeys(jsonConfig.peerDependencies);
function addInferredTypingsFromKeys(map: MapLike<string> | undefined): void {
for (const key in map) {
if (ts.hasProperty(map, key)) {
addInferredTyping(key);
}
}
}
const jsonConfig: PackageJson = readConfigFile(jsonPath, path => host.readFile(path)).config;
const jsonTypingNames = flatMap([jsonConfig.dependencies, jsonConfig.devDependencies, jsonConfig.optionalDependencies, jsonConfig.peerDependencies], getOwnKeys);
addInferredTypings(jsonTypingNames, `Typing names in '${jsonPath}' dependencies`);
}
/**
@@ -188,10 +176,7 @@ namespace ts.JsTyping {
return safeList.get(cleanedTypingName);
});
if (fromFileNames.length) {
if (log) log(`Inferred typings from file names: ${JSON.stringify(fromFileNames)}`);
for (const safe of fromFileNames) {
addInferredTyping(safe);
}
addInferredTypings(fromFileNames, "Inferred typings from file names");
}
const hasJsxFile = some(fileNames, f => fileExtensionIs(f, Extension.Jsx));
@@ -216,6 +201,7 @@ namespace ts.JsTyping {
// depth of 2, so we access `node_modules/foo` but not `node_modules/foo/bar`
const fileNames = host.readDirectory(packagesFolderPath, [".json"], /*excludes*/ undefined, /*includes*/ undefined, /*depth*/ 2);
if (log) log(`Searching for typing names in ${packagesFolderPath}; all files: ${JSON.stringify(fileNames)}`);
const packageNames: string[] = [];
for (const fileName of fileNames) {
const normalizedFileName = normalizePath(fileName);
const baseFileName = getBaseFileName(normalizedFileName);
@@ -238,14 +224,17 @@ namespace ts.JsTyping {
if (!packageJson.name) {
continue;
}
if (packageJson.typings) {
const absolutePath = getNormalizedAbsolutePath(packageJson.typings, getDirectoryPath(normalizedFileName));
const ownTypes = packageJson.types || packageJson.typings;
if (ownTypes) {
const absolutePath = getNormalizedAbsolutePath(ownTypes, getDirectoryPath(normalizedFileName));
if (log) log(` Package '${packageJson.name}' provides its own types.`);
inferredTypings.set(packageJson.name, absolutePath);
}
else {
addInferredTyping(packageJson.name);
packageNames.push(packageJson.name);
}
}
addInferredTypings(packageNames, " Found package names");
}
}
+3 -3
View File
@@ -54,7 +54,7 @@ namespace ts.NavigateTo {
if (decl.kind === SyntaxKind.ImportClause || decl.kind === SyntaxKind.ImportSpecifier || decl.kind === SyntaxKind.ImportEqualsDeclaration) {
const importer = checker.getSymbolAtLocation((decl as NamedDeclaration).name);
const imported = checker.getAliasedSymbol(importer);
return importer.name !== imported.name;
return importer.escapedName !== imported.escapedName;
}
else {
return true;
@@ -119,7 +119,7 @@ namespace ts.NavigateTo {
if (expression.kind === SyntaxKind.PropertyAccessExpression) {
const propertyAccess = <PropertyAccessExpression>expression;
if (includeLastPortion) {
containers.unshift(unescapeLeadingUnderscores(propertyAccess.name.text));
containers.unshift(propertyAccess.name.text);
}
return tryAddComputedPropertyName(propertyAccess.expression, containers, /*includeLastPortion*/ true);
@@ -191,7 +191,7 @@ namespace ts.NavigateTo {
fileName: rawItem.fileName,
textSpan: createTextSpanFromNode(declaration),
// TODO(jfreeman): What should be the containerName when the container has a computed name?
containerName: containerName ? unescapeLeadingUnderscores((<Identifier>containerName).text) : "",
containerName: containerName ? (<Identifier>containerName).text : "",
containerKind: containerName ? getNodeKind(container) : ScriptElementKind.unknown
};
}
+2 -2
View File
@@ -442,7 +442,7 @@ namespace ts.NavigationBar {
function getJSDocTypedefTagName(node: JSDocTypedefTag): string {
if (node.name) {
return unescapeLeadingUnderscores(node.name.text);
return node.name.text;
}
else {
const parentNode = node.parent && node.parent.parent;
@@ -450,7 +450,7 @@ namespace ts.NavigationBar {
if ((<VariableStatement>parentNode).declarationList.declarations.length > 0) {
const nameIdentifier = (<VariableStatement>parentNode).declarationList.declarations[0].name;
if (nameIdentifier.kind === SyntaxKind.Identifier) {
return unescapeLeadingUnderscores((<Identifier>nameIdentifier).text);
return nameIdentifier.text;
}
}
}
+1 -1
View File
@@ -239,7 +239,7 @@ namespace ts.Completions.PathCompletions {
const moduleNameFragment = isNestedModule ? fragment.substr(0, fragment.lastIndexOf(directorySeparator)) : undefined;
// Get modules that the type checker picked up
const ambientModules = map(typeChecker.getAmbientModules(), sym => stripQuotes(unescapeLeadingUnderscores(sym.name)));
const ambientModules = map(typeChecker.getAmbientModules(), sym => stripQuotes(sym.name));
let nonRelativeModuleNames = filter(ambientModules, moduleName => startsWith(moduleName, fragment));
// Nested modules of the form "module-name/sub" need to be adjusted to only return the string
@@ -163,7 +163,7 @@ namespace ts.refactor {
deleteNode(nodeToDelete);
if (!assignmentBinaryExpression.right) {
return createProperty([], modifiers, symbol.getUnescapedName(), /*questionToken*/ undefined,
return createProperty([], modifiers, symbol.name, /*questionToken*/ undefined,
/*type*/ undefined, /*initializer*/ undefined);
}
+25 -10
View File
@@ -304,7 +304,7 @@ namespace ts {
class SymbolObject implements Symbol {
flags: SymbolFlags;
name: __String;
escapedName: __String;
declarations?: Declaration[];
// Undefined is used to indicate the value has not been computed. If, after computing, the
@@ -317,19 +317,23 @@ namespace ts {
constructor(flags: SymbolFlags, name: __String) {
this.flags = flags;
this.name = name;
this.escapedName = name;
}
getFlags(): SymbolFlags {
return this.flags;
}
getName(): __String {
return this.name;
get name(): string {
return unescapeLeadingUnderscores(this.escapedName);
}
getUnescapedName(): string {
return unescapeLeadingUnderscores(this.name);
getEscapedName(): __String {
return this.escapedName;
}
getName(): string {
return this.name;
}
getDeclarations(): Declaration[] | undefined {
@@ -364,7 +368,7 @@ namespace ts {
class IdentifierObject extends TokenOrIdentifierObject implements Identifier {
public kind: SyntaxKind.Identifier;
public text: __String;
public escapedText: __String;
_primaryExpressionBrand: any;
_memberExpressionBrand: any;
_leftHandSideExpressionBrand: any;
@@ -375,6 +379,10 @@ namespace ts {
constructor(_kind: SyntaxKind.Identifier, pos: number, end: number) {
super(pos, end);
}
get text(): string {
return unescapeLeadingUnderscores(this.escapedText);
}
}
IdentifierObject.prototype.kind = SyntaxKind.Identifier;
@@ -601,7 +609,7 @@ namespace ts {
if (name.kind === SyntaxKind.ComputedPropertyName) {
const expr = (<ComputedPropertyName>name).expression;
if (expr.kind === SyntaxKind.PropertyAccessExpression) {
return unescapeLeadingUnderscores((<PropertyAccessExpression>expr).name.text);
return (<PropertyAccessExpression>expr).name.text;
}
return getTextOfIdentifierOrLiteral(expr as (Identifier | LiteralExpression));
@@ -1826,7 +1834,8 @@ namespace ts {
const fileContents = sourceFile.text;
const result: TodoComment[] = [];
if (descriptors.length > 0) {
// Exclude node_modules files as we don't want to show the todos of external libraries.
if (descriptors.length > 0 && !isNodeModulesFile(sourceFile.fileName)) {
const regExp = getTodoCommentsRegExp();
let matchArray: RegExpExecArray;
@@ -1950,6 +1959,12 @@ namespace ts {
(char >= CharacterCodes.A && char <= CharacterCodes.Z) ||
(char >= CharacterCodes._0 && char <= CharacterCodes._9);
}
function isNodeModulesFile(path: string): boolean {
const node_modulesFolderName = "/node_modules/";
return path.indexOf(node_modulesFolderName) !== -1;
}
}
function getRenameInfo(fileName: string, position: number): RenameInfo {
@@ -2050,7 +2065,7 @@ namespace ts {
function initializeNameTable(sourceFile: SourceFile): void {
const nameTable = sourceFile.nameTable = createUnderscoreEscapedMap<number>();
sourceFile.forEachChild(function walk(node) {
if ((isIdentifier(node) || isStringOrNumericLiteral(node) && literalIsName(node)) && node.text) {
if (isIdentifier(node) && node.escapedText || isStringOrNumericLiteral(node) && literalIsName(node)) {
const text = getEscapedTextOfIdentifierOrLiteral(node);
nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1);
}
+6 -2
View File
@@ -1005,6 +1005,7 @@ namespace ts {
class CoreServicesShimObject extends ShimBase implements CoreServicesShim {
private logPerformance = false;
private safeList: JsTyping.SafeList | undefined;
constructor(factory: ShimFactory, public readonly logger: Logger, private readonly host: CoreServicesShimHostAdapter) {
super(factory);
@@ -1114,12 +1115,15 @@ namespace ts {
const getCanonicalFileName = createGetCanonicalFileName(/*useCaseSensitivefileNames:*/ false);
return this.forwardJSONCall("discoverTypings()", () => {
const info = <DiscoverTypingsInfo>JSON.parse(discoverTypingsJson);
return ts.JsTyping.discoverTypings(
if (this.safeList === undefined) {
this.safeList = JsTyping.loadSafeList(this.host, toPath(info.safeListPath, info.safeListPath, getCanonicalFileName));
}
return JsTyping.discoverTypings(
this.host,
msg => this.logger.log(msg),
info.fileNames,
toPath(info.projectRootPath, info.projectRootPath, getCanonicalFileName),
toPath(info.safeListPath, info.safeListPath, getCanonicalFileName),
this.safeList,
info.packageNameToTypingLocation,
info.typeAcquisition,
info.unresolvedImports);
+4 -4
View File
@@ -65,14 +65,14 @@ namespace ts.SignatureHelp {
? (<PropertyAccessExpression>expression).name
: undefined;
if (!name || !name.text) {
if (!name || !name.escapedText) {
return undefined;
}
const typeChecker = program.getTypeChecker();
for (const sourceFile of program.getSourceFiles()) {
const nameToDeclarations = sourceFile.getNamedDeclarations();
const declarations = nameToDeclarations.get(unescapeLeadingUnderscores(name.text));
const declarations = nameToDeclarations.get(name.text);
if (declarations) {
for (const declaration of declarations) {
@@ -414,7 +414,7 @@ namespace ts.SignatureHelp {
typeChecker.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation));
return {
name: parameter.getUnescapedName(),
name: parameter.name,
documentation: parameter.getDocumentationComment(),
displayParts,
isOptional: typeChecker.isOptionalParameter(<ParameterDeclaration>parameter.valueDeclaration)
@@ -426,7 +426,7 @@ namespace ts.SignatureHelp {
typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, invocation));
return {
name: typeParameter.symbol.getUnescapedName(),
name: typeParameter.symbol.name,
documentation: emptyArray,
displayParts,
isOptional: false
+7 -2
View File
@@ -22,10 +22,15 @@ namespace ts {
forEachChild<T>(cbNode: (node: Node) => T | undefined, cbNodeArray?: (nodes: NodeArray<Node>) => T | undefined): T | undefined;
}
export interface Identifier {
readonly text: string;
}
export interface Symbol {
readonly name: string;
getFlags(): SymbolFlags;
getName(): __String;
getUnescapedName(): string;
getEscapedName(): __String;
getName(): string;
getDeclarations(): Declaration[] | undefined;
getDocumentationComment(): SymbolDisplayPart[];
getJsDocTags(): JSDocTagInfo[];
+2 -2
View File
@@ -203,7 +203,7 @@ namespace ts {
export function getTargetLabel(referenceNode: Node, labelName: string): Identifier {
while (referenceNode) {
if (referenceNode.kind === SyntaxKind.LabeledStatement && (<LabeledStatement>referenceNode).label.text === labelName) {
if (referenceNode.kind === SyntaxKind.LabeledStatement && (<LabeledStatement>referenceNode).label.escapedText === labelName) {
return (<LabeledStatement>referenceNode).label;
}
referenceNode = referenceNode.parent;
@@ -1090,7 +1090,7 @@ namespace ts {
/** True if the symbol is for an external module, as opposed to a namespace. */
export function isExternalModuleSymbol(moduleSymbol: Symbol): boolean {
Debug.assert(!!(moduleSymbol.flags & SymbolFlags.Module));
return moduleSymbol.getUnescapedName().charCodeAt(0) === CharacterCodes.doubleQuote;
return moduleSymbol.name.charCodeAt(0) === CharacterCodes.doubleQuote;
}
/** Returns `true` the first time it encounters a node and `false` afterwards. */
@@ -16,7 +16,7 @@
"kind": "Identifier",
"pos": 9,
"end": 12,
"text": "arg"
"escapedText": "arg"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
@@ -28,18 +28,13 @@
"end": 20
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 22,
"end": 27,
"text": "name1"
},
"name": {
"kind": "Identifier",
"pos": 22,
"end": 27,
"text": "name1"
"escapedText": "name1"
},
"isNameFirst": false,
"isBracketed": false,
"comment": "Description"
},
@@ -16,7 +16,7 @@
"kind": "Identifier",
"pos": 9,
"end": 17,
"text": "argument"
"escapedText": "argument"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
@@ -28,18 +28,13 @@
"end": 25
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 27,
"end": 32,
"text": "name1"
},
"name": {
"kind": "Identifier",
"pos": 27,
"end": 32,
"text": "name1"
"escapedText": "name1"
},
"isNameFirst": false,
"isBracketed": false,
"comment": "Description"
},
@@ -16,7 +16,7 @@
"kind": "Identifier",
"pos": 9,
"end": 13,
"text": "type"
"escapedText": "type"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
@@ -16,7 +16,7 @@
"kind": "Identifier",
"pos": 9,
"end": 13,
"text": "type"
"escapedText": "type"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
@@ -16,7 +16,7 @@
"kind": "Identifier",
"pos": 9,
"end": 15,
"text": "return"
"escapedText": "return"
},
"comment": ""
},
@@ -16,7 +16,7 @@
"kind": "Identifier",
"pos": 9,
"end": 13,
"text": "type"
"escapedText": "type"
},
"comment": ""
},
@@ -16,7 +16,7 @@
"kind": "Identifier",
"pos": 9,
"end": 14,
"text": "param"
"escapedText": "param"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
@@ -28,18 +28,13 @@
"end": 22
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 24,
"end": 29,
"text": "name1"
},
"name": {
"kind": "Identifier",
"pos": 24,
"end": 29,
"text": "name1"
"escapedText": "name1"
},
"isNameFirst": false,
"isBracketed": false,
"comment": ""
},
@@ -16,7 +16,7 @@
"kind": "Identifier",
"pos": 9,
"end": 14,
"text": "param"
"escapedText": "param"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
@@ -28,18 +28,13 @@
"end": 22
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 24,
"end": 29,
"text": "name1"
},
"name": {
"kind": "Identifier",
"pos": 24,
"end": 29,
"text": "name1"
"escapedText": "name1"
},
"isNameFirst": false,
"isBracketed": false,
"comment": "Description text follows"
},
@@ -16,7 +16,7 @@
"kind": "Identifier",
"pos": 9,
"end": 14,
"text": "param"
"escapedText": "param"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
@@ -28,18 +28,13 @@
"end": 22
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 25,
"end": 30,
"text": "name1"
},
"name": {
"kind": "Identifier",
"pos": 25,
"end": 30,
"text": "name1"
"escapedText": "name1"
},
"isNameFirst": false,
"isBracketed": true,
"comment": "Description text follows"
},
@@ -16,7 +16,7 @@
"kind": "Identifier",
"pos": 9,
"end": 14,
"text": "param"
"escapedText": "param"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
@@ -28,18 +28,13 @@
"end": 22
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 26,
"end": 31,
"text": "name1"
},
"name": {
"kind": "Identifier",
"pos": 26,
"end": 31,
"text": "name1"
"escapedText": "name1"
},
"isNameFirst": false,
"isBracketed": true,
"comment": "Description text follows"
},
@@ -16,13 +16,7 @@
"kind": "Identifier",
"pos": 9,
"end": 14,
"text": "param"
},
"preParameterName": {
"kind": "Identifier",
"pos": 15,
"end": 20,
"text": "name1"
"escapedText": "param"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
@@ -38,8 +32,9 @@
"kind": "Identifier",
"pos": 15,
"end": 20,
"text": "name1"
"escapedText": "name1"
},
"isNameFirst": true,
"isBracketed": false,
"comment": ""
},

Some files were not shown because too many files have changed in this diff Show More