public MethodDescription(AMethodDecl method)
        {
            Parser parser = new Parser(method);

            Start = parser.Start;
            End = parser.End;
            ReturnType = parser.ReturnType;
            Name = parser.Name;
            Formals = parser.Formals;
            Locals = parser.Locals;
            if (method.Parent() != null)
                method.Parent().RemoveChild(method);
            IsDelegate = method.GetDelegate() != null;
            //if (!IsDelegate)
                Decl = method;
            IsStatic = method.GetStatic() != null;
            Visibility = method.GetVisibilityModifier();
            realType = (PType)method.GetReturnType().Clone();
            Position = TextPoint.FromCompilerCoords(method.GetName());
        }
 public override void CaseAMethodDecl(AMethodDecl node)
 {
     InAMethodDecl(node);
     if (node.GetBlock() != null)
     {
         node.GetBlock().Apply(this);
     }
     {
         Object[] temp = new Object[node.GetFormals().Count];
         node.GetFormals().CopyTo(temp, 0);
         for (int i = temp.Length - 1; i >= 0; i--)
         {
             ((PLocalDecl)temp[i]).Apply(this);
         }
     }
     if (node.GetName() != null)
     {
         node.GetName().Apply(this);
     }
     if (node.GetReturnType() != null)
     {
         node.GetReturnType().Apply(this);
     }
     if (node.GetDelegate() != null)
     {
         node.GetDelegate().Apply(this);
     }
     if (node.GetInline() != null)
     {
         node.GetInline().Apply(this);
     }
     if (node.GetNative() != null)
     {
         node.GetNative().Apply(this);
     }
     if (node.GetStatic() != null)
     {
         node.GetStatic().Apply(this);
     }
     if (node.GetTrigger() != null)
     {
         node.GetTrigger().Apply(this);
     }
     if (node.GetVisibilityModifier() != null)
     {
         node.GetVisibilityModifier().Apply(this);
     }
     OutAMethodDecl(node);
 }
        /*public override void InAMethodDecl(AMethodDecl node)
        {
            AABlock block = (AABlock) node.GetBlock();
            if (block != null)
            {
                if (!data.Locals.ContainsKey(block))
                    data.Locals.Add(block, new List<AALocalDecl>());
                foreach (AALocalDecl formal in node.GetFormals())
                {
                    data.Locals[block].Add(formal);
                }
            }
        }

        public override void InAConstructorDecl(AConstructorDecl node)
        {
            AABlock block = (AABlock)node.GetBlock();
            if (block != null)
            {
                if (!data.Locals.ContainsKey(block))
                    data.Locals.Add(block, new List<AALocalDecl>());
                foreach (AALocalDecl formal in node.GetFormals())
                {
                    data.Locals[block].Add(formal);
                }
            }
        }*/
        public override void OutAMethodDecl(AMethodDecl node)
        {
            AStructDecl parentStruct = Util.GetAncestor<AStructDecl>(node);
            AEnrichmentDecl parentEnrichment = Util.GetAncestor<AEnrichmentDecl>(node);
            if (parentStruct != null)
            {
                //Struct method
                data.StructMethods[parentStruct].Add(node);
            }
            else if (parentEnrichment == null)
            {//Global method
                //Dont care about abstract methods - will add them later
                if (node.GetBlock() != null || node.GetNative() != null)
                {
                    data.Methods.Add(new SharedData.DeclItem<AMethodDecl>(currentSourceFile, node));
                    data.UserMethods.Add(node);
                }
                else if (node.GetDelegate() != null)
                    data.Delegates.Add(new SharedData.DeclItem<AMethodDecl>(currentSourceFile, node));
                else
                {
                    node.Parent().RemoveChild(node);
                    return;
                }
            }
            base.OutAMethodDecl(node);
        }
 public override void OutAMethodDecl(AMethodDecl node)
 {
     //If void return is missing, insert it.
     if (node.GetReturnType() is AVoidType && node.GetBlock() != null)
     {
         AABlock block = (AABlock)node.GetBlock();
         bool insertReturn = false;
         while (true)
         {
             if (block.GetStatements().Count == 0)
             {
                 insertReturn = true;
                 break;
             }
             PStm lastStm = (PStm)block.GetStatements()[block.GetStatements().Count - 1];
             if (lastStm is AVoidReturnStm)
                 break;
             if (lastStm is ABlockStm)
             {
                 block = (AABlock)((ABlockStm)block.GetStatements()[block.GetStatements().Count - 1]).GetBlock();
                 continue;
             }
             insertReturn = true;
             break;
         }
         if (insertReturn)
         {
             block.GetStatements().Add(new AVoidReturnStm(new TReturn("return", block.GetToken().Line, block.GetToken().Pos)));
         }
     }
     //Check if delegate is valid
     if (node.GetDelegate() != null)
     {
         if (node.GetBlock() != null)
             errors.Add(new ErrorCollection.Error(node.GetDelegate(), currentSourceFile, LocRM.GetString("ErrorText195")));
         if (node.GetInline() != null)
             errors.Add(new ErrorCollection.Error(node.GetDelegate(), currentSourceFile, LocRM.GetString("ErrorText196")));
         if (node.GetTrigger() != null)
             errors.Add(new ErrorCollection.Error(node.GetDelegate(), currentSourceFile, LocRM.GetString("ErrorText197")));
         if (node.GetStatic() != null)
             errors.Add(new ErrorCollection.Error(node.GetDelegate(), currentSourceFile, LocRM.GetString("ErrorText198")));
         if (node.GetNative() != null)
             errors.Add(new ErrorCollection.Error(node.GetDelegate(), currentSourceFile, LocRM.GetString("ErrorText199")));
     }
     //If it's protected, it must be in a struct
     if (!Util.HasAncestor<AStructDecl>(node))
     {
         if (node.GetVisibilityModifier() is AProtectedVisibilityModifier)
             errors.Add(new ErrorCollection.Error(node.GetName(),
                                                  LocRM.GetString("ErrorText200")));
     }
     base.OutAMethodDecl(node);
 }
        /*
        private PLvalue Disambiguate(PName name)
        {
            ASimpleName aName = (ASimpleName)name;
            AABlock block = Util.GetAncestor<AABlock>(aName);

            while (block != null || Util.HasAncestor<AConstructorDecl>(aName))
            {//We might reference a local
                if (block != null && !data.Locals.ContainsKey(block)) data.Locals.Add(block, new List<AALocalDecl>());
                List<AALocalDecl> locals = new List<AALocalDecl>();
                if (block != null)
                    locals = data.Locals[block];
                else
                {
                    foreach (AALocalDecl formal in Util.GetAncestor<AConstructorDecl>(aName).GetFormals())
                    {
                        locals.Add(formal);
                    }
                }

                foreach (AALocalDecl local in locals)
                {
                    if (aName.GetIdentifier().Text == local.GetName().Text)
                    {
                        //First, the local must not be used before it's declared
                        PStm currentStm = Util.GetAncestor<PStm>(name);
                        PStm targetStm = Util.GetAncestor<PStm>(local);
                        if (currentStm is ASwitchCaseStm)
                            currentStm = (PStm)currentStm.Parent();
                        if (targetStm is ASwitchCaseStm)
                            targetStm = (PStm)targetStm.Parent();
                        //If its a parameter, there will be no parent stm, and then there is no problem)
                        if (targetStm != null)
                        {
                            AABlock currentBlock = (AABlock) currentStm.Parent();
                            AABlock targetBlock = (AABlock)targetStm.Parent();
                            while (targetBlock != currentBlock)
                            {
                                if (Util.IsAncestor(targetStm, currentBlock))
                                {
                                    do
                                    {
                                        targetStm = Util.GetAncestor<PStm>(targetStm.Parent());
                                    } while (!(targetStm.Parent() is AABlock));
                                    targetBlock = (AABlock) targetStm.Parent();
                                    continue;
                                }
                                if (Util.IsAncestor(currentStm, targetBlock))
                                {
                                    do
                                    {
                                        currentStm = Util.GetAncestor<PStm>(currentStm.Parent());
                                    } while (!(currentStm.Parent() is AABlock));
                                    currentBlock = (AABlock)currentStm.Parent();
                                    continue;
                                }
                            }
                            if (currentBlock.GetStatements().IndexOf(currentStm) <= targetBlock.GetStatements().IndexOf(targetStm))
                            {
                                continue;
                            }
                        }

                        //We will replace with this, so might aswell add it to local_links
                        ALocalLvalue localLvalue = new ALocalLvalue(aName.GetIdentifier());
                        data.LocalLinks.Add(localLvalue, local);

                        return localLvalue;
                    }
                }
                if (block == null)
                    break;
                block = Util.GetAncestor<AABlock>(block.Parent());
            }

            //Look for struct fields if inside a struct
            bool matchedStatic = false;
            AStructDecl str = Util.GetAncestor<AStructDecl>(name);
            if (str != null)
            {
                foreach (AALocalDecl local in data.StructFields[str])
                {
                    if (aName.GetIdentifier().Text == local.GetName().Text)
                    {
                        //If it's an enherited private variable, you can't refer to it.
                        if (local.GetVisibilityModifier() is APrivateVisibilityModifier &&
                            data.EnheritanceLocalMap.ContainsKey(local))
                        {
                            continue;
                        }
                        if (local.GetStatic() != null)
                        {
                            //matchedStatic = true;
                            //continue;
                            ATypeLvalue typeLvalue = new ATypeLvalue(new TIdentifier(str.GetName().Text));
                            AStructLvalue structLvalue = new AStructLvalue(new ALvalueExp(typeLvalue), new ADotDotType(new TDot(".")), aName.GetIdentifier());
                            return structLvalue;
                        }

                        if (str.GetClassToken() == null && !Util.HasAncestor<AConstructorDecl>(name) && !Util.HasAncestor<ADeconstructorDecl>(name))
                        {
                            //We will replace with this, so might aswell add it to local_links
                            AStructFieldLvalue structFieldLvalue = new AStructFieldLvalue(aName.GetIdentifier());
                            data.StructMethodFieldLinks.Add(structFieldLvalue, local);
                            return structFieldLvalue;
                        }
                        else
                        {
                            AStructLvalue structLvalue =
                                new AStructLvalue(new ALvalueExp(new APointerLvalue(new TStar("*"), new ALvalueExp(new AThisLvalue(new TThis("this"))))),
                                                  new ADotDotType(new TDot(".")), aName.GetIdentifier());
                            return structLvalue;
                        }
                    }
                }

                //Might be a struct property
                foreach (APropertyDecl local in data.StructProperties[str])
                {
                    if (aName.GetIdentifier().Text == local.GetName().Text)
                    {

                        //If it's an enherited private variable, you can't refer to it.
                        if (local.GetVisibilityModifier() is APrivateVisibilityModifier &&
                            Util.GetAncestor<AStructDecl>(local) != str)
                        {
                            continue;
                        }

                        if (local.GetStatic() != null)
                        {
                            //matchedStatic = true;
                            //continue;
                            ATypeLvalue typeLvalue = new ATypeLvalue(new TIdentifier(str.GetName().Text));
                            AStructLvalue structLvalue = new AStructLvalue(new ALvalueExp(typeLvalue), new ADotDotType(new TDot(".")), aName.GetIdentifier());
                            return structLvalue;
                        }

                        if (str.GetClassToken() == null && !Util.HasAncestor<AConstructorDecl>(name) && !Util.HasAncestor<ADeconstructorDecl>(name))
                        {
                            //We will replace with this, so might aswell add it to local_links
                            AStructFieldLvalue structFieldLvalue = new AStructFieldLvalue(aName.GetIdentifier());
                            data.StructMethodPropertyLinks.Add(structFieldLvalue, local);
                            return structFieldLvalue;
                        }
                        else
                        {
                            AStructLvalue structLvalue =
                                new AStructLvalue(new ALvalueExp(new APointerLvalue(new TStar("*"), new ALvalueExp(new AThisLvalue(new TThis("this"))))),
                                                  new ADotDotType(new TDot(".")), aName.GetIdentifier());
                            return structLvalue;
                        }
                    }
                }
            }

            //Look for fields
            foreach (SharedData.DeclItem<AFieldDecl> declItem in data.Fields)
            {
                AFieldDecl field = declItem.Decl;
                if (!Util.IsVisible(name, field))
                    continue;
                //Static fields must be referenced from same file.
                if ((field.GetStatic() != null) &&
                    Util.GetAncestor<AASourceFile>(field) != Util.GetAncestor<AASourceFile>(aName))
                    continue;
                //Private fields must be referenced from same namespace
                if (field.GetVisibilityModifier() is APrivateVisibilityModifier &&
                    !Util.IsSameNamespace(field, name))
                    continue;

                if (aName.GetIdentifier().Text == field.GetName().Text)
                {
                    //We will replace with this, so might aswell add it to local_links
                    AFieldLvalue fieldLvalue = new AFieldLvalue(aName.GetIdentifier());
                    data.FieldLinks.Add(fieldLvalue, field);
                    return fieldLvalue;
                }
            }

            //Look for properties
            foreach (SharedData.DeclItem<APropertyDecl> declItem in data.Properties)
            {
                APropertyDecl property = declItem.Decl;
                if (!Util.IsVisible(name, property))
                    continue;
                //Static fields must be referenced from same file.
                if ((property.GetStatic() != null) &&
                    Util.GetAncestor<AASourceFile>(property) != Util.GetAncestor<AASourceFile>(aName))
                    continue;
                //Private fields must be referenced from same namespace
                if (property.GetVisibilityModifier() is APrivateVisibilityModifier &&
                    !Util.IsSameNamespace(property, name))
                    continue;
                if (aName.GetIdentifier().Text == property.GetName().Text)
                {
                    //We will replace with this, so might aswell add it to local_links
                    APropertyLvalue propertyLvalue = new APropertyLvalue(aName.GetIdentifier());
                    data.PropertyLinks.Add(propertyLvalue, property);
                    return propertyLvalue;
                }
            }

            //Look in lib fields
            foreach (AFieldDecl field in data.Libraries.Fields)
            {
                if (aName.GetIdentifier().Text == field.GetName().Text)
                {
                    //We will replace with this, so might aswell add it to local_links
                    AFieldLvalue fieldLvalue = new AFieldLvalue(aName.GetIdentifier());
                    data.FieldLinks.Add(fieldLvalue, field);
                    return fieldLvalue;
                }
            }

            //Look for methods
            /*if (name.Parent().Parent() is ALvalueExp && (name.Parent().Parent().Parent() is AAssignmentExp ||
                                                         name.Parent().Parent().Parent() is AALocalDecl ||
                                                         name.Parent().Parent().Parent() is AFieldDecl))//Methods can only be on the right side of an assignment
            {

                AMethodLvalue methodLvalue = new AMethodLvalue(aName.GetIdentifier());
                foreach (SharedData.DeclItem<AMethodDecl> declItem in data.Methods)
                {
                    AMethodDecl method = declItem.Decl;
                    if (!Util.IsVisible(name, method))
                        continue;
                    //Static fields must be referenced from same file.
                    if (method.GetStatic() != null && Util.GetAncestor<AASourceFile>(method) != Util.GetAncestor<AASourceFile>(aName))
                        continue;
                    if (aName.GetIdentifier().Text == method.GetName().Text)
                    {
                        if (!data.MethodLvalueLinks.ContainsKey(methodLvalue))
                            data.MethodLvalueLinks.Add(methodLvalue, new List<AMethodDecl>());
                        data.MethodLvalueLinks[methodLvalue].Add(method);
                    }
                }
                if (data.MethodLvalueLinks.ContainsKey(methodLvalue))
                    return methodLvalue;
            }*/
        /*

            if (name.Parent().Parent().Parent() is AStructLvalue || name.Parent().Parent().Parent() is ANonstaticInvokeExp)
            {
                bool matchesNamespace = false;
                bool matchesStaticType = GalaxyKeywords.Primitives.words.Contains(aName.GetIdentifier().Text);
                AAProgram program = Util.GetAncestor<AAProgram>(name);
                foreach (AASourceFile sourceFile in program.GetSourceFiles())
                {
                    if (sourceFile.GetNamespace() != null && sourceFile.GetNamespace().Text == aName.GetIdentifier().Text)
                    {
                        matchesNamespace = true;
                    }

                    if (Util.IsVisible(name, sourceFile))
                    {
                        foreach (AStructDecl s in sourceFile.GetDecl().OfType<AStructDecl>())
                        {
                            if (s.GetVisibilityModifier() is APrivateVisibilityModifier && !Util.IsSameNamespace(name, s))
                                continue;

                            if (s.GetName().Text == aName.GetIdentifier().Text)
                                matchesStaticType = true;
                        }
                    }
                }

                if (matchesStaticType)
                {
                    if (matchesNamespace)
                    {
                        return new AAmbiguousNameLvalue(name);
                    }
                    return new ATypeLvalue(aName.GetIdentifier());
                }
                if (matchesNamespace)
                {
                    return new ANamespaceLvalue(aName.GetIdentifier());
                }
            }

            /*
            //AmbigiousLvalue, LvalueExp, structlvalue/array/nonstaticInvoke
            //Might have been a namespace prefix
            if (name.Parent().Parent().Parent() is AStructLvalue && !(name.Parent().Parent().Parent().Parent() is ADelegateExp))
            {
                AStructLvalue structLvalue = (AStructLvalue) name.Parent().Parent().Parent();
                AAProgram program = Util.GetAncestor<AAProgram>(name);
                foreach (AASourceFile sourceFile in program.GetSourceFiles())
                {
                    if (sourceFile.GetNamespace() != null &&
                        sourceFile.GetNamespace().Text == aName.GetIdentifier().Text)
                    {
                        foreach (PDecl decl in sourceFile.GetDecl())
                        {
                            if (!(decl is AFieldDecl))
                                continue;
                            AFieldDecl field = (AFieldDecl)decl;
                            if (field.GetName().Text == structLvalue.GetName().Text)
                            {
                                //Static fields must be referenced from same file.
                                if ((field.GetStatic() != null || field.GetVisibilityModifier() is APrivateVisibilityModifier) &&
                                    Util.GetAncestor<AASourceFile>(field) != Util.GetAncestor<AASourceFile>(aName))
                                    continue;

                                AFieldLvalue fieldLvalue = new AFieldLvalue(structLvalue.GetName());
                                data.FieldLinks.Add(fieldLvalue, field);
                                structLvalue.ReplaceBy(fieldLvalue);
                                //fieldLvalue.Apply(this);
                                return null;
                            }
                        }
                    }
                }
            }
            if (name.Parent().Parent().Parent() is ANonstaticInvokeExp)
            {
                ANonstaticInvokeExp invoke = (ANonstaticInvokeExp) name.Parent().Parent().Parent();
                AAProgram program = Util.GetAncestor<AAProgram>(name);
                foreach (AASourceFile sourceFile in program.GetSourceFiles())
                {
                    if (sourceFile.GetNamespace() != null &&
                        sourceFile.GetNamespace().Text == aName.GetIdentifier().Text)
                    {
                        ASimpleInvokeExp simpleInvoke = new ASimpleInvokeExp(invoke.GetName(), new List<PExp>());
                        while (invoke.GetArgs().Count > 0)
                        {
                            simpleInvoke.GetArgs().Add(invoke.GetArgs()[0]);
                        }
                        data.SimpleNamespaceInvokes.Add(simpleInvoke, aName.GetIdentifier().Text);
                        invoke.ReplaceBy(simpleInvoke);
                        simpleInvoke.Apply(this);
                        return null;

                    }
                }
            }
            //Static field
            if (name.Parent().Parent() is ALvalueExp &&
                name.Parent().Parent().Parent() is AStructLvalue)
            {
                AStructLvalue strLvalue = (AStructLvalue)name.Parent().Parent().Parent();
                foreach (AStructDecl s in data.Structs.Select(declItem => declItem.Decl))
                {
                    if (s.GetName().Text == aName.GetIdentifier().Text)
                    {
                        foreach (AALocalDecl structField in s.GetLocals().OfType<AALocalDecl>())
                        {
                            if (structField.GetName().Text == strLvalue.GetName().Text && !data.EnheritanceLocalMap.ContainsKey(structField))
                            {
                                if (structField.GetStatic() == null)
                                {
                                    errors.Add(new ErrorCollection.Error(strLvalue.GetName(),
                                                                         "The struct field is not marked as static.",
                                                                         false,
                                                                         new ErrorCollection.Error(
                                                                             structField.GetName(), "Matching field")));
                                    throw new ParserException(null, "");
                                }
                                AStructFieldLvalue structFieldLvalue = new AStructFieldLvalue(new TIdentifier("renameMe"));
                                data.StructMethodFieldLinks[structFieldLvalue] = structField;
                                strLvalue.ReplaceBy(structFieldLvalue);
                                return null;
                            }
                        }
                    }
                }
            }
            //name.Parent is AAmbigiousLvalue
            //PP is lvalueExp
            //PPP is AStructLvalue
            if ( name.Parent().Parent() is ALvalueExp &&
                 name.Parent().Parent().Parent() is AStructLvalue &&
                 name.Parent().Parent().Parent().Parent() is ADelegateExp)
                return new ANamespaceLvalue(aName.GetIdentifier());
            */
        /*

            if (matchedStatic)
            {
                errors.Add(new ErrorCollection.Error(aName.GetIdentifier(), "To reference a static field/property, you must type " + str.GetName().Text + "." + aName.GetIdentifier().Text));
            }
            else
                errors.Add(new ErrorCollection.Error(aName.GetIdentifier(), currentSourceFile, aName.GetIdentifier().Text + " did not match any defined methods, fields, locals or namespaces"), true);
            return null;
        }*/
        public override void CaseAMethodDecl(AMethodDecl node)
        {
            if (node.GetDelegate() != null)
            {
                node.Parent().RemoveChild(node);
            }

            base.CaseAMethodDecl(node);
        }