Exemplo n.º 1
0
 public override void CaseANewExp(ANewExp node)
 {
     InANewExp(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.GetType() != null)
     {
         node.GetType().Apply(this);
     }
     if (node.GetToken() != null)
     {
         node.GetToken().Apply(this);
     }
     OutANewExp(node);
 }
        public override void OutANewExp(ANewExp node)
        {
            /*if (node.GetType() is AArrayTempType)
                data.ExpTypes[node] = node.GetType();
            else*/
                data.ExpTypes[node] = new APointerType(new TStar("*"), Util.MakeClone(node.GetType(), data));

            List<AEnrichmentDecl> enrichments = new List<AEnrichmentDecl>();
            List<IList> visibleDecls = Util.GetVisibleDecls(node, true);
            foreach (IList declList in visibleDecls)
            {
                foreach (PDecl decl in declList)
                {
                    if (decl is AEnrichmentDecl)
                    {
                        AEnrichmentDecl enrichment = (AEnrichmentDecl) decl;
                        if (!Util.TypesEqual(node.GetType(), enrichment.GetType(), data))
                            continue;
                        enrichments.Add(enrichment);
                    }
                }
            }
            if (enrichments.Count > 0 || node.GetType() is ANamedType)
            {
                List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>();
                ANamedType type = (ANamedType) node.GetType();
                if (enrichments.Count > 0 || data.StructTypeLinks.ContainsKey(type))
                {
                    //Find matching constructor
                    //Token token;
                    List<AConstructorDecl> candidates = new List<AConstructorDecl>();
                    if (enrichments.Count == 0)
                    {
                        AStructDecl str = data.StructTypeLinks[type];
                        if (data.Enums.ContainsKey(str))
                        {
                            errors.Add(new ErrorCollection.Error(node.GetToken(),
                                                                 LocRM.GetString("ErrorText138"), false,
                                                                 new ErrorCollection.Error(str.GetName(),
                                                                                           LocRM.GetString("ErrorText139"))));
                        }
                        //token = str.GetName();
                        subErrors.Add(new ErrorCollection.Error(str.GetName(), LocRM.GetString("ErrorText48") + Util.GetTypeName(str)));
                        foreach (AConstructorDecl constructorDecl in data.StructConstructors[str])
                        {
                            //Visiblity
                            if (constructorDecl.GetVisibilityModifier() is APrivateVisibilityModifier &&
                                Util.GetAncestor<AStructDecl>(constructorDecl) != Util.GetAncestor<AStructDecl>(node))
                                continue;
                            if (constructorDecl.GetVisibilityModifier() is AProtectedVisibilityModifier &&
                                (!Util.HasAncestor<AStructDecl>(node) ||
                                !Util.Extends(Util.GetAncestor<AStructDecl>(constructorDecl), Util.GetAncestor<AStructDecl>(node), data)))
                                continue;

                            if (constructorDecl.GetFormals().Count == node.GetArgs().Count)
                            {
                                //Check that parameters are assignable
                                bool add = true;
                                for (int i = 0; i < node.GetArgs().Count; i++)
                                {
                                    PType argType = data.ExpTypes[(PExp)node.GetArgs()[i]];
                                    AALocalDecl formal = (AALocalDecl)constructorDecl.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))
                                    {
                                        add = false;
                                        break;
                                    }
                                }
                                if (add)
                                    candidates.Add(constructorDecl);
                            }
                        }
                    }
                    else
                    {
                        //token = null;
                        foreach (AEnrichmentDecl enrich in enrichments)
                        {
                            //token = enrich.GetToken();
                            subErrors.Add(new ErrorCollection.Error(enrich.GetToken(), LocRM.GetString("ErrorText77")));
                            foreach (AConstructorDecl constructorDecl in enrich.GetDecl().OfType<AConstructorDecl>())
                            {
                                //Visiblity
                                if (constructorDecl.GetVisibilityModifier() is APrivateVisibilityModifier &&
                                    Util.GetAncestor<AEnrichmentDecl>(constructorDecl) !=
                                    Util.GetAncestor<AEnrichmentDecl>(node))
                                    continue;

                                if (constructorDecl.GetFormals().Count == node.GetArgs().Count)
                                {
                                    //Check that parameters are assignable
                                    bool add = true;
                                    for (int i = 0; i < node.GetArgs().Count; i++)
                                    {
                                        PType argType = data.ExpTypes[(PExp) node.GetArgs()[i]];
                                        AALocalDecl formal = (AALocalDecl) constructorDecl.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))
                                        {
                                            add = false;
                                            break;
                                        }
                                    }
                                    if (add)
                                        candidates.Add(constructorDecl);
                                }
                            }
                        }
                    }

                    if (candidates.Count == 0)
                    {
                        if (node.GetArgs().Count == 0 && enrichments.Count > 0)
                            return;

                        string msg = LocRM.GetString("ErrorText140");
                        foreach (PExp arg in node.GetArgs())
                        {
                            if (msg.EndsWith("("))
                                msg += Util.TypeToString(data.ExpTypes[arg]);
                            else
                                msg += ", " + Util.TypeToString(data.ExpTypes[arg]);
                        }
                        msg += ")";
                        errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, msg, false, subErrors.ToArray()), true);
                        return;
                    }
                    if (candidates.Count > 1)
                    {
                        subErrors = new List<ErrorCollection.Error>();
                        int i = 0;
                        foreach (AConstructorDecl candidate in candidates)
                        {
                            i++;
                            subErrors.Add(new ErrorCollection.Error(candidate.GetName(), LocRM.GetString("ErrorText141") + i));
                        }
                        errors.Add(
                            new ErrorCollection.Error(node.GetToken(), currentSourceFile,
                                                      LocRM.GetString("ErrorText142"), false,
                                                      subErrors.ToArray()), true);
                        return;
                    }
                    PStm pStm = Util.GetAncestor<PStm>(node);
                    if (pStm == null)
                    {
                        if (Util.HasAncestor<AFieldDecl>(node))
                        {
                            data.FieldsToInitInMapInit.Add(Util.GetAncestor<AFieldDecl>(node));
                        }
                        else if (Util.HasAncestor<AStructDecl>(node))
                        {
                            //Ignore - will be fixed
                        }
                        else
                            errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile,
                                                                 LocRM.GetString("ErrorText143")));
                    }
                    data.ConstructorLinks.Add(node, candidates[0]);

                    //For each formal marked as ref or out, the argument must be a variable
                    for (int i = 0; i < node.GetArgs().Count; i++)
                    {
                        AALocalDecl formal = (AALocalDecl)candidates[0].GetFormals()[i];
                        if (formal.GetRef() != null || formal.GetOut() != null)
                        {
                            PExp exp = (PExp)node.GetArgs()[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.GetToken(), 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");
                            }
                        }
                    }
                    return;
                }
            }
            //else
            if (node.GetArgs().Count > 0)
            {
                errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText144")));
            }
        }