public override void CaseADelegateInvokeExp(ADelegateInvokeExp node) { PExp expNode = (PExp)node; PType type = data.ExpTypes[expNode]; if (type is APointerType) type = new ANamedType(new TIdentifier("string"), null); ALocalLvalue local = new ALocalLvalue(new TIdentifier("tempName", 0, 0)); ALvalueExp exp = new ALvalueExp(local); PStm stm = Util.GetAncestor<PStm>(node); AABlock block = (AABlock)stm.Parent(); node.ReplaceBy(exp); AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(type, data), new TIdentifier(varName, 0, 0), expNode); ALocalDeclStm newStm = new ALocalDeclStm(new TSemicolon(";"), localDecl); block.GetStatements().Insert(block.GetStatements().IndexOf(stm), newStm); NewStatements.Add(newStm); data.LvalueTypes[local] = type; data.ExpTypes[exp] = type; data.LocalLinks[local] = localDecl; //localDecl.Apply(this); exp.Apply(this); return; }
internal Args_Cast(ADelegateInvokeExp obj) { this.obj = obj; }
public virtual void OutADelegateInvokeExp(ADelegateInvokeExp node) { DefaultOut(node); }
public virtual void InADelegateInvokeExp(ADelegateInvokeExp node) { DefaultIn(node); }
public virtual void CaseADelegateInvokeExp(ADelegateInvokeExp node) { DefaultCase(node); }
public override void CaseADelegateInvokeExp(ADelegateInvokeExp node) { InADelegateInvokeExp(node); { Object[] temp = new Object[node.GetArgs().Count]; node.GetArgs().CopyTo(temp, 0); for (int i = temp.Length - 1; i >= 0; i--) { ((PExp)temp[i]).Apply(this); } } if (node.GetReceiver() != null) { node.GetReceiver().Apply(this); } if (node.GetToken() != null) { node.GetToken().Apply(this); } OutADelegateInvokeExp(node); }
public override void CaseADelegateInvokeExp(ADelegateInvokeExp node) { IsConst = false; }
public override void OutANonstaticInvokeExp(ANonstaticInvokeExp node) { List<AMethodDecl> candidates = new List<AMethodDecl>(); List<AMethodDecl> implicitCandidates = new List<AMethodDecl>(); List<AMethodDecl> matchingNames = new List<AMethodDecl>(); List<AMethodDecl> delegateCandidates = new List<AMethodDecl>(); List<PType> argTypes = new List<PType>(); foreach (PExp exp in node.GetArgs()) { argTypes.Add(data.ExpTypes[exp]); } PExp baseExp; bool needsVistit = false; Node reciever = node.GetReceiver(); bool visitBaseExp = false; if (node.GetReceiver() is ALvalueExp && ((ALvalueExp)node.GetReceiver()).GetLvalue() is AAmbiguousNameLvalue) { visitBaseExp = true; reciever = ((AAmbiguousNameLvalue) ((ALvalueExp) node.GetReceiver()).GetLvalue()).GetAmbiguous(); } bool matchResize; GetTargets(node.GetName().Text, node.GetName(), reciever, null, argTypes, candidates, out matchResize, implicitCandidates, matchingNames, out baseExp, delegateCandidates, data, errors); if (visitBaseExp && baseExp != null) { node.GetArgs().Add(baseExp); baseExp.Apply(this); node.GetArgs().Remove(baseExp); } if (matchResize) { AArrayResizeExp replacer = new AArrayResizeExp(node.GetName(), baseExp, (PExp) node.GetArgs()[0]); node.ReplaceBy(replacer); data.ExpTypes[replacer] = new ANamedType(new TIdentifier("void"), null); return; } if (implicitCandidates.Count > 0) { //Do the implicit casts for (int i = 0; i < node.GetArgs().Count; i++) { PType argType = data.ExpTypes[(PExp)node.GetArgs()[i]]; AALocalDecl formal = (AALocalDecl)implicitCandidates[0].GetFormals()[i]; PType formalType = formal.GetType(); if (formal.GetOut() != null && !Assignable(formalType, argType) || formal.GetRef() != null && !(Assignable(argType, formalType) && Assignable(formalType, argType)) || formal.GetOut() == null && formal.GetRef() == null && !Assignable(argType, formalType)) { PExp exp = (PExp)node.GetArgs()[i]; ACastExp cast = new ACastExp(new TLParen("("), Util.MakeClone(formalType, data), null); exp.ReplaceBy(cast); cast.SetExp(exp); OutACastExp(cast); } } } if (delegateCandidates.Count > 0) {//Target is a delegate invoke ADelegateInvokeExp replacer = new ADelegateInvokeExp(node.GetName(), baseExp, new ArrayList()); while (node.GetArgs().Count > 0) { replacer.GetArgs().Add(node.GetArgs()[0]); } data.ExpTypes[replacer] = delegateCandidates[0].GetReturnType(); node.ReplaceBy(replacer); return; } AMethodDecl candidate = candidates.Count == 1 ? candidates[0] : implicitCandidates[0]; if (baseExp == null) { //Replace with a simple invoke to it. ASimpleInvokeExp replacementInvoke = new ASimpleInvokeExp(node.GetName(), new ArrayList()); while (node.GetArgs().Count > 0) { replacementInvoke.GetArgs().Add(node.GetArgs()[0]); } data.SimpleMethodLinks[replacementInvoke] = candidate; data.ExpTypes[replacementInvoke] = candidate.GetReturnType(); node.ReplaceBy(replacementInvoke); CheckInvoke(replacementInvoke, candidate); return; } node.SetReceiver(baseExp); data.StructMethodLinks[node] = candidate; data.ExpTypes[node] = candidate.GetReturnType(); if (candidate.GetInline() != null) { AMethodDecl pMethod = Util.GetAncestor<AMethodDecl>(node); AConstructorDecl pConstructor = Util.GetAncestor<AConstructorDecl>(node); APropertyDecl pProperty = Util.GetAncestor<APropertyDecl>(node); if (pMethod == null && pConstructor == null && pProperty == null && !Util.HasAncestor<ADeconstructorDecl>(node)) { errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText133"))); } else if (pMethod != null && !InlineMethodCalls[pMethod].Contains(candidate)) InlineMethodCalls[pMethod].Add(candidate); } base.OutANonstaticInvokeExp(node); }
public override void CaseADelegateInvokeExp(ADelegateInvokeExp node) { //Build a list of the possible methods AASourceFile currentFile = Util.GetAncestor<AASourceFile>(node); List<AMethodDecl> methods = new List<AMethodDecl>(); ANamedType type = (ANamedType) finalTrans.data.ExpTypes[node.GetReceiver()]; AMethodDecl delegateMethod = finalTrans.data.DelegateTypeLinks[type]; foreach (KeyValuePair<ADelegateExp, AMethodDecl> delegateCreationPair in finalTrans.data.DelegateCreationMethod) { if (TypeChecking.Assignable(delegateCreationPair.Key.GetType(), type)) { if (!methods.Contains(delegateCreationPair.Value)) methods.Add(delegateCreationPair.Value); } } MoveMethodDeclsOut mover; if (methods.Count == 0) { //Can only remove it if the return value is unused if (!(node.Parent() is AExpStm)) { finalTrans.errors.Add(new ErrorCollection.Error(node.GetToken(), currentFile, LocRM.GetString("Delegates_Text1"))); throw new ParserException(node.GetToken(), "Delegates.OutADelegateInvokeExp"); } mover = new MoveMethodDeclsOut("delegateVar", finalTrans.data); foreach (Node arg in node.GetArgs()) { arg.Apply(mover); } node.Parent().Parent().RemoveChild(node.Parent()); foreach (PStm stm in mover.NewStatements) { stm.Apply(this); } return; } if (methods.Count == 1) { ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("renameMe"), new ArrayList()); while (node.GetArgs().Count > 0) { invoke.GetArgs().Add(node.GetArgs()[0]); } //If we have a struct method, add the pointer from the delegate if (finalTrans.data.StructMethods.Any(str => str.Value.Contains(methods[0]))) { AStructDecl targetStr = finalTrans.data.StructMethods.First(str => str.Value.Contains(methods[0])).Key; AMethodDecl getPointerDecl = GetPointerMethod(targetStr.GetDimention() != null); ASimpleInvokeExp getPointerInvoke = new ASimpleInvokeExp(new TIdentifier("renameMe"), new ArrayList(){node.GetReceiver()}); invoke.GetArgs().Add(getPointerInvoke); finalTrans.data.SimpleMethodLinks[getPointerInvoke] = getPointerDecl; finalTrans.data.ExpTypes[getPointerInvoke] = getPointerDecl.GetReturnType(); } finalTrans.data.SimpleMethodLinks[invoke] = methods[0]; finalTrans.data.ExpTypes[invoke] = methods[0].GetReturnType(); node.ReplaceBy(invoke); return; } //Multiple methods. Make /* * <Methods moved out from reciever> * string delegate = GetMethodPart(<reciever>); * if (delegate == "...") * { * Foo(...); * } * else if (delegate == "...") * { * Bar(..., GetPointerPart(<reciever>); * } * else if(...) * ... * else * { * UIDisplayMessage(PlayerGroupAll(), c_messageAreaDebug, StringToText("[<file>:<line>]: No methods matched delegate.")); * int i = 1/0; * return; * } * */ AABlock block = new AABlock(new ArrayList(), new TRBrace("}")); mover = new MoveMethodDeclsOut("delegateVar", finalTrans.data); node.GetReceiver().Apply(mover); AMethodDecl methodPartMethod = GetMethodMethod(); ASimpleInvokeExp methodPartInvoke = new ASimpleInvokeExp(new TIdentifier("GetMethodPart"), new ArrayList() { Util.MakeClone(node.GetReceiver(), finalTrans.data) }); finalTrans.data.SimpleMethodLinks[methodPartInvoke] = methodPartMethod; finalTrans.data.ExpTypes[methodPartInvoke] = methodPartMethod.GetReturnType(); AALocalDecl methodPartDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("string"), null), new TIdentifier("methodPart"), methodPartInvoke); block.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), methodPartDecl)); //If the invoke's return value is used, get the lvalue PLvalue leftSide; if (node.Parent() is AALocalDecl) { leftSide = new ALocalLvalue(new TIdentifier("renameMe")); finalTrans.data.LocalLinks[(ALocalLvalue) leftSide] = (AALocalDecl) node.Parent(); finalTrans.data.LvalueTypes[leftSide] = new ANamedType(new TIdentifier("string"), null); PStm pStm = Util.GetAncestor<PStm>(node); AABlock pBlock = (AABlock) pStm.Parent(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm) + 1, new ABlockStm(new TLBrace("{"), block)); node.Parent().RemoveChild(node); } else if (node.Parent() is AAssignmentExp) { AAssignmentExp assignExp = (AAssignmentExp) node.Parent(); leftSide = assignExp.GetLvalue(); leftSide.Apply(mover); PStm pStm = Util.GetAncestor<PStm>(node); pStm.ReplaceBy(new ABlockStm(new TLBrace("{"), block)); } else if (node.Parent() is AExpStm) { //No assignments needed leftSide = null; node.Parent().ReplaceBy(new ABlockStm(new TLBrace("{"), block)); } else { //Create a new local AALocalDecl leftSideDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(delegateMethod.GetReturnType(), finalTrans.data), new TIdentifier("delegateVar"), null); ALocalLvalue leftSideLink = new ALocalLvalue(new TIdentifier("delegateVar")); ALvalueExp leftSideLinkExp = new ALvalueExp(leftSideLink); PStm pStm = Util.GetAncestor<PStm>(node); AABlock pBlock = (AABlock)pStm.Parent(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ABlockStm(new TLBrace("{"), block)); node.ReplaceBy(leftSideLinkExp); finalTrans.data.LocalLinks[leftSideLink] = leftSideDecl; finalTrans.data.LvalueTypes[leftSideLink] = finalTrans.data.ExpTypes[leftSideLinkExp] = leftSideDecl.GetType(); leftSide = leftSideLink; block.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), leftSideDecl)); } ABlockStm elseBranch; //Make final else branch /* { * UIDisplayMessage(PlayerGroupAll(), c_messageAreaDebug, StringToText("<file>[<line>, <pos>]: No methods matched delegate.")); * IntToString(1/0); * return; * } */ { AABlock innerBlock = new AABlock(new ArrayList(), new TRBrace("}")); ASimpleInvokeExp playerGroupInvoke = new ASimpleInvokeExp(new TIdentifier("PlayerGroupAll"), new ArrayList()); AFieldLvalue messageAreaLink = new AFieldLvalue(new TIdentifier("c_messageAreaDebug")); ALvalueExp messageAreaLinkExp = new ALvalueExp(messageAreaLink); AStringConstExp stringConst = new AStringConstExp( new TStringLiteral("\"" + currentFile.GetName().Text.Replace('\\', '/') + "[" + node.GetToken().Line + ", " + node.GetToken().Pos + "]: Got a null delegate.\"")); ASimpleInvokeExp stringToTextInvoke = new ASimpleInvokeExp(new TIdentifier("StringToText"), new ArrayList() {stringConst}); ASimpleInvokeExp displayMessageInvoke = new ASimpleInvokeExp(new TIdentifier("UIDisplayMessage"), new ArrayList() { playerGroupInvoke, messageAreaLinkExp, stringToTextInvoke }); AIntConstExp intConst1 = new AIntConstExp(new TIntegerLiteral("1")); AIntConstExp intConst2 = new AIntConstExp(new TIntegerLiteral("0")); ABinopExp binop = new ABinopExp(intConst1, new ADivideBinop(new TDiv("/")), intConst2); ASimpleInvokeExp intToStringInvoke = new ASimpleInvokeExp(new TIdentifier("IntToString"), new ArrayList() {binop}); innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), displayMessageInvoke)); innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), intToStringInvoke)); //innerBlock.GetStatements().Add(new AVoidReturnStm(new TReturn("return"))); elseBranch = new ABlockStm(new TLBrace("{"), innerBlock); finalTrans.data.SimpleMethodLinks[playerGroupInvoke] = finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == playerGroupInvoke.GetName().Text); finalTrans.data.SimpleMethodLinks[stringToTextInvoke] = finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == stringToTextInvoke.GetName().Text); finalTrans.data.SimpleMethodLinks[displayMessageInvoke] = finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == displayMessageInvoke.GetName().Text); finalTrans.data.SimpleMethodLinks[intToStringInvoke] = finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == intToStringInvoke.GetName().Text); finalTrans.data.FieldLinks[messageAreaLink] = finalTrans.data.Libraries.Fields.First(m => m.GetName().Text == messageAreaLink.GetName().Text); finalTrans.data.ExpTypes[playerGroupInvoke] = finalTrans.data.SimpleMethodLinks[playerGroupInvoke].GetReturnType(); finalTrans.data.LvalueTypes[messageAreaLink] = finalTrans.data.ExpTypes[messageAreaLinkExp] = finalTrans.data.FieldLinks[messageAreaLink].GetType(); finalTrans.data.ExpTypes[stringToTextInvoke] = finalTrans.data.SimpleMethodLinks[stringToTextInvoke].GetReturnType(); finalTrans.data.ExpTypes[stringConst] = finalTrans.data.ExpTypes[intToStringInvoke] = new ANamedType(new TIdentifier("string"), null); finalTrans.data.ExpTypes[displayMessageInvoke] = new AVoidType(); finalTrans.data.ExpTypes[intConst1] = finalTrans.data.ExpTypes[intConst2] = finalTrans.data.ExpTypes[binop] = new ANamedType(new TIdentifier("int"), null); } foreach (AMethodDecl method in methods) { /* * if (delegate == "...") * { * Foo(...); * } * else if (delegate == "...") * { * Bar(..., GetPointerPart(<reciever>); * } * else if(...) * ... */ AABlock innerBlock = new AABlock(new ArrayList(), new TRBrace("}")); ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier(method.GetName().Text), new ArrayList()); for (int i = 0; i < node.GetArgs().Count; i++) { PExp arg = (PExp) node.GetArgs()[i]; invoke.GetArgs().Add(Util.MakeClone(arg, finalTrans.data)); } //If we have a struct method, add the pointer from the delegate if (finalTrans.data.StructMethods.Any(str => str.Value.Contains(method))) { AStructDecl targetStr = finalTrans.data.StructMethods.First(str => str.Value.Contains(method)).Key; AMethodDecl getPointerDecl = GetPointerMethod(targetStr.GetDimention() != null); ASimpleInvokeExp getPointerInvoke = new ASimpleInvokeExp(new TIdentifier("renameMe"), new ArrayList() { Util.MakeClone(node.GetReceiver(), data) }); invoke.GetArgs().Add(getPointerInvoke); finalTrans.data.SimpleMethodLinks[getPointerInvoke] = getPointerDecl; finalTrans.data.ExpTypes[getPointerInvoke] = getPointerDecl.GetReturnType(); } finalTrans.data.SimpleMethodLinks[invoke] = method; finalTrans.data.ExpTypes[invoke] = method.GetReturnType(); if (leftSide == null) { innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), invoke)); } else { AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), Util.MakeClone(leftSide, finalTrans.data), invoke); finalTrans.data.ExpTypes[assignment] = finalTrans.data.ExpTypes[invoke]; innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment)); } ALocalLvalue methodPartLink = new ALocalLvalue(new TIdentifier("methodPart")); ALvalueExp methodPartLinkExp = new ALvalueExp(methodPartLink); AStringConstExp stringConst = new AStringConstExp(new TStringLiteral("\"" + GetName(method) + "\"")); finalTrans.data.LocalLinks[methodPartLink] = methodPartDecl; finalTrans.data.LvalueTypes[methodPartLink] = finalTrans.data.ExpTypes[methodPartLinkExp] = finalTrans.data.ExpTypes[stringConst] = new ANamedType(new TIdentifier("string"), null); ABinopExp binop = new ABinopExp(methodPartLinkExp, new AEqBinop(new TEq("==")), stringConst); finalTrans.data.ExpTypes[binop] = new ANamedType(new TIdentifier("bool"), null); AIfThenElseStm ifThenElse = new AIfThenElseStm(new TLParen("("), binop, new ABlockStm(new TLBrace("{"), innerBlock), elseBranch); elseBranch = new ABlockStm(new TLBrace("{"), new AABlock(new ArrayList() { ifThenElse }, new TRBrace("}"))); } block.GetStatements().Add(elseBranch); }