예제 #1
0
        public virtual void Visit(DMethod n)
        {
            VisitDNode(n);

            if (n.Parameters != null)
            {
                foreach (var par in n.Parameters)
                {
                    par.Accept(this);
                }
            }

            if (n.In != null)
            {
                n.In.Accept(this);
            }
            if (n.Body != null)
            {
                n.Body.Accept(this);
            }
            if (n.Out != null)
            {
                n.Out.Accept(this);
            }

            if (n.OutResultVariable != null)
            {
                n.OutResultVariable.Accept(this);
            }
        }
 public override void Visit(DMethod dm)
 {
     var back = ctxt.ScopedBlock;
     using (ctxt.Push(dm)) {
         if (back != ctxt.ScopedBlock)
             OnScopedBlockChanged(dm);
         base.Visit(dm);
     }
 }
예제 #3
0
        public static TooltipInformation Generate(DMethod dm, bool isTemplateParamInsight=false, int currentParam=-1)
        {
            var tti = new TooltipInformation();
            var sb = new StringBuilder();

            sb.Append ("<i>(");
            string name;
            switch (dm.SpecialType) {
                case DMethod.MethodType.Constructor:
                    sb.Append ("Constructor");
                    name = dm.Parent.Name;
                    break;
                case DMethod.MethodType.Destructor:
                    sb.Append ("Destructor");
                    name = dm.Parent.Name;
                    break;
                case DMethod.MethodType.Allocator:
                    sb.Append ("Allocator");
                    name = dm.Parent.Name;
                    break;
                default:
                    sb.Append ("Method");
                    name = dm.Name;
                    break;
            }
            sb.Append (")</i> ");

            if (dm.Type != null)
            {
                sb.Append(dm.Type.ToString(true));
                sb.Append(" ");
            }
            else if (dm.Attributes != null && dm.Attributes.Count != 0)
            {
                foreach (var attr in dm.Attributes)
                {
                    var m = attr as Modifier;
                    if (m != null && DTokens.StorageClass[m.Token])
                    {
                        sb.Append(DTokens.GetTokenString(m.Token));
                        sb.Append(" ");
                        break;
                    }
                }
            }

            sb.Append(name);

            /*TODO: Show attributes?
            if (dm.Attributes != null && dm.Attributes.Count > 0)
                s = dm.AttributeString + ' ';
            */

            RenderParamtersAndFooters (tti, dm, sb, isTemplateParamInsight, currentParam);

            return tti;
        }
예제 #4
0
 public override void Visit(DMethod dm)
 {
     var back = ctxt.ScopedBlock;
     if (back != dm) {
         ctxt.PushNewScope (dm);
         OnScopedBlockChanged (dm);
     }
     base.Visit (dm);
     if(back != dm)
         ctxt.Pop ();
 }
        public override void Visit(DMethod n)
        {
            // Format header
            FormatAttributedNode(n, !n.IsAnonymous && n.Type != null);

            VisitDNode(n);

            // Stick name to type
            if(n.Type != null)
                ForceSpacesBeforeRemoveNewLines(n.NameLocation, true);

            // Put parenthesis '(' token directly after the name
            var nameLength = 0;
            switch(n.SpecialType)
            {
                case DMethod.MethodType.Destructor:
                case DMethod.MethodType.Constructor:
                    nameLength = 4; // this
                    break;
                case DMethod.MethodType.Normal:
                    nameLength = n.Name.Length;
                    break;
            }

            if(nameLength > 0)
                ForceSpacesAfterRemoveLines(new CodeLocation(n.NameLocation.Column + nameLength, n.NameLocation.Line),false);

            // Format parameters

            // Find in, out(...) and body tokens
            if(!n.InToken.IsEmpty){
                FixIndentationForceNewLine(n.InToken);
            }
            if(!n.OutToken.IsEmpty){
                FixIndentationForceNewLine(n.OutToken);
            }
            if(!n.BodyToken.IsEmpty){
                FixIndentationForceNewLine(n.BodyToken);
            }

            // Visit body parts
            if (n.In != null)
                n.In.Accept (this);
            if (n.Body != null)
                n.Body.Accept (this);
            if (n.Out != null)
                n.Out.Accept (this);

            if (!n.IsAnonymous)
                EnsureBlankLinesAfter (n.EndLocation, policy.LinesAfterNode);
        }
		public virtual void Visit(DMethod n)
		{
			VisitDNode(n);

			foreach (var par in n.Parameters)
				par.Accept(this);

			if (n.In != null)
				n.In.Accept(this);
			if (n.Body != null)
				n.Body.Accept(this);
			if (n.Out != null)
				n.Out.Accept(this);

			if (n.OutResultVariable != null)
				n.OutResultVariable.Accept(this);
		}
예제 #7
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dm"></param>
        /// <param name="args"></param>
        /// <param name="baseValueProvider">Required for evaluating missing default parameters.</param>
        public static bool AssignCallArgumentsToIC(DMethod dm, ISymbolValue[] args, AbstractSymbolValueProvider baseValueProvider,
			out Dictionary<DVariable,ISymbolValue> targetArgs)
        {
            targetArgs = new Dictionary<DVariable, ISymbolValue>();
            var argsRemaining = args != null ? args.Length : 0;
            int argu = 0;

            for (int para = 0; para < dm.Parameters.Count; para++)
            {
                var par = dm.Parameters[para] as DVariable;

                if (par.Type is VarArgDecl && argsRemaining > 0)
                {
                    var va_args = new ISemantic[argsRemaining];
                    args.CopyTo(va_args, argu);
                    argsRemaining=0;
                    //TODO: Assign a value tuple to par
                    if (++para < dm.Parameters.Count)
                        return false;
                }

                if (argsRemaining > 0)
                {
                    targetArgs[par] = args[argu++];
                    argsRemaining--;
                }
                else if (par.Initializer != null)
                {
                    targetArgs[par] = Evaluation.EvaluateValue(par.Initializer, baseValueProvider);
                }
                else
                    return false;
            }

            return argsRemaining == 0;
        }
예제 #8
0
        void HandleMethod(DMethod dm, MemberSymbol alreadyResolvedMethod = null)
        {
            if (dm != null && dm.Parameters.Count > 0 && dm.Parameters[0].Type != null)
            {
                var pop = ctxt.ScopedBlock != dm;
                if (pop)
                    ctxt.PushNewScope (dm);

                var t = TypeDeclarationResolver.ResolveSingle (dm.Parameters [0].Type, ctxt);
                if (ResultComparer.IsImplicitlyConvertible (firstArgument, t, ctxt)) {
                    var res = alreadyResolvedMethod ?? new MemberSymbol (dm, null, sr);
                    res.Tag = new UfcsTag{ firstArgument=firstArgument };
                    matches.Add (res);
                }

                if (pop)
                    ctxt.Pop ();
            }
        }
예제 #9
0
        void DeclDef(DBlockNode module)
        {
            //AttributeSpecifier
            while (IsAttributeSpecifier())
            {
                AttributeSpecifier();

                if (t.Kind == Colon)
                    return;
            }

            if (laKind == Semicolon)
            {
                LastParsedObject = null;
                Step();
                return;
            }

            //ImportDeclaration
            if (laKind == Import)
                module.Add(ImportDeclaration());

            //Constructor
            else if (laKind == (This))
                module.Add(Constructor(module is DClassLike ? ((DClassLike)module).ClassType == DTokens.Struct : false));

            //Destructor
            else if (laKind == (Tilde) && Lexer.CurrentPeekToken.Kind == (This))
                module.Add(Destructor());

            //Invariant
            else if (laKind == (Invariant))
                module.Add(_Invariant());

            //UnitTest
            else if (laKind == (Unittest))
            {
                Step();
                var dbs = new DMethod(DMethod.MethodType.Unittest);
                LastParsedObject = dbs;
                dbs.Location = t.Location;
                FunctionBody(dbs);
                dbs.EndLocation = t.EndLocation;
                module.Add(dbs);
            }

            /*
             * VersionSpecification:
             *		version = Identifier ;
             *		version = IntegerLiteral ;
             *
             * DebugSpecification:
             *		debug = Identifier ;
             *		debug = IntegerLiteral ;
             */
            else if ((laKind == Version || laKind == Debug) && Peek(1).Kind == Assign)
            {
                Step();

                var ass = new VersionDebugSpecification
                {
                    Token = t.Kind,
                    Location = t.Location
                };
                LastParsedObject = ass;

                Step();

                if (laKind == Literal)
                {
                    Step();
                    ass.SpecifiedValue = new IdentifierExpression(t.LiteralValue, t.LiteralFormat)
                        {
                            Location = t.Location,
                            EndLocation = t.EndLocation
                        };
                }
                else if (Expect(Identifier))
                    ass.SpecifiedValue = new IdentifierExpression(t.LiteralValue, t.LiteralFormat)
                    {
                        Location = t.Location,
                        EndLocation = t.EndLocation
                    };

                Expect(Semicolon);

                ass.EndLocation = t.EndLocation;

                module.Add(ass);
            }

            else if (laKind == Version || laKind == Debug || laKind == If)
            {
                Step();

                var c = new DeclarationCondition(t.Kind);
                LastParsedObject = c;

                /*
                 * http://www.d-programming-language.org/version.html#VersionSpecification
                 * VersionCondition:
                 *		version ( IntegerLiteral )
                 *		version ( Identifier )
                 *		version ( unittest )
                 */
                if (c.IsVersionCondition && Expect(OpenParenthesis))
                {
                    if (laKind == Unittest)
                    {
                        Step();
                        c.Condition = new TokenExpression(Unittest) { Location = t.Location, EndLocation = t.EndLocation };
                    }
                    else if (laKind == Literal)
                    {
                        Step();
                        c.Condition = new IdentifierExpression(t.LiteralValue, t.LiteralFormat)
                        {
                            Location = t.Location,
                            EndLocation = t.EndLocation
                        };
                    }
                    else if (Expect(Identifier))
                        c.Condition = new IdentifierExpression(t.Value, t.LiteralFormat)
                        {
                            Location = t.Location,
                            EndLocation = t.EndLocation
                        };

                    if (Expect(CloseParenthesis))
                        TrackerVariables.ExpectingIdentifier = false;
                }

                /*
                 * DebugCondition:
                 *		debug
                 *		debug ( IntegerLiteral )
                 *		debug ( Identifier )
                 */
                else if (c.IsDebugCondition)
                {
                    if (laKind == OpenParenthesis)
                    {
                        Step();

                        if (laKind == Literal)
                        {
                            Step();
                            c.Condition = new IdentifierExpression(t.LiteralValue, t.LiteralFormat)
                            {
                                Location = t.Location,
                                EndLocation = t.EndLocation
                            };
                        }
                        else if (Expect(Identifier))
                            c.Condition = new IdentifierExpression(t.Value, t.LiteralFormat)
                            {
                                Location = t.Location,
                                EndLocation = t.EndLocation
                            };

                        Expect(CloseParenthesis);
                    }
                }

                /*
                 * StaticIfCondition:
                 *		static if ( AssignExpression )
                 */
                else if (c.IsStaticIfCondition && Expect(OpenParenthesis))
                {
                    if (DAttribute.ContainsAttribute(DeclarationAttributes, Static))
                        DeclarationAttributes.Clear();
                    else
                        SynErr(Static, "Conditional declaration checks must be static");

                    c.Condition = AssignExpression();

                    Expect(CloseParenthesis);
                }

                if (laKind == Colon)
                {
                    Step();
                    PushAttribute(c, true);
                    return;
                }
                else if (laKind == OpenCurlyBrace)
                {
                    BlockAttributes.Push(c);

                    ClassBody(module, true, false);

                    BlockAttributes.Pop();
                }
                else
                {
                    DeclarationAttributes.Push(c);

                    DeclDef(module);
                }

                if (laKind == Else)
                {
                    Step();

                    c = c.Clone() as DeclarationCondition;
                    c.Negate();

                    if (laKind == OpenCurlyBrace)
                    {
                        BlockAttributes.Push(c);

                        ClassBody(module, true, false);

                        BlockAttributes.Pop();
                    }
                    else
                    {
                        DeclarationAttributes.Push(c);

                        DeclDef(module);
                    }
                }
            }

            //StaticAssert
            else if (laKind == (Assert))
            {
                Step();

                if (DAttribute.ContainsAttribute(DeclarationAttributes, Static))
                {
                    //HACK: Assume that there's only our 'static' attribute applied to the 'if'-statement
                    DeclarationAttributes.Clear();
                }
                else
                    SynErr(Static, "Static assert statements must be explicitly marked as static");

                if (Expect(OpenParenthesis))
                {
                    AssignExpression();
                    if (laKind == (Comma))
                    {
                        Step();
                        AssignExpression();
                    }
                    Expect(CloseParenthesis);
                }
                Expect(Semicolon);
            }

            //TemplateMixinDeclaration
            else if (laKind == Mixin)
            {
                if (Peek(1).Kind == Template)
                    module.Add(TemplateDeclaration(module));

                //TemplateMixin
                else if (Lexer.CurrentPeekToken.Kind == Identifier)
                    module.Add(TemplateMixin());

                //MixinDeclaration
                else if (Lexer.CurrentPeekToken.Kind == OpenParenthesis)
                    module.Add(MixinDeclaration());
                else
                {
                    Step();
                    SynErr(Identifier);
                }
            }

            // {
            else if (laKind == (OpenCurlyBrace))
            {
                int popCount = DeclarationAttributes.Count;
                while (DeclarationAttributes.Count > 0)
                    BlockAttributes.Push(DeclarationAttributes.Pop());

                ClassBody(module, true, false);

                for (int i = popCount; i > 0; i--)
                    BlockAttributes.Pop();
            }

            // Class Allocators
            // Note: Although occuring in global scope, parse it anyway but declare it as semantic nonsense;)
            else if (laKind == (New))
            {
                Step();

                var dm = new DMethod(DMethod.MethodType.Allocator) { Location=t.Location };
                ApplyAttributes(dm);

                dm.Parameters = Parameters(dm);
                FunctionBody(dm);
                dm.EndLocation = t.EndLocation;
                module.Add(dm);
            }

            // Class Deallocators
            else if (laKind == Delete)
            {
                Step();

                var dm = new DMethod(DMethod.MethodType.Deallocator) { Location=t.Location };
                dm.Name = "delete";
                ApplyAttributes(dm);

                dm.Parameters = Parameters(dm);
                FunctionBody(dm);
                dm.EndLocation = t.EndLocation;
                module.Add(dm);
            }

            // else:
            else
                module.AddRange(Declaration(module));
        }
예제 #10
0
파일: Parser.cs 프로젝트: EnergonV/D_Parser
        public static DMethod ParseMethodDeclarationHeader(string headerCode, out ITypeDeclaration identifierChain)
        {
            using(var sr = new StringReader(headerCode))
            {
                var p = Create(sr);
                p.Step();

                var n = new DMethod();
                p.CheckForStorageClasses(p.doc);
                p.ApplyAttributes(n);
                p.FunctionAttributes(n);

                n.Type = p.Type();

                identifierChain = p.IdentifierList();
                if(identifierChain is IdentifierDeclaration)
                    n.NameHash = (identifierChain as IdentifierDeclaration).IdHash;

                n.Parameters = p.Parameters(n);

                return n;
            }
        }
예제 #11
0
        /// <summary>
        /// Parse parameters
        /// </summary>
        List<INode> Parameters(DMethod Parent)
        {
            var ret = new List<INode>();
            Expect(OpenParenthesis);

            // Empty parameter list
            if (laKind == (CloseParenthesis))
            {
                Step();
                return ret;
            }

            var stk_backup = BlockAttributes;
            BlockAttributes = new Stack<DAttribute>();

            DNode p;

            if (laKind != TripleDot && (p = Parameter(Parent)) != null)
            {
                p.Parent = Parent;
                ret.Add(p);
            }

            while (laKind == (Comma))
            {
                Step();
                if (laKind == TripleDot || laKind==CloseParenthesis || (p = Parameter(Parent)) == null)
                    break;
                p.Parent = Parent;
                ret.Add(p);
            }

            // It's not specified in the official D syntax spec, but we treat id-only typed anonymous parameters as non-typed id-full parameters
            if(Parent != null && Parent.SpecialType == DMethod.MethodType.AnonymousDelegate)
            {
                foreach(var r in ret)
                    if (r.NameHash == 0 && r.Type is IdentifierDeclaration && r.Type.InnerDeclaration == null)
                    {
                        r.NameHash = (r.Type as IdentifierDeclaration).IdHash;
                        r.Type = null;
                    }
            }

            /*
             * There can be only one '...' in every parameter list
             */
            if (laKind == TripleDot)
            {
                // If it doesn't have a comma, add a VarArgDecl to the last parameter
                bool HadComma = t.Kind == (Comma);

                Step();

                if (!HadComma && ret.Count > 0)
                {
                    // Put a VarArgDecl around the type of the last parameter
                    ret[ret.Count - 1].Type = new VarArgDecl(ret[ret.Count - 1].Type);
                }
                else
                {
                    var dv = new DVariable();
                    dv.Type = new VarArgDecl();
                    dv.Parent = Parent;
                    ret.Add(dv);
                }
            }

            Expect(CloseParenthesis);
            BlockAttributes = stk_backup;
            return ret;
        }
예제 #12
0
			public override void Visit(DMethod n)
			{
				base.Visit(n);
				VisitChildren(n);
			}
예제 #13
0
        void LambdaBody(DMethod anonymousMethod)
        {
            if (Expect(GoesTo))
            {
                if (laKind == OpenCurlyBrace)
                    anonymousMethod.Body = BlockStatement(anonymousMethod);
                else
                {
                    anonymousMethod.Body = new BlockStatement { Location = t.EndLocation, ParentNode = anonymousMethod };

                    var ae = AssignExpression(anonymousMethod);

                    // +1 due to SearchRegionAt which is enforcing < on EndLocations and not <=
                    var endLocation = IsEOF ? new CodeLocation(la.EndColumn + 1, la.Line) : t.EndLocation;

                    anonymousMethod.Body.Add(new ReturnStatement
                    {
                        Location = ae.Location,
                        EndLocation = endLocation,
                        ReturnExpression = ae
                    });

                    anonymousMethod.Body.EndLocation = endLocation;
                }
                anonymousMethod.EndLocation = anonymousMethod.Body.EndLocation;
            }
            else // (string | -- see IsLambdaExpression()
                anonymousMethod.EndLocation = la.Location;
        }
예제 #14
0
        INode Destructor()
        {
            Expect(Tilde);
            var dm = new DMethod{ Location = t.Location, NameLocation = la.Location };
            Expect(This);
            ApplyAttributes (dm);

            dm.SpecialType = DMethod.MethodType.Destructor;
            dm.Name = "~this";

            if (IsTemplateParameterList())
                TemplateParameterList(dm);

            dm.Parameters = Parameters(dm);

            // handle post argument attributes
            FunctionAttributes(dm);

            if (laKind == If)
                Constraint(dm);

            // handle post argument attributes
            FunctionAttributes(dm);

            FunctionBody(dm);
            return dm;
        }
예제 #15
0
        INode Constructor(DBlockNode scope,bool IsStruct)
        {
            Expect(This);
            var dm = new DMethod(){
                Parent = scope,
                SpecialType = DMethod.MethodType.Constructor,
                Location = t.Location,
                Name = DMethod.ConstructorIdentifier,
                NameLocation = t.Location
            };
            ApplyAttributes (dm);
            dm.Description = GetComments();

            if (IsTemplateParameterList())
                TemplateParameterList(dm);

            // http://dlang.org/struct.html#StructPostblit
            if (IsStruct && laKind == (OpenParenthesis) && Peek(1).Kind == (This))
            {
                var dv = new DVariable { Parent = dm, Name = "this" };
                dm.Parameters.Add(dv);
                Step();
                Step();
                Expect(CloseParenthesis);
            }
            else
            {
                dm.Parameters = Parameters(dm);
            }

            // handle post argument attributes
            FunctionAttributes(dm);

            if (laKind == If)
                Constraint(dm);

            // handle post argument attributes
            FunctionAttributes(dm);

            if(IsFunctionBody)
                FunctionBody(dm);
            return dm;
        }
예제 #16
0
        /// <summary>
        /// Parse parameters
        /// </summary>
        List<INode> Parameters(DMethod Parent)
        {
            var ret = new List<INode>();
            Expect(OpenParenthesis);

            // Empty parameter list
            if (laKind == (CloseParenthesis))
            {
                Step();
                return ret;
            }

            if (laKind != TripleDot)
                ret.Add(Parameter(Parent));

            while (laKind == (Comma))
            {
                Step();
                if (laKind == TripleDot || laKind==CloseParenthesis)
                    break;
                var p = Parameter(Parent);
                p.Parent = Parent;
                ret.Add(p);
            }

            /*
             * There can be only one '...' in every parameter list
             */
            if (laKind == TripleDot)
            {
                // If it doesn't have a comma, add a VarArgDecl to the last parameter
                bool HadComma = t.Kind == (Comma);

                Step();

                if (!HadComma && ret.Count > 0)
                {
                    // Put a VarArgDecl around the type of the last parameter
                    ret[ret.Count - 1].Type = new VarArgDecl(ret[ret.Count - 1].Type);
                }
                else
                {
                    var dv = new DVariable();
                    LastParsedObject = dv;
                    dv.Type = new VarArgDecl();
                    dv.Parent = Parent;
                    ret.Add(dv);
                }
            }

            Expect(CloseParenthesis);
            return ret;
        }
        private bool TryHandleMethodArgumentTuple(ref bool add,
			List<ISemantic> callArguments, 
			DMethod dm, 
			DeducedTypeDictionary deducedTypeDict, int currentParameter,ref int currentArg)
        {
            // .. so only check if it's an identifer & if the id represents a tuple parameter
            var id = dm.Parameters[currentParameter].Type as IdentifierDeclaration;
            var curNode = dm as DNode;
            TemplateParameter tpar = null;
            while (curNode != null && !curNode.TryGetTemplateParameter(id.IdHash, out tpar))
                curNode = curNode.Parent as DNode;

            if (!(tpar is TemplateTupleParameter))
                return false;

            int lastArgumentToTake = -1;
            /*
             * Note: an expression tuple parameter can occur also somewhere in between the parameter list!
             * void write(A...)(bool b, A a, double d) {}
             *
             * can be matched by
             * write(true, 1.2) as well as
             * write(true, "asdf", 1.2) as well as
             * write(true, 123, true, 'c', [3,4,5], 3.4) !
             */

            TemplateParameterSymbol tps;
            DTuple tuple = null;
            if (deducedTypeDict.TryGetValue(tpar, out tps) && tps != null)
            {
                if (tps.Base is DTuple)
                {
                    tuple = tps.Base as DTuple;
                    lastArgumentToTake = currentParameter + (tuple.Items == null ? 0 : (tuple.Items.Length-1));
                }
                else
                {
                    // Error: Type param must be tuple!
                }
            }
            // - Get the (amount of) arguments that shall be put into the tuple
            else if (currentParameter == dm.Parameters.Count - 1)
            {
                // The usual case: A tuple of a variable length is put at the end of a parameter list..
                // take all arguments from i until the end of the argument list..
                lastArgumentToTake = callArguments.Count - 1;

                // Also accept empty tuples..
                if (callArguments.Count == 0)
                    lastArgumentToTake = 0;
            }
            else
            {
                // Get the type of the next expected parameter
                var nextExpectedParameter = DResolver.StripMemberSymbols(TypeDeclarationResolver.ResolveSingle(dm.Parameters[currentParameter + 1].Type, ctxt));

                // Look for the first argument whose type is equal to the next parameter's type..
                for (int k = currentArg; k < callArguments.Count; k++)
                {
                    if (ResultComparer.IsEqual(AbstractType.Get(callArguments[k]), nextExpectedParameter))
                    {
                        // .. and assume the tuple to go from i to the previous argument..
                        lastArgumentToTake = k - 1;
                        break;
                    }
                }
            }

            if (lastArgumentToTake < 0)
            {
                // An error occurred somewhere..
                add = false;
                return true;
            }

            int argCountToHandle = lastArgumentToTake - currentArg;
            if (argCountToHandle > 0)
                argCountToHandle++;

            if (tuple != null)
            {
                // - If there's been set an explicit type tuple, compare all arguments' types with those in the tuple
                if(tuple.Items != null)
                    foreach (ISemantic item in tuple.Items)
                    {
                        if (currentArg >= callArguments.Count || !ResultComparer.IsImplicitlyConvertible(callArguments[currentArg++], AbstractType.Get(item), ctxt))
                        {
                            add = false;
                            return true;
                        }
                    }
            }
            else
            {
                // - If there was no explicit initialization, put all arguments' types into a type tuple
                var argsToTake = new ISemantic[argCountToHandle];
                callArguments.CopyTo(currentArg, argsToTake, 0, argsToTake.Length);
                currentArg += argsToTake.Length;
                var tt = new DTuple(null, argsToTake);
                tps = new TemplateParameterSymbol(tpar, tt);

                //   and set the actual template tuple parameter deduction
                deducedTypeDict[tpar] = tps;
            }
            add = true;
            return true;
        }
예제 #18
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, INode parent)
        {
            DNode ret = new DVariable() { Type=basicType, Location = la.Location, Parent = parent };
            ApplyAttributes (ret);

            while (IsBasicType2())
            {
                if (ret.Type == null)
                    ret.Type = BasicType2();
                else {
                    var ttd = BasicType2();
                    if(ttd!=null)
                        ttd.InnerDeclaration = ret.Type;
                    ret.Type = ttd;
                }
            }

            if (laKind != (OpenParenthesis))
            {
                // On external function declarations, no parameter names are required.
                // extern void Cfoo(HANDLE,char**);
                if (IsParam && laKind != (Identifier))
                {
                    if ((!(ret.Type is DTokenDeclaration) ||
                        (ret.Type as DTokenDeclaration).Token != DTokens.Incomplete) && IsEOF)
                        ret.NameHash = DTokens.IncompleteIdHash;
                    return ret;
                }

                if (Expect(Identifier))
                {
                    ret.Name = t.Value;
                    ret.NameLocation = t.Location;

                    // enum asdf(...) = ...;
                    if (laKind == OpenParenthesis && OverPeekBrackets(DTokens.OpenParenthesis, true) &&
                        Lexer.CurrentPeekToken.Kind == Assign)
                    {
                        var eponymousTemplateDecl = new EponymousTemplate ();
                        eponymousTemplateDecl.AssignFrom (ret);
                        ret = eponymousTemplateDecl;

                        TemplateParameterList (eponymousTemplateDecl);

                        return ret;
                    }
                }
                else
                {
                    if (IsEOF)
                    {
                        ret.NameHash = DTokens.IncompleteIdHash;
                        return ret;
                    }

                    return null;
                    // Code error! - to prevent infinite declaration loops, step one token forward anyway!
                    if(laKind != CloseCurlyBrace && laKind != CloseParenthesis)
                        Step();
                    return null;
                }
            }
            else
                OldCStyleFunctionPointer(ret, IsParam);

            if (IsDeclaratorSuffix || IsFunctionAttribute)
            {
                var dm = new DMethod { Parent = parent, Parameters = null };
                dm.AssignFrom(ret);

                DeclaratorSuffixes(dm);

                if (dm.Parameters != null)
                    ret = dm;
            }

            return ret;
        }
예제 #19
0
		void HandleMethod(DMethod dm, MemberSymbol alreadyResolvedMethod = null)
		{
			if (dm != null && dm.Parameters.Count > 0 && dm.Parameters[0].Type != null)
			{
				var loc = dm.Body != null ? dm.Body.Location : dm.Location;
				using (alreadyResolvedMethod != null ? ctxt.Push(alreadyResolvedMethod, loc) : ctxt.Push(dm, loc))
				{
					var t = TypeDeclarationResolver.ResolveSingle(dm.Parameters[0].Type, ctxt);
					if (ResultComparer.IsImplicitlyConvertible(firstArgument, t, ctxt))
					{
						var res = alreadyResolvedMethod ?? TypeDeclarationResolver.HandleNodeMatch(dm, ctxt, typeBase: sr);
						res.Tag(UfcsTag.Id, new UfcsTag { firstArgument = firstArgument });
						matches.Add(res);
					}
				}
			}
		}
예제 #20
0
        void FunctionBody(DMethod par)
        {
            if (laKind == Semicolon) // Abstract or virtual functions
            {
                Step();
                par.Description += CheckForPostSemicolonComment();
                par.EndLocation = t.EndLocation;
                return;
            }

            if (laKind == GoesTo)
            {
                LambdaBody(par);
                return;
            }

            var stk_Backup = BlockAttributes;
            BlockAttributes = new Stack<DAttribute> ();

            while (
                (laKind == In && par.In == null) ||
                (laKind == Out && par.Out == null))
            {
                if (laKind == In)
                {
                    Step();
                    par.InToken = t.Location;

                    par.In = BlockStatement(par);
                }

                if (laKind == Out)
                {
                    Step();
                    par.OutToken = t.Location;

                    if (laKind == OpenParenthesis)
                    {
                        Step();
                        if (Expect(Identifier))
                        {
                            par.OutResultVariable = new IdentifierDeclaration(t.Value) { Location=t.Location, EndLocation=t.EndLocation };
                        }
                        Expect(CloseParenthesis);
                    }

                    par.Out = BlockStatement(par);
                }
            }

            // Although there can be in&out constraints, there doesn't have to be a direct body definition. Used on abstract class/interface methods.
            if (laKind == Body){
                Step();
                par.BodyToken = t.Location;
            }

            if ((par.In==null && par.Out==null) ||
                laKind == OpenCurlyBrace)
            {
                par.Body = BlockStatement(par);
            }

            BlockAttributes = stk_Backup;
            par.EndLocation = par.Body != null ? par.Body.EndLocation : t.EndLocation;
        }
예제 #21
0
        internal void LambdaSingleStatementBody(DMethod lambdaFunction)
        {
            lambdaFunction.Body = new BlockStatement { Location= la.Location, ParentNode = lambdaFunction };

            var ae = AssignExpression(lambdaFunction);

            lambdaFunction.Body.Add(new ReturnStatement
                {
                    Location = ae.Location,
                    EndLocation = ae.EndLocation,
                    ReturnExpression=ae
                });

            lambdaFunction.Body.EndLocation = t.EndLocation;
        }
예제 #22
0
        public void DeclDef(DBlockNode module)
        {
            if (IsAttributeSpecifier) {
                do
                    AttributeSpecifier (module);
                while(IsAttributeSpecifier);

                var tkind = t.Kind;
                if(tkind == Semicolon || tkind == CloseCurlyBrace || tkind == Colon)
                    return;
            }

            if (laKind == Semicolon)
            {
                Step();
                return;
            }

            switch (laKind)
            {
                case Import:
                    module.Add(ImportDeclaration(module));
                    break;
                case This:
                    module.Add(Constructor(module, module is DClassLike && ((DClassLike)module).ClassType == DTokens.Struct));
                    break;
                case Tilde:
                    if (Lexer.CurrentPeekToken.Kind != This)
                        goto default;
                    module.Add(Destructor());
                    break;
                case Invariant:
                    module.Add(_Invariant());
                    break;
                case Unittest:
                    Step();
                    var dbs = new DMethod(DMethod.MethodType.Unittest);
                    ApplyAttributes(dbs);
                    dbs.Location = t.Location;
                    FunctionBody(dbs);
                    dbs.EndLocation = t.EndLocation;
                    module.Add(dbs);
                    break;
                /*
                 * VersionSpecification:
                 *		version = Identifier ;
                 *		version = IntegerLiteral ;
                 *
                 * DebugSpecification:
                 *		debug = Identifier ;
                 *		debug = IntegerLiteral ;
                 */
                case Version:
                case Debug:
                    if (Peek(1).Kind == Assign)
                    {
                        DebugSpecification ds = null;
                        VersionSpecification vs = null;

                        if (laKind == Version)
                            vs = new VersionSpecification {
                                Location = la.Location,
                                Attributes = GetCurrentAttributeSet_Array()
                            };
                        else
                            ds = new DebugSpecification {
                                Location = la.Location,
                                Attributes = GetCurrentAttributeSet_Array()
                            };

                        Step();
                        Step();

                        if (laKind == Literal)
                        {
                            Step();
                            if (t.LiteralFormat != LiteralFormat.Scalar)
                                SynErr(t.Kind, "Integer literal expected!");
                            try
                            {
                                if (vs != null)
                                    vs.SpecifiedNumber = Convert.ToInt32(t.LiteralValue);
                                else
                                    ds.SpecifiedDebugLevel = Convert.ToInt32(t.LiteralValue);
                            }
                            catch
                            {
                            }
                        }
                        else if (laKind == Identifier)
                        {
                            Step();
                            if (vs != null)
                                vs.SpecifiedId = t.Value;
                            else
                                ds.SpecifiedId = t.Value;
                        }
                        else if (ds == null)
                            Expect(Identifier);

                        Expect(Semicolon);

                        ((AbstractStatement)ds ?? vs).EndLocation = t.EndLocation;

                        module.Add(vs as StaticStatement ?? ds);
                    }
                    else
                        DeclarationCondition(module);
                    break;
                case Static:
                    if (Lexer.CurrentPeekToken.Kind == If)
                        goto case Version;
                    goto default;
                case Assert:
                    Step();
                    CheckForStorageClasses(module);
                    if (!Modifier.ContainsAttribute(DeclarationAttributes, Static))
                        SynErr(Static, "Static assert statements must be explicitly marked as static");

                    var ass = new StaticAssertStatement {
                        Attributes = GetCurrentAttributeSet_Array(),
                        Location = t.Location
                    };

                    if (Expect(OpenParenthesis))
                    {
                        ass.AssertedExpression = AssignExpression();
                        if (laKind == (Comma))
                        {
                            Step();
                            ass.Message = AssignExpression();
                        }
                        if (Expect(CloseParenthesis))
                            Expect(Semicolon);
                    }

                    ass.EndLocation = t.EndLocation;

                    module.Add(ass);
                    break;
                case Mixin:
                    if (Peek(1).Kind == Template)
                        module.Add(TemplateDeclaration(module));

                    //TemplateMixin
                    else if (Lexer.CurrentPeekToken.Kind == Identifier)
                    {
                        var tmx = TemplateMixin(module);
                        if (tmx.MixinId == null)
                            module.Add(tmx);
                        else
                            module.Add(new NamedTemplateMixinNode(tmx));
                    }

                    //MixinDeclaration
                    else if (Lexer.CurrentPeekToken.Kind == OpenParenthesis)
                        module.Add(MixinDeclaration(module, null));
                    else
                    {
                        Step();
                        SynErr(Identifier);
                    }
                    break;
                case OpenCurlyBrace:
                    AttributeBlock(module);
                    break;
                // Class Allocators
                // Note: Although occuring in global scope, parse it anyway but declare it as semantic nonsense;)
                case New:
                    Step();

                    var dm = new DMethod(DMethod.MethodType.Allocator) { Location = t.Location };
                    ApplyAttributes(dm);

                    dm.Parameters = Parameters(dm);
                    FunctionBody(dm);
                    dm.EndLocation = t.EndLocation;
                    module.Add(dm);
                    break;
                case Delete:
                    Step();

                    var ddm = new DMethod(DMethod.MethodType.Deallocator) { Location = t.Location };
                    ddm.Name = "delete";
                    ApplyAttributes(ddm);

                    ddm.Parameters = Parameters(ddm);
                    FunctionBody(ddm);
                    ddm.EndLocation = t.EndLocation;
                    module.Add(ddm);
                    break;
                default:
                    var decls = Declaration(module);
                    if(module != null && decls!=null)
                        module.AddRange(decls);
                    break;
            }
        }
예제 #23
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, INode parent)
        {
            DNode ret = new DVariable() { Type=basicType, Location = la.Location, Parent = parent };
            ApplyAttributes (ret);
            LastParsedObject = ret;

            while (IsBasicType2())
            {
                if (ret.Type == null)
                    ret.Type = BasicType2();
                else {
                    var ttd = BasicType2();
                    if(ttd!=null)
                        ttd.InnerDeclaration = ret.Type;
                    ret.Type = ttd;
                }
            }

            // Only return no variable if the BasicType2 wasn't parsed properly to ensure good code completion
            if (IsEOF && ret != LastParsedObject)
                return null;

            if (laKind != (OpenParenthesis))
            {
                // On external function declarations, no parameter names are required.
                // extern void Cfoo(HANDLE,char**);
                if (IsParam && laKind != (Identifier))
                {
                    if(ret.Type!=null && IsEOF)
                        ExpectingNodeName = true;
                    return ret;
                }

                if (Expect(Identifier))
                {
                    ret.Name = t.Value;
                    ret.NameLocation = t.Location;

                    if (laKind == OpenParenthesis && ret.Type == null) {
                        OverPeekBrackets (DTokens.OpenParenthesis, true);

                        var k = Lexer.LastToken.Kind;
                        if (k == DTokens.Alias || k == DTokens.Enum) {
                            if (ret.Attributes == null)
                                ret.Attributes = new List<DAttribute> ();
                            ret.Attributes.Add (new Modifier (k));
                        }

                        // enum asdf(...) = ...;
                        if (Lexer.CurrentPeekToken.Kind == Assign) {
                            var eponymousTemplateDecl = new EponymousTemplate ();
                            eponymousTemplateDecl.AssignFrom (ret);
                            ret = eponymousTemplateDecl;

                            TemplateParameterList (eponymousTemplateDecl);

                            return ret;
                        }
                    }
                }
                else
                {
                    if (IsEOF || IsParam)
                    {
                        ExpectingNodeName = true;
                        return ret;
                    }

                    return null;
                    // Code error! - to prevent infinite declaration loops, step one token forward anyway!
                    if(laKind != CloseCurlyBrace && laKind != CloseParenthesis)
                        Step();
                    return null;
                }
            }
            else
                OldCStyleFunctionPointer(ret, IsParam);

            if (IsDeclaratorSuffix || IsFunctionAttribute)
            {
                var dm = new DMethod { Parent = parent, Parameters = null };
                dm.AssignFrom(ret);
                LastParsedObject = dm;

                DeclaratorSuffixes(dm);

                if (dm.Parameters != null)
                    ret = dm;
                else
                    LastParsedObject = ret;
            }

            return ret;
        }
예제 #24
0
        DMethod _Invariant()
        {
            var inv = new DMethod { SpecialType= DMethod.MethodType.ClassInvariant };

            Expect(Invariant);
            inv.Location = t.Location;
            if (laKind == OpenParenthesis)
            {
                Step();
                Expect(CloseParenthesis);
            }
            if(!IsEOF)
                inv.Body=BlockStatement();
            inv.EndLocation = t.EndLocation;
            return inv;
        }
예제 #25
0
        void DeclDef(DBlockNode module)
        {
            //AttributeSpecifier
            while (IsAttributeSpecifier())
            {
                AttributeSpecifier(module);

                if (t.Kind == Colon || laKind == CloseCurlyBrace || IsEOF)
                    return;
            }

            if (laKind == Semicolon)
            {
                LastParsedObject = null;
                Step();
                return;
            }

            //ImportDeclaration
            if (laKind == Import)
                module.Add(ImportDeclaration(module));

            //Constructor
            else if (laKind == (This))
                module.Add(Constructor(module, module is DClassLike ? ((DClassLike)module).ClassType == DTokens.Struct : false));

            //Destructor
            else if (laKind == (Tilde) && Lexer.CurrentPeekToken.Kind == (This))
                module.Add(Destructor());

            //Invariant
            else if (laKind == (Invariant))
                module.Add(_Invariant());

            //UnitTest
            else if (laKind == (Unittest))
            {
                Step();
                var dbs = new DMethod(DMethod.MethodType.Unittest);
                ApplyAttributes(dbs);
                LastParsedObject = dbs;
                dbs.Location = t.Location;
                FunctionBody(dbs);
                dbs.EndLocation = t.EndLocation;
                module.Add(dbs);
            }

            /*
             * VersionSpecification:
             *		version = Identifier ;
             *		version = IntegerLiteral ;
             *
             * DebugSpecification:
             *		debug = Identifier ;
             *		debug = IntegerLiteral ;
             */
            else if ((laKind == Version || laKind == Debug) && Peek(1).Kind == Assign)
            {
                DebugSpecification ds = null;
                VersionSpecification vs = null;

                if (laKind == Version)
                    LastParsedObject = vs = new VersionSpecification { Location = la.Location, Attributes = GetCurrentAttributeSet_Array() };
                else
                    LastParsedObject = ds = new DebugSpecification { Location = la.Location, Attributes = GetCurrentAttributeSet_Array() };

                Step();
                Step();

                if (laKind == Literal)
                {
                    Step();
                    if (t.LiteralFormat != LiteralFormat.Scalar)
                        SynErr(t.Kind, "Integer literal expected!");
                    try
                    {
                        if (vs != null)
                            vs.SpecifiedNumber = Convert.ToInt32(t.LiteralValue);
                        else
                            ds.SpecifiedDebugLevel = Convert.ToInt32(t.LiteralValue);
                    }
                    catch { }
                }
                else if (laKind == Identifier)
                {
                    Step();
                    if (vs != null)
                        vs.SpecifiedId = t.Value;
                    else
                        ds.SpecifiedId = t.Value;
                }
                else if (ds == null)
                    Expect(Identifier);

                Expect(Semicolon);

                if (vs == null)
                    ds.EndLocation = t.EndLocation;
                else
                    vs.EndLocation = t.EndLocation;

                module.Add(vs as StaticStatement ?? ds);
            }

            else if (laKind == Version || laKind == Debug || (laKind == Static && Lexer.CurrentPeekToken.Kind == If))
                DeclarationCondition(module);

            //StaticAssert
            else if (laKind == (Assert))
            {
                Step();

                if (!Modifier.ContainsAttribute(DeclarationAttributes, Static))
                    SynErr(Static, "Static assert statements must be explicitly marked as static");

                var ass = new StaticAssertStatement { Attributes = GetCurrentAttributeSet_Array(), Location = t.Location };

                if (Expect(OpenParenthesis))
                {
                    ass.AssertedExpression = AssignExpression();
                    if (laKind == (Comma))
                    {
                        Step();
                        ass.Message = AssignExpression();
                    }
                    if(Expect(CloseParenthesis))
                        Expect(Semicolon);
                }

                ass.EndLocation = t.EndLocation;

                module.Add(ass);
            }

            //TemplateMixinDeclaration
            else if (laKind == Mixin)
            {
                if (Peek(1).Kind == Template)
                    module.Add(TemplateDeclaration(module));

                //TemplateMixin
                else if (Lexer.CurrentPeekToken.Kind == Identifier)
                {
                    var tmx = TemplateMixin(module);
                    if(tmx.MixinId==null)
                        module.Add(tmx);
                    else
                        module.Add(new NamedTemplateMixinNode(tmx));
                }

                //MixinDeclaration
                else if (Lexer.CurrentPeekToken.Kind == OpenParenthesis)
                    module.Add(MixinDeclaration(module,null));
                else
                {
                    Step();
                    SynErr(Identifier);
                }
            }

            // {
            else if (laKind == (OpenCurlyBrace))
                AttributeBlock(module);

            // Class Allocators
            // Note: Although occuring in global scope, parse it anyway but declare it as semantic nonsense;)
            else if (laKind == (New))
            {
                Step();

                var dm = new DMethod(DMethod.MethodType.Allocator) { Location = t.Location };
                ApplyAttributes(dm);

                dm.Parameters = Parameters(dm);
                FunctionBody(dm);
                dm.EndLocation = t.EndLocation;
                module.Add(dm);
            }

            // Class Deallocators
            else if (laKind == Delete)
            {
                Step();

                var dm = new DMethod(DMethod.MethodType.Deallocator) { Location = t.Location };
                dm.Name = "delete";
                ApplyAttributes(dm);

                dm.Parameters = Parameters(dm);
                FunctionBody(dm);
                dm.EndLocation = t.EndLocation;
                module.Add(dm);
            }

            // else:
            else
            {
                var decls = Declaration(module);
                if(module != null && decls!=null)
                    module.AddRange(decls);
            }
        }
		public void Visit(PostfixExpression_ArrayAccess x)
		{//TODO for Slices: Omit opIndex overloads if it's obvious that we don't want them -- a[1.. |
			if (x.Arguments != null)
				res.CurrentlyTypedArgumentIndex = x.Arguments.Length;

			res.IsMethodArguments = true;
			res.ParsedExpression = x;

			var overloads = new List<AbstractType>();

			if (x.PostfixForeExpression == null)
				return;

			var b = ExpressionTypeEvaluation.EvaluateType(x.PostfixForeExpression, ctxt);

			var ov = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(ExpressionTypeEvaluation.OpSliceIdHash, b, ctxt, x, false);
			if (ov != null)
				overloads.AddRange(ov);

			ov = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(ExpressionTypeEvaluation.OpIndexIdHash, b, ctxt, x, false);
			if (ov != null)
				overloads.AddRange(ov);

			if (overloads.Count == 0)
			{
				b = DResolver.StripMemberSymbols(b);
				var toTypeDecl = new DTypeToTypeDeclVisitor();
				var aa = b as AssocArrayType;
				if (aa != null){
					var retType = aa.ValueType != null ? aa.ValueType.Accept(toTypeDecl) : null;
					var dm = new DMethod { 
						Name = "opIndex",
						Type = retType
					};
					dm.Parameters.Add(new DVariable { 
						Name = "index",
						Type = aa.KeyType != null ? aa.KeyType.Accept(toTypeDecl) : null 
					});
					overloads.Add(new MemberSymbol(dm, aa.ValueType));

					if ((aa is ArrayType) && !(aa as ArrayType).IsStaticArray)
					{
						dm = new DMethod
						{
							Name = "opSlice",
							Type = retType
						};
						overloads.Add(new MemberSymbol(dm, aa.ValueType));
					}
				}
				else if (b is PointerType)
				{
					b = (b as PointerType).Base;
					var dm = new DMethod
					{
						Name = "opIndex",
						Type = b != null ? b.Accept(toTypeDecl) : null
					};
					dm.Parameters.Add(new DVariable
					{
						Name = "index",
						Type = new IdentifierDeclaration("size_t")
					});
					overloads.Add(new MemberSymbol(dm, b));
				}
			}

			res.ResolvedTypesOrMethods = overloads.ToArray();
		}
예제 #27
0
        INode Destructor()
        {
            Expect(Tilde);
            var dm = new DMethod{ Location = t.Location, NameLocation = la.Location };
            Expect(This);

            LastParsedObject = dm;

            dm.SpecialType = DMethod.MethodType.Destructor;
            dm.Name = "~this";

            if (IsTemplateParameterList())
                TemplateParameterList(dm);

            dm.Parameters = Parameters(dm);

            if (laKind == (If))
                Constraint(dm);

            FunctionBody(dm);
            return dm;
        }
예제 #28
0
        public static IBlockNode UpdateBlockPartly(this BlockStatement bs, string code, int caretOffset, CodeLocation caretLocation, out bool isInsideNonCodeSegment)
        {
            isInsideNonCodeSegment = false;
            var finalParentMethod = bs.ParentNode as DMethod;
            var finalStmtsList = bs._Statements;

            var startLoc = bs.Location;
            int startStmtIndex;
            for(startStmtIndex = finalStmtsList.Count-1; startStmtIndex >= 0; startStmtIndex--) {
                var n = finalStmtsList [startStmtIndex];
                if (n.EndLocation.Line > 0 && n.EndLocation.Line < caretLocation.Line) {
                    startLoc = --startStmtIndex == -1 ?
                        bs.Location : finalStmtsList [startStmtIndex].EndLocation;
                    break;
                }
            }

            var startOff = startLoc.Line > 1 ? DocumentHelper.GetOffsetByRelativeLocation (code, caretLocation, caretOffset, startLoc) : 0;

            if (startOff >= caretOffset)
                return null;

            var tempParentBlock = new DMethod();//new DBlockNode();
            var tempBlockStmt = new BlockStatement { ParentNode = tempParentBlock };
            tempParentBlock.Body = tempBlockStmt;
            tempBlockStmt.Location = startLoc;
            tempParentBlock.Location = startLoc;

            using (var sv = new StringView (code, startOff, caretOffset - startOff))
            using (var p = DParser.Create(sv)) {
                p.Lexer.SetInitialLocation (startLoc);
                p.Step ();

                if(p.laKind == DTokens.OpenCurlyBrace)
                    p.Step();

                while (!p.IsEOF) {

                    if (p.laKind == DTokens.CloseCurlyBrace) {
                        p.Step ();
                        /*if (metaDecls.Count > 0)
                            metaDecls.RemoveAt (metaDecls.Count - 1);*/
                        continue;
                    }

                    var stmt = p.Statement (true, false, tempParentBlock, tempBlockStmt);
                    if (stmt != null)
                        tempBlockStmt.Add(stmt);
                    else
                        p.Step();
                }

                tempBlockStmt.EndLocation = new CodeLocation(p.la.Column+1,p.la.Line);
                tempParentBlock.EndLocation = tempBlockStmt.EndLocation;

                if(isInsideNonCodeSegment = p.Lexer.endedWhileBeingInNonCodeSequence)
                    return null;
            }

            DoubleDeclarationSilencer.RemoveDoubles(finalParentMethod, tempParentBlock);

            tempParentBlock.Parent = finalParentMethod;
            //tempParentBlock.Add(new PseudoStaticStmt { Block = tempBlockStmt, ParentNode = tempParentBlock, Location = tempBlockStmt.Location, EndLocation = tempBlockStmt.EndLocation });

            return tempParentBlock;
        }
예제 #29
0
        public static TooltipInformation Generate(DMethod dm, bool isTemplateParamInsight=false, int currentParam=-1)
        {
            var tti = new TooltipInformation();
            var sb = new StringBuilder("<i>(");

            string name;
            switch (dm.SpecialType)
            {
                case DMethod.MethodType.Constructor:
                    sb.Append("Constructor");
                    name = dm.Parent.Name;
                    break;
                case DMethod.MethodType.Destructor:
                    sb.Append("Destructor"); name = dm.Parent.Name;
                    break;
                case DMethod.MethodType.Allocator:
                    sb.Append("Allocator"); name = dm.Parent.Name;
                    break;
                default:
                    sb.Append("Method");
                    name = dm.Name;
                    break;
            }
            sb.Append(")</i> ");

            if (dm.Type != null)
            {
                sb.Append(dm.Type.ToString(true));
                sb.Append(" ");
            }
            else if (dm.Attributes != null && dm.Attributes.Count != 0)
            {
                foreach (var attr in dm.Attributes)
                {
                    var m = attr as Modifier;
                    if (m != null && DTokens.StorageClass[m.Token])
                    {
                        sb.Append(DTokens.GetTokenString(m.Token));
                        sb.Append(" ");
                        break;
                    }
                }
            }

            sb.Append(name);

            /*TODO: Show attributes?
            if (dm.Attributes != null && dm.Attributes.Count > 0)
                s = dm.AttributeString + ' ';
            */

            // Template parameters
            if (dm.TemplateParameters != null && dm.TemplateParameters.Length > 0)
            {
                sb.Append("(");

                for (int i = 0; i < dm.TemplateParameters.Length; i++)
                {
                    var p = dm.TemplateParameters[i];
                    if (isTemplateParamInsight && i == currentParam)
                    {
                        sb.Append("<u>");
                        tti.AddCategory(p.Name, p.ToString());
                        sb.Append(p.ToString());
                        sb.Append("</u>");
                    }
                    else
                        sb.Append(p.ToString());

                    if (i < dm.TemplateParameters.Length - 1)
                        sb.Append(",");
                }

                sb.Append(")");
            }

            // Parameters
            sb.Append("(");

            for (int i = 0; i < dm.Parameters.Count; i++)
            {
                var p = dm.Parameters[i] as DNode;
                if (!isTemplateParamInsight && i == currentParam)
                {
                    sb.Append("<u>");
                    if (!string.IsNullOrEmpty(p.Description))
                        tti.AddCategory(p.Name, p.Description);
                    sb.Append(p.ToString(true, false));
                    sb.Append("</u>");
                }
                else
                    sb.Append(p.ToString(true, false));

                if (i < dm.Parameters.Count - 1)
                    sb.Append(",");
            }

            sb.Append(")");
            tti.SignatureMarkup = sb.ToString();

            tti.SummaryMarkup = dm.Description;
            tti.FooterMarkup = dm.ToString();
            return tti;
        }
예제 #30
0
        AbstractType Type(char type = '\0')
        {
            if(type == '\0')
                type = (char)r.Read();
            switch(type)
            {
                case 'O':
                    var t = Type();
                    t.Modifier = DTokens.Shared;
                    return t;
                case 'x':
                    t = Type();
                    t.Modifier = DTokens.Const;
                    return t;
                case 'y':
                    t = Type();
                    t.Modifier = DTokens.Immutable;
                    return t;
                case 'N':
                    switch(r.Read())
                    {
                        case 'g':
                            t = Type();
                            t.Modifier = DTokens.InOut;
                            return t;
                        case 'e': // TypeNewArray ?
                            Type();
                            return null;
                    }
                    break;
                case 'A':
                    return new ArrayType(Type());
                case 'G':
                    var len = (int)Number();
                    return new ArrayType(Type(), len);
                case 'H':
                    var keyType = Type();
                    t = Type();
                    return new AssocArrayType(t, keyType);
                case 'P':
                    return new PointerType(Type());
                case 'F':
                case 'U':
                case 'W':
                case 'V':
                case 'R':
                    AbstractType ret;
                    List<DAttribute> attrs;
                    Dictionary<INode,AbstractType> pars;
                    Function(out ret, out attrs, out pars, type);

                    var dm = new DMethod(){ Parameters = pars.Keys.ToList(), Attributes = attrs };
                    return new MemberSymbol(dm, ret, null);
                case 'C':
                case 'S':
                case 'E':
                case 'T':
                case 'I':
                return TypeDeclarationResolver.ResolveSingle (QualifiedName (), ctxt);
                /*
                    return new MemberSymbol(null,null, QualifiedName());
                case 'C':
                    return new ClassType(new DClassLike(DTokens.Class), QualifiedName(), null);
                case 'S':
                    return new StructType(new DClassLike(DTokens.Struct), QualifiedName());
                case 'E':
                    return new EnumType(new DEnum(), null, QualifiedName());
                case 'T':
                    return new AliasedType(null, null, QualifiedName());
                */case 'D':
                    Function(out ret, out attrs, out pars, type);
                    var dgArgs = new List<AbstractType>();

                    foreach(var kv in pars)
                        dgArgs.Add(new MemberSymbol(kv.Key as DNode, kv.Value, null));

                    return new DelegateType(ret,new DelegateDeclaration{ Parameters = pars.Keys.ToList() }, dgArgs);
                case 'v': return new PrimitiveType(DTokens.Void);
                case 'g': return new PrimitiveType(DTokens.Byte);
                case 'h': return new PrimitiveType(DTokens.Ubyte);
                case 's': return new PrimitiveType(DTokens.Short);
                case 't': return new PrimitiveType(DTokens.Ushort);
                case 'i': return new PrimitiveType(DTokens.Int);
                case 'k': return new PrimitiveType(DTokens.Uint);
                case 'l': return new PrimitiveType(DTokens.Long);
                case 'm': return new PrimitiveType(DTokens.Ulong);
                case 'f': return new PrimitiveType(DTokens.Float);
                case 'd': return new PrimitiveType(DTokens.Double);
                case 'e': return new PrimitiveType(DTokens.Real);
                case 'o': return new PrimitiveType(DTokens.Ifloat);
                case 'p': return new PrimitiveType(DTokens.Idouble);
                case 'j': return new PrimitiveType(DTokens.Ireal);
                case 'q': return new PrimitiveType(DTokens.Cfloat);
                case 'r': return new PrimitiveType(DTokens.Cdouble);
                case 'c': return new PrimitiveType(DTokens.Creal);
                case 'b': return new PrimitiveType(DTokens.Bool);
                case 'a': return new PrimitiveType(DTokens.Char);
                case 'u': return new PrimitiveType(DTokens.Wchar);
                case 'w': return new PrimitiveType(DTokens.Dchar);
                case 'n': return null;

                case 'B':
                    len = (int)Number();
                    var items = new AbstractType[len];
                    var c = (char)r.Read();
                    for (int i = 0; i < len; i++)
                    {
                        Argument(ref c, out items[i]);
                    }

                    return new DTuple(items);
            }

            return null;
        }
예제 #31
0
		static StaticProperties()
		{
			var props = new Dictionary<int, StaticPropertyInfo>();
			Properties[PropOwnerType.Generic] = props;

			props.AddProp(new StaticPropertyInfo("init", "A type's or variable's static initializer expression") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType });
			props.AddProp(new StaticPropertyInfo("sizeof", "Size of a type or variable in bytes", DTokens.Uint)); // Do not define it as size_t due to unnecessary recursive definition as typeof(int.sizeof)
			props.AddProp(new StaticPropertyInfo("alignof", "Variable offset", DTokens.Uint) { RequireThis = true });
			props.AddProp(new StaticPropertyInfo("mangleof", "String representing the ‘mangled’ representation of the type", "string"));
			props.AddProp(new StaticPropertyInfo("stringof", "String representing the source representation of the type", "string") { 
				ValueGetter = (vp, v) => {
					var t = AbstractType.Get(v);
					if(t == null)
						return new NullValue();
					return new ArrayValue(Evaluation.GetStringType(vp.ResolutionContext), (t is DSymbol) ? DNode.GetNodePath((t as DSymbol).Definition,true) : t.ToCode());
				}
			});



			props = new Dictionary<int, StaticPropertyInfo>();
			Properties[PropOwnerType.Integral] = props;

			props.AddProp(new StaticPropertyInfo("max", "Maximum value") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType });
			props.AddProp(new StaticPropertyInfo("min", "Minimum value") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType });



			props = new Dictionary<int, StaticPropertyInfo>();
			Properties[PropOwnerType.FloatingPoint] = props;

			props.AddProp(new StaticPropertyInfo("infinity", "Infinity value") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType });
			props.AddProp(new StaticPropertyInfo("nan", "Not-a-Number value") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType });
			props.AddProp(new StaticPropertyInfo("dig", "Number of decimal digits of precision", DTokens.Int));
			props.AddProp(new StaticPropertyInfo("epsilon", "Smallest increment to the value 1") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType });
			props.AddProp(new StaticPropertyInfo("mant_dig", "Number of bits in mantissa", DTokens.Int));
			props.AddProp(new StaticPropertyInfo("max_10_exp", "Maximum int value such that 10^max_10_exp is representable", DTokens.Int));
			props.AddProp(new StaticPropertyInfo("max_exp", "Maximum int value such that 2^max_exp-1 is representable", DTokens.Int));
			props.AddProp(new StaticPropertyInfo("min_10_exp", "Minimum int value such that 10^max_10_exp is representable", DTokens.Int));
			props.AddProp(new StaticPropertyInfo("min_exp", "Minimum int value such that 2^max_exp-1 is representable", DTokens.Int));
			props.AddProp(new StaticPropertyInfo("min_normal", "Number of decimal digits of precision", DTokens.Int));
			props.AddProp(new StaticPropertyInfo("re", "Real part") { TypeGetter = help_ReflectNonComplexType, ResolvedBaseTypeGetter = help_ReflectResolvedNonComplexType, RequireThis = true });
			props.AddProp(new StaticPropertyInfo("im", "Imaginary part") { TypeGetter = help_ReflectNonComplexType, ResolvedBaseTypeGetter = help_ReflectResolvedNonComplexType, RequireThis = true });



			props = new Dictionary<int, StaticPropertyInfo>();
			Properties[PropOwnerType.Array] = props;

			props.AddProp(new StaticPropertyInfo("length", "Array length", DTokens.Int) { 
				RequireThis = true,
			ValueGetter = 
				(vp, v) => {
					var av = v as ArrayValue;
					return new PrimitiveValue(av.Elements != null ? av.Elements.Length : 0); 
				}});

			props.AddProp(new StaticPropertyInfo("dup", "Create a dynamic array of the same size and copy the contents of the array into it.") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType, RequireThis = true });
			props.AddProp(new StaticPropertyInfo("idup", "D2.0 only! Creates immutable copy of the array") { TypeGetter = (t,ctxt) => new MemberFunctionAttributeDecl (DTokens.Immutable) { InnerType = help_ReflectType (t,ctxt) }, RequireThis = true });
			props.AddProp(new StaticPropertyInfo("reverse", "Reverses in place the order of the elements in the array. Returns the array.") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType, RequireThis = true });
			props.AddProp(new StaticPropertyInfo("sort", "Sorts in place the order of the elements in the array. Returns the array.") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType, RequireThis = true });
			props.AddProp(new StaticPropertyInfo("ptr", "Returns pointer to the array") {
				ResolvedBaseTypeGetter = (t, ctxt) => new PointerType((t as DerivedDataType).Base),
				TypeGetter = (t, ctxt) => new PointerDecl(DTypeToTypeDeclVisitor.GenerateTypeDecl((t as DerivedDataType).Base)), 
				RequireThis = true 
			});



			props = new Dictionary<int, StaticPropertyInfo>(props); // Copy from arrays' properties!
			Properties[PropOwnerType.AssocArray] = props;
			
			props.AddProp(new StaticPropertyInfo("length", "Returns number of values in the associative array. Unlike for dynamic arrays, it is read-only.", "size_t") { RequireThis = true });
			props.AddProp(new StaticPropertyInfo("keys", "Returns dynamic array, the elements of which are the keys in the associative array.") { TypeGetter = (t, ctxt) => new ArrayDecl { ValueType = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).KeyType) }, RequireThis = true });
			props.AddProp(new StaticPropertyInfo("values", "Returns dynamic array, the elements of which are the values in the associative array.") { TypeGetter = (t, ctxt) => new ArrayDecl { ValueType = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).ValueType) }, RequireThis = true });
			props.AddProp(new StaticPropertyInfo("rehash", "Reorganizes the associative array in place so that lookups are more efficient. rehash is effective when, for example, the program is done loading up a symbol table and now needs fast lookups in it. Returns a reference to the reorganized array.") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType, RequireThis = true });
			props.AddProp(new StaticPropertyInfo("byKey", "Returns a delegate suitable for use as an Aggregate to a ForeachStatement which will iterate over the keys of the associative array.") { TypeGetter = (t, ctxt) => new DelegateDeclaration() { ReturnType = new ArrayDecl() { ValueType = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).KeyType) } }, RequireThis = true });
			props.AddProp(new StaticPropertyInfo("byValue", "Returns a delegate suitable for use as an Aggregate to a ForeachStatement which will iterate over the values of the associative array.") { TypeGetter = (t, ctxt) => new DelegateDeclaration() { ReturnType = new ArrayDecl() { ValueType = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).ValueType) } }, RequireThis = true });
			props.AddProp(new StaticPropertyInfo("get", null)
			{
				RequireThis = true,
				NodeGetter = (t, ctxt) =>
				{
					var ad = t as AssocArrayType;
					var valueType = DTypeToTypeDeclVisitor.GenerateTypeDecl(ad.ValueType);
					var dm = new DMethod () {
						Name = "get",
						Description = "Looks up key; if it exists returns corresponding value else evaluates and returns defaultValue.",
						Type = valueType
					};
					dm.Parameters.Add(new DVariable () {
						Name = "key",
						Type = DTypeToTypeDeclVisitor.GenerateTypeDecl(ad.KeyType)
					});
					dm.Parameters.Add(new DVariable () {
						Name = "defaultValue",
						Type = valueType,
						Attributes = new List<DAttribute>{ new Modifier (DTokens.Lazy) }
					});
					return dm;
				}
			});
			props.AddProp(new StaticPropertyInfo("remove", null) {
				RequireThis = true,
				NodeGetter = (t, ctxt) => { 
					var dm =new DMethod	{
						Name = "remove",
						Description = "remove(key) does nothing if the given key does not exist and returns false. If the given key does exist, it removes it from the AA and returns true.",
						Type = new DTokenDeclaration (DTokens.Bool)
					};
					dm.Parameters.Add(new DVariable {
						Name = "key",
						Type = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).KeyType)
					});
					return dm;
				}
			});


			props = new Dictionary<int, StaticPropertyInfo>();
			Properties[PropOwnerType.TypeTuple] = props;

			props.AddProp(new StaticPropertyInfo("length", "Returns number of values in the type tuple.", "size_t") { 
				RequireThis = true,
				ValueGetter = 
				(vp, v) => {
					var tt = v as DTuple;
					if (tt == null && v is TypeValue)
						tt = (v as TypeValue).RepresentedType as DTuple;
					return tt != null ? new PrimitiveValue(tt.Items == null ? 0 : tt.Items.Length) : null; 
				} });




			props = new Dictionary<int, StaticPropertyInfo>();
			Properties[PropOwnerType.Delegate] = props;


			props.AddProp(new StaticPropertyInfo("ptr", "The .ptr property of a delegate will return the frame pointer value as a void*.",
				(ITypeDeclaration)new PointerDecl(new DTokenDeclaration(DTokens.Void))) { RequireThis = true });
			props.AddProp(new StaticPropertyInfo("funcptr", "The .funcptr property of a delegate will return the function pointer value as a function type.") { RequireThis = true });




			props = new Dictionary<int, StaticPropertyInfo>();
			Properties[PropOwnerType.ClassLike] = props;

			props.AddProp(new StaticPropertyInfo("classinfo", "Information about the dynamic type of the class", (ITypeDeclaration)new IdentifierDeclaration("TypeInfo_Class") { ExpressesVariableAccess = true, InnerDeclaration = new IdentifierDeclaration("object") }) { RequireThis = true });

			props = new Dictionary<int, StaticPropertyInfo>();
			Properties[PropOwnerType.Struct] = props;

			props.AddProp(new StaticPropertyInfo("sizeof", "Size in bytes of struct", DTokens.Uint));
			props.AddProp(new StaticPropertyInfo("alignof", "Size boundary struct needs to be aligned on", DTokens.Uint));
			props.AddProp(new StaticPropertyInfo("tupleof", "Gets type tuple of fields")
			{
				TypeGetter = (t, ctxt) =>
				{
					var members = GetStructMembers(t as StructType, ctxt);
					var l = new List<IExpression>();

					var vis = new DTypeToTypeDeclVisitor();
					foreach (var member in members)
					{
						var mt = DResolver.StripMemberSymbols(member);
						if(mt == null){
							l.Add(null);
							continue;
						}
						var td = mt.Accept(vis);
						if (td == null)
						{
							l.Add(null);
							continue;
						}
						l.Add(td as IExpression ?? new TypeDeclarationExpression(td));
					}

					return new TemplateInstanceExpression(new IdentifierDeclaration("Tuple")) { Arguments =  l.ToArray() };
				},

				ResolvedBaseTypeGetter = (t, ctxt) =>
				{
					var members = GetStructMembers(t as StructType, ctxt);
					var tupleItems = new List<ISemantic>();

					foreach (var member in members)
					{
						var mt = DResolver.StripMemberSymbols(member);
						if (mt != null)
							tupleItems.Add(mt);
					}

					return new DTuple(tupleItems);
				}
			});

		}