Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Control flow based type guards #6959

Closed
wants to merge 67 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
42a8efd
Merge remote-tracking branch 'Microsoft/master'
ivogabe Aug 15, 2015
80f42ed
Merge remote-tracking branch 'Microsoft/master'
ivogabe Aug 19, 2015
57f5d5c
Merge branch 'master' of https://github.com/Microsoft/TypeScript
ivogabe Nov 18, 2015
163291f
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Nov 30, 2015
441c999
Add flow markers to binder
ivogabe Dec 4, 2015
522a99c
Add BranchFlow for type guards
ivogabe Dec 4, 2015
78ca7b5
Add caching of identifier narrowing in binder
ivogabe Dec 6, 2015
1fb2db6
Implement flow based type guards in checker
ivogabe Dec 6, 2015
f1c9a82
Narrow assignments to unions only
ivogabe Dec 9, 2015
d3dd1fa
Make isDeclarationName a weak type guard for Identifiers
ivogabe Dec 9, 2015
702edac
Remove trailing space
ivogabe Dec 9, 2015
8670014
Make getNarrowedTypeOfSymbol work on all nodes again
ivogabe Dec 9, 2015
ecbf9e2
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Dec 9, 2015
c1abed2
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Dec 11, 2015
905a240
Bind flow of loops and named labels
ivogabe Feb 6, 2016
b8c0e2c
Fix flow based type guards in checker
ivogabe Feb 6, 2016
f6dc119
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Feb 6, 2016
b385472
Fix errors after merge
ivogabe Feb 6, 2016
6f1d84e
Remove restriction on type narrowing with assignments in loops
ivogabe Feb 6, 2016
ffa8db3
Fix assignment checking
ivogabe Feb 6, 2016
844a8c1
Remove flowIndex, use getNodeId
ivogabe Feb 8, 2016
ff1b2d6
Remove PreviousOccurency interface
ivogabe Feb 8, 2016
6c7c678
Fix typo
ivogabe Feb 8, 2016
7d2daf9
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Feb 8, 2016
035d973
Fix binding of condition less for statement
ivogabe Feb 8, 2016
b2e51a3
Handle narrowing in var declarations
ivogabe Feb 11, 2016
2747c98
Rename `showError` to `reportError`
ivogabe Feb 11, 2016
b58eb60
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Feb 11, 2016
3f0c283
Fix typos after merge
ivogabe Feb 11, 2016
a30fa8f
Merge master
ivogabe Feb 11, 2016
ac2f547
Remove old assertion
ivogabe Feb 12, 2016
0a91991
Keep narrowed types in a loop
ivogabe Feb 12, 2016
a44de51
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Feb 12, 2016
67913d8
Fix narrowing of union type assigned to a union type
ivogabe Feb 13, 2016
f15291f
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Feb 13, 2016
26a4d37
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Feb 26, 2016
074a05d
Add more caching
ivogabe Feb 26, 2016
2c57ee5
Use cache to speed up multiple paths to same node in flow graph
ivogabe Feb 26, 2016
927c562
Don't error when assigning to narrowed variable using destructuring
ivogabe Feb 29, 2016
a4b91f3
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Feb 29, 2016
8673a46
Narrow after destructuring assignment
ivogabe Mar 7, 2016
09e4302
Rewrite recursion to loop, reduces check time
ivogabe Mar 9, 2016
1037efa
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Mar 11, 2016
8331915
Fix issues with destructuring assignments
ivogabe Mar 12, 2016
8d4cea4
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Mar 13, 2016
c128582
Fix narrowing of JSX tags
ivogabe Mar 13, 2016
19b3f90
Use initial type when narrowing resulted in empty type
ivogabe Mar 14, 2016
59b543f
Move narrowing info from node to NodeLinks
ivogabe Mar 14, 2016
c0061c0
Allow narrowing in nested functions
ivogabe Mar 14, 2016
096c70a
Narrow after destructuring assignments with initializers
ivogabe Mar 15, 2016
fa77df5
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Mar 15, 2016
46786b3
Fix narrowing in for of statement
ivogabe Mar 15, 2016
3a7575b
Stop narrowing with guards that contain assignments
ivogabe Mar 15, 2016
b9f5b79
Add control flow tests
ivogabe Mar 15, 2016
21efd00
Add test for narrowing after assignment
ivogabe Mar 15, 2016
d5fbd4e
Modify existing tests for new type guards behavior
ivogabe Mar 15, 2016
f8a1827
Add more tests
ivogabe Mar 16, 2016
7cceb0c
Remove redundant bindFlowMarker calls
ivogabe Mar 16, 2016
bea32e2
Fix tests
ivogabe Mar 16, 2016
a659239
Accept baseline
ivogabe Mar 16, 2016
9e13d0f
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Mar 16, 2016
3490979
Update tests
ivogabe Mar 16, 2016
a719858
Merge remote-tracking branch 'Microsoft/master' into guards
ivogabe Mar 22, 2016
90a678d
Implement flow based type guards for this expression and dotted names
ivogabe Mar 23, 2016
7646af1
Fix unresolved symbols, wrong caching and empty type issues
ivogabe Mar 23, 2016
4a76fe2
Accept new baselines
ivogabe Mar 23, 2016
16555dd
Stop narrowing of dotted name after assignment of parent type
ivogabe Mar 23, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Merge remote-tracking branch 'Microsoft/master' into guards
# Conflicts:
#	src/compiler/binder.ts
  • Loading branch information
ivogabe committed Feb 11, 2016
commit b58eb60951c4a7f238baac81d0a895bafcc8967d
75 changes: 41 additions & 34 deletions Jakefile.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,51 +223,59 @@ var builtLocalCompiler = path.join(builtLocalDirectory, compilerFilename);
* @param prereqs: prerequisite tasks to compiling the file
* @param prefixes: a list of files to prepend to the target file
* @param useBuiltCompiler: true to use the built compiler, false to use the LKG
* @param noOutFile: true to compile without using --out
* @param generateDeclarations: true to compile using --declaration
* @param outDir: true to compile using --outDir
* @param keepComments: false to compile using --removeComments
* @parap {Object} opts - property bag containing auxiliary options
* @param {boolean} opts.noOutFile: true to compile without using --out
* @param {boolean} opts.generateDeclarations: true to compile using --declaration
* @param {string} opts.outDir: value for '--outDir' command line option
* @param {boolean} opts.keepComments: false to compile using --removeComments
* @param {boolean} opts.preserveConstEnums: true if compiler should keep const enums in code
* @param {boolean} opts.noResolve: true if compiler should not include non-rooted files in compilation
* @param {boolean} opts.stripInternal: true if compiler should remove declarations marked as @internal
* @param {boolean} opts.noMapRoot: true if compiler omit mapRoot option
* @param callback: a function to execute after the compilation process ends
*/
function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOutFile, generateDeclarations, outDir, preserveConstEnums, keepComments, noResolve, stripInternal, callback) {
function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts, callback) {
file(outFile, prereqs, function() {
var compilerPath = useBuiltCompiler ? builtLocalCompiler : LKGCompiler;
var options = "--noImplicitAny --noEmitOnError --pretty";

opts = opts || {};
// Keep comments when specifically requested
// or when in debug mode.
if (!(keepComments || useDebugMode)) {
if (!(opts.keepComments || useDebugMode)) {
options += " --removeComments";
}

if (generateDeclarations) {
if (opts.generateDeclarations) {
options += " --declaration";
}

if (preserveConstEnums || useDebugMode) {
if (opts.preserveConstEnums || useDebugMode) {
options += " --preserveConstEnums";
}

if (outDir) {
options += " --outDir " + outDir;
if (opts.outDir) {
options += " --outDir " + opts.outDir;
}

if (!noOutFile) {
if (!opts.noOutFile) {
options += " --out " + outFile;
}
else {
options += " --module commonjs"
}

if(noResolve) {
if(opts.noResolve) {
options += " --noResolve";
}

if (useDebugMode) {
options += " -sourcemap -mapRoot file:///" + path.resolve(path.dirname(outFile));
options += " -sourcemap";
if (!opts.noMapRoot) {
options += " -mapRoot file:///" + path.resolve(path.dirname(outFile));
}
}

if (stripInternal) {
if (opts.stripInternal) {
options += " --stripInternal"
}

Expand Down Expand Up @@ -382,13 +390,7 @@ compileFile(/*outfile*/configureNightlyJs,
/*prereqs*/ [configureNightlyTs],
/*prefixes*/ [],
/*useBuiltCompiler*/ false,
/*noOutFile*/ false,
/*generateDeclarations*/ false,
/*outDir*/ undefined,
/*preserveConstEnums*/ undefined,
/*keepComments*/ false,
/*noResolve*/ false,
/*stripInternal*/ false);
{ noOutFile: false, generateDeclarations: false, keepComments: false, noResolve: false, stripInternal: false });

task("setDebugMode", function() {
useDebugMode = true;
Expand Down Expand Up @@ -438,6 +440,7 @@ var tscFile = path.join(builtLocalDirectory, compilerFilename);
compileFile(tscFile, compilerSources, [builtLocalDirectory, copyright].concat(compilerSources), [copyright], /*useBuiltCompiler:*/ false);

var servicesFile = path.join(builtLocalDirectory, "typescriptServices.js");
var servicesFileInBrowserTest = path.join(builtLocalDirectory, "typescriptServicesInBrowserTest.js");
var standaloneDefinitionsFile = path.join(builtLocalDirectory, "typescriptServices.d.ts");
var nodePackageFile = path.join(builtLocalDirectory, "typescript.js");
var nodeDefinitionsFile = path.join(builtLocalDirectory, "typescript.d.ts");
Expand All @@ -446,13 +449,7 @@ var nodeStandaloneDefinitionsFile = path.join(builtLocalDirectory, "typescript_s
compileFile(servicesFile, servicesSources,[builtLocalDirectory, copyright].concat(servicesSources),
/*prefixes*/ [copyright],
/*useBuiltCompiler*/ true,
/*noOutFile*/ false,
/*generateDeclarations*/ true,
/*outDir*/ undefined,
/*preserveConstEnums*/ true,
/*keepComments*/ true,
/*noResolve*/ false,
/*stripInternal*/ true,
{ noOutFile: false, generateDeclarations: true, preserveConstEnums: true, keepComments: true, noResolve: false, stripInternal: true },
/*callback*/ function () {
jake.cpR(servicesFile, nodePackageFile, {silent: true});

Expand All @@ -475,6 +472,16 @@ compileFile(servicesFile, servicesSources,[builtLocalDirectory, copyright].conca
fs.writeFileSync(nodeStandaloneDefinitionsFile, nodeStandaloneDefinitionsFileContents);
});

compileFile(servicesFileInBrowserTest, servicesSources,[builtLocalDirectory, copyright].concat(servicesSources),
/*prefixes*/ [copyright],
/*useBuiltCompiler*/ true,
{ noOutFile: false, generateDeclarations: true, preserveConstEnums: true, keepComments: true, noResolve: false, stripInternal: true, noMapRoot: true },
/*callback*/ function () {
var content = fs.readFileSync(servicesFileInBrowserTest).toString();
var i = content.lastIndexOf("\n");
fs.writeFileSync(servicesFileInBrowserTest, content.substring(0, i) + "\r\n//# sourceURL=../built/local/typeScriptServices.js" + content.substring(i));
});


var serverFile = path.join(builtLocalDirectory, "tsserver.js");
compileFile(serverFile, serverSources,[builtLocalDirectory, copyright].concat(serverSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true);
Expand All @@ -486,8 +493,7 @@ compileFile(
[builtLocalDirectory, copyright].concat(languageServiceLibrarySources),
/*prefixes*/ [copyright],
/*useBuiltCompiler*/ true,
/*noOutFile*/ false,
/*generateDeclarations*/ true);
{ noOutFile: false, generateDeclarations: true });

// Local target to build the language service server library
desc("Builds language service server library");
Expand Down Expand Up @@ -720,7 +726,7 @@ task("generate-code-coverage", ["tests", builtLocalDirectory], function () {
// Browser tests
var nodeServerOutFile = 'tests/webTestServer.js'
var nodeServerInFile = 'tests/webTestServer.ts'
compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, /*noOutFile*/ true);
compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true });

desc("Runs browserify on run.js to produce a file suitable for running tests in the browser");
task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function() {
Expand All @@ -729,7 +735,7 @@ task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function()
}, {async: true});

desc("Runs the tests using the built run.js file like 'jake runtests'. Syntax is jake runtests-browser. Additional optional parameters tests=[regex], port=, browser=[chrome|IE]");
task("runtests-browser", ["tests", "browserify", builtLocalDirectory], function() {
task("runtests-browser", ["tests", "browserify", builtLocalDirectory, servicesFileInBrowserTest], function() {
cleanTestDirs();
host = "node"
port = process.env.port || process.env.p || '8888';
Expand Down Expand Up @@ -881,7 +887,8 @@ var tslintRulesOutFiles = tslintRules.map(function(p) {
desc("Compiles tslint rules to js");
task("build-rules", tslintRulesOutFiles);
tslintRulesFiles.forEach(function(ruleFile, i) {
compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false, /*noOutFile*/ true, /*generateDeclarations*/ false, path.join(builtLocalDirectory, "tslint"));
compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false,
{ noOutFile: true, generateDeclarations: false, outDir: path.join(builtLocalDirectory, "tslint")});
});

function getLinterOptions() {
Expand Down
4 changes: 4 additions & 0 deletions doc/handbook/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# The TypeScript Handbook

The contents of the TypeScript Handbook can be read from [its GitHub repository](https://github.com/Microsoft/TypeScript-Handbook).
Issues and pull requests should be directed there.
6 changes: 6 additions & 0 deletions doc/wiki/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# The TypeScript Wiki

To read the wiki, [visit the wiki on GitHub](https://github.com/Microsoft/TypeScript/wiki).

To contribute by filing an issue or sending a pull request, [visit the wiki repository](https://github.com/Microsoft/TypeScript-wiki).

12 changes: 6 additions & 6 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace ts {
}

const enum Reachability {
Unintialized = 1 << 0,
Uninitialized = 1 << 0,
Reachable = 1 << 1,
Unreachable = 1 << 2,
ReportedUnreachable = 1 << 3
Expand Down Expand Up @@ -439,7 +439,7 @@ namespace ts {
// the getLocalNameOfContainer function in the type checker to validate that the local name
// used for a container is unique.
function bindChildren(node: Node) {
// Before we recurse into a node's chilren, we first save the existing parent, container
// Before we recurse into a node's children, we first save the existing parent, container
// and block-container. Then after we pop out of processing the children, we restore
// these saved values.
const saveParent = parent;
Expand All @@ -464,7 +464,7 @@ namespace ts {
// Finally, if this is a block-container, then we clear out any existing .locals object
// it may contain within it. This happens in incremental scenarios. Because we can be
// reusing a node from a previous compilation, that node may have had 'locals' created
// for it. We must clear this so we don't accidently move any stale data forward from
// for it. We must clear this so we don't accidentally move any stale data forward from
// a previous compilation.
const containerFlags = getContainerFlags(node);
if (containerFlags & ContainerFlags.IsContainer) {
Expand Down Expand Up @@ -785,7 +785,7 @@ namespace ts {

const hasDefault = forEach(n.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause);

// post switch state is unreachable if switch is exaustive (has a default case) and does not have fallthrough from the last case
// post switch state is unreachable if switch is exhaustive (has a default case) and does not have fallthrough from the last case
const postSwitchState = hasDefault && currentReachabilityState.reachability !== Reachability.Reachable ? defaultUnreachable : preSwitchState;

popImplicitLabel(postSwitchLabel, postSwitchState);
Expand Down Expand Up @@ -889,7 +889,7 @@ namespace ts {

case SyntaxKind.Block:
// do not treat blocks directly inside a function as a block-scoped-container.
// Locals that reside in this block should go to the function locals. Othewise 'x'
// Locals that reside in this block should go to the function locals. Otherwise 'x'
// would not appear to be a redeclaration of a block scoped local in the following
// example:
//
Expand Down Expand Up @@ -1079,7 +1079,7 @@ namespace ts {

const identifier = <Identifier>prop.name;

// ECMA-262 11.1.5 Object Initialiser
// ECMA-262 11.1.5 Object Initializer
// If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
// a.This production is contained in strict code and IsDataDescriptor(previous) is true and
// IsDataDescriptor(propId.descriptor) is true.
Expand Down
Loading