Example #1
0
		IEnumerable<ICompletionData> DefaultControlSpaceItems (Tuple<CppParsedFile, AstNode, CompilationUnit> xp = null, bool controlSpace = true)
		{
			var wrapper = new CompletionDataWrapper (this);
			if (offset >= document.TextLength)
				offset = document.TextLength - 1;
			while (offset > 1 && char.IsWhiteSpace (document.GetCharAt (offset))) {
				offset--;
			}
			location = document.GetLocation (offset);
			
			if (xp == null)
				xp = GetExpressionAtCursor ();
			AstNode node;
			Tuple<ResolveResult, CppResolver> rr;
			if (xp != null) {
				node = xp.Item2;
				rr = ResolveExpression (xp.Item1, node, xp.Item3);
			} else {
				var unit = ParseStub ("a");
				node = unit.GetNodeAt (location);
				rr = ResolveExpression (CSharpParsedFile, node, unit);
			}
			
			if (node is Identifier && node.Parent is ForeachStatement) {
				var foreachStmt = (ForeachStatement)node.Parent;
				foreach (var possibleName in GenerateNameProposals (foreachStmt.VariableType)) {
					if (possibleName.Length > 0)
						wrapper.Result.Add (factory.CreateLiteralCompletionData (possibleName.ToString ()));
				}
					
				AutoSelect = false;
				AutoCompleteEmptyMatch = false;
				return wrapper.Result;
			}
			
			if (node is Identifier && node.Parent is ParameterDeclaration) {
				if (!controlSpace)
					return null;
				// Try Parameter name case 
				var param = node.Parent as ParameterDeclaration;
				if (param != null) {
					foreach (var possibleName in GenerateNameProposals (param.Type)) {
						if (possibleName.Length > 0)
							wrapper.Result.Add (factory.CreateLiteralCompletionData (possibleName.ToString ()));
					}
					AutoSelect = false;
					AutoCompleteEmptyMatch = false;
					return wrapper.Result;
				}
			}
			if (Unit != null && (node == null || node is TypeDeclaration)) {
				var constructor = Unit.GetNodeAt<ConstructorDeclaration> (location.Line, location.Column - 3);
				if (constructor != null && !constructor.ColonToken.IsNull && constructor.Initializer.IsNull) {
					wrapper.AddCustom ("this");
					wrapper.AddCustom ("base");
					return wrapper.Result;
				}
			}
			CppResolver csResolver = null;
			if (rr != null)
				csResolver = rr.Item2;
			if (csResolver == null) {
				if (node != null) {
					csResolver =  GetState ();
					//var astResolver = new CSharpAstResolver (csResolver, node, xp != null ? xp.Item1 : CSharpParsedFile);
					
					try {
						//csResolver = astResolver.GetResolverStateBefore (node);
						Console.WriteLine (csResolver.LocalVariables.Count ());
					} catch (Exception  e)  {
						Console.WriteLine ("E!!!" + e);
					}
					
				} else {
					csResolver = GetState ();
				}
			}
			
			AddContextCompletion (wrapper, csResolver, node);
			
			return wrapper.Result;
		}
Example #2
0
		void AddContextCompletion (CompletionDataWrapper wrapper, CppResolver state, AstNode node)
		{
			if (state != null && !(node is AstType)) {
				foreach (var variable in state.LocalVariables) {
					if (variable.Region.IsInside (location.Line, location.Column - 1))
						continue;
					wrapper.AddVariable (variable);
				}
			}
			
			if (currentMember is IUnresolvedParameterizedMember && !(node is AstType)) {
				var param = (IParameterizedMember)currentMember.CreateResolved (ctx);
				foreach (var p in param.Parameters) {
					wrapper.AddVariable (p);
				}
			}
			
			if (currentMember is IUnresolvedMethod) {
				var method = (IUnresolvedMethod)currentMember;
				foreach (var p in method.TypeParameters) {
					wrapper.AddTypeParameter (p);
				}
			}
			
			Predicate<IType> typePred = null;
			if (node is Attribute) {
				var attribute = Compilation.FindType (KnownTypeCode.Attribute);
				typePred = t => {
					return t.GetAllBaseTypeDefinitions ().Any (bt => bt.Equals (attribute));
				};
			}
			AddTypesAndNamespaces (wrapper, state, node, typePred);
			
			wrapper.Result.Add (factory.CreateLiteralCompletionData ("global"));
			
			if (!(node is AstType)) {
				if (currentMember != null) {
					AddKeywords (wrapper, statementStartKeywords);
					AddKeywords (wrapper, expressionLevelKeywords);
				} else if (currentType != null) {
					AddKeywords (wrapper, typeLevelKeywords);
				} else {
					AddKeywords (wrapper, globalLevelKeywords);
				}
				var prop = currentMember as IUnresolvedProperty;
				if (prop != null && prop.Setter != null && prop.Setter.Region.IsInside (location))
					wrapper.AddCustom ("value"); 
				if (currentMember is IUnresolvedEvent)
					wrapper.AddCustom ("value"); 
				
				if (IsInSwitchContext (node)) {
					wrapper.AddCustom ("case"); 
				}
				
			}
			AddKeywords (wrapper, primitiveTypesKeywords);
			if (currentMember != null)
				wrapper.AddCustom ("var"); 
			wrapper.Result.AddRange (factory.CreateCodeTemplateCompletionData ());
			
			if (node != null && node.Role == AstNode.Roles.Argument) {
				var resolved = ResolveExpression (CSharpParsedFile, node.Parent, Unit);
				var invokeResult = resolved != null ? resolved.Item1 as CppInvocationResolveResult : null;
				if (invokeResult != null) {
					int argNum = 0;
					foreach (var arg in node.Parent.Children.Where (c => c.Role == AstNode.Roles.Argument)) {
						if (arg == node)
							break;
						argNum++;
					}
					var param = argNum < invokeResult.Member.Parameters.Count ? invokeResult.Member.Parameters [argNum] : null;
					if (param != null && param.Type.Kind == TypeKind.Enum) {
						AddEnumMembers (wrapper, param.Type, state);
					}
				}
			}
			
		}
Example #3
0
		IEnumerable<ICompletionData> CreateCaseCompletionData (TextLocation location)
		{
			var unit = ParseStub ("a: break;");
			if (unit == null)
				return null;
			var s = unit.GetNodeAt<SwitchStatement> (location);
			if (s == null)
				return null;
			
			var offset = document.GetOffset (s.Expression.StartLocation);
			var expr = GetExpressionAt (offset);
			if (expr == null)
				return null;
			
			var resolveResult = ResolveExpression (expr.Item1, expr.Item2, expr.Item3);
			if (resolveResult == null || resolveResult.Item1.Type.Kind != TypeKind.Enum) 
				return null;
			var wrapper = new CompletionDataWrapper (this);
			AddEnumMembers (wrapper, resolveResult.Item1.Type, resolveResult.Item2);
			AutoCompleteEmptyMatch = false;
			return wrapper.Result;
		}
Example #4
0
		IEnumerable<ICompletionData> HandleAccessorContext ()
		{
			var unit = ParseStub ("get; }", false);
			var node = unit.GetNodeAt (location, cn => !(cn is CppTokenNode));
			if (node is Accessor)
				node = node.Parent;
			var contextList = new CompletionDataWrapper (this);
			if (node is PropertyDeclaration) {
				contextList.AddCustom ("get");
				contextList.AddCustom ("set");
				AddKeywords (contextList, accessorModifierKeywords);
			} else if (node is CustomEventDeclaration) {
				contextList.AddCustom ("add");
				contextList.AddCustom ("remove");
			} else {
				return null;
			}
			
			return contextList.Result;
		}
Example #5
0
		void AddEnumMembers (CompletionDataWrapper completionList, IType resolvedType, CppResolver state)
		{
			if (resolvedType.Kind != TypeKind.Enum)
				return;
			string typeString = GetShortType (resolvedType, state);
			if (typeString.Contains ("."))
				completionList.AddType (resolvedType, typeString);
			foreach (var field in resolvedType.GetFields ()) {
				if (field.IsConst || field.IsStatic)
					completionList.Result.Add (factory.CreateEntityCompletionData (field, typeString + "." + field.Name));
			}
			DefaultCompletionString = typeString;
		}
Example #6
0
		IEnumerable<ICompletionData> CreateCompletionData (TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CppResolver state)
		{
			if (resolveResult == null /*|| resolveResult.IsError*/)
				return null;
			
			if (resolveResult is NamespaceResolveResult) {
				var nr = (NamespaceResolveResult)resolveResult;
				var namespaceContents = new CompletionDataWrapper (this);
				
				foreach (var cl in nr.Namespace.Types) {
					namespaceContents.AddType (cl, cl.Name);
				}
				
				foreach (var ns in nr.Namespace.ChildNamespaces) {
					namespaceContents.AddNamespace (ns.Name);
				}
				return namespaceContents.Result;
			}
			
			IType type = resolveResult.Type;
			var typeDef = resolveResult.Type.GetDefinition ();
			var result = new CompletionDataWrapper (this);
			bool includeStaticMembers = false;
			
			if (resolveResult is LocalResolveResult) {
				if (resolvedNode is IdentifierExpression) {
					var mrr = (LocalResolveResult)resolveResult;
					includeStaticMembers = mrr.Variable.Name == mrr.Type.Name;
				}
			}
			if (resolveResult is TypeResolveResult && type.Kind == TypeKind.Enum) {
				foreach (var field in type.GetFields ()) {
					result.AddMember (field);
				}
				foreach (var m in type.GetMethods ()) {
					if (m.Name == "TryParse")
						result.AddMember (m);
				}
				return result.Result;
			}
			
			if (resolveResult is MemberResolveResult && resolvedNode is IdentifierExpression) {
				var mrr = (MemberResolveResult)resolveResult;
				includeStaticMembers = mrr.Member.Name == mrr.Type.Name;
				
				// ADD Aliases
				var scope = CSharpParsedFile.GetUsingScope (location).Resolve (Compilation);
			
				for (var n = scope; n != null; n = n.Parent) {
					foreach (var pair in n.UsingAliases) {
						if (pair.Key == mrr.Member.Name) {
							foreach (var r in CreateCompletionData (location, pair.Value, resolvedNode, state)) {
								if (r is IEntityCompletionData && ((IEntityCompletionData)r).Entity is IMember) {
									result.AddMember ((IMember)((IEntityCompletionData)r).Entity);
								} else {
									result.Add (r);
								}
							}
						}
					}
				}				
				
				
			}
			if (resolveResult is TypeResolveResult && (resolvedNode is IdentifierExpression || resolvedNode is MemberReferenceExpression)) {
				includeStaticMembers = true;
			}
			
//			Console.WriteLine ("type:" + type +"/"+type.GetType ());
//			Console.WriteLine ("current:" + ctx.CurrentTypeDefinition);
//			Console.WriteLine ("IS PROT ALLOWED:" + isProtectedAllowed + " static: "+ includeStaticMembers);
//			Console.WriteLine (resolveResult);
//			Console.WriteLine ("node:" + resolvedNode);
//			Console.WriteLine (currentMember !=  null ? currentMember.IsStatic : "currentMember == null");
			
			if (resolvedNode.Annotation<ObjectCreateExpression> () == null) { //tags the created expression as part of an object create expression.
				var lookup = new MemberLookup (ctx.CurrentTypeDefinition, Compilation.MainAssembly);
				bool isProtectedAllowed = resolveResult is ThisResolveResult ? true : lookup.IsProtectedAccessAllowed (type);
			
				var filteredList = new List<IMember> ();
				foreach (var member in type.GetMembers ()) {
//					Console.WriteLine ("member:" + member + member.IsShadowing);
					if (!lookup.IsAccessible (member, isProtectedAllowed)) {
//						Console.WriteLine ("skip access: " + member.FullName);
						continue;
					}
					if (resolvedNode is BaseReferenceExpression && member.IsAbstract)
						continue;
					bool memberIsStatic = member.IsStatic;
					if (!includeStaticMembers && memberIsStatic && !(resolveResult is TypeResolveResult)) {
//						Console.WriteLine ("skip static member: " + member.FullName);
						continue;
					}
					var field = member as IField;
					if (field != null)
						memberIsStatic |= field.IsConst;
					
					if (!memberIsStatic && (resolveResult is TypeResolveResult)) {
						continue;
					}
					
					if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize")
						continue;
					if (member.EntityType == EntityType.Operator)
						continue;
					if (member.IsShadowing)
						filteredList.RemoveAll (m => m.Name == member.Name);
					
					filteredList.Add (member);
				}
				
				foreach (var member in filteredList) {
//					Console.WriteLine ("add : "+ member.FullName + " --- " + member.IsStatic);
					result.AddMember (member);
				}
			}
			
			if (resolveResult is TypeResolveResult || includeStaticMembers) {
				foreach (var nested in type.GetNestedTypes ()) {
					result.AddType (nested, nested.Name);
				}
				
			} else {
				foreach (var meths in state.GetExtensionMethods (type)) {
					foreach (var m in meths) {
						result.AddMember (m);
					}
				}
			}
			
//			IEnumerable<object> objects = resolveResult.CreateResolveResult (dom, resolver != null ? resolver.CallingMember : null);
//			CompletionDataCollector col = new CompletionDataCollector (this, dom, result, Document.CompilationUnit, resolver != null ? resolver.CallingType : null, location);
//			col.HideExtensionParameter = !resolveResult.StaticResolve;
//			col.NamePrefix = expressionResult.Expression;
//			bool showOnlyTypes = expressionResult.Contexts.Any (ctx => ctx == ExpressionContext.InheritableType || ctx == ExpressionContext.Constraints);
//			if (objects != null) {
//				foreach (object obj in objects) {
//					if (expressionResult.ExpressionContext != null && expressionResult.ExpressionContext.FilterEntry (obj))
//						continue;
//					if (expressionResult.ExpressionContext == ExpressionContext.NamespaceNameExcepted && !(obj is Namespace))
//						continue;
//					if (showOnlyTypes && !(obj is IType))
//						continue;
//					CompletionData data = col.Add (obj);
//					if (data != null && expressionResult.ExpressionContext == ExpressionContext.Attribute && data.CompletionText != null && data.CompletionText.EndsWith ("Attribute")) {
//						string newText = data.CompletionText.Substring (0, data.CompletionText.Length - "Attribute".Length);
//						data.SetText (newText);
//					}
//				}
//			}
			
			return result.Result;
		}
Example #7
0
		IEnumerable<ICompletionData> CreateTypeAndNamespaceCompletionData (TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CppResolver state)
		{
			if (resolveResult == null || resolveResult.IsError)
				return null;
			var result = new CompletionDataWrapper (this);
			if (resolveResult is NamespaceResolveResult) {
				var nr = (NamespaceResolveResult)resolveResult;
				foreach (var cl in nr.Namespace.Types) {
					result.AddType (cl, cl.Name);
				}
				foreach (var ns in nr.Namespace.ChildNamespaces) {
					result.AddNamespace (ns.Name);
				}
			} else if (resolveResult is TypeResolveResult) {
				var type = resolveResult.Type;
				foreach (var nested in type.GetNestedTypes ()) {
					result.AddType (nested, nested.Name);
				}
			}
			return result.Result;
		}
Example #8
0
		IEnumerable<ICompletionData> GetOverrideCompletionData (IUnresolvedTypeDefinition type, string modifiers)
		{
			var wrapper = new CompletionDataWrapper (this);
			var alreadyInserted = new Dictionary<string, bool> ();
			bool addedVirtuals = false;
			
			int declarationBegin = offset;
			int j = declarationBegin;
			for (int i = 0; i < 3; i++) {
				switch (GetPreviousToken (ref j, true)) {
				case "public":
				case "protected":
				case "private":
				case "internal":
				case "sealed":
				case "override":
					declarationBegin = j;
					break;
				case "static":
					return null; // don't add override completion for static members
				}
			}
			AddVirtuals (alreadyInserted, wrapper, modifiers, type.Resolve (ctx), declarationBegin);
			return wrapper.Result;
		}
Example #9
0
		string AddDelegateHandlers (CompletionDataWrapper completionList, IType delegateType, bool addSemicolon = true, bool addDefault = true)
		{
			IMethod delegateMethod = delegateType.GetDelegateInvokeMethod ();
			var thisLineIndent = GetLineIndent (location.Line);
			string delegateEndString = EolMarker + thisLineIndent + "}" + (addSemicolon ? ";" : "");
			bool containsDelegateData = completionList.Result.Any (d => d.DisplayText.StartsWith ("delegate("));
			if (addDefault)
				completionList.AddCustom ("delegate", "Creates anonymous delegate.", "delegate {" + EolMarker + thisLineIndent + IndentString + "|" + delegateEndString);
			var sb = new StringBuilder ("(");
			var sbWithoutTypes = new StringBuilder ("(");
			for (int k = 0; k < delegateMethod.Parameters.Count; k++) {
				if (k > 0) {
					sb.Append (", ");
					sbWithoutTypes.Append (", ");
				}
				var parameterType = delegateMethod.Parameters [k].Type;
				sb.Append (GetShortType (parameterType, GetState ()));
				sb.Append (" ");
				sb.Append (delegateMethod.Parameters [k].Name);
				sbWithoutTypes.Append (delegateMethod.Parameters [k].Name);
			}
			sb.Append (")");
			sbWithoutTypes.Append (")");
			completionList.AddCustom ("delegate" + sb, "Creates anonymous delegate.", "delegate" + sb + " {" + EolMarker + thisLineIndent + IndentString + "|" + delegateEndString);
			if (!completionList.Result.Any (data => data.DisplayText == sbWithoutTypes.ToString ()))
				completionList.AddCustom (sbWithoutTypes.ToString (), "Creates lambda expression.", sbWithoutTypes + " => |" + (addSemicolon ? ";" : ""));
			/* TODO:Make factory method out of it.
			// It's  needed to temporarly disable inserting auto matching bracket because the anonymous delegates are selectable with '('
			// otherwise we would end up with () => )
			if (!containsDelegateData) {
				var savedValue = MonoDevelop.SourceEditor.DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket;
				MonoDevelop.SourceEditor.DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket = false;
				completionList.Result.CompletionListClosed += delegate {
					MonoDevelop.SourceEditor.DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket = savedValue;
				};
			}*/
			return sb.ToString ();
		}
Example #10
0
		IEnumerable<ICompletionData> MagicKeyCompletion (char completionChar, bool controlSpace)
		{
			switch (completionChar) {
			// Magic key completion
			case ':':
			case '.':
				if (IsInsideCommentOrString ())
					return Enumerable.Empty<ICompletionData> ();
				var expr = GetExpressionBeforeCursor ();
				if (expr == null)
					return null;
				// do not complete <number>. (but <number>.<number>.)
				if (expr.Item2 is PrimitiveExpression) {
					var pexpr = (PrimitiveExpression)expr.Item2;
					if (!(pexpr.Value is string || pexpr.Value is char) && !pexpr.LiteralValue.Contains ('.'))
						return null;
				}
				
				var resolveResult = ResolveExpression (expr.Item1, expr.Item2, expr.Item3);
				if (resolveResult == null)
					return null;
				if (expr.Item2 is AstType)
					return CreateTypeAndNamespaceCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2);
				return CreateCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2);
			case '#':
				if (IsInsideCommentOrString ())
					return null;
				return GetDirectiveCompletionData ();
			
// XML doc completion
			case '<':
				if (IsInsideDocComment ())
					return GetXmlDocumentationCompletionData ();
				if (controlSpace)
					return DefaultControlSpaceItems ();
				return null;
			case '>':
				if (!IsInsideDocComment ())
					return null;
				string lineText = document.GetText (document.GetLineByNumber (location.Line));
				int startIndex = Math.Min (location.Column - 1, lineText.Length - 1);
				
				while (startIndex >= 0 && lineText [startIndex] != '<') {
					--startIndex;
					if (lineText [startIndex] == '/') { // already closed.
						startIndex = -1;
						break;
					}
				}
				
				if (startIndex >= 0) {
					int endIndex = startIndex;
					while (endIndex <= location.Column && endIndex < lineText.Length && !Char.IsWhiteSpace (lineText [endIndex])) {
						endIndex++;
					}
					string tag = endIndex - startIndex - 1 > 0 ? lineText.Substring (startIndex + 1, endIndex - startIndex - 2) : null;
					if (!string.IsNullOrEmpty (tag) && commentTags.IndexOf (tag) >= 0)
						document.Insert (offset, "</" + tag + ">");
				}
				return null;
			
			// Parameter completion
			case '(':
				if (IsInsideCommentOrString ())
					return null;
				var invoke = GetInvocationBeforeCursor (true);
				if (invoke == null)
					return null;
				if (invoke.Item2 is TypeOfExpression)
					return CreateTypeList ();
				var invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
				if (invocationResult == null)
					return null;
				var methodGroup = invocationResult.Item1 as MethodGroupResolveResult;
				if (methodGroup != null)
					return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, 0, controlSpace);
				
				if (controlSpace)
					return DefaultControlSpaceItems (invoke);
				
				return null;
			case '=':
				return controlSpace ? DefaultControlSpaceItems () : null;
			case ',':
				int cpos2;
				if (!GetParameterCompletionCommandOffset (out cpos2)) 
					return null;
			//	completionContext = CompletionWidget.CreateCodeCompletionContext (cpos2);
			//	int currentParameter2 = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, completionContext) - 1;
//				return CreateParameterCompletion (CreateResolver (), location, ExpressionContext.MethodBody, provider.Methods, currentParameter);	
				break;
				
			// Completion on space:
			case ' ':
				if (IsInsideCommentOrString ())
					return null;
				
				int tokenIndex = offset;
				string token = GetPreviousToken (ref tokenIndex, false);
				// check propose name, for context <variable name> <ctrl+space> (but only in control space context)
				//IType isAsType = null;
				var isAsExpression = GetExpressionAt (offset);
				if (controlSpace && isAsExpression != null && isAsExpression.Item2 is VariableDeclarationStatement && token != "new") {
					var parent = isAsExpression.Item2 as VariableDeclarationStatement;
					var proposeNameList = new CompletionDataWrapper (this);
					
					foreach (var possibleName in GenerateNameProposals (parent.Type)) {
						if (possibleName.Length > 0)
							proposeNameList.Result.Add (factory.CreateLiteralCompletionData (possibleName.ToString ()));
					}
					
					AutoSelect = false;
					AutoCompleteEmptyMatch = false;
					return proposeNameList.Result;
				}
//				int tokenIndex = offset;
//				string token = GetPreviousToken (ref tokenIndex, false);
//				if (result.ExpressionContext == ExpressionContext.ObjectInitializer) {
//					resolver = CreateResolver ();
//					ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForObjectInitializer (document, resolver.Unit, Document.FileName, resolver.CallingType);
//					IReturnType objectInitializer = ((ExpressionContext.TypeExpressionContext)exactContext).UnresolvedType;
//					if (objectInitializer != null && objectInitializer.ArrayDimensions == 0 && objectInitializer.PointerNestingLevel == 0 && (token == "{" || token == ","))
//						return CreateCtrlSpaceCompletionData (completionContext, result); 
//				}
				if (token == "=") {
					int j = tokenIndex;
					string prevToken = GetPreviousToken (ref j, false);
					if (prevToken == "=" || prevToken == "+" || prevToken == "-") {
						token = prevToken + token;
						tokenIndex = j;
					}
				}
				switch (token) {
				case "(":
				case ",":
					int cpos;
					if (!GetParameterCompletionCommandOffset (out cpos)) 
						break;
					int currentParameter = GetCurrentParameterIndex (cpos, 0) - 1;
					if (currentParameter < 0)
						return null;
					invoke = GetInvocationBeforeCursor (token == "(");
					if (invoke == null)
						return null;
					invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
					if (invocationResult == null)
						return null;
					methodGroup = invocationResult.Item1 as MethodGroupResolveResult;
					if (methodGroup != null)
						return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, currentParameter, controlSpace);
					return null;
				case "=":
				case "==":
					GetPreviousToken (ref tokenIndex, false);
					var expressionOrVariableDeclaration = GetExpressionAt (tokenIndex);
					if (expressionOrVariableDeclaration == null)
						return null;
					
					resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3);
					
					if (resolveResult == null)
						return null;
					if (resolveResult.Item1.Type.Kind == TypeKind.Enum) {
						var wrapper = new CompletionDataWrapper (this);
						AddContextCompletion (wrapper, resolveResult.Item2, expressionOrVariableDeclaration.Item2);
						AddEnumMembers (wrapper, resolveResult.Item1.Type, resolveResult.Item2);
						AutoCompleteEmptyMatch = false;
						return wrapper.Result;
					}
//				
//					if (resolvedType.FullName == DomReturnType.Bool.FullName) {
//						CompletionDataList completionList = new ProjectDomCompletionDataList ();
//						CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
//						completionList.AutoCompleteEmptyMatch = false;
//						cdc.Add ("true", "md-keyword");
//						cdc.Add ("false", "md-keyword");
//						resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
//						return completionList;
//					}
//					if (resolvedType.ClassType == ClassType.Delegate && token == "=") {
//						CompletionDataList completionList = new ProjectDomCompletionDataList ();
//						string parameterDefinition = AddDelegateHandlers (completionList, resolvedType);
//						string varName = GetPreviousMemberReferenceExpression (tokenIndex);
//						completionList.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.CallingMember, resolvedType));
//						
//						CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
//						resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
//						foreach (var data in completionList) {
//							if (data is MemberCompletionData) 
//								((MemberCompletionData)data).IsDelegateExpected = true;
//						}
//						return completionList;
//					}
					return null;
				case "+=":
				case "-=":
					GetPreviousToken (ref tokenIndex, false);
					
					expressionOrVariableDeclaration = GetExpressionAt (tokenIndex);
					if (expressionOrVariableDeclaration == null)
						return null;
				
					resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3);
					if (resolveResult == null)
						return null;
					
					
					var mrr = resolveResult.Item1 as MemberResolveResult;
					if (mrr != null) {
						var evt = mrr.Member as IEvent;
						if (evt == null)
							return null;
						var delegateType = evt.ReturnType;
						if (delegateType.Kind != TypeKind.Delegate)
							return null;
						
						var wrapper = new CompletionDataWrapper (this);
						if (currentType != null) {
//							bool includeProtected = DomType.IncludeProtected (dom, typeFromDatabase, resolver.CallingType);
							foreach (var method in currentType.Methods) {
								if (MatchDelegate (delegateType, method) /*&& method.IsAccessibleFrom (dom, resolver.CallingType, resolver.CallingMember, includeProtected) &&*/) {
									wrapper.AddMember (method);
//									data.SetText (data.CompletionText + ";");
								}
							}
						}
						if (token == "+=") {
							string parameterDefinition = AddDelegateHandlers (wrapper, delegateType);
							string varName = GetPreviousMemberReferenceExpression (tokenIndex);
							wrapper.Result.Add (factory.CreateEventCreationCompletionData (varName, delegateType, evt, parameterDefinition, currentMember, currentType));
						}
					
						return wrapper.Result;
					}
					return null;
				case ":":
					
/* Breaks constructor initializer case:
					 * if (currentMember == null) {
						var wrapper = new CompletionDataWrapper (this);
						AddTypesAndNamespaces (wrapper, GetState (), null, t => currentType != null ? !currentType.Equals (t) : true);
						return wrapper.Result;
					}*/
					return null;
				}
				
				var keywordCompletion = HandleKeywordCompletion (tokenIndex, token);
				if (keywordCompletion == null && controlSpace)
					goto default;
				return keywordCompletion;
			// Automatic completion
			default:
				if (IsInsideCommentOrString ())
					return null;
				if (IsInLinqContext (offset)) {
					if (!controlSpace && !(char.IsLetter (completionChar) || completionChar == '_'))
						return null;
					tokenIndex = offset;
					token = GetPreviousToken (ref tokenIndex, false); // token last typed
					if (!char.IsWhiteSpace (completionChar) && !linqKeywords.Contains (token))
						token = GetPreviousToken (ref tokenIndex, false); // token last typed
					
					if (linqKeywords.Contains (token)) {
						if (token == "from") // after from no auto code completion.
							return null;
						return DefaultControlSpaceItems ();
					}
					var dataList = new CompletionDataWrapper (this);
					AddKeywords (dataList, linqKeywords);
					return dataList.Result;
				}
				if (currentType != null && currentType.Kind == TypeKind.Enum)
					return HandleEnumContext ();
				
				var contextList = new CompletionDataWrapper (this);
				var identifierStart = GetExpressionAtCursor ();
				
				if (identifierStart != null && identifierStart.Item2 is TypeParameterDeclaration)
					return null;
				
				if (identifierStart != null && identifierStart.Item2 is VariableInitializer && location <= ((VariableInitializer)identifierStart.Item2).NameToken.EndLocation) {
					return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems (identifierStart) : null;
				}
				if (!(char.IsLetter (completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null || !(identifierStart.Item2 is ArrayInitializerExpression))) {
					return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems (identifierStart) : null;
				}
				char prevCh = offset > 2 ? document.GetCharAt (offset - 2) : ';';
				char nextCh = offset < document.TextLength ? document.GetCharAt (offset) : ' ';
				const string allowedChars = ";,[](){}+-*/%^?:&|~!<>=";
				if (!Char.IsWhiteSpace (nextCh) && allowedChars.IndexOf (nextCh) < 0)
					return null;
				if (!(Char.IsWhiteSpace (prevCh) || allowedChars.IndexOf (prevCh) >= 0))
					return null;
				// Do not pop up completion on identifier identifier (should be handled by keyword completion).
				tokenIndex = offset - 1;
				token = GetPreviousToken (ref tokenIndex, false);
				if (token == "class" || token == "interface" || token == "struct" || token == "enum" || token == "namespace") // after these always follows a name
					return null;
				int prevTokenIndex = tokenIndex;
				var prevToken2 = GetPreviousToken (ref prevTokenIndex, false);
				if (prevToken2 == "delegate") // after these always follows a name
					return null;
				if (identifierStart == null && !string.IsNullOrEmpty (token) && !(IsInsideComment (tokenIndex) || IsInsideString (tokenIndex)) && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) {
					char last = token [token.Length - 1];
					if (char.IsLetterOrDigit (last) || last == '_' || token == ">") {
						return HandleKeywordCompletion (tokenIndex, token);
					}
				}
				if (identifierStart == null) {
					var accCtx = HandleAccessorContext ();
					if (accCtx != null)
						return accCtx;
					return DefaultControlSpaceItems (null, controlSpace);
				}
				CppResolver csResolver;
				AstNode n = identifierStart.Item2;
				
				if (n != null && n.Parent is AnonymousTypeCreateExpression) {
					AutoSelect = false;
				}
				
				// Handle foreach (type name _
				if (n is IdentifierExpression) {
					var prev = n.GetPrevNode () as ForeachStatement;
					if (prev != null && prev.InExpression.IsNull) {
						if (controlSpace) {
							contextList.AddCustom ("in");
							return contextList.Result;
						}
						return null;
					}
				}
				if (n != null && n.Parent is InvocationExpression) {
					var invokeParent = (InvocationExpression)n.Parent;
					var invokeResult = ResolveExpression (identifierStart.Item1, invokeParent.Target, identifierStart.Item3);
					var mgr = invokeResult != null ? invokeResult.Item1 as MethodGroupResolveResult : null;
					if (mgr != null) {
						int idx = 0;
						foreach (var arg in invokeParent.Arguments) {
							if (arg == n)
								break;
							idx++;
						}
						
						foreach (var method in mgr.Methods) {
							if (idx < method.Parameters.Count && method.Parameters[idx].Type.Kind == TypeKind.Delegate) {
								AutoSelect = false;
								AutoCompleteEmptyMatch = false;
							}
							foreach (var p in method.Parameters) {
								contextList.AddVariable (p);
							}
						}
						idx++;
						foreach (var list in mgr.GetExtensionMethods ()) {
							foreach (var method in list) {
								if (idx < method.Parameters.Count && method.Parameters[idx].Type.Kind == TypeKind.Delegate) {
									AutoSelect = false;
									AutoCompleteEmptyMatch = false;
								}
								
							}
						}
					}
				}
				
				if (n != null && n.Parent is ObjectCreateExpression) {
					var invokeResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3);
					var mgr = invokeResult != null ? invokeResult.Item1 as ResolveResult : null;
					
					if (mgr != null) {
						foreach (var constructor in mgr.Type.GetConstructors ()) {
							foreach (var p in constructor.Parameters) {
								contextList.AddVariable (p);
							}
						}
					}
				}
				
				if (n is IdentifierExpression) {
					var bop = n.Parent as BinaryOperatorExpression;
					Expression evaluationExpr = null;
					
					if (bop != null && bop.Right == n && (bop.Operator == BinaryOperatorType.Equality || bop.Operator == BinaryOperatorType.InEquality)) {
						evaluationExpr = bop.Left;
					}
					// check for compare to enum case 
					if (evaluationExpr != null) {
						resolveResult = ResolveExpression (identifierStart.Item1, evaluationExpr, identifierStart.Item3);
						if (resolveResult != null && resolveResult.Item1.Type.Kind == TypeKind.Enum) {
							var wrapper = new CompletionDataWrapper (this);
							AddContextCompletion (wrapper, resolveResult.Item2, evaluationExpr);
							AddEnumMembers (wrapper, resolveResult.Item1.Type, resolveResult.Item2);
							AutoCompleteEmptyMatch = false;
							return wrapper.Result;
						}
					}
				}
				
				
				if (n is Identifier && n.Parent is ForeachStatement) {
					if (controlSpace)
						return DefaultControlSpaceItems ();
					return null;
				}
				if (n is ArrayInitializerExpression) {
					// check for new [] {...} expression -> no need to resolve the type there
					var parent = n.Parent as ArrayCreateExpression;
					if (parent != null && parent.Type.IsNull)
						return DefaultControlSpaceItems ();
					
					var initalizerResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3);
					
					var concreteNode = identifierStart.Item3.GetNodeAt<IdentifierExpression> (location);
					// check if we're on the right side of an initializer expression
					if (concreteNode != null && concreteNode.Parent != null && concreteNode.Parent.Parent != null && concreteNode.Identifier != "a" && concreteNode.Parent.Parent is NamedExpression) {
						return DefaultControlSpaceItems ();
					}
					
					if (initalizerResult != null && initalizerResult.Item1.Type.Kind != TypeKind.Unknown) { 
						
						foreach (var property in initalizerResult.Item1.Type.GetProperties ()) {
							if (!property.IsPublic)
								continue;
							contextList.AddMember (property);
						}
						foreach (var field in initalizerResult.Item1.Type.GetFields ()) {       
							if (!field.IsPublic)
								continue;
							contextList.AddMember (field);
						}
						return contextList.Result;
					}
					return DefaultControlSpaceItems ();
				}
				if (n != null/* && !(identifierStart.Item2 is TypeDeclaration)*/) {
					csResolver = new CppResolver (ctx);
					var nodes = new List<AstNode> ();
					nodes.Add (n);
					if (n.Parent is ICSharpCode.NRefactory.Cpp.Attribute)
						nodes.Add (n.Parent);
					var astResolver = new CppAstResolver (csResolver, identifierStart.Item3, identifierStart.Item1);
					astResolver.ApplyNavigator (new NodeListResolveVisitorNavigator (nodes));
					try {
						csResolver = astResolver.GetResolverStateBefore (n);
					} catch (Exception) {
						csResolver = GetState ();
					}
					// add attribute properties.
					if (n.Parent is ICSharpCode.NRefactory.Cpp.Attribute) {
						var resolved = astResolver.Resolve (n.Parent);
						if (resolved != null && resolved.Type != null) {
							foreach (var property in resolved.Type.GetProperties (p => p.Accessibility == Accessibility.Public)) {
								contextList.AddMember (property);
							}
							foreach (var field in resolved.Type.GetFields (p => p.Accessibility == Accessibility.Public)) {
								contextList.AddMember (field);
							}
						}
					}
				} else {
					csResolver = GetState ();
				}
				// identifier has already started with the first letter
				offset--;
				AddContextCompletion (contextList, csResolver, identifierStart.Item2);
				return contextList.Result;
//				if (stub.Parent is BlockStatement)
				
//				result = FindExpression (dom, completionContext, -1);
//				if (result == null)
//					return null;
//				 else if (result.ExpressionContext != ExpressionContext.IdentifierExpected) {
//					triggerWordLength = 1;
//					bool autoSelect = true;
//					IType returnType = null;
//					if ((prevCh == ',' || prevCh == '(') && GetParameterCompletionCommandOffset (out cpos)) {
//						ctx = CompletionWidget.CreateCodeCompletionContext (cpos);
//						NRefactoryParameterDataProvider dataProvider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider;
//						if (dataProvider != null) {
//							int i = dataProvider.GetCurrentParameterIndex (CompletionWidget, ctx) - 1;
//							foreach (var method in dataProvider.Methods) {
//								if (i < method.Parameters.Count) {
//									returnType = dom.GetType (method.Parameters [i].ReturnType);
//									autoSelect = returnType == null || returnType.ClassType != ClassType.Delegate;
//									break;
//								}
//							}
//						}
//					}
//					// Bug 677531 - Auto-complete doesn't always highlight generic parameter in method signature
//					//if (result.ExpressionContext == ExpressionContext.TypeName)
//					//	autoSelect = false;
//					CompletionDataList dataList = CreateCtrlSpaceCompletionData (completionContext, result);
//					AddEnumMembers (dataList, returnType);
//					dataList.AutoSelect = autoSelect;
//					return dataList;
//				} else {
//					result = FindExpression (dom, completionContext, 0);
//					tokenIndex = offset;
//					
//					// check foreach case, unfortunately the expression finder is too dumb to handle full type names
//					// should be overworked if the expression finder is replaced with a mcs ast based analyzer.
//					var possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // starting letter
//					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varname
//				
//					// read return types to '(' token
//					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varType
//					if (possibleForeachToken == ">") {
//						while (possibleForeachToken != null && possibleForeachToken != "(") {
//							possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
//						}
//					} else {
//						possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // (
//						if (possibleForeachToken == ".")
//							while (possibleForeachToken != null && possibleForeachToken != "(")
//								possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
//					}
//					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // foreach
//				
//					if (possibleForeachToken == "foreach") {
//						result.ExpressionContext = ExpressionContext.ForeachInToken;
//					} else {
//						return null;
//						//								result.ExpressionContext = ExpressionContext.IdentifierExpected;
//					}
//					result.Expression = "";
//					result.Region = DomRegion.Empty;
//				
//					return CreateCtrlSpaceCompletionData (completionContext, result);
//				}
//				break;
			}
			return null;
		}
Example #11
0
		static void AddKeywords (CompletionDataWrapper wrapper, IEnumerable<string> keywords)
		{
			foreach (string keyword in keywords) {
				wrapper.AddCustom (keyword);
			}
		}
Example #12
0
		void AddVirtuals (Dictionary<string, bool> alreadyInserted, CompletionDataWrapper col, string modifiers, IType curType, int declarationBegin)
		{
			if (curType == null)
				return;
			foreach (var m in curType.GetMethods (m => !m.IsConstructor && !m.IsDestructor).Cast<IMember> ().Concat (curType.GetProperties ().Cast<IMember> ()).Reverse ()) {
				if (m.IsSynthetic || curType.Kind != TypeKind.Interface && !m.IsOverridable)
					continue;
				// filter out the "Finalize" methods, because finalizers should be done with destructors.
				if (m is IMethod && m.Name == "Finalize")
					continue;
				
				var data = factory.CreateNewOverrideCompletionData (declarationBegin, currentType, m);
				string text = GetNameWithParamCount (m);
				
				// check if the member is already implemented
				bool foundMember = curType.GetMembers ().Any (cm => GetNameWithParamCount (cm) == text && cm.DeclaringTypeDefinition == curType.GetDefinition ());
				if (foundMember)
					continue;
				if (alreadyInserted.ContainsKey (text))
					continue;
				alreadyInserted [text] = true;
				data.CompletionCategory = col.GetCompletionCategory (curType);
				col.Add (data);
			}
		}
Example #13
0
		IEnumerable<ICompletionData> GetPartialCompletionData (ITypeDefinition type, string modifiers)
		{
			var wrapper = new CompletionDataWrapper (this);
			int declarationBegin = offset;
			int j = declarationBegin;
			for (int i = 0; i < 3; i++) {
				switch (GetPreviousToken (ref j, true)) {
				case "public":
				case "protected":
				case "private":
				case "internal":
				case "sealed":
				case "override":
					declarationBegin = j;
					break;
				case "static":
					return null; // don't add override completion for static members
				}
			}
			
			var methods = new List<IUnresolvedMethod> ();
			
			foreach (var part in type.Parts) {
				foreach (var method in part.Methods) {
					if (method.BodyRegion.IsEmpty) {
						if (GetImplementation (type, method) != null)
							continue;
						methods.Add (method);
					}
				}	
			}
			
			foreach (var method in methods) {
				wrapper.Add (factory.CreateNewPartialCompletionData (declarationBegin, method.DeclaringTypeDefinition, method));
			} 
			
			return wrapper.Result;
		}
Example #14
0
		void AddTypesAndNamespaces (CompletionDataWrapper wrapper, CppResolver state, AstNode node, Predicate<IType> typePred = null, Predicate<IMember> memberPred = null)
		{
			if (currentType != null) {
				for (var ct = currentType; ct != null; ct = ct.DeclaringTypeDefinition) {
					foreach (var nestedType in ct.NestedTypes) {
						if (typePred == null || typePred (nestedType.Resolve (ctx))) {
							string name = nestedType.Name;
							if (node is Attribute && name.EndsWith ("Attribute") && name.Length > "Attribute".Length)
								name = name.Substring (0, name.Length - "Attribute".Length);
							wrapper.AddType (nestedType, name);
						}
					}
				}
				if (this.currentMember != null && !(node is AstType)) {
					var def = ctx.CurrentTypeDefinition ?? Compilation.MainAssembly.GetTypeDefinition (currentType);
					if (def != null) {
						foreach (var member in def.GetMembers ()) {
							if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize")
								continue;
							if (member.EntityType == EntityType.Operator)
								continue;
							if (memberPred == null || memberPred (member))
								wrapper.AddMember (member);
						}
						var declaring = def.DeclaringTypeDefinition;
						while (declaring != null) {
							foreach (var member in declaring.GetMembers (m => m.IsStatic)) {
								if (memberPred == null || memberPred (member))
									wrapper.AddMember (member);
							}
							declaring = declaring.DeclaringTypeDefinition;
						}
					}
				}
				foreach (var p in currentType.TypeParameters) {
					wrapper.AddTypeParameter (p);
				}
			}
			var scope = CSharpParsedFile.GetUsingScope (location).Resolve (Compilation);
			
			for (var n = scope; n != null; n = n.Parent) {
				foreach (var pair in n.UsingAliases) {
					wrapper.AddNamespace (pair.Key);
				}
				foreach (var u in n.Usings) {
					foreach (var type in u.Types) {
						if (typePred == null || typePred (type)) {
							string name = type.Name;
							if (node is Attribute && name.EndsWith ("Attribute") && name.Length > "Attribute".Length)
								name = name.Substring (0, name.Length - "Attribute".Length);
							wrapper.AddType (type, name);
						}
					}
				}
				
				foreach (var type in n.Namespace.Types) {
					if (typePred == null || typePred (type))
						wrapper.AddType (type, type.Name);
				}
				
				foreach (var curNs in n.Namespace.ChildNamespaces) {
					wrapper.AddNamespace (curNs.Name);
				}
			}
		}
Example #15
0
		IEnumerable<ICompletionData> CreateParameterCompletion (MethodGroupResolveResult resolveResult, CppResolver state, AstNode invocation, int parameter, bool controlSpace)
		{
			var result = new CompletionDataWrapper (this);
			var addedEnums = new HashSet<string> ();
			var addedDelegates = new HashSet<string> ();
			
			foreach (var method in resolveResult.Methods) {
				if (method.Parameters.Count <= parameter)
					continue;
				var resolvedType = method.Parameters [parameter].Type;
				if (resolvedType.Kind == TypeKind.Enum) {
					if (addedEnums.Contains (resolvedType.ReflectionName))
						continue;
					addedEnums.Add (resolvedType.ReflectionName);
					AddEnumMembers (result, resolvedType, state);
				} else if (resolvedType.Kind == TypeKind.Delegate) {
//					if (addedDelegates.Contains (resolvedType.DecoratedFullName))
//						continue;
//					addedDelegates.Add (resolvedType.DecoratedFullName);
//					string parameterDefinition = AddDelegateHandlers (completionList, resolvedType, false, addedDelegates.Count == 1);
//					string varName = "Handle" + method.Parameters [parameter].ReturnType.Name + method.Parameters [parameter].Name;
//					result.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.Unit.GetMemberAt (location), resolvedType) { AddSemicolon = false });
				
				}
			}
			if (!controlSpace) {
				if (addedEnums.Count + addedDelegates.Count == 0)
					return Enumerable.Empty<ICompletionData> ();
				AutoCompleteEmptyMatch = false;
				AutoSelect = false;
			}
			AddContextCompletion (result, state, invocation);
			
//			resolver.AddAccessibleCodeCompletionData (ExpressionContext.MethodBody, cdc);
//			if (addedDelegates.Count > 0) {
//				foreach (var data in result.Result) {
//					if (data is MemberCompletionData) 
//						((MemberCompletionData)data).IsDelegateExpected = true;
//				}
//			}
			return result.Result;
		}
Example #16
0
		IEnumerable<ICompletionData> HandleKeywordCompletion (int wordStart, string word)
		{
			if (IsInsideCommentOrString ())
				return null;
			switch (word) {
			case "using":
			case "namespace":
				if (currentType != null)
					return null;
				var wrapper = new CompletionDataWrapper (this);
				AddTypesAndNamespaces (wrapper, GetState (), null, t => false);
				return wrapper.Result;
			case "case":
				return CreateCaseCompletionData (location);
//				case ",":
//				case ":":
//					if (result.ExpressionContext == ExpressionContext.InheritableType) {
//						IType cls = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
//						CompletionDataList completionList = new ProjectDomCompletionDataList ();
//						List<string > namespaceList = GetUsedNamespaces ();
//						var col = new CSharpTextEditorCompletion.CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, null, location);
//						bool isInterface = false;
//						HashSet<string > baseTypeNames = new HashSet<string> ();
//						if (cls != null) {
//							baseTypeNames.Add (cls.Name);
//							if (cls.ClassType == ClassType.Struct)
//								isInterface = true;
//						}
//						int tokenIndex = offset;
//	
//						// Search base types " : [Type1, ... ,TypeN,] <Caret>"
//						string token = null;
//						do {
//							token = GetPreviousToken (ref tokenIndex, false);
//							if (string.IsNullOrEmpty (token))
//								break;
//							token = token.Trim ();
//							if (Char.IsLetterOrDigit (token [0]) || token [0] == '_') {
//								IType baseType = dom.SearchType (Document.CompilationUnit, cls, result.Region.Start, token);
//								if (baseType != null) {
//									if (baseType.ClassType != ClassType.Interface)
//										isInterface = true;
//									baseTypeNames.Add (baseType.Name);
//								}
//							}
//						} while (token != ":");
//						foreach (object o in dom.GetNamespaceContents (namespaceList, true, true)) {
//							IType type = o as IType;
//							if (type != null && (type.IsStatic || type.IsSealed || baseTypeNames.Contains (type.Name) || isInterface && type.ClassType != ClassType.Interface)) {
//								continue;
//							}
//							if (o is Namespace && !namespaceList.Any (ns => ns.StartsWith (((Namespace)o).FullName)))
//								continue;
//							col.Add (o);
//						}
//						// Add inner classes
//						Stack<IType > innerStack = new Stack<IType> ();
//						innerStack.Push (cls);
//						while (innerStack.Count > 0) {
//							IType curType = innerStack.Pop ();
//							if (curType == null)
//								continue;
//							foreach (IType innerType in curType.InnerTypes) {
//								if (innerType != cls)
//									// don't add the calling class as possible base type
//									col.Add (innerType);
//							}
//							if (curType.DeclaringType != null)
//								innerStack.Push (curType.DeclaringType);
//						}
//						return completionList;
//					}
//					break;
			case "is":
			case "as":
				if (currentType == null)
					return null;
				IType isAsType = null;
				var isAsExpression = GetExpressionAt (wordStart);
				if (isAsExpression != null) {
					var parent = isAsExpression.Item2.Parent;
					if (parent is VariableInitializer)
						parent = parent.Parent;
					if (parent is VariableDeclarationStatement) {
						var resolved = ResolveExpression (isAsExpression.Item1, parent, isAsExpression.Item3);
						if (resolved != null)
							isAsType = resolved.Item1.Type;
					}
				}
				var isAsWrapper = new CompletionDataWrapper (this);
				AddTypesAndNamespaces (isAsWrapper, GetState (), null, t => isAsType == null || t.GetDefinition ().IsDerivedFrom (isAsType.GetDefinition ()));
				return isAsWrapper.Result;
//					{
//						CompletionDataList completionList = new ProjectDomCompletionDataList ();
//						ExpressionResult expressionResult = FindExpression (dom, completionContext, wordStart - document.Caret.Offset);
//						NRefactoryResolver resolver = CreateResolver ();
//						ResolveResult resolveResult = resolver.Resolve (expressionResult, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
//						if (resolveResult != null && resolveResult.ResolvedType != null) {
//							CompletionDataCollector col = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
//							IType foundType = null;
//							if (word == "as") {
//								ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForAsCompletion (document, Document.CompilationUnit, Document.FileName, resolver.CallingType);
//								if (exactContext is ExpressionContext.TypeExpressionContext) {
//									foundType = resolver.SearchType (((ExpressionContext.TypeExpressionContext)exactContext).Type);
//									AddAsCompletionData (col, foundType);
//								}
//							}
//						
//							if (foundType == null)
//								foundType = resolver.SearchType (resolveResult.ResolvedType);
//						
//							if (foundType != null) {
//								if (foundType.ClassType == ClassType.Interface)
//									foundType = resolver.SearchType (DomReturnType.Object);
//							
//								foreach (IType type in dom.GetSubclasses (foundType)) {
//									if (type.IsSpecialName || type.Name.StartsWith ("<"))
//										continue;
//									AddAsCompletionData (col, type);
//								}
//							}
//							List<string > namespaceList = GetUsedNamespaces ();
//							foreach (object o in dom.GetNamespaceContents (namespaceList, true, true)) {
//								if (o is IType) {
//									IType type = (IType)o;
//									if (type.ClassType != ClassType.Interface || type.IsSpecialName || type.Name.StartsWith ("<"))
//										continue;
//	//								if (foundType != null && !dom.GetInheritanceTree (foundType).Any (x => x.FullName == type.FullName))
//	//									continue;
//									AddAsCompletionData (col, type);
//									continue;
//								}
//								if (o is Namespace)
//									continue;
//								col.Add (o);
//							}
//							return completionList;
//						}
//						result.ExpressionContext = ExpressionContext.TypeName;
//						return CreateCtrlSpaceCompletionData (completionContext, result);
//					}
			case "override":
				// Look for modifiers, in order to find the beginning of the declaration
				int firstMod = wordStart;
				int i = wordStart;
				for (int n = 0; n < 3; n++) {
					string mod = GetPreviousToken (ref i, true);
					if (mod == "public" || mod == "protected" || mod == "private" || mod == "internal" || mod == "sealed") {
						firstMod = i;
					} else if (mod == "static") {
						// static methods are not overridable
						return null;
					} else
						break;
				}
				if (!IsLineEmptyUpToEol ())
					return null;
				if (currentType != null && (currentType.Kind == TypeKind.Class || currentType.Kind == TypeKind.Struct)) {
					string modifiers = document.GetText (firstMod, wordStart - firstMod);
					return GetOverrideCompletionData (currentType, modifiers);
				}
				return null;
			case "partial":
				// Look for modifiers, in order to find the beginning of the declaration
				firstMod = wordStart;
				i = wordStart;
				for (int n = 0; n < 3; n++) {
					string mod = GetPreviousToken (ref i, true);
					if (mod == "public" || mod == "protected" || mod == "private" || mod == "internal" || mod == "sealed") {
						firstMod = i;
					} else if (mod == "static") {
						// static methods are not overridable
						return null;
					} else
						break;
				}
				if (!IsLineEmptyUpToEol ())
					return null;
				var state = GetState ();
				
				if (state.CurrentTypeDefinition != null && (state.CurrentTypeDefinition.Kind == TypeKind.Class || state.CurrentTypeDefinition.Kind == TypeKind.Struct)) {
					string modifiers = document.GetText (firstMod, wordStart - firstMod);
					return GetPartialCompletionData (state.CurrentTypeDefinition, modifiers);
				}
				return null;
				
			case "public":
			case "protected":
			case "private":
			case "internal":
			case "sealed":
			case "static":
				var accessorContext = HandleAccessorContext ();
				if (accessorContext != null)
					return accessorContext;
				wrapper = new CompletionDataWrapper (this);
				state = GetState ();
				AddTypesAndNamespaces (wrapper, state, null, null, m => false);
				AddKeywords (wrapper, typeLevelKeywords);
				AddKeywords (wrapper, primitiveTypesKeywords);
				return wrapper.Result;
			case "new":
				int j = offset - 4;
//				string token = GetPreviousToken (ref j, true);
				
				IType hintType = null;
				var expressionOrVariableDeclaration = GetNewExpressionAt (j);
				AstNode newParentNode = null;
				AstType hintTypeAst = null;
				if (expressionOrVariableDeclaration != null) {
					newParentNode = expressionOrVariableDeclaration.Item2.Parent;
					if (newParentNode is VariableInitializer)
						newParentNode = newParentNode.Parent;
				}
				if (newParentNode is InvocationExpression) {
					var invoke = (InvocationExpression)newParentNode;
					var resolved = ResolveExpression (expressionOrVariableDeclaration.Item1, invoke, expressionOrVariableDeclaration.Item3);
					if (resolved != null) {
						var mgr = resolved.Item1 as CppInvocationResolveResult;
						if (mgr != null) {
							int i1 = 0;
							foreach (var a in invoke.Arguments) {
								if (a == expressionOrVariableDeclaration.Item2) {
									if (mgr.Member.Parameters.Count > i1)
										hintType = mgr.Member.Parameters [i1].Type;
									break;
								}
								i1++;
							}
						}
					}
				}
				
				if (newParentNode is ObjectCreateExpression) {
					var invoke = (ObjectCreateExpression)newParentNode;
					var resolved = ResolveExpression (expressionOrVariableDeclaration.Item1, invoke, expressionOrVariableDeclaration.Item3);
					if (resolved != null) {
						var mgr = resolved.Item1 as CppInvocationResolveResult;
						if (mgr != null) {
							int i1 = 0;
							foreach (var a in invoke.Arguments) {
								if (a == expressionOrVariableDeclaration.Item2) {
									if (mgr.Member.Parameters.Count > i1)
										hintType = mgr.Member.Parameters [i1].Type;
									break;
								}
								i1++;
							}
						}
					}
				}
				
				if (newParentNode is AssignmentExpression) {
					var assign = (AssignmentExpression)newParentNode;
					var resolved = ResolveExpression (expressionOrVariableDeclaration.Item1, assign.Left, expressionOrVariableDeclaration.Item3);
					if (resolved != null) {
						hintType = resolved.Item1.Type;
					}
				}
				
				if (newParentNode is VariableDeclarationStatement) {
					var varDecl = (VariableDeclarationStatement)newParentNode;
					hintTypeAst = varDecl.Type;
					var resolved = ResolveExpression (expressionOrVariableDeclaration.Item1, varDecl.Type, expressionOrVariableDeclaration.Item3);
					if (resolved != null) {
						hintType = resolved.Item1.Type;
					}
				}
				
				if (newParentNode is FieldDeclaration) {
					var varDecl = (FieldDeclaration)newParentNode;
					hintTypeAst = varDecl.ReturnType;
					var resolved = ResolveExpression (expressionOrVariableDeclaration.Item1, varDecl.ReturnType, expressionOrVariableDeclaration.Item3);
					if (resolved != null)
						hintType = resolved.Item1.Type;
				}
				return CreateTypeCompletionData (hintType, hintTypeAst);
//					IType callingType = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new TextLocation (document.Caret.Line, document.Caret.Column));
//					ExpressionContext newExactContext = new NewCSharpExpressionFinder (dom).FindExactContextForNewCompletion (document, Document.CompilationUnit, Document.FileName, callingType);
//					if (newExactContext is ExpressionContext.TypeExpressionContext)
//						return CreateTypeCompletionData (location, callingType, newExactContext, ((ExpressionContext.TypeExpressionContext)newExactContext).Type, ((ExpressionContext.TypeExpressionContext)newExactContext).UnresolvedType);
//					if (newExactContext == null) {
//						int j = offset - 4;
//						
//						string yieldToken = GetPreviousToken (ref j, true);
//						if (token == "return") {
//							NRefactoryResolver resolver = CreateResolver ();
//							resolver.SetupResolver (new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
//							IReturnType returnType = resolver.CallingMember.ReturnType;
//							if (yieldToken == "yield" && returnType.GenericArguments.Count > 0)
//								returnType = returnType.GenericArguments [0];
//							if (resolver.CallingMember != null)
//								return CreateTypeCompletionData (location, callingType, newExactContext, null, returnType);
//						}
//					}
//					return CreateCtrlSpaceCompletionData (completionContext, null);
			case "if":
			case "elif":
				if (wordStart > 0 && document.GetCharAt (wordStart - 1) == '#') 
					return factory.CreatePreProcessorDefinesCompletionData ();
				return null;
			case "yield":
				var yieldDataList = new CompletionDataWrapper (this);
				DefaultCompletionString = "return";
				yieldDataList.AddCustom ("break");
				yieldDataList.AddCustom ("return");
				return yieldDataList.Result;
			case "in":
				var inList = new CompletionDataWrapper (this);
				var node = Unit.GetNodeAt (location);
				var rr = ResolveExpression (CSharpParsedFile, node, Unit);
				AddContextCompletion (inList, rr != null ? rr.Item2 : GetState (), node);
				return inList.Result;
//				case "where":
//					CompletionDataList whereDataList = new CompletionDataList ();
//					NRefactoryResolver constraintResolver = CreateResolver ();
//					constraintResolver.SetupResolver (new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
//					if (constraintResolver.CallingMember is IMethod) {
//						foreach (ITypeParameter tp in ((IMethod)constraintResolver.CallingMember).TypeParameters) {
//							whereDataList.Add (tp.Name, "md-keyword");
//						}
//					} else {
//						if (constraintResolver.CallingType != null) {
//							foreach (ITypeParameter tp in constraintResolver.CallingType.TypeParameters) {
//								whereDataList.Add (tp.Name, "md-keyword");
//							}
//						}
//					}
//	
//					return whereDataList;
			}
//				if (IsInLinqContext (result)) {
//					if (linqKeywords.Contains (word)) {
//						if (word == "from") // after from no auto code completion.
//							return null;
//						result.Expression = "";
//						return CreateCtrlSpaceCompletionData (completionContext, result);
//					}
//					CompletionDataList dataList = new ProjectDomCompletionDataList ();
//					CompletionDataCollector col = new CompletionDataCollector (this, dom, dataList, Document.CompilationUnit, null, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
//					foreach (string kw in linqKeywords) {
//						col.Add (kw, "md-keyword");
//					}
//					return dataList;
//				}
			return null;
		}
Example #17
0
		IEnumerable<ICompletionData> CreateTypeCompletionData (IType hintType, AstType hintTypeAst)
		{
			var wrapper = new CompletionDataWrapper (this);
			var state = GetState ();
			Predicate<IType> pred = null;
			if (hintType != null) {
				
				if (hintType.Kind != TypeKind.Unknown) {
					var lookup = new MemberLookup (ctx.CurrentTypeDefinition, Compilation.MainAssembly);
					pred = t => {
						// check if type is in inheritance tree.
						if (hintType.GetDefinition () != null && !t.GetDefinition ().IsDerivedFrom (hintType.GetDefinition ()))
							return false;
						
						// check for valid constructors
						if (t.GetConstructors ().Count () == 0)
							return true;
						bool isProtectedAllowed = currentType != null ? currentType.Resolve (ctx).GetDefinition ().IsDerivedFrom (t.GetDefinition ()) : false;
						return t.GetConstructors ().Any (m => lookup.IsAccessible (m, isProtectedAllowed));
					};
					DefaultCompletionString = GetShortType (hintType, GetState ());
					wrapper.AddType (hintType, DefaultCompletionString);
				} else {
					DefaultCompletionString = hintTypeAst.ToString ();
					wrapper.AddType (hintType, DefaultCompletionString);
				}
			} 
			AddTypesAndNamespaces (wrapper, state, null, pred, m => false);
			AddKeywords (wrapper, primitiveTypesKeywords.Where (k => k != "void"));
			CloseOnSquareBrackets = true;
			AutoCompleteEmptyMatch = true;
			return wrapper.Result;
		}