예제 #1
0
 public override void CaseADelegateExp(ADelegateExp node)
 {
     InADelegateExp(node);
     if (node.GetLvalue() != null)
     {
         node.GetLvalue().Apply(this);
     }
     if (node.GetType() != null)
     {
         node.GetType().Apply(this);
     }
     if (node.GetToken() != null)
     {
         node.GetToken().Apply(this);
     }
     OutADelegateExp(node);
 }
        public override void OutADelegateExp(ADelegateExp node)
        {
            //Find the type of delegate
            ANamedType type = (ANamedType) node.GetType();
            if (!data.DelegateTypeLinks.ContainsKey(type))
            {
                errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText93")));
                throw new ParserException(node.GetToken(), "TypeChecking.OutADelegateExp");
            }
            AMethodDecl delegateDef = data.DelegateTypeLinks[type];
            List<PType> argTypes = new List<PType>();
            foreach (AALocalDecl formal in delegateDef.GetFormals())
            {
                argTypes.Add(formal.GetType());
            }

            APointerLvalue reciever = null;
            string methodName;
            Token token;
            Node targetReciever;
            if (node.GetLvalue() is AAmbiguousNameLvalue)
            {
                AAmbiguousNameLvalue ambigious = (AAmbiguousNameLvalue)node.GetLvalue();
                AAName aName = (AAName)ambigious.GetAmbiguous();
                methodName = aName.AsString();
                token = (TIdentifier)aName.GetIdentifier()[aName.GetIdentifier().Count - 1];
                aName.GetIdentifier().RemoveAt(aName.GetIdentifier().Count - 1);
                targetReciever = aName.GetIdentifier().Count > 0 ? aName : null;
            }
            else//node.getLvalue is AStructLvalue
            {
                AStructLvalue lvalue = (AStructLvalue) node.GetLvalue();
                token = lvalue.GetName();
                methodName = token.Text;
                targetReciever = lvalue.GetReceiver();
            }

            List<AMethodDecl> candidates = new List<AMethodDecl>();
            List<AMethodDecl> implicitCandidates = new List<AMethodDecl>();
            List<AMethodDecl> matchingNames = new List<AMethodDecl>();
            PExp baseExp;
            bool matchResize;
            GetTargets(token.Text, node.GetToken(), targetReciever, delegateDef.GetReturnType(), argTypes, candidates, out matchResize, implicitCandidates, matchingNames, out baseExp, null, data, errors);

            if (candidates.Count == 0 && implicitCandidates.Count > 0)
            {
                //Implicit candidates not allowed
                errors.Add(new ErrorCollection.Error(token, LocRM.GetString("ErrorText94"),
                                                     false,
                                                     new ErrorCollection.Error(implicitCandidates[0].GetName(),
                                                                               LocRM.GetString("ErrorText38"))));
                throw new ParserException(token, "OutADelegateExp");
            }

            if (baseExp is ALvalueExp)
            {
                ALvalueExp exp = (ALvalueExp)baseExp;
                if (exp.GetLvalue() is APointerLvalue)
                {
                    reciever = (APointerLvalue) exp.GetLvalue();
                    node.SetLvalue(reciever);
                    reciever.Apply(this);
                }
                else
                {
                    errors.Add(new ErrorCollection.Error(token, LocRM.GetString("ErrorText95"),
                                                         false,
                                                         new ErrorCollection.Error(candidates[0].GetName(),
                                                                                   LocRM.GetString("ErrorText38"))));
                    throw new ParserException(token, "OutADelegateExp");
                }
            }
            else if (baseExp == null)
            {
                //Target is either a global method, a static struct method, or a struct method -> struct method
                //Last one is invalid.
                AStructDecl parentStruct = Util.GetAncestor<AStructDecl>(candidates[0]);
                if (parentStruct != null && candidates[0].GetStatic() == null &&
                    Util.GetAncestor<AStructDecl>(node).GetClassToken() == null &&
                    Util.GetAncestor<AConstructorDecl>(node) == null &&
                    Util.GetAncestor<ADeconstructorDecl>(node) == null)
                {
                    errors.Add(new ErrorCollection.Error(token, LocRM.GetString("ErrorText95"),
                                                         false,
                                                         new ErrorCollection.Error(candidates[0].GetName(),
                                                                                   LocRM.GetString("ErrorText38"))));
                    throw new ParserException(token, "OutADelegateExp");
                }
            }
            else
            {
                errors.Add(new ErrorCollection.Error(token, LocRM.GetString("ErrorText96"),
                                                     false,
                                                     new ErrorCollection.Error(candidates[0].GetName(),
                                                                               LocRM.GetString("ErrorText38"))));
                throw new ParserException(token, "OutADelegateExp");
            }

            //Found exactly 1 delegate method
            data.DelegateCreationMethod[node] = candidates[0];
            data.ExpTypes[node] = node.GetType();
            data.DelegateRecieveres[node] = reciever;
        }