Browse Source

Add GetInterestingFileNames to FindReferences.

Fixed a few resolver issues related to find references.
newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
46676a45fb
  1. 2
      ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs
  2. 4
      ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs
  3. 7
      ICSharpCode.NRefactory/CSharp/Resolver/FindReferencedEntities.cs
  4. 121
      ICSharpCode.NRefactory/CSharp/Resolver/FindReferences.cs
  5. 140
      ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs
  6. 6
      ICSharpCode.NRefactory/TypeSystem/IEntity.cs
  7. 4
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractMember.cs
  8. 10
      ICSharpCode.NRefactory/TypeSystem/Implementation/CompoundTypeDefinition.cs
  9. 21
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs
  10. 4
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMember.cs

2
ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs

@ -175,7 +175,7 @@ namespace ICSharpCode.NRefactory.CSharp
newType.TypeParameters.AddRange(currentTypeDefinition.TypeParameters); newType.TypeParameters.AddRange(currentTypeDefinition.TypeParameters);
currentTypeDefinition.NestedTypes.Add(newType); currentTypeDefinition.NestedTypes.Add(newType);
} else { } else {
newType = new DefaultTypeDefinition(usingScope.ProjectContent, usingScope.NamespaceName, name); newType = new DefaultTypeDefinition(parsedFile, usingScope.NamespaceName, name);
parsedFile.TopLevelTypeDefinitions.Add(newType); parsedFile.TopLevelTypeDefinitions.Add(newType);
} }
return newType; return newType;

4
ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs

@ -553,6 +553,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
get { throw new NotSupportedException(); } get { throw new NotSupportedException(); }
} }
IParsedFile IEntity.ParsedFile {
get { return null; }
}
string INamedElement.FullName { string INamedElement.FullName {
get { return "operator"; } get { return "operator"; }
} }

7
ICSharpCode.NRefactory/CSharp/Resolver/FindReferencedEntities.cs

@ -42,9 +42,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public void Resolved(AstNode node, ResolveResult result) public void Resolved(AstNode node, ResolveResult result)
{ {
if (ResolveVisitor.ActsAsParenthesizedExpression(node))
return;
MemberResolveResult mrr = result as MemberResolveResult; MemberResolveResult mrr = result as MemberResolveResult;
if (mrr != null) { if (mrr != null) {
referenceFound(node, mrr.Member); referenceFound(node, mrr.Member.MemberDefinition);
} }
TypeResolveResult trr = result as TypeResolveResult; TypeResolveResult trr = result as TypeResolveResult;
if (trr != null) { if (trr != null) {
@ -57,7 +60,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType) public void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
{ {
if (conversion.IsUserDefined || conversion.IsMethodGroupConversion) { if (conversion.IsUserDefined || conversion.IsMethodGroupConversion) {
referenceFound(expression, conversion.Method); referenceFound(expression, conversion.Method.MemberDefinition);
} }
} }
} }

121
ICSharpCode.NRefactory/CSharp/Resolver/FindReferences.cs

@ -20,7 +20,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using ICSharpCode.Editor;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.CSharp.Resolver namespace ICSharpCode.NRefactory.CSharp.Resolver
{ {
@ -43,6 +45,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
#endregion #endregion
#region Properties
/// <summary>
/// Gets/Sets whether to find type references even if an alias is being used.
/// </summary>
public bool FindTypeReferencesEvenIfAliased { get; set; }
#endregion
#region GetEffectiveAccessibility #region GetEffectiveAccessibility
/// <summary> /// <summary>
/// Gets the effective accessibility of the specified entity - /// Gets the effective accessibility of the specified entity -
@ -94,7 +103,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{ {
protected string searchTerm; protected string searchTerm;
internal Accessibility accessibility; internal Accessibility accessibility;
internal IEntity topLevelEntity; internal ITypeDefinition topLevelTypeDefinition;
internal FindReferences findReferences; internal FindReferences findReferences;
/// <summary> /// <summary>
@ -111,7 +120,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// <summary> /// <summary>
/// Gets the top-level entity that defines the search scope. /// Gets the top-level entity that defines the search scope.
/// </summary> /// </summary>
public IEntity TopLevelEntity { get { return topLevelEntity; } } public ITypeDefinition TopLevelTypeDefinition { get { return topLevelTypeDefinition; } }
internal abstract bool CanMatch(AstNode node); internal abstract bool CanMatch(AstNode node);
internal abstract bool IsMatch(ResolveResult rr); internal abstract bool IsMatch(ResolveResult rr);
@ -155,17 +164,20 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (entity == null) if (entity == null)
throw new ArgumentNullException("entity"); throw new ArgumentNullException("entity");
Accessibility effectiveAccessibility = GetEffectiveAccessibility(entity); Accessibility effectiveAccessibility = GetEffectiveAccessibility(entity);
IEntity topLevelEntity = entity; ITypeDefinition topLevelTypeDefinition = entity.DeclaringTypeDefinition;
while (topLevelEntity.DeclaringTypeDefinition != null) while (topLevelTypeDefinition != null && topLevelTypeDefinition.DeclaringTypeDefinition != null)
topLevelEntity = topLevelEntity.DeclaringTypeDefinition; topLevelTypeDefinition = topLevelTypeDefinition.DeclaringTypeDefinition;
SearchScope scope; SearchScope scope;
SearchScope additionalScope = null; SearchScope additionalScope = null;
switch (entity.EntityType) { switch (entity.EntityType) {
case EntityType.TypeDefinition: case EntityType.TypeDefinition:
scope = new FindTypeDefinitionReferences((ITypeDefinition)entity); scope = new FindTypeDefinitionReferences((ITypeDefinition)entity, this.FindTypeReferencesEvenIfAliased);
break; break;
case EntityType.Field: case EntityType.Field:
scope = new FindFieldReferences((IField)entity); if (entity.DeclaringTypeDefinition != null && entity.DeclaringTypeDefinition.Kind == TypeKind.Enum)
scope = new FindEnumMemberReferences((IField)entity);
else
scope = new FindFieldReferences((IField)entity);
break; break;
case EntityType.Property: case EntityType.Property:
scope = new FindPropertyReferences((IProperty)entity); scope = new FindPropertyReferences((IProperty)entity);
@ -194,12 +206,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
if (scope.accessibility == Accessibility.None) if (scope.accessibility == Accessibility.None)
scope.accessibility = effectiveAccessibility; scope.accessibility = effectiveAccessibility;
scope.topLevelEntity = topLevelEntity; scope.topLevelTypeDefinition = topLevelTypeDefinition;
scope.findReferences = this; scope.findReferences = this;
if (additionalScope != null) { if (additionalScope != null) {
if (additionalScope.accessibility == Accessibility.None) if (additionalScope.accessibility == Accessibility.None)
additionalScope.accessibility = effectiveAccessibility; additionalScope.accessibility = effectiveAccessibility;
additionalScope.topLevelEntity = topLevelEntity; additionalScope.topLevelTypeDefinition = topLevelTypeDefinition;
additionalScope.findReferences = this; additionalScope.findReferences = this;
return new[] { scope, additionalScope }; return new[] { scope, additionalScope };
} else { } else {
@ -208,11 +220,77 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
#endregion #endregion
#region FindReferencesInSolution
/// <summary>
/// Gets the file names that possibly contain references to the element being searched for.
/// </summary>
public IEnumerable<string> GetInterestingFileNames(SearchScope searchScope, ITypeResolveContext context)
{
IEnumerable<ITypeDefinition> interestingTypes;
if (searchScope.TopLevelTypeDefinition != null) {
switch (searchScope.Accessibility) {
case Accessibility.None:
case Accessibility.Private:
interestingTypes = new [] { searchScope.TopLevelTypeDefinition.GetDefinition() };
break;
case Accessibility.Protected:
interestingTypes = GetInterestingTypesProtected(context, searchScope.TopLevelTypeDefinition);
break;
case Accessibility.Internal:
interestingTypes = GetInterestingTypesInternal(context, searchScope.TopLevelTypeDefinition.ProjectContent);
break;
case Accessibility.ProtectedAndInternal:
interestingTypes = GetInterestingTypesProtected(context, searchScope.TopLevelTypeDefinition)
.Intersect(GetInterestingTypesInternal(context, searchScope.TopLevelTypeDefinition.ProjectContent));
break;
case Accessibility.ProtectedOrInternal:
interestingTypes = GetInterestingTypesProtected(context, searchScope.TopLevelTypeDefinition)
.Union(GetInterestingTypesInternal(context, searchScope.TopLevelTypeDefinition.ProjectContent));
break;
default:
interestingTypes = context.GetTypes();
break;
}
} else {
interestingTypes = context.GetTypes();
}
return (from typeDef in interestingTypes
from part in typeDef.GetParts()
where part.ParsedFile != null
select part.ParsedFile.FileName
).Distinct(Platform.FileNameComparer);
}
IEnumerable<ITypeDefinition> GetInterestingTypesProtected(ITypeResolveContext context, ITypeDefinition referencedTypeDefinition)
{
return referencedTypeDefinition.GetSubTypeDefinitions(context);
}
IEnumerable<ITypeDefinition> GetInterestingTypesInternal(ITypeResolveContext context, IProjectContent referencedProjectContent)
{
return context.GetTypes().Where(t => referencedProjectContent.InternalsVisibleTo(t.ProjectContent, context));
}
#endregion
#region FindReferencesInFile #region FindReferencesInFile
/// <summary> /// <summary>
/// Finds all references in the given file. /// Finds all references in the given file.
/// </summary> /// </summary>
/// <param name="searchScope">The search scopes for which to look.</param> /// <param name="searchScope">The search scope for which to look.</param>
/// <param name="parsedFile">The type system representation of the file being searched.</param>
/// <param name="compilationUnit">The compilation unit of the file being searched.</param>
/// <param name="context">The type resolve context to use for resolving the file.</param>
public void FindReferencesInFile(SearchScope searchScope, ParsedFile parsedFile, CompilationUnit compilationUnit, ITypeResolveContext context)
{
if (searchScope == null)
throw new ArgumentNullException("searchScope");
FindReferencesInFile(new[] { searchScope }, parsedFile, compilationUnit, context);
}
/// <summary>
/// Finds all references in the given file.
/// </summary>
/// <param name="searchScopes">The search scopes for which to look.</param>
/// <param name="parsedFile">The type system representation of the file being searched.</param> /// <param name="parsedFile">The type system representation of the file being searched.</param>
/// <param name="compilationUnit">The compilation unit of the file being searched.</param> /// <param name="compilationUnit">The compilation unit of the file being searched.</param>
/// <param name="context">The type resolve context to use for resolving the file.</param> /// <param name="context">The type resolve context to use for resolving the file.</param>
@ -252,10 +330,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{ {
ITypeDefinition typeDefinition; ITypeDefinition typeDefinition;
public FindTypeDefinitionReferences(ITypeDefinition typeDefinition) public FindTypeDefinitionReferences(ITypeDefinition typeDefinition, bool findTypeReferencesEvenIfAliased)
{ {
this.typeDefinition = typeDefinition; this.typeDefinition = typeDefinition;
if (ReflectionHelper.GetTypeCode(typeDefinition) == TypeCode.Empty) { if (!findTypeReferencesEvenIfAliased && ReflectionHelper.GetTypeCode(typeDefinition) == TypeCode.Empty) {
// not a built-in type // not a built-in type
this.searchTerm = typeDefinition.Name; this.searchTerm = typeDefinition.Name;
} }
@ -282,7 +360,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (searchTerm == null && node is PrimitiveType) if (searchTerm == null && node is PrimitiveType)
return true; return true;
return false; return node is TypeDeclaration;
} }
internal override bool IsMatch(ResolveResult rr) internal override bool IsMatch(ResolveResult rr)
@ -340,7 +418,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
internal override bool CanMatch(AstNode node) internal override bool CanMatch(AstNode node)
{ {
return node is FieldDeclaration || base.CanMatch(node); return node is FieldDeclaration || node is VariableInitializer || base.CanMatch(node);
}
}
sealed class FindEnumMemberReferences : FindMemberReferences
{
public FindEnumMemberReferences(IField field) : base(field)
{
}
internal override bool CanMatch(AstNode node)
{
return node is EnumMemberDeclaration || base.CanMatch(node);
} }
} }
@ -607,7 +697,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
internal override bool IsMatch(ResolveResult rr) internal override bool IsMatch(ResolveResult rr)
{ {
return false; MemberResolveResult mrr = rr as MemberResolveResult;
return mrr != null && op == mrr.Member.MemberDefinition;
} }
internal override void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType) internal override void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)

140
ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs

@ -174,6 +174,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// lambdas must be resolved so that they get stored in the 'undecided' list only once // lambdas must be resolved so that they get stored in the 'undecided' list only once
goto case ResolveVisitorNavigationMode.Resolve; goto case ResolveVisitorNavigationMode.Resolve;
} }
// We shouldn't scan nodes that were already resolved.
Debug.Assert(!resolveResultCache.ContainsKey(node));
// Doing so should be harmless since we allow scanning twice, but it indicates
// a bug in the logic that causes the scan.
bool oldResolverEnabled = resolverEnabled; bool oldResolverEnabled = resolverEnabled;
resolverEnabled = false; resolverEnabled = false;
StoreState(node, resolver.Clone()); StoreState(node, resolver.Clone());
@ -231,6 +237,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Debug.Assert(result != null); Debug.Assert(result != null);
if (node.IsNull) if (node.IsNull)
return; return;
Debug.Assert(!resolveResultCache.ContainsKey(node));
resolveResultCache.Add(node, result); resolveResultCache.Add(node, result);
if (navigator != null) if (navigator != null)
navigator.Resolved(node, result); navigator.Resolved(node, result);
@ -1631,7 +1638,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var lambda = new ExplicitlyTypedLambda(parameters, isAnonymousMethod, resolver.Clone(), this, body); var lambda = new ExplicitlyTypedLambda(parameters, isAnonymousMethod, resolver.Clone(), this, body);
Scan(body); // Don't scan the lambda body here - we'll do that later when analyzing the ExplicitlyTypedLambda.
resolver.PopBlock(); resolver.PopBlock();
return lambda; return lambda;
@ -2263,12 +2270,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult IAstVisitor<object, ResolveResult>.VisitFixedStatement(FixedStatement fixedStatement, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitFixedStatement(FixedStatement fixedStatement, object data)
{ {
resolver.PushBlock(); resolver.PushBlock();
ITypeReference type = MakeTypeReference(fixedStatement.Type);
VariableInitializer firstInitializer = fixedStatement.Variables.FirstOrDefault();
ITypeReference type = MakeTypeReference(fixedStatement.Type,
firstInitializer != null ? firstInitializer.Initializer : null,
false);
for (AstNode node = fixedStatement.FirstChild; node != null; node = node.NextSibling) { for (AstNode node = fixedStatement.FirstChild; node != null; node = node.NextSibling) {
if (node.Role == FixedStatement.Roles.Variable) { if (node.Role == FixedStatement.Roles.Variable) {
VariableInitializer vi = (VariableInitializer)node; VariableInitializer vi = (VariableInitializer)node;
@ -2283,10 +2285,23 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult IAstVisitor<object, ResolveResult>.VisitForeachStatement(ForeachStatement foreachStatement, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitForeachStatement(ForeachStatement foreachStatement, object data)
{ {
resolver.PushBlock(); resolver.PushBlock();
ITypeReference type = MakeTypeReference(foreachStatement.VariableType, foreachStatement.InExpression, true); ITypeReference type;
if (IsVar(foreachStatement.VariableType)) {
if (navigator.Scan(foreachStatement.VariableType) == ResolveVisitorNavigationMode.Resolve) {
IType collectionType = Resolve(foreachStatement.InExpression).Type;
IType elementType = GetElementType(collectionType, resolver.Context, false);
StoreResult(foreachStatement.VariableType, new TypeResolveResult(elementType));
type = elementType;
} else {
Scan(foreachStatement.InExpression);
type = MakeVarTypeReference(foreachStatement.InExpression, true);
}
} else {
type = ResolveType(foreachStatement.VariableType);
}
IVariable v = resolver.AddVariable(type, MakeRegion(foreachStatement.VariableNameToken), foreachStatement.VariableName); IVariable v = resolver.AddVariable(type, MakeRegion(foreachStatement.VariableNameToken), foreachStatement.VariableName);
StoreResult(foreachStatement.VariableNameToken, new LocalResolveResult(v, v.Type.Resolve(resolver.Context))); StoreResult(foreachStatement.VariableNameToken, new LocalResolveResult(v, v.Type.Resolve(resolver.Context)));
ScanChildren(foreachStatement); Scan(foreachStatement.EmbeddedStatement);
resolver.PopBlock(); resolver.PopBlock();
return voidResult; return voidResult;
} }
@ -2302,8 +2317,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult IAstVisitor<object, ResolveResult>.VisitCatchClause(CatchClause catchClause, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitCatchClause(CatchClause catchClause, object data)
{ {
resolver.PushBlock(); resolver.PushBlock();
if (catchClause.VariableName != null) { if (!string.IsNullOrEmpty(catchClause.VariableName)) {
ITypeReference variableType = MakeTypeReference(catchClause.Type, null, false); ITypeReference variableType = MakeTypeReference(catchClause.Type);
DomRegion region = MakeRegion(catchClause.VariableNameToken); DomRegion region = MakeRegion(catchClause.VariableNameToken);
IVariable v = resolver.AddVariable(variableType, region, catchClause.VariableName); IVariable v = resolver.AddVariable(variableType, region, catchClause.VariableName);
StoreResult(catchClause.VariableNameToken, new LocalResolveResult(v, v.Type.Resolve(resolver.Context))); StoreResult(catchClause.VariableNameToken, new LocalResolveResult(v, v.Type.Resolve(resolver.Context)));
@ -2318,33 +2333,56 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult IAstVisitor<object, ResolveResult>.VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement, object data)
{ {
bool isConst = (variableDeclarationStatement.Modifiers & Modifiers.Const) != 0; bool isConst = (variableDeclarationStatement.Modifiers & Modifiers.Const) != 0;
VariableInitializer firstInitializer = variableDeclarationStatement.Variables.FirstOrDefault(); if (!isConst && IsVar(variableDeclarationStatement.Type) && variableDeclarationStatement.Variables.Count == 1) {
ITypeReference type = MakeTypeReference(variableDeclarationStatement.Type, VariableInitializer vi = variableDeclarationStatement.Variables.Single();
firstInitializer != null ? firstInitializer.Initializer : null, bool needResolve = resolverEnabled
false); || navigator.Scan(variableDeclarationStatement.Type) == ResolveVisitorNavigationMode.Resolve
|| navigator.Scan(vi) == ResolveVisitorNavigationMode.Resolve;
int initializerCount = variableDeclarationStatement.Variables.Count; ITypeReference type;
ResolveResult result = null; if (needResolve) {
for (AstNode node = variableDeclarationStatement.FirstChild; node != null; node = node.NextSibling) { type = Resolve(vi.Initializer).Type;
if (node.Role == VariableDeclarationStatement.Roles.Variable) { } else {
VariableInitializer vi = (VariableInitializer)node; Scan(vi.Initializer);
type = MakeVarTypeReference(vi.Initializer, false);
IConstantValue cv = null; }
if (isConst) { IVariable v = resolver.AddVariable(type, MakeRegion(vi), vi.Name);
cv = TypeSystemConvertVisitor.ConvertConstantValue(type, vi.Initializer, resolver.CurrentTypeDefinition, resolver.CurrentMember as IMethod, resolver.CurrentUsingScope); StoreState(vi, resolver.Clone());
if (needResolve) {
ResolveResult result;
if (!resolveResultCache.TryGetValue(vi, out result)) {
result = new LocalResolveResult(v, type.Resolve(resolver.Context));
StoreResult(vi, result);
} }
resolver.AddVariable(type, MakeRegion(vi), vi.Name, cv); return result;
} else {
if (resolverEnabled && initializerCount == 1) { return null;
result = Resolve(node); }
} else {
ITypeReference type = MakeTypeReference(variableDeclarationStatement.Type);
int initializerCount = variableDeclarationStatement.Variables.Count;
ResolveResult result = null;
for (AstNode node = variableDeclarationStatement.FirstChild; node != null; node = node.NextSibling) {
if (node.Role == VariableDeclarationStatement.Roles.Variable) {
VariableInitializer vi = (VariableInitializer)node;
IConstantValue cv = null;
if (isConst) {
cv = TypeSystemConvertVisitor.ConvertConstantValue(type, vi.Initializer, resolver.CurrentTypeDefinition, resolver.CurrentMember as IMethod, resolver.CurrentUsingScope);
}
resolver.AddVariable(type, MakeRegion(vi), vi.Name, cv);
if (resolverEnabled && initializerCount == 1) {
result = Resolve(node);
} else {
Scan(node);
}
} else { } else {
Scan(node); Scan(node);
} }
} else {
Scan(node);
} }
return result;
} }
return result;
} }
#endregion #endregion
@ -2488,39 +2526,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endregion #endregion
#region Local Variable Type Inference #region Local Variable Type Inference
/// <summary>
/// Creates a type reference for the specified type node.
/// If the type node is 'var', performs type inference on the initializer expression.
/// </summary>
ITypeReference MakeTypeReference(AstType type, AstNode initializerExpression, bool isForEach)
{
bool typeNeedsResolving = (navigator.Scan(type) == ResolveVisitorNavigationMode.Resolve);
if (initializerExpression != null && IsVar(type)) {
var typeRef = new VarTypeReference(this, resolver.Clone(), initializerExpression, isForEach);
if (typeNeedsResolving) {
// Hack: I don't see a clean way to make the 'var' SimpleType resolve to the inferred type,
// so we just do it here and store the result in the resolver cache.
IType actualType = typeRef.Resolve(resolver.Context);
if (actualType.Kind != TypeKind.Unknown) {
StoreResult(type, new TypeResolveResult(actualType));
} else {
StoreResult(type, errorResult);
}
return actualType;
} else {
return typeRef;
}
} else {
// Perf: avoid duplicate resolving of the type (once as ITypeReference, once directly in ResolveVisitor)
// if possible. By using ResolveType when we know we need to resolve the node anyways, the resolve cache
// can take care of the duplicate call.
if (typeNeedsResolving)
return ResolveType(type);
else
return MakeTypeReference(type);
}
}
static bool IsVar(AstType returnType) static bool IsVar(AstType returnType)
{ {
SimpleType st = returnType as SimpleType; SimpleType st = returnType as SimpleType;
@ -2532,6 +2537,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return TypeSystemConvertVisitor.ConvertType(type, resolver.CurrentTypeDefinition, resolver.CurrentMember as IMethod, resolver.CurrentUsingScope, currentTypeLookupMode); return TypeSystemConvertVisitor.ConvertType(type, resolver.CurrentTypeDefinition, resolver.CurrentMember as IMethod, resolver.CurrentUsingScope, currentTypeLookupMode);
} }
ITypeReference MakeVarTypeReference(Expression initializer, bool isForEach)
{
return new VarTypeReference(this, resolver.Clone(), initializer, isForEach);
}
sealed class VarTypeReference : ITypeReference sealed class VarTypeReference : ITypeReference
{ {
ResolveVisitor visitor; ResolveVisitor visitor;

6
ICSharpCode.NRefactory/TypeSystem/IEntity.cs

@ -137,6 +137,12 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary> /// </summary>
IProjectContent ProjectContent { get; } IProjectContent ProjectContent { get; }
/// <summary>
/// Gets the parsed file in which this entity is defined.
/// Returns null if this entity wasn't parsed (loaded with CecilLoader).
/// </summary>
IParsedFile ParsedFile { get; }
//bool IsAccessible(IClass callingClass, bool isAccessThoughReferenceOfCurrentClass); //bool IsAccessible(IClass callingClass, bool isAccessThoughReferenceOfCurrentClass);
} }

4
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractMember.cs

@ -271,6 +271,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return declaringTypeDefinition.ProjectContent; } get { return declaringTypeDefinition.ProjectContent; }
} }
public IParsedFile ParsedFile {
get { return declaringTypeDefinition.ParsedFile; }
}
public string Name { public string Name {
get { return name; } get { return name; }
set { set {

10
ICSharpCode.NRefactory/TypeSystem/Implementation/CompoundTypeDefinition.cs

@ -35,6 +35,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{ {
} }
private CompoundTypeDefinition(IParsedFile parsedFile, string ns, string name)
: base(parsedFile, ns, name)
{
}
private CompoundTypeDefinition(IProjectContent projectContent, string ns, string name) private CompoundTypeDefinition(IProjectContent projectContent, string ns, string name)
: base(projectContent, ns, name) : base(projectContent, ns, name)
{ {
@ -74,7 +79,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
if (mainPart.DeclaringTypeDefinition != null) { if (mainPart.DeclaringTypeDefinition != null) {
throw new NotImplementedException("nested compound types not implemented"); throw new NotImplementedException("nested compound types not implemented");
} else { } else {
compound = new CompoundTypeDefinition(mainPart.ProjectContent, mainPart.Namespace, mainPart.Name); if (mainPart.ParsedFile != null)
compound = new CompoundTypeDefinition(mainPart.ParsedFile, mainPart.Namespace, mainPart.Name);
else
compound = new CompoundTypeDefinition(mainPart.ProjectContent, mainPart.Namespace, mainPart.Name);
} }
compound.parts = parts; compound.parts = parts;
compound.Region = mainPart.Region; compound.Region = mainPart.Region;

21
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs

@ -29,6 +29,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public class DefaultTypeDefinition : AbstractFreezable, ITypeDefinition public class DefaultTypeDefinition : AbstractFreezable, ITypeDefinition
{ {
readonly IProjectContent projectContent; readonly IProjectContent projectContent;
readonly IParsedFile parsedFile;
readonly ITypeDefinition declaringTypeDefinition; readonly ITypeDefinition declaringTypeDefinition;
volatile ITypeDefinition compoundTypeDefinition; volatile ITypeDefinition compoundTypeDefinition;
@ -79,13 +80,29 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
if (string.IsNullOrEmpty(name)) if (string.IsNullOrEmpty(name))
throw new ArgumentException("name"); throw new ArgumentException("name");
this.projectContent = declaringTypeDefinition.ProjectContent; this.projectContent = declaringTypeDefinition.ProjectContent;
this.parsedFile = declaringTypeDefinition.ParsedFile;
this.declaringTypeDefinition = declaringTypeDefinition; this.declaringTypeDefinition = declaringTypeDefinition;
this.name = name; this.name = name;
this.ns = declaringTypeDefinition.Namespace; this.ns = declaringTypeDefinition.Namespace;
this.compoundTypeDefinition = this; this.compoundTypeDefinition = this;
} }
public DefaultTypeDefinition(IParsedFile parsedFile, string ns, string name)
{
if (parsedFile == null)
throw new ArgumentNullException("parsedFile");
if (string.IsNullOrEmpty(name))
throw new ArgumentException("name");
this.parsedFile = parsedFile;
this.projectContent = parsedFile.ProjectContent;
this.ns = ns ?? string.Empty;
this.name = name;
this.compoundTypeDefinition = this;
}
public DefaultTypeDefinition(IProjectContent projectContent, string ns, string name) public DefaultTypeDefinition(IProjectContent projectContent, string ns, string name)
{ {
if (projectContent == null) if (projectContent == null)
@ -377,6 +394,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return projectContent; } get { return projectContent; }
} }
public IParsedFile ParsedFile {
get { return parsedFile; }
}
public IEnumerable<IType> GetBaseTypes(ITypeResolveContext context) public IEnumerable<IType> GetBaseTypes(ITypeResolveContext context)
{ {
ITypeDefinition compound = this.compoundTypeDefinition; ITypeDefinition compound = this.compoundTypeDefinition;

4
ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMember.cs

@ -171,6 +171,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return memberDefinition.ProjectContent; } get { return memberDefinition.ProjectContent; }
} }
public IParsedFile ParsedFile {
get { return memberDefinition.ParsedFile; }
}
public string FullName { public string FullName {
get { return memberDefinition.FullName; } get { return memberDefinition.FullName; }
} }

Loading…
Cancel
Save