📄 refactoringservice.cs
字号:
/// </summary>
/// <returns><c>true</c>, if the expression was an indexer expression and has been changed, <c>false</c> otherwise.</returns>
public static bool FixIndexerExpression(IExpressionFinder expressionFinder, ref ExpressionResult expr, MemberResolveResult mrr)
{
if (mrr != null && mrr.ResolvedMember is IProperty && ((IProperty)mrr.ResolvedMember).IsIndexer) {
// we got an indexer call as expression ("objectList[0].ToString()[2]")
// strip the index from the expression to resolve the underlying expression
string newExpr = expressionFinder.RemoveLastPart(expr.Expression);
if (newExpr.Length >= expr.Expression.Length) {
throw new ApplicationException("new expression must be shorter than old expression");
}
expr.Expression = newExpr;
return true;
}
return false;
}
/// <summary>
/// Determines the token that denotes a possible beginning of an indexer
/// expression in the specified file.
/// </summary>
static string GetIndexerExpressionStartToken(string fileName)
{
if (fileName != null) {
ParseInformation pi = ParserService.GetParseInformation(fileName);
if (pi != null &&
pi.MostRecentCompilationUnit != null &&
pi.MostRecentCompilationUnit.ProjectContent != null &&
pi.MostRecentCompilationUnit.ProjectContent.Language != null) {
return pi.MostRecentCompilationUnit.ProjectContent.Language.IndexerExpressionStartToken;
}
}
LoggingService.Warn("RefactoringService: unable to determine the correct indexer expression start token for file '"+fileName+"'");
return LanguageProperties.CSharp.IndexerExpressionStartToken;
}
static Point GetPosition(string fileContent, int pos)
{
int line = 1;
int column = 0;
for (int i = 0; i < pos; ++i) {
if (fileContent[i] == '\n') {
++line;
column = 0;
} else {
++column;
}
}
return new Point(column, line);
}
public static List<string> GetFileNames(IClass c)
{
List<string> list = new List<string>();
CompoundClass cc = c as CompoundClass;
if (cc != null) {
foreach (IClass part in cc.Parts) {
string fileName = part.CompilationUnit.FileName;
if (fileName != null)
list.Add(fileName);
}
} else {
string fileName = c.CompilationUnit.FileName;
if (fileName != null)
list.Add(fileName);
}
return list;
}
/// <summary>
/// Gets the files of files that could have a reference to the <paramref name="member"/>
/// int the <paramref name="ownerClass"/>.
/// </summary>
static List<ProjectItem> GetPossibleFiles(IClass ownerClass, IDecoration member)
{
List<ProjectItem> resultList = new List<ProjectItem>();
if (ProjectService.OpenSolution == null) {
FileProjectItem tempItem = new FileProjectItem(null, ItemType.Compile);
tempItem.Include = ownerClass.CompilationUnit.FileName;
resultList.Add(tempItem);
return resultList;
}
if (member == null) {
// get files possibly referencing ownerClass
while (ownerClass.DeclaringType != null) {
// for nested classes, treat class as member
member = ownerClass;
ownerClass = ownerClass.DeclaringType;
}
if (member == null) {
GetPossibleFilesInternal(resultList, ownerClass.ProjectContent, ownerClass.IsInternal);
return resultList;
}
}
if (member.IsPrivate) {
List<string> fileNames = GetFileNames(ownerClass);
foreach (string fileName in fileNames) {
ProjectItem item = FindItem(fileName);
if (item != null) resultList.Add(item);
}
return resultList;
}
if (member.IsProtected) {
// TODO: Optimize when member is protected
}
GetPossibleFilesInternal(resultList, ownerClass.ProjectContent, ownerClass.IsInternal || member.IsInternal && !member.IsProtected);
return resultList;
}
static ProjectItem FindItem(string fileName)
{
if (ProjectService.OpenSolution != null) {
foreach (IProject p in ProjectService.OpenSolution.Projects) {
foreach (ProjectItem item in p.Items) {
if (FileUtility.IsEqualFileName(fileName, item.FileName)) {
return item;
}
}
}
}
FileProjectItem tempItem = new FileProjectItem(null, ItemType.Compile);
tempItem.Include = fileName;
return tempItem;
}
static void GetPossibleFilesInternal(List<ProjectItem> resultList, IProjectContent ownerProjectContent, bool internalOnly)
{
if (ProjectService.OpenSolution == null) {
return;
}
foreach (IProject p in ProjectService.OpenSolution.Projects) {
IProjectContent pc = ParserService.GetProjectContent(p);
if (pc == null) continue;
if (pc != ownerProjectContent) {
if (internalOnly) {
// internal = can be only referenced from same project content
continue;
}
if (!pc.ReferencedContents.Contains(ownerProjectContent)) {
// project contents that do not reference the owner's content cannot reference the member
continue;
}
}
foreach (ProjectItem item in p.Items) {
if (item.ItemType == ItemType.Compile) {
resultList.Add(item);
}
}
}
}
#endregion
public static bool IsReferenceToLocalVariable(ResolveResult rr, IMember variable)
{
LocalResolveResult local = rr as LocalResolveResult;
if (local == null) {
return false;
} else {
return local.Field.Region.BeginLine == variable.Region.BeginLine
&& local.Field.Region.BeginColumn == variable.Region.BeginColumn;
}
}
/// <summary>
/// Gets if <paramref name="rr"/> is a reference to <paramref name="member"/>.
/// </summary>
public static bool IsReferenceToMember(IMember member, ResolveResult rr)
{
MemberResolveResult mrr = rr as MemberResolveResult;
if (mrr != null) {
return IsSimilarMember(mrr.ResolvedMember, member);
} else if (rr is MethodResolveResult) {
return IsSimilarMember((rr as MethodResolveResult).GetMethodIfSingleOverload(), member);
} else {
return false;
}
}
/// <summary>
/// Gets if member1 is the same as member2 or if member1 overrides member2.
/// </summary>
public static bool IsSimilarMember(IMember member1, IMember member2)
{
do {
if (IsSimilarMemberInternal(member1, member2))
return true;
} while ((member1 = FindBaseMember(member1)) != null);
return false;
}
static bool IsSimilarMemberInternal(IMember member1, IMember member2)
{
if (member1 == member2)
return true;
if (member1 == null || member2 == null)
return false;
if (member1.FullyQualifiedName != member2.FullyQualifiedName)
return false;
if (member1.IsStatic != member2.IsStatic)
return false;
if (member1 is IMethod) {
if (member2 is IMethod) {
if (DiffUtility.Compare(((IMethod)member1).Parameters, ((IMethod)member2).Parameters) != 0)
return false;
} else {
return false;
}
}
if (member1 is IProperty) {
if (member2 is IProperty) {
if (DiffUtility.Compare(((IProperty)member1).Parameters, ((IProperty)member2).Parameters) != 0)
return false;
} else {
return false;
}
}
return true;
}
public static IMember FindSimilarMember(IClass type, IMember member)
{
if (member is IMethod) {
IMethod parentMethod = (IMethod)member;
foreach (IMethod m in type.Methods) {
if (string.Equals(parentMethod.Name, m.Name, StringComparison.InvariantCultureIgnoreCase)) {
if (m.IsStatic == parentMethod.IsStatic) {
if (DiffUtility.Compare(parentMethod.Parameters, m.Parameters) == 0) {
return m;
}
}
}
}
} else if (member is IProperty) {
IProperty parentMethod = (IProperty)member;
foreach (IProperty m in type.Properties) {
if (string.Equals(parentMethod.Name, m.Name, StringComparison.InvariantCultureIgnoreCase)) {
if (m.IsStatic == parentMethod.IsStatic) {
if (DiffUtility.Compare(parentMethod.Parameters, m.Parameters) == 0) {
return m;
}
}
}
}
}
return null;
}
public static IMember FindBaseMember(IMember member)
{
if (member == null) return null;
IClass parentClass = member.DeclaringType;
IClass baseClass = parentClass.BaseClass;
if (baseClass == null) return null;
foreach (IClass childClass in baseClass.ClassInheritanceTree) {
IMember m = FindSimilarMember(childClass, member);
if (m != null)
return m;
}
return null;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -