⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nrefactoryresolver.cs

📁 SharpDevelop2.0.0 c#开发免费工具
💻 CS
📖 第 1 页 / 共 3 页
字号:
			}
			type = expr.AcceptVisitor(typeVisitor, null) as IReturnType;
			
			if (type == null || type.FullyQualifiedName == "") {
				return null;
			}
			if (expr is ObjectCreateExpression) {
				List<IMethod> constructors = new List<IMethod>();
				foreach (IMethod m in type.GetMethods()) {
					if (m.IsConstructor && !m.IsStatic)
						constructors.Add(m);
				}
				
				if (constructors.Count == 0) {
					// Class has no constructors -> create default constructor
					IClass c = type.GetUnderlyingClass();
					if (c != null) {
						return CreateMemberResolveResult(Constructor.CreateDefault(c));
					}
				}
				IReturnType[] typeParameters = null;
				if (type.TypeArguments != null) {
					typeParameters = new IReturnType[type.TypeArguments.Count];
					type.TypeArguments.CopyTo(typeParameters, 0);
				}
				ResolveResult rr = CreateMemberResolveResult(typeVisitor.FindOverload(constructors, typeParameters, ((ObjectCreateExpression)expr).Parameters, null));
				if (rr != null) {
					rr.ResolvedType = type;
				}
				return rr;
			}
			return new ResolveResult(callingClass, callingMember, type);
		}
		
		ResolveResult ResolveMemberReferenceExpression(IReturnType type, FieldReferenceExpression fieldReferenceExpression)
		{
			IClass c;
			IMember member;
			if (type is TypeVisitor.NamespaceReturnType) {
				string combinedName;
				if (type.FullyQualifiedName == "")
					combinedName = fieldReferenceExpression.FieldName;
				else
					combinedName = type.FullyQualifiedName + "." + fieldReferenceExpression.FieldName;
				if (projectContent.NamespaceExists(combinedName)) {
					return new NamespaceResolveResult(callingClass, callingMember, combinedName);
				}
				c = GetClass(combinedName);
				if (c != null) {
					return new TypeResolveResult(callingClass, callingMember, c);
				}
				if (languageProperties.ImportModules) {
					// go through the members of the modules
					foreach (object o in projectContent.GetNamespaceContents(type.FullyQualifiedName)) {
						member = o as IMember;
						if (member != null && IsSameName(member.Name, fieldReferenceExpression.FieldName)) {
							return CreateMemberResolveResult(member);
						}
					}
				}
				return null;
			}
			member = GetMember(type, fieldReferenceExpression.FieldName);
			if (member != null)
				return CreateMemberResolveResult(member);
			c = type.GetUnderlyingClass();
			if (c != null) {
				foreach (IClass baseClass in c.ClassInheritanceTree) {
					List<IClass> innerClasses = baseClass.InnerClasses;
					if (innerClasses != null) {
						foreach (IClass innerClass in innerClasses) {
							if (IsSameName(innerClass.Name, fieldReferenceExpression.FieldName)) {
								return new TypeResolveResult(callingClass, callingMember, innerClass);
							}
						}
					}
				}
			}
			return ResolveMethod(type, fieldReferenceExpression.FieldName);
		}
		
		/// <summary>
		/// Creates a new class containing only the specified member.
		/// This is useful because we only want to parse current method for local variables,
		/// as all fields etc. are already prepared in the AST.
		/// </summary>
		System.IO.TextReader ExtractMethod(string fileContent, IMember member)
		{
			// As the parse information is always some seconds old, the end line could be wrong
			// if the user just inserted a line in the method.
			// We can ignore that case because it is sufficient for the parser when the first part of the
			// method body is ok.
			// Since we are operating directly on the edited buffer, the parser might not be
			// able to resolve invalid declarations.
			// We can ignore even that because the 'invalid line' is the line the user is currently
			// editing, and the declarations he is using are always above that line.
			
			
			// The ExtractMethod-approach has the advantage that the method contents do not have
			// do be parsed and stored in memory before they are needed.
			// Previous SharpDevelop versions always stored the SharpRefactory[VB] parse tree as 'Tag'
			// to the AST CompilationUnit.
			// This approach doesn't need that, so one could even go and implement a special parser
			// mode that does not parse the method bodies for the normal run (in the ParserUpdateThread or
			// SolutionLoadThread). That could improve the parser's speed dramatically.
			
			if (member.Region.IsEmpty) return null;
			int startLine = member.Region.BeginLine;
			if (startLine < 1) return null;
			DomRegion bodyRegion;
			if (member is IMethodOrProperty) {
				bodyRegion = ((IMethodOrProperty)member).BodyRegion;
			} else if (member is IEvent) {
				bodyRegion = ((IEvent)member).BodyRegion;
			} else {
				return null;
			}
			if (bodyRegion.IsEmpty) return null;
			int endLine = bodyRegion.EndLine;
			
			// Fix for SD2-511 (Code completion in inserted line)
			if (language == SupportedLanguage.CSharp) {
				// Do not do this for VB: the parser does not correct create the
				// ForEachStatement when the method in truncated in the middle
				// VB does not have the "inserted line looks like variable declaration"-problem
				// anyways.
				if (caretLine > startLine && caretLine < endLine)
					endLine = caretLine;
			}
			
			int offset = 0;
			for (int i = 0; i < startLine - 1; ++i) { // -1 because the startLine must be included
				offset = fileContent.IndexOf('\n', offset) + 1;
				if (offset <= 0) return null;
			}
			int startOffset = offset;
			for (int i = startLine - 1; i < endLine; ++i) {
				int newOffset = fileContent.IndexOf('\n', offset) + 1;
				if (newOffset <= 0) break;
				offset = newOffset;
			}
			int length = offset - startOffset;
			string classDecl, endClassDecl;
			if (language == SupportedLanguage.VBNet) {
				classDecl = "Class A";
				endClassDecl = "End Class\n";
			} else {
				classDecl = "class A {";
				endClassDecl = "}\n";
			}
			System.Text.StringBuilder b = new System.Text.StringBuilder(classDecl, length + classDecl.Length + endClassDecl.Length + startLine - 1);
			b.Append('\n', startLine - 1);
			b.Append(fileContent, startOffset, length);
			b.Append(endClassDecl);
			return new System.IO.StringReader(b.ToString());
		}
		
		#region Resolve Identifier
		ResolveResult ResolveIdentifier(string identifier, ExpressionContext context)
		{
			ResolveResult result = ResolveIdentifierInternal(identifier);
			if (result is TypeResolveResult)
				return result;
			
			ResolveResult result2 = null;
			
			IReturnType t = SearchType(identifier);
			if (t != null) {
				result2 = new TypeResolveResult(callingClass, callingMember, t);
			} else {
				if (callingClass != null) {
					if (callingMember is IMethod) {
						foreach (ITypeParameter typeParameter in (callingMember as IMethod).TypeParameters) {
							if (IsSameName(identifier, typeParameter.Name)) {
								return new TypeResolveResult(callingClass, callingMember, new GenericReturnType(typeParameter));
							}
						}
					}
					foreach (ITypeParameter typeParameter in callingClass.TypeParameters) {
						if (IsSameName(identifier, typeParameter.Name)) {
							return new TypeResolveResult(callingClass, callingMember, new GenericReturnType(typeParameter));
						}
					}
				}
			}
			
			if (result == null)  return result2;
			if (result2 == null) return result;
			if (context == ExpressionContext.Type)
				return result2;
			return new MixedResolveResult(result, result2);
		}
		
		IField CreateLocalVariableField(LocalLookupVariable var, string identifier)
		{
			IReturnType type = GetVariableType(var);
			IField f = new DefaultField.LocalVariableField(type, identifier, new DomRegion(var.StartPos, var.EndPos), callingClass);
			if (var.IsConst) {
				f.Modifiers |= ModifierEnum.Const;
			}
			return f;
		}
		
		ResolveResult ResolveIdentifierInternal(string identifier)
		{
			if (callingMember != null) { // LocalResolveResult requires callingMember to be set
				LocalLookupVariable var = SearchVariable(identifier);
				if (var != null) {
					return new LocalResolveResult(callingMember, CreateLocalVariableField(var, identifier));
				}
				IParameter para = SearchMethodParameter(identifier);
				if (para != null) {
					IField field = new DefaultField.ParameterField(para.ReturnType, para.Name, para.Region, callingClass);
					return new LocalResolveResult(callingMember, field);
				}
				if (IsSameName(identifier, "value")) {
					IProperty property = callingMember as IProperty;
					if (property != null && property.SetterRegion.IsInside(caretLine, caretColumn)) {
						IField field = new DefaultField.ParameterField(property.ReturnType, "value", property.Region, callingClass);
						return new LocalResolveResult(callingMember, field);
					}
				}
			}
			if (callingClass != null) {
				IMember member = GetMember(callingClass.DefaultReturnType, identifier);
				if (member != null) {
					return CreateMemberResolveResult(member);
				}
				ResolveResult result = ResolveMethod(callingClass.DefaultReturnType, identifier);
				if (result != null)
					return result;
			}
			
			// try if there exists a static member in outer classes named typeName
			List<IClass> classes = cu.GetOuterClasses(caretLine, caretColumn);
			foreach (IClass c in classes) {
				IMember member = GetMember(c.DefaultReturnType, identifier);
				if (member != null && member.IsStatic) {
					return new MemberResolveResult(callingClass, callingMember, member);
				}
			}
			
			string namespaceName = SearchNamespace(identifier);
			if (namespaceName != null && namespaceName.Length > 0) {
				return new NamespaceResolveResult(callingClass, callingMember, namespaceName);
			}
			
			if (languageProperties.CanImportClasses) {
				foreach (IUsing @using in cu.Usings) {
					foreach (string import in @using.Usings) {
						IClass c = GetClass(import);
						if (c != null) {
							IMember member = GetMember(c.DefaultReturnType, identifier);
							if (member != null) {
								return CreateMemberResolveResult(member);
							}
							ResolveResult result = ResolveMethod(c.DefaultReturnType, identifier);
							if (result != null)
								return result;
						}
					}
				}
			}
			
			if (languageProperties.ImportModules) {
				ArrayList list = new ArrayList();
				AddImportedNamespaceContents(list, cu, callingClass);
				foreach (object o in list) {
					IClass c = o as IClass;
					if (c != null && IsSameName(identifier, c.Name)) {
						return new TypeResolveResult(callingClass, callingMember, c);
					}
					IMember member = o as IMember;
					if (member != null && IsSameName(identifier, member.Name)) {
						if (member is IMethod) {
							return new MethodResolveResult(callingClass, callingMember, member.DeclaringType.DefaultReturnType, member.Name);
						} else {
							return CreateMemberResolveResult(member);
						}
					}
				}
			}
			
			return null;
		}
		#endregion
		
		private ResolveResult CreateMemberResolveResult(IMember member)
		{
			if (member == null) return null;
			return new MemberResolveResult(callingClass, callingMember, member);
		}
		
		#region ResolveMethod
		ResolveResult ResolveMethod(IReturnType type, string identifier)
		{
			if (type == null)
				return null;
			foreach (IMethod method in type.GetMethods()) {
				if (IsSameName(identifier, method.Name))
					return new MethodResolveResult(callingClass, callingMember, type, identifier);
			}
			if (languageProperties.SupportsExtensionMethods && callingClass != null) {
				ArrayList list = new ArrayList();
				ResolveResult.AddExtensions(languageProperties, list, callingClass, type);
				foreach (IMethodOrProperty mp in list) {
					if (mp is IMethod && IsSameName(mp.Name, identifier)) {
						return new MethodResolveResult(callingClass, callingMember, type, identifier);
					}
				}
			}
			return null;
		}
		#endregion
		
		Expression SpecialConstructs(string expression)
		{
			if (language == SupportedLanguage.VBNet) {
				// MyBase and MyClass are no expressions, only MyBase.Identifier and MyClass.Identifier
				if ("mybase".Equals(expression, StringComparison.InvariantCultureIgnoreCase)) {
					return new BaseReferenceExpression();
				} else if ("myclass".Equals(expression, StringComparison.InvariantCultureIgnoreCase)) {
					return new ClassReferenceExpression();
				} // Global is handled in Resolve() because we don't need an expression for that
			} else if (language == SupportedLanguage.CSharp) {
				// generic type names are no expressions, only property access on them is an expression
				if (expression.EndsWith(">")) {
					FieldReferenceExpression expr = ParseExpression(expression + ".Prop") as FieldReferenceExpression;
					if (expr != null) {
						return expr.TargetObject;
					}
				}
				return null;
			}
			return null;
		}
		
		public bool IsSameName(string name1, string name2)
		{
			return languageProperties.NameComparer.Equals(name1, name2);
		}
		
		bool IsInside(Point between, Point start, Point end)
		{
			if (between.Y < start.Y || between.Y > end.Y) {
				return false;
			}
			if (between.Y > start.Y) {
				if (between.Y < end.Y) {
					return true;
				}
				// between.Y == end.Y
				return between.X <= end.X;
			}
			// between.Y == start.Y
			if (between.X < start.X) {
				return false;
			}
			// start is OK and between.Y <= end.Y
			return between.Y < end.Y || between.X <= end.X;
		}
		
		IMember GetCurrentMember()
		{
			if (callingClass == null)
				return null;
			foreach (IMethod method in callingClass.Methods) {
				if (method.Region.IsInside(caretLine, caretColumn) || method.BodyRegion.IsInside(caretLine, caretColumn)) {
					return method;
				}
			}
			foreach (IProperty property in callingClass.Properties) {
				if (property.Region.IsInside(caretLine, caretColumn) || property.BodyRegion.IsInside(caretLine, caretColumn)) {
					return property;
				}
			}
			return null;
		}
		
		/// <remarks>
		/// use the usings to find the correct name of a namespace
		/// </remarks>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -