本文整理汇总了C#中ExpressionStatement.Match方法的典型用法代码示例。如果您正苦于以下问题:C# ExpressionStatement.Match方法的具体用法?C# ExpressionStatement.Match怎么用?C# ExpressionStatement.Match使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ExpressionStatement
的用法示例。
在下文中一共展示了ExpressionStatement.Match方法的1个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: VisitBlockStatement
public override object VisitBlockStatement(BlockStatement blockStatement, object data)
{
base.VisitBlockStatement(blockStatement, data);
foreach (VariableDeclarationStatement stmt in blockStatement.Statements.OfType<VariableDeclarationStatement>()) {
if (stmt.Variables.Count() != 1)
continue;
var variable = stmt.Variables.Single();
TypeDefinition type = stmt.Type.Annotation<TypeDefinition>();
if (!IsPotentialClosure(type))
continue;
ObjectCreateExpression oce = variable.Initializer as ObjectCreateExpression;
if (oce == null || oce.Type.Annotation<TypeReference>() != type || oce.Arguments.Any() || !oce.Initializer.IsNull)
continue;
// Looks like we found a display class creation. Now let's verify that the variable is used only for field accesses:
bool ok = true;
foreach (var identExpr in blockStatement.Descendants.OfType<IdentifierExpression>()) {
if (identExpr.Identifier == variable.Name) {
if (!(identExpr.Parent is MemberReferenceExpression && identExpr.Parent.Annotation<FieldReference>() != null))
ok = false;
}
}
if (!ok)
continue;
Dictionary<FieldReference, AstNode> dict = new Dictionary<FieldReference, AstNode>();
// Delete the variable declaration statement:
AstNode cur = stmt.NextSibling;
stmt.Remove();
if (blockStatement.Parent.NodeType == NodeType.Member || blockStatement.Parent is Accessor) {
// Delete any following statements as long as they assign parameters to the display class
// Do parameter handling only for closures created in the top scope (direct child of method/accessor)
List<ParameterReference> parameterOccurrances = blockStatement.Descendants.OfType<IdentifierExpression>()
.Select(n => n.Annotation<ParameterReference>()).Where(p => p != null).ToList();
AstNode next;
for (; cur != null; cur = next) {
next = cur.NextSibling;
// Test for the pattern:
// "variableName.MemberName = right;"
ExpressionStatement closureFieldAssignmentPattern = new ExpressionStatement(
new AssignmentExpression(
new NamedNode("left", new MemberReferenceExpression { Target = new IdentifierExpression(variable.Name) }),
new AnyNode("right")
)
);
Match m = closureFieldAssignmentPattern.Match(cur);
if (m != null) {
AstNode right = m.Get("right").Single();
bool isParameter = false;
if (right is ThisReferenceExpression) {
isParameter = true;
} else if (right is IdentifierExpression) {
// handle parameters only if the whole method contains no other occurrance except for 'right'
ParameterReference param = right.Annotation<ParameterReference>();
isParameter = parameterOccurrances.Count(c => c == param) == 1;
}
if (isParameter) {
dict[m.Get<MemberReferenceExpression>("left").Single().Annotation<FieldReference>()] = right;
cur.Remove();
} else {
break;
}
} else {
break;
}
}
}
// Now create variables for all fields of the display class (except for those that we already handled as parameters)
List<Tuple<AstType, string>> variablesToDeclare = new List<Tuple<AstType, string>>();
foreach (FieldDefinition field in type.Fields) {
if (dict.ContainsKey(field))
continue;
variablesToDeclare.Add(Tuple.Create(AstBuilder.ConvertType(field.FieldType, field), field.Name));
dict[field] = new IdentifierExpression(field.Name);
}
// Now figure out where the closure was accessed and use the simpler replacement expression there:
foreach (var identExpr in blockStatement.Descendants.OfType<IdentifierExpression>()) {
if (identExpr.Identifier == variable.Name) {
MemberReferenceExpression mre = (MemberReferenceExpression)identExpr.Parent;
AstNode replacement;
if (dict.TryGetValue(mre.Annotation<FieldReference>(), out replacement)) {
mre.ReplaceWith(replacement.Clone());
}
}
}
// Now insert the variable declarations (we can do this after the replacements only so that the scope detection works):
foreach (var tuple in variablesToDeclare) {
var newVarDecl = DeclareVariableInSmallestScope.DeclareVariable(blockStatement, tuple.Item1, tuple.Item2, allowPassIntoLoops: false);
if (newVarDecl != null)
newVarDecl.Variables.Single().AddAnnotation(new CapturedVariableAnnotation());
}
}
return null;
}