public override StringBuilder VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, int data) { var result = new StringBuilder(); if (!(memberReferenceExpression.Target is ThisReferenceExpression)) { result.Append(memberReferenceExpression.Target.AcceptVisitor(this, data)).Append("."); } var def = memberReferenceExpression.Annotation <IMemberDefinition>(); if (def != null) { return(result.Append(Shader.ResolveName(def))); } var fref = memberReferenceExpression.Annotation <FieldReference>(); if (fref != null) { return(result.Append(Shader.ResolveName(fref.Resolve()))); } throw new NotImplementedException(); }
public override StringBuilder VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, int data) { var result = new StringBuilder(); if (!(memberReferenceExpression.Target is ThisReferenceExpression) && !(memberReferenceExpression.Target is BaseReferenceExpression)) { result.Append(memberReferenceExpression.Target.AcceptVisitor(this, data)).Append("."); } var def = memberReferenceExpression.Annotation <IMemberDefinition>(); if (def != null) { return(result.Append(def.Name)); } var fref = memberReferenceExpression.Annotation <FieldReference>(); if (fref != null) { return(result.Append(fref.Name)); } var iref = memberReferenceExpression.MemberNameToken.AcceptVisitor(this, data); if (iref.Length > 0) { return(result.Append(iref)); } throw new NotImplementedException(); }
/// <summary> /// Translates a member reference, e.g. a field called "_value". /// </summary> public override StringBuilder VisitMemberReferenceExpression(MemberReferenceExpression memberRefExpr) { var result = new StringBuilder(); if (!(memberRefExpr.Target is ThisReferenceExpression)) { result = memberRefExpr.Target.AcceptVisitor(this); if (result != null && result.Length > 0) { result.Dot(); } } var memberName = memberRefExpr.MemberName; if (memberRefExpr.Target is BaseReferenceExpression) { memberName = memberName.Replace("xsl", "gl_"); } // save member reference var memberRef = memberRefExpr.Annotation <IMemberDefinition>(); if (result != null && memberRef != null) { var instr = GetInstructionFromStmt(memberRefExpr.GetParent <Statement>()); RefVariables.Add(new VariableDesc { Definition = memberRef, Instruction = instr }); } return(result != null?result.Append(memberName) : new StringBuilder()); }
public static TypeReference GetTargetTypeRef(MemberReferenceExpression memberReferenceExpression) { var pd = memberReferenceExpression.Annotation <PropertyDefinition>(); if (pd != null) { return(pd.DeclaringType); } var fd = memberReferenceExpression.Annotation <FieldDefinition>(); if (fd == null) { fd = memberReferenceExpression.Annotation <FieldReference>() as FieldDefinition; } if (fd != null) { return(fd.DeclaringType); } return(Helpers.GetTypeRef(memberReferenceExpression.Target)); }
static bool IsWithoutSideEffects(Expression left) { if (left is ThisReferenceExpression) { return(true); } if (left is IdentifierExpression) { return(true); } MemberReferenceExpression mre = left as MemberReferenceExpression; if (mre != null) { return(mre.Annotation <FieldReference>() != null && IsWithoutSideEffects(mre.Target)); } return(false); }
public override object VisitBlockStatement(BlockStatement blockStatement, object data) { int numberOfVariablesOutsideBlock = currentlyUsedVariableNames.Count; base.VisitBlockStatement(blockStatement, data); foreach (ExpressionStatement stmt in blockStatement.Statements.OfType <ExpressionStatement>().ToArray()) { Match displayClassAssignmentMatch = displayClassAssignmentPattern.Match(stmt); if (!displayClassAssignmentMatch.Success) { continue; } ILVariable variable = displayClassAssignmentMatch.Get <AstNode>("variable").Single().Annotation <ILVariable>(); if (variable == null) { continue; } TypeDefinition type = variable.Type.ResolveWithinSameModule(); if (!IsPotentialClosure(context, type)) { continue; } if (displayClassAssignmentMatch.Get <AstType>("type").Single().Annotation <TypeReference>().ResolveWithinSameModule() != type) { 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 && identExpr != displayClassAssignmentMatch.Get("variable").Single()) { //check if it a cross reference to another generated delegate class's member if (identExpr.Parent is AssignmentExpression) { if ((identExpr.Parent as AssignmentExpression).Left is MemberReferenceExpression ) { MemberReferenceExpression tleft = (MemberReferenceExpression)(identExpr.Parent as AssignmentExpression).Left; ILVariable v = tleft.Target.Annotation <ILVariable>(); if (v != null) { TypeDefinition vtype = v.Type.ResolveWithinSameModule(); if (vtype.IsNested && IsPotentialClosure(context, vtype)) { Console.WriteLine(identExpr.Parent.ToString() + " cross reference by delegate should be ok"); continue; } } } } if (!(identExpr.Parent is MemberReferenceExpression && identExpr.Parent.Annotation <FieldReference>() != null)) { ok = false; break; } } } if (!ok) { continue; } Dictionary <FieldReference, AstNode> dict = new Dictionary <FieldReference, AstNode>(); // Delete the variable declaration statement: VariableDeclarationStatement displayClassVarDecl = PatternStatementTransform.FindVariableDeclaration(stmt, variable.Name); if (displayClassVarDecl != null) { displayClassVarDecl.Remove(); } // Delete the assignment statement: AstNode cur = stmt.NextSibling; stmt.Remove(); // Delete any following statements as long as they assign parameters to the display class BlockStatement rootBlock = blockStatement.Ancestors.OfType <BlockStatement>().LastOrDefault() ?? blockStatement; List <ILVariable> parameterOccurrances = rootBlock.Descendants.OfType <IdentifierExpression>() .Select(n => n.Annotation <ILVariable>()).Where(p => p != null && p.IsParameter).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), MemberName = Pattern.AnyString }), new AnyNode("right") ) ); Match m = closureFieldAssignmentPattern.Match(cur); if (m.Success) { FieldDefinition fieldDef = m.Get <MemberReferenceExpression>("left").Single().Annotation <FieldReference>().ResolveWithinSameModule(); AstNode right = m.Get <AstNode>("right").Single(); bool isParameter = false; bool isDisplayClassParentPointerAssignment = false; if (right is ThisReferenceExpression) { isParameter = true; } else if (right is IdentifierExpression) { // handle parameters only if the whole method contains no other occurrence except for 'right' ILVariable v = right.Annotation <ILVariable>(); isParameter = v.IsParameter && parameterOccurrances.Count(c => c == v) == 1; if (!isParameter && IsPotentialClosure(context, v.Type.ResolveWithinSameModule())) { // parent display class within the same method // (closure2.localsX = closure1;) isDisplayClassParentPointerAssignment = true; } } else if (right is MemberReferenceExpression) { // copy of parent display class reference from an outer lambda // closure2.localsX = this.localsY MemberReferenceExpression mre = m.Get <MemberReferenceExpression>("right").Single(); do { // descend into the targets of the mre as long as the field types are closures FieldDefinition fieldDef2 = mre.Annotation <FieldReference>().ResolveWithinSameModule(); if (fieldDef2 == null || !IsPotentialClosure(context, fieldDef2.FieldType.ResolveWithinSameModule())) { break; } // if we finally get to a this reference, it's copying a display class parent pointer if (mre.Target is ThisReferenceExpression) { isDisplayClassParentPointerAssignment = true; } mre = mre.Target as MemberReferenceExpression; } while (mre != null); } if (isParameter || isDisplayClassParentPointerAssignment) { dict[fieldDef] = right; cur.Remove(); } else { break; } } else { //why need to break? continue to match should be ok //break; } } // Now create variables for all fields of the display class (except for those that we already handled as parameters) List <Tuple <AstType, ILVariable> > variablesToDeclare = new List <Tuple <AstType, ILVariable> >(); foreach (FieldDefinition field in type.Fields) { if (field.IsStatic) { continue; // skip static fields } if (dict.ContainsKey(field)) // skip field if it already was handled as parameter { continue; } string capturedVariableName = field.Name; if (capturedVariableName.StartsWith("$VB$Local_", StringComparison.Ordinal) && capturedVariableName.Length > 10) { capturedVariableName = capturedVariableName.Substring(10); } EnsureVariableNameIsAvailable(blockStatement, capturedVariableName); currentlyUsedVariableNames.Add(capturedVariableName); ILVariable ilVar = new ILVariable { IsGenerated = true, Name = capturedVariableName, Type = field.FieldType, }; variablesToDeclare.Add(Tuple.Create(AstBuilder.ConvertType(field.FieldType, field), ilVar)); dict[field] = new IdentifierExpression(capturedVariableName).WithAnnotation(ilVar); } // 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) { if (!(identExpr.Parent is MemberReferenceExpression)) { //will delete by the next round of the cross reference delegate class continue; } MemberReferenceExpression mre = (MemberReferenceExpression)identExpr.Parent; AstNode replacement; if (dict.TryGetValue(mre.Annotation <FieldReference>().ResolveWithinSameModule(), 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): Statement insertionPoint = blockStatement.Statements.FirstOrDefault(); foreach (var tuple in variablesToDeclare) { var newVarDecl = new VariableDeclarationStatement(tuple.Item1, tuple.Item2.Name); newVarDecl.Variables.Single().AddAnnotation(new CapturedVariableAnnotation()); newVarDecl.Variables.Single().AddAnnotation(tuple.Item2); blockStatement.Statements.InsertBefore(insertionPoint, newVarDecl); } } currentlyUsedVariableNames.RemoveRange(numberOfVariablesOutsideBlock, currentlyUsedVariableNames.Count - numberOfVariablesOutsideBlock); return(null); }
public override StringBuilder VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, int data) { var result = new StringBuilder(); if (!(memberReferenceExpression.Target is ThisReferenceExpression)) result.Append(memberReferenceExpression.Target.AcceptVisitor(this, data)).Append("."); var def = memberReferenceExpression.Annotation<IMemberDefinition>(); if (def != null) return result.Append(Shader.ResolveName(def)); var fref = memberReferenceExpression.Annotation<FieldReference>(); if (fref != null) return result.Append(Shader.ResolveName(fref.Resolve())); throw new NotImplementedException(); }
public virtual void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { DebugExpression(memberReferenceExpression); StartNode(memberReferenceExpression); memberReferenceExpression.Target.AcceptVisitor(this); WriteToken(Roles.Dot, BoxedTextColor.Operator); WriteIdentifier(memberReferenceExpression.MemberNameToken, CSharpMetadataTextColorProvider.Instance.GetColor(memberReferenceExpression.MemberNameToken.Annotation<object>() ?? memberReferenceExpression.Annotation<object>())); WriteTypeArguments(memberReferenceExpression.TypeArguments, CodeBracesRangeFlags.AngleBrackets); EndNode(memberReferenceExpression); }
public override object VisitBlockStatement(BlockStatement blockStatement, object data) { base.VisitBlockStatement(blockStatement, data); foreach (ExpressionStatement stmt in blockStatement.Statements.OfType <ExpressionStatement>().ToArray()) { Match displayClassAssignmentMatch = displayClassAssignmentPattern.Match(stmt); if (displayClassAssignmentMatch == null) { continue; } ILVariable variable = displayClassAssignmentMatch.Get("variable").Single().Annotation <ILVariable>(); if (variable == null) { continue; } TypeDefinition type = variable.Type.ResolveWithinSameModule(); if (!IsPotentialClosure(context, type)) { continue; } if (displayClassAssignmentMatch.Get("type").Single().Annotation <TypeReference>().ResolveWithinSameModule() != type) { 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 && identExpr != displayClassAssignmentMatch.Get("variable").Single()) { 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 <ILVariable> parameterOccurrances = blockStatement.Descendants.OfType <IdentifierExpression>() .Select(n => n.Annotation <ILVariable>()).Where(p => p != null && p.IsParameter).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' ILVariable param = right.Annotation <ILVariable>(); isParameter = param.IsParameter && parameterOccurrances.Count(c => c == param) == 1; } if (isParameter) { dict[m.Get <MemberReferenceExpression>("left").Single().Annotation <FieldReference>().ResolveWithinSameModule()] = 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>().ResolveWithinSameModule(), 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): Statement insertionPoint = blockStatement.Statements.FirstOrDefault(); foreach (var tuple in variablesToDeclare) { var newVarDecl = new VariableDeclarationStatement(tuple.Item1, tuple.Item2); newVarDecl.Variables.Single().AddAnnotation(new CapturedVariableAnnotation()); blockStatement.Statements.InsertBefore(insertionPoint, newVarDecl); } } return(null); }
public virtual void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { DebugExpression(memberReferenceExpression); StartNode(memberReferenceExpression); memberReferenceExpression.Target.AcceptVisitor(this); WriteToken(Roles.Dot); WriteIdentifier(memberReferenceExpression.MemberNameToken, TextTokenHelper.GetTextTokenType(memberReferenceExpression.MemberNameToken.Annotation<object>() ?? memberReferenceExpression.Annotation<object>())); WriteTypeArguments(memberReferenceExpression.TypeArguments); EndNode(memberReferenceExpression); }
TypeReference GetTargetTypeRef (MemberReferenceExpression memberReferenceExpression) { var pd = memberReferenceExpression.Annotation<PropertyDefinition> (); if (pd != null) { return pd.DeclaringType; } var fd = memberReferenceExpression.Annotation<FieldDefinition> (); if (fd == null) fd = memberReferenceExpression.Annotation<FieldReference> () as FieldDefinition; if (fd != null) { return fd.DeclaringType; } return GetTypeRef (memberReferenceExpression.Target); }
public override void VisitMemberReferenceExpression (MemberReferenceExpression memberReferenceExpression) { base.VisitMemberReferenceExpression (memberReferenceExpression); var s = memberReferenceExpression.Target as BaseReferenceExpression; if (s != null) { if (memberReferenceExpression.Annotation<PropertyDefinition>() != null || memberReferenceExpression.Annotation<PropertyReference>() != null) { memberReferenceExpression.Target = new ThisReferenceExpression (); } } }
public override void VisitMemberReferenceExpression(MemberReferenceExpression e) { var md = e.Annotation<MethodDefinition>(); if (md != null && md.IsPrivate && md.IsCompilerGenerated()) { //public override void OnMasterMouseLeave(ModifierMouseArgs e) //{ // this.TB(ModifierGroup.YB, e); //} // //[CompilerGenerated] //private static void YB(IChartModifier x, ModifierEventArgsBase y) //{ // x.OnMasterMouseLeave((ModifierMouseArgs)y); //} // //====> //public override void OnMasterMouseLeave(ModifierMouseArgs e) //{ // this.TB((x, y) => x.OnMasterMouseLeave((ModifierMouseArgs)y), e); //} var td = e.Ancestors.OfType<TypeDeclaration>().FirstOrDefault(); if (td != null) { var method = td.Members.OfType<MethodDeclaration>().FirstOrDefault(x => x.Annotation<MethodDefinition>() == md); if (method != null) { LambdaExpression le = new LambdaExpression(); var body = method.Body; if (body.Statements.Count == 1) { le.Body = TryReduceLambdaBody(body.Statements.First()).Detach(); } else { le.Body = body.Detach(); } // 设置 Lambda 函数参数 if (method.Parameters.Count > 0) { var prmNames = new[] { "x", "y", "z", "u", "v", "w", "m", "n", "p", "q", "r", "s", "t" }; var usedNames = new HashSet<string>(body.Descendants.OfType<IdentifierExpression>().Select(x => x.Identifier).Distinct()); var index = 0; foreach (var x in method.Parameters) { var pn = index < prmNames.Length ? prmNames[index] : "e" + index.ToString(); index++; while (usedNames.Contains(pn)) { pn = index < prmNames.Length ? prmNames[index] : "e" + index.ToString(); index++; } foreach (var r in le.Body.Descendants.OfType<IdentifierExpression>().Where(r => r.Identifier == x.Name)) { r.Identifier = pn; } le.Parameters.Add(new ParameterDeclaration(pn)); } } DelayRemove(method); e.ReplaceWith(le); } } } base.VisitMemberReferenceExpression(e); }