提交 ec9f862e 编写于 作者: C Cyrus Najmabadi

Merge remote-tracking branch 'upstream/master' into renameOOP7

......@@ -68,6 +68,25 @@
"problemMatcher": "$msCompile",
"group": "build"
},
{
"label": "update xlf files",
"command": "./build.sh",
"type": "shell",
"args": [
"--skipAnalyzers"
],
"windows": {
"command": "./build.cmd",
"args": [
"-skipAnalyzers"
],
},
"options": {
"env": { "UpdateXlfOnBuild": "true" }
},
"problemMatcher": "$msCompile",
"group": "build"
},
{
"label": "run tests in current file (netcoreapp3.1)",
"command": "./.dotnet/dotnet",
......
......@@ -6,30 +6,35 @@ and will be updated as work progresses, features are added / removed, and as wor
This is not an exhaustive list of our features but rather the ones which have active development
efforts behind them.
# C# 9
# C# Next
| Feature | Branch | State | Developers | Reviewer | LDM Champ |
|----------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------|
| [Caller expression attribute](https://github.com/dotnet/csharplang/issues/287) | [caller-expression](https://github.com/dotnet/roslyn/tree/features/caller-expression) | Prototype | [alrz](https://github.com/alrz) | [jcouv](https://github.com/jcouv) | [jcouv](https://github.com/jcouv) |
| [Target-typed new](https://github.com/dotnet/csharplang/issues/100) | [target-typed-new](https://github.com/dotnet/roslyn/tree/features/target-typed-new) | [Merged into 16.7p1](https://github.com/dotnet/roslyn/issues/28489) | [alrz](https://github.com/alrz) | [jcouv](https://github.com/jcouv) | [jcouv](https://github.com/jcouv) |
| [Generic attributes](https://github.com/dotnet/csharplang/issues/124) | [generic-attributes](https://github.com/dotnet/roslyn/tree/features/generic-attributes) | [In Progress](https://github.com/dotnet/roslyn/issues/36285) | [AviAvni](https://github.com/AviAvni) | [agocke](https://github.com/agocke) | [mattwar](https://github.com/mattwar) |
| [Default in deconstruction](https://github.com/dotnet/roslyn/pull/25562) | [decon-default](https://github.com/dotnet/roslyn/tree/features/decon-default) | [Implemented](https://github.com/dotnet/roslyn/issues/25559) | [jcouv](https://github.com/jcouv) | [gafter](https://github.com/gafter) | [jcouv](https://github.com/jcouv) |
| [Relax ordering of `ref` and `partial` modifiers](https://github.com/dotnet/csharplang/issues/946) | [ref-partial](https://github.com/dotnet/roslyn/tree/features/ref-partial) | In Progress | [alrz](https://github.com/alrz) | [gafter](https://github.com/gafter) | [jcouv](https://github.com/jcouv) |
| [Parameter null-checking](https://github.com/dotnet/csharplang/issues/2145) | [param-nullchecking](https://github.com/dotnet/roslyn/tree/features/param-nullchecking) | [In Progress](https://github.com/dotnet/roslyn/issues/36024) | [fayrose](https://github.com/fayrose) | [agocke](https://github.com/agocke) | [jaredpar](https://github.com/jaredpar) |
| [Skip locals init](https://github.com/dotnet/csharplang/issues/1738) | [localsinit](https://github.com/dotnet/roslyn/tree/features/localsinit) | [Merged](https://github.com/dotnet/roslyn/issues/25780) | [t-camaia](https://github.com/t-camaia), [agocke](https://github.com/agocke) | [jaredpar](https://github.com/jaredpar) | [agocke](https://github.com/agocke) |
| [Lambda discard parameters](https://github.com/dotnet/csharplang/issues/111) | master | [Merged](https://github.com/dotnet/roslyn/issues/38820) | [jcouv](https://github.com/jcouv) | [AlekseyTs](https://github.com/AlekseyTs), [chsienki](https://github.com/chsienki) | [jcouv](https://github.com/jcouv) |
| [Native ints](https://github.com/dotnet/csharplang/issues/435) | [features/NativeInt](https://github.com/dotnet/roslyn/tree/features/NativeInt) | [Merged into 16.7p1](https://github.com/dotnet/roslyn/issues/38821) | [cston](https://github.com/cston) | [333fred](https://github.com/333fred), [gafter](https://github.com/gafter) | [jaredpar](https://github.com/jaredpar) |
| [Attributes on local functions](https://github.com/dotnet/csharplang/issues/1888) | [features/local-function-attributes](https://github.com/dotnet/roslyn/tree/features/local-function-attributes) | [Merged](https://github.com/dotnet/roslyn/issues/38801) | [RikkiGibson](https://github.com/RikkiGibson) | [agocke](https://github.com/agocke) | [agocke](https://github.com/agocke) |
| [Function pointers](https://github.com/dotnet/csharplang/issues/191) | [function-pointers](https://github.com/dotnet/roslyn/tree/features/function-pointers) | [In Progress](https://github.com/dotnet/roslyn/issues/38830) | [333fred](https://github.com/333fred) | [AlekseyTs](https://github.com/AlekseyTs) | [jaredpar](https://github.com/jaredpar) |
| [Function pointers](https://github.com/dotnet/csharplang/issues/191) | [function-pointers](https://github.com/dotnet/roslyn/tree/features/function-pointers) | [In Progress](https://github.com/dotnet/roslyn/issues/43321) | [333fred](https://github.com/333fred) | [AlekseyTs](https://github.com/AlekseyTs) | [jaredpar](https://github.com/jaredpar) |
| [Pattern matching improvements](https://github.com/dotnet/csharplang/issues/2850) | [features/patterns3](https://github.com/dotnet/roslyn/tree/features/patterns3) | [In progress](https://github.com/dotnet/roslyn/issues/41502) ([test](https://github.com/dotnet/roslyn/issues/40727)) | [gafter](https://github.com/gafter) | [RikkiGibson](https://github.com/RikkiGibson),[agocke](https://github.com/agocke) | [gafter](https://github.com/gafter) |
| [Static lambdas](https://github.com/dotnet/csharplang/issues/275) | [features/static-lambdas](https://github.com/dotnet/roslyn/tree/features/static-lambdas) | [In progress](https://github.com/dotnet/roslyn/issues/39606) | [CyrusNajmabadi](https://github.com/CyrusNajmabadi) | [jcouv](https://github.com/jcouv) | [jcouv](https://github.com/jcouv) |
| [Records](https://github.com/dotnet/csharplang/issues/39) | [features/records](https://github.com/dotnet/roslyn/tree/features/records) | [In progress](https://github.com/dotnet/roslyn/issues/40726) | [agocke](https://github.com/agocke) | [gafter](https://github.com/gafter), [333fred](https://github.com/333fred) | [agocke](https://github.com/agocke) |
| [Target-typed conditional](https://github.com/dotnet/csharplang/issues/2460) | [features/target-typing](https://github.com/dotnet/roslyn/tree/features/target-typing) | [In Progress](https://github.com/dotnet/roslyn/issues/43186) | [gafter](https://github.com/gafter) | [agocke](https://github.com/agocke), [RikkiGibson](https://github.com/RikkiGibson) | [gafter](https://github.com/gafter) |
| [Covariant](https://github.com/dotnet/csharplang/issues/49) [Returns](https://github.com/dotnet/csharplang/issues/2844) | [features/covariant-returns](https://github.com/dotnet/roslyn/tree/features/covariant-returns) | [In Progress](https://github.com/dotnet/roslyn/issues/43188) | [gafter](https://github.com/gafter) | TBD,TBD | [gafter](https://github.com/gafter) |
| [Covariant](https://github.com/dotnet/csharplang/issues/49) [Returns](https://github.com/dotnet/csharplang/issues/2844) | [features/covariant-returns](https://github.com/dotnet/roslyn/tree/features/covariant-returns) | [In Progress](https://github.com/dotnet/roslyn/issues/43188) | [gafter](https://github.com/gafter) | [AlekseyTs](https://github.com/AlekseyTs), [agocke](https://github.com/agocke) | [gafter](https://github.com/gafter) |
| [Extension GetEnumerator](https://github.com/dotnet/csharplang/issues/3194) | [features/extension-foreach](https://github.com/dotnet/roslyn/tree/features/extension-foreach) | [In Progress](https://github.com/dotnet/roslyn/issues/43184) | [YairHalberstadt](https://github.com/YairHalberstadt) | [333fred](https://github.com/333fred) | [333fred](https://github.com/333fred) |
| [Module initializers](https://github.com/RikkiGibson/csharplang/blob/module-initializers/proposals/module-initializers.md) | TBD | [In progress / design](https://github.com/dotnet/roslyn/issues/40500) | [RikkiGibson](https://github.com/RikkiGibson) [jnm2](https://github.com/jnm2)| [AlekseyTs](https://github.com/AlekseyTs) | [gafter](https://github.com/gafter) |
| [Extending Partial](https://github.com/jaredpar/csharplang/blob/partial/proposals/extending-partial-methods.md) | [features/partial-methods](https://github.com/dotnet/roslyn/tree/features/partial-methods) | In-Progress | [RikkiGibson](https://github.com/RikkiGibson) | [chsienki](https://github.com/chsienki) | [jaredpar](https://github.com/jaredpar) |
| [Top-level statements](https://github.com/dotnet/csharplang/blob/master/proposals/top-level-statements.md) | [features/SimplePrograms](https://github.com/dotnet/roslyn/tree/features/SimplePrograms) | [In-Progress](https://github.com/dotnet/roslyn/issues/43563) | [AlekseyTs](https://github.com/AlekseyTs) | [cston](https://github.com/cston), [RikkiGibson](https://github.com/RikkiGibson) | [MadsTorgersen](https://github.com/MadsTorgersen) |
# C# Next
| Feature | Branch | State | Developers | Reviewer | LDM Champ |
|----------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------|
| [Caller expression attribute](https://github.com/dotnet/csharplang/issues/287) | [caller-expression](https://github.com/dotnet/roslyn/tree/features/caller-expression) | Prototype | [alrz](https://github.com/alrz) | [jcouv](https://github.com/jcouv) | [jcouv](https://github.com/jcouv) |
| [Generic attributes](https://github.com/dotnet/csharplang/issues/124) | [generic-attributes](https://github.com/dotnet/roslyn/tree/features/generic-attributes) | [In Progress](https://github.com/dotnet/roslyn/issues/36285) | [AviAvni](https://github.com/AviAvni) | [agocke](https://github.com/agocke) | [mattwar](https://github.com/mattwar) |
| [Default in deconstruction](https://github.com/dotnet/roslyn/pull/25562) | [decon-default](https://github.com/dotnet/roslyn/tree/features/decon-default) | [Implemented](https://github.com/dotnet/roslyn/issues/25559) | [jcouv](https://github.com/jcouv) | [gafter](https://github.com/gafter) | [jcouv](https://github.com/jcouv) |
# C# 8.0
......
......@@ -186,13 +186,13 @@
<RoslynOptProfRunSettingsGeneratorVersion>1.0.0-beta3.19057.1</RoslynOptProfRunSettingsGeneratorVersion>
<RoslynMicrosoftVisualStudioExtensionManagerVersion>0.0.4</RoslynMicrosoftVisualStudioExtensionManagerVersion>
<SourceBrowserVersion>1.0.21</SourceBrowserVersion>
<SystemBuffersVersion>4.5.0</SystemBuffersVersion>
<SystemBuffersVersion>4.5.1</SystemBuffersVersion>
<SystemComponentModelCompositionVersion>4.5.0</SystemComponentModelCompositionVersion>
<SystemDrawingCommonVersion>4.5.0</SystemDrawingCommonVersion>
<SystemIOFileSystemVersion>4.3.0</SystemIOFileSystemVersion>
<SystemIOFileSystemPrimitivesVersion>4.3.0</SystemIOFileSystemPrimitivesVersion>
<SystemIOPipesAccessControlVersion>4.5.1</SystemIOPipesAccessControlVersion>
<SystemMemoryVersion>4.5.3</SystemMemoryVersion>
<SystemMemoryVersion>4.5.4</SystemMemoryVersion>
<SystemRuntimeCompilerServicesUnsafeVersion>4.7.0</SystemRuntimeCompilerServicesUnsafeVersion>
<SystemRuntimeLoaderVersion>4.3.0</SystemRuntimeLoaderVersion>
<SystemTextEncodingCodePagesVersion>4.5.1</SystemTextEncodingCodePagesVersion>
......
......@@ -874,6 +874,7 @@ private ImmutableArray<ParameterSymbol> BindCrefParameters(BaseCrefParameterList
{
RefKind refKind = parameter.RefKindKeyword.Kind().GetRefKind();
Debug.Assert(parameterListSyntax.Parent is object);
TypeSymbol type = BindCrefParameterOrReturnType(parameter.Type, (MemberCrefSyntax)parameterListSyntax.Parent, diagnostics);
parameterBuilder.Add(new SignatureOnlyParameterSymbol(TypeWithAnnotations.Create(type), ImmutableArray<CustomModifier>.Empty, isParams: false, refKind: refKind));
......@@ -909,6 +910,7 @@ private TypeSymbol BindCrefParameterOrReturnType(TypeSyntax typeSyntax, MemberCr
{
if (HasNonObsoleteError(unusedDiagnostics))
{
Debug.Assert(typeSyntax.Parent is object);
ErrorCode code = typeSyntax.Parent.Kind() == SyntaxKind.ConversionOperatorMemberCref
? ErrorCode.WRN_BadXMLRefReturnType
: ErrorCode.WRN_BadXMLRefParamType;
......@@ -950,7 +952,7 @@ private static bool HasNonObsoleteError(DiagnosticBag unusedDiagnostics)
private static CrefSyntax GetRootCrefSyntax(MemberCrefSyntax syntax)
{
SyntaxNode parentSyntax = syntax.Parent; // Could be null when speculating.
SyntaxNode? parentSyntax = syntax.Parent; // Could be null when speculating.
return parentSyntax == null || parentSyntax.IsKind(SyntaxKind.XmlCrefAttribute)
? syntax
: (CrefSyntax)parentSyntax;
......
......@@ -375,7 +375,7 @@ internal static IList<DirectiveTriviaSyntax> GetDirectives(this SyntaxNode node,
/// <summary>
/// Gets the first directive of the tree rooted by this node.
/// </summary>
public static DirectiveTriviaSyntax GetFirstDirective(this SyntaxNode node, Func<DirectiveTriviaSyntax, bool>? predicate = null)
public static DirectiveTriviaSyntax? GetFirstDirective(this SyntaxNode node, Func<DirectiveTriviaSyntax, bool>? predicate = null)
{
return ((CSharpSyntaxNode)node).GetFirstDirective(predicate);
}
......@@ -383,7 +383,7 @@ public static DirectiveTriviaSyntax GetFirstDirective(this SyntaxNode node, Func
/// <summary>
/// Gets the last directive of the tree rooted by this node.
/// </summary>
public static DirectiveTriviaSyntax GetLastDirective(this SyntaxNode node, Func<DirectiveTriviaSyntax, bool>? predicate = null)
public static DirectiveTriviaSyntax? GetLastDirective(this SyntaxNode node, Func<DirectiveTriviaSyntax, bool>? predicate = null)
{
return ((CSharpSyntaxNode)node).GetLastDirective(predicate);
}
......
......@@ -541,7 +541,8 @@ private void CompileNamedType(NamedTypeSymbol containingType)
case SymbolKind.Field:
{
FieldSymbol fieldSymbol = member as FieldSymbol;
var field = (FieldSymbol)member;
var fieldSymbol = (field.TupleUnderlyingField ?? field) as SourceMemberFieldSymbol;
if ((object)fieldSymbol != null)
{
if (fieldSymbol.IsConst)
......
......@@ -407,6 +407,7 @@ IEnumerable<Cci.IFieldDefinition> Cci.ITypeDefinition.GetFields(EmitContext cont
foreach (var f in GetFieldsToEmit())
{
Debug.Assert((object)(f.TupleUnderlyingField ?? f) == f);
if (isStruct || f.ShouldInclude(context))
{
yield return f;
......
......@@ -271,19 +271,26 @@ internal sealed override IEnumerable<Cci.INestedTypeDefinition> GetSynthesizedNe
break;
case SymbolKind.Property:
AddSymbolLocation(result, member);
break;
case SymbolKind.Field:
// NOTE: Dev11 does not add synthesized backing fields for properties,
// but adds backing fields for events, Roslyn adds both
AddSymbolLocation(result, member);
{
var field = (FieldSymbol)member;
AddSymbolLocation(result, field.TupleUnderlyingField ?? field);
}
break;
case SymbolKind.Event:
AddSymbolLocation(result, member);
// event backing fields do not show up in GetMembers
FieldSymbol field = ((EventSymbol)member).AssociatedField;
if ((object)field != null)
{
AddSymbolLocation(result, field);
FieldSymbol field = ((EventSymbol)member).AssociatedField;
if ((object)field != null)
{
AddSymbolLocation(result, field.TupleUnderlyingField ?? field);
}
}
break;
......@@ -1003,7 +1010,7 @@ internal static Cci.IGenericParameterReference Translate(TypeParameterSymbol par
bool needDeclaration = false)
{
Debug.Assert(fieldSymbol.IsDefinitionOrDistinct());
Debug.Assert(!fieldSymbol.IsVirtualTupleField, "virtual tuple fields should be rewritten to underlying by now");
Debug.Assert(!fieldSymbol.IsVirtualTupleField && (object)(fieldSymbol.TupleUnderlyingField ?? fieldSymbol) == fieldSymbol, "tuple fields should be rewritten to underlying by now");
if (!fieldSymbol.IsDefinition)
{
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
namespace Microsoft.CodeAnalysis.CSharp
{
public class CSharpDiagnosticFormatter : DiagnosticFormatter
......
......@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.Syntax.InternalSyntax;
using Roslyn.Utilities;
......@@ -61,6 +61,7 @@ public override BoundStatement InstrumentExpressionStatement(BoundExpressionStat
case SyntaxKind.BaseConstructorInitializer:
case SyntaxKind.ThisConstructorInitializer:
var init = (ConstructorInitializerSyntax)original.Syntax;
Debug.Assert(init.Parent is object);
return new BoundSequencePointWithSpan(init, rewritten, CreateSpanForConstructorInitializer((ConstructorDeclarationSyntax)init.Parent));
}
}
......
......@@ -552,7 +552,8 @@ private void LowerWhenClause(BoundWhenDecisionDagNode whenClause)
LabelSymbol labelToSectionScope = GetDagNodeLabel(whenClause);
// We need the section syntax to get the section builder from the map. Unfortunately this is a bit awkward
SyntaxNode sectionSyntax = whenClause.Syntax is SwitchLabelSyntax l ? l.Parent : whenClause.Syntax;
SyntaxNode? sectionSyntax = whenClause.Syntax is SwitchLabelSyntax l ? l.Parent : whenClause.Syntax;
Debug.Assert(sectionSyntax is { });
bool foundSectionBuilder = _switchArms.TryGetValue(sectionSyntax, out ArrayBuilder<BoundStatement>? sectionBuilder);
Debug.Assert(foundSectionBuilder && sectionBuilder is { });
sectionBuilder.Add(_factory.Label(labelToSectionScope));
......
......@@ -878,7 +878,7 @@ internal override IEnumerable<FieldSymbol> GetFieldsToEmit()
else
{
// If there are any non-event fields, they are at the very beginning.
IEnumerable<FieldSymbol> nonEventFields = GetMembers<FieldSymbol>(this.GetMembers(), SymbolKind.Field, offset: 0);
IEnumerable<FieldSymbol> nonEventFields = GetMembers<FieldSymbol>(this.GetMembers(), SymbolKind.Field, offset: 0).Select(f => f.TupleUnderlyingField ?? f);
// Event backing fields are not part of the set returned by GetMembers. Let's add them manually.
ArrayBuilder<FieldSymbol> eventFields = null;
......@@ -889,6 +889,9 @@ internal override IEnumerable<FieldSymbol> GetFieldsToEmit()
if ((object)associatedField != null)
{
Debug.Assert((object)associatedField.AssociatedSymbol != null);
associatedField = associatedField.TupleUnderlyingField ?? associatedField;
Debug.Assert(!nonEventFields.Contains(associatedField));
if (eventFields == null)
......
......@@ -140,6 +140,7 @@ internal SyntaxList<AttributeListSyntax> AttributeDeclarationSyntaxList
case SyntaxKind.EventDeclaration:
return ((EventDeclarationSyntax)syntax).AttributeLists;
case SyntaxKind.VariableDeclarator:
Debug.Assert(syntax.Parent!.Parent is object);
return ((EventFieldDeclarationSyntax)syntax.Parent.Parent).AttributeLists;
default:
throw ExceptionUtilities.UnexpectedValue(syntax.Kind());
......@@ -147,7 +148,7 @@ internal SyntaxList<AttributeListSyntax> AttributeDeclarationSyntaxList
}
}
return default(SyntaxList<AttributeListSyntax>);
return default;
}
}
......@@ -597,7 +598,7 @@ protected void CheckModifiersAndType(DiagnosticBag diagnostics)
diagnostics.Add(location, useSiteDiagnostics);
}
public override string GetDocumentationCommentXml(CultureInfo? preferredCulture = null, bool expandIncludes = false, CancellationToken cancellationToken = default(CancellationToken))
public override string GetDocumentationCommentXml(CultureInfo? preferredCulture = null, bool expandIncludes = false, CancellationToken cancellationToken = default)
{
ref var lazyDocComment = ref expandIncludes ? ref _lazyExpandedDocComment : ref _lazyDocComment;
return SourceDocumentationCommentUtils.GetAndCacheDocumentationComment(this, expandIncludes, ref lazyDocComment);
......
......@@ -30,6 +30,8 @@ internal SourceFieldLikeEventSymbol(SourceMemberContainerTypeSymbol containingTy
: base(containingType, declaratorSyntax, modifiers, isFieldLike: true, interfaceSpecifierSyntaxOpt: null,
nameTokenSyntax: declaratorSyntax.Identifier, diagnostics: diagnostics)
{
Debug.Assert(declaratorSyntax.Parent is object);
_name = declaratorSyntax.Identifier.ValueText;
var declaratorDiagnostics = DiagnosticBag.GetInstance();
......
......@@ -1279,13 +1279,14 @@ internal override IEnumerable<FieldSymbol> GetFieldsToEmit()
switch (m.Kind)
{
case SymbolKind.Field:
yield return (FieldSymbol)m;
var field = (FieldSymbol)m;
yield return field.TupleUnderlyingField ?? field;
break;
case SymbolKind.Event:
FieldSymbol associatedField = ((EventSymbol)m).AssociatedField;
if ((object)associatedField != null)
{
yield return associatedField;
yield return associatedField.TupleUnderlyingField ?? associatedField;
}
break;
}
......
......@@ -44,7 +44,7 @@ protected SourceMethodSymbolWithAttributes(SyntaxReference syntaxReferenceOpt)
case AccessorDeclarationSyntax accessor:
return (CSharpSyntaxNode?)accessor.Body ?? accessor.ExpressionBody;
case ArrowExpressionClauseSyntax arrowExpression:
Debug.Assert(arrowExpression.Parent.Kind() == SyntaxKind.PropertyDeclaration ||
Debug.Assert(arrowExpression.Parent!.Kind() == SyntaxKind.PropertyDeclaration ||
arrowExpression.Parent.Kind() == SyntaxKind.IndexerDeclaration);
return arrowExpression;
case LocalFunctionStatementSyntax localFunction:
......
......@@ -2,13 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects;
......@@ -26,7 +26,7 @@ namespace Microsoft.CodeAnalysis.CSharp
//deferral can result in meaningful savings of strings.
public abstract partial class CSharpSyntaxNode : SyntaxNode, IFormattable
{
internal CSharpSyntaxNode(GreenNode green, SyntaxNode parent, int position)
internal CSharpSyntaxNode(GreenNode green, SyntaxNode? parent, int position)
: base(green, parent, position)
{
}
......@@ -58,8 +58,8 @@ internal new SyntaxTree SyntaxTree
private static SyntaxTree ComputeSyntaxTree(CSharpSyntaxNode node)
{
ArrayBuilder<CSharpSyntaxNode> nodes = null;
SyntaxTree tree = null;
ArrayBuilder<CSharpSyntaxNode>? nodes = null;
SyntaxTree? tree = null;
// Find the nearest parent with a non-null syntax tree
while (true)
......@@ -121,19 +121,19 @@ private static SyntaxTree ComputeSyntaxTree(CSharpSyntaxNode node)
/// <summary>
/// The node that contains this node in its Children collection.
/// </summary>
internal new CSharpSyntaxNode Parent
internal new CSharpSyntaxNode? Parent
{
get
{
return (CSharpSyntaxNode)base.Parent;
return (CSharpSyntaxNode?)base.Parent;
}
}
internal new CSharpSyntaxNode ParentOrStructuredTriviaParent
internal new CSharpSyntaxNode? ParentOrStructuredTriviaParent
{
get
{
return (CSharpSyntaxNode)base.ParentOrStructuredTriviaParent;
return (CSharpSyntaxNode?)base.ParentOrStructuredTriviaParent;
}
}
......@@ -237,7 +237,7 @@ public new IEnumerable<Diagnostic> GetDiagnostics()
#region Directives
internal IList<DirectiveTriviaSyntax> GetDirectives(Func<DirectiveTriviaSyntax, bool> filter = null)
internal IList<DirectiveTriviaSyntax> GetDirectives(Func<DirectiveTriviaSyntax, bool>? filter = null)
{
return ((SyntaxNodeOrToken)this).GetDirectives<DirectiveTriviaSyntax>(filter);
}
......@@ -245,15 +245,15 @@ internal IList<DirectiveTriviaSyntax> GetDirectives(Func<DirectiveTriviaSyntax,
/// <summary>
/// Gets the first directive of the tree rooted by this node.
/// </summary>
public DirectiveTriviaSyntax GetFirstDirective(Func<DirectiveTriviaSyntax, bool> predicate = null)
public DirectiveTriviaSyntax? GetFirstDirective(Func<DirectiveTriviaSyntax, bool>? predicate = null)
{
foreach (var child in this.ChildNodesAndTokens())
{
if (child.ContainsDirectives)
{
if (child.IsNode)
if (child.AsNode(out var node))
{
var d = child.AsNode().GetFirstDirective(predicate);
var d = node.GetFirstDirective(predicate);
if (d != null)
{
return d;
......@@ -268,7 +268,7 @@ public DirectiveTriviaSyntax GetFirstDirective(Func<DirectiveTriviaSyntax, bool>
{
if (tr.IsDirective)
{
var d = (DirectiveTriviaSyntax)tr.GetStructure();
var d = (DirectiveTriviaSyntax)tr.GetStructure()!;
if (predicate == null || predicate(d))
{
return d;
......@@ -285,15 +285,15 @@ public DirectiveTriviaSyntax GetFirstDirective(Func<DirectiveTriviaSyntax, bool>
/// <summary>
/// Gets the last directive of the tree rooted by this node.
/// </summary>
public DirectiveTriviaSyntax GetLastDirective(Func<DirectiveTriviaSyntax, bool> predicate = null)
public DirectiveTriviaSyntax? GetLastDirective(Func<DirectiveTriviaSyntax, bool>? predicate = null)
{
foreach (var child in this.ChildNodesAndTokens().Reverse())
{
if (child.ContainsDirectives)
{
if (child.IsNode)
if (child.AsNode(out var node))
{
var d = child.AsNode().GetLastDirective(predicate);
var d = node.GetLastDirective(predicate);
if (d != null)
{
return d;
......@@ -308,7 +308,7 @@ public DirectiveTriviaSyntax GetLastDirective(Func<DirectiveTriviaSyntax, bool>
{
if (tr.IsDirective)
{
var d = (DirectiveTriviaSyntax)tr.GetStructure();
var d = (DirectiveTriviaSyntax)tr.GetStructure()!;
if (predicate == null || predicate(d))
{
return d;
......@@ -349,7 +349,7 @@ public new SyntaxToken GetFirstToken(bool includeZeroWidth = false, bool include
/// <param name="stepInto">Steps into trivia if this is not null. Only trivia for which this delegate returns
/// true are included.</param>
/// <returns></returns>
internal SyntaxToken GetFirstToken(Func<SyntaxToken, bool> predicate, Func<SyntaxTrivia, bool> stepInto = null)
internal SyntaxToken GetFirstToken(Func<SyntaxToken, bool>? predicate, Func<SyntaxTrivia, bool>? stepInto = null)
{
return SyntaxNavigator.Instance.GetFirstToken(this, predicate, stepInto);
}
......@@ -406,12 +406,12 @@ internal SyntaxToken FindTokenIncludingCrefAndNameAttributes(int position)
}
Debug.Assert(trivia.HasStructure);
SyntaxToken triviaToken = ((CSharpSyntaxNode)trivia.GetStructure()).FindTokenInternal(position);
SyntaxToken triviaToken = ((CSharpSyntaxNode)trivia.GetStructure()!).FindTokenInternal(position);
// CONSIDER: We might want to use the trivia token anywhere within a doc comment.
// Otherwise, we'll fall back on the enclosing scope outside of name and cref
// attribute values.
CSharpSyntaxNode curr = (CSharpSyntaxNode)triviaToken.Parent;
CSharpSyntaxNode? curr = (CSharpSyntaxNode?)triviaToken.Parent;
while (curr != null)
{
// Don't return a trivia token unless we're in the scope of a cref or name attribute.
......@@ -480,12 +480,12 @@ protected override SyntaxTree SyntaxTreeCore
}
protected internal override SyntaxNode ReplaceCore<TNode>(
IEnumerable<TNode> nodes = null,
Func<TNode, TNode, SyntaxNode> computeReplacementNode = null,
IEnumerable<SyntaxToken> tokens = null,
Func<SyntaxToken, SyntaxToken, SyntaxToken> computeReplacementToken = null,
IEnumerable<SyntaxTrivia> trivia = null,
Func<SyntaxTrivia, SyntaxTrivia, SyntaxTrivia> computeReplacementTrivia = null)
IEnumerable<TNode>? nodes = null,
Func<TNode, TNode, SyntaxNode>? computeReplacementNode = null,
IEnumerable<SyntaxToken>? tokens = null,
Func<SyntaxToken, SyntaxToken, SyntaxToken>? computeReplacementToken = null,
IEnumerable<SyntaxTrivia>? trivia = null,
Func<SyntaxTrivia, SyntaxTrivia, SyntaxTrivia>? computeReplacementTrivia = null)
{
return SyntaxReplacer.Replace(this, nodes, computeReplacementNode, tokens, computeReplacementToken, trivia, computeReplacementTrivia).AsRootOfNewTreeWithOptionsFrom(this.SyntaxTree);
}
......@@ -551,7 +551,7 @@ internal override bool ShouldCreateWeakList()
#endregion
string IFormattable.ToString(string format, IFormatProvider formatProvider)
string IFormattable.ToString(string? format, IFormatProvider? formatProvider)
{
return ToString();
}
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Syntax;
......@@ -13,9 +15,7 @@ namespace Microsoft.CodeAnalysis.CSharp
/// Represents a <see cref="CSharpSyntaxVisitor{TResult}"/> which descends an entire <see cref="CSharpSyntaxNode"/> graph and
/// may replace or remove visited SyntaxNodes in depth-first order.
/// </summary>
#nullable enable
public abstract partial class CSharpSyntaxRewriter : CSharpSyntaxVisitor<SyntaxNode?>
#nullable restore
{
private readonly bool _visitIntoStructuredTrivia;
......@@ -31,7 +31,7 @@ public virtual bool VisitIntoStructuredTrivia
private int _recursionDepth;
public override SyntaxNode Visit(SyntaxNode node)
public override SyntaxNode? Visit(SyntaxNode? node)
{
if (node != null)
{
......@@ -118,7 +118,7 @@ public virtual SyntaxTrivia VisitTrivia(SyntaxTrivia trivia)
if (this.VisitIntoStructuredTrivia && trivia.HasStructure)
{
var structure = (CSharpSyntaxNode)trivia.GetStructure()!;
var newStructure = (StructuredTriviaSyntax)this.Visit(structure);
var newStructure = (StructuredTriviaSyntax?)this.Visit(structure);
if (newStructure != structure)
{
if (newStructure != null)
......@@ -137,7 +137,7 @@ public virtual SyntaxTrivia VisitTrivia(SyntaxTrivia trivia)
public virtual SyntaxList<TNode> VisitList<TNode>(SyntaxList<TNode> list) where TNode : SyntaxNode
{
SyntaxListBuilder alternate = null;
SyntaxListBuilder? alternate = null;
for (int i = 0, n = list.Count; i < n; i++)
{
var item = list[i];
......@@ -162,9 +162,9 @@ public virtual SyntaxTrivia VisitTrivia(SyntaxTrivia trivia)
return list;
}
public virtual TNode VisitListElement<TNode>(TNode node) where TNode : SyntaxNode
public virtual TNode? VisitListElement<TNode>(TNode? node) where TNode : SyntaxNode
{
return (TNode)this.Visit(node);
return (TNode?)this.Visit(node);
}
public virtual SeparatedSyntaxList<TNode> VisitList<TNode>(SeparatedSyntaxList<TNode> list) where TNode : SyntaxNode
......@@ -249,7 +249,7 @@ public virtual SyntaxToken VisitListSeparator(SyntaxToken separator)
public virtual SyntaxTokenList VisitList(SyntaxTokenList list)
{
SyntaxTokenListBuilder alternate = null;
SyntaxTokenListBuilder? alternate = null;
var count = list.Count;
var index = -1;
......@@ -282,7 +282,7 @@ public virtual SyntaxTriviaList VisitList(SyntaxTriviaList list)
var count = list.Count;
if (count != 0)
{
SyntaxTriviaListBuilder alternate = null;
SyntaxTriviaListBuilder? alternate = null;
var index = -1;
foreach (var item in list)
......
......@@ -2,10 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
#nullable enable
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.CodeAnalysis.CSharp
{
......@@ -19,7 +18,8 @@ namespace Microsoft.CodeAnalysis.CSharp
/// </typeparam>
public abstract partial class CSharpSyntaxVisitor<TResult>
{
public virtual TResult Visit(SyntaxNode node)
[return: MaybeNull]
public virtual TResult Visit(SyntaxNode? node)
{
if (node != null)
{
......@@ -27,12 +27,13 @@ public virtual TResult Visit(SyntaxNode node)
}
// should not come here too often so we will put this at the end of the method.
return default(TResult);
return default;
}
[return: MaybeNull]
public virtual TResult DefaultVisit(SyntaxNode node)
{
return default(TResult);
return default;
}
}
......@@ -42,7 +43,7 @@ public virtual TResult DefaultVisit(SyntaxNode node)
/// </summary>
public abstract partial class CSharpSyntaxVisitor
{
public virtual void Visit(SyntaxNode node)
public virtual void Visit(SyntaxNode? node)
{
if (node != null)
{
......
......@@ -129,6 +129,7 @@ public static SyntaxTriviaList ToSyntaxTriviaList(this IEnumerable<SyntaxTrivia>
internal static XmlNameAttributeElementKind GetElementKind(this XmlNameAttributeSyntax attributeSyntax)
{
Debug.Assert(attributeSyntax.Parent is object);
CSharpSyntaxNode parentSyntax = attributeSyntax.Parent;
SyntaxKind parentKind = parentSyntax.Kind();
......
......@@ -2114,7 +2114,7 @@ public static ExpressionSyntax GetStandaloneExpression(ExpressionSyntax expressi
return node;
}
CSharpSyntaxNode parent = node.Parent;
CSharpSyntaxNode? parent = node.Parent;
if (parent == null)
{
......@@ -2161,7 +2161,7 @@ public static ExpressionSyntax GetStandaloneExpression(ExpressionSyntax expressi
case SyntaxKind.NameMemberCref:
if (((NameMemberCrefSyntax)parent).Name == node)
{
CSharpSyntaxNode grandparent = parent.Parent;
CSharpSyntaxNode? grandparent = parent.Parent;
return grandparent != null && grandparent.Kind() == SyntaxKind.QualifiedCref
? grandparent
: parent;
......
......@@ -26462,6 +26462,7 @@ void verifyTupleTypeWithErrorUnderlyingType(CSharpCompilation compilation, bool
[Fact]
[WorkItem(41207, "https://github.com/dotnet/roslyn/issues/41207")]
[WorkItem(1056281, "https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1056281")]
[WorkItem(43549, "https://github.com/dotnet/roslyn/issues/43549")]
public void CustomFields_01()
{
var source0 = @"
......@@ -26508,25 +26509,44 @@ public static void Main()
}
";
var comp1 = CreateCompilation(source0 + source1, targetFramework: TargetFramework.Mscorlib46, options: TestOptions.DebugExe);
var comp1 = CreateCompilation(source0 + source1, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe);
CompileAndVerify(comp1, expectedOutput: "123");
verifyField(comp1);
var comp1Ref = new[] { comp1.ToMetadataReference() };
var comp1ImageRef = new[] { comp1.EmitToImageReference() };
var comp4 = CreateCompilation(source0 + source2, targetFramework: TargetFramework.Mscorlib46, options: TestOptions.DebugExe);
var comp4 = CreateCompilation(source0 + source2, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe);
CompileAndVerify(comp4, expectedOutput: "123");
var comp5 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib46, options: TestOptions.DebugExe, references: comp1Ref);
var comp5 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe, references: comp1Ref);
CompileAndVerify(comp5, expectedOutput: "123");
verifyField(comp5);
var comp6 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib46, options: TestOptions.DebugExe, references: comp1ImageRef);
var comp6 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe, references: comp1ImageRef);
CompileAndVerify(comp6, expectedOutput: "123");
verifyField(comp6);
// Uncomment after https://github.com/dotnet/roslyn/issues/43549 is fixed.
//var comp7 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib46, options: TestOptions.DebugExe, references: comp1Ref);
//CompileAndVerify(comp7, expectedOutput: "123");
//verifyField(comp7);
void verifyField(CSharpCompilation comp)
{
var field = comp.GetMember<FieldSymbol>("System.ValueTuple.F1");
Assert.NotNull(field.TupleUnderlyingField);
Assert.NotSame(field, field.TupleUnderlyingField);
var toEmit = field.ContainingType.GetFieldsToEmit().Where(f => f.Name == "F1").Single();
Assert.Same(toEmit, toEmit.TupleUnderlyingField);
Assert.Same(field.TupleUnderlyingField, toEmit);
}
}
[Fact]
[WorkItem(41207, "https://github.com/dotnet/roslyn/issues/41207")]
[WorkItem(1056281, "https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1056281")]
[WorkItem(43549, "https://github.com/dotnet/roslyn/issues/43549")]
public void CustomFields_02()
{
var source0 = @"
......@@ -26574,20 +26594,224 @@ public static void Main()
}
";
var comp1 = CreateCompilation(source0 + source1, targetFramework: TargetFramework.Mscorlib46, options: TestOptions.DebugExe);
var comp1 = CreateCompilation(source0 + source1, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe);
CompileAndVerify(comp1, expectedOutput: "123");
verifyField(comp1);
var comp1Ref = new[] { comp1.ToMetadataReference() };
var comp1ImageRef = new[] { comp1.EmitToImageReference() };
var comp4 = CreateCompilation(source0 + source2, targetFramework: TargetFramework.Mscorlib46, options: TestOptions.DebugExe);
var comp4 = CreateCompilation(source0 + source2, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe);
CompileAndVerify(comp4, expectedOutput: "123");
var comp5 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib46, options: TestOptions.DebugExe, references: comp1Ref);
var comp5 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe, references: comp1Ref);
CompileAndVerify(comp5, expectedOutput: "123");
verifyField(comp5);
var comp6 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib46, options: TestOptions.DebugExe, references: comp1ImageRef);
var comp6 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe, references: comp1ImageRef);
CompileAndVerify(comp6, expectedOutput: "123");
verifyField(comp6);
// Uncomment after https://github.com/dotnet/roslyn/issues/43549 is fixed.
//var comp7 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib46, options: TestOptions.DebugExe, references: comp1Ref);
//CompileAndVerify(comp7, expectedOutput: "123");
//verifyField(comp7);
void verifyField(CSharpCompilation comp)
{
var field = comp.GetMember<FieldSymbol>("System.ValueTuple.F1");
Assert.NotNull(field.TupleUnderlyingField);
Assert.NotSame(field, field.TupleUnderlyingField);
var toEmit = field.ContainingType.GetFieldsToEmit().Where(f => f.Name == "F1").Single();
Assert.Same(toEmit, toEmit.TupleUnderlyingField);
Assert.Same(field.TupleUnderlyingField, toEmit);
}
}
[Fact]
[WorkItem(43524, "https://github.com/dotnet/roslyn/issues/43524")]
[WorkItem(1095184, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1095184")]
[WorkItem(43549, "https://github.com/dotnet/roslyn/issues/43549")]
public void CustomFields_03()
{
var source0 = @"
namespace System
{
public struct ValueTuple
{
public static readonly int F1 = 4;
public static int CombineHashCodes(int h1, int h2)
{
return F1 + h1 + h2;
}
}
}
";
var source1 = @"
class Program
{
static void Main()
{
System.Console.WriteLine(System.ValueTuple.CombineHashCodes(2, 3));
}
}
";
var source2 = @"
class Program
{
public static void Main()
{
System.Console.WriteLine(System.ValueTuple.F1 + 2 + 3);
}
}
";
var comp1 = CreateCompilation(source0 + source1, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe);
CompileAndVerify(comp1, expectedOutput: "9");
verifyField(comp1);
var comp1Ref = new[] { comp1.ToMetadataReference() };
var comp1ImageRef = new[] { comp1.EmitToImageReference() };
var comp4 = CreateCompilation(source0 + source2, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe);
CompileAndVerify(comp4, expectedOutput: "9");
var comp5 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe, references: comp1Ref);
CompileAndVerify(comp5, expectedOutput: "9");
verifyField(comp5);
var comp6 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe, references: comp1ImageRef);
CompileAndVerify(comp6, expectedOutput: "9");
verifyField(comp6);
// Uncomment after https://github.com/dotnet/roslyn/issues/43549 is fixed.
//var comp7 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib46, options: TestOptions.DebugExe, references: comp1Ref);
//CompileAndVerify(comp7, expectedOutput: "9");
//verifyField(comp7);
void verifyField(CSharpCompilation comp)
{
var field = comp.GetMember<FieldSymbol>("System.ValueTuple.F1");
Assert.NotNull(field.TupleUnderlyingField);
Assert.NotSame(field, field.TupleUnderlyingField);
var toEmit = field.ContainingType.GetFieldsToEmit().Single();
Assert.Same(toEmit, toEmit.TupleUnderlyingField);
Assert.Same(field.TupleUnderlyingField, toEmit);
}
}
[Fact]
[WorkItem(43524, "https://github.com/dotnet/roslyn/issues/43524")]
[WorkItem(1095184, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1095184")]
[WorkItem(43549, "https://github.com/dotnet/roslyn/issues/43549")]
public void CustomFields_04()
{
var source0 = @"
namespace System
{
public struct ValueTuple
{
public int F1;
public int CombineHashCodes(int h1, int h2)
{
return F1 + h1 + h2;
}
}
}
";
var source1 = @"
class Program
{
static void Main()
{
System.ValueTuple tuple = default;
tuple.F1 = 4;
System.Console.WriteLine(tuple.CombineHashCodes(2, 3));
}
}
";
var source2 = @"
class Program
{
public static void Main()
{
System.ValueTuple tuple = default;
tuple.F1 = 4;
System.Console.WriteLine(tuple.F1 + 2 + 3);
}
}
";
var comp1 = CreateCompilation(source0 + source1, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe);
CompileAndVerify(comp1, expectedOutput: "9");
verifyField(comp1);
var comp1Ref = new[] { comp1.ToMetadataReference() };
var comp1ImageRef = new[] { comp1.EmitToImageReference() };
var comp4 = CreateCompilation(source0 + source2, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe);
CompileAndVerify(comp4, expectedOutput: "9");
var comp5 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe, references: comp1Ref);
CompileAndVerify(comp5, expectedOutput: "9");
verifyField(comp5);
var comp6 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib40, options: TestOptions.DebugExe, references: comp1ImageRef);
CompileAndVerify(comp6, expectedOutput: "9");
verifyField(comp6);
// Uncomment after https://github.com/dotnet/roslyn/issues/43549 is fixed.
//var comp7 = CreateCompilation(source2, targetFramework: TargetFramework.Mscorlib46, options: TestOptions.DebugExe, references: comp1Ref);
//CompileAndVerify(comp7, expectedOutput: "9");
//verifyField(comp7);
void verifyField(CSharpCompilation comp)
{
var field = comp.GetMember<FieldSymbol>("System.ValueTuple.F1");
Assert.NotNull(field.TupleUnderlyingField);
Assert.NotSame(field, field.TupleUnderlyingField);
var toEmit = field.ContainingType.GetFieldsToEmit().Single();
Assert.Same(toEmit, toEmit.TupleUnderlyingField);
Assert.Same(field.TupleUnderlyingField, toEmit);
}
}
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/43621")]
[WorkItem(43621, "https://github.com/dotnet/roslyn/issues/43621")]
public void CustomFields_05()
{
var source0 = @"
using System;
namespace System
{
public class C
{
public unsafe static void Main()
{
var s = new ValueTuple();
int* p = s.MessageType;
s.MessageType[0] = 12;
p[1] = p[0];
Console.WriteLine(s.MessageType[1]);
}
}
public unsafe struct ValueTuple
{
public fixed int MessageType[50];
}
}
";
var comp1 = CreateCompilation(source0, options: TestOptions.DebugExe.WithAllowUnsafe(true));
CompileAndVerify(comp1, expectedOutput: "12");
}
[Fact]
......@@ -27087,5 +27311,32 @@ .maxstack 7
}
");
}
[Fact]
[WorkItem(24517, "https://github.com/dotnet/roslyn/issues/24517")]
public void Issue24517()
{
var source = @"
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
class C
{
static void Main()
{
Expression<Func<ValueTuple<int, int>>> e1 = () => new ValueTuple<int, int>(1, 2);
Expression<Func<KeyValuePair<int, int>>> e2 = () => new KeyValuePair<int, int>(1, 2);
e1.Compile()();
e2.Compile()();
Console.WriteLine(""Done."");
}
}";
var comp = CreateCompilation(
source,
options: TestOptions.ReleaseExe);
CompileAndVerify(comp, expectedOutput: @"Done.");
}
}
}
......@@ -158,13 +158,14 @@ public async Task DequeueAfterCompleteWithData()
}
[Fact]
public void DequeueAsyncWithCancellation()
public async Task DequeueAsyncWithCancellation()
{
var queue = new AsyncQueue<int>();
var cts = new CancellationTokenSource();
var task = queue.DequeueAsync(cts.Token);
Assert.False(task.IsCanceled);
cts.Cancel();
await Assert.ThrowsAsync<TaskCanceledException>(() => task);
Assert.Equal(TaskStatus.Canceled, task.Status);
}
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
......@@ -21,13 +23,13 @@ namespace Microsoft.CodeAnalysis.Diagnostics
internal sealed class AnalysisResultBuilder
{
private readonly object _gate = new object();
private readonly Dictionary<DiagnosticAnalyzer, TimeSpan> _analyzerExecutionTimeOpt;
private readonly Dictionary<DiagnosticAnalyzer, TimeSpan>? _analyzerExecutionTimeOpt;
private readonly HashSet<DiagnosticAnalyzer> _completedAnalyzers;
private readonly Dictionary<DiagnosticAnalyzer, AnalyzerActionCounts> _analyzerActionCounts;
private Dictionary<SyntaxTree, Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>> _localSemanticDiagnosticsOpt = null;
private Dictionary<SyntaxTree, Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>> _localSyntaxDiagnosticsOpt = null;
private Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder> _nonLocalDiagnosticsOpt = null;
private Dictionary<SyntaxTree, Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>>? _localSemanticDiagnosticsOpt = null;
private Dictionary<SyntaxTree, Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>>? _localSyntaxDiagnosticsOpt = null;
private Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>? _nonLocalDiagnosticsOpt = null;
internal AnalysisResultBuilder(bool logAnalyzerExecutionTime, ImmutableArray<DiagnosticAnalyzer> analyzers)
{
......@@ -41,7 +43,7 @@ internal AnalysisResultBuilder(bool logAnalyzerExecutionTime, ImmutableArray<Dia
var map = new Dictionary<DiagnosticAnalyzer, TimeSpan>(analyzers.Length);
foreach (var analyzer in analyzers)
{
map[analyzer] = default(TimeSpan);
map[analyzer] = default;
}
return map;
......@@ -61,7 +63,7 @@ internal ImmutableArray<DiagnosticAnalyzer> GetPendingAnalyzers(ImmutableArray<D
{
lock (_gate)
{
ArrayBuilder<DiagnosticAnalyzer> builder = null;
ArrayBuilder<DiagnosticAnalyzer>? builder = null;
foreach (var analyzer in analyzers)
{
if (!_completedAnalyzers.Contains(analyzer))
......@@ -126,7 +128,7 @@ internal void ApplySuppressionsAndStoreAnalysisResult(AnalysisScope analysisScop
DiagnosticAnalyzer analyzer,
ImmutableArray<Diagnostic> diagnostics,
bool overwrite,
ref Dictionary<SyntaxTree, Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>> lazyLocalDiagnostics)
ref Dictionary<SyntaxTree, Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>>? lazyLocalDiagnostics)
{
if (diagnostics.IsEmpty)
{
......@@ -138,15 +140,16 @@ internal void ApplySuppressionsAndStoreAnalysisResult(AnalysisScope analysisScop
foreach (var diagsByTree in diagnostics.GroupBy(d => d.Location.SourceTree))
{
var tree = diagsByTree.Key;
Debug.Assert(tree is object);
Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder> allDiagnostics;
Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>? allDiagnostics;
if (!lazyLocalDiagnostics.TryGetValue(tree, out allDiagnostics))
{
allDiagnostics = new Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>();
lazyLocalDiagnostics[tree] = allDiagnostics;
}
ImmutableArray<Diagnostic>.Builder analyzerDiagnostics;
ImmutableArray<Diagnostic>.Builder? analyzerDiagnostics;
if (!allDiagnostics.TryGetValue(analyzer, out analyzerDiagnostics))
{
analyzerDiagnostics = ImmutableArray.CreateBuilder<Diagnostic>();
......@@ -171,7 +174,7 @@ private void UpdateNonLocalDiagnostics_NoLock(DiagnosticAnalyzer analyzer, Immut
_nonLocalDiagnosticsOpt = _nonLocalDiagnosticsOpt ?? new Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>();
ImmutableArray<Diagnostic>.Builder currentDiagnostics;
ImmutableArray<Diagnostic>.Builder? currentDiagnostics;
if (!_nonLocalDiagnosticsOpt.TryGetValue(analyzer, out currentDiagnostics))
{
currentDiagnostics = ImmutableArray.CreateBuilder<Diagnostic>();
......@@ -225,7 +228,7 @@ private ImmutableArray<Diagnostic> GetDiagnostics_NoLock(AnalysisScope analysisS
}
private static void AddAllLocalDiagnostics_NoLock(
Dictionary<SyntaxTree, Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>> localDiagnostics,
Dictionary<SyntaxTree, Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>>? localDiagnostics,
AnalysisScope analysisScope,
ImmutableArray<Diagnostic>.Builder builder)
{
......@@ -239,11 +242,11 @@ private ImmutableArray<Diagnostic> GetDiagnostics_NoLock(AnalysisScope analysisS
}
private static void AddLocalDiagnosticsForPartialAnalysis_NoLock(
Dictionary<SyntaxTree, Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>> localDiagnostics,
Dictionary<SyntaxTree, Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>>? localDiagnostics,
AnalysisScope analysisScope,
ImmutableArray<Diagnostic>.Builder builder)
{
Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder> diagnosticsForTree;
Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>? diagnosticsForTree;
if (localDiagnostics != null && localDiagnostics.TryGetValue(analysisScope.FilterTreeOpt, out diagnosticsForTree))
{
AddDiagnostics_NoLock(diagnosticsForTree, analysisScope, builder);
......@@ -259,7 +262,7 @@ private ImmutableArray<Diagnostic> GetDiagnostics_NoLock(AnalysisScope analysisS
foreach (var analyzer in analysisScope.Analyzers)
{
ImmutableArray<Diagnostic>.Builder diagnosticsByAnalyzer;
ImmutableArray<Diagnostic>.Builder? diagnosticsByAnalyzer;
if (diagnostics.TryGetValue(analyzer, out diagnosticsByAnalyzer))
{
builder.AddRange(diagnosticsByAnalyzer);
......@@ -284,13 +287,13 @@ internal AnalysisResult ToAnalysisResult(ImmutableArray<DiagnosticAnalyzer> anal
}
cancellationToken.ThrowIfCancellationRequested();
var analyzerTelemetryInfo = GetTelemetryInfo(analyzers, cancellationToken);
var analyzerTelemetryInfo = GetTelemetryInfo(analyzers);
return new AnalysisResult(analyzers, localSyntaxDiagnostics, localSemanticDiagnostics, nonLocalDiagnostics, analyzerTelemetryInfo);
}
private static ImmutableDictionary<SyntaxTree, ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>>> GetImmutable(
ImmutableHashSet<DiagnosticAnalyzer> analyzers,
Dictionary<SyntaxTree, Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>> localDiagnosticsOpt)
Dictionary<SyntaxTree, Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>>? localDiagnosticsOpt)
{
if (localDiagnosticsOpt == null)
{
......@@ -320,7 +323,7 @@ internal AnalysisResult ToAnalysisResult(ImmutableArray<DiagnosticAnalyzer> anal
private static ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>> GetImmutable(
ImmutableHashSet<DiagnosticAnalyzer> analyzers,
Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder> nonLocalDiagnosticsOpt)
Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>? nonLocalDiagnosticsOpt)
{
if (nonLocalDiagnosticsOpt == null)
{
......@@ -340,8 +343,7 @@ internal AnalysisResult ToAnalysisResult(ImmutableArray<DiagnosticAnalyzer> anal
}
private ImmutableDictionary<DiagnosticAnalyzer, AnalyzerTelemetryInfo> GetTelemetryInfo(
ImmutableArray<DiagnosticAnalyzer> analyzers,
CancellationToken cancellationToken)
ImmutableArray<DiagnosticAnalyzer> analyzers)
{
var builder = ImmutableDictionary.CreateBuilder<DiagnosticAnalyzer, AnalyzerTelemetryInfo>();
......@@ -351,7 +353,7 @@ internal AnalysisResult ToAnalysisResult(ImmutableArray<DiagnosticAnalyzer> anal
{
var actionCounts = _analyzerActionCounts[analyzer];
var suppressionActionCounts = analyzer is DiagnosticSuppressor ? 1 : 0;
var executionTime = _analyzerExecutionTimeOpt != null ? _analyzerExecutionTimeOpt[analyzer] : default(TimeSpan);
var executionTime = _analyzerExecutionTimeOpt != null ? _analyzerExecutionTimeOpt[analyzer] : default;
var telemetryInfo = new AnalyzerTelemetryInfo(actionCounts, suppressionActionCounts, executionTime);
builder.Add(analyzer, telemetryInfo);
}
......
......@@ -2,8 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
......@@ -31,13 +34,18 @@ public AnalysisValueProvider(Func<TKey, TValue> computeValue, IEqualityComparer<
private sealed class WrappedValue
{
public TValue Value { get; set; }
public WrappedValue(TValue value)
{
Value = value;
}
public TValue Value { get; }
}
private WrappedValue ComputeValue(TKey key)
{
var value = _computeValue(key);
return new WrappedValue { Value = value };
return new WrappedValue(value);
}
internal bool TryGetValue(TKey key, [MaybeNull][NotNullWhen(true)] out TValue value)
......@@ -46,6 +54,7 @@ internal bool TryGetValue(TKey key, [MaybeNull][NotNullWhen(true)] out TValue va
try
{
value = _valueCache.GetValue(key, _valueCacheCallback).Value;
Debug.Assert(value is object);
return true;
}
catch (Exception)
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
namespace Microsoft.CodeAnalysis.Diagnostics
{
/// <summary>
......
......@@ -1213,29 +1213,28 @@ private async Task<CompilationCompletedEvent> ProcessCompilationEventsCoreAsync(
}
CompilationEvent e;
try
if (!CompilationEventQueue.TryDequeue(out e))
{
if (!CompilationEventQueue.TryDequeue(out e))
if (!prePopulatedEventQueue)
{
if (!prePopulatedEventQueue)
{
e = await CompilationEventQueue.DequeueAsync(cancellationToken).ConfigureAwait(false);
}
else
var optionalEvent = await CompilationEventQueue.TryDequeueAsync(cancellationToken).ConfigureAwait(false);
if (!optionalEvent.HasValue)
{
return completedEvent;
// When the queue is completed with a pending TryDequeueAsync return, the
// the Optional<T> will not have a value. This signals the queue has reached
// completion and no more items will be added to it.
// This failure is being tracked by https://github.com/dotnet/roslyn/issues/5962
// Debug.Assert(CompilationEventQueue.IsCompleted, "TryDequeueAsync should provide a value unless the AsyncQueue<T> is completed.");
break;
}
}
}
catch (TaskCanceledException) when (!prePopulatedEventQueue)
{
// When the queue is completed with a pending DequeueAsync return then a
// TaskCanceledException will be thrown. This just signals the queue is
// complete and we should finish processing it.
// This failure is being tracked by https://github.com/dotnet/roslyn/issues/5962
// Debug.Assert(CompilationEventQueue.IsCompleted, "DequeueAsync should never throw unless the AsyncQueue<T> is completed.");
break;
e = optionalEvent.Value;
}
else
{
return completedEvent;
}
}
// Don't process the compilation completed event as other worker threads might still be processing other compilation events.
......
......@@ -22,7 +22,7 @@ internal sealed class AsyncQueue<TElement>
// Note: All of the below fields are accessed in parallel and may only be accessed
// when protected by lock (SyncObject)
private readonly Queue<TElement> _data = new Queue<TElement>();
private Queue<TaskCompletionSource<TElement>> _waiters;
private Queue<TaskCompletionSource<Optional<TElement>>> _waiters;
private bool _completed;
private bool _disallowEnqueue;
......@@ -76,7 +76,7 @@ private bool EnqueueCore(TElement value)
throw new InvalidOperationException($"Cannot enqueue data after PromiseNotToEnqueue.");
}
TaskCompletionSource<TElement> waiter;
TaskCompletionSource<Optional<TElement>> waiter;
lock (SyncObject)
{
if (_completed)
......@@ -163,7 +163,7 @@ public bool TryComplete()
private bool CompleteCore()
{
Queue<TaskCompletionSource<TElement>> existingWaiters;
Queue<TaskCompletionSource<Optional<TElement>>> existingWaiters;
lock (SyncObject)
{
if (_completed)
......@@ -191,7 +191,7 @@ private bool CompleteCore()
Debug.Assert(this.Count == 0, "we should not be cancelling the waiters when we have items in the queue");
foreach (var tcs in existingWaiters)
{
tcs.SetCanceled();
tcs.SetResult(default);
}
}
......@@ -224,7 +224,36 @@ public Task WhenCompletedTask
[PerformanceSensitive("https://github.com/dotnet/roslyn/issues/23582", OftenCompletesSynchronously = true)]
public Task<TElement> DequeueAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return WithCancellationAsync(DequeueCoreAsync(), cancellationToken);
var optionalResult = TryDequeueAsync(cancellationToken);
if (optionalResult.IsCompletedSuccessfully)
{
var result = optionalResult.Result;
return result.HasValue
? Task.FromResult(result.Value)
: Task.FromCanceled<TElement>(new CancellationToken(canceled: true));
}
return dequeueSlowAsync(optionalResult);
static async Task<TElement> dequeueSlowAsync(ValueTask<Optional<TElement>> optionalResult)
{
var result = await optionalResult.ConfigureAwait(false);
if (!result.HasValue)
new CancellationToken(canceled: true).ThrowIfCancellationRequested();
return result.Value;
}
}
/// <summary>
/// Gets a task whose result is the element at the head of the queue. If the queue
/// is empty, the returned task waits for an element to be enqueued. If <see cref="Complete"/>
/// is called before an element becomes available, the returned task is completed and
/// <see cref="Optional{T}.HasValue"/> will be <see langword="false"/>.
/// </summary>
public ValueTask<Optional<TElement>> TryDequeueAsync(CancellationToken cancellationToken)
{
return WithCancellationAsync(TryDequeueCoreAsync(), cancellationToken);
}
/// <summary>
......@@ -232,7 +261,7 @@ public Task<TElement> DequeueAsync(CancellationToken cancellationToken = default
/// Note: The early cancellation behavior is intentional.
/// </summary>
[PerformanceSensitive("https://github.com/dotnet/roslyn/issues/23582", OftenCompletesSynchronously = true)]
private static Task<T> WithCancellationAsync<T>(Task<T> task, CancellationToken cancellationToken)
private static ValueTask<T> WithCancellationAsync<T>(ValueTask<T> task, CancellationToken cancellationToken)
{
if (task.IsCompleted || !cancellationToken.CanBeCanceled)
{
......@@ -241,14 +270,15 @@ private static Task<T> WithCancellationAsync<T>(Task<T> task, CancellationToken
if (cancellationToken.IsCancellationRequested)
{
return new Task<T>(() => default(T), cancellationToken);
task.Preserve();
return new ValueTask<T>(Task.FromCanceled<T>(cancellationToken));
}
return task.ContinueWith(t => t, cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default).Unwrap();
return new ValueTask<T>(task.AsTask().ContinueWith(t => t, cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default).Unwrap());
}
[PerformanceSensitive("https://github.com/dotnet/roslyn/issues/23582", OftenCompletesSynchronously = true)]
private Task<TElement> DequeueCoreAsync()
private ValueTask<Optional<TElement>> TryDequeueCoreAsync()
{
lock (SyncObject)
{
......@@ -256,25 +286,23 @@ private Task<TElement> DequeueCoreAsync()
// in the queue. This keeps the behavior in line with TryDequeue
if (_data.Count > 0)
{
return Task.FromResult(_data.Dequeue());
return new ValueTask<Optional<TElement>>(_data.Dequeue());
}
if (_completed)
{
var tcs = new TaskCompletionSource<TElement>();
tcs.SetCanceled();
return tcs.Task;
return new ValueTask<Optional<TElement>>(default(Optional<TElement>));
}
else
{
if (_waiters == null)
{
_waiters = new Queue<TaskCompletionSource<TElement>>();
_waiters = new Queue<TaskCompletionSource<Optional<TElement>>>();
}
var waiter = new TaskCompletionSource<TElement>();
var waiter = new TaskCompletionSource<Optional<TElement>>();
_waiters.Enqueue(waiter);
return waiter.Task;
return new ValueTask<Optional<TElement>>(waiter.Task);
}
}
}
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis.Diagnostics
......
......@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
namespace Microsoft.CodeAnalysis.Diagnostics
......@@ -113,6 +114,7 @@ public override void Enqueue(Diagnostic diagnostic)
public override void EnqueueLocal(Diagnostic diagnostic, DiagnosticAnalyzer analyzer, bool isSyntaxDiagnostic)
{
Debug.Assert(diagnostic.Location.IsInSource);
if (isSyntaxDiagnostic)
{
EnqueueCore(ref _lazyLocalSyntaxDiagnostics, diagnostic, analyzer);
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis.Text;
......@@ -21,7 +23,7 @@ public sealed class SourceTextValueProvider<TValue>
/// <param name="computeValue">Delegate to compute the value associated with a given <see cref="SourceText"/> instance.</param>
/// <param name="sourceTextComparer">Optional equality comparer to determine equivalent <see cref="SourceText"/> instances that have the same value.
/// If no comparer is provided, then <see cref="SourceTextComparer"/> is used by default.</param>
public SourceTextValueProvider(Func<SourceText, TValue> computeValue, IEqualityComparer<SourceText> sourceTextComparer = null)
public SourceTextValueProvider(Func<SourceText, TValue> computeValue, IEqualityComparer<SourceText>? sourceTextComparer = null)
{
CoreValueProvider = new AnalysisValueProvider<SourceText, TValue>(computeValue, sourceTextComparer ?? SourceTextComparer.Instance);
}
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
......@@ -61,7 +63,7 @@ public static Suppression Create(SuppressionDescriptor descriptor, Diagnostic su
return !(left == right);
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is Suppression suppression
&& Equals(suppression);
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
......@@ -20,7 +22,7 @@ public sealed class SyntaxTreeValueProvider<TValue>
/// <param name="computeValue">Delegate to compute the value associated with a given <see cref="SyntaxTree"/> instance.</param>
/// <param name="syntaxTreeComparer">Optional equality comparer to determine equivalent <see cref="SyntaxTree"/> instances that have the same value.
/// If no comparer is provided, then <see cref="SyntaxTreeComparer"/> is used by default.</param>
public SyntaxTreeValueProvider(Func<SyntaxTree, TValue> computeValue, IEqualityComparer<SyntaxTree> syntaxTreeComparer = null)
public SyntaxTreeValueProvider(Func<SyntaxTree, TValue> computeValue, IEqualityComparer<SyntaxTree>? syntaxTreeComparer = null)
{
CoreValueProvider = new AnalysisValueProvider<SyntaxTree, TValue>(computeValue, syntaxTreeComparer ?? SyntaxTreeComparer.Instance);
}
......
......@@ -2,10 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Threading;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis
{
......@@ -21,7 +22,7 @@ protected internal override string GetDocumentationForSymbol(string documentatio
return "";
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
// Only one instance is expected to exist, so reference equality is fine.
return (object)this == obj;
......
......@@ -2,10 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
#nullable enable
using System.Globalization;
using System.Threading;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis
{
......@@ -31,10 +31,10 @@ protected DocumentationProvider()
/// results from another culture if the preferred culture was unavailable.</param>
/// <param name="cancellationToken">A cancellation token for the search.</param>
/// <returns>A DocumentationComment.</returns>
protected internal abstract string GetDocumentationForSymbol(
protected internal abstract string? GetDocumentationForSymbol(
string documentationMemberID,
CultureInfo preferredCulture,
CancellationToken cancellationToken = default(CancellationToken));
CancellationToken cancellationToken = default);
/// <summary>
/// DocumentationProviders are compared when determining whether an AssemblySymbol can be reused.
......@@ -42,7 +42,7 @@ protected DocumentationProvider()
/// Equals (and GetHashCode) be overridden to capture this fact. Otherwise, it is possible to end
/// up with multiple AssemblySymbols for the same assembly, which plays havoc with the type hierarchy.
/// </summary>
public abstract override bool Equals(object obj);
public abstract override bool Equals(object? obj);
/// <summary>
/// DocumentationProviders are compared when determining whether an AssemblySymbol can be reused.
......
......@@ -2,13 +2,15 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.CodeAnalysis.Collections;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
......@@ -152,15 +154,14 @@ private string GetDebuggerDisplay()
return GetDisplayName(fullKey: true);
}
public static bool TryParseDisplayName(string displayName, out AssemblyIdentity identity)
public static bool TryParseDisplayName(string displayName, [NotNullWhen(true)] out AssemblyIdentity? identity)
{
if (displayName == null)
{
throw new ArgumentNullException(nameof(displayName));
}
AssemblyIdentityParts parts;
return TryParseDisplayName(displayName, out identity, out parts);
return TryParseDisplayName(displayName, out identity, parts: out _);
}
/// <summary>
......@@ -180,7 +181,7 @@ public static bool TryParseDisplayName(string displayName, out AssemblyIdentity
/// If neither public key nor token is specified the identity is considered weak.
/// </remarks>
/// <exception cref="ArgumentNullException"><paramref name="displayName"/> is null.</exception>
public static bool TryParseDisplayName(string displayName, out AssemblyIdentity identity, out AssemblyIdentityParts parts)
public static bool TryParseDisplayName(string displayName, [NotNullWhen(true)] out AssemblyIdentity? identity, out AssemblyIdentityParts parts)
{
// see ndp\clr\src\Binder\TextualIdentityParser.cpp, ndp\clr\src\Binder\StringLexer.cpp
......@@ -198,7 +199,7 @@ public static bool TryParseDisplayName(string displayName, out AssemblyIdentity
}
int position = 0;
string simpleName;
string? simpleName;
if (!TryParseNameToken(displayName, ref position, out simpleName))
{
return false;
......@@ -207,8 +208,8 @@ public static bool TryParseDisplayName(string displayName, out AssemblyIdentity
var parsedParts = AssemblyIdentityParts.Name;
var seen = AssemblyIdentityParts.Name;
Version version = null;
string culture = null;
Version? version = null;
string? culture = null;
bool isRetargetable = false;
var contentType = AssemblyContentType.Default;
var publicKey = default(ImmutableArray<byte>);
......@@ -224,7 +225,7 @@ public static bool TryParseDisplayName(string displayName, out AssemblyIdentity
position++;
string propertyName;
string? propertyName;
if (!TryParseNameToken(displayName, ref position, out propertyName))
{
return false;
......@@ -237,7 +238,7 @@ public static bool TryParseDisplayName(string displayName, out AssemblyIdentity
position++;
string propertyValue;
string? propertyValue;
if (!TryParseNameToken(displayName, ref position, out propertyValue))
{
return false;
......@@ -417,7 +418,7 @@ public static bool TryParseDisplayName(string displayName, out AssemblyIdentity
return true;
}
private static bool TryParseNameToken(string displayName, ref int position, out string value)
private static bool TryParseNameToken(string displayName, ref int position, [NotNullWhen(true)] out string? value)
{
Debug.Assert(displayName.IndexOf('\0') == -1);
......@@ -640,7 +641,7 @@ private static bool TryParsePublicKey(string value, out ImmutableArray<byte> key
if (!TryParseHexBytes(value, out key) ||
!MetadataHelpers.IsValidPublicKey(key))
{
key = default(ImmutableArray<byte>);
key = default;
return false;
}
......@@ -661,7 +662,7 @@ private static bool TryParsePublicKeyToken(string value, out ImmutableArray<byte
ImmutableArray<byte> result;
if (value.Length != (PublicKeyTokenBytes * 2) || !TryParseHexBytes(value, out result))
{
token = default(ImmutableArray<byte>);
token = default;
return false;
}
......@@ -673,7 +674,7 @@ private static bool TryParseHexBytes(string value, out ImmutableArray<byte> resu
{
if (value.Length == 0 || (value.Length % 2) != 0)
{
result = default(ImmutableArray<byte>);
result = default;
return false;
}
......@@ -686,7 +687,7 @@ private static bool TryParseHexBytes(string value, out ImmutableArray<byte> resu
if (hi < 0 || lo < 0)
{
result = default(ImmutableArray<byte>);
result = default;
bytes.Free();
return false;
}
......@@ -723,7 +724,7 @@ private static bool IsWhiteSpace(char c)
return c == ' ' || c == '\t' || c == '\r' || c == '\n';
}
private static void EscapeName(StringBuilder result, string name)
private static void EscapeName(StringBuilder result, string? name)
{
if (string.IsNullOrEmpty(name))
{
......@@ -775,7 +776,7 @@ private static void EscapeName(StringBuilder result, string name)
}
}
private static bool TryUnescape(string str, int start, int end, out string value)
private static bool TryUnescape(string str, int start, int end, [NotNullWhen(true)] out string? value)
{
var sb = PooledStringBuilder.GetInstance();
......
......@@ -105,7 +105,7 @@ internal ComparisonResult Compare(AssemblyIdentity? reference, string? reference
}
else
{
if (!AssemblyIdentity.TryParseDisplayName(referenceDisplayName, out reference, out parts) ||
if (!AssemblyIdentity.TryParseDisplayName(referenceDisplayName!, out reference, out parts) ||
reference.ContentType != definition.ContentType)
{
return ComparisonResult.NotEquivalent;
......
......@@ -217,7 +217,7 @@ public interface ISymbol : IEquatable<ISymbol?>
/// <param name="expandIncludes">Optionally, expand &lt;include&gt; elements. No impact on non-source documentation comments.</param>
/// <param name="cancellationToken">Token allowing cancellation of request.</param>
/// <returns>The XML that would be written to the documentation file for the symbol.</returns>
string? GetDocumentationCommentXml(CultureInfo? preferredCulture = null, bool expandIncludes = false, CancellationToken cancellationToken = default(CancellationToken));
string? GetDocumentationCommentXml(CultureInfo? preferredCulture = null, bool expandIncludes = false, CancellationToken cancellationToken = default);
/// <summary>
/// Converts the symbol to a string representation.
......
......@@ -56,7 +56,7 @@ private enum SyntaxKinds
return includeZeroWidth ? SyntaxToken.Any : SyntaxToken.NonZeroWidth;
}
private static bool Matches(Func<SyntaxToken, bool> predicate, SyntaxToken token)
private static bool Matches(Func<SyntaxToken, bool>? predicate, SyntaxToken token)
{
return predicate == null || ReferenceEquals(predicate, SyntaxToken.Any) || predicate(token);
}
......@@ -94,7 +94,7 @@ internal SyntaxToken GetNextToken(in SyntaxToken current, Func<SyntaxToken, bool
private static readonly ObjectPool<Stack<ChildSyntaxList.Enumerator>> s_childEnumeratorStackPool
= new ObjectPool<Stack<ChildSyntaxList.Enumerator>>(() => new Stack<ChildSyntaxList.Enumerator>(), 10);
internal SyntaxToken GetFirstToken(SyntaxNode current, Func<SyntaxToken, bool> predicate, Func<SyntaxTrivia, bool>? stepInto)
internal SyntaxToken GetFirstToken(SyntaxNode current, Func<SyntaxToken, bool>? predicate, Func<SyntaxTrivia, bool>? stepInto)
{
var stack = s_childEnumeratorStackPool.Allocate();
try
......@@ -186,7 +186,7 @@ internal SyntaxToken GetLastToken(SyntaxNode current, Func<SyntaxToken, bool> pr
private SyntaxToken GetFirstToken(
SyntaxTriviaList triviaList,
Func<SyntaxToken, bool> predicate,
Func<SyntaxToken, bool>? predicate,
Func<SyntaxTrivia, bool> stepInto)
{
Debug.Assert(stepInto != null);
......@@ -244,7 +244,7 @@ internal SyntaxToken GetLastToken(SyntaxNode current, Func<SyntaxToken, bool> pr
private SyntaxToken GetFirstToken(
SyntaxToken token,
Func<SyntaxToken, bool> predicate,
Func<SyntaxToken, bool>? predicate,
Func<SyntaxTrivia, bool>? stepInto)
{
// find first token that matches (either specified token or token inside related trivia)
......
......@@ -6,6 +6,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.CodeAnalysis
{
......@@ -430,7 +431,8 @@ public static SyntaxToken WithoutTrivia(this SyntaxToken token)
/// <summary>
/// Attaches the node to a SyntaxTree that the same options as <paramref name="oldTree"/>
/// </summary>
internal static SyntaxNode? AsRootOfNewTreeWithOptionsFrom(this SyntaxNode node, SyntaxTree oldTree)
[return: NotNullIfNotNull("node")]
internal static SyntaxNode? AsRootOfNewTreeWithOptionsFrom(this SyntaxNode? node, SyntaxTree oldTree)
{
return node != null ? oldTree.WithRootAndOptions(node, oldTree.Options).GetRoot() : null;
}
......
......@@ -22872,20 +22872,34 @@ class Program
End Class
"
Dim comp1 = CreateCompilation(source0 + source1, targetFramework:=TargetFramework.Mscorlib46, options:=TestOptions.DebugExe)
Dim verifyField = Sub(comp As VisualBasicCompilation)
Dim field = comp.GetMember(Of FieldSymbol)("System.ValueTuple.F1")
Assert.Null(field.TupleUnderlyingField)
Dim toEmit = field.ContainingType.GetFieldsToEmit().Where(Function(f) f.Name = "F1").Single()
Assert.Same(field, toEmit)
End Sub
Dim comp1 = CreateCompilation(source0 + source1, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe)
CompileAndVerify(comp1, expectedOutput:="123")
verifyField(comp1)
Dim comp1Ref = {comp1.ToMetadataReference()}
Dim comp1ImageRef = {comp1.EmitToImageReference()}
Dim comp4 = CreateCompilation(source0 + source2, targetFramework:=TargetFramework.Mscorlib46, options:=TestOptions.DebugExe)
Dim comp4 = CreateCompilation(source0 + source2, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe)
CompileAndVerify(comp4, expectedOutput:="123")
Dim comp5 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib46, options:=TestOptions.DebugExe, references:=comp1Ref)
Dim comp5 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe, references:=comp1Ref)
CompileAndVerify(comp5, expectedOutput:="123")
verifyField(comp5)
Dim comp6 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib46, options:=TestOptions.DebugExe, references:=comp1ImageRef)
Dim comp6 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe, references:=comp1ImageRef)
CompileAndVerify(comp6, expectedOutput:="123")
verifyField(comp6)
Dim comp7 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib46, options:=TestOptions.DebugExe, references:=comp1Ref)
CompileAndVerify(comp7, expectedOutput:="123")
verifyField(comp7)
End Sub
<Fact>
......@@ -22928,20 +22942,162 @@ class Program
End Class
"
Dim comp1 = CreateCompilation(source0 + source1, targetFramework:=TargetFramework.Mscorlib46, options:=TestOptions.DebugExe)
Dim verifyField = Sub(comp As VisualBasicCompilation)
Dim field = comp.GetMember(Of FieldSymbol)("System.ValueTuple.F1")
Assert.Null(field.TupleUnderlyingField)
Dim toEmit = field.ContainingType.GetFieldsToEmit().Where(Function(f) f.Name = "F1").Single()
Assert.Same(field, toEmit)
End Sub
Dim comp1 = CreateCompilation(source0 + source1, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe)
CompileAndVerify(comp1, expectedOutput:="123")
verifyField(comp1)
Dim comp1Ref = {comp1.ToMetadataReference()}
Dim comp1ImageRef = {comp1.EmitToImageReference()}
Dim comp4 = CreateCompilation(source0 + source2, targetFramework:=TargetFramework.Mscorlib46, options:=TestOptions.DebugExe)
Dim comp4 = CreateCompilation(source0 + source2, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe)
CompileAndVerify(comp4, expectedOutput:="123")
Dim comp5 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib46, options:=TestOptions.DebugExe, references:=comp1Ref)
Dim comp5 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe, references:=comp1Ref)
CompileAndVerify(comp5, expectedOutput:="123")
verifyField(comp5)
Dim comp6 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib46, options:=TestOptions.DebugExe, references:=comp1ImageRef)
Dim comp6 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe, references:=comp1ImageRef)
CompileAndVerify(comp6, expectedOutput:="123")
verifyField(comp6)
Dim comp7 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib46, options:=TestOptions.DebugExe, references:=comp1Ref)
CompileAndVerify(comp7, expectedOutput:="123")
verifyField(comp7)
End Sub
<Fact>
<WorkItem(43524, "https://github.com/dotnet/roslyn/issues/43524")>
<WorkItem(1095184, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1095184")>
Public Sub CustomFields_03()
Dim source0 = "
namespace System
public structure ValueTuple
public shared readonly F1 As Integer = 4
public Shared Function CombineHashCodes(h1 As Integer, h2 As Integer) As Integer
return F1 + h1 + h2
End Function
End Structure
End Namespace
"
Dim source1 = "
class Program
shared sub Main()
System.Console.WriteLine(System.ValueTuple.CombineHashCodes(2, 3))
End Sub
End Class
"
Dim source2 = "
class Program
public shared Sub Main()
System.Console.WriteLine(System.ValueTuple.F1 + 2 + 3)
End Sub
End Class
"
Dim verifyField = Sub(comp As VisualBasicCompilation)
Dim field = comp.GetMember(Of FieldSymbol)("System.ValueTuple.F1")
Assert.Null(field.TupleUnderlyingField)
Dim toEmit = field.ContainingType.GetFieldsToEmit().Single()
Assert.Same(field, toEmit)
End Sub
Dim comp1 = CreateCompilation(source0 + source1, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe)
CompileAndVerify(comp1, expectedOutput:="9")
verifyField(comp1)
Dim comp1Ref = {comp1.ToMetadataReference()}
Dim comp1ImageRef = {comp1.EmitToImageReference()}
Dim comp4 = CreateCompilation(source0 + source2, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe)
CompileAndVerify(comp4, expectedOutput:="9")
Dim comp5 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe, references:=comp1Ref)
CompileAndVerify(comp5, expectedOutput:="9")
verifyField(comp5)
Dim comp6 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe, references:=comp1ImageRef)
CompileAndVerify(comp6, expectedOutput:="9")
verifyField(comp6)
Dim comp7 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib46, options:=TestOptions.DebugExe, references:=comp1Ref)
CompileAndVerify(comp7, expectedOutput:="9")
verifyField(comp7)
End Sub
<Fact>
<WorkItem(43524, "https://github.com/dotnet/roslyn/issues/43524")>
<WorkItem(1095184, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1095184")>
Public Sub CustomFields_04()
Dim source0 = "
namespace System
public structure ValueTuple
public F1 as Integer
public Function CombineHashCodes(h1 as Integer, h2 as Integer) as Integer
return F1 + h1 + h2
End Function
End Structure
End Namespace
"
Dim source1 = "
class Program
shared sub Main()
Dim tuple as System.ValueTuple = Nothing
tuple.F1 = 4
System.Console.WriteLine(tuple.CombineHashCodes(2, 3))
End Sub
End Class
"
Dim source2 = "
class Program
public shared Sub Main()
Dim tuple as System.ValueTuple = Nothing
tuple.F1 = 4
System.Console.WriteLine(tuple.F1 + 2 + 3)
End Sub
End Class
"
Dim verifyField = Sub(comp As VisualBasicCompilation)
Dim field = comp.GetMember(Of FieldSymbol)("System.ValueTuple.F1")
Assert.Null(field.TupleUnderlyingField)
Dim toEmit = field.ContainingType.GetFieldsToEmit().Single()
Assert.Same(field, toEmit)
End Sub
Dim comp1 = CreateCompilation(source0 + source1, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe)
CompileAndVerify(comp1, expectedOutput:="9")
verifyField(comp1)
Dim comp1Ref = {comp1.ToMetadataReference()}
Dim comp1ImageRef = {comp1.EmitToImageReference()}
Dim comp4 = CreateCompilation(source0 + source2, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe)
CompileAndVerify(comp4, expectedOutput:="9")
Dim comp5 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe, references:=comp1Ref)
CompileAndVerify(comp5, expectedOutput:="9")
verifyField(comp5)
Dim comp6 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib40, options:=TestOptions.DebugExe, references:=comp1ImageRef)
CompileAndVerify(comp6, expectedOutput:="9")
verifyField(comp6)
Dim comp7 = CreateCompilation(source2, targetFramework:=TargetFramework.Mscorlib46, options:=TestOptions.DebugExe, references:=comp1Ref)
CompileAndVerify(comp7, expectedOutput:="9")
verifyField(comp7)
End Sub
<Fact>
......@@ -23084,6 +23240,33 @@ Module Module1
System.Console.WriteLine(""Done"")
End Sub
End Module
"
Dim comp1 = CreateCompilation(source0, options:=TestOptions.DebugExe)
CompileAndVerify(comp1, expectedOutput:="Done")
End Sub
<Fact>
<WorkItem(24517, "https://github.com/dotnet/roslyn/issues/24517")>
Public Sub Issue24517()
Dim source0 = "
Imports System
Imports System.Collections.Generic
Imports System.Linq.Expressions
Module Module1
Sub Main()
Dim e1 As Expression(Of Func(Of ValueTuple(Of Integer, Integer))) = Function() new ValueTuple(Of Integer, Integer)(1, 2)
Dim e2 As Expression(Of Func(Of KeyValuePair(Of Integer, Integer))) = Function() new KeyValuePair(Of Integer, Integer)(1, 2)
e1.Compile()()
e2.Compile()()
System.Console.WriteLine(""Done"")
End Sub
End Module
"
......
......@@ -7,7 +7,6 @@
using System.IO;
using System.Linq;
using System.Xml;
using static System.String;
namespace CSharpSyntaxGenerator
{
......@@ -32,6 +31,7 @@ private void WriteFileHeader()
WriteLine();
WriteLine("using System;");
WriteLine("using System.Collections.Generic;");
WriteLine("using System.Diagnostics.CodeAnalysis;");
WriteLine("using Microsoft.CodeAnalysis.Syntax.InternalSyntax;");
WriteLine("using Roslyn.Utilities;");
WriteLine();
......@@ -68,6 +68,7 @@ private void WriteMain()
WriteLine("namespace Microsoft.CodeAnalysis.CSharp");
OpenBlock();
WriteLine("using Microsoft.CodeAnalysis.CSharp.Syntax;");
WriteLine("using System.Diagnostics.CodeAnalysis;");
this.WriteRedVisitors();
this.WriteRedRewriter();
this.WriteRedFactories();
......@@ -1138,6 +1139,8 @@ private void WriteRedAcceptMethods(Node node)
private void WriteRedAcceptMethod(Node node, bool genericResult)
{
string genericArgs = genericResult ? "<TResult>" : "";
if (genericResult)
WriteLine("[return: MaybeNull]");
WriteLine($"public override {(genericResult ? "TResult" : "void")} Accept{genericArgs}(CSharpSyntaxVisitor{genericArgs} visitor) => visitor.Visit{StripPost(node.Name, "Syntax")}(this);");
}
......@@ -1162,6 +1165,8 @@ private void WriteRedVisitor(bool genericResult)
WriteLine();
nWritten++;
WriteComment($"<summary>Called when the visitor visits a {node.Name} node.</summary>");
if (genericResult)
WriteLine("[return: MaybeNull]");
WriteLine($"public virtual {(genericResult ? "TResult" : "void")} Visit{StripPost(node.Name, "Syntax")}({node.Name} node) => this.DefaultVisit(node);");
}
CloseBlock();
......
......@@ -24,16 +24,9 @@
<ProjectReference Include="..\..\EditorFeatures\Core.Wpf\Microsoft.CodeAnalysis.EditorFeatures.Wpf.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.ComponentModel.Composition" />
<PackageReference Include="Microsoft.VisualStudio.SDK.EmbedInteropTypes" Version="$(MicrosoftVisualStudioSDKEmbedInteropTypesVersion)" />
<PackageReference Include="Microsoft.ServiceHub.Client" Version="$(MicrosoftServiceHubClientVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Imaging" Version="$(MicrosoftVisualStudioImagingVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Language" Version="$(MicrosoftVisualStudioLanguageVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Language.Intellisense" Version="$(MicrosoftVisualStudioLanguageIntellisenseVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Text.UI.Wpf" Version="$(MicrosoftVisualStudioTextUIWpfVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="$(MicrosoftVisualStudioThreadingVersion)" />
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" />
<PackageReference Include="StreamJsonRpc" Version="$(StreamJsonRpcVersion)" />
</ItemGroup>
<ItemGroup>
<PublicAPI Include="PublicAPI.Shipped.txt" />
......
......@@ -177,9 +177,11 @@
<PackageReference Include="VsWebsite.Interop" Version="$(VsWebsiteInteropVersion)" />
<PackageReference Include="NuGet.VisualStudio" Version="$(NuGetVisualStudioVersion)" />
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" />
<PackageReference Include="Microsoft.VisualStudio.SDK.EmbedInteropTypes" Version="$(MicrosoftVisualStudioSDKEmbedInteropTypesVersion)" />
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="$(SystemThreadingTasksDataflowVersion)" />
<PackageReference Include="Microsoft.VisualStudio.StaticReviews.Embeddable" Version="$(MicrosoftVisualStudioStaticReviewsEmbeddableVersion)" />
<!-- By default build assets that define embedded interop types do not flow. Set PrivateAssets to none to make them flow. -->
<PackageReference Include="Microsoft.VisualStudio.SDK.EmbedInteropTypes" Version="$(MicrosoftVisualStudioSDKEmbedInteropTypesVersion)" PrivateAssets="none" />
<PackageReference Include="Microsoft.VisualStudio.StaticReviews.Embeddable" Version="$(MicrosoftVisualStudioStaticReviewsEmbeddableVersion)" PrivateAssets="none" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="ServicesVSResources.resx" GenerateSource="true" />
......
......@@ -19,22 +19,8 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="EnvDTE" Version="$(EnvDTEVersion)" />
<PackageReference Include="VSLangProj" Version="$(VSLangProjVersion)" />
<PackageReference Include="VSLangProj2" Version="$(VSLangProj2Version)" />
<PackageReference Include="VSLangProj80" Version="$(VSLangProj80Version)" />
<PackageReference Include="VSLangProj140" Version="$(VSLangProj140Version)" />
<PackageReference Include="Microsoft.CSharp" Version="$(MicrosoftCSharpVersion)" />
<PackageReference Include="Microsoft.VisualStudio.CodeAnalysis.Sdk.UI" Version="$(MicrosoftVisualStudioCodeAnalysisSdkUIVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Language.Intellisense" Version="$(MicrosoftVisualStudioLanguageIntellisenseVersion)" />
<PackageReference Include="Microsoft.VisualStudio.ComponentModelHost" Version="$(MicrosoftVisualStudioComponentModelHostVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.15.0" Version="$(MicrosoftVisualStudioShell150Version)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.12.1.DesignTime" Version="$(MicrosoftVisualStudioShellInterop121DesignTimeVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Design" Version="$(MicrosoftVisualStudioShellDesignVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Framework" Version="$(MicrosoftVisualStudioShellFrameworkVersion)" />
<PackageReference Include="Microsoft.Build.Framework" Version="$(MicrosoftBuildFrameworkVersion)" />
<PackageReference Include="Microsoft.VisualStudio.SDK.EmbedInteropTypes" Version="$(MicrosoftVisualStudioSDKEmbedInteropTypesVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="$(MicrosoftVisualStudioThreadingVersion)" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="Roslyn.VisualStudio.Setup" />
......
......@@ -55,15 +55,9 @@
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="EnvDTE" Version="$(EnvDTEVersion)" />
<PackageReference Include="EnvDTE80" Version="$(EnvDTE80Version)" />
<PackageReference Include="Microsoft.VisualStudio.ComponentModelHost" Version="$(MicrosoftVisualStudioComponentModelHostVersion)" />
<PackageReference Include="Microsoft.VisualStudio.SDK.Analyzers" Version="$(MicrosoftVisualStudioSDKAnalyzersVersion)" PrivateAssets="all" />
<PackageReference Include="Microsoft.VisualStudio.Text.UI" Version="$(MicrosoftVisualStudioTextUIVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Text.UI.Wpf" Version="$(MicrosoftVisualStudioTextUIWpfVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Shell.15.0" Version="$(MicrosoftVisualStudioShell150Version)" />
<PackageReference Include="Microsoft.VisualStudio.SDK.EmbedInteropTypes" Version="$(MicrosoftVisualStudioSDKEmbedInteropTypesVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="$(MicrosoftVisualStudioThreadingVersion)" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources.resx" GenerateSource="true" />
......
......@@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
using System.Composition;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.CodeActions;
......@@ -97,6 +98,9 @@ private class Rewriter : CSharpSyntaxRewriter
public override bool VisitIntoStructuredTrivia => true;
[return: NotNullIfNotNull("node")]
public override SyntaxNode? Visit(SyntaxNode? node) => base.Visit(node);
public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node)
{
// We only care about xml doc comments
......@@ -123,18 +127,18 @@ public override SyntaxNode VisitGenericName(GenericNameSyntax node)
return expanded.WithLeadingTrivia(leadingTrivia);
}
var typeArgumentList = (TypeArgumentListSyntax)base.Visit(node.TypeArgumentList);
var typeArgumentList = (TypeArgumentListSyntax)Visit(node.TypeArgumentList);
return node.Update(node.Identifier.WithLeadingTrivia(leadingTrivia), typeArgumentList);
}
public override SyntaxNode VisitQualifiedName(QualifiedNameSyntax node)
{
var left = (NameSyntax)base.Visit(node.Left);
var left = (NameSyntax)Visit(node.Left);
// We don't recurse on the right, as if B is a member of the imported namespace, A.B is still not ambiguous
var right = node.Right;
if (right is GenericNameSyntax genericName)
{
var typeArgumentList = (TypeArgumentListSyntax)base.Visit(genericName.TypeArgumentList);
var typeArgumentList = (TypeArgumentListSyntax)Visit(genericName.TypeArgumentList);
right = genericName.Update(genericName.Identifier, typeArgumentList);
}
return node.Update(left, node.DotToken, right);
......
......@@ -5,6 +5,7 @@
#nullable enable
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Roslyn.Utilities;
......@@ -32,8 +33,7 @@ public static SafeHandleLease Lease(this SafeHandle handle)
try
{
handle.DangerousAddRef(ref success);
if (!success)
throw new ObjectDisposedException(handle.GetType().FullName);
Debug.Assert(success, $"{nameof(SafeHandle.DangerousAddRef)} does not return when {nameof(success)} is false.");
return new SafeHandleLease(handle);
}
......
......@@ -38,7 +38,7 @@ public static SafeSqliteStatementHandle sqlite3_prepare_v2(SafeSqliteHandle db,
{
using var _ = db.Lease();
result = (Result)raw.sqlite3_prepare_v2(db.DangerousGetHandle(), sql, out var wrapper);
result = (Result)raw.sqlite3_prepare_v2(db.DangerousGetWrapper(), sql, out var wrapper);
if (result != (int)Result.OK)
{
wrapper = null;
......@@ -61,7 +61,7 @@ public static SafeSqliteBlobHandle sqlite3_blob_open(SafeSqliteHandle db, string
{
using var _ = db.Lease();
result = (Result)raw.sqlite3_blob_open(db.DangerousGetHandle(), sdb, table, col, rowid, flags, out var wrapper);
result = (Result)raw.sqlite3_blob_open(db.DangerousGetWrapper(), sdb, table, col, rowid, flags, out var wrapper);
if (result != (int)Result.OK)
{
wrapper = null;
......@@ -83,7 +83,7 @@ public static SafeSqliteBlobHandle sqlite3_blob_open(SafeSqliteHandle db, string
public static string sqlite3_errmsg(SafeSqliteHandle db)
{
using var _ = db.Lease();
return raw.sqlite3_errmsg(db.DangerousGetHandle());
return raw.sqlite3_errmsg(db.DangerousGetWrapper());
}
public static string sqlite3_errstr(int rc)
......@@ -94,79 +94,79 @@ public static string sqlite3_errstr(int rc)
public static int sqlite3_extended_errcode(SafeSqliteHandle db)
{
using var _ = db.Lease();
return raw.sqlite3_extended_errcode(db.DangerousGetHandle());
return raw.sqlite3_extended_errcode(db.DangerousGetWrapper());
}
public static Result sqlite3_busy_timeout(SafeSqliteHandle db, int ms)
{
using var _ = db.Lease();
return (Result)raw.sqlite3_busy_timeout(db.DangerousGetHandle(), ms);
return (Result)raw.sqlite3_busy_timeout(db.DangerousGetWrapper(), ms);
}
public static long sqlite3_last_insert_rowid(SafeSqliteHandle db)
{
using var _ = db.Lease();
return raw.sqlite3_last_insert_rowid(db.DangerousGetHandle());
return raw.sqlite3_last_insert_rowid(db.DangerousGetWrapper());
}
public static int sqlite3_blob_bytes(SafeSqliteBlobHandle blob)
{
using var _ = blob.Lease();
return raw.sqlite3_blob_bytes(blob.DangerousGetHandle());
return raw.sqlite3_blob_bytes(blob.DangerousGetWrapper());
}
public static Result sqlite3_blob_read(SafeSqliteBlobHandle blob, byte[] b, int n, int offset)
{
using var _ = blob.Lease();
return (Result)raw.sqlite3_blob_read(blob.DangerousGetHandle(), b, n, offset);
return (Result)raw.sqlite3_blob_read(blob.DangerousGetWrapper(), b, n, offset);
}
public static Result sqlite3_reset(SafeSqliteStatementHandle stmt)
{
using var _ = stmt.Lease();
return (Result)raw.sqlite3_reset(stmt.DangerousGetHandle());
return (Result)raw.sqlite3_reset(stmt.DangerousGetWrapper());
}
public static Result sqlite3_step(SafeSqliteStatementHandle stmt)
{
using var _ = stmt.Lease();
return (Result)raw.sqlite3_step(stmt.DangerousGetHandle());
return (Result)raw.sqlite3_step(stmt.DangerousGetWrapper());
}
public static Result sqlite3_bind_text(SafeSqliteStatementHandle stmt, int index, string val)
{
using var _ = stmt.Lease();
return (Result)raw.sqlite3_bind_text(stmt.DangerousGetHandle(), index, val);
return (Result)raw.sqlite3_bind_text(stmt.DangerousGetWrapper(), index, val);
}
public static Result sqlite3_bind_int64(SafeSqliteStatementHandle stmt, int index, long val)
{
using var _ = stmt.Lease();
return (Result)raw.sqlite3_bind_int64(stmt.DangerousGetHandle(), index, val);
return (Result)raw.sqlite3_bind_int64(stmt.DangerousGetWrapper(), index, val);
}
public static byte[] sqlite3_column_blob(SafeSqliteStatementHandle stmt, int index)
{
using var _ = stmt.Lease();
return raw.sqlite3_column_blob(stmt.DangerousGetHandle(), index);
return raw.sqlite3_column_blob(stmt.DangerousGetWrapper(), index);
}
public static int sqlite3_column_int(SafeSqliteStatementHandle stmt, int index)
{
using var _ = stmt.Lease();
return raw.sqlite3_column_int(stmt.DangerousGetHandle(), index);
return raw.sqlite3_column_int(stmt.DangerousGetWrapper(), index);
}
public static long sqlite3_column_int64(SafeSqliteStatementHandle stmt, int index)
{
using var _ = stmt.Lease();
return raw.sqlite3_column_int64(stmt.DangerousGetHandle(), index);
return raw.sqlite3_column_int64(stmt.DangerousGetWrapper(), index);
}
public static string sqlite3_column_text(SafeSqliteStatementHandle stmt, int index)
{
using var _ = stmt.Lease();
return raw.sqlite3_column_text(stmt.DangerousGetHandle(), index);
return raw.sqlite3_column_text(stmt.DangerousGetWrapper(), index);
}
}
}
......@@ -26,13 +26,14 @@ public SafeSqliteBlobHandle(SafeSqliteHandle sqliteHandle, sqlite3_blob? wrapper
public override bool IsInvalid => handle == IntPtr.Zero;
public new sqlite3_blob DangerousGetHandle()
public sqlite3_blob DangerousGetWrapper()
=> _wrapper!;
protected override bool ReleaseHandle()
{
using var _ = _lease;
var result = (Result)raw.sqlite3_blob_close(_wrapper);
SetHandle(IntPtr.Zero);
return result == Result.OK;
}
}
......
......@@ -23,12 +23,13 @@ public SafeSqliteHandle(sqlite3? wrapper)
public override bool IsInvalid => handle == IntPtr.Zero;
public new sqlite3 DangerousGetHandle()
public sqlite3 DangerousGetWrapper()
=> _wrapper!;
protected override bool ReleaseHandle()
{
var result = (Result)raw.sqlite3_close(_wrapper);
SetHandle(IntPtr.Zero);
return result == Result.OK;
}
}
......
......@@ -26,13 +26,14 @@ public SafeSqliteStatementHandle(SafeSqliteHandle sqliteHandle, sqlite3_stmt? wr
public override bool IsInvalid => handle == IntPtr.Zero;
public new sqlite3_stmt DangerousGetHandle()
public sqlite3_stmt DangerousGetWrapper()
=> _wrapper!;
protected override bool ReleaseHandle()
{
using var _ = _lease;
var result = (Result)raw.sqlite3_finalize(_wrapper);
SetHandle(IntPtr.Zero);
return result == Result.OK;
}
}
......
......@@ -296,7 +296,7 @@ public void Throw(Result result)
public static void Throw(SafeSqliteHandle handle, Result result)
{
throw new SqlException(result,
NativeMethods.sqlite3_errmsg(handle) + "\r\n" +
NativeMethods.sqlite3_errmsg(handle) + Environment.NewLine +
NativeMethods.sqlite3_errstr(NativeMethods.sqlite3_extended_errcode(handle)));
}
}
......
......@@ -320,7 +320,7 @@ public void Throw(Result result)
public static void Throw(SafeSqliteHandle handle, Result result)
=> throw new SqlException(result,
NativeMethods.sqlite3_errmsg(handle) + "\r\n" +
NativeMethods.sqlite3_errmsg(handle) + Environment.NewLine +
NativeMethods.sqlite3_errstr(NativeMethods.sqlite3_extended_errcode(handle)));
}
}
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Globalization;
using System.Threading;
......@@ -14,7 +16,7 @@ internal class DeferredDocumentationProvider : DocumentationProvider
public DeferredDocumentationProvider(Compilation compilation)
=> _compilation = compilation;
protected override string GetDocumentationForSymbol(string documentationMemberID, CultureInfo preferredCulture, CancellationToken cancellationToken = default)
protected override string? GetDocumentationForSymbol(string documentationMemberID, CultureInfo preferredCulture, CancellationToken cancellationToken = default)
{
var symbol = DocumentationCommentId.GetFirstSymbolForDeclarationId(documentationMemberID, _compilation);
......@@ -26,7 +28,7 @@ protected override string GetDocumentationForSymbol(string documentationMemberID
return string.Empty;
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
=> object.ReferenceEquals(this, obj);
public override int GetHashCode()
......
......@@ -533,7 +533,7 @@ public static bool IsReturnableConstruct(this SyntaxNode node)
}
var rewriter = new SingleLineRewriter(useElasticTrivia);
return (TNode)rewriter.Visit(node);
return (TNode?)rewriter.Visit(node);
}
/// <summary>
......
......@@ -7,6 +7,7 @@
using System;
using System.Collections.Immutable;
using System.Composition;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using Microsoft.CodeAnalysis.AddImports;
using Microsoft.CodeAnalysis.CSharp.Extensions;
......@@ -116,6 +117,10 @@ private class Rewriter : CSharpSyntaxRewriter
_cancellationToken = cancellationToken;
}
[return: NotNullIfNotNull("node")]
public override SyntaxNode? Visit(SyntaxNode? node)
=> base.Visit(node);
public override SyntaxNode VisitNamespaceDeclaration(NamespaceDeclarationSyntax node)
{
// recurse downwards so we visit inner namespaces first.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册