{"action":"created","issue":{"url":"https://api.github.com/repos/dart-lang/dev_compiler/issues/432","labels_url":"https://api.github.com/repos/dart-lang/dev_compiler/issues/432/labels{/name}","comments_url":"https://api.github.com/repos/dart-lang/dev_compiler/issues/432/comments","events_url":"https://api.github.com/repos/dart-lang/dev_compiler/issues/432/events","html_url":"https://github.com/dart-lang/dev_compiler/pull/432","id":129570852,"number":432,"title":"Less dart.notNull checks for local vars using flow-insensitive nullability inference.","user":{"login":"ochafik","id":273860,"avatar_url":"https://avatars.githubusercontent.com/u/273860?v=3","gravatar_id":"","url":"https://api.github.com/users/ochafik","html_url":"https://github.com/ochafik","followers_url":"https://api.github.com/users/ochafik/followers","following_url":"https://api.github.com/users/ochafik/following{/other_user}","gists_url":"https://api.github.com/users/ochafik/gists{/gist_id}","starred_url":"https://api.github.com/users/ochafik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ochafik/subscriptions","organizations_url":"https://api.github.com/users/ochafik/orgs","repos_url":"https://api.github.com/users/ochafik/repos","events_url":"https://api.github.com/users/ochafik/events{/privacy}","received_events_url":"https://api.github.com/users/ochafik/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2016-01-28T20:27:12Z","updated_at":"2016-01-29T17:50:51Z","closed_at":"2016-01-28T20:35:40Z","pull_request":{"url":"https://api.github.com/repos/dart-lang/dev_compiler/pulls/432","html_url":"https://github.com/dart-lang/dev_compiler/pull/432","diff_url":"https://github.com/dart-lang/dev_compiler/pull/432.diff","patch_url":"https://github.com/dart-lang/dev_compiler/pull/432.patch"},"body":"Less dart.notNull checks for local vars using flow-insensitive nullability inference.\r\n\r\nWithin some AST context (at library granularity, for convenience), we\r\ncollect all the assignments to local vars:\r\n- Declaration with no initializer amounts to `null` assignment\r\n- Assignment ops are expanded naively: `x++` yield an assigned value of\r\n`x + 1`, etc\r\n\r\nWe detect \"trivially nullable\" variables (e.g. `var x;`, `x =\r\nbreaking.out;`) by spotting assigned values that are nullable under the\r\noptimistic assumption that all known variables are non-nullable.\r\n\r\nThen we build a nullability dependency graph in linear time: whenever\r\nwe see `x = y;`, we know that \"y is nullable\" implies \"x is nullable\".\r\n\r\nFinally, we propagate \"trivial nullabilities\" through that graph: any\r\nvariable that wasn't reached is deemed not-nullable.\r\n\r\n(this is similar to mark and sweep garbage collection, where the roots\r\nare the \"trivially nullable\" variables; credits to leafpetersen@ for\r\nlinear solution)\r\n\r\n(LGTM'd in [this review thread](https://codereview.chromium.org/1508963005))"},"comment":{"url":"https://api.github.com/repos/dart-lang/dev_compiler/issues/comments/176885199","html_url":"https://github.com/dart-lang/dev_compiler/pull/432#issuecomment-176885199","issue_url":"https://api.github.com/repos/dart-lang/dev_compiler/issues/432","id":176885199,"user":{"login":"jmesserly","id":1081711,"avatar_url":"https://avatars.githubusercontent.com/u/1081711?v=3","gravatar_id":"","url":"https://api.github.com/users/jmesserly","html_url":"https://github.com/jmesserly","followers_url":"https://api.github.com/users/jmesserly/followers","following_url":"https://api.github.com/users/jmesserly/following{/other_user}","gists_url":"https://api.github.com/users/jmesserly/gists{/gist_id}","starred_url":"https://api.github.com/users/jmesserly/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jmesserly/subscriptions","organizations_url":"https://api.github.com/users/jmesserly/orgs","repos_url":"https://api.github.com/users/jmesserly/repos","events_url":"https://api.github.com/users/jmesserly/events{/privacy}","received_events_url":"https://api.github.com/users/jmesserly/received_events","type":"User","site_admin":false},"created_at":"2016-01-29T17:50:51Z","updated_at":"2016-01-29T17:50:51Z","body":"Ohhhh, yeah, that makes sense! Squashing is a workflow for doing pull requests, definitely works, but it can lead to more conflicts especially if you're iterating and keeping up with other changes. I try and use \"merge\" as much as possible (it's smarter about ... merging :) ), and only squash at the very end. And \"git cl land\" will squash for you -- one of its more useful features. :)"}}