Exemple #1
0
        public static string GetResolveResultString(ResolveResult rr)
        {
            if (rr is MemberResult)
                return DNode.GetNodePath((rr as MemberResult).ResolvedMember, true);
            if (rr is TypeResult)
                return DNode.GetNodePath((rr as TypeResult).ResolvedTypeDefinition, true);
            if (rr is StaticTypeResult)
                return (rr as StaticTypeResult).TypeDeclarationBase.ToString();
            if (rr is ModuleResult)
            {
                var mrr = rr as ModuleResult;

                var parts = mrr.ResolvedModule.ModuleName.Split('.');
                var ret = "";
                for (int i = 0; i < mrr.AlreadyTypedModuleNameParts; i++)
                    ret += parts[i] + '.';

                return ret.TrimEnd('.');
            }

            return null;
        }
Exemple #2
0
        public static ResolveResult[] HandleNodeMatches(IEnumerable<INode> matches,
			ResolverContext ctxt,
			IBlockNode currentlyScopedNode = null,
			ResolveResult resultBase = null,
			ITypeDeclaration TypeDeclaration = null)
        {
            var rl = new List<ResolveResult>();
            if (matches != null)
                foreach (var m in matches)
                {
                    if (m == null)
                        continue;
                    var res = HandleNodeMatch(m, ctxt, currentlyScopedNode, resultBase, typeBase: TypeDeclaration);
                    if (res != null)
                        rl.Add(res);
                }
            return rl.ToArray();
        }
Exemple #3
0
        /// <summary>
        /// The variable's or method's base type will be resolved (if auto type, the intializer's type will be taken).
        /// A class' base class will be searched.
        /// etc..
        /// </summary>
        /// <returns></returns>
        public static ResolveResult HandleNodeMatch(
			INode m,
			ResolverContext ctxt,
			IBlockNode currentlyScopedNode = null,
			ResolveResult resultBase = null, ITypeDeclaration typeBase = null)
        {
            if (currentlyScopedNode == null)
                currentlyScopedNode = ctxt.ScopedBlock;

            stackNum_HandleNodeMatch++;

            //HACK: Really dirty stack overflow prevention via manually counting call depth
            var DoResolveBaseType =
                stackNum_HandleNodeMatch > 5 ?
                false : ctxt.ResolveBaseTypes;
            // Prevent infinite recursion if the type accidently equals the node's name
            if (m.Type != null && m.Type.ToString(false) == m.Name)
                DoResolveBaseType = false;

            if (m is DVariable)
            {
                var v = m as DVariable;

                var memberbaseTypes = DoResolveBaseType ? ResolveType(v.Type, ctxt, currentlyScopedNode) : null;

                // For auto variables, use the initializer to get its type
                if (memberbaseTypes == null && DoResolveBaseType && v.ContainsAttribute(DTokens.Auto) && v.Initializer != null)
                {
                    var init = v.Initializer;
                    memberbaseTypes = ResolveType(init.ExpressionTypeRepresentation, ctxt, currentlyScopedNode);
                }

                // Resolve aliases if wished
                if (ctxt.ResolveAliases && memberbaseTypes != null)
                {
                    /*
                     * To ensure that absolutely all kinds of alias definitions became resolved (includes aliased alias definitions!),
                     * loop through the resolution process again, after at least one aliased type has been found.
                     */
                    while (memberbaseTypes.Length > 0)
                    {
                        bool hadAliasResolution = false;
                        var memberBaseTypes_Override = new List<ResolveResult>();

                        foreach (var type in memberbaseTypes)
                        {
                            var mr = type as MemberResult;
                            if (mr != null && mr.ResolvedMember is DVariable)
                            {
                                var dv = mr.ResolvedMember as DVariable;
                                // Note: Normally, a variable's base type mustn't be an other variable but an alias defintion...
                                if (dv.IsAlias)
                                {
                                    var newRes = ResolveType(dv.Type, ctxt, currentlyScopedNode);
                                    if (newRes != null)
                                        memberBaseTypes_Override.AddRange(newRes);
                                    hadAliasResolution = true;
                                    continue;
                                }
                            }

                            // If no alias found, re-add it to our override list again
                            memberBaseTypes_Override.Add(type);
                        }
                        memberbaseTypes = memberBaseTypes_Override.ToArray();

                        if (!hadAliasResolution)
                            break;
                    }
                }

                // Note: Also works for aliases! In this case, we simply try to resolve the aliased type, otherwise the variable's base type
                stackNum_HandleNodeMatch--;
                return new MemberResult()
                {
                    ResolvedMember = m,
                    MemberBaseTypes = memberbaseTypes,
                    ResultBase = resultBase,
                    TypeDeclarationBase = typeBase
                };
            }
            else if (m is DMethod)
            {
                var method = m as DMethod;

                var methodType = method.Type;

                /*
                 * If a method's type equals null, assume that it's an 'auto' function..
                 * 1) Search for a return statement
                 * 2) Resolve the returned expression
                 * 3) Use that one as the method's type
                 */
                //TODO: What about handling 'null'-returns?
                if (methodType == null && method.Body != null)
                {
                    ReturnStatement returnStmt = null;
                    var list = new List<IStatement> { method.Body };
                    var list2 = new List<IStatement>();

                    while (returnStmt == null && list.Count > 0)
                    {
                        foreach (var stmt in list)
                        {
                            if (stmt is ReturnStatement)
                            {
                                returnStmt = stmt as ReturnStatement;
                                break;
                            }

                            if (stmt is StatementContainingStatement)
                                list2.AddRange((stmt as StatementContainingStatement).SubStatements);
                        }

                        list = list2;
                        list2 = new List<IStatement>();
                    }

                    if (returnStmt != null && returnStmt.ReturnExpression != null)
                    {
                        currentlyScopedNode = method;
                        methodType = returnStmt.ReturnExpression.ExpressionTypeRepresentation;
                    }
                }

                var ret = new MemberResult()
                {
                    ResolvedMember = m,
                    MemberBaseTypes = DoResolveBaseType ? ResolveType(methodType, ctxt, currentlyScopedNode) : null,
                    ResultBase = resultBase,
                    TypeDeclarationBase = typeBase
                };
                stackNum_HandleNodeMatch--;
                return ret;
            }
            else if (m is DClassLike)
            {
                var Class = m as DClassLike;

                var bc = DoResolveBaseType ? ResolveBaseClass(Class, ctxt) : null;

                stackNum_HandleNodeMatch--;
                return new TypeResult()
                {
                    ResolvedTypeDefinition = Class,
                    BaseClass = bc,
                    ResultBase = resultBase,
                    TypeDeclarationBase = typeBase
                };
            }
            else if (m is IAbstractSyntaxTree)
            {
                stackNum_HandleNodeMatch--;
                return new ModuleResult()
                {
                    ResolvedModule = m as IAbstractSyntaxTree,
                    AlreadyTypedModuleNameParts = 1,
                    ResultBase = resultBase,
                    TypeDeclarationBase = typeBase
                };
            }
            else if (m is DEnum)
            {
                stackNum_HandleNodeMatch--;
                return new TypeResult()
                {
                    ResolvedTypeDefinition = m as IBlockNode,
                    ResultBase = resultBase,
                    TypeDeclarationBase = typeBase
                };
            }
            else if (m is TemplateParameterNode)
            {
                stackNum_HandleNodeMatch--;
                return new MemberResult()
                {
                    ResolvedMember = m,
                    TypeDeclarationBase = typeBase,
                    ResultBase = resultBase
                };
            }

            stackNum_HandleNodeMatch--;
            // This never should happen..
            return null;
        }
Exemple #4
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="TypeDeclarationString"></param>
        /// <param name="NodeMatches"></param>
        /// <param name="ScopedType">If null, ScopedBlock variable will be assumed</param>
        /// <returns></returns>
        public bool TryGetAlreadyResolvedType(string TypeDeclarationString, out ResolveResult[] NodeMatches, object ScopedType = null)
        {
            if (ScopedType == null)
                ScopedType = ScopedBlock;

            Dictionary<string, ResolveResult[]> subDict = null;

            if (ScopedType!=null && !ResolvedTypes.TryGetValue(ScopedType, out subDict))
            {
                NodeMatches = null;
                return false;
            }

            if(subDict!=null)
                return subDict.TryGetValue(TypeDeclarationString, out NodeMatches);

            NodeMatches = null;
            return false;
        }
Exemple #5
0
        public void TryAddResults(string TypeDeclarationString, ResolveResult[] NodeMatches, IBlockNode ScopedType = null)
        {
            if (ScopedType == null)
                ScopedType = ScopedBlock;

            Dictionary<string, ResolveResult[]> subDict = null;

            if (!ResolvedTypes.TryGetValue(ScopedType, out subDict))
                ResolvedTypes.Add(ScopedType, subDict = new Dictionary<string, ResolveResult[]>());

            if (!subDict.ContainsKey(TypeDeclarationString))
                subDict.Add(TypeDeclarationString, NodeMatches);
        }
Exemple #6
0
            /// <summary>
            /// Tries to resolve a static property's name.
            /// Returns a result describing the theoretical member (".init"-%gt;MemberResult; ".typeof"-&gt;TypeResult etc).
            /// Returns null if nothing was found.
            /// </summary>
            /// <param name="InitialResult"></param>
            /// <returns></returns>
            public static ResolveResult TryResolveStaticProperties(ResolveResult InitialResult, IdentifierDeclaration Identifier, ResolverContext ctxt = null)
            {
                if (InitialResult == null || Identifier == null || InitialResult is ModuleResult)
                {
                    return null;
                }

                var propertyName = Identifier.Value as string;
                if (propertyName == null)
                    return null;

                INode relatedNode = null;

                if (InitialResult is MemberResult)
                    relatedNode = (InitialResult as MemberResult).ResolvedMember;
                else if (InitialResult is TypeResult)
                    relatedNode = (InitialResult as TypeResult).ResolvedTypeDefinition;

                #region init
                if (propertyName == "init")
                {
                    var prop_Init = new DVariable
                    {
                        Name = "init",
                        Description = "Initializer"
                    };

                    if (relatedNode != null)
                    {
                        if (!(relatedNode is DVariable))
                        {
                            prop_Init.Parent = relatedNode.Parent;
                            prop_Init.Type = new IdentifierDeclaration(relatedNode.Name);
                        }
                        else
                        {
                            prop_Init.Parent = relatedNode;
                            prop_Init.Initializer = (relatedNode as DVariable).Initializer;
                            prop_Init.Type = relatedNode.Type;
                        }
                    }

                    return new MemberResult
                    {
                        ResultBase = InitialResult,
                        MemberBaseTypes = new[] { InitialResult },
                        TypeDeclarationBase = Identifier,
                        ResolvedMember = prop_Init
                    };
                }
                #endregion

                #region sizeof
                if (propertyName == "sizeof")
                    return new MemberResult
                    {
                        ResultBase = InitialResult,
                        TypeDeclarationBase = Identifier,
                        ResolvedMember = new DVariable
                        {
                            Name = "sizeof",
                            Type = new DTokenDeclaration(DTokens.Int),
                            Initializer = new IdentifierExpression(4),
                            Description = "Size in bytes (equivalent to C's sizeof(type))"
                        }
                    };
                #endregion

                #region alignof
                if (propertyName == "alignof")
                    return new MemberResult
                    {
                        ResultBase = InitialResult,
                        TypeDeclarationBase = Identifier,
                        ResolvedMember = new DVariable
                        {
                            Name = "alignof",
                            Type = new DTokenDeclaration(DTokens.Int),
                            Description = "Alignment size"
                        }
                    };
                #endregion

                #region mangleof
                if (propertyName == "mangleof")
                    return new MemberResult
                    {
                        ResultBase = InitialResult,
                        TypeDeclarationBase = Identifier,
                        ResolvedMember = new DVariable
                        {
                            Name = "mangleof",
                            Type = new IdentifierDeclaration("string"),
                            Description = "String representing the ‘mangled’ representation of the type"
                        },
                        MemberBaseTypes = ResolveType(new IdentifierDeclaration("string"), ctxt)
                    };
                #endregion

                #region stringof
                if (propertyName == "stringof")
                    return new MemberResult
                    {
                        ResultBase = InitialResult,
                        TypeDeclarationBase = Identifier,
                        ResolvedMember = new DVariable
                        {
                            Name = "stringof",
                            Type = new IdentifierDeclaration("string"),
                            Description = "String representing the source representation of the type"
                        },
                        MemberBaseTypes = ResolveType(new IdentifierDeclaration("string"), ctxt)
                    };
                #endregion

                bool
                    isArray = false,
                    isAssocArray = false,
                    isInt = false,
                    isFloat = false;

                #region See AbsractCompletionSupport.StaticPropertyAddition
                if (InitialResult is StaticTypeResult)
                {
                    var srr = InitialResult as StaticTypeResult;

                    var type = srr.TypeDeclarationBase;

                    // on things like immutable(char), pass by the surrounding attribute..
                    while (type is MemberFunctionAttributeDecl)
                        type = (type as MemberFunctionAttributeDecl).InnerType;

                    if (type is ArrayDecl)
                    {
                        var ad = type as ArrayDecl;

                        // Normal array
                        if (ad.KeyType is DTokenDeclaration && DTokens.BasicTypes_Integral[(ad.KeyType as DTokenDeclaration).Token])
                            isArray = true;
                        // Associative array
                        else
                            isAssocArray = true;
                    }
                    else if (!(type is PointerDecl))
                    {
                        int TypeToken = srr.BaseTypeToken;

                        if (TypeToken <= 0 && type is DTokenDeclaration)
                            TypeToken = (type as DTokenDeclaration).Token;

                        if (TypeToken > 0)
                        {
                            // Determine whether float by the var's base type
                            isInt = DTokens.BasicTypes_Integral[srr.BaseTypeToken];
                            isFloat = DTokens.BasicTypes_FloatingPoint[srr.BaseTypeToken];
                        }
                    }
                }
                else if (InitialResult is ExpressionResult)
                {
                    var err = InitialResult as ExpressionResult;
                    var expr = err.Expression;

                    // 'Skip' surrounding parentheses
                    while (expr is SurroundingParenthesesExpression)
                        expr = (expr as SurroundingParenthesesExpression).Expression;

                    var idExpr = expr as IdentifierExpression;
                    if (idExpr != null)
                    {
                        // Char literals, Integrals types & Floats
                        if ((idExpr.Format & LiteralFormat.Scalar) == LiteralFormat.Scalar || idExpr.Format == LiteralFormat.CharLiteral)
                        {
                            // Floats also imply integral properties
                            isInt = true;
                            isFloat = (idExpr.Format & LiteralFormat.FloatingPoint) == LiteralFormat.FloatingPoint;
                        }
                        // String literals
                        else if (idExpr.Format == LiteralFormat.StringLiteral || idExpr.Format == LiteralFormat.VerbatimStringLiteral)
                        {
                            isArray = true;
                        }
                    }
                    // Pointer conversions (e.g. (myInt*).sizeof)
                }
                #endregion

                //TODO: Resolve static [assoc] array props
                if (isArray || isAssocArray)
                {

                }

                return null;
            }