public override void CaseAALocalDecl(AALocalDecl node)
        {
            if (node.GetType() is ANamedType)
            {
                ANamedType type = (ANamedType)node.GetType();
                if (finalTrans.data.StructTypeLinks.ContainsKey(type))
                {
                    AStructDecl strDecl = finalTrans.data.StructTypeLinks[type];
                    if (strDecl.GetLocals().Cast<PLocalDecl>().Select(decl => decl is AALocalDecl).Count() == 0)
                    {
                        MoveMethodDeclsOut mover = new MoveMethodDeclsOut("removedStructVar", finalTrans.data);
                        node.Apply(mover);
                        foreach (PStm stm in mover.NewStatements)
                        {
                            stm.Apply(this);
                        }
                        PStm pStm = Util.GetAncestor<PStm>(node);
                        if (pStm == null)
                        {
                            strDecl = Util.GetAncestor<AStructDecl>(node);

                            node.Parent().RemoveChild(node);

                            if (strDecl != null && strDecl.GetLocals().Cast<PLocalDecl>().Select(decl => decl is AALocalDecl).Count() == 0)
                                reqRerun = true;

                        }
                        else
                            pStm.Parent().RemoveChild(pStm);
                        return;
                    }
                }
            }
            base.CaseAALocalDecl(node);
        }
        //Convert struct variables to a collection of local variables
        public override void CaseAALocalDecl(AALocalDecl node)
        {
            if (node.GetType() is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType) node.GetType()) && Util.HasAncestor<PStm>(node))
            {
                //Can not have init - it would be bulk copy
                AStructDecl str = data.StructTypeLinks[(ANamedType) node.GetType()];
                Dictionary<AALocalDecl, AALocalDecl> variableMap = new Dictionary<AALocalDecl, AALocalDecl>();
                PStm pStm = (PStm) node.Parent();
                AABlock pBlock = (AABlock) pStm.Parent();
                foreach (AALocalDecl structLocal in str.GetLocals())
                {

                    AALocalDecl replacementLocal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                   Util.MakeClone(structLocal.GetType(), data),
                                                                   new TIdentifier(node.GetName().Text + "_" +
                                                                                   structLocal.GetName().Text), null);
                    pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), replacementLocal));

                    AALocalDecl baseLocal = structLocal;
                    if (data.EnheritanceLocalMap.ContainsKey(baseLocal))
                        baseLocal = data.EnheritanceLocalMap[baseLocal];
                    List<AALocalDecl> localsToAdd = new List<AALocalDecl>();
                    localsToAdd.AddRange(data.EnheritanceLocalMap.Where(pair => pair.Value == baseLocal).Select(pair => pair.Key));
                    localsToAdd.Add(baseLocal);
                    foreach (AALocalDecl localDecl in localsToAdd)
                    {
                        variableMap[localDecl] = replacementLocal;
                    }
                }
                List<ALocalLvalue> uses = new List<ALocalLvalue>();
                uses.AddRange(data.LocalLinks.Where(k => k.Value == node && Util.GetAncestor<AAProgram>(k.Key) != null).Select(k => k.Key));
                foreach (ALocalLvalue lvalue in uses)
                {
                    AStructLvalue structLocalRef = (AStructLvalue) lvalue.Parent().Parent();

                    AALocalDecl replacementLocal = variableMap[data.StructFieldLinks[structLocalRef]];
                    ALocalLvalue replacementLvalue = new ALocalLvalue(new TIdentifier(replacementLocal.GetName().Text));
                    data.LocalLinks[replacementLvalue] = replacementLocal;
                    data.LvalueTypes[replacementLvalue] = replacementLocal.GetType();
                    structLocalRef.ReplaceBy(replacementLvalue);
                }
                foreach (AALocalDecl replacementLocal in variableMap.Select(k => k.Value))
                {
                    replacementLocal.Apply(this);
                }
            }
            base.CaseAALocalDecl(node);
        }
 public override void CaseAMultiLocalDecl(AMultiLocalDecl node)
 {
     PStm pStm = Util.GetAncestor<PStm>(node);
     if (!(pStm.Parent() is AABlock))
     {
         errors.Add(new ErrorCollection.Error(GetToken(node.GetType()), currentSourceFile, LocRM.GetString("ErrorText203")));
         return;
     }
     AABlock pBlock = (AABlock) pStm.Parent();
     List<AALocalDecl> newDecls = new List<AALocalDecl>();
     foreach (AALocalDeclRight right in node.GetLocalDeclRight())
     {
         if (right.GetName() == null)
         {
             errors.Add(new ErrorCollection.Error(GetToken(node.GetType()), currentSourceFile, LocRM.GetString("ErrorText204")));
             continue;
         }
         if ((right.GetAssignop() == null) != (right.GetInit() == null))
         {
             errors.Add(new ErrorCollection.Error(GetToken(node.GetType()), currentSourceFile, LocRM.GetString("ErrorText205")));
             continue;
         }
         AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null,
                                                 node.GetConst() != null
                                                     ? (TConst) node.GetConst().Clone()
                                                     : null,
                                                 (PType) node.GetType().Clone(),
                                                 right.GetName(),
                                                 right.GetInit());
         newDecls.Add(localDecl);
         pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), localDecl));
     }
     pBlock.RemoveChild(pStm);
     foreach (AALocalDecl localDecl in newDecls)
     {
         localDecl.Apply(this);
     }
 }
        public override void CaseANonstaticInvokeExp(ANonstaticInvokeExp node)
        {
            PExp reciever = node.GetReceiver();
            PType type = finalTrans.data.ExpTypes[reciever];

            //If the reciever is not a var, put it in a new var.
            if (!(reciever is ALvalueExp))
            {
                AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(type, data), new TIdentifier("nonstaticInvokeVar"), reciever);
                ALocalLvalue localRef = new ALocalLvalue(new TIdentifier("nonstaticInvokeVar"));
                ALvalueExp localRefExp = new ALvalueExp(localRef);
                node.SetReceiver(localRefExp);
                PStm pStm = Util.GetAncestor<PStm>(node);
                AABlock pBlock = (AABlock) pStm.Parent();
                pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), localDecl));
                reciever = localRefExp;

                data.LvalueTypes[localRef] =
                    data.ExpTypes[localRefExp] = type;
                data.LocalLinks[localRef] = localDecl;

                localDecl.Apply(this);
            }

            if (type is ANamedType && finalTrans.data.StructTypeLinks.ContainsKey((ANamedType)type))
            {
                //ANamedType type = (ANamedType) finalTrans.data.ExpTypes[reciever];
                if (finalTrans.data.StructTypeLinks[(ANamedType) type].GetClassToken() != null)
                {
                    //Pass the pointer
                    ALvalueExp lvalueExp = (ALvalueExp) reciever;
                    APointerLvalue pointerLvalue = (APointerLvalue) lvalueExp.GetLvalue();
                    reciever = pointerLvalue.GetBase();
                }

                AMethodDecl method = finalTrans.data.StructMethodLinks[node];
                ASimpleInvokeExp simpleInvoke = new ASimpleInvokeExp();
                simpleInvoke.SetName(node.GetName());
                PExp[] exps = new PExp[node.GetArgs().Count];
                node.GetArgs().CopyTo(exps, 0);
                foreach (PExp exp in exps)
                {
                    simpleInvoke.GetArgs().Add(exp);
                }
                simpleInvoke.GetArgs().Add(reciever);
                node.ReplaceBy(simpleInvoke);
                finalTrans.data.SimpleMethodLinks[simpleInvoke] = method;
                finalTrans.data.StructMethodLinks.Remove(node);
                finalTrans.data.ExpTypes[simpleInvoke] = method.GetReturnType();
                finalTrans.data.ExpTypes.Remove(node);
                simpleInvoke.Apply(this);
            }
            else
            {//Enrichment
                /*AEnrichmentDecl enrichment = finalTrans.data.EnrichmentTypeLinks[type];

                foreach (AEnrichmentDecl enrichmentDecl in finalTrans.data.Enrichments)
                {
                    if (Util.IsVisible(node, enrichmentDecl) &&
                        Util.IsDeclVisible(enrichmentDecl, Util.GetAncestor<AASourceFile>(node)) &&
                        Util.TypesEqual(type, enrichmentDecl.GetType(), finalTrans.data))
                    {
                        enrichment = enrichmentDecl;
                        break;
                    }
                }
                if (enrichment == null)
                {
                    finalTrans.errors.Add(new ErrorCollection.Error(node.GetName(), "TransFormMethodDecls.NonStaticInvoke: Expected enrichment - this is a bug. It should have been caught earlier"));
                    throw new ParserException(node.GetName(), "");
                }*/
                AMethodDecl method = finalTrans.data.StructMethodLinks[node];
                ASimpleInvokeExp simpleInvoke = new ASimpleInvokeExp();
                simpleInvoke.SetName(node.GetName());
                PExp[] exps = new PExp[node.GetArgs().Count];
                node.GetArgs().CopyTo(exps, 0);
                foreach (PExp exp in exps)
                {
                    simpleInvoke.GetArgs().Add(exp);
                }
                simpleInvoke.GetArgs().Add(reciever);
                node.ReplaceBy(simpleInvoke);
                finalTrans.data.SimpleMethodLinks[simpleInvoke] = method;
                finalTrans.data.StructMethodLinks.Remove(node);
                finalTrans.data.ExpTypes[simpleInvoke] = method.GetReturnType();
                finalTrans.data.ExpTypes.Remove(node);
                simpleInvoke.Apply(this);

            }
        }
            public override void OutAALocalDecl(AALocalDecl node)
            {
                if (node.GetInit() != null)
                {
                    PType type = node.GetType();
                    if (Util.IsBulkCopy(type))
                    {
                        node.Apply(mover);
                        ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(node.GetName().Text));
                        data.LocalLinks[lvalue] = node;
                        data.LvalueTypes[lvalue] = type;
                        List<PStm> replacementStatements = MakeAssignments(lvalue, node.GetInit(),
                                                                           new List<AALocalDecl>() { null });
                        PStm pStm = Util.GetAncestor<PStm>(node);
                        AABlock pBlock = (AABlock)pStm.Parent();
                        foreach (PStm stm in replacementStatements)
                        {
                            pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm) + 1, stm);
                        }
                        node.SetInit(null);
                    }

                }
                base.OutAALocalDecl(node);
            }