Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions run-test.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
set DOTNET_RuntimeAsync=1
dotnet test Q:\repos\roslyn\src\Compilers\CSharp\Test\Emit\Microsoft.CodeAnalysis.CSharp.Emit.UnitTests.csproj -f net10.0
REM dotnet test Q:\repos\roslyn\src\Compilers\CSharp\Test\Emit\Microsoft.CodeAnalysis.CSharp.Emit.UnitTests.csproj --filter "DisplayName~TryFinally_YieldBreak" -f net10.0
REM dotnet test Q:\repos\roslyn\src\Compilers\CSharp\Test\Emit\Microsoft.CodeAnalysis.CSharp.Emit.UnitTests.csproj --filter "FullyQualifiedName~CodeGenAsyncIteratorTests" -f net10.0
REM dotnet test Q:\repos\roslyn\src\Compilers\CSharp\Test\Emit3\Microsoft.CodeAnalysis.CSharp.Emit3.UnitTests.csproj --filter "FullyQualifiedName~LockTests" -f net10.0

REM dotnet test Q:\repos\roslyn\src\Compilers\CSharp\Test\Emit2\Microsoft.CodeAnalysis.CSharp.Emit2.UnitTests.csproj --filter "FullyQualifiedName~LocalStateTracingTests" -f net10.0

REM TODO2 remove file

174 changes: 139 additions & 35 deletions src/Compilers/CSharp/Portable/BoundTree/BoundNode_Source.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +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 System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Text;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Roslyn.Utilities;
Expand Down Expand Up @@ -85,6 +87,11 @@ void appendSourceCore(BoundNode node, int indent, Dictionary<SynthesizedLocal, i
case BoundBlock block:
{
var statements = block.Statements;
if (statements.Length == 0)
{
break;
}

if (statements.Length == 1 && block.Locals.IsEmpty)
{
appendSource(statements[0]);
Expand Down Expand Up @@ -168,8 +175,9 @@ void appendSourceCore(BoundNode node, int indent, Dictionary<SynthesizedLocal, i
case BoundConditionalGoto gotoStatement:
{
append("if (");
append(gotoStatement.JumpIfTrue ? "" : "!");
append(gotoStatement.JumpIfTrue ? "" : "!(");
appendSource(gotoStatement.Condition);
append(gotoStatement.JumpIfTrue ? "" : ")");
append(") ");

append("goto ");
Expand Down Expand Up @@ -221,16 +229,7 @@ void appendSourceCore(BoundNode node, int indent, Dictionary<SynthesizedLocal, i

append(call.Method.Name);
append("(");
bool first = true;
foreach (var argument in call.Arguments)
{
if (!first)
{
append(", ");
}
first = false;
appendSource(argument);
}
appendSourceItems(call.Arguments);
append(")");
break;
}
Expand Down Expand Up @@ -339,9 +338,22 @@ void appendSourceCore(BoundNode node, int indent, Dictionary<SynthesizedLocal, i
}
case BoundBinaryOperator binary:
{
string relation = (binary.OperatorKind & BinaryOperatorKind.OpMask) switch
{
BinaryOperatorKind.GreaterThan => ">",
BinaryOperatorKind.GreaterThanOrEqual => ">=",
BinaryOperatorKind.LessThan => "<",
BinaryOperatorKind.LessThanOrEqual => "<=",
BinaryOperatorKind.Equal => "==",
BinaryOperatorKind.NotEqual => "!=",
BinaryOperatorKind.Addition => "+",
BinaryOperatorKind.Subtraction => "-",
_ => binary.OperatorKind.ToString()
};

appendSource(binary.Left);
append(" ");
append(binary.OperatorKind.ToString());
append(relation);
append(" ");
appendSource(binary.Right);
break;
Expand Down Expand Up @@ -370,11 +382,7 @@ void appendSourceCore(BoundNode node, int indent, Dictionary<SynthesizedLocal, i
case BoundListPattern listPattern:
{
append("[");
for (int i = 0; i < listPattern.Subpatterns.Length; i++)
{
if (i != 0) append(", ");
appendSource(listPattern.Subpatterns[i]);
}
appendSourceItems(listPattern.Subpatterns);
append("]");
break;
}
Expand Down Expand Up @@ -408,29 +416,30 @@ void appendSourceCore(BoundNode node, int indent, Dictionary<SynthesizedLocal, i
if (recursivePattern.Deconstruction is { IsDefault: false } deconstruction)
{
append("(");
for (int i = 0; i < deconstruction.Length; i++)
{
if (i != 0) append(", ");
appendSource(deconstruction[i].Pattern);
}
appendSourceItems(deconstruction);
append(")");
}

if (recursivePattern.Properties is { IsDefault: false } properties)
{
append("{");
for (int i = 0; i < properties.Length; i++)
{
if (i != 0) append(", ");
BoundPropertySubpattern property = properties[i];
append(property.Member?.Symbol?.Name);
append(": ");
appendSource(property.Pattern);
}
appendSourceItems(properties);
append("}");
}
break;
}
case BoundPositionalSubpattern positionalSubpattern:
{
appendSource(positionalSubpattern.Pattern);
break;
}
case BoundPropertySubpattern propertySubpattern:
{
append(propertySubpattern.Member?.Symbol?.Name);
append(": ");
appendSource(propertySubpattern.Pattern);
break;
}
case BoundDeclarationPattern declarationPattern:
{
if (declarationPattern.IsVar)
Expand All @@ -449,11 +458,7 @@ void appendSourceCore(BoundNode node, int indent, Dictionary<SynthesizedLocal, i
case BoundITuplePattern ituplePattern:
{
append("(");
for (int i = 0; i < ituplePattern.Subpatterns.Length; i++)
{
if (i != 0) append(", ");
appendSource(ituplePattern.Subpatterns[i].Pattern);
}
appendSourceItems(ituplePattern.Subpatterns);
append(")");
break;
}
Expand All @@ -473,6 +478,78 @@ void appendSourceCore(BoundNode node, int indent, Dictionary<SynthesizedLocal, i
appendConstantValue(relationalPattern.ConstantValue);
break;
}
case BoundObjectCreationExpression objectCreation:
{
append("new ");
append(objectCreation.Type.Name);

if (objectCreation.Type is NamedTypeSymbol { TypeArgumentsWithAnnotationsNoUseSiteDiagnostics: var typeArguments }
&& typeArguments.Length > 0)
{
appendTypeArguments(typeArguments);
}

append("(");
appendSourceItems(objectCreation.Arguments);
append(")");
break;
}
case BoundSwitchDispatch switchDispatch:
{
append("switch dispatch(");
appendSource(switchDispatch.Expression);
appendLine(")");
appendLine("{");
incrementIndent();

foreach (var (value, label) in switchDispatch.Cases)
{
append("case ");
appendConstantValue(value);
append(" => ");
appendLine(label.ToString());
}

append("default => ");
appendLine(switchDispatch.DefaultLabel.ToString());
decrementIndent();
appendLine("}");
break;
}
case BoundPropertyAccess propertyAccess:
{
var receiver = propertyAccess.ReceiverOpt;
if (receiver != null)
{
appendSource(receiver);
append(".");
}
append(propertyAccess.PropertySymbol.Name);
break;
}
case BoundParameter parameter:
{
append(parameter.ParameterSymbol.Name);
break;
}
case BoundBaseReference baseReference:
{
append("base");
break;
}
case BoundPassByCopy passByCopy:
{
append("passByCopy ");
appendSource(passByCopy.Expression);
break;
}
case BoundAsOperator asOperator:
{
appendSource(asOperator.Operand);
append(" as ");
appendSource(asOperator.TargetType);
break;
}
default:
appendLine(node.Kind.ToString());
break;
Expand All @@ -490,6 +567,15 @@ void appendSource(BoundNode? n)
}
}

void appendSourceItems<T>(ImmutableArray<T> nodes) where T : BoundNode
{
for (int i = 0; i < nodes.Length; i++)
{
if (i != 0) append(", ");
appendSource(nodes[i]);
}
}

void append(string? s)
{
builder.Append(s);
Expand Down Expand Up @@ -571,6 +657,24 @@ void appendConstantValue(ConstantValue? constantValueOpt)
break;
}
}

void appendTypeArguments(ImmutableArray<TypeWithAnnotations> typeArguments)
{
append("<");
bool first = true;
foreach (var typeArgument in typeArguments)
{
if (!first)
{
append(", ");
}

first = false;
append(typeArgument.Type.Name); // TODO2
}

append(">");
}
}
}
#endif
Expand Down
22 changes: 12 additions & 10 deletions src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -356,14 +356,17 @@ internal bool IsRuntimeAsyncEnabledIn(Symbol? symbol)

Debug.Assert(ReferenceEquals(method.ContainingAssembly, Assembly));

var methodReturn = method.ReturnType.OriginalDefinition;
if (((InternalSpecialType)methodReturn.ExtendedSpecialType) is not (
InternalSpecialType.System_Threading_Tasks_Task or
InternalSpecialType.System_Threading_Tasks_Task_T or
InternalSpecialType.System_Threading_Tasks_ValueTask or
InternalSpecialType.System_Threading_Tasks_ValueTask_T))
{
return false;
if (!method.IsAsyncReturningIAsyncEnumerable(this) && !method.IsAsyncReturningIAsyncEnumerator(this))
{
var methodReturn = method.ReturnType.OriginalDefinition;
if (((InternalSpecialType)methodReturn.ExtendedSpecialType) is not (
InternalSpecialType.System_Threading_Tasks_Task or
InternalSpecialType.System_Threading_Tasks_Task_T or
InternalSpecialType.System_Threading_Tasks_ValueTask or
InternalSpecialType.System_Threading_Tasks_ValueTask_T))
{
return false;
}
}

return symbol switch
Expand Down Expand Up @@ -2854,8 +2857,7 @@ internal void RecordImport(ExternAliasDirectiveSyntax syntax)

private void RecordImportInternal(CSharpSyntaxNode syntax)
{
// Note: the suppression will be unnecessary once LazyInitializer is properly annotated
LazyInitializer.EnsureInitialized(ref _lazyImportInfos)!.
LazyInitializer.EnsureInitialized(ref _lazyImportInfos).
TryAdd(new ImportInfo(syntax.SyntaxTree, syntax.Kind(), syntax.Span), default);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Reflection;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;

Expand Down Expand Up @@ -227,6 +228,9 @@ internal override bool SynthesizesLoweredBoundBody
get { return true; }
}

public override bool IsAsync => false;
internal override MethodImplAttributes ImplementationAttributes => default;

/// <summary>
/// Given a SynthesizedExplicitImplementationMethod (effectively a tuple (interface method, implementing method, implementing type)),
/// construct a BoundBlock body. Consider the tuple (Interface.Goo, Base.Goo, Derived). The generated method will look like:
Expand Down
Loading
Loading