Ejemplo n.º 1
0
        protected bool IsInsideAsmCode(int offset)
        {
            var lexer = new MiniLexer(document.Text);

            lexer.Parse(0, offset);
            return(lexer.IsInAsmCode);
        }
Ejemplo n.º 2
0
        protected bool IsInsideAsmCode()
        {
            var text  = GetMemberTextToCaret();
            var lexer = new MiniLexer(text.Item1);

            lexer.Parse();
            return
                (lexer.IsInAsmCode);
        }
        protected bool IsInsideCommentStringOrDirective(int offset)
        {
            var lexer = new MiniLexer(document.Text);

            lexer.Parse(0, offset);
            return
                (lexer.IsInSingleComment ||
                 lexer.IsInString ||
                 lexer.IsInVerbatimString ||
                 lexer.IsInChar ||
                 lexer.IsInMultiLineComment ||
                 lexer.IsInPreprocessorDirective);
        }
        protected bool IsInsideCommentStringOrDirective()
        {
            var text  = GetMemberTextToCaret();
            var lexer = new MiniLexer(text.Item1);

            lexer.Parse();
            return
                (lexer.IsInSingleComment ||
                 lexer.IsInString ||
                 lexer.IsInVerbatimString ||
                 lexer.IsInChar ||
                 lexer.IsInMultiLineComment ||
                 lexer.IsInPreprocessorDirective);
        }
Ejemplo n.º 5
0
		IEnumerable<ICompletionData> MagicKeyCompletion(char completionChar, bool controlSpace, out bool isComplete)
		{
			isComplete = false;
			ExpressionResolveResult resolveResult;
			switch (completionChar) {
				// Magic key completion
				case ':':
					var text = GetMemberTextToCaret();
					var lexer = new MiniLexer(text.Item1);
					lexer.Parse();
					if (lexer.IsInSingleComment ||
						lexer.IsInChar ||
						lexer.IsInMultiLineComment ||
						lexer.IsInPreprocessorDirective) {
						return Enumerable.Empty<ICompletionData>();
					}

					if (lexer.IsInString || lexer.IsInVerbatimString)
						return HandleStringFormatItems();
					return HandleMemberReferenceCompletion(GetExpressionBeforeCursor());
				case '"':
					text = GetMemberTextToCaret();
					lexer = new MiniLexer(text.Item1);
					lexer.Parse();
					if (lexer.IsInSingleComment ||
						lexer.IsInChar ||
						lexer.IsInMultiLineComment ||
						lexer.IsInPreprocessorDirective) {
						return Enumerable.Empty<ICompletionData>();
					}

					if (lexer.IsInString || lexer.IsInVerbatimString)
						return HandleToStringFormatItems();
					return Enumerable.Empty<ICompletionData>();
				case '.':
					if (IsInsideCommentStringOrDirective()) {
						return Enumerable.Empty<ICompletionData>();
					}
					return HandleMemberReferenceCompletion(GetExpressionBeforeCursor());
				case '#':
					if (!IsInPreprocessorDirective())
						return null;
					return GetDirectiveCompletionData();
					// XML doc completion
				case '<':
					if (IsInsideDocComment()) {
						return GetXmlDocumentationCompletionData();
					}
					if (controlSpace) {
						return DefaultControlSpaceItems(ref isComplete);
					}
					return null;
				case '>':
					if (!IsInsideDocComment()) {
						if (offset > 2 && document.GetCharAt(offset - 2) == '-' && !IsInsideCommentStringOrDirective()) {
							return HandleMemberReferenceCompletion(GetExpressionBeforeCursor());
						}
						return null;
					}
					return null;

					// Parameter completion
				case '(':
					if (IsInsideCommentStringOrDirective()) {
						return null;
					}
					var invoke = GetInvocationBeforeCursor(true);
					if (invoke == null) {
						if (controlSpace)
							return DefaultControlSpaceItems(ref isComplete, invoke);
						return null;
					}
					if (invoke.Node is TypeOfExpression) {
						return CreateTypeList();
					}
					var invocationResult = ResolveExpression(invoke);
					if (invocationResult == null) {
						return null;
					}
					var methodGroup = invocationResult.Result as MethodGroupResolveResult;
					if (methodGroup != null) {
						return CreateParameterCompletion(
							methodGroup,
							invocationResult.Resolver,
							invoke.Node,
							invoke.Unit,
							0,
							controlSpace
						);
					}

					if (controlSpace) {
						return DefaultControlSpaceItems(ref isComplete, invoke);
					}
					return null;
				case '=':
					return controlSpace ? DefaultControlSpaceItems(ref isComplete) : 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 ' ':
					int tokenIndex = offset;
					string token = GetPreviousToken(ref tokenIndex, false);
					if (IsInsideCommentStringOrDirective()) {
						return null;
					}
					// 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.Node is VariableDeclarationStatement && token != "new") {
						var parent = isAsExpression.Node as VariableDeclarationStatement;
						var proposeNameList = new CompletionDataWrapper(this);
						if (parent.Variables.Count != 1)
							return DefaultControlSpaceItems(ref isComplete, isAsExpression, controlSpace);

						foreach (var possibleName in GenerateNameProposals (parent.Type)) {
							if (possibleName.Length > 0) {
								proposeNameList.Result.Add(factory.CreateLiteralCompletionData(possibleName.ToString()));
							}
						}

						AutoSelect = false;
						AutoCompleteEmptyMatch = false;
						isComplete = true;
						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 == "-" || prevToken == "!") {
							token = prevToken + token;
							tokenIndex = j;
						}
					}
					switch (token) {
						case "(":
						case ",":
							int cpos;
							if (!GetParameterCompletionCommandOffset(out cpos)) { 
								break;
							}
							int currentParameter = GetCurrentParameterIndex(cpos - 1, this.offset) - 1;
							if (currentParameter < 0) {
								return null;
							}
							invoke = GetInvocationBeforeCursor(token == "(");
							if (invoke == null) {
								return null;
							}
							invocationResult = ResolveExpression(invoke);
							if (invocationResult == null) {
								return null;
							}
							methodGroup = invocationResult.Result as MethodGroupResolveResult;
							if (methodGroup != null) {
								return CreateParameterCompletion(
									methodGroup,
									invocationResult.Resolver,
									invoke.Node,
									invoke.Unit,
									currentParameter,
									controlSpace);
							}
							return null;
						case "=":
						case "==":
						case "!=":
							GetPreviousToken(ref tokenIndex, false);
							var expressionOrVariableDeclaration = GetExpressionAt(tokenIndex);
							if (expressionOrVariableDeclaration == null) {
								return null;
							}
							resolveResult = ResolveExpression(expressionOrVariableDeclaration);
							if (resolveResult == null) {
								return null;
							}
							if (resolveResult.Result.Type.Kind == TypeKind.Enum) {
								var wrapper = new CompletionDataWrapper(this);
								AddContextCompletion(
									wrapper,
									resolveResult.Resolver,
									expressionOrVariableDeclaration.Node);
								AddEnumMembers(wrapper, resolveResult.Result.Type, resolveResult.Resolver);
								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);
							if (resolveResult == null) {
								return null;
							}


							var mrr = resolveResult.Result 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 ctx.CurrentTypeDefinition.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 ":":
							if (currentMember == null) {
								token = GetPreviousToken(ref tokenIndex, false);
								token = GetPreviousToken(ref tokenIndex, false);
								if (token == "enum")
									return HandleEnumContext();
								var wrapper = new CompletionDataWrapper(this);
								AddTypesAndNamespaces(
									wrapper,
									GetState(),
									null,
									t =>  {
										if (currentType != null && currentType.ReflectionName.Equals(t.ReflectionName))
											return null;
										var def = t.GetDefinition();
										if (def != null && t.Kind != TypeKind.Interface && (def.IsSealed ||def.IsStatic))
											return null;
										return t;
									}
								);
								return wrapper.Result;
							}
							return null;
					}

					var keywordCompletion = HandleKeywordCompletion(tokenIndex, token);
					if (keywordCompletion == null && controlSpace) {
						goto default;
					}
					return keywordCompletion;
					// Automatic completion
				default:
					if (IsInsideCommentStringOrDirective()) {
						tokenIndex = offset;
						token = GetPreviousToken(ref tokenIndex, false);
						if (IsInPreprocessorDirective() && (token.Length == 1 && char.IsLetter(completionChar) || controlSpace)) {
							while (token != null && document.GetCharAt(tokenIndex - 1) != '#') {
								token = GetPreviousToken(ref tokenIndex, false);
							}
							if (token != null)
								return HandleKeywordCompletion(tokenIndex, token);
						}
						return 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) || !(Char.IsWhiteSpace(prevCh) || allowedChars.IndexOf(prevCh) >= 0)) {
						if (!controlSpace)
							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(ref isComplete);
						}
						var dataList = new CompletionDataWrapper(this);
						AddKeywords(dataList, linqKeywords);
						return dataList.Result;
					}
					if (currentType != null && currentType.Kind == TypeKind.Enum) {
						if (!char.IsLetter(completionChar))
							return null;
						return HandleEnumContext();
					}
					var contextList = new CompletionDataWrapper(this);
					var identifierStart = GetExpressionAtCursor();
					if (!(char.IsLetter(completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null)) {
						return controlSpace ? HandleAccessorContext() ?? DefaultControlSpaceItems(ref isComplete, identifierStart) : null;
					}

					if (identifierStart != null) {
						if (identifierStart.Node is TypeParameterDeclaration) {
							return null;
						}

						if (identifierStart.Node is MemberReferenceExpression) {
							return HandleMemberReferenceCompletion(
								new ExpressionResult(
									((MemberReferenceExpression)identifierStart.Node).Target,
									identifierStart.Unit
								)
							);
						}

						if (identifierStart.Node is Identifier) {
							if (identifierStart.Node.Parent is GotoStatement)
								return null;

							// May happen in variable names
							return controlSpace ? DefaultControlSpaceItems(ref isComplete, identifierStart) : null;
						}
						if (identifierStart.Node is VariableInitializer && location <= ((VariableInitializer)identifierStart.Node).NameToken.EndLocation) {
							return controlSpace ? HandleAccessorContext() ?? DefaultControlSpaceItems(ref isComplete, identifierStart) : null;
						}
						if (identifierStart.Node is CatchClause) {
							if (((CatchClause)identifierStart.Node).VariableNameToken.IsInside(location)) {
								return null;
							}
						}
						if (identifierStart.Node is AstType && identifierStart.Node.Parent is CatchClause) {
							return HandleCatchClauseType(identifierStart);
						}

						var pDecl = identifierStart.Node as ParameterDeclaration;
						if (pDecl != null && pDecl.Parent is LambdaExpression) {
							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;
					}
					var keywordresult = HandleKeywordCompletion(tokenIndex, token);
					if (keywordresult != null) {
						return keywordresult;
					}

					if ((!Char.IsWhiteSpace(nextCh) && allowedChars.IndexOf(nextCh) < 0) || !(Char.IsWhiteSpace(prevCh) || allowedChars.IndexOf(prevCh) >= 0)) {
						if (controlSpace)
							return DefaultControlSpaceItems(ref isComplete, identifierStart);
					}

					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) && !IsInsideCommentStringOrDirective() && (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(ref isComplete, null, controlSpace);
					}
					CSharpResolver csResolver;
					AstNode n = identifierStart.Node;
					if (n.Parent is NamedArgumentExpression)
						n = n.Parent;

					if (n != null && n.Parent is AnonymousTypeCreateExpression) {
						AutoSelect = false;
					}

					// new { b$ } 
					if (n is IdentifierExpression && n.Parent is AnonymousTypeCreateExpression)
						return null;

					// Handle foreach (type name _
					if (n is IdentifierExpression) {
						var prev = n.GetPrevNode() as ForeachStatement;
						while (prev != null && prev.EmbeddedStatement is ForeachStatement)
							prev = (ForeachStatement)prev.EmbeddedStatement;
						if (prev != null && prev.InExpression.IsNull) {
							if (IncludeKeywordsInCompletionList)
								contextList.AddCustom("in");
							return contextList.Result;
						}
					}
					// Handle object/enumerable initialzer expressions: "new O () { P$"
					if (n is IdentifierExpression && n.Parent is ArrayInitializerExpression && !(n.Parent.Parent is ArrayCreateExpression)) {
						var result = HandleObjectInitializer(identifierStart.Unit, n);
						if (result != null)
							return result;
					}

					if (n != null && n.Parent is InvocationExpression ||
						n.Parent is ParenthesizedExpression && n.Parent.Parent is InvocationExpression) {
						if (n.Parent is ParenthesizedExpression)
							n = n.Parent;
						var invokeParent = (InvocationExpression)n.Parent;
						var invokeResult = ResolveExpression(
							invokeParent.Target
						);
						var mgr = invokeResult != null ? invokeResult.Result 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.AddNamedParameterVariable(p);
								}
							}
							idx++;
							foreach (var list in mgr.GetEligibleExtensionMethods (true)) {
								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(n.Parent);
						var mgr = invokeResult != null ? invokeResult.Result 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(evaluationExpr);
							if (resolveResult != null && resolveResult.Result.Type.Kind == TypeKind.Enum) {
								var wrapper = new CompletionDataWrapper(this);
								AddContextCompletion(
									wrapper,
									resolveResult.Resolver,
									evaluationExpr
								);
								AddEnumMembers(wrapper, resolveResult.Result.Type, resolveResult.Resolver);
								AutoCompleteEmptyMatch = false;
								return wrapper.Result;
							}
						}
					}

					if (n is Identifier && n.Parent is ForeachStatement) {
						if (controlSpace) {
							return DefaultControlSpaceItems(ref isComplete);
						}
						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(ref isComplete);
						}

						var initalizerResult = ResolveExpression(n.Parent);

						var concreteNode = identifierStart.Unit.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(ref isComplete);
						}
						if (initalizerResult != null && initalizerResult.Result.Type.Kind != TypeKind.Unknown) { 

							foreach (var property in initalizerResult.Result.Type.GetProperties ()) {
								if (!property.IsPublic) {
									continue;
								}
								var data = contextList.AddMember(property);
								if (data != null)
									data.DisplayFlags |= DisplayFlags.NamedArgument;
							}
							foreach (var field in initalizerResult.Result.Type.GetFields ()) {       
								if (!field.IsPublic) {
									continue;
								}
								var data = contextList.AddMember(field);
								if (data != null)
									data.DisplayFlags |= DisplayFlags.NamedArgument;
							}
							return contextList.Result;
						}
						return DefaultControlSpaceItems(ref isComplete);
					}

					if (IsAttributeContext(n)) {
						// add attribute targets
						if (currentType == null) {
							contextList.AddCustom("assembly");
							contextList.AddCustom("module");
							contextList.AddCustom("type");
						} else {
							contextList.AddCustom("param");
							contextList.AddCustom("field");
							contextList.AddCustom("property");
							contextList.AddCustom("method");
							contextList.AddCustom("event");
						}
						contextList.AddCustom("return");
					}
					if (n is MemberType) {
						resolveResult = ResolveExpression(
							((MemberType)n).Target
						);
						return CreateTypeAndNamespaceCompletionData(
							location,
							resolveResult.Result,
							((MemberType)n).Target,
							resolveResult.Resolver
						);
					}
					if (n != null/*					 && !(identifierStart.Item2 is TypeDeclaration)*/) {
						csResolver = new CSharpResolver(ctx);
						var nodes = new List<AstNode>();
						nodes.Add(n);
						if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) {
							nodes.Add(n.Parent);
						}
						var astResolver = CompletionContextProvider.GetResolver(csResolver, identifierStart.Unit);
						astResolver.ApplyNavigator(new NodeListResolveVisitorNavigator(nodes));
						try {
							csResolver = astResolver.GetResolverStateBefore(n);
						} catch (Exception) {
							csResolver = GetState();
						}
						// add attribute properties.
						if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) {
							var rr = ResolveExpression(n.Parent);
							if (rr != null)
								AddAttributeProperties(contextList, rr.Result);
						}
					} else {
						csResolver = GetState();
					}
					// identifier has already started with the first letter
					offset--;
					AddContextCompletion(
						contextList,
						csResolver,
						identifierStart.Node
					);
					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;

		}
Ejemplo n.º 6
0
		bool IsInPreprocessorDirective()
		{
			var text = GetMemberTextToCaret().Item1;
			var miniLexer = new MiniLexer(text);
			miniLexer.Parse();
			return miniLexer.IsInPreprocessorDirective;
		}
		protected bool IsInsideCommentStringOrDirective()
		{
			var text = GetMemberTextToCaret();
			var lexer = new MiniLexer(text.Item1);
			lexer.Parse();
			return
				lexer.IsInSingleComment || 
				lexer.IsInString ||
				lexer.IsInVerbatimString ||
				lexer.IsInChar ||
				lexer.IsInMultiLineComment || 
				lexer.IsInPreprocessorDirective;
		}
		protected bool IsInsideCommentStringOrDirective(int offset)
		{
			var lexer = new MiniLexer(document.Text);
			lexer.Parse(0, offset);
			return
				lexer.IsInSingleComment || 
				lexer.IsInString ||
				lexer.IsInVerbatimString ||
				lexer.IsInChar ||
				lexer.IsInMultiLineComment || 
				lexer.IsInPreprocessorDirective;
		}
Ejemplo n.º 9
0
        public IParameterDataProvider GetParameterDataProvider(int offset, char completionChar)
        {
            //Ignoring completionChar == '\0' because it usually means moving with arrow keys, tab or enter
            //we don't want to trigger on those events but it probably should be handled somewhere else
            //since our job is to resolve method and not to decide when to display tooltip or not
            if (offset <= 0 || completionChar == '\0')
            {
                return(null);
            }
            SetOffset(offset);
            int    startOffset;
            string text;

            if (currentMember == null && currentType == null)
            {
                //In case of attributes parse all file
                startOffset = 0;
                text        = document.Text;
            }
            else
            {
                var memberText = GetMemberTextToCaret();
                text        = memberText.Item1;
                startOffset = document.GetOffset(memberText.Item2);
            }

            var parenStack   = new Stack <int> ();
            var chevronStack = new Stack <int> ();
            var squareStack  = new Stack <int> ();
            var bracketStack = new Stack <int> ();

            var  lex    = new MiniLexer(text);
            bool failed = lex.Parse((ch, off) => {
                if (lex.IsInString || lex.IsInChar || lex.IsInVerbatimString || lex.IsInSingleComment || lex.IsInMultiLineComment || lex.IsInPreprocessorDirective)
                {
                    return(false);
                }
                switch (ch)
                {
                case '(':
                    parenStack.Push(startOffset + off);
                    break;

                case ')':
                    if (parenStack.Count == 0)
                    {
                        return(true);
                    }
                    parenStack.Pop();
                    break;

                case '<':
                    chevronStack.Push(startOffset + off);
                    break;

                case '>':
                    //Don't abort if we don't have macthing '<' for '>' it could be if (i > 0) Foo($
                    if (chevronStack.Count == 0)
                    {
                        return(false);
                    }
                    chevronStack.Pop();
                    break;

                case '[':
                    squareStack.Push(startOffset + off);
                    break;

                case ']':
                    if (squareStack.Count == 0)
                    {
                        return(true);
                    }
                    squareStack.Pop();
                    break;

                case '{':
                    bracketStack.Push(startOffset + off);
                    break;

                case '}':
                    if (bracketStack.Count == 0)
                    {
                        return(true);
                    }
                    bracketStack.Pop();
                    break;
                }
                return(false);
            });

            if (failed)
            {
                return(null);
            }
            int result = -1;

            if (parenStack.Count > 0)
            {
                result = parenStack.Pop();
            }
            if (squareStack.Count > 0)
            {
                result = Math.Max(result, squareStack.Pop());
            }
            if (chevronStack.Count > 0)
            {
                result = Math.Max(result, chevronStack.Pop());
            }

            //If we are inside { bracket we don't want to display anything
            if (bracketStack.Count > 0 && bracketStack.Pop() > result)
            {
                return(null);
            }
            if (result == -1)
            {
                return(null);
            }
            SetOffset(result + 1);
            ResolveResult resolveResult;

            switch (document.GetCharAt(result))
            {
            case '(':
                var invoke = GetInvocationBeforeCursor(true) ?? GetConstructorInitializerBeforeCursor();
                if (invoke == null)
                {
                    return(null);
                }
                if (invoke.Node is ConstructorInitializer)
                {
                    var init = (ConstructorInitializer)invoke.Node;
                    if (init.ConstructorInitializerType == ConstructorInitializerType.This)
                    {
                        return(factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), ctx.CurrentTypeDefinition, init));
                    }
                    else
                    {
                        var baseType = ctx.CurrentTypeDefinition.DirectBaseTypes.FirstOrDefault(bt => bt.Kind != TypeKind.Interface);
                        if (baseType == null)
                        {
                            return(null);
                        }
                        return(factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), baseType));
                    }
                }
                if (invoke.Node is ObjectCreateExpression)
                {
                    var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type);
                    if (createType.Result.Type.Kind == TypeKind.Unknown)
                    {
                        return(null);
                    }
                    return(factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Result.Type));
                }

                if (invoke.Node is ICSharpCode.NRefactory.CSharp.Attribute)
                {
                    var attribute = ResolveExpression(invoke);
                    if (attribute == null || attribute.Result == null)
                    {
                        return(null);
                    }
                    return(factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), attribute.Result.Type));
                }
                var invocationExpression = ResolveExpression(invoke);
                if (invocationExpression == null || invocationExpression.Result == null || invocationExpression.Result.IsError)
                {
                    return(null);
                }
                resolveResult = invocationExpression.Result;
                if (resolveResult is MethodGroupResolveResult)
                {
                    return(factory.CreateMethodDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectMethods(invoke.Node, resolveResult as MethodGroupResolveResult)));
                }
                if (resolveResult is MemberResolveResult)
                {
                    var mr = resolveResult as MemberResolveResult;
                    if (mr.Member is IMethod)
                    {
                        return(factory.CreateMethodDataProvider(document.GetOffset(invoke.Node.StartLocation), new [] { (IMethod)mr.Member }));
                    }
                }

                if (resolveResult.Type.Kind == TypeKind.Delegate)
                {
                    return(factory.CreateDelegateDataProvider(document.GetOffset(invoke.Node.StartLocation), resolveResult.Type));
                }

                //
                //				if (result.ExpressionContext == ExpressionContext.BaseConstructorCall) {
                //					if (resolveResult is ThisResolveResult)
                //						return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as ThisResolveResult);
                //					if (resolveResult is BaseResolveResult)
                //						return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as BaseResolveResult);
                //				}
                //				IType resolvedType = resolver.SearchType (resolveResult.ResolvedType);
                //				if (resolvedType != null && resolvedType.ClassType == ClassType.Delegate) {
                //					return new NRefactoryParameterDataProvider (textEditorData, result.Expression, resolvedType);
                //				}
                break;

            case '<':
                invoke = GetMethodTypeArgumentInvocationBeforeCursor();
                if (invoke != null)
                {
                    var tExpr2 = ResolveExpression(invoke);
                    if (tExpr2 != null && tExpr2.Result is MethodGroupResolveResult && !tExpr2.Result.IsError)
                    {
                        return(factory.CreateTypeParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectMethods(invoke.Node, tExpr2.Result as MethodGroupResolveResult)));
                    }
                }
                invoke = GetTypeBeforeCursor();
                if (invoke == null || invoke.Node.StartLocation.IsEmpty)
                {
                    return(null);
                }
                var tExpr = ResolveExpression(invoke);
                if (tExpr == null || tExpr.Result == null || tExpr.Result.IsError)
                {
                    return(null);
                }

                return(factory.CreateTypeParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectAllTypes(tExpr.Result.Type)));

            case '[':
                invoke = GetIndexerBeforeCursor();
                if (invoke == null)
                {
                    return(null);
                }
                if (invoke.Node is ArrayCreateExpression)
                {
                    return(null);
                }
                var indexerExpression = ResolveExpression(invoke);
                if (indexerExpression == null || indexerExpression.Result == null || indexerExpression.Result.IsError)
                {
                    return(null);
                }
                return(factory.CreateIndexerParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), indexerExpression.Result.Type, GetAccessibleIndexers(indexerExpression.Result.Type), invoke.Node));
            }
            return(null);
        }
		public IParameterDataProvider GetParameterDataProvider(int offset, char completionChar)
		{
			//Ignoring completionChar == '\0' because it usually means moving with arrow keys, tab or enter
			//we don't want to trigger on those events but it probably should be handled somewhere else
			//since our job is to resolve method and not to decide when to display tooltip or not
			if (offset <= 0 || completionChar == '\0') {
				return null;
			}
			SetOffset (offset);
			int startOffset;
			string text;
			if (currentMember == null && currentType == null) {
				//In case of attributes parse all file
				startOffset = 0;
				text = document.Text;
			} else {
				var memberText = GetMemberTextToCaret ();
				text = memberText.Item1;
				startOffset = document.GetOffset (memberText.Item2);
			}

			var parenStack = new Stack<int> ();
			var chevronStack = new Stack<int> ();
			var squareStack = new Stack<int> ();
			var bracketStack = new Stack<int> ();

			var lex = new MiniLexer (text);
			bool failed = lex.Parse ((ch, off) => {
				if (lex.IsInString || lex.IsInChar || lex.IsInVerbatimString || lex.IsInSingleComment || lex.IsInMultiLineComment || lex.IsInPreprocessorDirective)
					return false;
				switch (ch) {
				case '(':
					parenStack.Push (startOffset + off);
					break;
				case ')':
					if (parenStack.Count == 0) {
						return true;
					}
					parenStack.Pop ();
					break;
				case '<':
					chevronStack.Push (startOffset + off);
					break;
				case '>':
					//Don't abort if we don't have macthing '<' for '>' it could be if (i > 0) Foo($
					if (chevronStack.Count == 0) {
						return false;
					}
					chevronStack.Pop ();
					break;
				case '[':
					squareStack.Push (startOffset + off);
					break;
				case ']':
					if (squareStack.Count == 0) {
						return true;
					}
					squareStack.Pop ();
					break;
				case '{':
					bracketStack.Push (startOffset + off);
					break;
				case '}':
					if (bracketStack.Count == 0) {
						return true;
					}
					bracketStack.Pop ();
					break;
				}
				return false;
			});
			if (failed)
				return null;
			int result = -1;
			if (parenStack.Count > 0)
				result = parenStack.Pop ();
			if (squareStack.Count > 0)
				result = Math.Max (result, squareStack.Pop ());
			if (chevronStack.Count > 0)
				result = Math.Max (result, chevronStack.Pop ());

			//If we are inside { bracket we don't want to display anything
			if (bracketStack.Count > 0 && bracketStack.Pop () > result)
				return null;
			if (result == -1)
				return null;
			SetOffset (result + 1);
			ResolveResult resolveResult;
			switch (document.GetCharAt (result)) {
				case '(':
					var invoke = GetInvocationBeforeCursor(true) ?? GetConstructorInitializerBeforeCursor();
					if (invoke == null) {
						return null;
					}
					if (invoke.Node is ConstructorInitializer) {
						var init = (ConstructorInitializer)invoke.Node;
						if (init.ConstructorInitializerType == ConstructorInitializerType.This) {
							return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), ctx.CurrentTypeDefinition, init);
						} else {
							var baseType = ctx.CurrentTypeDefinition.DirectBaseTypes.FirstOrDefault(bt => bt.Kind != TypeKind.Interface);
							if (baseType == null) {
								return null;
							}
							return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), baseType);
						}
					}
					if (invoke.Node is ObjectCreateExpression) {
						var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type);
						if (createType.Result.Type.Kind == TypeKind.Unknown)
							return null;
						return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Result.Type);
					}
					
					if (invoke.Node is ICSharpCode.NRefactory.CSharp.Attribute) {
						var attribute = ResolveExpression(invoke);
						if (attribute == null || attribute.Result == null) {
							return null;
						}
						return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), attribute.Result.Type);
					}
					var invocationExpression = ResolveExpression(invoke);
					if (invocationExpression == null || invocationExpression.Result == null || invocationExpression.Result.IsError) {
						return null;
					}
					resolveResult = invocationExpression.Result;
					if (resolveResult is MethodGroupResolveResult) {
						return factory.CreateMethodDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectMethods(invoke.Node, resolveResult as MethodGroupResolveResult));
					}
					if (resolveResult is MemberResolveResult) {
						var mr = resolveResult as MemberResolveResult;
						if (mr.Member is IMethod) {
							return factory.CreateMethodDataProvider(document.GetOffset(invoke.Node.StartLocation), new [] { (IMethod)mr.Member });
						}
					}
					
					if (resolveResult.Type.Kind == TypeKind.Delegate) {
						return factory.CreateDelegateDataProvider(document.GetOffset(invoke.Node.StartLocation), resolveResult.Type);
					}
					
					//				
					//				if (result.ExpressionContext == ExpressionContext.BaseConstructorCall) {
					//					if (resolveResult is ThisResolveResult)
					//						return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as ThisResolveResult);
					//					if (resolveResult is BaseResolveResult)
					//						return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as BaseResolveResult);
					//				}
					//				IType resolvedType = resolver.SearchType (resolveResult.ResolvedType);
					//				if (resolvedType != null && resolvedType.ClassType == ClassType.Delegate) {
					//					return new NRefactoryParameterDataProvider (textEditorData, result.Expression, resolvedType);
					//				}
					break;
				case '<':
					invoke = GetMethodTypeArgumentInvocationBeforeCursor();
					if (invoke != null) {
						var tExpr2 = ResolveExpression(invoke);
						if (tExpr2 != null && tExpr2.Result is MethodGroupResolveResult && !tExpr2.Result.IsError) {
							return factory.CreateTypeParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectMethods(invoke.Node, tExpr2.Result as MethodGroupResolveResult));
						}
					}
					invoke = GetTypeBeforeCursor();
					if (invoke == null || invoke.Node.StartLocation.IsEmpty) {
						return null;
					}
					var tExpr = ResolveExpression(invoke);
					if (tExpr == null || tExpr.Result == null || tExpr.Result.IsError) {
						return null;
					}

					return factory.CreateTypeParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectAllTypes(tExpr.Result.Type));
				case '[':
					invoke = GetIndexerBeforeCursor();
					if (invoke == null) {
						return null;
					}
					if (invoke.Node is ArrayCreateExpression) {
						return null;
					}
					var indexerExpression = ResolveExpression(invoke);
					if (indexerExpression == null || indexerExpression.Result == null || indexerExpression.Result.IsError) {
						return null;
					}
					return factory.CreateIndexerParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), indexerExpression.Result.Type, GetAccessibleIndexers (indexerExpression.Result.Type), invoke.Node);
			}
			return null;
		}