// ********************************************************************************************************************************

        /// <summary>
        /// Gets a list of patterns that can be searched for in the specified file
        /// to find possible resource references that are supported by this
        /// resolver.
        /// </summary>
        /// <param name="fileName">The name of the file to get a list of possible patterns for.</param>
        public IEnumerable <string> GetPossiblePatternsForFile(string fileName)
        {
            return(new string[] {
                "GetString",
                "GetObject",
                "GetStream",
                "ApplyResources",
                (NRefactoryResourceResolver.GetLanguagePropertiesForFile(fileName) ?? LanguageProperties.None).IndexerExpressionStartToken
            });
        }
        /// <summary>
        /// Tries to determine the resource set which is referenced by the
        /// resource manager which is assigned to the specified member.
        /// </summary>
        /// <param name="member">The referenced member to examine.</param>
        /// <returns>
        /// The ResourceSetReference, if successful, or a null reference, if the
        /// specified member is not a resource manager or if the
        /// resource file cannot be determined.
        /// </returns>
        static ResourceSetReference ResolveResourceSet(IMember member)
        {
            if (member != null && member.ReturnType != null &&
                member.DeclaringType != null && member.DeclaringType.CompilationUnit != null)
            {
                ResourceSetReference rsr;
                if (!NRefactoryAstCacheService.CacheEnabled || !cachedResourceSetReferenceMappings.TryGetValue(member, out rsr))
                {
                    string declaringFileName = member.DeclaringType.CompilationUnit.FileName;
                    if (declaringFileName != null)
                    {
                        if (IsResourceManager(member.ReturnType, declaringFileName))
                        {
                            SupportedLanguage?language = NRefactoryResourceResolver.GetFileLanguage(declaringFileName);
                            if (language == null)
                            {
                                return(null);
                            }

                            CompilationUnit cu = NRefactoryAstCacheService.GetFullAst(language.Value, declaringFileName, ResourceResolverService.GetParsableFileContent(declaringFileName));
                            if (cu != null)
                            {
                                ResourceManagerInitializationFindVisitor visitor = new ResourceManagerInitializationFindVisitor(member);
                                cu.AcceptVisitor(visitor, null);
                                if (visitor.FoundResourceSet != null)
                                {
                                    rsr = visitor.FoundResourceSet;

                                    if (NRefactoryAstCacheService.CacheEnabled)
                                    {
                                        cachedResourceSetReferenceMappings.Add(member, rsr);
                                    }

                                    return(rsr);
                                }
                            }
                        }
                    }

                    return(null);
                }

                return(rsr);
            }
            return(null);
        }
예제 #3
0
        // ********************************************************************************************************************************

        /// <summary>
        /// Parses an expression with NRefactory.
        /// </summary>
        /// <param name="fileName">The file name of the source code file that contains the expression.</param>
        /// <param name="expression">The expression to parse.</param>
        /// <param name="caretLine">The 1-based line number of the expression.</param>
        /// <param name="caretColumn">The 1-based column number of the expression.</param>
        /// <returns>The parsed expression or <c>null</c> if the expression cannot be parsed or the language of the source code file is not supported.</returns>
        public static Expression ParseExpression(string fileName, string expression, int caretLine, int caretColumn)
        {
            SupportedLanguage?l = NRefactoryResourceResolver.GetFileLanguage(fileName);

            if (l == null)
            {
                return(null);
            }

            using (ICSharpCode.NRefactory.IParser p = ICSharpCode.NRefactory.ParserFactory.CreateParser(l.Value, new System.IO.StringReader(expression))) {
                Expression expr = p.ParseExpression();
                if (expr != null)
                {
                    expr.AcceptVisitor(new SetAllNodePointsAstVisitor(new Location(caretColumn, caretLine), new Location(caretColumn + 1, caretLine)), null);
                }
                return(expr);
            }
        }
            public override object TrackedVisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
            {
                if (data as bool? ?? false)
                {
                                        #if DEBUG
                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found object initialization: " + objectCreateExpression.ToString());
                                        #endif

                    // Resolve the constructor.
                    // A type derived from the declaration type is also allowed.
                    MemberResolveResult mrr = this.Resolve(objectCreateExpression) as MemberResolveResult;

                                        #if DEBUG
                    if (mrr != null)
                    {
                        LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: resolved constructor: " + mrr.ResolvedMember.ToString());
                    }
                                        #endif

                    if (mrr != null &&
                        mrr.ResolvedMember is IMethod &&
                        (mrr.ResolvedMember.DeclaringType.CompareTo(this.resourceManagerMember.ReturnType.GetUnderlyingClass()) == 0 ||
                         mrr.ResolvedMember.DeclaringType.IsTypeInInheritanceTree(this.resourceManagerMember.ReturnType.GetUnderlyingClass()))
                        )
                    {
                                                #if DEBUG
                        LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: This is the correct constructor.");
                                                #endif

                        // This most probably is the resource manager initialization we are looking for.
                        // Find a parameter that indicates the resources being referenced.

                        foreach (Expression param in objectCreateExpression.Parameters)
                        {
                            PrimitiveExpression p = param as PrimitiveExpression;
                            if (p != null)
                            {
                                string pValue = p.Value as string;
                                if (!String.IsNullOrEmpty(pValue))
                                {
                                                                        #if DEBUG
                                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found string parameter: '" + pValue + "'");
                                                                        #endif

                                    this.foundResourceSet = NRefactoryResourceResolver.GetResourceSetReference(this.resourceManagerMember.DeclaringType.CompilationUnit.FileName, pValue);
                                                                        #if DEBUG
                                    if (this.foundResourceSet.FileName != null)
                                    {
                                        LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found resource file: " + this.foundResourceSet.FileName);
                                    }
                                                                        #endif

                                    break;
                                }

                                continue;
                            }

                            // Support typeof(...)
                            TypeOfExpression t = param as TypeOfExpression;
                            if (t != null && this.PositionAvailable)
                            {
                                                                #if DEBUG
                                LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: Found TypeOfExpression in constructor call: " + t.ToString());
                                                                #endif

                                ResolveResult rr = this.Resolve(new TypeReferenceExpression(t.TypeReference), ExpressionContext.Type);

                                                                #if DEBUG
                                if (rr == null)
                                {
                                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: The TypeReference of the TypeOfExpression could not be resolved.");
                                }
                                else
                                {
                                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: The TypeReference resolved to: " + rr.ToString());
                                }
                                                                #endif

                                if (rr != null)
                                {
                                                                        #if DEBUG
                                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found typeof(...) parameter, type: '" + rr.ResolvedType.ToString() + "'");
                                                                        #endif

                                    this.foundResourceSet = NRefactoryResourceResolver.GetResourceSetReference(this.resourceManagerMember.DeclaringType.CompilationUnit.FileName, rr.ResolvedType.FullyQualifiedName);
                                                                        #if DEBUG
                                    if (this.foundResourceSet.FileName != null)
                                    {
                                        LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found resource file: " + this.foundResourceSet.FileName);
                                    }
                                                                        #endif

                                    break;
                                }
                            }
                        }
                    }
                }

                return(base.TrackedVisitObjectCreateExpression(objectCreateExpression, data));
            }
        /// <summary>
        /// Tries to find a resource reference in the specified expression.
        /// </summary>
        /// <param name="expressionResult">The ExpressionResult for the expression.</param>
        /// <param name="expr">The AST representation of the full expression.</param>
        /// <param name="resolveResult">SharpDevelop's ResolveResult for the expression.</param>
        /// <param name="caretLine">The 0-based line where the expression is located.</param>
        /// <param name="caretColumn">The 0-based column where the expression is located.</param>
        /// <param name="fileName">The name of the source file where the expression is located.</param>
        /// <param name="fileContent">The content of the source file where the expression is located.</param>
        /// <param name="expressionFinder">The ExpressionFinder for the file.</param>
        /// <param name="charTyped">The character that has been typed at the caret position but is not yet in the buffer (this is used when invoked from code completion), or <c>null</c>.</param>
        /// <returns>A ResourceResolveResult describing the referenced resource, or <c>null</c>, if this expression does not reference a resource using the standard .NET framework classes.</returns>
        public ResourceResolveResult Resolve(ExpressionResult expressionResult, Expression expr, ResolveResult resolveResult, int caretLine, int caretColumn, string fileName, string fileContent, IExpressionFinder expressionFinder, char?charTyped)
        {
            /*
             * We need to catch the following cases here:
             *
             * Something.GetString(
             * Something.GetString("...")
             * Something.ApplyResources(obj, "...")
             * Something[
             * Something["..."]
             *
             */

            if (charTyped == '(')
            {
                // Something.GetString
                // This is a MethodResolveResult and we need the reference to "Something",
                // which is the next outer expression.
                // This is only valid when invoked from code completion
                // and the method invocation character ('(' in C# and VB)
                // has been typed.

                // This code is also reused when reducing a complete InvocationExpression
                // (MemberResolveResult) to the method reference by passing '(' as
                // charTyped explicitly.

                MethodGroupResolveResult methrr = resolveResult as MethodGroupResolveResult;
                if (methrr != null)
                {
                    if ((methrr.Name == "GetString" || methrr.Name == "GetObject" || methrr.Name == "GetStream" || methrr.Name == "ApplyResources") &&
                        (resolveResult = NRefactoryAstCacheService.ResolveNextOuterExpression(ref expressionResult, caretLine, caretColumn, fileName, fileContent, expressionFinder)) != null)
                    {
                        return(ResolveResource(resolveResult, expr));
                    }
                    else
                    {
                        return(null);
                    }
                }
            }

            // Do not use "else if" here.
            // '(' is also the IndexerExpressionStartToken for VB,
            // so the "else" block further down might still apply.

            if (charTyped == null)
            {
                // A MemberResolveResult with a complete expression
                // must only be considered a valid resource reference
                // when Resolve is not invoked from code completion
                // (i.e. charTyped == null) because this indicates
                // that the resource reference is already before the typed character
                // and we are not interested in the following expression.
                // This may happen when typing something like:
                // Something.GetString("...")[

                MemberResolveResult mrr = resolveResult as MemberResolveResult;
                if (mrr != null)
                {
                    if (mrr.ResolvedMember is IMethod &&
                        (mrr.ResolvedMember.Name == "GetString" || mrr.ResolvedMember.Name == "GetObject" || mrr.ResolvedMember.Name == "GetStream" || mrr.ResolvedMember.Name == "ApplyResources"))
                    {
                        // Something.GetString("...")
                        // This is a MemberResolveResult and we need the reference to "Something".
                        // The expression finder may only remove the string literal, so
                        // we have to call Resolve again in this case to resolve
                        // the method reference.

                        if ((resolveResult = NRefactoryAstCacheService.ResolveNextOuterExpression(ref expressionResult, caretLine, caretColumn, fileName, fileContent, expressionFinder)) != null)
                        {
                            if (resolveResult is MethodGroupResolveResult)
                            {
                                return(this.Resolve(expressionResult, expr, resolveResult, caretLine, caretColumn, fileName, fileContent, expressionFinder, '('));
                            }
                            else
                            {
                                return(ResolveResource(resolveResult, expr));
                            }
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    else if (expr is IndexerExpression &&
                             IsResourceManager(mrr.ResolvedMember.DeclaringType.DefaultReturnType, fileName))
                    {
                        // Something["..."] is an IndexerExpression.
                        // We need the reference to Something and this is
                        // the next outer expression.

                        if ((resolveResult = NRefactoryAstCacheService.ResolveNextOuterExpression(ref expressionResult, caretLine, caretColumn, fileName, fileContent, expressionFinder)) != null)
                        {
                            return(ResolveResource(resolveResult, expr));
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }
            }
            else
            {
                // This request is triggered from code completion.
                // The only case that has not been caught above is:
                // Something[
                // The reference to "Something" is already in this expression.
                // So we have to test the trigger character against the
                // indexer expression start token of the file's language.

                LanguageProperties lp = NRefactoryResourceResolver.GetLanguagePropertiesForFile(fileName);
                if (lp != null &&
                    !String.IsNullOrEmpty(lp.IndexerExpressionStartToken) &&
                    lp.IndexerExpressionStartToken[0] == charTyped)
                {
                                        #if DEBUG
                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: Indexer expression start typed, ResolveResult: " + resolveResult.ToString());
                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: -> Expression: " + expr.ToString());
                                        #endif

                    return(ResolveResource(resolveResult, expr));
                }
            }

            return(null);
        }