Merge branch 'master' into fixAsyncReturnTypeCheck

This commit is contained in:
Ron Buckton committed 2016-10-31 15:17:26 -07:00
commit 884e9f47db
1333 files changed
+113992 -80906

No files matched your search

+2
View File
@@ -41,7 +41,9 @@ tests/cases/**/*.js.map
scripts/debug.bat
scripts/run.bat
scripts/word2md.js
scripts/buildProtocol.js
scripts/ior.js
scripts/buildProtocol.js
scripts/*.js.map
scripts/typings/
coverage/
+1 -1
View File
@@ -15,7 +15,7 @@ matrix:
branches:
only:
- master
- release-2.0
- release-2.1
install:
- npm uninstall typescript
-2
View File
@@ -183,5 +183,3 @@ jake baseline-accept
```
to establish the new baselines as the desired behavior. This will change the files in `tests\baselines\reference`, which should be included as part of your commit. It's important to carefully validate changes in the baselines.
**Note** that `baseline-accept` should only be run after a full test run! Accepting baselines after running a subset of tests will delete baseline files for the tests that didn't run.
+58 -17
View File
@@ -70,13 +70,15 @@ var compilerSources = [
"visitor.ts",
"transformers/destructuring.ts",
"transformers/ts.ts",
"transformers/module/es6.ts",
"transformers/jsx.ts",
"transformers/es2017.ts",
"transformers/es2016.ts",
"transformers/es2015.ts",
"transformers/generators.ts",
"transformers/es5.ts",
"transformers/module/es2015.ts",
"transformers/module/system.ts",
"transformers/module/module.ts",
"transformers/jsx.ts",
"transformers/es7.ts",
"transformers/generators.ts",
"transformers/es6.ts",
"transformer.ts",
"sourcemap.ts",
"comments.ts",
@@ -104,13 +106,15 @@ var servicesSources = [
"visitor.ts",
"transformers/destructuring.ts",
"transformers/ts.ts",
"transformers/module/es6.ts",
"transformers/jsx.ts",
"transformers/es2017.ts",
"transformers/es2016.ts",
"transformers/es2015.ts",
"transformers/generators.ts",
"transformers/es5.ts",
"transformers/module/es2015.ts",
"transformers/module/system.ts",
"transformers/module/module.ts",
"transformers/jsx.ts",
"transformers/es7.ts",
"transformers/generators.ts",
"transformers/es6.ts",
"transformer.ts",
"sourcemap.ts",
"comments.ts",
@@ -174,7 +178,7 @@ var serverCoreSources = [
"lsHost.ts",
"project.ts",
"editorServices.ts",
"protocol.d.ts",
"protocol.ts",
"session.ts",
"server.ts"
].map(function (f) {
@@ -198,14 +202,13 @@ var typingsInstallerSources = [
var serverSources = serverCoreSources.concat(servicesSources);
var languageServiceLibrarySources = [
"protocol.d.ts",
"protocol.ts",
"utilities.ts",
"scriptVersionCache.ts",
"scriptInfo.ts",
"lsHost.ts",
"project.ts",
"editorServices.ts",
"protocol.d.ts",
"session.ts",
].map(function (f) {
@@ -259,7 +262,7 @@ var harnessSources = harnessCoreSources.concat([
].map(function (f) {
return path.join(unittestsDirectory, f);
})).concat([
"protocol.d.ts",
"protocol.ts",
"utilities.ts",
"scriptVersionCache.ts",
"scriptInfo.ts",
@@ -267,7 +270,6 @@ var harnessSources = harnessCoreSources.concat([
"project.ts",
"typingsCache.ts",
"editorServices.ts",
"protocol.d.ts",
"session.ts",
].map(function (f) {
return path.join(serverDirectory, f);
@@ -355,6 +357,7 @@ function concatenateFiles(destinationFile, sourceFiles) {
if (!fs.existsSync(sourceFiles[i])) {
fail(sourceFiles[i] + " does not exist!");
}
fs.appendFileSync(temp, "\n\n");
fs.appendFileSync(temp, fs.readFileSync(sourceFiles[i]));
}
// Move the file to the final destination
@@ -445,6 +448,8 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts
options += " --stripInternal";
}
options += " --target es5 --noUnusedLocals --noUnusedParameters";
var cmd = host + " " + compilerPath + " " + options + " ";
cmd = cmd + sources.join(" ");
console.log(cmd + "\n");
@@ -518,6 +523,40 @@ compileFile(processDiagnosticMessagesJs,
[],
/*useBuiltCompiler*/ false);
var buildProtocolTs = path.join(scriptsDirectory, "buildProtocol.ts");
var buildProtocolJs = path.join(scriptsDirectory, "buildProtocol.js");
var buildProtocolDts = path.join(builtLocalDirectory, "protocol.d.ts");
var typescriptServicesDts = path.join(builtLocalDirectory, "typescriptServices.d.ts");
file(buildProtocolTs);
compileFile(buildProtocolJs,
[buildProtocolTs],
[buildProtocolTs],
[],
/*useBuiltCompiler*/ false,
{noOutFile: true});
file(buildProtocolDts, [buildProtocolTs, buildProtocolJs, typescriptServicesDts], function() {
var protocolTs = path.join(serverDirectory, "protocol.ts");
var cmd = host + " " + buildProtocolJs + " "+ protocolTs + " " + typescriptServicesDts + " " + buildProtocolDts;
console.log(cmd);
var ex = jake.createExec([cmd]);
// Add listeners for output and error
ex.addListener("stdout", function (output) {
process.stdout.write(output);
});
ex.addListener("stderr", function (error) {
process.stderr.write(error);
});
ex.addListener("cmdEnd", function () {
complete();
});
ex.run();
}, { async: true })
// The generated diagnostics map; built for the compiler and for the 'generate-diagnostics' task
file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], function () {
var cmd = host + " " + processDiagnosticMessagesJs + " " + diagnosticMessagesJson;
@@ -655,6 +694,8 @@ compileFile(
inlineSourceMap: true
});
file(typescriptServicesDts, [servicesFile]);
var cancellationTokenFile = path.join(builtLocalDirectory, "cancellationToken.js");
compileFile(cancellationTokenFile, cancellationTokenSources, [builtLocalDirectory].concat(cancellationTokenSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { outDir: builtLocalDirectory, noOutFile: true });
@@ -689,7 +730,7 @@ task("build-fold-end", [], function () {
// Local target to build the compiler and services
desc("Builds the full compiler and services");
task("local", ["build-fold-start", "generate-diagnostics", "lib", tscFile, servicesFile, nodeDefinitionsFile, serverFile, builtGeneratedDiagnosticMessagesJSON, "lssl", "build-fold-end"]);
task("local", ["build-fold-start", "generate-diagnostics", "lib", tscFile, servicesFile, nodeDefinitionsFile, serverFile, buildProtocolDts, builtGeneratedDiagnosticMessagesJSON, "lssl", "build-fold-end"]);
// Local target to build only tsc.js
desc("Builds only the compiler");
@@ -745,7 +786,7 @@ task("generate-spec", [specMd]);
// Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory
desc("Makes a new LKG out of the built js files");
task("LKG", ["clean", "release", "local"].concat(libraryTargets), function () {
var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile].concat(libraryTargets);
var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile, buildProtocolDts].concat(libraryTargets);
var missingFiles = expectedFiles.filter(function (f) {
return !fs.existsSync(f);
});
+1 -1
View File
@@ -2,7 +2,7 @@
<!-- QUESTIONS: This is not a general support forum! Ask Qs at http://stackoverflow.com/questions/tagged/typescript -->
<!-- SUGGESTIONS: See https://github.com/Microsoft/TypeScript-wiki/blob/master/Writing-Good-Design-Proposals.md -->
**TypeScript Version:** 1.8.0 / nightly (2.0.0-dev.201xxxxx)
**TypeScript Version:** 2.0.3 / nightly (2.1.0-dev.201xxxxx)
**Code**
Executable
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
# Set up NVM
export NVM_DIR="/home/dotnet-bot/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm install $1
npm uninstall typescript
npm uninstall tslint
npm install
npm update
npm test
+2
View File
@@ -39,3 +39,5 @@ function createCancellationToken(args) {
};
}
module.exports = createCancellationToken;
//# sourceMappingURL=cancellationToken.js.map
+227 -189
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
/////////////////////////////
/// ECMAScript APIs
/////////////////////////////
@@ -260,6 +264,9 @@ interface Function {
*/
bind(this: Function, thisArg: any, ...argArray: any[]): any;
/** Returns a string representation of a function. */
toString(): string;
prototype: any;
readonly length: number;
@@ -1216,6 +1223,30 @@ interface Array<T> {
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
map<U>(this: [T, T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U, U];
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
map<U>(this: [T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U];
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
map<U>(this: [T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U];
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
map<U>(this: [T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U];
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
@@ -4122,6 +4153,8 @@ interface Date {
*/
toLocaleTimeString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;
}
/////////////////////////////
/// IE DOM APIs
@@ -11660,11 +11693,12 @@ declare var HashChangeEvent: {
interface History {
readonly length: number;
readonly state: any;
back(distance?: any): void;
forward(distance?: any): void;
go(delta?: any): void;
pushState(statedata: any, title?: string, url?: string): void;
replaceState(statedata: any, title?: string, url?: string): void;
scrollRestoration: ScrollRestoration;
back(): void;
forward(): void;
go(delta?: number): void;
pushState(data: any, title: string, url?: string | null): void;
replaceState(data: any, title: string, url?: string | null): void;
}
declare var History: {
@@ -17236,7 +17270,6 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window
addEventListener(type: "waiting", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "wheel", listener: (this: this, ev: WheelEvent) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
[index: number]: Window;
}
declare var Window: {
@@ -17267,7 +17300,7 @@ declare var XMLDocument: {
}
interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
onreadystatechange: (this: this, ev: ProgressEvent) => any;
onreadystatechange: (this: this, ev: Event) => any;
readonly readyState: number;
readonly response: any;
readonly responseText: string;
@@ -17294,13 +17327,13 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
readonly LOADING: number;
readonly OPENED: number;
readonly UNSENT: number;
addEventListener(type: "abort", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "load", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "abort", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "load", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "loadend", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "loadstart", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "loadstart", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "progress", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "readystatechange", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "readystatechange", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "timeout", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -17641,183 +17674,183 @@ interface NavigatorUserMedia {
}
interface NodeSelector {
querySelector(selectors: "a"): HTMLAnchorElement;
querySelector(selectors: "abbr"): HTMLElement;
querySelector(selectors: "acronym"): HTMLElement;
querySelector(selectors: "address"): HTMLElement;
querySelector(selectors: "applet"): HTMLAppletElement;
querySelector(selectors: "area"): HTMLAreaElement;
querySelector(selectors: "article"): HTMLElement;
querySelector(selectors: "aside"): HTMLElement;
querySelector(selectors: "audio"): HTMLAudioElement;
querySelector(selectors: "b"): HTMLElement;
querySelector(selectors: "base"): HTMLBaseElement;
querySelector(selectors: "basefont"): HTMLBaseFontElement;
querySelector(selectors: "bdo"): HTMLElement;
querySelector(selectors: "big"): HTMLElement;
querySelector(selectors: "blockquote"): HTMLQuoteElement;
querySelector(selectors: "body"): HTMLBodyElement;
querySelector(selectors: "br"): HTMLBRElement;
querySelector(selectors: "button"): HTMLButtonElement;
querySelector(selectors: "canvas"): HTMLCanvasElement;
querySelector(selectors: "caption"): HTMLTableCaptionElement;
querySelector(selectors: "center"): HTMLElement;
querySelector(selectors: "circle"): SVGCircleElement;
querySelector(selectors: "cite"): HTMLElement;
querySelector(selectors: "clippath"): SVGClipPathElement;
querySelector(selectors: "code"): HTMLElement;
querySelector(selectors: "col"): HTMLTableColElement;
querySelector(selectors: "colgroup"): HTMLTableColElement;
querySelector(selectors: "datalist"): HTMLDataListElement;
querySelector(selectors: "dd"): HTMLElement;
querySelector(selectors: "defs"): SVGDefsElement;
querySelector(selectors: "del"): HTMLModElement;
querySelector(selectors: "desc"): SVGDescElement;
querySelector(selectors: "dfn"): HTMLElement;
querySelector(selectors: "dir"): HTMLDirectoryElement;
querySelector(selectors: "div"): HTMLDivElement;
querySelector(selectors: "dl"): HTMLDListElement;
querySelector(selectors: "dt"): HTMLElement;
querySelector(selectors: "ellipse"): SVGEllipseElement;
querySelector(selectors: "em"): HTMLElement;
querySelector(selectors: "embed"): HTMLEmbedElement;
querySelector(selectors: "feblend"): SVGFEBlendElement;
querySelector(selectors: "fecolormatrix"): SVGFEColorMatrixElement;
querySelector(selectors: "fecomponenttransfer"): SVGFEComponentTransferElement;
querySelector(selectors: "fecomposite"): SVGFECompositeElement;
querySelector(selectors: "feconvolvematrix"): SVGFEConvolveMatrixElement;
querySelector(selectors: "fediffuselighting"): SVGFEDiffuseLightingElement;
querySelector(selectors: "fedisplacementmap"): SVGFEDisplacementMapElement;
querySelector(selectors: "fedistantlight"): SVGFEDistantLightElement;
querySelector(selectors: "feflood"): SVGFEFloodElement;
querySelector(selectors: "fefunca"): SVGFEFuncAElement;
querySelector(selectors: "fefuncb"): SVGFEFuncBElement;
querySelector(selectors: "fefuncg"): SVGFEFuncGElement;
querySelector(selectors: "fefuncr"): SVGFEFuncRElement;
querySelector(selectors: "fegaussianblur"): SVGFEGaussianBlurElement;
querySelector(selectors: "feimage"): SVGFEImageElement;
querySelector(selectors: "femerge"): SVGFEMergeElement;
querySelector(selectors: "femergenode"): SVGFEMergeNodeElement;
querySelector(selectors: "femorphology"): SVGFEMorphologyElement;
querySelector(selectors: "feoffset"): SVGFEOffsetElement;
querySelector(selectors: "fepointlight"): SVGFEPointLightElement;
querySelector(selectors: "fespecularlighting"): SVGFESpecularLightingElement;
querySelector(selectors: "fespotlight"): SVGFESpotLightElement;
querySelector(selectors: "fetile"): SVGFETileElement;
querySelector(selectors: "feturbulence"): SVGFETurbulenceElement;
querySelector(selectors: "fieldset"): HTMLFieldSetElement;
querySelector(selectors: "figcaption"): HTMLElement;
querySelector(selectors: "figure"): HTMLElement;
querySelector(selectors: "filter"): SVGFilterElement;
querySelector(selectors: "font"): HTMLFontElement;
querySelector(selectors: "footer"): HTMLElement;
querySelector(selectors: "foreignobject"): SVGForeignObjectElement;
querySelector(selectors: "form"): HTMLFormElement;
querySelector(selectors: "frame"): HTMLFrameElement;
querySelector(selectors: "frameset"): HTMLFrameSetElement;
querySelector(selectors: "g"): SVGGElement;
querySelector(selectors: "h1"): HTMLHeadingElement;
querySelector(selectors: "h2"): HTMLHeadingElement;
querySelector(selectors: "h3"): HTMLHeadingElement;
querySelector(selectors: "h4"): HTMLHeadingElement;
querySelector(selectors: "h5"): HTMLHeadingElement;
querySelector(selectors: "h6"): HTMLHeadingElement;
querySelector(selectors: "head"): HTMLHeadElement;
querySelector(selectors: "header"): HTMLElement;
querySelector(selectors: "hgroup"): HTMLElement;
querySelector(selectors: "hr"): HTMLHRElement;
querySelector(selectors: "html"): HTMLHtmlElement;
querySelector(selectors: "i"): HTMLElement;
querySelector(selectors: "iframe"): HTMLIFrameElement;
querySelector(selectors: "image"): SVGImageElement;
querySelector(selectors: "img"): HTMLImageElement;
querySelector(selectors: "input"): HTMLInputElement;
querySelector(selectors: "ins"): HTMLModElement;
querySelector(selectors: "isindex"): HTMLUnknownElement;
querySelector(selectors: "kbd"): HTMLElement;
querySelector(selectors: "keygen"): HTMLElement;
querySelector(selectors: "label"): HTMLLabelElement;
querySelector(selectors: "legend"): HTMLLegendElement;
querySelector(selectors: "li"): HTMLLIElement;
querySelector(selectors: "line"): SVGLineElement;
querySelector(selectors: "lineargradient"): SVGLinearGradientElement;
querySelector(selectors: "link"): HTMLLinkElement;
querySelector(selectors: "listing"): HTMLPreElement;
querySelector(selectors: "map"): HTMLMapElement;
querySelector(selectors: "mark"): HTMLElement;
querySelector(selectors: "marker"): SVGMarkerElement;
querySelector(selectors: "marquee"): HTMLMarqueeElement;
querySelector(selectors: "mask"): SVGMaskElement;
querySelector(selectors: "menu"): HTMLMenuElement;
querySelector(selectors: "meta"): HTMLMetaElement;
querySelector(selectors: "metadata"): SVGMetadataElement;
querySelector(selectors: "meter"): HTMLMeterElement;
querySelector(selectors: "nav"): HTMLElement;
querySelector(selectors: "nextid"): HTMLUnknownElement;
querySelector(selectors: "nobr"): HTMLElement;
querySelector(selectors: "noframes"): HTMLElement;
querySelector(selectors: "noscript"): HTMLElement;
querySelector(selectors: "object"): HTMLObjectElement;
querySelector(selectors: "ol"): HTMLOListElement;
querySelector(selectors: "optgroup"): HTMLOptGroupElement;
querySelector(selectors: "option"): HTMLOptionElement;
querySelector(selectors: "p"): HTMLParagraphElement;
querySelector(selectors: "param"): HTMLParamElement;
querySelector(selectors: "path"): SVGPathElement;
querySelector(selectors: "pattern"): SVGPatternElement;
querySelector(selectors: "picture"): HTMLPictureElement;
querySelector(selectors: "plaintext"): HTMLElement;
querySelector(selectors: "polygon"): SVGPolygonElement;
querySelector(selectors: "polyline"): SVGPolylineElement;
querySelector(selectors: "pre"): HTMLPreElement;
querySelector(selectors: "progress"): HTMLProgressElement;
querySelector(selectors: "q"): HTMLQuoteElement;
querySelector(selectors: "radialgradient"): SVGRadialGradientElement;
querySelector(selectors: "rect"): SVGRectElement;
querySelector(selectors: "rt"): HTMLElement;
querySelector(selectors: "ruby"): HTMLElement;
querySelector(selectors: "s"): HTMLElement;
querySelector(selectors: "samp"): HTMLElement;
querySelector(selectors: "script"): HTMLScriptElement;
querySelector(selectors: "section"): HTMLElement;
querySelector(selectors: "select"): HTMLSelectElement;
querySelector(selectors: "small"): HTMLElement;
querySelector(selectors: "source"): HTMLSourceElement;
querySelector(selectors: "span"): HTMLSpanElement;
querySelector(selectors: "stop"): SVGStopElement;
querySelector(selectors: "strike"): HTMLElement;
querySelector(selectors: "strong"): HTMLElement;
querySelector(selectors: "style"): HTMLStyleElement;
querySelector(selectors: "sub"): HTMLElement;
querySelector(selectors: "sup"): HTMLElement;
querySelector(selectors: "svg"): SVGSVGElement;
querySelector(selectors: "switch"): SVGSwitchElement;
querySelector(selectors: "symbol"): SVGSymbolElement;
querySelector(selectors: "table"): HTMLTableElement;
querySelector(selectors: "tbody"): HTMLTableSectionElement;
querySelector(selectors: "td"): HTMLTableDataCellElement;
querySelector(selectors: "template"): HTMLTemplateElement;
querySelector(selectors: "text"): SVGTextElement;
querySelector(selectors: "textpath"): SVGTextPathElement;
querySelector(selectors: "textarea"): HTMLTextAreaElement;
querySelector(selectors: "tfoot"): HTMLTableSectionElement;
querySelector(selectors: "th"): HTMLTableHeaderCellElement;
querySelector(selectors: "thead"): HTMLTableSectionElement;
querySelector(selectors: "title"): HTMLTitleElement;
querySelector(selectors: "tr"): HTMLTableRowElement;
querySelector(selectors: "track"): HTMLTrackElement;
querySelector(selectors: "tspan"): SVGTSpanElement;
querySelector(selectors: "tt"): HTMLElement;
querySelector(selectors: "u"): HTMLElement;
querySelector(selectors: "ul"): HTMLUListElement;
querySelector(selectors: "use"): SVGUseElement;
querySelector(selectors: "var"): HTMLElement;
querySelector(selectors: "video"): HTMLVideoElement;
querySelector(selectors: "view"): SVGViewElement;
querySelector(selectors: "wbr"): HTMLElement;
querySelector(selectors: "x-ms-webview"): MSHTMLWebViewElement;
querySelector(selectors: "xmp"): HTMLPreElement;
querySelector(selectors: string): Element;
querySelector(selectors: "a"): HTMLAnchorElement | null;
querySelector(selectors: "abbr"): HTMLElement | null;
querySelector(selectors: "acronym"): HTMLElement | null;
querySelector(selectors: "address"): HTMLElement | null;
querySelector(selectors: "applet"): HTMLAppletElement | null;
querySelector(selectors: "area"): HTMLAreaElement | null;
querySelector(selectors: "article"): HTMLElement | null;
querySelector(selectors: "aside"): HTMLElement | null;
querySelector(selectors: "audio"): HTMLAudioElement | null;
querySelector(selectors: "b"): HTMLElement | null;
querySelector(selectors: "base"): HTMLBaseElement | null;
querySelector(selectors: "basefont"): HTMLBaseFontElement | null;
querySelector(selectors: "bdo"): HTMLElement | null;
querySelector(selectors: "big"): HTMLElement | null;
querySelector(selectors: "blockquote"): HTMLQuoteElement | null;
querySelector(selectors: "body"): HTMLBodyElement | null;
querySelector(selectors: "br"): HTMLBRElement | null;
querySelector(selectors: "button"): HTMLButtonElement | null;
querySelector(selectors: "canvas"): HTMLCanvasElement | null;
querySelector(selectors: "caption"): HTMLTableCaptionElement | null;
querySelector(selectors: "center"): HTMLElement | null;
querySelector(selectors: "circle"): SVGCircleElement | null;
querySelector(selectors: "cite"): HTMLElement | null;
querySelector(selectors: "clippath"): SVGClipPathElement | null;
querySelector(selectors: "code"): HTMLElement | null;
querySelector(selectors: "col"): HTMLTableColElement | null;
querySelector(selectors: "colgroup"): HTMLTableColElement | null;
querySelector(selectors: "datalist"): HTMLDataListElement | null;
querySelector(selectors: "dd"): HTMLElement | null;
querySelector(selectors: "defs"): SVGDefsElement | null;
querySelector(selectors: "del"): HTMLModElement | null;
querySelector(selectors: "desc"): SVGDescElement | null;
querySelector(selectors: "dfn"): HTMLElement | null;
querySelector(selectors: "dir"): HTMLDirectoryElement | null;
querySelector(selectors: "div"): HTMLDivElement | null;
querySelector(selectors: "dl"): HTMLDListElement | null;
querySelector(selectors: "dt"): HTMLElement | null;
querySelector(selectors: "ellipse"): SVGEllipseElement | null;
querySelector(selectors: "em"): HTMLElement | null;
querySelector(selectors: "embed"): HTMLEmbedElement | null;
querySelector(selectors: "feblend"): SVGFEBlendElement | null;
querySelector(selectors: "fecolormatrix"): SVGFEColorMatrixElement | null;
querySelector(selectors: "fecomponenttransfer"): SVGFEComponentTransferElement | null;
querySelector(selectors: "fecomposite"): SVGFECompositeElement | null;
querySelector(selectors: "feconvolvematrix"): SVGFEConvolveMatrixElement | null;
querySelector(selectors: "fediffuselighting"): SVGFEDiffuseLightingElement | null;
querySelector(selectors: "fedisplacementmap"): SVGFEDisplacementMapElement | null;
querySelector(selectors: "fedistantlight"): SVGFEDistantLightElement | null;
querySelector(selectors: "feflood"): SVGFEFloodElement | null;
querySelector(selectors: "fefunca"): SVGFEFuncAElement | null;
querySelector(selectors: "fefuncb"): SVGFEFuncBElement | null;
querySelector(selectors: "fefuncg"): SVGFEFuncGElement | null;
querySelector(selectors: "fefuncr"): SVGFEFuncRElement | null;
querySelector(selectors: "fegaussianblur"): SVGFEGaussianBlurElement | null;
querySelector(selectors: "feimage"): SVGFEImageElement | null;
querySelector(selectors: "femerge"): SVGFEMergeElement | null;
querySelector(selectors: "femergenode"): SVGFEMergeNodeElement | null;
querySelector(selectors: "femorphology"): SVGFEMorphologyElement | null;
querySelector(selectors: "feoffset"): SVGFEOffsetElement | null;
querySelector(selectors: "fepointlight"): SVGFEPointLightElement | null;
querySelector(selectors: "fespecularlighting"): SVGFESpecularLightingElement | null;
querySelector(selectors: "fespotlight"): SVGFESpotLightElement | null;
querySelector(selectors: "fetile"): SVGFETileElement | null;
querySelector(selectors: "feturbulence"): SVGFETurbulenceElement | null;
querySelector(selectors: "fieldset"): HTMLFieldSetElement | null;
querySelector(selectors: "figcaption"): HTMLElement | null;
querySelector(selectors: "figure"): HTMLElement | null;
querySelector(selectors: "filter"): SVGFilterElement | null;
querySelector(selectors: "font"): HTMLFontElement | null;
querySelector(selectors: "footer"): HTMLElement | null;
querySelector(selectors: "foreignobject"): SVGForeignObjectElement | null;
querySelector(selectors: "form"): HTMLFormElement | null;
querySelector(selectors: "frame"): HTMLFrameElement | null;
querySelector(selectors: "frameset"): HTMLFrameSetElement | null;
querySelector(selectors: "g"): SVGGElement | null;
querySelector(selectors: "h1"): HTMLHeadingElement | null;
querySelector(selectors: "h2"): HTMLHeadingElement | null;
querySelector(selectors: "h3"): HTMLHeadingElement | null;
querySelector(selectors: "h4"): HTMLHeadingElement | null;
querySelector(selectors: "h5"): HTMLHeadingElement | null;
querySelector(selectors: "h6"): HTMLHeadingElement | null;
querySelector(selectors: "head"): HTMLHeadElement | null;
querySelector(selectors: "header"): HTMLElement | null;
querySelector(selectors: "hgroup"): HTMLElement | null;
querySelector(selectors: "hr"): HTMLHRElement | null;
querySelector(selectors: "html"): HTMLHtmlElement | null;
querySelector(selectors: "i"): HTMLElement | null;
querySelector(selectors: "iframe"): HTMLIFrameElement | null;
querySelector(selectors: "image"): SVGImageElement | null;
querySelector(selectors: "img"): HTMLImageElement | null;
querySelector(selectors: "input"): HTMLInputElement | null;
querySelector(selectors: "ins"): HTMLModElement | null;
querySelector(selectors: "isindex"): HTMLUnknownElement | null;
querySelector(selectors: "kbd"): HTMLElement | null;
querySelector(selectors: "keygen"): HTMLElement | null;
querySelector(selectors: "label"): HTMLLabelElement | null;
querySelector(selectors: "legend"): HTMLLegendElement | null;
querySelector(selectors: "li"): HTMLLIElement | null;
querySelector(selectors: "line"): SVGLineElement | null;
querySelector(selectors: "lineargradient"): SVGLinearGradientElement | null;
querySelector(selectors: "link"): HTMLLinkElement | null;
querySelector(selectors: "listing"): HTMLPreElement | null;
querySelector(selectors: "map"): HTMLMapElement | null;
querySelector(selectors: "mark"): HTMLElement | null;
querySelector(selectors: "marker"): SVGMarkerElement | null;
querySelector(selectors: "marquee"): HTMLMarqueeElement | null;
querySelector(selectors: "mask"): SVGMaskElement | null;
querySelector(selectors: "menu"): HTMLMenuElement | null;
querySelector(selectors: "meta"): HTMLMetaElement | null;
querySelector(selectors: "metadata"): SVGMetadataElement | null;
querySelector(selectors: "meter"): HTMLMeterElement | null;
querySelector(selectors: "nav"): HTMLElement | null;
querySelector(selectors: "nextid"): HTMLUnknownElement | null;
querySelector(selectors: "nobr"): HTMLElement | null;
querySelector(selectors: "noframes"): HTMLElement | null;
querySelector(selectors: "noscript"): HTMLElement | null;
querySelector(selectors: "object"): HTMLObjectElement | null;
querySelector(selectors: "ol"): HTMLOListElement | null;
querySelector(selectors: "optgroup"): HTMLOptGroupElement | null;
querySelector(selectors: "option"): HTMLOptionElement | null;
querySelector(selectors: "p"): HTMLParagraphElement | null;
querySelector(selectors: "param"): HTMLParamElement | null;
querySelector(selectors: "path"): SVGPathElement | null;
querySelector(selectors: "pattern"): SVGPatternElement | null;
querySelector(selectors: "picture"): HTMLPictureElement | null;
querySelector(selectors: "plaintext"): HTMLElement | null;
querySelector(selectors: "polygon"): SVGPolygonElement | null;
querySelector(selectors: "polyline"): SVGPolylineElement | null;
querySelector(selectors: "pre"): HTMLPreElement | null;
querySelector(selectors: "progress"): HTMLProgressElement | null;
querySelector(selectors: "q"): HTMLQuoteElement | null;
querySelector(selectors: "radialgradient"): SVGRadialGradientElement | null;
querySelector(selectors: "rect"): SVGRectElement | null;
querySelector(selectors: "rt"): HTMLElement | null;
querySelector(selectors: "ruby"): HTMLElement | null;
querySelector(selectors: "s"): HTMLElement | null;
querySelector(selectors: "samp"): HTMLElement | null;
querySelector(selectors: "script"): HTMLScriptElement | null;
querySelector(selectors: "section"): HTMLElement | null;
querySelector(selectors: "select"): HTMLSelectElement | null;
querySelector(selectors: "small"): HTMLElement | null;
querySelector(selectors: "source"): HTMLSourceElement | null;
querySelector(selectors: "span"): HTMLSpanElement | null;
querySelector(selectors: "stop"): SVGStopElement | null;
querySelector(selectors: "strike"): HTMLElement | null;
querySelector(selectors: "strong"): HTMLElement | null;
querySelector(selectors: "style"): HTMLStyleElement | null;
querySelector(selectors: "sub"): HTMLElement | null;
querySelector(selectors: "sup"): HTMLElement | null;
querySelector(selectors: "svg"): SVGSVGElement | null;
querySelector(selectors: "switch"): SVGSwitchElement | null;
querySelector(selectors: "symbol"): SVGSymbolElement | null;
querySelector(selectors: "table"): HTMLTableElement | null;
querySelector(selectors: "tbody"): HTMLTableSectionElement | null;
querySelector(selectors: "td"): HTMLTableDataCellElement | null;
querySelector(selectors: "template"): HTMLTemplateElement | null;
querySelector(selectors: "text"): SVGTextElement | null;
querySelector(selectors: "textpath"): SVGTextPathElement | null;
querySelector(selectors: "textarea"): HTMLTextAreaElement | null;
querySelector(selectors: "tfoot"): HTMLTableSectionElement | null;
querySelector(selectors: "th"): HTMLTableHeaderCellElement | null;
querySelector(selectors: "thead"): HTMLTableSectionElement | null;
querySelector(selectors: "title"): HTMLTitleElement | null;
querySelector(selectors: "tr"): HTMLTableRowElement | null;
querySelector(selectors: "track"): HTMLTrackElement | null;
querySelector(selectors: "tspan"): SVGTSpanElement | null;
querySelector(selectors: "tt"): HTMLElement | null;
querySelector(selectors: "u"): HTMLElement | null;
querySelector(selectors: "ul"): HTMLUListElement | null;
querySelector(selectors: "use"): SVGUseElement | null;
querySelector(selectors: "var"): HTMLElement | null;
querySelector(selectors: "video"): HTMLVideoElement | null;
querySelector(selectors: "view"): SVGViewElement | null;
querySelector(selectors: "wbr"): HTMLElement | null;
querySelector(selectors: "x-ms-webview"): MSHTMLWebViewElement | null;
querySelector(selectors: "xmp"): HTMLPreElement | null;
querySelector(selectors: string): Element | null;
querySelectorAll(selectors: "a"): NodeListOf<HTMLAnchorElement>;
querySelectorAll(selectors: "abbr"): NodeListOf<HTMLElement>;
querySelectorAll(selectors: "acronym"): NodeListOf<HTMLElement>;
@@ -18747,11 +18780,16 @@ type ScrollLogicalPosition = "start" | "center" | "end" | "nearest";
type IDBValidKey = number | string | Date | IDBArrayKey;
type BufferSource = ArrayBuffer | ArrayBufferView;
type MouseWheelEvent = WheelEvent;
type ScrollRestoration = "auto" | "manual";
/////////////////////////////
/// WorkerGlobalScope APIs
/////////////////////////////
// These are only available in a Web Worker
declare function importScripts(...urls: string[]): void;
/////////////////////////////
+195 -190
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
/////////////////////////////
/// IE DOM APIs
@@ -7552,11 +7556,12 @@ declare var HashChangeEvent: {
interface History {
readonly length: number;
readonly state: any;
back(distance?: any): void;
forward(distance?: any): void;
go(delta?: any): void;
pushState(statedata: any, title?: string, url?: string): void;
replaceState(statedata: any, title?: string, url?: string): void;
scrollRestoration: ScrollRestoration;
back(): void;
forward(): void;
go(delta?: number): void;
pushState(data: any, title: string, url?: string | null): void;
replaceState(data: any, title: string, url?: string | null): void;
}
declare var History: {
@@ -13128,7 +13133,6 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window
addEventListener(type: "waiting", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "wheel", listener: (this: this, ev: WheelEvent) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
[index: number]: Window;
}
declare var Window: {
@@ -13159,7 +13163,7 @@ declare var XMLDocument: {
}
interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
onreadystatechange: (this: this, ev: ProgressEvent) => any;
onreadystatechange: (this: this, ev: Event) => any;
readonly readyState: number;
readonly response: any;
readonly responseText: string;
@@ -13186,13 +13190,13 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
readonly LOADING: number;
readonly OPENED: number;
readonly UNSENT: number;
addEventListener(type: "abort", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "load", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "abort", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "load", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "loadend", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "loadstart", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "loadstart", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "progress", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "readystatechange", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "readystatechange", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "timeout", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -13533,183 +13537,183 @@ interface NavigatorUserMedia {
}
interface NodeSelector {
querySelector(selectors: "a"): HTMLAnchorElement;
querySelector(selectors: "abbr"): HTMLElement;
querySelector(selectors: "acronym"): HTMLElement;
querySelector(selectors: "address"): HTMLElement;
querySelector(selectors: "applet"): HTMLAppletElement;
querySelector(selectors: "area"): HTMLAreaElement;
querySelector(selectors: "article"): HTMLElement;
querySelector(selectors: "aside"): HTMLElement;
querySelector(selectors: "audio"): HTMLAudioElement;
querySelector(selectors: "b"): HTMLElement;
querySelector(selectors: "base"): HTMLBaseElement;
querySelector(selectors: "basefont"): HTMLBaseFontElement;
querySelector(selectors: "bdo"): HTMLElement;
querySelector(selectors: "big"): HTMLElement;
querySelector(selectors: "blockquote"): HTMLQuoteElement;
querySelector(selectors: "body"): HTMLBodyElement;
querySelector(selectors: "br"): HTMLBRElement;
querySelector(selectors: "button"): HTMLButtonElement;
querySelector(selectors: "canvas"): HTMLCanvasElement;
querySelector(selectors: "caption"): HTMLTableCaptionElement;
querySelector(selectors: "center"): HTMLElement;
querySelector(selectors: "circle"): SVGCircleElement;
querySelector(selectors: "cite"): HTMLElement;
querySelector(selectors: "clippath"): SVGClipPathElement;
querySelector(selectors: "code"): HTMLElement;
querySelector(selectors: "col"): HTMLTableColElement;
querySelector(selectors: "colgroup"): HTMLTableColElement;
querySelector(selectors: "datalist"): HTMLDataListElement;
querySelector(selectors: "dd"): HTMLElement;
querySelector(selectors: "defs"): SVGDefsElement;
querySelector(selectors: "del"): HTMLModElement;
querySelector(selectors: "desc"): SVGDescElement;
querySelector(selectors: "dfn"): HTMLElement;
querySelector(selectors: "dir"): HTMLDirectoryElement;
querySelector(selectors: "div"): HTMLDivElement;
querySelector(selectors: "dl"): HTMLDListElement;
querySelector(selectors: "dt"): HTMLElement;
querySelector(selectors: "ellipse"): SVGEllipseElement;
querySelector(selectors: "em"): HTMLElement;
querySelector(selectors: "embed"): HTMLEmbedElement;
querySelector(selectors: "feblend"): SVGFEBlendElement;
querySelector(selectors: "fecolormatrix"): SVGFEColorMatrixElement;
querySelector(selectors: "fecomponenttransfer"): SVGFEComponentTransferElement;
querySelector(selectors: "fecomposite"): SVGFECompositeElement;
querySelector(selectors: "feconvolvematrix"): SVGFEConvolveMatrixElement;
querySelector(selectors: "fediffuselighting"): SVGFEDiffuseLightingElement;
querySelector(selectors: "fedisplacementmap"): SVGFEDisplacementMapElement;
querySelector(selectors: "fedistantlight"): SVGFEDistantLightElement;
querySelector(selectors: "feflood"): SVGFEFloodElement;
querySelector(selectors: "fefunca"): SVGFEFuncAElement;
querySelector(selectors: "fefuncb"): SVGFEFuncBElement;
querySelector(selectors: "fefuncg"): SVGFEFuncGElement;
querySelector(selectors: "fefuncr"): SVGFEFuncRElement;
querySelector(selectors: "fegaussianblur"): SVGFEGaussianBlurElement;
querySelector(selectors: "feimage"): SVGFEImageElement;
querySelector(selectors: "femerge"): SVGFEMergeElement;
querySelector(selectors: "femergenode"): SVGFEMergeNodeElement;
querySelector(selectors: "femorphology"): SVGFEMorphologyElement;
querySelector(selectors: "feoffset"): SVGFEOffsetElement;
querySelector(selectors: "fepointlight"): SVGFEPointLightElement;
querySelector(selectors: "fespecularlighting"): SVGFESpecularLightingElement;
querySelector(selectors: "fespotlight"): SVGFESpotLightElement;
querySelector(selectors: "fetile"): SVGFETileElement;
querySelector(selectors: "feturbulence"): SVGFETurbulenceElement;
querySelector(selectors: "fieldset"): HTMLFieldSetElement;
querySelector(selectors: "figcaption"): HTMLElement;
querySelector(selectors: "figure"): HTMLElement;
querySelector(selectors: "filter"): SVGFilterElement;
querySelector(selectors: "font"): HTMLFontElement;
querySelector(selectors: "footer"): HTMLElement;
querySelector(selectors: "foreignobject"): SVGForeignObjectElement;
querySelector(selectors: "form"): HTMLFormElement;
querySelector(selectors: "frame"): HTMLFrameElement;
querySelector(selectors: "frameset"): HTMLFrameSetElement;
querySelector(selectors: "g"): SVGGElement;
querySelector(selectors: "h1"): HTMLHeadingElement;
querySelector(selectors: "h2"): HTMLHeadingElement;
querySelector(selectors: "h3"): HTMLHeadingElement;
querySelector(selectors: "h4"): HTMLHeadingElement;
querySelector(selectors: "h5"): HTMLHeadingElement;
querySelector(selectors: "h6"): HTMLHeadingElement;
querySelector(selectors: "head"): HTMLHeadElement;
querySelector(selectors: "header"): HTMLElement;
querySelector(selectors: "hgroup"): HTMLElement;
querySelector(selectors: "hr"): HTMLHRElement;
querySelector(selectors: "html"): HTMLHtmlElement;
querySelector(selectors: "i"): HTMLElement;
querySelector(selectors: "iframe"): HTMLIFrameElement;
querySelector(selectors: "image"): SVGImageElement;
querySelector(selectors: "img"): HTMLImageElement;
querySelector(selectors: "input"): HTMLInputElement;
querySelector(selectors: "ins"): HTMLModElement;
querySelector(selectors: "isindex"): HTMLUnknownElement;
querySelector(selectors: "kbd"): HTMLElement;
querySelector(selectors: "keygen"): HTMLElement;
querySelector(selectors: "label"): HTMLLabelElement;
querySelector(selectors: "legend"): HTMLLegendElement;
querySelector(selectors: "li"): HTMLLIElement;
querySelector(selectors: "line"): SVGLineElement;
querySelector(selectors: "lineargradient"): SVGLinearGradientElement;
querySelector(selectors: "link"): HTMLLinkElement;
querySelector(selectors: "listing"): HTMLPreElement;
querySelector(selectors: "map"): HTMLMapElement;
querySelector(selectors: "mark"): HTMLElement;
querySelector(selectors: "marker"): SVGMarkerElement;
querySelector(selectors: "marquee"): HTMLMarqueeElement;
querySelector(selectors: "mask"): SVGMaskElement;
querySelector(selectors: "menu"): HTMLMenuElement;
querySelector(selectors: "meta"): HTMLMetaElement;
querySelector(selectors: "metadata"): SVGMetadataElement;
querySelector(selectors: "meter"): HTMLMeterElement;
querySelector(selectors: "nav"): HTMLElement;
querySelector(selectors: "nextid"): HTMLUnknownElement;
querySelector(selectors: "nobr"): HTMLElement;
querySelector(selectors: "noframes"): HTMLElement;
querySelector(selectors: "noscript"): HTMLElement;
querySelector(selectors: "object"): HTMLObjectElement;
querySelector(selectors: "ol"): HTMLOListElement;
querySelector(selectors: "optgroup"): HTMLOptGroupElement;
querySelector(selectors: "option"): HTMLOptionElement;
querySelector(selectors: "p"): HTMLParagraphElement;
querySelector(selectors: "param"): HTMLParamElement;
querySelector(selectors: "path"): SVGPathElement;
querySelector(selectors: "pattern"): SVGPatternElement;
querySelector(selectors: "picture"): HTMLPictureElement;
querySelector(selectors: "plaintext"): HTMLElement;
querySelector(selectors: "polygon"): SVGPolygonElement;
querySelector(selectors: "polyline"): SVGPolylineElement;
querySelector(selectors: "pre"): HTMLPreElement;
querySelector(selectors: "progress"): HTMLProgressElement;
querySelector(selectors: "q"): HTMLQuoteElement;
querySelector(selectors: "radialgradient"): SVGRadialGradientElement;
querySelector(selectors: "rect"): SVGRectElement;
querySelector(selectors: "rt"): HTMLElement;
querySelector(selectors: "ruby"): HTMLElement;
querySelector(selectors: "s"): HTMLElement;
querySelector(selectors: "samp"): HTMLElement;
querySelector(selectors: "script"): HTMLScriptElement;
querySelector(selectors: "section"): HTMLElement;
querySelector(selectors: "select"): HTMLSelectElement;
querySelector(selectors: "small"): HTMLElement;
querySelector(selectors: "source"): HTMLSourceElement;
querySelector(selectors: "span"): HTMLSpanElement;
querySelector(selectors: "stop"): SVGStopElement;
querySelector(selectors: "strike"): HTMLElement;
querySelector(selectors: "strong"): HTMLElement;
querySelector(selectors: "style"): HTMLStyleElement;
querySelector(selectors: "sub"): HTMLElement;
querySelector(selectors: "sup"): HTMLElement;
querySelector(selectors: "svg"): SVGSVGElement;
querySelector(selectors: "switch"): SVGSwitchElement;
querySelector(selectors: "symbol"): SVGSymbolElement;
querySelector(selectors: "table"): HTMLTableElement;
querySelector(selectors: "tbody"): HTMLTableSectionElement;
querySelector(selectors: "td"): HTMLTableDataCellElement;
querySelector(selectors: "template"): HTMLTemplateElement;
querySelector(selectors: "text"): SVGTextElement;
querySelector(selectors: "textpath"): SVGTextPathElement;
querySelector(selectors: "textarea"): HTMLTextAreaElement;
querySelector(selectors: "tfoot"): HTMLTableSectionElement;
querySelector(selectors: "th"): HTMLTableHeaderCellElement;
querySelector(selectors: "thead"): HTMLTableSectionElement;
querySelector(selectors: "title"): HTMLTitleElement;
querySelector(selectors: "tr"): HTMLTableRowElement;
querySelector(selectors: "track"): HTMLTrackElement;
querySelector(selectors: "tspan"): SVGTSpanElement;
querySelector(selectors: "tt"): HTMLElement;
querySelector(selectors: "u"): HTMLElement;
querySelector(selectors: "ul"): HTMLUListElement;
querySelector(selectors: "use"): SVGUseElement;
querySelector(selectors: "var"): HTMLElement;
querySelector(selectors: "video"): HTMLVideoElement;
querySelector(selectors: "view"): SVGViewElement;
querySelector(selectors: "wbr"): HTMLElement;
querySelector(selectors: "x-ms-webview"): MSHTMLWebViewElement;
querySelector(selectors: "xmp"): HTMLPreElement;
querySelector(selectors: string): Element;
querySelector(selectors: "a"): HTMLAnchorElement | null;
querySelector(selectors: "abbr"): HTMLElement | null;
querySelector(selectors: "acronym"): HTMLElement | null;
querySelector(selectors: "address"): HTMLElement | null;
querySelector(selectors: "applet"): HTMLAppletElement | null;
querySelector(selectors: "area"): HTMLAreaElement | null;
querySelector(selectors: "article"): HTMLElement | null;
querySelector(selectors: "aside"): HTMLElement | null;
querySelector(selectors: "audio"): HTMLAudioElement | null;
querySelector(selectors: "b"): HTMLElement | null;
querySelector(selectors: "base"): HTMLBaseElement | null;
querySelector(selectors: "basefont"): HTMLBaseFontElement | null;
querySelector(selectors: "bdo"): HTMLElement | null;
querySelector(selectors: "big"): HTMLElement | null;
querySelector(selectors: "blockquote"): HTMLQuoteElement | null;
querySelector(selectors: "body"): HTMLBodyElement | null;
querySelector(selectors: "br"): HTMLBRElement | null;
querySelector(selectors: "button"): HTMLButtonElement | null;
querySelector(selectors: "canvas"): HTMLCanvasElement | null;
querySelector(selectors: "caption"): HTMLTableCaptionElement | null;
querySelector(selectors: "center"): HTMLElement | null;
querySelector(selectors: "circle"): SVGCircleElement | null;
querySelector(selectors: "cite"): HTMLElement | null;
querySelector(selectors: "clippath"): SVGClipPathElement | null;
querySelector(selectors: "code"): HTMLElement | null;
querySelector(selectors: "col"): HTMLTableColElement | null;
querySelector(selectors: "colgroup"): HTMLTableColElement | null;
querySelector(selectors: "datalist"): HTMLDataListElement | null;
querySelector(selectors: "dd"): HTMLElement | null;
querySelector(selectors: "defs"): SVGDefsElement | null;
querySelector(selectors: "del"): HTMLModElement | null;
querySelector(selectors: "desc"): SVGDescElement | null;
querySelector(selectors: "dfn"): HTMLElement | null;
querySelector(selectors: "dir"): HTMLDirectoryElement | null;
querySelector(selectors: "div"): HTMLDivElement | null;
querySelector(selectors: "dl"): HTMLDListElement | null;
querySelector(selectors: "dt"): HTMLElement | null;
querySelector(selectors: "ellipse"): SVGEllipseElement | null;
querySelector(selectors: "em"): HTMLElement | null;
querySelector(selectors: "embed"): HTMLEmbedElement | null;
querySelector(selectors: "feblend"): SVGFEBlendElement | null;
querySelector(selectors: "fecolormatrix"): SVGFEColorMatrixElement | null;
querySelector(selectors: "fecomponenttransfer"): SVGFEComponentTransferElement | null;
querySelector(selectors: "fecomposite"): SVGFECompositeElement | null;
querySelector(selectors: "feconvolvematrix"): SVGFEConvolveMatrixElement | null;
querySelector(selectors: "fediffuselighting"): SVGFEDiffuseLightingElement | null;
querySelector(selectors: "fedisplacementmap"): SVGFEDisplacementMapElement | null;
querySelector(selectors: "fedistantlight"): SVGFEDistantLightElement | null;
querySelector(selectors: "feflood"): SVGFEFloodElement | null;
querySelector(selectors: "fefunca"): SVGFEFuncAElement | null;
querySelector(selectors: "fefuncb"): SVGFEFuncBElement | null;
querySelector(selectors: "fefuncg"): SVGFEFuncGElement | null;
querySelector(selectors: "fefuncr"): SVGFEFuncRElement | null;
querySelector(selectors: "fegaussianblur"): SVGFEGaussianBlurElement | null;
querySelector(selectors: "feimage"): SVGFEImageElement | null;
querySelector(selectors: "femerge"): SVGFEMergeElement | null;
querySelector(selectors: "femergenode"): SVGFEMergeNodeElement | null;
querySelector(selectors: "femorphology"): SVGFEMorphologyElement | null;
querySelector(selectors: "feoffset"): SVGFEOffsetElement | null;
querySelector(selectors: "fepointlight"): SVGFEPointLightElement | null;
querySelector(selectors: "fespecularlighting"): SVGFESpecularLightingElement | null;
querySelector(selectors: "fespotlight"): SVGFESpotLightElement | null;
querySelector(selectors: "fetile"): SVGFETileElement | null;
querySelector(selectors: "feturbulence"): SVGFETurbulenceElement | null;
querySelector(selectors: "fieldset"): HTMLFieldSetElement | null;
querySelector(selectors: "figcaption"): HTMLElement | null;
querySelector(selectors: "figure"): HTMLElement | null;
querySelector(selectors: "filter"): SVGFilterElement | null;
querySelector(selectors: "font"): HTMLFontElement | null;
querySelector(selectors: "footer"): HTMLElement | null;
querySelector(selectors: "foreignobject"): SVGForeignObjectElement | null;
querySelector(selectors: "form"): HTMLFormElement | null;
querySelector(selectors: "frame"): HTMLFrameElement | null;
querySelector(selectors: "frameset"): HTMLFrameSetElement | null;
querySelector(selectors: "g"): SVGGElement | null;
querySelector(selectors: "h1"): HTMLHeadingElement | null;
querySelector(selectors: "h2"): HTMLHeadingElement | null;
querySelector(selectors: "h3"): HTMLHeadingElement | null;
querySelector(selectors: "h4"): HTMLHeadingElement | null;
querySelector(selectors: "h5"): HTMLHeadingElement | null;
querySelector(selectors: "h6"): HTMLHeadingElement | null;
querySelector(selectors: "head"): HTMLHeadElement | null;
querySelector(selectors: "header"): HTMLElement | null;
querySelector(selectors: "hgroup"): HTMLElement | null;
querySelector(selectors: "hr"): HTMLHRElement | null;
querySelector(selectors: "html"): HTMLHtmlElement | null;
querySelector(selectors: "i"): HTMLElement | null;
querySelector(selectors: "iframe"): HTMLIFrameElement | null;
querySelector(selectors: "image"): SVGImageElement | null;
querySelector(selectors: "img"): HTMLImageElement | null;
querySelector(selectors: "input"): HTMLInputElement | null;
querySelector(selectors: "ins"): HTMLModElement | null;
querySelector(selectors: "isindex"): HTMLUnknownElement | null;
querySelector(selectors: "kbd"): HTMLElement | null;
querySelector(selectors: "keygen"): HTMLElement | null;
querySelector(selectors: "label"): HTMLLabelElement | null;
querySelector(selectors: "legend"): HTMLLegendElement | null;
querySelector(selectors: "li"): HTMLLIElement | null;
querySelector(selectors: "line"): SVGLineElement | null;
querySelector(selectors: "lineargradient"): SVGLinearGradientElement | null;
querySelector(selectors: "link"): HTMLLinkElement | null;
querySelector(selectors: "listing"): HTMLPreElement | null;
querySelector(selectors: "map"): HTMLMapElement | null;
querySelector(selectors: "mark"): HTMLElement | null;
querySelector(selectors: "marker"): SVGMarkerElement | null;
querySelector(selectors: "marquee"): HTMLMarqueeElement | null;
querySelector(selectors: "mask"): SVGMaskElement | null;
querySelector(selectors: "menu"): HTMLMenuElement | null;
querySelector(selectors: "meta"): HTMLMetaElement | null;
querySelector(selectors: "metadata"): SVGMetadataElement | null;
querySelector(selectors: "meter"): HTMLMeterElement | null;
querySelector(selectors: "nav"): HTMLElement | null;
querySelector(selectors: "nextid"): HTMLUnknownElement | null;
querySelector(selectors: "nobr"): HTMLElement | null;
querySelector(selectors: "noframes"): HTMLElement | null;
querySelector(selectors: "noscript"): HTMLElement | null;
querySelector(selectors: "object"): HTMLObjectElement | null;
querySelector(selectors: "ol"): HTMLOListElement | null;
querySelector(selectors: "optgroup"): HTMLOptGroupElement | null;
querySelector(selectors: "option"): HTMLOptionElement | null;
querySelector(selectors: "p"): HTMLParagraphElement | null;
querySelector(selectors: "param"): HTMLParamElement | null;
querySelector(selectors: "path"): SVGPathElement | null;
querySelector(selectors: "pattern"): SVGPatternElement | null;
querySelector(selectors: "picture"): HTMLPictureElement | null;
querySelector(selectors: "plaintext"): HTMLElement | null;
querySelector(selectors: "polygon"): SVGPolygonElement | null;
querySelector(selectors: "polyline"): SVGPolylineElement | null;
querySelector(selectors: "pre"): HTMLPreElement | null;
querySelector(selectors: "progress"): HTMLProgressElement | null;
querySelector(selectors: "q"): HTMLQuoteElement | null;
querySelector(selectors: "radialgradient"): SVGRadialGradientElement | null;
querySelector(selectors: "rect"): SVGRectElement | null;
querySelector(selectors: "rt"): HTMLElement | null;
querySelector(selectors: "ruby"): HTMLElement | null;
querySelector(selectors: "s"): HTMLElement | null;
querySelector(selectors: "samp"): HTMLElement | null;
querySelector(selectors: "script"): HTMLScriptElement | null;
querySelector(selectors: "section"): HTMLElement | null;
querySelector(selectors: "select"): HTMLSelectElement | null;
querySelector(selectors: "small"): HTMLElement | null;
querySelector(selectors: "source"): HTMLSourceElement | null;
querySelector(selectors: "span"): HTMLSpanElement | null;
querySelector(selectors: "stop"): SVGStopElement | null;
querySelector(selectors: "strike"): HTMLElement | null;
querySelector(selectors: "strong"): HTMLElement | null;
querySelector(selectors: "style"): HTMLStyleElement | null;
querySelector(selectors: "sub"): HTMLElement | null;
querySelector(selectors: "sup"): HTMLElement | null;
querySelector(selectors: "svg"): SVGSVGElement | null;
querySelector(selectors: "switch"): SVGSwitchElement | null;
querySelector(selectors: "symbol"): SVGSymbolElement | null;
querySelector(selectors: "table"): HTMLTableElement | null;
querySelector(selectors: "tbody"): HTMLTableSectionElement | null;
querySelector(selectors: "td"): HTMLTableDataCellElement | null;
querySelector(selectors: "template"): HTMLTemplateElement | null;
querySelector(selectors: "text"): SVGTextElement | null;
querySelector(selectors: "textpath"): SVGTextPathElement | null;
querySelector(selectors: "textarea"): HTMLTextAreaElement | null;
querySelector(selectors: "tfoot"): HTMLTableSectionElement | null;
querySelector(selectors: "th"): HTMLTableHeaderCellElement | null;
querySelector(selectors: "thead"): HTMLTableSectionElement | null;
querySelector(selectors: "title"): HTMLTitleElement | null;
querySelector(selectors: "tr"): HTMLTableRowElement | null;
querySelector(selectors: "track"): HTMLTrackElement | null;
querySelector(selectors: "tspan"): SVGTSpanElement | null;
querySelector(selectors: "tt"): HTMLElement | null;
querySelector(selectors: "u"): HTMLElement | null;
querySelector(selectors: "ul"): HTMLUListElement | null;
querySelector(selectors: "use"): SVGUseElement | null;
querySelector(selectors: "var"): HTMLElement | null;
querySelector(selectors: "video"): HTMLVideoElement | null;
querySelector(selectors: "view"): SVGViewElement | null;
querySelector(selectors: "wbr"): HTMLElement | null;
querySelector(selectors: "x-ms-webview"): MSHTMLWebViewElement | null;
querySelector(selectors: "xmp"): HTMLPreElement | null;
querySelector(selectors: string): Element | null;
querySelectorAll(selectors: "a"): NodeListOf<HTMLAnchorElement>;
querySelectorAll(selectors: "abbr"): NodeListOf<HTMLElement>;
querySelectorAll(selectors: "acronym"): NodeListOf<HTMLElement>;
@@ -14638,4 +14642,5 @@ type ScrollBehavior = "auto" | "instant" | "smooth";
type ScrollLogicalPosition = "start" | "center" | "end" | "nearest";
type IDBValidKey = number | string | Date | IDBArrayKey;
type BufferSource = ArrayBuffer | ArrayBufferView;
type MouseWheelEvent = WheelEvent;
type MouseWheelEvent = WheelEvent;
type ScrollRestoration = "auto" | "manual";
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
/// <reference path="lib.dom.d.ts" />
interface DOMTokenList {
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
interface Map<K, V> {
clear(): void;
delete(key: K): boolean;
+5 -1
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
declare type PropertyKey = string | number | symbol;
interface Array<T> {
@@ -217,7 +221,7 @@ interface NumberConstructor {
/**
* Returns true if passed value is finite.
* Unlike the global isFininte, Number.isFinite doesn't forcibly convert the parameter to a
* Unlike the global isFinite, Number.isFinite doesn't forcibly convert the parameter to a
* number. Only finite values of the type number, result in true.
* @param number A numeric value.
*/
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
/// <reference path="lib.es2015.core.d.ts" />
/// <reference path="lib.es2015.collection.d.ts" />
/// <reference path="lib.es2015.generator.d.ts" />
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
interface GeneratorFunction extends Function { }
interface GeneratorFunctionConstructor {
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
/// <reference path="lib.es2015.symbol.d.ts" />
interface SymbolConstructor {
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
/**
* Represents the completion of an asynchronous operation
*/
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
interface ProxyHandler<T> {
getPrototypeOf? (target: T): any;
setPrototypeOf? (target: T, v: any): boolean;
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
declare namespace Reflect {
function apply(target: Function, thisArgument: any, argumentsList: ArrayLike<any>): any;
function construct(target: Function, argumentsList: ArrayLike<any>, newTarget?: any): any;
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
interface Symbol {
/** Returns a string representation of an object. */
toString(): string;
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
/// <reference path="lib.es2015.symbol.d.ts" />
interface SymbolConstructor {
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
interface Array<T> {
/**
* Determines whether an array includes a certain element, returning true or false as appropriate.
+4
View File
@@ -13,6 +13,10 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
/// <reference path="lib.es2015.d.ts" />
/// <reference path="lib.es2016.array.include.d.ts" />
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
/// <reference path="lib.es2016.d.ts" />
/// <reference path="lib.es2017.object.d.ts" />
/// <reference path="lib.es2017.sharedmemory.d.ts" />
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
interface ObjectConstructor {
/**
* Returns an array of values of the enumerable properties of an object
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
/// <reference path="lib.es2015.symbol.d.ts" />
/// <reference path="lib.es2015.symbol.wellknown.d.ts" />
+31
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
/////////////////////////////
/// ECMAScript APIs
/////////////////////////////
@@ -260,6 +264,9 @@ interface Function {
*/
bind(this: Function, thisArg: any, ...argArray: any[]): any;
/** Returns a string representation of a function. */
toString(): string;
prototype: any;
readonly length: number;
@@ -1216,6 +1223,30 @@ interface Array<T> {
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
map<U>(this: [T, T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U, U];
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
map<U>(this: [T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U];
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
map<U>(this: [T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U];
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
map<U>(this: [T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U];
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
+254 -196
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
/////////////////////////////
/// ECMAScript APIs
/////////////////////////////
@@ -260,6 +264,9 @@ interface Function {
*/
bind(this: Function, thisArg: any, ...argArray: any[]): any;
/** Returns a string representation of a function. */
toString(): string;
prototype: any;
readonly length: number;
@@ -1216,6 +1223,30 @@ interface Array<T> {
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
map<U>(this: [T, T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U, U];
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
map<U>(this: [T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U];
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
map<U>(this: [T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U];
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
map<U>(this: [T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U];
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
@@ -4122,6 +4153,8 @@ interface Date {
*/
toLocaleTimeString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;
}
declare type PropertyKey = string | number | symbol;
interface Array<T> {
@@ -4325,7 +4358,7 @@ interface NumberConstructor {
/**
* Returns true if passed value is finite.
* Unlike the global isFininte, Number.isFinite doesn't forcibly convert the parameter to a
* Unlike the global isFinite, Number.isFinite doesn't forcibly convert the parameter to a
* number. Only finite values of the type number, result in true.
* @param number A numeric value.
*/
@@ -4646,6 +4679,8 @@ interface StringConstructor {
*/
raw(template: TemplateStringsArray, ...substitutions: any[]): string;
}
interface Map<K, V> {
clear(): void;
delete(key: K): boolean;
@@ -4718,6 +4753,8 @@ interface WeakSetConstructor {
readonly prototype: WeakSet<any>;
}
declare var WeakSet: WeakSetConstructor;
interface GeneratorFunction extends Function { }
interface GeneratorFunctionConstructor {
@@ -4730,6 +4767,8 @@ interface GeneratorFunctionConstructor {
readonly prototype: GeneratorFunction;
}
declare var GeneratorFunction: GeneratorFunctionConstructor;
/// <reference path="lib.es2015.symbol.d.ts" />
interface SymbolConstructor {
@@ -5174,7 +5213,9 @@ interface Float64ArrayConstructor {
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Float64Array;
}/**
}
/**
* Represents the completion of an asynchronous operation
*/
interface Promise<T> {
@@ -5427,7 +5468,9 @@ interface PromiseConstructor {
resolve(): Promise<void>;
}
declare var Promise: PromiseConstructor;interface ProxyHandler<T> {
declare var Promise: PromiseConstructor;
interface ProxyHandler<T> {
getPrototypeOf? (target: T): any;
setPrototypeOf? (target: T, v: any): boolean;
isExtensible? (target: T): boolean;
@@ -5448,7 +5491,9 @@ interface ProxyConstructor {
revocable<T>(target: T, handler: ProxyHandler<T>): { proxy: T; revoke: () => void; };
new <T>(target: T, handler: ProxyHandler<T>): T
}
declare var Proxy: ProxyConstructor;declare namespace Reflect {
declare var Proxy: ProxyConstructor;
declare namespace Reflect {
function apply(target: Function, thisArgument: any, argumentsList: ArrayLike<any>): any;
function construct(target: Function, argumentsList: ArrayLike<any>, newTarget?: any): any;
function defineProperty(target: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): boolean;
@@ -5462,7 +5507,9 @@ declare var Proxy: ProxyConstructor;declare namespace Reflect {
function preventExtensions(target: any): boolean;
function set(target: any, propertyKey: PropertyKey, value: any, receiver?: any): boolean;
function setPrototypeOf(target: any, proto: any): boolean;
}interface Symbol {
}
interface Symbol {
/** Returns a string representation of an object. */
toString(): string;
@@ -5497,7 +5544,9 @@ interface SymbolConstructor {
keyFor(sym: symbol): string | undefined;
}
declare var Symbol: SymbolConstructor;/// <reference path="lib.es2015.symbol.d.ts" />
declare var Symbol: SymbolConstructor;
/// <reference path="lib.es2015.symbol.d.ts" />
interface SymbolConstructor {
/**
@@ -5823,7 +5872,9 @@ interface Float32Array {
*/
interface Float64Array {
readonly [Symbol.toStringTag]: "Float64Array";
}
}
/////////////////////////////
/// IE DOM APIs
/////////////////////////////
@@ -13361,11 +13412,12 @@ declare var HashChangeEvent: {
interface History {
readonly length: number;
readonly state: any;
back(distance?: any): void;
forward(distance?: any): void;
go(delta?: any): void;
pushState(statedata: any, title?: string, url?: string): void;
replaceState(statedata: any, title?: string, url?: string): void;
scrollRestoration: ScrollRestoration;
back(): void;
forward(): void;
go(delta?: number): void;
pushState(data: any, title: string, url?: string | null): void;
replaceState(data: any, title: string, url?: string | null): void;
}
declare var History: {
@@ -18937,7 +18989,6 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window
addEventListener(type: "waiting", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "wheel", listener: (this: this, ev: WheelEvent) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
[index: number]: Window;
}
declare var Window: {
@@ -18968,7 +19019,7 @@ declare var XMLDocument: {
}
interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
onreadystatechange: (this: this, ev: ProgressEvent) => any;
onreadystatechange: (this: this, ev: Event) => any;
readonly readyState: number;
readonly response: any;
readonly responseText: string;
@@ -18995,13 +19046,13 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
readonly LOADING: number;
readonly OPENED: number;
readonly UNSENT: number;
addEventListener(type: "abort", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "load", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "abort", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "load", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "loadend", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "loadstart", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "loadstart", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "progress", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "readystatechange", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "readystatechange", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "timeout", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@@ -19342,183 +19393,183 @@ interface NavigatorUserMedia {
}
interface NodeSelector {
querySelector(selectors: "a"): HTMLAnchorElement;
querySelector(selectors: "abbr"): HTMLElement;
querySelector(selectors: "acronym"): HTMLElement;
querySelector(selectors: "address"): HTMLElement;
querySelector(selectors: "applet"): HTMLAppletElement;
querySelector(selectors: "area"): HTMLAreaElement;
querySelector(selectors: "article"): HTMLElement;
querySelector(selectors: "aside"): HTMLElement;
querySelector(selectors: "audio"): HTMLAudioElement;
querySelector(selectors: "b"): HTMLElement;
querySelector(selectors: "base"): HTMLBaseElement;
querySelector(selectors: "basefont"): HTMLBaseFontElement;
querySelector(selectors: "bdo"): HTMLElement;
querySelector(selectors: "big"): HTMLElement;
querySelector(selectors: "blockquote"): HTMLQuoteElement;
querySelector(selectors: "body"): HTMLBodyElement;
querySelector(selectors: "br"): HTMLBRElement;
querySelector(selectors: "button"): HTMLButtonElement;
querySelector(selectors: "canvas"): HTMLCanvasElement;
querySelector(selectors: "caption"): HTMLTableCaptionElement;
querySelector(selectors: "center"): HTMLElement;
querySelector(selectors: "circle"): SVGCircleElement;
querySelector(selectors: "cite"): HTMLElement;
querySelector(selectors: "clippath"): SVGClipPathElement;
querySelector(selectors: "code"): HTMLElement;
querySelector(selectors: "col"): HTMLTableColElement;
querySelector(selectors: "colgroup"): HTMLTableColElement;
querySelector(selectors: "datalist"): HTMLDataListElement;
querySelector(selectors: "dd"): HTMLElement;
querySelector(selectors: "defs"): SVGDefsElement;
querySelector(selectors: "del"): HTMLModElement;
querySelector(selectors: "desc"): SVGDescElement;
querySelector(selectors: "dfn"): HTMLElement;
querySelector(selectors: "dir"): HTMLDirectoryElement;
querySelector(selectors: "div"): HTMLDivElement;
querySelector(selectors: "dl"): HTMLDListElement;
querySelector(selectors: "dt"): HTMLElement;
querySelector(selectors: "ellipse"): SVGEllipseElement;
querySelector(selectors: "em"): HTMLElement;
querySelector(selectors: "embed"): HTMLEmbedElement;
querySelector(selectors: "feblend"): SVGFEBlendElement;
querySelector(selectors: "fecolormatrix"): SVGFEColorMatrixElement;
querySelector(selectors: "fecomponenttransfer"): SVGFEComponentTransferElement;
querySelector(selectors: "fecomposite"): SVGFECompositeElement;
querySelector(selectors: "feconvolvematrix"): SVGFEConvolveMatrixElement;
querySelector(selectors: "fediffuselighting"): SVGFEDiffuseLightingElement;
querySelector(selectors: "fedisplacementmap"): SVGFEDisplacementMapElement;
querySelector(selectors: "fedistantlight"): SVGFEDistantLightElement;
querySelector(selectors: "feflood"): SVGFEFloodElement;
querySelector(selectors: "fefunca"): SVGFEFuncAElement;
querySelector(selectors: "fefuncb"): SVGFEFuncBElement;
querySelector(selectors: "fefuncg"): SVGFEFuncGElement;
querySelector(selectors: "fefuncr"): SVGFEFuncRElement;
querySelector(selectors: "fegaussianblur"): SVGFEGaussianBlurElement;
querySelector(selectors: "feimage"): SVGFEImageElement;
querySelector(selectors: "femerge"): SVGFEMergeElement;
querySelector(selectors: "femergenode"): SVGFEMergeNodeElement;
querySelector(selectors: "femorphology"): SVGFEMorphologyElement;
querySelector(selectors: "feoffset"): SVGFEOffsetElement;
querySelector(selectors: "fepointlight"): SVGFEPointLightElement;
querySelector(selectors: "fespecularlighting"): SVGFESpecularLightingElement;
querySelector(selectors: "fespotlight"): SVGFESpotLightElement;
querySelector(selectors: "fetile"): SVGFETileElement;
querySelector(selectors: "feturbulence"): SVGFETurbulenceElement;
querySelector(selectors: "fieldset"): HTMLFieldSetElement;
querySelector(selectors: "figcaption"): HTMLElement;
querySelector(selectors: "figure"): HTMLElement;
querySelector(selectors: "filter"): SVGFilterElement;
querySelector(selectors: "font"): HTMLFontElement;
querySelector(selectors: "footer"): HTMLElement;
querySelector(selectors: "foreignobject"): SVGForeignObjectElement;
querySelector(selectors: "form"): HTMLFormElement;
querySelector(selectors: "frame"): HTMLFrameElement;
querySelector(selectors: "frameset"): HTMLFrameSetElement;
querySelector(selectors: "g"): SVGGElement;
querySelector(selectors: "h1"): HTMLHeadingElement;
querySelector(selectors: "h2"): HTMLHeadingElement;
querySelector(selectors: "h3"): HTMLHeadingElement;
querySelector(selectors: "h4"): HTMLHeadingElement;
querySelector(selectors: "h5"): HTMLHeadingElement;
querySelector(selectors: "h6"): HTMLHeadingElement;
querySelector(selectors: "head"): HTMLHeadElement;
querySelector(selectors: "header"): HTMLElement;
querySelector(selectors: "hgroup"): HTMLElement;
querySelector(selectors: "hr"): HTMLHRElement;
querySelector(selectors: "html"): HTMLHtmlElement;
querySelector(selectors: "i"): HTMLElement;
querySelector(selectors: "iframe"): HTMLIFrameElement;
querySelector(selectors: "image"): SVGImageElement;
querySelector(selectors: "img"): HTMLImageElement;
querySelector(selectors: "input"): HTMLInputElement;
querySelector(selectors: "ins"): HTMLModElement;
querySelector(selectors: "isindex"): HTMLUnknownElement;
querySelector(selectors: "kbd"): HTMLElement;
querySelector(selectors: "keygen"): HTMLElement;
querySelector(selectors: "label"): HTMLLabelElement;
querySelector(selectors: "legend"): HTMLLegendElement;
querySelector(selectors: "li"): HTMLLIElement;
querySelector(selectors: "line"): SVGLineElement;
querySelector(selectors: "lineargradient"): SVGLinearGradientElement;
querySelector(selectors: "link"): HTMLLinkElement;
querySelector(selectors: "listing"): HTMLPreElement;
querySelector(selectors: "map"): HTMLMapElement;
querySelector(selectors: "mark"): HTMLElement;
querySelector(selectors: "marker"): SVGMarkerElement;
querySelector(selectors: "marquee"): HTMLMarqueeElement;
querySelector(selectors: "mask"): SVGMaskElement;
querySelector(selectors: "menu"): HTMLMenuElement;
querySelector(selectors: "meta"): HTMLMetaElement;
querySelector(selectors: "metadata"): SVGMetadataElement;
querySelector(selectors: "meter"): HTMLMeterElement;
querySelector(selectors: "nav"): HTMLElement;
querySelector(selectors: "nextid"): HTMLUnknownElement;
querySelector(selectors: "nobr"): HTMLElement;
querySelector(selectors: "noframes"): HTMLElement;
querySelector(selectors: "noscript"): HTMLElement;
querySelector(selectors: "object"): HTMLObjectElement;
querySelector(selectors: "ol"): HTMLOListElement;
querySelector(selectors: "optgroup"): HTMLOptGroupElement;
querySelector(selectors: "option"): HTMLOptionElement;
querySelector(selectors: "p"): HTMLParagraphElement;
querySelector(selectors: "param"): HTMLParamElement;
querySelector(selectors: "path"): SVGPathElement;
querySelector(selectors: "pattern"): SVGPatternElement;
querySelector(selectors: "picture"): HTMLPictureElement;
querySelector(selectors: "plaintext"): HTMLElement;
querySelector(selectors: "polygon"): SVGPolygonElement;
querySelector(selectors: "polyline"): SVGPolylineElement;
querySelector(selectors: "pre"): HTMLPreElement;
querySelector(selectors: "progress"): HTMLProgressElement;
querySelector(selectors: "q"): HTMLQuoteElement;
querySelector(selectors: "radialgradient"): SVGRadialGradientElement;
querySelector(selectors: "rect"): SVGRectElement;
querySelector(selectors: "rt"): HTMLElement;
querySelector(selectors: "ruby"): HTMLElement;
querySelector(selectors: "s"): HTMLElement;
querySelector(selectors: "samp"): HTMLElement;
querySelector(selectors: "script"): HTMLScriptElement;
querySelector(selectors: "section"): HTMLElement;
querySelector(selectors: "select"): HTMLSelectElement;
querySelector(selectors: "small"): HTMLElement;
querySelector(selectors: "source"): HTMLSourceElement;
querySelector(selectors: "span"): HTMLSpanElement;
querySelector(selectors: "stop"): SVGStopElement;
querySelector(selectors: "strike"): HTMLElement;
querySelector(selectors: "strong"): HTMLElement;
querySelector(selectors: "style"): HTMLStyleElement;
querySelector(selectors: "sub"): HTMLElement;
querySelector(selectors: "sup"): HTMLElement;
querySelector(selectors: "svg"): SVGSVGElement;
querySelector(selectors: "switch"): SVGSwitchElement;
querySelector(selectors: "symbol"): SVGSymbolElement;
querySelector(selectors: "table"): HTMLTableElement;
querySelector(selectors: "tbody"): HTMLTableSectionElement;
querySelector(selectors: "td"): HTMLTableDataCellElement;
querySelector(selectors: "template"): HTMLTemplateElement;
querySelector(selectors: "text"): SVGTextElement;
querySelector(selectors: "textpath"): SVGTextPathElement;
querySelector(selectors: "textarea"): HTMLTextAreaElement;
querySelector(selectors: "tfoot"): HTMLTableSectionElement;
querySelector(selectors: "th"): HTMLTableHeaderCellElement;
querySelector(selectors: "thead"): HTMLTableSectionElement;
querySelector(selectors: "title"): HTMLTitleElement;
querySelector(selectors: "tr"): HTMLTableRowElement;
querySelector(selectors: "track"): HTMLTrackElement;
querySelector(selectors: "tspan"): SVGTSpanElement;
querySelector(selectors: "tt"): HTMLElement;
querySelector(selectors: "u"): HTMLElement;
querySelector(selectors: "ul"): HTMLUListElement;
querySelector(selectors: "use"): SVGUseElement;
querySelector(selectors: "var"): HTMLElement;
querySelector(selectors: "video"): HTMLVideoElement;
querySelector(selectors: "view"): SVGViewElement;
querySelector(selectors: "wbr"): HTMLElement;
querySelector(selectors: "x-ms-webview"): MSHTMLWebViewElement;
querySelector(selectors: "xmp"): HTMLPreElement;
querySelector(selectors: string): Element;
querySelector(selectors: "a"): HTMLAnchorElement | null;
querySelector(selectors: "abbr"): HTMLElement | null;
querySelector(selectors: "acronym"): HTMLElement | null;
querySelector(selectors: "address"): HTMLElement | null;
querySelector(selectors: "applet"): HTMLAppletElement | null;
querySelector(selectors: "area"): HTMLAreaElement | null;
querySelector(selectors: "article"): HTMLElement | null;
querySelector(selectors: "aside"): HTMLElement | null;
querySelector(selectors: "audio"): HTMLAudioElement | null;
querySelector(selectors: "b"): HTMLElement | null;
querySelector(selectors: "base"): HTMLBaseElement | null;
querySelector(selectors: "basefont"): HTMLBaseFontElement | null;
querySelector(selectors: "bdo"): HTMLElement | null;
querySelector(selectors: "big"): HTMLElement | null;
querySelector(selectors: "blockquote"): HTMLQuoteElement | null;
querySelector(selectors: "body"): HTMLBodyElement | null;
querySelector(selectors: "br"): HTMLBRElement | null;
querySelector(selectors: "button"): HTMLButtonElement | null;
querySelector(selectors: "canvas"): HTMLCanvasElement | null;
querySelector(selectors: "caption"): HTMLTableCaptionElement | null;
querySelector(selectors: "center"): HTMLElement | null;
querySelector(selectors: "circle"): SVGCircleElement | null;
querySelector(selectors: "cite"): HTMLElement | null;
querySelector(selectors: "clippath"): SVGClipPathElement | null;
querySelector(selectors: "code"): HTMLElement | null;
querySelector(selectors: "col"): HTMLTableColElement | null;
querySelector(selectors: "colgroup"): HTMLTableColElement | null;
querySelector(selectors: "datalist"): HTMLDataListElement | null;
querySelector(selectors: "dd"): HTMLElement | null;
querySelector(selectors: "defs"): SVGDefsElement | null;
querySelector(selectors: "del"): HTMLModElement | null;
querySelector(selectors: "desc"): SVGDescElement | null;
querySelector(selectors: "dfn"): HTMLElement | null;
querySelector(selectors: "dir"): HTMLDirectoryElement | null;
querySelector(selectors: "div"): HTMLDivElement | null;
querySelector(selectors: "dl"): HTMLDListElement | null;
querySelector(selectors: "dt"): HTMLElement | null;
querySelector(selectors: "ellipse"): SVGEllipseElement | null;
querySelector(selectors: "em"): HTMLElement | null;
querySelector(selectors: "embed"): HTMLEmbedElement | null;
querySelector(selectors: "feblend"): SVGFEBlendElement | null;
querySelector(selectors: "fecolormatrix"): SVGFEColorMatrixElement | null;
querySelector(selectors: "fecomponenttransfer"): SVGFEComponentTransferElement | null;
querySelector(selectors: "fecomposite"): SVGFECompositeElement | null;
querySelector(selectors: "feconvolvematrix"): SVGFEConvolveMatrixElement | null;
querySelector(selectors: "fediffuselighting"): SVGFEDiffuseLightingElement | null;
querySelector(selectors: "fedisplacementmap"): SVGFEDisplacementMapElement | null;
querySelector(selectors: "fedistantlight"): SVGFEDistantLightElement | null;
querySelector(selectors: "feflood"): SVGFEFloodElement | null;
querySelector(selectors: "fefunca"): SVGFEFuncAElement | null;
querySelector(selectors: "fefuncb"): SVGFEFuncBElement | null;
querySelector(selectors: "fefuncg"): SVGFEFuncGElement | null;
querySelector(selectors: "fefuncr"): SVGFEFuncRElement | null;
querySelector(selectors: "fegaussianblur"): SVGFEGaussianBlurElement | null;
querySelector(selectors: "feimage"): SVGFEImageElement | null;
querySelector(selectors: "femerge"): SVGFEMergeElement | null;
querySelector(selectors: "femergenode"): SVGFEMergeNodeElement | null;
querySelector(selectors: "femorphology"): SVGFEMorphologyElement | null;
querySelector(selectors: "feoffset"): SVGFEOffsetElement | null;
querySelector(selectors: "fepointlight"): SVGFEPointLightElement | null;
querySelector(selectors: "fespecularlighting"): SVGFESpecularLightingElement | null;
querySelector(selectors: "fespotlight"): SVGFESpotLightElement | null;
querySelector(selectors: "fetile"): SVGFETileElement | null;
querySelector(selectors: "feturbulence"): SVGFETurbulenceElement | null;
querySelector(selectors: "fieldset"): HTMLFieldSetElement | null;
querySelector(selectors: "figcaption"): HTMLElement | null;
querySelector(selectors: "figure"): HTMLElement | null;
querySelector(selectors: "filter"): SVGFilterElement | null;
querySelector(selectors: "font"): HTMLFontElement | null;
querySelector(selectors: "footer"): HTMLElement | null;
querySelector(selectors: "foreignobject"): SVGForeignObjectElement | null;
querySelector(selectors: "form"): HTMLFormElement | null;
querySelector(selectors: "frame"): HTMLFrameElement | null;
querySelector(selectors: "frameset"): HTMLFrameSetElement | null;
querySelector(selectors: "g"): SVGGElement | null;
querySelector(selectors: "h1"): HTMLHeadingElement | null;
querySelector(selectors: "h2"): HTMLHeadingElement | null;
querySelector(selectors: "h3"): HTMLHeadingElement | null;
querySelector(selectors: "h4"): HTMLHeadingElement | null;
querySelector(selectors: "h5"): HTMLHeadingElement | null;
querySelector(selectors: "h6"): HTMLHeadingElement | null;
querySelector(selectors: "head"): HTMLHeadElement | null;
querySelector(selectors: "header"): HTMLElement | null;
querySelector(selectors: "hgroup"): HTMLElement | null;
querySelector(selectors: "hr"): HTMLHRElement | null;
querySelector(selectors: "html"): HTMLHtmlElement | null;
querySelector(selectors: "i"): HTMLElement | null;
querySelector(selectors: "iframe"): HTMLIFrameElement | null;
querySelector(selectors: "image"): SVGImageElement | null;
querySelector(selectors: "img"): HTMLImageElement | null;
querySelector(selectors: "input"): HTMLInputElement | null;
querySelector(selectors: "ins"): HTMLModElement | null;
querySelector(selectors: "isindex"): HTMLUnknownElement | null;
querySelector(selectors: "kbd"): HTMLElement | null;
querySelector(selectors: "keygen"): HTMLElement | null;
querySelector(selectors: "label"): HTMLLabelElement | null;
querySelector(selectors: "legend"): HTMLLegendElement | null;
querySelector(selectors: "li"): HTMLLIElement | null;
querySelector(selectors: "line"): SVGLineElement | null;
querySelector(selectors: "lineargradient"): SVGLinearGradientElement | null;
querySelector(selectors: "link"): HTMLLinkElement | null;
querySelector(selectors: "listing"): HTMLPreElement | null;
querySelector(selectors: "map"): HTMLMapElement | null;
querySelector(selectors: "mark"): HTMLElement | null;
querySelector(selectors: "marker"): SVGMarkerElement | null;
querySelector(selectors: "marquee"): HTMLMarqueeElement | null;
querySelector(selectors: "mask"): SVGMaskElement | null;
querySelector(selectors: "menu"): HTMLMenuElement | null;
querySelector(selectors: "meta"): HTMLMetaElement | null;
querySelector(selectors: "metadata"): SVGMetadataElement | null;
querySelector(selectors: "meter"): HTMLMeterElement | null;
querySelector(selectors: "nav"): HTMLElement | null;
querySelector(selectors: "nextid"): HTMLUnknownElement | null;
querySelector(selectors: "nobr"): HTMLElement | null;
querySelector(selectors: "noframes"): HTMLElement | null;
querySelector(selectors: "noscript"): HTMLElement | null;
querySelector(selectors: "object"): HTMLObjectElement | null;
querySelector(selectors: "ol"): HTMLOListElement | null;
querySelector(selectors: "optgroup"): HTMLOptGroupElement | null;
querySelector(selectors: "option"): HTMLOptionElement | null;
querySelector(selectors: "p"): HTMLParagraphElement | null;
querySelector(selectors: "param"): HTMLParamElement | null;
querySelector(selectors: "path"): SVGPathElement | null;
querySelector(selectors: "pattern"): SVGPatternElement | null;
querySelector(selectors: "picture"): HTMLPictureElement | null;
querySelector(selectors: "plaintext"): HTMLElement | null;
querySelector(selectors: "polygon"): SVGPolygonElement | null;
querySelector(selectors: "polyline"): SVGPolylineElement | null;
querySelector(selectors: "pre"): HTMLPreElement | null;
querySelector(selectors: "progress"): HTMLProgressElement | null;
querySelector(selectors: "q"): HTMLQuoteElement | null;
querySelector(selectors: "radialgradient"): SVGRadialGradientElement | null;
querySelector(selectors: "rect"): SVGRectElement | null;
querySelector(selectors: "rt"): HTMLElement | null;
querySelector(selectors: "ruby"): HTMLElement | null;
querySelector(selectors: "s"): HTMLElement | null;
querySelector(selectors: "samp"): HTMLElement | null;
querySelector(selectors: "script"): HTMLScriptElement | null;
querySelector(selectors: "section"): HTMLElement | null;
querySelector(selectors: "select"): HTMLSelectElement | null;
querySelector(selectors: "small"): HTMLElement | null;
querySelector(selectors: "source"): HTMLSourceElement | null;
querySelector(selectors: "span"): HTMLSpanElement | null;
querySelector(selectors: "stop"): SVGStopElement | null;
querySelector(selectors: "strike"): HTMLElement | null;
querySelector(selectors: "strong"): HTMLElement | null;
querySelector(selectors: "style"): HTMLStyleElement | null;
querySelector(selectors: "sub"): HTMLElement | null;
querySelector(selectors: "sup"): HTMLElement | null;
querySelector(selectors: "svg"): SVGSVGElement | null;
querySelector(selectors: "switch"): SVGSwitchElement | null;
querySelector(selectors: "symbol"): SVGSymbolElement | null;
querySelector(selectors: "table"): HTMLTableElement | null;
querySelector(selectors: "tbody"): HTMLTableSectionElement | null;
querySelector(selectors: "td"): HTMLTableDataCellElement | null;
querySelector(selectors: "template"): HTMLTemplateElement | null;
querySelector(selectors: "text"): SVGTextElement | null;
querySelector(selectors: "textpath"): SVGTextPathElement | null;
querySelector(selectors: "textarea"): HTMLTextAreaElement | null;
querySelector(selectors: "tfoot"): HTMLTableSectionElement | null;
querySelector(selectors: "th"): HTMLTableHeaderCellElement | null;
querySelector(selectors: "thead"): HTMLTableSectionElement | null;
querySelector(selectors: "title"): HTMLTitleElement | null;
querySelector(selectors: "tr"): HTMLTableRowElement | null;
querySelector(selectors: "track"): HTMLTrackElement | null;
querySelector(selectors: "tspan"): SVGTSpanElement | null;
querySelector(selectors: "tt"): HTMLElement | null;
querySelector(selectors: "u"): HTMLElement | null;
querySelector(selectors: "ul"): HTMLUListElement | null;
querySelector(selectors: "use"): SVGUseElement | null;
querySelector(selectors: "var"): HTMLElement | null;
querySelector(selectors: "video"): HTMLVideoElement | null;
querySelector(selectors: "view"): SVGViewElement | null;
querySelector(selectors: "wbr"): HTMLElement | null;
querySelector(selectors: "x-ms-webview"): MSHTMLWebViewElement | null;
querySelector(selectors: "xmp"): HTMLPreElement | null;
querySelector(selectors: string): Element | null;
querySelectorAll(selectors: "a"): NodeListOf<HTMLAnchorElement>;
querySelectorAll(selectors: "abbr"): NodeListOf<HTMLElement>;
querySelectorAll(selectors: "acronym"): NodeListOf<HTMLElement>;
@@ -20448,11 +20499,16 @@ type ScrollLogicalPosition = "start" | "center" | "end" | "nearest";
type IDBValidKey = number | string | Date | IDBArrayKey;
type BufferSource = ArrayBuffer | ArrayBufferView;
type MouseWheelEvent = WheelEvent;
type ScrollRestoration = "auto" | "manual";
/////////////////////////////
/// WorkerGlobalScope APIs
/////////////////////////////
// These are only available in a Web Worker
declare function importScripts(...urls: string[]): void;
/////////////////////////////
@@ -20744,6 +20800,8 @@ interface DateConstructor {
interface Date {
getVarDate: () => VarDate;
}
/// <reference path="lib.dom.d.ts" />
interface DOMTokenList {
+4
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
/////////////////////////////
+10 -6
View File
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
/////////////////////////////
/// IE Worker APIs
@@ -744,7 +748,7 @@ declare var Worker: {
}
interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
onreadystatechange: (this: this, ev: ProgressEvent) => any;
onreadystatechange: (this: this, ev: Event) => any;
readonly readyState: number;
readonly response: any;
readonly responseText: string;
@@ -770,13 +774,13 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
readonly LOADING: number;
readonly OPENED: number;
readonly UNSENT: number;
addEventListener(type: "abort", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "load", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "abort", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "load", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "loadend", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "loadstart", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "loadstart", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "progress", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "readystatechange", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "readystatechange", listener: (this: this, ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "timeout", listener: (this: this, ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
+1848
View File
File diff suppressed because it is too large. Load diff
+11027 -9072
View File
File diff suppressed because it is too large. Load diff
+18872 -14709
View File
File diff suppressed because it is too large. Load diff
+1996 -7628
View File
File diff suppressed because it is too large. Load diff
+18721 -14691
View File
File diff suppressed because it is too large. Load diff
+648 -360
View File
File diff suppressed because it is too large. Load diff
+14367 -12967
View File
File diff suppressed because it is too large. Load diff
+648 -360
View File
File diff suppressed because it is too large. Load diff
+14367 -12967
View File
File diff suppressed because it is too large. Load diff
+1532 -435
View File
File diff suppressed because it is too large. Load diff
+22
View File
@@ -0,0 +1,22 @@
// Import the utility functionality.
import jobs.generation.Utilities;
// Defines a the new of the repo, used elsewhere in the file
def project = GithubProject
def branch = GithubBranchName
def nodeVersions = ['stable', '4']
nodeVersions.each { nodeVer ->
def newJobName = "typescript_node.${nodeVer}"
def newJob = job(Utilities.getFullJobName(project, newJobName, true)) {
steps {
shell("./jenkins.sh ${nodeVer}")
}
}
Utilities.standardJobSetup(newJob, project, true, "*/${branch}")
Utilities.setMachineAffinity(newJob, 'Ubuntu', '20161020')
Utilities.addGithubPRTriggerForBranch(newJob, branch, "TypeScript Test Run ${newJobName}")
}
+185
View File
@@ -0,0 +1,185 @@
/// <reference types="node"/>
import * as ts from "../lib/typescript";
import * as path from "path";
function endsWith(s: string, suffix: string) {
return s.lastIndexOf(suffix, s.length - suffix.length) !== -1;
}
class DeclarationsWalker {
private visitedTypes: ts.Type[] = [];
private text = "";
private removedTypes: ts.Type[] = [];
private constructor(private typeChecker: ts.TypeChecker, private protocolFile: ts.SourceFile) {
}
static getExtraDeclarations(typeChecker: ts.TypeChecker, protocolFile: ts.SourceFile): string {
let text = "declare namespace ts.server.protocol {\n";
var walker = new DeclarationsWalker(typeChecker, protocolFile);
walker.visitTypeNodes(protocolFile);
text = walker.text
? `declare namespace ts.server.protocol {\n${walker.text}}`
: "";
if (walker.removedTypes) {
text += "\ndeclare namespace ts {\n";
text += " // these types are empty stubs for types from services and should not be used directly\n"
for (const type of walker.removedTypes) {
text += ` export type ${type.symbol.name} = never;\n`;
}
text += "}"
}
return text;
}
private processType(type: ts.Type): void {
if (this.visitedTypes.indexOf(type) >= 0) {
return;
}
this.visitedTypes.push(type);
let s = type.aliasSymbol || type.getSymbol();
if (!s) {
return;
}
if (s.name === "Array") {
// we should process type argument instead
return this.processType((<any>type).typeArguments[0]);
}
else {
for (const decl of s.getDeclarations()) {
const sourceFile = decl.getSourceFile();
if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") {
return;
}
if (decl.kind === ts.SyntaxKind.EnumDeclaration) {
this.removedTypes.push(type);
return;
}
else {
// splice declaration in final d.ts file
let text = decl.getFullText();
this.text += `${text}\n`;
// recursively pull all dependencies into result dts file
this.visitTypeNodes(decl);
}
}
}
}
private visitTypeNodes(node: ts.Node) {
if (node.parent) {
switch (node.parent.kind) {
case ts.SyntaxKind.VariableDeclaration:
case ts.SyntaxKind.MethodDeclaration:
case ts.SyntaxKind.MethodSignature:
case ts.SyntaxKind.PropertyDeclaration:
case ts.SyntaxKind.PropertySignature:
case ts.SyntaxKind.Parameter:
case ts.SyntaxKind.IndexSignature:
if (((<ts.VariableDeclaration | ts.MethodDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration | ts.PropertySignature | ts.MethodSignature | ts.IndexSignatureDeclaration>node.parent).type) === node) {
this.processTypeOfNode(node);
}
break;
case ts.SyntaxKind.InterfaceDeclaration:
const heritageClauses = (<ts.InterfaceDeclaration>node.parent).heritageClauses;
if (heritageClauses) {
if (heritageClauses[0].token !== ts.SyntaxKind.ExtendsKeyword) {
throw new Error(`Unexpected kind of heritage clause: ${ts.SyntaxKind[heritageClauses[0].kind]}`);
}
for (const type of heritageClauses[0].types) {
this.processTypeOfNode(type);
}
}
break;
}
}
ts.forEachChild(node, n => this.visitTypeNodes(n));
}
private processTypeOfNode(node: ts.Node): void {
if (node.kind === ts.SyntaxKind.UnionType) {
for (const t of (<ts.UnionTypeNode>node).types) {
this.processTypeOfNode(t);
}
}
else {
const type = this.typeChecker.getTypeAtLocation(node);
if (type && !(type.flags & (ts.TypeFlags.TypeParameter))) {
this.processType(type);
}
}
}
}
function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string): string {
const options = { target: ts.ScriptTarget.ES5, declaration: true, noResolve: true, types: <string[]>[], stripInternal: true };
/**
* 1st pass - generate a program from protocol.ts and typescriptservices.d.ts and emit core version of protocol.d.ts with all internal members stripped
* @return text of protocol.d.t.s
*/
function getInitialDtsFileForProtocol() {
const program = ts.createProgram([protocolTs, typeScriptServicesDts], options);
let protocolDts: string;
program.emit(program.getSourceFile(protocolTs), (file, content) => {
if (endsWith(file, ".d.ts")) {
protocolDts = content;
}
});
if (protocolDts === undefined) {
throw new Error(`Declaration file for protocol.ts is not generated`)
}
return protocolDts;
}
const protocolFileName = "protocol.d.ts";
/**
* Second pass - generate a program from protocol.d.ts and typescriptservices.d.ts, then augment core protocol.d.ts with extra types from typescriptservices.d.ts
*/
function getProgramWithProtocolText(protocolDts: string, includeTypeScriptServices: boolean) {
const host = ts.createCompilerHost(options);
const originalGetSourceFile = host.getSourceFile;
host.getSourceFile = (fileName) => {
if (fileName === protocolFileName) {
return ts.createSourceFile(fileName, protocolDts, options.target);
}
return originalGetSourceFile.apply(host, [fileName]);
}
const rootFiles = includeTypeScriptServices ? [protocolFileName, typeScriptServicesDts] : [protocolFileName];
return ts.createProgram(rootFiles, options, host);
}
let protocolDts = getInitialDtsFileForProtocol();
const program = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ true);
const protocolFile = program.getSourceFile("protocol.d.ts");
const extraDeclarations = DeclarationsWalker.getExtraDeclarations(program.getTypeChecker(), protocolFile);
if (extraDeclarations) {
protocolDts += extraDeclarations;
}
protocolDts += "\nimport protocol = ts.server.protocol;";
protocolDts += "\nexport = protocol;";
protocolDts += "\nexport as namespace protocol;";
// do sanity check and try to compile generated text as standalone program
const sanityCheckProgram = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ false);
const diagnostics = [...sanityCheckProgram.getSyntacticDiagnostics(), ...sanityCheckProgram.getSemanticDiagnostics(), ...sanityCheckProgram.getGlobalDiagnostics()];
if (diagnostics.length) {
const flattenedDiagnostics = diagnostics.map(d => ts.flattenDiagnosticMessageText(d.messageText, "\n")).join("\n");
throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`);
}
return protocolDts;
}
if (process.argv.length < 5) {
console.log(`Expected 3 arguments: path to 'protocol.ts', path to 'typescriptservices.d.ts' and path to output file`);
process.exit(1);
}
const protocolTs = process.argv[2];
const typeScriptServicesDts = process.argv[3];
const outputFile = process.argv[4];
const generatedProtocolDts = generateProtocolFile(protocolTs, typeScriptServicesDts);
ts.sys.writeFile(outputFile, generatedProtocolDts);
+1 -1
View File
@@ -126,7 +126,7 @@ class PreferConstWalker extends Lint.RuleWalker {
visitModuleDeclaration(node: ts.ModuleDeclaration) {
if (node.body.kind === ts.SyntaxKind.ModuleBlock) {
// For some reason module blocks are left out of the visit block traversal
this.visitBlock(node.body as ts.ModuleBlock);
this.visitBlock(node.body as any as ts.Block);
}
super.visitModuleDeclaration(node);
}
+7 -2
View File
@@ -18,8 +18,13 @@ class TypeOperatorSpacingWalker extends Lint.RuleWalker {
for (let i = 1; i < types.length; i++) {
const currentType = types[i];
if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) {
const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
this.addFailure(failure);
const sourceFile = currentType.getSourceFile();
const previousTypeEndPos = sourceFile.getLineAndCharacterOfPosition(types[i - 1].end);
const currentTypeStartPos = sourceFile.getLineAndCharacterOfPosition(currentType.pos);
if (previousTypeEndPos.line === currentTypeStartPos.line) {
const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
this.addFailure(failure);
}
}
expectedStart = currentType.end + 2;
}
+281 -119
View File
@@ -54,6 +54,11 @@ namespace ts {
const body = (<ModuleDeclaration>node).body;
return body ? getModuleInstanceState(body) : ModuleInstanceState.Instantiated;
}
// Only jsdoc typedef definition can exist in jsdoc namespace, and it should
// be considered the same as type alias
else if (node.kind === SyntaxKind.Identifier && (<Identifier>node).isInJSDocNamespace) {
return ModuleInstanceState.NonInstantiated;
}
else {
return ModuleInstanceState.Instantiated;
}
@@ -84,6 +89,7 @@ namespace ts {
IsFunctionExpression = 1 << 4,
HasLocals = 1 << 5,
IsInterface = 1 << 6,
IsObjectLiteralOrClassExpressionMethod = 1 << 7,
}
const binder = createBinder();
@@ -121,7 +127,8 @@ namespace ts {
// If this file is an external module, then it is automatically in strict-mode according to
// ES6. If it is not an external module, then we'll determine if it is in strict mode or
// not depending on if we see "use strict" in certain places (or if we hit a class/namespace).
// not depending on if we see "use strict" in certain places or if we hit a class/namespace
// or if compiler options contain alwaysStrict.
let inStrictMode: boolean;
let symbolCount = 0;
@@ -139,7 +146,7 @@ namespace ts {
file = f;
options = opts;
languageVersion = getEmitScriptTarget(options);
inStrictMode = !!file.externalModuleIndicator;
inStrictMode = bindInStrictMode(file, opts);
classifiableNames = createMap<string>();
symbolCount = 0;
skipTransformFlagAggregation = isDeclarationFile(file);
@@ -174,6 +181,16 @@ namespace ts {
return bindSourceFile;
function bindInStrictMode(file: SourceFile, opts: CompilerOptions): boolean {
if (opts.alwaysStrict && !isDeclarationFile(file)) {
// bind in strict mode source files with alwaysStrict option
return true;
}
else {
return !!file.externalModuleIndicator;
}
}
function createSymbol(flags: SymbolFlags, name: string): Symbol {
symbolCount++;
return new Symbol(flags, name);
@@ -355,11 +372,24 @@ namespace ts {
? Diagnostics.Cannot_redeclare_block_scoped_variable_0
: Diagnostics.Duplicate_identifier_0;
forEach(symbol.declarations, declaration => {
if (hasModifier(declaration, ModifierFlags.Default)) {
if (symbol.declarations && symbol.declarations.length) {
// If the current node is a default export of some sort, then check if
// there are any other default exports that we need to error on.
// We'll know whether we have other default exports depending on if `symbol` already has a declaration list set.
if (isDefaultExport) {
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
}
});
else {
// This is to properly report an error in the case "export default { }" is after export default of class declaration or function declaration.
// Error on multiple export default in the following case:
// 1. multiple export default of class declaration or function declaration by checking NodeFlags.Default
// 2. multiple export default of export assignment. This one doesn't have NodeFlags.Default on (as export default doesn't considered as modifiers)
if (symbol.declarations && symbol.declarations.length &&
(isDefaultExport || (node.kind === SyntaxKind.ExportAssignment && !(<ExportAssignment>node).isExportEquals))) {
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
}
}
}
forEach(symbol.declarations, declaration => {
file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
@@ -404,7 +434,11 @@ namespace ts {
// during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation
// and this case is specially handled. Module augmentations should only be merged with original module definition
// and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
if (!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) {
const isJSDocTypedefInJSDocNamespace = node.kind === SyntaxKind.JSDocTypedefTag &&
node.name &&
node.name.kind === SyntaxKind.Identifier &&
(<Identifier>node.name).isInJSDocNamespace;
if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypedefInJSDocNamespace) {
const exportKind =
(symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) |
(symbolFlags & SymbolFlags.Type ? SymbolFlags.ExportType : 0) |
@@ -465,16 +499,16 @@ namespace ts {
const saveReturnTarget = currentReturnTarget;
const saveActiveLabels = activeLabels;
const saveHasExplicitReturn = hasExplicitReturn;
const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !!getImmediatelyInvokedFunctionExpression(node);
// An IIFE is considered part of the containing control flow. Return statements behave
const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) && !!getImmediatelyInvokedFunctionExpression(node);
// A non-async IIFE is considered part of the containing control flow. Return statements behave
// similarly to break statements that exit to a label just past the statement body.
if (isIIFE) {
currentReturnTarget = createBranchLabel();
}
else {
currentFlow = { flags: FlowFlags.Start };
if (containerFlags & ContainerFlags.IsFunctionExpression) {
(<FlowStart>currentFlow).container = <FunctionExpression | ArrowFunction>node;
if (containerFlags & (ContainerFlags.IsFunctionExpression | ContainerFlags.IsObjectLiteralOrClassExpressionMethod)) {
(<FlowStart>currentFlow).container = <FunctionExpression | ArrowFunction | MethodDeclaration>node;
}
currentReturnTarget = undefined;
}
@@ -760,6 +794,15 @@ namespace ts {
};
}
function createFlowArrayMutation(antecedent: FlowNode, node: CallExpression | BinaryExpression): FlowNode {
setFlowNodeReferenced(antecedent);
return <FlowArrayMutation>{
flags: FlowFlags.ArrayMutation,
antecedent,
node
};
}
function finishFlowLabel(flow: FlowLabel): FlowNode {
const antecedents = flow.antecedents;
if (!antecedents) {
@@ -849,8 +892,13 @@ namespace ts {
function bindDoStatement(node: DoStatement): void {
const preDoLabel = createLoopLabel();
const preConditionLabel = createBranchLabel();
const postDoLabel = createBranchLabel();
const enclosingLabeledStatement = node.parent.kind === SyntaxKind.LabeledStatement
? lastOrUndefined(activeLabels)
: undefined;
// if do statement is wrapped in labeled statement then target labels for break/continue with or without
// label should be the same
const preConditionLabel = enclosingLabeledStatement ? enclosingLabeledStatement.continueTarget : createBranchLabel();
const postDoLabel = enclosingLabeledStatement ? enclosingLabeledStatement.breakTarget : createBranchLabel();
addAntecedent(preDoLabel, currentFlow);
currentFlow = preDoLabel;
bindIterativeStatement(node.statement, postDoLabel, preConditionLabel);
@@ -950,24 +998,44 @@ namespace ts {
}
function bindTryStatement(node: TryStatement): void {
const postFinallyLabel = createBranchLabel();
const preFinallyLabel = createBranchLabel();
const preTryFlow = currentFlow;
// TODO: Every statement in try block is potentially an exit point!
bind(node.tryBlock);
addAntecedent(postFinallyLabel, currentFlow);
addAntecedent(preFinallyLabel, currentFlow);
const flowAfterTry = currentFlow;
let flowAfterCatch = unreachableFlow;
if (node.catchClause) {
currentFlow = preTryFlow;
bind(node.catchClause);
addAntecedent(postFinallyLabel, currentFlow);
addAntecedent(preFinallyLabel, currentFlow);
flowAfterCatch = currentFlow;
}
if (node.finallyBlock) {
currentFlow = preTryFlow;
// in finally flow is combined from pre-try/flow from try/flow from catch
// pre-flow is necessary to make sure that finally is reachable even if finally flows in both try and finally blocks are unreachable
addAntecedent(preFinallyLabel, preTryFlow);
currentFlow = finishFlowLabel(preFinallyLabel);
bind(node.finallyBlock);
// if flow after finally is unreachable - keep it
// otherwise check if flows after try and after catch are unreachable
// if yes - convert current flow to unreachable
// i.e.
// try { return "1" } finally { console.log(1); }
// console.log(2); // this line should be unreachable even if flow falls out of finally block
if (!(currentFlow.flags & FlowFlags.Unreachable)) {
if ((flowAfterTry.flags & FlowFlags.Unreachable) && (flowAfterCatch.flags & FlowFlags.Unreachable)) {
currentFlow = flowAfterTry === reportedUnreachableFlow || flowAfterCatch === reportedUnreachableFlow
? reportedUnreachableFlow
: unreachableFlow;
}
}
}
// if try statement has finally block and flow after finally block is unreachable - keep it
// otherwise use whatever flow was accumulated at postFinallyLabel
if (!node.finallyBlock || !(currentFlow.flags & FlowFlags.Unreachable)) {
currentFlow = finishFlowLabel(postFinallyLabel);
else {
currentFlow = finishFlowLabel(preFinallyLabel);
}
}
@@ -1048,8 +1116,11 @@ namespace ts {
if (!activeLabel.referenced && !options.allowUnusedLabels) {
file.bindDiagnostics.push(createDiagnosticForNode(node.label, Diagnostics.Unused_label));
}
addAntecedent(postStatementLabel, currentFlow);
currentFlow = finishFlowLabel(postStatementLabel);
if (!node.statement || node.statement.kind !== SyntaxKind.DoStatement) {
// do statement sets current flow inside bindDoStatement
addAntecedent(postStatementLabel, currentFlow);
currentFlow = finishFlowLabel(postStatementLabel);
}
}
function bindDestructuringTargetFlow(node: Expression) {
@@ -1111,7 +1182,7 @@ namespace ts {
}
else {
forEachChild(node, bind);
if (node.operator === SyntaxKind.PlusEqualsToken || node.operator === SyntaxKind.MinusMinusToken) {
if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) {
bindAssignmentTargetFlow(node.operand);
}
}
@@ -1140,6 +1211,12 @@ namespace ts {
forEachChild(node, bind);
if (operator === SyntaxKind.EqualsToken && !isAssignmentTarget(node)) {
bindAssignmentTargetFlow(node.left);
if (node.left.kind === SyntaxKind.ElementAccessExpression) {
const elementAccess = <ElementAccessExpression>node.left;
if (isNarrowableOperand(elementAccess.expression)) {
currentFlow = createFlowArrayMutation(currentFlow, node);
}
}
}
}
}
@@ -1200,6 +1277,12 @@ namespace ts {
else {
forEachChild(node, bind);
}
if (node.expression.kind === SyntaxKind.PropertyAccessExpression) {
const propertyAccess = <PropertyAccessExpression>node.expression;
if (isNarrowableOperand(propertyAccess.expression) && isPushOrUnshiftIdentifier(propertyAccess.name)) {
currentFlow = createFlowArrayMutation(currentFlow, node);
}
}
}
function getContainerFlags(node: Node): ContainerFlags {
@@ -1224,9 +1307,12 @@ namespace ts {
case SyntaxKind.SourceFile:
return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals;
case SyntaxKind.MethodDeclaration:
if (isObjectLiteralOrClassExpressionMethod(node)) {
return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike | ContainerFlags.IsObjectLiteralOrClassExpressionMethod;
}
case SyntaxKind.Constructor:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
@@ -1360,7 +1446,7 @@ namespace ts {
function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean {
const body = node.kind === SyntaxKind.SourceFile ? node : (<ModuleDeclaration>node).body;
if (body && (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock)) {
for (const stat of (<Block>body).statements) {
for (const stat of (<BlockLike>body).statements) {
if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) {
return true;
}
@@ -1636,7 +1722,7 @@ namespace ts {
}
function checkStrictModeFunctionDeclaration(node: FunctionDeclaration) {
if (languageVersion < ScriptTarget.ES6) {
if (languageVersion < ScriptTarget.ES2015) {
// Report error if function is not top level function declaration
if (blockScopeContainer.kind !== SyntaxKind.SourceFile &&
blockScopeContainer.kind !== SyntaxKind.ModuleDeclaration &&
@@ -1759,6 +1845,17 @@ namespace ts {
switch (node.kind) {
/* Strict mode checks */
case SyntaxKind.Identifier:
// for typedef type names with namespaces, bind the new jsdoc type symbol here
// because it requires all containing namespaces to be in effect, namely the
// current "blockScopeContainer" needs to be set to its immediate namespace parent.
if ((<Identifier>node).isInJSDocNamespace) {
let parentNode = node.parent;
while (parentNode && parentNode.kind !== SyntaxKind.JSDocTypedefTag) {
parentNode = parentNode.parent;
}
bindBlockScopedDeclaration(<Declaration>parentNode, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
break;
}
case SyntaxKind.ThisKeyword:
if (currentFlow && (isExpression(node) || parent.kind === SyntaxKind.ShorthandPropertyAssignment)) {
node.flowNode = currentFlow;
@@ -1882,6 +1979,10 @@ namespace ts {
case SyntaxKind.InterfaceDeclaration:
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes);
case SyntaxKind.JSDocTypedefTag:
if (!(<JSDocTypedefTag>node).fullName || (<JSDocTypedefTag>node).fullName.kind === SyntaxKind.Identifier) {
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
}
break;
case SyntaxKind.TypeAliasDeclaration:
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
case SyntaxKind.EnumDeclaration:
@@ -1944,12 +2045,15 @@ namespace ts {
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node));
}
else {
// An export default clause with an expression exports a value
// We want to exclude both class and function here, this is necessary to issue an error when there are both
// default export-assignment and default export function and class declaration.
const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node)
// An export default clause with an EntityNameExpression exports all meanings of that identifier
? SymbolFlags.Alias
// An export default clause with any other expression exports a value
: SymbolFlags.Property;
declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes);
declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.Property | SymbolFlags.AliasExcludes | SymbolFlags.Class | SymbolFlags.Function);
}
}
@@ -2000,7 +2104,9 @@ namespace ts {
function setCommonJsModuleIndicator(node: Node) {
if (!file.commonJsModuleIndicator) {
file.commonJsModuleIndicator = node;
bindSourceFileAsExternalModule();
if (!file.externalModuleIndicator) {
bindSourceFileAsExternalModule();
}
}
}
@@ -2207,9 +2313,9 @@ namespace ts {
if (currentFlow) {
node.flowNode = currentFlow;
}
checkStrictModeFunctionName(<FunctionExpression>node);
const bindingName = (<FunctionExpression>node).name ? (<FunctionExpression>node).name.text : "__function";
return bindAnonymousDeclaration(<FunctionExpression>node, SymbolFlags.Function, bindingName);
checkStrictModeFunctionName(node);
const bindingName = node.name ? node.name.text : "__function";
return bindAnonymousDeclaration(node, SymbolFlags.Function, bindingName);
}
function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
@@ -2222,6 +2328,10 @@ namespace ts {
}
}
if (currentFlow && isObjectLiteralOrClassExpressionMethod(node)) {
node.flowNode = currentFlow;
}
return hasDynamicName(node)
? bindAnonymousDeclaration(node, symbolFlags, "__computed")
: declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
@@ -2295,6 +2405,9 @@ namespace ts {
case SyntaxKind.CallExpression:
return computeCallExpression(<CallExpression>node, subtreeFlags);
case SyntaxKind.NewExpression:
return computeNewExpression(<NewExpression>node, subtreeFlags);
case SyntaxKind.ModuleDeclaration:
return computeModuleDeclaration(<ModuleDeclaration>node, subtreeFlags);
@@ -2340,6 +2453,9 @@ namespace ts {
case SyntaxKind.HeritageClause:
return computeHeritageClause(<HeritageClause>node, subtreeFlags);
case SyntaxKind.CatchClause:
return computeCatchClause(<CatchClause>node, subtreeFlags);
case SyntaxKind.ExpressionWithTypeArguments:
return computeExpressionWithTypeArguments(<ExpressionWithTypeArguments>node, subtreeFlags);
@@ -2372,11 +2488,15 @@ namespace ts {
const expression = node.expression;
const expressionKind = expression.kind;
if (node.typeArguments) {
transformFlags |= TransformFlags.AssertTypeScript;
}
if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression
|| isSuperOrSuperProperty(expression, expressionKind)) {
// If the this node contains a SpreadElementExpression, or is a super call, then it is an ES6
// node.
transformFlags |= TransformFlags.AssertES6;
transformFlags |= TransformFlags.AssertES2015;
}
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
@@ -2398,6 +2518,21 @@ namespace ts {
return false;
}
function computeNewExpression(node: NewExpression, subtreeFlags: TransformFlags) {
let transformFlags = subtreeFlags;
if (node.typeArguments) {
transformFlags |= TransformFlags.AssertTypeScript;
}
if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression) {
// If the this node contains a SpreadElementExpression then it is an ES6
// node.
transformFlags |= TransformFlags.AssertES2015;
}
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes;
}
function computeBinaryExpression(node: BinaryExpression, subtreeFlags: TransformFlags) {
let transformFlags = subtreeFlags;
const operatorTokenKind = node.operatorToken.kind;
@@ -2407,12 +2542,12 @@ namespace ts {
&& (leftKind === SyntaxKind.ObjectLiteralExpression
|| leftKind === SyntaxKind.ArrayLiteralExpression)) {
// Destructuring assignments are ES6 syntax.
transformFlags |= TransformFlags.AssertES6 | TransformFlags.DestructuringAssignment;
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertDestructuringAssignment;
}
else if (operatorTokenKind === SyntaxKind.AsteriskAsteriskToken
|| operatorTokenKind === SyntaxKind.AsteriskAsteriskEqualsToken) {
// Exponentiation is ES7 syntax.
transformFlags |= TransformFlags.AssertES7;
// Exponentiation is ES2016 syntax.
transformFlags |= TransformFlags.AssertES2016;
}
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
@@ -2426,13 +2561,12 @@ namespace ts {
const initializer = node.initializer;
const dotDotDotToken = node.dotDotDotToken;
// If the parameter has a question token, then it is TypeScript syntax.
if (node.questionToken) {
transformFlags |= TransformFlags.AssertTypeScript;
}
// If the parameter's name is 'this', then it is TypeScript syntax.
if (subtreeFlags & TransformFlags.ContainsDecorators || isThisIdentifier(name)) {
// The '?' token, type annotations, decorators, and 'this' parameters are TypeSCript
// syntax.
if (node.questionToken
|| node.type
|| subtreeFlags & TransformFlags.ContainsDecorators
|| isThisIdentifier(name)) {
transformFlags |= TransformFlags.AssertTypeScript;
}
@@ -2444,7 +2578,7 @@ namespace ts {
// If a parameter has an initializer, a binding pattern or a dotDotDot token, then
// it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel.
if (subtreeFlags & TransformFlags.ContainsBindingPattern || initializer || dotDotDotToken) {
transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsDefaultValueAssignments;
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsDefaultValueAssignments;
}
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
@@ -2485,13 +2619,14 @@ namespace ts {
}
else {
// A ClassDeclaration is ES6 syntax.
transformFlags = subtreeFlags | TransformFlags.AssertES6;
transformFlags = subtreeFlags | TransformFlags.AssertES2015;
// A class with a parameter property assignment, property initializer, or decorator is
// TypeScript syntax.
// An exported declaration may be TypeScript syntax.
// An exported declaration may be TypeScript syntax, but is handled by the visitor
// for a namespace declaration.
if ((subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask)
|| (modifierFlags & ModifierFlags.Export)) {
|| node.typeParameters) {
transformFlags |= TransformFlags.AssertTypeScript;
}
@@ -2508,11 +2643,12 @@ namespace ts {
function computeClassExpression(node: ClassExpression, subtreeFlags: TransformFlags) {
// A ClassExpression is ES6 syntax.
let transformFlags = subtreeFlags | TransformFlags.AssertES6;
let transformFlags = subtreeFlags | TransformFlags.AssertES2015;
// A class with a parameter property assignment, property initializer, or decorator is
// TypeScript syntax.
if (subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask) {
if (subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask
|| node.typeParameters) {
transformFlags |= TransformFlags.AssertTypeScript;
}
@@ -2532,7 +2668,7 @@ namespace ts {
switch (node.token) {
case SyntaxKind.ExtendsKeyword:
// An `extends` HeritageClause is ES6 syntax.
transformFlags |= TransformFlags.AssertES6;
transformFlags |= TransformFlags.AssertES2015;
break;
case SyntaxKind.ImplementsKeyword:
@@ -2549,10 +2685,21 @@ namespace ts {
return transformFlags & ~TransformFlags.NodeExcludes;
}
function computeCatchClause(node: CatchClause, subtreeFlags: TransformFlags) {
let transformFlags = subtreeFlags;
if (node.variableDeclaration && isBindingPattern(node.variableDeclaration.name)) {
transformFlags |= TransformFlags.AssertES2015;
}
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
return transformFlags & ~TransformFlags.NodeExcludes;
}
function computeExpressionWithTypeArguments(node: ExpressionWithTypeArguments, subtreeFlags: TransformFlags) {
// An ExpressionWithTypeArguments is ES6 syntax, as it is used in the
// extends clause of a class.
let transformFlags = subtreeFlags | TransformFlags.AssertES6;
let transformFlags = subtreeFlags | TransformFlags.AssertES2015;
// If an ExpressionWithTypeArguments contains type arguments, then it
// is TypeScript syntax.
@@ -2566,10 +2713,10 @@ namespace ts {
function computeConstructor(node: ConstructorDeclaration, subtreeFlags: TransformFlags) {
let transformFlags = subtreeFlags;
const body = node.body;
if (body === undefined) {
// An overload constructor is TypeScript syntax.
// TypeScript-specific modifiers and overloads are TypeScript syntax
if (hasModifier(node, ModifierFlags.TypeScriptModifier)
|| !node.body) {
transformFlags |= TransformFlags.AssertTypeScript;
}
@@ -2579,23 +2726,25 @@ namespace ts {
function computeMethod(node: MethodDeclaration, subtreeFlags: TransformFlags) {
// A MethodDeclaration is ES6 syntax.
let transformFlags = subtreeFlags | TransformFlags.AssertES6;
const modifierFlags = getModifierFlags(node);
const body = node.body;
const typeParameters = node.typeParameters;
const asteriskToken = node.asteriskToken;
let transformFlags = subtreeFlags | TransformFlags.AssertES2015;
// A MethodDeclaration is TypeScript syntax if it is either async, abstract, overloaded,
// generic, or has a decorator.
if (!body
|| typeParameters
|| (modifierFlags & (ModifierFlags.Async | ModifierFlags.Abstract))
|| (subtreeFlags & TransformFlags.ContainsDecorators)) {
// Decorators, TypeScript-specific modifiers, type parameters, type annotations, and
// overloads are TypeScript syntax.
if (node.decorators
|| hasModifier(node, ModifierFlags.TypeScriptModifier)
|| node.typeParameters
|| node.type
|| !node.body) {
transformFlags |= TransformFlags.AssertTypeScript;
}
// An async method declaration is ES2017 syntax.
if (hasModifier(node, ModifierFlags.Async)) {
transformFlags |= TransformFlags.AssertES2017;
}
// Currently, we only support generators that were originally async function bodies.
if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
transformFlags |= TransformFlags.AssertGenerator;
}
@@ -2605,14 +2754,13 @@ namespace ts {
function computeAccessor(node: AccessorDeclaration, subtreeFlags: TransformFlags) {
let transformFlags = subtreeFlags;
const modifierFlags = getModifierFlags(node);
const body = node.body;
// A MethodDeclaration is TypeScript syntax if it is either async, abstract, overloaded,
// generic, or has a decorator.
if (!body
|| (modifierFlags & (ModifierFlags.Async | ModifierFlags.Abstract))
|| (subtreeFlags & TransformFlags.ContainsDecorators)) {
// Decorators, TypeScript-specific modifiers, type annotations, and overloads are
// TypeScript syntax.
if (node.decorators
|| hasModifier(node, ModifierFlags.TypeScriptModifier)
|| node.type
|| !node.body) {
transformFlags |= TransformFlags.AssertTypeScript;
}
@@ -2638,7 +2786,6 @@ namespace ts {
let transformFlags: TransformFlags;
const modifierFlags = getModifierFlags(node);
const body = node.body;
const asteriskToken = node.asteriskToken;
if (!body || (modifierFlags & ModifierFlags.Ambient)) {
// An ambient declaration is TypeScript syntax.
@@ -2648,21 +2795,24 @@ namespace ts {
else {
transformFlags = subtreeFlags | TransformFlags.ContainsHoistedDeclarationOrCompletion;
// If a FunctionDeclaration is exported, then it is either ES6 or TypeScript syntax.
if (modifierFlags & ModifierFlags.Export) {
transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES6;
// TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
// syntax.
if (modifierFlags & ModifierFlags.TypeScriptModifier
|| node.typeParameters
|| node.type) {
transformFlags |= TransformFlags.AssertTypeScript;
}
// If a FunctionDeclaration is async, then it is TypeScript syntax.
// An async function declaration is ES2017 syntax.
if (modifierFlags & ModifierFlags.Async) {
transformFlags |= TransformFlags.AssertTypeScript;
transformFlags |= TransformFlags.AssertES2017;
}
// If a FunctionDeclaration's subtree has marked the container as needing to capture the
// lexical this, or the function contains parameters with initializers, then this node is
// ES6 syntax.
if (subtreeFlags & TransformFlags.ES6FunctionSyntaxMask) {
transformFlags |= TransformFlags.AssertES6;
if (subtreeFlags & TransformFlags.ES2015FunctionSyntaxMask) {
transformFlags |= TransformFlags.AssertES2015;
}
// If a FunctionDeclaration is generator function and is the body of a
@@ -2670,7 +2820,7 @@ namespace ts {
// down-level generator.
// Currently we do not support transforming any other generator fucntions
// down level.
if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
transformFlags |= TransformFlags.AssertGenerator;
}
}
@@ -2681,19 +2831,25 @@ namespace ts {
function computeFunctionExpression(node: FunctionExpression, subtreeFlags: TransformFlags) {
let transformFlags = subtreeFlags;
const modifierFlags = getModifierFlags(node);
const asteriskToken = node.asteriskToken;
// An async function expression is TypeScript syntax.
if (modifierFlags & ModifierFlags.Async) {
// TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
// syntax.
if (hasModifier(node, ModifierFlags.TypeScriptModifier)
|| node.typeParameters
|| node.type) {
transformFlags |= TransformFlags.AssertTypeScript;
}
// An async function expression is ES2017 syntax.
if (hasModifier(node, ModifierFlags.Async)) {
transformFlags |= TransformFlags.AssertES2017;
}
// If a FunctionExpression's subtree has marked the container as needing to capture the
// lexical this, or the function contains parameters with initializers, then this node is
// ES6 syntax.
if (subtreeFlags & TransformFlags.ES6FunctionSyntaxMask) {
transformFlags |= TransformFlags.AssertES6;
if (subtreeFlags & TransformFlags.ES2015FunctionSyntaxMask) {
transformFlags |= TransformFlags.AssertES2015;
}
// If a FunctionExpression is generator function and is the body of a
@@ -2701,7 +2857,7 @@ namespace ts {
// down-level generator.
// Currently we do not support transforming any other generator fucntions
// down level.
if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
transformFlags |= TransformFlags.AssertGenerator;
}
@@ -2711,14 +2867,21 @@ namespace ts {
function computeArrowFunction(node: ArrowFunction, subtreeFlags: TransformFlags) {
// An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction.
let transformFlags = subtreeFlags | TransformFlags.AssertES6;
const modifierFlags = getModifierFlags(node);
let transformFlags = subtreeFlags | TransformFlags.AssertES2015;
// An async arrow function is TypeScript syntax.
if (modifierFlags & ModifierFlags.Async) {
// TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
// syntax.
if (hasModifier(node, ModifierFlags.TypeScriptModifier)
|| node.typeParameters
|| node.type) {
transformFlags |= TransformFlags.AssertTypeScript;
}
// An async arrow function is ES2017 syntax.
if (hasModifier(node, ModifierFlags.Async)) {
transformFlags |= TransformFlags.AssertES2017;
}
// If an ArrowFunction contains a lexical this, its container must capture the lexical this.
if (subtreeFlags & TransformFlags.ContainsLexicalThis) {
transformFlags |= TransformFlags.ContainsCapturedLexicalThis;
@@ -2749,7 +2912,12 @@ namespace ts {
// A VariableDeclaration with a binding pattern is ES6 syntax.
if (nameKind === SyntaxKind.ObjectBindingPattern || nameKind === SyntaxKind.ArrayBindingPattern) {
transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsBindingPattern;
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
}
// Type annotations are TypeScript syntax.
if (node.type) {
transformFlags |= TransformFlags.AssertTypeScript;
}
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
@@ -2768,13 +2936,8 @@ namespace ts {
else {
transformFlags = subtreeFlags;
// If a VariableStatement is exported, then it is either ES6 or TypeScript syntax.
if (modifierFlags & ModifierFlags.Export) {
transformFlags |= TransformFlags.AssertES6 | TransformFlags.AssertTypeScript;
}
if (declarationListTransformFlags & TransformFlags.ContainsBindingPattern) {
transformFlags |= TransformFlags.AssertES6;
transformFlags |= TransformFlags.AssertES2015;
}
}
@@ -2788,7 +2951,7 @@ namespace ts {
// A labeled statement containing a block scoped binding *may* need to be transformed from ES6.
if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding
&& isIterationStatement(node, /*lookInLabeledStatements*/ true)) {
transformFlags |= TransformFlags.AssertES6;
transformFlags |= TransformFlags.AssertES2015;
}
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
@@ -2814,7 +2977,7 @@ namespace ts {
// then we treat the statement as ES6 so that we can indicate that we do not
// need to hold on to the right-hand side.
if (node.expression.transformFlags & TransformFlags.DestructuringAssignment) {
transformFlags |= TransformFlags.AssertES6;
transformFlags |= TransformFlags.AssertES2015;
}
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
@@ -2837,12 +3000,12 @@ namespace ts {
let transformFlags = subtreeFlags | TransformFlags.ContainsHoistedDeclarationOrCompletion;
if (subtreeFlags & TransformFlags.ContainsBindingPattern) {
transformFlags |= TransformFlags.AssertES6;
transformFlags |= TransformFlags.AssertES2015;
}
// If a VariableDeclarationList is `let` or `const`, then it is ES6 syntax.
if (node.flags & NodeFlags.BlockScoped) {
transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsBlockScopedBinding;
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBlockScopedBinding;
}
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
@@ -2855,14 +3018,18 @@ namespace ts {
let excludeFlags = TransformFlags.NodeExcludes;
switch (kind) {
case SyntaxKind.AsyncKeyword:
case SyntaxKind.AwaitExpression:
// async/await is ES2017 syntax
transformFlags |= TransformFlags.AssertES2017;
break;
case SyntaxKind.PublicKeyword:
case SyntaxKind.PrivateKeyword:
case SyntaxKind.ProtectedKeyword:
case SyntaxKind.AbstractKeyword:
case SyntaxKind.DeclareKeyword:
case SyntaxKind.AsyncKeyword:
case SyntaxKind.ConstKeyword:
case SyntaxKind.AwaitExpression:
case SyntaxKind.EnumDeclaration:
case SyntaxKind.EnumMember:
case SyntaxKind.TypeAssertionExpression:
@@ -2885,12 +3052,6 @@ namespace ts {
transformFlags |= TransformFlags.AssertJsx;
break;
case SyntaxKind.ExportKeyword:
// This node is both ES6 and TypeScript syntax.
transformFlags |= TransformFlags.AssertES6 | TransformFlags.AssertTypeScript;
break;
case SyntaxKind.DefaultKeyword:
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.TemplateHead:
case SyntaxKind.TemplateMiddle:
@@ -2899,13 +3060,14 @@ namespace ts {
case SyntaxKind.TaggedTemplateExpression:
case SyntaxKind.ShorthandPropertyAssignment:
case SyntaxKind.ForOfStatement:
case SyntaxKind.StaticKeyword:
// These nodes are ES6 syntax.
transformFlags |= TransformFlags.AssertES6;
transformFlags |= TransformFlags.AssertES2015;
break;
case SyntaxKind.YieldExpression:
// This node is ES6 syntax.
transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsYield;
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsYield;
break;
case SyntaxKind.AnyKeyword:
@@ -2966,7 +3128,7 @@ namespace ts {
case SyntaxKind.SuperKeyword:
// This node is ES6 syntax.
transformFlags |= TransformFlags.AssertES6;
transformFlags |= TransformFlags.AssertES2015;
break;
case SyntaxKind.ThisKeyword:
@@ -2977,7 +3139,7 @@ namespace ts {
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
// These nodes are ES6 syntax.
transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsBindingPattern;
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
break;
case SyntaxKind.Decorator:
@@ -2990,7 +3152,7 @@ namespace ts {
if (subtreeFlags & TransformFlags.ContainsComputedPropertyName) {
// If an ObjectLiteralExpression contains a ComputedPropertyName, then it
// is an ES6 node.
transformFlags |= TransformFlags.AssertES6;
transformFlags |= TransformFlags.AssertES2015;
}
if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) {
@@ -3007,7 +3169,7 @@ namespace ts {
if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression) {
// If the this node contains a SpreadElementExpression, then it is an ES6
// node.
transformFlags |= TransformFlags.AssertES6;
transformFlags |= TransformFlags.AssertES2015;
}
break;
@@ -3018,14 +3180,14 @@ namespace ts {
case SyntaxKind.ForInStatement:
// A loop containing a block scoped binding *may* need to be transformed from ES6.
if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding) {
transformFlags |= TransformFlags.AssertES6;
transformFlags |= TransformFlags.AssertES2015;
}
break;
case SyntaxKind.SourceFile:
if (subtreeFlags & TransformFlags.ContainsCapturedLexicalThis) {
transformFlags |= TransformFlags.AssertES6;
transformFlags |= TransformFlags.AssertES2015;
}
break;
+759 -360
View File
File diff suppressed because it is too large. Load diff
+54 -18
View File
@@ -101,7 +101,7 @@ namespace ts {
"amd": ModuleKind.AMD,
"system": ModuleKind.System,
"umd": ModuleKind.UMD,
"es6": ModuleKind.ES6,
"es6": ModuleKind.ES2015,
"es2015": ModuleKind.ES2015,
}),
description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015,
@@ -261,8 +261,10 @@ namespace ts {
type: createMap({
"es3": ScriptTarget.ES3,
"es5": ScriptTarget.ES5,
"es6": ScriptTarget.ES6,
"es6": ScriptTarget.ES2015,
"es2015": ScriptTarget.ES2015,
"es2016": ScriptTarget.ES2016,
"es2017": ScriptTarget.ES2017,
}),
description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015,
paramType: Diagnostics.VERSION,
@@ -444,6 +446,11 @@ namespace ts {
name: "importHelpers",
type: "boolean",
description: Diagnostics.Import_emit_helpers_from_tslib
},
{
name: "alwaysStrict",
type: "boolean",
description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file
}
];
@@ -508,10 +515,7 @@ namespace ts {
/* @internal */
export function createCompilerDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType): Diagnostic {
const namesOfType: string[] = [];
for (const key in opt.type) {
namesOfType.push(` '${key}'`);
}
const namesOfType = Object.keys(opt.type).map(key => `'${key}'`).join(", ");
return createCompilerDiagnostic(Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, namesOfType);
}
@@ -595,7 +599,13 @@ namespace ts {
i++;
break;
case "boolean":
options[opt.name] = true;
// boolean flag has optional value true, false, others
let optValue = args[i];
options[opt.name] = optValue !== "false";
// consume next argument as boolean flag value
if (optValue === "false" || optValue === "true") {
i++;
}
break;
case "string":
options[opt.name] = args[i] || "";
@@ -902,6 +912,9 @@ namespace ts {
if (hasProperty(json, "files")) {
if (isArray(json["files"])) {
fileNames = <string[]>json["files"];
if (fileNames.length === 0) {
errors.push(createCompilerDiagnostic(Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json"));
}
}
else {
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "files", "Array"));
@@ -944,7 +957,18 @@ namespace ts {
includeSpecs = ["**/*"];
}
return matchFileNames(fileNames, includeSpecs, excludeSpecs, basePath, options, host, errors);
const result = matchFileNames(fileNames, includeSpecs, excludeSpecs, basePath, options, host, errors);
if (result.fileNames.length === 0 && !hasProperty(json, "files") && resolutionStack.length === 0) {
errors.push(
createCompilerDiagnostic(
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
configFileName || "tsconfig.json",
JSON.stringify(includeSpecs || []),
JSON.stringify(excludeSpecs || [])));
}
return result;
}
}
@@ -975,7 +999,7 @@ namespace ts {
basePath: string, errors: Diagnostic[], configFileName?: string): CompilerOptions {
const options: CompilerOptions = getBaseFileName(configFileName) === "jsconfig.json"
? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true }
? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true }
: {};
convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_compiler_option_0, errors);
return options;
@@ -984,9 +1008,7 @@ namespace ts {
function convertTypingOptionsFromJsonWorker(jsonOptions: any,
basePath: string, errors: Diagnostic[], configFileName?: string): TypingOptions {
const options: TypingOptions = getBaseFileName(configFileName) === "jsconfig.json"
? { enableAutoDiscovery: true, include: [], exclude: [] }
: { enableAutoDiscovery: false, include: [], exclude: [] };
const options: TypingOptions = { enableAutoDiscovery: getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] };
convertOptionsFromJson(typingOptionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_typing_option_0, errors);
return options;
}
@@ -1239,12 +1261,13 @@ 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) {
function getWildcardDirectories(include: string[], exclude: string[], path: string, useCaseSensitiveFileNames: boolean): Map<WatchDirectoryFlags> {
// We watch a directory recursively if it contains a wildcard anywhere in a directory segment
// of the pattern:
//
// /a/b/**/d - Watch /a/b recursively to catch changes to any d in any subfolder recursively
// /a/b/*/d - Watch /a/b recursively to catch any d in any immediate subfolder, even if a new subfolder is added
// /a/b - Watch /a/b recursively to catch changes to anything in any recursive subfoler
//
// We watch a directory without recursion if it contains a wildcard in the file segment of
// the pattern:
@@ -1257,15 +1280,14 @@ namespace ts {
if (include !== undefined) {
const recursiveKeys: string[] = [];
for (const file of include) {
const name = normalizePath(combinePaths(path, file));
if (excludeRegex && excludeRegex.test(name)) {
const spec = normalizePath(combinePaths(path, file));
if (excludeRegex && excludeRegex.test(spec)) {
continue;
}
const match = wildcardDirectoryPattern.exec(name);
const match = getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames);
if (match) {
const key = useCaseSensitiveFileNames ? match[0] : match[0].toLowerCase();
const flags = watchRecursivePattern.test(name) ? WatchDirectoryFlags.Recursive : WatchDirectoryFlags.None;
const { key, flags } = match;
const existingFlags = wildcardDirectories[key];
if (existingFlags === undefined || existingFlags < flags) {
wildcardDirectories[key] = flags;
@@ -1289,6 +1311,20 @@ namespace ts {
return wildcardDirectories;
}
function getWildcardDirectoryFromSpec(spec: string, useCaseSensitiveFileNames: boolean): { key: string, flags: WatchDirectoryFlags } | undefined {
const match = wildcardDirectoryPattern.exec(spec);
if (match) {
return {
key: useCaseSensitiveFileNames ? match[0] : match[0].toLowerCase(),
flags: watchRecursivePattern.test(spec) ? WatchDirectoryFlags.Recursive : WatchDirectoryFlags.None
};
}
if (isImplicitGlob(spec)) {
return { key: spec, flags: WatchDirectoryFlags.Recursive };
}
return undefined;
}
/**
* Determines whether a literal or wildcard file has already been included that has a higher
* extension priority.
+3 -3
View File
@@ -188,7 +188,7 @@ namespace ts {
}
}
function emitLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) {
function emitLeadingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) {
if (!hasWrittenComment) {
emitNewLineBeforeLeadingCommentOfPosition(currentLineMap, writer, rangePos, commentPos);
hasWrittenComment = true;
@@ -211,7 +211,7 @@ namespace ts {
forEachTrailingCommentToEmit(pos, emitTrailingComment);
}
function emitTrailingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean) {
function emitTrailingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) {
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/
if (!writer.isAtStartOfLine()) {
writer.write(" ");
@@ -242,7 +242,7 @@ namespace ts {
}
}
function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean) {
function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) {
// trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
emitPos(commentPos);
+313 -124
View File
@@ -20,6 +20,9 @@ namespace ts {
const createObject = Object.create;
// More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times.
export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined;
export function createMap<T>(template?: MapLike<T>): Map<T> {
const map: Map<T> = createObject(null); // tslint:disable-line:no-null-keyword
@@ -121,6 +124,13 @@ namespace ts {
return undefined;
}
export function zipWith<T, U>(arrayA: T[], arrayB: U[], callback: (a: T, b: U, index: number) => void): void {
Debug.assert(arrayA.length === arrayB.length);
for (let i = 0; i < arrayA.length; i++) {
callback(arrayA[i], arrayB[i], i);
}
}
/**
* Iterates through `array` by index and performs the callback on each element of array until the callback
* returns a falsey value, then returns false.
@@ -265,13 +275,33 @@ namespace ts {
if (array) {
result = [];
for (let i = 0; i < array.length; i++) {
const v = array[i];
result.push(f(v, i));
result.push(f(array[i], i));
}
}
return result;
}
// Maps from T to T and avoids allocation if all elements map to themselves
export function sameMap<T>(array: T[], f: (x: T, i: number) => T): T[] {
let result: T[];
if (array) {
for (let i = 0; i < array.length; i++) {
if (result) {
result.push(f(array[i], i));
}
else {
const item = array[i];
const mapped = f(item, i);
if (item !== mapped) {
result = array.slice(0, i);
result.push(mapped);
}
}
}
}
return result || array;
}
/**
* Flattens an array containing a mix of array or non-array elements.
*
@@ -399,9 +429,25 @@ namespace ts {
return result;
}
export function some<T>(array: T[], predicate?: (value: T) => boolean): boolean {
if (array) {
if (predicate) {
for (const v of array) {
if (predicate(v)) {
return true;
}
}
}
else {
return array.length > 0;
}
}
return false;
}
export function concatenate<T>(array1: T[], array2: T[]): T[] {
if (isEmptyArray(array2)) return array1;
if (isEmptyArray(array1)) return array2;
if (!some(array2)) return array1;
if (!some(array1)) return array2;
return [...array1, ...array2];
}
@@ -422,6 +468,44 @@ namespace ts {
return result;
}
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T>, array2: ReadonlyArray<T>, equaler?: (a: T, b: T) => boolean): boolean {
if (!array1 || !array2) {
return array1 === array2;
}
if (array1.length !== array2.length) {
return false;
}
for (let i = 0; i < array1.length; i++) {
const equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
if (!equals) {
return false;
}
}
return true;
}
export function changesAffectModuleResolution(oldOptions: CompilerOptions, newOptions: CompilerOptions): boolean {
return !oldOptions ||
(oldOptions.module !== newOptions.module) ||
(oldOptions.moduleResolution !== newOptions.moduleResolution) ||
(oldOptions.noResolve !== newOptions.noResolve) ||
(oldOptions.target !== newOptions.target) ||
(oldOptions.noLib !== newOptions.noLib) ||
(oldOptions.jsx !== newOptions.jsx) ||
(oldOptions.allowJs !== newOptions.allowJs) ||
(oldOptions.rootDir !== newOptions.rootDir) ||
(oldOptions.configFilePath !== newOptions.configFilePath) ||
(oldOptions.baseUrl !== newOptions.baseUrl) ||
(oldOptions.maxNodeModuleJsDepth !== newOptions.maxNodeModuleJsDepth) ||
!arrayIsEqualTo(oldOptions.lib, newOptions.lib) ||
!arrayIsEqualTo(oldOptions.typeRoots, newOptions.typeRoots) ||
!arrayIsEqualTo(oldOptions.rootDirs, newOptions.rootDirs) ||
!equalOwnProperties(oldOptions.paths, newOptions.paths);
}
/**
* Compacts an array, removing any falsey elements.
*/
@@ -472,14 +556,35 @@ namespace ts {
return result;
}
export function addRange<T>(to: T[], from: T[]): void {
if (to && from) {
for (const v of from) {
if (v !== undefined) {
to.push(v);
}
}
/**
* Appends a value to an array, returning the array.
*
* @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array
* is created if `value` was appended.
* @param value The value to append to the array. If `value` is `undefined`, nothing is
* appended.
*/
export function append<T>(to: T[] | undefined, value: T | undefined): T[] | undefined {
if (value === undefined) return to;
if (to === undefined) to = [];
to.push(value);
return to;
}
/**
* Appends a range of value to an array, returning the array.
*
* @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array
* is created if `value` was appended.
* @param from The values to append to the array. If `from` is `undefined`, nothing is
* appended. If an element of `from` is `undefined`, that element is not appended.
*/
export function addRange<T>(to: T[] | undefined, from: T[] | undefined): T[] | undefined {
if (from === undefined) return to;
for (const v of from) {
to = append(to, v);
}
return to;
}
export function rangeEquals<T>(array1: T[], array2: T[], pos: number, end: number) {
@@ -492,31 +597,47 @@ namespace ts {
return true;
}
/**
* Returns the first element of an array if non-empty, `undefined` otherwise.
*/
export function firstOrUndefined<T>(array: T[]): T {
return array && array.length > 0
? array[0]
: undefined;
}
/**
* Returns the last element of an array if non-empty, `undefined` otherwise.
*/
export function lastOrUndefined<T>(array: T[]): T {
return array && array.length > 0
? array[array.length - 1]
: undefined;
}
/**
* Returns the only element of an array if it contains only one element, `undefined` otherwise.
*/
export function singleOrUndefined<T>(array: T[]): T {
return array && array.length === 1
? array[0]
: undefined;
}
/**
* Returns the only element of an array if it contains only one element; otheriwse, returns the
* array.
*/
export function singleOrMany<T>(array: T[]): T | T[] {
return array && array.length === 1
? array[0]
: array;
}
/**
* Returns the last element of an array if non-empty, undefined otherwise.
*/
export function lastOrUndefined<T>(array: T[]): T {
return array && array.length > 0
? array[array.length - 1]
: undefined;
export function replaceElement<T>(array: T[], index: number, value: T): T[] {
const result = array.slice(0);
result[index] = value;
return result;
}
/**
@@ -802,7 +923,7 @@ namespace ts {
return result;
}
export function extend<T1, T2>(first: T1 , second: T2): T1 & T2 {
export function extend<T1, T2>(first: T1, second: T2): T1 & T2 {
const result: T1 & T2 = <any>{};
for (const id in second) if (hasOwnProperty.call(second, id)) {
(result as any)[id] = (second as any)[id];
@@ -817,7 +938,7 @@ namespace ts {
* Adds the value to an array of values associated with the key, and returns the array.
* Creates the array if it does not already exist.
*/
export function multiMapAdd<V>(map: Map<V[]>, key: string, value: V): V[] {
export function multiMapAdd<V>(map: Map<V[]>, key: string | number, value: V): V[] {
const values = map[key];
if (values) {
values.push(value);
@@ -850,8 +971,12 @@ namespace ts {
return Array.isArray ? Array.isArray(value) : value instanceof Array;
}
export function isEmptyArray(value: any[] | undefined): boolean {
return !value || !value.length;
/** Does nothing. */
export function noop(): void {}
/** Throws an error because a function is not implemented. */
export function notImplemented(): never {
throw new Error("Not implemented");
}
export function memoize<T>(callback: () => T): () => T {
@@ -894,7 +1019,7 @@ namespace ts {
return t => compose(a(t));
}
else {
return t => u => u;
return _ => u => u;
}
}
@@ -931,10 +1056,10 @@ namespace ts {
}
}
function formatStringFromArgs(text: string, args: { [index: number]: any; }, baseIndex?: number): string {
function formatStringFromArgs(text: string, args: { [index: number]: string; }, baseIndex?: number): string {
baseIndex = baseIndex || 0;
return text.replace(/{(\d+)}/g, (match, index?) => args[+index + baseIndex]);
return text.replace(/{(\d+)}/g, (_match, index?) => args[+index + baseIndex]);
}
export let localizedDiagnosticMessages: Map<string> = undefined;
@@ -943,7 +1068,7 @@ namespace ts {
return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message;
}
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: any[]): Diagnostic;
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number)[]): Diagnostic;
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): Diagnostic {
const end = start + length;
@@ -951,8 +1076,8 @@ namespace ts {
Debug.assert(length >= 0, "length must be non-negative, is " + length);
if (file) {
Debug.assert(start <= file.text.length, `start must be within the bounds of the file. ${ start } > ${ file.text.length }`);
Debug.assert(end <= file.text.length, `end must be the bounds of the file. ${ end } > ${ file.text.length }`);
Debug.assert(start <= file.text.length, `start must be within the bounds of the file. ${start} > ${file.text.length}`);
Debug.assert(end <= file.text.length, `end must be the bounds of the file. ${end} > ${file.text.length}`);
}
let text = getLocaleSpecificMessage(message);
@@ -973,7 +1098,7 @@ namespace ts {
}
/* internal */
export function formatMessage(dummy: any, message: DiagnosticMessage): string {
export function formatMessage(_dummy: any, message: DiagnosticMessage): string {
let text = getLocaleSpecificMessage(message);
if (arguments.length > 2) {
@@ -983,7 +1108,7 @@ namespace ts {
return text;
}
export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: any[]): Diagnostic;
export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: (string | number)[]): Diagnostic;
export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic {
let text = getLocaleSpecificMessage(message);
@@ -1041,7 +1166,8 @@ namespace ts {
if (a === undefined) return Comparison.LessThan;
if (b === undefined) return Comparison.GreaterThan;
if (ignoreCase) {
if (String.prototype.localeCompare) {
if (collator && String.prototype.localeCompare) {
// accent means a ≠ b, a ≠ á, a = A
const result = a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" });
return result < 0 ? Comparison.LessThan : result > 0 ? Comparison.GreaterThan : Comparison.EqualTo;
}
@@ -1122,7 +1248,9 @@ namespace ts {
return path.replace(/\\/g, "/");
}
// Returns length of path root (i.e. length of "/", "x:/", "//server/share/, file:///user/files")
/**
* Returns length of path root (i.e. length of "/", "x:/", "//server/share/, file:///user/files")
*/
export function getRootLength(path: string): number {
if (path.charCodeAt(0) === CharacterCodes.slash) {
if (path.charCodeAt(1) !== CharacterCodes.slash) return 1;
@@ -1151,9 +1279,14 @@ namespace ts {
return 0;
}
/**
* Internally, we represent paths as strings with '/' as the directory separator.
* When we make system calls (eg: LanguageServiceHost.getDirectory()),
* we expect the host to correctly handle paths in our specified format.
*/
export const directorySeparator = "/";
const directorySeparatorCharCode = CharacterCodes.slash;
function getNormalizedParts(normalizedSlashedPath: string, rootLength: number) {
function getNormalizedParts(normalizedSlashedPath: string, rootLength: number): string[] {
const parts = normalizedSlashedPath.substr(rootLength).split(directorySeparator);
const normalized: string[] = [];
for (const part of parts) {
@@ -1193,9 +1326,14 @@ namespace ts {
return path.charCodeAt(path.length - 1) === directorySeparatorCharCode;
}
/**
* Returns the path except for its basename. Eg:
*
* /path/to/file.ext -> /path/to
*/
export function getDirectoryPath(path: Path): Path;
export function getDirectoryPath(path: string): string;
export function getDirectoryPath(path: string): any {
export function getDirectoryPath(path: string): string {
return path.substr(0, Math.max(getRootLength(path), path.lastIndexOf(directorySeparator)));
}
@@ -1216,7 +1354,7 @@ namespace ts {
export function getEmitModuleKind(compilerOptions: CompilerOptions) {
return typeof compilerOptions.module === "number" ?
compilerOptions.module :
getEmitScriptTarget(compilerOptions) === ScriptTarget.ES6 ? ModuleKind.ES6 : ModuleKind.CommonJS;
getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2015 ? ModuleKind.ES2015 : ModuleKind.CommonJS;
}
/* @internal */
@@ -1455,6 +1593,10 @@ namespace ts {
return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
}
export function hasExtension(fileName: string): boolean {
return getBaseFileName(fileName).indexOf(".") >= 0;
}
export function fileExtensionIs(path: string, extension: string): boolean {
return path.length > extension.length && endsWith(path, extension);
}
@@ -1489,7 +1631,7 @@ namespace ts {
return undefined;
}
const replaceWildcardCharacter = usage === "files" ? replaceWildCardCharacterFiles : replaceWildCardCharacterOther;
const replaceWildcardCharacter = usage === "files" ? replaceWildCardCharacterFiles : replaceWildCardCharacterOther;
const singleAsteriskRegexFragment = usage === "files" ? singleAsteriskRegexFragmentFiles : singleAsteriskRegexFragmentOther;
/**
@@ -1500,73 +1642,21 @@ namespace ts {
let pattern = "";
let hasWrittenSubpattern = false;
spec: for (const spec of specs) {
for (const spec of specs) {
if (!spec) {
continue;
}
let subpattern = "";
let hasRecursiveDirectoryWildcard = false;
let hasWrittenComponent = false;
const components = getNormalizedPathComponents(spec, basePath);
if (usage !== "exclude" && components[components.length - 1] === "**") {
continue spec;
}
// getNormalizedPathComponents includes the separator for the root component.
// We need to remove to create our regex correctly.
components[0] = removeTrailingDirectorySeparator(components[0]);
let optionalCount = 0;
for (let component of components) {
if (component === "**") {
if (hasRecursiveDirectoryWildcard) {
continue spec;
}
subpattern += doubleAsteriskRegexFragment;
hasRecursiveDirectoryWildcard = true;
hasWrittenComponent = true;
}
else {
if (usage === "directories") {
subpattern += "(";
optionalCount++;
}
if (hasWrittenComponent) {
subpattern += directorySeparator;
}
if (usage !== "exclude") {
// The * and ? wildcards should not match directories or files that start with . if they
// appear first in a component. Dotted directories and files can be included explicitly
// like so: **/.*/.*
if (component.charCodeAt(0) === CharacterCodes.asterisk) {
subpattern += "([^./]" + singleAsteriskRegexFragment + ")?";
component = component.substr(1);
}
else if (component.charCodeAt(0) === CharacterCodes.question) {
subpattern += "[^./]";
component = component.substr(1);
}
}
subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
hasWrittenComponent = true;
}
}
while (optionalCount > 0) {
subpattern += ")?";
optionalCount--;
const subPattern = getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter);
if (subPattern === undefined) {
continue;
}
if (hasWrittenSubpattern) {
pattern += "|";
}
pattern += "(" + subpattern + ")";
pattern += "(" + subPattern + ")";
hasWrittenSubpattern = true;
}
@@ -1574,7 +1664,83 @@ namespace ts {
return undefined;
}
return "^(" + pattern + (usage === "exclude" ? ")($|/)" : ")$");
// If excluding, match "foo/bar/baz...", but if including, only allow "foo".
const terminator = usage === "exclude" ? "($|/)" : "$";
return `^(${pattern})${terminator}`;
}
/**
* An "includes" path "foo" is implicitly a glob "foo/** /*" (without the space) if its last component has no extension,
* and does not contain any glob characters itself.
*/
export function isImplicitGlob(lastPathComponent: string): boolean {
return !/[.*?]/.test(lastPathComponent);
}
function getSubPatternFromSpec(spec: string, basePath: string, usage: "files" | "directories" | "exclude", singleAsteriskRegexFragment: string, doubleAsteriskRegexFragment: string, replaceWildcardCharacter: (match: string) => string): string | undefined {
let subpattern = "";
let hasRecursiveDirectoryWildcard = false;
let hasWrittenComponent = false;
const components = getNormalizedPathComponents(spec, basePath);
const lastComponent = lastOrUndefined(components);
if (usage !== "exclude" && lastComponent === "**") {
return undefined;
}
// getNormalizedPathComponents includes the separator for the root component.
// We need to remove to create our regex correctly.
components[0] = removeTrailingDirectorySeparator(components[0]);
if (isImplicitGlob(lastComponent)) {
components.push("**", "*");
}
let optionalCount = 0;
for (let component of components) {
if (component === "**") {
if (hasRecursiveDirectoryWildcard) {
return undefined;
}
subpattern += doubleAsteriskRegexFragment;
hasRecursiveDirectoryWildcard = true;
}
else {
if (usage === "directories") {
subpattern += "(";
optionalCount++;
}
if (hasWrittenComponent) {
subpattern += directorySeparator;
}
if (usage !== "exclude") {
// The * and ? wildcards should not match directories or files that start with . if they
// appear first in a component. Dotted directories and files can be included explicitly
// like so: **/.*/.*
if (component.charCodeAt(0) === CharacterCodes.asterisk) {
subpattern += "([^./]" + singleAsteriskRegexFragment + ")?";
component = component.substr(1);
}
else if (component.charCodeAt(0) === CharacterCodes.question) {
subpattern += "[^./]";
component = component.substr(1);
}
}
subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
}
hasWrittenComponent = true;
}
while (optionalCount > 0) {
subpattern += ")?";
optionalCount--;
}
return subpattern;
}
function replaceWildCardCharacterFiles(match: string) {
@@ -1601,7 +1767,7 @@ namespace ts {
basePaths: string[];
}
export function getFileMatcherPatterns(path: string, extensions: string[], excludes: string[], includes: string[], useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns {
export function getFileMatcherPatterns(path: string, excludes: string[], includes: string[], useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns {
path = normalizePath(path);
currentDirectory = normalizePath(currentDirectory);
const absolutePath = combinePaths(currentDirectory, path);
@@ -1618,7 +1784,7 @@ namespace ts {
path = normalizePath(path);
currentDirectory = normalizePath(currentDirectory);
const patterns = getFileMatcherPatterns(path, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory);
const patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory);
const regexFlag = useCaseSensitiveFileNames ? "" : "i";
const includeFileRegex = patterns.includeFilePattern && new RegExp(patterns.includeFilePattern, regexFlag);
@@ -1661,6 +1827,7 @@ namespace ts {
function getBasePaths(path: string, includes: string[], useCaseSensitiveFileNames: boolean) {
// Storage for our results in the form of literal paths (e.g. the paths as written by the user).
const basePaths: string[] = [path];
if (includes) {
// Storage for literal base paths amongst the include patterns.
const includeBasePaths: string[] = [];
@@ -1668,14 +1835,8 @@ namespace ts {
// We also need to check the relative paths by converting them to absolute and normalizing
// in case they escape the base path (e.g "..\somedirectory")
const absolute: string = isRootedDiskPath(include) ? include : normalizePath(combinePaths(path, include));
const wildcardOffset = indexOfAnyCharCode(absolute, wildcardCharCodes);
const includeBasePath = wildcardOffset < 0
? removeTrailingDirectorySeparator(getDirectoryPath(absolute))
: absolute.substring(0, absolute.lastIndexOf(directorySeparator, wildcardOffset));
// Append the literal and canonical candidate base paths.
includeBasePaths.push(includeBasePath);
includeBasePaths.push(getIncludeBasePath(absolute));
}
// Sort the offsets array using either the literal or canonical path representations.
@@ -1683,21 +1844,27 @@ namespace ts {
// Iterate over each include base path and include unique base paths that are not a
// subpath of an existing base path
include: for (let i = 0; i < includeBasePaths.length; i++) {
const includeBasePath = includeBasePaths[i];
for (let j = 0; j < basePaths.length; j++) {
if (containsPath(basePaths[j], includeBasePath, path, !useCaseSensitiveFileNames)) {
continue include;
}
for (const includeBasePath of includeBasePaths) {
if (ts.every(basePaths, basePath => !containsPath(basePath, includeBasePath, path, !useCaseSensitiveFileNames))) {
basePaths.push(includeBasePath);
}
basePaths.push(includeBasePath);
}
}
return basePaths;
}
function getIncludeBasePath(absolute: string): string {
const wildcardOffset = indexOfAnyCharCode(absolute, wildcardCharCodes);
if (wildcardOffset < 0) {
// No "*" or "?" in the path
return !hasExtension(absolute)
? absolute
: removeTrailingDirectorySeparator(getDirectoryPath(absolute));
}
return absolute.substring(0, absolute.lastIndexOf(directorySeparator, wildcardOffset));
}
export function ensureScriptKind(fileName: string, scriptKind?: ScriptKind): ScriptKind {
// Using scriptKind as a condition handles both:
// - 'scriptKind' is unspecified and thus it is `undefined`
@@ -1731,7 +1898,7 @@ namespace ts {
/** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */
export const supportedTypescriptExtensionsForExtractExtension = [".d.ts", ".ts", ".tsx"];
export const supportedJavascriptExtensions = [".js", ".jsx"];
const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions);
const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions);
export function getSupportedExtensions(options?: CompilerOptions): string[] {
return options && options.allowJs ? allSupportedExtensions : supportedTypeScriptExtensions;
@@ -1828,19 +1995,15 @@ namespace ts {
return path.substring(0, path.length - extension.length);
}
export function isJsxOrTsxExtension(ext: string): boolean {
return ext === ".jsx" || ext === ".tsx";
}
export function changeExtension<T extends string | Path>(path: T, newExtension: string): T {
return <T>(removeFileExtension(path) + newExtension);
}
export interface ObjectAllocator {
getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node;
getTokenConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token;
getIdentifierConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token;
getSourceFileConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => SourceFile;
getTokenConstructor(): new <TKind extends SyntaxKind>(kind: TKind, pos?: number, end?: number) => Token<TKind>;
getIdentifierConstructor(): new (kind: SyntaxKind.Identifier, pos?: number, end?: number) => Identifier;
getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos?: number, end?: number) => SourceFile;
getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol;
getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type;
getSignatureConstructor(): new (checker: TypeChecker) => Signature;
@@ -1852,11 +2015,11 @@ namespace ts {
this.declarations = undefined;
}
function Type(this: Type, checker: TypeChecker, flags: TypeFlags) {
function Type(this: Type, _checker: TypeChecker, flags: TypeFlags) {
this.flags = flags;
}
function Signature(checker: TypeChecker) {
function Signature() {
}
function Node(this: Node, kind: SyntaxKind, pos: number, end: number) {
@@ -1889,9 +2052,6 @@ namespace ts {
}
export namespace Debug {
declare var process: any;
declare var require: any;
export let currentAssertionLevel = AssertionLevel.None;
export function shouldAssert(level: AssertionLevel): boolean {
@@ -2027,4 +2187,33 @@ namespace ts {
// pos === undefined || pos === null || isNaN(pos) || pos < 0;
return !(pos >= 0);
}
/** True if an extension is one of the supported TypeScript extensions. */
export function extensionIsTypeScript(ext: Extension): boolean {
return ext <= Extension.LastTypeScriptExtension;
}
/**
* Gets the extension from a path.
* Path must have a valid extension.
*/
export function extensionFromPath(path: string): Extension {
if (fileExtensionIs(path, ".d.ts")) {
return Extension.Dts;
}
if (fileExtensionIs(path, ".ts")) {
return Extension.Ts;
}
if (fileExtensionIs(path, ".tsx")) {
return Extension.Tsx;
}
if (fileExtensionIs(path, ".js")) {
return Extension.Js;
}
if (fileExtensionIs(path, ".jsx")) {
return Extension.Jsx;
}
Debug.fail(`File ${path} has unknown extension.`);
return Extension.Js;
}
}
+10 -11
View File
@@ -63,7 +63,7 @@ namespace ts {
let isCurrentFileExternalModule: boolean;
let reportedDeclarationError = false;
let errorNameNode: DeclarationName;
const emitJsDocComments = compilerOptions.removeComments ? function (declaration: Node) { } : writeJsDocComments;
const emitJsDocComments = compilerOptions.removeComments ? noop : writeJsDocComments;
const emit = compilerOptions.stripInternal ? stripInternal : emitNode;
let noDeclare: boolean;
@@ -580,7 +580,7 @@ namespace ts {
writeAsynchronousModuleElements(nodes);
}
function getDefaultExportAccessibilityDiagnostic(diagnostic: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
function getDefaultExportAccessibilityDiagnostic(): SymbolAccessibilityDiagnostic {
return {
diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
errorNode: node
@@ -710,7 +710,7 @@ namespace ts {
}
writer.writeLine();
function getImportEntityNameVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
function getImportEntityNameVisibilityError(): SymbolAccessibilityDiagnostic {
return {
diagnosticMessage: Diagnostics.Import_declaration_0_is_using_private_name_1,
errorNode: node,
@@ -888,7 +888,7 @@ namespace ts {
writeLine();
enclosingDeclaration = prevEnclosingDeclaration;
function getTypeAliasDeclarationVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
function getTypeAliasDeclarationVisibilityError(): SymbolAccessibilityDiagnostic {
return {
diagnosticMessage: Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1,
errorNode: node.type,
@@ -955,7 +955,7 @@ namespace ts {
}
}
function getTypeParameterConstraintVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
function getTypeParameterConstraintVisibilityError(): SymbolAccessibilityDiagnostic {
// Type parameter constraints are named by user so we should always be able to name it
let diagnosticMessage: DiagnosticMessage;
switch (node.parent.kind) {
@@ -1029,7 +1029,7 @@ namespace ts {
resolver.writeBaseConstructorTypeOfClass(<ClassLikeDeclaration>enclosingDeclaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer);
}
function getHeritageClauseVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
function getHeritageClauseVisibilityError(): SymbolAccessibilityDiagnostic {
let diagnosticMessage: DiagnosticMessage;
// Heritage clause is written by user so it can always be named
if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
@@ -1121,7 +1121,7 @@ namespace ts {
writeLine();
}
function emitVariableDeclaration(node: VariableDeclaration) {
function emitVariableDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration) {
// If we are emitting property it isn't moduleElement and hence we already know it needs to be emitted
// so there is no check needed to see if declaration is visible
if (node.kind !== SyntaxKind.VariableDeclaration || resolver.isDeclarationVisible(node)) {
@@ -1136,7 +1136,7 @@ namespace ts {
// If optional property emit ? but in the case of parameterProperty declaration with "?" indicating optional parameter for the constructor
// we don't want to emit property declaration with "?"
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature ||
(node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(node))) && hasQuestionToken(node)) {
(node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(<ParameterDeclaration>node))) && hasQuestionToken(node)) {
write("?");
}
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) {
@@ -1626,8 +1626,7 @@ namespace ts {
}
}
function emitBindingElement(bindingElement: BindingElement) {
function emitBindingElement(bindingElement: BindingElement | OmittedExpression) {
if (bindingElement.kind === SyntaxKind.OmittedExpression) {
// If bindingElement is an omittedExpression (i.e. containing elision),
// we will emit blank space (although this may differ from users' original code,
@@ -1744,7 +1743,7 @@ namespace ts {
}
return addedBundledEmitReference;
function getDeclFileName(emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean) {
function getDeclFileName(emitFileNames: EmitFileNames, _sourceFiles: SourceFile[], isBundledEmit: boolean) {
// Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path
if (isBundledEmit && !addBundledFileReference) {
return;
+60 -7
View File
@@ -603,10 +603,6 @@
"category": "Error",
"code": 1194
},
"Catch clause variable name must be an identifier.": {
"category": "Error",
"code": 1195
},
"Catch clause variable cannot have a type annotation.": {
"category": "Error",
"code": 1196
@@ -1923,7 +1919,7 @@
"category": "Error",
"code": 2685
},
"Identifier '{0}' must be imported from a module": {
"'{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead.": {
"category": "Error",
"code": 2686
},
@@ -2697,7 +2693,7 @@
"category": "Message",
"code": 6099
},
"'package.json' does not have 'types' field.": {
"'package.json' does not have a 'types' or 'main' field.": {
"category": "Message",
"code": 6100
},
@@ -2845,7 +2841,7 @@
"category": "Message",
"code": 6136
},
"No types specified in 'package.json' but 'allowJs' is set, so returning 'main' value of '{0}'": {
"No types specified in 'package.json', so returning 'main' value of '{0}'": {
"category": "Message",
"code": 6137
},
@@ -2861,6 +2857,18 @@
"category": "Error",
"code": 6140
},
"Parse in strict mode and emit \"use strict\" for each source file": {
"category": "Message",
"code": 6141
},
"Module '{0}' was resolved to '{1}', but '--jsx' is not set.": {
"category": "Error",
"code": 6142
},
"Module '{0}' was resolved to '{1}', but '--allowJs' is not set.": {
"category": "Error",
"code": 6143
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
"code": 7005
@@ -2893,6 +2901,10 @@
"category": "Error",
"code": 7015
},
"Could not find a declaration file for module '{0}'. '{1}' implicitly has an 'any' type.": {
"category": "Error",
"code": 7016
},
"Index signature of object type implicitly has an 'any' type.": {
"category": "Error",
"code": 7017
@@ -2957,6 +2969,10 @@
"category": "Error",
"code": 7033
},
"Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined.": {
"category": "Error",
"code": 7034
},
"You cannot rename this element.": {
"category": "Error",
"code": 8000
@@ -3077,5 +3093,42 @@
"The path in an 'extends' options must be relative or rooted.": {
"category": "Error",
"code": 18001
},
"The 'files' list in config file '{0}' is empty.": {
"category": "Error",
"code": 18002
},
"No inputs were found in config file '{0}'. Specified 'include' paths were '{1}' and 'exclude' paths were '{2}'.": {
"category": "Error",
"code": 18003
},
"Add missing 'super()' call.": {
"category": "Message",
"code": 90001
},
"Make 'super()' call the first statement in the constructor.": {
"category": "Message",
"code": 90002
},
"Change 'extends' to 'implements'": {
"category": "Message",
"code": 90003
},
"Remove unused identifiers": {
"category": "Message",
"code": 90004
},
"Implement interface on reference": {
"category": "Message",
"code": 90005
},
"Implement interface on class": {
"category": "Message",
"code": 90006
},
"Implement inherited abstract class": {
"category": "Message",
"code": 90007
}
}
+46 -22
View File
@@ -14,7 +14,7 @@ namespace ts {
}
const id = (s: SourceFile) => s;
const nullTransformers: Transformer[] = [ctx => id];
const nullTransformers: Transformer[] = [_ => id];
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean): EmitResult {
@@ -68,7 +68,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
@@ -504,15 +504,29 @@ const _super = (function (geti, seti) {
// Contextual keywords
case SyntaxKind.AbstractKeyword:
case SyntaxKind.AsKeyword:
case SyntaxKind.AnyKeyword:
case SyntaxKind.AsyncKeyword:
case SyntaxKind.AwaitKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.ConstructorKeyword:
case SyntaxKind.DeclareKeyword:
case SyntaxKind.NumberKeyword:
case SyntaxKind.GetKeyword:
case SyntaxKind.IsKeyword:
case SyntaxKind.ModuleKeyword:
case SyntaxKind.NamespaceKeyword:
case SyntaxKind.NeverKeyword:
case SyntaxKind.ReadonlyKeyword:
case SyntaxKind.RequireKeyword:
case SyntaxKind.NumberKeyword:
case SyntaxKind.SetKeyword:
case SyntaxKind.StringKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.TypeKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.FromKeyword:
case SyntaxKind.GlobalKeyword:
case SyntaxKind.OfKeyword:
writeTokenText(kind);
return;
@@ -579,7 +593,7 @@ const _super = (function (geti, seti) {
case SyntaxKind.ExpressionWithTypeArguments:
return emitExpressionWithTypeArguments(<ExpressionWithTypeArguments>node);
case SyntaxKind.ThisType:
return emitThisType(<ThisTypeNode>node);
return emitThisType();
case SyntaxKind.LiteralType:
return emitLiteralType(<LiteralTypeNode>node);
@@ -595,7 +609,7 @@ const _super = (function (geti, seti) {
case SyntaxKind.TemplateSpan:
return emitTemplateSpan(<TemplateSpan>node);
case SyntaxKind.SemicolonClassElement:
return emitSemicolonClassElement(<SemicolonClassElement>node);
return emitSemicolonClassElement();
// Statements
case SyntaxKind.Block:
@@ -603,7 +617,7 @@ const _super = (function (geti, seti) {
case SyntaxKind.VariableStatement:
return emitVariableStatement(<VariableStatement>node);
case SyntaxKind.EmptyStatement:
return emitEmptyStatement(<EmptyStatement>node);
return emitEmptyStatement();
case SyntaxKind.ExpressionStatement:
return emitExpressionStatement(<ExpressionStatement>node);
case SyntaxKind.IfStatement:
@@ -655,7 +669,7 @@ const _super = (function (geti, seti) {
case SyntaxKind.ModuleDeclaration:
return emitModuleDeclaration(<ModuleDeclaration>node);
case SyntaxKind.ModuleBlock:
return emitModuleBlock(<Block>node);
return emitModuleBlock(<ModuleBlock>node);
case SyntaxKind.CaseBlock:
return emitCaseBlock(<CaseBlock>node);
case SyntaxKind.ImportEqualsDeclaration:
@@ -1000,7 +1014,7 @@ const _super = (function (geti, seti) {
write(";");
}
function emitSemicolonClassElement(node: SemicolonClassElement) {
function emitSemicolonClassElement() {
write(";");
}
@@ -1070,7 +1084,7 @@ const _super = (function (geti, seti) {
write(")");
}
function emitThisType(node: ThisTypeNode) {
function emitThisType() {
write("this");
}
@@ -1198,12 +1212,14 @@ const _super = (function (geti, seti) {
function emitCallExpression(node: CallExpression) {
emitExpression(node.expression);
emitTypeArguments(node, node.typeArguments);
emitExpressionList(node, node.arguments, ListFormat.CallExpressionArguments);
}
function emitNewExpression(node: NewExpression) {
write("new ");
emitExpression(node.expression);
emitTypeArguments(node, node.typeArguments);
emitExpressionList(node, node.arguments, ListFormat.NewExpressionArguments);
}
@@ -1381,7 +1397,7 @@ const _super = (function (geti, seti) {
// Statements
//
function emitBlock(node: Block, format?: ListFormat) {
function emitBlock(node: Block) {
if (isSingleLineEmptyBlock(node)) {
writeToken(SyntaxKind.OpenBraceToken, node.pos, /*contextNode*/ node);
write(" ");
@@ -1394,7 +1410,7 @@ const _super = (function (geti, seti) {
}
}
function emitBlockStatements(node: Block) {
function emitBlockStatements(node: BlockLike) {
if (getEmitFlags(node) & EmitFlags.SingleLine) {
emitList(node, node.statements, ListFormat.SingleLineBlockStatements);
}
@@ -1409,7 +1425,7 @@ const _super = (function (geti, seti) {
write(";");
}
function emitEmptyStatement(node: EmptyStatement) {
function emitEmptyStatement() {
write(";");
}
@@ -1575,6 +1591,7 @@ const _super = (function (geti, seti) {
function emitVariableDeclaration(node: VariableDeclaration) {
emit(node.name);
emitWithPrefix(": ", node.type);
emitExpressionWithPrefix(" = ", node.initializer);
}
@@ -1606,13 +1623,13 @@ const _super = (function (geti, seti) {
if (getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) {
emitSignatureHead(node);
emitBlockFunctionBody(node, body);
emitBlockFunctionBody(body);
}
else {
const savedTempFlags = tempFlags;
tempFlags = 0;
emitSignatureHead(node);
emitBlockFunctionBody(node, body);
emitBlockFunctionBody(body);
tempFlags = savedTempFlags;
}
@@ -1639,7 +1656,7 @@ const _super = (function (geti, seti) {
emitWithPrefix(": ", node.type);
}
function shouldEmitBlockFunctionBodyOnSingleLine(parentNode: Node, body: Block) {
function shouldEmitBlockFunctionBodyOnSingleLine(body: Block) {
// We must emit a function body as a single-line body in the following case:
// * The body has NodeEmitFlags.SingleLine specified.
@@ -1677,12 +1694,12 @@ const _super = (function (geti, seti) {
return true;
}
function emitBlockFunctionBody(parentNode: Node, body: Block) {
function emitBlockFunctionBody(body: Block) {
write(" {");
increaseIndent();
emitBodyWithDetachedComments(body, body.statements,
shouldEmitBlockFunctionBodyOnSingleLine(parentNode, body)
shouldEmitBlockFunctionBodyOnSingleLine(body)
? emitBlockFunctionBodyOnSingleLine
: emitBlockFunctionBodyWorker);
@@ -1795,7 +1812,7 @@ const _super = (function (geti, seti) {
}
function emitModuleBlock(node: ModuleBlock) {
if (isSingleLineEmptyBlock(node)) {
if (isEmptyBlock(node)) {
write("{ }");
}
else {
@@ -2165,7 +2182,7 @@ const _super = (function (geti, seti) {
// Only Emit __extends function when target ES5.
// For target ES6 and above, we can emit classDeclaration as is.
if ((languageVersion < ScriptTarget.ES6) && (!extendsEmitted && node.flags & NodeFlags.HasClassExtends)) {
if ((languageVersion < ScriptTarget.ES2015) && (!extendsEmitted && node.flags & NodeFlags.HasClassExtends)) {
writeLines(extendsHelper);
extendsEmitted = true;
helpersEmitted = true;
@@ -2192,9 +2209,12 @@ const _super = (function (geti, seti) {
helpersEmitted = true;
}
if (!awaiterEmitted && node.flags & NodeFlags.HasAsyncFunctions) {
// Only emit __awaiter function when target ES5/ES6.
// Only emit __generator function when target ES5.
// For target ES2017 and above, we can emit async/await as is.
if ((languageVersion < ScriptTarget.ES2017) && (!awaiterEmitted && node.flags & NodeFlags.HasAsyncFunctions)) {
writeLines(awaiterHelper);
if (languageVersion < ScriptTarget.ES6) {
if (languageVersion < ScriptTarget.ES2015) {
writeLines(generatorHelper);
}
@@ -2615,7 +2635,11 @@ const _super = (function (geti, seti) {
function isSingleLineEmptyBlock(block: Block) {
return !block.multiLine
&& block.statements.length === 0
&& isEmptyBlock(block);
}
function isEmptyBlock(block: BlockLike) {
return block.statements.length === 0
&& rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile);
}
+233 -87
View File
@@ -105,22 +105,23 @@ namespace ts {
export function createLiteral(textSource: StringLiteral | Identifier, location?: TextRange): StringLiteral;
export function createLiteral(value: string, location?: TextRange): StringLiteral;
export function createLiteral(value: number, location?: TextRange): NumericLiteral;
export function createLiteral(value: boolean, location?: TextRange): BooleanLiteral;
export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression;
export function createLiteral(value: string | number | boolean | StringLiteral | Identifier, location?: TextRange): PrimaryExpression {
if (typeof value === "number") {
const node = <LiteralExpression>createNode(SyntaxKind.NumericLiteral, location, /*flags*/ undefined);
const node = <NumericLiteral>createNode(SyntaxKind.NumericLiteral, location, /*flags*/ undefined);
node.text = value.toString();
return node;
}
else if (typeof value === "boolean") {
return <PrimaryExpression>createNode(value ? SyntaxKind.TrueKeyword : SyntaxKind.FalseKeyword, location, /*flags*/ undefined);
return <BooleanLiteral>createNode(value ? SyntaxKind.TrueKeyword : SyntaxKind.FalseKeyword, location, /*flags*/ undefined);
}
else if (typeof value === "string") {
const node = <StringLiteral>createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined);
node.text = value;
return node;
}
else {
else if (value) {
const node = <StringLiteral>createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined);
node.textSourceNode = value;
node.text = value.text;
@@ -187,8 +188,8 @@ namespace ts {
// Punctuation
export function createToken(token: SyntaxKind) {
return createNode(token);
export function createToken<TKind extends SyntaxKind>(token: TKind) {
return <Token<TKind>>createNode(token);
}
// Reserved words
@@ -225,20 +226,7 @@ namespace ts {
// Signature elements
export function createParameter(name: string | Identifier | BindingPattern, initializer?: Expression, location?: TextRange) {
return createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
name,
/*questionToken*/ undefined,
/*type*/ undefined,
initializer,
location
);
}
export function createParameterDeclaration(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: Node, name: string | Identifier | BindingPattern, questionToken: Node, type: TypeNode, initializer: Expression, location?: TextRange, flags?: NodeFlags) {
export function createParameter(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression, location?: TextRange, flags?: NodeFlags) {
const node = <ParameterDeclaration>createNode(SyntaxKind.Parameter, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
@@ -250,9 +238,9 @@ namespace ts {
return node;
}
export function updateParameterDeclaration(node: ParameterDeclaration, decorators: Decorator[], modifiers: Modifier[], name: BindingName, type: TypeNode, initializer: Expression) {
export function updateParameter(node: ParameterDeclaration, decorators: Decorator[], modifiers: Modifier[], name: BindingName, type: TypeNode, initializer: Expression) {
if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.type !== type || node.initializer !== initializer) {
return updateNode(createParameterDeclaration(decorators, modifiers, node.dotDotDotToken, name, node.questionToken, type, initializer, /*location*/ node, /*flags*/ node.flags), node);
return updateNode(createParameter(decorators, modifiers, node.dotDotDotToken, name, node.questionToken, type, initializer, /*location*/ node, /*flags*/ node.flags), node);
}
return node;
@@ -260,7 +248,7 @@ namespace ts {
// Type members
export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: Node, type: TypeNode, initializer: Expression, location?: TextRange) {
export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange) {
const node = <PropertyDeclaration>createNode(SyntaxKind.PropertyDeclaration, location);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
@@ -278,7 +266,7 @@ namespace ts {
return node;
}
export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: Node, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
const node = <MethodDeclaration>createNode(SyntaxKind.MethodDeclaration, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
@@ -381,7 +369,7 @@ namespace ts {
return node;
}
export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: Node, name: string | BindingName, initializer?: Expression, location?: TextRange) {
export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: DotDotDotToken, name: string | BindingName, initializer?: Expression, location?: TextRange) {
const node = <BindingElement>createNode(SyntaxKind.BindingElement, location);
node.propertyName = typeof propertyName === "string" ? createIdentifier(propertyName) : propertyName;
node.dotDotDotToken = dotDotDotToken;
@@ -497,14 +485,14 @@ namespace ts {
return node;
}
export function createTaggedTemplate(tag: Expression, template: Template, location?: TextRange) {
export function createTaggedTemplate(tag: Expression, template: TemplateLiteral, location?: TextRange) {
const node = <TaggedTemplateExpression>createNode(SyntaxKind.TaggedTemplateExpression, location);
node.tag = parenthesizeForAccess(tag);
node.template = template;
return node;
}
export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: Template) {
export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral) {
if (node.tag !== tag || node.template !== template) {
return updateNode(createTaggedTemplate(tag, template, node), node);
}
@@ -524,9 +512,9 @@ namespace ts {
return node;
}
export function createFunctionExpression(asteriskToken: Node, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
export function createFunctionExpression(modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
const node = <FunctionExpression>createNode(SyntaxKind.FunctionExpression, location, flags);
node.modifiers = undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.asteriskToken = asteriskToken;
node.name = typeof name === "string" ? createIdentifier(name) : name;
node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined;
@@ -536,20 +524,20 @@ namespace ts {
return node;
}
export function updateFunctionExpression(node: FunctionExpression, name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
if (node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) {
return updateNode(createFunctionExpression(node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node);
export function updateFunctionExpression(node: FunctionExpression, modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
if (node.name !== name || node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) {
return updateNode(createFunctionExpression(modifiers, node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node);
}
return node;
}
export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: Node, body: ConciseBody, location?: TextRange, flags?: NodeFlags) {
export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody, location?: TextRange, flags?: NodeFlags) {
const node = <ArrowFunction>createNode(SyntaxKind.ArrowFunction, location, flags);
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined;
node.parameters = createNodeArray(parameters);
node.type = type;
node.equalsGreaterThanToken = equalsGreaterThanToken || createNode(SyntaxKind.EqualsGreaterThanToken);
node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(SyntaxKind.EqualsGreaterThanToken);
node.body = parenthesizeConciseBody(body);
return node;
}
@@ -613,7 +601,7 @@ namespace ts {
return node;
}
export function createPrefix(operator: SyntaxKind, operand: Expression, location?: TextRange) {
export function createPrefix(operator: PrefixUnaryOperator, operand: Expression, location?: TextRange) {
const node = <PrefixUnaryExpression>createNode(SyntaxKind.PrefixUnaryExpression, location);
node.operator = operator;
node.operand = parenthesizePrefixOperand(operand);
@@ -627,7 +615,7 @@ namespace ts {
return node;
}
export function createPostfix(operand: Expression, operator: SyntaxKind, location?: TextRange) {
export function createPostfix(operand: Expression, operator: PostfixUnaryOperator, location?: TextRange) {
const node = <PostfixUnaryExpression>createNode(SyntaxKind.PostfixUnaryExpression, location);
node.operand = parenthesizePostfixOperand(operand);
node.operator = operator;
@@ -641,8 +629,8 @@ namespace ts {
return node;
}
export function createBinary(left: Expression, operator: SyntaxKind | Node, right: Expression, location?: TextRange) {
const operatorToken = typeof operator === "number" ? createSynthesizedNode(operator) : operator;
export function createBinary(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression, location?: TextRange) {
const operatorToken = typeof operator === "number" ? createToken(operator) : operator;
const operatorKind = operatorToken.kind;
const node = <BinaryExpression>createNode(SyntaxKind.BinaryExpression, location);
node.left = parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined);
@@ -658,7 +646,7 @@ namespace ts {
return node;
}
export function createConditional(condition: Expression, questionToken: Node, whenTrue: Expression, colonToken: Node, whenFalse: Expression, location?: TextRange) {
export function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression, location?: TextRange) {
const node = <ConditionalExpression>createNode(SyntaxKind.ConditionalExpression, location);
node.condition = condition;
node.questionToken = questionToken;
@@ -675,21 +663,21 @@ namespace ts {
return node;
}
export function createTemplateExpression(head: TemplateLiteralFragment, templateSpans: TemplateSpan[], location?: TextRange) {
export function createTemplateExpression(head: TemplateHead, templateSpans: TemplateSpan[], location?: TextRange) {
const node = <TemplateExpression>createNode(SyntaxKind.TemplateExpression, location);
node.head = head;
node.templateSpans = createNodeArray(templateSpans);
return node;
}
export function updateTemplateExpression(node: TemplateExpression, head: TemplateLiteralFragment, templateSpans: TemplateSpan[]) {
export function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: TemplateSpan[]) {
if (node.head !== head || node.templateSpans !== templateSpans) {
return updateNode(createTemplateExpression(head, templateSpans, node), node);
}
return node;
}
export function createYield(asteriskToken: Node, expression: Expression, location?: TextRange) {
export function createYield(asteriskToken: AsteriskToken, expression: Expression, location?: TextRange) {
const node = <YieldExpression>createNode(SyntaxKind.YieldExpression, location);
node.asteriskToken = asteriskToken;
node.expression = expression;
@@ -756,14 +744,14 @@ namespace ts {
// Misc
export function createTemplateSpan(expression: Expression, literal: TemplateLiteralFragment, location?: TextRange) {
export function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail, location?: TextRange) {
const node = <TemplateSpan>createNode(SyntaxKind.TemplateSpan, location);
node.expression = expression;
node.literal = literal;
return node;
}
export function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateLiteralFragment) {
export function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail) {
if (node.expression !== expression || node.literal !== literal) {
return updateNode(createTemplateSpan(expression, literal, node), node);
}
@@ -932,14 +920,14 @@ namespace ts {
return node;
}
export function updateForOf(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement) {
export function updateForOf(node: ForOfStatement, initializer: ForInitializer, expression: Expression, statement: Statement) {
if (node.initializer !== initializer || node.expression !== expression || node.statement !== statement) {
return updateNode(createForOf(initializer, expression, statement, node), node);
}
return node;
}
export function createContinue(label?: Identifier, location?: TextRange): BreakStatement {
export function createContinue(label?: Identifier, location?: TextRange): ContinueStatement {
const node = <ContinueStatement>createNode(SyntaxKind.ContinueStatement, location);
if (label) {
node.label = label;
@@ -1065,7 +1053,7 @@ namespace ts {
return node;
}
export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: Node, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
const node = <FunctionDeclaration>createNode(SyntaxKind.FunctionDeclaration, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
@@ -1473,6 +1461,28 @@ namespace ts {
return node;
}
/**
* Creates a synthetic element to act as a placeholder for the end of an emitted declaration in
* order to properly emit exports.
*/
export function createEndOfDeclarationMarker(original: Node) {
const node = <EndOfDeclarationMarker>createNode(SyntaxKind.EndOfDeclarationMarker);
node.emitNode = {};
node.original = original;
return node;
}
/**
* Creates a synthetic element to act as a placeholder for the beginning of a merged declaration in
* order to properly emit exports.
*/
export function createMergeDeclarationMarker(original: Node) {
const node = <MergeDeclarationMarker>createNode(SyntaxKind.MergeDeclarationMarker);
node.emitNode = {};
node.original = original;
return node;
}
/**
* Creates a synthetic expression to act as a placeholder for a not-emitted expression in
* order to preserve comments or sourcemap positions.
@@ -1556,18 +1566,6 @@ namespace ts {
}
}
export function createRestParameter(name: string | Identifier) {
return createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createSynthesizedNode(SyntaxKind.DotDotDotToken),
name,
/*questionToken*/ undefined,
/*type*/ undefined,
/*initializer*/ undefined
);
}
export function createFunctionCall(func: Expression, thisArg: Expression, argumentsList: Expression[], location?: TextRange) {
return createCall(
createPropertyAccess(func, "call"),
@@ -1624,7 +1622,9 @@ namespace ts {
// flag and setting a parent node.
const react = createIdentifier(reactNamespace || "React");
react.flags &= ~NodeFlags.Synthesized;
react.parent = parent;
// Set the parent that is in parse tree
// this makes sure that parent chain is intact for checker to traverse complete scope tree
react.parent = getParseTreeNode(parent);
return react;
}
@@ -1661,6 +1661,18 @@ namespace ts {
);
}
export function createExportDefault(expression: Expression) {
return createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, expression);
}
export function createExternalModuleExport(exportName: Identifier) {
return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(exportName)]));
}
export function createLetStatement(name: Identifier, initializer: Expression, location?: TextRange) {
return createVariableStatement(/*modifiers*/ undefined, createLetDeclarationList([createVariableDeclaration(name, /*type*/ undefined, initializer)]), location);
}
export function createLetDeclarationList(declarations: VariableDeclaration[], location?: TextRange) {
return createVariableDeclarationList(declarations, location, NodeFlags.Let);
}
@@ -1735,7 +1747,8 @@ namespace ts {
export function createAwaiterHelper(externalHelpersModuleName: Identifier | undefined, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) {
const generatorFunc = createFunctionExpression(
createNode(SyntaxKind.AsteriskToken),
/*modifiers*/ undefined,
createToken(SyntaxKind.AsteriskToken),
/*name*/ undefined,
/*typeParameters*/ undefined,
/*parameters*/ [],
@@ -1779,13 +1792,10 @@ namespace ts {
return createArrowFunction(
/*modifiers*/ undefined,
/*typeParameters*/ undefined,
[createParameter("name")],
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "name")],
/*type*/ undefined,
/*equalsGreaterThanToken*/ undefined,
createElementAccess(
target,
createIdentifier("name")
)
createToken(SyntaxKind.EqualsGreaterThanToken),
createElementAccess(target, createIdentifier("name"))
);
}
@@ -1795,11 +1805,11 @@ namespace ts {
/*modifiers*/ undefined,
/*typeParameters*/ undefined,
[
createParameter("name"),
createParameter("value")
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "name"),
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "value")
],
/*type*/ undefined,
/*equalsGreaterThanToken*/ undefined,
createToken(SyntaxKind.EqualsGreaterThanToken),
createAssignment(
createElementAccess(
target,
@@ -1851,7 +1861,7 @@ namespace ts {
/*decorators*/ undefined,
/*modifiers*/ undefined,
"value",
[createParameter("v")],
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "v")],
createBlock([
createStatement(
createCall(
@@ -1871,9 +1881,9 @@ namespace ts {
createArrowFunction(
/*modifiers*/ undefined,
/*typeParameters*/ undefined,
[createParameter("name")],
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "name")],
/*type*/ undefined,
/*equalsGreaterThanToken*/ undefined,
createToken(SyntaxKind.EqualsGreaterThanToken),
createLogicalOr(
createElementAccess(
createIdentifier("cache"),
@@ -1908,12 +1918,13 @@ namespace ts {
createCall(
createParen(
createFunctionExpression(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
[
createParameter("geti"),
createParameter("seti")
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "geti"),
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "seti")
],
/*type*/ undefined,
createBlock([
@@ -1983,7 +1994,7 @@ namespace ts {
}
else if (callee.kind === SyntaxKind.SuperKeyword) {
thisArg = createThis();
target = languageVersion < ScriptTarget.ES6 ? createIdentifier("_super", /*location*/ callee) : <PrimaryExpression>callee;
target = languageVersion < ScriptTarget.ES2015 ? createIdentifier("_super", /*location*/ callee) : <PrimaryExpression>callee;
}
else {
switch (callee.kind) {
@@ -2089,6 +2100,7 @@ namespace ts {
const properties: ObjectLiteralElementLike[] = [];
if (getAccessor) {
const getterFunction = createFunctionExpression(
getAccessor.modifiers,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
@@ -2104,6 +2116,7 @@ namespace ts {
if (setAccessor) {
const setterFunction = createFunctionExpression(
setAccessor.modifiers,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
@@ -2170,6 +2183,7 @@ namespace ts {
createMemberAccessForPropertyName(receiver, method.name, /*location*/ method.name),
setOriginalNode(
createFunctionExpression(
method.modifiers,
method.asteriskToken,
/*name*/ undefined,
/*typeParameters*/ undefined,
@@ -2187,6 +2201,107 @@ namespace ts {
);
}
/**
* Gets the local name of a declaration. This is primarily used for declarations that can be
* referred to by name in the declaration's immediate scope (classes, enums, namespaces). A
* local name will *never* be prefixed with an module or namespace export modifier like
* "exports." when emitted as an expression.
*
* @param node The declaration.
* @param allowComments A value indicating whether comments may be emitted for the name.
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
*/
export function getLocalName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) {
return getName(node, allowComments, allowSourceMaps, EmitFlags.LocalName);
}
/**
* Gets whether an identifier should only be referred to by its local name.
*/
export function isLocalName(node: Identifier) {
return (getEmitFlags(node) & EmitFlags.LocalName) !== 0;
}
/**
* Gets the export name of a declaration. This is primarily used for declarations that can be
* referred to by name in the declaration's immediate scope (classes, enums, namespaces). An
* export name will *always* be prefixed with an module or namespace export modifier like
* `"exports."` when emitted as an expression if the name points to an exported symbol.
*
* @param node The declaration.
* @param allowComments A value indicating whether comments may be emitted for the name.
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
*/
export function getExportName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier {
return getName(node, allowComments, allowSourceMaps, EmitFlags.ExportName);
}
/**
* Gets whether an identifier should only be referred to by its export representation if the
* name points to an exported symbol.
*/
export function isExportName(node: Identifier) {
return (getEmitFlags(node) & EmitFlags.ExportName) !== 0;
}
/**
* Gets the name of a declaration for use in declarations.
*
* @param node The declaration.
* @param allowComments A value indicating whether comments may be emitted for the name.
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
*/
export function getDeclarationName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) {
return getName(node, allowComments, allowSourceMaps);
}
function getName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
if (node.name && isIdentifier(node.name) && !isGeneratedIdentifier(node.name)) {
const name = getMutableClone(node.name);
emitFlags |= getEmitFlags(node.name);
if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap;
if (!allowComments) emitFlags |= EmitFlags.NoComments;
if (emitFlags) setEmitFlags(name, emitFlags);
return name;
}
return getGeneratedNameForNode(node);
}
/**
* Gets the exported name of a declaration for use in expressions.
*
* An exported name will *always* be prefixed with an module or namespace export modifier like
* "exports." if the name points to an exported symbol.
*
* @param ns The namespace identifier.
* @param node The declaration.
* @param allowComments A value indicating whether comments may be emitted for the name.
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
*/
export function getExternalModuleOrNamespaceExportName(ns: Identifier | undefined, node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier | PropertyAccessExpression {
if (ns && hasModifier(node, ModifierFlags.Export)) {
return getNamespaceMemberName(ns, getName(node), allowComments, allowSourceMaps);
}
return getExportName(node, allowComments, allowSourceMaps);
}
/**
* Gets a namespace-qualified name for use in expressions.
*
* @param ns The namespace identifier.
* @param name The name.
* @param allowComments A value indicating whether comments may be emitted for the name.
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
*/
export function getNamespaceMemberName(ns: Identifier, name: Identifier, allowComments?: boolean, allowSourceMaps?: boolean): PropertyAccessExpression {
const qualifiedName = createPropertyAccess(ns, nodeIsSynthesized(name) ? name : getSynthesizedClone(name), /*location*/ name);
let emitFlags: EmitFlags;
if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap;
if (!allowComments) emitFlags |= EmitFlags.NoComments;
if (emitFlags) setEmitFlags(qualifiedName, emitFlags);
return qualifiedName;
}
// Utilities
function isUseStrictPrologue(node: ExpressionStatement): boolean {
@@ -2205,7 +2320,7 @@ namespace ts {
* @param visitor: Optional callback used to visit any custom prologue directives.
*/
export function addPrologueDirectives(target: Statement[], source: Statement[], ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult<Node>): number {
Debug.assert(target.length === 0, "PrologueDirectives should be at the first statement in the target statements array");
Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array");
let foundUseStrict = false;
let statementOffset = 0;
const numStatements = source.length;
@@ -2218,22 +2333,53 @@ namespace ts {
target.push(statement);
}
else {
if (ensureUseStrict && !foundUseStrict) {
target.push(startOnNewLine(createStatement(createLiteral("use strict"))));
foundUseStrict = true;
}
if (getEmitFlags(statement) & EmitFlags.CustomPrologue) {
target.push(visitor ? visitNode(statement, visitor, isStatement) : statement);
}
else {
break;
}
break;
}
statementOffset++;
}
if (ensureUseStrict && !foundUseStrict) {
target.push(startOnNewLine(createStatement(createLiteral("use strict"))));
}
while (statementOffset < numStatements) {
const statement = source[statementOffset];
if (getEmitFlags(statement) & EmitFlags.CustomPrologue) {
target.push(visitor ? visitNode(statement, visitor, isStatement) : statement);
}
else {
break;
}
statementOffset++;
}
return statementOffset;
}
/**
* Ensures "use strict" directive is added
*
* @param node source file
*/
export function ensureUseStrict(node: SourceFile): SourceFile {
let foundUseStrict = false;
for (const statement of node.statements) {
if (isPrologueDirective(statement)) {
if (isUseStrictPrologue(statement as ExpressionStatement)) {
foundUseStrict = true;
break;
}
}
else {
break;
}
}
if (!foundUseStrict) {
const statements: Statement[] = [];
statements.push(startOnNewLine(createStatement(createLiteral("use strict"))));
// add "use strict" as the first statement
return updateSourceFileNode(node, statements.concat(node.statements));
}
return node;
}
/**
* Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended
* order of operations.
@@ -2909,4 +3055,4 @@ namespace ts {
function tryGetModuleNameFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) {
return tryGetModuleNameFromFile(resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions);
}
}
}
+212 -161
View File
@@ -2,39 +2,86 @@
/// <reference path="diagnosticInformationMap.generated.ts" />
namespace ts {
/* @internal */
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage): void {
function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
function trace(host: ModuleResolutionHost): void {
host.trace(formatMessage.apply(undefined, arguments));
}
/* @internal */
export function isTraceEnabled(compilerOptions: CompilerOptions, host: ModuleResolutionHost): boolean {
function isTraceEnabled(compilerOptions: CompilerOptions, host: ModuleResolutionHost): boolean {
return compilerOptions.traceResolution && host.trace !== undefined;
}
/* @internal */
export function createResolvedModule(resolvedFileName: string, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
return { resolvedModule: resolvedFileName ? { resolvedFileName, isExternalLibraryImport } : undefined, failedLookupLocations };
/**
* Result of trying to resolve a module.
* At least one of `ts` and `js` should be defined, or the whole thing should be `undefined`.
*/
interface Resolved {
path: string;
extension: Extension;
}
/**
* Kinds of file that we are currently looking for.
* Typically there is one pass with Extensions.TypeScript, then a second pass with Extensions.JavaScript.
*/
const enum Extensions {
TypeScript, /** '.ts', '.tsx', or '.d.ts' */
JavaScript, /** '.js' or '.jsx' */
DtsOnly /** Only '.d.ts' */
}
/** Used with `Extensions.DtsOnly` to extract the path from TypeScript results. */
function resolvedTypeScriptOnly(resolved: Resolved | undefined): string | undefined {
if (!resolved) {
return undefined;
}
Debug.assert(extensionIsTypeScript(resolved.extension));
return resolved.path;
}
/** Create Resolved from a file with unknown extension. */
function resolvedFromAnyFile(path: string): Resolved | undefined {
return { path, extension: extensionFromPath(path) };
}
/** Adds `isExernalLibraryImport` to a Resolved to get a ResolvedModule. */
function resolvedModuleFromResolved({ path, extension }: Resolved, isExternalLibraryImport: boolean): ResolvedModuleFull {
return { resolvedFileName: path, extension, isExternalLibraryImport };
}
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
return { resolvedModule: resolved && resolvedModuleFromResolved(resolved, isExternalLibraryImport), failedLookupLocations };
}
function moduleHasNonRelativeName(moduleName: string): boolean {
return !(isRootedDiskPath(moduleName) || isExternalModuleNameRelative(moduleName));
}
/* @internal */
export interface ModuleResolutionState {
interface ModuleResolutionState {
host: ModuleResolutionHost;
compilerOptions: CompilerOptions;
// We only use this subset of the compiler options.
compilerOptions: { rootDirs?: string[], baseUrl?: string, paths?: MapLike<string[]> };
traceEnabled: boolean;
// skip .tsx files if jsx is not enabled
skipTsx: boolean;
}
function tryReadTypesSection(packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string {
function tryReadTypesSection(extensions: Extensions, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string {
const jsonContent = readJson(packageJsonPath, state.host);
switch (extensions) {
case Extensions.DtsOnly:
case Extensions.TypeScript:
return tryReadFromField("typings") || tryReadFromField("types");
case Extensions.JavaScript:
if (typeof jsonContent.main === "string") {
if (state.traceEnabled) {
trace(state.host, Diagnostics.No_types_specified_in_package_json_so_returning_main_value_of_0, jsonContent.main);
}
return normalizePath(combinePaths(baseDirectory, jsonContent.main));
}
return undefined;
}
function tryReadFromField(fieldName: string) {
if (hasProperty(jsonContent, fieldName)) {
const typesFile = (<any>jsonContent)[fieldName];
@@ -52,21 +99,6 @@ namespace ts {
}
}
}
const typesFilePath = tryReadFromField("typings") || tryReadFromField("types");
if (typesFilePath) {
return typesFilePath;
}
// Use the main module for inferring types if no types package specified and the allowJs is set
if (state.compilerOptions.allowJs && jsonContent.main && typeof jsonContent.main === "string") {
if (state.traceEnabled) {
trace(state.host, Diagnostics.No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0, jsonContent.main);
}
const mainFilePath = normalizePath(combinePaths(baseDirectory, jsonContent.main));
return mainFilePath;
}
return undefined;
}
function readJson(path: string, host: ModuleResolutionHost): { typings?: string, types?: string, main?: string } {
@@ -80,8 +112,6 @@ namespace ts {
}
}
const typeReferenceExtensions = [".d.ts"];
export function getEffectiveTypeRoots(options: CompilerOptions, host: { directoryExists?: (directoryName: string) => boolean, getCurrentDirectory?: () => string }): string[] | undefined {
if (options.typeRoots) {
return options.typeRoots;
@@ -132,12 +162,11 @@ namespace ts {
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
* is assumed to be the same as root directory of the project.
*/
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
const traceEnabled = isTraceEnabled(options, host);
const moduleResolutionState: ModuleResolutionState = {
compilerOptions: options,
host: host,
skipTsx: true,
traceEnabled
};
@@ -168,19 +197,20 @@ namespace ts {
if (traceEnabled) {
trace(host, Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", "));
}
const primarySearchPaths = typeRoots;
for (const typeRoot of primarySearchPaths) {
for (const typeRoot of typeRoots) {
const candidate = combinePaths(typeRoot, typeReferenceDirectiveName);
const candidateDirectory = getDirectoryPath(candidate);
const resolvedFile = loadNodeModuleFromDirectory(typeReferenceExtensions, candidate, failedLookupLocations,
!directoryProbablyExists(candidateDirectory, host), moduleResolutionState);
if (resolvedFile) {
const resolved = resolvedTypeScriptOnly(
loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate, failedLookupLocations,
!directoryProbablyExists(candidateDirectory, host), moduleResolutionState));
if (resolved) {
if (traceEnabled) {
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFile, true);
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved, true);
}
return {
resolvedTypeReferenceDirective: { primary: true, resolvedFileName: resolvedFile },
resolvedTypeReferenceDirective: { primary: true, resolvedFileName: resolved },
failedLookupLocations
};
}
@@ -193,17 +223,14 @@ namespace ts {
}
let resolvedFile: string;
let initialLocationForSecondaryLookup: string;
if (containingFile) {
initialLocationForSecondaryLookup = getDirectoryPath(containingFile);
}
const initialLocationForSecondaryLookup = containingFile && getDirectoryPath(containingFile);
if (initialLocationForSecondaryLookup !== undefined) {
// check secondary locations
if (traceEnabled) {
trace(host, Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup);
}
resolvedFile = loadModuleFromNodeModules(typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState, /*checkOneLevel*/ false);
resolvedFile = resolvedTypeScriptOnly(loadModuleFromNodeModules(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState, /*checkOneLevel*/ false));
if (traceEnabled) {
if (resolvedFile) {
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFile, false);
@@ -219,9 +246,7 @@ namespace ts {
}
}
return {
resolvedTypeReferenceDirective: resolvedFile
? { primary: false, resolvedFileName: resolvedFile }
: undefined,
resolvedTypeReferenceDirective: resolvedFile ? { primary: false, resolvedFileName: resolvedFile } : undefined,
failedLookupLocations
};
}
@@ -313,7 +338,7 @@ namespace ts {
* 'typings' entry or file 'index' with some supported extension
* - Classic loader will only try to interpret '/a/b/c' as file.
*/
type ResolutionKindSpecificLoader = (candidate: string, extensions: string[], failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState) => string;
type ResolutionKindSpecificLoader = (extensions: Extensions, candidate: string, failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState) => Resolved | undefined;
/**
* Any module resolution kind can be augmented with optional settings: 'baseUrl', 'paths' and 'rootDirs' - they are used to
@@ -375,19 +400,19 @@ namespace ts {
* be converted to a path relative to found rootDir entry './content/protocols/file2' (*). As a last step compiler will check all remaining
* entries in 'rootDirs', use them to build absolute path out of (*) and try to resolve module from this location.
*/
function tryLoadModuleUsingOptionalResolutionSettings(moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
failedLookupLocations: string[], supportedExtensions: string[], state: ModuleResolutionState): string {
function tryLoadModuleUsingOptionalResolutionSettings(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
if (moduleHasNonRelativeName(moduleName)) {
return tryLoadModuleUsingBaseUrl(moduleName, loader, failedLookupLocations, supportedExtensions, state);
return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, failedLookupLocations, state);
}
else {
return tryLoadModuleUsingRootDirs(moduleName, containingDirectory, loader, failedLookupLocations, supportedExtensions, state);
return tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state);
}
}
function tryLoadModuleUsingRootDirs(moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
failedLookupLocations: string[], supportedExtensions: string[], state: ModuleResolutionState): string {
function tryLoadModuleUsingRootDirs(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
if (!state.compilerOptions.rootDirs) {
return undefined;
@@ -432,7 +457,7 @@ namespace ts {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, matchedNormalizedPrefix, candidate);
}
const resolvedFileName = loader(candidate, supportedExtensions, failedLookupLocations, !directoryProbablyExists(containingDirectory, state.host), state);
const resolvedFileName = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(containingDirectory, state.host), state);
if (resolvedFileName) {
return resolvedFileName;
}
@@ -451,7 +476,7 @@ namespace ts {
trace(state.host, Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, rootDir, candidate);
}
const baseDirectory = getDirectoryPath(candidate);
const resolvedFileName = loader(candidate, supportedExtensions, failedLookupLocations, !directoryProbablyExists(baseDirectory, state.host), state);
const resolvedFileName = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(baseDirectory, state.host), state);
if (resolvedFileName) {
return resolvedFileName;
}
@@ -463,9 +488,7 @@ namespace ts {
return undefined;
}
function tryLoadModuleUsingBaseUrl(moduleName: string, loader: ResolutionKindSpecificLoader, failedLookupLocations: string[],
supportedExtensions: string[], state: ModuleResolutionState): string {
function tryLoadModuleUsingBaseUrl(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
if (!state.compilerOptions.baseUrl) {
return undefined;
}
@@ -494,9 +517,9 @@ namespace ts {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path);
}
const resolvedFileName = loader(candidate, supportedExtensions, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
if (resolvedFileName) {
return resolvedFileName;
const resolved = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
if (resolved) {
return resolved;
}
}
return undefined;
@@ -508,56 +531,64 @@ namespace ts {
trace(state.host, Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, state.compilerOptions.baseUrl, candidate);
}
return loader(candidate, supportedExtensions, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
}
}
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
const containingDirectory = getDirectoryPath(containingFile);
const supportedExtensions = getSupportedExtensions(compilerOptions);
const traceEnabled = isTraceEnabled(compilerOptions, host);
const failedLookupLocations: string[] = [];
const state = { compilerOptions, host, traceEnabled, skipTsx: false };
let resolvedFileName = tryLoadModuleUsingOptionalResolutionSettings(moduleName, containingDirectory, nodeLoadModuleByRelativeName,
failedLookupLocations, supportedExtensions, state);
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
const result = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
if (result) {
const { resolved, isExternalLibraryImport } = result;
return createResolvedModuleWithFailedLookupLocations(resolved && resolvedWithRealpath(resolved, host, traceEnabled), isExternalLibraryImport, failedLookupLocations);
}
return { resolvedModule: undefined, failedLookupLocations };
function tryResolve(extensions: Extensions): { resolved: Resolved, isExternalLibraryImport: boolean } | undefined {
const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, nodeLoadModuleByRelativeName, failedLookupLocations, state);
if (resolved) {
return { resolved, isExternalLibraryImport: false };
}
let isExternalLibraryImport = false;
if (!resolvedFileName) {
if (moduleHasNonRelativeName(moduleName)) {
if (traceEnabled) {
trace(host, Diagnostics.Loading_module_0_from_node_modules_folder, moduleName);
}
resolvedFileName = loadModuleFromNodeModules(moduleName, containingDirectory, failedLookupLocations, state, /*checkOneLevel*/ false);
isExternalLibraryImport = resolvedFileName !== undefined;
const resolved = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, /*checkOneLevel*/ false);
return resolved && { resolved, isExternalLibraryImport: true };
}
else {
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
resolvedFileName = nodeLoadModuleByRelativeName(candidate, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state);
return resolved && { resolved, isExternalLibraryImport: false };
}
}
if (resolvedFileName && host.realpath) {
const originalFileName = resolvedFileName;
resolvedFileName = normalizePath(host.realpath(resolvedFileName));
if (traceEnabled) {
trace(host, Diagnostics.Resolving_real_path_for_0_result_1, originalFileName, resolvedFileName);
}
}
return createResolvedModule(resolvedFileName, isExternalLibraryImport, failedLookupLocations);
}
function nodeLoadModuleByRelativeName(candidate: string, supportedExtensions: string[], failedLookupLocations: string[],
onlyRecordFailures: boolean, state: ModuleResolutionState): string {
function resolvedWithRealpath(resolved: Resolved, host: ModuleResolutionHost, traceEnabled: boolean): Resolved {
if (!host.realpath) {
return resolved;
}
const real = normalizePath(host.realpath(resolved.path));
if (traceEnabled) {
trace(host, Diagnostics.Resolving_real_path_for_0_result_1, resolved.path, real);
}
return { path: real, extension: resolved.extension };
}
function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string, failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0, candidate);
}
const resolvedFileName = !pathEndsWithDirectorySeparator(candidate) && loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, onlyRecordFailures, state);
return resolvedFileName || loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, onlyRecordFailures, state);
const resolvedFromFile = !pathEndsWithDirectorySeparator(candidate) && loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state);
return resolvedFromFile || loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state);
}
/* @internal */
@@ -570,9 +601,9 @@ namespace ts {
* @param {boolean} onlyRecordFailures - if true then function won't try to actually load files but instead record all attempts as failures. This flag is necessary
* in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations.
*/
function loadModuleFromFile(candidate: string, extensions: string[], failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): string | undefined {
function loadModuleFromFile(extensions: Extensions, candidate: string, failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
// First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts"
const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocation, onlyRecordFailures, state);
const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state);
if (resolvedByAddingExtension) {
return resolvedByAddingExtension;
}
@@ -585,12 +616,12 @@ namespace ts {
const extension = candidate.substring(extensionless.length);
trace(state.host, Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension);
}
return tryAddingExtensions(extensionless, extensions, failedLookupLocation, onlyRecordFailures, state);
return tryAddingExtensions(extensionless, extensions, failedLookupLocations, onlyRecordFailures, state);
}
}
/** Try to return an existing file that adds one of the `extensions` to `candidate`. */
function tryAddingExtensions(candidate: string, extensions: string[], failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): string | undefined {
function tryAddingExtensions(candidate: string, extensions: Extensions, failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
if (!onlyRecordFailures) {
// check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing
const directory = getDirectoryPath(candidate);
@@ -598,8 +629,20 @@ namespace ts {
onlyRecordFailures = !directoryProbablyExists(directory, state.host);
}
}
return forEach(extensions, ext =>
!(state.skipTsx && isJsxOrTsxExtension(ext)) && tryFile(candidate + ext, failedLookupLocation, onlyRecordFailures, state));
switch (extensions) {
case Extensions.DtsOnly:
return tryExtension(".d.ts", Extension.Dts);
case Extensions.TypeScript:
return tryExtension(".ts", Extension.Ts) || tryExtension(".tsx", Extension.Tsx) || tryExtension(".d.ts", Extension.Dts);
case Extensions.JavaScript:
return tryExtension(".js", Extension.Js) || tryExtension(".jsx", Extension.Jsx);
}
function tryExtension(ext: string, extension: Extension): Resolved | undefined {
const path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state);
return path && { path, extension };
}
}
/** Return the file if it exists. */
@@ -619,26 +662,31 @@ namespace ts {
}
}
function loadNodeModuleFromDirectory(extensions: string[], candidate: string, failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): string {
function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
const packageJsonPath = pathToPackageJson(candidate);
const directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host);
if (directoryExists && state.host.fileExists(packageJsonPath)) {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath);
}
const typesFile = tryReadTypesSection(packageJsonPath, candidate, state);
const typesFile = tryReadTypesSection(extensions, packageJsonPath, candidate, state);
if (typesFile) {
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(typesFile), state.host);
// A package.json "typings" may specify an exact filename, or may choose to omit an extension.
const result = tryFile(typesFile, failedLookupLocation, onlyRecordFailures, state) ||
tryAddingExtensions(typesFile, extensions, failedLookupLocation, onlyRecordFailures, state);
if (result) {
return result;
const fromFile = tryFile(typesFile, failedLookupLocation, onlyRecordFailures, state);
if (fromFile) {
// Note: this would allow a package.json to specify a ".js" file as typings. Maybe that should be forbidden.
return resolvedFromAnyFile(fromFile);
}
const x = tryAddingExtensions(typesFile, Extensions.TypeScript, failedLookupLocation, onlyRecordFailures, state);
if (x) {
return x;
}
}
else {
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_does_not_have_types_field);
trace(state.host, Diagnostics.package_json_does_not_have_a_types_or_main_field);
}
}
}
@@ -650,104 +698,90 @@ namespace ts {
failedLookupLocation.push(packageJsonPath);
}
return loadModuleFromFile(combinePaths(candidate, "index"), extensions, failedLookupLocation, !directoryExists, state);
return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocation, !directoryExists, state);
}
function pathToPackageJson(directory: string): string {
return combinePaths(directory, "package.json");
}
function loadModuleFromNodeModulesFolder(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): string {
function loadModuleFromNodeModulesFolder(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
const nodeModulesFolder = combinePaths(directory, "node_modules");
const nodeModulesFolderExists = directoryProbablyExists(nodeModulesFolder, state.host);
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
const supportedExtensions = getSupportedExtensions(state.compilerOptions);
let result = loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, !nodeModulesFolderExists, state);
if (result) {
return result;
}
result = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state);
if (result) {
return result;
}
return loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) ||
loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state);
}
/* @internal */
export function loadModuleFromNodeModules(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean): string {
return loadModuleFromNodeModulesWorker(moduleName, directory, failedLookupLocations, state, checkOneLevel, /*typesOnly*/ false);
function loadModuleFromNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean): Resolved | undefined {
return loadModuleFromNodeModulesWorker(extensions, moduleName, directory, failedLookupLocations, state, checkOneLevel, /*typesOnly*/ false);
}
function loadModuleFromNodeModulesAtTypes(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
return loadModuleFromNodeModulesWorker(Extensions.TypeScript, moduleName, directory, failedLookupLocations, state, /*checkOneLevel*/ false, /*typesOnly*/ true);
}
function loadModuleFromNodeModulesAtTypes(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): string {
return loadModuleFromNodeModulesWorker(moduleName, directory, failedLookupLocations, state, /*checkOneLevel*/ false, /*typesOnly*/ true);
}
function loadModuleFromNodeModulesWorker(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean, typesOnly: boolean): string {
function loadModuleFromNodeModulesWorker(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean, typesOnly: boolean): Resolved | undefined {
directory = normalizeSlashes(directory);
while (true) {
const baseName = getBaseFileName(directory);
if (baseName !== "node_modules") {
let packageResult: string | undefined;
if (!typesOnly) {
// Try to load source from the package
packageResult = loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state);
if (packageResult && hasTypeScriptFileExtension(packageResult)) {
// Always prefer a TypeScript (.ts, .tsx, .d.ts) file shipped with the package
return packageResult;
}
}
// Else prefer a types package over non-TypeScript results (e.g. JavaScript files)
const typesResult = loadModuleFromNodeModulesFolder(combinePaths("@types", moduleName), directory, failedLookupLocations, state);
if (typesResult || packageResult) {
return typesResult || packageResult;
if (getBaseFileName(directory) !== "node_modules") {
const resolved = tryInDirectory();
if (resolved) {
return resolved;
}
}
const parentPath = getDirectoryPath(directory);
if (parentPath === directory || checkOneLevel) {
break;
return undefined;
}
directory = parentPath;
}
return undefined;
function tryInDirectory(): Resolved | undefined {
const packageResult = typesOnly ? undefined : loadModuleFromNodeModulesFolder(extensions, moduleName, directory, failedLookupLocations, state);
return packageResult || loadModuleFromNodeModulesFolder(extensions, combinePaths("@types", moduleName), directory, failedLookupLocations, state);
}
}
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
const traceEnabled = isTraceEnabled(compilerOptions, host);
const state = { compilerOptions, host, traceEnabled, skipTsx: !compilerOptions.jsx };
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
const failedLookupLocations: string[] = [];
const supportedExtensions = getSupportedExtensions(compilerOptions);
const containingDirectory = getDirectoryPath(containingFile);
const resolvedFileName = tryLoadModuleUsingOptionalResolutionSettings(moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, supportedExtensions, state);
if (resolvedFileName) {
return createResolvedModule(resolvedFileName, /*isExternalLibraryImport*/false, failedLookupLocations);
}
const resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ false, failedLookupLocations);
let referencedSourceFile: string;
if (moduleHasNonRelativeName(moduleName)) {
referencedSourceFile = referencedSourceFile = loadModuleFromAncestorDirectories(moduleName, containingDirectory, supportedExtensions, failedLookupLocations, state) ||
// If we didn't find the file normally, look it up in @types.
loadModuleFromNodeModulesAtTypes(moduleName, containingDirectory, failedLookupLocations, state);
}
else {
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
referencedSourceFile = loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
}
function tryResolve(extensions: Extensions): Resolved | undefined {
const resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, state);
if (resolvedUsingSettings) {
return resolvedUsingSettings;
}
return referencedSourceFile
? { resolvedModule: { resolvedFileName: referencedSourceFile }, failedLookupLocations }
: { resolvedModule: undefined, failedLookupLocations };
if (moduleHasNonRelativeName(moduleName)) {
const resolved = loadModuleFromAncestorDirectories(extensions, moduleName, containingDirectory, failedLookupLocations, state);
if (resolved) {
return resolved;
}
if (extensions === Extensions.TypeScript) {
// If we didn't find the file normally, look it up in @types.
return loadModuleFromNodeModulesAtTypes(moduleName, containingDirectory, failedLookupLocations, state);
}
}
else {
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
return loadModuleFromFile(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state);
}
}
}
/** Climb up parent directories looking for a module. */
function loadModuleFromAncestorDirectories(moduleName: string, containingDirectory: string, supportedExtensions: string[], failedLookupLocations: string[], state: ModuleResolutionState): string | undefined {
function loadModuleFromAncestorDirectories(extensions: Extensions, moduleName: string, containingDirectory: string, failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
while (true) {
const searchName = normalizePath(combinePaths(containingDirectory, moduleName));
const referencedSourceFile = loadModuleFromFile(searchName, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
const referencedSourceFile = loadModuleFromFile(extensions, searchName, failedLookupLocations, /*onlyRecordFailures*/ false, state);
if (referencedSourceFile) {
return referencedSourceFile;
}
@@ -758,4 +792,21 @@ namespace ts {
containingDirectory = parentPath;
}
}
/**
* LSHost may load a module from a global cache of typings.
* This is the minumum code needed to expose that functionality; the rest is in LSHost.
*/
/* @internal */
export function loadModuleFromGlobalCache(moduleName: string, projectName: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, globalCache: string): ResolvedModuleWithFailedLookupLocations {
const traceEnabled = isTraceEnabled(compilerOptions, host);
if (traceEnabled) {
trace(host, Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache);
}
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
const failedLookupLocations: string[] = [];
const resolved = loadModuleFromNodeModules(Extensions.TypeScript, moduleName, globalCache, failedLookupLocations, state, /*checkOneLevel*/ true) ||
loadModuleFromNodeModules(Extensions.JavaScript, moduleName, globalCache, failedLookupLocations, state, /*checkOneLevel*/ true);
return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations);
}
}
+95 -52
View File
@@ -411,6 +411,7 @@ namespace ts {
return visitNodes(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);
case SyntaxKind.JSDocTypeLiteral:
@@ -572,10 +573,10 @@ namespace ts {
// attached to the EOF token.
let parseErrorBeforeNextFinishedNode = false;
export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, scriptKind?: ScriptKind): SourceFile {
export function parseSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, scriptKind?: ScriptKind): SourceFile {
scriptKind = ensureScriptKind(fileName, scriptKind);
initializeState(fileName, _sourceText, languageVersion, _syntaxCursor, scriptKind);
initializeState(sourceText, languageVersion, syntaxCursor, scriptKind);
const result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind);
@@ -589,7 +590,7 @@ namespace ts {
return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS ? LanguageVariant.JSX : LanguageVariant.Standard;
}
function initializeState(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) {
function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) {
NodeConstructor = objectAllocator.getNodeConstructor();
TokenConstructor = objectAllocator.getTokenConstructor();
IdentifierConstructor = objectAllocator.getIdentifierConstructor();
@@ -637,7 +638,7 @@ namespace ts {
sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement);
Debug.assert(token() === SyntaxKind.EndOfFileToken);
sourceFile.endOfFileToken = parseTokenNode();
sourceFile.endOfFileToken = <EndOfFileToken>parseTokenNode();
setExternalModuleIndicator(sourceFile);
@@ -1004,6 +1005,7 @@ namespace ts {
return false;
}
function parseOptionalToken<TKind extends SyntaxKind>(t: TKind): Token<TKind>;
function parseOptionalToken(t: SyntaxKind): Node {
if (token() === t) {
return parseTokenNode();
@@ -1011,6 +1013,7 @@ namespace ts {
return undefined;
}
function parseExpectedToken<TKind extends SyntaxKind>(t: TKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Token<TKind>;
function parseExpectedToken(t: SyntaxKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Node {
return parseOptionalToken(t) ||
createMissingNode(t, reportAtCurrentPosition, diagnosticMessage, arg0);
@@ -1047,7 +1050,7 @@ namespace ts {
}
// note: this function creates only node
function createNode(kind: SyntaxKind, pos?: number): Node | Token | Identifier {
function createNode<TKind extends SyntaxKind>(kind: TKind, pos?: number): Node | Token<TKind> | Identifier {
nodeCount++;
if (!(pos >= 0)) {
pos = scanner.getStartPos();
@@ -1920,7 +1923,7 @@ namespace ts {
function parseTemplateExpression(): TemplateExpression {
const template = <TemplateExpression>createNode(SyntaxKind.TemplateExpression);
template.head = parseTemplateLiteralFragment();
template.head = parseTemplateHead();
Debug.assert(template.head.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
const templateSpans = createNodeArray<TemplateSpan>();
@@ -1940,14 +1943,13 @@ namespace ts {
const span = <TemplateSpan>createNode(SyntaxKind.TemplateSpan);
span.expression = allowInAnd(parseExpression);
let literal: TemplateLiteralFragment;
let literal: TemplateMiddle | TemplateTail;
if (token() === SyntaxKind.CloseBraceToken) {
reScanTemplateToken();
literal = parseTemplateLiteralFragment();
literal = parseTemplateMiddleOrTemplateTail();
}
else {
literal = <TemplateLiteralFragment>parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken));
literal = <TemplateTail>parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken));
}
span.literal = literal;
@@ -1958,8 +1960,16 @@ namespace ts {
return <LiteralExpression>parseLiteralLikeNode(token(), internName);
}
function parseTemplateLiteralFragment(): TemplateLiteralFragment {
return <TemplateLiteralFragment>parseLiteralLikeNode(token(), /*internName*/ false);
function parseTemplateHead(): TemplateHead {
const fragment = parseLiteralLikeNode(token(), /*internName*/ false);
Debug.assert(fragment.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
return <TemplateHead>fragment;
}
function parseTemplateMiddleOrTemplateTail(): TemplateMiddle | TemplateTail {
const fragment = parseLiteralLikeNode(token(), /*internName*/ false);
Debug.assert(fragment.kind === SyntaxKind.TemplateMiddle || fragment.kind === SyntaxKind.TemplateTail, "Template fragment has wrong token kind");
return <TemplateMiddle | TemplateTail>fragment;
}
function parseLiteralLikeNode(kind: SyntaxKind, internName: boolean): LiteralLikeNode {
@@ -2719,7 +2729,7 @@ namespace ts {
}
let expr = parseAssignmentExpressionOrHigher();
let operatorToken: Node;
let operatorToken: BinaryOperatorToken;
while ((operatorToken = parseOptionalToken(SyntaxKind.CommaToken))) {
expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher());
}
@@ -2812,7 +2822,7 @@ namespace ts {
// Note: we call reScanGreaterToken so that we get an appropriately merged token
// for cases like > > = becoming >>=
if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) {
return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
return makeBinaryExpression(expr, <BinaryOperatorToken>parseTokenNode(), parseAssignmentExpressionOrHigher());
}
// It wasn't an assignment or a lambda. This is a conditional expression:
@@ -3247,7 +3257,7 @@ namespace ts {
}
}
else {
leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
leftOperand = makeBinaryExpression(leftOperand, <BinaryOperatorToken>parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
}
}
@@ -3307,7 +3317,7 @@ namespace ts {
return -1;
}
function makeBinaryExpression(left: Expression, operatorToken: Node, right: Expression): BinaryExpression {
function makeBinaryExpression(left: Expression, operatorToken: BinaryOperatorToken, right: Expression): BinaryExpression {
const node = <BinaryExpression>createNode(SyntaxKind.BinaryExpression, left.pos);
node.left = left;
node.operatorToken = operatorToken;
@@ -3324,7 +3334,7 @@ namespace ts {
function parsePrefixUnaryExpression() {
const node = <PrefixUnaryExpression>createNode(SyntaxKind.PrefixUnaryExpression);
node.operator = token();
node.operator = <PrefixUnaryOperator>token();
nextToken();
node.operand = parseSimpleUnaryExpression();
@@ -3511,7 +3521,7 @@ namespace ts {
function parseIncrementExpression(): IncrementExpression {
if (token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) {
const node = <PrefixUnaryExpression>createNode(SyntaxKind.PrefixUnaryExpression);
node.operator = token();
node.operator = <PrefixUnaryOperator>token();
nextToken();
node.operand = parseLeftHandSideExpressionOrHigher();
return finishNode(node);
@@ -3527,7 +3537,7 @@ namespace ts {
if ((token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) && !scanner.hasPrecedingLineBreak()) {
const node = <PostfixUnaryExpression>createNode(SyntaxKind.PostfixUnaryExpression, expression.pos);
node.operand = expression;
node.operator = token();
node.operator = <PostfixUnaryOperator>token();
nextToken();
return finishNode(node);
}
@@ -3700,7 +3710,7 @@ namespace ts {
badNode.end = invalidElement.end;
badNode.left = result;
badNode.right = invalidElement;
badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
badNode.operatorToken = <BinaryOperatorToken>createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
return <JsxElement><Node>badNode;
}
@@ -3836,7 +3846,7 @@ namespace ts {
if (token() === SyntaxKind.EqualsToken) {
switch (scanJsxAttributeValue()) {
case SyntaxKind.StringLiteral:
node.initializer = parseLiteralNode();
node.initializer = <StringLiteral>parseLiteralNode();
break;
default:
node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
@@ -3921,7 +3931,7 @@ namespace ts {
const tagExpression = <TaggedTemplateExpression>createNode(SyntaxKind.TaggedTemplateExpression, expression.pos);
tagExpression.tag = expression;
tagExpression.template = token() === SyntaxKind.NoSubstitutionTemplateLiteral
? parseLiteralNode()
? <NoSubstitutionTemplateLiteral>parseLiteralNode()
: parseTemplateExpression();
expression = finishNode(tagExpression);
continue;
@@ -4959,7 +4969,7 @@ namespace ts {
return addJSDocComment(finishNode(node));
}
function parseMethodDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>, asteriskToken: Node, name: PropertyName, questionToken: Node, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
function parseMethodDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>, asteriskToken: AsteriskToken, name: PropertyName, questionToken: QuestionToken, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
const method = <MethodDeclaration>createNode(SyntaxKind.MethodDeclaration, fullStart);
method.decorators = decorators;
method.modifiers = modifiers;
@@ -4973,7 +4983,7 @@ namespace ts {
return addJSDocComment(finishNode(method));
}
function parsePropertyDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>, name: PropertyName, questionToken: Node): ClassElement {
function parsePropertyDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>, name: PropertyName, questionToken: QuestionToken): ClassElement {
const property = <PropertyDeclaration>createNode(SyntaxKind.PropertyDeclaration, fullStart);
property.decorators = decorators;
property.modifiers = modifiers;
@@ -5250,7 +5260,7 @@ namespace ts {
parseExpected(SyntaxKind.ClassKeyword);
node.name = parseNameOfClassDeclarationOrExpression();
node.typeParameters = parseTypeParameters();
node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ true);
node.heritageClauses = parseHeritageClauses();
if (parseExpected(SyntaxKind.OpenBraceToken)) {
// ClassTail[Yield,Await] : (Modified) See 14.5
@@ -5280,7 +5290,7 @@ namespace ts {
return token() === SyntaxKind.ImplementsKeyword && lookAhead(nextTokenIsIdentifierOrKeyword);
}
function parseHeritageClauses(isClassHeritageClause: boolean): NodeArray<HeritageClause> {
function parseHeritageClauses(): NodeArray<HeritageClause> {
// ClassTail[Yield,Await] : (Modified) See 14.5
// ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
@@ -5328,7 +5338,7 @@ namespace ts {
parseExpected(SyntaxKind.InterfaceKeyword);
node.name = parseIdentifier();
node.typeParameters = parseTypeParameters();
node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ false);
node.heritageClauses = parseHeritageClauses();
node.members = parseObjectTypeMembers();
return addJSDocComment(finishNode(node));
}
@@ -5343,7 +5353,7 @@ namespace ts {
parseExpected(SyntaxKind.EqualsToken);
node.type = parseType();
parseSemicolon();
return finishNode(node);
return addJSDocComment(finishNode(node));
}
// In an ambient declaration, the grammar only allows integer literals as initializers.
@@ -5395,7 +5405,7 @@ namespace ts {
node.flags |= flags;
node.name = parseIdentifier();
node.body = parseOptional(SyntaxKind.DotToken)
? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag)
? <NamespaceDeclaration>parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag)
: parseModuleBlock();
return addJSDocComment(finishNode(node));
}
@@ -5463,7 +5473,7 @@ namespace ts {
exportDeclaration.name = parseIdentifier();
parseExpected(SyntaxKind.SemicolonToken);
parseSemicolon();
return finishNode(exportDeclaration);
}
@@ -5574,8 +5584,10 @@ namespace ts {
return finishNode(namespaceImport);
}
function parseNamedImportsOrExports(kind: SyntaxKind.NamedImports): NamedImports;
function parseNamedImportsOrExports(kind: SyntaxKind.NamedExports): NamedExports;
function parseNamedImportsOrExports(kind: SyntaxKind): NamedImportsOrExports {
const node = <NamedImports>createNode(kind);
const node = <NamedImports | NamedExports>createNode(kind);
// NamedImports:
// { }
@@ -5585,7 +5597,7 @@ namespace ts {
// ImportsList:
// ImportSpecifier
// ImportsList, ImportSpecifier
node.elements = parseBracketedList(ParsingContext.ImportOrExportSpecifiers,
node.elements = <NodeArray<ImportSpecifier> | NodeArray<ExportSpecifier>>parseBracketedList(ParsingContext.ImportOrExportSpecifiers,
kind === SyntaxKind.NamedImports ? parseImportSpecifier : parseExportSpecifier,
SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken);
return finishNode(node);
@@ -5806,7 +5818,7 @@ namespace ts {
}
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number) {
initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS);
scanner.setText(content, start, length);
currentToken = scanner.scan();
@@ -5969,14 +5981,15 @@ namespace ts {
const parameter = <ParameterDeclaration>createNode(SyntaxKind.Parameter);
parameter.type = parseJSDocType();
if (parseOptional(SyntaxKind.EqualsToken)) {
parameter.questionToken = createNode(SyntaxKind.EqualsToken);
// TODO(rbuckton): Can this be changed to SyntaxKind.QuestionToken?
parameter.questionToken = <QuestionToken>createNode(SyntaxKind.EqualsToken);
}
return finishNode(parameter);
}
function parseJSDocTypeReference(): JSDocTypeReference {
const result = <JSDocTypeReference>createNode(SyntaxKind.JSDocTypeReference);
result.name = parseSimplePropertyName();
result.name = <Identifier>parseSimplePropertyName();
if (token() === SyntaxKind.LessThanToken) {
result.typeArguments = parseTypeArguments();
@@ -6122,7 +6135,7 @@ namespace ts {
}
export function parseIsolatedJSDocComment(content: string, start: number, length: number) {
initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
sourceFile = <SourceFile>{ languageVariant: LanguageVariant.Standard, text: content };
const jsDoc = parseJSDocCommentWorker(start, length);
const diagnostics = parseDiagnostics;
@@ -6304,7 +6317,7 @@ namespace ts {
function parseTag(indent: number) {
Debug.assert(token() === SyntaxKind.AtToken);
const atToken = createNode(SyntaxKind.AtToken, scanner.getTokenPos());
const atToken = <AtToken>createNode(SyntaxKind.AtToken, scanner.getTokenPos());
atToken.end = scanner.getTextPos();
nextJSDocToken();
@@ -6410,7 +6423,7 @@ namespace ts {
return comments;
}
function parseUnknownTag(atToken: Node, tagName: Identifier) {
function parseUnknownTag(atToken: AtToken, tagName: Identifier) {
const result = <JSDocTag>createNode(SyntaxKind.JSDocTag, atToken.pos);
result.atToken = atToken;
result.tagName = tagName;
@@ -6440,7 +6453,7 @@ namespace ts {
});
}
function parseParamTag(atToken: Node, tagName: Identifier) {
function parseParamTag(atToken: AtToken, tagName: Identifier) {
let typeExpression = tryParseTypeExpression();
skipWhitespace();
@@ -6491,7 +6504,7 @@ namespace ts {
return finishNode(result);
}
function parseReturnTag(atToken: Node, tagName: Identifier): JSDocReturnTag {
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);
}
@@ -6503,7 +6516,7 @@ namespace ts {
return finishNode(result);
}
function parseTypeTag(atToken: Node, tagName: Identifier): JSDocTypeTag {
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);
}
@@ -6515,7 +6528,7 @@ namespace ts {
return finishNode(result);
}
function parsePropertyTag(atToken: Node, tagName: Identifier): JSDocPropertyTag {
function parsePropertyTag(atToken: AtToken, tagName: Identifier): JSDocPropertyTag {
const typeExpression = tryParseTypeExpression();
skipWhitespace();
const name = parseJSDocIdentifierName();
@@ -6533,14 +6546,21 @@ namespace ts {
return finishNode(result);
}
function parseTypedefTag(atToken: Node, tagName: Identifier): JSDocTypedefTag {
function parseTypedefTag(atToken: AtToken, tagName: Identifier): JSDocTypedefTag {
const typeExpression = tryParseTypeExpression();
skipWhitespace();
const typedefTag = <JSDocTypedefTag>createNode(SyntaxKind.JSDocTypedefTag, atToken.pos);
typedefTag.atToken = atToken;
typedefTag.tagName = tagName;
typedefTag.name = parseJSDocIdentifierName();
typedefTag.fullName = parseJSDocTypeNameWithNamespace(/*flags*/ 0);
if (typedefTag.fullName) {
let rightNode = typedefTag.fullName;
while (rightNode.kind !== SyntaxKind.Identifier) {
rightNode = rightNode.body;
}
typedefTag.name = rightNode;
}
typedefTag.typeExpression = typeExpression;
skipWhitespace();
@@ -6555,7 +6575,7 @@ namespace ts {
}
}
if (!typedefTag.jsDocTypeLiteral) {
typedefTag.jsDocTypeLiteral = typeExpression.type;
typedefTag.jsDocTypeLiteral = <JSDocTypeLiteral>typeExpression.type;
}
}
else {
@@ -6603,11 +6623,30 @@ namespace ts {
scanner.setTextPos(resumePos);
return finishNode(jsDocTypeLiteral);
}
function parseJSDocTypeNameWithNamespace(flags: NodeFlags) {
const pos = scanner.getTokenPos();
const typeNameOrNamespaceName = parseJSDocIdentifierName();
if (typeNameOrNamespaceName && parseOptional(SyntaxKind.DotToken)) {
const jsDocNamespaceNode = <JSDocNamespaceDeclaration>createNode(SyntaxKind.ModuleDeclaration, pos);
jsDocNamespaceNode.flags |= flags;
jsDocNamespaceNode.name = typeNameOrNamespaceName;
jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(NodeFlags.NestedNamespace);
return jsDocNamespaceNode;
}
if (typeNameOrNamespaceName && flags & NodeFlags.NestedNamespace) {
typeNameOrNamespaceName.isInJSDocNamespace = true;
}
return typeNameOrNamespaceName;
}
}
function tryParseChildTag(parentTag: JSDocTypeLiteral): boolean {
Debug.assert(token() === SyntaxKind.AtToken);
const atToken = createNode(SyntaxKind.AtToken, scanner.getStartPos());
const atToken = <AtToken>createNode(SyntaxKind.AtToken, scanner.getStartPos());
atToken.end = scanner.getTextPos();
nextJSDocToken();
@@ -6627,17 +6666,21 @@ namespace ts {
return true;
case "prop":
case "property":
if (!parentTag.jsDocPropertyTags) {
parentTag.jsDocPropertyTags = <NodeArray<JSDocPropertyTag>>[];
}
const propertyTag = parsePropertyTag(atToken, tagName);
parentTag.jsDocPropertyTags.push(propertyTag);
return true;
if (propertyTag) {
if (!parentTag.jsDocPropertyTags) {
parentTag.jsDocPropertyTags = <NodeArray<JSDocPropertyTag>>[];
}
parentTag.jsDocPropertyTags.push(propertyTag);
return true;
}
// Error parsing property tag
return false;
}
return false;
}
function parseTemplateTag(atToken: Node, tagName: Identifier): JSDocTemplateTag {
function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag {
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTemplateTag)) {
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
}
+1 -1
View File
@@ -12,7 +12,7 @@ namespace ts.performance {
const profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true
? onProfilerEvent
: (markName: string) => { };
: (_markName: string) => { };
let enabled = false;
let profilerStart = 0;
+105 -79
View File
@@ -307,7 +307,7 @@ namespace ts {
// - This calls resolveModuleNames, and then calls findSourceFile for each resolved module.
// As all these operations happen - and are nested - within the createProgram call, they close over the below variables.
// The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses.
const maxNodeModulesJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0;
const maxNodeModuleJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0;
let currentNodeModulesDepth = 0;
// If a module has some of its imports skipped due to being at the depth limit under node_modules, then track
@@ -329,9 +329,17 @@ namespace ts {
// Map storing if there is emit blocking diagnostics for given input
const hasEmitBlockingDiagnostics = createFileMap<boolean>(getCanonicalFileName);
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string) => ResolvedModule[];
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string) => ResolvedModuleFull[];
if (host.resolveModuleNames) {
resolveModuleNamesWorker = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile);
resolveModuleNamesWorker = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile).map(resolved => {
// An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
if (!resolved || (resolved as ResolvedModuleFull).extension !== undefined) {
return resolved as ResolvedModuleFull;
}
const withExtension = clone(resolved) as ResolvedModuleFull;
withExtension.extension = extensionFromPath(resolved.resolvedFileName);
return withExtension;
});
}
else {
const loader = (moduleName: string, containingFile: string) => resolveModuleName(moduleName, containingFile, options, host).resolvedModule;
@@ -358,7 +366,7 @@ namespace ts {
// load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders
const typeReferences: string[] = getAutomaticTypeDirectiveNames(options, host);
if (typeReferences) {
if (typeReferences.length) {
// This containingFilename needs to match with the one used in managed-side
const containingFilename = combinePaths(host.getCurrentDirectory(), "__inferred type names__.ts");
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
@@ -462,21 +470,7 @@ namespace ts {
// check properties that can affect structure of the program or module resolution strategy
// if any of these properties has changed - structure cannot be reused
const oldOptions = oldProgram.getCompilerOptions();
if ((oldOptions.module !== options.module) ||
(oldOptions.moduleResolution !== options.moduleResolution) ||
(oldOptions.noResolve !== options.noResolve) ||
(oldOptions.target !== options.target) ||
(oldOptions.noLib !== options.noLib) ||
(oldOptions.jsx !== options.jsx) ||
(oldOptions.allowJs !== options.allowJs) ||
(oldOptions.rootDir !== options.rootDir) ||
(oldOptions.configFilePath !== options.configFilePath) ||
(oldOptions.baseUrl !== options.baseUrl) ||
(oldOptions.maxNodeModuleJsDepth !== options.maxNodeModuleJsDepth) ||
!arrayIsEqualTo(oldOptions.lib, options.lib) ||
!arrayIsEqualTo(oldOptions.typeRoots, oldOptions.typeRoots) ||
!arrayIsEqualTo(oldOptions.rootDirs, options.rootDirs) ||
!equalOwnProperties(oldOptions.paths, options.paths)) {
if (changesAffectModuleResolution(oldOptions, options)) {
return false;
}
@@ -724,7 +718,15 @@ namespace ts {
}
}
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
// For JavaScript files, we report semantic errors for using TypeScript-only
// constructs from within a JavaScript file as syntactic errors.
if (isSourceFileJavaScript(sourceFile)) {
if (!sourceFile.additionalSyntacticDiagnostics) {
sourceFile.additionalSyntacticDiagnostics = getJavaScriptSyntacticDiagnosticsForFile(sourceFile);
}
return concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.parseDiagnostics);
}
return sourceFile.parseDiagnostics;
}
@@ -757,20 +759,18 @@ namespace ts {
Debug.assert(!!sourceFile.bindDiagnostics);
const bindDiagnostics = sourceFile.bindDiagnostics;
// For JavaScript files, we don't want to report the normal typescript semantic errors.
// Instead, we just report errors for using TypeScript-only constructs from within a
// JavaScript file.
const checkDiagnostics = isSourceFileJavaScript(sourceFile) ?
getJavaScriptSemanticDiagnosticsForFile(sourceFile, cancellationToken) :
typeChecker.getDiagnostics(sourceFile, cancellationToken);
// For JavaScript files, we don't want to report semantic errors.
// Instead, we'll report errors for using TypeScript-only constructs from within a
// JavaScript file when we get syntactic diagnostics for the file.
const checkDiagnostics = isSourceFileJavaScript(sourceFile) ? [] : typeChecker.getDiagnostics(sourceFile, cancellationToken);
const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
return bindDiagnostics.concat(checkDiagnostics).concat(fileProcessingDiagnosticsInFile).concat(programDiagnosticsInFile);
return bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
});
}
function getJavaScriptSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
function getJavaScriptSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
return runWithCancellationToken(() => {
const diagnostics: Diagnostic[] = [];
walk(sourceFile);
@@ -950,8 +950,7 @@ namespace ts {
return runWithCancellationToken(() => {
const resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
// Don't actually write any files since we're just getting diagnostics.
const writeFile: WriteFileCallback = () => { };
return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile);
return ts.getDeclarationDiagnostics(getEmitHost(noop), resolver, sourceFile);
});
}
@@ -972,12 +971,8 @@ namespace ts {
return sortAndDeduplicateDiagnostics(allDiagnostics);
}
function hasExtension(fileName: string): boolean {
return getBaseFileName(fileName).indexOf(".") >= 0;
}
function processRootFile(fileName: string, isDefaultLib: boolean) {
processSourceFile(normalizePath(fileName), isDefaultLib, /*isReference*/ true);
processSourceFile(normalizePath(fileName), isDefaultLib);
}
function fileReferenceIsEqualTo(a: FileReference, b: FileReference): boolean {
@@ -1085,10 +1080,7 @@ namespace ts {
}
}
/**
* 'isReference' indicates whether the file was brought in via a reference directive (rather than an import declaration)
*/
function processSourceFile(fileName: string, isDefaultLib: boolean, isReference: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) {
function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) {
let diagnosticArgument: string[];
let diagnostic: DiagnosticMessage;
if (hasExtension(fileName)) {
@@ -1096,7 +1088,7 @@ namespace ts {
diagnostic = Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1;
diagnosticArgument = [fileName, "'" + supportedExtensions.join("', '") + "'"];
}
else if (!findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd)) {
else if (!findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd)) {
diagnostic = Diagnostics.File_0_not_found;
diagnosticArgument = [fileName];
}
@@ -1106,13 +1098,13 @@ namespace ts {
}
}
else {
const nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd);
const nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd);
if (!nonTsFile) {
if (options.allowNonTsExtensions) {
diagnostic = Diagnostics.File_0_not_found;
diagnosticArgument = [fileName];
}
else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, toPath(fileName + extension, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd))) {
else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, toPath(fileName + extension, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd))) {
diagnostic = Diagnostics.File_0_not_found;
fileName += ".ts";
diagnosticArgument = [fileName];
@@ -1141,7 +1133,7 @@ namespace ts {
}
// Get source file from normalized fileName
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, isReference: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
if (filesByName.contains(path)) {
const file = filesByName.get(path);
// try to check if we've already seen this file but with a different casing in path
@@ -1155,18 +1147,18 @@ namespace ts {
if (file && sourceFilesFoundSearchingNodeModules[file.path] && currentNodeModulesDepth == 0) {
sourceFilesFoundSearchingNodeModules[file.path] = false;
if (!options.noResolve) {
processReferencedFiles(file, getDirectoryPath(fileName), isDefaultLib);
processReferencedFiles(file, isDefaultLib);
processTypeReferenceDirectives(file);
}
modulesWithElidedImports[file.path] = false;
processImportedModules(file, getDirectoryPath(fileName));
processImportedModules(file);
}
// See if we need to reprocess the imports due to prior skipped imports
else if (file && modulesWithElidedImports[file.path]) {
if (currentNodeModulesDepth < maxNodeModulesJsDepth) {
if (currentNodeModulesDepth < maxNodeModuleJsDepth) {
modulesWithElidedImports[file.path] = false;
processImportedModules(file, getDirectoryPath(fileName));
processImportedModules(file);
}
}
@@ -1202,14 +1194,13 @@ namespace ts {
skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
const basePath = getDirectoryPath(fileName);
if (!options.noResolve) {
processReferencedFiles(file, basePath, isDefaultLib);
processReferencedFiles(file, isDefaultLib);
processTypeReferenceDirectives(file);
}
// always process imported modules to record module name resolutions
processImportedModules(file, basePath);
processImportedModules(file);
if (isDefaultLib) {
files.unshift(file);
@@ -1222,10 +1213,10 @@ namespace ts {
return file;
}
function processReferencedFiles(file: SourceFile, basePath: string, isDefaultLib: boolean) {
function processReferencedFiles(file: SourceFile, isDefaultLib: boolean) {
forEach(file.referencedFiles, ref => {
const referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
processSourceFile(referencedFileName, isDefaultLib, /*isReference*/ true, file, ref.pos, ref.end);
processSourceFile(referencedFileName, isDefaultLib, file, ref.pos, ref.end);
});
}
@@ -1256,7 +1247,7 @@ namespace ts {
if (resolvedTypeReferenceDirective) {
if (resolvedTypeReferenceDirective.primary) {
// resolved from the primary path
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*isReference*/ true, refFile, refPos, refEnd);
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, refFile, refPos, refEnd);
}
else {
// If we already resolved to this file, it must have been a secondary reference. Check file contents
@@ -1276,7 +1267,7 @@ namespace ts {
}
else {
// First resolution of this library
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*isReference*/ true, refFile, refPos, refEnd);
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, refFile, refPos, refEnd);
}
}
}
@@ -1302,42 +1293,46 @@ namespace ts {
return host.getCanonicalFileName(fileName);
}
function processImportedModules(file: SourceFile, basePath: string) {
function processImportedModules(file: SourceFile) {
collectExternalModuleReferences(file);
if (file.imports.length || file.moduleAugmentations.length) {
file.resolvedModules = createMap<ResolvedModule>();
file.resolvedModules = createMap<ResolvedModuleFull>();
const moduleNames = map(concatenate(file.imports, file.moduleAugmentations), getTextOfLiteral);
const resolutions = resolveModuleNamesWorker(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory));
Debug.assert(resolutions.length === moduleNames.length);
for (let i = 0; i < moduleNames.length; i++) {
const resolution = resolutions[i];
setResolvedModule(file, moduleNames[i], resolution);
const resolvedPath = resolution ? toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName) : undefined;
if (!resolution) {
continue;
}
const isFromNodeModulesSearch = resolution.isExternalLibraryImport;
const isJsFileFromNodeModules = isFromNodeModulesSearch && !extensionIsTypeScript(resolution.extension);
const resolvedFileName = resolution.resolvedFileName;
if (isFromNodeModulesSearch) {
currentNodeModulesDepth++;
}
// add file to program only if:
// - resolution was successful
// - noResolve is falsy
// - module name comes from the list of imports
// - it's not a top level JavaScript module that exceeded the search max
const isFromNodeModulesSearch = resolution && resolution.isExternalLibraryImport;
const isJsFileFromNodeModules = isFromNodeModulesSearch && hasJavaScriptFileExtension(resolution.resolvedFileName);
if (isFromNodeModulesSearch) {
currentNodeModulesDepth++;
}
const elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModulesJsDepth;
const shouldAddFile = resolution && !options.noResolve && i < file.imports.length && !elideImport;
const elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModuleJsDepth;
// Don't add the file if it has a bad extension (e.g. 'tsx' if we don't have '--allowJs')
// This may still end up being an untyped module -- the file won't be included but imports will be allowed.
const shouldAddFile = resolvedFileName && !getResolutionDiagnostic(options, resolution) && !options.noResolve && i < file.imports.length && !elideImport;
if (elideImport) {
modulesWithElidedImports[file.path] = true;
}
else if (shouldAddFile) {
findSourceFile(resolution.resolvedFileName,
resolvedPath,
/*isDefaultLib*/ false, /*isReference*/ false,
file,
skipTrivia(file.text, file.imports[i].pos),
file.imports[i].end);
const path = toPath(resolvedFileName, currentDirectory, getCanonicalFileName);
const pos = skipTrivia(file.text, file.imports[i].pos);
findSourceFile(resolvedFileName, path, /*isDefaultLib*/ false, file, pos, file.imports[i].end);
}
if (isFromNodeModulesSearch) {
@@ -1349,7 +1344,6 @@ namespace ts {
// no imports - drop cached module resolutions
file.resolvedModules = undefined;
}
return;
}
function computeCommonSourceDirectory(sourceFiles: SourceFile[]): string {
@@ -1474,12 +1468,16 @@ namespace ts {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib"));
}
if (options.noImplicitUseStrict && options.alwaysStrict) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict"));
}
const languageVersion = options.target || ScriptTarget.ES3;
const outFile = options.outFile || options.out;
const firstNonAmbientExternalModuleSourceFile = forEach(files, f => isExternalModule(f) && !isDeclarationFile(f) ? f : undefined);
if (options.isolatedModules) {
if (options.module === ModuleKind.None && languageVersion < ScriptTarget.ES6) {
if (options.module === ModuleKind.None && languageVersion < ScriptTarget.ES2015) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher));
}
@@ -1489,7 +1487,7 @@ namespace ts {
programDiagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided));
}
}
else if (firstNonAmbientExternalModuleSourceFile && languageVersion < ScriptTarget.ES6 && options.module === ModuleKind.None) {
else if (firstNonAmbientExternalModuleSourceFile && languageVersion < ScriptTarget.ES2015 && options.module === ModuleKind.None) {
// We cannot use createDiagnosticFromNode because nodes do not have parents yet
const span = getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
programDiagnostics.add(createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none));
@@ -1538,7 +1536,7 @@ namespace ts {
if (!options.noEmit && !options.suppressOutputPathCheck) {
const emitHost = getEmitHost();
const emitFilesSeen = createFileMap<boolean>(!host.useCaseSensitiveFileNames() ? key => key.toLocaleLowerCase() : undefined);
forEachExpectedEmitFile(emitHost, (emitFileNames, sourceFiles, isBundledEmit) => {
forEachExpectedEmitFile(emitHost, (emitFileNames) => {
verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen);
verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen);
});
@@ -1550,13 +1548,13 @@ namespace ts {
const emitFilePath = toPath(emitFileName, currentDirectory, getCanonicalFileName);
// Report error if the output overwrites input file
if (filesByName.contains(emitFilePath)) {
createEmitBlockingDiagnostics(emitFileName, emitFilePath, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file);
createEmitBlockingDiagnostics(emitFileName, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file);
}
// Report error if multiple files write into same file
if (emitFilesSeen.contains(emitFilePath)) {
// Already seen the same emit file - report error
createEmitBlockingDiagnostics(emitFileName, emitFilePath, Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files);
createEmitBlockingDiagnostics(emitFileName, Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files);
}
else {
emitFilesSeen.set(emitFilePath, true);
@@ -1565,9 +1563,37 @@ namespace ts {
}
}
function createEmitBlockingDiagnostics(emitFileName: string, emitFilePath: Path, message: DiagnosticMessage) {
function createEmitBlockingDiagnostics(emitFileName: string, message: DiagnosticMessage) {
hasEmitBlockingDiagnostics.set(toPath(emitFileName, currentDirectory, getCanonicalFileName), true);
programDiagnostics.add(createCompilerDiagnostic(message, emitFileName));
}
}
/* @internal */
/**
* Returns a DiagnosticMessage if we won't include a resolved module due to its extension.
* The DiagnosticMessage's parameters are the imported module name, and the filename it resolved to.
* This returns a diagnostic even if the module will be an untyped module.
*/
export function getResolutionDiagnostic(options: CompilerOptions, { extension }: ResolvedModuleFull): DiagnosticMessage | undefined {
switch (extension) {
case Extension.Ts:
case Extension.Dts:
// These are always allowed.
return undefined;
case Extension.Tsx:
return needJsx();
case Extension.Jsx:
return needJsx() || needAllowJs();
case Extension.Js:
return needAllowJs();
}
function needJsx() {
return options.jsx ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set;
}
function needAllowJs() {
return options.allowJs ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_allowJs_is_not_set;
}
}
}
+5 -2
View File
@@ -723,7 +723,7 @@ namespace ts {
return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial);
}
function appendCommentRange(pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: any, comments: CommentRange[]) {
function appendCommentRange(pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[]) {
if (!comments) {
comments = [];
}
@@ -1190,7 +1190,7 @@ namespace ts {
}
function scanBinaryOrOctalDigits(base: number): number {
Debug.assert(base !== 2 || base !== 8, "Expected either base 2 or base 8");
Debug.assert(base === 2 || base === 8, "Expected either base 2 or base 8");
let value = 0;
// For counting number of digits; Valid binaryIntegerLiteral must have at least one binary digit following B or b.
@@ -1799,6 +1799,9 @@ namespace ts {
case CharacterCodes.comma:
pos++;
return token = SyntaxKind.CommaToken;
case CharacterCodes.dot:
pos++;
return token = SyntaxKind.DotToken;
}
if (isIdentifierStart(ch, ScriptTarget.Latest)) {
+13 -9
View File
@@ -34,6 +34,8 @@ namespace ts {
realpath?(path: string): string;
/*@internal*/ getEnvironmentVariable(name: string): string;
/*@internal*/ tryEnableSourceMapsForHost?(): void;
setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
clearTimeout?(timeoutId: any): void;
}
export interface FileWatcher {
@@ -46,13 +48,9 @@ namespace ts {
}
declare var require: any;
declare var module: any;
declare var process: any;
declare var global: any;
declare var __filename: string;
declare var Buffer: {
new (str: string, encoding?: string): any;
};
declare class Enumerator {
public atEnd(): boolean;
@@ -324,7 +322,7 @@ namespace ts {
const platform: string = _os.platform();
const useCaseSensitiveFileNames = isFileSystemCaseSensitive();
function readFile(fileName: string, encoding?: string): string {
function readFile(fileName: string, _encoding?: string): string {
if (!fileExists(fileName)) {
return undefined;
}
@@ -476,6 +474,10 @@ namespace ts {
// Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
// (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
let options: any;
if (!directoryExists(directoryName)) {
return;
}
if (isNode4OrLater() && (process.platform === "win32" || process.platform === "darwin")) {
options = { persistent: true, recursive: !!recursive };
}
@@ -560,7 +562,9 @@ namespace ts {
catch (e) {
// Could not enable source maps.
}
}
},
setTimeout,
clearTimeout
};
return nodeSystem;
}
@@ -572,7 +576,7 @@ namespace ts {
args: ChakraHost.args,
useCaseSensitiveFileNames: !!ChakraHost.useCaseSensitiveFileNames,
write: ChakraHost.echo,
readFile(path: string, encoding?: string) {
readFile(path: string, _encoding?: string) {
// encoding is automatically handled by the implementation in ChakraHost
return ChakraHost.readFile(path);
},
@@ -591,9 +595,9 @@ namespace ts {
getExecutingFilePath: () => ChakraHost.executingFile,
getCurrentDirectory: () => ChakraHost.currentDirectory,
getDirectories: ChakraHost.getDirectories,
getEnvironmentVariable: ChakraHost.getEnvironmentVariable || ((name: string) => ""),
getEnvironmentVariable: ChakraHost.getEnvironmentVariable || (() => ""),
readDirectory: (path: string, extensions?: string[], excludes?: string[], includes?: string[]) => {
const pattern = getFileMatcherPatterns(path, extensions, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory);
const pattern = getFileMatcherPatterns(path, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory);
return ChakraHost.readDirectory(path, extensions, pattern.basePaths, pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern);
},
exit: ChakraHost.quit,
+25 -10
View File
@@ -1,17 +1,19 @@
/// <reference path="visitor.ts" />
/// <reference path="transformers/ts.ts" />
/// <reference path="transformers/jsx.ts" />
/// <reference path="transformers/es7.ts" />
/// <reference path="transformers/es6.ts" />
/// <reference path="transformers/es2017.ts" />
/// <reference path="transformers/es2016.ts" />
/// <reference path="transformers/es2015.ts" />
/// <reference path="transformers/generators.ts" />
/// <reference path="transformers/es5.ts" />
/// <reference path="transformers/module/module.ts" />
/// <reference path="transformers/module/system.ts" />
/// <reference path="transformers/module/es6.ts" />
/// <reference path="transformers/module/es2015.ts" />
/* @internal */
namespace ts {
const moduleTransformerMap = createMap<Transformer>({
[ModuleKind.ES6]: transformES6Module,
[ModuleKind.ES2015]: transformES2015Module,
[ModuleKind.System]: transformSystemModule,
[ModuleKind.AMD]: transformModule,
[ModuleKind.CommonJS]: transformModule,
@@ -109,19 +111,32 @@ namespace ts {
const transformers: Transformer[] = [];
transformers.push(transformTypeScript);
transformers.push(moduleTransformerMap[moduleKind] || moduleTransformerMap[ModuleKind.None]);
if (jsx === JsxEmit.React) {
transformers.push(transformJsx);
}
transformers.push(transformES7);
if (languageVersion < ScriptTarget.ES2017) {
transformers.push(transformES2017);
}
if (languageVersion < ScriptTarget.ES6) {
transformers.push(transformES6);
if (languageVersion < ScriptTarget.ES2016) {
transformers.push(transformES2016);
}
if (languageVersion < ScriptTarget.ES2015) {
transformers.push(transformES2015);
transformers.push(transformGenerators);
}
transformers.push(moduleTransformerMap[moduleKind] || moduleTransformerMap[ModuleKind.None]);
// The ES5 transformer is last so that it can substitute expressions like `exports.default`
// for ES3.
if (languageVersion < ScriptTarget.ES5) {
transformers.push(transformES5);
}
return transformers;
}
@@ -153,7 +168,7 @@ namespace ts {
hoistFunctionDeclaration,
startLexicalEnvironment,
endLexicalEnvironment,
onSubstituteNode: (emitContext, node) => node,
onSubstituteNode: (_emitContext, node) => node,
enableSubstitution,
isSubstitutionEnabled,
onEmitNode: (node, emitContext, emitCallback) => emitCallback(node, emitContext),
@@ -339,4 +354,4 @@ namespace ts {
return statements;
}
}
}
}
+16 -18
View File
@@ -51,7 +51,7 @@ namespace ts {
location = value;
}
flattenDestructuring(context, node, value, location, emitAssignment, emitTempVariableAssignment, visitor);
flattenDestructuring(node, value, location, emitAssignment, emitTempVariableAssignment, visitor);
if (needsValue) {
expressions.push(value);
@@ -87,13 +87,12 @@ namespace ts {
* @param visitor An optional visitor to use to visit expressions.
*/
export function flattenParameterDestructuring(
context: TransformationContext,
node: ParameterDeclaration,
value: Expression,
visitor?: (node: Node) => VisitResult<Node>) {
const declarations: VariableDeclaration[] = [];
flattenDestructuring(context, node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
return declarations;
@@ -123,7 +122,6 @@ namespace ts {
* @param visitor An optional visitor to use to visit expressions.
*/
export function flattenVariableDestructuring(
context: TransformationContext,
node: VariableDeclaration,
value?: Expression,
visitor?: (node: Node) => VisitResult<Node>,
@@ -131,7 +129,7 @@ namespace ts {
const declarations: VariableDeclaration[] = [];
let pendingAssignments: Expression[];
flattenDestructuring(context, node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
return declarations;
@@ -176,37 +174,39 @@ namespace ts {
*
* @param node The VariableDeclaration to flatten.
* @param recordTempVariable A callback used to record new temporary variables.
* @param nameSubstitution An optional callback used to substitute binding names.
* @param createAssignmentCallback An optional callback used to create assignment expressions
* for non-temporary variables.
* @param visitor An optional visitor to use to visit expressions.
*/
export function flattenVariableDestructuringToExpression(
context: TransformationContext,
node: VariableDeclaration,
recordTempVariable: (name: Identifier) => void,
nameSubstitution?: (name: Identifier) => Expression,
createAssignmentCallback?: (name: Identifier, value: Expression, location?: TextRange) => Expression,
visitor?: (node: Node) => VisitResult<Node>) {
const pendingAssignments: Expression[] = [];
flattenDestructuring(context, node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment, visitor);
flattenDestructuring(node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment, visitor);
const expression = inlineExpressions(pendingAssignments);
aggregateTransformFlags(expression);
return expression;
function emitAssignment(name: Identifier, value: Expression, location: TextRange, original: Node) {
const left = nameSubstitution && nameSubstitution(name) || name;
emitPendingAssignment(left, value, location, original);
const expression = createAssignmentCallback
? createAssignmentCallback(name, value, location)
: createAssignment(name, value, location);
emitPendingAssignment(expression, original);
}
function emitTempVariableAssignment(value: Expression, location: TextRange) {
const name = createTempVariable(recordTempVariable);
emitPendingAssignment(name, value, location, /*original*/ undefined);
emitPendingAssignment(createAssignment(name, value, location), /*original*/ undefined);
return name;
}
function emitPendingAssignment(name: Expression, value: Expression, location: TextRange, original: Node) {
const expression = createAssignment(name, value, location);
function emitPendingAssignment(expression: Expression, original: Node) {
expression.original = original;
// NOTE: this completely disables source maps, but aligns with the behavior of
@@ -214,13 +214,11 @@ namespace ts {
setEmitFlags(expression, EmitFlags.NoNestedSourceMaps);
pendingAssignments.push(expression);
return expression;
}
}
function flattenDestructuring(
context: TransformationContext,
root: BindingElement | BinaryExpression,
root: VariableDeclaration | ParameterDeclaration | BindingElement | BinaryExpression,
value: Expression,
location: TextRange,
emitAssignment: (name: Identifier, value: Expression, location: TextRange, original: Node) => void,
@@ -320,7 +318,7 @@ namespace ts {
}
}
function emitBindingElement(target: BindingElement, value: Expression) {
function emitBindingElement(target: VariableDeclaration | ParameterDeclaration | BindingElement, value: Expression) {
// Any temporary assignments needed to emit target = value should point to target
const initializer = visitor ? visitNode(target.initializer, visitor, isExpression) : target.initializer;
if (initializer) {
@@ -4,7 +4,7 @@
/*@internal*/
namespace ts {
const enum ES6SubstitutionFlags {
const enum ES2015SubstitutionFlags {
/** Enables substitutions for captured `this` */
CapturedThis = 1 << 0,
/** Enables substitutions for block-scoped bindings. */
@@ -163,7 +163,7 @@ namespace ts {
ReplaceWithReturn,
}
export function transformES6(context: TransformationContext) {
export function transformES2015(context: TransformationContext) {
const {
startLexicalEnvironment,
endLexicalEnvironment,
@@ -186,6 +186,7 @@ namespace ts {
let enclosingFunction: FunctionLikeDeclaration;
let enclosingNonArrowFunction: FunctionLikeDeclaration;
let enclosingNonAsyncFunctionBody: FunctionLikeDeclaration | ClassElement;
let isInConstructorWithCapturedSuper: boolean;
/**
* Used to track if we are emitting body of the converted loop
@@ -197,7 +198,7 @@ namespace ts {
* They are persisted between each SourceFile transformation and should not
* be reset.
*/
let enabledSubstitutions: ES6SubstitutionFlags;
let enabledSubstitutions: ES2015SubstitutionFlags;
return transformSourceFile;
@@ -231,14 +232,17 @@ namespace ts {
const savedCurrentParent = currentParent;
const savedCurrentNode = currentNode;
const savedConvertedLoopState = convertedLoopState;
const savedIsInConstructorWithCapturedSuper = isInConstructorWithCapturedSuper;
if (nodeStartsNewLexicalEnvironment(node)) {
// don't treat content of nodes that start new lexical environment as part of converted loop copy
// don't treat content of nodes that start new lexical environment as part of converted loop copy or constructor body
isInConstructorWithCapturedSuper = false;
convertedLoopState = undefined;
}
onBeforeVisitNode(node);
const visited = f(node);
isInConstructorWithCapturedSuper = savedIsInConstructorWithCapturedSuper;
convertedLoopState = savedConvertedLoopState;
enclosingFunction = savedEnclosingFunction;
enclosingNonArrowFunction = savedEnclosingNonArrowFunction;
@@ -251,17 +255,31 @@ namespace ts {
return visited;
}
function returnCapturedThis(node: Node): Node {
return setOriginalNode(createReturn(createIdentifier("_this")), node);
}
function isReturnVoidStatementInConstructorWithCapturedSuper(node: Node): boolean {
return isInConstructorWithCapturedSuper && node.kind === SyntaxKind.ReturnStatement && !(<ReturnStatement>node).expression;
}
function shouldCheckNode(node: Node): boolean {
return (node.transformFlags & TransformFlags.ES6) !== 0 ||
return (node.transformFlags & TransformFlags.ES2015) !== 0 ||
node.kind === SyntaxKind.LabeledStatement ||
(isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node));
}
function visitorWorker(node: Node): VisitResult<Node> {
if (shouldCheckNode(node)) {
if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
return returnCapturedThis(<ReturnStatement>node);
}
else if (shouldCheckNode(node)) {
return visitJavaScript(node);
}
else if (node.transformFlags & TransformFlags.ContainsES6) {
else if (node.transformFlags & TransformFlags.ContainsES2015 || (isInConstructorWithCapturedSuper && !isExpression(node))) {
// we want to dive in this branch either if node has children with ES2015 specific syntax
// or we are inside constructor that captures result of the super call so all returns without expression should be
// rewritten. Note: we skip expressions since returns should never appear there
return visitEachChild(node, visitor, context);
}
else {
@@ -283,6 +301,7 @@ namespace ts {
function visitNodesInConvertedLoop(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.ReturnStatement:
node = isReturnVoidStatementInConstructorWithCapturedSuper(node) ? returnCapturedThis(node) : node;
return visitReturnStatement(<ReturnStatement>node);
case SyntaxKind.VariableStatement:
@@ -308,8 +327,8 @@ namespace ts {
function visitJavaScript(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.ExportKeyword:
return node;
case SyntaxKind.StaticKeyword:
return undefined; // elide static keyword
case SyntaxKind.ClassDeclaration:
return visitClassDeclaration(<ClassDeclaration>node);
@@ -362,6 +381,9 @@ namespace ts {
case SyntaxKind.ObjectLiteralExpression:
return visitObjectLiteralExpression(<ObjectLiteralExpression>node);
case SyntaxKind.CatchClause:
return visitCatchClause(<CatchClause>node);
case SyntaxKind.ShorthandPropertyAssignment:
return visitShorthandPropertyAssignment(<ShorthandPropertyAssignment>node);
@@ -396,7 +418,7 @@ namespace ts {
return visitYieldExpression(<YieldExpression>node);
case SyntaxKind.SuperKeyword:
return visitSuperKeyword(<PrimaryExpression>node);
return visitSuperKeyword();
case SyntaxKind.YieldExpression:
// `yield` will be handled by a generators transform.
@@ -584,47 +606,39 @@ namespace ts {
// return C;
// }());
const modifierFlags = getModifierFlags(node);
const isExported = modifierFlags & ModifierFlags.Export;
const isDefault = modifierFlags & ModifierFlags.Default;
// Add an `export` modifier to the statement if needed (for `--target es5 --module es6`)
const modifiers = isExported && !isDefault
? filter(node.modifiers, isExportModifier)
: undefined;
const statement = createVariableStatement(
modifiers,
createVariableDeclarationList([
createVariableDeclaration(
getDeclarationName(node, /*allowComments*/ true),
/*type*/ undefined,
transformClassLikeDeclarationToExpression(node)
)
]),
/*location*/ node
const variable = createVariableDeclaration(
getLocalName(node, /*allowComments*/ true),
/*type*/ undefined,
transformClassLikeDeclarationToExpression(node)
);
setOriginalNode(variable, node);
const statements: Statement[] = [];
const statement = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([variable]), /*location*/ node);
setOriginalNode(statement, node);
startOnNewLine(statement);
statements.push(statement);
// Add an `export default` statement for default exports (for `--target es5 --module es6`)
if (isExported && isDefault) {
const statements: Statement[] = [statement];
statements.push(createExportAssignment(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*isExportEquals*/ false,
getDeclarationName(node, /*allowComments*/ false)
));
return statements;
if (hasModifier(node, ModifierFlags.Export)) {
const exportStatement = hasModifier(node, ModifierFlags.Default)
? createExportDefault(getLocalName(node))
: createExternalModuleExport(getLocalName(node));
setOriginalNode(exportStatement, statement);
statements.push(exportStatement);
}
return statement;
}
const emitFlags = getEmitFlags(node);
if ((emitFlags & EmitFlags.HasEndOfDeclarationMarker) === 0) {
// Add a DeclarationMarker as a marker for the end of the declaration
statements.push(createEndOfDeclarationMarker(node));
setEmitFlags(statement, emitFlags | EmitFlags.HasEndOfDeclarationMarker);
}
function isExportModifier(node: Modifier) {
return node.kind === SyntaxKind.ExportKeyword;
return singleOrMany(statements);
}
/**
@@ -681,10 +695,11 @@ namespace ts {
const extendsClauseElement = getClassExtendsHeritageClauseElement(node);
const classFunction = createFunctionExpression(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
extendsClauseElement ? [createParameter("_super")] : [],
extendsClauseElement ? [createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "_super")] : [],
/*type*/ undefined,
transformClassBody(node, extendsClauseElement)
);
@@ -763,7 +778,7 @@ namespace ts {
if (extendsClauseElement) {
statements.push(
createStatement(
createExtendsHelper(currentSourceFile.externalHelpersModuleName, getDeclarationName(node)),
createExtendsHelper(currentSourceFile.externalHelpersModuleName, getLocalName(node)),
/*location*/ extendsClauseElement
)
);
@@ -860,7 +875,10 @@ namespace ts {
}
if (constructor) {
const body = saveStateAndInvoke(constructor, constructor => visitNodes(constructor.body.statements, visitor, isStatement, /*start*/ statementOffset));
const body = saveStateAndInvoke(constructor, constructor => {
isInConstructorWithCapturedSuper = superCaptureStatus === SuperCaptureResult.ReplaceSuperCapture;
return visitNodes(constructor.body.statements, visitor, isStatement, /*start*/ statementOffset);
});
addRange(statements, body);
}
@@ -982,7 +1000,7 @@ namespace ts {
if (statementOffset < ctorStatements.length) {
firstStatement = ctorStatements[statementOffset];
if (firstStatement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((firstStatement as ExpressionStatement).expression)) {
if (firstStatement.kind === SyntaxKind.ExpressionStatement && isSuperCall((firstStatement as ExpressionStatement).expression)) {
const superCall = (firstStatement as ExpressionStatement).expression as CallExpression;
superCallExpression = setOriginalNode(
saveStateAndInvoke(superCall, visitImmediateSuperCallInBody),
@@ -1034,7 +1052,12 @@ namespace ts {
// evaluated inside the function body.
return setOriginalNode(
createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
getGeneratedNameForNode(node),
/*questionToken*/ undefined,
/*type*/ undefined,
/*initializer*/ undefined,
/*location*/ node
),
@@ -1045,7 +1068,12 @@ namespace ts {
// Initializers are elided
return setOriginalNode(
createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
node.name,
/*questionToken*/ undefined,
/*type*/ undefined,
/*initializer*/ undefined,
/*location*/ node
),
@@ -1117,7 +1145,7 @@ namespace ts {
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
flattenParameterDestructuring(context, parameter, temp, visitor)
flattenParameterDestructuring(parameter, temp, visitor)
)
),
EmitFlags.CustomPrologue
@@ -1416,6 +1444,7 @@ namespace ts {
if (getAccessor) {
const getterFunction = transformFunctionLikeToExpression(getAccessor, /*location*/ undefined, /*name*/ undefined);
setSourceMapRange(getterFunction, getSourceMapRange(getAccessor));
setEmitFlags(getterFunction, EmitFlags.NoLeadingComments);
const getter = createPropertyAssignment("get", getterFunction);
setCommentRange(getter, getCommentRange(getAccessor));
properties.push(getter);
@@ -1424,6 +1453,7 @@ namespace ts {
if (setAccessor) {
const setterFunction = transformFunctionLikeToExpression(setAccessor, /*location*/ undefined, /*name*/ undefined);
setSourceMapRange(setterFunction, getSourceMapRange(setAccessor));
setEmitFlags(setterFunction, EmitFlags.NoLeadingComments);
const setter = createPropertyAssignment("set", setterFunction);
setCommentRange(setter, getCommentRange(setAccessor));
properties.push(setter);
@@ -1509,6 +1539,7 @@ namespace ts {
const expression = setOriginalNode(
createFunctionExpression(
/*modifiers*/ undefined,
node.asteriskToken,
name,
/*typeParameters*/ undefined,
@@ -1686,7 +1717,7 @@ namespace ts {
if (decl.initializer) {
let assignment: Expression;
if (isBindingPattern(decl.name)) {
assignment = flattenVariableDestructuringToExpression(context, decl, hoistVariableDeclaration, /*nameSubstitution*/ undefined, visitor);
assignment = flattenVariableDestructuringToExpression(decl, hoistVariableDeclaration, /*createAssignmentCallback*/ undefined, visitor);
}
else {
assignment = createBinary(<Identifier>decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression));
@@ -1839,7 +1870,7 @@ namespace ts {
if (isBindingPattern(node.name)) {
const recordTempVariablesInLine = !enclosingVariableStatement
|| !hasModifier(enclosingVariableStatement, ModifierFlags.Export);
return flattenVariableDestructuring(context, node, /*value*/ undefined, visitor,
return flattenVariableDestructuring(node, /*value*/ undefined, visitor,
recordTempVariablesInLine ? undefined : hoistVariableDeclaration);
}
@@ -1942,7 +1973,6 @@ namespace ts {
// This works whether the declaration is a var, let, or const.
// It will use rhsIterationValue _a[_i] as the initializer.
const declarations = flattenVariableDestructuring(
context,
firstOriginalDeclaration,
createElementAccess(rhsReference, counter),
visitor
@@ -1970,13 +2000,16 @@ namespace ts {
statements.push(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
/*type*/ undefined,
createElementAccess(rhsReference, counter)
)
], /*location*/ moveRangePos(initializer, -1)),
setOriginalNode(
createVariableDeclarationList([
createVariableDeclaration(
firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
/*type*/ undefined,
createElementAccess(rhsReference, counter)
)
], /*location*/ moveRangePos(initializer, -1)),
initializer
),
/*location*/ moveRangeEnd(initializer, -1)
)
);
@@ -2038,10 +2071,13 @@ namespace ts {
setEmitFlags(body, EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps);
const forStatement = createFor(
createVariableDeclarationList([
createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0), /*location*/ moveRangePos(node.expression, -1)),
createVariableDeclaration(rhsReference, /*type*/ undefined, expression, /*location*/ node.expression)
], /*location*/ node.expression),
setEmitFlags(
createVariableDeclarationList([
createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0), /*location*/ moveRangePos(node.expression, -1)),
createVariableDeclaration(rhsReference, /*type*/ undefined, expression, /*location*/ node.expression)
], /*location*/ node.expression),
EmitFlags.NoHoisting
),
createLessThan(
counter,
createPropertyAccess(rhsReference, "length"),
@@ -2233,24 +2269,28 @@ namespace ts {
const convertedLoopVariable =
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
[
createVariableDeclaration(
functionName,
/*type*/ undefined,
setEmitFlags(
createFunctionExpression(
isAsyncBlockContainingAwait ? createToken(SyntaxKind.AsteriskToken) : undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
loopParameters,
/*type*/ undefined,
<Block>loopBody
),
loopBodyFlags
setEmitFlags(
createVariableDeclarationList(
[
createVariableDeclaration(
functionName,
/*type*/ undefined,
setEmitFlags(
createFunctionExpression(
/*modifiers*/ undefined,
isAsyncBlockContainingAwait ? createToken(SyntaxKind.AsteriskToken) : undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
loopParameters,
/*type*/ undefined,
<Block>loopBody
),
loopBodyFlags
)
)
)
]
]
),
EmitFlags.NoHoisting
)
);
@@ -2501,7 +2541,7 @@ namespace ts {
}
}
else {
loopParameters.push(createParameter(name));
loopParameters.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
if (resolver.getNodeCheckFlags(decl) & NodeCheckFlags.NeedsLoopOutParameter) {
const outParamName = createUniqueName("out_" + name.text);
loopOutParameters.push({ originalName: name, outParamName });
@@ -2534,15 +2574,15 @@ namespace ts {
break;
case SyntaxKind.PropertyAssignment:
expressions.push(transformPropertyAssignmentToExpression(node, <PropertyAssignment>property, receiver, node.multiLine));
expressions.push(transformPropertyAssignmentToExpression(<PropertyAssignment>property, receiver, node.multiLine));
break;
case SyntaxKind.ShorthandPropertyAssignment:
expressions.push(transformShorthandPropertyAssignmentToExpression(node, <ShorthandPropertyAssignment>property, receiver, node.multiLine));
expressions.push(transformShorthandPropertyAssignmentToExpression(<ShorthandPropertyAssignment>property, receiver, node.multiLine));
break;
case SyntaxKind.MethodDeclaration:
expressions.push(transformObjectLiteralMethodDeclarationToExpression(node, <MethodDeclaration>property, receiver, node.multiLine));
expressions.push(transformObjectLiteralMethodDeclarationToExpression(<MethodDeclaration>property, receiver, node.multiLine));
break;
default:
@@ -2559,7 +2599,7 @@ namespace ts {
* @param property The PropertyAssignment node.
* @param receiver The receiver for the assignment.
*/
function transformPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: PropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
function transformPropertyAssignmentToExpression(property: PropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
const expression = createAssignment(
createMemberAccessForPropertyName(
receiver,
@@ -2581,7 +2621,7 @@ namespace ts {
* @param property The ShorthandPropertyAssignment node.
* @param receiver The receiver for the assignment.
*/
function transformShorthandPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: ShorthandPropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
function transformShorthandPropertyAssignmentToExpression(property: ShorthandPropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
const expression = createAssignment(
createMemberAccessForPropertyName(
receiver,
@@ -2603,7 +2643,7 @@ namespace ts {
* @param method The MethodDeclaration node.
* @param receiver The receiver for the assignment.
*/
function transformObjectLiteralMethodDeclarationToExpression(node: ObjectLiteralExpression, method: MethodDeclaration, receiver: Expression, startsOnNewLine: boolean) {
function transformObjectLiteralMethodDeclarationToExpression(method: MethodDeclaration, receiver: Expression, startsOnNewLine: boolean) {
const expression = createAssignment(
createMemberAccessForPropertyName(
receiver,
@@ -2618,6 +2658,24 @@ namespace ts {
return expression;
}
function visitCatchClause(node: CatchClause): CatchClause {
Debug.assert(isBindingPattern(node.variableDeclaration.name));
const temp = createTempVariable(undefined);
const newVariableDeclaration = createVariableDeclaration(temp, undefined, undefined, node.variableDeclaration);
const vars = flattenVariableDestructuring(node.variableDeclaration, temp, visitor);
const list = createVariableDeclarationList(vars, /*location*/node.variableDeclaration, /*flags*/node.variableDeclaration.flags);
const destructure = createVariableStatement(undefined, list);
return updateCatchClause(node, newVariableDeclaration, addStatementToStartOfBlock(node.block, destructure));
}
function addStatementToStartOfBlock(block: Block, statement: Statement): Block {
const transformedStatements = visitNodes(block.statements, visitor, isStatement);
return updateBlock(block, [statement].concat(transformedStatements));
}
/**
* Visits a MethodDeclaration of an ObjectLiteralExpression and transforms it into a
* PropertyAssignment.
@@ -2793,7 +2851,7 @@ namespace ts {
// expressions into an array literal.
const numElements = elements.length;
const segments = flatten(
spanMap(elements, partitionSpreadElement, (partition, visitPartition, start, end) =>
spanMap(elements, partitionSpreadElement, (partition, visitPartition, _start, end) =>
visitPartition(partition, multiLine, hasTrailingComma && end === numElements)
)
);
@@ -2815,7 +2873,7 @@ namespace ts {
: visitSpanOfNonSpreadElements;
}
function visitSpanOfSpreadElements(chunk: Expression[], multiLine: boolean, hasTrailingComma: boolean): VisitResult<Expression> {
function visitSpanOfSpreadElements(chunk: Expression[]): VisitResult<Expression> {
return map(chunk, visitExpressionOfSpreadElement);
}
@@ -3004,7 +3062,7 @@ namespace ts {
/**
* Visits the `super` keyword
*/
function visitSuperKeyword(node: PrimaryExpression): LeftHandSideExpression {
function visitSuperKeyword(): LeftHandSideExpression {
return enclosingNonAsyncFunctionBody
&& isClassElement(enclosingNonAsyncFunctionBody)
&& !hasModifier(enclosingNonAsyncFunctionBody, ModifierFlags.Static)
@@ -3034,7 +3092,7 @@ namespace ts {
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
const savedEnclosingFunction = enclosingFunction;
if (enabledSubstitutions & ES6SubstitutionFlags.CapturedThis && isFunctionLike(node)) {
if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis && isFunctionLike(node)) {
// If we are tracking a captured `this`, keep track of the enclosing function.
enclosingFunction = node;
}
@@ -3049,8 +3107,8 @@ namespace ts {
* contains block-scoped bindings (e.g. `let` or `const`).
*/
function enableSubstitutionsForBlockScopedBindings() {
if ((enabledSubstitutions & ES6SubstitutionFlags.BlockScopedBindings) === 0) {
enabledSubstitutions |= ES6SubstitutionFlags.BlockScopedBindings;
if ((enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) === 0) {
enabledSubstitutions |= ES2015SubstitutionFlags.BlockScopedBindings;
context.enableSubstitution(SyntaxKind.Identifier);
}
}
@@ -3060,8 +3118,8 @@ namespace ts {
* contains a captured `this`.
*/
function enableSubstitutionsForCapturedThis() {
if ((enabledSubstitutions & ES6SubstitutionFlags.CapturedThis) === 0) {
enabledSubstitutions |= ES6SubstitutionFlags.CapturedThis;
if ((enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis) === 0) {
enabledSubstitutions |= ES2015SubstitutionFlags.CapturedThis;
context.enableSubstitution(SyntaxKind.ThisKeyword);
context.enableEmitNotification(SyntaxKind.Constructor);
context.enableEmitNotification(SyntaxKind.MethodDeclaration);
@@ -3076,9 +3134,8 @@ namespace ts {
/**
* Hooks node substitutions.
*
* @param emitContext The context for the emitter.
* @param node The node to substitute.
* @param isExpression A value indicating whether the node is to be used in an expression
* position.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
@@ -3100,7 +3157,7 @@ namespace ts {
function substituteIdentifier(node: Identifier) {
// Only substitute the identifier if we have enabled substitutions for block-scoped
// bindings.
if (enabledSubstitutions & ES6SubstitutionFlags.BlockScopedBindings) {
if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) {
const original = getParseTreeNode(node, isIdentifier);
if (original && isNameOfDeclarationWithCollidingName(original)) {
return getGeneratedNameForNode(original);
@@ -3153,7 +3210,7 @@ namespace ts {
* @param node An Identifier node.
*/
function substituteExpressionIdentifier(node: Identifier): Identifier {
if (enabledSubstitutions & ES6SubstitutionFlags.BlockScopedBindings) {
if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) {
const declaration = resolver.getReferencedDeclarationWithCollidingName(node);
if (declaration) {
return getGeneratedNameForNode(declaration.name);
@@ -3169,7 +3226,7 @@ namespace ts {
* @param node The ThisKeyword node.
*/
function substituteThisKeyword(node: PrimaryExpression): PrimaryExpression {
if (enabledSubstitutions & ES6SubstitutionFlags.CapturedThis
if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis
&& enclosingFunction
&& getEmitFlags(enclosingFunction) & EmitFlags.CapturesThis) {
return createIdentifier("_this", /*location*/ node);
@@ -3178,45 +3235,6 @@ namespace ts {
return node;
}
/**
* Gets the local name for a declaration for use in expressions.
*
* A local name will *never* be prefixed with an module or namespace export modifier like
* "exports.".
*
* @param node The declaration.
* @param allowComments A value indicating whether comments may be emitted for the name.
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
*/
function getLocalName(node: ClassDeclaration | ClassExpression | FunctionDeclaration, allowComments?: boolean, allowSourceMaps?: boolean) {
return getDeclarationName(node, allowComments, allowSourceMaps, EmitFlags.LocalName);
}
/**
* Gets the name of a declaration, without source map or comments.
*
* @param node The declaration.
* @param allowComments Allow comments for the name.
*/
function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
if (node.name && !isGeneratedIdentifier(node.name)) {
const name = getMutableClone(node.name);
emitFlags |= getEmitFlags(node.name);
if (!allowSourceMaps) {
emitFlags |= EmitFlags.NoSourceMap;
}
if (!allowComments) {
emitFlags |= EmitFlags.NoComments;
}
if (emitFlags) {
setEmitFlags(name, emitFlags);
}
return name;
}
return getGeneratedNameForNode(node);
}
function getClassMemberPrefix(node: ClassExpression | ClassDeclaration, member: ClassElement) {
const expression = getLocalName(node);
return hasModifier(member, ModifierFlags.Static) ? expression : createPropertyAccess(expression, "prototype");
@@ -3256,4 +3274,4 @@ namespace ts {
return isIdentifier(expression) && expression === parameter.name;
}
}
}
}
@@ -3,7 +3,7 @@
/*@internal*/
namespace ts {
export function transformES7(context: TransformationContext) {
export function transformES2016(context: TransformationContext) {
const { hoistVariableDeclaration } = context;
return transformSourceFile;
@@ -17,10 +17,10 @@ namespace ts {
}
function visitor(node: Node): VisitResult<Node> {
if (node.transformFlags & TransformFlags.ES7) {
if (node.transformFlags & TransformFlags.ES2016) {
return visitorWorker(node);
}
else if (node.transformFlags & TransformFlags.ContainsES7) {
else if (node.transformFlags & TransformFlags.ContainsES2016) {
return visitEachChild(node, visitor, context);
}
else {
@@ -40,7 +40,7 @@ namespace ts {
}
function visitBinaryExpression(node: BinaryExpression): Expression {
// We are here because ES7 adds support for the exponentiation operator.
// We are here because ES2016 adds support for the exponentiation operator.
const left = visitNode(node.left, visitor, isExpression);
const right = visitNode(node.right, visitor, isExpression);
if (node.operatorToken.kind === SyntaxKind.AsteriskAsteriskEqualsToken) {
@@ -98,4 +98,4 @@ namespace ts {
}
}
}
}
}
+512
View File
@@ -0,0 +1,512 @@
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
/*@internal*/
namespace ts {
type SuperContainer = ClassDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration;
export function transformES2017(context: TransformationContext) {
const enum ES2017SubstitutionFlags {
/** Enables substitutions for async methods with `super` calls. */
AsyncMethodsWithSuper = 1 << 0
}
const {
startLexicalEnvironment,
endLexicalEnvironment,
} = context;
const resolver = context.getEmitResolver();
const compilerOptions = context.getCompilerOptions();
const languageVersion = getEmitScriptTarget(compilerOptions);
// These variables contain state that changes as we descend into the tree.
let currentSourceFileExternalHelpersModuleName: Identifier;
/**
* Keeps track of whether expression substitution has been enabled for specific edge cases.
* They are persisted between each SourceFile transformation and should not be reset.
*/
let enabledSubstitutions: ES2017SubstitutionFlags;
/**
* Keeps track of whether we are within any containing namespaces when performing
* just-in-time substitution while printing an expression identifier.
*/
let applicableSubstitutions: ES2017SubstitutionFlags;
/**
* This keeps track of containers where `super` is valid, for use with
* just-in-time substitution for `super` expressions inside of async methods.
*/
let currentSuperContainer: SuperContainer;
// Save the previous transformation hooks.
const previousOnEmitNode = context.onEmitNode;
const previousOnSubstituteNode = context.onSubstituteNode;
// Set new transformation hooks.
context.onEmitNode = onEmitNode;
context.onSubstituteNode = onSubstituteNode;
let currentScope: SourceFile | Block | ModuleBlock | CaseBlock;
return transformSourceFile;
function transformSourceFile(node: SourceFile) {
if (isDeclarationFile(node)) {
return node;
}
currentSourceFileExternalHelpersModuleName = node.externalHelpersModuleName;
return visitEachChild(node, visitor, context);
}
function visitor(node: Node): VisitResult<Node> {
if (node.transformFlags & TransformFlags.ES2017) {
return visitorWorker(node);
}
else if (node.transformFlags & TransformFlags.ContainsES2017) {
return visitEachChild(node, visitor, context);
}
return node;
}
function visitorWorker(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.AsyncKeyword:
// ES2017 async modifier should be elided for targets < ES2017
return undefined;
case SyntaxKind.AwaitExpression:
// ES2017 'await' expressions must be transformed for targets < ES2017.
return visitAwaitExpression(<AwaitExpression>node);
case SyntaxKind.MethodDeclaration:
// ES2017 method declarations may be 'async'
return visitMethodDeclaration(<MethodDeclaration>node);
case SyntaxKind.FunctionDeclaration:
// ES2017 function declarations may be 'async'
return visitFunctionDeclaration(<FunctionDeclaration>node);
case SyntaxKind.FunctionExpression:
// ES2017 function expressions may be 'async'
return visitFunctionExpression(<FunctionExpression>node);
case SyntaxKind.ArrowFunction:
// ES2017 arrow functions may be 'async'
return visitArrowFunction(<ArrowFunction>node);
default:
Debug.failBadSyntaxKind(node);
return node;
}
}
/**
* Visits an await expression.
*
* This function will be called any time a ES2017 await expression is encountered.
*
* @param node The await expression node.
*/
function visitAwaitExpression(node: AwaitExpression): Expression {
return setOriginalNode(
createYield(
/*asteriskToken*/ undefined,
visitNode(node.expression, visitor, isExpression),
/*location*/ node
),
node
);
}
/**
* Visits a method declaration of a class.
*
* This function will be called when one of the following conditions are met:
* - The node is marked as async
*
* @param node The method node.
*/
function visitMethodDeclaration(node: MethodDeclaration) {
if (!isAsyncFunctionLike(node)) {
return node;
}
const method = createMethod(
/*decorators*/ undefined,
visitNodes(node.modifiers, visitor, isModifier),
node.asteriskToken,
node.name,
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
transformFunctionBody(node),
/*location*/ node
);
// While we emit the source map for the node after skipping decorators and modifiers,
// we need to emit the comments for the original range.
setCommentRange(method, node);
setSourceMapRange(method, moveRangePastDecorators(node));
setOriginalNode(method, node);
return method;
}
/**
* Visits a function declaration.
*
* This function will be called when one of the following conditions are met:
* - The node is marked async
*
* @param node The function node.
*/
function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult<Statement> {
if (!isAsyncFunctionLike(node)) {
return node;
}
const func = createFunctionDeclaration(
/*decorators*/ undefined,
visitNodes(node.modifiers, visitor, isModifier),
node.asteriskToken,
node.name,
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
transformFunctionBody(node),
/*location*/ node
);
setOriginalNode(func, node);
return func;
}
/**
* Visits a function expression node.
*
* This function will be called when one of the following conditions are met:
* - The node is marked async
*
* @param node The function expression node.
*/
function visitFunctionExpression(node: FunctionExpression): Expression {
if (!isAsyncFunctionLike(node)) {
return node;
}
if (nodeIsMissing(node.body)) {
return createOmittedExpression();
}
const func = createFunctionExpression(
/*modifiers*/ undefined,
node.asteriskToken,
node.name,
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
transformFunctionBody(node),
/*location*/ node
);
setOriginalNode(func, node);
return func;
}
/**
* @remarks
* This function will be called when one of the following conditions are met:
* - The node is marked async
*/
function visitArrowFunction(node: ArrowFunction) {
if (!isAsyncFunctionLike(node)) {
return node;
}
const func = createArrowFunction(
visitNodes(node.modifiers, visitor, isModifier),
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
node.equalsGreaterThanToken,
transformConciseBody(node),
/*location*/ node
);
setOriginalNode(func, node);
return func;
}
function transformFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody {
return <FunctionBody>transformAsyncFunctionBody(node);
}
function transformConciseBody(node: ArrowFunction): ConciseBody {
return transformAsyncFunctionBody(node);
}
function transformFunctionBodyWorker(body: Block, start = 0) {
const savedCurrentScope = currentScope;
currentScope = body;
startLexicalEnvironment();
const statements = visitNodes(body.statements, visitor, isStatement, start);
const visited = updateBlock(body, statements);
const declarations = endLexicalEnvironment();
currentScope = savedCurrentScope;
return mergeFunctionBodyLexicalEnvironment(visited, declarations);
}
function transformAsyncFunctionBody(node: FunctionLikeDeclaration): ConciseBody | FunctionBody {
const original = getOriginalNode(node, isFunctionLike);
const nodeType = original.type;
const promiseConstructor = languageVersion < ScriptTarget.ES2015 ? getPromiseConstructor(nodeType) : undefined;
const isArrowFunction = node.kind === SyntaxKind.ArrowFunction;
const hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0;
// An async function is emit as an outer function that calls an inner
// generator function. To preserve lexical bindings, we pass the current
// `this` and `arguments` objects to `__awaiter`. The generator function
// passed to `__awaiter` is executed inside of the callback to the
// promise constructor.
if (!isArrowFunction) {
const statements: Statement[] = [];
const statementOffset = addPrologueDirectives(statements, (<Block>node.body).statements, /*ensureUseStrict*/ false, visitor);
statements.push(
createReturn(
createAwaiterHelper(
currentSourceFileExternalHelpersModuleName,
hasLexicalArguments,
promiseConstructor,
transformFunctionBodyWorker(<Block>node.body, statementOffset)
)
)
);
const block = createBlock(statements, /*location*/ node.body, /*multiLine*/ true);
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
// This step isn't needed if we eventually transform this to ES5.
if (languageVersion >= ScriptTarget.ES2015) {
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) {
enableSubstitutionForAsyncMethodsWithSuper();
setEmitFlags(block, EmitFlags.EmitAdvancedSuperHelper);
}
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) {
enableSubstitutionForAsyncMethodsWithSuper();
setEmitFlags(block, EmitFlags.EmitSuperHelper);
}
}
return block;
}
else {
return createAwaiterHelper(
currentSourceFileExternalHelpersModuleName,
hasLexicalArguments,
promiseConstructor,
<Block>transformConciseBodyWorker(node.body, /*forceBlockFunctionBody*/ true)
);
}
}
function transformConciseBodyWorker(body: Block | Expression, forceBlockFunctionBody: boolean) {
if (isBlock(body)) {
return transformFunctionBodyWorker(body);
}
else {
startLexicalEnvironment();
const visited: Expression | Block = visitNode(body, visitor, isConciseBody);
const declarations = endLexicalEnvironment();
const merged = mergeFunctionBodyLexicalEnvironment(visited, declarations);
if (forceBlockFunctionBody && !isBlock(merged)) {
return createBlock([
createReturn(<Expression>merged)
]);
}
else {
return merged;
}
}
}
function getPromiseConstructor(type: TypeNode) {
if (type) {
const typeName = getEntityNameFromTypeNode(type);
if (typeName && isEntityName(typeName)) {
const serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
if (serializationKind === TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue
|| serializationKind === TypeReferenceSerializationKind.Unknown) {
return typeName;
}
}
}
return undefined;
}
function enableSubstitutionForAsyncMethodsWithSuper() {
if ((enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper) === 0) {
enabledSubstitutions |= ES2017SubstitutionFlags.AsyncMethodsWithSuper;
// We need to enable substitutions for call, property access, and element access
// if we need to rewrite super calls.
context.enableSubstitution(SyntaxKind.CallExpression);
context.enableSubstitution(SyntaxKind.PropertyAccessExpression);
context.enableSubstitution(SyntaxKind.ElementAccessExpression);
// We need to be notified when entering and exiting declarations that bind super.
context.enableEmitNotification(SyntaxKind.ClassDeclaration);
context.enableEmitNotification(SyntaxKind.MethodDeclaration);
context.enableEmitNotification(SyntaxKind.GetAccessor);
context.enableEmitNotification(SyntaxKind.SetAccessor);
context.enableEmitNotification(SyntaxKind.Constructor);
}
}
function substituteExpression(node: Expression) {
switch (node.kind) {
case SyntaxKind.PropertyAccessExpression:
return substitutePropertyAccessExpression(<PropertyAccessExpression>node);
case SyntaxKind.ElementAccessExpression:
return substituteElementAccessExpression(<ElementAccessExpression>node);
case SyntaxKind.CallExpression:
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper) {
return substituteCallExpression(<CallExpression>node);
}
break;
}
return node;
}
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) {
const flags = getSuperContainerAsyncMethodFlags();
if (flags) {
return createSuperAccessInAsyncMethod(
createLiteral(node.name.text),
flags,
node
);
}
}
return node;
}
function substituteElementAccessExpression(node: ElementAccessExpression) {
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) {
const flags = getSuperContainerAsyncMethodFlags();
if (flags) {
return createSuperAccessInAsyncMethod(
node.argumentExpression,
flags,
node
);
}
}
return node;
}
function substituteCallExpression(node: CallExpression): Expression {
const expression = node.expression;
if (isSuperProperty(expression)) {
const flags = getSuperContainerAsyncMethodFlags();
if (flags) {
const argumentExpression = isPropertyAccessExpression(expression)
? substitutePropertyAccessExpression(expression)
: substituteElementAccessExpression(expression);
return createCall(
createPropertyAccess(argumentExpression, "call"),
/*typeArguments*/ undefined,
[
createThis(),
...node.arguments
]
);
}
}
return node;
}
function isSuperContainer(node: Node): node is SuperContainer {
const kind = node.kind;
return kind === SyntaxKind.ClassDeclaration
|| kind === SyntaxKind.Constructor
|| kind === SyntaxKind.MethodDeclaration
|| kind === SyntaxKind.GetAccessor
|| kind === SyntaxKind.SetAccessor;
}
/**
* Hook for node emit.
*
* @param node The node to emit.
* @param emit A callback used to emit the node in the printer.
*/
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
const savedApplicableSubstitutions = applicableSubstitutions;
const savedCurrentSuperContainer = currentSuperContainer;
// If we need to support substitutions for `super` in an async method,
// we should track it here.
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
currentSuperContainer = node;
}
previousOnEmitNode(emitContext, node, emitCallback);
applicableSubstitutions = savedApplicableSubstitutions;
currentSuperContainer = savedCurrentSuperContainer;
}
/**
* Hooks node substitutions.
*
* @param node The node to substitute.
* @param isExpression A value indicating whether the node is to be used in an expression
* position.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
if (emitContext === EmitContext.Expression) {
return substituteExpression(<Expression>node);
}
return node;
}
function createSuperAccessInAsyncMethod(argumentExpression: Expression, flags: NodeCheckFlags, location: TextRange): LeftHandSideExpression {
if (flags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
return createPropertyAccess(
createCall(
createIdentifier("_super"),
/*typeArguments*/ undefined,
[argumentExpression]
),
"value",
location
);
}
else {
return createCall(
createIdentifier("_super"),
/*typeArguments*/ undefined,
[argumentExpression],
location
);
}
}
function getSuperContainerAsyncMethodFlags() {
return currentSuperContainer !== undefined
&& resolver.getNodeCheckFlags(currentSuperContainer) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding);
}
}
}
+83
View File
@@ -0,0 +1,83 @@
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
/*@internal*/
namespace ts {
/**
* Transforms ES5 syntax into ES3 syntax.
*
* @param context Context and state information for the transformation.
*/
export function transformES5(context: TransformationContext) {
const previousOnSubstituteNode = context.onSubstituteNode;
context.onSubstituteNode = onSubstituteNode;
context.enableSubstitution(SyntaxKind.PropertyAccessExpression);
context.enableSubstitution(SyntaxKind.PropertyAssignment);
return transformSourceFile;
/**
* Transforms an ES5 source file to ES3.
*
* @param node A SourceFile
*/
function transformSourceFile(node: SourceFile) {
return node;
}
/**
* Hooks node substitutions.
*
* @param emitContext The context for the emitter.
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
if (isPropertyAccessExpression(node)) {
return substitutePropertyAccessExpression(node);
}
else if (isPropertyAssignment(node)) {
return substitutePropertyAssignment(node);
}
return node;
}
/**
* Substitutes a PropertyAccessExpression whose name is a reserved word.
*
* @param node A PropertyAccessExpression
*/
function substitutePropertyAccessExpression(node: PropertyAccessExpression): Expression {
const literalName = trySubstituteReservedName(node.name);
if (literalName) {
return createElementAccess(node.expression, literalName, /*location*/ node);
}
return node;
}
/**
* Substitutes a PropertyAssignment whose name is a reserved word.
*
* @param node A PropertyAssignment
*/
function substitutePropertyAssignment(node: PropertyAssignment): PropertyAssignment {
const literalName = isIdentifier(node.name) && trySubstituteReservedName(node.name);
if (literalName) {
return updatePropertyAssignment(node, literalName, node.initializer);
}
return node;
}
/**
* If an identifier name is a reserved word, returns a string literal for the name.
*
* @param name An Identifier
*/
function trySubstituteReservedName(name: Identifier) {
const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(name.text) : undefined);
if (token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) {
return createLiteral(name, /*location*/ name);
}
return undefined;
}
}
}
+12 -10
View File
@@ -496,6 +496,7 @@ namespace ts {
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
node = setOriginalNode(
createFunctionExpression(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
node.name,
/*typeParameters*/ undefined,
@@ -528,7 +529,7 @@ namespace ts {
*
* @param node The node to visit.
*/
function visitAccessorDeclaration(node: GetAccessorDeclaration) {
function visitAccessorDeclaration(node: AccessorDeclaration) {
const savedInGeneratorFunctionBody = inGeneratorFunctionBody;
const savedInStatementContainingYield = inStatementContainingYield;
inGeneratorFunctionBody = false;
@@ -660,12 +661,12 @@ namespace ts {
}
}
function isCompoundAssignment(kind: SyntaxKind) {
function isCompoundAssignment(kind: BinaryOperator): kind is CompoundAssignmentOperator {
return kind >= SyntaxKind.FirstCompoundAssignment
&& kind <= SyntaxKind.LastCompoundAssignment;
}
function getOperatorForCompoundAssignment(kind: SyntaxKind) {
function getOperatorForCompoundAssignment(kind: CompoundAssignmentOperator): BitwiseOperatorOrHigher {
switch (kind) {
case SyntaxKind.PlusEqualsToken: return SyntaxKind.PlusToken;
case SyntaxKind.MinusEqualsToken: return SyntaxKind.MinusToken;
@@ -955,7 +956,7 @@ namespace ts {
* @param elements The elements to visit.
* @param multiLine Whether array literals created should be emitted on multiple lines.
*/
function visitElements(elements: NodeArray<Expression>, multiLine: boolean) {
function visitElements(elements: NodeArray<Expression>, _multiLine?: boolean) {
// [source]
// ar = [1, yield, 2];
//
@@ -1101,7 +1102,7 @@ namespace ts {
createFunctionApply(
cacheExpression(visitNode(target, visitor, isLeftHandSideExpression)),
thisArg,
visitElements(node.arguments, /*multiLine*/ false),
visitElements(node.arguments),
/*location*/ node
),
node
@@ -1130,7 +1131,7 @@ namespace ts {
createFunctionApply(
cacheExpression(visitNode(target, visitor, isExpression)),
thisArg,
visitElements(node.arguments, /*multiLine*/ false)
visitElements(node.arguments)
),
/*typeArguments*/ undefined,
[],
@@ -2368,7 +2369,7 @@ namespace ts {
labelExpressions = [];
}
const expression = <LiteralExpression>createSynthesizedNode(SyntaxKind.NumericLiteral);
const expression = createLiteral(-1);
if (labelExpressions[label] === undefined) {
labelExpressions[label] = [expression];
}
@@ -2379,7 +2380,7 @@ namespace ts {
return expression;
}
return <OmittedExpression>createNode(SyntaxKind.OmittedExpression);
return createOmittedExpression();
}
/**
@@ -2591,10 +2592,11 @@ namespace ts {
createThis(),
setEmitFlags(
createFunctionExpression(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
[createParameter(state)],
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, state)],
/*type*/ undefined,
createBlock(
buildResult,
@@ -3080,4 +3082,4 @@ namespace ts {
);
}
}
}
}
@@ -0,0 +1,39 @@
/// <reference path="../../factory.ts" />
/// <reference path="../../visitor.ts" />
/*@internal*/
namespace ts {
export function transformES2015Module(context: TransformationContext) {
const compilerOptions = context.getCompilerOptions();
return transformSourceFile;
function transformSourceFile(node: SourceFile) {
if (isDeclarationFile(node)) {
return node;
}
if (isExternalModule(node) || compilerOptions.isolatedModules) {
return visitEachChild(node, visitor, context);
}
return node;
}
function visitor(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.ImportEqualsDeclaration:
// Elide `import=` as it is not legal with --module ES6
return undefined;
case SyntaxKind.ExportAssignment:
return visitExportAssignment(<ExportAssignment>node);
}
return node;
}
function visitExportAssignment(node: ExportAssignment): VisitResult<ExportAssignment> {
// Elide `export=` as it is not legal with --module ES6
return node.isExportEquals ? undefined : node;
}
}
}
-144
View File
@@ -1,144 +0,0 @@
/// <reference path="../../factory.ts" />
/// <reference path="../../visitor.ts" />
/*@internal*/
namespace ts {
export function transformES6Module(context: TransformationContext) {
const compilerOptions = context.getCompilerOptions();
const resolver = context.getEmitResolver();
let currentSourceFile: SourceFile;
return transformSourceFile;
function transformSourceFile(node: SourceFile) {
if (isDeclarationFile(node)) {
return node;
}
if (isExternalModule(node) || compilerOptions.isolatedModules) {
currentSourceFile = node;
return visitEachChild(node, visitor, context);
}
return node;
}
function visitor(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.ImportDeclaration:
return visitImportDeclaration(<ImportDeclaration>node);
case SyntaxKind.ImportEqualsDeclaration:
return visitImportEqualsDeclaration(<ImportEqualsDeclaration>node);
case SyntaxKind.ImportClause:
return visitImportClause(<ImportClause>node);
case SyntaxKind.NamedImports:
case SyntaxKind.NamespaceImport:
return visitNamedBindings(<NamedImportBindings>node);
case SyntaxKind.ImportSpecifier:
return visitImportSpecifier(<ImportSpecifier>node);
case SyntaxKind.ExportAssignment:
return visitExportAssignment(<ExportAssignment>node);
case SyntaxKind.ExportDeclaration:
return visitExportDeclaration(<ExportDeclaration>node);
case SyntaxKind.NamedExports:
return visitNamedExports(<NamedExports>node);
case SyntaxKind.ExportSpecifier:
return visitExportSpecifier(<ExportSpecifier>node);
}
return node;
}
function visitExportAssignment(node: ExportAssignment): ExportAssignment {
if (node.isExportEquals) {
return undefined; // do not emit export equals for ES6
}
const original = getOriginalNode(node);
return nodeIsSynthesized(original) || resolver.isValueAliasDeclaration(original) ? node : undefined;
}
function visitExportDeclaration(node: ExportDeclaration): ExportDeclaration {
if (!node.exportClause) {
return resolver.moduleExportsSomeValue(node.moduleSpecifier) ? node : undefined;
}
if (!resolver.isValueAliasDeclaration(node)) {
return undefined;
}
const newExportClause = visitNode(node.exportClause, visitor, isNamedExports, /*optional*/ true);
if (node.exportClause === newExportClause) {
return node;
}
return newExportClause
? createExportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
newExportClause,
node.moduleSpecifier)
: undefined;
}
function visitNamedExports(node: NamedExports): NamedExports {
const newExports = visitNodes(node.elements, visitor, isExportSpecifier);
if (node.elements === newExports) {
return node;
}
return newExports.length ? createNamedExports(newExports) : undefined;
}
function visitExportSpecifier(node: ExportSpecifier): ExportSpecifier {
return resolver.isValueAliasDeclaration(node) ? node : undefined;
}
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): ImportEqualsDeclaration {
return !isExternalModuleImportEqualsDeclaration(node) || resolver.isReferencedAliasDeclaration(node) ? node : undefined;
}
function visitImportDeclaration(node: ImportDeclaration) {
if (node.importClause) {
const newImportClause = visitNode(node.importClause, visitor, isImportClause);
if (!newImportClause.name && !newImportClause.namedBindings) {
return undefined;
}
else if (newImportClause !== node.importClause) {
return createImportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
newImportClause,
node.moduleSpecifier);
}
}
return node;
}
function visitImportClause(node: ImportClause): ImportClause {
let newDefaultImport = node.name;
if (!resolver.isReferencedAliasDeclaration(node)) {
newDefaultImport = undefined;
}
const newNamedBindings = visitNode(node.namedBindings, visitor, isNamedImportBindings, /*optional*/ true);
return newDefaultImport !== node.name || newNamedBindings !== node.namedBindings
? createImportClause(newDefaultImport, newNamedBindings)
: node;
}
function visitNamedBindings(node: NamedImportBindings): VisitResult<NamedImportBindings> {
if (node.kind === SyntaxKind.NamespaceImport) {
return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
}
else {
const newNamedImportElements = visitNodes((<NamedImports>node).elements, visitor, isImportSpecifier);
if (!newNamedImportElements || newNamedImportElements.length == 0) {
return undefined;
}
if (newNamedImportElements === (<NamedImports>node).elements) {
return node;
}
return createNamedImports(newNamedImportElements);
}
}
function visitImportSpecifier(node: ImportSpecifier) {
return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
}
}
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+20 -12
View File
@@ -29,7 +29,7 @@ namespace ts {
}
}
function reportEmittedFiles(files: string[], host: CompilerHost): void {
function reportEmittedFiles(files: string[]): void {
if (!files || files.length == 0) {
return;
}
@@ -111,7 +111,7 @@ namespace ts {
return count;
}
function getDiagnosticText(message: DiagnosticMessage, ...args: any[]): string {
function getDiagnosticText(_message: DiagnosticMessage, ..._args: any[]): string {
const diagnostic = createCompilerDiagnostic.apply(undefined, arguments);
return <string>diagnostic.messageText;
}
@@ -250,8 +250,8 @@ namespace ts {
let compilerOptions: CompilerOptions; // Compiler options for compilation
let compilerHost: CompilerHost; // Compiler host
let hostGetSourceFile: typeof compilerHost.getSourceFile; // getSourceFile method from default host
let timerHandleForRecompilation: number; // Handle for 0.25s wait timer to trigger recompilation
let timerHandleForDirectoryChanges: number; // Handle for 0.25s wait timer to trigger directory change handler
let timerHandleForRecompilation: any; // Handle for 0.25s wait timer to trigger recompilation
let timerHandleForDirectoryChanges: any; // Handle for 0.25s wait timer to trigger directory change handler
// This map stores and reuses results of fileExists check that happen inside 'createProgram'
// This allows to save time in module resolution heavy scenarios when existence of the same file might be checked multiple times.
@@ -456,7 +456,7 @@ namespace ts {
const sourceFile = hostGetSourceFile(fileName, languageVersion, onError);
if (sourceFile && isWatchSet(compilerOptions) && sys.watchFile) {
// Attach a file watcher
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (fileName: string, removed?: boolean) => sourceFileChanged(sourceFile, removed));
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (_fileName: string, removed?: boolean) => sourceFileChanged(sourceFile, removed));
}
return sourceFile;
}
@@ -503,10 +503,14 @@ namespace ts {
}
function startTimerForHandlingDirectoryChanges() {
if (timerHandleForDirectoryChanges) {
clearTimeout(timerHandleForDirectoryChanges);
if (!sys.setTimeout || !sys.clearTimeout) {
return;
}
timerHandleForDirectoryChanges = setTimeout(directoryChangeHandler, 250);
if (timerHandleForDirectoryChanges) {
sys.clearTimeout(timerHandleForDirectoryChanges);
}
timerHandleForDirectoryChanges = sys.setTimeout(directoryChangeHandler, 250);
}
function directoryChangeHandler() {
@@ -525,10 +529,14 @@ namespace ts {
// operations (such as saving all modified files in an editor) a chance to complete before we kick
// off a new compilation.
function startTimerForRecompilation() {
if (timerHandleForRecompilation) {
clearTimeout(timerHandleForRecompilation);
if (!sys.setTimeout || !sys.clearTimeout) {
return;
}
timerHandleForRecompilation = setTimeout(recompile, 250);
if (timerHandleForRecompilation) {
sys.clearTimeout(timerHandleForRecompilation);
}
timerHandleForRecompilation = sys.setTimeout(recompile, 250);
}
function recompile() {
@@ -617,7 +625,7 @@ namespace ts {
reportDiagnostics(sortAndDeduplicateDiagnostics(diagnostics), compilerHost);
reportEmittedFiles(emitOutput.emittedFiles, compilerHost);
reportEmittedFiles(emitOutput.emittedFiles);
if (emitOutput.emitSkipped && diagnostics.length > 0) {
// If the emitter didn't emit anything, then pass that value along.
+10 -4
View File
@@ -8,7 +8,10 @@
"outFile": "../../built/local/tsc.js",
"sourceMap": true,
"declaration": true,
"stripInternal": true
"stripInternal": true,
"target": "es5",
"noUnusedLocals": true,
"noUnusedParameters": true
},
"files": [
"core.ts",
@@ -24,13 +27,16 @@
"visitor.ts",
"transformers/ts.ts",
"transformers/jsx.ts",
"transformers/es7.ts",
"transformers/es6.ts",
"transformers/es2017.ts",
"transformers/es2016.ts",
"transformers/es2015.ts",
"transformers/es5.ts",
"transformers/generators.ts",
"transformers/es5.ts",
"transformers/destructuring.ts",
"transformers/module/module.ts",
"transformers/module/system.ts",
"transformers/module/es6.ts",
"transformers/module/es2015.ts",
"transformer.ts",
"comments.ts",
"sourcemap.ts",
+646 -310
View File
File diff suppressed because it is too large. Load diff
+204 -81
View File
@@ -63,11 +63,11 @@ namespace ts {
// Completely ignore indentation for string writers. And map newlines to
// a single space.
writeLine: () => str += " ",
increaseIndent: () => { },
decreaseIndent: () => { },
increaseIndent: noop,
decreaseIndent: noop,
clear: () => str = "",
trackSymbol: () => { },
reportInaccessibleThisError: () => { }
trackSymbol: noop,
reportInaccessibleThisError: noop
};
}
@@ -83,36 +83,17 @@ namespace ts {
return node.end - node.pos;
}
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T>, array2: ReadonlyArray<T>, equaler?: (a: T, b: T) => boolean): boolean {
if (!array1 || !array2) {
return array1 === array2;
}
if (array1.length !== array2.length) {
return false;
}
for (let i = 0; i < array1.length; i++) {
const equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
if (!equals) {
return false;
}
}
return true;
}
export function hasResolvedModule(sourceFile: SourceFile, moduleNameText: string): boolean {
return !!(sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules[moduleNameText]);
}
export function getResolvedModule(sourceFile: SourceFile, moduleNameText: string): ResolvedModule {
export function getResolvedModule(sourceFile: SourceFile, moduleNameText: string): ResolvedModuleFull {
return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules[moduleNameText] : undefined;
}
export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModule): void {
export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModuleFull): void {
if (!sourceFile.resolvedModules) {
sourceFile.resolvedModules = createMap<ResolvedModule>();
sourceFile.resolvedModules = createMap<ResolvedModuleFull>();
}
sourceFile.resolvedModules[moduleNameText] = resolvedModule;
@@ -127,8 +108,10 @@ namespace ts {
}
/* @internal */
export function moduleResolutionIsEqualTo(oldResolution: ResolvedModule, newResolution: ResolvedModule): boolean {
return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport;
export function moduleResolutionIsEqualTo(oldResolution: ResolvedModuleFull, newResolution: ResolvedModuleFull): boolean {
return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport &&
oldResolution.extension === newResolution.extension &&
oldResolution.resolvedFileName === newResolution.resolvedFileName;
}
/* @internal */
@@ -337,7 +320,7 @@ namespace ts {
export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile, languageVersion: ScriptTarget) {
// Any template literal or string literal with an extended escape
// (e.g. "\u{0067}") will need to be downleveled as a escaped string literal.
if (languageVersion < ScriptTarget.ES6 && (isTemplateLiteralKind(node.kind) || node.hasExtendedUnicodeEscape)) {
if (languageVersion < ScriptTarget.ES2015 && (isTemplateLiteralKind(node.kind) || node.hasExtendedUnicodeEscape)) {
return getQuotedEscapedLiteralText('"', node.text, '"');
}
@@ -345,7 +328,7 @@ namespace ts {
// the node's parent reference, then simply get the text as it was originally written.
if (!nodeIsSynthesized(node) && node.parent) {
const text = getSourceTextOfNodeFromSourceFile(sourceFile, node);
if (languageVersion < ScriptTarget.ES6 && isBinaryOrOctalIntegerLiteral(node, text)) {
if (languageVersion < ScriptTarget.ES2015 && isBinaryOrOctalIntegerLiteral(node, text)) {
return node.text;
}
return text;
@@ -406,7 +389,12 @@ namespace ts {
export function isBlockOrCatchScoped(declaration: Declaration) {
return (getCombinedNodeFlags(declaration) & NodeFlags.BlockScoped) !== 0 ||
isCatchClauseVariableDeclaration(declaration);
isCatchClauseVariableDeclarationOrBindingElement(declaration);
}
export function isCatchClauseVariableDeclarationOrBindingElement(declaration: Declaration) {
const node = getRootDeclaration(declaration);
return node.kind === SyntaxKind.VariableDeclaration && node.parent.kind === SyntaxKind.CatchClause;
}
export function isAmbientModule(node: Node): boolean {
@@ -414,8 +402,9 @@ namespace ts {
((<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral || isGlobalScopeAugmentation(<ModuleDeclaration>node));
}
export function isShorthandAmbientModuleSymbol(moduleSymbol: Symbol): boolean {
return isShorthandAmbientModule(moduleSymbol.valueDeclaration);
/** Given a symbol for a module, checks that it is either an untyped import or a shorthand ambient module. */
export function isUntypedModuleSymbol(moduleSymbol: Symbol): boolean {
return !moduleSymbol.valueDeclaration || isShorthandAmbientModule(moduleSymbol.valueDeclaration);
}
function isShorthandAmbientModule(node: Node): boolean {
@@ -489,13 +478,6 @@ namespace ts {
}
}
export function isCatchClauseVariableDeclaration(declaration: Declaration) {
return declaration &&
declaration.kind === SyntaxKind.VariableDeclaration &&
declaration.parent &&
declaration.parent.kind === SyntaxKind.CatchClause;
}
// Return display name of an identifier
// Computed property names will just be emitted as "[<expr>]", where <expr> is the source
// text of the expression in the computed property.
@@ -514,7 +496,7 @@ namespace ts {
}
}
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): Diagnostic {
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic {
const sourceFile = getSourceFileOfNode(node);
const span = getErrorSpanForNode(sourceFile, node);
return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2);
@@ -620,7 +602,7 @@ namespace ts {
return !!(getCombinedNodeFlags(node) & NodeFlags.Let);
}
export function isSuperCallExpression(n: Node): boolean {
export function isSuperCall(n: Node): n is SuperCall {
return n.kind === SyntaxKind.CallExpression && (<CallExpression>n).expression.kind === SyntaxKind.SuperKeyword;
}
@@ -906,6 +888,12 @@ namespace ts {
return node && node.kind === SyntaxKind.MethodDeclaration && node.parent.kind === SyntaxKind.ObjectLiteralExpression;
}
export function isObjectLiteralOrClassExpressionMethod(node: Node): node is MethodDeclaration {
return node.kind === SyntaxKind.MethodDeclaration &&
(node.parent.kind === SyntaxKind.ObjectLiteralExpression ||
node.parent.kind === SyntaxKind.ClassExpression);
}
export function isIdentifierTypePredicate(predicate: TypePredicate): predicate is IdentifierTypePredicate {
return predicate && predicate.kind === TypePredicateKind.Identifier;
}
@@ -1058,7 +1046,7 @@ namespace ts {
/**
* Determines whether a node is a property or element access expression for super.
*/
export function isSuperProperty(node: Node): node is (PropertyAccessExpression | ElementAccessExpression) {
export function isSuperProperty(node: Node): node is SuperProperty {
const kind = node.kind;
return (kind === SyntaxKind.PropertyAccessExpression || kind === SyntaxKind.ElementAccessExpression)
&& (<PropertyAccessExpression | ElementAccessExpression>node).expression.kind === SyntaxKind.SuperKeyword;
@@ -1388,7 +1376,7 @@ namespace ts {
}
}
export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) {
export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): ImportEqualsDeclaration | NamespaceImport {
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
return <ImportEqualsDeclaration>node;
}
@@ -1908,6 +1896,10 @@ namespace ts {
return node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "Symbol";
}
export function isPushOrUnshiftIdentifier(node: Identifier) {
return node.text === "push" || node.text === "unshift";
}
export function isModifierKind(token: SyntaxKind): boolean {
switch (token) {
case SyntaxKind.AbstractKeyword:
@@ -1956,14 +1948,16 @@ namespace ts {
|| positionIsSynthesized(node.end);
}
export function getOriginalNode(node: Node): Node {
export function getOriginalNode(node: Node): Node;
export function getOriginalNode<T extends Node>(node: Node, nodeTest: (node: Node) => node is T): T;
export function getOriginalNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
if (node) {
while (node.original !== undefined) {
node = node.original;
}
}
return node;
return !nodeTest || nodeTest(node) ? node : undefined;
}
/**
@@ -2472,7 +2466,7 @@ namespace ts {
return file.moduleName || getExternalModuleNameFromPath(host, file.fileName);
}
export function getExternalModuleNameFromDeclaration(host: EmitHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration): string {
export function getExternalModuleNameFromDeclaration(host: EmitHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration): string {
const file = resolver.getExternalModuleFileFromDeclaration(declaration);
if (!file || isDeclarationFile(file)) {
return undefined;
@@ -2569,7 +2563,7 @@ namespace ts {
const options = host.getCompilerOptions();
// Emit on each source file
if (options.outFile || options.out) {
onBundledEmit(host, sourceFiles);
onBundledEmit(sourceFiles);
}
else {
for (const sourceFile of sourceFiles) {
@@ -2602,7 +2596,7 @@ namespace ts {
action(jsFilePath, sourceMapFilePath, declarationFilePath, [sourceFile], /*isBundledEmit*/ false);
}
function onBundledEmit(host: EmitHost, sourceFiles: SourceFile[]) {
function onBundledEmit(sourceFiles: SourceFile[]) {
if (sourceFiles.length) {
const jsFilePath = options.outFile || options.out;
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
@@ -3041,7 +3035,7 @@ namespace ts {
}
}
if (node.flags & NodeFlags.NestedNamespace) {
if (node.flags & NodeFlags.NestedNamespace || (node.kind === SyntaxKind.Identifier && (<Identifier>node).isInJSDocNamespace)) {
flags |= ModifierFlags.Export;
}
@@ -3085,7 +3079,13 @@ namespace ts {
}
}
export function isDestructuringAssignment(node: Node): node is BinaryExpression {
export function isAssignmentExpression(node: Node): node is AssignmentExpression {
return isBinaryExpression(node)
&& isAssignmentOperator(node.operatorToken.kind)
&& isLeftHandSideExpression(node.left);
}
export function isDestructuringAssignment(node: Node): node is DestructuringAssignment {
if (isBinaryExpression(node)) {
if (node.operatorToken.kind === SyntaxKind.EqualsToken) {
const kind = node.left.kind;
@@ -3509,50 +3509,69 @@ namespace ts {
return positionIsSynthesized(range.pos) ? -1 : skipTrivia(sourceFile.text, range.pos);
}
export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver) {
export interface ExternalModuleInfo {
externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]; // imports of other external modules
exportSpecifiers: Map<ExportSpecifier[]>; // export specifiers by name
exportedBindings: Map<Identifier[]>; // exported names of local declarations
exportedNames: Identifier[]; // all exported names local to module
exportEquals: ExportAssignment | undefined; // an export= declaration if one was present
hasExportStarsToExportValues: boolean; // whether this module contains export*
}
export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver): ExternalModuleInfo {
const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = [];
const exportSpecifiers = createMap<ExportSpecifier[]>();
const exportedBindings = createMap<Identifier[]>();
const uniqueExports = createMap<Identifier>();
let hasExportDefault = false;
let exportEquals: ExportAssignment = undefined;
let hasExportStarsToExportValues = false;
for (const node of sourceFile.statements) {
switch (node.kind) {
case SyntaxKind.ImportDeclaration:
if (!(<ImportDeclaration>node).importClause ||
resolver.isReferencedAliasDeclaration((<ImportDeclaration>node).importClause, /*checkChildren*/ true)) {
// import "mod"
// import x from "mod" where x is referenced
// import * as x from "mod" where x is referenced
// import { x, y } from "mod" where at least one import is referenced
externalImports.push(<ImportDeclaration>node);
}
// import "mod"
// import x from "mod"
// import * as x from "mod"
// import { x, y } from "mod"
externalImports.push(<ImportDeclaration>node);
break;
case SyntaxKind.ImportEqualsDeclaration:
if ((<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference && resolver.isReferencedAliasDeclaration(node)) {
// import x = require("mod") where x is referenced
if ((<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference) {
// import x = require("mod")
externalImports.push(<ImportEqualsDeclaration>node);
}
break;
case SyntaxKind.ExportDeclaration:
if ((<ExportDeclaration>node).moduleSpecifier) {
if (!(<ExportDeclaration>node).exportClause) {
// export * from "mod"
if (resolver.moduleExportsSomeValue((<ExportDeclaration>node).moduleSpecifier)) {
externalImports.push(<ExportDeclaration>node);
hasExportStarsToExportValues = true;
}
externalImports.push(<ExportDeclaration>node);
hasExportStarsToExportValues = true;
}
else if (resolver.isValueAliasDeclaration(node)) {
// export { x, y } from "mod" where at least one export is a value symbol
else {
// export { x, y } from "mod"
externalImports.push(<ExportDeclaration>node);
}
}
else {
// export { x, y }
for (const specifier of (<ExportDeclaration>node).exportClause.elements) {
const name = (specifier.propertyName || specifier.name).text;
(exportSpecifiers[name] || (exportSpecifiers[name] = [])).push(specifier);
if (!uniqueExports[specifier.name.text]) {
const name = specifier.propertyName || specifier.name;
multiMapAdd(exportSpecifiers, name.text, specifier);
const decl = resolver.getReferencedImportDeclaration(name)
|| resolver.getReferencedValueDeclaration(name);
if (decl) {
multiMapAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
}
uniqueExports[specifier.name.text] = specifier.name;
}
}
}
break;
@@ -3563,10 +3582,94 @@ namespace ts {
exportEquals = <ExportAssignment>node;
}
break;
case SyntaxKind.VariableStatement:
if (hasModifier(node, ModifierFlags.Export)) {
for (const decl of (<VariableStatement>node).declarationList.declarations) {
collectExportedVariableInfo(decl, uniqueExports);
}
}
break;
case SyntaxKind.FunctionDeclaration:
if (hasModifier(node, ModifierFlags.Export)) {
if (hasModifier(node, ModifierFlags.Default)) {
// export default function() { }
if (!hasExportDefault) {
multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<FunctionDeclaration>node));
hasExportDefault = true;
}
}
else {
// export function x() { }
const name = (<FunctionDeclaration>node).name;
if (!uniqueExports[name.text]) {
multiMapAdd(exportedBindings, getOriginalNodeId(node), name);
uniqueExports[name.text] = name;
}
}
}
break;
case SyntaxKind.ClassDeclaration:
if (hasModifier(node, ModifierFlags.Export)) {
if (hasModifier(node, ModifierFlags.Default)) {
// export default class { }
if (!hasExportDefault) {
multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<ClassDeclaration>node));
hasExportDefault = true;
}
}
else {
// export class x { }
const name = (<ClassDeclaration>node).name;
if (!uniqueExports[name.text]) {
multiMapAdd(exportedBindings, getOriginalNodeId(node), name);
uniqueExports[name.text] = name;
}
}
}
break;
}
}
return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues };
let exportedNames: Identifier[];
for (const key in uniqueExports) {
exportedNames = ts.append(exportedNames, uniqueExports[key]);
}
return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues, exportedBindings, exportedNames };
}
function collectExportedVariableInfo(decl: VariableDeclaration | BindingElement, uniqueExports: Map<Identifier>) {
if (isBindingPattern(decl.name)) {
for (const element of decl.name.elements) {
if (!isOmittedExpression(element)) {
collectExportedVariableInfo(element, uniqueExports);
}
}
}
else if (!isGeneratedIdentifier(decl.name)) {
if (!uniqueExports[decl.name.text]) {
uniqueExports[decl.name.text] = decl.name;
}
}
}
/**
* Determines whether a name was originally the declaration name of an enum or namespace
* declaration.
*/
export function isDeclarationNameOfEnumOrNamespace(node: Identifier) {
const parseNode = getParseTreeNode(node);
if (parseNode) {
switch (parseNode.parent.kind) {
case SyntaxKind.EnumDeclaration:
case SyntaxKind.ModuleDeclaration:
return parseNode === (<EnumDeclaration | ModuleDeclaration>parseNode.parent).name;
}
}
return false;
}
export function getInitializedVariables(node: VariableDeclarationList) {
@@ -3638,14 +3741,14 @@ namespace ts {
return SyntaxKind.FirstTemplateToken <= kind && kind <= SyntaxKind.LastTemplateToken;
}
function isTemplateLiteralFragmentKind(kind: SyntaxKind) {
return kind === SyntaxKind.TemplateHead
|| kind === SyntaxKind.TemplateMiddle
|| kind === SyntaxKind.TemplateTail;
export function isTemplateHead(node: Node): node is TemplateHead {
return node.kind === SyntaxKind.TemplateHead;
}
export function isTemplateLiteralFragment(node: Node): node is TemplateLiteralFragment {
return isTemplateLiteralFragmentKind(node.kind);
export function isTemplateMiddleOrTemplateTail(node: Node): node is TemplateMiddle | TemplateTail {
const kind = node.kind;
return kind === SyntaxKind.TemplateMiddle
|| kind === SyntaxKind.TemplateTail;
}
// Identifiers
@@ -3654,7 +3757,7 @@ namespace ts {
return node.kind === SyntaxKind.Identifier;
}
export function isGeneratedIdentifier(node: Node): boolean {
export function isGeneratedIdentifier(node: Node): node is GeneratedIdentifier {
// Using `>` here catches both `GeneratedIdentifierKind.None` and `undefined`.
return isIdentifier(node) && node.autoGenerateKind > GeneratedIdentifierKind.None;
}
@@ -3790,6 +3893,14 @@ namespace ts {
// Expression
export function isArrayLiteralExpression(node: Node): node is ArrayLiteralExpression {
return node.kind === SyntaxKind.ArrayLiteralExpression;
}
export function isObjectLiteralExpression(node: Node): node is ObjectLiteralExpression {
return node.kind === SyntaxKind.ObjectLiteralExpression;
}
export function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression {
return node.kind === SyntaxKind.PropertyAccessExpression;
}
@@ -3810,7 +3921,7 @@ namespace ts {
return node.kind === SyntaxKind.CallExpression;
}
export function isTemplate(node: Node): node is Template {
export function isTemplateLiteral(node: Node): node is TemplateLiteral {
const kind = node.kind;
return kind === SyntaxKind.TemplateExpression
|| kind === SyntaxKind.NoSubstitutionTemplateLiteral;
@@ -4049,7 +4160,9 @@ namespace ts {
|| kind === SyntaxKind.VariableStatement
|| kind === SyntaxKind.WhileStatement
|| kind === SyntaxKind.WithStatement
|| kind === SyntaxKind.NotEmittedStatement;
|| kind === SyntaxKind.NotEmittedStatement
|| kind === SyntaxKind.EndOfDeclarationMarker
|| kind === SyntaxKind.MergeDeclarationMarker;
}
export function isDeclaration(node: Node): node is Declaration {
@@ -4174,7 +4287,17 @@ namespace ts {
namespace ts {
export function getDefaultLibFileName(options: CompilerOptions): string {
return options.target === ScriptTarget.ES6 ? "lib.es6.d.ts" : "lib.d.ts";
switch (options.target) {
case ScriptTarget.ES2017:
return "lib.es2017.d.ts";
case ScriptTarget.ES2016:
return "lib.es2016.d.ts";
case ScriptTarget.ES2015:
return "lib.es6.d.ts";
default:
return "lib.d.ts";
}
}
export function textSpanEnd(span: TextSpan) {
+9 -8
View File
@@ -692,7 +692,7 @@ namespace ts {
// Signature elements
case SyntaxKind.Parameter:
return updateParameterDeclaration(<ParameterDeclaration>node,
return updateParameter(<ParameterDeclaration>node,
visitNodes((<ParameterDeclaration>node).decorators, visitor, isDecorator),
visitNodes((<ParameterDeclaration>node).modifiers, visitor, isModifier),
visitNode((<ParameterDeclaration>node).name, visitor, isBindingName),
@@ -799,7 +799,7 @@ namespace ts {
case SyntaxKind.TaggedTemplateExpression:
return updateTaggedTemplate(<TaggedTemplateExpression>node,
visitNode((<TaggedTemplateExpression>node).tag, visitor, isExpression),
visitNode((<TaggedTemplateExpression>node).template, visitor, isTemplate));
visitNode((<TaggedTemplateExpression>node).template, visitor, isTemplateLiteral));
case SyntaxKind.ParenthesizedExpression:
return updateParen(<ParenthesizedExpression>node,
@@ -807,6 +807,7 @@ namespace ts {
case SyntaxKind.FunctionExpression:
return updateFunctionExpression(<FunctionExpression>node,
visitNodes((<FunctionExpression>node).modifiers, visitor, isModifier),
visitNode((<FunctionExpression>node).name, visitor, isPropertyName),
visitNodes((<FunctionExpression>node).typeParameters, visitor, isTypeParameter),
(context.startLexicalEnvironment(), visitNodes((<FunctionExpression>node).parameters, visitor, isParameter)),
@@ -862,7 +863,7 @@ namespace ts {
case SyntaxKind.TemplateExpression:
return updateTemplateExpression(<TemplateExpression>node,
visitNode((<TemplateExpression>node).head, visitor, isTemplateLiteralFragment),
visitNode((<TemplateExpression>node).head, visitor, isTemplateHead),
visitNodes((<TemplateExpression>node).templateSpans, visitor, isTemplateSpan));
case SyntaxKind.YieldExpression:
@@ -890,7 +891,7 @@ namespace ts {
case SyntaxKind.TemplateSpan:
return updateTemplateSpan(<TemplateSpan>node,
visitNode((<TemplateSpan>node).expression, visitor, isExpression),
visitNode((<TemplateSpan>node).literal, visitor, isTemplateLiteralFragment));
visitNode((<TemplateSpan>node).literal, visitor, isTemplateMiddleOrTemplateTail));
// Element
case SyntaxKind.Block:
@@ -1330,18 +1331,18 @@ namespace ts {
export namespace Debug {
export const failNotOptional = shouldAssert(AssertionLevel.Normal)
? (message?: string) => assert(false, message || "Node not optional.")
: (message?: string) => {};
: noop;
export const failBadSyntaxKind = shouldAssert(AssertionLevel.Normal)
? (node: Node, message?: string) => assert(false, message || "Unexpected node.", () => `Node ${formatSyntaxKind(node.kind)} was unexpected.`)
: (node: Node, message?: string) => {};
: noop;
export const assertNode = shouldAssert(AssertionLevel.Normal)
? (node: Node, test: (node: Node) => boolean, message?: string) => assert(
test === undefined || test(node),
message || "Unexpected node.",
() => `Node ${formatSyntaxKind(node.kind)} did not pass test '${getFunctionName(test)}'.`)
: (node: Node, test: (node: Node) => boolean, message?: string) => {};
: noop;
function getFunctionName(func: Function) {
if (typeof func !== "function") {
@@ -1357,4 +1358,4 @@ namespace ts {
}
}
}
}
}
+147 -134
View File
@@ -1,4 +1,4 @@
//
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -47,19 +47,6 @@ namespace FourSlash {
ranges: Range[];
}
interface MemberListData {
result: {
maybeInaccurate: boolean;
isMemberCompletion: boolean;
entries: {
name: string;
type: string;
kind: string;
kindModifiers: string;
}[];
};
}
export interface Marker {
fileName: string;
position: number;
@@ -178,15 +165,9 @@ namespace FourSlash {
// Return object may lack some functionalities for other purposes.
function createScriptSnapShot(sourceText: string): ts.IScriptSnapshot {
return {
getText: (start: number, end: number) => {
return sourceText.substr(start, end - start);
},
getLength: () => {
return sourceText.length;
},
getChangeRange: (oldSnapshot: ts.IScriptSnapshot) => {
return <ts.TextChangeRange>undefined;
}
getText: (start: number, end: number) => sourceText.substr(start, end - start),
getLength: () => sourceText.length,
getChangeRange: () => undefined
};
}
@@ -419,15 +400,14 @@ namespace FourSlash {
public verifyErrorExistsBetweenMarkers(startMarkerName: string, endMarkerName: string, negative: boolean) {
const startMarker = this.getMarkerByName(startMarkerName);
const endMarker = this.getMarkerByName(endMarkerName);
const predicate = function(errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) {
return ((errorMinChar === startPos) && (errorLimChar === endPos)) ? true : false;
};
const predicate = (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) =>
((errorMinChar === startPos) && (errorLimChar === endPos)) ? true : false;
const exists = this.anyErrorInRange(predicate, startMarker, endMarker);
if (exists !== negative) {
this.printErrorLog(negative, this.getAllDiagnostics());
throw new Error("Failure between markers: " + startMarkerName + ", " + endMarkerName);
throw new Error(`Failure between markers: '${startMarkerName}', '${endMarkerName}'`);
}
}
@@ -458,9 +438,8 @@ namespace FourSlash {
private getAllDiagnostics(): ts.Diagnostic[] {
const diagnostics: ts.Diagnostic[] = [];
const fileNames = this.languageServiceAdapterHost.getFilenames();
for (let i = 0, n = fileNames.length; i < n; i++) {
diagnostics.push.apply(this.getDiagnostics(fileNames[i]));
for (const fileName of this.languageServiceAdapterHost.getFilenames()) {
diagnostics.push.apply(this.getDiagnostics(fileName));
}
return diagnostics;
@@ -471,14 +450,12 @@ namespace FourSlash {
let predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) => boolean;
if (after) {
predicate = function(errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) {
return ((errorMinChar >= startPos) && (errorLimChar >= startPos)) ? true : false;
};
predicate = (errorMinChar: number, errorLimChar: number, startPos: number) =>
((errorMinChar >= startPos) && (errorLimChar >= startPos)) ? true : false;
}
else {
predicate = function(errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) {
return ((errorMinChar <= startPos) && (errorLimChar <= startPos)) ? true : false;
};
predicate = (errorMinChar: number, errorLimChar: number, startPos: number) =>
((errorMinChar <= startPos) && (errorLimChar <= startPos)) ? true : false;
}
const exists = this.anyErrorInRange(predicate, marker);
@@ -602,12 +579,12 @@ namespace FourSlash {
this.raiseError(`goToDefinitions failed - expected to find ${endMarkers.length} definitions but got ${definitions.length}`);
}
for (let i = 0; i < endMarkers.length; i++) {
const marker = this.getMarkerByName(endMarkers[i]), definition = definitions[i];
ts.zipWith(endMarkers, definitions, (endMarker, definition, i) => {
const marker = this.getMarkerByName(endMarker);
if (marker.fileName !== definition.fileName || marker.position !== definition.textSpan.start) {
this.raiseError(`goToDefinition failed for definition ${i}: expected ${marker.fileName} at ${marker.position}, got ${definition.fileName} at ${definition.textSpan.start}`);
}
}
});
}
public verifyGetEmitOutputForCurrentFile(expected: string): void {
@@ -624,10 +601,10 @@ namespace FourSlash {
public verifyGetEmitOutputContentsForCurrentFile(expected: ts.OutputFile[]): void {
const emit = this.languageService.getEmitOutput(this.activeFile.fileName);
assert.equal(emit.outputFiles.length, expected.length, "Number of emit output files");
for (let i = 0; i < emit.outputFiles.length; i++) {
assert.equal(emit.outputFiles[i].name, expected[i].name, "FileName");
assert.equal(emit.outputFiles[i].text, expected[i].text, "Content");
}
ts.zipWith(emit.outputFiles, expected, (outputFile, expected) => {
assert.equal(outputFile.name, expected.name, "FileName");
assert.equal(outputFile.text, expected.text, "Content");
});
}
public verifyMemberListContains(symbol: string, text?: string, documentation?: string, kind?: string) {
@@ -690,9 +667,9 @@ namespace FourSlash {
const entries = this.getCompletionListAtCaret().entries;
assert.isTrue(items.length <= entries.length, `Amount of expected items in completion list [ ${items.length} ] is greater than actual number of items in list [ ${entries.length} ]`);
for (let i = 0; i < items.length; i++) {
assert.equal(entries[i].name, items[i], `Unexpected item in completion list`);
}
ts.zipWith(entries, items, (entry, item) => {
assert.equal(entry.name, item, `Unexpected item in completion list`);
});
}
public noItemsWithSameNameButDifferentKind(): void {
@@ -714,15 +691,7 @@ namespace FourSlash {
this.raiseError("Member list is empty at Caret");
}
else if ((members && members.entries.length !== 0) && !negative) {
let errorMsg = "\n" + "Member List contains: [" + members.entries[0].name;
for (let i = 1; i < members.entries.length; i++) {
errorMsg += ", " + members.entries[i].name;
}
errorMsg += "]\n";
this.raiseError("Member list is not empty at Caret: " + errorMsg);
this.raiseError(`Member list is not empty at Caret:\nMember List contains: ${stringify(members.entries.map(e => e.name))}`);
}
}
@@ -732,17 +701,11 @@ namespace FourSlash {
this.raiseError("Completion list is empty at caret at position " + this.activeFile.fileName + " " + this.currentCaretPosition);
}
else if (completions && completions.entries.length !== 0 && !negative) {
let errorMsg = "\n" + "Completion List contains: [" + completions.entries[0].name;
for (let i = 1; i < completions.entries.length; i++) {
errorMsg += ", " + completions.entries[i].name;
}
errorMsg += "]\n";
this.raiseError("Completion list is not empty at caret at position " + this.activeFile.fileName + " " + this.currentCaretPosition + errorMsg);
this.raiseError(`Completion list is not empty at caret at position ${this.activeFile.fileName} ${this.currentCaretPosition}\n` +
`Completion List contains: ${stringify(completions.entries.map(e => e.name))}`);
}
}
public verifyCompletionListAllowsNewIdentifier(negative: boolean) {
const completions = this.getCompletionListAtCaret();
@@ -913,8 +876,7 @@ namespace FourSlash {
}
private verifyReferencesWorker(references: ts.ReferenceEntry[], fileName: string, start: number, end: number, isWriteAccess?: boolean, isDefinition?: boolean) {
for (let i = 0; i < references.length; i++) {
const reference = references[i];
for (const reference of references) {
if (reference && reference.fileName === fileName && reference.textSpan.start === start && ts.textSpanEnd(reference.textSpan) === end) {
if (typeof isWriteAccess !== "undefined" && reference.isWriteAccess !== isWriteAccess) {
this.raiseError(`verifyReferencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ${reference.isWriteAccess}, expected: ${isWriteAccess}.`);
@@ -1031,16 +993,11 @@ namespace FourSlash {
ranges = ranges.sort((r1, r2) => r1.start - r2.start);
references = references.sort((r1, r2) => r1.textSpan.start - r2.textSpan.start);
for (let i = 0, n = ranges.length; i < n; i++) {
const reference = references[i];
const range = ranges[i];
if (reference.textSpan.start !== range.start ||
ts.textSpanEnd(reference.textSpan) !== range.end) {
ts.zipWith(references, ranges, (reference, range) => {
if (reference.textSpan.start !== range.start || ts.textSpanEnd(reference.textSpan) !== range.end) {
this.raiseError("Rename location results do not match.\n\nExpected: " + stringify(ranges) + "\n\nActual:" + JSON.stringify(references));
}
}
});
}
else {
this.raiseError("Expected rename to succeed, but it actually failed.");
@@ -1180,7 +1137,7 @@ namespace FourSlash {
private alignmentForExtraInfo = 50;
private spanInfoToString(pos: number, spanInfo: ts.TextSpan, prefixString: string) {
private spanInfoToString(spanInfo: ts.TextSpan, prefixString: string) {
let resultString = "SpanInfo: " + JSON.stringify(spanInfo);
if (spanInfo) {
const spanString = this.activeFile.content.substr(spanInfo.start, spanInfo.length);
@@ -1231,7 +1188,7 @@ namespace FourSlash {
startColumn = 0;
length = 0;
}
const spanInfo = this.spanInfoToString(pos, getSpanAtPos(pos), prefixString);
const spanInfo = this.spanInfoToString(getSpanAtPos(pos), prefixString);
if (previousSpanInfo && previousSpanInfo !== spanInfo) {
addSpanInfoString();
previousSpanInfo = spanInfo;
@@ -1270,8 +1227,7 @@ namespace FourSlash {
const emitFiles: FourSlashFile[] = []; // List of FourSlashFile that has emitThisFile flag on
const allFourSlashFiles = this.testData.files;
for (let idx = 0; idx < allFourSlashFiles.length; idx++) {
const file = allFourSlashFiles[idx];
for (const file of allFourSlashFiles) {
if (file.fileOptions[metadataOptionNames.emitThisFile] === "true") {
// Find a file with the flag emitThisFile turned on
emitFiles.push(file);
@@ -1296,15 +1252,15 @@ namespace FourSlash {
if (emitOutput.emitSkipped) {
resultString += "Diagnostics:" + Harness.IO.newLine();
const diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram());
for (let i = 0, n = diagnostics.length; i < n; i++) {
resultString += " " + diagnostics[0].messageText + Harness.IO.newLine();
for (const diagnostic of diagnostics) {
resultString += " " + diagnostic.messageText + Harness.IO.newLine();
}
}
emitOutput.outputFiles.forEach((outputFile, idx, array) => {
for (const outputFile of emitOutput.outputFiles) {
const fileName = "FileName : " + outputFile.name + Harness.IO.newLine();
resultString = resultString + fileName + outputFile.text;
});
}
resultString += Harness.IO.newLine();
});
@@ -1329,7 +1285,7 @@ namespace FourSlash {
}
public printBreakpointLocation(pos: number) {
Harness.IO.log("\n**Pos: " + pos + " " + this.spanInfoToString(pos, this.getBreakpointStatementLocation(pos), " "));
Harness.IO.log("\n**Pos: " + pos + " " + this.spanInfoToString(this.getBreakpointStatementLocation(pos), " "));
}
public printBreakpointAtCurrentLocation() {
@@ -1363,8 +1319,7 @@ namespace FourSlash {
}
public printCurrentFileState(makeWhitespaceVisible = false, makeCaretVisible = true) {
for (let i = 0; i < this.testData.files.length; i++) {
const file = this.testData.files[i];
for (const file of this.testData.files) {
const active = (this.activeFile === file);
Harness.IO.log(`=== Script (${file.fileName}) ${(active ? "(active, cursor at |)" : "")} ===`);
let content = this.getFileContent(file.fileName);
@@ -1599,10 +1554,10 @@ namespace FourSlash {
edits = edits.sort((a, b) => a.span.start - b.span.start);
// Get a snapshot of the content of the file so we can make sure any formatting edits didn't destroy non-whitespace characters
const oldContent = this.getFileContent(this.activeFile.fileName);
for (let j = 0; j < edits.length; j++) {
this.languageServiceAdapterHost.editScript(fileName, edits[j].span.start + runningOffset, ts.textSpanEnd(edits[j].span) + runningOffset, edits[j].newText);
this.updateMarkersForEdit(fileName, edits[j].span.start + runningOffset, ts.textSpanEnd(edits[j].span) + runningOffset, edits[j].newText);
const change = (edits[j].span.start - ts.textSpanEnd(edits[j].span)) + edits[j].newText.length;
for (const edit of edits) {
this.languageServiceAdapterHost.editScript(fileName, edit.span.start + runningOffset, ts.textSpanEnd(edit.span) + runningOffset, edit.newText);
this.updateMarkersForEdit(fileName, edit.span.start + runningOffset, ts.textSpanEnd(edit.span) + runningOffset, edit.newText);
const change = (edit.span.start - ts.textSpanEnd(edit.span)) + edit.newText.length;
runningOffset += change;
// TODO: Consider doing this at least some of the time for higher fidelity. Currently causes a failure (bug 707150)
// this.languageService.getScriptLexicalStructure(fileName);
@@ -1611,7 +1566,7 @@ namespace FourSlash {
if (isFormattingEdit) {
const newContent = this.getFileContent(fileName);
if (newContent.replace(/\s/g, "") !== oldContent.replace(/\s/g, "")) {
if (this.removeWhitespace(newContent) !== this.removeWhitespace(oldContent)) {
this.raiseError("Formatting operation destroyed non-whitespace content");
}
}
@@ -1677,6 +1632,10 @@ namespace FourSlash {
}
}
private removeWhitespace(text: string): string {
return text.replace(/\s/g, "");
}
public goToBOF() {
this.goToPosition(0);
}
@@ -1827,7 +1786,7 @@ namespace FourSlash {
return result;
}
private rangeText({fileName, start, end}: Range, more = false): string {
private rangeText({fileName, start, end}: Range): string {
return this.getFileContent(fileName).slice(start, end);
}
@@ -1922,7 +1881,7 @@ namespace FourSlash {
}
public printNameOrDottedNameSpans(pos: number) {
Harness.IO.log(this.spanInfoToString(pos, this.getNameOrDottedNameSpan(pos), "**"));
Harness.IO.log(this.spanInfoToString(this.getNameOrDottedNameSpan(pos), "**"));
}
private verifyClassifications(expected: { classificationType: string; text: string; textSpan?: TextSpan }[], actual: ts.ClassifiedSpan[]) {
@@ -1932,10 +1891,7 @@ namespace FourSlash {
jsonMismatchString());
}
for (let i = 0; i < expected.length; i++) {
const expectedClassification = expected[i];
const actualClassification = actual[i];
ts.zipWith(expected, actual, (expectedClassification, actualClassification) => {
const expectedType: string = (<any>ts.ClassificationTypeNames)[expectedClassification.classificationType];
if (expectedType !== actualClassification.classificationType) {
this.raiseError("verifyClassifications failed - expected classifications type to be " +
@@ -1965,7 +1921,7 @@ namespace FourSlash {
actualText +
jsonMismatchString());
}
}
});
function jsonMismatchString() {
return Harness.IO.newLine() +
@@ -2010,13 +1966,11 @@ namespace FourSlash {
this.raiseError(`verifyOutliningSpans failed - expected total spans to be ${spans.length}, but was ${actual.length}`);
}
for (let i = 0; i < spans.length; i++) {
const expectedSpan = spans[i];
const actualSpan = actual[i];
ts.zipWith(spans, actual, (expectedSpan, actualSpan, i) => {
if (expectedSpan.start !== actualSpan.textSpan.start || expectedSpan.end !== ts.textSpanEnd(actualSpan.textSpan)) {
this.raiseError(`verifyOutliningSpans failed - span ${(i + 1)} expected: (${expectedSpan.start},${expectedSpan.end}), actual: (${actualSpan.textSpan.start},${ts.textSpanEnd(actualSpan.textSpan)})`);
}
}
});
}
public verifyTodoComments(descriptors: string[], spans: TextSpan[]) {
@@ -2027,14 +1981,53 @@ namespace FourSlash {
this.raiseError(`verifyTodoComments failed - expected total spans to be ${spans.length}, but was ${actual.length}`);
}
for (let i = 0; i < spans.length; i++) {
const expectedSpan = spans[i];
const actualComment = actual[i];
ts.zipWith(spans, actual, (expectedSpan, actualComment, i) => {
const actualCommentSpan = ts.createTextSpan(actualComment.position, actualComment.message.length);
if (expectedSpan.start !== actualCommentSpan.start || expectedSpan.end !== ts.textSpanEnd(actualCommentSpan)) {
this.raiseError(`verifyOutliningSpans failed - span ${(i + 1)} expected: (${expectedSpan.start},${expectedSpan.end}), actual: (${actualCommentSpan.start},${ts.textSpanEnd(actualCommentSpan)})`);
}
});
}
private getCodeFixes(errorCode?: number) {
const fileName = this.activeFile.fileName;
const diagnostics = this.getDiagnostics(fileName);
if (diagnostics.length === 0) {
this.raiseError("Errors expected.");
}
if (diagnostics.length > 1 && errorCode !== undefined) {
this.raiseError("When there's more than one error, you must specify the errror to fix.");
}
const diagnostic = !errorCode ? diagnostics[0] : ts.find(diagnostics, d => d.code == errorCode);
return this.languageService.getCodeFixesAtPosition(fileName, diagnostic.start, diagnostic.length, [diagnostic.code]);
}
public verifyCodeFixAtPosition(expectedText: string, errorCode?: number) {
const ranges = this.getRanges();
if (ranges.length == 0) {
this.raiseError("At least one range should be specified in the testfile.");
}
const actual = this.getCodeFixes(errorCode);
if (!actual || actual.length == 0) {
this.raiseError("No codefixes returned.");
}
if (actual.length > 1) {
this.raiseError("More than 1 codefix returned.");
}
this.applyEdits(actual[0].changes[0].fileName, actual[0].changes[0].textChanges, /*isFormattingEdit*/ false);
const actualText = this.rangeText(ranges[0]);
if (this.removeWhitespace(actualText) !== this.removeWhitespace(expectedText)) {
this.raiseError(`Actual text doesn't match expected text. Actual: '${actualText}' Expected: '${expectedText}'`);
}
}
@@ -2141,11 +2134,9 @@ namespace FourSlash {
public verifyNavigationItemsCount(expected: number, searchValue: string, matchKind?: string, fileName?: string) {
const items = this.languageService.getNavigateToItems(searchValue, /*maxResultCount*/ undefined, fileName);
let actual = 0;
let item: ts.NavigateToItem;
// Count only the match that match the same MatchKind
for (let i = 0; i < items.length; i++) {
item = items[i];
for (const item of items) {
if (!matchKind || item.matchKind === matchKind) {
actual++;
}
@@ -2173,8 +2164,7 @@ namespace FourSlash {
this.raiseError("verifyNavigationItemsListContains failed - found 0 navigation items, expected at least one.");
}
for (let i = 0; i < items.length; i++) {
const item = items[i];
for (const item of items) {
if (item && item.name === name && item.kind === kind &&
(matchKind === undefined || item.matchKind === matchKind) &&
(fileName === undefined || item.fileName === fileName) &&
@@ -2211,26 +2201,30 @@ namespace FourSlash {
}
}
public verifyNavigationTree(json: any) {
const tree = this.languageService.getNavigationTree(this.activeFile.fileName);
if (JSON.stringify(tree, replacer) !== JSON.stringify(json)) {
this.raiseError(`verifyNavigationTree failed - expected: ${stringify(json)}, got: ${stringify(tree, replacer)}`);
}
function replacer(key: string, value: any) {
// Don't check "spans", and omit falsy values.
return key === "spans" ? undefined : (value || undefined);
}
}
public printNavigationItems(searchValue: string) {
const items = this.languageService.getNavigateToItems(searchValue);
const length = items && items.length;
Harness.IO.log(`NavigationItems list (${length} items)`);
for (let i = 0; i < length; i++) {
const item = items[i];
Harness.IO.log(`NavigationItems list (${items.length} items)`);
for (const item of items) {
Harness.IO.log(`name: ${item.name}, kind: ${item.kind}, parentName: ${item.containerName}, fileName: ${item.fileName}`);
}
}
public printNavigationBar() {
const items = this.languageService.getNavigationBarItems(this.activeFile.fileName);
const length = items && items.length;
Harness.IO.log(`Navigation bar (${length} items)`);
for (let i = 0; i < length; i++) {
const item = items[i];
Harness.IO.log(`Navigation bar (${items.length} items)`);
for (const item of items) {
Harness.IO.log(`${repeatString(item.indent, " ")}name: ${item.text}, kind: ${item.kind}, childItems: ${item.childItems.map(child => child.text)}`);
}
}
@@ -2309,6 +2303,18 @@ namespace FourSlash {
}
}
public verifyCodeFixAvailable(negative: boolean, errorCode?: number) {
const fixes = this.getCodeFixes(errorCode);
if (negative && fixes && fixes.length > 0) {
this.raiseError(`verifyCodeFixAvailable failed - expected no fixes, actual: ${fixes.length}`);
}
if (!negative && (fixes === undefined || fixes.length === 0)) {
this.raiseError(`verifyCodeFixAvailable failed - expected code fixes, actual: 0`);
}
}
// Get the text of the entire line the caret is currently at
private getCurrentLineContent() {
const text = this.getFileContent(this.activeFile.fileName);
@@ -2339,8 +2345,7 @@ namespace FourSlash {
}
private assertItemInCompletionList(items: ts.CompletionEntry[], name: string, text?: string, documentation?: string, kind?: string, spanIndex?: number) {
for (let i = 0; i < items.length; i++) {
const item = items[i];
for (const item of items) {
if (item.name === name) {
if (documentation != undefined || text !== undefined) {
const details = this.getCompletionEntryDetails(item.name);
@@ -2389,20 +2394,17 @@ namespace FourSlash {
name = name.indexOf("/") === -1 ? (this.basePath + "/" + name) : name;
const availableNames: string[] = [];
let foundIt = false;
for (let i = 0; i < this.testData.files.length; i++) {
const fn = this.testData.files[i].fileName;
result = ts.forEach(this.testData.files, file => {
const fn = file.fileName;
if (fn) {
if (fn === name) {
result = this.testData.files[i];
foundIt = true;
break;
return file;
}
availableNames.push(fn);
}
}
});
if (!foundIt) {
if (!result) {
throw new Error(`No test file named "${name}" exists. Available file names are: ${availableNames.join(", ")}`);
}
}
@@ -2503,8 +2505,8 @@ ${code}
function chompLeadingSpace(content: string) {
const lines = content.split("\n");
for (let i = 0; i < lines.length; i++) {
if ((lines[i].length !== 0) && (lines[i].charAt(0) !== " ")) {
for (const line of lines) {
if ((line.length !== 0) && (line.charAt(0) !== " ")) {
return content;
}
}
@@ -2542,8 +2544,7 @@ ${code}
currentFileName = fileName;
}
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
for (let line of lines) {
const lineLength = line.length;
if (lineLength > 0 && line.charAt(lineLength - 1) === "\r") {
@@ -3096,6 +3097,10 @@ namespace FourSlashInterface {
public isValidBraceCompletionAtPosition(openingBrace: string) {
this.state.verifyBraceCompletionAtPosition(this.negative, openingBrace);
}
public codeFixAvailable(errorCode?: number) {
this.state.verifyCodeFixAvailable(this.negative, errorCode);
}
}
export class Verify extends VerifyNegatable {
@@ -3275,10 +3280,18 @@ namespace FourSlashInterface {
this.DocCommentTemplate(/*expectedText*/ undefined, /*expectedOffset*/ undefined, /*empty*/ true);
}
public codeFixAtPosition(expectedText: string, errorCode?: number): void {
this.state.verifyCodeFixAtPosition(expectedText, errorCode);
}
public navigationBar(json: any) {
this.state.verifyNavigationBar(json);
}
public navigationTree(json: any) {
this.state.verifyNavigationTree(json);
}
public navigationItemsListCount(count: number, searchValue: string, matchKind?: string, fileName?: string) {
this.state.verifyNavigationItemsCount(count, searchValue, matchKind, fileName);
}
+62 -42
View File
@@ -220,9 +220,7 @@ namespace Utils {
}
export function sourceFileToJSON(file: ts.Node): string {
return JSON.stringify(file, (k, v) => {
return isNodeOrArray(v) ? serializeNode(v) : v;
}, " ");
return JSON.stringify(file, (_, v) => isNodeOrArray(v) ? serializeNode(v) : v, " ");
function getKindName(k: number | string): string {
if (typeof k === "string") {
@@ -692,7 +690,7 @@ namespace Harness {
export const getCurrentDirectory = () => "";
export const args = () => <string[]>[];
export const getExecutingFilePath = () => "";
export const exit = (exitCode: number) => { };
export const exit = ts.noop;
export const getDirectories = () => <string[]>[];
export let log = (s: string) => console.log(s);
@@ -742,7 +740,7 @@ namespace Harness {
}
}
export function createDirectory(path: string) {
export function createDirectory() {
// Do nothing (?)
}
@@ -750,7 +748,7 @@ namespace Harness {
Http.writeToServerSync(serverRoot + path, "DELETE");
}
export function directoryExists(path: string): boolean {
export function directoryExists(): boolean {
return false;
}
@@ -792,7 +790,7 @@ namespace Harness {
return response.status === 200;
}
export function _listFilesImpl(path: string, spec?: RegExp, options?: any) {
export let listFiles = Utils.memoize((path: string, spec?: RegExp): string[] => {
const response = Http.getFileFromServerSync(serverRoot + path);
if (response.status === 200) {
const results = response.responseText.split(",");
@@ -806,8 +804,7 @@ namespace Harness {
else {
return [""];
}
};
export let listFiles = Utils.memoize(_listFilesImpl);
});
export function readFile(file: string) {
const response = Http.getFileFromServerSync(serverRoot + file);
@@ -941,7 +938,17 @@ namespace Harness {
}
export function getDefaultLibFileName(options: ts.CompilerOptions): string {
return options.target === ts.ScriptTarget.ES6 ? es2015DefaultLibFileName : defaultLibFileName;
switch (options.target) {
case ts.ScriptTarget.ES2017:
return "lib.es2017.d.ts";
case ts.ScriptTarget.ES2016:
return "lib.es2016.d.ts";
case ts.ScriptTarget.ES2015:
return es2015DefaultLibFileName;
default:
return defaultLibFileName;
}
}
// Cache these between executions so we don't have to re-parse them for every test
@@ -981,7 +988,7 @@ namespace Harness {
}
}
function getSourceFile(fileName: string, languageVersion: ts.ScriptTarget) {
function getSourceFile(fileName: string) {
fileName = ts.normalizePath(fileName);
const path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
if (fileMap.contains(path)) {
@@ -1022,7 +1029,7 @@ namespace Harness {
},
realpath: realPathMap && ((f: string) => {
const path = ts.toPath(f, currentDirectory, getCanonicalFileName);
return realPathMap.contains(path) ? realPathMap.get(path) : path;
return realPathMap.get(path) || path;
}),
directoryExists: dir => {
let path = ts.toPath(dir, currentDirectory, getCanonicalFileName);
@@ -1030,18 +1037,12 @@ namespace Harness {
if (path[path.length - 1] === "/") {
path = <ts.Path>path.substr(0, path.length - 1);
}
let exists = false;
fileMap.forEachValue(key => {
if (key.indexOf(path) === 0 && key[path.length] === "/") {
exists = true;
}
});
return exists;
return mapHasFileInDirectory(path, fileMap) || mapHasFileInDirectory(path, realPathMap);
},
getDirectories: d => {
const path = ts.toPath(d, currentDirectory, getCanonicalFileName);
const result: string[] = [];
fileMap.forEachValue((key, value) => {
fileMap.forEachValue(key => {
if (key.indexOf(path) === 0 && key.lastIndexOf("/") > path.length) {
let dirName = key.substr(path.length, key.indexOf("/", path.length + 1) - path.length);
if (dirName[0] === "/") {
@@ -1057,6 +1058,19 @@ namespace Harness {
};
}
function mapHasFileInDirectory(directoryPath: ts.Path, map: ts.FileMap<any>): boolean {
if (!map) {
return false;
}
let exists = false;
map.forEachValue(fileName => {
if (!exists && ts.startsWith(fileName, directoryPath) && fileName[directoryPath.length] === "/") {
exists = true;
}
});
return exists;
}
interface HarnessOptions {
useCaseSensitiveFileNames?: boolean;
includeBuiltFile?: string;
@@ -1101,22 +1115,7 @@ namespace Harness {
const option = getCommandLineOption(name);
if (option) {
const errors: ts.Diagnostic[] = [];
switch (option.type) {
case "boolean":
options[option.name] = value.toLowerCase() === "true";
break;
case "string":
options[option.name] = value;
break;
// If not a primitive, the possible types are specified in what is effectively a map of options.
case "list":
options[option.name] = ts.parseListTypeOption(<ts.CommandLineOptionOfListType>option, value, errors);
break;
default:
options[option.name] = ts.parseCustomTypeOption(<ts.CommandLineOptionOfCustomType>option, value, errors);
break;
}
options[option.name] = optionValue(option, value, errors);
if (errors.length > 0) {
throw new Error(`Unknown value '${value}' for compiler option '${name}'.`);
}
@@ -1128,6 +1127,27 @@ namespace Harness {
}
}
function optionValue(option: ts.CommandLineOption, value: string, errors: ts.Diagnostic[]): any {
switch (option.type) {
case "boolean":
return value.toLowerCase() === "true";
case "string":
return value;
case "number": {
const number = parseInt(value, 10);
if (isNaN(number)) {
throw new Error(`Value must be a number, got: ${JSON.stringify(value)}`);
}
return number;
}
// If not a primitive, the possible types are specified in what is effectively a map of options.
case "list":
return ts.parseListTypeOption(<ts.CommandLineOptionOfListType>option, value, errors);
default:
return ts.parseCustomTypeOption(<ts.CommandLineOptionOfCustomType>option, value, errors);
}
}
export interface TestFile {
unitName: string;
content: string;
@@ -1231,7 +1251,7 @@ namespace Harness {
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles));
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
const output = compileFiles(declInputFiles, declOtherFiles, harnessSettings, options, currentDirectory);
const output = compileFiles(declInputFiles, declOtherFiles, harnessSettings, options, currentDirectory || harnessSettings["currentDirectory"]);
return { declInputFiles, declOtherFiles, declResult: output.result };
}
@@ -1634,7 +1654,7 @@ namespace Harness {
export function collateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): string {
// Collect, test, and sort the fileNames
outputFiles.sort((a, b) => cleanName(a.fileName).localeCompare(cleanName(b.fileName)));
outputFiles.sort((a, b) => ts.compareStrings(cleanName(a.fileName), cleanName(b.fileName)));
// Emit them
let result = "";
@@ -1659,9 +1679,9 @@ namespace Harness {
}
// This does not need to exist strictly speaking, but many tests will need to be updated if it's removed
export function compileString(code: string, unitName: string, callback: (result: CompilerResult) => void) {
export function compileString(_code: string, _unitName: string, _callback: (result: CompilerResult) => void) {
// NEWTODO: Re-implement 'compileString'
throw new Error("compileString NYI");
return ts.notImplemented();
}
export interface GeneratedFile {
@@ -1843,8 +1863,8 @@ namespace Harness {
// unit tests always list files explicitly
const parseConfigHost: ts.ParseConfigHost = {
useCaseSensitiveFileNames: false,
readDirectory: (name) => [],
fileExists: (name) => true,
readDirectory: () => [],
fileExists: () => true,
readFile: (name) => ts.forEach(testUnitData, data => data.name.toLowerCase() === name.toLowerCase() ? data.content : undefined)
};
+42 -39
View File
@@ -165,7 +165,7 @@ namespace Harness.LanguageService {
throw new Error("No script with name '" + fileName + "'");
}
public openFile(fileName: string, content?: string, scriptKindName?: string): void {
public openFile(_fileName: string, _content?: string, _scriptKindName?: string): void {
}
/**
@@ -198,7 +198,7 @@ namespace Harness.LanguageService {
const script = this.getScriptInfo(fileName);
return script ? new ScriptSnapshot(script) : undefined;
}
getScriptKind(fileName: string): ts.ScriptKind { return ts.ScriptKind.Unknown; }
getScriptKind(): ts.ScriptKind { return ts.ScriptKind.Unknown; }
getScriptVersion(fileName: string): string {
const script = this.getScriptInfo(fileName);
return script ? script.version.toString() : undefined;
@@ -214,7 +214,7 @@ namespace Harness.LanguageService {
this.getCurrentDirectory(),
(p) => this.virtualFileSystem.getAccessibleFileSystemEntries(p));
}
readFile(path: string, encoding?: string): string {
readFile(path: string): string {
const snapshot = this.getScriptSnapshot(path);
return snapshot.getText(0, snapshot.getLength());
}
@@ -223,9 +223,9 @@ namespace Harness.LanguageService {
}
log(s: string): void { }
trace(s: string): void { }
error(s: string): void { }
log(_: string): void { }
trace(_: string): void { }
error(_: string): void { }
}
export class NativeLanguageServiceAdapter implements LanguageServiceAdapter {
@@ -308,19 +308,15 @@ namespace Harness.LanguageService {
const nativeScriptSnapshot = this.nativeHost.getScriptSnapshot(fileName);
return nativeScriptSnapshot && new ScriptSnapshotProxy(nativeScriptSnapshot);
}
getScriptKind(fileName: string): ts.ScriptKind { return this.nativeHost.getScriptKind(fileName); }
getScriptKind(): ts.ScriptKind { return this.nativeHost.getScriptKind(); }
getScriptVersion(fileName: string): string { return this.nativeHost.getScriptVersion(fileName); }
getLocalizedDiagnosticMessages(): string { return JSON.stringify({}); }
readDirectory(rootDir: string, extension: string): string {
throw new Error("NYI");
}
readDirectoryNames(path: string): string {
throw new Error("Not implemented.");
}
readFileNames(path: string): string {
throw new Error("Not implemented.");
readDirectory(_rootDir: string, _extension: string): string {
return ts.notImplemented();
}
readDirectoryNames = ts.notImplemented;
readFileNames = ts.notImplemented;
fileExists(fileName: string) { return this.getScriptInfo(fileName) !== undefined; }
readFile(fileName: string) {
const snapshot = this.nativeHost.getScriptSnapshot(fileName);
@@ -329,7 +325,7 @@ namespace Harness.LanguageService {
log(s: string): void { this.nativeHost.log(s); }
trace(s: string): void { this.nativeHost.trace(s); }
error(s: string): void { this.nativeHost.error(s); }
directoryExists(directoryName: string): boolean {
directoryExists(): boolean {
// for tests pessimistically assume that directory always exists
return true;
}
@@ -338,8 +334,8 @@ namespace Harness.LanguageService {
class ClassifierShimProxy implements ts.Classifier {
constructor(private shim: ts.ClassifierShim) {
}
getEncodedLexicalClassifications(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics?: boolean): ts.Classifications {
throw new Error("NYI");
getEncodedLexicalClassifications(_text: string, _lexState: ts.EndOfLineState, _classifyKeywordsInGenerics?: boolean): ts.Classifications {
return ts.notImplemented();
}
getClassificationsForLine(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics?: boolean): ts.ClassificationResult {
const result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split("\n");
@@ -411,7 +407,7 @@ namespace Harness.LanguageService {
getCompletionEntryDetails(fileName: string, position: number, entryName: string): ts.CompletionEntryDetails {
return unwrapJSONCallResult(this.shim.getCompletionEntryDetails(fileName, position, entryName));
}
getCompletionEntrySymbol(fileName: string, position: number, entryName: string): ts.Symbol {
getCompletionEntrySymbol(): ts.Symbol {
throw new Error("getCompletionEntrySymbol not implemented across the shim layer.");
}
getQuickInfoAtPosition(fileName: string, position: number): ts.QuickInfo {
@@ -459,6 +455,10 @@ namespace Harness.LanguageService {
getNavigationBarItems(fileName: string): ts.NavigationBarItem[] {
return unwrapJSONCallResult(this.shim.getNavigationBarItems(fileName));
}
getNavigationTree(fileName: string): ts.NavigationTree {
return unwrapJSONCallResult(this.shim.getNavigationTree(fileName));
}
getOutliningSpans(fileName: string): ts.OutliningSpan[] {
return unwrapJSONCallResult(this.shim.getOutliningSpans(fileName));
}
@@ -486,16 +486,19 @@ namespace Harness.LanguageService {
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean {
return unwrapJSONCallResult(this.shim.isValidBraceCompletionAtPosition(fileName, position, openingBrace));
}
getCodeFixesAtPosition(): ts.CodeAction[] {
throw new Error("Not supported on the shim.");
}
getEmitOutput(fileName: string): ts.EmitOutput {
return unwrapJSONCallResult(this.shim.getEmitOutput(fileName));
}
getProgram(): ts.Program {
throw new Error("Program can not be marshaled across the shim layer.");
}
getNonBoundSourceFile(fileName: string): ts.SourceFile {
getNonBoundSourceFile(): ts.SourceFile {
throw new Error("SourceFile can not be marshaled across the shim layer.");
}
getSourceFile(fileName: string): ts.SourceFile {
getSourceFile(): ts.SourceFile {
throw new Error("SourceFile can not be marshaled across the shim layer.");
}
dispose(): void { this.shim.dispose({}); }
@@ -565,11 +568,11 @@ namespace Harness.LanguageService {
super(cancellationToken, settings);
}
onMessage(message: string): void {
onMessage(): void {
}
writeMessage(message: string): void {
writeMessage(): void {
}
@@ -597,11 +600,11 @@ namespace Harness.LanguageService {
this.newLine = this.host.getNewLine();
}
onMessage(message: string): void {
onMessage(): void {
}
writeMessage(message: string): void {
writeMessage(_message: string): void {
}
write(message: string): void {
@@ -617,7 +620,7 @@ namespace Harness.LanguageService {
return snapshot && snapshot.getText(0, snapshot.getLength());
}
writeFile(name: string, text: string, writeByteOrderMark: boolean): void {
writeFile(): void {
}
resolvePath(path: string): string {
@@ -628,7 +631,7 @@ namespace Harness.LanguageService {
return !!this.host.getScriptSnapshot(path);
}
directoryExists(path: string): boolean {
directoryExists(): boolean {
// for tests assume that directory exists
return true;
}
@@ -637,18 +640,18 @@ namespace Harness.LanguageService {
return "";
}
exit(exitCode: number): void {
exit(): void {
}
createDirectory(directoryName: string): void {
throw new Error("Not Implemented Yet.");
createDirectory(_directoryName: string): void {
return ts.notImplemented();
}
getCurrentDirectory(): string {
return this.host.getCurrentDirectory();
}
getDirectories(path: string): string[] {
getDirectories(): string[] {
return [];
}
@@ -656,16 +659,16 @@ namespace Harness.LanguageService {
return ts.sys.getEnvironmentVariable(name);
}
readDirectory(path: string, extension?: string[], exclude?: string[], include?: string[]): string[] {
throw new Error("Not implemented Yet.");
readDirectory(_path: string, _extension?: string[], _exclude?: string[], _include?: string[]): string[] {
return ts.notImplemented();
}
watchFile(fileName: string, callback: (fileName: string) => void): ts.FileWatcher {
return { close() { } };
watchFile(): ts.FileWatcher {
return { close: ts.noop };
}
watchDirectory(path: string, callback: (path: string) => void, recursive?: boolean): ts.FileWatcher {
return { close() { } };
watchDirectory(): ts.FileWatcher {
return { close: ts.noop };
}
close(): void {
@@ -710,7 +713,7 @@ namespace Harness.LanguageService {
clearTimeout(timeoutId);
}
setImmediate(callback: (...args: any[]) => void, ms: number, ...args: any[]): any {
setImmediate(callback: (...args: any[]) => void, _ms: number, ...args: any[]): any {
return setImmediate(callback, args);
}
@@ -753,6 +756,6 @@ namespace Harness.LanguageService {
getHost() { return this.host; }
getLanguageService(): ts.LanguageService { return this.client; }
getClassifier(): ts.Classifier { throw new Error("getClassifier is not available using the server interface."); }
getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { throw new Error("getPreProcessedFileInfo is not available using the server interface."); }
getPreProcessedFileInfo(): ts.PreProcessedFileInfo { throw new Error("getPreProcessedFileInfo is not available using the server interface."); }
}
}
+15 -11
View File
@@ -173,7 +173,7 @@ namespace Playback {
path => callAndRecord(underlying.fileExists(path), recordLog.fileExists, { path }),
memoize(path => {
// If we read from the file, it must exist
if (findFileByPath(wrapper, replayLog.filesRead, path, /*throwFileNotFoundError*/ false)) {
if (findFileByPath(replayLog.filesRead, path, /*throwFileNotFoundError*/ false)) {
return true;
}
else {
@@ -217,7 +217,7 @@ namespace Playback {
recordLog.filesRead.push(logEntry);
return result;
},
memoize(path => findFileByPath(wrapper, replayLog.filesRead, path, /*throwFileNotFoundError*/ true).contents));
memoize(path => findFileByPath(replayLog.filesRead, path, /*throwFileNotFoundError*/ true).contents));
wrapper.readDirectory = recordReplay(wrapper.readDirectory, underlying)(
(path, extensions, exclude, include) => {
@@ -226,7 +226,7 @@ namespace Playback {
recordLog.directoriesRead.push(logEntry);
return result;
},
(path, extensions, exclude) => {
path => {
// Because extensions is an array of all allowed extension, we will want to merge each of the replayLog.directoriesRead into one
// if each of the directoriesRead has matched path with the given path (directory with same path but different extension will considered
// different entry).
@@ -244,7 +244,7 @@ namespace Playback {
wrapper.writeFile = recordReplay(wrapper.writeFile, underlying)(
(path: string, contents: string) => callAndRecord(underlying.writeFile(path, contents), recordLog.filesWritten, { path, contents, bom: false }),
(path: string, contents: string) => noOpReplay("writeFile"));
() => noOpReplay("writeFile"));
wrapper.exit = (exitCode) => {
if (recordLog !== undefined) {
@@ -295,7 +295,7 @@ namespace Playback {
return results[0].result;
}
function findFileByPath(wrapper: { resolvePath(s: string): string }, logArray: IOLogFile[],
function findFileByPath(logArray: IOLogFile[],
expectedPath: string, throwFileNotFoundError: boolean): FileInformation {
const normalizedName = ts.normalizePath(expectedPath).toLowerCase();
// Try to find the result through normal fileName
@@ -314,7 +314,7 @@ namespace Playback {
}
}
function noOpReplay(name: string) {
function noOpReplay(_name: string) {
// console.log("Swallowed write operation during replay: " + name);
}
@@ -322,13 +322,17 @@ namespace Playback {
const wrapper: PlaybackIO = <any>{};
initWrapper(wrapper, underlying);
wrapper.directoryName = (path): string => { throw new Error("NotSupported"); };
wrapper.createDirectory = (path): void => { throw new Error("NotSupported"); };
wrapper.directoryExists = (path): boolean => { throw new Error("NotSupported"); };
wrapper.deleteFile = (path): void => { throw new Error("NotSupported"); };
wrapper.listFiles = (path, filter, options): string[] => { throw new Error("NotSupported"); };
wrapper.directoryName = notSupported;
wrapper.createDirectory = notSupported;
wrapper.directoryExists = notSupported;
wrapper.deleteFile = notSupported;
wrapper.listFiles = notSupported;
return wrapper;
function notSupported(): never {
throw new Error("NotSupported");
}
}
export function wrapSystem(underlying: ts.System): PlaybackSystem {
+2 -2
View File
@@ -178,7 +178,7 @@ class ProjectRunner extends RunnerBase {
function createCompilerHost(): ts.CompilerHost {
return {
getSourceFile,
getDefaultLibFileName: options => Harness.Compiler.defaultLibFileName,
getDefaultLibFileName: () => Harness.Compiler.defaultLibFileName,
writeFile,
getCurrentDirectory,
getCanonicalFileName: Harness.Compiler.getCanonicalFileName,
@@ -421,7 +421,7 @@ class ProjectRunner extends RunnerBase {
return undefined;
}
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean) {
function writeFile() {
}
}
+1 -1
View File
@@ -222,5 +222,5 @@ else {
}
if (!runUnitTests) {
// patch `describe` to skip unit tests
describe = <any>(function () { });
describe = ts.noop as any;
}
+10 -4
View File
@@ -10,7 +10,10 @@
"stripInternal": true,
"types": [
"node", "mocha", "chai"
]
],
"target": "es5",
"noUnusedLocals": true,
"noUnusedParameters": true
},
"files": [
"../compiler/core.ts",
@@ -26,13 +29,16 @@
"../compiler/visitor.ts",
"../compiler/transformers/ts.ts",
"../compiler/transformers/jsx.ts",
"../compiler/transformers/es7.ts",
"../compiler/transformers/es6.ts",
"../compiler/transformers/es2017.ts",
"../compiler/transformers/es2016.ts",
"../compiler/transformers/es2015.ts",
"../compiler/transformers/es5.ts",
"../compiler/transformers/generators.ts",
"../compiler/transformers/es5.ts",
"../compiler/transformers/destructuring.ts",
"../compiler/transformers/module/module.ts",
"../compiler/transformers/module/system.ts",
"../compiler/transformers/module/es6.ts",
"../compiler/transformers/module/es2015.ts",
"../compiler/transformer.ts",
"../compiler/comments.ts",
"../compiler/sourcemap.ts",
+25 -35
View File
@@ -21,16 +21,15 @@ namespace ts {
args: <string[]>[],
newLine: "\r\n",
useCaseSensitiveFileNames: false,
write: (s: string) => {
},
readFile: (path: string, encoding?: string): string => {
write: noop,
readFile: (path: string): string => {
return path in fileMap ? fileMap[path].content : undefined;
},
writeFile: (path: string, data: string, writeByteOrderMark?: boolean) => {
throw new Error("NYI");
writeFile: (_path: string, _data: string, _writeByteOrderMark?: boolean) => {
return ts.notImplemented();
},
resolvePath: (path: string): string => {
throw new Error("NYI");
resolvePath: (_path: string): string => {
return ts.notImplemented();
},
fileExists: (path: string): boolean => {
return path in fileMap;
@@ -38,31 +37,25 @@ namespace ts {
directoryExists: (path: string): boolean => {
return existingDirectories[path] || false;
},
createDirectory: (path: string) => {
},
createDirectory: noop,
getExecutingFilePath: (): string => {
return "";
},
getCurrentDirectory: (): string => {
return "";
},
getDirectories: (path: string) => [],
getEnvironmentVariable: (name: string) => "",
readDirectory: (path: string, extension?: string[], exclude?: string[], include?: string[]): string[] => {
throw new Error("NYI");
},
exit: (exitCode?: number) => {
},
watchFile: (path, callback) => {
return {
close: () => { }
};
},
watchDirectory: (path, callback, recursive?) => {
return {
close: () => { }
};
getDirectories: () => [],
getEnvironmentVariable: () => "",
readDirectory: (_path: string, _extension?: string[], _exclude?: string[], _include?: string[]): string[] => {
return ts.notImplemented();
},
exit: noop,
watchFile: () => ({
close: noop
}),
watchDirectory: () => ({
close: noop
}),
setTimeout,
clearTimeout,
setImmediate,
@@ -72,14 +65,14 @@ namespace ts {
function createProject(rootFile: string, serverHost: server.ServerHost): { project: server.Project, rootScriptInfo: server.ScriptInfo } {
const logger: server.Logger = {
close() { },
close: noop,
hasLevel: () => false,
loggingEnabled: () => false,
perftrc: (s: string) => { },
info: (s: string) => { },
startGroup: () => { },
endGroup: () => { },
msg: (s: string, type?: string) => { },
perftrc: noop,
info: noop,
startGroup: noop,
endGroup: noop,
msg: noop,
getLogFileName: (): string => undefined
};
@@ -116,10 +109,7 @@ namespace ts {
const originalFileExists = serverHost.fileExists;
{
// patch fileExists to make sure that disk is not touched
serverHost.fileExists = (fileName): boolean => {
assert.isTrue(false, "fileExists should not be called");
return false;
};
serverHost.fileExists = notImplemented;
const newContent = `import {x} from "f1"
var x: string = 1;`;
+42 -9
View File
@@ -1,4 +1,4 @@
/// <reference path="..\harness.ts" />
/// <reference path="..\harness.ts" />
/// <reference path="..\..\compiler\commandLineParser.ts" />
namespace ts {
@@ -60,7 +60,7 @@ namespace ts {
assertParseResult(["--lib", "es5,invalidOption", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
@@ -87,7 +87,7 @@ namespace ts {
start: undefined,
length: undefined,
}, {
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
@@ -113,7 +113,7 @@ namespace ts {
start: undefined,
length: undefined,
}, {
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
@@ -139,7 +139,7 @@ namespace ts {
start: undefined,
length: undefined,
}, {
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
@@ -165,7 +165,7 @@ namespace ts {
start: undefined,
length: undefined,
}, {
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015'",
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
@@ -191,7 +191,7 @@ namespace ts {
start: undefined,
length: undefined,
}, {
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
@@ -263,7 +263,7 @@ namespace ts {
assertParseResult(["--lib", "es5,", "es7", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
@@ -283,7 +283,7 @@ namespace ts {
assertParseResult(["--lib", "es5, ", "es7", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
@@ -338,5 +338,38 @@ namespace ts {
}
});
});
it("Parse explicit boolean flag value", () => {
assertParseResult(["--strictNullChecks", "false", "0.ts"],
{
errors: [],
fileNames: ["0.ts"],
options: {
strictNullChecks: false,
}
});
});
it("Parse non boolean argument after boolean flag", () => {
assertParseResult(["--noImplicitAny", "t", "0.ts"],
{
errors: [],
fileNames: ["t", "0.ts"],
options: {
noImplicitAny: true,
}
});
});
it("Parse implicit boolean flag value", () => {
assertParseResult(["--strictNullChecks"],
{
errors: [],
fileNames: [],
options: {
strictNullChecks: true,
}
});
});
});
}
+21 -19
View File
@@ -3,6 +3,8 @@
/// <reference path="../../server/typingsInstaller/typingsInstaller.ts" />
namespace ts.projectSystem {
import CommandNames = server.CommandNames;
function createTestTypingsInstaller(host: server.ServerHost) {
return new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
}
@@ -75,7 +77,7 @@ namespace ts.projectSystem {
};
// Change the content of file1 to `export var T: number;export function Foo() { };`
changeModuleFile1ShapeRequest1 = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
changeModuleFile1ShapeRequest1 = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 1,
@@ -85,7 +87,7 @@ namespace ts.projectSystem {
});
// Change the content of file1 to `export var T: number;export function Foo() { };`
changeModuleFile1InternalRequest1 = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
changeModuleFile1InternalRequest1 = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 1,
@@ -95,7 +97,7 @@ namespace ts.projectSystem {
});
// Change the content of file1 to `export var T: number;export function Foo() { };`
changeModuleFile1ShapeRequest2 = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
changeModuleFile1ShapeRequest2 = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 1,
@@ -104,7 +106,7 @@ namespace ts.projectSystem {
insertString: `export var T2: number;`
});
moduleFile1FileListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(server.CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path, projectFileName: configFile.path });
moduleFile1FileListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path, projectFileName: configFile.path });
});
it("should contains only itself if a module file's shape didn't change, and all files referencing it if its shape changed", () => {
@@ -120,7 +122,7 @@ namespace ts.projectSystem {
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]);
// Change the content of file1 to `export var T: number;export function Foo() { console.log('hi'); };`
const changeFile1InternalRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
const changeFile1InternalRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 46,
@@ -143,7 +145,7 @@ namespace ts.projectSystem {
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]);
// Change file2 content to `let y = Foo();`
const removeFile1Consumer1ImportRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
const removeFile1Consumer1ImportRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
file: file1Consumer1.path,
line: 1,
offset: 1,
@@ -156,7 +158,7 @@ namespace ts.projectSystem {
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer2] }]);
// Add the import statements back to file2
const addFile2ImportRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
const addFile2ImportRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
file: file1Consumer1.path,
line: 1,
offset: 1,
@@ -167,7 +169,7 @@ namespace ts.projectSystem {
session.executeCommand(addFile2ImportRequest);
// Change the content of file1 to `export var T2: string;export var T: number;export function Foo() { };`
const changeModuleFile1ShapeRequest2 = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
const changeModuleFile1ShapeRequest2 = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 1,
@@ -272,7 +274,7 @@ namespace ts.projectSystem {
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
openFilesForSession([globalFile3], session);
const changeGlobalFile3ShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
const changeGlobalFile3ShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
file: globalFile3.path,
line: 1,
offset: 1,
@@ -283,7 +285,7 @@ namespace ts.projectSystem {
// check after file1 shape changes
session.executeCommand(changeGlobalFile3ShapeRequest);
const globalFile3FileListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(server.CommandNames.CompileOnSaveAffectedFileList, { file: globalFile3.path });
const globalFile3FileListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: globalFile3.path });
sendAffectedFileRequestAndCheckResult(session, globalFile3FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2] }]);
});
@@ -316,7 +318,7 @@ namespace ts.projectSystem {
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
openFilesForSession([moduleFile1], session);
const file1ChangeShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
const file1ChangeShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 27,
@@ -345,7 +347,7 @@ namespace ts.projectSystem {
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
openFilesForSession([moduleFile1], session);
const file1ChangeShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
const file1ChangeShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 27,
@@ -369,7 +371,7 @@ namespace ts.projectSystem {
openFilesForSession([moduleFile1, file1Consumer1], session);
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer1Consumer1] }]);
const changeFile1Consumer1ShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
const changeFile1Consumer1ShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
file: file1Consumer1.path,
line: 2,
offset: 1,
@@ -400,7 +402,7 @@ namespace ts.projectSystem {
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
openFilesForSession([file1, file2], session);
const file1AffectedListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(server.CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
const file1AffectedListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
sendAffectedFileRequestAndCheckResult(session, file1AffectedListRequest, [{ projectFileName: configFile.path, files: [file1, file2] }]);
});
@@ -415,7 +417,7 @@ namespace ts.projectSystem {
const session = createSession(host);
openFilesForSession([file1, file2, file3], session);
const file1AffectedListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(server.CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
const file1AffectedListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
sendAffectedFileRequestAndCheckResult(session, file1AffectedListRequest, [
{ projectFileName: configFile1.path, files: [file1, file2] },
@@ -437,11 +439,11 @@ namespace ts.projectSystem {
host.reloadFS([referenceFile1, configFile]);
host.triggerFileWatcherCallback(moduleFile1.path, /*removed*/ true);
const request = makeSessionRequest<server.protocol.FileRequestArgs>(server.CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path });
const request = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path });
sendAffectedFileRequestAndCheckResult(session, request, [
{ projectFileName: configFile.path, files: [referenceFile1] }
]);
const requestForMissingFile = makeSessionRequest<server.protocol.FileRequestArgs>(server.CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path });
const requestForMissingFile = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path });
sendAffectedFileRequestAndCheckResult(session, requestForMissingFile, []);
});
@@ -456,7 +458,7 @@ namespace ts.projectSystem {
const session = createSession(host);
openFilesForSession([referenceFile1], session);
const request = makeSessionRequest<server.protocol.FileRequestArgs>(server.CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path });
const request = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path });
sendAffectedFileRequestAndCheckResult(session, request, [
{ projectFileName: configFile.path, files: [referenceFile1] }
]);
@@ -483,7 +485,7 @@ namespace ts.projectSystem {
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
openFilesForSession([file1, file2], session);
const compileFileRequest = makeSessionRequest<server.protocol.CompileOnSaveEmitFileRequestArgs>(server.CommandNames.CompileOnSaveEmitFile, { file: file1.path, projectFileName: configFile.path });
const compileFileRequest = makeSessionRequest<server.protocol.CompileOnSaveEmitFileRequestArgs>(CommandNames.CompileOnSaveEmitFile, { file: file1.path, projectFileName: configFile.path });
session.executeCommand(compileFileRequest);
const expectedEmittedFileName = "/a/b/f1.js";
@@ -94,7 +94,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -122,7 +122,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -150,7 +150,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -176,7 +176,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015'",
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -202,7 +202,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -233,7 +233,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -264,7 +264,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -295,7 +295,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -326,7 +326,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -405,6 +405,7 @@ namespace ts {
allowJs: true,
maxNodeModuleJsDepth: 2,
allowSyntheticDefaultImports: true,
skipLibCheck: true,
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
@@ -433,6 +434,7 @@ namespace ts {
allowJs: false,
maxNodeModuleJsDepth: 2,
allowSyntheticDefaultImports: true,
skipLibCheck: true,
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
@@ -456,7 +458,8 @@ namespace ts {
{
allowJs: true,
maxNodeModuleJsDepth: 2,
allowSyntheticDefaultImports: true
allowSyntheticDefaultImports: true,
skipLibCheck: true
},
errors: [{
file: undefined,
@@ -477,7 +480,8 @@ namespace ts {
{
allowJs: true,
maxNodeModuleJsDepth: 2,
allowSyntheticDefaultImports: true
allowSyntheticDefaultImports: true,
skipLibCheck: true
},
errors: <Diagnostic[]>[]
}
+1 -1
View File
@@ -101,7 +101,7 @@ namespace ts {
Harness.Baseline.runBaseline("JSDocParsing/DocComments.parsesCorrectly." + name + ".json",
() => JSON.stringify(comment.jsDoc,
(k, v) => v && v.pos !== undefined ? JSON.parse(Utils.sourceFileToJSON(v)) : v, 4));
(_, v) => v && v.pos !== undefined ? JSON.parse(Utils.sourceFileToJSON(v)) : v, 4));
});
}
+131 -177
View File
@@ -3,6 +3,7 @@
namespace ts {
const caseInsensitiveBasePath = "c:/dev/";
const caseInsensitiveTsconfigPath = "c:/dev/tsconfig.json";
const caseInsensitiveHost = new Utils.MockParseConfigHost(caseInsensitiveBasePath, /*useCaseSensitiveFileNames*/ false, [
"c:/dev/a.ts",
"c:/dev/a.d.ts",
@@ -88,6 +89,14 @@ namespace ts {
"c:/dev/g.min.js/.g/g.ts"
]);
const defaultExcludes = ["node_modules", "bower_components", "jspm_packages"];
function assertParsed(actual: ts.ParsedCommandLine, expected: ts.ParsedCommandLine): void {
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
}
describe("matchFiles", () => {
describe("with literal file list", () => {
it("without exclusions", () => {
@@ -107,9 +116,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("missing files are still present", () => {
const json = {
@@ -128,9 +135,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("are not removed due to excludes", () => {
const json = {
@@ -152,9 +157,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
});
@@ -176,9 +179,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with non .ts file extensions are excluded", () => {
const json = {
@@ -189,14 +190,15 @@ namespace ts {
};
const expected: ts.ParsedCommandLine = {
options: {},
errors: [],
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
],
fileNames: [],
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assertParsed(actual, expected);
});
it("with missing files are excluded", () => {
const json = {
@@ -207,14 +209,15 @@ namespace ts {
};
const expected: ts.ParsedCommandLine = {
options: {},
errors: [],
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
],
fileNames: [],
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assertParsed(actual, expected);
});
it("with literal excludes", () => {
const json = {
@@ -235,9 +238,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with wildcard excludes", () => {
const json = {
@@ -265,9 +266,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with recursive excludes", () => {
const json = {
@@ -294,9 +293,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with case sensitive exclude", () => {
const json = {
@@ -316,9 +313,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseSensitiveHost, caseSensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with common package folders and no exclusions", () => {
const json = {
@@ -340,9 +335,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with common package folders and exclusions", () => {
const json = {
@@ -369,9 +362,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with common package folders and empty exclude", () => {
const json = {
@@ -397,9 +388,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
});
@@ -423,9 +412,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("`*` matches only ts files", () => {
const json = {
@@ -446,9 +433,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("`?` matches only a single character", () => {
const json = {
@@ -468,9 +453,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with recursive directory", () => {
const json = {
@@ -492,9 +475,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with multiple recursive directories", () => {
const json = {
@@ -518,9 +499,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("case sensitive", () => {
const json = {
@@ -539,9 +518,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseSensitiveHost, caseSensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with missing files are excluded", () => {
const json = {
@@ -551,16 +528,17 @@ namespace ts {
};
const expected: ts.ParsedCommandLine = {
options: {},
errors: [],
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
],
fileNames: [],
wildcardDirectories: {
"c:/dev": ts.WatchDirectoryFlags.Recursive
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assertParsed(actual, expected);
});
it("always include literal files", () => {
const json = {
@@ -585,9 +563,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("exclude folders", () => {
const json = {
@@ -612,14 +588,12 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with common package folders and no exclusions", () => {
const json = {
include: [
"**/a.ts"
"**/a.ts"
]
};
const expected: ts.ParsedCommandLine = {
@@ -633,9 +607,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with common package folders and exclusions", () => {
const json = {
@@ -659,9 +631,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with common package folders and empty exclude", () => {
const json = {
@@ -684,9 +654,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("exclude .js files when allowJs=false", () => {
const json = {
@@ -701,16 +669,17 @@ namespace ts {
options: {
allowJs: false
},
errors: [],
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
],
fileNames: [],
wildcardDirectories: {
"c:/dev/js": ts.WatchDirectoryFlags.None
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assertParsed(actual, expected);
});
it("include .js files when allowJs=true", () => {
const json = {
@@ -735,9 +704,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("include explicitly listed .min.js files when allowJs=true", () => {
const json = {
@@ -762,9 +729,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("include paths outside of the project", () => {
const json = {
@@ -788,9 +753,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("include paths outside of the project using relative paths", () => {
const json = {
@@ -813,9 +776,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("exclude paths outside of the project using relative paths", () => {
const json = {
@@ -828,14 +789,15 @@ namespace ts {
};
const expected: ts.ParsedCommandLine = {
options: {},
errors: [],
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude))]
,
fileNames: [],
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assertParsed(actual, expected);
});
it("include files with .. in their name", () => {
const json = {
@@ -855,9 +817,7 @@ namespace ts {
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("exclude files with .. in their name", () => {
const json = {
@@ -879,9 +839,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with jsx=none, allowJs=false", () => {
const json = {
@@ -904,9 +862,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with jsx=preserve, allowJs=false", () => {
const json = {
@@ -931,9 +887,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with jsx=none, allowJs=true", () => {
const json = {
@@ -958,9 +912,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with jsx=preserve, allowJs=true", () => {
const json = {
@@ -987,9 +939,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("exclude .min.js files using wildcards", () => {
const json = {
@@ -1016,9 +966,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
describe("with trailing recursive directory", () => {
it("in includes", () => {
@@ -1030,15 +978,15 @@ namespace ts {
const expected: ts.ParsedCommandLine = {
options: {},
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**")
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**"),
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
],
fileNames: [],
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assertParsed(actual, expected);
});
it("in excludes", () => {
const json = {
@@ -1051,14 +999,15 @@ namespace ts {
};
const expected: ts.ParsedCommandLine = {
options: {},
errors: [],
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude))
],
fileNames: [],
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assertParsed(actual, expected);
});
});
describe("with multiple recursive directory patterns", () => {
@@ -1071,15 +1020,15 @@ namespace ts {
const expected: ts.ParsedCommandLine = {
options: {},
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**/*")
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**/*"),
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
],
fileNames: [],
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assertParsed(actual, expected);
});
it("in excludes", () => {
const json = {
@@ -1106,9 +1055,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
});
@@ -1122,15 +1069,15 @@ namespace ts {
const expected: ts.ParsedCommandLine = {
options: {},
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/../*")
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/../*"),
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
],
fileNames: [],
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assertParsed(actual, expected);
});
it("in includes after a subdirectory", () => {
@@ -1142,15 +1089,15 @@ namespace ts {
const expected: ts.ParsedCommandLine = {
options: {},
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/../*")
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/../*"),
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
],
fileNames: [],
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assertParsed(actual, expected);
});
it("in excludes immediately after", () => {
@@ -1178,9 +1125,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("in excludes after a subdirectory", () => {
@@ -1195,7 +1140,7 @@ namespace ts {
const expected: ts.ParsedCommandLine = {
options: {},
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/..")
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/..")
],
fileNames: [
"c:/dev/a.ts",
@@ -1208,9 +1153,25 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
});
describe("with implicit globbification", () => {
it("Expands 'z' to 'z/**/*'", () => {
const json = {
include: ["z"]
};
const expected: ts.ParsedCommandLine = {
options: {},
errors: [],
fileNames: [ "a.ts", "aba.ts", "abz.ts", "b.ts", "bba.ts", "bbz.ts" ].map(x => `c:/dev/z/${x}`),
wildcardDirectories: {
"c:/dev/z": ts.WatchDirectoryFlags.Recursive
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assertParsed(actual, expected);
});
});
});
@@ -1235,9 +1196,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
describe("that are explicitly included", () => {
it("without wildcards", () => {
@@ -1257,9 +1216,7 @@ namespace ts {
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with recursive wildcards that match directories", () => {
const json = {
@@ -1281,9 +1238,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with recursive wildcards that match nothing", () => {
const json = {
@@ -1305,9 +1260,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with wildcard excludes that implicitly exclude dotted files", () => {
const json = {
@@ -1320,14 +1273,15 @@ namespace ts {
};
const expected: ts.ParsedCommandLine = {
options: {},
errors: [],
errors: [
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude))
],
fileNames: [],
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assertParsed(actual, expected);
});
});
});
+88 -65
View File
@@ -1,6 +1,28 @@
/// <reference path="..\harness.ts" />
namespace ts {
export function checkResolvedModule(expected: ResolvedModuleFull, actual: ResolvedModuleFull): boolean {
if (!expected === !actual) {
if (expected) {
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
assert.isTrue(expected.extension === actual.extension, `'ext': expected '${Extension[expected.extension]}' to be equal to '${Extension[actual.extension]}'`);
assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
}
return true;
}
return false;
}
export function checkResolvedModuleWithFailedLookupLocations(actual: ResolvedModuleWithFailedLookupLocations, expectedResolvedModule: ResolvedModuleFull, expectedFailedLookupLocations: string[]): void {
assert.isTrue(actual.resolvedModule !== undefined, "module should be resolved");
checkResolvedModule(actual.resolvedModule, expectedResolvedModule);
assert.deepEqual(actual.failedLookupLocations, expectedFailedLookupLocations);
}
export function createResolvedModule(resolvedFileName: string, isExternalLibraryImport = false): ResolvedModuleFull {
return { resolvedFileName, extension: extensionFromPath(resolvedFileName), isExternalLibraryImport };
}
interface File {
name: string;
content?: string;
@@ -53,8 +75,7 @@ namespace ts {
const containingFile = { name: containingFileName };
const moduleFile = { name: moduleFileNameNoExt + ext };
const resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
checkResolvedModule(resolution.resolvedModule, createResolvedModule(moduleFile.name));
const failedLookupLocations: string[] = [];
const dir = getDirectoryPath(containingFileName);
@@ -97,8 +118,7 @@ namespace ts {
const packageJson = { name: packageJsonFileName, content: JSON.stringify({ "typings": fieldRef }) };
const moduleFile = { name: moduleFileName };
const resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
checkResolvedModule(resolution.resolvedModule, createResolvedModule(moduleFile.name));
// expect three failed lookup location - attempt to load module as file with all supported extensions
assert.equal(resolution.failedLookupLocations.length, supportedTypeScriptExtensions.length);
}
@@ -125,7 +145,7 @@ namespace ts {
const resolution = nodeModuleNameResolver("b", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile, indexFile));
assert.equal(resolution.resolvedModule.resolvedFileName, indexPath);
checkResolvedModule(resolution.resolvedModule, createResolvedModule(indexPath, /*isExternalLibraryImport*/true));
}
}
@@ -138,7 +158,6 @@ namespace ts {
/* tslint:enable no-null-keyword */
testTypingsIgnored(undefined);
});
it("module name as directory - load index.d.ts", () => {
test(/*hasDirectoryExists*/ false);
test(/*hasDirectoryExists*/ true);
@@ -148,9 +167,7 @@ namespace ts {
const packageJson = { name: "/a/b/foo/package.json", content: JSON.stringify({ main: "/c/d" }) };
const indexFile = { name: "/a/b/foo/index.d.ts" };
const resolution = nodeModuleNameResolver("./foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, indexFile));
assert.equal(resolution.resolvedModule.resolvedFileName, indexFile.name);
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
assert.deepEqual(resolution.failedLookupLocations, [
checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(indexFile.name), [
"/a/b/foo.ts",
"/a/b/foo.tsx",
"/a/b/foo.d.ts",
@@ -170,33 +187,39 @@ namespace ts {
const containingFile = { name: "/a/b/c/d/e.ts" };
const moduleFile = { name: "/a/b/node_modules/foo.ts" };
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.deepEqual(resolution.failedLookupLocations, [
checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true), [
"/a/b/c/d/node_modules/foo.ts",
"/a/b/c/d/node_modules/foo.tsx",
"/a/b/c/d/node_modules/foo.d.ts",
"/a/b/c/d/node_modules/foo/package.json",
"/a/b/c/d/node_modules/foo/index.ts",
"/a/b/c/d/node_modules/foo/index.tsx",
"/a/b/c/d/node_modules/foo/index.d.ts",
"/a/b/c/d/node_modules/@types/foo.ts",
"/a/b/c/d/node_modules/@types/foo.tsx",
"/a/b/c/d/node_modules/@types/foo.d.ts",
"/a/b/c/d/node_modules/@types/foo/package.json",
"/a/b/c/d/node_modules/@types/foo/index.ts",
"/a/b/c/d/node_modules/@types/foo/index.tsx",
"/a/b/c/d/node_modules/@types/foo/index.d.ts",
"/a/b/c/node_modules/foo.ts",
"/a/b/c/node_modules/foo.tsx",
"/a/b/c/node_modules/foo.d.ts",
"/a/b/c/node_modules/foo/package.json",
"/a/b/c/node_modules/foo/index.ts",
"/a/b/c/node_modules/foo/index.tsx",
"/a/b/c/node_modules/foo/index.d.ts",
"/a/b/c/node_modules/@types/foo.ts",
"/a/b/c/node_modules/@types/foo.tsx",
"/a/b/c/node_modules/@types/foo.d.ts",
"/a/b/c/node_modules/@types/foo/package.json",
"/a/b/c/node_modules/@types/foo/index.ts",
"/a/b/c/node_modules/@types/foo/index.tsx",
"/a/b/c/node_modules/@types/foo/index.d.ts",
@@ -212,8 +235,7 @@ namespace ts {
const containingFile = { name: "/a/b/c/d/e.ts" };
const moduleFile = { name: "/a/b/node_modules/foo.d.ts" };
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
checkResolvedModule(resolution.resolvedModule, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true));
}
});
@@ -225,55 +247,66 @@ namespace ts {
const containingFile = { name: "/a/node_modules/b/c/node_modules/d/e.ts" };
const moduleFile = { name: "/a/node_modules/foo/index.d.ts" };
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
assert.deepEqual(resolution.failedLookupLocations, [
checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true), [
"/a/node_modules/b/c/node_modules/d/node_modules/foo.ts",
"/a/node_modules/b/c/node_modules/d/node_modules/foo.tsx",
"/a/node_modules/b/c/node_modules/d/node_modules/foo.d.ts",
"/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json",
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.ts",
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.tsx",
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.d.ts",
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.ts",
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.tsx",
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.d.ts",
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/package.json",
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/index.ts",
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/index.tsx",
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/index.d.ts",
"/a/node_modules/b/c/node_modules/foo.ts",
"/a/node_modules/b/c/node_modules/foo.tsx",
"/a/node_modules/b/c/node_modules/foo.d.ts",
"/a/node_modules/b/c/node_modules/foo/package.json",
"/a/node_modules/b/c/node_modules/foo/index.ts",
"/a/node_modules/b/c/node_modules/foo/index.tsx",
"/a/node_modules/b/c/node_modules/foo/index.d.ts",
"/a/node_modules/b/c/node_modules/@types/foo.ts",
"/a/node_modules/b/c/node_modules/@types/foo.tsx",
"/a/node_modules/b/c/node_modules/@types/foo.d.ts",
"/a/node_modules/b/c/node_modules/@types/foo/package.json",
"/a/node_modules/b/c/node_modules/@types/foo/index.ts",
"/a/node_modules/b/c/node_modules/@types/foo/index.tsx",
"/a/node_modules/b/c/node_modules/@types/foo/index.d.ts",
"/a/node_modules/b/node_modules/foo.ts",
"/a/node_modules/b/node_modules/foo.tsx",
"/a/node_modules/b/node_modules/foo.d.ts",
"/a/node_modules/b/node_modules/foo/package.json",
"/a/node_modules/b/node_modules/foo/index.ts",
"/a/node_modules/b/node_modules/foo/index.tsx",
"/a/node_modules/b/node_modules/foo/index.d.ts",
"/a/node_modules/b/node_modules/@types/foo.ts",
"/a/node_modules/b/node_modules/@types/foo.tsx",
"/a/node_modules/b/node_modules/@types/foo.d.ts",
"/a/node_modules/b/node_modules/@types/foo/package.json",
"/a/node_modules/b/node_modules/@types/foo/index.ts",
"/a/node_modules/b/node_modules/@types/foo/index.tsx",
"/a/node_modules/b/node_modules/@types/foo/index.d.ts",
"/a/node_modules/foo.ts",
"/a/node_modules/foo.tsx",
"/a/node_modules/foo.d.ts",
"/a/node_modules/foo/package.json",
"/a/node_modules/foo/index.ts",
"/a/node_modules/foo/index.tsx"
]);
@@ -290,7 +323,7 @@ namespace ts {
return path in files ? createSourceFile(fileName, files[path], languageVersion) : undefined;
},
getDefaultLibFileName: () => "lib.d.ts",
writeFile: (fileName, content): void => { throw new Error("NotImplemented"); },
writeFile: notImplemented,
getCurrentDirectory: () => currentDirectory,
getDirectories: () => [],
getCanonicalFileName: fileName => fileName.toLowerCase(),
@@ -300,7 +333,7 @@ namespace ts {
const path = normalizePath(combinePaths(currentDirectory, fileName));
return path in files;
},
readFile: (fileName): string => { throw new Error("NotImplemented"); }
readFile: notImplemented
};
const program = createProgram(rootFiles, options, host);
@@ -370,7 +403,7 @@ export = C;
return path in files ? createSourceFile(fileName, files[path], languageVersion) : undefined;
},
getDefaultLibFileName: () => "lib.d.ts",
writeFile: (fileName, content): void => { throw new Error("NotImplemented"); },
writeFile: notImplemented,
getCurrentDirectory: () => currentDirectory,
getDirectories: () => [],
getCanonicalFileName,
@@ -380,7 +413,7 @@ export = C;
const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName)));
return path in files;
},
readFile: (fileName): string => { throw new Error("NotImplemented"); }
readFile: notImplemented
};
const program = createProgram(rootFiles, options, host);
const diagnostics = sortAndDeduplicateDiagnostics(program.getSemanticDiagnostics().concat(program.getOptionsDiagnostics()));
@@ -481,21 +514,15 @@ import b = require("./moduleB");
const options: CompilerOptions = { moduleResolution, baseUrl: "/root" };
{
const result = resolveModuleName("folder2/file2", file1.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, file2.name);
assert.deepEqual(result.failedLookupLocations, []);
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(file2.name), []);
}
{
const result = resolveModuleName("./file3", file2.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, file3.name);
assert.deepEqual(result.failedLookupLocations, []);
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(file3.name), []);
}
{
const result = resolveModuleName("/root/folder1/file1", file2.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, file1.name);
assert.deepEqual(result.failedLookupLocations, []);
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(file1.name), []);
}
}
}
@@ -520,12 +547,11 @@ import b = require("./moduleB");
check("m1", main, m1);
check("m2", main, m2);
check("m3", main, m3Typings);
check("m4", main, m4);
check("m4", main, m4, /*isExternalLibraryImport*/true);
function check(name: string, caller: File, expected: File) {
function check(name: string, caller: File, expected: File, isExternalLibraryImport = false) {
const result = resolveModuleName(name, caller.name, options, host);
assert.isTrue(result.resolvedModule !== undefined);
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
checkResolvedModule(result.resolvedModule, createResolvedModule(expected.name, isExternalLibraryImport));
}
}
});
@@ -547,8 +573,7 @@ import b = require("./moduleB");
function check(name: string, caller: File, expected: File) {
const result = resolveModuleName(name, caller.name, options, host);
assert.isTrue(result.resolvedModule !== undefined);
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
checkResolvedModule(result.resolvedModule, createResolvedModule(expected.name));
}
}
});
@@ -590,9 +615,10 @@ import b = require("./moduleB");
"/root/folder1/file2.tsx",
"/root/folder1/file2.d.ts",
"/root/folder1/file2/package.json",
"/root/folder1/file2/index.ts",
"/root/folder1/file2/index.tsx",
"/root/folder1/file2/index.d.ts"
"/root/folder1/file2/index.d.ts",
// then first attempt on 'generated/*' was successful
]);
check("folder2/file3", file3, [
@@ -601,14 +627,17 @@ import b = require("./moduleB");
"/root/folder2/file3.tsx",
"/root/folder2/file3.d.ts",
"/root/folder2/file3/package.json",
"/root/folder2/file3/index.ts",
"/root/folder2/file3/index.tsx",
"/root/folder2/file3/index.d.ts",
// then use remapped location
"/root/generated/folder2/file3.ts",
"/root/generated/folder2/file3.tsx",
"/root/generated/folder2/file3.d.ts",
"/root/generated/folder2/file3/package.json",
"/root/generated/folder2/file3/index.ts",
"/root/generated/folder2/file3/index.tsx",
// success on index.d.ts
@@ -619,13 +648,15 @@ import b = require("./moduleB");
"/root/folder2/file4.tsx",
"/root/folder2/file4.d.ts",
"/root/folder2/file4/package.json",
"/root/folder2/file4/index.ts",
"/root/folder2/file4/index.tsx",
"/root/folder2/file4/index.d.ts",
// try to load from file from remapped location
"/root/generated/folder2/file4.ts",
"/root/generated/folder2/file4.tsx",
"/root/generated/folder2/file4.d.ts"
"/root/generated/folder2/file4.d.ts",
// success on loading as from folder
]);
check("somefolder/file5", file5, [
@@ -634,6 +665,7 @@ import b = require("./moduleB");
"/root/someanotherfolder/file5.ts",
"/root/someanotherfolder/file5.tsx",
"/root/someanotherfolder/file5.d.ts",
// load from folder
"/root/someanotherfolder/file5/package.json",
"/root/someanotherfolder/file5/index.ts",
@@ -646,46 +678,51 @@ import b = require("./moduleB");
"/root/file6.ts",
"/root/file6.tsx",
"/root/file6.d.ts",
// load from folder
"/root/file6/package.json",
"/root/file6/index.ts",
"/root/file6/index.tsx",
"/root/file6/index.d.ts",
// then try 'generated/*'
// load from file
"/root/generated/file6.ts",
"/root/generated/file6.tsx",
"/root/generated/file6.d.ts",
// load from folder
"/root/generated/file6/package.json",
"/root/generated/file6/index.ts",
"/root/generated/file6/index.tsx",
"/root/generated/file6/index.d.ts",
// fallback to standard node behavior
// load from file
"/root/folder1/node_modules/file6.ts",
"/root/folder1/node_modules/file6.tsx",
"/root/folder1/node_modules/file6.d.ts",
// load from folder
"/root/folder1/node_modules/file6/package.json",
"/root/folder1/node_modules/file6/index.ts",
"/root/folder1/node_modules/file6/index.tsx",
"/root/folder1/node_modules/file6/index.d.ts",
"/root/folder1/node_modules/@types/file6.ts",
"/root/folder1/node_modules/@types/file6.tsx",
"/root/folder1/node_modules/@types/file6.d.ts",
"/root/folder1/node_modules/@types/file6/package.json",
"/root/folder1/node_modules/@types/file6/index.ts",
"/root/folder1/node_modules/@types/file6/index.tsx",
"/root/folder1/node_modules/@types/file6/index.d.ts"
"/root/folder1/node_modules/@types/file6/index.d.ts",
// success on /root/node_modules/file6.ts
]);
], /*isExternalLibraryImport*/ true);
function check(name: string, expected: File, expectedFailedLookups: string[]) {
function check(name: string, expected: File, expectedFailedLookups: string[], isExternalLibraryImport = false) {
const result = resolveModuleName(name, main.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name, isExternalLibraryImport), expectedFailedLookups);
}
}
});
@@ -744,9 +781,7 @@ import b = require("./moduleB");
function check(name: string, expected: File, expectedFailedLookups: string[]) {
const result = resolveModuleName(name, main.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name), expectedFailedLookups);
}
}
});
@@ -819,9 +854,7 @@ import b = require("./moduleB");
function check(name: string, container: File, expected: File, expectedFailedLookups: string[]) {
const result = resolveModuleName(name, container.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name), expectedFailedLookups);
}
}
});
@@ -875,9 +908,7 @@ import b = require("./moduleB");
function check(name: string, container: File, expected: File, expectedFailedLookups: string[]) {
const result = resolveModuleName(name, container.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name), expectedFailedLookups);
}
}
});
@@ -899,9 +930,7 @@ import b = require("./moduleB");
}
};
const result = resolveModuleName("libs/guid", app.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, libsTypings.name);
assert.deepEqual(result.failedLookupLocations, [
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(libsTypings.name), [
// first try to load module as file
"/root/src/libs/guid.ts",
"/root/src/libs/guid.tsx",
@@ -911,15 +940,11 @@ import b = require("./moduleB");
});
});
function notImplemented(name: string): () => any {
return () => assert(`${name} is not implemented and should not be called`);
}
describe("ModuleResolutionHost.directoryExists", () => {
it("No 'fileExists' calls if containing directory is missing", () => {
const host: ModuleResolutionHost = {
readFile: notImplemented("readFile"),
fileExists: notImplemented("fileExists"),
readFile: notImplemented,
fileExists: notImplemented,
directoryExists: _ => false
};
@@ -1017,14 +1042,12 @@ import b = require("./moduleB");
const files = [f1, f2, f3, f4];
const names = map(files, f => f.name);
const sourceFiles = arrayToMap(map(files, f => createSourceFile(f.name, f.content, ScriptTarget.ES6)), f => f.fileName);
const sourceFiles = arrayToMap(map(files, f => createSourceFile(f.name, f.content, ScriptTarget.ES2015)), f => f.fileName);
const compilerHost: CompilerHost = {
fileExists : fileName => fileName in sourceFiles,
getSourceFile: fileName => sourceFiles[fileName],
getDefaultLibFileName: () => "lib.d.ts",
writeFile(file, text) {
throw new Error("NYI");
},
writeFile: notImplemented,
getCurrentDirectory: () => "/",
getDirectories: () => [],
getCanonicalFileName: f => f.toLowerCase(),
+10 -27
View File
@@ -111,13 +111,11 @@ namespace ts {
getDefaultLibFileName(): string {
return "lib.d.ts";
},
writeFile(file, text) {
throw new Error("NYI");
},
writeFile: notImplemented,
getCurrentDirectory(): string {
return "";
},
getDirectories(path: string): string[] {
getDirectories(): string[] {
return [];
},
getCanonicalFileName(fileName): string {
@@ -152,17 +150,6 @@ namespace ts {
return program;
}
function checkResolvedModule(expected: ResolvedModule, actual: ResolvedModule): boolean {
if (!expected === !actual) {
if (expected) {
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
}
return true;
}
return false;
}
function checkResolvedTypeDirective(expected: ResolvedTypeReferenceDirective, actual: ResolvedTypeReferenceDirective): boolean {
if (!expected === !actual) {
if (expected) {
@@ -244,17 +231,13 @@ namespace ts {
it("fails if change affects type references", () => {
const program_1 = newProgram(files, ["a.ts"], { types: ["a"] });
updateProgram(program_1, ["a.ts"], { types: ["b"] }, files => {
});
updateProgram(program_1, ["a.ts"], { types: ["b"] }, noop);
assert.isTrue(!program_1.structureIsReused);
});
it("succeeds if change doesn't affect type references", () => {
const program_1 = newProgram(files, ["a.ts"], { types: ["a"] });
updateProgram(program_1, ["a.ts"], { types: ["a"] }, files => {
});
updateProgram(program_1, ["a.ts"], { types: ["a"] }, noop);
assert.isTrue(program_1.structureIsReused);
});
@@ -280,19 +263,19 @@ namespace ts {
it("fails if module kind changes", () => {
const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS });
updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.AMD }, files => void 0);
updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.AMD }, noop);
assert.isTrue(!program_1.structureIsReused);
});
it("fails if rootdir changes", () => {
const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/b" });
updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/c" }, files => void 0);
updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/c" }, noop);
assert.isTrue(!program_1.structureIsReused);
});
it("fails if config path changes", () => {
const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/b/tsconfig.json" });
updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/c/tsconfig.json" }, files => void 0);
updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/c/tsconfig.json" }, noop);
assert.isTrue(!program_1.structureIsReused);
});
@@ -306,7 +289,7 @@ namespace ts {
const options: CompilerOptions = { target };
const program_1 = newProgram(files, ["a.ts"], options);
checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": { resolvedFileName: "b.ts" } }));
checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": createResolvedModule("b.ts") }));
checkResolvedModulesCache(program_1, "b.ts", undefined);
const program_2 = updateProgram(program_1, ["a.ts"], options, files => {
@@ -315,7 +298,7 @@ namespace ts {
assert.isTrue(program_1.structureIsReused);
// content of resolution cache should not change
checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": { resolvedFileName: "b.ts" } }));
checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": createResolvedModule("b.ts") }));
checkResolvedModulesCache(program_1, "b.ts", undefined);
// imports has changed - program is not reused
@@ -332,7 +315,7 @@ namespace ts {
files[0].text = files[0].text.updateImportsAndExports(newImports);
});
assert.isTrue(!program_3.structureIsReused);
checkResolvedModulesCache(program_4, "a.ts", createMap({ "b": { resolvedFileName: "b.ts" }, "c": undefined }));
checkResolvedModulesCache(program_4, "a.ts", createMap({ "b": createResolvedModule("b.ts"), "c": undefined }));
});
it("resolved type directives cache follows type directives", () => {
@@ -62,7 +62,7 @@ describe("DocumentRegistry", () => {
const snapshot = ts.ScriptSnapshot.fromString(contents);
// Always treat any change as a full change.
snapshot.getChangeRange = old => ts.createTextChangeRange(ts.createTextSpan(0, contents.length), contents.length);
snapshot.getChangeRange = () => ts.createTextChangeRange(ts.createTextSpan(0, contents.length), contents.length);
// Simulate one LS getting the document.
documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, snapshot, /* version */ "1");
+75 -27
View File
@@ -10,41 +10,47 @@ namespace ts.server {
useCaseSensitiveFileNames: true,
write(s): void { lastWrittenToHost = s; },
readFile(): string { return void 0; },
writeFile(): void {},
writeFile: noop,
resolvePath(): string { return void 0; },
fileExists: () => false,
directoryExists: () => false,
getDirectories: () => [],
createDirectory(): void {},
createDirectory: noop,
getExecutingFilePath(): string { return void 0; },
getCurrentDirectory(): string { return void 0; },
getEnvironmentVariable(name: string): string { return ""; },
getEnvironmentVariable(): string { return ""; },
readDirectory(): string[] { return []; },
exit(): void { },
setTimeout(callback, ms, ...args) { return 0; },
clearTimeout(timeoutId) { },
exit: noop,
setTimeout() { return 0; },
clearTimeout: noop,
setImmediate: () => 0,
clearImmediate() {}
clearImmediate: noop
};
const nullCancellationToken: HostCancellationToken = { isCancellationRequested: () => false };
const mockLogger: Logger = {
close(): void {},
close: noop,
hasLevel(): boolean { return false; },
loggingEnabled(): boolean { return false; },
perftrc(s: string): void {},
info(s: string): void {},
startGroup(): void {},
endGroup(): void {},
msg(s: string, type?: string): void {},
perftrc: noop,
info: noop,
startGroup: noop,
endGroup: noop,
msg: noop,
getLogFileName: (): string => undefined
};
class TestSession extends Session {
getProjectService() {
return this.projectService;
}
}
describe("the Session class", () => {
let session: Session;
let session: TestSession;
let lastSent: protocol.Message;
beforeEach(() => {
session = new Session(mockHost, nullCancellationToken, /*useOneInferredProject*/ false, /*typingsInstaller*/ undefined, Utils.byteLength, process.hrtime, mockLogger, /*canUseEvents*/ true);
session = new TestSession(mockHost, nullCancellationToken, /*useOneInferredProject*/ false, /*typingsInstaller*/ undefined, Utils.byteLength, process.hrtime, mockLogger, /*canUseEvents*/ true);
session.send = (msg: protocol.Message) => {
lastSent = msg;
};
@@ -55,7 +61,7 @@ namespace ts.server {
const req: protocol.FileRequest = {
command: CommandNames.Open,
seq: 0,
type: "command",
type: "request",
arguments: {
file: undefined
}
@@ -67,7 +73,7 @@ namespace ts.server {
const req: protocol.Request = {
command: "foobar",
seq: 0,
type: "command"
type: "request"
};
session.executeCommand(req);
@@ -85,7 +91,7 @@ namespace ts.server {
const req: protocol.ConfigureRequest = {
command: CommandNames.Configure,
seq: 0,
type: "command",
type: "request",
arguments: {
hostInfo: "unit test",
formatOptions: {
@@ -106,6 +112,48 @@ namespace ts.server {
body: undefined
});
});
it ("should handle literal types in request", () => {
const configureRequest: protocol.ConfigureRequest = {
command: CommandNames.Configure,
seq: 0,
type: "request",
arguments: {
formatOptions: {
indentStyle: "Block"
}
}
};
session.onMessage(JSON.stringify(configureRequest));
assert.equal(session.getProjectService().getFormatCodeOptions().indentStyle, IndentStyle.Block);
const setOptionsRequest: protocol.SetCompilerOptionsForInferredProjectsRequest = {
command: CommandNames.CompilerOptionsForInferredProjects,
seq: 1,
type: "request",
arguments: {
options: {
module: "System",
target: "ES5",
jsx: "React",
newLine: "Lf",
moduleResolution: "Node"
}
}
};
session.onMessage(JSON.stringify(setOptionsRequest));
assert.deepEqual(
session.getProjectService().getCompilerOptionsForInferredProjects(),
<CompilerOptions>{
module: ModuleKind.System,
target: ScriptTarget.ES5,
jsx: JsxEmit.React,
newLine: NewLineKind.LineFeed,
moduleResolution: ModuleResolutionKind.NodeJs,
allowNonTsExtensions: true // injected by tsserver
});
});
});
describe("onMessage", () => {
@@ -118,7 +166,7 @@ namespace ts.server {
const req: protocol.Request = {
command: name,
seq: i,
type: "command"
type: "request"
};
i++;
session.onMessage(JSON.stringify(req));
@@ -151,7 +199,7 @@ namespace ts.server {
const req: protocol.ConfigureRequest = {
command: CommandNames.Configure,
seq: 0,
type: "command",
type: "request",
arguments: {
hostInfo: "unit test",
formatOptions: {
@@ -175,7 +223,7 @@ namespace ts.server {
describe("send", () => {
it("is an overrideable handle which sends protocol messages over the wire", () => {
const msg = { seq: 0, type: "none" };
const msg: server.protocol.Request = { seq: 0, type: "request", command: "" };
const strmsg = JSON.stringify(msg);
const len = 1 + Utils.byteLength(strmsg, "utf8");
const resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`;
@@ -198,12 +246,12 @@ namespace ts.server {
responseRequired: true
};
session.addProtocolHandler(command, (req) => result);
session.addProtocolHandler(command, () => result);
expect(session.executeCommand({
command,
seq: 0,
type: "command"
type: "request"
})).to.deep.equal(result);
});
it("throws when a duplicate handler is passed", () => {
@@ -216,9 +264,9 @@ namespace ts.server {
};
const command = "newhandle";
session.addProtocolHandler(command, (req) => resp);
session.addProtocolHandler(command, () => resp);
expect(() => session.addProtocolHandler(command, (req) => resp))
expect(() => session.addProtocolHandler(command, () => resp))
.to.throw(`Protocol handler already exists for command "${command}"`);
});
});
@@ -304,7 +352,7 @@ namespace ts.server {
expect(session.executeCommand({
seq: 0,
type: "command",
type: "request",
command: session.customHandler
})).to.deep.equal({
response: undefined,
@@ -405,7 +453,7 @@ namespace ts.server {
this.seq++;
this.server.enqueue({
seq: this.seq,
type: "command",
type: "request",
command,
arguments: args
});
+4
View File
@@ -253,6 +253,10 @@ var x = 0;`, {
options: { compilerOptions: { allowUnusedLabels: true }, fileName: "input.js", reportDiagnostics: true }
});
transpilesCorrectly("Supports setting 'alwaysStrict'", "x;", {
options: { compilerOptions: { alwaysStrict: true }, fileName: "input.js", reportDiagnostics: true }
});
transpilesCorrectly("Supports setting 'baseUrl'", "x;", {
options: { compilerOptions: { baseUrl: "./folder/baseUrl" }, fileName: "input.js", reportDiagnostics: true }
});
+67
View File
@@ -28,6 +28,14 @@ namespace ts {
assert.isTrue(arrayIsEqualTo(parsed.fileNames.sort(), expectedFileList.sort()));
}
function assertParseFileDiagnostics(jsonText: string, configFileName: string, basePath: string, allFileList: string[], expectedDiagnosticCode: number) {
const json = JSON.parse(jsonText);
const host: ParseConfigHost = new Utils.MockParseConfigHost(basePath, true, allFileList);
const parsed = ts.parseJsonConfigFileContent(json, host, basePath, /*existingOptions*/ undefined, configFileName);
assert.isTrue(parsed.errors.length >= 0);
assert.isTrue(parsed.errors.filter(e => e.code === expectedDiagnosticCode).length > 0, `Expected error code ${expectedDiagnosticCode} to be in ${JSON.stringify(parsed.errors)}`);
}
it("returns empty config for file with only whitespaces", () => {
assertParseResult("", { config : {} });
assertParseResult(" ", { config : {} });
@@ -202,5 +210,64 @@ namespace ts {
assert.isTrue(diagnostics.length === 2);
assert.equal(JSON.stringify(configJsonObject), JSON.stringify(expectedResult));
});
it("generates errors for empty files list", () => {
const content = `{
"files": []
}`;
assertParseFileDiagnostics(content,
"/apath/tsconfig.json",
"tests/cases/unittests",
["/apath/a.ts"],
Diagnostics.The_files_list_in_config_file_0_is_empty.code);
});
it("generates errors for directory with no .ts files", () => {
const content = `{
}`;
assertParseFileDiagnostics(content,
"/apath/tsconfig.json",
"tests/cases/unittests",
["/apath/a.js"],
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
});
it("generates errors for empty directory", () => {
const content = `{
"compilerOptions": {
"allowJs": true
}
}`;
assertParseFileDiagnostics(content,
"/apath/tsconfig.json",
"tests/cases/unittests",
[],
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
});
it("generates errors for empty include", () => {
const content = `{
"include": []
}`;
assertParseFileDiagnostics(content,
"/apath/tsconfig.json",
"tests/cases/unittests",
["/apath/a.ts"],
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
});
it("generates errors for includes with outDir", () => {
const content = `{
"compilerOptions": {
"outDir": "./"
},
"include": ["**/*"]
}`;
assertParseFileDiagnostics(content,
"/apath/tsconfig.json",
"tests/cases/unittests",
["/apath/a.ts"],
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
});
});
}
+454 -70
View File
@@ -1,8 +1,10 @@
/// <reference path="..\harness.ts" />
/// <reference path="..\harness.ts" />
/// <reference path="../../server/typingsInstaller/typingsInstaller.ts" />
namespace ts.projectSystem {
import TI = server.typingsInstaller;
import protocol = server.protocol;
import CommandNames = server.CommandNames;
const safeList = {
path: <Path>"/safeList.json",
@@ -17,14 +19,8 @@ namespace ts.projectSystem {
export interface PostExecAction {
readonly requestKind: TI.RequestKind;
readonly error: Error;
readonly stdout: string;
readonly stderr: string;
readonly callback: (err: Error, stdout: string, stderr: string) => void;
}
export function notImplemented(): any {
throw new Error("Not yet implemented");
readonly success: boolean;
readonly callback: TI.RequestCompletedAction;
}
export const nullLogger: server.Logger = {
@@ -52,7 +48,7 @@ namespace ts.projectSystem {
export class TestTypingsInstaller extends TI.TypingsInstaller implements server.ITypingsInstaller {
protected projectService: server.ProjectService;
constructor(readonly globalTypingsCacheLocation: string, throttleLimit: number, readonly installTypingHost: server.ServerHost, log?: TI.Log) {
super(globalTypingsCacheLocation, "npm", safeList.path, throttleLimit, log);
super(globalTypingsCacheLocation, safeList.path, throttleLimit, log);
this.init();
}
@@ -63,7 +59,7 @@ namespace ts.projectSystem {
const actionsToRun = this.postExecActions;
this.postExecActions = [];
for (const action of actionsToRun) {
action.callback(action.error, action.stdout, action.stderr);
action.callback(action.success);
}
}
@@ -72,7 +68,7 @@ namespace ts.projectSystem {
this.postExecActions.forEach((act, i) => assert.equal(act.requestKind, expected[i], "Unexpected post install action"));
}
onProjectClosed(p: server.Project) {
onProjectClosed() {
}
attach(projectService: server.ProjectService) {
@@ -83,7 +79,7 @@ namespace ts.projectSystem {
return this.installTypingHost;
}
runCommand(requestKind: TI.RequestKind, requestId: number, command: string, cwd: string, cb: (err: Error, stdout: string, stderr: string) => void): void {
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
switch (requestKind) {
case TI.NpmViewRequest:
case TI.NpmInstallRequest:
@@ -98,17 +94,15 @@ namespace ts.projectSystem {
this.projectService.updateTypingsForProject(response);
}
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions) {
const request = server.createInstallTypingsRequest(project, typingOptions, this.globalTypingsCacheLocation);
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions, unresolvedImports: server.SortedReadonlyArray<string>) {
const request = server.createInstallTypingsRequest(project, typingOptions, unresolvedImports, this.globalTypingsCacheLocation);
this.install(request);
}
addPostExecAction(requestKind: TI.RequestKind, stdout: string | string[], cb: TI.RequestCompletedAction) {
const out = typeof stdout === "string" ? stdout : createNpmPackageJsonString(stdout);
const action: PostExecAction = {
error: undefined,
stdout: out,
stderr: "",
success: !!out,
callback: cb,
requestKind
};
@@ -124,11 +118,11 @@ namespace ts.projectSystem {
return JSON.stringify({ dependencies: dependencies });
}
export function getExecutingFilePathFromLibFile(libFilePath: string): string {
export function getExecutingFilePathFromLibFile(): string {
return combinePaths(getDirectoryPath(libFile.path), "tsc.js");
}
export function toExternalFile(fileName: string): server.protocol.ExternalFile {
export function toExternalFile(fileName: string): protocol.ExternalFile {
return { fileName };
}
@@ -136,6 +130,19 @@ namespace ts.projectSystem {
return map(fileNames, toExternalFile);
}
export class TestServerEventManager {
public events: server.ProjectServiceEvent[] = [];
handler: server.ProjectServiceEventHandler = (event: server.ProjectServiceEvent) => {
this.events.push(event);
}
checkEventCountOfType(eventType: "context" | "configFileDiag", expectedCount: number) {
const eventsOfType = filter(this.events, e => e.eventName === eventType);
assert.equal(eventsOfType.length, expectedCount, `The actual event counts of type ${eventType} is ${eventsOfType.length}, while expected ${expectedCount}`);
}
}
export interface TestServerHostCreationParameters {
useCaseSensitiveFileNames?: boolean;
executingFilePath?: string;
@@ -143,27 +150,31 @@ namespace ts.projectSystem {
currentDirectory?: string;
}
export function createServerHost(fileOrFolderList: FileOrFolder[],
params?: TestServerHostCreationParameters,
libFilePath: string = libFile.path): TestServerHost {
export function createServerHost(fileOrFolderList: FileOrFolder[], params?: TestServerHostCreationParameters): TestServerHost {
if (!params) {
params = {};
}
const host = new TestServerHost(
params.useCaseSensitiveFileNames !== undefined ? params.useCaseSensitiveFileNames : false,
params.executingFilePath || getExecutingFilePathFromLibFile(libFilePath),
params.executingFilePath || getExecutingFilePathFromLibFile(),
params.currentDirectory || "/",
fileOrFolderList);
host.createFileOrFolder(safeList, /*createParentDirectory*/ true);
return host;
}
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller) {
class TestSession extends server.Session {
getProjectService() {
return this.projectService;
}
};
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler) {
if (typingsInstaller === undefined) {
typingsInstaller = new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
}
return new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
return new TestSession(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler);
}
export interface CreateProjectServiceParameters {
@@ -304,9 +315,9 @@ namespace ts.projectSystem {
count() {
let n = 0;
/* tslint:disable:no-unused-variable */
for (const _ in this.map) {
/* tslint:enable:no-unused-variable */
// TODO: GH#11734
_;
n++;
}
return n;
@@ -455,7 +466,7 @@ namespace ts.projectSystem {
}
// TOOD: record and invoke callbacks to simulate timer events
setTimeout(callback: TimeOutCallback, time: number, ...args: any[]) {
setTimeout(callback: TimeOutCallback, _time: number, ...args: any[]) {
return this.timeoutCallbacks.register(callback, args);
};
@@ -472,7 +483,7 @@ namespace ts.projectSystem {
this.timeoutCallbacks.invoke();
}
setImmediate(callback: TimeOutCallback, time: number, ...args: any[]) {
setImmediate(callback: TimeOutCallback, _time: number, ...args: any[]) {
return this.immediateCallbacks.register(callback, args);
}
@@ -504,17 +515,18 @@ namespace ts.projectSystem {
this.reloadFS(filesOrFolders);
}
write() { }
readonly readFile = (s: string) => (<File>this.fs.get(this.toPath(s))).content;
readonly resolvePath = (s: string) => s;
readonly getExecutingFilePath = () => this.executingFilePath;
readonly getCurrentDirectory = () => this.currentDirectory;
readonly write = (s: string) => notImplemented();
readonly exit = () => notImplemented();
readonly getEnvironmentVariable = (v: string) => notImplemented();
readonly exit = notImplemented;
readonly getEnvironmentVariable = notImplemented;
}
export function makeSessionRequest<T>(command: string, args: T) {
const newRequest: server.protocol.Request = {
const newRequest: protocol.Request = {
seq: 0,
type: "request",
command,
@@ -525,7 +537,7 @@ namespace ts.projectSystem {
export function openFilesForSession(files: FileOrFolder[], session: server.Session) {
for (const file of files) {
const request = makeSessionRequest<server.protocol.OpenRequestArgs>(server.CommandNames.Open, { file: file.path });
const request = makeSessionRequest<protocol.OpenRequestArgs>(CommandNames.Open, { file: file.path });
session.executeCommand(request);
}
}
@@ -1647,67 +1659,74 @@ namespace ts.projectSystem {
"File '/a/b/node_modules/lib.ts' does not exist.",
"File '/a/b/node_modules/lib.tsx' does not exist.",
"File '/a/b/node_modules/lib.d.ts' does not exist.",
"File '/a/b/node_modules/lib.js' does not exist.",
"File '/a/b/node_modules/lib.jsx' does not exist.",
"File '/a/b/node_modules/lib/package.json' does not exist.",
"File '/a/b/node_modules/lib/index.ts' does not exist.",
"File '/a/b/node_modules/lib/index.tsx' does not exist.",
"File '/a/b/node_modules/lib/index.d.ts' does not exist.",
"File '/a/b/node_modules/lib/index.js' does not exist.",
"File '/a/b/node_modules/lib/index.jsx' does not exist.",
"File '/a/b/node_modules/@types/lib.ts' does not exist.",
"File '/a/b/node_modules/@types/lib.tsx' does not exist.",
"File '/a/b/node_modules/@types/lib.d.ts' does not exist.",
"File '/a/b/node_modules/@types/lib.js' does not exist.",
"File '/a/b/node_modules/@types/lib.jsx' does not exist.",
"File '/a/b/node_modules/@types/lib/package.json' does not exist.",
"File '/a/b/node_modules/@types/lib/index.ts' does not exist.",
"File '/a/b/node_modules/@types/lib/index.tsx' does not exist.",
"File '/a/b/node_modules/@types/lib/index.d.ts' does not exist.",
"File '/a/b/node_modules/@types/lib/index.js' does not exist.",
"File '/a/b/node_modules/@types/lib/index.jsx' does not exist.",
"File '/a/node_modules/lib.ts' does not exist.",
"File '/a/node_modules/lib.tsx' does not exist.",
"File '/a/node_modules/lib.d.ts' does not exist.",
"File '/a/node_modules/lib.js' does not exist.",
"File '/a/node_modules/lib.jsx' does not exist.",
"File '/a/node_modules/lib/package.json' does not exist.",
"File '/a/node_modules/lib/index.ts' does not exist.",
"File '/a/node_modules/lib/index.tsx' does not exist.",
"File '/a/node_modules/lib/index.d.ts' does not exist.",
"File '/a/node_modules/lib/index.js' does not exist.",
"File '/a/node_modules/lib/index.jsx' does not exist.",
"File '/a/node_modules/@types/lib.ts' does not exist.",
"File '/a/node_modules/@types/lib.tsx' does not exist.",
"File '/a/node_modules/@types/lib.d.ts' does not exist.",
"File '/a/node_modules/@types/lib.js' does not exist.",
"File '/a/node_modules/@types/lib.jsx' does not exist.",
"File '/a/node_modules/@types/lib/package.json' does not exist.",
"File '/a/node_modules/@types/lib/index.ts' does not exist.",
"File '/a/node_modules/@types/lib/index.tsx' does not exist.",
"File '/a/node_modules/@types/lib/index.d.ts' does not exist.",
"File '/a/node_modules/@types/lib/index.js' does not exist.",
"File '/a/node_modules/@types/lib/index.jsx' does not exist.",
"File '/node_modules/lib.ts' does not exist.",
"File '/node_modules/lib.tsx' does not exist.",
"File '/node_modules/lib.d.ts' does not exist.",
"File '/node_modules/lib.js' does not exist.",
"File '/node_modules/lib.jsx' does not exist.",
"File '/node_modules/lib/package.json' does not exist.",
"File '/node_modules/lib/index.ts' does not exist.",
"File '/node_modules/lib/index.tsx' does not exist.",
"File '/node_modules/lib/index.d.ts' does not exist.",
"File '/node_modules/lib/index.js' does not exist.",
"File '/node_modules/lib/index.jsx' does not exist.",
"File '/node_modules/@types/lib.ts' does not exist.",
"File '/node_modules/@types/lib.tsx' does not exist.",
"File '/node_modules/@types/lib.d.ts' does not exist.",
"File '/node_modules/@types/lib.js' does not exist.",
"File '/node_modules/@types/lib.jsx' does not exist.",
"File '/node_modules/@types/lib/package.json' does not exist.",
"File '/node_modules/@types/lib/index.ts' does not exist.",
"File '/node_modules/@types/lib/index.tsx' does not exist.",
"File '/node_modules/@types/lib/index.d.ts' does not exist.",
"Loading module 'lib' from 'node_modules' folder.",
"File '/a/b/node_modules/lib.js' does not exist.",
"File '/a/b/node_modules/lib.jsx' does not exist.",
"File '/a/b/node_modules/lib/package.json' does not exist.",
"File '/a/b/node_modules/lib/index.js' does not exist.",
"File '/a/b/node_modules/lib/index.jsx' does not exist.",
"File '/a/b/node_modules/@types/lib.js' does not exist.",
"File '/a/b/node_modules/@types/lib.jsx' does not exist.",
"File '/a/b/node_modules/@types/lib/package.json' does not exist.",
"File '/a/b/node_modules/@types/lib/index.js' does not exist.",
"File '/a/b/node_modules/@types/lib/index.jsx' does not exist.",
"File '/a/node_modules/lib.js' does not exist.",
"File '/a/node_modules/lib.jsx' does not exist.",
"File '/a/node_modules/lib/package.json' does not exist.",
"File '/a/node_modules/lib/index.js' does not exist.",
"File '/a/node_modules/lib/index.jsx' does not exist.",
"File '/a/node_modules/@types/lib.js' does not exist.",
"File '/a/node_modules/@types/lib.jsx' does not exist.",
"File '/a/node_modules/@types/lib/package.json' does not exist.",
"File '/a/node_modules/@types/lib/index.js' does not exist.",
"File '/a/node_modules/@types/lib/index.jsx' does not exist.",
"File '/node_modules/lib.js' does not exist.",
"File '/node_modules/lib.jsx' does not exist.",
"File '/node_modules/lib/package.json' does not exist.",
"File '/node_modules/lib/index.js' does not exist.",
"File '/node_modules/lib/index.jsx' does not exist.",
"File '/node_modules/@types/lib.js' does not exist.",
"File '/node_modules/@types/lib.jsx' does not exist.",
"File '/node_modules/@types/lib/package.json' does not exist.",
"File '/node_modules/@types/lib/index.js' does not exist.",
"File '/node_modules/@types/lib/index.jsx' does not exist.",
"======== Module name 'lib' was not resolved. ========",
@@ -1715,19 +1734,13 @@ namespace ts.projectSystem {
"File '/a/cache/node_modules/lib.ts' does not exist.",
"File '/a/cache/node_modules/lib.tsx' does not exist.",
"File '/a/cache/node_modules/lib.d.ts' does not exist.",
"File '/a/cache/node_modules/lib.js' does not exist.",
"File '/a/cache/node_modules/lib.jsx' does not exist.",
"File '/a/cache/node_modules/lib/package.json' does not exist.",
"File '/a/cache/node_modules/lib/index.ts' does not exist.",
"File '/a/cache/node_modules/lib/index.tsx' does not exist.",
"File '/a/cache/node_modules/lib/index.d.ts' does not exist.",
"File '/a/cache/node_modules/lib/index.js' does not exist.",
"File '/a/cache/node_modules/lib/index.jsx' does not exist.",
"File '/a/cache/node_modules/@types/lib.ts' does not exist.",
"File '/a/cache/node_modules/@types/lib.tsx' does not exist.",
"File '/a/cache/node_modules/@types/lib.d.ts' does not exist.",
"File '/a/cache/node_modules/@types/lib.js' does not exist.",
"File '/a/cache/node_modules/@types/lib.jsx' does not exist.",
"File '/a/cache/node_modules/@types/lib/package.json' does not exist.",
"File '/a/cache/node_modules/@types/lib/index.ts' does not exist.",
"File '/a/cache/node_modules/@types/lib/index.tsx' does not exist.",
@@ -1738,7 +1751,7 @@ namespace ts.projectSystem {
});
describe("navigate-to for javascript project", () => {
function containsNavToItem(items: server.protocol.NavtoItem[], itemName: string, itemKind: string) {
function containsNavToItem(items: protocol.NavtoItem[], itemName: string, itemKind: string) {
return find(items, item => item.name === itemName && item.kind === itemKind) !== undefined;
}
@@ -1756,12 +1769,12 @@ namespace ts.projectSystem {
openFilesForSession([file1], session);
// Try to find some interface type defined in lib.d.ts
const libTypeNavToRequest = makeSessionRequest<server.protocol.NavtoRequestArgs>(server.CommandNames.Navto, { searchValue: "Document", file: file1.path, projectFileName: configFile.path });
const items: server.protocol.NavtoItem[] = session.executeCommand(libTypeNavToRequest).response;
const libTypeNavToRequest = makeSessionRequest<protocol.NavtoRequestArgs>(CommandNames.Navto, { searchValue: "Document", file: file1.path, projectFileName: configFile.path });
const items: protocol.NavtoItem[] = session.executeCommand(libTypeNavToRequest).response;
assert.isFalse(containsNavToItem(items, "Document", "interface"), `Found lib.d.ts symbol in JavaScript project nav to request result.`);
const localFunctionNavToRequst = makeSessionRequest<server.protocol.NavtoRequestArgs>(server.CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path });
const items2: server.protocol.NavtoItem[] = session.executeCommand(localFunctionNavToRequst).response;
const localFunctionNavToRequst = makeSessionRequest<protocol.NavtoRequestArgs>(CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path });
const items2: protocol.NavtoItem[] = session.executeCommand(localFunctionNavToRequst).response;
assert.isTrue(containsNavToItem(items2, "foo", "function"), `Cannot find function symbol "foo".`);
});
});
@@ -2084,7 +2097,7 @@ namespace ts.projectSystem {
const projectFileName = "externalProject";
const host = createServerHost([f]);
const projectService = createProjectService(host);
// create a project
// create a project
projectService.openExternalProject({ projectFileName, rootFiles: [toExternalFile(f.path)], options: {} });
projectService.checkNumberOfProjects({ externalProjects: 1 });
@@ -2121,4 +2134,375 @@ namespace ts.projectSystem {
projectService.inferredProjects[0].getLanguageService().getProgram();
});
});
describe("rename a module file and rename back", () => {
it("should restore the states for inferred projects", () => {
const moduleFile = {
path: "/a/b/moduleFile.ts",
content: "export function bar() { };"
};
const file1 = {
path: "/a/b/file1.ts",
content: "import * as T from './moduleFile'; T.bar();"
};
const host = createServerHost([moduleFile, file1]);
const session = createSession(host);
openFilesForSession([file1], session);
const getErrRequest = makeSessionRequest<server.protocol.SemanticDiagnosticsSyncRequestArgs>(
server.CommandNames.SemanticDiagnosticsSync,
{ file: file1.path }
);
let diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
assert.equal(diags.length, 0);
const moduleFileOldPath = moduleFile.path;
const moduleFileNewPath = "/a/b/moduleFile1.ts";
moduleFile.path = moduleFileNewPath;
host.reloadFS([moduleFile, file1]);
host.triggerFileWatcherCallback(moduleFileOldPath);
host.triggerDirectoryWatcherCallback("/a/b", moduleFile.path);
host.runQueuedTimeoutCallbacks();
diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
assert.equal(diags.length, 1);
moduleFile.path = moduleFileOldPath;
host.reloadFS([moduleFile, file1]);
host.triggerFileWatcherCallback(moduleFileNewPath);
host.triggerDirectoryWatcherCallback("/a/b", moduleFile.path);
host.runQueuedTimeoutCallbacks();
// Make a change to trigger the program rebuild
const changeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(
server.CommandNames.Change,
{ file: file1.path, line: 1, offset: 44, endLine: 1, endOffset: 44, insertString: "\n" }
);
session.executeCommand(changeRequest);
host.runQueuedTimeoutCallbacks();
diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
assert.equal(diags.length, 0);
});
it("should restore the states for configured projects", () => {
const moduleFile = {
path: "/a/b/moduleFile.ts",
content: "export function bar() { };"
};
const file1 = {
path: "/a/b/file1.ts",
content: "import * as T from './moduleFile'; T.bar();"
};
const configFile = {
path: "/a/b/tsconfig.json",
content: `{}`
};
const host = createServerHost([moduleFile, file1, configFile]);
const session = createSession(host);
openFilesForSession([file1], session);
const getErrRequest = makeSessionRequest<server.protocol.SemanticDiagnosticsSyncRequestArgs>(
server.CommandNames.SemanticDiagnosticsSync,
{ file: file1.path }
);
let diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
assert.equal(diags.length, 0);
const moduleFileOldPath = moduleFile.path;
const moduleFileNewPath = "/a/b/moduleFile1.ts";
moduleFile.path = moduleFileNewPath;
host.reloadFS([moduleFile, file1, configFile]);
host.triggerFileWatcherCallback(moduleFileOldPath);
host.triggerDirectoryWatcherCallback("/a/b", moduleFile.path);
host.runQueuedTimeoutCallbacks();
diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
assert.equal(diags.length, 1);
moduleFile.path = moduleFileOldPath;
host.reloadFS([moduleFile, file1, configFile]);
host.triggerFileWatcherCallback(moduleFileNewPath);
host.triggerDirectoryWatcherCallback("/a/b", moduleFile.path);
host.runQueuedTimeoutCallbacks();
diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
assert.equal(diags.length, 0);
});
});
describe("add the missing module file for inferred project", () => {
it("should remove the `module not found` error", () => {
const moduleFile = {
path: "/a/b/moduleFile.ts",
content: "export function bar() { };"
};
const file1 = {
path: "/a/b/file1.ts",
content: "import * as T from './moduleFile'; T.bar();"
};
const host = createServerHost([file1]);
const session = createSession(host);
openFilesForSession([file1], session);
const getErrRequest = makeSessionRequest<server.protocol.SemanticDiagnosticsSyncRequestArgs>(
server.CommandNames.SemanticDiagnosticsSync,
{ file: file1.path }
);
let diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
assert.equal(diags.length, 1);
host.reloadFS([file1, moduleFile]);
host.triggerDirectoryWatcherCallback(getDirectoryPath(file1.path), moduleFile.path);
host.runQueuedTimeoutCallbacks();
// Make a change to trigger the program rebuild
const changeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(
server.CommandNames.Change,
{ file: file1.path, line: 1, offset: 44, endLine: 1, endOffset: 44, insertString: "\n" }
);
session.executeCommand(changeRequest);
// Recheck
diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
assert.equal(diags.length, 0);
});
});
describe("Configure file diagnostics events", () => {
it("are generated when the config file has errors", () => {
const serverEventManager = new TestServerEventManager();
const file = {
path: "/a/b/app.ts",
content: "let x = 10"
};
const configFile = {
path: "/a/b/tsconfig.json",
content: `{
"compilerOptions": {
"foo": "bar",
"allowJS": true
}
}`
};
const host = createServerHost([file, configFile]);
const session = createSession(host, /*typingsInstaller*/ undefined, serverEventManager.handler);
openFilesForSession([file], session);
serverEventManager.checkEventCountOfType("configFileDiag", 1);
for (const event of serverEventManager.events) {
if (event.eventName === "configFileDiag") {
assert.equal(event.data.configFileName, configFile.path);
assert.equal(event.data.triggerFile, file.path);
return;
}
}
});
it("are generated when the config file doesn't have errors", () => {
const serverEventManager = new TestServerEventManager();
const file = {
path: "/a/b/app.ts",
content: "let x = 10"
};
const configFile = {
path: "/a/b/tsconfig.json",
content: `{
"compilerOptions": {}
}`
};
const host = createServerHost([file, configFile]);
const session = createSession(host, /*typingsInstaller*/ undefined, serverEventManager.handler);
openFilesForSession([file], session);
serverEventManager.checkEventCountOfType("configFileDiag", 1);
});
});
describe("skipLibCheck", () => {
it("should be turned on for js-only inferred projects", () => {
const file1 = {
path: "/a/b/file1.js",
content: `
/// <reference path="file2.d.ts" />
var x = 1;`
};
const file2 = {
path: "/a/b/file2.d.ts",
content: `
interface T {
name: string;
};
interface T {
name: number;
};`
};
const host = createServerHost([file1, file2]);
const session = createSession(host);
openFilesForSession([file1, file2], session);
const file2GetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
CommandNames.SemanticDiagnosticsSync,
{ file: file2.path }
);
let errorResult = <protocol.Diagnostic[]>session.executeCommand(file2GetErrRequest).response;
assert.isTrue(errorResult.length === 0);
const closeFileRequest = makeSessionRequest<protocol.FileRequestArgs>(CommandNames.Close, { file: file1.path });
session.executeCommand(closeFileRequest);
errorResult = <protocol.Diagnostic[]>session.executeCommand(file2GetErrRequest).response;
assert.isTrue(errorResult.length !== 0);
openFilesForSession([file1], session);
errorResult = <protocol.Diagnostic[]>session.executeCommand(file2GetErrRequest).response;
assert.isTrue(errorResult.length === 0);
});
it("should be turned on for js-only external projects", () => {
const jsFile = {
path: "/a/b/file1.js",
content: "let x =1;"
};
const dTsFile = {
path: "/a/b/file2.d.ts",
content: `
interface T {
name: string;
};
interface T {
name: number;
};`
};
const host = createServerHost([jsFile, dTsFile]);
const session = createSession(host);
const openExternalProjectRequest = makeSessionRequest<protocol.OpenExternalProjectArgs>(
CommandNames.OpenExternalProject,
{
projectFileName: "project1",
rootFiles: toExternalFiles([jsFile.path, dTsFile.path]),
options: {}
}
);
session.executeCommand(openExternalProjectRequest);
const dTsFileGetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
CommandNames.SemanticDiagnosticsSync,
{ file: dTsFile.path }
);
const errorResult = <protocol.Diagnostic[]>session.executeCommand(dTsFileGetErrRequest).response;
assert.isTrue(errorResult.length === 0);
});
});
describe("non-existing directories listed in config file input array", () => {
it("should be tolerated without crashing the server", () => {
const configFile = {
path: "/a/b/tsconfig.json",
content: `{
"compilerOptions": {},
"include": ["app/*", "test/**/*", "something"]
}`
};
const file1 = {
path: "/a/b/file1.ts",
content: "let t = 10;"
};
const host = createServerHost([file1, configFile]);
const projectService = createProjectService(host);
projectService.openClientFile(file1.path);
host.runQueuedTimeoutCallbacks();
checkNumberOfConfiguredProjects(projectService, 1);
checkNumberOfInferredProjects(projectService, 1);
const configuredProject = projectService.configuredProjects[0];
assert.isTrue(configuredProject.getFileNames().length == 0);
const inferredProject = projectService.inferredProjects[0];
assert.isTrue(inferredProject.containsFile(<server.NormalizedPath>file1.path));
});
});
describe("reload", () => {
it("should work with temp file", () => {
const f1 = {
path: "/a/b/app.ts",
content: "let x = 1"
};
const tmp = {
path: "/a/b/app.tmp",
content: "const y = 42"
};
const host = createServerHost([f1, tmp]);
const session = createSession(host);
// send open request
session.executeCommand(<server.protocol.OpenRequest>{
type: "request",
command: "open",
seq: 1,
arguments: { file: f1.path }
});
// reload from tmp file
session.executeCommand(<server.protocol.ReloadRequest>{
type: "request",
command: "reload",
seq: 2,
arguments: { file: f1.path, tmpfile: tmp.path }
});
// verify content
const projectServiice = session.getProjectService();
const snap1 = projectServiice.getScriptInfo(f1.path).snap();
assert.equal(snap1.getText(0, snap1.getLength()), tmp.content, "content should be equal to the content of temp file");
// reload from original file file
session.executeCommand(<server.protocol.ReloadRequest>{
type: "request",
command: "reload",
seq: 2,
arguments: { file: f1.path }
});
// verify content
const snap2 = projectServiice.getScriptInfo(f1.path).snap();
assert.equal(snap2.getText(0, snap2.getLength()), f1.content, "content should be equal to the content of original file");
});
});
describe("Inferred projects", () => {
it("should support files without extensions", () => {
const f = {
path: "/a/compile",
content: "let x = 1"
};
const host = createServerHost([f]);
const session = createSession(host);
session.executeCommand(<server.protocol.SetCompilerOptionsForInferredProjectsRequest>{
seq: 1,
type: "request",
command: "compilerOptionsForInferredProjects",
arguments: {
options: {
allowJs: true
}
}
});
session.executeCommand(<server.protocol.OpenRequest>{
seq: 2,
type: "request",
command: "open",
arguments: {
file: f.path,
fileContent: f.content,
scriptKindName: "JS"
}
});
const projectService = session.getProjectService();
checkNumberOfProjects(projectService, { inferredProjects: 1 });
checkProjectActualFiles(projectService.inferredProjects[0], [f.path]);
});
});
}
+232 -31
View File
@@ -31,11 +31,11 @@ namespace ts.projectSystem {
function executeCommand(self: Installer, host: TestServerHost, installedTypings: string[], typingFiles: FileOrFolder[], requestKind: TI.RequestKind, cb: TI.RequestCompletedAction): void {
switch (requestKind) {
case TI.NpmInstallRequest:
self.addPostExecAction(requestKind, installedTypings, (err, stdout, stderr) => {
self.addPostExecAction(requestKind, installedTypings, success => {
for (const file of typingFiles) {
host.createFileOrFolder(file, /*createParentDirectory*/ true);
}
cb(err, stdout, stderr);
cb(success);
});
break;
case TI.NpmViewRequest:
@@ -81,7 +81,7 @@ namespace ts.projectSystem {
constructor() {
super(host);
}
runCommand(requestKind: TI.RequestKind, requestId: number, command: string, cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
const installedTypings = ["@types/jquery"];
const typingFiles = [jquery];
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
@@ -125,7 +125,7 @@ namespace ts.projectSystem {
constructor() {
super(host);
}
runCommand(requestKind: TI.RequestKind, requestId: number, command: string, cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
const installedTypings = ["@types/jquery"];
const typingFiles = [jquery];
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
@@ -217,11 +217,11 @@ namespace ts.projectSystem {
constructor() {
super(host);
}
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions) {
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions, unresolvedImports: server.SortedReadonlyArray<string>) {
enqueueIsCalled = true;
super.enqueueInstallTypingsRequest(project, typingOptions);
super.enqueueInstallTypingsRequest(project, typingOptions, unresolvedImports);
}
runCommand(requestKind: TI.RequestKind, requestId: number, command: string, cwd: string, cb: TI.RequestCompletedAction): void {
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
const installedTypings = ["@types/jquery"];
const typingFiles = [jquery];
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
@@ -275,7 +275,7 @@ namespace ts.projectSystem {
constructor() {
super(host);
}
runCommand(requestKind: TI.RequestKind, requestId: number, command: string, cwd: string, cb: TI.RequestCompletedAction): void {
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
const installedTypings = ["@types/lodash", "@types/react"];
const typingFiles = [lodash, react];
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
@@ -319,11 +319,11 @@ namespace ts.projectSystem {
constructor() {
super(host);
}
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions) {
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions, unresolvedImports: server.SortedReadonlyArray<string>) {
enqueueIsCalled = true;
super.enqueueInstallTypingsRequest(project, typingOptions);
super.enqueueInstallTypingsRequest(project, typingOptions, unresolvedImports);
}
runCommand(requestKind: TI.RequestKind, requestId: number, command: string, cwd: string, cb: TI.RequestCompletedAction): void {
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
const installedTypings: string[] = [];
const typingFiles: FileOrFolder[] = [];
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
@@ -398,7 +398,7 @@ namespace ts.projectSystem {
constructor() {
super(host);
}
runCommand(requestKind: TI.RequestKind, requestId: number, command: string, cwd: string, cb: TI.RequestCompletedAction): void {
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
const installedTypings = ["@types/commander", "@types/express", "@types/jquery", "@types/moment"];
const typingFiles = [commander, express, jquery, moment];
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
@@ -477,7 +477,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { throttleLimit: 3 });
}
runCommand(requestKind: TI.RequestKind, requestId: number, command: string, cwd: string, cb: TI.RequestCompletedAction): void {
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
const installedTypings = ["@types/commander", "@types/express", "@types/jquery", "@types/moment", "@types/lodash"];
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
}
@@ -567,10 +567,10 @@ namespace ts.projectSystem {
constructor() {
super(host, { throttleLimit: 3 });
}
runCommand(requestKind: TI.RequestKind, requestId: number, command: string, cwd: string, cb: TI.RequestCompletedAction): void {
executeRequest(requestKind: TI.RequestKind, _requestId: number, args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
if (requestKind === TI.NpmInstallRequest) {
let typingFiles: (FileOrFolder & { typings: string}) [] = [];
if (command.indexOf("commander") >= 0) {
let typingFiles: (FileOrFolder & { typings: string })[] = [];
if (args.indexOf("@types/commander") >= 0) {
typingFiles = [commander, jquery, lodash, cordova];
}
else {
@@ -591,7 +591,7 @@ namespace ts.projectSystem {
projectFileName: projectFileName1,
options: { allowJS: true, moduleResolution: ModuleResolutionKind.NodeJs },
rootFiles: [toExternalFile(lodashJs.path), toExternalFile(commanderJs.path), toExternalFile(file3.path)],
typingOptions: { include: ["jquery", "cordova" ] }
typingOptions: { include: ["jquery", "cordova"] }
});
installer.checkPendingCommands([TI.NpmViewRequest, TI.NpmViewRequest, TI.NpmViewRequest]);
@@ -626,7 +626,7 @@ namespace ts.projectSystem {
installer.executePendingCommands();
checkProjectActualFiles(p1, [lodashJs.path, commanderJs.path, file3.path, commander.path, jquery.path, lodash.path, cordova.path]);
checkProjectActualFiles(p2, [file3.path, grunt.path, gulp.path ]);
checkProjectActualFiles(p2, [file3.path, grunt.path, gulp.path]);
});
it("configured projects discover from node_modules", () => {
@@ -655,7 +655,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp" });
}
runCommand(requestKind: TI.RequestKind, requestId: number, command: string, cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
const installedTypings = ["@types/jquery"];
const typingFiles = [jqueryDTS];
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
@@ -687,10 +687,10 @@ namespace ts.projectSystem {
const bowerJson = {
path: "/bower.json",
content: JSON.stringify({
"dependencies": {
"jquery": "^3.1.0"
}
})
"dependencies": {
"jquery": "^3.1.0"
}
})
};
const jqueryDTS = {
path: "/tmp/node_modules/@types/jquery/index.d.ts",
@@ -701,7 +701,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp" });
}
runCommand(requestKind: TI.RequestKind, requestId: number, command: string, cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
const installedTypings = ["@types/jquery"];
const typingFiles = [jqueryDTS];
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
@@ -720,26 +720,196 @@ namespace ts.projectSystem {
checkNumberOfProjects(projectService, { configuredProjects: 1 });
checkProjectActualFiles(p, [app.path, jqueryDTS.path]);
});
it("Malformed package.json should be watched", () => {
const f = {
path: "/a/b/app.js",
content: "var x = 1"
};
const brokenPackageJson = {
path: "/a/b/package.json",
content: `{ "dependencies": { "co } }`
};
const fixedPackageJson = {
path: brokenPackageJson.path,
content: `{ "dependencies": { "commander": "0.0.2" } }`
};
const cachePath = "/a/cache/";
const commander = {
path: cachePath + "node_modules/@types/commander/index.d.ts",
content: "export let x: number"
};
const host = createServerHost([f, brokenPackageJson]);
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: cachePath });
}
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
const installedTypings = ["@types/commander"];
const typingFiles = [commander];
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
}
})();
const service = createProjectService(host, { typingsInstaller: installer });
service.openClientFile(f.path);
installer.checkPendingCommands([]);
host.reloadFS([f, fixedPackageJson]);
host.triggerFileWatcherCallback(fixedPackageJson.path, /*removed*/ false);
// expected one view and one install request
installer.installAll([TI.NpmViewRequest], [TI.NpmInstallRequest]);
service.checkNumberOfProjects({ inferredProjects: 1 });
checkProjectActualFiles(service.inferredProjects[0], [f.path, commander.path]);
});
it("should install typings for unresolved imports", () => {
const file = {
path: "/a/b/app.js",
content: `
import * as fs from "fs";
import * as commander from "commander";`
};
const cachePath = "/a/cache";
const node = {
path: cachePath + "/node_modules/@types/node/index.d.ts",
content: "export let x: number"
};
const commander = {
path: cachePath + "/node_modules/@types/commander/index.d.ts",
content: "export let y: string"
};
const host = createServerHost([file]);
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: cachePath });
}
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
const installedTypings = ["@types/node", "@types/commander"];
const typingFiles = [node, commander];
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
}
})();
const service = createProjectService(host, { typingsInstaller: installer });
service.openClientFile(file.path);
service.checkNumberOfProjects({ inferredProjects: 1 });
checkProjectActualFiles(service.inferredProjects[0], [file.path]);
installer.installAll([TI.NpmViewRequest, TI.NpmViewRequest], [TI.NpmInstallRequest]);
assert.isTrue(host.fileExists(node.path), "typings for 'node' should be created");
assert.isTrue(host.fileExists(commander.path), "typings for 'commander' should be created");
checkProjectActualFiles(service.inferredProjects[0], [file.path, node.path, commander.path]);
});
it("should pick typing names from non-relative unresolved imports", () => {
const f1 = {
path: "/a/b/app.js",
content: `
import * as a from "foo/a/a";
import * as b from "foo/a/b";
import * as c from "foo/a/c";
import * as d from "@bar/router/";
import * as e from "@bar/common/shared";
import * as e from "@bar/common/apps";
import * as f from "./lib"
`
};
const host = createServerHost([f1]);
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp" });
}
executeRequest(requestKind: TI.RequestKind, _requestId: number, args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
if (requestKind === TI.NpmViewRequest) {
// args should have only non-scoped packages - scoped packages are not yet supported
assert.deepEqual(args, ["foo"]);
}
executeCommand(this, host, ["foo"], [], requestKind, cb);
}
})();
const projectService = createProjectService(host, { typingsInstaller: installer });
projectService.openClientFile(f1.path);
projectService.checkNumberOfProjects({ inferredProjects: 1 });
const proj = projectService.inferredProjects[0];
proj.updateGraph();
assert.deepEqual(
proj.getCachedUnresolvedImportsPerFile_TestOnly().get(<Path>f1.path),
["foo", "foo", "foo", "@bar/router", "@bar/common", "@bar/common"]
);
installer.installAll([TI.NpmViewRequest], [TI.NpmInstallRequest]);
});
it("cached unresolved typings are not recomputed if program structure did not change", () => {
const host = createServerHost([]);
const session = createSession(host);
const f = {
path: "/a/app.js",
content: `
import * as fs from "fs";
import * as cmd from "commander
`
};
session.executeCommand(<server.protocol.OpenRequest>{
seq: 1,
type: "request",
command: "open",
arguments: {
file: f.path,
fileContent: f.content
}
});
const projectService = session.getProjectService();
checkNumberOfProjects(projectService, { inferredProjects: 1 });
const proj = projectService.inferredProjects[0];
const version1 = proj.getCachedUnresolvedImportsPerFile_TestOnly().getVersion();
// make a change that should not affect the structure of the program
session.executeCommand(<server.protocol.ChangeRequest>{
seq: 2,
type: "request",
command: "change",
arguments: {
file: f.path,
insertString: "\nlet x = 1;",
line: 2,
offset: 0,
endLine: 2,
endOffset: 0
}
});
host.checkTimeoutQueueLength(1);
host.runQueuedTimeoutCallbacks();
const version2 = proj.getCachedUnresolvedImportsPerFile_TestOnly().getVersion();
assert.equal(version1, version2, "set of unresolved imports should not change");
});
});
describe("Validate package name:", () => {
it ("name cannot be too long", () => {
it("name cannot be too long", () => {
let packageName = "a";
for (let i = 0; i < 8; i++) {
packageName += packageName;
}
assert.equal(TI.validatePackageName(packageName), TI.PackageNameValidationResult.NameTooLong);
});
it ("name cannot start with dot", () => {
it("name cannot start with dot", () => {
assert.equal(TI.validatePackageName(".foo"), TI.PackageNameValidationResult.NameStartsWithDot);
});
it ("name cannot start with underscore", () => {
it("name cannot start with underscore", () => {
assert.equal(TI.validatePackageName("_foo"), TI.PackageNameValidationResult.NameStartsWithUnderscore);
});
it ("scoped packages not supported", () => {
it("scoped packages not supported", () => {
assert.equal(TI.validatePackageName("@scope/bar"), TI.PackageNameValidationResult.ScopedPackagesNotSupported);
});
it ("non URI safe characters are not supported", () => {
it("non URI safe characters are not supported", () => {
assert.equal(TI.validatePackageName(" scope "), TI.PackageNameValidationResult.NameContainsNonURISafeCharacters);
assert.equal(TI.validatePackageName("; say ‘Hello from TypeScript!’ #"), TI.PackageNameValidationResult.NameContainsNonURISafeCharacters);
assert.equal(TI.validatePackageName("a/b/c"), TI.PackageNameValidationResult.NameContainsNonURISafeCharacters);
@@ -747,7 +917,7 @@ namespace ts.projectSystem {
});
describe("Invalid package names", () => {
it ("should not be installed", () => {
it("should not be installed", () => {
const f1 = {
path: "/a/b/app.js",
content: "let x = 1"
@@ -766,7 +936,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp" }, { isEnabled: () => true, writeLine: msg => messages.push(msg) });
}
runCommand(requestKind: TI.RequestKind, requestId: number, command: string, cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
executeRequest() {
assert(false, "runCommand should not be invoked");
}
})();
@@ -777,4 +947,35 @@ namespace ts.projectSystem {
assert.isTrue(messages.indexOf("Package name '; say ‘Hello from TypeScript!’ #' contains non URI safe characters") > 0, "should find package with invalid name");
});
});
describe("discover typings", () => {
it("should return node for core modules", () => {
const f = {
path: "/a/b/app.js",
content: ""
};
const host = createServerHost([f]);
const cache = createMap<string>();
for (const name of JsTyping.nodeCoreModuleList) {
const result = JsTyping.discoverTypings(host, [f.path], getDirectoryPath(<Path>f.path), /*safeListPath*/ undefined, cache, { enableAutoDiscovery: true }, [name, "somename"]);
assert.deepEqual(result.newTypingNames.sort(), ["node", "somename"]);
}
});
it("should use cached locaitons", () => {
const f = {
path: "/a/b/app.js",
content: ""
};
const node = {
path: "/a/b/node.d.ts",
content: ""
};
const host = createServerHost([f, node]);
const cache = createMap<string>({ "node": node.path });
const result = JsTyping.discoverTypings(host, [f.path], getDirectoryPath(<Path>f.path), /*safeListPath*/ undefined, cache, { enableAutoDiscovery: true }, ["fs", "bar"]);
assert.deepEqual(result.cachedTypingPaths, [node.path]);
assert.deepEqual(result.newTypingNames, ["bar"]);
});
});
}
+16 -12
View File
@@ -1679,6 +1679,7 @@ interface CSSStyleDeclaration {
writingMode: string | null;
zIndex: string | null;
zoom: string | null;
resize: string | null;
getPropertyPriority(propertyName: string): string;
getPropertyValue(propertyName: string): string;
item(index: number): string;
@@ -1748,6 +1749,7 @@ declare var CanvasGradient: {
}
interface CanvasPattern {
setTransform(matrix: SVGMatrix): void;
}
declare var CanvasPattern: {
@@ -2173,7 +2175,7 @@ interface DataTransfer {
effectAllowed: string;
readonly files: FileList;
readonly items: DataTransferItemList;
readonly types: DOMStringList;
readonly types: string[];
clearData(format?: string): boolean;
getData(format: string): string;
setData(format: string, data: string): boolean;
@@ -7584,7 +7586,7 @@ declare var IDBCursorWithValue: {
interface IDBDatabase extends EventTarget {
readonly name: string;
readonly objectStoreNames: DOMStringList;
readonly objectStoreNames: string[];
onabort: (this: this, ev: Event) => any;
onerror: (this: this, ev: ErrorEvent) => any;
version: number;
@@ -7650,7 +7652,7 @@ declare var IDBKeyRange: {
}
interface IDBObjectStore {
readonly indexNames: DOMStringList;
readonly indexNames: string[];
keyPath: string | string[];
readonly name: string;
readonly transaction: IDBTransaction;
@@ -8602,7 +8604,7 @@ interface MouseEvent extends UIEvent {
readonly x: number;
readonly y: number;
getModifierState(keyArg: string): boolean;
initMouseEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number, screenXArg: number, screenYArg: number, clientXArg: number, clientYArg: number, ctrlKeyArg: boolean, altKeyArg: boolean, shiftKeyArg: boolean, metaKeyArg: boolean, buttonArg: number, relatedTargetArg: EventTarget): void;
initMouseEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number, screenXArg: number, screenYArg: number, clientXArg: number, clientYArg: number, ctrlKeyArg: boolean, altKeyArg: boolean, shiftKeyArg: boolean, metaKeyArg: boolean, buttonArg: number, relatedTargetArg: EventTarget | null): void;
}
declare var MouseEvent: {
@@ -8715,6 +8717,7 @@ interface Navigator extends Object, NavigatorID, NavigatorOnLine, NavigatorConte
readonly plugins: PluginArray;
readonly pointerEnabled: boolean;
readonly webdriver: boolean;
readonly hardwareConcurrency: number;
getGamepads(): Gamepad[];
javaEnabled(): boolean;
msLaunchUri(uri: string, successCallback?: MSLaunchUriCallback, noHandlerCallback?: MSLaunchUriCallback): void;
@@ -8732,18 +8735,18 @@ interface Node extends EventTarget {
readonly attributes: NamedNodeMap;
readonly baseURI: string | null;
readonly childNodes: NodeList;
readonly firstChild: Node;
readonly lastChild: Node;
readonly firstChild: Node | null;
readonly lastChild: Node | null;
readonly localName: string | null;
readonly namespaceURI: string | null;
readonly nextSibling: Node;
readonly nextSibling: Node | null;
readonly nodeName: string;
readonly nodeType: number;
nodeValue: string | null;
readonly ownerDocument: Document;
readonly parentElement: HTMLElement;
readonly parentNode: Node;
readonly previousSibling: Node;
readonly parentElement: HTMLElement | null;
readonly parentNode: Node | null;
readonly previousSibling: Node | null;
textContent: string | null;
appendChild(newChild: Node): Node;
cloneNode(deep?: boolean): Node;
@@ -12853,7 +12856,7 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window
readonly devicePixelRatio: number;
readonly doNotTrack: string;
readonly document: Document;
event: Event;
event: Event | undefined;
readonly external: External;
readonly frameElement: Element;
readonly frames: Window;
@@ -13155,6 +13158,7 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
readonly upload: XMLHttpRequestUpload;
withCredentials: boolean;
msCaching?: string;
readonly responseURL: string;
abort(): void;
getAllResponseHeaders(): string;
getResponseHeader(header: string): string | null;
@@ -14301,7 +14305,7 @@ declare var defaultStatus: string;
declare var devicePixelRatio: number;
declare var doNotTrack: string;
declare var document: Document;
declare var event: Event;
declare var event: Event | undefined;
declare var external: External;
declare var frameElement: Element;
declare var frames: Window;
+5 -5
View File
@@ -201,17 +201,17 @@ interface NumberConstructor {
/**
* Returns true if passed value is finite.
* Unlike the global isFininte, Number.isFinite doesn't forcibly convert the parameter to a
* Unlike the global isFinite, Number.isFinite doesn't forcibly convert the parameter to a
* number. Only finite values of the type number, result in true.
* @param number A numeric value.
*/
isFinite(number: number): boolean;
isFinite(value: any): value is number;
/**
* Returns true if the value passed is an integer, false otherwise.
* @param number A numeric value.
*/
isInteger(number: number): boolean;
isInteger(value: any): value is number;
/**
* Returns a Boolean value that indicates whether a value is the reserved value NaN (not a
@@ -219,13 +219,13 @@ interface NumberConstructor {
* to a number. Only values of the type number, that are also NaN, result in true.
* @param number A numeric value.
*/
isNaN(number: number): boolean;
isNaN(value: any): value is number;
/**
* Returns true if the value passed is a safe integer.
* @param number A numeric value.
*/
isSafeInteger(number: number): boolean;
isSafeInteger(value: any): value is number;
/**
* The value of the largest integer n such that n and n + 1 are both exactly representable as
+3
View File
@@ -244,6 +244,9 @@ interface Function {
*/
bind(this: Function, thisArg: any, ...argArray: any[]): any;
/** Returns a string representation of a function. */
toString(): string;
prototype: any;
readonly length: number;
+4 -2
View File
@@ -341,7 +341,7 @@ declare var IDBCursorWithValue: {
interface IDBDatabase extends EventTarget {
readonly name: string;
readonly objectStoreNames: DOMStringList;
readonly objectStoreNames: string[];
onabort: (this: this, ev: Event) => any;
onerror: (this: this, ev: ErrorEvent) => any;
version: number;
@@ -407,7 +407,7 @@ declare var IDBKeyRange: {
}
interface IDBObjectStore {
readonly indexNames: DOMStringList;
readonly indexNames: string[];
keyPath: string | string[];
readonly name: string;
readonly transaction: IDBTransaction;
@@ -740,6 +740,7 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
readonly upload: XMLHttpRequestUpload;
withCredentials: boolean;
msCaching?: string;
readonly responseURL: string;
abort(): void;
getAllResponseHeaders(): string;
getResponseHeader(header: string): string | null;
@@ -902,6 +903,7 @@ declare var WorkerLocation: {
}
interface WorkerNavigator extends Object, NavigatorID, NavigatorOnLine {
readonly hardwareConcurrency: number;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
Loaded 100 of 1333 files, more files were not shown because too many files have changed in this diff. Show more