diff options
author | Mike Krüger <mkrueger@xamarin.com> | 2012-07-23 18:56:16 +0400 |
---|---|---|
committer | Mike Krüger <mkrueger@xamarin.com> | 2012-07-24 11:27:12 +0400 |
commit | 78fc1b50bd2217efc792066418eb59b1ec9e0c90 (patch) | |
tree | fd88b456f4783cbc8c45696df80e889a5f0ea121 /main/contrib | |
parent | ab26f31840de37faad60fe3f1f6c1fca9b975e58 (diff) |
[NRefactory] Updated completion engine.
Diffstat (limited to 'main/contrib')
-rw-r--r-- | main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs | 1789 |
1 files changed, 890 insertions, 899 deletions
diff --git a/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs b/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs index 655d0d4585..0584ddfe17 100644 --- a/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs +++ b/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs @@ -135,26 +135,26 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (type is PrimitiveType) { var pt = (PrimitiveType)type; switch (pt.Keyword) { - case "object": - yield return "o"; - yield return "obj"; - break; - case "bool": - yield return "b"; - yield return "pred"; - break; - case "double": - case "float": - case "decimal": - yield return "d"; - yield return "f"; - yield return "m"; - break; - default: - yield return "i"; - yield return "j"; - yield return "k"; - break; + case "object": + yield return "o"; + yield return "obj"; + break; + case "bool": + yield return "b"; + yield return "pred"; + break; + case "double": + case "float": + case "decimal": + yield return "d"; + yield return "f"; + yield return "m"; + break; + default: + yield return "i"; + yield return "j"; + yield return "k"; + break; } yield break; } @@ -213,6 +213,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion ); } + return CreateCompletionData( location, resolveResult.Item1, @@ -261,7 +262,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return contextList.Result; } - foreach (var m in initializerResult.Item1.Type.GetMembers (m => !m.IsSynthetic && m.IsPublic && (m.EntityType == EntityType.Property || m.EntityType == EntityType.Field))) { + foreach (var m in initializerResult.Item1.Type.GetMembers (m => m.IsPublic && (m.EntityType == EntityType.Property || m.EntityType == EntityType.Field))) { contextList.AddMember(m); } @@ -292,694 +293,694 @@ namespace ICSharpCode.NRefactory.CSharp.Completion Tuple<ResolveResult, CSharpResolver> resolveResult; switch (completionChar) { // Magic key completion - case ':': - 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(); + case ':': + 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(); + } + return null; + case '>': + if (!IsInsideDocComment()) { + if (offset > 2 && document.GetCharAt(offset - 2) == '-' && !IsInsideCommentStringOrDirective()) { + return HandleMemberReferenceCompletion(GetExpressionBeforeCursor()); } return null; - case '>': - if (!IsInsideDocComment()) { - if (offset > 2 && document.GetCharAt (offset - 2) == '-' && !IsInsideCommentStringOrDirective()) { - return HandleMemberReferenceCompletion(GetExpressionBeforeCursor()); - } - 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; } - 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 + ">", AnchorMovementType.BeforeInsertion); } + } + return null; + + // Parameter completion + case '(': + if (IsInsideCommentStringOrDirective()) { + return null; + } + var invoke = GetInvocationBeforeCursor(true); + if (invoke == null) { + if (controlSpace) + return DefaultControlSpaceItems(invoke); + return null; + } + if (invoke.Node is TypeOfExpression) { + return CreateTypeList(); + } + var invocationResult = ResolveExpression(invoke); + if (invocationResult == null) { + return null; + } + var methodGroup = invocationResult.Item1 as MethodGroupResolveResult; + if (methodGroup != null) { + return CreateParameterCompletion( + methodGroup, + invocationResult.Item2, + invoke.Node, + invoke.Unit, + 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 ' ': + int tokenIndex = offset; + string token = GetPreviousToken(ref tokenIndex, false); + if (IsInsideCommentStringOrDirective()) { + if (IsInPreprocessorDirective()) + return HandleKeywordCompletion(tokenIndex, token); + 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(isAsExpression, controlSpace); - 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 + ">", AnchorMovementType.BeforeInsertion); + foreach (var possibleName in GenerateNameProposals (parent.Type)) { + if (possibleName.Length > 0) { + proposeNameList.Result.Add(factory.CreateLiteralCompletionData(possibleName.ToString())); } } - return null; - // Parameter completion - case '(': - if (IsInsideCommentStringOrDirective()) { + 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 - 1, this.offset) - 1; + if (currentParameter < 0) { return null; } - var invoke = GetInvocationBeforeCursor(true); + invoke = GetInvocationBeforeCursor(token == "("); if (invoke == null) { - if (controlSpace) - return DefaultControlSpaceItems(invoke); return null; } - if (invoke.Node is TypeOfExpression) { - return CreateTypeList(); - } - var invocationResult = ResolveExpression(invoke); + invocationResult = ResolveExpression(invoke); if (invocationResult == null) { return null; } - var methodGroup = invocationResult.Item1 as MethodGroupResolveResult; + methodGroup = invocationResult.Item1 as MethodGroupResolveResult; if (methodGroup != null) { return CreateParameterCompletion( methodGroup, invocationResult.Item2, invoke.Node, invoke.Unit, - 0, - controlSpace - ); - } - - if (controlSpace) { - return DefaultControlSpaceItems(invoke); + currentParameter, + controlSpace); } return null; - case '=': - return controlSpace ? DefaultControlSpaceItems() : null; - case ',': - int cpos2; - if (!GetParameterCompletionCommandOffset(out cpos2)) { + case "=": + case "==": + GetPreviousToken(ref tokenIndex, false); + var expressionOrVariableDeclaration = GetExpressionAt(tokenIndex); + if (expressionOrVariableDeclaration == null) { 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()) { - if (IsInPreprocessorDirective()) - return HandleKeywordCompletion(tokenIndex, token); + resolveResult = ResolveExpression(expressionOrVariableDeclaration); + + if (resolveResult == null) { 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(isAsExpression, controlSpace); - - foreach (var possibleName in GenerateNameProposals (parent.Type)) { - if (possibleName.Length > 0) { - proposeNameList.Result.Add(factory.CreateLiteralCompletionData(possibleName.ToString())); - } - } - - AutoSelect = false; + if (resolveResult.Item1.Type.Kind == TypeKind.Enum) { + var wrapper = new CompletionDataWrapper(this); + AddContextCompletion( + wrapper, + resolveResult.Item2, + expressionOrVariableDeclaration.Node); + AddEnumMembers(wrapper, resolveResult.Item1.Type, resolveResult.Item2); 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 - 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.Item1 as MethodGroupResolveResult; - if (methodGroup != null) { - return CreateParameterCompletion( - methodGroup, - invocationResult.Item2, - invoke.Node, - invoke.Unit, - currentParameter, - controlSpace); - } - return null; - 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.Item1.Type.Kind == TypeKind.Enum) { - var wrapper = new CompletionDataWrapper(this); - AddContextCompletion( - wrapper, - resolveResult.Item2, - expressionOrVariableDeclaration.Node); - 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); - 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 ":": - 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 => currentType != null && !currentType.ReflectionName.Equals(t.ReflectionName) ? t : null - ); - return wrapper.Result; - } - return null; + 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); - var keywordCompletion = HandleKeywordCompletion(tokenIndex, token); - if (keywordCompletion == null && controlSpace) { - goto default; + expressionOrVariableDeclaration = GetExpressionAt(tokenIndex); + if (expressionOrVariableDeclaration == null) { + return null; } - return keywordCompletion; - // Automatic completion - default: - if (IsInsideCommentStringOrDirective()) { + + resolveResult = ResolveExpression(expressionOrVariableDeclaration); + if (resolveResult == null) { return null; } - if (IsInLinqContext(offset)) { - if (!controlSpace && !(char.IsLetter(completionChar) || completionChar == '_')) { + + + var mrr = resolveResult.Item1 as MemberResolveResult; + if (mrr != null) { + var evt = mrr.Member as IEvent; + if (evt == null) { return null; } - tokenIndex = offset; - token = GetPreviousToken(ref tokenIndex, false); - // token last typed - if (!char.IsWhiteSpace(completionChar) && !linqKeywords.Contains(token)) { - token = GetPreviousToken(ref tokenIndex, false); + var delegateType = evt.ReturnType; + if (delegateType.Kind != TypeKind.Delegate) { + return null; } - // token last typed - if (linqKeywords.Contains(token)) { - if (token == "from") { - // after from no auto code completion. - 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 + ";"); + } } - 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) { - if (identifierStart.Node is TypeParameterDeclaration) { - return null; } - - if (identifierStart.Node is MemberReferenceExpression) { - return HandleMemberReferenceCompletion( - new ExpressionResult( - ((MemberReferenceExpression)identifierStart.Node).Target, - identifierStart.Unit - ) + if (token == "+=") { + string parameterDefinition = AddDelegateHandlers( + wrapper, + delegateType + ); + string varName = GetPreviousMemberReferenceExpression(tokenIndex); + wrapper.Result.Add( + factory.CreateEventCreationCompletionData( + varName, + delegateType, + evt, + parameterDefinition, + currentMember, + currentType) ); } - if (identifierStart.Node is Identifier) { - // May happen in variable names - return controlSpace ? DefaultControlSpaceItems(identifierStart) : null; - } - if (identifierStart.Node is VariableInitializer && location <= ((VariableInitializer)identifierStart.Node).NameToken.EndLocation) { - return controlSpace ? HandleAccessorContext() ?? DefaultControlSpaceItems(identifierStart) : null; - } - - if (identifierStart.Node is CatchClause) { - if (((CatchClause)identifierStart.Node).VariableNameToken.Contains(location)) { - return null; - } - return HandleCatchClauseType(identifierStart); - } - } - if (!(char.IsLetter(completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null || !(identifierStart.Node.Parent is ArrayInitializerExpression))) { - return controlSpace ? HandleAccessorContext() ?? DefaultControlSpaceItems(identifierStart) : null; + return wrapper.Result; } - - 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; + 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 => currentType != null && !currentType.ReflectionName.Equals(t.ReflectionName) ? t : null + ); + return wrapper.Result; } - if (!(Char.IsWhiteSpace(prevCh) || allowedChars.IndexOf(prevCh) >= 0)) { + return null; + } + + var keywordCompletion = HandleKeywordCompletion(tokenIndex, token); + if (keywordCompletion == null && controlSpace) { + goto default; + } + return keywordCompletion; + // Automatic completion + default: + if (IsInsideCommentStringOrDirective()) { + return null; + } + if (IsInLinqContext(offset)) { + if (!controlSpace && !(char.IsLetter(completionChar) || completionChar == '_')) { return null; } - - // Do not pop up completion on identifier identifier (should be handled by keyword completion). - tokenIndex = offset - 1; + tokenIndex = offset; 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; + // token last typed + if (!char.IsWhiteSpace(completionChar) && !linqKeywords.Contains(token)) { + token = GetPreviousToken(ref tokenIndex, false); } + // token last typed - int prevTokenIndex = tokenIndex; - var prevToken2 = GetPreviousToken(ref prevTokenIndex, false); - if (prevToken2 == "delegate") { - // after these always follows a name + 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) { + if (identifierStart.Node is TypeParameterDeclaration) { 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.Node is MemberReferenceExpression) { + return HandleMemberReferenceCompletion( + new ExpressionResult( + ((MemberReferenceExpression)identifierStart.Node).Target, + identifierStart.Unit + ) + ); } - if (identifierStart == null) { - var accCtx = HandleAccessorContext(); - if (accCtx != null) { - return accCtx; - } - return DefaultControlSpaceItems(null, controlSpace); + if (identifierStart.Node is Identifier) { + // May happen in variable names + return controlSpace ? DefaultControlSpaceItems(identifierStart) : null; } - CSharpResolver csResolver; - AstNode n = identifierStart.Node; - if (n != null && n.Parent is AnonymousTypeCreateExpression) { - AutoSelect = false; + if (identifierStart.Node is VariableInitializer && location <= ((VariableInitializer)identifierStart.Node).NameToken.EndLocation) { + return controlSpace ? HandleAccessorContext() ?? DefaultControlSpaceItems(identifierStart) : null; } - // 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; - } + if (identifierStart.Node is CatchClause) { + if (((CatchClause)identifierStart.Node).VariableNameToken.Contains(location)) { return null; } - - // var astResolver = new CSharpAstResolver( - // GetState(), - // identifierStart.Unit, - // CSharpParsedFile - // ); - // - // foreach (var type in CreateFieldAction.GetValidTypes(astResolver, (Expression)n)) { - // if (type.Kind == TypeKind.Delegate) { - // AddDelegateHandlers(contextList, type, false, false); - // AutoSelect = false; - // AutoCompleteEmptyMatch = false; - // } - // } + return HandleCatchClauseType(identifierStart); } - - // Handle object/enumerable initialzer expressions: "new O () { P$" - if (n is IdentifierExpression && n.Parent is ArrayInitializerExpression) { - var result = HandleObjectInitializer(identifierStart.Unit, n); - if (result != null) - return result; + } + if (!(char.IsLetter(completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null || !(identifierStart.Node.Parent 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; + } + var keywordresult = HandleKeywordCompletion(tokenIndex, token); + if (keywordresult != null) { + return keywordresult; + } + + 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(null, controlSpace); + } + CSharpResolver csResolver; + AstNode n = identifierStart.Node; + 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( - invokeParent.Target - ); - 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++; + // var astResolver = new CSharpAstResolver( + // GetState(), + // identifierStart.Unit, + // CSharpParsedFile + // ); + // + // foreach (var type in CreateFieldAction.GetValidTypes(astResolver, (Expression)n)) { + // if (type.Kind == TypeKind.Delegate) { + // AddDelegateHandlers(contextList, type, false, false); + // AutoSelect = false; + // AutoCompleteEmptyMatch = false; + // } + // } + } + + // Handle object/enumerable initialzer expressions: "new O () { P$" + if (n is IdentifierExpression && n.Parent is ArrayInitializerExpression) { + var result = HandleObjectInitializer(identifierStart.Unit, n); + if (result != null) + return result; + } + + if (n != null && n.Parent is InvocationExpression) { + var invokeParent = (InvocationExpression)n.Parent; + var invokeResult = ResolveExpression( + invokeParent.Target + ); + 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; } - - foreach (var method in mgr.Methods) { + 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; } - 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.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 != null && n.Parent is ObjectCreateExpression) { + var invokeResult = ResolveExpression(n.Parent); + 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 (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.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 (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.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 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(); } - 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(n.Parent); + 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(); + } + if (initalizerResult != null && initalizerResult.Item1.Type.Kind != TypeKind.Unknown) { - 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(); - } - 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 property in initalizerResult.Item1.Type.GetProperties ()) { + if (!property.IsPublic) { + continue; } - foreach (var field in initalizerResult.Item1.Type.GetFields ()) { - if (!field.IsPublic) { - continue; - } - contextList.AddMember(field); + contextList.AddMember(property); + } + foreach (var field in initalizerResult.Item1.Type.GetFields ()) { + if (!field.IsPublic) { + continue; } - return contextList.Result; + contextList.AddMember(field); } - return DefaultControlSpaceItems(); + return contextList.Result; } - 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"); + return DefaultControlSpaceItems(); + } + 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"); } - if (n is MemberType) { - resolveResult = ResolveExpression( - ((MemberType)n).Target - ); - return CreateTypeAndNamespaceCompletionData( - location, - resolveResult.Item1, - ((MemberType)n).Target, - resolveResult.Item2 - ); + contextList.AddCustom("return"); + } + if (n is MemberType) { + resolveResult = ResolveExpression( + ((MemberType)n).Target + ); + return CreateTypeAndNamespaceCompletionData( + location, + resolveResult.Item1, + ((MemberType)n).Target, + resolveResult.Item2 + ); + } + 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); } - 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 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); - } + 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 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.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; + } 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; } @@ -1280,7 +1281,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion var root = node; while (root.Parent != null) root = root.Parent; - var astResolver = CompletionContextProvider.GetResolver (state, root); + var astResolver = CompletionContextProvider.GetResolver(state, root); foreach (var type in CreateFieldAction.GetValidTypes(astResolver, (Expression)node)) { if (type.Kind == TypeKind.Enum) { AddEnumMembers(wrapper, type, state); @@ -1321,8 +1322,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion for (var ct = currentType; ct != null; ct = ct.DeclaringTypeDefinition) { foreach (var nestedType in ct.NestedTypes) { string name = nestedType.Name; - if (nestedType.IsSynthetic) - continue; if (IsAttributeContext(node) && name.EndsWith("Attribute") && name.Length > "Attribute".Length) { name = name.Substring(0, name.Length - "Attribute".Length); } @@ -1350,8 +1349,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") { continue; } - if (member.IsSynthetic) - continue; if (member.EntityType == EntityType.Operator) { continue; } @@ -1368,7 +1365,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } var declaring = def.DeclaringTypeDefinition; while (declaring != null) { - foreach (var member in declaring.GetMembers (m => m.IsStatic && !m.IsSynthetic)) { + foreach (var member in declaring.GetMembers (m => m.IsStatic)) { if (memberPred == null || memberPred(member)) { wrapper.AddMember(member); } @@ -1437,254 +1434,254 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return null; } switch (word) { - case "namespace": + case "namespace": + return null; + case "using": + if (currentType != null) { return null; - case "using": - if (currentType != null) { - return null; - } - var wrapper = new CompletionDataWrapper(this); - AddTypesAndNamespaces(wrapper, GetState(), null, t => null); - 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.Node.Parent; - if (parent is VariableInitializer) { - parent = parent.Parent; - } - if (parent is VariableDeclarationStatement) { - var resolved = ResolveExpression(parent); - if (resolved != null) { - isAsType = resolved.Item1.Type; - } - } - } - var isAsWrapper = new CompletionDataWrapper(this); - var def = isAsType != null ? isAsType.GetDefinition() : null; - AddTypesAndNamespaces( - isAsWrapper, - GetState(), - null, - t => t.GetDefinition() == null || def == null || t.GetDefinition().IsDerivedFrom(def) ? t : null, - m => false); - 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; + } + var wrapper = new CompletionDataWrapper(this); + AddTypesAndNamespaces(wrapper, GetState(), null, t => null); + 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.Node.Parent; + if (parent is VariableInitializer) { + parent = parent.Parent; + } + if (parent is VariableDeclarationStatement) { + var resolved = ResolveExpression(parent); + if (resolved != null) { + isAsType = resolved.Item1.Type; } } - if (!IsLineEmptyUpToEol()) { + } + var isAsWrapper = new CompletionDataWrapper(this); + var def = isAsType != null ? isAsType.GetDefinition() : null; + AddTypesAndNamespaces( + isAsWrapper, + GetState(), + null, + t => t.GetDefinition() == null || def == null || t.GetDefinition().IsDerivedFrom(def) ? t : null, + m => false); + 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 (currentType != null && (currentType.Kind == TypeKind.Class || currentType.Kind == TypeKind.Struct)) { - string modifiers = document.GetText(firstMod, wordStart - firstMod); - return GetOverrideCompletionData(currentType, modifiers); - } + } + if (!IsLineEmptyUpToEol()) { 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()) { + } + 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; } - 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); - } + } + if (!IsLineEmptyUpToEol()) { 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(); - if (currentType != null) { - AddTypesAndNamespaces(wrapper, state, null, null, m => false); - AddKeywords(wrapper, primitiveTypesKeywords); - } - AddKeywords(wrapper, typeLevelKeywords); - return wrapper.Result; - case "new": - int j = offset - 4; - // string token = GetPreviousToken (ref j, true); - - IType hintType = null; - var expressionOrVariableDeclaration = GetNewExpressionAt(j); - if (expressionOrVariableDeclaration == null) - return null; - var astResolver = CompletionContextProvider.GetResolver(GetState(), expressionOrVariableDeclaration.Unit); - hintType = CreateFieldAction.GetValidTypes( - astResolver, - expressionOrVariableDeclaration.Node as Expression - ) - .FirstOrDefault(); - - return CreateTypeCompletionData(hintType); - 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 expr = GetExpressionAtCursor(); - var rr = ResolveExpression(expr); - - AddContextCompletion( - inList, - rr != null ? rr.Item2 : GetState(), - expr.Node - ); - return inList.Result; + } + 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(); + if (currentType != null) { + AddTypesAndNamespaces(wrapper, state, null, null, m => false); + AddKeywords(wrapper, primitiveTypesKeywords); + } + AddKeywords(wrapper, typeLevelKeywords); + return wrapper.Result; + case "new": + int j = offset - 4; + // string token = GetPreviousToken (ref j, true); + + IType hintType = null; + var expressionOrVariableDeclaration = GetNewExpressionAt(j); + if (expressionOrVariableDeclaration == null) + return null; + var astResolver = CompletionContextProvider.GetResolver(GetState(), expressionOrVariableDeclaration.Unit); + hintType = CreateFieldAction.GetValidTypes( + astResolver, + expressionOrVariableDeclaration.Node as Expression + ) + .FirstOrDefault(); + + return CreateTypeCompletionData(hintType); + 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 expr = GetExpressionAtCursor(); + var rr = ResolveExpression(expr); + + AddContextCompletion( + inList, + rr != null ? rr.Item2 : GetState(), + expr.Node + ); + return inList.Result; } return null; } @@ -1823,16 +1820,16 @@ namespace ICSharpCode.NRefactory.CSharp.Completion 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 + 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( @@ -1852,16 +1849,16 @@ namespace ICSharpCode.NRefactory.CSharp.Completion 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 + 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 } } @@ -1915,7 +1912,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return; } foreach (var m in curType.GetMembers ().Reverse ()) { - if (m.IsSynthetic || curType.Kind != TypeKind.Interface && !m.IsOverridable) { + if (curType.Kind != TypeKind.Interface && !m.IsOverridable) { continue; } // filter out the "Finalize" methods, because finalizers should be done with destructors. @@ -2150,8 +2147,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion var nr = (NamespaceResolveResult)resolveResult; if (!(resolvedNode.Parent is UsingDeclaration || resolvedNode.Parent != null && resolvedNode.Parent.Parent is UsingDeclaration)) { foreach (var cl in nr.Namespace.Types) { - if (cl.IsSynthetic) - continue; string name = cl.Name; if (hintType != null && hintType.Kind != TypeKind.Array && cl.Kind == TypeKind.Interface) { continue; @@ -2167,7 +2162,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } } else if (resolveResult is TypeResolveResult) { var type = resolveResult.Type; - foreach (var nested in type.GetNestedTypes (t => !t.IsSynthetic)) { + foreach (var nested in type.GetNestedTypes ()) { if (hintType != null && hintType.Kind != TypeKind.Array && nested.Kind == TypeKind.Interface) { continue; } @@ -2275,7 +2270,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return; } string typeString = GetShortType(resolvedType, state); - completionList.AddEnumMembers (resolvedType, state, typeString); + completionList.AddEnumMembers(resolvedType, state, typeString); DefaultCompletionString = typeString; } @@ -2284,13 +2279,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion 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) { - if (cl.IsSynthetic) - continue; IType addType = typePred != null ? typePred(cl) : cl; if (addType != null) namespaceContents.AddType(addType, addType.Name); @@ -2391,8 +2385,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion var filteredList = new List<IMember>(); foreach (var member in type.GetMembers ()) { - if (member.IsSynthetic) - continue; if (member.EntityType == EntityType.Indexer || member.EntityType == EntityType.Operator || member.EntityType == EntityType.Constructor || member.EntityType == EntityType.Destructor) { continue; } @@ -2443,10 +2435,9 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } if (resolveResult is TypeResolveResult || includeStaticMembers) { - foreach (var nested in type.GetNestedTypes (t => !t.IsSynthetic)) { - if (!lookup.IsAccessible(nested.GetDefinition (), isProtectedAllowed)) + foreach (var nested in type.GetNestedTypes ()) { + if (!lookup.IsAccessible(nested.GetDefinition(), isProtectedAllowed)) continue; - IType addType = typePred != null ? typePred(nested) : nested; if (addType != null) result.AddType(addType, addType.Name); @@ -2877,13 +2868,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } ); - string GetLastClosingXmlCommentTag () + string GetLastClosingXmlCommentTag() { var line = document.GetLineByNumber(location.Line); restart: string lineText = document.GetText(line); - if (!lineText.Trim ().StartsWith ("///")) + if (!lineText.Trim().StartsWith("///")) return null; int startIndex = Math.Min(location.Column - 1, lineText.Length - 1) - 1; while (startIndex > 0 && lineText [startIndex] != '<') { @@ -2917,7 +2908,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion IEnumerable<ICompletionData> GetXmlDocumentationCompletionData() { - var closingTag = GetLastClosingXmlCommentTag (); + var closingTag = GetLastClosingXmlCommentTag(); if (closingTag != null) { yield return factory.CreateLiteralCompletionData( "/" + closingTag + ">" |