public virtual void Visit(DelegateDeclaration td)
        {
            VisitInner(td);
            // ReturnType == InnerDeclaration

            if (td.Modifiers != null && td.Modifiers.Length != 0)
            {
                foreach (var attr in td.Modifiers)
                {
                    attr.Accept(this);
                }
            }

            foreach (var p in td.Parameters)
            {
                p.Accept(this);
            }
        }
Example #2
0
        public static TooltipInformation Generate(DelegateDeclaration dd, int currentParam = -1)
        {
            var sb = new StringBuilder("<i>(Delegate)</i> ");

            if (dd.ReturnType != null)
                sb.Append(dd.ReturnType.ToString(true)).Append(' ');

            if (dd.IsFunction)
                sb.Append("function");
            else
                sb.Append("delegate");

            sb.Append('(');
            if (dd.Parameters != null && dd.Parameters.Count != 0)
            {
                for (int i = 0; i < dd.Parameters.Count; i++)
                {
                    var p = dd.Parameters[i] as DNode;
                    if (i == currentParam)
                    {
                        sb.Append("<u>");
                        sb.Append(p.ToString(false));
                        sb.Append("</u>,");
                    }
                    else
                        sb.Append(p.ToString(false)).Append(',');
                }

                sb.Remove(sb.Length - 1, 1);
            }
            sb.Append(')');

            var tti = new TooltipInformation();
            tti.SignatureMarkup = sb.ToString();

            return tti;
        }
Example #3
0
        public DelegateType(AbstractType ReturnType,DelegateDeclaration Declaration, IEnumerable<AbstractType> Parameters = null)
            : base(ReturnType, Declaration)
        {
            this.IsFunction = Declaration.IsFunction;

            if (Parameters is AbstractType[])
                this.Parameters = (AbstractType[])Parameters;
            else if(Parameters!=null)
                this.Parameters = Parameters.ToArray();
        }
        bool HandleDecl(TemplateTypeParameter par, DelegateDeclaration d, DelegateType dr)
        {
            // Delegate literals or other expressions are not allowed
            if(dr==null || dr.IsFunctionLiteral)
                return false;

            var dr_decl = (DelegateDeclaration)dr.DeclarationOrExpressionBase;

            // Compare return types
            if(	d.IsFunction == dr_decl.IsFunction &&
                dr.ReturnType != null &&
                HandleDecl(par, d.ReturnType,dr.ReturnType))
            {
                // If no delegate args expected, it's valid
                if ((d.Parameters == null || d.Parameters.Count == 0) &&
                    dr_decl.Parameters == null || dr_decl.Parameters.Count == 0)
                    return true;

                // If parameter counts unequal, return false
                else if (d.Parameters == null || dr_decl.Parameters == null || d.Parameters.Count != dr_decl.Parameters.Count)
                    return false;

                // Compare & Evaluate each expected with given parameter
                var dr_paramEnum = dr_decl.Parameters.GetEnumerator();
                foreach (var p in d.Parameters)
                {
                    // Compare attributes with each other
                    if (p is DNode)
                    {
                        if (!(dr_paramEnum.Current is DNode))
                            return false;

                        var dn = (DNode)p;
                        var dn_arg = (DNode)dr_paramEnum.Current;

                        if ((dn.Attributes == null || dn.Attributes.Count == 0) &&
                            (dn_arg.Attributes == null || dn_arg.Attributes.Count == 0))
                            return true;

                        else if (dn.Attributes == null || dn_arg.Attributes == null ||
                            dn.Attributes.Count != dn_arg.Attributes.Count)
                            return false;

                        foreach (var attr in dn.Attributes)
                        {
                            if(!dn_arg.ContainsAttribute(attr))
                                return false;
                        }
                    }

                    // Compare types
                    if (p.Type!=null && dr_paramEnum.MoveNext() && dr_paramEnum.Current.Type!=null)
                    {
                        var dr_resolvedParamType = TypeDeclarationResolver.ResolveSingle(dr_paramEnum.Current.Type, ctxt);

                        if (dr_resolvedParamType == null  ||
                            !HandleDecl(par, p.Type, dr_resolvedParamType))
                            return false;
                    }
                    else
                        return false;
                }
            }

            return false;
        }
Example #5
0
        /// <summary>
        /// Add some syntax possibilities here
        /// int (x);
        /// int(*foo);
        /// This way of declaring function pointers is deprecated
        /// </summary>
        void OldCStyleFunctionPointer(DNode ret, bool IsParam)
        {
            Step();
            //SynErr(OpenParenthesis,"C-style function pointers are deprecated. Use the function() syntax instead."); // Only deprecated in D2
            var cd = new DelegateDeclaration() as ITypeDeclaration;
            ret.Type = cd;
            var deleg = cd as DelegateDeclaration;

            /*
             * Parse all basictype2's that are following the initial '('
             */
            while (IsBasicType2())
            {
                var ttd = BasicType2();

                if (deleg.ReturnType == null)
                    deleg.ReturnType = ttd;
                else
                {
                    if(ttd!=null)
                        ttd.InnerDeclaration = deleg.ReturnType;
                    deleg.ReturnType = ttd;
                }
            }

            /*
             * Here can be an identifier with some optional DeclaratorSuffixes
             */
            if (laKind != (CloseParenthesis))
            {
                if (IsParam && laKind != (Identifier))
                {
                    /* If this Declarator is a parameter of a function, don't expect anything here
                     * except a '*' that means that here's an anonymous function pointer
                     */
                    if (t.Kind != (Times))
                        SynErr(Times);
                }
                else
                {
                    if(Expect(Identifier))
                        ret.Name = t.Value;

                    /*
                     * Just here suffixes can follow!
                     */
                    if (laKind != (CloseParenthesis))
                    {
                        DeclaratorSuffixes(ret);
                    }
                }
            }
            ret.Type = cd;
            Expect(CloseParenthesis);
        }
Example #6
0
        ITypeDeclaration BasicType2()
        {
            // *
            if (laKind == (Times))
            {
                Step();
                return new PointerDecl() { Location=t.Location, EndLocation=t.EndLocation };
            }

            // [ ... ]
            else if (laKind == (OpenSquareBracket))
            {
                var startLoc = la.Location;
                Step();
                // [ ]
                if (laKind == (CloseSquareBracket))
                {
                    Step();
                    return new ArrayDecl() { Location=startLoc, EndLocation=t.EndLocation };
                }

                ITypeDeclaration cd = null;

                // [ Type ]
                Lexer.PushLookAheadBackup();
                bool weaktype = AllowWeakTypeParsing;
                AllowWeakTypeParsing = true;

                var keyType = Type();

                AllowWeakTypeParsing = weaktype;

                if (keyType != null && laKind == CloseSquareBracket && !(keyType is IdentifierDeclaration))
                {
                    //HACK: Both new int[size_t] as well as new int[someConstNumber] are legal. So better treat them as expressions.
                    cd = new ArrayDecl() { KeyType = keyType, ClampsEmpty = false, Location = startLoc };
                    Lexer.PopLookAheadBackup();
                }
                else
                {
                    Lexer.RestoreLookAheadBackup();

                    var fromExpression = AssignExpression();

                    // [ AssignExpression .. AssignExpression ]
                    if (laKind == DoubleDot)
                    {
                        Step();
                        cd = new ArrayDecl() {
                            Location=startLoc,
                            ClampsEmpty=false,
                            KeyType=null,
                            KeyExpression= new PostfixExpression_Slice() {
                                FromExpression=fromExpression,
                                ToExpression=AssignExpression()}};
                    }
                    else
                        cd = new ArrayDecl() { KeyType=null, KeyExpression=fromExpression,ClampsEmpty=false,Location=startLoc };
                }

                if ((AllowWeakTypeParsing && laKind != CloseSquareBracket) || IsEOF)
                    return null;

                Expect(CloseSquareBracket);
                if(cd!=null)
                    cd.EndLocation = t.EndLocation;
                return cd;
            }

            // delegate | function
            else if (laKind == (Delegate) || laKind == (Function))
            {
                Step();
                var dd = new DelegateDeclaration() { Location=t.Location};
                dd.IsFunction = t.Kind == Function;

                if (AllowWeakTypeParsing && laKind != OpenParenthesis)
                    return null;

                dd.Parameters = Parameters(null);

                var attributes = new List<DAttribute>();
                FunctionAttributes(ref attributes);
                dd.Modifiers= attributes.Count > 0 ? attributes.ToArray() : null;

                dd.EndLocation = t.EndLocation;
                return dd;
            }
            else
                SynErr(Identifier);
            return null;
        }
        public virtual void Visit(DelegateDeclaration td)
        {
            VisitInner(td);
            // ReturnType == InnerDeclaration

            if (td.Modifiers != null && td.Modifiers.Length != 0)
                foreach (var attr in td.Modifiers)
                    if(attr != null)
                        attr.Accept(this);

            foreach (var p in td.Parameters)
                if(p != null)
                    p.Accept(this);
        }
Example #8
0
        /// <summary>
        /// Parses a type declarator
        /// </summary>
        /// <returns>A dummy node that contains the return type, the variable name and possible parameters of a function declaration</returns>
        DNode Declarator(ITypeDeclaration basicType,bool IsParam)
        {
            DNode ret = new DVariable() { Type=basicType, Location = la.Location };
            LastParsedObject = ret;
            ITypeDeclaration ttd = null;

            while (IsBasicType2())
            {
                if (ret.Type == null)
                    ret.Type = BasicType2();
                else {
                    ttd = BasicType2();
                    if(ttd!=null)
                        ttd.InnerDeclaration = ret.Type;
                    ret.Type = ttd;
                }
            }
            /*
             * Add some syntax possibilities here
             * like
             * int (x);
             * int(*foo);
             */
            #region This way of declaring function pointers is deprecated
            if (laKind == (OpenParenthesis))
            {
                Step();
                //SynErr(OpenParenthesis,"C-style function pointers are deprecated. Use the function() syntax instead."); // Only deprecated in D2
                var cd = new DelegateDeclaration() as ITypeDeclaration;
                LastParsedObject = cd;
                ret.Type = cd;
                var deleg = cd as DelegateDeclaration;

                /*
                 * Parse all basictype2's that are following the initial '('
                 */
                while (IsBasicType2())
                {
                    ttd = BasicType2();

                    if (deleg.ReturnType == null)
                        deleg.ReturnType = ttd;
                    else
                    {
                        if(ttd!=null)
                            ttd.InnerDeclaration = deleg.ReturnType;
                        deleg.ReturnType = ttd;
                    }
                }

                /*
                 * Here can be an identifier with some optional DeclaratorSuffixes
                 */
                if (laKind != (CloseParenthesis))
                {
                    if (IsParam && laKind != (Identifier))
                    {
                        /* If this Declarator is a parameter of a function, don't expect anything here
                         * except a '*' that means that here's an anonymous function pointer
                         */
                        if (t.Kind != (Times))
                            SynErr(Times);
                    }
                    else
                    {
                        if(Expect(Identifier))
                            ret.Name = t.Value;

                        /*
                         * Just here suffixes can follow!
                         */
                        if (laKind != (CloseParenthesis))
                        {
                            ITemplateParameter[] _unused2 = null;
                            List<INode> _unused = null;
                            List<DAttribute> _unused3 = new List<DAttribute>();
                            ttd = DeclaratorSuffixes(out _unused2, out _unused, _unused3);

                            if (ttd != null)
                            {
                                ttd.InnerDeclaration = cd;
                                cd = ttd;
                            }
                        }
                    }
                }
                ret.Type = cd;
                Expect(CloseParenthesis);
            }
            #endregion
            else
            {
                // On external function declarations, no parameter names are required.
                // extern void Cfoo(HANDLE,char**);
                if (IsParam && laKind != (Identifier))
                {
                    if(ret.Type!=null)
                        ExpectingIdentifier = true;
                    return ret;
                }

                if (Expect(Identifier))
                {
                    ret.Name = t.Value;
                    ret.NameLocation = t.Location;
                }
                else
                {
                    // Code error! - to prevent infinite declaration loops, step one token forward anyway!
                    Step();
                    return ret;
                }
            }

            if (IsDeclaratorSuffix || MemberFunctionAttribute[laKind])
            {
                var dm = new DMethod();
                LastParsedObject = dm;

                // DeclaratorSuffixes
                List<INode> _Parameters;
                ttd = DeclaratorSuffixes(out (ret as DNode).TemplateParameters, out _Parameters, ret.Attributes);
                if (ttd != null)
                {
                    ttd.InnerDeclaration = ret.Type;
                    ret.Type = ttd;
                }

                if (_Parameters == null)
                    LastParsedObject = ret;

                if (_Parameters != null)
                {
                    dm.AssignFrom(ret);
                    dm.Parameters = _Parameters;
                    foreach (var pp in dm.Parameters)
                        pp.Parent = dm;
                    return dm;
                }
            }

            return ret;
        }
Example #9
0
        ITypeDeclaration BasicType2()
        {
            // *
            if (laKind == (Times))
            {
                Step();
                return new PointerDecl() { Location=t.Location, EndLocation=t.EndLocation };
            }

            // [ ... ]
            else if (laKind == (OpenSquareBracket))
            {
                var startLoc = la.Location;
                Step();
                // [ ]
                if (laKind == (CloseSquareBracket))
                {
                    Step();
                    return new ArrayDecl() { Location=startLoc, EndLocation=t.EndLocation };
                }

                ITypeDeclaration cd = null;

                // [ Type ]
                if (!IsAssignExpression())
                {
                    var la_backup = la;
                    bool weaktype = AllowWeakTypeParsing;
                    AllowWeakTypeParsing = true;
                    var keyType = Type();
                    AllowWeakTypeParsing = weaktype;

                    if (keyType != null && laKind == CloseSquareBracket)
                        cd = new ArrayDecl() { KeyType = keyType, Location=startLoc };
                    else
                        la = la_backup;
                }

                if(cd==null)
                {
                    var fromExpression = AssignExpression();

                    // [ AssignExpression .. AssignExpression ]
                    if (laKind == DoubleDot)
                    {
                        Step();
                        cd = new ArrayDecl() {
                            Location=startLoc
                            ,KeyExpression= new PostfixExpression_Slice() {
                                FromExpression=fromExpression,
                                ToExpression=AssignExpression()}};
                    }
                    else
                        cd = new ArrayDecl() { KeyExpression=fromExpression,Location=startLoc };
                }

                if (AllowWeakTypeParsing && laKind != CloseSquareBracket)
                    return null;

                Expect(CloseSquareBracket);
                if(cd!=null)
                    cd.EndLocation = t.EndLocation;
                return cd;
            }

            // delegate | function
            else if (laKind == (Delegate) || laKind == (Function))
            {
                Step();
                ITypeDeclaration td = null;
                var dd = new DelegateDeclaration() { Location=t.Location};
                dd.IsFunction = t.Kind == Function;

                dd.Parameters = Parameters(null);
                td = dd;
                //TODO: add attributes to declaration
                while (FunctionAttribute[laKind])
                {
                    Step();
                    td = new DTokenDeclaration(t.Kind, td) { Location=t.Location, EndLocation=t.EndLocation };
                }
                td.EndLocation = t.EndLocation;
                return td;
            }
            else
                SynErr(Identifier);
            return null;
        }
        public static DelegateType Resolve(DelegateDeclaration dg, ResolutionContext ctxt)
        {
            var returnTypes = Resolve(dg.ReturnType, ctxt);

            ctxt.CheckForSingleResult(returnTypes, dg.ReturnType);

            if (returnTypes != null && returnTypes.Length != 0)
            {
                List<AbstractType> paramTypes=null;
                if(dg.Parameters!=null &&
                   dg.Parameters.Count != 0)
                {
                    paramTypes = new List<AbstractType>();
                    foreach(var par in dg.Parameters)
                        paramTypes.Add(ResolveSingle(par.Type, ctxt));
                }
                return new DelegateType(returnTypes[0], dg, paramTypes);
            }
            return null;
        }
        public static DelegateType Resolve(DelegateDeclaration dg, ResolverContextStack ctxt)
        {
            var returnTypes = Resolve(dg.ReturnType, ctxt);

            ctxt.CheckForSingleResult(returnTypes, dg.ReturnType);

            if (returnTypes != null && returnTypes.Length != 0)
                return new DelegateType(returnTypes[0], dg); // Parameter types will be resolved later on
            return null;
        }