Skip to content

Commit 7c55c2c

Browse files
committed
Move source generators to a feature branch
Revert "Merge pull request #12282 from cston/gen-move" This reverts commit e54f73d, reversing changes made to f42dea8.
1 parent e54f73d commit 7c55c2c

File tree

91 files changed

+4340
-49
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+4340
-49
lines changed

src/Compilers/CSharp/Portable/Binder/BinderFactory.BinderFactoryVisitor.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,15 @@ private Symbol GetMemberSymbol(string memberName, TextSpan memberSpan, NamedType
541541
{
542542
return sym;
543543
}
544+
545+
// Replaced members are not included in GetMembers().
546+
foreach (var replaced in sym.GetReplacedMembers())
547+
{
548+
if (InSpan(replaced.Locations, this.syntaxTree, memberSpan))
549+
{
550+
return replaced;
551+
}
552+
}
544553
}
545554

546555
return null;

src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,8 @@ private bool MemberGroupFinalValidationAccessibilityChecks(BoundExpression recei
542542
// Perform final validation of the method to be invoked.
543543

544544
Debug.Assert(memberSymbol.Kind != SymbolKind.Method ||
545-
memberSymbol.CanBeReferencedByName);
545+
memberSymbol.CanBeReferencedByName || //should be true since the caller has LookupOptions.MustBeReferenceableByName set
546+
(object)memberSymbol.ReplacedBy != null);
546547
//note that the same assert does not hold for all properties. Some properties and (all indexers) are not referenceable by name, yet
547548
//their binding brings them through here, perhaps needlessly.
548549

src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,8 @@ private BoundExpression BindExpressionInternal(ExpressionSyntax node, Diagnostic
447447
return BindThis((ThisExpressionSyntax)node, diagnostics);
448448
case SyntaxKind.BaseExpression:
449449
return BindBase((BaseExpressionSyntax)node, diagnostics);
450+
case SyntaxKind.OriginalExpression:
451+
return BindOriginal((OriginalExpressionSyntax)node, diagnostics);
450452
case SyntaxKind.InvocationExpression:
451453
return BindInvocationExpression((InvocationExpressionSyntax)node, diagnostics);
452454
case SyntaxKind.ArrayInitializerExpression:
@@ -1884,6 +1886,77 @@ private void GenerateExplicitConversionErrorsForTupleLiteralArguments(
18841886
}
18851887
}
18861888

1889+
private BoundExpression BindOriginal(OriginalExpressionSyntax syntax, DiagnosticBag diagnostics)
1890+
{
1891+
var containingMethod = (MethodSymbol)this.ContainingMember();
1892+
var symbol = containingMethod.AssociatedSymbol ?? containingMethod; // property, event, or non-accessor method
1893+
var receiver = symbol.IsStatic ? null : ThisReference(syntax, symbol.ContainingType, wasCompilerGenerated: true);
1894+
var replaced = symbol.Replaced;
1895+
1896+
if ((object)replaced == null)
1897+
{
1898+
Error(diagnostics, ErrorCode.ERR_NoOriginalMember, syntax, symbol);
1899+
return BadExpression(syntax, LookupResultKind.Empty, ImmutableArray.Create(symbol));
1900+
}
1901+
1902+
Debug.Assert(replaced.Kind == symbol.Kind);
1903+
1904+
switch (symbol.Kind)
1905+
{
1906+
case SymbolKind.Method:
1907+
{
1908+
var replacedMethod = (MethodSymbol)replaced;
1909+
var replacedByMethod = (MethodSymbol)symbol;
1910+
return new BoundMethodGroup(
1911+
syntax,
1912+
replacedByMethod.TypeArguments,
1913+
replacedMethod.Name,
1914+
ImmutableArray.Create(replacedMethod),
1915+
lookupSymbolOpt: replacedMethod,
1916+
lookupError: null,
1917+
flags: BoundMethodGroupFlags.None,
1918+
receiverOpt: receiver,
1919+
resultKind: LookupResultKind.Viable);
1920+
}
1921+
case SymbolKind.Property:
1922+
{
1923+
var replacedProperty = (PropertySymbol)replaced;
1924+
Debug.Assert((object)replacedProperty != null);
1925+
if (replacedProperty.IsIndexer || replacedProperty.IsIndexedProperty)
1926+
{
1927+
return new BoundPropertyGroup(
1928+
syntax,
1929+
ImmutableArray.Create(replacedProperty),
1930+
receiver,
1931+
LookupResultKind.Viable);
1932+
}
1933+
else
1934+
{
1935+
return new BoundPropertyAccess(
1936+
syntax,
1937+
receiver,
1938+
replacedProperty,
1939+
LookupResultKind.Viable,
1940+
replacedProperty.Type);
1941+
}
1942+
}
1943+
case SymbolKind.Event:
1944+
{
1945+
var replacedEvent = (EventSymbol)replaced;
1946+
Debug.Assert((object)replacedEvent != null);
1947+
return new BoundEventAccess(
1948+
syntax,
1949+
receiver,
1950+
replacedEvent,
1951+
replacedEvent.HasAssociatedField,
1952+
LookupResultKind.Viable,
1953+
replacedEvent.Type);
1954+
}
1955+
default:
1956+
throw ExceptionUtilities.UnexpectedValue(symbol.Kind);
1957+
}
1958+
}
1959+
18871960
/// <summary>
18881961
/// This implements the casting behavior described in section 6.2.3 of the spec:
18891962
///

src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,6 +1809,7 @@ private static CSharpSyntaxNode GetEventName(BoundEventAccess expr)
18091809
// This case is reachable only through SemanticModel
18101810
return ((QualifiedNameSyntax)syntax).Right;
18111811
case SyntaxKind.IdentifierName:
1812+
case SyntaxKind.OriginalExpression:
18121813
return syntax;
18131814
case SyntaxKind.MemberBindingExpression:
18141815
return ((MemberBindingExpressionSyntax)syntax).Name;

src/Compilers/CSharp/Portable/BoundTree/Expression.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ internal partial class BoundCall : IInvocationExpression
4343
(object)this.Method != null &&
4444
this.ReceiverOpt != null &&
4545
(this.Method.IsVirtual || this.Method.IsAbstract || this.Method.IsOverride) &&
46+
(object)this.Method.ReplacedBy == null &&
4647
!this.ReceiverOpt.SuppressVirtualCalls;
4748

4849
ImmutableArray<IArgument> IInvocationExpression.ArgumentsInSourceOrder
@@ -442,6 +443,7 @@ IOperation IMemberReferenceExpression.Instance
442443
bool IMethodBindingExpression.IsVirtual =>
443444
(object)this.MethodOpt != null &&
444445
(this.MethodOpt.IsVirtual || this.MethodOpt.IsAbstract || this.MethodOpt.IsOverride) &&
446+
(object)this.MethodOpt.ReplacedBy == null &&
445447
!this.SuppressVirtualCalls;
446448

447449
ISymbol IMemberReferenceExpression.Member => this.MethodOpt;
@@ -749,6 +751,7 @@ bool IMethodBindingExpression.IsVirtual
749751
var method = this.SymbolOpt;
750752
return (object)method != null &&
751753
(method.IsAbstract || method.IsOverride || method.IsVirtual) &&
754+
(object)method.ReplacedBy == null &&
752755
!this.SuppressVirtualCalls;
753756
}
754757
}

src/Compilers/CSharp/Portable/CSharpResources.Designer.cs

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Compilers/CSharp/Portable/CSharpResources.resx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4824,6 +4824,15 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
48244824
<data name="ERR_RefReturningCallAndAwait" xml:space="preserve">
48254825
<value>'await' cannot be used in an expression containing a call to '{0}' because it returns by reference</value>
48264826
</data>
4827+
<data name="ERR_NoOriginalMember" xml:space="preserve">
4828+
<value>No original member for '{0}'</value>
4829+
</data>
4830+
<data name="ERR_DuplicateReplace" xml:space="preserve">
4831+
<value>Type already contains a replacement for '{0}'</value>
4832+
</data>
4833+
<data name="ERR_PartialReplace" xml:space="preserve">
4834+
<value>Replacement methods cannot be partial</value>
4835+
</data>
48274836
<data name="ERR_ExpressionTreeContainsLocalFunction" xml:space="preserve">
48284837
<value>An expression tree may not contain a reference to a local function</value>
48294838
</data>

src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,11 @@ private void EmitCallExpression(BoundCall call, UseKind useKind)
13821382

13831383
tempOpt = EmitReceiverRef(receiver, isAccessConstrained: callKind == CallKind.ConstrainedCallVirt);
13841384
}
1385+
1386+
if (method.ReplacedBy != null)
1387+
{
1388+
callKind = CallKind.Call;
1389+
}
13851390
}
13861391

13871392
// When emitting a callvirt to a virtual method we always emit the method info of the

src/Compilers/CSharp/Portable/CommandLine/CSharpCompiler.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,13 @@ protected override bool TryGetCompilerDiagnosticCode(string diagnosticId, out ui
271271
return CommonCompiler.TryGetCompilerDiagnosticCode(diagnosticId, "CS", out code);
272272
}
273273

274-
protected override ImmutableArray<DiagnosticAnalyzer> ResolveAnalyzersFromArguments(
274+
protected override void ResolveAnalyzersAndGeneratorsFromArguments(
275275
List<DiagnosticInfo> diagnostics,
276-
CommonMessageProvider messageProvider)
276+
CommonMessageProvider messageProvider,
277+
out ImmutableArray<DiagnosticAnalyzer> analyzers,
278+
out ImmutableArray<SourceGenerator> generators)
277279
{
278-
return Arguments.ResolveAnalyzersFromArguments(LanguageNames.CSharp, diagnostics, messageProvider, AssemblyLoader);
280+
Arguments.ResolveAnalyzersAndGeneratorsFromArguments(LanguageNames.CSharp, diagnostics, messageProvider, AssemblyLoader, out analyzers, out generators);
279281
}
280282
}
281283
}

src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,9 @@ private void CompileNamedType(NamedTypeSymbol containingType)
378378
bool hasStaticConstructor = false;
379379

380380
var members = containingType.GetMembers();
381+
// 'extendedOrdinal' is used for replaced methods, to ensure all methods
382+
// defined in source in the containing type have unique ordinals.
383+
int extendedOrdinal = members.Length;
381384
for (int memberOrdinal = 0; memberOrdinal < members.Length; memberOrdinal++)
382385
{
383386
var member = members[memberOrdinal];
@@ -436,6 +439,18 @@ private void CompileNamedType(NamedTypeSymbol containingType)
436439
{
437440
hasStaticConstructor = true;
438441
}
442+
443+
// Replaced methods are not included in GetMembers().
444+
foreach (MethodSymbol replaced in method.GetReplacedMembers())
445+
{
446+
if (replaced.IsImplicitlyDeclared &&
447+
(replaced.MethodKind == MethodKind.EventAdd || replaced.MethodKind == MethodKind.EventRemove))
448+
{
449+
continue;
450+
}
451+
CompileMethod(replaced, extendedOrdinal, ref processedInitializers, synthesizedSubmissionFields, compilationState);
452+
extendedOrdinal++;
453+
}
439454
break;
440455
}
441456

0 commit comments

Comments
 (0)