Esempio n. 1
0
        bool IterateThrough(DClassLike cls, MemberFilter VisibleMembers, ref bool breakOnNextScope)
        {
            var curWatchedClass = cls;

            // MyClass > BaseA > BaseB > Object
            while (curWatchedClass != null)
            {
                if (curWatchedClass.TemplateParameters != null &&
                    (breakOnNextScope = HandleItems(curWatchedClass.TemplateParameterNodes as IEnumerable <INode>)) && breakImmediately)
                {
                    return(true);
                }

                var ch = PrefilterSubnodes(curWatchedClass);
                if (ch != null)
                {
                    foreach (var m in ch)
                    {
                        var dm2 = m as DNode;
                        var dm3 = m as DMethod;                         // Only show normal & delegate methods
                        if (!CanAddMemberOfType(VisibleMembers, m) || dm2 == null ||
                            (dm3 != null && !(dm3.SpecialType == DMethod.MethodType.Normal || dm3.SpecialType == DMethod.MethodType.Delegate)))
                        {
                            continue;
                        }

                        // Add static and non-private members of all base classes;
                        // Add everything if we're still handling the currently scoped class
                        if ((curWatchedClass == cls || dm2.IsStatic || (!(m is DVariable) || ((DVariable)dm2).IsConst) || !dm2.ContainsAttribute(DTokens.Private)) &&
                            (breakOnNextScope = HandleItem(m)) &&
                            breakImmediately)
                        {
                            return(true);
                        }
                    }
                }

                // 3)
                if (cls.ClassType == DTokens.Class)
                {
                    var tr = DResolver.ResolveBaseClasses(new ClassType(curWatchedClass, curWatchedClass, null), ctxt, true);

                    if (tr.Base is TemplateIntermediateType)
                    {
                        curWatchedClass = ((TemplateIntermediateType)tr.Base).Definition;
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            return(false);
        }
        protected override bool HandleItem(INode n)
        {
            // Find all class+interface definitions
            var dc = n as DClassLike;

            if (dc == null ||
                dc.BaseClasses == null || dc.BaseClasses.Count < 0 ||
                alreadyResolvedClasses.Contains(dc))
            {
                return(false);
            }

            // resolve immediate base classes/interfaces; Rely on dc being either a class or an interface, nothing else.
            var t = DResolver.ResolveBaseClasses(dc.ClassType == DTokens.Class ? (UserDefinedType) new ClassType(dc, null, null) : new InterfaceType(dc, null), ctxt) as TemplateIntermediateType;

            alreadyResolvedClasses.Add(dc);

            // Look for classes/interfaces that match dc (check all dcs to have better performance on ambiguous lastresults),
            var bt = DResolver.StripMemberSymbols(t.Base) as TemplateIntermediateType;

            while (bt != null)
            {
                var def = bt.Definition;
                if (def == typeNodeToFind)
                {
                    if (!results.Contains(t))
                    {
                        results.Add(t);
                    }
                }
                if (!alreadyResolvedClasses.Contains(def))
                {
                    alreadyResolvedClasses.Add(def);
                }
                bt = DResolver.StripMemberSymbols(bt.Base) as TemplateIntermediateType;
            }

            return(false);
        }
Esempio n. 3
0
        ISemantic E(TokenExpression x)
        {
            switch (x.Token)
            {
            // References current class scope
            case DTokens.This:
                if (eval && resolveConstOnly)
                {
                    EvalError(new NoConstException(x));
                    return(null);
                }

                var classDef = ctxt.ScopedBlock;

                while (!(classDef is DClassLike) && classDef != null)
                {
                    classDef = classDef.Parent as IBlockNode;
                }

                if (classDef is DClassLike)
                {
                    return(TypeDeclarationResolver.HandleNodeMatch(classDef, ctxt, null, x));
                }

                /*
                 * TODO: Return an object reference to the 'this' object.
                 */
                break;


            case DTokens.Super:
                // References super type of currently scoped class declaration

                if (eval && resolveConstOnly)
                {
                    EvalError(new NoConstException(x));
                    return(null);
                }

                classDef = ctxt.ScopedBlock;

                while (!(classDef is DClassLike) && classDef != null)
                {
                    classDef = classDef.Parent as IBlockNode;
                }

                if (classDef != null)
                {
                    var tr = DResolver.ResolveBaseClasses(new ClassType(classDef as DClassLike, null, null), ctxt, true);

                    if (tr.Base != null)
                    {
                        // Important: Overwrite type decl base with 'super' token
                        tr.Base.DeclarationOrExpressionBase = x;

                        return(tr.Base);
                    }
                }

                /*
                 * TODO: Return an object reference to 'this', wheras the type is the superior type.
                 */
                break;

            case DTokens.Null:
                if (eval && resolveConstOnly)
                {
                    EvalError(new NoConstException(x));
                    return(null);
                }

                if (eval)
                {
                    //TODO
                }

                return(null);

            case DTokens.Dollar:
                if (!eval)
                {
                    return(new PrimitiveType(DTokens.Int));
                }
                // It's only allowed if the evaluation stack contains an array value
                if (ValueProvider.CurrentArrayLength != -1)
                {
                    return(new PrimitiveValue(DTokens.Int, ValueProvider.CurrentArrayLength, x));
                }
                else
                {
                    EvalError(x, "Dollar not allowed here!");
                    return(null);
                }

            case DTokens.True:
                if (!eval)
                {
                    return(new PrimitiveType(DTokens.Bool));
                }
                return(new PrimitiveValue(DTokens.Bool, 1, x));

            case DTokens.False:
                if (!eval)
                {
                    return(new PrimitiveType(DTokens.Bool));
                }
                return(new PrimitiveValue(DTokens.Bool, 0, x));

            case DTokens.__FILE__:
                if (!eval)
                {
                    return(GetStringType());
                }
                return(new ArrayValue(GetStringType(), (ctxt.ScopedBlock.NodeRoot as DModule).FileName));

            case DTokens.__LINE__:
                if (!eval)
                {
                    return(new PrimitiveType(DTokens.Int));
                }
                return(new PrimitiveValue(DTokens.Int, x.Location.Line, x));

            case DTokens.__MODULE__:
                if (!eval)
                {
                    return(GetStringType());
                }
                return(new ArrayValue(GetStringType(), (ctxt.ScopedBlock.NodeRoot as DModule).ModuleName));

            case DTokens.__FUNCTION__:
            //TODO
            case DTokens.__PRETTY_FUNCTION__:
                if (!eval)
                {
                    return(GetStringType());
                }
                var dm = ctxt.ScopedStatement.ParentNode as DMethod;
                return(new ArrayValue(GetStringType(), dm == null ? "<not inside function>" : dm.ToString(false, true)));
            }


            return(null);
        }
Esempio n. 4
0
        /// <summary>
        /// Item1 - True, if isExpression returns true
        /// Item2 - If Item1 is true, it contains the type of the alias that is defined in the isExpression
        /// </summary>
        private Tuple <bool, AbstractType> evalIsExpression_EvalSpecToken(IsExpression isExpression, AbstractType typeToCheck, bool DoAliasHandling = false)
        {
            bool         r   = false;
            AbstractType res = null;

            switch (isExpression.TypeSpecializationToken)
            {
            /*
             * To handle semantic tokens like "return" or "super" it's just needed to
             * look into the current resolver context -
             * then, we'll be able to gather either the parent method or the currently scoped class definition.
             */
            case DTokens.Struct:
            case DTokens.Union:
            case DTokens.Class:
            case DTokens.Interface:
                if (r = typeToCheck is UserDefinedType &&
                        ((TemplateIntermediateType)typeToCheck).Definition.ClassType == isExpression.TypeSpecializationToken)
                {
                    res = typeToCheck;
                }
                break;

            case DTokens.Enum:
                if (!(typeToCheck is EnumType))
                {
                    break;
                }
                {
                    var tr = (UserDefinedType)typeToCheck;
                    r   = true;
                    res = tr.Base;
                }
                break;

            case DTokens.Function:
            case DTokens.Delegate:
                if (typeToCheck is DelegateType)
                {
                    var isFun = false;
                    var dgr   = (DelegateType)typeToCheck;
                    if (!dgr.IsFunctionLiteral)
                    {
                        r = isExpression.TypeSpecializationToken == (
                            (isFun = ((DelegateDeclaration)dgr.DeclarationOrExpressionBase).IsFunction) ? DTokens.Function : DTokens.Delegate);
                    }
                    // Must be a delegate otherwise
                    else
                    {
                        isFun = !(r = isExpression.TypeSpecializationToken == DTokens.Delegate);
                    }

                    if (r)
                    {
                        //TODO
                        if (isFun)
                        {
                            // TypeTuple of the function parameter types. For C- and D-style variadic functions, only the non-variadic parameters are included.
                            // For typesafe variadic functions, the ... is ignored.
                        }
                        else
                        {
                            // the function type of the delegate
                        }
                    }
                }
                else                         // Normal functions are also accepted as delegates
                {
                    r = isExpression.TypeSpecializationToken == DTokens.Delegate &&
                        typeToCheck is MemberSymbol &&
                        ((DSymbol)typeToCheck).Definition is DMethod;

                    //TODO: Alias handling, same as couple of lines above
                }
                break;

            case DTokens.Super:                     //TODO: Test this
                var dc = DResolver.SearchClassLikeAt(ctxt.ScopedBlock, isExpression.Location) as DClassLike;

                if (dc != null)
                {
                    var udt = DResolver.ResolveBaseClasses(new ClassType(dc, dc, null), ctxt, true) as ClassType;

                    if (r = udt.Base != null && ResultComparer.IsEqual(typeToCheck, udt.Base))
                    {
                        var l = new List <AbstractType>();
                        if (udt.Base != null)
                        {
                            l.Add(udt.Base);
                        }
                        if (udt.BaseInterfaces != null && udt.BaseInterfaces.Length != 0)
                        {
                            l.AddRange(udt.BaseInterfaces);
                        }

                        res = new DTuple(isExpression, l);
                    }
                }
                break;

            case DTokens.Const:
            case DTokens.Immutable:
            case DTokens.InOut:                     // TODO?
            case DTokens.Shared:
                if (r = typeToCheck.Modifier == isExpression.TypeSpecializationToken)
                {
                    res = typeToCheck;
                }
                break;

            case DTokens.Return:                     // TODO: Test
                IStatement _u = null;
                var        dm = DResolver.SearchBlockAt(ctxt.ScopedBlock, isExpression.Location, out _u) as DMethod;

                if (dm != null)
                {
                    var retType_ = TypeDeclarationResolver.GetMethodReturnType(dm, ctxt);

                    if (r = retType_ != null && ResultComparer.IsEqual(typeToCheck, retType_))
                    {
                        res = retType_;
                    }
                }
                break;
            }

            return(new Tuple <bool, AbstractType>(r, res));
        }
Esempio n. 5
0
        /// <summary>
        /// Scans through the node. Also checks if n is a DClassLike or an other kind of type node and checks their specific child and/or base class nodes.
        /// </summary>
        /// <param name="parseCache">Needed when trying to search base classes</param>
        public static INode[] ScanNodeForIdentifier(IBlockNode curScope, string name, ResolverContextStack ctxt)
        {
            if (__stack > 40)
            {
                return(null);
            }

            __stack++;

            var matches = new List <INode>();

            // Watch for anonymous enums
            var children = curScope[string.Empty];

            if (children != null)
            {
                foreach (var n in children)
                {
                    if (n is DEnum)
                    {
                        var de = (DEnum)n;

                        var enumChildren = de[name];

                        if (enumChildren != null)
                        {
                            matches.AddRange(enumChildren);
                        }
                    }
                }
            }

            // Scan for normal members called 'name'
            if ((children = curScope[name]) != null)
            {
                matches.AddRange(children);
            }

            // If our current Level node is a class-like, also attempt to search in its baseclass!
            if (curScope is DClassLike)
            {
                var dc = (DClassLike)curScope;

                if (dc.ClassType == DTokens.Class)
                {
                    var tr  = DResolver.ResolveBaseClasses(new ClassType(dc, dc, null), ctxt, true);
                    var tit = tr.Base as TemplateIntermediateType;
                    if (tit != null && tit.Definition != dc)
                    {
                        // Search for items called name in the base class(es)
                        var r = ScanNodeForIdentifier(tit.Definition, name, ctxt);

                        if (r != null)
                        {
                            matches.AddRange(r);
                        }
                    }
                }
                else if (dc.ClassType == DTokens.Interface)
                {
                    var tr = DResolver.ResolveBaseClasses(new InterfaceType(dc, dc), ctxt) as InterfaceType;
                    if (tr != null && tr.BaseInterfaces != null && tr.BaseInterfaces.Length != 0)
                    {
                        foreach (var I in tr.BaseInterfaces)
                        {
                            if (I.Definition == dc)
                            {
                                break;
                            }

                            // Search for items called name in the base class(es)
                            var r = ScanNodeForIdentifier(I.Definition, name, ctxt);

                            if (r != null)
                            {
                                matches.AddRange(r);
                            }
                        }
                    }
                }
            }

            // Check parameters
            var dn = curScope as DNode;

            if (dn != null)
            {
                var dm = dn as DMethod;
                if (dm != null && dm.Parameters != null && dm.Parameters.Count != 0)
                {
                    foreach (var ch in ((DMethod)curScope).Parameters)
                    {
                        if (name == ch.Name)
                        {
                            matches.Add(ch);
                        }
                    }
                }

                // and template parameters
                if (dn.TemplateParameters != null)
                {
                    foreach (var ch in dn.TemplateParameters)
                    {
                        if (name == ch.Name)
                        {
                            matches.Add(new TemplateParameterNode(ch)
                            {
                                Parent = curScope
                            });
                        }
                    }
                }
            }

            __stack--;

            return(matches.Count > 0 ? matches.ToArray() : null);
        }
Esempio n. 6
0
        protected bool DeepScanClass(UserDefinedType udt, MemberFilter vis, bool resolveBaseClassIfRequired = true)
        {
            bool isBase = false;
            bool scopeIsInInheritanceHierarchy = udt != null && ctxt.ScopedBlockIsInNodeHierarchy(udt.Definition);
            bool takeStaticChildrenOnly        = ctxt.ScopedBlock is DMethod && (ctxt.ScopedBlock as DMethod).IsStatic;

            // Check if the scoped node's parent is the current class
            if (takeStaticChildrenOnly)
            {
                takeStaticChildrenOnly = false;
                var sc = udt.Definition as IBlockNode;
                while (sc != null)
                {
                    if (ctxt.ScopedBlock.Parent == sc)
                    {
                        takeStaticChildrenOnly = true;
                        break;
                    }
                    sc = sc.Parent as IBlockNode;
                }
            }

            List <InterfaceType> interfaces = null;

            while (udt != null)
            {
                if (scanChildren(udt.Definition as DBlockNode, vis, false, isBase, false, takeStaticChildrenOnly, scopeIsInInheritanceHierarchy))
                {
                    return(true);
                }

                if (udt is TemplateIntermediateType)
                {
                    var tit  = udt as TemplateIntermediateType;
                    var type = (tit.Definition as DClassLike).ClassType;

                    if ((type == DTokens.Struct || type == DTokens.Class || type == DTokens.Template) &&
                        HandleAliasThisDeclarations(tit, vis))
                    {
                        return(true);
                    }

                    if (tit.BaseInterfaces != null)
                    {
                        if (interfaces == null)
                        {
                            interfaces = new List <InterfaceType> ();
                        }
                        foreach (var I in tit.BaseInterfaces)
                        {
                            if (!interfaces.Contains(I))
                            {
                                interfaces.Add(I);
                            }
                        }
                    }

                    if (resolveBaseClassIfRequired && udt.Base == null && type == DTokens.Class)
                    {
                        udt = DResolver.ResolveBaseClasses(udt, ctxt);
                    }

                    udt = udt.Base as UserDefinedType;

                    isBase = true;
                }
                else
                {
                    break;
                }
            }

            if (interfaces != null)
            {
                foreach (var I in interfaces)
                {
                    if (scanChildren(I.Definition, vis, false, true, false, takeStaticChildrenOnly, scopeIsInInheritanceHierarchy))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }