{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/roslyn/pulls/comments/242363811","pull_request_review_id":185856025,"id":242363811,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI0MjM2MzgxMQ==","diff_hunk":"@@ -0,0 +1,241 @@\n+# Nullability API Design Notes\n+\n+## Guiding Principles\n+\n+When designing this API, there were a few core principles that we tried to keep in mind:\n+\n+1. First and foremost, we do not want to break existing analyzers and refactorings.\n+This means that common patterns that used to work need to continue to work.\n+These include reference equality for `ITypeSymbol`s that aren't generic, such as `string`.\n+2. We'd like the ability to avoid computing nullability information if it's not required.\n+Currently, the `SemanticModel` APIs do a good job of only causing the minimal amount of binding required to answer the question being asked, but attempting to compute nullability information will cause significantly more to be bound.\n+To fully determine nullability, we must bind the entire method and run nullability analysis up to the point requested by the caller, unlike today where individual statements can get away with being bound by themselves.\n+Even if the standard path calculates nullability info, we feel that some scenarios will be both perf sensitive and not care about results of nullability analysis.\n+This includes features like intellisense.\n+3. Users should be able to get at both declared nullability for variables, as well as seeing the inferred nullability at each expression from flow analysis.\n+\n+## General Concepts\n+\n+Nullability information is exposed publicly as an enum, `Nullability`.\n+There are 5 possible values:\n+\n+* `NotApplicable` - This is used when nullability information is requested about something that does not have a nullability, such as a statement, directive, or other similar constructs.\n+* `NotAnalyzed` - This is used to fulfill priority #2.\n+If the user requests information while asking for nullability to not be calculated, we'll use this to stand in for nullability.\n+* `Unknown` - This is used for legacy C# code that does not know about nullability.\n+This can appear in modern C# code that calls unannotated C#, or in certain generic variance scenarios where a common nullability cannot be inferred from the supplied arguments.\n+For use in this document unknown is represented with the `~` character, but this character does not appear in source.\n+* `NotNull` - This is used when we know the nullability is not null.\n+* `MayBeNull` - This is used when we know the nullability may be null.\n+\n+Nullability information will be retrieved from the `SemanticModel`, much like type information.\n+`GetSemanticModel` will return a `SemanticModel` that is aware of nullability information, and will force binding and calculation of nullability information when queried.\n+We will offer a method off of `SemanticModel`, `GetSingleStatementSemanticModel()`, which will return a `SemanticModel` that does not calculate nullability information, for particularly performance-sensitive scenarios.\n+This `SemanticModel` will share a cache with its parent, much like speculative `SemanticModel`s, and all nullabilities accessed on symbols retrieved from this `SemanticModel` will be `NotAnalyzed`.\n+\n+Generally speaking, when you want to determine the nullability of an `ITypeSymbol`, you need to check the containing context.\n+The declaring symbol (e.g. `ILocalSymbol`, `IFieldSymbol`, etc.) will have the declared nullability of the type.\n+`GetTypeInfo` will give you both the `ITypeSymbol` and the `Nullability` of an expression.\n+Nested nullabilities for type parameters are contained on the containing `ITypeSymbol`.\n+For example, if you wanted to know whether an array's contents are nullable, you will need to check the `IArrayTypeSymbol` for `ElementNullability`.\n+\n+Value types are always considered `NotNull`.\n+Nullable value types and reference types have their state tracked, and are either `NotNull` or `MayBeNull` depending on flow state.\n+Unconstrained generic parameters are being tracked, but what they will return for flow state information before explicit null checks occur in source code has not yet been decided.\n+\n+### Declared Nullability\n+\n+Declared nullability is the nullability that was explicitly typed in the source code by the programmer.\n+There are some cases where this is inferred, such as lambda arguments/return types, `var` variables, and type parameter substitution.\n+For these cases, flow state is necessary to compute the declared nullability.\n+For example:\n+\n+```C#\n+string? s1 = string.Empty;\n+var s2 = s1;\n+s2 = null; // This will warn, because the type of s2 is string, not string?\n+```\n+\n+The declared nullability of `s1` is `MayBeNull`, even though it is being initialized with a non-null value.\n+However, because of the flow state of `s1` is `NotNull`, we will infer the declared nullability of `s2` to be `NotNull` as well.\n+\n+Declared nullability can be retreived from the declaration symbol (e.g. `IFieldSymbol`, `IMethodSymbol`, etc.).\n+\n+### Flow State\n+\n+When the nullable feature is enabled, Roslyn will track the flow state of expressions throughout a method, regardless of what the variable was declared as.\n+`SemanticModel` can be used to request flow state information for individual expressions or sub-expressions through the `GetTypeInfo` APIs.\n+The `TypeInfo` struct will be augmented with `Nullability` and `ConvertedNullability` information, similar to how it currently has `Type` and `ConvertedType`.\n+Nullability of symbols at a location can be retrieved through the `GetSymbolInfo` API: if the expression successfully resolved to a single symbol, the `Symbol` property will have nullability calculated.\n+`CandidateSymbols` will not have calculated nullabilities, as we cannot run nullable analysis on code that has failed overload resolution.\n+\n+### `GetSemanticModel(bool skipNullabilityInformation)`\n+\n+This API proposal changes the way `SemanticModel` calls behave by default.\n+Currently, if semantic information is requested for a `SyntaxNode`, we make an effort to bind as little as possible to provide semantic information about that statement, usually a single statement.\n+However, if that semantic information will include `Nullability`, we must bind all statements that come before that statement and run nullability analysis up to and including that statement.\n+We believe that this change will be ok for most scenarios, as things such as colorization and analyzers are already running in the background near-constantly, binding pretty much everything on screen and in the file anyway.\n+There are a few specific scenarios that will be perf-sensitive, and an overload for `GetSemanticModel()` that skips nullability information will be provided for these.","path":"docs/compilers/CSharp/Nullability Public API Design Notes.md","position":78,"original_position":78,"commit_id":"21d0494db56def82f7bb068278a5c5dc54e315e2","original_commit_id":"21d0494db56def82f7bb068278a5c5dc54e315e2","user":{"login":"333fred","id":2371880,"node_id":"MDQ6VXNlcjIzNzE4ODA=","avatar_url":"https://avatars0.githubusercontent.com/u/2371880?v=4","gravatar_id":"","url":"https://api.github.com/users/333fred","html_url":"https://github.com/333fred","followers_url":"https://api.github.com/users/333fred/followers","following_url":"https://api.github.com/users/333fred/following{/other_user}","gists_url":"https://api.github.com/users/333fred/gists{/gist_id}","starred_url":"https://api.github.com/users/333fred/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/333fred/subscriptions","organizations_url":"https://api.github.com/users/333fred/orgs","repos_url":"https://api.github.com/users/333fred/repos","events_url":"https://api.github.com/users/333fred/events{/privacy}","received_events_url":"https://api.github.com/users/333fred/received_events","type":"User","site_admin":false},"body":"I'll add a note about this that we'll only provide this API if dogfooding shows that it's necessary.","created_at":"2018-12-18T00:05:19Z","updated_at":"2018-12-18T00:05:19Z","html_url":"https://github.com/dotnet/roslyn/pull/31704#discussion_r242363811","pull_request_url":"https://api.github.com/repos/dotnet/roslyn/pulls/31704","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/comments/242363811"},"html":{"href":"https://github.com/dotnet/roslyn/pull/31704#discussion_r242363811"},"pull_request":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/31704"}},"in_reply_to_id":240850664},"pull_request":{"url":"https://api.github.com/repos/dotnet/roslyn/pulls/31704","id":237874681,"node_id":"MDExOlB1bGxSZXF1ZXN0MjM3ODc0Njgx","html_url":"https://github.com/dotnet/roslyn/pull/31704","diff_url":"https://github.com/dotnet/roslyn/pull/31704.diff","patch_url":"https://github.com/dotnet/roslyn/pull/31704.patch","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/31704","number":31704,"state":"open","locked":false,"title":"Document the initial public API design for Nullable Reference Types","user":{"login":"333fred","id":2371880,"node_id":"MDQ6VXNlcjIzNzE4ODA=","avatar_url":"https://avatars0.githubusercontent.com/u/2371880?v=4","gravatar_id":"","url":"https://api.github.com/users/333fred","html_url":"https://github.com/333fred","followers_url":"https://api.github.com/users/333fred/followers","following_url":"https://api.github.com/users/333fred/following{/other_user}","gists_url":"https://api.github.com/users/333fred/gists{/gist_id}","starred_url":"https://api.github.com/users/333fred/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/333fred/subscriptions","organizations_url":"https://api.github.com/users/333fred/orgs","repos_url":"https://api.github.com/users/333fred/repos","events_url":"https://api.github.com/users/333fred/events{/privacy}","received_events_url":"https://api.github.com/users/333fred/received_events","type":"User","site_admin":false},"body":"Adds a document giving an overview of the public API we're targeting for exposing nullable reference types information from the compiler layer to IDE and analyzer services. This includes the initial API design but is missing some parts, especially around syntax generation. These will come later.\r\n\r\n@dotnet/roslyn-compiler @dotnet/roslyn-ide @CyrusNajmabadi @terrajobst @mattwar please take a look.","created_at":"2018-12-12T00:32:14Z","updated_at":"2018-12-18T00:05:19Z","closed_at":null,"merged_at":null,"merge_commit_sha":"75ded9d5000d75e2d362d5e80f526d1ed524bd59","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":166673288,"node_id":"MDU6TGFiZWwxNjY2NzMyODg=","url":"https://api.github.com/repos/dotnet/roslyn/labels/Area-Compilers","name":"Area-Compilers","color":"5319e7","default":false},{"id":177193291,"node_id":"MDU6TGFiZWwxNzcxOTMyOTE=","url":"https://api.github.com/repos/dotnet/roslyn/labels/Documentation","name":"Documentation","color":"e52727","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/roslyn/pulls/31704/commits","review_comments_url":"https://api.github.com/repos/dotnet/roslyn/pulls/31704/comments","review_comment_url":"https://api.github.com/repos/dotnet/roslyn/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/31704/comments","statuses_url":"https://api.github.com/repos/dotnet/roslyn/statuses/21d0494db56def82f7bb068278a5c5dc54e315e2","head":{"label":"333fred:nullability-api-doc","ref":"nullability-api-doc","sha":"21d0494db56def82f7bb068278a5c5dc54e315e2","user":{"login":"333fred","id":2371880,"node_id":"MDQ6VXNlcjIzNzE4ODA=","avatar_url":"https://avatars0.githubusercontent.com/u/2371880?v=4","gravatar_id":"","url":"https://api.github.com/users/333fred","html_url":"https://github.com/333fred","followers_url":"https://api.github.com/users/333fred/followers","following_url":"https://api.github.com/users/333fred/following{/other_user}","gists_url":"https://api.github.com/users/333fred/gists{/gist_id}","starred_url":"https://api.github.com/users/333fred/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/333fred/subscriptions","organizations_url":"https://api.github.com/users/333fred/orgs","repos_url":"https://api.github.com/users/333fred/repos","events_url":"https://api.github.com/users/333fred/events{/privacy}","received_events_url":"https://api.github.com/users/333fred/received_events","type":"User","site_admin":false},"repo":{"id":70755125,"node_id":"MDEwOlJlcG9zaXRvcnk3MDc1NTEyNQ==","name":"roslyn","full_name":"333fred/roslyn","private":false,"owner":{"login":"333fred","id":2371880,"node_id":"MDQ6VXNlcjIzNzE4ODA=","avatar_url":"https://avatars0.githubusercontent.com/u/2371880?v=4","gravatar_id":"","url":"https://api.github.com/users/333fred","html_url":"https://github.com/333fred","followers_url":"https://api.github.com/users/333fred/followers","following_url":"https://api.github.com/users/333fred/following{/other_user}","gists_url":"https://api.github.com/users/333fred/gists{/gist_id}","starred_url":"https://api.github.com/users/333fred/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/333fred/subscriptions","organizations_url":"https://api.github.com/users/333fred/orgs","repos_url":"https://api.github.com/users/333fred/repos","events_url":"https://api.github.com/users/333fred/events{/privacy}","received_events_url":"https://api.github.com/users/333fred/received_events","type":"User","site_admin":false},"html_url":"https://github.com/333fred/roslyn","description":"The .NET Compiler Platform (\"Roslyn\") provides open-source C# and Visual Basic compilers with rich code analysis APIs.","fork":true,"url":"https://api.github.com/repos/333fred/roslyn","forks_url":"https://api.github.com/repos/333fred/roslyn/forks","keys_url":"https://api.github.com/repos/333fred/roslyn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/333fred/roslyn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/333fred/roslyn/teams","hooks_url":"https://api.github.com/repos/333fred/roslyn/hooks","issue_events_url":"https://api.github.com/repos/333fred/roslyn/issues/events{/number}","events_url":"https://api.github.com/repos/333fred/roslyn/events","assignees_url":"https://api.github.com/repos/333fred/roslyn/assignees{/user}","branches_url":"https://api.github.com/repos/333fred/roslyn/branches{/branch}","tags_url":"https://api.github.com/repos/333fred/roslyn/tags","blobs_url":"https://api.github.com/repos/333fred/roslyn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/333fred/roslyn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/333fred/roslyn/git/refs{/sha}","trees_url":"https://api.github.com/repos/333fred/roslyn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/333fred/roslyn/statuses/{sha}","languages_url":"https://api.github.com/repos/333fred/roslyn/languages","stargazers_url":"https://api.github.com/repos/333fred/roslyn/stargazers","contributors_url":"https://api.github.com/repos/333fred/roslyn/contributors","subscribers_url":"https://api.github.com/repos/333fred/roslyn/subscribers","subscription_url":"https://api.github.com/repos/333fred/roslyn/subscription","commits_url":"https://api.github.com/repos/333fred/roslyn/commits{/sha}","git_commits_url":"https://api.github.com/repos/333fred/roslyn/git/commits{/sha}","comments_url":"https://api.github.com/repos/333fred/roslyn/comments{/number}","issue_comment_url":"https://api.github.com/repos/333fred/roslyn/issues/comments{/number}","contents_url":"https://api.github.com/repos/333fred/roslyn/contents/{+path}","compare_url":"https://api.github.com/repos/333fred/roslyn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/333fred/roslyn/merges","archive_url":"https://api.github.com/repos/333fred/roslyn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/333fred/roslyn/downloads","issues_url":"https://api.github.com/repos/333fred/roslyn/issues{/number}","pulls_url":"https://api.github.com/repos/333fred/roslyn/pulls{/number}","milestones_url":"https://api.github.com/repos/333fred/roslyn/milestones{/number}","notifications_url":"https://api.github.com/repos/333fred/roslyn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/333fred/roslyn/labels{/name}","releases_url":"https://api.github.com/repos/333fred/roslyn/releases{/id}","deployments_url":"https://api.github.com/repos/333fred/roslyn/deployments","created_at":"2016-10-13T01:01:16Z","updated_at":"2018-12-05T00:31:54Z","pushed_at":"2018-12-13T20:36:36Z","git_url":"git://github.com/333fred/roslyn.git","ssh_url":"git@github.com:333fred/roslyn.git","clone_url":"https://github.com/333fred/roslyn.git","svn_url":"https://github.com/333fred/roslyn","homepage":"","size":451083,"stargazers_count":4,"watchers_count":4,"language":"C#","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":0,"watchers":4,"default_branch":"master"}},"base":{"label":"dotnet:master","ref":"master","sha":"03518080277b1e1c759b40e022324f5e293411fd","user":{"login":"dotnet","id":9141961,"node_id":"MDEyOk9yZ2FuaXphdGlvbjkxNDE5NjE=","avatar_url":"https://avatars0.githubusercontent.com/u/9141961?v=4","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"repo":{"id":29078997,"node_id":"MDEwOlJlcG9zaXRvcnkyOTA3ODk5Nw==","name":"roslyn","full_name":"dotnet/roslyn","private":false,"owner":{"login":"dotnet","id":9141961,"node_id":"MDEyOk9yZ2FuaXphdGlvbjkxNDE5NjE=","avatar_url":"https://avatars0.githubusercontent.com/u/9141961?v=4","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/dotnet/roslyn","description":"The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.","fork":false,"url":"https://api.github.com/repos/dotnet/roslyn","forks_url":"https://api.github.com/repos/dotnet/roslyn/forks","keys_url":"https://api.github.com/repos/dotnet/roslyn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/roslyn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/roslyn/teams","hooks_url":"https://api.github.com/repos/dotnet/roslyn/hooks","issue_events_url":"https://api.github.com/repos/dotnet/roslyn/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/roslyn/events","assignees_url":"https://api.github.com/repos/dotnet/roslyn/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/roslyn/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/roslyn/tags","blobs_url":"https://api.github.com/repos/dotnet/roslyn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/roslyn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/roslyn/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/roslyn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/roslyn/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/roslyn/languages","stargazers_url":"https://api.github.com/repos/dotnet/roslyn/stargazers","contributors_url":"https://api.github.com/repos/dotnet/roslyn/contributors","subscribers_url":"https://api.github.com/repos/dotnet/roslyn/subscribers","subscription_url":"https://api.github.com/repos/dotnet/roslyn/subscription","commits_url":"https://api.github.com/repos/dotnet/roslyn/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/roslyn/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/roslyn/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/roslyn/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/roslyn/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/roslyn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/roslyn/merges","archive_url":"https://api.github.com/repos/dotnet/roslyn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/roslyn/downloads","issues_url":"https://api.github.com/repos/dotnet/roslyn/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/roslyn/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/roslyn/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/roslyn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/roslyn/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/roslyn/releases{/id}","deployments_url":"https://api.github.com/repos/dotnet/roslyn/deployments","created_at":"2015-01-11T02:39:03Z","updated_at":"2018-12-17T23:54:05Z","pushed_at":"2018-12-18T00:00:33Z","git_url":"git://github.com/dotnet/roslyn.git","ssh_url":"git@github.com:dotnet/roslyn.git","clone_url":"https://github.com/dotnet/roslyn.git","svn_url":"https://github.com/dotnet/roslyn","homepage":"https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/","size":503805,"stargazers_count":10517,"watchers_count":10517,"language":"C#","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2494,"mirror_url":null,"archived":false,"open_issues_count":5576,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":2494,"open_issues":5576,"watchers":10517,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/31704"},"html":{"href":"https://github.com/dotnet/roslyn/pull/31704"},"issue":{"href":"https://api.github.com/repos/dotnet/roslyn/issues/31704"},"comments":{"href":"https://api.github.com/repos/dotnet/roslyn/issues/31704/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/31704/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/31704/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/roslyn/statuses/21d0494db56def82f7bb068278a5c5dc54e315e2"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"333fred"}}