예제 #1
0
 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);
 }
예제 #2
0
 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);
 }
        public override void OutAMethodDecl(AMethodDecl node)
        {
            if (node.GetTrigger() != null)
            {
                bool validSignature = IsBoolType(node.GetReturnType());
                validSignature &= node.GetFormals().Count == 2;
                foreach (AALocalDecl formal in node.GetFormals())
                {
                    validSignature &= IsBoolType(formal.GetType());
                    validSignature &= formal.GetRef() == null && formal.GetOut() == null;
                }
                if (!validSignature)
                {
                    errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile,
                                                         LocRM.GetString("ErrorText156")));
                }
            }

            //Check that all code paths return a value
            if (!(node.GetReturnType() is AVoidType))
            {
                CheckReturns returnChecker = new CheckReturns();
                node.GetBlock().Apply(returnChecker);
                if (!returnChecker.Returned)
                {
                    errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText157")));
                }
            }

            //If the return type or the type of any formals is a private struct, and the method is a public context, give an error
            {
                AStructDecl pStruct = Util.GetAncestor<AStructDecl>(node);
                //Is public context
                if (pStruct == null && node.GetVisibilityModifier() is APublicVisibilityModifier ||
                    pStruct != null && pStruct.GetVisibilityModifier() is APublicVisibilityModifier && !(node.GetVisibilityModifier() is APrivateVisibilityModifier))
                {
                    PType type = node.GetReturnType();
                    int i = 0;
                    FindPrivateTypes finder = new FindPrivateTypes(data);
                    while (true)
                    {
                        type.Apply(finder);

                        if (i == node.GetFormals().Count)
                            break;
                        AALocalDecl formal = (AALocalDecl) node.GetFormals()[i];
                        type = formal.GetType();
                        i++;
                    }

                    if (finder.PrivateTypes.Count > 0)
                    {
                        List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>();
                        List<PDecl> usedDecls = new List<PDecl>();
                        foreach (ANamedType namedType in finder.PrivateTypes)
                        {
                            if (data.StructTypeLinks.ContainsKey(namedType))
                            {
                                AStructDecl decl = data.StructTypeLinks[namedType];
                                if (usedDecls.Contains(decl))
                                    continue;
                                usedDecls.Add(decl);
                                subErrors.Add(new ErrorCollection.Error(decl.GetName(), LocRM.GetString("ErrorText64")));
                            }
                            else if (data.DelegateTypeLinks.ContainsKey(namedType))
                            {
                                AMethodDecl decl = data.DelegateTypeLinks[namedType];
                                if (usedDecls.Contains(decl))
                                    continue;
                                usedDecls.Add(decl);
                                subErrors.Add(new ErrorCollection.Error(decl.GetName(), LocRM.GetString("ErrorText154")));
                            }
                        }

                        errors.Add(new ErrorCollection.Error(node.GetName(), LocRM.GetString("ErrorText155"), false, subErrors.ToArray()));
                    }
                }
            }

            base.OutAMethodDecl(node);
        }
        //private List<ErrorCollection.Error> multipleEntryCandidates = new List<ErrorCollection.Error>();
        public override void CaseAMethodDecl(AMethodDecl node)
        {
            //Done in a previous iteration
            /*if (node.GetName().Text == "InitMap" && node.GetFormals().Count == 0)
            {
                if (finalTrans.multipleMainEntries)
                {
                    multipleEntryCandidates.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor<AASourceFile>(node.GetName()), "Candidate"));
                }
                else if (finalTrans.mainEntry != null)
                {
                    multipleEntryCandidates.Add(new ErrorCollection.Error(finalTrans.mainEntry.GetName(), Util.GetAncestor<AASourceFile>(finalTrans.mainEntry.GetName()), "Candidate"));
                    multipleEntryCandidates.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor<AASourceFile>(node.GetName()), "Candidate"));
                    //finalTrans.errors.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor<AASourceFile>(node), "Found multiple candidates for a main entry", true));
                    finalTrans.multipleMainEntries = true;
                    finalTrans.mainEntry = null;
                }
                else
                    finalTrans.mainEntry = node;
            }*/

            AStructDecl str = Util.GetAncestor<AStructDecl>(node);
            if (str != null)
            {
                if (node.GetStatic() == null)
                    structMethods.Add(node);
                //Move the method outside the struct
                str.RemoveChild(node.Parent());
                AASourceFile file = (AASourceFile)str.Parent();
                int i = file.GetDecl().IndexOf(str);
                file.GetDecl().Insert(i/* + 1*/, node);
                node.GetName().Text = GetUniqueStructMethodName(str.GetName().Text + "_" + node.GetName().Text);

                if (node.GetStatic() == null)
                {
                    //Add the struct as a parameter
                    PType structType = new ANamedType(new TIdentifier(str.GetName().Text), null);
                    finalTrans.data.StructTypeLinks[(ANamedType) structType] = str;
                    if (str.GetClassToken() != null)
                    {
                        structType = new APointerType(new TStar("*"), structType);
                    }
                    structFormal = new AALocalDecl(new APublicVisibilityModifier(), null,
                                                   str.GetClassToken() == null ? new TRef("ref") : null, null, null,
                                                   structType,
                                                   new TIdentifier("currentStruct", node.GetName().Line,
                                                                   node.GetName().Pos), null);
                    node.GetFormals().Add(structFormal);
                    data.Locals[(AABlock) node.GetBlock()].Add(structFormal);
                }
                else
                    node.SetStatic(null);
                finalTrans.data.Methods.Add(new SharedData.DeclItem<AMethodDecl>(file, node));
                if (node.GetStatic() == null)
                    OldParentStruct[node] = str;
                //Fix refferences to other struct stuff);
                base.CaseAMethodDecl(node);
                //Will visit later, since it's added after the struct
                //base.CaseAMethodDecl(node);
                //if (str.GetLocals().Count == 0)
                //    str.Parent().RemoveChild(str);
                return;
            }
            AEnrichmentDecl enrichment = Util.GetAncestor<AEnrichmentDecl>(node);
            if (enrichment != null)
            {
                if (node.GetStatic() == null)
                    structMethods.Add(node);
                //Move the method outside the struct
                enrichment.RemoveChild(node);
                AASourceFile file = (AASourceFile)enrichment.Parent();
                int i = file.GetDecl().IndexOf(enrichment);
                file.GetDecl().Insert(i/* + 1*/, node);
                node.GetName().Text = GetUniqueStructMethodName(Util.TypeToIdentifierString(enrichment.GetType()) + "_" + node.GetName().Text);

                if (node.GetStatic() == null)
                {
                    //Add the struct as a parameter
                    PType structType = Util.MakeClone(enrichment.GetType(), finalTrans.data);
                    structFormal = new AALocalDecl(new APublicVisibilityModifier(), null, new TRef("ref"), null, null,
                                                   structType,
                                                   new TIdentifier("currentEnrichment", node.GetName().Line,
                                                                   node.GetName().Pos), null);
                    node.GetFormals().Add(structFormal);
                }
                finalTrans.data.Methods.Add(new SharedData.DeclItem<AMethodDecl>(file, node));
                //Fix refferences to other struct stuff);
                base.CaseAMethodDecl(node);
                //Will visit later, since it's added after the struct
                //base.CaseAMethodDecl(node);
                //if (str.GetLocals().Count == 0)
                //    str.Parent().RemoveChild(str);
                return;
            }
            //Build a list of overloads
            List<AMethodDecl> overloads = new List<AMethodDecl>();
            List<string> prefixMatches = new List<string>();

            foreach (SharedData.DeclItem<AMethodDecl> declItem in finalTrans.data.Methods)
            {
                if (!Util.IsSameNamespace(declItem.Decl, node))
                    continue;
                if (declItem.Decl.GetName().Text == node.GetName().Text)
                    overloads.Add(declItem.Decl);
                if (declItem.Decl.GetName().Text.StartsWith(node.GetName().Text + "O"))
                    prefixMatches.Add(declItem.Decl.GetName().Text);
            }

            foreach (AMethodDecl method in finalTrans.data.Libraries.Methods)
            {
                if (method.GetBlock() != null || method.GetNative() != null)
                {
                    if (method.GetName().Text == node.GetName().Text)
                        overloads.Add(method);
                    if (method.GetName().Text.StartsWith(node.GetName().Text + "O"))
                        prefixMatches.Add(method.GetName().Text);
                }
            }

            //Add fields
            foreach (SharedData.DeclItem<AFieldDecl> declItem in finalTrans.data.Fields)
            {
                if (declItem.Decl.GetName().Text.StartsWith(node.GetName().Text + "O"))
                    prefixMatches.Add(declItem.Decl.GetName().Text);
            }

            foreach (AFieldDecl field in finalTrans.data.Libraries.Fields)
            {
                if (field.GetName().Text.StartsWith(node.GetName().Text + "O"))
                    prefixMatches.Add(field.GetName().Text);
            }

            //Dont want to hit another method by appending O#
            string postfix = "";
            while (true)
            {
                postfix += "O";
                if (prefixMatches.Any(text => text.StartsWith(node.GetName().Text + postfix)))
                {
                    continue;
                }
                break;
            }

            if (overloads.Count > 1)
            {
                int i = 0;
                foreach (AMethodDecl method in overloads)
                {
                    if (node == finalTrans.mainEntry || (node.GetTrigger() != null && finalTrans.data.HasUnknownTrigger))
                        continue;
                    i++;
                    method.GetName().Text += postfix + i;
                }
            }

            if (node != finalTrans.mainEntry && (node.GetTrigger() == null || !finalTrans.data.HasUnknownTrigger))
                node.GetName().Text = namespacePrefix + node.GetName().Text;

            base.CaseAMethodDecl(node);
        }
        public override void CaseAMethodDecl(AMethodDecl node)
        {
            if (processStructs || processFieldsOnly || processMethodsOnly)
            {
                base.CaseAMethodDecl(node);
                return;
            }

            bool removed = true;
            List<AALocalDecl> couldntRemove = new List<AALocalDecl>();
            while (removed)
            {
                removed = false;
                definedLocals.Clear();
                usedLocals.Clear();
                assignedToLocals.Clear();
                base.CaseAMethodDecl(node);
                usedLocals.AddRange(finalTrans.data.GeneratedVariables);
                foreach (AALocalDecl definedLocal in definedLocals)
                {
                    if (!usedLocals.Contains(definedLocal) && !couldntRemove.Contains(definedLocal))
                    {
                        if ((Util.GetAncestor<AABlock>(definedLocal) != null || node.GetTrigger() == null) &&
                            finalTrans.data.UserLocals.Contains(definedLocal))
                            children.Add(new ErrorCollection.Error(definedLocal.GetName(),
                                                                            Util.GetAncestor<AASourceFile>(node),
                                                                            LocRM.GetString("ErrorText67") + definedLocal.GetName().Text, true));

                        removed = true;
                        //Remove decl);
                        if (definedLocal.Parent() is ALocalDeclStm)
                        {
                            ALocalDeclStm localDeclStm = (ALocalDeclStm)definedLocal.Parent();
                            RemoveVariableStatement(localDeclStm, definedLocal.GetInit(), localDeclStm.GetToken().Line, localDeclStm.GetToken().Pos);
                        }
                        //Dont remove parameters
                        else
                            couldntRemove.Add(definedLocal);

                        //Remove assignments);
                        foreach (AAssignmentExp assignmentExp in assignedToLocals[definedLocal])
                        {
                            if (assignmentExp.Parent() is AExpStm)
                            {
                                AExpStm stm = (AExpStm)assignmentExp.Parent();
                                RemoveVariableStatement(stm, assignmentExp.GetExp(), stm.GetToken().Line, stm.GetToken().Pos);

                                continue;
                            }
                            PExp exp = assignmentExp.GetExp();
                            assignmentExp.ReplaceBy(exp);
                        }
                    }
                }
            }
        }
 public override void CaseAMethodDecl(AMethodDecl node)
 {
     if (node.GetInline() == null && node.GetTrigger() == null && !(data.ConstructorMap.ContainsValue(node) && !inlineConstructors) && node != finalTrans.mainEntry)
     {
         CountStatements counter = new CountStatements();
         node.Apply(counter);
         if (counter.Count <= 2)
         {
             //Don't inline if it has a recurssive call to itself
             FindRecurssiveCall recurssiveCallSearcher = new FindRecurssiveCall(node, data);
             node.Apply(recurssiveCallSearcher);
             if (!recurssiveCallSearcher.InlinedCallToItself)
             {
                 node.SetInline(new TInline("inline"));
             }
         }
     }
     base.CaseAMethodDecl(node);
 }