Example #1
0
        /// <summary>
        /// Scans the syntax tree for all kinds of identifier declarations, 
        /// tries to resolve them,
        /// adds them to a dictionary. If not found, 
        /// they will be added to a second, special array.
        /// 
        /// Note: For performance reasons, it's recommended to disable 'ResolveAliases' in the ResolverContext parameter
        /// </summary>
        /// <param name="lastResCtxt"></param>
        /// <param name="SyntaxTree"></param>
        /// <returns></returns>
        public static CodeScanResult ScanSymbols(ResolverContext lastResCtxt,IAbstractSyntaxTree SyntaxTree)
        {
            var csr = new CodeScanResult();

            var compDict = new Dictionary<string, ResolveResult>();

            // Step 1: Enum all existing type id's that shall become resolved'n displayed
            var typeObjects = CodeScanner.ScanForTypeIdentifiers(SyntaxTree);

            foreach (var o in typeObjects)
            {
                if (o == null)
                    continue;

                #region Identifier Declarations
                if (o is IdentifierDeclaration)
                {
                    HandleIdDeclaration(o as IdentifierDeclaration,
                        lastResCtxt,
                        SyntaxTree,
                        csr,
                        compDict);
                }
                #endregion
                    /*
                #region Method call check
                else if (o is PostfixExpression_MethodCall)
                {
                    var mc=o as PostfixExpression_MethodCall;

                    int argc = mc.ArgumentCount;

                    var methodOverloads=HandleIdDeclaration(mc.ExpressionTypeRepresentation as IdentifierDeclaration,
                        lastResCtxt,
                        SyntaxTree,
                        csr,
                        compDict);

                    // Important: Also check template parameters and arguments!
                    IExpression[] TemplateArguments=null;

                    if (mc.PostfixForeExpression is TemplateInstanceExpression)
                        TemplateArguments = (mc.PostfixForeExpression as TemplateInstanceExpression).Arguments;

                    int TemplateArgCount = TemplateArguments == null ? 0 : TemplateArguments.Length;

                    // Note: If no method members were found, we already show the semantic error as a generically missing symbol
                    if (methodOverloads != null)
                    {
                        var l1 = new List<DMethod>();
                        var l2 = new List<DMethod>();

                        #region First add all available method overloads
                        foreach (var rr_ in methodOverloads)
                        {
                            // Like every time, remove unnecessary aliasing
                            var rr = DResolver.TryRemoveAliasesFromResult(rr_);

                            // Can be either 1) a normal method OR 2) a type related opCall

                            // 1)
                            if (rr is MemberResult)
                            {
                                var mr = rr as MemberResult;

                                //FIXME: What about delegate aliases'n stuff?
                                if (!(mr.ResolvedMember is DMethod))
                                    continue;

                                var dm = mr.ResolvedMember as DMethod;

                                // Even before checking argument types etc, pre-select possibly chosen overloads
                                // by comparing the method's parameter count with the call's argument count
                                if (dm.Parameters.Count == argc && (dm.TemplateParameters==null?true:
                                    dm.TemplateParameters.Length==TemplateArgCount))
                                    l1.Add(dm);
                            }

                            // 2)
                            else if (rr is TypeResult)
                            {
                                var tr = rr as TypeResult;

                                // Scan the type for opCall members
                                var opCalls=DResolver.ScanNodeForIdentifier(tr.ResolvedTypeDefinition, "opCall", lastResCtxt);

                                if (opCalls != null)
                                    foreach (var n in opCalls)
                                    {
                                        var dm = n as DMethod;

                                        // Also pre-filter opCall members by param count comparison
                                        if (dm!=null &&
                                            dm.Parameters.Count == argc && (dm.TemplateParameters == null ? true :
                                            dm.TemplateParameters.Length == TemplateArgCount))
                                            l1.Add(dm);
                                    }
                            }
                        }
                        #endregion

                        // Must be a semantic error - no method fits in any way
                        if(l1.Count<1)
                        {
                            csr.ParameterActions.Add(o as IExpression, null);
                            continue;
                        }

                        // Compare template arguments first
                    }
                }
                #endregion
                */
            }

            return csr;
        }
Example #2
0
        /// <summary>
        /// Scans the syntax tree for all kinds of identifier declarations,
        /// tries to resolve them,
        /// adds them to a dictionary. If not found,
        /// they will be added to a second, special array.
        ///
        /// Note: For performance reasons, it's recommended to disable 'ResolveAliases' in the ResolverContext parameter
        /// </summary>
        /// <param name="lastResCtxt"></param>
        /// <param name="SyntaxTree"></param>
        /// <returns></returns>
        public static CodeScanResult ScanSymbols(ResolverContext lastResCtxt, IAbstractSyntaxTree SyntaxTree)
        {
            var csr = new CodeScanResult();

            var compDict = new Dictionary <string, ResolveResult>();

            // Step 1: Enum all existing type id's that shall become resolved'n displayed
            var typeObjects = CodeScanner.ScanForTypeIdentifiers(SyntaxTree);

            foreach (var o in typeObjects)
            {
                if (o == null)
                {
                    continue;
                }

                #region Identifier Declarations
                if (o is IdentifierDeclaration)
                {
                    HandleIdDeclaration(o as IdentifierDeclaration,
                                        lastResCtxt,
                                        SyntaxTree,
                                        csr,
                                        compDict);
                }
                #endregion

                /*
                 #region Method call check
                 * else if (o is PostfixExpression_MethodCall)
                 * {
                 * var mc=o as PostfixExpression_MethodCall;
                 *
                 * int argc = mc.ArgumentCount;
                 *
                 * var methodOverloads=HandleIdDeclaration(mc.ExpressionTypeRepresentation as IdentifierDeclaration,
                 *      lastResCtxt,
                 *      SyntaxTree,
                 *      csr,
                 *      compDict);
                 *
                 * // Important: Also check template parameters and arguments!
                 * IExpression[] TemplateArguments=null;
                 *
                 * if (mc.PostfixForeExpression is TemplateInstanceExpression)
                 *      TemplateArguments = (mc.PostfixForeExpression as TemplateInstanceExpression).Arguments;
                 *
                 * int TemplateArgCount = TemplateArguments == null ? 0 : TemplateArguments.Length;
                 *
                 * // Note: If no method members were found, we already show the semantic error as a generically missing symbol
                 * if (methodOverloads != null)
                 * {
                 *      var l1 = new List<DMethod>();
                 *      var l2 = new List<DMethod>();
                 *
                 #region First add all available method overloads
                 *      foreach (var rr_ in methodOverloads)
                 *      {
                 *              // Like every time, remove unnecessary aliasing
                 *              var rr = DResolver.TryRemoveAliasesFromResult(rr_);
                 *
                 *              // Can be either 1) a normal method OR 2) a type related opCall
                 *
                 *              // 1)
                 *              if (rr is MemberResult)
                 *              {
                 *                      var mr = rr as MemberResult;
                 *
                 *                      //FIXME: What about delegate aliases'n stuff?
                 *                      if (!(mr.ResolvedMember is DMethod))
                 *                              continue;
                 *
                 *                      var dm = mr.ResolvedMember as DMethod;
                 *
                 *                      // Even before checking argument types etc, pre-select possibly chosen overloads
                 *                      // by comparing the method's parameter count with the call's argument count
                 *                      if (dm.Parameters.Count == argc && (dm.TemplateParameters==null?true:
                 *                              dm.TemplateParameters.Length==TemplateArgCount))
                 *                              l1.Add(dm);
                 *              }
                 *
                 *              // 2)
                 *              else if (rr is TypeResult)
                 *              {
                 *                      var tr = rr as TypeResult;
                 *
                 *                      // Scan the type for opCall members
                 *                      var opCalls=DResolver.ScanNodeForIdentifier(tr.ResolvedTypeDefinition, "opCall", lastResCtxt);
                 *
                 *                      if (opCalls != null)
                 *                              foreach (var n in opCalls)
                 *                              {
                 *                                      var dm = n as DMethod;
                 *
                 *                                      // Also pre-filter opCall members by param count comparison
                 *                                      if (dm!=null &&
                 *                                              dm.Parameters.Count == argc && (dm.TemplateParameters == null ? true :
                 *                                              dm.TemplateParameters.Length == TemplateArgCount))
                 *                                              l1.Add(dm);
                 *                              }
                 *              }
                 *      }
                 #endregion
                 *
                 *      // Must be a semantic error - no method fits in any way
                 *      if(l1.Count<1)
                 *      {
                 *              csr.ParameterActions.Add(o as IExpression, null);
                 *              continue;
                 *      }
                 *
                 *      // Compare template arguments first
                 * }
                 * }
                 #endregion
                 */
            }

            return(csr);
        }
Example #3
0
        static ResolveResult[] HandleIdDeclaration(IdentifierDeclaration typeId,
			ResolverContext lastResCtxt,
			IAbstractSyntaxTree SyntaxTree,
			CodeScanResult csr, 
			Dictionary<string, ResolveResult> compDict)
        {
            var typeString = typeId.ToString();

            bool WasAlreadyResolved = false;
            ResolveResult[] allCurrentResults = null;
            ResolveResult rr = null;

            /*
             * string,wstring,dstring are highlighted by the editor's syntax definition automatically..
             * Anyway, allow to resolve e.g. "object.string"
             */
            if (typeString == "" || typeString == "string" || typeString == "wstring" || typeString == "dstring")
                return null;

            lastResCtxt.ScopedBlock = DResolver.SearchBlockAt(SyntaxTree, typeId.Location, out lastResCtxt.ScopedStatement);
            if (typeString == "th" && typeId.Location.Line == 114)
            {

            }
            if (!(WasAlreadyResolved = compDict.TryGetValue(typeString, out rr)))
            {
                allCurrentResults = DResolver.ResolveType(typeId, lastResCtxt);

                if (allCurrentResults != null && allCurrentResults.Length > 0)
                    rr = allCurrentResults[0];
            }

            if (rr == null)
            {
                if (typeId is IdentifierDeclaration)
                    csr.UnresolvedIdentifiers.Add(typeId as IdentifierDeclaration);
            }
            else
            {
                /*
                 * Note: It is of course possible to highlight more than one type in one type declaration!
                 * So, we scan down the result hierarchy for TypeResults and highlight all of them later.
                 */
                var curRes = rr;

                /*
                 * Note: Since we want to use results multiple times,
                 * we at least have to 'update' their type declarations
                 * to ensure that the second, third, fourth etc. occurence of this result
                 * are also highlit (and won't(!) cause an Already-Added-Exception of our finalDict-Array)
                 */
                var curTypeDeclBase = typeId as ITypeDeclaration;

                while (curRes != null)
                {
                    if (curRes is MemberResult)
                    {
                        var mr = curRes as MemberResult;

                        // If curRes is an alias or a template parameter, highlight it
                        if (mr.ResolvedMember is TemplateParameterNode ||
                            (mr.ResolvedMember is DVariable &&
                            (mr.ResolvedMember as DVariable).IsAlias))
                        {
                            try
                            {
                                csr.ResolvedIdentifiers.Add(curTypeDeclBase as IdentifierDeclaration, curRes);
                            }
                            catch { }

                            // See performance reasons
                            //if (curRes != rr && !WasAlreadyResolved && !) compDict.Add(curTypeDeclBase.ToString(), curRes);
                        }
                    }

                    else if (curRes is TypeResult)
                    {
                        // Yeah, in quite all cases we do identify a class via its name ;-)
                        if (curTypeDeclBase is IdentifierDeclaration &&
                            !(curTypeDeclBase is DTokenDeclaration) &&
                            !csr.ResolvedIdentifiers.ContainsKey(curTypeDeclBase as IdentifierDeclaration))
                        {
                            csr.ResolvedIdentifiers.Add(curTypeDeclBase as IdentifierDeclaration, curRes);

                            // See performance reasons
                            //if (curRes != rr && !WasAlreadyResolved) compDict.Add(curTypeDeclBase.ToString(), curRes);
                        }
                    }

                    else if (curRes is ModuleResult)
                    {
                        if (curTypeDeclBase is IdentifierDeclaration &&
                            !csr.ResolvedIdentifiers.ContainsKey(curTypeDeclBase as IdentifierDeclaration))
                            csr.ResolvedIdentifiers.Add(curTypeDeclBase as IdentifierDeclaration, curRes);
                    }

                    curRes = curRes.ResultBase;
                    curTypeDeclBase = curTypeDeclBase.InnerDeclaration;
                }
            }
            return allCurrentResults;
        }
Example #4
0
        static ResolveResult[] HandleIdDeclaration(IdentifierDeclaration typeId,
                                                   ResolverContext lastResCtxt,
                                                   IAbstractSyntaxTree SyntaxTree,
                                                   CodeScanResult csr,
                                                   Dictionary <string, ResolveResult> compDict)
        {
            var typeString = typeId.ToString();

            bool WasAlreadyResolved = false;

            ResolveResult[] allCurrentResults = null;
            ResolveResult   rr = null;

            /*
             * string,wstring,dstring are highlighted by the editor's syntax definition automatically..
             * Anyway, allow to resolve e.g. "object.string"
             */
            if (typeString == "" || typeString == "string" || typeString == "wstring" || typeString == "dstring")
            {
                return(null);
            }

            lastResCtxt.ScopedBlock = DResolver.SearchBlockAt(SyntaxTree, typeId.Location, out lastResCtxt.ScopedStatement);
            if (typeString == "th" && typeId.Location.Line == 114)
            {
            }
            if (!(WasAlreadyResolved = compDict.TryGetValue(typeString, out rr)))
            {
                allCurrentResults = DResolver.ResolveType(typeId, lastResCtxt);

                if (allCurrentResults != null && allCurrentResults.Length > 0)
                {
                    rr = allCurrentResults[0];
                }
            }

            if (rr == null)
            {
                if (typeId is IdentifierDeclaration)
                {
                    csr.UnresolvedIdentifiers.Add(typeId as IdentifierDeclaration);
                }
            }
            else
            {
                /*
                 * Note: It is of course possible to highlight more than one type in one type declaration!
                 * So, we scan down the result hierarchy for TypeResults and highlight all of them later.
                 */
                var curRes = rr;

                /*
                 * Note: Since we want to use results multiple times,
                 * we at least have to 'update' their type declarations
                 * to ensure that the second, third, fourth etc. occurence of this result
                 * are also highlit (and won't(!) cause an Already-Added-Exception of our finalDict-Array)
                 */
                var curTypeDeclBase = typeId as ITypeDeclaration;

                while (curRes != null)
                {
                    if (curRes is MemberResult)
                    {
                        var mr = curRes as MemberResult;

                        // If curRes is an alias or a template parameter, highlight it
                        if (mr.ResolvedMember is TemplateParameterNode ||
                            (mr.ResolvedMember is DVariable &&
                             (mr.ResolvedMember as DVariable).IsAlias))
                        {
                            try
                            {
                                csr.ResolvedIdentifiers.Add(curTypeDeclBase as IdentifierDeclaration, curRes);
                            }
                            catch { }

                            // See performance reasons
                            //if (curRes != rr && !WasAlreadyResolved && !) compDict.Add(curTypeDeclBase.ToString(), curRes);
                        }
                    }

                    else if (curRes is TypeResult)
                    {
                        // Yeah, in quite all cases we do identify a class via its name ;-)
                        if (curTypeDeclBase is IdentifierDeclaration &&
                            !(curTypeDeclBase is DTokenDeclaration) &&
                            !csr.ResolvedIdentifiers.ContainsKey(curTypeDeclBase as IdentifierDeclaration))
                        {
                            csr.ResolvedIdentifiers.Add(curTypeDeclBase as IdentifierDeclaration, curRes);

                            // See performance reasons
                            //if (curRes != rr && !WasAlreadyResolved) compDict.Add(curTypeDeclBase.ToString(), curRes);
                        }
                    }

                    else if (curRes is ModuleResult)
                    {
                        if (curTypeDeclBase is IdentifierDeclaration &&
                            !csr.ResolvedIdentifiers.ContainsKey(curTypeDeclBase as IdentifierDeclaration))
                        {
                            csr.ResolvedIdentifiers.Add(curTypeDeclBase as IdentifierDeclaration, curRes);
                        }
                    }

                    curRes          = curRes.ResultBase;
                    curTypeDeclBase = curTypeDeclBase.InnerDeclaration;
                }
            }
            return(allCurrentResults);
        }