提交 3295ab18 编写于 作者: A Andy Gocke

Respond to PR comments

上级 26923316
......@@ -6804,9 +6804,8 @@ private BoundExpression BindArrayAccess(ExpressionSyntax node, BoundExpression e
}
}
HashSet<DiagnosticInfo> useSiteDiagnostics = null;
var resultType = rank == 1 &&
convertedArguments[0].Type == GetWellKnownType(WellKnownType.System_Range, ref useSiteDiagnostics)
convertedArguments[0].Type == Compilation.GetWellKnownType(WellKnownType.System_Range)
? arrayType
: arrayType.ElementType.TypeSymbol;
......@@ -6839,7 +6838,7 @@ private BoundExpression ConvertToArrayIndex(BoundExpression index, SyntaxNode no
TryImplicitConversionToArrayIndex(index, WellKnownType.System_Range, node, diagnostics);
}
if (result == null)
if (result is null)
{
// Give the error that would be given upon conversion to int32.
NamedTypeSymbol int32 = GetSpecialType(SpecialType.System_Int32, diagnostics, node);
......@@ -6860,19 +6859,19 @@ private BoundExpression TryImplicitConversionToArrayIndex(BoundExpression expr,
HashSet<DiagnosticInfo> useSiteDiagnostics = null;
TypeSymbol type = GetWellKnownType(wellKnownType, ref useSiteDiagnostics);
if (!type.IsErrorType())
if (type.IsErrorType())
{
var attemptDiagnostics = DiagnosticBag.GetInstance();
var result = TryImplicitConversionToArrayIndex(expr, type, node, attemptDiagnostics);
if (!(result is null))
{
diagnostics.AddRange(attemptDiagnostics);
}
attemptDiagnostics.Free();
return result;
return null;
}
return null;
var attemptDiagnostics = DiagnosticBag.GetInstance();
var result = TryImplicitConversionToArrayIndex(expr, type, node, attemptDiagnostics);
if (!(result is null))
{
diagnostics.AddRange(attemptDiagnostics);
}
attemptDiagnostics.Free();
return result;
}
private BoundExpression TryImplicitConversionToArrayIndex(BoundExpression expr, SpecialType specialType, SyntaxNode node, DiagnosticBag diagnostics)
......@@ -7157,19 +7156,18 @@ private BoundExpression BindIndexedPropertyAccess(SyntaxNode syntax, BoundExpres
if (!analyzedArguments.HasErrors)
{
// PROTOTYPE: REMOVE BEFORE SHIPPING DEV16
// https://github.com/dotnet/roslyn/issues/30620
// Pretend like there are indexers that support range and index
if (receiverOpt?.Type.SpecialType == SpecialType.System_String &&
analyzedArguments.Arguments.Count == 1)
{
HashSet<DiagnosticInfo> diags = null;
var argType = analyzedArguments.Arguments[0].Type;
TypeSymbol resultType = null;
if (argType == GetWellKnownType(WellKnownType.System_Index, ref diags))
if (argType == Compilation.GetWellKnownType(WellKnownType.System_Index))
{
resultType = GetSpecialType(SpecialType.System_Char, diagnostics, syntax);
}
else if (argType == GetWellKnownType(WellKnownType.System_Range, ref diags))
else if (argType == Compilation.GetWellKnownType(WellKnownType.System_Range))
{
resultType = GetSpecialType(SpecialType.System_String, diagnostics, syntax);
}
......@@ -7177,7 +7175,8 @@ private BoundExpression BindIndexedPropertyAccess(SyntaxNode syntax, BoundExpres
if (!(resultType is null))
{
var args = analyzedArguments.Arguments.ToImmutable();
overloadResolutionResult.Free();
return new BoundIndexerAccess(
syntax,
receiverOpt,
......
......@@ -527,21 +527,22 @@ public override BoundNode VisitTypeOrInstanceInitializers(BoundTypeOrInstanceIni
public override BoundNode VisitArrayAccess(BoundArrayAccess node)
{
// https://github.com/dotnet/roslyn/issues/30620
// If the array access index is of type System.Index or System.Range
// we need to translate it into a call into an actual indexer, instead
// we need to emit code as if there were a real indexer, instead
// of a simple array element access.
if (this.EmitModule is null ||
node.Indices.Length != 1 ||
node.Indices[0].Type.SpecialType != SpecialType.None)
if (node.Indices.Length != 1)
{
return base.VisitArrayAccess(node);
}
// PROTOTYPE: THIS MUST BE REMOVED BEFORE DEV16
// Since it takes a long time to update mscorlib we fake up the right
// code to pretend there are two indexers that support Index and Range
// on arrays.
TypeSymbol rawIndexType = node.Indices[0].Type;
if (!(rawIndexType == _compilation.GetWellKnownType(WellKnownType.System_Index) ||
rawIndexType == _compilation.GetWellKnownType(WellKnownType.System_Range)))
{
return base.VisitArrayAccess(node);
}
var syntax = node.Syntax;
var F = _factory;
......@@ -603,7 +604,7 @@ public override BoundNode VisitArrayAccess(BoundArrayAccess node)
BinaryOperatorKind.Subtraction,
F.SpecialType(SpecialType.System_Int32),
F.ArrayLength(arrayLocal),
F.Property(F.Property(indexLocal, rangeEndSymbol), indexValueSymbol)),
F.Property(F.Property(indexLocal, rangeStartSymbol), indexValueSymbol)),
F.Property(F.Property(indexLocal, rangeStartSymbol), indexValueSymbol),
F.SpecialType(SpecialType.System_Int32)),
out BoundAssignmentOperator startAssign);
......
......@@ -83,7 +83,7 @@ private BoundExpression VisitIndexerAccess(BoundIndexerAccess node, bool isLeftO
// NOTE: This is done later by MakeArguments, for now we just lower each argument.
ImmutableArray<BoundExpression> rewrittenArguments = VisitList(node.Arguments);
// PROTOTYPE: REMOVE BEFORE SHIPPING DEV16
// https://github.com/dotnet/roslyn/issues/30620
if (rewrittenReceiver?.Type.SpecialType == SpecialType.System_String &&
rewrittenArguments.Length == 1 && rewrittenArguments[0].Type.SpecialType == SpecialType.None)
{
......@@ -111,13 +111,13 @@ private BoundExpression VisitIndexerAccess(BoundIndexerAccess node, bool isLeftO
stringAssign),
F.Conditional(
F.Property(indexLocal, indexFromEndSymbol),
F.Property(stringLocal, node.Indexer,
F.Indexer(stringLocal, node.Indexer,
F.Binary(
BinaryOperatorKind.Subtraction,
F.SpecialType(SpecialType.System_Int32),
F.Call(stringLocal, F.SpecialMethod(SpecialMember.System_String__Length)),
indexValueExpr)),
F.Property(stringLocal, node.Indexer, indexValueExpr),
F.Indexer(stringLocal, node.Indexer, indexValueExpr),
F.SpecialType(SpecialType.System_Char)));
}
else if (argType == _compilation.GetWellKnownType(WellKnownType.System_Range))
......@@ -137,7 +137,7 @@ private BoundExpression VisitIndexerAccess(BoundIndexerAccess node, bool isLeftO
BinaryOperatorKind.Subtraction,
F.SpecialType(SpecialType.System_Int32),
F.Call(stringLocal, F.SpecialMethod(SpecialMember.System_String__Length)),
F.Property(F.Property(indexLocal, rangeEndSymbol), indexValueSymbol)),
F.Property(F.Property(indexLocal, rangeStartSymbol), indexValueSymbol)),
F.Property(F.Property(indexLocal, rangeStartSymbol), indexValueSymbol),
F.SpecialType(SpecialType.System_Int32)),
out BoundAssignmentOperator startAssign);
......
......@@ -288,7 +288,7 @@ public BoundExpression Property(BoundExpression receiverOpt, PropertySymbol prop
return Call(receiverOpt, property.GetMethod); // TODO: should we use property.GetBaseProperty().GetMethod to ensure we generate a call to the overridden method?
}
public BoundExpression Property(BoundExpression receiverOpt, PropertySymbol property, BoundExpression arg0)
public BoundExpression Indexer(BoundExpression receiverOpt, PropertySymbol property, BoundExpression arg0)
{
Debug.Assert((receiverOpt == null) == property.IsStatic);
return Call(receiverOpt, property.GetMethod, arg0); // TODO: should we use property.GetBaseProperty().GetMethod to ensure we generate a call to the overridden method?
......
......@@ -8,6 +8,22 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.CodeGen
{
public class IndexAndRangeTests : CSharpTestBase
{
[Fact]
public void RangeIndexerStringFromEndStart()
{
var comp = CreateCompilationWithIndexAndRange(@"
using System;
class C
{
public static void Main()
{
var s = ""abcdef"";
Console.WriteLine(s[^2..]);
}
}", options: TestOptions.ReleaseExe);
CompileAndVerify(comp, expectedOutput: "ef");
}
[Fact]
public void IndexIndexerStringTwoArgs()
{
......@@ -480,6 +496,30 @@ .maxstack 5
");
}
[Fact]
public void FakeRangeStartFromEndIndexerArray()
{
var comp = CreateCompilationWithIndexAndRange(@"
using System;
class C
{
public static void Main()
{
var arr = new[] { 1, 2, 3, 11 };
var result = M(arr);
Console.WriteLine(result.Length);
foreach (var x in result)
{
Console.WriteLine(x);
}
}
public static int[] M(int[] array) => array[^2..];
}", TestOptions.ReleaseExe);
CompileAndVerify(comp, expectedOutput: @"2
3
11");
}
[Fact]
public void FakeRangeToEndIndexerArray()
{
......
......@@ -884,6 +884,10 @@ public void AllWellKnownTypeMembers()
case WellKnownMember.System_ReadOnlySpan_T__get_Item:
case WellKnownMember.System_ReadOnlySpan_T__get_Length:
case WellKnownMember.System_Index__ctor:
case WellKnownMember.System_Index__FromEnd:
case WellKnownMember.System_Index__Value:
case WellKnownMember.System_Range__Start:
case WellKnownMember.System_Range__End:
case WellKnownMember.System_Range__All:
case WellKnownMember.System_Range__Create:
case WellKnownMember.System_Range__FromStart:
......
......@@ -657,6 +657,10 @@ End Namespace
WellKnownMember.System_Runtime_CompilerServices_IsByRefLikeAttribute__ctor,
WellKnownMember.System_Runtime_CompilerServices_IsUnmanagedAttribute__ctor,
WellKnownMember.System_Index__ctor,
WellKnownMember.System_Index__FromEnd,
WellKnownMember.System_Index__Value,
WellKnownMember.System_Range__Start,
WellKnownMember.System_Range__End,
WellKnownMember.System_Range__All,
WellKnownMember.System_Range__Create,
WellKnownMember.System_Range__FromStart,
......@@ -779,6 +783,10 @@ End Namespace
WellKnownMember.System_Runtime_CompilerServices_IsByRefLikeAttribute__ctor,
WellKnownMember.System_Runtime_CompilerServices_IsUnmanagedAttribute__ctor,
WellKnownMember.System_Index__ctor,
WellKnownMember.System_Index__FromEnd,
WellKnownMember.System_Index__Value,
WellKnownMember.System_Range__Start,
WellKnownMember.System_Range__End,
WellKnownMember.System_Range__All,
WellKnownMember.System_Range__Create,
WellKnownMember.System_Range__FromStart,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册