Skip to content

Commit

Permalink
Merge pull request #23893 from Microsoft/libReference
Browse files Browse the repository at this point in the history
Adds 'lib' reference directives
  • Loading branch information
rbuckton authored Jun 4, 2018
2 parents c437404 + 6668412 commit fbeb58a
Show file tree
Hide file tree
Showing 1,559 changed files with 9,716 additions and 9,288 deletions.
11 changes: 8 additions & 3 deletions Gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const concat = require("gulp-concat");
const clone = require("gulp-clone");
const newer = require("gulp-newer");
const tsc = require("gulp-typescript");
const tsc_oop = require("./scripts/build/gulp-typescript-oop");
const insert = require("gulp-insert");
const sourcemaps = require("gulp-sourcemaps");
const Q = require("q");
Expand Down Expand Up @@ -412,6 +413,10 @@ function prependCopyright(outputCopyright = !useDebugMode) {
return insert.prepend(outputCopyright ? (copyrightContent || (copyrightContent = fs.readFileSync(copyright).toString())) : "");
}

function getCompilerPath(useBuiltCompiler) {
return useBuiltCompiler ? "./built/local/typescript.js" : "./lib/typescript.js";
}

gulp.task(builtLocalCompiler, /*help*/ false, [servicesFile], () => {
const localCompilerProject = tsc.createProject("src/compiler/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/ true));
return localCompilerProject.src()
Expand All @@ -424,7 +429,7 @@ gulp.task(builtLocalCompiler, /*help*/ false, [servicesFile], () => {
});

gulp.task(servicesFile, /*help*/ false, ["lib", "generate-diagnostics"], () => {
const servicesProject = tsc.createProject("src/services/tsconfig.json", getCompilerSettings({ removeComments: false }, /*useBuiltCompiler*/ false));
const servicesProject = tsc_oop.createProject("src/services/tsconfig.json", getCompilerSettings({ removeComments: false }), { typescript: getCompilerPath(/*useBuiltCompiler*/ false) });
const {js, dts} = servicesProject.src()
.pipe(newer(servicesFile))
.pipe(sourcemaps.init())
Expand Down Expand Up @@ -499,7 +504,7 @@ const tsserverLibraryFile = path.join(builtLocalDirectory, "tsserverlibrary.js")
const tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverlibrary.d.ts");

gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile, typesMapJson], (done) => {
const serverLibraryProject = tsc.createProject("src/server/tsconfig.library.json", getCompilerSettings({ removeComments: false }, /*useBuiltCompiler*/ true));
const serverLibraryProject = tsc_oop.createProject("src/server/tsconfig.library.json", getCompilerSettings({ removeComments: false }), { typescript: getCompilerPath(/*useBuiltCompiler*/ true) });
/** @type {{ js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream }} */
const {js, dts} = serverLibraryProject.src()
.pipe(sourcemaps.init())
Expand Down Expand Up @@ -590,7 +595,7 @@ gulp.task("LKG", "Makes a new LKG out of the built js files", ["clean", "dontUse
// Task to build the tests infrastructure using the built compiler
const run = path.join(builtLocalDirectory, "run.js");
gulp.task(run, /*help*/ false, [servicesFile, tsserverLibraryFile], () => {
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/ true));
const testProject = tsc_oop.createProject("src/harness/tsconfig.json", getCompilerSettings({}), { typescript: getCompilerPath(/*useBuiltCompiler*/ true) });
return testProject.src()
.pipe(newer(run))
.pipe(sourcemaps.init())
Expand Down
88 changes: 88 additions & 0 deletions scripts/build/gulp-typescript-oop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// @ts-check
const path = require("path");
const child_process = require("child_process");
const tsc = require("gulp-typescript");
const Vinyl = require("vinyl");
const { Duplex, Readable } = require("stream");

/**
* @param {string} tsConfigFileName
* @param {tsc.Settings} settings
* @param {Object} options
* @param {string} [options.typescript]
*/
function createProject(tsConfigFileName, settings, options) {
settings = { ...settings };
options = { ...options };
if (settings.typescript) throw new Error();

const localSettings = { ...settings };
if (options.typescript) {
options.typescript = path.resolve(options.typescript);
localSettings.typescript = require(options.typescript);
}

const project = tsc.createProject(tsConfigFileName, localSettings);
const wrappedProject = /** @type {tsc.Project} */(() => {
const proc = child_process.fork(require.resolve("./main.js"));
/** @type {Duplex & { js?: Readable, dts?: Readable }} */
const compileStream = new Duplex({
objectMode: true,
read() {},
/** @param {*} file */
write(file, encoding, callback) {
proc.send({ method: "write", params: { path: file.path, cwd: file.cwd, base: file.base }});
callback();
},
final(callback) {
proc.send({ method: "final" });
callback();
}
});
const jsStream = compileStream.js = new Readable({
objectMode: true,
read() {}
});
const dtsStream = compileStream.dts = new Readable({
objectMode: true,
read() {}
});
proc.send({ method: "createProject", params: { tsConfigFileName, settings, options } });
proc.on("message", ({ method, params }) => {
if (method === "write") {
const file = new Vinyl({
path: params.path,
cwd: params.cwd,
base: params.base,
contents: Buffer.from(params.contents, "utf8")
});
if (params.sourceMap) file.sourceMap = params.sourceMap
compileStream.push(file);;
if (file.path.endsWith(".d.ts")) {
dtsStream.push(file);
}
else {
jsStream.push(file);
}
}
else if (method === "final") {
compileStream.push(null);
jsStream.push(null);
dtsStream.push(null);
proc.kill();
}
else if (method === "error") {
const error = new Error();
error.name = params.name;
error.message = params.message;
error.stack = params.stack;
compileStream.emit("error", error);
proc.kill();
}
});
return /** @type {*} */(compileStream);
});
return Object.assign(wrappedProject, project);
}

exports.createProject = createProject;
91 changes: 91 additions & 0 deletions scripts/build/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// @ts-check
const path = require("path");
const fs = require("fs");
const tsc = require("gulp-typescript");
const Vinyl = require("vinyl");
const { Readable, Writable } = require("stream");

/** @type {tsc.Project} */
let project;

/** @type {Readable} */
let inputStream;

/** @type {Writable} */
let outputStream;

/** @type {tsc.CompileStream} */
let compileStream;

process.on("message", ({ method, params }) => {
try {
if (method === "createProject") {
const { tsConfigFileName, settings, options } = params;
if (options.typescript) {
settings.typescript = require(options.typescript);
}
project = tsc.createProject(tsConfigFileName, settings);
inputStream = new Readable({
objectMode: true,
read() {}
});
outputStream = new Writable({
objectMode: true,
/**
* @param {*} file
*/
write(file, encoding, callback) {
process.send({
method: "write",
params: {
path: file.path,
cwd: file.cwd,
base: file.base,
contents: file.contents.toString(),
sourceMap: file.sourceMap
}
});
callback();
},
final(callback) {
process.send({ method: "final" });
callback();
}
});
outputStream.on("error", error => {
process.send({
method: "error",
params: {
name: error.name,
message: error.message,
stack: error.stack
}
});
});
compileStream = project();
inputStream.pipe(compileStream).pipe(outputStream);
}
else if (method === "write") {
const file = new Vinyl({
path: params.path,
cwd: params.cwd,
base: params.base
});
file.contents = fs.readFileSync(file.path);
inputStream.push(/** @type {*} */(file));
}
else if (method === "final") {
inputStream.push(null);
}
}
catch (e) {
process.send({
method: "error",
params: {
name: e.name,
message: e.message,
stack: e.stack
}
});
}
});
83 changes: 3 additions & 80 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17382,88 +17382,11 @@ namespace ts {
* and 1 insertion/deletion at 3 characters)
*/
function getSpellingSuggestionForName(name: string, symbols: Symbol[], meaning: SymbolFlags): Symbol | undefined {
const maximumLengthDifference = Math.min(2, Math.floor(name.length * 0.34));
let bestDistance = Math.floor(name.length * 0.4) + 1; // If the best result isn't better than this, don't bother.
let bestCandidate: Symbol | undefined;
let justCheckExactMatches = false;
const nameLowerCase = name.toLowerCase();
for (const candidate of symbols) {
return getSpellingSuggestion(name, symbols, getCandidateName);
function getCandidateName(candidate: Symbol) {
const candidateName = symbolName(candidate);
if (candidateName.charCodeAt(0) === CharacterCodes.doubleQuote
|| !(candidate.flags & meaning && Math.abs(candidateName.length - nameLowerCase.length) <= maximumLengthDifference)) {
continue;
}
const candidateNameLowerCase = candidateName.toLowerCase();
if (candidateNameLowerCase === nameLowerCase) {
return candidate;
}
if (justCheckExactMatches) {
continue;
}
if (candidateName.length < 3) {
// Don't bother, user would have noticed a 2-character name having an extra character
continue;
}
// Only care about a result better than the best so far.
const distance = levenshteinWithMax(nameLowerCase, candidateNameLowerCase, bestDistance - 1);
if (distance === undefined) {
continue;
}
if (distance < 3) {
justCheckExactMatches = true;
bestCandidate = candidate;
}
else {
Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined
bestDistance = distance;
bestCandidate = candidate;
}
return !startsWith(candidateName, "\"") && candidate.flags & meaning ? candidateName : undefined;
}
return bestCandidate;
}

function levenshteinWithMax(s1: string, s2: string, max: number): number | undefined {
let previous = new Array(s2.length + 1);
let current = new Array(s2.length + 1);
/** Represents any value > max. We don't care about the particular value. */
const big = max + 1;

for (let i = 0; i <= s2.length; i++) {
previous[i] = i;
}

for (let i = 1; i <= s1.length; i++) {
const c1 = s1.charCodeAt(i - 1);
const minJ = i > max ? i - max : 1;
const maxJ = s2.length > max + i ? max + i : s2.length;
current[0] = i;
/** Smallest value of the matrix in the ith column. */
let colMin = i;
for (let j = 1; j < minJ; j++) {
current[j] = big;
}
for (let j = minJ; j <= maxJ; j++) {
const dist = c1 === s2.charCodeAt(j - 1)
? previous[j - 1]
: Math.min(/*delete*/ previous[j] + 1, /*insert*/ current[j - 1] + 1, /*substitute*/ previous[j - 1] + 2);
current[j] = dist;
colMin = Math.min(colMin, dist);
}
for (let j = maxJ + 1; j <= s2.length; j++) {
current[j] = big;
}
if (colMin > max) {
// Give up -- everything in this column is > max and it can't get better in future columns.
return undefined;
}

const temp = previous;
previous = current;
current = temp;
}

const res = previous[s2.length];
return res > max ? undefined : res;
}

function markPropertyAsReferenced(prop: Symbol, nodeForCheckWriteOnly: Node | undefined, isThisAccess: boolean) {
Expand Down
Loading

0 comments on commit fbeb58a

Please sign in to comment.