Make a few nodes lazy where they weren't previously, and address a couple of other feedback items.

上级 6a894871
...@@ -414,7 +414,7 @@ private IOperation CreateBoundCallOperation(BoundCall boundCall) ...@@ -414,7 +414,7 @@ private IOperation CreateBoundCallOperation(BoundCall boundCall)
return new CSharpLazyInvocationOperation(this, boundCall, targetMethod, isVirtual, _semanticModel, syntax, type, constantValue, isImplicit); return new CSharpLazyInvocationOperation(this, boundCall, targetMethod, isVirtual, _semanticModel, syntax, type, constantValue, isImplicit);
} }
private IOperation CreateBoundLocalOperation(BoundLocal boundLocal) internal IOperation CreateBoundLocalOperation(BoundLocal boundLocal, bool createDeclaration = true)
{ {
ILocalSymbol local = boundLocal.LocalSymbol; ILocalSymbol local = boundLocal.LocalSymbol;
bool isDeclaration = boundLocal.DeclarationKind != BoundLocalDeclarationKind.None; bool isDeclaration = boundLocal.DeclarationKind != BoundLocalDeclarationKind.None;
...@@ -425,13 +425,15 @@ private IOperation CreateBoundLocalOperation(BoundLocal boundLocal) ...@@ -425,13 +425,15 @@ private IOperation CreateBoundLocalOperation(BoundLocal boundLocal)
if (isDeclaration && syntax is DeclarationExpressionSyntax declarationExpressionSyntax) if (isDeclaration && syntax is DeclarationExpressionSyntax declarationExpressionSyntax)
{ {
syntax = declarationExpressionSyntax.Designation; syntax = declarationExpressionSyntax.Designation;
var localReference = new LocalReferenceOperation(local, isDeclaration, _semanticModel, syntax, type, constantValue, isImplicit); if (createDeclaration)
return new DeclarationExpressionOperation(localReference, _semanticModel, declarationExpressionSyntax, type, constantValue: default, isImplicit: false); {
return new CSharpLazyDeclarationExpressionOperation(this, boundLocal, _semanticModel, declarationExpressionSyntax, type, constantValue: default, isImplicit: false);
}
} }
return new LocalReferenceOperation(local, isDeclaration, _semanticModel, syntax, type, constantValue, isImplicit); return new LocalReferenceOperation(local, isDeclaration, _semanticModel, syntax, type, constantValue, isImplicit);
} }
private IOperation CreateBoundFieldAccessOperation(BoundFieldAccess boundFieldAccess) internal IOperation CreateBoundFieldAccessOperation(BoundFieldAccess boundFieldAccess, bool createDeclaration = true)
{ {
IFieldSymbol field = boundFieldAccess.FieldSymbol; IFieldSymbol field = boundFieldAccess.FieldSymbol;
bool isDeclaration = boundFieldAccess.IsDeclaration; bool isDeclaration = boundFieldAccess.IsDeclaration;
...@@ -443,8 +445,11 @@ private IOperation CreateBoundFieldAccessOperation(BoundFieldAccess boundFieldAc ...@@ -443,8 +445,11 @@ private IOperation CreateBoundFieldAccessOperation(BoundFieldAccess boundFieldAc
if (isDeclaration && syntax is DeclarationExpressionSyntax declarationExpressionSyntax) if (isDeclaration && syntax is DeclarationExpressionSyntax declarationExpressionSyntax)
{ {
syntax = declarationExpressionSyntax.Designation; syntax = declarationExpressionSyntax.Designation;
var fieldReference = new CSharpLazyFieldReferenceOperation(this, instance, field, isDeclaration, _semanticModel, syntax, type, constantValue, isImplicit);
return new DeclarationExpressionOperation(fieldReference, _semanticModel, declarationExpressionSyntax, type, constantValue: default, isImplicit: false); if (createDeclaration)
{
return new CSharpLazyDeclarationExpressionOperation(this, boundFieldAccess, _semanticModel, declarationExpressionSyntax, type, constantValue: default, isImplicit: false);
}
} }
return new CSharpLazyFieldReferenceOperation(this, instance, field, isDeclaration, _semanticModel, syntax, type, constantValue, isImplicit); return new CSharpLazyFieldReferenceOperation(this, instance, field, isDeclaration, _semanticModel, syntax, type, constantValue, isImplicit);
} }
...@@ -520,7 +525,6 @@ private IOperation CreateBoundIndexerAccessOperation(BoundIndexerAccess boundInd ...@@ -520,7 +525,6 @@ private IOperation CreateBoundIndexerAccessOperation(BoundIndexerAccess boundInd
return CreateInvalidExpressionForHasArgumentsExpression(boundIndexerAccess.ReceiverOpt, boundIndexerAccess.Arguments, null, syntax, type, constantValue, isImplicit); return CreateInvalidExpressionForHasArgumentsExpression(boundIndexerAccess.ReceiverOpt, boundIndexerAccess.Arguments, null, syntax, type, constantValue, isImplicit);
} }
BoundNode instance = boundIndexerAccess.ReceiverOpt;
return new CSharpLazyPropertyReferenceOperation(this, boundIndexerAccess, isObjectOrCollectionInitializer, property, _semanticModel, syntax, type, constantValue, isImplicit); return new CSharpLazyPropertyReferenceOperation(this, boundIndexerAccess, isObjectOrCollectionInitializer, property, _semanticModel, syntax, type, constantValue, isImplicit);
} }
...@@ -696,11 +700,6 @@ private IObjectOrCollectionInitializerOperation CreateBoundCollectionInitializer ...@@ -696,11 +700,6 @@ private IObjectOrCollectionInitializerOperation CreateBoundCollectionInitializer
private IOperation CreateBoundObjectInitializerMemberOperation(BoundObjectInitializerMember boundObjectInitializerMember, bool isObjectOrCollectionInitializer = false) private IOperation CreateBoundObjectInitializerMemberOperation(BoundObjectInitializerMember boundObjectInitializerMember, bool isObjectOrCollectionInitializer = false)
{ {
Symbol memberSymbol = boundObjectInitializerMember.MemberSymbol; Symbol memberSymbol = boundObjectInitializerMember.MemberSymbol;
IOperation instance = memberSymbol?.IsStatic == true ?
null :
CreateImplicitReciever(boundObjectInitializerMember.Syntax, boundObjectInitializerMember.ReceiverType);
SyntaxNode syntax = boundObjectInitializerMember.Syntax; SyntaxNode syntax = boundObjectInitializerMember.Syntax;
ITypeSymbol type = boundObjectInitializerMember.Type; ITypeSymbol type = boundObjectInitializerMember.Type;
Optional<object> constantValue = ConvertToOptional(boundObjectInitializerMember.ConstantValue); Optional<object> constantValue = ConvertToOptional(boundObjectInitializerMember.ConstantValue);
...@@ -720,10 +719,10 @@ private IOperation CreateBoundObjectInitializerMemberOperation(BoundObjectInitia ...@@ -720,10 +719,10 @@ private IOperation CreateBoundObjectInitializerMemberOperation(BoundObjectInitia
case SymbolKind.Field: case SymbolKind.Field:
var field = (FieldSymbol)memberSymbol; var field = (FieldSymbol)memberSymbol;
bool isDeclaration = false; bool isDeclaration = false;
return new FieldReferenceOperation(field, isDeclaration, instance, _semanticModel, syntax, type, constantValue, isImplicit); return new FieldReferenceOperation(field, isDeclaration, createReceiver(), _semanticModel, syntax, type, constantValue, isImplicit);
case SymbolKind.Event: case SymbolKind.Event:
var eventSymbol = (EventSymbol)memberSymbol; var eventSymbol = (EventSymbol)memberSymbol;
return new EventReferenceOperation(eventSymbol, instance, _semanticModel, syntax, type, constantValue, isImplicit); return new EventReferenceOperation(eventSymbol, createReceiver(), _semanticModel, syntax, type, constantValue, isImplicit);
case SymbolKind.Property: case SymbolKind.Property:
var property = (PropertySymbol)memberSymbol; var property = (PropertySymbol)memberSymbol;
if (boundObjectInitializerMember.Arguments.Any()) if (boundObjectInitializerMember.Arguments.Any())
...@@ -742,6 +741,10 @@ private IOperation CreateBoundObjectInitializerMemberOperation(BoundObjectInitia ...@@ -742,6 +741,10 @@ private IOperation CreateBoundObjectInitializerMemberOperation(BoundObjectInitia
default: default:
throw ExceptionUtilities.Unreachable; throw ExceptionUtilities.Unreachable;
} }
IOperation createReceiver() => memberSymbol?.IsStatic == true ?
null :
CreateImplicitReciever(boundObjectInitializerMember.Syntax, boundObjectInitializerMember.ReceiverType);
} }
private IOperation CreateBoundDynamicObjectInitializerMemberOperation(BoundDynamicObjectInitializerMember boundDynamicObjectInitializerMember) private IOperation CreateBoundDynamicObjectInitializerMemberOperation(BoundDynamicObjectInitializerMember boundDynamicObjectInitializerMember)
...@@ -1789,17 +1792,17 @@ private IExpressionStatementOperation CreateBoundExpressionStatementOperation(Bo ...@@ -1789,17 +1792,17 @@ private IExpressionStatementOperation CreateBoundExpressionStatementOperation(Bo
return new CSharpLazyExpressionStatementOperation(this, expression, _semanticModel, syntax, type, constantValue, isImplicit); return new CSharpLazyExpressionStatementOperation(this, expression, _semanticModel, syntax, type, constantValue, isImplicit);
} }
private IOperation CreateBoundTupleLiteralOperation(BoundTupleLiteral boundTupleLiteral) internal IOperation CreateBoundTupleLiteralOperation(BoundTupleLiteral boundTupleLiteral, bool createDeclaration = true)
{ {
return CreateTupleOperation(boundTupleLiteral, boundTupleLiteral.Type); return CreateTupleOperation(boundTupleLiteral, boundTupleLiteral.Type, createDeclaration);
} }
private IOperation CreateBoundConvertedTupleLiteralOperation(BoundConvertedTupleLiteral boundConvertedTupleLiteral) internal IOperation CreateBoundConvertedTupleLiteralOperation(BoundConvertedTupleLiteral boundConvertedTupleLiteral, bool createDeclaration = true)
{ {
return CreateTupleOperation(boundConvertedTupleLiteral, boundConvertedTupleLiteral.NaturalTypeOpt); return CreateTupleOperation(boundConvertedTupleLiteral, boundConvertedTupleLiteral.NaturalTypeOpt, createDeclaration);
} }
private IOperation CreateTupleOperation(BoundTupleExpression boundTupleExpression, ITypeSymbol naturalType) internal IOperation CreateTupleOperation(BoundTupleExpression boundTupleExpression, ITypeSymbol naturalType, bool createDeclaration)
{ {
SyntaxNode syntax = boundTupleExpression.Syntax; SyntaxNode syntax = boundTupleExpression.Syntax;
bool isImplicit = boundTupleExpression.WasCompilerGenerated; bool isImplicit = boundTupleExpression.WasCompilerGenerated;
...@@ -1807,9 +1810,11 @@ private IOperation CreateTupleOperation(BoundTupleExpression boundTupleExpressio ...@@ -1807,9 +1810,11 @@ private IOperation CreateTupleOperation(BoundTupleExpression boundTupleExpressio
Optional<object> constantValue = default; Optional<object> constantValue = default;
if (syntax is DeclarationExpressionSyntax declarationExpressionSyntax) if (syntax is DeclarationExpressionSyntax declarationExpressionSyntax)
{ {
var tupleSyntax = declarationExpressionSyntax.Designation; syntax = declarationExpressionSyntax.Designation;
var tuple = new CSharpLazyTupleOperation(this, boundTupleExpression, _semanticModel, tupleSyntax, type, naturalType, constantValue, isImplicit); if (createDeclaration)
return new DeclarationExpressionOperation(tuple, _semanticModel, declarationExpressionSyntax, type, constantValue: default, isImplicit: false); {
return new CSharpLazyDeclarationExpressionOperation(this, boundTupleExpression, _semanticModel, declarationExpressionSyntax, type, constantValue: default, isImplicit: false);
}
} }
return new CSharpLazyTupleOperation(this, boundTupleExpression, _semanticModel, syntax, type, naturalType, constantValue, isImplicit); return new CSharpLazyTupleOperation(this, boundTupleExpression, _semanticModel, syntax, type, naturalType, constantValue, isImplicit);
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Operations namespace Microsoft.CodeAnalysis.Operations
{ {
...@@ -205,6 +208,42 @@ protected override IOperation CreateValue() ...@@ -205,6 +208,42 @@ protected override IOperation CreateValue()
} }
} }
internal sealed class CSharpLazyDeclarationExpressionOperation : LazyDeclarationExpressionOperation
{
private readonly CSharpOperationFactory _operationFactory;
private readonly BoundExpression _underlyingReference;
public CSharpLazyDeclarationExpressionOperation(CSharpOperationFactory operationFactory, BoundExpression underlyingReference, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(semanticModel, syntax, type, constantValue, isImplicit)
{
Debug.Assert(underlyingReference.Kind == BoundKind.Local ||
underlyingReference.Kind == BoundKind.FieldAccess ||
underlyingReference is BoundTupleExpression);
_operationFactory = operationFactory;
_underlyingReference = underlyingReference;
}
protected override IOperation CreateExpression()
{
SyntaxNode underlyingSyntax = ((DeclarationExpressionSyntax)_underlyingReference.Syntax).Designation;
switch (_underlyingReference)
{
case BoundLocal local:
return _operationFactory.CreateBoundLocalOperation(local, createDeclaration: false);
case BoundTupleLiteral tupleLiteral:
return _operationFactory.CreateBoundTupleLiteralOperation(tupleLiteral, createDeclaration: false);
case BoundConvertedTupleLiteral convertedTupleLiteral:
return _operationFactory.CreateBoundConvertedTupleLiteralOperation(convertedTupleLiteral, createDeclaration: false);
case BoundFieldAccess fieldAccess:
return _operationFactory.CreateBoundFieldAccessOperation(fieldAccess, createDeclaration: false);
default:
throw ExceptionUtilities.UnexpectedValue(_underlyingReference.Kind);
}
}
}
internal sealed class CSharpLazyAwaitOperation : LazyAwaitOperation internal sealed class CSharpLazyAwaitOperation : LazyAwaitOperation
{ {
private readonly CSharpOperationFactory _operationFactory; private readonly CSharpOperationFactory _operationFactory;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册