本文整理汇总了C#中Microsoft.CodeAnalysis.CSharp.BoundExpression.AsImmutableOrNull方法的典型用法代码示例。如果您正苦于以下问题:C# BoundExpression.AsImmutableOrNull方法的具体用法?C# BoundExpression.AsImmutableOrNull怎么用?C# BoundExpression.AsImmutableOrNull使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Microsoft.CodeAnalysis.CSharp.BoundExpression
的用法示例。
在下文中一共展示了BoundExpression.AsImmutableOrNull方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: BindAnonymousObjectCreation
private BoundExpression BindAnonymousObjectCreation(AnonymousObjectCreationExpressionSyntax node, DiagnosticBag diagnostics)
{
// prepare
var initializers = node.Initializers;
int fieldCount = initializers.Count;
bool hasError = false;
// bind field initializers
BoundExpression[] boundExpressions = new BoundExpression[fieldCount];
AnonymousTypeField[] fields = new AnonymousTypeField[fieldCount];
CSharpSyntaxNode[] fieldSyntaxNodes = new CSharpSyntaxNode[fieldCount];
// WARNING: Note that SemanticModel.GetDeclaredSymbol for field initializer node relies on
// the fact that the order of properties in anonymous type template corresponds
// 1-to-1 to the appropriate filed initializer syntax nodes; This means such
// correspondence must be preserved all the time including erroneos scenarios
// set of names already used
HashSet<string> uniqueFieldNames = new HashSet<string>();
for (int i = 0; i < fieldCount; i++)
{
AnonymousObjectMemberDeclaratorSyntax fieldInitializer = initializers[i];
NameEqualsSyntax nameEquals = fieldInitializer.NameEquals;
ExpressionSyntax expression = fieldInitializer.Expression;
SyntaxToken nameToken = default(SyntaxToken);
if (nameEquals != null)
{
nameToken = nameEquals.Name.Identifier;
}
else
{
nameToken = expression.ExtractAnonymousTypeMemberName();
}
hasError = hasError || expression.HasErrors;
boundExpressions[i] = this.BindValue(expression, diagnostics, BindValueKind.RValue);
// check the name to be unique
string fieldName = null;
if (nameToken.Kind() == SyntaxKind.IdentifierToken)
{
fieldName = nameToken.ValueText;
if (uniqueFieldNames.Contains(fieldName))
{
// name duplication
Error(diagnostics, ErrorCode.ERR_AnonymousTypeDuplicatePropertyName, fieldInitializer);
hasError = true;
fieldName = null;
}
else
{
uniqueFieldNames.Add(fieldName);
}
}
else
{
// there is something wrong with field's name
hasError = true;
}
// calculate the expression's type and report errors if needed
TypeSymbol fieldType = GetAnonymousTypeFieldType(boundExpressions[i], fieldInitializer, diagnostics, ref hasError);
// build anonymous type field descriptor
fieldSyntaxNodes[i] = (nameToken.Kind() == SyntaxKind.IdentifierToken) ? (CSharpSyntaxNode)nameToken.Parent : fieldInitializer;
fields[i] = new AnonymousTypeField(fieldName == null ? "$" + i.ToString() : fieldName, fieldSyntaxNodes[i].Location, fieldType);
// NOTE: ERR_InvalidAnonymousTypeMemberDeclarator (CS0746) would be generated by parser if needed
}
// Create anonymous type
AnonymousTypeManager manager = this.Compilation.AnonymousTypeManager;
AnonymousTypeDescriptor descriptor = new AnonymousTypeDescriptor(fields.AsImmutableOrNull(), node.NewKeyword.GetLocation());
NamedTypeSymbol anonymousType = manager.ConstructAnonymousTypeSymbol(descriptor);
// declarators - bound nodes created for providing semantic info
// on anonymous type fields having explicitly specified name
ArrayBuilder<BoundAnonymousPropertyDeclaration> declarators =
ArrayBuilder<BoundAnonymousPropertyDeclaration>.GetInstance();
for (int i = 0; i < fieldCount; i++)
{
NameEqualsSyntax explicitName = initializers[i].NameEquals;
if (explicitName != null)
{
AnonymousTypeField field = fields[i];
if (field.Name != null)
{
// get property symbol and create a bound property declaration node
foreach (var symbol in anonymousType.GetMembers(field.Name))
{
if (symbol.Kind == SymbolKind.Property)
{
declarators.Add(new BoundAnonymousPropertyDeclaration(fieldSyntaxNodes[i], (PropertySymbol)symbol, field.Type));
break;
}
}
}
}
//.........这里部分代码省略.........
示例2: Array
public BoundExpression Array(TypeSymbol elementType, BoundExpression[] elements)
{
return Array(elementType, elements.AsImmutableOrNull());
}
示例3: TransformCompoundAssignmentLHS
//.........这里部分代码省略.........
ArrayBuilder<BoundAssignmentOperator> storesToTemps = ArrayBuilder<BoundAssignmentOperator>.GetInstance(rewrittenArguments.Length);
ArrayBuilder<RefKind> refKinds = ArrayBuilder<RefKind>.GetInstance(parameters.Length, RefKind.None);
// Step one: Store everything that is non-trivial into a temporary; record the
// stores in storesToTemps and make the actual argument a reference to the temp.
// Do not yet attempt to deal with params arrays or optional arguments.
BuildStoresToTemps(expanded, argsToParamsOpt, argumentRefKinds, rewrittenArguments, actualArguments, refKinds, storesToTemps);
// Step two: If we have a params array, build the array and fill in the argument.
if (expanded)
{
BoundExpression array = BuildParamsArray(syntax, indexer, argsToParamsOpt, rewrittenArguments, parameters, actualArguments[actualArguments.Length - 1]);
BoundAssignmentOperator storeToTemp;
var boundTemp = this.factory.StoreToTemp(array, out storeToTemp);
stores.Add(storeToTemp);
temps.Add(boundTemp.LocalSymbol);
actualArguments[actualArguments.Length - 1] = boundTemp;
}
// Step three: Now fill in the optional arguments. (Dev11 uses the
// getter for optional arguments in compound assignments.)
var getMethod = indexer.GetOwnOrInheritedGetMethod();
Debug.Assert((object)getMethod != null);
InsertMissingOptionalArguments(syntax, getMethod.Parameters, actualArguments);
// For a call, step four would be to optimize away some of the temps. However, we need them all to prevent
// duplicate side-effects, so we'll skip that step.
if (indexer.ContainingType.IsComImport)
{
RewriteArgumentsForComCall(parameters, actualArguments, refKinds, temps);
}
rewrittenArguments = actualArguments.AsImmutableOrNull();
foreach (BoundAssignmentOperator tempAssignment in storesToTemps)
{
temps.Add(((BoundLocal)tempAssignment.Left).LocalSymbol);
stores.Add(tempAssignment);
}
storesToTemps.Free();
argumentRefKinds = GetRefKindsOrNull(refKinds);
refKinds.Free();
// CONSIDER: this is a temporary object that will be rewritten away before this lowering completes.
// Mitigation: this will only produce short-lived garbage for compound assignments and increments/decrements of indexers.
return new BoundIndexerAccess(
syntax,
transformedReceiver,
indexer,
rewrittenArguments,
default(ImmutableArray<string>),
argumentRefKinds,
false,
default(ImmutableArray<int>),
indexerAccess.Type);
}
case BoundKind.Local:
case BoundKind.Parameter:
case BoundKind.ThisReference: // a special kind of parameter
// No temporaries are needed. Just generate local = local + value
return originalLHS;
case BoundKind.DeclarationExpression:
示例4: GetCallSiteArguments
internal static ImmutableArray<BoundExpression> GetCallSiteArguments(BoundExpression callSiteFieldAccess, BoundExpression receiver, ImmutableArray<BoundExpression> arguments, BoundExpression right)
{
var result = new BoundExpression[1 + (receiver != null ? 1 : 0) + arguments.Length + (right != null ? 1 : 0)];
int j = 0;
result[j++] = callSiteFieldAccess;
if (receiver != null)
{
result[j++] = receiver;
}
arguments.CopyTo(result, j);
j += arguments.Length;
if (right != null)
{
result[j++] = right;
}
return result.AsImmutableOrNull();
}
示例5: Sequence
public BoundExpression Sequence(BoundExpression[] sideEffects, BoundExpression result, TypeSymbol type = null)
{
return new BoundSequence(Syntax, ImmutableArray<LocalSymbol>.Empty, sideEffects.AsImmutableOrNull(), result, type ?? result.Type) { WasCompilerGenerated = true };
}
示例6: MergeArgumentsAndSideEffects
/// <summary>
/// Process tempStores and add them as side-effects to arguments where needed. The return
/// value tells how many temps are actually needed. For unnecessary temps the corresponding
/// temp store will be cleared.
/// </summary>
private static int MergeArgumentsAndSideEffects(
BoundExpression[] arguments,
ArrayBuilder<RefKind> refKinds,
ArrayBuilder<BoundAssignmentOperator> tempStores)
{
Debug.Assert(arguments != null);
Debug.Assert(refKinds != null);
Debug.Assert(tempStores != null);
int tempsRemainedInUse = tempStores.Count;
// Suppose we've got temporaries: t0 = A(), t1 = B(), t2 = C(), t4 = D(), t5 = E()
// and arguments: t0, t2, t1, t4, 10, t5
//
// We wish to produce arguments list: A(), SEQ(t1=B(), C()), t1, D(), 10, E()
//
// Our algorithm essentially finds temp stores that must happen before given argument
// load, and if there are any they become side effects of the given load.
// Stores immediately followed by loads of the same thing can be eliminated.
//
// Constraints:
// Stores must happen before corresponding loads.
// Stores cannot move relative to other stores. If arg was movable it would not need a temp.
int firstUnclaimedStore = 0;
for (int a = 0; a < arguments.Length; ++a)
{
var argument = arguments[a];
// if argument is a load, search for corresponding store. if store is found, extract
// the actual expression we were storing and add it as an argument - this one does
// not need a temp. if there are any unclaimed stores before the found one, add them
// as side effects that precede this arg, they cannot happen later.
// NOTE: missing optional parameters are not filled yet and therefore nulls - no need to do anything for them
if (argument?.Kind == BoundKind.Local)
{
var correspondingStore = -1;
for (int i = firstUnclaimedStore; i < tempStores.Count; i++)
{
if (tempStores[i].Left == argument)
{
correspondingStore = i;
break;
}
}
// store found?
if (correspondingStore != -1)
{
var value = tempStores[correspondingStore].Right;
// When we created the temp, we dropped the argument RefKind
// since the local contained its own RefKind. Since we're removing
// the temp, the argument RefKind needs to be restored.
refKinds[a] = ((BoundLocal)argument).LocalSymbol.RefKind;
// the matched store will not need to go into side-effects, only ones before it will
// remove the store to signal that we are not using its temp.
tempStores[correspondingStore] = null;
tempsRemainedInUse--;
// no need for side-effects?
// just combine store and load
if (correspondingStore == firstUnclaimedStore)
{
arguments[a] = value;
}
else
{
var sideeffects = new BoundExpression[correspondingStore - firstUnclaimedStore];
for (int s = 0; s < sideeffects.Length; s++)
{
sideeffects[s] = tempStores[firstUnclaimedStore + s];
}
arguments[a] = new BoundSequence(
value.Syntax,
// this sequence does not own locals. Note that temps that
// we use for the rewrite are stored in one arg and loaded
// in another so they must live in a scope above.
ImmutableArray<LocalSymbol>.Empty,
sideeffects.AsImmutableOrNull(),
value,
value.Type);
}
firstUnclaimedStore = correspondingStore + 1;
}
}
}
Debug.Assert(firstUnclaimedStore == tempStores.Count, "not all side-effects were claimed");
return tempsRemainedInUse;
}
示例7: MakeBinderConstruction
private BoundExpression MakeBinderConstruction(WellKnownMember factoryMethod, BoundExpression[] args)
{
var binderFactory = _factory.WellKnownMember(factoryMethod);
if ((object)binderFactory == null)
{
return null;
}
return _factory.Call(null, (MethodSymbol)binderFactory, args.AsImmutableOrNull());
}
示例8: MakeArguments
//.........这里部分代码省略.........
{
temps = default(ImmutableArray<LocalSymbol>);
return rewrittenArguments;
}
// We have:
// * a list of arguments, already converted to their proper types,
// in source code order. Some optional arguments might be missing.
// * a map showing which parameter each argument corresponds to. If
// this is null, then the argument to parameter mapping is one-to-one.
// * the ref kind of each argument, in source code order. That is, whether
// the argument was marked as ref, out, or value (neither).
// * a method symbol.
// * whether the call is expanded or normal form.
// We rewrite the call so that:
// * if in its expanded form, we create the params array.
// * if the call requires reordering of arguments because of named arguments, temporaries are generated as needed
// Doing this transformation can move around refness in interesting ways. For example, consider
//
// A().M(y : ref B()[C()], x : out D());
//
// This will be created as a call with receiver A(), symbol M, argument list ( B()[C()], D() ),
// name list ( y, x ) and ref list ( ref, out ). We can rewrite this into temporaries:
//
// A().M(
// seq ( ref int temp_y = ref B()[C()], out D() ),
// temp_y );
//
// Now we have a call with receiver A(), symbol M, argument list as shown, no name list,
// and ref list ( out, value ). We do not want to pass a *ref* to temp_y; the temporary
// storage is not the thing being ref'd! We want to pass the *value* of temp_y, which
// *contains* a reference.
// We attempt to minimize the number of temporaries required. Arguments which neither
// produce nor observe a side effect can be placed into their proper position without
// recourse to a temporary. For example:
//
// Where(predicate: x=>x.Length!=0, sequence: S())
//
// can be rewritten without any temporaries because the conversion from lambda to
// delegate does not produce any side effect that could be observed by S().
//
// By contrast:
//
// Foo(z: this.p, y: this.Q(), x: (object)10)
//
// The boxing of 10 can be reordered, but the fetch of this.p has to happen before the
// call to this.Q() because the call could change the value of this.p.
//
// We start by binding everything that is not obviously reorderable as a temporary, and
// then run an optimizer to remove unnecessary temporaries.
ImmutableArray<ParameterSymbol> parameters = methodOrIndexer.GetParameters();
BoundExpression[] actualArguments = new BoundExpression[parameters.Length]; // The actual arguments that will be passed; one actual argument per formal parameter.
ArrayBuilder<BoundAssignmentOperator> storesToTemps = ArrayBuilder<BoundAssignmentOperator>.GetInstance(rewrittenArguments.Length);
ArrayBuilder<RefKind> refKinds = ArrayBuilder<RefKind>.GetInstance(parameters.Length, RefKind.None);
// Step one: Store everything that is non-trivial into a temporary; record the
// stores in storesToTemps and make the actual argument a reference to the temp.
// Do not yet attempt to deal with params arrays or optional arguments.
BuildStoresToTemps(expanded, argsToParamsOpt, argumentRefKindsOpt, rewrittenArguments, actualArguments, refKinds, storesToTemps);
// all the formal arguments, except missing optionals, are now in place.
// Optimize away unnecessary temporaries.
// Necessary temporaries have their store instructions merged into the appropriate
// argument expression.
ArrayBuilder<LocalSymbol> temporariesBuilder = ArrayBuilder<LocalSymbol>.GetInstance();
OptimizeTemporaries(actualArguments, refKinds, storesToTemps, temporariesBuilder);
// Step two: If we have a params array, build the array and fill in the argument.
if (expanded)
{
actualArguments[actualArguments.Length - 1] = BuildParamsArray(syntax, methodOrIndexer, argsToParamsOpt, rewrittenArguments, parameters, actualArguments[actualArguments.Length - 1]);
}
// Step three: Now fill in the optional arguments.
InsertMissingOptionalArguments(syntax, optionalParametersMethod.Parameters, actualArguments, enableCallerInfo);
if (isComReceiver)
{
RewriteArgumentsForComCall(parameters, actualArguments, refKinds, temporariesBuilder);
}
temps = temporariesBuilder.ToImmutableAndFree();
storesToTemps.Free();
// * The refkind map is now filled out to match the arguments.
// * The list of parameter names is now null because the arguments have been reordered.
// * The args-to-params map is now null because every argument exactly matches its parameter.
// * The call is no longer in its expanded form.
argumentRefKindsOpt = GetRefKindsOrNull(refKinds);
refKinds.Free();
return actualArguments.AsImmutableOrNull();
}
示例9: TypeOfs
public ImmutableArray<BoundExpression> TypeOfs(ImmutableArray<TypeSymbol> typeArguments)
{
var result = new BoundExpression[typeArguments.Length];
for (int i = 0; i < typeArguments.Length; i++)
{
result[i] = Typeof(typeArguments[i]);
}
return result.AsImmutableOrNull();
}
示例10: TransformDynamicIndexerAccess
private BoundDynamicIndexerAccess TransformDynamicIndexerAccess(BoundDynamicIndexerAccess indexerAccess, ArrayBuilder<BoundExpression> stores, ArrayBuilder<LocalSymbol> temps)
{
BoundExpression loweredReceiver;
if (CanChangeValueBetweenReads(indexerAccess.ReceiverOpt))
{
BoundAssignmentOperator assignmentToTemp;
var temp = _factory.StoreToTemp(VisitExpression(indexerAccess.ReceiverOpt), out assignmentToTemp);
stores.Add(assignmentToTemp);
temps.Add(temp.LocalSymbol);
loweredReceiver = temp;
}
else
{
loweredReceiver = indexerAccess.ReceiverOpt;
}
var arguments = indexerAccess.Arguments;
var loweredArguments = new BoundExpression[arguments.Length];
for (int i = 0; i < arguments.Length; i++)
{
if (CanChangeValueBetweenReads(arguments[i]))
{
BoundAssignmentOperator assignmentToTemp;
var temp = _factory.StoreToTemp(VisitExpression(arguments[i]), out assignmentToTemp, indexerAccess.ArgumentRefKindsOpt.RefKinds(i) != RefKind.None ? RefKind.Ref : RefKind.None);
stores.Add(assignmentToTemp);
temps.Add(temp.LocalSymbol);
loweredArguments[i] = temp;
}
else
{
loweredArguments[i] = arguments[i];
}
}
return new BoundDynamicIndexerAccess(
indexerAccess.Syntax,
loweredReceiver,
loweredArguments.AsImmutableOrNull(),
indexerAccess.ArgumentNamesOpt,
indexerAccess.ArgumentRefKindsOpt,
indexerAccess.ApplicableIndexers,
indexerAccess.Type);
}
示例11: TransformIndexerAccess
//.........这里部分代码省略.........
//
// tempc = C()
// tempz = Z()
// tempc.M(X(), Y(), tempz)
//
// See, we can optimize away two of the temporaries, for x and y. But we cannot optimize away any of the
// temporaries in
//
// C().Collection[z : Z(), x : X(), y : Y()] += 1;
//
// because we have to ensure not just that Z() happens first, but in addition that X() and Y() are only
// called once. We have to generate this as
//
// tempc = C().Collection
// tempz = Z()
// tempx = X()
// tempy = Y()
// tempc[tempx, tempy, tempz] = tempc[tempx, tempy, tempz] + 1;
//
// Fortunately arguments to indexers are never ref or out, so we don't need to worry about that.
// However, we can still do the optimization where constants are not stored in
// temporaries; if we have
//
// C().Collection[z : 123, y : Y(), x : X()] += 1;
//
// Then we can generate that as
//
// tempc = C().Collection
// tempx = X()
// tempy = Y()
// tempc[tempx, tempy, 123] = tempc[tempx, tempy, 123] + 1;
ImmutableArray<BoundExpression> rewrittenArguments = VisitList(indexerAccess.Arguments);
SyntaxNode syntax = indexerAccess.Syntax;
PropertySymbol indexer = indexerAccess.Indexer;
ImmutableArray<RefKind> argumentRefKinds = indexerAccess.ArgumentRefKindsOpt;
bool expanded = indexerAccess.Expanded;
ImmutableArray<int> argsToParamsOpt = indexerAccess.ArgsToParamsOpt;
ImmutableArray<ParameterSymbol> parameters = indexer.Parameters;
BoundExpression[] actualArguments = new BoundExpression[parameters.Length]; // The actual arguments that will be passed; one actual argument per formal parameter.
ArrayBuilder<BoundAssignmentOperator> storesToTemps = ArrayBuilder<BoundAssignmentOperator>.GetInstance(rewrittenArguments.Length);
ArrayBuilder<RefKind> refKinds = ArrayBuilder<RefKind>.GetInstance(parameters.Length, RefKind.None);
// Step one: Store everything that is non-trivial into a temporary; record the
// stores in storesToTemps and make the actual argument a reference to the temp.
// Do not yet attempt to deal with params arrays or optional arguments.
BuildStoresToTemps(expanded, argsToParamsOpt, argumentRefKinds, rewrittenArguments, actualArguments, refKinds, storesToTemps);
// Step two: If we have a params array, build the array and fill in the argument.
if (expanded)
{
BoundExpression array = BuildParamsArray(syntax, indexer, argsToParamsOpt, rewrittenArguments, parameters, actualArguments[actualArguments.Length - 1]);
BoundAssignmentOperator storeToTemp;
var boundTemp = _factory.StoreToTemp(array, out storeToTemp);
stores.Add(storeToTemp);
temps.Add(boundTemp.LocalSymbol);
actualArguments[actualArguments.Length - 1] = boundTemp;
}
// Step three: Now fill in the optional arguments. (Dev11 uses the
// getter for optional arguments in compound assignments.)
var getMethod = indexer.GetOwnOrInheritedGetMethod();
Debug.Assert((object)getMethod != null);
InsertMissingOptionalArguments(syntax, getMethod.Parameters, actualArguments);
// For a call, step four would be to optimize away some of the temps. However, we need them all to prevent
// duplicate side-effects, so we'll skip that step.
if (indexer.ContainingType.IsComImport)
{
RewriteArgumentsForComCall(parameters, actualArguments, refKinds, temps);
}
rewrittenArguments = actualArguments.AsImmutableOrNull();
foreach (BoundAssignmentOperator tempAssignment in storesToTemps)
{
temps.Add(((BoundLocal)tempAssignment.Left).LocalSymbol);
stores.Add(tempAssignment);
}
storesToTemps.Free();
argumentRefKinds = GetRefKindsOrNull(refKinds);
refKinds.Free();
// CONSIDER: this is a temporary object that will be rewritten away before this lowering completes.
// Mitigation: this will only produce short-lived garbage for compound assignments and increments/decrements of indexers.
return new BoundIndexerAccess(
syntax,
transformedReceiver,
indexer,
rewrittenArguments,
default(ImmutableArray<string>),
argumentRefKinds,
false,
default(ImmutableArray<int>),
indexerAccess.Type);
}
示例12: MakeObjectCreationWithInitializer
// Shared helper for MakeObjectCreationWithInitializer and MakeNewT
private BoundExpression MakeObjectCreationWithInitializer(
CSharpSyntaxNode syntax,
BoundExpression rewrittenObjectCreation,
BoundExpression initializerExpression,
TypeSymbol type)
{
Debug.Assert(!inExpressionLambda);
Debug.Assert(initializerExpression != null && !initializerExpression.HasErrors);
// Create a temp and assign it with the object creation expression.
BoundAssignmentOperator boundAssignmentToTemp;
BoundLocal boundTemp = this.factory.StoreToTemp(rewrittenObjectCreation, out boundAssignmentToTemp);
// Rewrite object/collection initializer expressions
ArrayBuilder<BoundExpression> dynamicSiteInitializers = null;
ArrayBuilder<BoundExpression> loweredInitializers = ArrayBuilder<BoundExpression>.GetInstance();
AddObjectOrCollectionInitializers(ref dynamicSiteInitializers, loweredInitializers, boundTemp, initializerExpression);
int dynamicSiteCount = (dynamicSiteInitializers != null) ? dynamicSiteInitializers.Count : 0;
var sideEffects = new BoundExpression[1 + dynamicSiteCount + loweredInitializers.Count];
sideEffects[0] = boundAssignmentToTemp;
if (dynamicSiteCount > 0)
{
dynamicSiteInitializers.CopyTo(sideEffects, 1);
dynamicSiteInitializers.Free();
}
loweredInitializers.CopyTo(sideEffects, 1 + dynamicSiteCount);
loweredInitializers.Free();
return new BoundSequence(
syntax: syntax,
locals: ImmutableArray.Create(boundTemp.LocalSymbol),
sideEffects: sideEffects.AsImmutableOrNull(),
value: boundTemp,
type: type);
}