예제 #1
0
        public static bool CanAddMemberOfType(MemberFilter vis, INode n)
        {
            if (n is DMethod)
                return n.NameHash != 0 && ((vis & MemberFilter.Methods) == MemberFilter.Methods);

            else if (n is DVariable)
            {
                var d = n as DVariable;

                if (d.IsAliasThis)
                    return false;

                // Only add aliases if at least types,methods or variables shall be shown.
                if (d.IsAlias)
                    return
                        vis.HasFlag(MemberFilter.Methods) ||
                        vis.HasFlag(MemberFilter.Types) ||
                        vis.HasFlag(MemberFilter.Variables);

                return (vis & MemberFilter.Variables) == MemberFilter.Variables;
            }

            else if (n is DClassLike)
            {
                var dc = n as DClassLike;
                switch (dc.ClassType)
                {
                    case DTokens.Class:
                        return (vis & MemberFilter.Classes) != 0;
                    case DTokens.Interface:
                        return (vis & MemberFilter.Interfaces) != 0;
                    case DTokens.Template:
                        return (vis & MemberFilter.Templates) != 0;
                    case DTokens.Struct:
                    case DTokens.Union:
                        return (vis & MemberFilter.StructsAndUnions) != 0;
                }
            }

            else if (n is DEnum)
            {
                var d = n as DEnum;

                // Only show enums if a) they're named and enums are allowed or b) variables are allowed
                return d.IsAnonymous ?
                    (vis & MemberFilter.Variables) != 0 :
                    (vis & MemberFilter.Enums) != 0;
            }
            else if (n is NamedTemplateMixinNode)
                return (vis & (MemberFilter.Variables | MemberFilter.Types)) == (MemberFilter.Variables | MemberFilter.Types);

            return false;
        }
예제 #2
0
        private AccessPathFilter(Member member, MemberFilter memberFilter, Type returnType) : this(member, memberFilter)
        {
            // We do not want compiler generated in postconditions
            if (memberFilter.HasFlag(MemberFilter.FROM_POSTCONDITION))
            {
                this.flags |= Flags.AvoidCompilerGenerated;
            }

            this.returnType = returnType;
        }
예제 #3
0
        static bool CanAddMemberOfType(MemberFilter VisibleMembers, INode n)
        {
            if (n is DMethod)
            {
                return(!string.IsNullOrEmpty(n.Name) && VisibleMembers.HasFlag(MemberFilter.Methods));
            }

            if (n is DVariable)
            {
                var d = n as DVariable;

                // Only add aliases if at least types,methods or variables shall be shown.
                if (d.IsAlias)
                {
                    return
                        (VisibleMembers.HasFlag(MemberFilter.Methods) ||
                         VisibleMembers.HasFlag(MemberFilter.Types) ||
                         VisibleMembers.HasFlag(MemberFilter.Variables));
                }

                return(VisibleMembers.HasFlag(MemberFilter.Variables));
            }

            if (n is DClassLike)
            {
                return(VisibleMembers.HasFlag(MemberFilter.Types));
            }

            if (n is DEnum)
            {
                var d = n as DEnum;

                // Only show enums if a) they're named and types are allowed or b) variables are allowed
                return((d.IsAnonymous ? false : VisibleMembers.HasFlag(MemberFilter.Types)) ||
                       VisibleMembers.HasFlag(MemberFilter.Variables));
            }

            return(false);
        }
		private bool GetVisibleMemberFilter(IEditorData Editor, char enteredChar, ref MemberFilter visibleMembers, ref IStatement curStmt)
		{
			if (trackVars == null)
			{
				// --> Happens if no actual declaration syntax given --> Show types/keywords anyway
				visibleMembers = MemberFilter.Types | MemberFilter.Keywords | MemberFilter.TypeParameters;
			}
			else
			{
				var n = trackVars.LastParsedObject as INode;
				var dv = n as DVariable;
				if (trackVars.ExpectingNodeName) {
					if (dv != null && dv.IsAlias && dv.Type == null) {
						// Show completion because no aliased type has been entered yet
					} else if (n != null && n.NameHash==0 && enteredChar != '\0')
						return false;
				}

				else if (trackVars.LastParsedObject is TokenExpression &&
					DTokens.BasicTypes[(trackVars.LastParsedObject as TokenExpression).Token] &&
					DTokens.IsIdentifierChar(enteredChar))
					return false;

				if (trackVars.LastParsedObject is Modifier)
				{
					var attr = trackVars.LastParsedObject as Modifier;

					if (attr.IsStorageClass && attr.Token != DTokens.Abstract)
						return false;
				}

				else if (trackVars.IsParsingBaseClassList)
				{
					var dc = parsedBlock as DClassLike;
					if (dc != null && dc.ClassType == DTokens.Interface)
						visibleMembers = MemberFilter.Interfaces | MemberFilter.Templates;
					else
						visibleMembers = MemberFilter.Classes | MemberFilter.Interfaces | MemberFilter.Templates;
					return true;
				}
				
				if (trackVars.IsParsingAssignExpression)
				{
					visibleMembers = MemberFilter.All;
					return true;
				}

				if ((trackVars.LastParsedObject is NewExpression && trackVars.IsParsingInitializer) ||
					trackVars.LastParsedObject is TemplateInstanceExpression && ((TemplateInstanceExpression)trackVars.LastParsedObject).Arguments == null)
					visibleMembers = MemberFilter.Types;
				else if (enteredChar == ' ')
					return false;
				// In class bodies, do not show variables
				else if (!(parsedBlock is BlockStatement || trackVars.IsParsingInitializer))
				{
					bool showVariables = false;
					var dbn = parsedBlock as DBlockNode;
					if (dbn != null && dbn.StaticStatements != null && dbn.StaticStatements.Count > 0)
					{
						var ss = dbn.StaticStatements[dbn.StaticStatements.Count - 1];
						if (Editor.CaretLocation > ss.Location && Editor.CaretLocation <= ss.EndLocation)
						{
							showVariables = true;
						}
					}

					if (!showVariables)
						visibleMembers = MemberFilter.All ^ MemberFilter.Variables;
				}

				// Hide completion if having typed a '0.' literal
				else if (trackVars.LastParsedObject is IdentifierExpression &&
					   (trackVars.LastParsedObject as IdentifierExpression).Format == LiteralFormat.Scalar)
					return false;

				/*
				 * Handle module-scoped things:
				 * When typing a dot without anything following, trigger completion and show types, methods and vars that are located in the module & import scope
				 */
				else if (trackVars.LastParsedObject is TokenExpression &&
					((TokenExpression)trackVars.LastParsedObject).Token == DTokens.Dot)
				{
					visibleMembers = MemberFilter.Methods | MemberFilter.Types | MemberFilter.Variables | MemberFilter.TypeParameters;
					curBlock = Editor.SyntaxTree;
					curStmt = null;
				}

				// In a method, parse from the method's start until the actual caret position to get an updated insight
				if (visibleMembers.HasFlag(MemberFilter.Variables) &&
					curBlock is DMethod &&
					parsedBlock is BlockStatement)
				{}
				else
					curStmt = null;
			}
			return true;
		}
예제 #5
0
        private bool GetVisibleMemberFilter(IEditorData Editor, char enteredChar, ref MemberFilter visibleMembers, ref IStatement curStmt)
        {
            if (trackVars == null)
            {
                // --> Happens if no actual declaration syntax given --> Show types/keywords anyway
                visibleMembers = MemberFilter.Types | MemberFilter.Keywords | MemberFilter.TypeParameters;
            }
            else
            {
                var n  = trackVars.LastParsedObject as INode;
                var dv = n as DVariable;
                if (trackVars.ExpectingNodeName)
                {
                    if (dv != null && dv.IsAlias && dv.Type == null)
                    {
                        // Show completion because no aliased type has been entered yet
                    }
                    else if (n != null && n.NameHash == 0 && enteredChar != '\0')
                    {
                        return(false);
                    }
                }

                else if (trackVars.LastParsedObject is TokenExpression &&
                         DTokens.BasicTypes[(trackVars.LastParsedObject as TokenExpression).Token] &&
                         DTokens.IsIdentifierChar(enteredChar))
                {
                    return(false);
                }

                if (trackVars.LastParsedObject is Modifier)
                {
                    var attr = trackVars.LastParsedObject as Modifier;

                    if (attr.IsStorageClass && attr.Token != DTokens.Abstract)
                    {
                        return(false);
                    }
                }

                else if (trackVars.IsParsingBaseClassList)
                {
                    var dc = parsedBlock as DClassLike;
                    if (dc != null && dc.ClassType == DTokens.Interface)
                    {
                        visibleMembers = MemberFilter.Interfaces | MemberFilter.Templates;
                    }
                    else
                    {
                        visibleMembers = MemberFilter.Classes | MemberFilter.Interfaces | MemberFilter.Templates;
                    }
                    return(true);
                }

                if (trackVars.IsParsingAssignExpression)
                {
                    visibleMembers = MemberFilter.All;
                    return(true);
                }

                if ((trackVars.LastParsedObject is NewExpression && trackVars.IsParsingInitializer) ||
                    trackVars.LastParsedObject is TemplateInstanceExpression && ((TemplateInstanceExpression)trackVars.LastParsedObject).Arguments == null)
                {
                    visibleMembers = MemberFilter.Types;
                }
                else if (enteredChar == ' ')
                {
                    return(false);
                }
                // In class bodies, do not show variables
                else if (!(parsedBlock is BlockStatement || trackVars.IsParsingInitializer))
                {
                    bool showVariables = false;
                    var  dbn           = parsedBlock as DBlockNode;
                    if (dbn != null && dbn.StaticStatements != null && dbn.StaticStatements.Count > 0)
                    {
                        var ss = dbn.StaticStatements[dbn.StaticStatements.Count - 1];
                        if (Editor.CaretLocation > ss.Location && Editor.CaretLocation <= ss.EndLocation)
                        {
                            showVariables = true;
                        }
                    }

                    if (!showVariables)
                    {
                        visibleMembers = MemberFilter.All ^ MemberFilter.Variables;
                    }
                }

                // Hide completion if having typed a '0.' literal
                else if (trackVars.LastParsedObject is IdentifierExpression &&
                         (trackVars.LastParsedObject as IdentifierExpression).Format == LiteralFormat.Scalar)
                {
                    return(false);
                }

                /*
                 * Handle module-scoped things:
                 * When typing a dot without anything following, trigger completion and show types, methods and vars that are located in the module & import scope
                 */
                else if (trackVars.LastParsedObject is TokenExpression &&
                         ((TokenExpression)trackVars.LastParsedObject).Token == DTokens.Dot)
                {
                    visibleMembers = MemberFilter.Methods | MemberFilter.Types | MemberFilter.Variables | MemberFilter.TypeParameters;
                    curBlock       = Editor.SyntaxTree;
                    curStmt        = null;
                }

                // In a method, parse from the method's start until the actual caret position to get an updated insight
                if (visibleMembers.HasFlag(MemberFilter.Variables) &&
                    curBlock is DMethod &&
                    parsedBlock is BlockStatement)
                {
                }
                else
                {
                    curStmt = null;
                }
            }
            return(true);
        }
예제 #6
0
        public virtual void IterateThroughScopeLayers(CodeLocation Caret, MemberFilter VisibleMembers= MemberFilter.All)
        {
            // 1)
            if (ctxt.ScopedStatement != null &&
                IterateThroughItemHierarchy(ctxt.ScopedStatement, Caret, VisibleMembers) &&
                    (ctxt.Options.HasFlag(ResolutionOptions.StopAfterFirstOverloads) ||
                    ctxt.Options.HasFlag(ResolutionOptions.StopAfterFirstMatch)))
                    return;

            var curScope = ctxt.ScopedBlock;

            bool breakOnNextScope = false;

            // 2)
            while (curScope != null)
            {
                // Walk up inheritance hierarchy
                if (curScope is DClassLike)
                {
                    if (IterateThrough((DClassLike)curScope, VisibleMembers, ref breakOnNextScope))
                        return;
                }
                else if (curScope is DMethod)
                {
                    var dm = curScope as DMethod;

                    // Add 'out' variable if typing in the out test block currently
                    if (dm.OutResultVariable != null && dm.Out != null && dm.GetSubBlockAt(Caret) == dm.Out &&
                        (breakOnNextScope = HandleItem(new DVariable // Create pseudo-variable
                            {
                                Name = dm.OutResultVariable.Id as string,
                                NameLocation = dm.OutResultVariable.Location,
                                Type = dm.Type, // TODO: What to do on auto functions?
                                Parent = dm,
                                Location = dm.OutResultVariable.Location,
                                EndLocation = dm.OutResultVariable.EndLocation,
                            })) &&
                            breakImmediately)
                        return;

                    if (VisibleMembers.HasFlag(MemberFilter.Variables) &&
                        (breakOnNextScope = HandleItems(dm.Parameters)) &&
                        breakImmediately)
                        return;

                    if (dm.TemplateParameters != null &&
                        (breakOnNextScope = HandleItems(dm.TemplateParameterNodes as IEnumerable<INode>)) &&
                        breakImmediately)
                        return;

                    // The method's declaration children are handled above already via BlockStatement.GetItemHierarchy().
                    // except AdditionalChildren:
                    foreach (var ch in dm.AdditionalChildren)
                        if (CanAddMemberOfType(VisibleMembers, ch) &&
                            (breakOnNextScope = HandleItem(ch) && breakImmediately))
                            return;

                    // If the method is a nested method,
                    // this method won't be 'linked' to the parent statement tree directly -
                    // so, we've to gather the parent method and add its locals to the return list
                    if (dm.Parent is DMethod)
                    {
                        var nestedBlock = (dm.Parent as DMethod).GetSubBlockAt(Caret);

                        // Search for the deepest statement scope and add all declarations done in the entire hierarchy
                        if (nestedBlock != null &&
                            (breakOnNextScope = IterateThroughItemHierarchy(nestedBlock.SearchStatementDeeply(Caret), Caret, VisibleMembers)) &&
                            breakImmediately)
                            return;
                    }
                }
                else
                {
                    var ch = PrefilterSubnodes(curScope);
                    if(ch!=null)
                        foreach (var n in ch)
                        {
                            // Add anonymous enums' items
                            if (n is DEnum && string.IsNullOrEmpty(n.Name) && CanAddMemberOfType(VisibleMembers, n))
                            {
                                if ((breakOnNextScope = HandleItems(((DEnum)n).Children)) && breakImmediately)
                                    return;
                                continue;
                            }

                            var dm3 = n as DMethod; // Only show normal & delegate methods
                            if (
                                !CanAddMemberOfType(VisibleMembers, n) ||
                                (dm3 != null && !(dm3.SpecialType == DMethod.MethodType.Normal || dm3.SpecialType == DMethod.MethodType.Delegate)))
                                continue;

                            if ((breakOnNextScope = HandleItem(n)) && breakImmediately)
                                return;
                        }
                }

                // Handle imports
                if (curScope is DBlockNode)
                    if ((breakOnNextScope = HandleDBlockNode((DBlockNode)curScope, VisibleMembers)) && breakImmediately)
                        return;

                if (breakOnNextScope && ctxt.Options.HasFlag(ResolutionOptions.StopAfterFirstOverloads))
                    return;

                curScope = curScope.Parent as IBlockNode;
            }

            // Add __ctfe variable
            if (!breakOnNextScope && CanAddMemberOfType(VisibleMembers, __ctfe))
                if (HandleItem(__ctfe))
                    return;
        }
예제 #7
0
        static bool CanAddMemberOfType(MemberFilter VisibleMembers, INode n)
        {
            if (n is DMethod)
                return !string.IsNullOrEmpty(n.Name) && VisibleMembers.HasFlag(MemberFilter.Methods);

            if (n is DVariable)
            {
                var d = n as DVariable;

                // Only add aliases if at least types,methods or variables shall be shown.
                if (d.IsAlias)
                    return
                        VisibleMembers.HasFlag(MemberFilter.Methods) ||
                        VisibleMembers.HasFlag(MemberFilter.Types) ||
                        VisibleMembers.HasFlag(MemberFilter.Variables);

                return VisibleMembers.HasFlag(MemberFilter.Variables);
            }

            if (n is DClassLike)
                return VisibleMembers.HasFlag(MemberFilter.Types);

            if (n is DEnum)
            {
                var d = n as DEnum;

                // Only show enums if a) they're named and types are allowed or b) variables are allowed
                return (d.IsAnonymous ? false : VisibleMembers.HasFlag(MemberFilter.Types)) ||
                    VisibleMembers.HasFlag(MemberFilter.Variables);
            }

            return false;
        }
예제 #8
0
        public static bool CanAddMemberOfType(MemberFilter vis, INode n)
        {
            if (n is DMethod)
            {
                return(n.NameHash != 0 && ((vis & MemberFilter.Methods) == MemberFilter.Methods));
            }

            else if (n is DVariable)
            {
                var d = n as DVariable;

                if (d.IsAliasThis)
                {
                    return(false);
                }

                // Only add aliases if at least types,methods or variables shall be shown.
                if (d.IsAlias)
                {
                    return
                        (vis.HasFlag(MemberFilter.Methods) ||
                         vis.HasFlag(MemberFilter.Types) ||
                         vis.HasFlag(MemberFilter.Variables));
                }

                return((vis & MemberFilter.Variables) == MemberFilter.Variables);
            }

            else if (n is DClassLike)
            {
                var dc = n as DClassLike;
                switch (dc.ClassType)
                {
                case DTokens.Class:
                    return((vis & MemberFilter.Classes) != 0);

                case DTokens.Interface:
                    return((vis & MemberFilter.Interfaces) != 0);

                case DTokens.Template:
                    return((vis & MemberFilter.Templates) != 0);

                case DTokens.Struct:
                case DTokens.Union:
                    return((vis & MemberFilter.StructsAndUnions) != 0);
                }
            }

            else if (n is DEnum)
            {
                var d = n as DEnum;

                // Only show enums if a) they're named and enums are allowed or b) variables are allowed
                return(d.IsAnonymous ?
                       (vis & MemberFilter.Variables) != 0 :
                       (vis & MemberFilter.Enums) != 0);
            }
            else if (n is NamedTemplateMixinNode)
            {
                return((vis & (MemberFilter.Variables | MemberFilter.Types)) == (MemberFilter.Variables | MemberFilter.Types));
            }

            return(false);
        }
예제 #9
0
        public virtual void IterateThroughScopeLayers(CodeLocation Caret, MemberFilter VisibleMembers = MemberFilter.All)
        {
            // 1)
            if (ctxt.ScopedStatement != null &&
                IterateThroughItemHierarchy(ctxt.ScopedStatement, Caret, VisibleMembers) &&
                (ctxt.Options.HasFlag(ResolutionOptions.StopAfterFirstOverloads) ||
                 ctxt.Options.HasFlag(ResolutionOptions.StopAfterFirstMatch)))
            {
                return;
            }

            var curScope = ctxt.ScopedBlock;

            bool breakOnNextScope = false;

            // 2)
            while (curScope != null)
            {
                // Walk up inheritance hierarchy
                if (curScope is DClassLike)
                {
                    if (IterateThrough((DClassLike)curScope, VisibleMembers, ref breakOnNextScope))
                    {
                        return;
                    }
                }
                else if (curScope is DMethod)
                {
                    var dm = curScope as DMethod;

                    // Add 'out' variable if typing in the out test block currently
                    if (dm.OutResultVariable != null && dm.Out != null && dm.GetSubBlockAt(Caret) == dm.Out &&
                        (breakOnNextScope = HandleItem(new DVariable                         // Create pseudo-variable
                    {
                        Name = dm.OutResultVariable.Id as string,
                        NameLocation = dm.OutResultVariable.Location,
                        Type = dm.Type,                                         // TODO: What to do on auto functions?
                        Parent = dm,
                        Location = dm.OutResultVariable.Location,
                        EndLocation = dm.OutResultVariable.EndLocation,
                    })) &&
                        breakImmediately)
                    {
                        return;
                    }

                    if (VisibleMembers.HasFlag(MemberFilter.Variables) &&
                        (breakOnNextScope = HandleItems(dm.Parameters)) &&
                        breakImmediately)
                    {
                        return;
                    }

                    if (dm.TemplateParameters != null &&
                        (breakOnNextScope = HandleItems(dm.TemplateParameterNodes as IEnumerable <INode>)) &&
                        breakImmediately)
                    {
                        return;
                    }

                    // The method's declaration children are handled above already via BlockStatement.GetItemHierarchy().
                    // except AdditionalChildren:
                    foreach (var ch in dm.AdditionalChildren)
                    {
                        if (CanAddMemberOfType(VisibleMembers, ch) &&
                            (breakOnNextScope = HandleItem(ch) && breakImmediately))
                        {
                            return;
                        }
                    }

                    // If the method is a nested method,
                    // this method won't be 'linked' to the parent statement tree directly -
                    // so, we've to gather the parent method and add its locals to the return list
                    if (dm.Parent is DMethod)
                    {
                        var nestedBlock = (dm.Parent as DMethod).GetSubBlockAt(Caret);

                        // Search for the deepest statement scope and add all declarations done in the entire hierarchy
                        if (nestedBlock != null &&
                            (breakOnNextScope = IterateThroughItemHierarchy(nestedBlock.SearchStatementDeeply(Caret), Caret, VisibleMembers)) &&
                            breakImmediately)
                        {
                            return;
                        }
                    }
                }
                else
                {
                    var ch = PrefilterSubnodes(curScope);
                    if (ch != null)
                    {
                        foreach (var n in ch)
                        {
                            // Add anonymous enums' items
                            if (n is DEnum && string.IsNullOrEmpty(n.Name) && CanAddMemberOfType(VisibleMembers, n))
                            {
                                if ((breakOnNextScope = HandleItems(((DEnum)n).Children)) && breakImmediately)
                                {
                                    return;
                                }
                                continue;
                            }

                            var dm3 = n as DMethod;                             // Only show normal & delegate methods
                            if (
                                !CanAddMemberOfType(VisibleMembers, n) ||
                                (dm3 != null && !(dm3.SpecialType == DMethod.MethodType.Normal || dm3.SpecialType == DMethod.MethodType.Delegate)))
                            {
                                continue;
                            }

                            if ((breakOnNextScope = HandleItem(n)) && breakImmediately)
                            {
                                return;
                            }
                        }
                    }
                }

                // Handle imports
                if (curScope is DBlockNode)
                {
                    if ((breakOnNextScope = HandleDBlockNode((DBlockNode)curScope, VisibleMembers)) && breakImmediately)
                    {
                        return;
                    }
                }

                if (breakOnNextScope && ctxt.Options.HasFlag(ResolutionOptions.StopAfterFirstOverloads))
                {
                    return;
                }

                curScope = curScope.Parent as IBlockNode;
            }

            // Add __ctfe variable
            if (!breakOnNextScope && CanAddMemberOfType(VisibleMembers, __ctfe))
            {
                if (HandleItem(__ctfe))
                {
                    return;
                }
            }
        }