public override void OutASimpleInvokeExp(ASimpleInvokeExp node) { if (data.SimpleMethodLinks.ContainsKey(node)) return; List<AMethodDecl> candidates = new List<AMethodDecl>(); List<AMethodDecl> implicitCandidates = new List<AMethodDecl>(); List<AMethodDecl> matchingNames = new List<AMethodDecl>(); List<PType> argTypes = new List<PType>(); foreach (PExp exp in node.GetArgs()) { argTypes.Add(data.ExpTypes[exp]); } PExp baseExp; bool matchResize; GetTargets(node.GetName().Text, node.GetName(), null, null, argTypes, candidates, out matchResize, implicitCandidates, matchingNames, out baseExp, null, data, errors); if (baseExp != null) { ANonstaticInvokeExp replacer = new ANonstaticInvokeExp(baseExp, new ADotDotType(new TDot(".")), node.GetName(), new ArrayList()); while (node.GetArgs().Count > 0) { replacer.GetArgs().Add(node.GetArgs()[0]); } node.ReplaceBy(replacer); baseExp.Apply(this); OutANonstaticInvokeExp(replacer); return; } AMethodDecl decl; if (candidates.Count == 0 && implicitCandidates.Count == 1) { //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); } } decl = implicitCandidates[0]; } else decl = candidates[0]; data.SimpleMethodLinks.Add(node, decl); data.ExpTypes.Add(node, decl.GetReturnType()); CheckInvoke(node, decl); base.OutASimpleInvokeExp(node); }
private void MakeInvoke(InvokeStm node) { //Find target method List<AMethodDecl> candidates = new List<AMethodDecl>(); List<AMethodDecl> implicitCandidates = new List<AMethodDecl>(); List<AMethodDecl> matchingNames = new List<AMethodDecl>(); List<PType> argTypes = new List<PType>(); foreach (PExp exp in node.Args) { argTypes.Add(data.ExpTypes[exp]); } PExp baseExp; bool needsVisit = node.Base == null || node.Base is AAName; bool matchResize; if (node.Base != null) { } GetTargets(node.Name.Text, node.Token, node.Base, null, argTypes, candidates, out matchResize, implicitCandidates, matchingNames, out baseExp, null, data, errors); if (needsVisit && baseExp != null) { //Add as an arg, visit it, then remove it node.Args.Add(baseExp); baseExp.Apply(this); node.Args.Remove(baseExp); } AMethodDecl candidate = candidates.Count == 1 ? candidates[0] : implicitCandidates[0]; bool isImplicitCandidate = candidates.Count != 1; if (baseExp != null && baseExp is ALvalueExp && ((ALvalueExp)baseExp).GetLvalue() is APointerLvalue && Util.HasAncestor<AStructDecl>(candidate)) { baseExp = ((APointerLvalue) ((ALvalueExp) baseExp).GetLvalue()).GetBase(); } node.BaseExp = baseExp; if (isImplicitCandidate) { //Do the implicit casts for (int i = 0; i < node.Args.Count; i++) { PType argType = argTypes[i]; AALocalDecl formal = (AALocalDecl) candidate.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.Args[i]; ACastExp cast = new ACastExp(new TLParen("("), Util.MakeClone(formalType, data), null); exp.ReplaceBy(cast); cast.SetExp(exp); OutACastExp(cast); } } } if (!data.Invokes.ContainsKey(candidate)) data.Invokes.Add(candidate, new List<InvokeStm>()); data.Invokes[candidate].Add(node); if (!node.IsAsync) data.ExpTypes.Add(node.SyncNode, candidate.GetReturnType()); //For each formal marked as ref or out, the argument must be a variable for (int i = 0; i < node.Args.Count; i++) { AALocalDecl formal = (AALocalDecl)candidate.GetFormals()[i]; if (formal.GetRef() != null || formal.GetOut() != null) { PExp exp = (PExp)node.Args[i]; while (true) { PLvalue lvalue; if (exp is ALvalueExp) { lvalue = ((ALvalueExp)exp).GetLvalue(); } else if (exp is AAssignmentExp) { lvalue = ((AAssignmentExp)exp).GetLvalue(); } else { errors.Add(new ErrorCollection.Error(node.Token, currentSourceFile, LocRM.GetString("ErrorText129") + (i + 1) + LocRM.GetString("ErrorText130"))); break; } if (lvalue is ALocalLvalue || lvalue is AFieldLvalue || lvalue is AStructFieldLvalue) break; if (lvalue is AStructLvalue) { exp = ((AStructLvalue)lvalue).GetReceiver(); continue; } if (lvalue is AArrayLvalue) { exp = ((AArrayLvalue)lvalue).GetBase(); continue; } throw new Exception("Unexpected lvalue"); } } } }
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); }