diff --git a/src/AddIns/Misc/ResourceToolkit/Project/ResourceToolkit.csproj b/src/AddIns/Misc/ResourceToolkit/Project/ResourceToolkit.csproj
index 9c1eab1832..6639d8c2c7 100644
--- a/src/AddIns/Misc/ResourceToolkit/Project/ResourceToolkit.csproj
+++ b/src/AddIns/Misc/ResourceToolkit/Project/ResourceToolkit.csproj
@@ -147,4 +147,4 @@
-
+
\ No newline at end of file
diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/BclNRefactoryResourceResolver.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/BclNRefactoryResourceResolver.cs
index 9f6b1cf6e4..93dfea0995 100644
--- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/BclNRefactoryResourceResolver.cs
+++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/BclNRefactoryResourceResolver.cs
@@ -66,7 +66,7 @@ namespace Hornung.ResourceToolkit.Resolver
MethodGroupResolveResult methrr = resolveResult as MethodGroupResolveResult;
if (methrr != null) {
if ((methrr.Name == "GetString" || methrr.Name == "GetObject" || methrr.Name == "GetStream") &&
- (resolveResult = NRefactoryAstCacheService.ResolveNextOuterExpression(ref expressionResult, caretLine, caretColumn, fileName, expressionFinder)) != null) {
+ (resolveResult = NRefactoryAstCacheService.ResolveNextOuterExpression(ref expressionResult, caretLine, caretColumn, fileName, fileContent, expressionFinder)) != null) {
return ResolveResource(resolveResult, expr);
@@ -106,7 +106,7 @@ namespace Hornung.ResourceToolkit.Resolver
// we have to call Resolve again in this case to resolve
// the method reference.
- if ((resolveResult = NRefactoryAstCacheService.ResolveNextOuterExpression(ref expressionResult, caretLine, caretColumn, fileName, expressionFinder)) != null) {
+ 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, '(');
@@ -127,7 +127,7 @@ namespace Hornung.ResourceToolkit.Resolver
// We need the reference to Something and this is
// the next outer expression.
- if ((resolveResult = NRefactoryAstCacheService.ResolveNextOuterExpression(ref expressionResult, caretLine, caretColumn, fileName, expressionFinder)) != null) {
+ if ((resolveResult = NRefactoryAstCacheService.ResolveNextOuterExpression(ref expressionResult, caretLine, caretColumn, fileName, fileContent, expressionFinder)) != null) {
return ResolveResource(resolveResult, expr);
} else {
return null;
@@ -252,7 +252,7 @@ namespace Hornung.ResourceToolkit.Resolver
return null;
}
- CompilationUnit cu = NRefactoryAstCacheService.GetFullAst(language.Value, declaringFileName);
+ CompilationUnit cu = NRefactoryAstCacheService.GetFullAst(language.Value, declaringFileName, ResourceResolverService.GetParsableFileContent(declaringFileName));
if (cu != null) {
ResourceManagerInitializationFindVisitor visitor = new ResourceManagerInitializationFindVisitor(member);
@@ -297,7 +297,7 @@ namespace Hornung.ResourceToolkit.Resolver
if (p == null) {
pc = ParserService.CurrentProjectContent;
} else {
- pc = ParserService.GetProjectContent(p);
+ pc = ResourceResolverService.GetProjectContent(p);
}
if (pc == null) {
@@ -352,7 +352,8 @@ namespace Hornung.ResourceToolkit.Resolver
/// Initializes a new instance of the class.
///
/// The member which the resource manager to be found is assigned to.
- public ResourceManagerInitializationFindVisitor(IMember resourceManagerMember) : base()
+ public ResourceManagerInitializationFindVisitor(IMember resourceManagerMember)
+ : base(resourceManagerMember.DeclaringType.CompilationUnit.FileName, ResourceResolverService.GetParsableFileContent(resourceManagerMember.DeclaringType.CompilationUnit.FileName))
{
this.resourceManagerMember = resourceManagerMember;
IField resourceManagerField = resourceManagerMember as IField;
@@ -446,7 +447,7 @@ namespace Hornung.ResourceToolkit.Resolver
) {
IMember resolvedMember = null;
- ResolveResult rr = this.Resolve(assignmentExpression.Left, this.resourceManagerMember.DeclaringType.CompilationUnit.FileName);
+ ResolveResult rr = this.Resolve(assignmentExpression.Left);
if (rr != null) {
// Support both local variables and member variables
MemberResolveResult mrr = rr as MemberResolveResult;
@@ -497,7 +498,7 @@ namespace Hornung.ResourceToolkit.Resolver
} else if (this.resourceManagerMember is IField && resolvedMember is IProperty) {
// Find out if the resolved member is a property whose set block assigns the value to the resourceManagerMember.
- PropertyFieldAssociationVisitor visitor = new PropertyFieldAssociationVisitor((IField)this.resourceManagerMember);
+ PropertyFieldAssociationVisitor visitor = new PropertyFieldAssociationVisitor((IField)this.resourceManagerMember, this.FileName, this.FileContent);
this.compilationUnit.AcceptVisitor(visitor, null);
if (visitor.AssociatedProperty != null && visitor.AssociatedProperty.CompareTo(resolvedMember) == 0) {
#if DEBUG
@@ -534,7 +535,7 @@ namespace Hornung.ResourceToolkit.Resolver
if (prop != null) {
// Resolve the property association.
- PropertyFieldAssociationVisitor visitor = new PropertyFieldAssociationVisitor(prop);
+ PropertyFieldAssociationVisitor visitor = new PropertyFieldAssociationVisitor(prop, this.FileName, this.FileContent);
this.compilationUnit.AcceptVisitor(visitor, null);
// Store the association in the instance field.
@@ -555,7 +556,7 @@ namespace Hornung.ResourceToolkit.Resolver
// Resolve the constructor.
// A type derived from the declaration type is also allowed.
- MemberResolveResult mrr = this.Resolve(objectCreateExpression, this.resourceManagerMember.DeclaringType.CompilationUnit.FileName) as MemberResolveResult;
+ MemberResolveResult mrr = this.Resolve(objectCreateExpression) as MemberResolveResult;
#if DEBUG
if (mrr != null) {
@@ -609,7 +610,7 @@ namespace Hornung.ResourceToolkit.Resolver
LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: Found TypeOfExpression in constructor call: " + t.ToString());
#endif
- ResolveResult rr = this.Resolve(new TypeReferenceExpression(t.TypeReference), this.resourceManagerMember.DeclaringType.CompilationUnit.FileName, ExpressionContext.Type);
+ ResolveResult rr = this.Resolve(new TypeReferenceExpression(t.TypeReference), ExpressionContext.Type);
#if DEBUG
if (rr == null) {
diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreResourceResolver.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreResourceResolver.cs
index 52f71f79a7..934592f34d 100644
--- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreResourceResolver.cs
+++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreResourceResolver.cs
@@ -41,7 +41,7 @@ namespace Hornung.ResourceToolkit.Resolver
public override bool SupportsFile(string fileName)
{
// Any parseable source code file may contain references
- if (ICSharpCode.SharpDevelop.ParserService.GetParser(fileName) != null) {
+ if (ResourceResolverService.GetParser(fileName) != null) {
return true;
}
diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/NRefactoryAstCacheService.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/NRefactoryAstCacheService.cs
index 97f57c24db..f34e8dacb6 100644
--- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/NRefactoryAstCacheService.cs
+++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/NRefactoryAstCacheService.cs
@@ -75,11 +75,13 @@ namespace Hornung.ResourceToolkit.Resolver
///
public static void DisableCache()
{
- cacheEnabled = false;
- cachedAstInfo.Clear();
- cachedMemberMappings.Clear();
- LoggingService.Info("ResourceToolkit: NRefactoryAstCacheService cache disabled and cleared");
- OnCacheEnabledChanged(EventArgs.Empty);
+ if (CacheEnabled) {
+ cacheEnabled = false;
+ cachedAstInfo.Clear();
+ cachedMemberMappings.Clear();
+ LoggingService.Info("ResourceToolkit: NRefactoryAstCacheService cache disabled and cleared");
+ OnCacheEnabledChanged(EventArgs.Empty);
+ }
}
///
@@ -87,13 +89,14 @@ namespace Hornung.ResourceToolkit.Resolver
///
/// The language of the file.
/// The file to get the AST for.
+ /// The content of the file to get the AST for.
/// A that contains the AST for the specified file, or null if the file cannot be parsed.
/// Between calls to and the file is parsed only once. On subsequent accesses the AST is retrieved from the cache.
- public static CompilationUnit GetFullAst(SupportedLanguage language, string fileName)
+ public static CompilationUnit GetFullAst(SupportedLanguage language, string fileName, string fileContent)
{
CompilationUnit cu;
if (!CacheEnabled || !cachedAstInfo.TryGetValue(fileName, out cu)) {
- cu = Parse(language, fileName);
+ cu = Parse(language, fileName, fileContent);
if (cu != null && CacheEnabled) {
cachedAstInfo.Add(fileName, cu);
}
@@ -101,9 +104,9 @@ namespace Hornung.ResourceToolkit.Resolver
return cu;
}
- static CompilationUnit Parse(SupportedLanguage language, string fileName)
+ static CompilationUnit Parse(SupportedLanguage language, string fileName, string fileContent)
{
- using(ICSharpCode.NRefactory.IParser parser = ParserFactory.CreateParser(language, new StringReader(ParserService.GetParseableFileContent(fileName)))) {
+ using(ICSharpCode.NRefactory.IParser parser = ParserFactory.CreateParser(language, new StringReader(fileContent))) {
if (parser != null) {
#if DEBUG
LoggingService.Debug("ResourceToolkit: NRefactoryAstCacheService: Parsing file '"+fileName+"'");
@@ -168,17 +171,18 @@ namespace Hornung.ResourceToolkit.Resolver
/// use of the cache if possible.
///
/// The file name of the source code file that contains the expression to be resolved.
+ /// The content of the source code file that contains the expression to be resolved.
/// The 1-based line number of the expression.
/// The 1-based column number of the expression.
/// The CompilationUnit that contains the NRefactory AST for this file. May be null (then the CompilationUnit is retrieved from the cache or the file is parsed).
/// The expression to be resolved.
/// The ExpressionContext of the expression.
/// A ResolveResult or null if the expression cannot be resolved.
- public static ResolveResult ResolveLowLevel(string fileName, int caretLine, int caretColumn, CompilationUnit compilationUnit, string expression, ExpressionContext context)
+ public static ResolveResult ResolveLowLevel(string fileName, string fileContent, int caretLine, int caretColumn, CompilationUnit compilationUnit, string expression, ExpressionContext context)
{
Expression expr = ParseExpression(fileName, expression, caretLine, caretColumn);
if (expr == null) return null;
- return ResolveLowLevel(fileName, caretLine, caretColumn, compilationUnit, expression, expr, context);
+ return ResolveLowLevel(fileName, fileContent, caretLine, caretColumn, compilationUnit, expression, expr, context);
}
///
@@ -186,6 +190,7 @@ namespace Hornung.ResourceToolkit.Resolver
/// use of the cache if possible.
///
/// The file name of the source code file that contains the expression to be resolved.
+ /// The content of the source code file that contains the expression to be resolved.
/// The 1-based line number of the expression.
/// The 1-based column number of the expression.
/// The CompilationUnit that contains the NRefactory AST for this file. May be null (then the CompilationUnit is retrieved from the cache or the file is parsed).
@@ -194,11 +199,14 @@ namespace Hornung.ResourceToolkit.Resolver
/// The ExpressionContext of the expression.
/// A ResolveResult or null if the expression cannot be resolved.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:AvoidTypeNamesInParameters", MessageId = "4#")]
- public static ResolveResult ResolveLowLevel(string fileName, int caretLine, int caretColumn, CompilationUnit compilationUnit, string expressionString, Expression expression, ExpressionContext context)
+ public static ResolveResult ResolveLowLevel(string fileName, string fileContent, int caretLine, int caretColumn, CompilationUnit compilationUnit, string expressionString, Expression expression, ExpressionContext context)
{
if (fileName == null) {
throw new ArgumentNullException("fileName");
}
+ if (fileContent == null) {
+ throw new ArgumentNullException("fileName");
+ }
if (expression == null) {
throw new ArgumentNullException("expression");
}
@@ -209,19 +217,19 @@ namespace Hornung.ResourceToolkit.Resolver
return null;
}
- IProjectContent pc = ParserService.GetProjectContent(p);
+ IProjectContent pc = ResourceResolverService.GetProjectContent(p);
if (pc == null) {
LoggingService.Info("ResourceToolkit: NRefactoryAstCacheService: ResolveLowLevel failed. ProjectContent is null for project '"+p.ToString()+"'");
return null;
}
- NRefactoryResolver resolver = ParserService.CreateResolver(fileName) as NRefactoryResolver;
+ NRefactoryResolver resolver = ResourceResolverService.CreateResolver(fileName) as NRefactoryResolver;
if (resolver == null) {
resolver = new NRefactoryResolver(LanguageProperties.CSharp);
}
if (compilationUnit == null) {
- compilationUnit = GetFullAst(resolver.Language, fileName);
+ compilationUnit = GetFullAst(resolver.Language, fileName, fileContent);
}
if (compilationUnit == null) {
LoggingService.Info("ResourceToolkit: NRefactoryAstCacheService: ResolveLowLevel failed due to the compilation unit being unavailable.");
@@ -280,14 +288,15 @@ namespace Hornung.ResourceToolkit.Resolver
/// The 0-based line number of the expression.
/// The 0-based column number of the expression.
/// The file name of the source code file that contains the expression to be resolved.
+ /// The content of the source code file that contains the expression to be resolved.
/// The ExpressionFinder for this source code file.
/// A ResolveResult or null if the outer expression cannot be resolved or if the specified expression is the outermost expression.
- public static ResolveResult ResolveNextOuterExpression(ref ExpressionResult expressionResult, int caretLine, int caretColumn, string fileName, IExpressionFinder expressionFinder)
+ public static ResolveResult ResolveNextOuterExpression(ref ExpressionResult expressionResult, int caretLine, int caretColumn, string fileName, string fileContent, IExpressionFinder expressionFinder)
{
if (!String.IsNullOrEmpty(expressionResult.Expression = expressionFinder.RemoveLastPart(expressionResult.Expression))) {
Expression nextExpression;
if ((nextExpression = ParseExpression(fileName, expressionResult.Expression, caretLine + 1, caretColumn + 1)) != null) {
- return ResolveLowLevel(fileName, caretLine + 1, caretColumn + 1, null, expressionResult.Expression, nextExpression, expressionResult.Context);
+ return ResolveLowLevel(fileName, fileContent, caretLine + 1, caretColumn + 1, null, expressionResult.Expression, nextExpression, expressionResult.Context);
}
}
return null;
diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/NRefactoryResourceResolver.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/NRefactoryResourceResolver.cs
index 76d72360d8..d44c38ebc3 100644
--- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/NRefactoryResourceResolver.cs
+++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/NRefactoryResourceResolver.cs
@@ -48,6 +48,11 @@ namespace Hornung.ResourceToolkit.Resolver
}
}
+ public static void SetResourceResolversListUnitTestOnly(IEnumerable resolversToSet)
+ {
+ resolvers = new List(resolversToSet);
+ }
+
// ********************************************************************************************************************************
///
@@ -106,7 +111,7 @@ namespace Hornung.ResourceToolkit.Resolver
/// A that describes which resource is referenced by the expression at the specified position in the specified file, or null if that expression does not reference a (known) resource.
protected override ResourceResolveResult Resolve(string fileName, IDocument document, int caretLine, int caretColumn, int caretOffset, char? charTyped)
{
- IExpressionFinder ef = ParserService.GetExpressionFinder(fileName);
+ IExpressionFinder ef = ResourceResolverService.GetExpressionFinder(fileName);
if (ef == null) {
return null;
}
@@ -152,7 +157,7 @@ namespace Hornung.ResourceToolkit.Resolver
///
static ResourceResolveResult TryResolve(ExpressionResult result, Expression expr, int caretLine, int caretColumn, string fileName, string fileContent, IExpressionFinder expressionFinder, char? charTyped)
{
- ResolveResult rr = NRefactoryAstCacheService.ResolveLowLevel(fileName, caretLine+1, caretColumn+1, null, result.Expression, expr, result.Context);
+ ResolveResult rr = NRefactoryAstCacheService.ResolveLowLevel(fileName, fileContent, caretLine+1, caretColumn+1, null, result.Expression, expr, result.Context);
if (rr != null) {
ResourceResolveResult rrr;
@@ -205,7 +210,7 @@ namespace Hornung.ResourceToolkit.Resolver
// Find all source files that contain a type with the same
// name as the resource we are looking for.
List possibleSourceFiles = new List();
- IProjectContent pc = ParserService.GetProjectContent(p);
+ IProjectContent pc = ResourceResolverService.GetProjectContent(p);
if (pc != null) {
IClass resourceClass = pc.GetClass(resourceName, 0);
@@ -449,7 +454,7 @@ namespace Hornung.ResourceToolkit.Resolver
/// The language properties of the specified file, or null if the language cannot be determined.
public static LanguageProperties GetLanguagePropertiesForFile(string fileName)
{
- ICSharpCode.SharpDevelop.Dom.IParser p = ParserService.GetParser(fileName);
+ ICSharpCode.SharpDevelop.Dom.IParser p = ResourceResolverService.GetParser(fileName);
if (p == null) {
return null;
}
diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/PositionTrackingAstVisitor.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/PositionTrackingAstVisitor.cs
index f7e8caae99..3585605f92 100644
--- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/PositionTrackingAstVisitor.cs
+++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/PositionTrackingAstVisitor.cs
@@ -20,8 +20,10 @@ namespace Hornung.ResourceToolkit.Resolver
///
public abstract class PositionTrackingAstVisitor : ICSharpCode.NRefactory.Visitors.NodeTrackingAstVisitor
{
+ readonly Stack parentNodes = new Stack();
- private Stack parentNodes;
+ readonly string fileName;
+ readonly string fileContent;
protected override void BeginVisit(INode node)
{
@@ -77,6 +79,14 @@ namespace Hornung.ResourceToolkit.Resolver
}
}
+ protected string FileName {
+ get { return fileName; }
+ }
+
+ protected string FileContent {
+ get { return fileContent; }
+ }
+
// ********************************************************************************************************************************
private CompilationUnit compilationUnit;
@@ -93,19 +103,17 @@ namespace Hornung.ResourceToolkit.Resolver
/// Resolves an expression in the current node's context.
///
/// The expression to be resolved.
- /// The file name of the source file that contains the expression to be resolved.
- public ResolveResult Resolve(Expression expression, string fileName)
+ public ResolveResult Resolve(Expression expression)
{
- return this.Resolve(expression, fileName, ExpressionContext.Default);
+ return this.Resolve(expression, ExpressionContext.Default);
}
///
/// Resolves an expression in the current node's context.
///
/// The expression to be resolved.
- /// The file name of the source file that contains the expression to be resolved.
/// The ExpressionContext.
- public ResolveResult Resolve(Expression expression, string fileName, ExpressionContext context)
+ public ResolveResult Resolve(Expression expression, ExpressionContext context)
{
if (!this.PositionAvailable) {
LoggingService.Info("ResourceToolkit: PositionTrackingAstVisitor: Resolve failed due to position information being unavailable. Expression: "+expression.ToString());
@@ -116,7 +124,7 @@ namespace Hornung.ResourceToolkit.Resolver
LoggingService.Debug("ResourceToolkit: PositionTrackingAstVisitor: Using this parent node for resolve: "+this.parentNodes.Peek().ToString());
#endif
- return NRefactoryAstCacheService.ResolveLowLevel(fileName, this.CurrentNodeStartLocation.Y, this.CurrentNodeStartLocation.X+1, this.compilationUnit, null, expression, context);
+ return NRefactoryAstCacheService.ResolveLowLevel(this.fileName, this.fileContent, this.CurrentNodeStartLocation.Y, this.CurrentNodeStartLocation.X+1, this.compilationUnit, null, expression, context);
}
// ********************************************************************************************************************************
@@ -124,9 +132,18 @@ namespace Hornung.ResourceToolkit.Resolver
///
/// Initializes a new instance of the class.
///
- protected PositionTrackingAstVisitor() : base()
+ protected PositionTrackingAstVisitor(string fileName, string fileContent)
+ : base()
{
- this.parentNodes = new Stack();
+ if (fileName == null) {
+ throw new ArgumentNullException("fileName");
+ }
+ if (fileContent == null) {
+ throw new ArgumentNullException("fileContent");
+ }
+
+ this.fileName = fileName;
+ this.fileContent = fileContent;
}
}
}
diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/PropertyFieldAssociationVisitor.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/PropertyFieldAssociationVisitor.cs
index 280d2c2c1f..762b36759f 100644
--- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/PropertyFieldAssociationVisitor.cs
+++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/PropertyFieldAssociationVisitor.cs
@@ -115,7 +115,10 @@ namespace Hornung.ResourceToolkit.Resolver
}
// Resolve the expression.
- MemberResolveResult mrr = this.Resolve(expr, this.memberToFind.DeclaringType.CompilationUnit.FileName) as MemberResolveResult;
+ if (!FileUtility.IsEqualFileName(this.FileName, this.memberToFind.DeclaringType.CompilationUnit.FileName)) {
+ throw new InvalidOperationException("The PropertyFieldAssociationVisitor does currently not support the case that the field is declared in a different file than the property.");
+ }
+ MemberResolveResult mrr = this.Resolve(expr) as MemberResolveResult;
if (mrr != null && mrr.ResolvedMember is IField) {
PropertyDeclaration pd;
@@ -138,7 +141,7 @@ namespace Hornung.ResourceToolkit.Resolver
if (this.memberToFind.CompareTo(mrr.ResolvedMember) == 0) {
// Resolve the property.
- MemberResolveResult prr = NRefactoryAstCacheService.ResolveLowLevel(this.memberToFind.DeclaringType.CompilationUnit.FileName, pd.StartLocation.Y, pd.StartLocation.X+1, null, pd.Name, ExpressionContext.Default) as MemberResolveResult;
+ MemberResolveResult prr = NRefactoryAstCacheService.ResolveLowLevel(this.FileName, this.FileContent, pd.StartLocation.Y, pd.StartLocation.X+1, null, pd.Name, ExpressionContext.Default) as MemberResolveResult;
if (prr != null) {
#if DEBUG
@@ -174,7 +177,10 @@ namespace Hornung.ResourceToolkit.Resolver
assignmentExpression.Op == AssignmentOperatorType.Assign && data != null) {
// Resolve the expression.
- MemberResolveResult mrr = this.Resolve(assignmentExpression.Left, this.memberToFind.DeclaringType.CompilationUnit.FileName) as MemberResolveResult;
+ if (!FileUtility.IsEqualFileName(this.FileName, this.memberToFind.DeclaringType.CompilationUnit.FileName)) {
+ throw new InvalidOperationException("The PropertyFieldAssociationVisitor does currently not support the case that the field is declared in a different file than the property.");
+ }
+ MemberResolveResult mrr = this.Resolve(assignmentExpression.Left) as MemberResolveResult;
if (mrr != null && mrr.ResolvedMember is IField && !((IField)mrr.ResolvedMember).IsLocalVariable) {
PropertyDeclaration pd;
@@ -197,7 +203,7 @@ namespace Hornung.ResourceToolkit.Resolver
if (this.memberToFind.CompareTo(mrr.ResolvedMember) == 0) {
// Resolve the property.
- MemberResolveResult prr = NRefactoryAstCacheService.ResolveLowLevel(this.memberToFind.DeclaringType.CompilationUnit.FileName, pd.StartLocation.Y, pd.StartLocation.X+1, null, pd.Name, ExpressionContext.Default) as MemberResolveResult;
+ MemberResolveResult prr = NRefactoryAstCacheService.ResolveLowLevel(this.FileName, this.FileContent, pd.StartLocation.Y, pd.StartLocation.X+1, null, pd.Name, ExpressionContext.Default) as MemberResolveResult;
if (prr != null) {
#if DEBUG
@@ -230,7 +236,8 @@ namespace Hornung.ResourceToolkit.Resolver
/// Initializes a new instance of the class.
///
/// The property to find the associated field for.
- public PropertyFieldAssociationVisitor(IProperty property) : base()
+ public PropertyFieldAssociationVisitor(IProperty property, string fileName, string fileContent)
+ : base(fileName, fileContent)
{
if (property == null) {
throw new ArgumentNullException("property");
@@ -243,7 +250,8 @@ namespace Hornung.ResourceToolkit.Resolver
///
/// The field to find the associated property for.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.ArgumentException.#ctor(System.String,System.String)")]
- public PropertyFieldAssociationVisitor(IField field) : base()
+ public PropertyFieldAssociationVisitor(IField field, string fileName, string fileContent)
+ : base(fileName, fileContent)
{
if (field == null) {
throw new ArgumentNullException("field");
diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/ResourceFileContent/ResourceFileContentRegistry.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/ResourceFileContent/ResourceFileContentRegistry.cs
index aa054fc042..8ede5a858d 100644
--- a/src/AddIns/Misc/ResourceToolkit/Project/Src/ResourceFileContent/ResourceFileContentRegistry.cs
+++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/ResourceFileContent/ResourceFileContentRegistry.cs
@@ -42,15 +42,14 @@ namespace Hornung.ResourceToolkit.ResourceFileContent
/// Gets the resource content for the specified file.
///
/// The name of the file to get a resource content for.
- /// The resource content for the specified file.
- /// The format of the specified resource file cannot be handled.
+ /// The resource content for the specified file, or null if the format of the specified resource file cannot be handled.
public static IResourceFileContent GetResourceFileContent(string fileName)
{
IResourceFileContent c;
if (!resourceFileContents.TryGetValue(fileName, out c)) {
c = CreateResourceFileContent(fileName);
if (c == null) {
- throw new NotSupportedException("The format of the resource file '"+fileName+"' cannot be handled by any registered resource file content factory.");
+ return null;
}
resourceFileContents[fileName] = c;
}
diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/ResourceResolverService.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/ResourceResolverService.cs
index dca4f77a89..38d085fd44 100644
--- a/src/AddIns/Misc/ResourceToolkit/Project/Src/ResourceResolverService.cs
+++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/ResourceResolverService.cs
@@ -12,6 +12,9 @@ using System.Text;
using Hornung.ResourceToolkit.Resolver;
using Hornung.ResourceToolkit.ResourceFileContent;
using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document;
@@ -44,6 +47,11 @@ namespace Hornung.ResourceToolkit
}
}
+ public static void SetResourceResolversListUnitTestOnly(IEnumerable resolversToSet)
+ {
+ resolvers = new List(resolversToSet);
+ }
+
// ********************************************************************************************************************************
///
@@ -133,5 +141,79 @@ namespace Hornung.ResourceToolkit
return sb.ToString();
}
+ // ********************************************************************************************************************************
+
+ // The following helper methods are needed to support running
+ // in the unit testing mode where the addin tree is not available.
+
+ static Dictionary presetParsersUnitTestOnly;
+
+ public static void SetParsersUnitTestOnly(Dictionary parsers)
+ {
+ presetParsersUnitTestOnly = parsers;
+ }
+
+ public static IParser GetParser(string fileName)
+ {
+ IParser p;
+ if (presetParsersUnitTestOnly == null) {
+ p = ParserService.GetParser(fileName);
+ } else {
+ presetParsersUnitTestOnly.TryGetValue(System.IO.Path.GetExtension(fileName), out p);
+ }
+ return p;
+ }
+
+ public static IExpressionFinder GetExpressionFinder(string fileName)
+ {
+ IParser p = GetParser(fileName);
+ if (p == null) return null;
+ return p.CreateExpressionFinder(fileName);
+ }
+
+ public static IResolver CreateResolver(string fileName)
+ {
+ IParser p = GetParser(fileName);
+ if (p == null) return null;
+ return p.CreateResolver();
+ }
+
+ static Dictionary fileContents;
+
+ public static void SetFileContentUnitTestOnly(string fileName, string fileContent)
+ {
+ if (fileContents == null) {
+ fileContents = new Dictionary();
+ }
+ fileContents[fileName] = fileContent;
+ }
+
+ public static string GetParsableFileContent(string fileName)
+ {
+ if (fileContents == null) {
+ return ParserService.GetParseableFileContent(fileName);
+ } else {
+ return fileContents[fileName];
+ }
+ }
+
+ static Dictionary projectContents;
+
+ public static void SetProjectContentUnitTestOnly(IProject project, IProjectContent projectContent)
+ {
+ if (projectContents == null) {
+ projectContents = new Dictionary();
+ }
+ projectContents[project] = projectContent;
+ }
+
+ public static IProjectContent GetProjectContent(IProject project)
+ {
+ if (projectContents == null) {
+ return ParserService.GetProjectContent(project);
+ } else {
+ return projectContents[project];
+ }
+ }
}
}
diff --git a/src/AddIns/Misc/ResourceToolkit/Test/AbstractResourceResolverTestFixture.cs b/src/AddIns/Misc/ResourceToolkit/Test/AbstractResourceResolverTestFixture.cs
new file mode 100644
index 0000000000..fad8ebd772
--- /dev/null
+++ b/src/AddIns/Misc/ResourceToolkit/Test/AbstractResourceResolverTestFixture.cs
@@ -0,0 +1,85 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+
+using Hornung.ResourceToolkit;
+using Hornung.ResourceToolkit.Resolver;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.TextEditor.Document;
+using NUnit.Framework;
+
+namespace ResourceToolkit.Tests
+{
+ public abstract class AbstractResourceResolverTestFixture : AbstractTestProjectTestFixture
+ {
+ protected abstract string DefaultFileName {
+ get;
+ }
+
+ protected override void DoSetUp()
+ {
+ base.DoSetUp();
+ TestHelper.InitializeResolvers();
+ }
+
+ protected void EnlistTestFile(string fileName, string code, bool parseFile)
+ {
+ ResourceResolverService.SetFileContentUnitTestOnly(fileName, code);
+ ProjectFileDictionaryService.AddFile(fileName, this.Project);
+
+ if (parseFile) {
+ IParser parser = ResourceResolverService.GetParser(fileName);
+ Assert.IsNotNull(parser, "Could not get parser for " + fileName+ ".");
+ ICompilationUnit cu = parser.Parse(this.DefaultProjectContent, fileName, code);
+ cu.Freeze();
+ Assert.IsFalse(cu.ErrorsDuringCompile, "Errors while parsing test program.");
+ ParserService.RegisterParseInformation(fileName, cu);
+ this.DefaultProjectContent.UpdateCompilationUnit(null, cu, fileName);
+ }
+ }
+
+ ///
+ /// Resolves a resource reference.
+ /// Line and column are 0-based.
+ ///
+ protected ResourceResolveResult Resolve(string fileName, string code, int caretLine, int caretColumn, char? charTyped, bool parseFile)
+ {
+ this.EnlistTestFile(fileName, code, parseFile);
+ IDocument doc = new DocumentFactory().CreateDocument();
+ doc.TextContent = code;
+ return ResourceResolverService.Resolve(fileName, doc, caretLine, caretColumn, charTyped);
+ }
+
+ ///
+ /// Resolves a resource reference.
+ /// Line and column are 0-based.
+ ///
+ protected ResourceResolveResult Resolve(string code, int caretLine, int caretColumn, char? charTyped)
+ {
+ return this.Resolve(this.DefaultFileName, code, caretLine, caretColumn, charTyped, true);
+ }
+
+ protected override void DoTearDown()
+ {
+ base.DoTearDown();
+ NRefactoryAstCacheService.DisableCache();
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ try {
+ if (disposing) {
+ NRefactoryAstCacheService.DisableCache();
+ }
+ } finally {
+ base.Dispose(disposing);
+ }
+ }
+ }
+}
diff --git a/src/AddIns/Misc/ResourceToolkit/Test/AbstractTestProjectTestFixture.cs b/src/AddIns/Misc/ResourceToolkit/Test/AbstractTestProjectTestFixture.cs
new file mode 100644
index 0000000000..632587dc35
--- /dev/null
+++ b/src/AddIns/Misc/ResourceToolkit/Test/AbstractTestProjectTestFixture.cs
@@ -0,0 +1,110 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+
+using Hornung.ResourceToolkit;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+using NUnit.Framework;
+
+namespace ResourceToolkit.Tests
+{
+ public abstract class AbstractTestProjectTestFixture : IDisposable
+ {
+ Solution solution;
+ IProject project;
+ DefaultProjectContent defaultPC;
+
+ [SetUp]
+ public void SetUp()
+ {
+ this.DoSetUp();
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ this.DoTearDown();
+ }
+
+ public void Dispose()
+ {
+ this.Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing) {
+ this.DoTearDown();
+ }
+ }
+
+ protected virtual void DoSetUp()
+ {
+ TestHelper.InitializeParsers();
+
+ this.solution = new Solution();
+ this.project = this.CreateTestProject();
+ ProjectService.CurrentProject = this.project;
+
+ DefaultProjectContent pc = this.CreateNewProjectContent(this.project);
+ HostCallback.GetCurrentProjectContent = delegate {
+ return pc;
+ };
+ ResourceResolverService.SetProjectContentUnitTestOnly(this.project, pc);
+ this.defaultPC = pc;
+ }
+
+ protected virtual void DoTearDown()
+ {
+ if (this.defaultPC != null) {
+ this.defaultPC.Dispose();
+ this.defaultPC = null;
+ }
+ if (this.project != null) {
+ this.project.Dispose();
+ this.project = null;
+ }
+ if (this.solution != null) {
+ this.solution.Dispose();
+ this.solution = null;
+ }
+ }
+
+ protected abstract IProject CreateTestProject();
+
+ protected IProject Project {
+ get { return this.project; }
+ }
+
+ protected DefaultProjectContent DefaultProjectContent {
+ get { return this.defaultPC; }
+ }
+
+ protected Solution Solution {
+ get { return this.solution; }
+ }
+
+ protected virtual DefaultProjectContent CreateNewProjectContent(IProject project)
+ {
+ DefaultProjectContent pc = new DefaultProjectContent();
+
+ pc.ReferencedContents.Add(ParserService.DefaultProjectContentRegistry.Mscorlib);
+ pc.ReferencedContents.Add(ParserService.DefaultProjectContentRegistry.GetProjectContentForReference("System", "System"));
+
+ if (project != null) {
+ if (project.LanguageProperties != null) {
+ pc.Language = project.LanguageProperties;
+ }
+ }
+
+ return pc;
+ }
+ }
+}
diff --git a/src/AddIns/Misc/ResourceToolkit/Test/CSharp/AbstractCSharpResourceResolverTestFixture.cs b/src/AddIns/Misc/ResourceToolkit/Test/CSharp/AbstractCSharpResourceResolverTestFixture.cs
new file mode 100644
index 0000000000..c9656830ad
--- /dev/null
+++ b/src/AddIns/Misc/ResourceToolkit/Test/CSharp/AbstractCSharpResourceResolverTestFixture.cs
@@ -0,0 +1,38 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.IO;
+
+using CSharpBinding;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Internal.Templates;
+using ICSharpCode.SharpDevelop.Project;
+using NUnit.Framework;
+
+namespace ResourceToolkit.Tests.CSharp
+{
+ public abstract class AbstractCSharpResourceResolverTestFixture : AbstractResourceResolverTestFixture
+ {
+ protected override string DefaultFileName {
+ get { return "a.cs"; }
+ }
+
+ protected override IProject CreateTestProject()
+ {
+ ProjectCreateInformation info = new ProjectCreateInformation();
+ info.ProjectName = "Test";
+ info.RootNamespace = "Test";
+ info.OutputProjectFileName = Path.Combine(Path.GetTempPath(), "Test.csproj");
+ info.Solution = this.Solution;
+
+ CSharpProject p = new CSharpProject(info);
+ return p;
+ }
+ }
+}
diff --git a/src/AddIns/Misc/ResourceToolkit/Test/CSharp/AnyResourceReferenceFinderTests.cs b/src/AddIns/Misc/ResourceToolkit/Test/CSharp/AnyResourceReferenceFinderTests.cs
new file mode 100644
index 0000000000..c6a663873b
--- /dev/null
+++ b/src/AddIns/Misc/ResourceToolkit/Test/CSharp/AnyResourceReferenceFinderTests.cs
@@ -0,0 +1,104 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+
+using Hornung.ResourceToolkit.Refactoring;
+using Hornung.ResourceToolkit.Resolver;
+using NUnit.Framework;
+
+namespace ResourceToolkit.Tests.CSharp
+{
+ ///
+ /// Tests the AnyResourceReferenceFinder in C#.
+ ///
+ [TestFixture]
+ public sealed class AnyResourceReferenceFinderTests
+ {
+ [TestFixtureSetUp]
+ public void FixtureSetUp()
+ {
+ TestHelper.InitializeParsers();
+ TestHelper.InitializeResolvers();
+ }
+
+ // ********************************************************************************************************************************
+
+ static AnyResourceReferenceFinder CreateFinder()
+ {
+ return new AnyResourceReferenceFinder();
+ }
+
+ [Test]
+ public void NoReference()
+ {
+ const string Code = @"class A {
+ void B() {
+ DoSomething();
+ }
+}";
+ AnyResourceReferenceFinder finder = CreateFinder();
+ Assert.AreEqual(-1, finder.GetNextPossibleOffset("a.cs", Code, -1), "Incorrect offset.");
+ }
+
+ [Test]
+ public void OneReference()
+ {
+ const string Code = @"class A {
+ void B() {
+ resMgr.GetString(""TestKey"");
+ }
+}";
+ AnyResourceReferenceFinder finder = CreateFinder();
+ Assert.AreEqual(33, finder.GetNextPossibleOffset("a.cs", Code, -1), "Incorrect offset.");
+ Assert.AreEqual(-1, finder.GetNextPossibleOffset("a.cs", Code, 33), "Incorrect offset.");
+ }
+
+ [Test]
+ public void TwoReferences()
+ {
+ const string Code = @"class A {
+ void B() {
+ resMgr.GetString(""TestKey"");
+ resMgr[""TestKey""];
+ }
+}";
+ AnyResourceReferenceFinder finder = CreateFinder();
+ Assert.AreEqual(33, finder.GetNextPossibleOffset("a.cs", Code, -1), "Incorrect offset.");
+ Assert.AreEqual(64, finder.GetNextPossibleOffset("a.cs", Code, 33), "Incorrect offset.");
+ Assert.AreEqual(-1, finder.GetNextPossibleOffset("a.cs", Code, 64), "Incorrect offset.");
+ }
+
+ [Test]
+ public void FourReferencesMixed()
+ {
+ const string Code = @"class A {
+ void B() {
+ resMgr.GetString(""TestKey"");
+ X(""${res:TestKey2}"");
+ resMgr[""TestKey""];
+ X(""${res:TestKey3}"");
+ }
+}";
+ AnyResourceReferenceFinder finder = CreateFinder();
+ Assert.AreEqual(33, finder.GetNextPossibleOffset("a.cs", Code, -1), "Incorrect offset.");
+ Assert.AreEqual(61, finder.GetNextPossibleOffset("a.cs", Code, 33), "Incorrect offset.");
+ Assert.AreEqual(89, finder.GetNextPossibleOffset("a.cs", Code, 61), "Incorrect offset.");
+ Assert.AreEqual(108, finder.GetNextPossibleOffset("a.cs", Code, 89), "Incorrect offset.");
+ Assert.AreEqual(-1, finder.GetNextPossibleOffset("a.cs", Code, 108), "Incorrect offset.");
+ }
+
+ // ********************************************************************************************************************************
+
+ [Test]
+ public void ResultMatch()
+ {
+ AnyResourceReferenceFinder finder = CreateFinder();
+ Assert.IsTrue(finder.IsReferenceToResource(new ResourceResolveResult(null, null, null, new ResourceSetReference("SomeResources", "C:\\SomeResources.resx"), "SomeKey")));
+ }
+ }
+}
diff --git a/src/AddIns/Misc/ResourceToolkit/Test/CSharp/BclNRefactoryResourceResolverTests.cs b/src/AddIns/Misc/ResourceToolkit/Test/CSharp/BclNRefactoryResourceResolverTests.cs
new file mode 100644
index 0000000000..c45f4e3c98
--- /dev/null
+++ b/src/AddIns/Misc/ResourceToolkit/Test/CSharp/BclNRefactoryResourceResolverTests.cs
@@ -0,0 +1,815 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using Hornung.ResourceToolkit;
+using Hornung.ResourceToolkit.Resolver;
+using NUnit.Framework;
+
+namespace ResourceToolkit.Tests.CSharp
+{
+ [TestFixture]
+ public sealed class BclNRefactoryResourceResolverTests : AbstractCSharpResourceResolverTestFixture
+ {
+ readonly IResourceResolver resolver = new NRefactoryResourceResolver();
+
+ IResourceResolver Resolver {
+ get { return this.resolver; }
+ }
+
+ // ********************************************************************************************************************************
+
+ #region === Tests with local variables ===
+
+ const string CodeLocalSRMDirectInitFullName = @"class A
+{
+ void B()
+ {
+ System.Resources.ResourceManager mgr = new System.Resources.ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ mgr.GetString(""TestKey"");
+ mgr[""TestKey2""];
+ }
+
+ void C()
+ {
+ mgr.GetString(""TestKey"");
+ mgr[""TestKey2""];
+ }
+}
+";
+
+ [Test]
+ public void LocalSRMDirectInitFullNameGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalSRMDirectInitFullName, 5, 18, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ [Test]
+ public void LocalSRMDirectInitFullNameNoIndexer()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalSRMDirectInitFullName, 6, 7, null);
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ [Test]
+ public void LocalSRMDirectInitFullNameOutOfScope()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalSRMDirectInitFullName, 11, 18, null);
+ TestHelper.CheckNoReference(rrr);
+
+ rrr = Resolve(CodeLocalSRMDirectInitFullName, 12, 7, null);
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeLocalSRMDirectInitFullNameGetStringCompletion = @"class A
+{
+ void B()
+ {
+ System.Resources.ResourceManager mgr = new System.Resources.ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ mgr.GetString
+ }
+}
+";
+
+ [Test]
+ public void LocalSRMDirectInitFullNameGetStringIncomplete()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalSRMDirectInitFullNameGetStringCompletion, 5, 15, null);
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ [Test]
+ public void LocalSRMDirectInitFullNameGetStringCompletion()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalSRMDirectInitFullNameGetStringCompletion, 5, 15, '(');
+ TestHelper.CheckReference(rrr, "Test.TestResources", null, "A", "A.B");
+ }
+
+ [Test]
+ public void LocalSRMDirectInitFullNameGetStringNoCompletion()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalSRMDirectInitFullNameGetStringCompletion, 5, 15, '[');
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ const string CodeLocalSRMDirectInitFullNameGetStringCompletionBug1 = @"class A
+{
+ void B()
+ {
+ System.Resources.ResourceManager mgr = new System.Resources.ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ mgr.GetString(""TestKey"").Replace
+ }
+}
+";
+
+ [Test]
+ public void LocalSRMDirectInitFullNameGetStringCompletionBug1()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalSRMDirectInitFullNameGetStringCompletionBug1, 5, 34, '(');
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeLocalIndexerRMDirectInit = @"class IndexerRM : System.Resources.ResourceManager
+{
+ public IndexerRM(string name, System.Reflection.Assembly assembly) : base(name, assembly)
+ {
+ }
+ public string this[string key] {
+ get { return this.GetString(key); }
+ }
+}
+
+class A
+{
+ void B()
+ {
+ IndexerRM mgr = new IndexerRM(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ mgr[""TestKey""];
+ mgr
+ }
+}
+";
+
+ [Test]
+ public void LocalIndexerRMDirectInit()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalIndexerRMDirectInit, 15, 7, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ [Test]
+ public void LocalIndexerRMDirectInitCompletionBug1()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalIndexerRMDirectInit, 15, 16, '[');
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ [Test]
+ public void LocalIndexerRMDirectInitCompletion()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalIndexerRMDirectInit, 16, 5, '[');
+ TestHelper.CheckReference(rrr, "Test.TestResources", null, "A", "A.B");
+ }
+
+ [Test]
+ public void LocalIndexerRMDirectInitNoCompletion()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalIndexerRMDirectInit, 16, 5, null);
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ [Test]
+ public void LocalIndexerRMDirectInitNoCompletionWrongChar()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalIndexerRMDirectInit, 16, 5, '(');
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeLocalIndexerRMBug1 = @"class IndexerRM : System.Resources.ResourceManager
+{
+ public IndexerRM(string name, System.Reflection.Assembly assembly) : base(name, assembly)
+ {
+ }
+ public string this[string key] {
+ get { return this.GetString(key); }
+ }
+}
+
+class A
+{
+ void B()
+ {
+ IndexerRM mgr = new IndexerRM(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ DoSomething(mgr[""TestKey""], ""["");
+ }
+}
+";
+
+ [Test]
+ public void LocalIndexerRMBug1FirstRef()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalIndexerRMBug1, 15, 19, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeLocalSRMDirectInitAlias = @"using SRM = System.Resources.ResourceManager;
+class A
+{
+ void B()
+ {
+ SRM mgr = new SRM(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ mgr.GetString(""TestKey"");
+ mgr[""TestKey2""];
+ }
+}
+";
+
+ [Test]
+ public void LocalSRMDirectInitAliasGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalSRMDirectInitAlias, 6, 18, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ [Test]
+ public void LocalSRMDirectInitAliasNoIndexer()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalSRMDirectInitAlias, 7, 7, null);
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeLocalSRMDeferredInitUsing = @"using System.Resources;
+class A
+{
+ void B()
+ {
+ ResourceManager mgr;
+
+ mgr = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ mgr.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void LocalSRMDeferredInitUsingGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeLocalSRMDeferredInitUsing, 8, 18, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ #endregion
+
+ // ********************************************************************************************************************************
+
+ #region === Tests with instance fields ===
+
+ const string CodeInstanceFieldSRMDirectInitUsing = @"using System.Resources;
+class A
+{
+ ResourceManager mgr = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+
+ void B()
+ {
+ this.mgr.GetString(""TestKey"");
+ mgr.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void InstanceFieldSRMDirectInitUsingThisGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeInstanceFieldSRMDirectInitUsing, 7, 22, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ [Test]
+ public void InstanceFieldSRMDirectInitUsingGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeInstanceFieldSRMDirectInitUsing, 8, 17, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeInstanceFieldSRMDeferredInitThisUsing = @"using System.Resources;
+class A
+{
+ ResourceManager mgr;
+ public A()
+ {
+ this.mgr = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ }
+ void B()
+ {
+ this.mgr.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void InstanceFieldSRMDeferredInitThisUsingThisGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeInstanceFieldSRMDeferredInitThisUsing, 10, 22, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ const string CodeInstanceFieldSRMDeferredInitUsing = @"using System.Resources;
+class A
+{
+ ResourceManager mgr;
+ public A()
+ {
+ mgr = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ }
+ void B()
+ {
+ this.mgr.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void InstanceFieldSRMDeferredInitUsingThisGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeInstanceFieldSRMDeferredInitUsing, 10, 22, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ #endregion
+
+ // ********************************************************************************************************************************
+
+ #region === Tests with static fields ===
+
+ const string CodeStaticFieldSRMDirectInitUsing = @"using System.Resources;
+class A
+{
+ static ResourceManager mgr = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+
+ void B()
+ {
+ A.mgr.GetString(""TestKey"");
+ mgr.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void StaticFieldSRMDirectInitUsingClassGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeStaticFieldSRMDirectInitUsing, 7, 19, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ [Test]
+ public void StaticFieldSRMDirectInitUsingGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeInstanceFieldSRMDirectInitUsing, 8, 17, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeStaticFieldSRMDeferredInitClassUsing = @"using System.Resources;
+class A
+{
+ static ResourceManager mgr;
+ static A()
+ {
+ A.mgr = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ }
+ void B()
+ {
+ A.mgr.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void StaticFieldSRMDeferredInitClassUsingClassGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeStaticFieldSRMDeferredInitClassUsing, 10, 19, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ const string CodeStaticFieldSRMDeferredInitUsing = @"using System.Resources;
+class A
+{
+ static ResourceManager mgr;
+ static A()
+ {
+ mgr = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ }
+ void B()
+ {
+ A.mgr.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void StaticFieldSRMDeferredInitUsingClassGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeStaticFieldSRMDeferredInitUsing, 10, 19, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ #endregion
+
+ // ********************************************************************************************************************************
+
+ #region === Tests with instance properties ===
+
+ const string CodeInstancePropertySRMFieldDirectInitUsing = @"using System.Resources;
+class A
+{
+ public ResourceManager Resources {
+ get { return mgr; }
+ }
+
+ ResourceManager mgr = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+
+ void B()
+ {
+ this.Resources.GetString(""TestKey"");
+ Resources.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void InstancePropertySRMFieldDirectInitUsingThisGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeInstancePropertySRMFieldDirectInitUsing, 11, 28, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ [Test]
+ public void InstancePropertySRMFieldDirectInitUsingGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeInstancePropertySRMFieldDirectInitUsing, 12, 23, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeInstancePropertySRMDeferredFieldInitThisUsing = @"using System.Resources;
+class A
+{
+ ResourceManager mgr;
+
+ public ResourceManager Resources {
+ get { return mgr; }
+ }
+
+ public A()
+ {
+ this.mgr = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ }
+ void B()
+ {
+ this.Resources.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void InstancePropertySRMDeferredFieldInitThisUsingThisGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeInstancePropertySRMDeferredFieldInitThisUsing, 15, 28, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeInstancePropertySRMDeferredPropertyInitThisUsing = @"using System.Resources;
+class A
+{
+ ResourceManager mgr;
+
+ public ResourceManager Resources {
+ get { return mgr; }
+ private set { mgr = value; }
+ }
+
+ public A()
+ {
+ this.Resources = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ }
+ void B()
+ {
+ this.Resources.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void InstancePropertySRMDeferredPropertyInitThisUsingThisGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeInstancePropertySRMDeferredPropertyInitThisUsing, 16, 28, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ const string CodeInstanceFieldSRMDeferredWriteOnlyPropertyInitThisUsing = @"using System.Resources;
+class A
+{
+ ResourceManager mgr;
+
+ private ResourceManager Resources {
+ set { mgr = value; }
+ }
+
+ public A()
+ {
+ this.Resources = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ }
+ void B()
+ {
+ this.mgr.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void InstanceFieldSRMDeferredWriteOnlyPropertyInitThisUsingThisGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeInstanceFieldSRMDeferredWriteOnlyPropertyInitThisUsing, 15, 22, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeInstancePropertySRMInvalidReturnTypeBug = @"using System.Resources;
+class A
+{
+ ResourceManager mgr;
+
+ public ResourceManager Resources {
+ get { return mgr; }
+ private set { mgr = value; }
+ }
+
+ public A()
+ {
+ foo bar;
+ bar = 1;
+ this.Resources = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ this.Resources.GetString
+ }
+}
+";
+
+ [Test]
+ public void InstancePropertySRMInvalidReturnTypeBug()
+ {
+ ResourceResolveResult rrr = Resolve(CodeInstancePropertySRMInvalidReturnTypeBug, 15, 26, '(');
+ TestHelper.CheckReference(rrr, "Test.TestResources", null, "A", "A.#ctor");
+ }
+
+ #endregion
+
+ // ********************************************************************************************************************************
+
+ #region === Tests with static properties ===
+
+ const string CodeStaticPropertySRMFieldDirectInitUsing = @"using System.Resources;
+class A
+{
+ public static ResourceManager Resources {
+ get { return mgr; }
+ }
+
+ static ResourceManager mgr = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+
+ void B()
+ {
+ A.Resources.GetString(""TestKey"");
+ Resources.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void StaticPropertySRMFieldDirectInitUsingClassGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeStaticPropertySRMFieldDirectInitUsing, 11, 25, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ [Test]
+ public void StaticPropertySRMFieldDirectInitUsingGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeStaticPropertySRMFieldDirectInitUsing, 12, 23, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeStaticPropertySRMDeferredFieldInitClassUsing = @"using System.Resources;
+class A
+{
+ static ResourceManager mgr;
+
+ public static ResourceManager Resources {
+ get { return mgr; }
+ }
+
+ static A()
+ {
+ A.mgr = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ }
+ void B()
+ {
+ A.Resources.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void StaticPropertySRMDeferredFieldInitClassUsingClassGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeStaticPropertySRMDeferredFieldInitClassUsing, 15, 25, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeStaticPropertySRMDeferredPropertyInitClassUsing = @"using System.Resources;
+class A
+{
+ static ResourceManager mgr;
+
+ public static ResourceManager Resources {
+ get { return mgr; }
+ private set { mgr = value; }
+ }
+
+ static A()
+ {
+ A.Resources = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ }
+ void B()
+ {
+ A.Resources.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void StaticPropertySRMDeferredPropertyInitClassUsingClassGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeStaticPropertySRMDeferredPropertyInitClassUsing, 16, 25, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ const string CodeStaticFieldSRMDeferredWriteOnlyPropertyInitClassUsing = @"using System.Resources;
+class A
+{
+ static ResourceManager mgr;
+
+ private static ResourceManager Resources {
+ set { mgr = value; }
+ }
+
+ static A()
+ {
+ A.Resources = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ }
+ void B()
+ {
+ A.mgr.GetString(""TestKey"");
+ }
+}
+";
+
+ [Test]
+ public void StaticFieldSRMDeferredWriteOnlyPropertyInitClassUsingClassGetString()
+ {
+ ResourceResolveResult rrr = Resolve(CodeStaticFieldSRMDeferredWriteOnlyPropertyInitClassUsing, 15, 19, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+ }
+
+ #endregion
+
+ // ********************************************************************************************************************************
+ // ********************************************************************************************************************************
+
+ #region === Tests for specific behavior ===
+
+ const string CodeUnescapeResourceKey = @"using System.Resources;
+class A {
+ void B()
+ {
+ ResourceManager mgr = new ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ mgr.GetString(""Some\""strange\""key"");
+ }
+}
+";
+
+ [Test]
+ public void UnescapeResourceKey()
+ {
+ ResourceResolveResult rrr = Resolve(CodeUnescapeResourceKey, 5, 17, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "Some\"strange\"key", "A", "A.B");
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeSRMTypeOfInit = @"using System.Resources;
+namespace Test {
+ class A {
+ void B()
+ {
+ ResourceManager mgr = new ResourceManager(typeof(A));
+ mgr.GetString(""TestKey"");
+ }
+ }
+}
+";
+
+ [Test]
+ public void SRMTypeOfInit()
+ {
+ ResourceResolveResult rrr = Resolve(CodeSRMTypeOfInit, 6, 18, null);
+ TestHelper.CheckReference(rrr, "Test.A", "TestKey", "Test.A", "Test.A.B");
+ }
+
+ // ********************************************************************************************************************************
+
+ [Test]
+ public void ResolverSupportsCSharpFiles()
+ {
+ Assert.IsTrue(this.Resolver.SupportsFile("a.cs"));
+ }
+
+ [Test]
+ public void CSharpFilePatterns()
+ {
+ List patterns = new List(this.Resolver.GetPossiblePatternsForFile("a.cs"));
+ Assert.Contains("GetString", patterns);
+ Assert.Contains("GetStream", patterns);
+ Assert.Contains("GetObject", patterns);
+ Assert.Contains("[", patterns);
+ Assert.AreEqual(4, patterns.Count, "Incorrect number of resource access patterns for C# files.");
+ }
+
+ [Test]
+ public void ResolverDoesNotSupportBooFiles()
+ {
+ Assert.IsFalse(this.Resolver.SupportsFile("a.boo"));
+ }
+
+ [Test]
+ public void UnsupportedFilePatterns()
+ {
+ IEnumerable list = this.Resolver.GetPossiblePatternsForFile("a.boo");
+ Assert.IsNotNull(list, "IResourceResolver.GetPossiblePatternsForFile must not return null.");
+
+ List patterns = new List(list);
+ Assert.AreEqual(0, patterns.Count);
+ }
+
+ #endregion
+
+ // ********************************************************************************************************************************
+
+ #region Cache tests
+
+ const string CodeCacheTest = @"class A
+{
+ void B()
+ {
+ System.Resources.ResourceManager mgr = new System.Resources.ResourceManager(""Test.TestResources"", System.Reflection.Assembly.GetExecutingAssembly());
+ mgr.GetString(""TestKey"");
+ mgr.GetString(""TestKey2"");
+ }
+}
+";
+
+ [Test]
+ public void UseAstCache()
+ {
+ NRefactoryAstCacheService.EnableCache();
+
+ ResourceResolveResult rrr = Resolve(CodeCacheTest, 5, 17, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+
+ rrr = Resolve(CodeCacheTest, 5, 17, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey", "A", "A.B");
+
+ rrr = Resolve(CodeCacheTest, 6, 17, null);
+ TestHelper.CheckReference(rrr, "Test.TestResources", "TestKey2", "A", "A.B");
+
+ NRefactoryAstCacheService.DisableCache();
+ }
+
+ [Test]
+ [ExpectedException(typeof(InvalidOperationException), ExpectedMessage="The AST cache is already enabled.")]
+ public void AstCacheEnableTwice()
+ {
+ NRefactoryAstCacheService.EnableCache();
+ NRefactoryAstCacheService.EnableCache();
+ }
+
+ #endregion
+ }
+}
diff --git a/src/AddIns/Misc/ResourceToolkit/Test/CSharp/ICSharpCodeCoreNRefactoryResourceResolverTests.cs b/src/AddIns/Misc/ResourceToolkit/Test/CSharp/ICSharpCodeCoreNRefactoryResourceResolverTests.cs
new file mode 100644
index 0000000000..9f994ec74b
--- /dev/null
+++ b/src/AddIns/Misc/ResourceToolkit/Test/CSharp/ICSharpCodeCoreNRefactoryResourceResolverTests.cs
@@ -0,0 +1,84 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+
+using Hornung.ResourceToolkit;
+using Hornung.ResourceToolkit.Resolver;
+using NUnit.Framework;
+
+namespace ResourceToolkit.Tests.CSharp
+{
+ [TestFixture]
+ public sealed class ICSharpCodeCoreNRefactoryResourceResolverTests : AbstractCSharpResourceResolverTestFixture
+ {
+ protected override void DoSetUp()
+ {
+ base.DoSetUp();
+
+ const string ICSharpCodeCoreCode = @"namespace ICSharpCode.Core
+{
+ public class ResourceService
+ {
+ public static string GetString(string key)
+ {
+ return """";
+ }
+ }
+}
+";
+ this.EnlistTestFile("ICSharpCodeCore.cs", ICSharpCodeCoreCode, true);
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeClass = @"class A {
+ void B() {
+ ICSharpCode.Core.ResourceService.GetString(""TestKey"");
+ ICSharpCode.Core.ResourceService.GetString
+ }
+}";
+
+ [Test]
+ public void GetStringClass()
+ {
+ ResourceResolveResult rrr = Resolve(CodeClass, 2, 46, null);
+ TestHelper.CheckReference(rrr, "[ICSharpCodeCoreHostResourceSet]", "TestKey", "A", "A.B");
+ }
+
+ [Test]
+ public void GetStringClassCompletion()
+ {
+ ResourceResolveResult rrr = Resolve(CodeClass, 3, 44, '(');
+ TestHelper.CheckReference(rrr, "[ICSharpCodeCoreHostResourceSet]", null, "A", "A.B");
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeUsing = @"using ICSharpCode.Core;
+class A {
+ void B() {
+ ResourceService.GetString(""TestKey"");
+ ResourceService.GetString
+ }
+}";
+
+ [Test]
+ public void GetStringUsing()
+ {
+ ResourceResolveResult rrr = Resolve(CodeUsing, 3, 29, null);
+ TestHelper.CheckReference(rrr, "[ICSharpCodeCoreHostResourceSet]", "TestKey", "A", "A.B");
+ }
+
+ [Test]
+ public void GetStringUsingCompletion()
+ {
+ ResourceResolveResult rrr = Resolve(CodeUsing, 4, 27, '(');
+ TestHelper.CheckReference(rrr, "[ICSharpCodeCoreHostResourceSet]", null, "A", "A.B");
+ }
+ }
+}
diff --git a/src/AddIns/Misc/ResourceToolkit/Test/CSharp/ICSharpCodeCoreResourceResolverTests.cs b/src/AddIns/Misc/ResourceToolkit/Test/CSharp/ICSharpCodeCoreResourceResolverTests.cs
new file mode 100644
index 0000000000..9945c3ca45
--- /dev/null
+++ b/src/AddIns/Misc/ResourceToolkit/Test/CSharp/ICSharpCodeCoreResourceResolverTests.cs
@@ -0,0 +1,195 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using Hornung.ResourceToolkit;
+using Hornung.ResourceToolkit.Resolver;
+using NUnit.Framework;
+
+namespace ResourceToolkit.Tests.CSharp
+{
+ [TestFixture]
+ public sealed class ICSharpCodeCoreResourceResolverTests : AbstractCSharpResourceResolverTestFixture
+ {
+ readonly IResourceResolver resolver = new ICSharpCodeCoreResourceResolver();
+
+ IResourceResolver Resolver {
+ get { return this.resolver; }
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeResourceAccess = @"class A {
+ string B() {
+ return ""${res:TestKey}"";
+ }
+}";
+
+ [Test]
+ public void ResourceAccessStart()
+ {
+ ResourceResolveResult rrr = Resolve(CodeResourceAccess, 2, 10, null);
+ TestHelper.CheckReference(rrr, "[ICSharpCodeCoreHostResourceSet]", "TestKey", null, null);
+ }
+
+ [Test]
+ public void ResourceAccessAtKey()
+ {
+ ResourceResolveResult rrr = Resolve(CodeResourceAccess, 2, 17, null);
+ TestHelper.CheckReference(rrr, "[ICSharpCodeCoreHostResourceSet]", "TestKey", null, null);
+ }
+
+ [Test]
+ public void ResourceAccessAtEndOfKey()
+ {
+ ResourceResolveResult rrr = Resolve(CodeResourceAccess, 2, 23, null);
+ TestHelper.CheckReference(rrr, "[ICSharpCodeCoreHostResourceSet]", "TestKey", null, null);
+ }
+
+ [Test]
+ public void NoCompletionWrongChar()
+ {
+ ResourceResolveResult rrr = Resolve(CodeResourceAccess, 2, 15, 'x');
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ [Test]
+ public void ResourceAccessAtKeyWithCache()
+ {
+ NRefactoryAstCacheService.EnableCache();
+
+ ResourceResolveResult rrr = Resolve(CodeResourceAccess, 2, 17, null);
+ TestHelper.CheckReference(rrr, "[ICSharpCodeCoreHostResourceSet]", "TestKey", null, null);
+
+ rrr = Resolve(CodeResourceAccess, 2, 17, null);
+ TestHelper.CheckReference(rrr, "[ICSharpCodeCoreHostResourceSet]", "TestKey", null, null);
+
+ NRefactoryAstCacheService.DisableCache();
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeBoundaryTests = @"//${res
+class A {
+ string B() {
+ return ""${res:TestKey}"";
+ return ""${res:"";
+ }
+}
+//${res";
+
+ [Test]
+ public void StartOfDocument()
+ {
+ ResourceResolveResult rrr = Resolve(CodeBoundaryTests, 0, 0, null);
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ [Test]
+ public void StartOfDocumentTag()
+ {
+ ResourceResolveResult rrr = Resolve(CodeBoundaryTests, 0, 3, null);
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ [Test]
+ public void MiddleOfDocument()
+ {
+ ResourceResolveResult rrr = Resolve(CodeBoundaryTests, 3, 10, null);
+ TestHelper.CheckReference(rrr, "[ICSharpCodeCoreHostResourceSet]", "TestKey", null, null);
+ }
+
+ [Test]
+ public void MiddleOfDocumentIncompleteTag()
+ {
+ ResourceResolveResult rrr = Resolve(CodeBoundaryTests, 4, 10, null);
+ TestHelper.CheckReference(rrr, "[ICSharpCodeCoreHostResourceSet]", null, null, null);
+ }
+
+ [Test]
+ public void EndOfDocumentTag()
+ {
+ ResourceResolveResult rrr = Resolve(CodeBoundaryTests, 7, 3, null);
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ [Test]
+ public void EndOfDocument()
+ {
+ ResourceResolveResult rrr = Resolve(CodeBoundaryTests, 7, 6, null);
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ [Test]
+ public void AfterEndOfDocument()
+ {
+ ResourceResolveResult rrr = Resolve(CodeBoundaryTests, 8, 0, null);
+ TestHelper.CheckNoReference(rrr);
+ }
+
+ // ********************************************************************************************************************************
+
+ const string CodeAddinFile = @"
+
+
+
+";
+
+ [Test]
+ public void ResourceAccessInAddinFile()
+ {
+ ResourceResolveResult rrr = Resolve("test.addin", CodeAddinFile, 2, 34, null, false);
+ TestHelper.CheckReference(rrr, "[ICSharpCodeCoreHostResourceSet]", "TestKey", null, null);
+ }
+
+ // ********************************************************************************************************************************
+
+ [Test]
+ public void ResolverSupportsCSharpFiles()
+ {
+ Assert.IsTrue(this.Resolver.SupportsFile("a.cs"));
+ }
+
+ [Test]
+ public void ResolverSupportsAddInFiles()
+ {
+ Assert.IsTrue(this.Resolver.SupportsFile("Test.AddIn"));
+ }
+
+ [Test]
+ public void ResolverSupportsXfrmFiles()
+ {
+ Assert.IsTrue(this.Resolver.SupportsFile("Test.XFrm"));
+ }
+
+ [Test]
+ public void CSharpFilePatterns()
+ {
+ List patterns = new List(this.Resolver.GetPossiblePatternsForFile("a.cs"));
+ Assert.Contains("${res:", patterns);
+ Assert.AreEqual(1, patterns.Count, "Incorrect number of resource access patterns for C# files.");
+ }
+
+ [Test]
+ public void ResolverUnsupportedExtension()
+ {
+ Assert.IsFalse(this.Resolver.SupportsFile("Test.resx"));
+ }
+
+ [Test]
+ public void UnsupportedFilePatterns()
+ {
+ IEnumerable list = this.Resolver.GetPossiblePatternsForFile("a.resx");
+ Assert.IsNotNull(list, "IResourceResolver.GetPossiblePatternsForFile must not return null.");
+
+ List patterns = new List(list);
+ Assert.AreEqual(0, patterns.Count);
+ }
+ }
+}
diff --git a/src/AddIns/Misc/ResourceToolkit/Test/CSharp/SpecificResourceReferenceFinderTests.cs b/src/AddIns/Misc/ResourceToolkit/Test/CSharp/SpecificResourceReferenceFinderTests.cs
new file mode 100644
index 0000000000..0b5fd37ad3
--- /dev/null
+++ b/src/AddIns/Misc/ResourceToolkit/Test/CSharp/SpecificResourceReferenceFinderTests.cs
@@ -0,0 +1,118 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+
+using Hornung.ResourceToolkit.Refactoring;
+using Hornung.ResourceToolkit.Resolver;
+using NUnit.Framework;
+
+namespace ResourceToolkit.Tests.CSharp
+{
+ ///
+ /// Tests the SpecificResourceReferenceFinder in C#.
+ ///
+ [TestFixture]
+ public sealed class SpecificResourceReferenceFinderTests
+ {
+ [TestFixtureSetUpAttribute]
+ public void FixtureSetUp()
+ {
+ TestHelper.InitializeParsers();
+ TestHelper.InitializeResolvers();
+ }
+
+ // ********************************************************************************************************************************
+
+ [Test]
+ [ExpectedException(typeof(ArgumentNullException))]
+ public void NullResourceFileName()
+ {
+ SpecificResourceReferenceFinder finder = new SpecificResourceReferenceFinder(null, "TestKey");
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentNullException))]
+ public void NullKey()
+ {
+ SpecificResourceReferenceFinder finder = new SpecificResourceReferenceFinder("C:\\TestResources.resx", null);
+ }
+
+ // ********************************************************************************************************************************
+
+ static SpecificResourceReferenceFinder CreateFinder()
+ {
+ SpecificResourceReferenceFinder finder = new SpecificResourceReferenceFinder("C:\\TestResources.resx", "TestKey");
+ Assert.AreEqual(finder.ResourceFileName, "C:\\TestResources.resx");
+ Assert.AreEqual(finder.Key, "TestKey");
+ return finder;
+ }
+
+ [Test]
+ public void NoReference()
+ {
+ const string Code = @"class A {
+ void B() {
+ DoSomething();
+ }
+}";
+ SpecificResourceReferenceFinder finder = CreateFinder();
+ Assert.AreEqual(-1, finder.GetNextPossibleOffset("a.cs", Code, -1), "Incorrect offset.");
+ }
+
+ [Test]
+ public void OneReference()
+ {
+ const string Code = @"class A {
+ void B() {
+ resMgr.GetString(""TestKey"");
+ }
+}";
+ SpecificResourceReferenceFinder finder = CreateFinder();
+ Assert.AreEqual(44, finder.GetNextPossibleOffset("a.cs", Code, -1), "Incorrect offset.");
+ Assert.AreEqual(-1, finder.GetNextPossibleOffset("a.cs", Code, 44), "Incorrect offset.");
+ }
+
+ [Test]
+ public void TwoReferences()
+ {
+ const string Code = @"class A {
+ void B() {
+ resMgr.GetString(""TestKey"");
+ resMgr[""TestKey""];
+ }
+}";
+ SpecificResourceReferenceFinder finder = CreateFinder();
+ Assert.AreEqual(44, finder.GetNextPossibleOffset("a.cs", Code, -1), "Incorrect offset.");
+ Assert.AreEqual(66, finder.GetNextPossibleOffset("a.cs", Code, 44), "Incorrect offset.");
+ Assert.AreEqual(-1, finder.GetNextPossibleOffset("a.cs", Code, 66), "Incorrect offset.");
+ }
+
+ // ********************************************************************************************************************************
+
+ [Test]
+ public void ResultNoMatchWrongFile()
+ {
+ SpecificResourceReferenceFinder finder = CreateFinder();
+ Assert.IsFalse(finder.IsReferenceToResource(new ResourceResolveResult(null, null, null, new ResourceSetReference("SomeResources", "C:\\SomeResources.resx"), "TestKey")));
+ }
+
+ [Test]
+ public void ResultNoMatchWrongKey()
+ {
+ SpecificResourceReferenceFinder finder = CreateFinder();
+ Assert.IsFalse(finder.IsReferenceToResource(new ResourceResolveResult(null, null, null, new ResourceSetReference("TestResources", "C:\\TestResources.resx"), "SomeKey")));
+ }
+
+ [Test]
+ public void ResultMatch()
+ {
+ SpecificResourceReferenceFinder finder = CreateFinder();
+ Assert.IsTrue(finder.IsReferenceToResource(new ResourceResolveResult(null, null, null, new ResourceSetReference("TestResources", "C:\\TestResources.resx"), "TestKey")));
+ }
+ }
+}
diff --git a/src/AddIns/Misc/ResourceToolkit/Test/Properties/AssemblyInfo.cs b/src/AddIns/Misc/ResourceToolkit/Test/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..a3ecc1b316
--- /dev/null
+++ b/src/AddIns/Misc/ResourceToolkit/Test/Properties/AssemblyInfo.cs
@@ -0,0 +1,38 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+#region Using directives
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+#endregion
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ResourceToolkit Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SharpDevelop")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// This sets the default COM visibility of types in the assembly to invisible.
+// If you need to expose a type to COM, use [ComVisible(true)] on that type.
+[assembly: ComVisible(false)]
+
+// The assembly version has following format :
+//
+// Major.Minor.Build.Revision
+//
+// You can specify all the values or you can use the default the Revision and
+// Build Numbers by using the '*' as shown below:
+[assembly: AssemblyVersion("3.0.0.0")]
diff --git a/src/AddIns/Misc/ResourceToolkit/Test/ResourceToolkit.Tests.csproj b/src/AddIns/Misc/ResourceToolkit/Test/ResourceToolkit.Tests.csproj
new file mode 100644
index 0000000000..0de4c40c66
--- /dev/null
+++ b/src/AddIns/Misc/ResourceToolkit/Test/ResourceToolkit.Tests.csproj
@@ -0,0 +1,93 @@
+
+
+ {DD9AE6A5-2B9D-443A-BC71-38BE578C36BD}
+ Debug
+ AnyCPU
+ Library
+ ResourceToolkit.Tests
+ ResourceToolkit.Tests
+ v3.5
+ Properties
+ ..\..\..\..\..\bin\UnitTests\
+ False
+ False
+ True
+ False
+ 4
+ false
+
+
+ true
+ Full
+ DEBUG;TRACE
+
+
+ False
+ None
+ TRACE
+
+
+ False
+ Auto
+ 4194304
+ AnyCPU
+ 4096
+
+
+
+
+ ..\..\..\..\Tools\NUnit\nunit.framework.dll
+
+
+
+ 3.5
+
+
+
+ 3.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}
+ ICSharpCode.TextEditor
+
+
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}
+ ICSharpCode.SharpDevelop
+
+
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}
+ ICSharpCode.Core
+
+
+ {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}
+ ICSharpCode.SharpDevelop.Dom
+
+
+ {1F1AC7CD-D154-45BB-8EAF-804CA8055F5A}
+ CSharpBinding
+
+
+ {BF38FB72-B380-4196-AF8C-95749D726C61}
+ VBNetBinding
+
+
+ {461606BD-E824-4D0A-8CBA-01810B1F5E02}
+ ResourceToolkit
+
+
+
+
\ No newline at end of file
diff --git a/src/AddIns/Misc/ResourceToolkit/Test/TestHelper.cs b/src/AddIns/Misc/ResourceToolkit/Test/TestHelper.cs
new file mode 100644
index 0000000000..fe8fc6495c
--- /dev/null
+++ b/src/AddIns/Misc/ResourceToolkit/Test/TestHelper.cs
@@ -0,0 +1,97 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using Hornung.ResourceToolkit;
+using Hornung.ResourceToolkit.Resolver;
+using ICSharpCode.SharpDevelop.Dom;
+using NUnit.Framework;
+
+namespace ResourceToolkit.Tests
+{
+ static class TestHelper
+ {
+ public static void InitializeResolvers()
+ {
+ NRefactoryResourceResolver.SetResourceResolversListUnitTestOnly(
+ new INRefactoryResourceResolver[] {
+ new BclNRefactoryResourceResolver(),
+ new ICSharpCodeCoreNRefactoryResourceResolver()
+ });
+ ResourceResolverService.SetResourceResolversListUnitTestOnly(
+ new IResourceResolver[] {
+ new NRefactoryResourceResolver(),
+ new ICSharpCodeCoreResourceResolver()
+ });
+ }
+
+ public static void InitializeParsers()
+ {
+ Dictionary parsers = new Dictionary();
+ parsers.Add(".cs", new CSharpBinding.Parser.TParser());
+ parsers.Add(".vb", new VBNetBinding.Parser.TParser());
+ ResourceResolverService.SetParsersUnitTestOnly(parsers);
+ }
+
+ public static void CheckReference(ResourceResolveResult result, string expectedResourceSetName, string expectedKey, string expectedCallingClassFullName, string expectedCallingMemberFullName)
+ {
+ Assert.IsNotNull(result, "Resource reference should be detected.");
+
+ if (expectedResourceSetName == null) {
+
+ Assert.IsNull(result.ResourceSetReference, "Resource set reference should not be detected.");
+
+ } else {
+
+ Assert.IsNotNull(result.ResourceSetReference, "Resource set reference should be detected.");
+ Assert.IsNotNull(result.ResourceSetReference.ResourceSetName, "Resource set name must not be null.");
+ Assert.AreEqual(expectedResourceSetName, result.ResourceSetReference.ResourceSetName, "Incorrect resource set name.");
+
+ }
+
+ if (expectedKey == null) {
+
+ Assert.IsNull(result.Key, "Resource key should not be detected.");
+
+ } else {
+
+ Assert.IsNotNull(result.Key, "Resource key should be detected.");
+ Assert.AreEqual(expectedKey, result.Key, "Incorrect resource key.");
+
+ }
+
+ if (expectedCallingClassFullName == null) {
+
+ Assert.IsNull(result.CallingClass, "Calling class should not be detected.");
+
+ } else {
+
+ Assert.IsNotNull(result.CallingClass, "Calling class should be detected.");
+ Assert.AreEqual(expectedCallingClassFullName, result.CallingClass.FullyQualifiedName, "Incorrect calling class.");
+
+ }
+
+ if (expectedCallingMemberFullName == null) {
+
+ Assert.IsNull(result.CallingMember, "Calling member should not be detected.");
+
+ } else {
+
+ Assert.IsNotNull(result.CallingMember, "Calling member should be detected.");
+ Assert.AreEqual(expectedCallingMemberFullName, result.CallingMember.FullyQualifiedName, "Incorrect calling member.");
+
+ }
+ }
+
+ public static void CheckNoReference(ResourceResolveResult result)
+ {
+ Assert.IsNull(result, "Resource reference should not be detected.");
+ }
+ }
+}
diff --git a/src/SharpDevelop.Tests.sln b/src/SharpDevelop.Tests.sln
index 820bc830de..90ad1edf4f 100644
--- a/src/SharpDevelop.Tests.sln
+++ b/src/SharpDevelop.Tests.sln
@@ -1,11 +1,15 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
-# SharpDevelop 3.0.0.3264
+# SharpDevelop 3.0.0.3278
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AddIns", "AddIns", "{14A277EE-7DF1-4529-B639-7D1EF334C1C5}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceToolkit.Tests", "AddIns\Misc\ResourceToolkit\Test\ResourceToolkit.Tests.csproj", "{DD9AE6A5-2B9D-443A-BC71-38BE578C36BD}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceToolkit", "AddIns\Misc\ResourceToolkit\Project\ResourceToolkit.csproj", "{461606BD-E824-4D0A-8CBA-01810B1F5E02}"
+EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Boo", "Boo", "{5DA95927-5F2D-46D8-9265-D092734B6F0E}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
@@ -318,6 +322,14 @@ Global
{7DB80259-24D4-46C3-A024-53FF1987733D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7DB80259-24D4-46C3-A024-53FF1987733D}.Release|Any CPU.Build.0 = Release|Any CPU
{7DB80259-24D4-46C3-A024-53FF1987733D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {461606BD-E824-4D0A-8CBA-01810B1F5E02}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {461606BD-E824-4D0A-8CBA-01810B1F5E02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {461606BD-E824-4D0A-8CBA-01810B1F5E02}.Release|Any CPU.Build.0 = Release|Any CPU
+ {461606BD-E824-4D0A-8CBA-01810B1F5E02}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DD9AE6A5-2B9D-443A-BC71-38BE578C36BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DD9AE6A5-2B9D-443A-BC71-38BE578C36BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DD9AE6A5-2B9D-443A-BC71-38BE578C36BD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DD9AE6A5-2B9D-443A-BC71-38BE578C36BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -342,6 +354,8 @@ Global
{9196DD8A-B4D4-4780-8742-C5762E547FC2} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5}
{A569DCC1-C608-45FD-B770-4F79335EF154} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5}
{5DA95927-5F2D-46D8-9265-D092734B6F0E} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5}
+ {461606BD-E824-4D0A-8CBA-01810B1F5E02} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5}
+ {DD9AE6A5-2B9D-443A-BC71-38BE578C36BD} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5}
{4AC2D5F1-F671-480C-A075-6BF62B3721B2} = {5DA95927-5F2D-46D8-9265-D092734B6F0E}
{6FA16499-896F-4C02-BB43-1AF5C6C7C713} = {5DA95927-5F2D-46D8-9265-D092734B6F0E}
{DBCF20A1-BA13-4582-BFA9-74DE4D987B73} = {5DA95927-5F2D-46D8-9265-D092734B6F0E}