Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Krüger <mkrueger@xamarin.com>2011-11-02 15:44:00 +0400
committerMike Krüger <mkrueger@xamarin.com>2011-11-02 15:44:00 +0400
commited16848a5761e4b5f2cb9d52b22f12d5a537966e (patch)
treec9dd6d370fbff2946d01af5e237dce076b7b2974 /main/contrib
parent7599c630af310f5900d3166083a140fbd5efc640 (diff)
[NRefactory] Synced with nrefactory.
Diffstat (limited to 'main/contrib')
-rw-r--r--main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs4100
-rw-r--r--main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs889
-rw-r--r--main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs402
-rw-r--r--main/contrib/ICSharpCode.NRefactory.CSharp/Completion/IParameterCompletionDataFactory.cs2
-rw-r--r--main/contrib/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs7
-rw-r--r--main/contrib/ICSharpCode.NRefactory.CSharp/Parser/TypeSystemConvertVisitor.cs3
-rw-r--r--main/contrib/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs13
-rw-r--r--main/contrib/ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs4
-rw-r--r--main/contrib/ICSharpCode.NRefactory/TypeSystem/IMember.cs7
-rw-r--r--main/contrib/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractMember.cs11
-rw-r--r--main/contrib/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMember.cs4
11 files changed, 2771 insertions, 2671 deletions
diff --git a/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs b/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
index 00386f7827..fd7a51b823 100644
--- a/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
+++ b/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
@@ -1,2014 +1,2086 @@
-//
-// CSharpCompletionEngine.cs
-//
-// Author:
-// Mike Krüger <mkrueger@xamarin.com>
-//
-// Copyright (c) 2011 Xamarin Inc. (http://xamarin.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using ICSharpCode.NRefactory.Completion;
-using ICSharpCode.NRefactory.CSharp.Refactoring;
-using ICSharpCode.NRefactory.CSharp.Resolver;
-using ICSharpCode.NRefactory.Editor;
-using ICSharpCode.NRefactory.Semantics;
-using ICSharpCode.NRefactory.TypeSystem;
-
-namespace ICSharpCode.NRefactory.CSharp.Completion
-{
- public class CSharpCompletionEngine : CSharpCompletionEngineBase
- {
- internal ICompletionDataFactory factory;
-
- #region Additional input properties
- public CSharpFormattingOptions FormattingPolicy { get; set; }
- public string EolMarker { get; set; }
- public string IndentString { get; set; }
- #endregion
-
- #region Result properties
- public bool AutoCompleteEmptyMatch;
- public bool AutoSelect;
- public string DefaultCompletionString;
- #endregion
-
- public CSharpCompletionEngine (IDocument document, ICompletionDataFactory factory)
- {
- this.document = document;
- this.factory = factory;
- }
-
- public IEnumerable<ICompletionData> GetCompletionData (int offset, bool controlSpace)
- {
- this.AutoCompleteEmptyMatch = true;
- this.AutoSelect = true;
- this.DefaultCompletionString = null;
- SetOffset (offset);
- if (offset > 0) {
- char lastChar = document.GetCharAt (offset - 1);
- var result = MagicKeyCompletion (lastChar, controlSpace) ?? Enumerable.Empty<ICompletionData> ();
- if (controlSpace && char.IsWhiteSpace (lastChar)) {
- offset -= 2;
- while (offset >= 0 && char.IsWhiteSpace (document.GetCharAt (offset)))
- offset--;
- if (offset > 0) {
- var nonWsResult = MagicKeyCompletion (document.GetCharAt (offset), controlSpace);
- if (nonWsResult != null)
- result = result.Concat (nonWsResult);
- }
- }
-
- return result;
- }
- return Enumerable.Empty<ICompletionData> ();
- }
-
- IEnumerable<string> GenerateNameProposals (AstType type)
- {
- if (type is PrimitiveType) {
- var pt = (PrimitiveType)type;
- Console.WriteLine (pt.Keyword);
- 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;
- }
- yield break;
- }
-
- var names = new List<string> ();
- int offset1 = document.GetOffset (type.StartLocation);
- int offset2 = document.GetOffset (type.EndLocation);
-
- string name = document.GetText (offset1, offset2 - offset1);
- int lastNameStart = 0;
- for (int i = 1; i < name.Length; i++) {
- if (Char.IsUpper (name [i])) {
- names.Add (name.Substring (lastNameStart, i - lastNameStart));
- lastNameStart = i;
- }
- }
-
- names.Add (name.Substring (lastNameStart, name.Length - lastNameStart));
-
- var possibleName = new StringBuilder ();
- for (int i = 0; i < names.Count; i++) {
- possibleName.Length = 0;
- for (int j = i; j < names.Count; j++) {
- if (string.IsNullOrEmpty (names [j]))
- continue;
- if (j == i)
- names [j] = Char.ToLower (names [j] [0]) + names [j].Substring (1);
- possibleName.Append (names [j]);
- }
- yield return possibleName.ToString ();
- }
- }
-
- IEnumerable<ICompletionData> MagicKeyCompletion (char completionChar, bool controlSpace)
- {
- switch (completionChar) {
- // Magic key completion
- case ':':
- case '.':
- if (IsInsideCommentOrString ())
- return Enumerable.Empty<ICompletionData> ();
- var expr = GetExpressionBeforeCursor ();
- if (expr == null)
- return null;
- // do not complete <number>. (but <number>.<number>.)
- if (expr.Item2 is PrimitiveExpression) {
- var pexpr = (PrimitiveExpression)expr.Item2;
- if (!(pexpr.Value is string || pexpr.Value is char) && !pexpr.LiteralValue.Contains ('.'))
- return null;
- }
-
-
- var resolveResult = ResolveExpression (expr.Item1, expr.Item2, expr.Item3);
-
- if (resolveResult == null)
- return null;
- if (expr.Item2 is AstType)
- return CreateTypeAndNamespaceCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2);
-
- return CreateCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2);
- case '#':
- if (IsInsideCommentOrString ())
- return null;
- return GetDirectiveCompletionData ();
-
-// XML doc completion
- case '<':
- if (IsInsideDocComment ())
- return GetXmlDocumentationCompletionData ();
- if (controlSpace)
- return DefaultControlSpaceItems ();
- return null;
- case '>':
- if (!IsInsideDocComment ())
- return null;
- string lineText = document.GetText (document.GetLineByNumber (location.Line));
- int startIndex = Math.Min (location.Column - 1, lineText.Length - 1);
-
- while (startIndex >= 0 && lineText [startIndex] != '<') {
- --startIndex;
- if (lineText [startIndex] == '/') { // already closed.
- startIndex = -1;
- break;
- }
- }
-
- if (startIndex >= 0) {
- int endIndex = startIndex;
- while (endIndex <= location.Column && endIndex < lineText.Length && !Char.IsWhiteSpace (lineText [endIndex])) {
- endIndex++;
- }
- string tag = endIndex - startIndex - 1 > 0 ? lineText.Substring (startIndex + 1, endIndex - startIndex - 2) : null;
- if (!string.IsNullOrEmpty (tag) && commentTags.IndexOf (tag) >= 0)
- document.Insert (offset, "</" + tag + ">");
- }
- return null;
-
- // Parameter completion
- case '(':
- if (IsInsideCommentOrString ())
- return null;
- var invoke = GetInvocationBeforeCursor (true);
- if (invoke == null)
- return null;
- if (invoke.Item2 is TypeOfExpression)
- return CreateTypeList ();
- var invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
- if (invocationResult == null)
- return null;
- var methodGroup = invocationResult.Item1 as MethodGroupResolveResult;
- if (methodGroup != null)
- return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, 0, controlSpace);
- return null;
- case '=':
- return controlSpace ? DefaultControlSpaceItems () : null;
- case ',':
- int cpos2;
- if (!GetParameterCompletionCommandOffset (out cpos2))
- return null;
- // completionContext = CompletionWidget.CreateCodeCompletionContext (cpos2);
- // int currentParameter2 = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, completionContext) - 1;
-// return CreateParameterCompletion (CreateResolver (), location, ExpressionContext.MethodBody, provider.Methods, currentParameter);
- break;
-
- // Completion on space:
- case ' ':
- if (IsInsideCommentOrString ())
- return null;
-
- int tokenIndex = offset;
- string token = GetPreviousToken (ref tokenIndex, false);
-
- // check propose name, for context <variable name> <ctrl+space> (but only in control space context)
- IType isAsType = null;
- var isAsExpression = GetExpressionAt (offset);
- if (controlSpace && isAsExpression != null && isAsExpression.Item2 is VariableDeclarationStatement && token != "new") {
- var parent = isAsExpression.Item2 as VariableDeclarationStatement;
- var proposeNameList = new CompletionDataWrapper (this);
-
- foreach (var possibleName in GenerateNameProposals (parent.Type)) {
- if (possibleName.Length > 0)
- proposeNameList.Result.Add (factory.CreateLiteralCompletionData (possibleName.ToString ()));
- }
-
- AutoSelect = false;
- AutoCompleteEmptyMatch = false;
- return proposeNameList.Result;
- }
-// int tokenIndex = offset;
-// string token = GetPreviousToken (ref tokenIndex, false);
-// if (result.ExpressionContext == ExpressionContext.ObjectInitializer) {
-// resolver = CreateResolver ();
-// ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForObjectInitializer (document, resolver.Unit, Document.FileName, resolver.CallingType);
-// IReturnType objectInitializer = ((ExpressionContext.TypeExpressionContext)exactContext).UnresolvedType;
-// if (objectInitializer != null && objectInitializer.ArrayDimensions == 0 && objectInitializer.PointerNestingLevel == 0 && (token == "{" || token == ","))
-// return CreateCtrlSpaceCompletionData (completionContext, result);
-// }
- if (token == "=") {
- int j = tokenIndex;
- string prevToken = GetPreviousToken (ref j, false);
- if (prevToken == "=" || prevToken == "+" || prevToken == "-") {
- token = prevToken + token;
- tokenIndex = j;
- }
- }
- switch (token) {
- case "(":
- case ",":
- int cpos;
- if (!GetParameterCompletionCommandOffset (out cpos))
- break;
- int currentParameter = GetCurrentParameterIndex (cpos, 0) - 1;
- if (currentParameter < 0)
- return null;
- invoke = GetInvocationBeforeCursor (token == "(");
- if (invoke == null)
- return null;
- invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
- if (invocationResult == null)
- return null;
- methodGroup = invocationResult.Item1 as MethodGroupResolveResult;
- if (methodGroup != null)
- return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, currentParameter, controlSpace);
- return null;
- case "=":
- case "==":
- GetPreviousToken (ref tokenIndex, false);
-
- var expressionOrVariableDeclaration = GetExpressionAt (tokenIndex);
- if (expressionOrVariableDeclaration == null)
- return null;
-
- resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3);
- if (resolveResult == null)
- return null;
-
- if (resolveResult.Item1.Type.Kind == TypeKind.Enum) {
- var wrapper = new CompletionDataWrapper (this);
- AddContextCompletion (wrapper, resolveResult.Item2, expressionOrVariableDeclaration.Item2);
- AddEnumMembers (wrapper, resolveResult.Item1.Type, resolveResult.Item2);
- AutoCompleteEmptyMatch = false;
- return wrapper.Result;
- }
-//
-// if (resolvedType.FullName == DomReturnType.Bool.FullName) {
-// CompletionDataList completionList = new ProjectDomCompletionDataList ();
-// CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
-// completionList.AutoCompleteEmptyMatch = false;
-// cdc.Add ("true", "md-keyword");
-// cdc.Add ("false", "md-keyword");
-// resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
-// return completionList;
-// }
-// if (resolvedType.ClassType == ClassType.Delegate && token == "=") {
-// CompletionDataList completionList = new ProjectDomCompletionDataList ();
-// string parameterDefinition = AddDelegateHandlers (completionList, resolvedType);
-// string varName = GetPreviousMemberReferenceExpression (tokenIndex);
-// completionList.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.CallingMember, resolvedType));
-//
-// CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
-// resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
-// foreach (var data in completionList) {
-// if (data is MemberCompletionData)
-// ((MemberCompletionData)data).IsDelegateExpected = true;
-// }
-// return completionList;
-// }
- return null;
- case "+=":
- case "-=":
- GetPreviousToken (ref tokenIndex, false);
-
- expressionOrVariableDeclaration = GetExpressionAt (tokenIndex);
- if (expressionOrVariableDeclaration == null)
- return null;
-
- resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3);
- if (resolveResult == null)
- return null;
-
-
- var mrr = resolveResult.Item1 as MemberResolveResult;
- if (mrr != null) {
- var evt = mrr.Member as IEvent;
- if (evt == null)
- return null;
- var delegateType = evt.ReturnType.Resolve (ctx);
- if (!delegateType.IsDelegate ())
- return null;
-
- var wrapper = new CompletionDataWrapper (this);
- if (currentType != null) {
-// bool includeProtected = DomType.IncludeProtected (dom, typeFromDatabase, resolver.CallingType);
- foreach (var method in currentType.GetMethods (ctx)) {
- 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) {
- var wrapper = new CompletionDataWrapper (this);
- AddTypesAndNamespaces (wrapper, GetState (), null, t => currentType != null ? !currentType.Equals (t) : true);
- return wrapper.Result;
- }
- return null;
- }
-
- var keywordCompletion = HandleKeywordCompletion (tokenIndex, token);
- if (keywordCompletion == null && controlSpace)
- goto default;
- return keywordCompletion;
- // Automatic completion
- default:
- if (IsInsideCommentOrString ())
- return null;
- if (IsInLinqContext (offset)) {
- tokenIndex = offset;
- token = GetPreviousToken (ref tokenIndex, false); // token last typed
- if (linqKeywords.Contains (token)) {
- if (token == "from") // after from no auto code completion.
- return null;
- return DefaultControlSpaceItems ();
- }
- var dataList = new CompletionDataWrapper (this);
- AddKeywords (dataList, linqKeywords);
- return dataList.Result;
- }
-
- var contextList = new CompletionDataWrapper (this);
-
- var identifierStart = GetExpressionAtCursor ();
- if (!(char.IsLetter (completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null || !(identifierStart.Item2 is ArrayInitializerExpression))) {
- return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems () : null;
- }
-
- char prevCh = offset > 2 ? document.GetCharAt (offset - 2) : '\0';
- 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 (identifierStart == null && !string.IsNullOrEmpty (token) && !(IsInsideComment (tokenIndex) || IsInsideString (tokenIndex))) {
- char last = token [token.Length - 1];
- if (char.IsLetterOrDigit (last) || last == '_' || token == ">") {
- return null;
- }
- }
- if (identifierStart == null)
- return HandleAccessorContext () ?? DefaultControlSpaceItems ();
-
- CSharpResolver csResolver;
- AstNode n = identifierStart.Item2;
- if (n is ArrayInitializerExpression) {
- var initalizerResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3);
-
- var concreteNode = identifierStart.Item3.GetNodeAt<IdentifierExpression> (location);
- // check if we're on the right side of an initializer expression
- if (concreteNode != null && concreteNode.Parent != null && concreteNode.Parent.Parent != null && concreteNode.Identifier != "a" && concreteNode.Parent.Parent is NamedExpression)
- return DefaultControlSpaceItems ();
-
- if (initalizerResult != null) {
-
- foreach (var property in initalizerResult.Item1.Type.GetProperties (ctx)) {
- if (!property.IsPublic)
- continue;
- contextList.AddMember (property);
- }
- foreach (var field in initalizerResult.Item1.Type.GetFields (ctx)){
- if (!field.IsPublic)
- continue;
- contextList.AddMember (field);
- }
- return contextList.Result;
- }
- return null;
- }
- if (n != null/* && !(identifierStart.Item2 is TypeDeclaration)*/) {
- csResolver = new CSharpResolver (ctx, System.Threading.CancellationToken.None);
- var nodes = new List<AstNode> ();
- nodes.Add (n);
- if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute)
- nodes.Add (n.Parent);
- var navigator = new NodeListResolveVisitorNavigator (nodes);
- var visitor = new ResolveVisitor (csResolver, identifierStart.Item1, navigator);
- visitor.Scan (identifierStart.Item3);
- try {
- csResolver = visitor.GetResolverStateBefore (n);
- } catch (Exception) {
- csResolver = GetState ();
- }
- // add attribute properties.
- if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) {
- var resolved = visitor.GetResolveResult (n.Parent);
- if (resolved != null && resolved.Type != null) {
- foreach (var property in resolved.Type.GetProperties (ctx).Where (p => p.Accessibility == Accessibility.Public)) {
- contextList.AddMember (property);
- }
- foreach (var field in resolved.Type.GetFields (ctx).Where (p => p.Accessibility == Accessibility.Public)) {
- contextList.AddMember (field);
- }
- }
- }
- } else {
- csResolver = GetState ();
- }
-
- // identifier has already started with the first letter
- offset--;
-
- AddContextCompletion (contextList, csResolver, identifierStart.Item2);
- return contextList.Result;
-// if (stub.Parent is BlockStatement)
-
-// result = FindExpression (dom, completionContext, -1);
-// if (result == null)
-// return null;
-// else if (result.ExpressionContext != ExpressionContext.IdentifierExpected) {
-// triggerWordLength = 1;
-// bool autoSelect = true;
-// IType returnType = null;
-// if ((prevCh == ',' || prevCh == '(') && GetParameterCompletionCommandOffset (out cpos)) {
-// ctx = CompletionWidget.CreateCodeCompletionContext (cpos);
-// NRefactoryParameterDataProvider dataProvider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider;
-// if (dataProvider != null) {
-// int i = dataProvider.GetCurrentParameterIndex (CompletionWidget, ctx) - 1;
-// foreach (var method in dataProvider.Methods) {
-// if (i < method.Parameters.Count) {
-// returnType = dom.GetType (method.Parameters [i].ReturnType);
-// autoSelect = returnType == null || returnType.ClassType != ClassType.Delegate;
-// break;
-// }
-// }
-// }
-// }
-// // Bug 677531 - Auto-complete doesn't always highlight generic parameter in method signature
-// //if (result.ExpressionContext == ExpressionContext.TypeName)
-// // autoSelect = false;
-// CompletionDataList dataList = CreateCtrlSpaceCompletionData (completionContext, result);
-// AddEnumMembers (dataList, returnType);
-// dataList.AutoSelect = autoSelect;
-// return dataList;
-// } else {
-// result = FindExpression (dom, completionContext, 0);
-// tokenIndex = offset;
-//
-// // check foreach case, unfortunately the expression finder is too dumb to handle full type names
-// // should be overworked if the expression finder is replaced with a mcs ast based analyzer.
-// var possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // starting letter
-// possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varname
-//
-// // read return types to '(' token
-// possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varType
-// if (possibleForeachToken == ">") {
-// while (possibleForeachToken != null && possibleForeachToken != "(") {
-// possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
-// }
-// } else {
-// possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // (
-// if (possibleForeachToken == ".")
-// while (possibleForeachToken != null && possibleForeachToken != "(")
-// possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
-// }
-// possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // foreach
-//
-// if (possibleForeachToken == "foreach") {
-// result.ExpressionContext = ExpressionContext.ForeachInToken;
-// } else {
-// return null;
-// // result.ExpressionContext = ExpressionContext.IdentifierExpected;
-// }
-// result.Expression = "";
-// result.Region = DomRegion.Empty;
-//
-// return CreateCtrlSpaceCompletionData (completionContext, result);
-// }
-// break;
- }
- return null;
- }
-
- bool IsInLinqContext (int offset)
- {
- string token;
- while (null != (token = GetPreviousToken (ref offset, true))) {
- if (token == "from")
- return true;
- if (token == ";")
- return false;
- }
- return false;
- }
-
- IEnumerable<ICompletionData> HandleAccessorContext ()
- {
- var unit = ParseStub ("get; }", false);
- var node = unit.GetNodeAt (location, cn => !(cn is CSharpTokenNode));
- if (node is Accessor)
- node = node.Parent;
- var contextList = new CompletionDataWrapper (this);
- if (node is PropertyDeclaration) {
- contextList.AddCustom ("get");
- contextList.AddCustom ("set");
- AddKeywords (contextList, accessorModifierKeywords);
- } else if (node is CustomEventDeclaration) {
- contextList.AddCustom ("add");
- contextList.AddCustom ("remove");
- } else {
- return null;
- }
-
- return contextList.Result;
- }
-
- IEnumerable<ICompletionData> DefaultControlSpaceItems ()
- {
- var wrapper = new CompletionDataWrapper (this);
- while (offset > 0 && char.IsWhiteSpace (document.GetCharAt (offset))) {
- offset--;
- }
- location = document.GetLocation (offset);
- var xp = GetExpressionAtCursor ();
-
- AstNode node;
- Tuple<ResolveResult, CSharpResolver> rr;
- if (xp != null) {
- node = xp.Item2;
- rr = ResolveExpression (xp.Item1, node, xp.Item3);
- } else {
- node = Unit.GetNodeAt (location);
- rr = ResolveExpression (CSharpParsedFile, node, Unit);
- }
-
- AddContextCompletion (wrapper, rr != null && (node is Expression) ? rr.Item2 : GetState (), node);
-
- return wrapper.Result;
- }
-
- void AddContextCompletion (CompletionDataWrapper wrapper, CSharpResolver state, AstNode node)
- {
- if (state == null)
- return;
- foreach (var variable in state.LocalVariables) {
- wrapper.AddVariable (variable);
- }
- if (state.CurrentMember is IParameterizedMember) {
- var param = (IParameterizedMember)state.CurrentMember;
- foreach (var p in param.Parameters) {
- wrapper.AddVariable (p);
- }
- }
-
- if (state.CurrentMember is IMethod) {
- var method = (IMethod)state.CurrentMember;
- foreach (var p in method.TypeParameters) {
- wrapper.AddTypeParameter (p);
- }
- }
- Predicate<ITypeDefinition> typePred = null;
- if (node is Attribute) {
- var attribute = ctx.GetTypeDefinition ("System", "Attribute", 0, StringComparer.Ordinal);
- typePred = t => t.GetAllBaseTypeDefinitions (ctx).Any (bt => bt.Equals (attribute));
- }
- AddTypesAndNamespaces (wrapper, state, node, typePred);
-
- wrapper.Result.Add (factory.CreateLiteralCompletionData ("global"));
- if (state.CurrentMember != null) {
- AddKeywords (wrapper, statementStartKeywords);
- AddKeywords (wrapper, expressionLevelKeywords);
- } else if (state.CurrentTypeDefinition != null) {
- AddKeywords (wrapper, typeLevelKeywords);
- } else {
- AddKeywords (wrapper, globalLevelKeywords);
- }
-
- if (IsInSwitchContext(node)) {
- wrapper.AddCustom ("case");
- wrapper.AddCustom ("default");
- }
-
- AddKeywords (wrapper, primitiveTypesKeywords);
- wrapper.Result.AddRange (factory.CreateCodeTemplateCompletionData ());
- }
-
- static bool IsInSwitchContext(AstNode node)
- {
- var n = node;
- while (n != null && !(n is MemberDeclaration)) {
- if (n is SwitchStatement)
- return true;
- if (n is BlockStatement)
- return false;
- n = n.Parent;
- }
- return false;
- }
-
- void AddTypesAndNamespaces (CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Predicate<ITypeDefinition> typePred = null, Predicate<IMember> memberPred = null)
- {
- var currentType = state.CurrentTypeDefinition ?? this.currentType;
- var currentMember = state.CurrentMember ?? this.currentMember;
- if (currentType != null) {
- for (var ct = currentType; ct != null; ct = ct.DeclaringTypeDefinition) {
- foreach (var nestedType in ct.NestedTypes) {
- if (typePred == null || typePred (nestedType)) {
- string name = nestedType.Name;
- if (node is Attribute && name.EndsWith ("Attribute") && name.Length > "Attribute".Length)
- name = name.Substring (0, name.Length - "Attribute".Length);
- wrapper.AddType (nestedType, name);
- }
- }
- }
- if (currentMember != null) {
- foreach (var member in currentType.Resolve (ctx).GetMembers (ctx)) {
- if (memberPred == null || memberPred (member))
- wrapper.AddMember (member);
- }
- }
- foreach (var p in currentType.TypeParameters) {
- wrapper.AddTypeParameter (p);
- }
- }
-
- for (var n = state.CurrentUsingScope; n != null; n = n.Parent) {
- foreach (var pair in n.UsingAliases) {
- wrapper.AddNamespace ("", pair.Key);
- }
-
- foreach (var u in n.Usings) {
- var ns = u.ResolveNamespace (ctx);
- if (ns == null)
- continue;
- foreach (var type in ctx.GetTypes (ns.NamespaceName, StringComparer.Ordinal)) {
- if (typePred == null || typePred (type)) {
- string name = type.Name;
- if (node is Attribute && name.EndsWith ("Attribute") && name.Length > "Attribute".Length)
- name = name.Substring (0, name.Length - "Attribute".Length);
- wrapper.AddType (type, name);
- }
- }
- }
-
- foreach (var type in ctx.GetTypes (n.NamespaceName, StringComparer.Ordinal)) {
- if (typePred == null || typePred (type)) {
- wrapper.AddType (type, type.Name);
- }
- }
-
- foreach (var curNs in ctx.GetNamespaces ().Where (sn => sn.StartsWith (n.NamespaceName) && sn != n.NamespaceName)) {
- wrapper.AddNamespace (n.NamespaceName, curNs);
- }
- }
- }
-
- IEnumerable<ICompletionData> HandleKeywordCompletion (int wordStart, string word)
- {
- if (IsInsideCommentOrString ())
- return null;
- switch (word) {
- case "using":
- case "namespace":
- if (currentType != null)
- return null;
- var wrapper = new CompletionDataWrapper (this);
- AddTypesAndNamespaces (wrapper, GetState (), null, t => false);
- return wrapper.Result;
- case "case":
- return CreateCaseCompletionData (location);
-// case ",":
-// case ":":
-// if (result.ExpressionContext == ExpressionContext.InheritableType) {
-// IType cls = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
-// CompletionDataList completionList = new ProjectDomCompletionDataList ();
-// List<string > namespaceList = GetUsedNamespaces ();
-// var col = new CSharpTextEditorCompletion.CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, null, location);
-// bool isInterface = false;
-// HashSet<string > baseTypeNames = new HashSet<string> ();
-// if (cls != null) {
-// baseTypeNames.Add (cls.Name);
-// if (cls.ClassType == ClassType.Struct)
-// isInterface = true;
-// }
-// int tokenIndex = offset;
-//
-// // Search base types " : [Type1, ... ,TypeN,] <Caret>"
-// string token = null;
-// do {
-// token = GetPreviousToken (ref tokenIndex, false);
-// if (string.IsNullOrEmpty (token))
-// break;
-// token = token.Trim ();
-// if (Char.IsLetterOrDigit (token [0]) || token [0] == '_') {
-// IType baseType = dom.SearchType (Document.CompilationUnit, cls, result.Region.Start, token);
-// if (baseType != null) {
-// if (baseType.ClassType != ClassType.Interface)
-// isInterface = true;
-// baseTypeNames.Add (baseType.Name);
-// }
-// }
-// } while (token != ":");
-// foreach (object o in dom.GetNamespaceContents (namespaceList, true, true)) {
-// IType type = o as IType;
-// if (type != null && (type.IsStatic || type.IsSealed || baseTypeNames.Contains (type.Name) || isInterface && type.ClassType != ClassType.Interface)) {
-// continue;
-// }
-// if (o is Namespace && !namespaceList.Any (ns => ns.StartsWith (((Namespace)o).FullName)))
-// continue;
-// col.Add (o);
-// }
-// // Add inner classes
-// Stack<IType > innerStack = new Stack<IType> ();
-// innerStack.Push (cls);
-// while (innerStack.Count > 0) {
-// IType curType = innerStack.Pop ();
-// if (curType == null)
-// continue;
-// foreach (IType innerType in curType.InnerTypes) {
-// if (innerType != cls)
-// // don't add the calling class as possible base type
-// col.Add (innerType);
-// }
-// if (curType.DeclaringType != null)
-// innerStack.Push (curType.DeclaringType);
-// }
-// return completionList;
-// }
-// break;
- case "is":
- case "as":
- if (currentType == null)
- return null;
- IType isAsType = null;
- var isAsExpression = GetExpressionAt (wordStart);
- if (isAsExpression != null) {
- var parent = isAsExpression.Item2.Parent;
- if (parent is VariableInitializer)
- parent = parent.Parent;
- if (parent is VariableDeclarationStatement) {
- var resolved = ResolveExpression (isAsExpression.Item1, parent, isAsExpression.Item3);
- if (resolved != null)
- isAsType = resolved.Item1.Type;
- }
- }
-
- var isAsWrapper = new CompletionDataWrapper (this);
- AddTypesAndNamespaces (isAsWrapper, GetState (), null, t => isAsType == null || t.IsDerivedFrom (isAsType.GetDefinition (), ctx));
- return isAsWrapper.Result;
-// {
-// CompletionDataList completionList = new ProjectDomCompletionDataList ();
-// ExpressionResult expressionResult = FindExpression (dom, completionContext, wordStart - document.Caret.Offset);
-// NRefactoryResolver resolver = CreateResolver ();
-// ResolveResult resolveResult = resolver.Resolve (expressionResult, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
-// if (resolveResult != null && resolveResult.ResolvedType != null) {
-// CompletionDataCollector col = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
-// IType foundType = null;
-// if (word == "as") {
-// ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForAsCompletion (document, Document.CompilationUnit, Document.FileName, resolver.CallingType);
-// if (exactContext is ExpressionContext.TypeExpressionContext) {
-// foundType = resolver.SearchType (((ExpressionContext.TypeExpressionContext)exactContext).Type);
-// AddAsCompletionData (col, foundType);
-// }
-// }
-//
-// if (foundType == null)
-// foundType = resolver.SearchType (resolveResult.ResolvedType);
-//
-// if (foundType != null) {
-// if (foundType.ClassType == ClassType.Interface)
-// foundType = resolver.SearchType (DomReturnType.Object);
-//
-// foreach (IType type in dom.GetSubclasses (foundType)) {
-// if (type.IsSpecialName || type.Name.StartsWith ("<"))
-// continue;
-// AddAsCompletionData (col, type);
-// }
-// }
-// List<string > namespaceList = GetUsedNamespaces ();
-// foreach (object o in dom.GetNamespaceContents (namespaceList, true, true)) {
-// if (o is IType) {
-// IType type = (IType)o;
-// if (type.ClassType != ClassType.Interface || type.IsSpecialName || type.Name.StartsWith ("<"))
-// continue;
-// // if (foundType != null && !dom.GetInheritanceTree (foundType).Any (x => x.FullName == type.FullName))
-// // continue;
-// AddAsCompletionData (col, type);
-// continue;
-// }
-// if (o is Namespace)
-// continue;
-// col.Add (o);
-// }
-// return completionList;
-// }
-// result.ExpressionContext = ExpressionContext.TypeName;
-// return CreateCtrlSpaceCompletionData (completionContext, result);
-// }
- case "override":
- // Look for modifiers, in order to find the beginning of the declaration
- int firstMod = wordStart;
- int i = wordStart;
- for (int n = 0; n < 3; n++) {
- string mod = GetPreviousToken (ref i, true);
- if (mod == "public" || mod == "protected" || mod == "private" || mod == "internal" || mod == "sealed") {
- firstMod = i;
- } else if (mod == "static") {
- // static methods are not overridable
- return null;
- } else
- break;
- }
- if (!IsLineEmptyUpToEol ())
- return null;
- var overrideCls = CSharpParsedFile.GetInnermostTypeDefinition (location);
-
- if (overrideCls != null && (overrideCls.Kind == TypeKind.Class || overrideCls.Kind == TypeKind.Struct)) {
- string modifiers = document.GetText (firstMod, wordStart - firstMod);
- return GetOverrideCompletionData (overrideCls, modifiers);
- }
- return null;
-// case "partial":
-// // Look for modifiers, in order to find the beginning of the declaration
-// firstMod = wordStart;
-// i = wordStart;
-// for (int n = 0; n < 3; n++) {
-// string mod = GetPreviousToken (ref i, true);
-// if (mod == "public" || mod == "protected" || mod == "private" || mod == "internal" || mod == "sealed") {
-// firstMod = i;
-// } else if (mod == "static") {
-// // static methods are not overridable
-// return null;
-// } else
-// break;
-// }
-// if (!IsLineEmptyUpToEol ())
-// return null;
-//
-// overrideCls = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
-// if (overrideCls != null && (overrideCls.ClassType == ClassType.Class || overrideCls.ClassType == ClassType.Struct)) {
-// string modifiers = document.GetTextBetween (firstMod, wordStart);
-// return GetPartialCompletionData (completionContext, overrideCls, modifiers);
-// }
-// return null;
-//
- case "public":
- case "protected":
- case "private":
- case "internal":
- case "sealed":
- case "static":
- wrapper = new CompletionDataWrapper (this);
- var state = GetState ();
- AddTypesAndNamespaces (wrapper, state, null, null, m => false);
- AddKeywords (wrapper, typeLevelKeywords);
- AddKeywords (wrapper, primitiveTypesKeywords);
- return wrapper.Result;
- case "new":
- int j = offset - 4;
-// string token = GetPreviousToken (ref j, true);
-
- IType hintType = null;
- var expressionOrVariableDeclaration = GetNewExpressionAt (j);
- AstNode newParentNode = null;
- AstType hintTypeAst = null;
- if (expressionOrVariableDeclaration != null) {
- newParentNode = expressionOrVariableDeclaration.Item2.Parent;
- if (newParentNode is VariableInitializer)
- newParentNode = newParentNode.Parent;
- }
-
- if (newParentNode is VariableDeclarationStatement) {
- var varDecl = (VariableDeclarationStatement)newParentNode;
- hintTypeAst = varDecl.Type;
- var resolved = ResolveExpression (expressionOrVariableDeclaration.Item1, varDecl.Type, expressionOrVariableDeclaration.Item3);
- if (resolved != null) {
- hintType = resolved.Item1.Type;
- }
- }
-
- if (newParentNode is FieldDeclaration) {
- var varDecl = (FieldDeclaration)newParentNode;
- hintTypeAst = varDecl.ReturnType;
- var resolved = ResolveExpression (expressionOrVariableDeclaration.Item1, varDecl.ReturnType, expressionOrVariableDeclaration.Item3);
- if (resolved != null)
- hintType = resolved.Item1.Type;
- }
- return CreateTypeCompletionData (hintType, hintTypeAst);
-// IType callingType = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new TextLocation (document.Caret.Line, document.Caret.Column));
-// ExpressionContext newExactContext = new NewCSharpExpressionFinder (dom).FindExactContextForNewCompletion (document, Document.CompilationUnit, Document.FileName, callingType);
-// if (newExactContext is ExpressionContext.TypeExpressionContext)
-// return CreateTypeCompletionData (location, callingType, newExactContext, ((ExpressionContext.TypeExpressionContext)newExactContext).Type, ((ExpressionContext.TypeExpressionContext)newExactContext).UnresolvedType);
-// if (newExactContext == null) {
-// int j = offset - 4;
-//
-// string yieldToken = GetPreviousToken (ref j, true);
-// if (token == "return") {
-// NRefactoryResolver resolver = CreateResolver ();
-// resolver.SetupResolver (new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
-// IReturnType returnType = resolver.CallingMember.ReturnType;
-// if (yieldToken == "yield" && returnType.GenericArguments.Count > 0)
-// returnType = returnType.GenericArguments [0];
-// if (resolver.CallingMember != null)
-// return CreateTypeCompletionData (location, callingType, newExactContext, null, returnType);
-// }
-// }
-// return CreateCtrlSpaceCompletionData (completionContext, null);
-// case "if":
-// case "elif":
-// if (stateTracker.Engine.IsInsidePreprocessorDirective)
-// return GetDefineCompletionData ();
-// return null;
- case "yield":
- var yieldDataList = new CompletionDataWrapper (this);
- DefaultCompletionString = "return";
- yieldDataList.AddCustom ("break");
- yieldDataList.AddCustom ("return");
- return yieldDataList.Result;
- case "in":
- var inList = new CompletionDataWrapper (this);
- var node = Unit.GetNodeAt (location);
- var rr = ResolveExpression (CSharpParsedFile, node, Unit);
- AddContextCompletion (inList, rr != null ? rr.Item2 : GetState (), node);
- return inList.Result;
-// case "where":
-// CompletionDataList whereDataList = new CompletionDataList ();
-// NRefactoryResolver constraintResolver = CreateResolver ();
-// constraintResolver.SetupResolver (new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
-// if (constraintResolver.CallingMember is IMethod) {
-// foreach (ITypeParameter tp in ((IMethod)constraintResolver.CallingMember).TypeParameters) {
-// whereDataList.Add (tp.Name, "md-keyword");
-// }
-// } else {
-// if (constraintResolver.CallingType != null) {
-// foreach (ITypeParameter tp in constraintResolver.CallingType.TypeParameters) {
-// whereDataList.Add (tp.Name, "md-keyword");
-// }
-// }
-// }
-//
-// return whereDataList;
- }
-// if (IsInLinqContext (result)) {
-// if (linqKeywords.Contains (word)) {
-// if (word == "from") // after from no auto code completion.
-// return null;
-// result.Expression = "";
-// return CreateCtrlSpaceCompletionData (completionContext, result);
-// }
-// CompletionDataList dataList = new ProjectDomCompletionDataList ();
-// CompletionDataCollector col = new CompletionDataCollector (this, dom, dataList, Document.CompilationUnit, null, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
-// foreach (string kw in linqKeywords) {
-// col.Add (kw, "md-keyword");
-// }
-// return dataList;
-// }
- return null;
- }
-
- bool IsLineEmptyUpToEol ()
- {
- var line = document.GetLineByNumber (location.Line);
- for (int j = offset; j < line.EndOffset; j++) {
- char ch = document.GetCharAt (j);
- if (!char.IsWhiteSpace (ch))
- return false;
- }
- return true;
- }
- string GetLineIndent (int lineNr)
- {
- var line = document.GetLineByNumber (lineNr);
- for (int j = offset; j < line.EndOffset; j++) {
- char ch = document.GetCharAt (j);
- if (!char.IsWhiteSpace (ch))
- return document.GetText (line.Offset, j - line.Offset - 1);
- }
- return "";
- }
-
- IEnumerable<ICompletionData> CreateTypeCompletionData (IType hintType, AstType hintTypeAst)
- {
- var wrapper = new CompletionDataWrapper (this);
- var state = GetState ();
- Predicate<ITypeDefinition> pred = null;
- if (hintType != null) {
- if (!hintType.Equals (SharedTypes.UnknownType)) {
- var lookup = new MemberLookup (ctx, currentType, ProjectContent);
- pred = t => {
- // check if type is in inheritance tree.
- if (hintType.GetDefinition () != null && !t.IsDerivedFrom (hintType.GetDefinition (), ctx))
- return false;
- // check for valid constructors
- if (t.Methods.Count (m => m.IsConstructor) == 0)
- return true;
- bool isProtectedAllowed = currentType != null ? currentType.IsDerivedFrom (t, ctx) : false;
- return t.Methods.Any (m => m.IsConstructor && lookup.IsAccessible (m, isProtectedAllowed));
- };
- DefaultCompletionString = GetShortType (hintType, GetState ());
- wrapper.AddType (hintType, DefaultCompletionString);
- } else {
- DefaultCompletionString = hintTypeAst.ToString ();
- wrapper.AddType (hintType, DefaultCompletionString);
- }
- }
- AddTypesAndNamespaces (wrapper, state, null, pred, m => false);
- AddKeywords (wrapper, primitiveTypesKeywords.Where (k => k != "void"));
- AutoCompleteEmptyMatch = true;
- return wrapper.Result;
- }
-
- IEnumerable<ICompletionData> GetOverrideCompletionData (ITypeDefinition type, string modifiers)
- {
- var wrapper = new CompletionDataWrapper (this);
- var alreadyInserted = new Dictionary<string, bool> ();
- bool addedVirtuals = false;
-
- int declarationBegin = offset;
- int j = declarationBegin;
- for (int i = 0; i < 3; i++) {
- switch (GetPreviousToken (ref j, true)) {
- case "public":
- case "protected":
- case "private":
- case "internal":
- case "sealed":
- case "override":
- declarationBegin = j;
- break;
- case "static":
- return null; // don't add override completion for static members
- }
- }
- foreach (var baseType in type.GetAllBaseTypeDefinitions (ctx)) {
- AddVirtuals (alreadyInserted, wrapper, type, modifiers, baseType, declarationBegin);
- addedVirtuals = true;
- }
- if (!addedVirtuals)
- AddVirtuals (alreadyInserted, wrapper, type, modifiers, ctx.GetTypeDefinition (typeof(object)), declarationBegin);
- return wrapper.Result;
- }
-
- static string GetNameWithParamCount (IMember member)
- {
- var e = member as IMethod;
- if (e == null || e.TypeParameters.Count == 0)
- return member.Name;
- return e.Name + "`" + e.TypeParameters.Count;
- }
-
- void AddVirtuals (Dictionary<string, bool> alreadyInserted, CompletionDataWrapper col, ITypeDefinition type, string modifiers, ITypeDefinition curType, int declarationBegin)
- {
- if (curType == null)
- return;
- foreach (var m in curType.Methods.Where (m => !m.IsConstructor && !m.IsDestructor).Cast<IMember> ().Concat (curType.Properties.Cast<IMember> ())) {
- if (m.IsSynthetic || curType.Kind != TypeKind.Interface && !(m.IsVirtual || m.IsOverride || m.IsAbstract))
- continue;
- // filter out the "Finalize" methods, because finalizers should be done with destructors.
- if (m is IMethod && m.Name == "Finalize")
- continue;
-
- var data = factory.CreateNewOverrideCompletionData (declarationBegin, type, m);
- string text = GetNameWithParamCount (m);
-
- // check if the member is already implemented
- bool foundMember = type.Members.Any (cm => GetNameWithParamCount (cm) == text);
- if (!foundMember && !alreadyInserted.ContainsKey (text)) {
- alreadyInserted [text] = true;
- data.CompletionCategory = col.GetCompletionCategory (curType);
- col.Add (data);
- }
- }
- }
-
- static void AddKeywords (CompletionDataWrapper wrapper, IEnumerable<string> keywords)
- {
- foreach (string keyword in keywords) {
- wrapper.AddCustom (keyword);
- }
- }
-
- public string GetPreviousMemberReferenceExpression (int tokenIndex)
- {
- string result = GetPreviousToken (ref tokenIndex, false);
- result = GetPreviousToken (ref tokenIndex, false);
- if (result != ".") {
- result = null;
- } else {
- var names = new List<string> ();
- while (result == ".") {
- result = GetPreviousToken (ref tokenIndex, false);
- if (result == "this") {
- names.Add ("handle");
- } else if (result != null) {
- string trimmedName = result.Trim ();
- if (trimmedName.Length == 0)
- break;
- names.Insert (0, trimmedName);
- }
- result = GetPreviousToken (ref tokenIndex, false);
- }
- result = String.Join ("", names.ToArray ());
- foreach (char ch in result) {
- if (!char.IsLetterOrDigit (ch) && ch != '_') {
- result = "";
- break;
- }
- }
- }
- return result;
- }
-
- bool MatchDelegate (IType delegateType, IMethod method)
- {
- var delegateMethod = delegateType.GetDelegateInvokeMethod ();
- if (delegateMethod == null || delegateMethod.Parameters.Count != method.Parameters.Count)
- return false;
-
- for (int i = 0; i < delegateMethod.Parameters.Count; i++) {
- if (!delegateMethod.Parameters [i].Type.Resolve (ctx).Equals (method.Parameters [i].Type.Resolve (ctx)))
- return false;
- }
- return true;
- }
-
- string AddDelegateHandlers (CompletionDataWrapper completionList, IType delegateType, bool addSemicolon = true, bool addDefault = true)
- {
- IMethod delegateMethod = delegateType.GetDelegateInvokeMethod ();
- var thisLineIndent = GetLineIndent (location.Line);
- string delegateEndString = EolMarker + thisLineIndent + "}" + (addSemicolon ? ";" : "");
- bool containsDelegateData = completionList.Result.Any (d => d.DisplayText.StartsWith ("delegate("));
- if (addDefault)
- completionList.AddCustom ("delegate", "Creates anonymous delegate.", "delegate {" + EolMarker + thisLineIndent + IndentString + "|" + delegateEndString);
- var sb = new StringBuilder ("(");
- var sbWithoutTypes = new StringBuilder ("(");
- for (int k = 0; k < delegateMethod.Parameters.Count; k++) {
- if (k > 0) {
- sb.Append (", ");
- sbWithoutTypes.Append (", ");
- }
- var parameterType = delegateMethod.Parameters [k].Type.Resolve (ctx);
- sb.Append (GetShortType (parameterType, GetState ()));
- sb.Append (" ");
- sb.Append (delegateMethod.Parameters [k].Name);
- sbWithoutTypes.Append (delegateMethod.Parameters [k].Name);
- }
- sb.Append (")");
- sbWithoutTypes.Append (")");
- completionList.AddCustom ("delegate" + sb, "Creates anonymous delegate.", "delegate" + sb + " {" + EolMarker + thisLineIndent + IndentString + "|" + delegateEndString);
- if (!completionList.Result.Any (data => data.DisplayText == sbWithoutTypes.ToString ()))
- completionList.AddCustom (sbWithoutTypes.ToString (), "Creates lambda expression.", sbWithoutTypes + " => |" + (addSemicolon ? ";" : ""));
- /* TODO:Make factory method out of it.
- // It's needed to temporarly disable inserting auto matching bracket because the anonymous delegates are selectable with '('
- // otherwise we would end up with () => )
- if (!containsDelegateData) {
- var savedValue = MonoDevelop.SourceEditor.DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket;
- MonoDevelop.SourceEditor.DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket = false;
- completionList.Result.CompletionListClosed += delegate {
- MonoDevelop.SourceEditor.DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket = savedValue;
- };
- }*/
- return sb.ToString ();
- }
-
- bool IsAccessibleFrom (IEntity member, ITypeDefinition calledType, IMember currentMember, bool includeProtected)
- {
- if (currentMember == null)
- return member.IsStatic || member.IsPublic;
-// if (currentMember is MonoDevelop.Projects.Dom.BaseResolveResult.BaseMemberDecorator)
-// return member.IsPublic | member.IsProtected;
- // if (member.IsStatic && !IsStatic)
- // return false;
- if (member.IsPublic || calledType != null && calledType.Kind == TypeKind.Interface && !member.IsProtected)
- return true;
- if (member.DeclaringTypeDefinition != null) {
- if (member.DeclaringTypeDefinition.Kind == TypeKind.Interface)
- return IsAccessibleFrom (member.DeclaringTypeDefinition, calledType, currentMember, includeProtected);
-
- if (member.IsProtected && !(member.DeclaringTypeDefinition.IsProtectedOrInternal && !includeProtected))
- return includeProtected;
- }
- if (member.IsInternal || member.IsProtectedAndInternal || member.IsProtectedOrInternal) {
- var type1 = member is ITypeDefinition ? (ITypeDefinition)member : member.DeclaringTypeDefinition;
- var type2 = currentMember is ITypeDefinition ? (ITypeDefinition)currentMember : currentMember.DeclaringTypeDefinition;
- bool result;
- // easy case, projects are the same
- if (type1.ProjectContent == type2.ProjectContent) {
- result = true;
- } else if (type1.ProjectContent != null) {
- // maybe type2 hasn't project dom set (may occur in some cases), check if the file is in the project
- //TODO !!
-// result = type1.ProjectContent.Annotation<MonoDevelop.Projects.Project> ().GetProjectFile (type2.Region.FileName) != null;
- result = false;
- } else if (type2.ProjectContent != null) {
- //TODO!!
-// result = type2.ProjectContent.Annotation<MonoDevelop.Projects.Project> ().GetProjectFile (type1.Region.FileName) != null;
- result = false;
- } else {
- // should never happen !
- result = true;
- }
- return member.IsProtectedAndInternal ? includeProtected && result : result;
- }
-
- if (!(currentMember is IType) && (currentMember.DeclaringTypeDefinition == null || member.DeclaringTypeDefinition == null))
- return false;
-
- // inner class
- var declaringType = currentMember.DeclaringTypeDefinition;
- while (declaringType != null) {
- if (declaringType.ReflectionName == currentMember.DeclaringType.ReflectionName)
- return true;
- declaringType = declaringType.DeclaringTypeDefinition;
- }
-
-
- return currentMember.DeclaringTypeDefinition != null && member.DeclaringTypeDefinition.FullName == currentMember.DeclaringTypeDefinition.FullName;
- }
-
- IEnumerable<ICompletionData> CreateTypeAndNamespaceCompletionData (TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state)
- {
- if (resolveResult == null || resolveResult.IsError)
- return null;
- var result = new CompletionDataWrapper (this);
-
- if (resolveResult is NamespaceResolveResult) {
- var nr = (NamespaceResolveResult)resolveResult;
- foreach (var cl in ctx.GetTypes (nr.NamespaceName, StringComparer.Ordinal)) {
- result.AddType (cl, cl.Name);
- }
- foreach (var ns in ctx.GetNamespaces ().Where (n => n.Length > nr.NamespaceName.Length && n.StartsWith (nr.NamespaceName))) {
- result.AddNamespace (nr.NamespaceName, ns);
- }
- } else if (resolveResult is TypeResolveResult) {
- var type = resolveResult.Type.Resolve (ctx);
- foreach (var nested in type.GetNestedTypes (ctx)) {
- result.AddType (nested, nested.Name);
- }
- }
- return result.Result;
- }
-
- IEnumerable<ICompletionData> CreateTypeList ()
- {
- foreach (var cl in ctx.GetTypes ("", StringComparer.Ordinal)) {
- yield return factory.CreateTypeCompletionData (cl, cl.Name);
- }
- foreach (var ns in ctx.GetNamespaces ()) {
- string name = ns;
- int idx = name.IndexOf (".");
- if (idx >= 0)
- name = name.Substring (0, idx);
- yield return factory.CreateNamespaceCompletionData (name);
- }
- }
-
- public ITypeDefinition GetTypeFromContext (ITypeDefinition type)
- {
- if (type == null || type.DeclaringType != null)
- return type;
- var result = ctx.GetTypeDefinition (type.Namespace, type.Name, type.TypeParameterCount, StringComparer.Ordinal) ?? type;
- if (result.GetParts ().Count == 1)
- return type;
-// Console.WriteLine ("result:"+ result);
- return result;
- }
-
- IEnumerable<ICompletionData> CreateParameterCompletion (MethodGroupResolveResult resolveResult, CSharpResolver state, AstNode invocation, int parameter, bool controlSpace)
- {
- var result = new CompletionDataWrapper (this);
- var addedEnums = new HashSet<string> ();
- var addedDelegates = new HashSet<string> ();
-
- foreach (var method in resolveResult.Methods) {
- if (method.Parameters.Count <= parameter)
- continue;
- var resolvedType = method.Parameters [parameter].Type.Resolve (ctx);
- if (resolvedType.Kind == TypeKind.Enum) {
- if (addedEnums.Contains (resolvedType.ReflectionName))
- continue;
- addedEnums.Add (resolvedType.ReflectionName);
- AddEnumMembers (result, resolvedType, state);
- } else if (resolvedType.Kind == TypeKind.Delegate) {
-// if (addedDelegates.Contains (resolvedType.DecoratedFullName))
-// continue;
-// addedDelegates.Add (resolvedType.DecoratedFullName);
-// string parameterDefinition = AddDelegateHandlers (completionList, resolvedType, false, addedDelegates.Count == 1);
-// string varName = "Handle" + method.Parameters [parameter].ReturnType.Name + method.Parameters [parameter].Name;
-// result.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.Unit.GetMemberAt (location), resolvedType) { AddSemicolon = false });
-
- }
- }
- if (!controlSpace) {
- if (addedEnums.Count + addedDelegates.Count == 0)
- return Enumerable.Empty<ICompletionData> ();
- AutoCompleteEmptyMatch = false;
- AutoSelect = false;
- }
- AddContextCompletion (result, state, invocation);
-
-// resolver.AddAccessibleCodeCompletionData (ExpressionContext.MethodBody, cdc);
-// if (addedDelegates.Count > 0) {
-// foreach (var data in result.Result) {
-// if (data is MemberCompletionData)
-// ((MemberCompletionData)data).IsDelegateExpected = true;
-// }
-// }
- return result.Result;
- }
-
- string GetShortType (IType type, CSharpResolver state)
- {
- var builder = new TypeSystemAstBuilder (state);
- var shortType = builder.ConvertType (type);
- using (var w = new System.IO.StringWriter ()) {
- var visitor = new CSharpOutputVisitor (w, FormattingPolicy);
- shortType.AcceptVisitor (visitor, null);
- return w.ToString ();
- }
- }
-
- void AddEnumMembers (CompletionDataWrapper completionList, IType resolvedType, CSharpResolver state)
- {
- if (resolvedType.Kind != TypeKind.Enum)
- return;
- string typeString = GetShortType (resolvedType, state);
- if (typeString.Contains ("."))
- completionList.AddType (resolvedType, typeString);
- foreach (var field in resolvedType.GetFields (ctx)) {
- if (field.IsConst || field.IsStatic)
- completionList.Result.Add (factory.CreateEntityCompletionData (field, typeString + "." + field.Name));
- }
- DefaultCompletionString = typeString;
- }
-
- IEnumerable<ICompletionData> CreateCompletionData (TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state)
- {
- if (resolveResult == null /*|| resolveResult.IsError*/)
- return null;
- if (resolveResult is NamespaceResolveResult) {
- var nr = (NamespaceResolveResult)resolveResult;
- var namespaceContents = new CompletionDataWrapper (this);
- foreach (var cl in ctx.GetTypes (nr.NamespaceName, StringComparer.Ordinal)) {
- namespaceContents.AddType (cl, cl.Name);
- }
- foreach (var ns in ctx.GetNamespaces ().Where (n => n.Length > nr.NamespaceName.Length && n.StartsWith (nr.NamespaceName))) {
- namespaceContents.AddNamespace (nr.NamespaceName, ns);
- }
-
- return namespaceContents.Result;
- }
-
- IType type = GetTypeFromContext (resolveResult.Type.GetDefinition ()) ?? resolveResult.Type;
- var typeDef = resolveResult.Type.GetDefinition ();
- var lookup = new MemberLookup (ctx, currentType, ProjectContent);
- var result = new CompletionDataWrapper (this);
- bool isProtectedAllowed = false;
- bool includeStaticMembers = false;
-
- if (resolveResult is LocalResolveResult) {
- isProtectedAllowed = currentType != null && typeDef != null ? typeDef.GetAllBaseTypeDefinitions (ctx).Any (bt => bt.Equals (currentType)) : false;
- if (resolvedNode is IdentifierExpression) {
- var mrr = (LocalResolveResult)resolveResult;
- includeStaticMembers = mrr.Variable.Name == mrr.Type.Name;
- }
- } else {
- isProtectedAllowed = currentType != null && typeDef != null ? currentType.GetAllBaseTypeDefinitions (ctx).Any (bt => bt.Equals (typeDef)) : false;
- }
- if (resolveResult is TypeResolveResult && type.Kind == TypeKind.Enum) {
- foreach (var field in type.GetFields (ctx)) {
- result.AddMember (field);
- }
- foreach (var m in type.GetMethods (ctx)) {
- if (m.Name == "TryParse")
- result.AddMember (m);
- }
- return result.Result;
- }
-
- if (resolveResult is MemberResolveResult && resolvedNode is IdentifierExpression) {
- var mrr = (MemberResolveResult)resolveResult;
- includeStaticMembers = mrr.Member.Name == mrr.Type.Name;
- }
-
-// Console.WriteLine ("type:" + type +"/"+type.GetType ());
-// Console.WriteLine ("IS PROT ALLOWED:" + isProtectedAllowed);
-// Console.WriteLine (resolveResult);
-// Console.WriteLine (currentMember != null ? currentMember.IsStatic : "currentMember == null");
- if (resolvedNode.Annotation<ObjectCreateExpression> () == null) { //tags the created expression as part of an object create expression.
- foreach (var member in type.GetMembers (ctx)) {
- if (!lookup.IsAccessible (member, isProtectedAllowed)) {
- // Console.WriteLine ("skip access: " + member.FullName);
- continue;
- }
- if (resolvedNode is BaseReferenceExpression && member.IsAbstract)
- continue;
-
- if (!includeStaticMembers && member.IsStatic && !(resolveResult is TypeResolveResult)) {
- // Console.WriteLine ("skip static member: " + member.FullName);
- continue;
- }
- if (!member.IsStatic && (resolveResult is TypeResolveResult)) {
- // Console.WriteLine ("skip non static member: " + member.FullName);
- continue;
- }
- // Console.WriteLine ("add : "+ member.FullName + " --- " + member.IsStatic);
- result.AddMember (member);
- }
- }
-
- if (resolveResult is TypeResolveResult || includeStaticMembers) {
- foreach (var nested in type.GetNestedTypes (ctx)) {
- result.AddType (nested, nested.Name);
- }
-
- } else {
- var baseTypes = new List<IType> (type.GetAllBaseTypes (ctx));
- var conv = new Conversions (ctx);
- for (var n = state.CurrentUsingScope; n != null; n = n.Parent) {
- AddExtensionMethods (result, conv, baseTypes, n.NamespaceName);
- foreach (var u in n.Usings) {
- var ns = u.ResolveNamespace (ctx);
- if (ns == null)
- continue;
- AddExtensionMethods (result, conv, baseTypes, ns.NamespaceName);
- }
- }
- }
-
-// IEnumerable<object> objects = resolveResult.CreateResolveResult (dom, resolver != null ? resolver.CallingMember : null);
-// CompletionDataCollector col = new CompletionDataCollector (this, dom, result, Document.CompilationUnit, resolver != null ? resolver.CallingType : null, location);
-// col.HideExtensionParameter = !resolveResult.StaticResolve;
-// col.NamePrefix = expressionResult.Expression;
-// bool showOnlyTypes = expressionResult.Contexts.Any (ctx => ctx == ExpressionContext.InheritableType || ctx == ExpressionContext.Constraints);
-// if (objects != null) {
-// foreach (object obj in objects) {
-// if (expressionResult.ExpressionContext != null && expressionResult.ExpressionContext.FilterEntry (obj))
-// continue;
-// if (expressionResult.ExpressionContext == ExpressionContext.NamespaceNameExcepted && !(obj is Namespace))
-// continue;
-// if (showOnlyTypes && !(obj is IType))
-// continue;
-// CompletionData data = col.Add (obj);
-// if (data != null && expressionResult.ExpressionContext == ExpressionContext.Attribute && data.CompletionText != null && data.CompletionText.EndsWith ("Attribute")) {
-// string newText = data.CompletionText.Substring (0, data.CompletionText.Length - "Attribute".Length);
-// data.SetText (newText);
-// }
-// }
-// }
-
- return result.Result;
- }
-
- void AddExtensionMethods (CompletionDataWrapper result, Conversions conv, List<IType> baseTypes, string namespaceName)
- {
- foreach (var typeDefinition in ctx.GetTypes (namespaceName, StringComparer.Ordinal).Where (t => t.IsStatic && t.HasExtensionMethods)) {
- foreach (var m in typeDefinition.Methods.Where (m => m.IsExtensionMethod )) {
- var pt = m.Parameters.First ().Type.Resolve (ctx);
- string reflectionName = pt is ParameterizedType ? ((ParameterizedType)pt).GetDefinition ().ReflectionName : pt.ReflectionName;
- if (baseTypes.Any (bt => (bt is ParameterizedType ? ((ParameterizedType)bt).GetDefinition ().ReflectionName : bt.ReflectionName) == reflectionName)) {
- result.AddMember (m);
- }
- }
- }
- }
- IEnumerable<ICompletionData> CreateCaseCompletionData (TextLocation location)
- {
- var unit = ParseStub ("a: break;");
- if (unit == null)
- return null;
- var s = unit.GetNodeAt<SwitchStatement> (location);
- if (s == null)
- return null;
-
- var offset = document.GetOffset (s.Expression.StartLocation);
- var expr = GetExpressionAt (offset);
- if (expr == null)
- return null;
-
- var resolveResult = ResolveExpression (expr.Item1, expr.Item2, expr.Item3);
- if (resolveResult == null || resolveResult.Item1.Type.Kind != TypeKind.Enum)
- return null;
- var wrapper = new CompletionDataWrapper (this);
- AddEnumMembers (wrapper, resolveResult.Item1.Type, resolveResult.Item2);
- AutoCompleteEmptyMatch = false;
- return wrapper.Result;
- }
-
- #region Parsing methods
- Tuple<CSharpParsedFile, AstNode, CompilationUnit> GetExpressionBeforeCursor ()
- {
- CompilationUnit baseUnit;
- if (currentMember == null) {
- baseUnit = ParseStub ("st {}", false);
- var type = baseUnit.GetNodeAt<MemberType> (location);
- if (type == null) {
- baseUnit = ParseStub ("a;", false);
- type = baseUnit.GetNodeAt<MemberType> (location);
- }
- if (type != null) {
- // insert target type into compilation unit, to respect the
- var target = type.Target;
- target.Remove ();
- var node = Unit.GetNodeAt (location) ?? Unit;
- node.AddChild (target, AstNode.Roles.Type);
- return Tuple.Create (CSharpParsedFile, (AstNode)target, Unit);
- }
- }
-
- if (currentMember == null && currentType == null) {
- return null;
- }
- baseUnit = ParseStub ("a()");
-
- // Hack for handle object initializer continuation expressions
- if (baseUnit.GetNodeAt (location) is AttributedNode) {
- baseUnit = ParseStub ("a()};");
- }
-
- var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
- var mref = baseUnit.GetNodeAt<MemberReferenceExpression> (location);
-
- if (mref == null){
- var invoke = baseUnit.GetNodeAt<InvocationExpression> (location);
- if (invoke != null)
- mref = invoke.Target as MemberReferenceExpression;
- }
- Expression expr = null;
- if (mref != null) {
- expr = mref.Target.Clone ();
- mref.Parent.ReplaceWith (expr);
- } else {
- Expression tref = baseUnit.GetNodeAt<TypeReferenceExpression> (location);
- var memberType = tref != null ? ((TypeReferenceExpression)tref).Type as MemberType : null;
- if (memberType == null) {
- memberType = baseUnit.GetNodeAt<MemberType> (location);
- if (memberType != null) {
- tref = baseUnit.GetNodeAt<Expression> (location);
- if (tref == null)
- return null;
- }
- if (tref is ObjectCreateExpression) {
- expr = new TypeReferenceExpression (memberType.Target.Clone ());
- expr.AddAnnotation (new ObjectCreateExpression ());
- }
- }
-
- if (memberType == null)
- return null;
- if (expr == null)
- expr = new TypeReferenceExpression (memberType.Target.Clone ());
- tref.ReplaceWith (expr);
- }
-
- var member = Unit.GetNodeAt<AttributedNode> (memberLocation);
- var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation);
- member2.Remove ();
- member.ReplaceWith (member2);
- var tsvisitor = new TypeSystemConvertVisitor (ProjectContent, this.CSharpParsedFile.FileName);
- Unit.AcceptVisitor (tsvisitor, null);
- return Tuple.Create (tsvisitor.ParsedFile, (AstNode)expr, Unit);
- }
-
- Tuple<CSharpParsedFile, AstNode, CompilationUnit> GetExpressionAtCursor ()
- {
-// if (currentMember == null && currentType == null)
-// return null;
-
- TextLocation memberLocation;
- if (currentMember != null) {
- memberLocation = currentMember.Region.Begin;
- } else if (currentType != null) {
- memberLocation = currentType.Region.Begin;
- } else {
- memberLocation = location;
- }
-
- var baseUnit = ParseStub ("");
- var tmpUnit = baseUnit;
- AstNode expr = baseUnit.GetNodeAt<IdentifierExpression> (location.Line, location.Column - 1);
- if (expr == null)
- expr = baseUnit.GetNodeAt<Attribute> (location.Line, location.Column - 1);
-
- if (expr == null) {
- baseUnit = ParseStub ("()");
- expr = baseUnit.GetNodeAt<IdentifierExpression> (location.Line, location.Column - 1);
- }
-
- // try initializer expression
- if (expr == null) {
- baseUnit = ParseStub ("a = b};", false);
- expr = baseUnit.GetNodeAt<ArrayInitializerExpression> (location.Line, location.Column - 1);
- }
-
- // try statement
- if (expr == null) {
- expr = tmpUnit.GetNodeAt<SwitchStatement> (location.Line, location.Column - 1);
- baseUnit = tmpUnit;
- }
-
- if (expr == null) {
- var forStmt = tmpUnit.GetNodeAt<ForStatement> (location.Line, location.Column - 3);
- expr = forStmt;
- if (forStmt != null && forStmt.EmbeddedStatement.IsNull) {
- var id = new IdentifierExpression ("stub");
- forStmt.EmbeddedStatement = new BlockStatement () { Statements = { new ExpressionStatement (id) }};
- expr = id;
- }
- baseUnit = tmpUnit;
- }
-
- if (expr == null)
- return null;
- var member = Unit.GetNodeAt<AttributedNode> (memberLocation);
- var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation);
- if (member != null && member2 != null) {
- member2.Remove ();
-
- if (member is TypeDeclaration) {
- member.AddChild (member2, TypeDeclaration.MemberRole);
- } else {
- member.ReplaceWith (member2);
- }
- } else {
- var tsvisitor2 = new TypeSystemConvertVisitor (ProjectContent, CSharpParsedFile.FileName);
- Unit.AcceptVisitor (tsvisitor2, null);
- return Tuple.Create (tsvisitor2.ParsedFile, expr, baseUnit);
- }
- var tsvisitor = new TypeSystemConvertVisitor (ProjectContent, CSharpParsedFile.FileName);
- Unit.AcceptVisitor (tsvisitor, null);
- return Tuple.Create (tsvisitor.ParsedFile, expr, Unit);
- }
-
- Tuple<CSharpParsedFile, AstNode, CompilationUnit> GetExpressionAt (int offset)
- {
- var parser = new CSharpParser ();
- string text = this.document.GetText (0, this.offset);
- var sb = new StringBuilder (text);
- sb.Append ("a;");
- AppendMissingClosingBrackets (sb, text, false);
- var stream = new System.IO.StringReader (sb.ToString ());
- var completionUnit = parser.Parse (stream, 0);
- stream.Close ();
- var loc = document.GetLocation (offset);
-
- var expr = completionUnit.GetNodeAt (loc, n => n is Expression || n is VariableDeclarationStatement);
- if (expr == null)
- return null;
- var tsvisitor = new TypeSystemConvertVisitor (ProjectContent, CSharpParsedFile.FileName);
- completionUnit.AcceptVisitor (tsvisitor, null);
-
- return Tuple.Create (tsvisitor.ParsedFile, expr, completionUnit);
- }
-
-
- Tuple<CSharpParsedFile, AstNode, CompilationUnit> GetNewExpressionAt (int offset)
- {
- var parser = new CSharpParser ();
- string text = this.document.GetText (0, this.offset);
- var sb = new StringBuilder (text);
- sb.Append ("a ();");
- AppendMissingClosingBrackets (sb, text, false);
- var stream = new System.IO.StringReader (sb.ToString ());
- var completionUnit = parser.Parse (stream, 0);
- stream.Close ();
- var loc = document.GetLocation (offset);
-
- var expr = completionUnit.GetNodeAt (loc, n => n is Expression);
- if (expr == null)
- return null;
- var tsvisitor = new TypeSystemConvertVisitor (ProjectContent, CSharpParsedFile.FileName);
- completionUnit.AcceptVisitor (tsvisitor, null);
-
- return Tuple.Create (tsvisitor.ParsedFile, expr, completionUnit);
- }
-
-
- #endregion
-
- #region Helper methods
- string GetPreviousToken (ref int i, bool allowLineChange)
- {
- char c;
- if (i <= 0)
- return null;
-
- do {
- c = document.GetCharAt (--i);
- } while (i > 0 && char.IsWhiteSpace (c) && (allowLineChange ? true : c != '\n'));
-
- if (i == 0)
- return null;
-
- if (!char.IsLetterOrDigit (c))
- return new string (c, 1);
-
- int endOffset = i + 1;
-
- do {
- c = document.GetCharAt (i - 1);
- if (!(char.IsLetterOrDigit (c) || c == '_'))
- break;
-
- i--;
- } while (i > 0);
-
- return document.GetText (i, endOffset - i);
- }
-
- bool GetParameterCompletionCommandOffset (out int cpos)
- {
- // Start calculating the parameter offset from the beginning of the
- // current member, instead of the beginning of the file.
- cpos = offset - 1;
- IMember mem = currentMember;
- if (mem == null || (mem is IType))
- return false;
- int startPos = document.GetOffset (mem.Region.BeginLine, mem.Region.BeginColumn);
- int parenDepth = 0;
- int chevronDepth = 0;
- while (cpos > startPos) {
- char c = document.GetCharAt (cpos);
- if (c == ')')
- parenDepth++;
- if (c == '>')
- chevronDepth++;
- if (parenDepth == 0 && c == '(' || chevronDepth == 0 && c == '<') {
- int p = GetCurrentParameterIndex (cpos + 1, startPos);
- if (p != -1) {
- cpos++;
- return true;
- } else {
- return false;
- }
- }
- if (c == '(')
- parenDepth--;
- if (c == '<')
- chevronDepth--;
- cpos--;
- }
- return false;
- }
-
- int GetCurrentParameterIndex (int offset, int memberStart)
- {
- int cursor = this.offset;
- int i = offset;
-
- if (i > cursor)
- return -1;
- if (i == cursor)
- return 1; // parameters are 1 based
- int index = memberStart + 1;
- int parentheses = 0;
- int bracket = 0;
- bool insideQuote = false, insideString = false, insideSingleLineComment = false, insideMultiLineComment = false;
- do {
- char c = document.GetCharAt (i - 1);
- switch (c) {
- case '\\':
- if (insideString || insideQuote)
- i++;
- break;
- case '\'':
- if (!insideString && !insideSingleLineComment && !insideMultiLineComment)
- insideQuote = !insideQuote;
- break;
- case '"':
- if (!insideQuote && !insideSingleLineComment && !insideMultiLineComment)
- insideString = !insideString;
- break;
- case '/':
- if (!insideQuote && !insideString && !insideMultiLineComment) {
- if (document.GetCharAt (i) == '/')
- insideSingleLineComment = true;
- if (document.GetCharAt (i) == '*')
- insideMultiLineComment = true;
- }
- break;
- case '*':
- if (insideMultiLineComment && document.GetCharAt (i) == '/')
- insideMultiLineComment = false;
- break;
- case '\n':
- case '\r':
- insideSingleLineComment = false;
- break;
- case '{':
- if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment)
- bracket++;
- break;
- case '}':
- if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment)
- bracket--;
- break;
- case '(':
- if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment)
- parentheses++;
- break;
- case ')':
- if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment)
- parentheses--;
- break;
- case ',':
- if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment && parentheses == 1 && bracket == 0)
- index++;
- break;
- }
- i++;
- } while (i <= cursor && parentheses >= 0);
-
- return parentheses != 1 || bracket > 0 ? -1 : index;
- }
-
- CSharpResolver GetState ()
- {
- var state = new CSharpResolver (ctx, System.Threading.CancellationToken.None);
-
- state.CurrentMember = CSharpParsedFile.GetMember (location);
- state.CurrentTypeDefinition = CSharpParsedFile.GetInnermostTypeDefinition (location);
- state.CurrentUsingScope = CSharpParsedFile.GetUsingScope (location);
- if (state.CurrentMember != null) {
- var node = Unit.GetNodeAt (location);
- if (node == null)
- return state;
- var navigator = new NodeListResolveVisitorNavigator (new[] { node });
- var visitor = new ResolveVisitor (state, CSharpParsedFile, navigator);
- Unit.AcceptVisitor (visitor, null);
- try {
- var newState = visitor.GetResolverStateBefore (node);
- if (newState != null)
- state = newState;
- } catch (Exception) {
- }
- }
-
- return state;
- }
- #endregion
-
- #region Preprocessor
-
- IEnumerable<ICompletionData> GetDirectiveCompletionData ()
- {
- yield return factory.CreateLiteralCompletionData ("if");
- yield return factory.CreateLiteralCompletionData ("else");
- yield return factory.CreateLiteralCompletionData ("elif");
- yield return factory.CreateLiteralCompletionData ("endif");
- yield return factory.CreateLiteralCompletionData ("define");
- yield return factory.CreateLiteralCompletionData ("undef");
- yield return factory.CreateLiteralCompletionData ("warning");
- yield return factory.CreateLiteralCompletionData ("error");
- yield return factory.CreateLiteralCompletionData ("pragma");
- yield return factory.CreateLiteralCompletionData ("line");
- yield return factory.CreateLiteralCompletionData ("line hidden");
- yield return factory.CreateLiteralCompletionData ("line default");
- yield return factory.CreateLiteralCompletionData ("region");
- yield return factory.CreateLiteralCompletionData ("endregion");
- }
- #endregion
-
- #region Xml Comments
- static readonly List<string> commentTags = new List<string> (new string[] { "c", "code", "example", "exception", "include", "list", "listheader", "item", "term", "description", "para", "param", "paramref", "permission", "remarks", "returns", "see", "seealso", "summary", "value" });
-
- IEnumerable<ICompletionData> GetXmlDocumentationCompletionData ()
- {
- yield return factory.CreateLiteralCompletionData ("c", "Set text in a code-like font");
- yield return factory.CreateLiteralCompletionData ("code", "Set one or more lines of source code or program output");
- yield return factory.CreateLiteralCompletionData ("example", "Indicate an example");
- yield return factory.CreateLiteralCompletionData ("exception", "Identifies the exceptions a method can throw", "exception cref=\"|\"></exception>");
- yield return factory.CreateLiteralCompletionData ("include", "Includes comments from a external file", "include file=\"|\" path=\"\">");
- yield return factory.CreateLiteralCompletionData ("list", "Create a list or table", "list type=\"|\">");
- yield return factory.CreateLiteralCompletionData ("listheader", "Define the heading row");
- yield return factory.CreateLiteralCompletionData ("item", "Defines list or table item");
-
- yield return factory.CreateLiteralCompletionData ("term", "A term to define");
- yield return factory.CreateLiteralCompletionData ("description", "Describes a list item");
- yield return factory.CreateLiteralCompletionData ("para", "Permit structure to be added to text");
-
- yield return factory.CreateLiteralCompletionData ("param", "Describe a parameter for a method or constructor", "param name=\"|\">");
- yield return factory.CreateLiteralCompletionData ("paramref", "Identify that a word is a parameter name", "paramref name=\"|\"/>");
-
- yield return factory.CreateLiteralCompletionData ("permission", "Document the security accessibility of a member", "permission cref=\"|\"");
- yield return factory.CreateLiteralCompletionData ("remarks", "Describe a type");
- yield return factory.CreateLiteralCompletionData ("returns", "Describe the return value of a method");
- yield return factory.CreateLiteralCompletionData ("see", "Specify a link", "see cref=\"|\"/>");
- yield return factory.CreateLiteralCompletionData ("seealso", "Generate a See Also entry", "seealso cref=\"|\"/>");
- yield return factory.CreateLiteralCompletionData ("summary", "Describe a member of a type");
- yield return factory.CreateLiteralCompletionData ("typeparam", "Describe a type parameter for a generic type or method");
- yield return factory.CreateLiteralCompletionData ("typeparamref", "Identify that a word is a type parameter name");
- yield return factory.CreateLiteralCompletionData ("value", "Describe a property");
- }
- #endregion
-
- #region Keywords
- static string[] expressionLevelKeywords = new string [] { "as", "is", "else", "out", "ref", "null", "delegate", "default"};
-
- static string[] primitiveTypesKeywords = new string [] { "void", "object", "bool", "byte", "sbyte", "char", "short", "int", "long", "ushort", "uint", "ulong", "float", "double", "decimal", "string"};
-
- static string[] statementStartKeywords = new string [] { "base", "new", "sizeof", "this",
- "true", "false", "typeof", "checked", "unchecked", "from", "break", "checked",
- "unchecked", "const", "continue", "do", "finally", "fixed", "for", "foreach",
- "goto", "if", "lock", "return", "stackalloc", "switch", "throw", "try", "unsafe",
- "using", "while", "yield", "dynamic", "var" };
-
- static string[] globalLevelKeywords = new string [] {
- "namespace", "using", "extern", "public", "internal",
- "class", "interface", "struct", "enum", "delegate",
- "abstract", "sealed", "static", "unsafe", "partial"
- };
-
- static string[] accessorModifierKeywords = new string [] {
- "public", "internal", "protected", "private"
- };
-
- static string[] typeLevelKeywords = new string [] {
- "public", "internal", "protected", "private",
- "class", "interface", "struct", "enum", "delegate",
- "abstract", "sealed", "static", "unsafe", "partial",
- "const", "event", "extern", "fixed","new",
- "operator", "explicit", "implicit",
- "override", "readonly", "virtual", "volatile"
- };
- static string[] linqKeywords = new string[] { "from", "where", "select", "group", "into", "orderby", "join", "let", "in", "on", "equals", "by", "ascending", "descending" };
- #endregion
- }
-}
-
+//
+// CSharpCompletionEngine.cs
+//
+// Author:
+// Mike Krüger <mkrueger@xamarin.com>
+//
+// Copyright (c) 2011 Xamarin Inc. (http://xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using ICSharpCode.NRefactory.Completion;
+using ICSharpCode.NRefactory.CSharp.Refactoring;
+using ICSharpCode.NRefactory.CSharp.Resolver;
+using ICSharpCode.NRefactory.Editor;
+using ICSharpCode.NRefactory.Semantics;
+using ICSharpCode.NRefactory.TypeSystem;
+
+namespace ICSharpCode.NRefactory.CSharp.Completion
+{
+ public class CSharpCompletionEngine : CSharpCompletionEngineBase
+ {
+ internal ICompletionDataFactory factory;
+
+ #region Additional input properties
+ public CSharpFormattingOptions FormattingPolicy { get; set; }
+ public string EolMarker { get; set; }
+ public string IndentString { get; set; }
+ #endregion
+
+ #region Result properties
+ public bool AutoCompleteEmptyMatch;
+ public bool AutoSelect;
+ public string DefaultCompletionString;
+ #endregion
+
+ public CSharpCompletionEngine (IDocument document, ICompletionDataFactory factory)
+ {
+ this.document = document;
+ this.factory = factory;
+ }
+
+ public IEnumerable<ICompletionData> GetCompletionData (int offset, bool controlSpace)
+ {
+ this.AutoCompleteEmptyMatch = true;
+ this.AutoSelect = true;
+ this.DefaultCompletionString = null;
+ SetOffset (offset);
+ if (offset > 0) {
+ char lastChar = document.GetCharAt (offset - 1);
+ var result = MagicKeyCompletion (lastChar, controlSpace) ?? Enumerable.Empty<ICompletionData> ();
+ if (controlSpace && char.IsWhiteSpace (lastChar)) {
+ offset -= 2;
+ while (offset >= 0 && char.IsWhiteSpace (document.GetCharAt (offset)))
+ offset--;
+ if (offset > 0) {
+ var nonWsResult = MagicKeyCompletion (document.GetCharAt (offset), controlSpace);
+ if (nonWsResult != null)
+ result = result.Concat (nonWsResult);
+ }
+ }
+
+ return result;
+ }
+ return Enumerable.Empty<ICompletionData> ();
+ }
+
+ IEnumerable<string> GenerateNameProposals (AstType type)
+ {
+ if (type is PrimitiveType) {
+ var pt = (PrimitiveType)type;
+ Console.WriteLine (pt.Keyword);
+ 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;
+ }
+ yield break;
+ }
+
+ var names = new List<string> ();
+ int offset1 = document.GetOffset (type.StartLocation);
+ int offset2 = document.GetOffset (type.EndLocation);
+
+ string name = document.GetText (offset1, offset2 - offset1);
+ int lastNameStart = 0;
+ for (int i = 1; i < name.Length; i++) {
+ if (Char.IsUpper (name [i])) {
+ names.Add (name.Substring (lastNameStart, i - lastNameStart));
+ lastNameStart = i;
+ }
+ }
+
+ names.Add (name.Substring (lastNameStart, name.Length - lastNameStart));
+
+ var possibleName = new StringBuilder ();
+ for (int i = 0; i < names.Count; i++) {
+ possibleName.Length = 0;
+ for (int j = i; j < names.Count; j++) {
+ if (string.IsNullOrEmpty (names [j]))
+ continue;
+ if (j == i)
+ names [j] = Char.ToLower (names [j] [0]) + names [j].Substring (1);
+ possibleName.Append (names [j]);
+ }
+ yield return possibleName.ToString ();
+ }
+ }
+
+ IEnumerable<ICompletionData> MagicKeyCompletion (char completionChar, bool controlSpace)
+ {
+ switch (completionChar) {
+ // Magic key completion
+ case ':':
+ case '.':
+ if (IsInsideCommentOrString ())
+ return Enumerable.Empty<ICompletionData> ();
+ var expr = GetExpressionBeforeCursor ();
+ if (expr == null)
+ return null;
+ // do not complete <number>. (but <number>.<number>.)
+ if (expr.Item2 is PrimitiveExpression) {
+ var pexpr = (PrimitiveExpression)expr.Item2;
+ if (!(pexpr.Value is string || pexpr.Value is char) && !pexpr.LiteralValue.Contains ('.'))
+ return null;
+ }
+
+
+ var resolveResult = ResolveExpression (expr.Item1, expr.Item2, expr.Item3);
+
+ if (resolveResult == null)
+ return null;
+ if (expr.Item2 is AstType)
+ return CreateTypeAndNamespaceCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2);
+
+ return CreateCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2);
+ case '#':
+ if (IsInsideCommentOrString ())
+ return null;
+ return GetDirectiveCompletionData ();
+
+// XML doc completion
+ case '<':
+ if (IsInsideDocComment ())
+ return GetXmlDocumentationCompletionData ();
+ if (controlSpace)
+ return DefaultControlSpaceItems ();
+ return null;
+ case '>':
+ if (!IsInsideDocComment ())
+ return null;
+ string lineText = document.GetText (document.GetLineByNumber (location.Line));
+ int startIndex = Math.Min (location.Column - 1, lineText.Length - 1);
+
+ while (startIndex >= 0 && lineText [startIndex] != '<') {
+ --startIndex;
+ if (lineText [startIndex] == '/') { // already closed.
+ startIndex = -1;
+ break;
+ }
+ }
+
+ if (startIndex >= 0) {
+ int endIndex = startIndex;
+ while (endIndex <= location.Column && endIndex < lineText.Length && !Char.IsWhiteSpace (lineText [endIndex])) {
+ endIndex++;
+ }
+ string tag = endIndex - startIndex - 1 > 0 ? lineText.Substring (startIndex + 1, endIndex - startIndex - 2) : null;
+ if (!string.IsNullOrEmpty (tag) && commentTags.IndexOf (tag) >= 0)
+ document.Insert (offset, "</" + tag + ">");
+ }
+ return null;
+
+ // Parameter completion
+ case '(':
+ if (IsInsideCommentOrString ())
+ return null;
+ var invoke = GetInvocationBeforeCursor (true);
+ if (invoke == null)
+ return null;
+ if (invoke.Item2 is TypeOfExpression)
+ return CreateTypeList ();
+ var invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
+ if (invocationResult == null)
+ return null;
+ var methodGroup = invocationResult.Item1 as MethodGroupResolveResult;
+ if (methodGroup != null)
+ return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, 0, controlSpace);
+ return null;
+ case '=':
+ return controlSpace ? DefaultControlSpaceItems () : null;
+ case ',':
+ int cpos2;
+ if (!GetParameterCompletionCommandOffset (out cpos2))
+ return null;
+ // completionContext = CompletionWidget.CreateCodeCompletionContext (cpos2);
+ // int currentParameter2 = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, completionContext) - 1;
+// return CreateParameterCompletion (CreateResolver (), location, ExpressionContext.MethodBody, provider.Methods, currentParameter);
+ break;
+
+ // Completion on space:
+ case ' ':
+ if (IsInsideCommentOrString ())
+ return null;
+
+ int tokenIndex = offset;
+ string token = GetPreviousToken (ref tokenIndex, false);
+
+ // check propose name, for context <variable name> <ctrl+space> (but only in control space context)
+ IType isAsType = null;
+ var isAsExpression = GetExpressionAt (offset);
+ if (controlSpace && isAsExpression != null && isAsExpression.Item2 is VariableDeclarationStatement && token != "new") {
+ var parent = isAsExpression.Item2 as VariableDeclarationStatement;
+ var proposeNameList = new CompletionDataWrapper (this);
+
+ foreach (var possibleName in GenerateNameProposals (parent.Type)) {
+ if (possibleName.Length > 0)
+ proposeNameList.Result.Add (factory.CreateLiteralCompletionData (possibleName.ToString ()));
+ }
+
+ AutoSelect = false;
+ AutoCompleteEmptyMatch = false;
+ return proposeNameList.Result;
+ }
+// int tokenIndex = offset;
+// string token = GetPreviousToken (ref tokenIndex, false);
+// if (result.ExpressionContext == ExpressionContext.ObjectInitializer) {
+// resolver = CreateResolver ();
+// ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForObjectInitializer (document, resolver.Unit, Document.FileName, resolver.CallingType);
+// IReturnType objectInitializer = ((ExpressionContext.TypeExpressionContext)exactContext).UnresolvedType;
+// if (objectInitializer != null && objectInitializer.ArrayDimensions == 0 && objectInitializer.PointerNestingLevel == 0 && (token == "{" || token == ","))
+// return CreateCtrlSpaceCompletionData (completionContext, result);
+// }
+ if (token == "=") {
+ int j = tokenIndex;
+ string prevToken = GetPreviousToken (ref j, false);
+ if (prevToken == "=" || prevToken == "+" || prevToken == "-") {
+ token = prevToken + token;
+ tokenIndex = j;
+ }
+ }
+ switch (token) {
+ case "(":
+ case ",":
+ int cpos;
+ if (!GetParameterCompletionCommandOffset (out cpos))
+ break;
+ int currentParameter = GetCurrentParameterIndex (cpos, 0) - 1;
+ if (currentParameter < 0)
+ return null;
+ invoke = GetInvocationBeforeCursor (token == "(");
+ if (invoke == null)
+ return null;
+ invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
+ if (invocationResult == null)
+ return null;
+ methodGroup = invocationResult.Item1 as MethodGroupResolveResult;
+ if (methodGroup != null)
+ return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, currentParameter, controlSpace);
+ return null;
+ case "=":
+ case "==":
+ GetPreviousToken (ref tokenIndex, false);
+
+ var expressionOrVariableDeclaration = GetExpressionAt (tokenIndex);
+ if (expressionOrVariableDeclaration == null)
+ return null;
+
+ resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3);
+ if (resolveResult == null)
+ return null;
+
+ if (resolveResult.Item1.Type.Kind == TypeKind.Enum) {
+ var wrapper = new CompletionDataWrapper (this);
+ AddContextCompletion (wrapper, resolveResult.Item2, expressionOrVariableDeclaration.Item2);
+ AddEnumMembers (wrapper, resolveResult.Item1.Type, resolveResult.Item2);
+ AutoCompleteEmptyMatch = false;
+ return wrapper.Result;
+ }
+//
+// if (resolvedType.FullName == DomReturnType.Bool.FullName) {
+// CompletionDataList completionList = new ProjectDomCompletionDataList ();
+// CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
+// completionList.AutoCompleteEmptyMatch = false;
+// cdc.Add ("true", "md-keyword");
+// cdc.Add ("false", "md-keyword");
+// resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
+// return completionList;
+// }
+// if (resolvedType.ClassType == ClassType.Delegate && token == "=") {
+// CompletionDataList completionList = new ProjectDomCompletionDataList ();
+// string parameterDefinition = AddDelegateHandlers (completionList, resolvedType);
+// string varName = GetPreviousMemberReferenceExpression (tokenIndex);
+// completionList.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.CallingMember, resolvedType));
+//
+// CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
+// resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
+// foreach (var data in completionList) {
+// if (data is MemberCompletionData)
+// ((MemberCompletionData)data).IsDelegateExpected = true;
+// }
+// return completionList;
+// }
+ return null;
+ case "+=":
+ case "-=":
+ GetPreviousToken (ref tokenIndex, false);
+
+ expressionOrVariableDeclaration = GetExpressionAt (tokenIndex);
+ if (expressionOrVariableDeclaration == null)
+ return null;
+
+ resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3);
+ if (resolveResult == null)
+ return null;
+
+
+ var mrr = resolveResult.Item1 as MemberResolveResult;
+ if (mrr != null) {
+ var evt = mrr.Member as IEvent;
+ if (evt == null)
+ return null;
+ var delegateType = evt.ReturnType.Resolve (ctx);
+ if (!delegateType.IsDelegate ())
+ return null;
+
+ var wrapper = new CompletionDataWrapper (this);
+ if (currentType != null) {
+// bool includeProtected = DomType.IncludeProtected (dom, typeFromDatabase, resolver.CallingType);
+ foreach (var method in currentType.GetMethods (ctx)) {
+ 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) {
+ var wrapper = new CompletionDataWrapper (this);
+ AddTypesAndNamespaces (wrapper, GetState (), null, t => currentType != null ? !currentType.Equals (t) : true);
+ return wrapper.Result;
+ }
+ return null;
+ }
+
+ var keywordCompletion = HandleKeywordCompletion (tokenIndex, token);
+ if (keywordCompletion == null && controlSpace)
+ goto default;
+ return keywordCompletion;
+ // Automatic completion
+ default:
+ if (IsInsideCommentOrString ())
+ return null;
+ if (IsInLinqContext (offset)) {
+ tokenIndex = offset;
+ token = GetPreviousToken (ref tokenIndex, false); // token last typed
+ if (linqKeywords.Contains (token)) {
+ if (token == "from") // after from no auto code completion.
+ return null;
+ return DefaultControlSpaceItems ();
+ }
+ var dataList = new CompletionDataWrapper (this);
+ AddKeywords (dataList, linqKeywords);
+ return dataList.Result;
+ }
+
+ var contextList = new CompletionDataWrapper (this);
+
+ var identifierStart = GetExpressionAtCursor ();
+ if (!(char.IsLetter (completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null || !(identifierStart.Item2 is ArrayInitializerExpression))) {
+ return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems () : null;
+ }
+
+ char prevCh = offset > 2 ? document.GetCharAt (offset - 2) : '\0';
+ 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 (identifierStart == null && !string.IsNullOrEmpty (token) && !(IsInsideComment (tokenIndex) || IsInsideString (tokenIndex))) {
+ char last = token [token.Length - 1];
+ if (char.IsLetterOrDigit (last) || last == '_' || token == ">") {
+ return null;
+ }
+ }
+ if (identifierStart == null)
+ return HandleAccessorContext () ?? DefaultControlSpaceItems ();
+
+ CSharpResolver csResolver;
+ AstNode n = identifierStart.Item2;
+ if (n is ArrayInitializerExpression) {
+ var initalizerResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3);
+
+ var concreteNode = identifierStart.Item3.GetNodeAt<IdentifierExpression> (location);
+ // check if we're on the right side of an initializer expression
+ if (concreteNode != null && concreteNode.Parent != null && concreteNode.Parent.Parent != null && concreteNode.Identifier != "a" && concreteNode.Parent.Parent is NamedExpression)
+ return DefaultControlSpaceItems ();
+
+ if (initalizerResult != null) {
+
+ foreach (var property in initalizerResult.Item1.Type.GetProperties (ctx)) {
+ if (!property.IsPublic)
+ continue;
+ contextList.AddMember (property);
+ }
+ foreach (var field in initalizerResult.Item1.Type.GetFields (ctx)){
+ if (!field.IsPublic)
+ continue;
+ contextList.AddMember (field);
+ }
+ return contextList.Result;
+ }
+ return null;
+ }
+ if (n != null/* && !(identifierStart.Item2 is TypeDeclaration)*/) {
+ csResolver = new CSharpResolver (ctx, System.Threading.CancellationToken.None);
+ var nodes = new List<AstNode> ();
+ nodes.Add (n);
+ if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute)
+ nodes.Add (n.Parent);
+ var navigator = new NodeListResolveVisitorNavigator (nodes);
+ var visitor = new ResolveVisitor (csResolver, identifierStart.Item1, navigator);
+ visitor.Scan (identifierStart.Item3);
+ try {
+ csResolver = visitor.GetResolverStateBefore (n);
+ } catch (Exception) {
+ csResolver = GetState ();
+ }
+ // add attribute properties.
+ if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) {
+ var resolved = visitor.GetResolveResult (n.Parent);
+ if (resolved != null && resolved.Type != null) {
+ foreach (var property in resolved.Type.GetProperties (ctx).Where (p => p.Accessibility == Accessibility.Public)) {
+ contextList.AddMember (property);
+ }
+ foreach (var field in resolved.Type.GetFields (ctx).Where (p => p.Accessibility == Accessibility.Public)) {
+ contextList.AddMember (field);
+ }
+ }
+ }
+ } else {
+ csResolver = GetState ();
+ }
+
+ // identifier has already started with the first letter
+ offset--;
+
+ AddContextCompletion (contextList, csResolver, identifierStart.Item2);
+ return contextList.Result;
+// if (stub.Parent is BlockStatement)
+
+// result = FindExpression (dom, completionContext, -1);
+// if (result == null)
+// return null;
+// else if (result.ExpressionContext != ExpressionContext.IdentifierExpected) {
+// triggerWordLength = 1;
+// bool autoSelect = true;
+// IType returnType = null;
+// if ((prevCh == ',' || prevCh == '(') && GetParameterCompletionCommandOffset (out cpos)) {
+// ctx = CompletionWidget.CreateCodeCompletionContext (cpos);
+// NRefactoryParameterDataProvider dataProvider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider;
+// if (dataProvider != null) {
+// int i = dataProvider.GetCurrentParameterIndex (CompletionWidget, ctx) - 1;
+// foreach (var method in dataProvider.Methods) {
+// if (i < method.Parameters.Count) {
+// returnType = dom.GetType (method.Parameters [i].ReturnType);
+// autoSelect = returnType == null || returnType.ClassType != ClassType.Delegate;
+// break;
+// }
+// }
+// }
+// }
+// // Bug 677531 - Auto-complete doesn't always highlight generic parameter in method signature
+// //if (result.ExpressionContext == ExpressionContext.TypeName)
+// // autoSelect = false;
+// CompletionDataList dataList = CreateCtrlSpaceCompletionData (completionContext, result);
+// AddEnumMembers (dataList, returnType);
+// dataList.AutoSelect = autoSelect;
+// return dataList;
+// } else {
+// result = FindExpression (dom, completionContext, 0);
+// tokenIndex = offset;
+//
+// // check foreach case, unfortunately the expression finder is too dumb to handle full type names
+// // should be overworked if the expression finder is replaced with a mcs ast based analyzer.
+// var possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // starting letter
+// possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varname
+//
+// // read return types to '(' token
+// possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varType
+// if (possibleForeachToken == ">") {
+// while (possibleForeachToken != null && possibleForeachToken != "(") {
+// possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
+// }
+// } else {
+// possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // (
+// if (possibleForeachToken == ".")
+// while (possibleForeachToken != null && possibleForeachToken != "(")
+// possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
+// }
+// possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // foreach
+//
+// if (possibleForeachToken == "foreach") {
+// result.ExpressionContext = ExpressionContext.ForeachInToken;
+// } else {
+// return null;
+// // result.ExpressionContext = ExpressionContext.IdentifierExpected;
+// }
+// result.Expression = "";
+// result.Region = DomRegion.Empty;
+//
+// return CreateCtrlSpaceCompletionData (completionContext, result);
+// }
+// break;
+ }
+ return null;
+ }
+
+ bool IsInLinqContext (int offset)
+ {
+ string token;
+ while (null != (token = GetPreviousToken (ref offset, true))) {
+ if (token == "from")
+ return true;
+ if (token == ";")
+ return false;
+ }
+ return false;
+ }
+
+ IEnumerable<ICompletionData> HandleAccessorContext ()
+ {
+ var unit = ParseStub ("get; }", false);
+ var node = unit.GetNodeAt (location, cn => !(cn is CSharpTokenNode));
+ if (node is Accessor)
+ node = node.Parent;
+ var contextList = new CompletionDataWrapper (this);
+ if (node is PropertyDeclaration) {
+ contextList.AddCustom ("get");
+ contextList.AddCustom ("set");
+ AddKeywords (contextList, accessorModifierKeywords);
+ } else if (node is CustomEventDeclaration) {
+ contextList.AddCustom ("add");
+ contextList.AddCustom ("remove");
+ } else {
+ return null;
+ }
+
+ return contextList.Result;
+ }
+
+ IEnumerable<ICompletionData> DefaultControlSpaceItems ()
+ {
+ var wrapper = new CompletionDataWrapper (this);
+ while (offset > 0 && char.IsWhiteSpace (document.GetCharAt (offset))) {
+ offset--;
+ }
+ location = document.GetLocation (offset);
+ var xp = GetExpressionAtCursor ();
+
+ AstNode node;
+ Tuple<ResolveResult, CSharpResolver> rr;
+ if (xp != null) {
+ node = xp.Item2;
+ rr = ResolveExpression (xp.Item1, node, xp.Item3);
+ } else {
+ node = Unit.GetNodeAt (location);
+ rr = ResolveExpression (CSharpParsedFile, node, Unit);
+ }
+
+ AddContextCompletion (wrapper, rr != null && (node is Expression) ? rr.Item2 : GetState (), node);
+
+ return wrapper.Result;
+ }
+
+ void AddContextCompletion (CompletionDataWrapper wrapper, CSharpResolver state, AstNode node)
+ {
+ if (state == null)
+ return;
+ foreach (var variable in state.LocalVariables) {
+ wrapper.AddVariable (variable);
+ }
+ if (state.CurrentMember is IParameterizedMember) {
+ var param = (IParameterizedMember)state.CurrentMember;
+ foreach (var p in param.Parameters) {
+ wrapper.AddVariable (p);
+ }
+ }
+
+ if (state.CurrentMember is IMethod) {
+ var method = (IMethod)state.CurrentMember;
+ foreach (var p in method.TypeParameters) {
+ wrapper.AddTypeParameter (p);
+ }
+ }
+ Predicate<ITypeDefinition> typePred = null;
+ if (node is Attribute) {
+ var attribute = ctx.GetTypeDefinition ("System", "Attribute", 0, StringComparer.Ordinal);
+ typePred = t => t.GetAllBaseTypeDefinitions (ctx).Any (bt => bt.Equals (attribute));
+ }
+ AddTypesAndNamespaces (wrapper, state, node, typePred);
+
+ wrapper.Result.Add (factory.CreateLiteralCompletionData ("global"));
+ if (state.CurrentMember != null) {
+ AddKeywords (wrapper, statementStartKeywords);
+ AddKeywords (wrapper, expressionLevelKeywords);
+ } else if (state.CurrentTypeDefinition != null) {
+ AddKeywords (wrapper, typeLevelKeywords);
+ } else {
+ AddKeywords (wrapper, globalLevelKeywords);
+ }
+
+ if (IsInSwitchContext(node)) {
+ wrapper.AddCustom ("case");
+ wrapper.AddCustom ("default");
+ }
+
+ AddKeywords (wrapper, primitiveTypesKeywords);
+ wrapper.Result.AddRange (factory.CreateCodeTemplateCompletionData ());
+ }
+
+ static bool IsInSwitchContext(AstNode node)
+ {
+ var n = node;
+ while (n != null && !(n is MemberDeclaration)) {
+ if (n is SwitchStatement)
+ return true;
+ if (n is BlockStatement)
+ return false;
+ n = n.Parent;
+ }
+ return false;
+ }
+
+ void AddTypesAndNamespaces (CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Predicate<ITypeDefinition> typePred = null, Predicate<IMember> memberPred = null)
+ {
+ var currentType = state.CurrentTypeDefinition ?? this.currentType;
+ var currentMember = state.CurrentMember ?? this.currentMember;
+ if (currentType != null) {
+ for (var ct = currentType; ct != null; ct = ct.DeclaringTypeDefinition) {
+ foreach (var nestedType in ct.NestedTypes) {
+ if (typePred == null || typePred (nestedType)) {
+ string name = nestedType.Name;
+ if (node is Attribute && name.EndsWith ("Attribute") && name.Length > "Attribute".Length)
+ name = name.Substring (0, name.Length - "Attribute".Length);
+ wrapper.AddType (nestedType, name);
+ }
+ }
+ }
+ if (currentMember != null) {
+ foreach (var member in currentType.Resolve (ctx).GetMembers (ctx)) {
+ if (memberPred == null || memberPred (member))
+ wrapper.AddMember (member);
+ }
+ }
+ foreach (var p in currentType.TypeParameters) {
+ wrapper.AddTypeParameter (p);
+ }
+ }
+
+ for (var n = state.CurrentUsingScope; n != null; n = n.Parent) {
+ foreach (var pair in n.UsingAliases) {
+ wrapper.AddNamespace ("", pair.Key);
+ }
+
+ foreach (var u in n.Usings) {
+ var ns = u.ResolveNamespace (ctx);
+ if (ns == null)
+ continue;
+ foreach (var type in ctx.GetTypes (ns.NamespaceName, StringComparer.Ordinal)) {
+ if (typePred == null || typePred (type)) {
+ string name = type.Name;
+ if (node is Attribute && name.EndsWith ("Attribute") && name.Length > "Attribute".Length)
+ name = name.Substring (0, name.Length - "Attribute".Length);
+ wrapper.AddType (type, name);
+ }
+ }
+ }
+
+ foreach (var type in ctx.GetTypes (n.NamespaceName, StringComparer.Ordinal)) {
+ if (typePred == null || typePred (type)) {
+ wrapper.AddType (type, type.Name);
+ }
+ }
+
+ foreach (var curNs in ctx.GetNamespaces ().Where (sn => sn.StartsWith (n.NamespaceName) && sn != n.NamespaceName)) {
+ wrapper.AddNamespace (n.NamespaceName, curNs);
+ }
+ }
+ }
+
+ IEnumerable<ICompletionData> HandleKeywordCompletion (int wordStart, string word)
+ {
+ if (IsInsideCommentOrString ())
+ return null;
+ switch (word) {
+ case "using":
+ case "namespace":
+ if (currentType != null)
+ return null;
+ var wrapper = new CompletionDataWrapper (this);
+ AddTypesAndNamespaces (wrapper, GetState (), null, t => false);
+ return wrapper.Result;
+ case "case":
+ return CreateCaseCompletionData (location);
+// case ",":
+// case ":":
+// if (result.ExpressionContext == ExpressionContext.InheritableType) {
+// IType cls = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
+// CompletionDataList completionList = new ProjectDomCompletionDataList ();
+// List<string > namespaceList = GetUsedNamespaces ();
+// var col = new CSharpTextEditorCompletion.CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, null, location);
+// bool isInterface = false;
+// HashSet<string > baseTypeNames = new HashSet<string> ();
+// if (cls != null) {
+// baseTypeNames.Add (cls.Name);
+// if (cls.ClassType == ClassType.Struct)
+// isInterface = true;
+// }
+// int tokenIndex = offset;
+//
+// // Search base types " : [Type1, ... ,TypeN,] <Caret>"
+// string token = null;
+// do {
+// token = GetPreviousToken (ref tokenIndex, false);
+// if (string.IsNullOrEmpty (token))
+// break;
+// token = token.Trim ();
+// if (Char.IsLetterOrDigit (token [0]) || token [0] == '_') {
+// IType baseType = dom.SearchType (Document.CompilationUnit, cls, result.Region.Start, token);
+// if (baseType != null) {
+// if (baseType.ClassType != ClassType.Interface)
+// isInterface = true;
+// baseTypeNames.Add (baseType.Name);
+// }
+// }
+// } while (token != ":");
+// foreach (object o in dom.GetNamespaceContents (namespaceList, true, true)) {
+// IType type = o as IType;
+// if (type != null && (type.IsStatic || type.IsSealed || baseTypeNames.Contains (type.Name) || isInterface && type.ClassType != ClassType.Interface)) {
+// continue;
+// }
+// if (o is Namespace && !namespaceList.Any (ns => ns.StartsWith (((Namespace)o).FullName)))
+// continue;
+// col.Add (o);
+// }
+// // Add inner classes
+// Stack<IType > innerStack = new Stack<IType> ();
+// innerStack.Push (cls);
+// while (innerStack.Count > 0) {
+// IType curType = innerStack.Pop ();
+// if (curType == null)
+// continue;
+// foreach (IType innerType in curType.InnerTypes) {
+// if (innerType != cls)
+// // don't add the calling class as possible base type
+// col.Add (innerType);
+// }
+// if (curType.DeclaringType != null)
+// innerStack.Push (curType.DeclaringType);
+// }
+// return completionList;
+// }
+// break;
+ case "is":
+ case "as":
+ if (currentType == null)
+ return null;
+ IType isAsType = null;
+ var isAsExpression = GetExpressionAt (wordStart);
+ if (isAsExpression != null) {
+ var parent = isAsExpression.Item2.Parent;
+ if (parent is VariableInitializer)
+ parent = parent.Parent;
+ if (parent is VariableDeclarationStatement) {
+ var resolved = ResolveExpression (isAsExpression.Item1, parent, isAsExpression.Item3);
+ if (resolved != null)
+ isAsType = resolved.Item1.Type;
+ }
+ }
+
+ var isAsWrapper = new CompletionDataWrapper (this);
+ AddTypesAndNamespaces (isAsWrapper, GetState (), null, t => isAsType == null || t.IsDerivedFrom (isAsType.GetDefinition (), ctx));
+ return isAsWrapper.Result;
+// {
+// CompletionDataList completionList = new ProjectDomCompletionDataList ();
+// ExpressionResult expressionResult = FindExpression (dom, completionContext, wordStart - document.Caret.Offset);
+// NRefactoryResolver resolver = CreateResolver ();
+// ResolveResult resolveResult = resolver.Resolve (expressionResult, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
+// if (resolveResult != null && resolveResult.ResolvedType != null) {
+// CompletionDataCollector col = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
+// IType foundType = null;
+// if (word == "as") {
+// ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForAsCompletion (document, Document.CompilationUnit, Document.FileName, resolver.CallingType);
+// if (exactContext is ExpressionContext.TypeExpressionContext) {
+// foundType = resolver.SearchType (((ExpressionContext.TypeExpressionContext)exactContext).Type);
+// AddAsCompletionData (col, foundType);
+// }
+// }
+//
+// if (foundType == null)
+// foundType = resolver.SearchType (resolveResult.ResolvedType);
+//
+// if (foundType != null) {
+// if (foundType.ClassType == ClassType.Interface)
+// foundType = resolver.SearchType (DomReturnType.Object);
+//
+// foreach (IType type in dom.GetSubclasses (foundType)) {
+// if (type.IsSpecialName || type.Name.StartsWith ("<"))
+// continue;
+// AddAsCompletionData (col, type);
+// }
+// }
+// List<string > namespaceList = GetUsedNamespaces ();
+// foreach (object o in dom.GetNamespaceContents (namespaceList, true, true)) {
+// if (o is IType) {
+// IType type = (IType)o;
+// if (type.ClassType != ClassType.Interface || type.IsSpecialName || type.Name.StartsWith ("<"))
+// continue;
+// // if (foundType != null && !dom.GetInheritanceTree (foundType).Any (x => x.FullName == type.FullName))
+// // continue;
+// AddAsCompletionData (col, type);
+// continue;
+// }
+// if (o is Namespace)
+// continue;
+// col.Add (o);
+// }
+// return completionList;
+// }
+// result.ExpressionContext = ExpressionContext.TypeName;
+// return CreateCtrlSpaceCompletionData (completionContext, result);
+// }
+ case "override":
+ // Look for modifiers, in order to find the beginning of the declaration
+ int firstMod = wordStart;
+ int i = wordStart;
+ for (int n = 0; n < 3; n++) {
+ string mod = GetPreviousToken (ref i, true);
+ if (mod == "public" || mod == "protected" || mod == "private" || mod == "internal" || mod == "sealed") {
+ firstMod = i;
+ } else if (mod == "static") {
+ // static methods are not overridable
+ return null;
+ } else
+ break;
+ }
+ if (!IsLineEmptyUpToEol ())
+ return null;
+ var overrideCls = CSharpParsedFile.GetInnermostTypeDefinition (location);
+ if (overrideCls != null && (overrideCls.Kind == TypeKind.Class || overrideCls.Kind == TypeKind.Struct)) {
+ string modifiers = document.GetText (firstMod, wordStart - firstMod);
+ return GetOverrideCompletionData (overrideCls, modifiers);
+ }
+ return null;
+ case "partial":
+ // Look for modifiers, in order to find the beginning of the declaration
+ firstMod = wordStart;
+ i = wordStart;
+ for (int n = 0; n < 3; n++) {
+ string mod = GetPreviousToken (ref i, true);
+ if (mod == "public" || mod == "protected" || mod == "private" || mod == "internal" || mod == "sealed") {
+ firstMod = i;
+ } else if (mod == "static") {
+ // static methods are not overridable
+ return null;
+ } else
+ break;
+ }
+ if (!IsLineEmptyUpToEol ())
+ return null;
+
+ overrideCls = CSharpParsedFile.GetInnermostTypeDefinition (location);
+ if (overrideCls != null && (overrideCls.Kind == TypeKind.Class || overrideCls.Kind == TypeKind.Struct)) {
+ string modifiers = document.GetText (firstMod, wordStart - firstMod);
+ return GetPartialCompletionData (overrideCls, modifiers);
+ }
+ return null;
+
+ case "public":
+ case "protected":
+ case "private":
+ case "internal":
+ case "sealed":
+ case "static":
+ wrapper = new CompletionDataWrapper (this);
+ var state = GetState ();
+ AddTypesAndNamespaces (wrapper, state, null, null, m => false);
+ AddKeywords (wrapper, typeLevelKeywords);
+ AddKeywords (wrapper, primitiveTypesKeywords);
+ return wrapper.Result;
+ case "new":
+ int j = offset - 4;
+// string token = GetPreviousToken (ref j, true);
+
+ IType hintType = null;
+ var expressionOrVariableDeclaration = GetNewExpressionAt (j);
+ AstNode newParentNode = null;
+ AstType hintTypeAst = null;
+ if (expressionOrVariableDeclaration != null) {
+ newParentNode = expressionOrVariableDeclaration.Item2.Parent;
+ if (newParentNode is VariableInitializer)
+ newParentNode = newParentNode.Parent;
+ }
+
+ if (newParentNode is VariableDeclarationStatement) {
+ var varDecl = (VariableDeclarationStatement)newParentNode;
+ hintTypeAst = varDecl.Type;
+ var resolved = ResolveExpression (expressionOrVariableDeclaration.Item1, varDecl.Type, expressionOrVariableDeclaration.Item3);
+ if (resolved != null) {
+ hintType = resolved.Item1.Type;
+ }
+ }
+
+ if (newParentNode is FieldDeclaration) {
+ var varDecl = (FieldDeclaration)newParentNode;
+ hintTypeAst = varDecl.ReturnType;
+ var resolved = ResolveExpression (expressionOrVariableDeclaration.Item1, varDecl.ReturnType, expressionOrVariableDeclaration.Item3);
+ if (resolved != null)
+ hintType = resolved.Item1.Type;
+ }
+ return CreateTypeCompletionData (hintType, hintTypeAst);
+// IType callingType = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new TextLocation (document.Caret.Line, document.Caret.Column));
+// ExpressionContext newExactContext = new NewCSharpExpressionFinder (dom).FindExactContextForNewCompletion (document, Document.CompilationUnit, Document.FileName, callingType);
+// if (newExactContext is ExpressionContext.TypeExpressionContext)
+// return CreateTypeCompletionData (location, callingType, newExactContext, ((ExpressionContext.TypeExpressionContext)newExactContext).Type, ((ExpressionContext.TypeExpressionContext)newExactContext).UnresolvedType);
+// if (newExactContext == null) {
+// int j = offset - 4;
+//
+// string yieldToken = GetPreviousToken (ref j, true);
+// if (token == "return") {
+// NRefactoryResolver resolver = CreateResolver ();
+// resolver.SetupResolver (new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
+// IReturnType returnType = resolver.CallingMember.ReturnType;
+// if (yieldToken == "yield" && returnType.GenericArguments.Count > 0)
+// returnType = returnType.GenericArguments [0];
+// if (resolver.CallingMember != null)
+// return CreateTypeCompletionData (location, callingType, newExactContext, null, returnType);
+// }
+// }
+// return CreateCtrlSpaceCompletionData (completionContext, null);
+// case "if":
+// case "elif":
+// if (stateTracker.Engine.IsInsidePreprocessorDirective)
+// return GetDefineCompletionData ();
+// return null;
+ case "yield":
+ var yieldDataList = new CompletionDataWrapper (this);
+ DefaultCompletionString = "return";
+ yieldDataList.AddCustom ("break");
+ yieldDataList.AddCustom ("return");
+ return yieldDataList.Result;
+ case "in":
+ var inList = new CompletionDataWrapper (this);
+ var node = Unit.GetNodeAt (location);
+ var rr = ResolveExpression (CSharpParsedFile, node, Unit);
+ AddContextCompletion (inList, rr != null ? rr.Item2 : GetState (), node);
+ return inList.Result;
+// case "where":
+// CompletionDataList whereDataList = new CompletionDataList ();
+// NRefactoryResolver constraintResolver = CreateResolver ();
+// constraintResolver.SetupResolver (new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
+// if (constraintResolver.CallingMember is IMethod) {
+// foreach (ITypeParameter tp in ((IMethod)constraintResolver.CallingMember).TypeParameters) {
+// whereDataList.Add (tp.Name, "md-keyword");
+// }
+// } else {
+// if (constraintResolver.CallingType != null) {
+// foreach (ITypeParameter tp in constraintResolver.CallingType.TypeParameters) {
+// whereDataList.Add (tp.Name, "md-keyword");
+// }
+// }
+// }
+//
+// return whereDataList;
+ }
+// if (IsInLinqContext (result)) {
+// if (linqKeywords.Contains (word)) {
+// if (word == "from") // after from no auto code completion.
+// return null;
+// result.Expression = "";
+// return CreateCtrlSpaceCompletionData (completionContext, result);
+// }
+// CompletionDataList dataList = new ProjectDomCompletionDataList ();
+// CompletionDataCollector col = new CompletionDataCollector (this, dom, dataList, Document.CompilationUnit, null, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
+// foreach (string kw in linqKeywords) {
+// col.Add (kw, "md-keyword");
+// }
+// return dataList;
+// }
+ return null;
+ }
+
+ bool IsLineEmptyUpToEol ()
+ {
+ var line = document.GetLineByNumber (location.Line);
+ for (int j = offset; j < line.EndOffset; j++) {
+ char ch = document.GetCharAt (j);
+ if (!char.IsWhiteSpace (ch))
+ return false;
+ }
+ return true;
+ }
+ string GetLineIndent (int lineNr)
+ {
+ var line = document.GetLineByNumber (lineNr);
+ for (int j = offset; j < line.EndOffset; j++) {
+ char ch = document.GetCharAt (j);
+ if (!char.IsWhiteSpace (ch))
+ return document.GetText (line.Offset, j - line.Offset - 1);
+ }
+ return "";
+ }
+
+ IEnumerable<ICompletionData> CreateTypeCompletionData (IType hintType, AstType hintTypeAst)
+ {
+ var wrapper = new CompletionDataWrapper (this);
+ var state = GetState ();
+ Predicate<ITypeDefinition> pred = null;
+ if (hintType != null) {
+ if (!hintType.Equals (SharedTypes.UnknownType)) {
+ var lookup = new MemberLookup (ctx, currentType, ProjectContent);
+ pred = t => {
+ // check if type is in inheritance tree.
+ if (hintType.GetDefinition () != null && !t.IsDerivedFrom (hintType.GetDefinition (), ctx))
+ return false;
+ // check for valid constructors
+ if (t.Methods.Count (m => m.IsConstructor) == 0)
+ return true;
+ bool isProtectedAllowed = currentType != null ? currentType.IsDerivedFrom (t, ctx) : false;
+ return t.Methods.Any (m => m.IsConstructor && lookup.IsAccessible (m, isProtectedAllowed));
+ };
+ DefaultCompletionString = GetShortType (hintType, GetState ());
+ wrapper.AddType (hintType, DefaultCompletionString);
+ } else {
+ DefaultCompletionString = hintTypeAst.ToString ();
+ wrapper.AddType (hintType, DefaultCompletionString);
+ }
+ }
+ AddTypesAndNamespaces (wrapper, state, null, pred, m => false);
+ AddKeywords (wrapper, primitiveTypesKeywords.Where (k => k != "void"));
+ AutoCompleteEmptyMatch = true;
+ return wrapper.Result;
+ }
+
+ IEnumerable<ICompletionData> GetOverrideCompletionData (ITypeDefinition type, string modifiers)
+ {
+ var wrapper = new CompletionDataWrapper (this);
+ var alreadyInserted = new Dictionary<string, bool> ();
+ bool addedVirtuals = false;
+
+ int declarationBegin = offset;
+ int j = declarationBegin;
+ for (int i = 0; i < 3; i++) {
+ switch (GetPreviousToken (ref j, true)) {
+ case "public":
+ case "protected":
+ case "private":
+ case "internal":
+ case "sealed":
+ case "override":
+ declarationBegin = j;
+ break;
+ case "static":
+ return null; // don't add override completion for static members
+ }
+ }
+ foreach (var baseType in type.GetAllBaseTypeDefinitions (ctx)) {
+ AddVirtuals (alreadyInserted, wrapper, type, modifiers, baseType, declarationBegin);
+ addedVirtuals = true;
+ }
+ if (!addedVirtuals)
+ AddVirtuals (alreadyInserted, wrapper, type, modifiers, ctx.GetTypeDefinition (typeof(object)), declarationBegin);
+ return wrapper.Result;
+ }
+
+ IEnumerable<ICompletionData> GetPartialCompletionData (ITypeDefinition type, string modifiers)
+ {
+ var wrapper = new CompletionDataWrapper (this);
+ var partialType = GetTypeFromContext (type);
+ if (partialType != null) {
+ int declarationBegin = offset;
+ int j = declarationBegin;
+ for (int i = 0; i < 3; i++) {
+ switch (GetPreviousToken (ref j, true)) {
+ case "public":
+ case "protected":
+ case "private":
+ case "internal":
+ case "sealed":
+ case "override":
+ declarationBegin = j;
+ break;
+ case "static":
+ return null; // don't add override completion for static members
+ }
+ }
+
+ var methods = new List<IMethod> ();
+ // gather all partial methods without implementation
+ foreach (var part in partialType.GetParts ())
+ foreach (var method in part.Methods) {
+ if (method.IsPartial && method.BodyRegion.IsEmpty) {
+ methods.Add (method);
+ }
+ }
+
+ // now filter all methods that are implemented in the compound class
+ foreach (var part in partialType.GetParts ()) {
+ if (part == type)
+ continue;
+ for (int i = 0; i < methods.Count; i++) {
+ var curMethod = methods[i];
+ var method = GetImplementation (partialType, curMethod);
+ if (method != null && !method.BodyRegion.IsEmpty) {
+ methods.RemoveAt (i);
+ i--;
+ continue;
+ }
+ }
+ }
+
+ foreach (var method in methods) {
+ wrapper.Add (factory.CreateNewOverrideCompletionData (declarationBegin, type, method));
+ }
+
+ }
+ return wrapper.Result;
+ }
+
+ IMethod GetImplementation (ITypeDefinition type, IMethod method)
+ {
+ foreach (var cur in type.Methods) {
+ if (cur.Name == method.Name && cur.Parameters.Count == method.Parameters.Count && !cur.BodyRegion.IsEmpty) {
+ bool equal = true;
+ for (int i = 0; i < cur.Parameters.Count; i++) {
+ if (!cur.Parameters[i].Type.Resolve (ctx).Equals (method.Parameters[i].Type.Resolve (ctx))) {
+ equal = false;
+ break;
+ }
+ }
+ if (equal)
+ return cur;
+ }
+ }
+ return null;
+ }
+
+
+ static string GetNameWithParamCount (IMember member)
+ {
+ var e = member as IMethod;
+ if (e == null || e.TypeParameters.Count == 0)
+ return member.Name;
+ return e.Name + "`" + e.TypeParameters.Count;
+ }
+
+ void AddVirtuals (Dictionary<string, bool> alreadyInserted, CompletionDataWrapper col, ITypeDefinition type, string modifiers, ITypeDefinition curType, int declarationBegin)
+ {
+ if (curType == null)
+ return;
+ foreach (var m in curType.Methods.Where (m => !m.IsConstructor && !m.IsDestructor).Cast<IMember> ().Concat (curType.Properties.Cast<IMember> ())) {
+ if (m.IsSynthetic || curType.Kind != TypeKind.Interface && !(m.IsVirtual || m.IsOverride || m.IsAbstract))
+ continue;
+ // filter out the "Finalize" methods, because finalizers should be done with destructors.
+ if (m is IMethod && m.Name == "Finalize")
+ continue;
+
+ var data = factory.CreateNewOverrideCompletionData (declarationBegin, type, m);
+ string text = GetNameWithParamCount (m);
+
+ // check if the member is already implemented
+ bool foundMember = type.Members.Any (cm => GetNameWithParamCount (cm) == text);
+ if (!foundMember && !alreadyInserted.ContainsKey (text)) {
+ alreadyInserted [text] = true;
+ data.CompletionCategory = col.GetCompletionCategory (curType);
+ col.Add (data);
+ }
+ }
+ }
+
+ static void AddKeywords (CompletionDataWrapper wrapper, IEnumerable<string> keywords)
+ {
+ foreach (string keyword in keywords) {
+ wrapper.AddCustom (keyword);
+ }
+ }
+
+ public string GetPreviousMemberReferenceExpression (int tokenIndex)
+ {
+ string result = GetPreviousToken (ref tokenIndex, false);
+ result = GetPreviousToken (ref tokenIndex, false);
+ if (result != ".") {
+ result = null;
+ } else {
+ var names = new List<string> ();
+ while (result == ".") {
+ result = GetPreviousToken (ref tokenIndex, false);
+ if (result == "this") {
+ names.Add ("handle");
+ } else if (result != null) {
+ string trimmedName = result.Trim ();
+ if (trimmedName.Length == 0)
+ break;
+ names.Insert (0, trimmedName);
+ }
+ result = GetPreviousToken (ref tokenIndex, false);
+ }
+ result = String.Join ("", names.ToArray ());
+ foreach (char ch in result) {
+ if (!char.IsLetterOrDigit (ch) && ch != '_') {
+ result = "";
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ bool MatchDelegate (IType delegateType, IMethod method)
+ {
+ var delegateMethod = delegateType.GetDelegateInvokeMethod ();
+ if (delegateMethod == null || delegateMethod.Parameters.Count != method.Parameters.Count)
+ return false;
+
+ for (int i = 0; i < delegateMethod.Parameters.Count; i++) {
+ if (!delegateMethod.Parameters [i].Type.Resolve (ctx).Equals (method.Parameters [i].Type.Resolve (ctx)))
+ return false;
+ }
+ return true;
+ }
+
+ string AddDelegateHandlers (CompletionDataWrapper completionList, IType delegateType, bool addSemicolon = true, bool addDefault = true)
+ {
+ IMethod delegateMethod = delegateType.GetDelegateInvokeMethod ();
+ var thisLineIndent = GetLineIndent (location.Line);
+ string delegateEndString = EolMarker + thisLineIndent + "}" + (addSemicolon ? ";" : "");
+ bool containsDelegateData = completionList.Result.Any (d => d.DisplayText.StartsWith ("delegate("));
+ if (addDefault)
+ completionList.AddCustom ("delegate", "Creates anonymous delegate.", "delegate {" + EolMarker + thisLineIndent + IndentString + "|" + delegateEndString);
+ var sb = new StringBuilder ("(");
+ var sbWithoutTypes = new StringBuilder ("(");
+ for (int k = 0; k < delegateMethod.Parameters.Count; k++) {
+ if (k > 0) {
+ sb.Append (", ");
+ sbWithoutTypes.Append (", ");
+ }
+ var parameterType = delegateMethod.Parameters [k].Type.Resolve (ctx);
+ sb.Append (GetShortType (parameterType, GetState ()));
+ sb.Append (" ");
+ sb.Append (delegateMethod.Parameters [k].Name);
+ sbWithoutTypes.Append (delegateMethod.Parameters [k].Name);
+ }
+ sb.Append (")");
+ sbWithoutTypes.Append (")");
+ completionList.AddCustom ("delegate" + sb, "Creates anonymous delegate.", "delegate" + sb + " {" + EolMarker + thisLineIndent + IndentString + "|" + delegateEndString);
+ if (!completionList.Result.Any (data => data.DisplayText == sbWithoutTypes.ToString ()))
+ completionList.AddCustom (sbWithoutTypes.ToString (), "Creates lambda expression.", sbWithoutTypes + " => |" + (addSemicolon ? ";" : ""));
+ /* TODO:Make factory method out of it.
+ // It's needed to temporarly disable inserting auto matching bracket because the anonymous delegates are selectable with '('
+ // otherwise we would end up with () => )
+ if (!containsDelegateData) {
+ var savedValue = MonoDevelop.SourceEditor.DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket;
+ MonoDevelop.SourceEditor.DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket = false;
+ completionList.Result.CompletionListClosed += delegate {
+ MonoDevelop.SourceEditor.DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket = savedValue;
+ };
+ }*/
+ return sb.ToString ();
+ }
+
+ bool IsAccessibleFrom (IEntity member, ITypeDefinition calledType, IMember currentMember, bool includeProtected)
+ {
+ if (currentMember == null)
+ return member.IsStatic || member.IsPublic;
+// if (currentMember is MonoDevelop.Projects.Dom.BaseResolveResult.BaseMemberDecorator)
+// return member.IsPublic | member.IsProtected;
+ // if (member.IsStatic && !IsStatic)
+ // return false;
+ if (member.IsPublic || calledType != null && calledType.Kind == TypeKind.Interface && !member.IsProtected)
+ return true;
+ if (member.DeclaringTypeDefinition != null) {
+ if (member.DeclaringTypeDefinition.Kind == TypeKind.Interface)
+ return IsAccessibleFrom (member.DeclaringTypeDefinition, calledType, currentMember, includeProtected);
+
+ if (member.IsProtected && !(member.DeclaringTypeDefinition.IsProtectedOrInternal && !includeProtected))
+ return includeProtected;
+ }
+ if (member.IsInternal || member.IsProtectedAndInternal || member.IsProtectedOrInternal) {
+ var type1 = member is ITypeDefinition ? (ITypeDefinition)member : member.DeclaringTypeDefinition;
+ var type2 = currentMember is ITypeDefinition ? (ITypeDefinition)currentMember : currentMember.DeclaringTypeDefinition;
+ bool result;
+ // easy case, projects are the same
+ if (type1.ProjectContent == type2.ProjectContent) {
+ result = true;
+ } else if (type1.ProjectContent != null) {
+ // maybe type2 hasn't project dom set (may occur in some cases), check if the file is in the project
+ //TODO !!
+// result = type1.ProjectContent.Annotation<MonoDevelop.Projects.Project> ().GetProjectFile (type2.Region.FileName) != null;
+ result = false;
+ } else if (type2.ProjectContent != null) {
+ //TODO!!
+// result = type2.ProjectContent.Annotation<MonoDevelop.Projects.Project> ().GetProjectFile (type1.Region.FileName) != null;
+ result = false;
+ } else {
+ // should never happen !
+ result = true;
+ }
+ return member.IsProtectedAndInternal ? includeProtected && result : result;
+ }
+
+ if (!(currentMember is IType) && (currentMember.DeclaringTypeDefinition == null || member.DeclaringTypeDefinition == null))
+ return false;
+
+ // inner class
+ var declaringType = currentMember.DeclaringTypeDefinition;
+ while (declaringType != null) {
+ if (declaringType.ReflectionName == currentMember.DeclaringType.ReflectionName)
+ return true;
+ declaringType = declaringType.DeclaringTypeDefinition;
+ }
+
+
+ return currentMember.DeclaringTypeDefinition != null && member.DeclaringTypeDefinition.FullName == currentMember.DeclaringTypeDefinition.FullName;
+ }
+
+ IEnumerable<ICompletionData> CreateTypeAndNamespaceCompletionData (TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state)
+ {
+ if (resolveResult == null || resolveResult.IsError)
+ return null;
+ var result = new CompletionDataWrapper (this);
+
+ if (resolveResult is NamespaceResolveResult) {
+ var nr = (NamespaceResolveResult)resolveResult;
+ foreach (var cl in ctx.GetTypes (nr.NamespaceName, StringComparer.Ordinal)) {
+ result.AddType (cl, cl.Name);
+ }
+ foreach (var ns in ctx.GetNamespaces ().Where (n => n.Length > nr.NamespaceName.Length && n.StartsWith (nr.NamespaceName))) {
+ result.AddNamespace (nr.NamespaceName, ns);
+ }
+ } else if (resolveResult is TypeResolveResult) {
+ var type = resolveResult.Type.Resolve (ctx);
+ foreach (var nested in type.GetNestedTypes (ctx)) {
+ result.AddType (nested, nested.Name);
+ }
+ }
+ return result.Result;
+ }
+
+ IEnumerable<ICompletionData> CreateTypeList ()
+ {
+ foreach (var cl in ctx.GetTypes ("", StringComparer.Ordinal)) {
+ yield return factory.CreateTypeCompletionData (cl, cl.Name);
+ }
+ foreach (var ns in ctx.GetNamespaces ()) {
+ string name = ns;
+ int idx = name.IndexOf (".");
+ if (idx >= 0)
+ name = name.Substring (0, idx);
+ yield return factory.CreateNamespaceCompletionData (name);
+ }
+ }
+
+ public ITypeDefinition GetTypeFromContext (ITypeDefinition type)
+ {
+ if (type == null || type.DeclaringType != null)
+ return type;
+ var result = ctx.GetTypeDefinition (type.Namespace, type.Name, type.TypeParameterCount, StringComparer.Ordinal) ?? type;
+ if (result.GetParts ().Count == 1)
+ return type;
+// Console.WriteLine ("result:"+ result);
+ return result;
+ }
+
+ IEnumerable<ICompletionData> CreateParameterCompletion (MethodGroupResolveResult resolveResult, CSharpResolver state, AstNode invocation, int parameter, bool controlSpace)
+ {
+ var result = new CompletionDataWrapper (this);
+ var addedEnums = new HashSet<string> ();
+ var addedDelegates = new HashSet<string> ();
+
+ foreach (var method in resolveResult.Methods) {
+ if (method.Parameters.Count <= parameter)
+ continue;
+ var resolvedType = method.Parameters [parameter].Type.Resolve (ctx);
+ if (resolvedType.Kind == TypeKind.Enum) {
+ if (addedEnums.Contains (resolvedType.ReflectionName))
+ continue;
+ addedEnums.Add (resolvedType.ReflectionName);
+ AddEnumMembers (result, resolvedType, state);
+ } else if (resolvedType.Kind == TypeKind.Delegate) {
+// if (addedDelegates.Contains (resolvedType.DecoratedFullName))
+// continue;
+// addedDelegates.Add (resolvedType.DecoratedFullName);
+// string parameterDefinition = AddDelegateHandlers (completionList, resolvedType, false, addedDelegates.Count == 1);
+// string varName = "Handle" + method.Parameters [parameter].ReturnType.Name + method.Parameters [parameter].Name;
+// result.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.Unit.GetMemberAt (location), resolvedType) { AddSemicolon = false });
+
+ }
+ }
+ if (!controlSpace) {
+ if (addedEnums.Count + addedDelegates.Count == 0)
+ return Enumerable.Empty<ICompletionData> ();
+ AutoCompleteEmptyMatch = false;
+ AutoSelect = false;
+ }
+ AddContextCompletion (result, state, invocation);
+
+// resolver.AddAccessibleCodeCompletionData (ExpressionContext.MethodBody, cdc);
+// if (addedDelegates.Count > 0) {
+// foreach (var data in result.Result) {
+// if (data is MemberCompletionData)
+// ((MemberCompletionData)data).IsDelegateExpected = true;
+// }
+// }
+ return result.Result;
+ }
+
+ string GetShortType (IType type, CSharpResolver state)
+ {
+ var builder = new TypeSystemAstBuilder (state);
+ var shortType = builder.ConvertType (type);
+ using (var w = new System.IO.StringWriter ()) {
+ var visitor = new CSharpOutputVisitor (w, FormattingPolicy);
+ shortType.AcceptVisitor (visitor, null);
+ return w.ToString ();
+ }
+ }
+
+ void AddEnumMembers (CompletionDataWrapper completionList, IType resolvedType, CSharpResolver state)
+ {
+ if (resolvedType.Kind != TypeKind.Enum)
+ return;
+ string typeString = GetShortType (resolvedType, state);
+ if (typeString.Contains ("."))
+ completionList.AddType (resolvedType, typeString);
+ foreach (var field in resolvedType.GetFields (ctx)) {
+ if (field.IsConst || field.IsStatic)
+ completionList.Result.Add (factory.CreateEntityCompletionData (field, typeString + "." + field.Name));
+ }
+ DefaultCompletionString = typeString;
+ }
+
+ IEnumerable<ICompletionData> CreateCompletionData (TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state)
+ {
+ if (resolveResult == null /*|| resolveResult.IsError*/)
+ return null;
+ if (resolveResult is NamespaceResolveResult) {
+ var nr = (NamespaceResolveResult)resolveResult;
+ var namespaceContents = new CompletionDataWrapper (this);
+ foreach (var cl in ctx.GetTypes (nr.NamespaceName, StringComparer.Ordinal)) {
+ namespaceContents.AddType (cl, cl.Name);
+ }
+ foreach (var ns in ctx.GetNamespaces ().Where (n => n.Length > nr.NamespaceName.Length && n.StartsWith (nr.NamespaceName))) {
+ namespaceContents.AddNamespace (nr.NamespaceName, ns);
+ }
+
+ return namespaceContents.Result;
+ }
+
+ IType type = GetTypeFromContext (resolveResult.Type.GetDefinition ()) ?? resolveResult.Type;
+ var typeDef = resolveResult.Type.GetDefinition ();
+ var lookup = new MemberLookup (ctx, currentType, ProjectContent);
+ var result = new CompletionDataWrapper (this);
+ bool isProtectedAllowed = false;
+ bool includeStaticMembers = false;
+
+ if (resolveResult is LocalResolveResult) {
+ isProtectedAllowed = currentType != null && typeDef != null ? typeDef.GetAllBaseTypeDefinitions (ctx).Any (bt => bt.Equals (currentType)) : false;
+ if (resolvedNode is IdentifierExpression) {
+ var mrr = (LocalResolveResult)resolveResult;
+ includeStaticMembers = mrr.Variable.Name == mrr.Type.Name;
+ }
+ } else {
+ isProtectedAllowed = currentType != null && typeDef != null ? currentType.GetAllBaseTypeDefinitions (ctx).Any (bt => bt.Equals (typeDef)) : false;
+ }
+ if (resolveResult is TypeResolveResult && type.Kind == TypeKind.Enum) {
+ foreach (var field in type.GetFields (ctx)) {
+ result.AddMember (field);
+ }
+ foreach (var m in type.GetMethods (ctx)) {
+ if (m.Name == "TryParse")
+ result.AddMember (m);
+ }
+ return result.Result;
+ }
+
+ if (resolveResult is MemberResolveResult && resolvedNode is IdentifierExpression) {
+ var mrr = (MemberResolveResult)resolveResult;
+ includeStaticMembers = mrr.Member.Name == mrr.Type.Name;
+ }
+
+// Console.WriteLine ("type:" + type +"/"+type.GetType ());
+// Console.WriteLine ("IS PROT ALLOWED:" + isProtectedAllowed);
+// Console.WriteLine (resolveResult);
+// Console.WriteLine (currentMember != null ? currentMember.IsStatic : "currentMember == null");
+ if (resolvedNode.Annotation<ObjectCreateExpression> () == null) { //tags the created expression as part of an object create expression.
+ foreach (var member in type.GetMembers (ctx)) {
+ if (!lookup.IsAccessible (member, isProtectedAllowed)) {
+ // Console.WriteLine ("skip access: " + member.FullName);
+ continue;
+ }
+ if (resolvedNode is BaseReferenceExpression && member.IsAbstract)
+ continue;
+
+ if (!includeStaticMembers && member.IsStatic && !(resolveResult is TypeResolveResult)) {
+ // Console.WriteLine ("skip static member: " + member.FullName);
+ continue;
+ }
+ if (!member.IsStatic && (resolveResult is TypeResolveResult)) {
+ // Console.WriteLine ("skip non static member: " + member.FullName);
+ continue;
+ }
+ // Console.WriteLine ("add : "+ member.FullName + " --- " + member.IsStatic);
+ result.AddMember (member);
+ }
+ }
+
+ if (resolveResult is TypeResolveResult || includeStaticMembers) {
+ foreach (var nested in type.GetNestedTypes (ctx)) {
+ result.AddType (nested, nested.Name);
+ }
+
+ } else {
+ var baseTypes = new List<IType> (type.GetAllBaseTypes (ctx));
+ var conv = new Conversions (ctx);
+ for (var n = state.CurrentUsingScope; n != null; n = n.Parent) {
+ AddExtensionMethods (result, conv, baseTypes, n.NamespaceName);
+ foreach (var u in n.Usings) {
+ var ns = u.ResolveNamespace (ctx);
+ if (ns == null)
+ continue;
+ AddExtensionMethods (result, conv, baseTypes, ns.NamespaceName);
+ }
+ }
+ }
+
+// IEnumerable<object> objects = resolveResult.CreateResolveResult (dom, resolver != null ? resolver.CallingMember : null);
+// CompletionDataCollector col = new CompletionDataCollector (this, dom, result, Document.CompilationUnit, resolver != null ? resolver.CallingType : null, location);
+// col.HideExtensionParameter = !resolveResult.StaticResolve;
+// col.NamePrefix = expressionResult.Expression;
+// bool showOnlyTypes = expressionResult.Contexts.Any (ctx => ctx == ExpressionContext.InheritableType || ctx == ExpressionContext.Constraints);
+// if (objects != null) {
+// foreach (object obj in objects) {
+// if (expressionResult.ExpressionContext != null && expressionResult.ExpressionContext.FilterEntry (obj))
+// continue;
+// if (expressionResult.ExpressionContext == ExpressionContext.NamespaceNameExcepted && !(obj is Namespace))
+// continue;
+// if (showOnlyTypes && !(obj is IType))
+// continue;
+// CompletionData data = col.Add (obj);
+// if (data != null && expressionResult.ExpressionContext == ExpressionContext.Attribute && data.CompletionText != null && data.CompletionText.EndsWith ("Attribute")) {
+// string newText = data.CompletionText.Substring (0, data.CompletionText.Length - "Attribute".Length);
+// data.SetText (newText);
+// }
+// }
+// }
+
+ return result.Result;
+ }
+
+ void AddExtensionMethods (CompletionDataWrapper result, Conversions conv, List<IType> baseTypes, string namespaceName)
+ {
+ foreach (var typeDefinition in ctx.GetTypes (namespaceName, StringComparer.Ordinal).Where (t => t.IsStatic && t.HasExtensionMethods)) {
+ foreach (var m in typeDefinition.Methods.Where (m => m.IsExtensionMethod )) {
+ var pt = m.Parameters.First ().Type.Resolve (ctx);
+ string reflectionName = pt is ParameterizedType ? ((ParameterizedType)pt).GetDefinition ().ReflectionName : pt.ReflectionName;
+ if (baseTypes.Any (bt => (bt is ParameterizedType ? ((ParameterizedType)bt).GetDefinition ().ReflectionName : bt.ReflectionName) == reflectionName)) {
+ result.AddMember (m);
+ }
+ }
+ }
+ }
+ IEnumerable<ICompletionData> CreateCaseCompletionData (TextLocation location)
+ {
+ var unit = ParseStub ("a: break;");
+ if (unit == null)
+ return null;
+ var s = unit.GetNodeAt<SwitchStatement> (location);
+ if (s == null)
+ return null;
+
+ var offset = document.GetOffset (s.Expression.StartLocation);
+ var expr = GetExpressionAt (offset);
+ if (expr == null)
+ return null;
+
+ var resolveResult = ResolveExpression (expr.Item1, expr.Item2, expr.Item3);
+ if (resolveResult == null || resolveResult.Item1.Type.Kind != TypeKind.Enum)
+ return null;
+ var wrapper = new CompletionDataWrapper (this);
+ AddEnumMembers (wrapper, resolveResult.Item1.Type, resolveResult.Item2);
+ AutoCompleteEmptyMatch = false;
+ return wrapper.Result;
+ }
+
+ #region Parsing methods
+ Tuple<CSharpParsedFile, AstNode, CompilationUnit> GetExpressionBeforeCursor ()
+ {
+ CompilationUnit baseUnit;
+ if (currentMember == null) {
+ baseUnit = ParseStub ("st {}", false);
+ var type = baseUnit.GetNodeAt<MemberType> (location);
+ if (type == null) {
+ baseUnit = ParseStub ("a;", false);
+ type = baseUnit.GetNodeAt<MemberType> (location);
+ }
+ if (type != null) {
+ // insert target type into compilation unit, to respect the
+ var target = type.Target;
+ target.Remove ();
+ var node = Unit.GetNodeAt (location) ?? Unit;
+ node.AddChild (target, AstNode.Roles.Type);
+ return Tuple.Create (CSharpParsedFile, (AstNode)target, Unit);
+ }
+ }
+
+ if (currentMember == null && currentType == null) {
+ return null;
+ }
+ baseUnit = ParseStub ("a()");
+
+ // Hack for handle object initializer continuation expressions
+ if (baseUnit.GetNodeAt (location) is AttributedNode) {
+ baseUnit = ParseStub ("a()};");
+ }
+
+ var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
+ var mref = baseUnit.GetNodeAt<MemberReferenceExpression> (location);
+
+ if (mref == null){
+ var invoke = baseUnit.GetNodeAt<InvocationExpression> (location);
+ if (invoke != null)
+ mref = invoke.Target as MemberReferenceExpression;
+ }
+ Expression expr = null;
+ if (mref != null) {
+ expr = mref.Target.Clone ();
+ mref.Parent.ReplaceWith (expr);
+ } else {
+ Expression tref = baseUnit.GetNodeAt<TypeReferenceExpression> (location);
+ var memberType = tref != null ? ((TypeReferenceExpression)tref).Type as MemberType : null;
+ if (memberType == null) {
+ memberType = baseUnit.GetNodeAt<MemberType> (location);
+ if (memberType != null) {
+ tref = baseUnit.GetNodeAt<Expression> (location);
+ if (tref == null)
+ return null;
+ }
+ if (tref is ObjectCreateExpression) {
+ expr = new TypeReferenceExpression (memberType.Target.Clone ());
+ expr.AddAnnotation (new ObjectCreateExpression ());
+ }
+ }
+
+ if (memberType == null)
+ return null;
+ if (expr == null)
+ expr = new TypeReferenceExpression (memberType.Target.Clone ());
+ tref.ReplaceWith (expr);
+ }
+
+ var member = Unit.GetNodeAt<AttributedNode> (memberLocation);
+ var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation);
+ member2.Remove ();
+ member.ReplaceWith (member2);
+ var tsvisitor = new TypeSystemConvertVisitor (ProjectContent, this.CSharpParsedFile.FileName);
+ Unit.AcceptVisitor (tsvisitor, null);
+ return Tuple.Create (tsvisitor.ParsedFile, (AstNode)expr, Unit);
+ }
+
+ Tuple<CSharpParsedFile, AstNode, CompilationUnit> GetExpressionAtCursor ()
+ {
+// if (currentMember == null && currentType == null)
+// return null;
+
+ TextLocation memberLocation;
+ if (currentMember != null) {
+ memberLocation = currentMember.Region.Begin;
+ } else if (currentType != null) {
+ memberLocation = currentType.Region.Begin;
+ } else {
+ memberLocation = location;
+ }
+
+ var baseUnit = ParseStub ("");
+ var tmpUnit = baseUnit;
+ AstNode expr = baseUnit.GetNodeAt<IdentifierExpression> (location.Line, location.Column - 1);
+ if (expr == null)
+ expr = baseUnit.GetNodeAt<Attribute> (location.Line, location.Column - 1);
+
+ if (expr == null) {
+ baseUnit = ParseStub ("()");
+ expr = baseUnit.GetNodeAt<IdentifierExpression> (location.Line, location.Column - 1);
+ }
+
+ // try initializer expression
+ if (expr == null) {
+ baseUnit = ParseStub ("a = b};", false);
+ expr = baseUnit.GetNodeAt<ArrayInitializerExpression> (location.Line, location.Column - 1);
+ }
+
+ // try statement
+ if (expr == null) {
+ expr = tmpUnit.GetNodeAt<SwitchStatement> (location.Line, location.Column - 1);
+ baseUnit = tmpUnit;
+ }
+
+ if (expr == null) {
+ var forStmt = tmpUnit.GetNodeAt<ForStatement> (location.Line, location.Column - 3);
+ expr = forStmt;
+ if (forStmt != null && forStmt.EmbeddedStatement.IsNull) {
+ var id = new IdentifierExpression ("stub");
+ forStmt.EmbeddedStatement = new BlockStatement () { Statements = { new ExpressionStatement (id) }};
+ expr = id;
+ }
+ baseUnit = tmpUnit;
+ }
+
+ if (expr == null)
+ return null;
+ var member = Unit.GetNodeAt<AttributedNode> (memberLocation);
+ var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation);
+ if (member != null && member2 != null) {
+ member2.Remove ();
+
+ if (member is TypeDeclaration) {
+ member.AddChild (member2, TypeDeclaration.MemberRole);
+ } else {
+ member.ReplaceWith (member2);
+ }
+ } else {
+ var tsvisitor2 = new TypeSystemConvertVisitor (ProjectContent, CSharpParsedFile.FileName);
+ Unit.AcceptVisitor (tsvisitor2, null);
+ return Tuple.Create (tsvisitor2.ParsedFile, expr, baseUnit);
+ }
+ var tsvisitor = new TypeSystemConvertVisitor (ProjectContent, CSharpParsedFile.FileName);
+ Unit.AcceptVisitor (tsvisitor, null);
+ return Tuple.Create (tsvisitor.ParsedFile, expr, Unit);
+ }
+
+ Tuple<CSharpParsedFile, AstNode, CompilationUnit> GetExpressionAt (int offset)
+ {
+ var parser = new CSharpParser ();
+ string text = this.document.GetText (0, this.offset);
+ var sb = new StringBuilder (text);
+ sb.Append ("a;");
+ AppendMissingClosingBrackets (sb, text, false);
+ var stream = new System.IO.StringReader (sb.ToString ());
+ var completionUnit = parser.Parse (stream, 0);
+ stream.Close ();
+ var loc = document.GetLocation (offset);
+
+ var expr = completionUnit.GetNodeAt (loc, n => n is Expression || n is VariableDeclarationStatement);
+ if (expr == null)
+ return null;
+ var tsvisitor = new TypeSystemConvertVisitor (ProjectContent, CSharpParsedFile.FileName);
+ completionUnit.AcceptVisitor (tsvisitor, null);
+
+ return Tuple.Create (tsvisitor.ParsedFile, expr, completionUnit);
+ }
+
+
+ Tuple<CSharpParsedFile, AstNode, CompilationUnit> GetNewExpressionAt (int offset)
+ {
+ var parser = new CSharpParser ();
+ string text = this.document.GetText (0, this.offset);
+ var sb = new StringBuilder (text);
+ sb.Append ("a ();");
+ AppendMissingClosingBrackets (sb, text, false);
+ var stream = new System.IO.StringReader (sb.ToString ());
+ var completionUnit = parser.Parse (stream, 0);
+ stream.Close ();
+ var loc = document.GetLocation (offset);
+
+ var expr = completionUnit.GetNodeAt (loc, n => n is Expression);
+ if (expr == null)
+ return null;
+ var tsvisitor = new TypeSystemConvertVisitor (ProjectContent, CSharpParsedFile.FileName);
+ completionUnit.AcceptVisitor (tsvisitor, null);
+
+ return Tuple.Create (tsvisitor.ParsedFile, expr, completionUnit);
+ }
+
+
+ #endregion
+
+ #region Helper methods
+ string GetPreviousToken (ref int i, bool allowLineChange)
+ {
+ char c;
+ if (i <= 0)
+ return null;
+
+ do {
+ c = document.GetCharAt (--i);
+ } while (i > 0 && char.IsWhiteSpace (c) && (allowLineChange ? true : c != '\n'));
+
+ if (i == 0)
+ return null;
+
+ if (!char.IsLetterOrDigit (c))
+ return new string (c, 1);
+
+ int endOffset = i + 1;
+
+ do {
+ c = document.GetCharAt (i - 1);
+ if (!(char.IsLetterOrDigit (c) || c == '_'))
+ break;
+
+ i--;
+ } while (i > 0);
+
+ return document.GetText (i, endOffset - i);
+ }
+
+ bool GetParameterCompletionCommandOffset (out int cpos)
+ {
+ // Start calculating the parameter offset from the beginning of the
+ // current member, instead of the beginning of the file.
+ cpos = offset - 1;
+ IMember mem = currentMember;
+ if (mem == null || (mem is IType))
+ return false;
+ int startPos = document.GetOffset (mem.Region.BeginLine, mem.Region.BeginColumn);
+ int parenDepth = 0;
+ int chevronDepth = 0;
+ while (cpos > startPos) {
+ char c = document.GetCharAt (cpos);
+ if (c == ')')
+ parenDepth++;
+ if (c == '>')
+ chevronDepth++;
+ if (parenDepth == 0 && c == '(' || chevronDepth == 0 && c == '<') {
+ int p = GetCurrentParameterIndex (cpos + 1, startPos);
+ if (p != -1) {
+ cpos++;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ if (c == '(')
+ parenDepth--;
+ if (c == '<')
+ chevronDepth--;
+ cpos--;
+ }
+ return false;
+ }
+
+ int GetCurrentParameterIndex (int offset, int memberStart)
+ {
+ int cursor = this.offset;
+ int i = offset;
+
+ if (i > cursor)
+ return -1;
+ if (i == cursor)
+ return 1; // parameters are 1 based
+ int index = memberStart + 1;
+ int parentheses = 0;
+ int bracket = 0;
+ bool insideQuote = false, insideString = false, insideSingleLineComment = false, insideMultiLineComment = false;
+ do {
+ char c = document.GetCharAt (i - 1);
+ switch (c) {
+ case '\\':
+ if (insideString || insideQuote)
+ i++;
+ break;
+ case '\'':
+ if (!insideString && !insideSingleLineComment && !insideMultiLineComment)
+ insideQuote = !insideQuote;
+ break;
+ case '"':
+ if (!insideQuote && !insideSingleLineComment && !insideMultiLineComment)
+ insideString = !insideString;
+ break;
+ case '/':
+ if (!insideQuote && !insideString && !insideMultiLineComment) {
+ if (document.GetCharAt (i) == '/')
+ insideSingleLineComment = true;
+ if (document.GetCharAt (i) == '*')
+ insideMultiLineComment = true;
+ }
+ break;
+ case '*':
+ if (insideMultiLineComment && document.GetCharAt (i) == '/')
+ insideMultiLineComment = false;
+ break;
+ case '\n':
+ case '\r':
+ insideSingleLineComment = false;
+ break;
+ case '{':
+ if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment)
+ bracket++;
+ break;
+ case '}':
+ if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment)
+ bracket--;
+ break;
+ case '(':
+ if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment)
+ parentheses++;
+ break;
+ case ')':
+ if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment)
+ parentheses--;
+ break;
+ case ',':
+ if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment && parentheses == 1 && bracket == 0)
+ index++;
+ break;
+ }
+ i++;
+ } while (i <= cursor && parentheses >= 0);
+
+ return parentheses != 1 || bracket > 0 ? -1 : index;
+ }
+
+ CSharpResolver GetState ()
+ {
+ var state = new CSharpResolver (ctx, System.Threading.CancellationToken.None);
+
+ state.CurrentMember = CSharpParsedFile.GetMember (location);
+ state.CurrentTypeDefinition = CSharpParsedFile.GetInnermostTypeDefinition (location);
+ state.CurrentUsingScope = CSharpParsedFile.GetUsingScope (location);
+ if (state.CurrentMember != null) {
+ var node = Unit.GetNodeAt (location);
+ if (node == null)
+ return state;
+ var navigator = new NodeListResolveVisitorNavigator (new[] { node });
+ var visitor = new ResolveVisitor (state, CSharpParsedFile, navigator);
+ Unit.AcceptVisitor (visitor, null);
+ try {
+ var newState = visitor.GetResolverStateBefore (node);
+ if (newState != null)
+ state = newState;
+ } catch (Exception) {
+ }
+ }
+
+ return state;
+ }
+ #endregion
+
+ #region Preprocessor
+
+ IEnumerable<ICompletionData> GetDirectiveCompletionData ()
+ {
+ yield return factory.CreateLiteralCompletionData ("if");
+ yield return factory.CreateLiteralCompletionData ("else");
+ yield return factory.CreateLiteralCompletionData ("elif");
+ yield return factory.CreateLiteralCompletionData ("endif");
+ yield return factory.CreateLiteralCompletionData ("define");
+ yield return factory.CreateLiteralCompletionData ("undef");
+ yield return factory.CreateLiteralCompletionData ("warning");
+ yield return factory.CreateLiteralCompletionData ("error");
+ yield return factory.CreateLiteralCompletionData ("pragma");
+ yield return factory.CreateLiteralCompletionData ("line");
+ yield return factory.CreateLiteralCompletionData ("line hidden");
+ yield return factory.CreateLiteralCompletionData ("line default");
+ yield return factory.CreateLiteralCompletionData ("region");
+ yield return factory.CreateLiteralCompletionData ("endregion");
+ }
+ #endregion
+
+ #region Xml Comments
+ static readonly List<string> commentTags = new List<string> (new string[] { "c", "code", "example", "exception", "include", "list", "listheader", "item", "term", "description", "para", "param", "paramref", "permission", "remarks", "returns", "see", "seealso", "summary", "value" });
+
+ IEnumerable<ICompletionData> GetXmlDocumentationCompletionData ()
+ {
+ yield return factory.CreateLiteralCompletionData ("c", "Set text in a code-like font");
+ yield return factory.CreateLiteralCompletionData ("code", "Set one or more lines of source code or program output");
+ yield return factory.CreateLiteralCompletionData ("example", "Indicate an example");
+ yield return factory.CreateLiteralCompletionData ("exception", "Identifies the exceptions a method can throw", "exception cref=\"|\"></exception>");
+ yield return factory.CreateLiteralCompletionData ("include", "Includes comments from a external file", "include file=\"|\" path=\"\">");
+ yield return factory.CreateLiteralCompletionData ("list", "Create a list or table", "list type=\"|\">");
+ yield return factory.CreateLiteralCompletionData ("listheader", "Define the heading row");
+ yield return factory.CreateLiteralCompletionData ("item", "Defines list or table item");
+
+ yield return factory.CreateLiteralCompletionData ("term", "A term to define");
+ yield return factory.CreateLiteralCompletionData ("description", "Describes a list item");
+ yield return factory.CreateLiteralCompletionData ("para", "Permit structure to be added to text");
+
+ yield return factory.CreateLiteralCompletionData ("param", "Describe a parameter for a method or constructor", "param name=\"|\">");
+ yield return factory.CreateLiteralCompletionData ("paramref", "Identify that a word is a parameter name", "paramref name=\"|\"/>");
+
+ yield return factory.CreateLiteralCompletionData ("permission", "Document the security accessibility of a member", "permission cref=\"|\"");
+ yield return factory.CreateLiteralCompletionData ("remarks", "Describe a type");
+ yield return factory.CreateLiteralCompletionData ("returns", "Describe the return value of a method");
+ yield return factory.CreateLiteralCompletionData ("see", "Specify a link", "see cref=\"|\"/>");
+ yield return factory.CreateLiteralCompletionData ("seealso", "Generate a See Also entry", "seealso cref=\"|\"/>");
+ yield return factory.CreateLiteralCompletionData ("summary", "Describe a member of a type");
+ yield return factory.CreateLiteralCompletionData ("typeparam", "Describe a type parameter for a generic type or method");
+ yield return factory.CreateLiteralCompletionData ("typeparamref", "Identify that a word is a type parameter name");
+ yield return factory.CreateLiteralCompletionData ("value", "Describe a property");
+ }
+ #endregion
+
+ #region Keywords
+ static string[] expressionLevelKeywords = new string [] { "as", "is", "else", "out", "ref", "null", "delegate", "default"};
+
+ static string[] primitiveTypesKeywords = new string [] { "void", "object", "bool", "byte", "sbyte", "char", "short", "int", "long", "ushort", "uint", "ulong", "float", "double", "decimal", "string"};
+
+ static string[] statementStartKeywords = new string [] { "base", "new", "sizeof", "this",
+ "true", "false", "typeof", "checked", "unchecked", "from", "break", "checked",
+ "unchecked", "const", "continue", "do", "finally", "fixed", "for", "foreach",
+ "goto", "if", "lock", "return", "stackalloc", "switch", "throw", "try", "unsafe",
+ "using", "while", "yield", "dynamic", "var" };
+
+ static string[] globalLevelKeywords = new string [] {
+ "namespace", "using", "extern", "public", "internal",
+ "class", "interface", "struct", "enum", "delegate",
+ "abstract", "sealed", "static", "unsafe", "partial"
+ };
+
+ static string[] accessorModifierKeywords = new string [] {
+ "public", "internal", "protected", "private"
+ };
+
+ static string[] typeLevelKeywords = new string [] {
+ "public", "internal", "protected", "private",
+ "class", "interface", "struct", "enum", "delegate",
+ "abstract", "sealed", "static", "unsafe", "partial",
+ "const", "event", "extern", "fixed","new",
+ "operator", "explicit", "implicit",
+ "override", "readonly", "virtual", "volatile"
+ };
+ static string[] linqKeywords = new string[] { "from", "where", "select", "group", "into", "orderby", "join", "let", "in", "on", "equals", "by", "ascending", "descending" };
+ #endregion
+ }
+}
+
diff --git a/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs b/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs
index 2cb81e30bb..767826ba8a 100644
--- a/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs
+++ b/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs
@@ -1,445 +1,446 @@
-//
-// CSharpCompletionEngineBase.cs
-//
-// Author:
-// Mike Krüger <mkrueger@xamarin.com>
-//
-// Copyright (c) 2011 Xamarin Inc. (http://xamarin.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using ICSharpCode.NRefactory.CSharp.Resolver;
-using ICSharpCode.NRefactory.Editor;
-using ICSharpCode.NRefactory.TypeSystem;
-using ICSharpCode.NRefactory.Semantics;
-
-namespace ICSharpCode.NRefactory.CSharp.Completion
-{
- /// <summary>
- /// Acts as a common base between code completion and parameter completion.
- /// </summary>
- public class CSharpCompletionEngineBase
- {
- protected IDocument document;
- protected int offset;
- protected TextLocation location;
-
- protected ITypeDefinition currentType;
- protected IMember currentMember;
-
- #region Input properties
- public ITypeResolveContext ctx { get; set; }
- public CompilationUnit Unit { get; set; }
- public CSharpParsedFile CSharpParsedFile { get; set; }
- public IProjectContent ProjectContent { get; set; }
- #endregion
-
- protected void SetOffset (int offset)
- {
- Reset ();
-
- this.offset = offset;
- this.location = document.GetLocation (offset);
-
- this.currentType = CSharpParsedFile.GetInnermostTypeDefinition (location);
- this.currentMember = CSharpParsedFile.GetMember (location);
- }
-
- #region Context helper methods
- protected bool IsInsideCommentOrString ()
- {
- var text = GetMemberTextToCaret ();
- bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false;
-
- for (int i = 0; i < text.Item1.Length - 1; i++) {
- char ch = text.Item1[i];
- char nextCh = text.Item1[i + 1];
-
- switch (ch) {
- case '/':
- if (inString || inChar || inVerbatimString)
- break;
- if (nextCh == '/') {
- i++;
- inSingleComment = true;
- }
- if (nextCh == '*')
- inMultiLineComment = true;
- break;
- case '*':
- if (inString || inChar || inVerbatimString || inSingleComment)
- break;
- if (nextCh == '/') {
- i++;
- inMultiLineComment = false;
- }
- break;
- case '@':
- if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment)
- break;
- if (nextCh == '"') {
- i++;
- inVerbatimString = true;
- }
- break;
- case '\n':
- case '\r':
- inSingleComment = false;
- inString = false;
- inChar = false;
- break;
- case '\\':
- if (inString || inChar)
- i++;
- break;
- case '"':
- if (inSingleComment || inMultiLineComment || inChar)
- break;
- if (inVerbatimString) {
- if (nextCh == '"') {
- i++;
- break;
- }
- inVerbatimString = false;
- break;
- }
- inString = !inString;
- break;
- case '\'':
- if (inSingleComment || inMultiLineComment || inString || inVerbatimString)
- break;
- inChar = !inChar;
- break;
- }
- }
-
- return inSingleComment || inString || inVerbatimString || inChar || inMultiLineComment;
- }
-
- protected bool IsInsideComment (int offset)
- {
- var loc = document.GetLocation (offset);
- return Unit.GetNodeAt<ICSharpCode.NRefactory.CSharp.Comment> (loc.Line, loc.Column) != null;
- }
-
- protected bool IsInsideDocComment ()
- {
- var loc = document.GetLocation (offset);
- var cmt = Unit.GetNodeAt<ICSharpCode.NRefactory.CSharp.Comment> (loc.Line, loc.Column - 1);
- return cmt != null && cmt.CommentType == CommentType.Documentation;
- }
-
- protected bool IsInsideString (int offset)
- {
-
- var loc = document.GetLocation (offset);
- var expr = Unit.GetNodeAt<PrimitiveExpression> (loc.Line, loc.Column);
- return expr != null && expr.Value is string;
- }
- #endregion
-
- #region Basic parsing/resolving functions
- protected void AppendMissingClosingBrackets (StringBuilder wrapper, string memberText, bool appendSemicolon)
- {
- var bracketStack = new Stack<Tuple<char, int>> ();
-
- bool isInString = false, isInChar = false;
- bool isInLineComment = false, isInBlockComment = false;
-
- for (int pos = 0; pos < memberText.Length; pos++) {
- char ch = memberText [pos];
- switch (ch) {
- case '(':
- case '[':
- case '{':
- if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
- bracketStack.Push (Tuple.Create (ch, pos));
- break;
- case ')':
- case ']':
- case '}':
- if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
- if (bracketStack.Count > 0)
- bracketStack.Pop ();
- break;
- case '\r':
- case '\n':
- isInLineComment = false;
- break;
- case '/':
- if (isInBlockComment) {
- if (pos > 0 && memberText [pos - 1] == '*')
- isInBlockComment = false;
- } else if (!isInString && !isInChar && pos + 1 < memberText.Length) {
- char nextChar = memberText [pos + 1];
- if (nextChar == '/')
- isInLineComment = true;
- if (!isInLineComment && nextChar == '*')
- isInBlockComment = true;
- }
- break;
- case '"':
- if (!(isInChar || isInLineComment || isInBlockComment))
- isInString = !isInString;
- break;
- case '\'':
- if (!(isInString || isInLineComment || isInBlockComment))
- isInChar = !isInChar;
- break;
- default :
- break;
- }
- }
- bool didAppendSemicolon = !appendSemicolon;
-
- char lastBracket = '\0';
- while (bracketStack.Count > 0) {
- var t = bracketStack.Pop ();
- switch (t.Item1) {
- case '(':
- wrapper.Append (')');
- didAppendSemicolon = false;
- lastBracket = ')';
- break;
- case '[':
- wrapper.Append (']');
- didAppendSemicolon = false;
- lastBracket = ']';
- break;
- case '<':
- wrapper.Append ('>');
- didAppendSemicolon = false;
- lastBracket = '>';
- break;
- case '{':
- int o = t.Item2 - 1;
- if (!didAppendSemicolon) {
- didAppendSemicolon = true;
- wrapper.Append (';');
- }
-
- bool didAppendCatch = false;
- while (o >= "try".Length) {
- char ch = memberText[o];
- if (!char.IsWhiteSpace (ch)) {
- if (ch == 'y' && memberText[o - 1] == 'r' && memberText[o - 2] == 't') {
- wrapper.Append ("} catch {}");
- didAppendCatch = true;
- }
- break;
- }
- o--;
- }
- if (!didAppendCatch)
- wrapper.Append ('}');
- break;
- }
- }
- if (currentMember == null && lastBracket == ']') {
- // attribute context
- wrapper.Append ("class GenAttr {}");
- } else {
- if (!didAppendSemicolon)
- wrapper.Append (';');
- }
- }
-
- protected CompilationUnit ParseStub (string continuation, bool appendSemicolon = true)
- {
- var mt = GetMemberTextToCaret ();
- if (mt == null)
- return null;
-
- string memberText = mt.Item1;
- bool wrapInClass = mt.Item2;
-
- var wrapper = new StringBuilder ();
- if (wrapInClass) {
- wrapper.Append ("class Stub {");
- wrapper.AppendLine ();
- }
-
- wrapper.Append (memberText);
- wrapper.Append (continuation);
- AppendMissingClosingBrackets (wrapper, memberText, appendSemicolon);
-
- if (wrapInClass)
- wrapper.Append ('}');
-
- TextLocation memberLocation;
- if (currentMember != null) {
- memberLocation = currentMember.Region.Begin;
- } else if (currentType != null) {
- memberLocation = currentType.Region.Begin;
- } else {
- memberLocation = new TextLocation (1, 1);
- }
- using (var stream = new System.IO.StringReader (wrapper.ToString ())) {
- var parser = new CSharpParser ();
- return parser.Parse (stream, wrapInClass ? memberLocation.Line - 2 : 0);
- }
- }
-
- string cachedText = null;
-
- protected virtual void Reset ()
- {
- cachedText = null;
- }
-
- protected Tuple<string, bool> GetMemberTextToCaret ()
- {
- int startOffset;
- if (currentMember != null) {
- startOffset = document.GetOffset (currentMember.Region.BeginLine, currentMember.Region.BeginColumn);
- } else if (currentType != null) {
- startOffset = document.GetOffset (currentType.Region.BeginLine, currentType.Region.BeginColumn);
- } else {
- startOffset = 0;
- }
- if (cachedText == null)
- cachedText = document.GetText (startOffset, offset - startOffset);
-
- return Tuple.Create (cachedText, startOffset != 0);
- }
-
- protected Tuple<CSharpParsedFile, AstNode, CompilationUnit> GetInvocationBeforeCursor (bool afterBracket)
- {
- CompilationUnit baseUnit;
- if (currentMember == null) {
- baseUnit = ParseStub ("", false);
- var section = baseUnit.GetNodeAt<AttributeSection> (location.Line, location.Column - 2);
- var attr = section != null ? section.Attributes.LastOrDefault () : null;
- if (attr != null) {
- // insert target type into compilation unit, to respect the
- attr.Remove ();
- var node = Unit.GetNodeAt (location) ?? Unit;
- node.AddChild (attr, AttributeSection.AttributeRole);
- return Tuple.Create (CSharpParsedFile, (AstNode)attr, Unit);
- }
- }
-
- if (currentMember == null && currentType == null) {
- return null;
- }
- baseUnit = ParseStub (afterBracket ? "" : "x");
-
- var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
- var mref = baseUnit.GetNodeAt (location.Line, location.Column - 1, n => n is InvocationExpression || n is ObjectCreateExpression);
- AstNode expr;
- if (mref is InvocationExpression) {
- expr = ((InvocationExpression)mref).Target;
- } else if (mref is ObjectCreateExpression) {
- expr = mref;
- } else {
- return null;
- }
-
- /* var member = Unit.GetNodeAt<AttributedNode> (memberLocation);
- var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation);
- member2.Remove ();
- member.ReplaceWith (member2);
- var tsvisitor = new TypeSystemConvertVisitor (ProjectContent, CSharpParsedFile.FileName);
- baseUnit.AcceptVisitor (tsvisitor, null);*/
- return Tuple.Create (CSharpParsedFile, (AstNode)expr, baseUnit);
-
- /*
-
- ///////
- if (currentMember == null && currentType == null)
- return null;
-
- CSharpParser parser = new CSharpParser ();
- int startOffset;
- if (currentMember != null) {
- startOffset = document.Editor.LocationToOffset (currentMember.Region.BeginLine, currentMember.Region.BeginColumn);
- } else {
- startOffset = document.Editor.LocationToOffset (currentType.Region.BeginLine, currentType.Region.BeginColumn);
- }
- string memberText = Document.Editor.GetTextBetween (startOffset, Document.Editor.Caret.Offset - 1);
-
- var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
- StringBuilder wrapper = new StringBuilder ();
- wrapper.Append ("class Stub {");
- wrapper.AppendLine ();
- wrapper.Append (memberText);
-
- if (afterBracket) {
- wrapper.Append ("();");
- } else {
- wrapper.Append ("x);");
- }
-
- wrapper.Append (" SomeCall (); } } }");
- var stream = new System.IO.StringReader (wrapper.ToString ());
- var baseUnit = parser.Parse (stream, memberLocation.Line - 2);
- stream.Close ();
- var expr = baseUnit.GetNodeAt<Expression> (document.Editor.Caret.Line, document.Editor.Caret.Column);
- if (expr is InvocationExpression) {
- expr = ((InvocationExpression)expr).Target;
- }
- if (expr == null)
- return null;
- var member = Unit.GetNodeAt<AttributedNode> (memberLocation);
- var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation);
- member2.Remove ();
- member.ReplaceWith (member2);
-
- var tsvisitor = new TypeSystemConvertVisitor (ProjectContext, Document.FileName);
- Unit.AcceptVisitor (tsvisitor, null);
- return Tuple.Create (tsvisitor.ParsedFile, expr, Unit);*/
- }
-
- protected Tuple<ResolveResult, CSharpResolver> ResolveExpression (CSharpParsedFile file, AstNode expr, CompilationUnit unit)
- {
- if (expr == null)
- return null;
- AstNode resolveNode;
- if (expr is Expression || expr is AstType) {
- resolveNode = expr;
- } else if (expr is VariableDeclarationStatement) {
- resolveNode = ((VariableDeclarationStatement)expr).Type;
- } else {
- resolveNode = expr;
- }
-
- var csResolver = new CSharpResolver (ctx, System.Threading.CancellationToken.None);
- var navigator = new NodeListResolveVisitorNavigator (new[] { resolveNode });
- var visitor = new ResolveVisitor (csResolver, file, navigator);
- visitor.Scan (unit);
-// Print (unit);
- var state = visitor.GetResolverStateBefore (resolveNode);
- var result = visitor.GetResolveResult (resolveNode);
- return Tuple.Create (result, state);
- }
-
- protected static void Print (AstNode node)
- {
- var v = new CSharpOutputVisitor (Console.Out, new CSharpFormattingOptions ());
- node.AcceptVisitor (v, null);
- }
-
- #endregion
- }
+//
+// CSharpCompletionEngineBase.cs
+//
+// Author:
+// Mike Krüger <mkrueger@xamarin.com>
+//
+// Copyright (c) 2011 Xamarin Inc. (http://xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using ICSharpCode.NRefactory.CSharp.Resolver;
+using ICSharpCode.NRefactory.Editor;
+using ICSharpCode.NRefactory.TypeSystem;
+using ICSharpCode.NRefactory.Semantics;
+
+namespace ICSharpCode.NRefactory.CSharp.Completion
+{
+ /// <summary>
+ /// Acts as a common base between code completion and parameter completion.
+ /// </summary>
+ public class CSharpCompletionEngineBase
+ {
+ protected IDocument document;
+ protected int offset;
+ protected TextLocation location;
+
+ protected ITypeDefinition currentType;
+ protected IMember currentMember;
+
+ #region Input properties
+ public ITypeResolveContext ctx { get; set; }
+ public CompilationUnit Unit { get; set; }
+ public CSharpParsedFile CSharpParsedFile { get; set; }
+ public IProjectContent ProjectContent { get; set; }
+ #endregion
+
+ protected void SetOffset (int offset)
+ {
+ Reset ();
+
+ this.offset = offset;
+ this.location = document.GetLocation (offset);
+
+ this.currentType = CSharpParsedFile.GetInnermostTypeDefinition (location);
+ this.currentMember = CSharpParsedFile.GetMember (location);
+ }
+
+ #region Context helper methods
+ protected bool IsInsideCommentOrString ()
+ {
+ var text = GetMemberTextToCaret ();
+ bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false;
+
+ for (int i = 0; i < text.Item1.Length - 1; i++) {
+ char ch = text.Item1[i];
+ char nextCh = text.Item1[i + 1];
+
+ switch (ch) {
+ case '/':
+ if (inString || inChar || inVerbatimString)
+ break;
+ if (nextCh == '/') {
+ i++;
+ inSingleComment = true;
+ }
+ if (nextCh == '*')
+ inMultiLineComment = true;
+ break;
+ case '*':
+ if (inString || inChar || inVerbatimString || inSingleComment)
+ break;
+ if (nextCh == '/') {
+ i++;
+ inMultiLineComment = false;
+ }
+ break;
+ case '@':
+ if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment)
+ break;
+ if (nextCh == '"') {
+ i++;
+ inVerbatimString = true;
+ }
+ break;
+ case '\n':
+ case '\r':
+ inSingleComment = false;
+ inString = false;
+ inChar = false;
+ break;
+ case '\\':
+ if (inString || inChar)
+ i++;
+ break;
+ case '"':
+ if (inSingleComment || inMultiLineComment || inChar)
+ break;
+ if (inVerbatimString) {
+ if (nextCh == '"') {
+ i++;
+ break;
+ }
+ inVerbatimString = false;
+ break;
+ }
+ inString = !inString;
+ break;
+ case '\'':
+ if (inSingleComment || inMultiLineComment || inString || inVerbatimString)
+ break;
+ inChar = !inChar;
+ break;
+ }
+ }
+
+ return inSingleComment || inString || inVerbatimString || inChar || inMultiLineComment;
+ }
+
+ protected bool IsInsideComment (int offset)
+ {
+ var loc = document.GetLocation (offset);
+ return Unit.GetNodeAt<ICSharpCode.NRefactory.CSharp.Comment> (loc.Line, loc.Column) != null;
+ }
+
+ protected bool IsInsideDocComment ()
+ {
+ var loc = document.GetLocation (offset);
+ var cmt = Unit.GetNodeAt<ICSharpCode.NRefactory.CSharp.Comment> (loc.Line, loc.Column - 1);
+ return cmt != null && cmt.CommentType == CommentType.Documentation;
+ }
+
+ protected bool IsInsideString (int offset)
+ {
+
+ var loc = document.GetLocation (offset);
+ var expr = Unit.GetNodeAt<PrimitiveExpression> (loc.Line, loc.Column);
+ return expr != null && expr.Value is string;
+ }
+ #endregion
+
+ #region Basic parsing/resolving functions
+ protected void AppendMissingClosingBrackets (StringBuilder wrapper, string memberText, bool appendSemicolon)
+ {
+ var bracketStack = new Stack<Tuple<char, int>> ();
+
+ bool isInString = false, isInChar = false;
+ bool isInLineComment = false, isInBlockComment = false;
+
+ for (int pos = 0; pos < memberText.Length; pos++) {
+ char ch = memberText [pos];
+ switch (ch) {
+ case '(':
+ case '[':
+ case '{':
+ if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
+ bracketStack.Push (Tuple.Create (ch, pos));
+ break;
+ case ')':
+ case ']':
+ case '}':
+ if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
+ if (bracketStack.Count > 0)
+ bracketStack.Pop ();
+ break;
+ case '\r':
+ case '\n':
+ isInLineComment = false;
+ break;
+ case '/':
+ if (isInBlockComment) {
+ if (pos > 0 && memberText [pos - 1] == '*')
+ isInBlockComment = false;
+ } else if (!isInString && !isInChar && pos + 1 < memberText.Length) {
+ char nextChar = memberText [pos + 1];
+ if (nextChar == '/')
+ isInLineComment = true;
+ if (!isInLineComment && nextChar == '*')
+ isInBlockComment = true;
+ }
+ break;
+ case '"':
+ if (!(isInChar || isInLineComment || isInBlockComment))
+ isInString = !isInString;
+ break;
+ case '\'':
+ if (!(isInString || isInLineComment || isInBlockComment))
+ isInChar = !isInChar;
+ break;
+ default :
+ break;
+ }
+ }
+ bool didAppendSemicolon = !appendSemicolon;
+
+ char lastBracket = '\0';
+ while (bracketStack.Count > 0) {
+ var t = bracketStack.Pop ();
+ switch (t.Item1) {
+ case '(':
+ wrapper.Append (')');
+ didAppendSemicolon = false;
+ lastBracket = ')';
+ break;
+ case '[':
+ wrapper.Append (']');
+ didAppendSemicolon = false;
+ lastBracket = ']';
+ break;
+ case '<':
+ wrapper.Append ('>');
+ didAppendSemicolon = false;
+ lastBracket = '>';
+ break;
+ case '{':
+ int o = t.Item2 - 1;
+ if (!didAppendSemicolon) {
+ didAppendSemicolon = true;
+ wrapper.Append (';');
+ }
+
+ bool didAppendCatch = false;
+ while (o >= "try".Length) {
+ char ch = memberText[o];
+ if (!char.IsWhiteSpace (ch)) {
+ if (ch == 'y' && memberText[o - 1] == 'r' && memberText[o - 2] == 't') {
+ wrapper.Append ("} catch {}");
+ didAppendCatch = true;
+ }
+ break;
+ }
+ o--;
+ }
+ if (!didAppendCatch)
+ wrapper.Append ('}');
+ break;
+ }
+ }
+ if (currentMember == null && lastBracket == ']') {
+ // attribute context
+ wrapper.Append ("class GenAttr {}");
+ } else {
+ if (!didAppendSemicolon)
+ wrapper.Append (';');
+ }
+ }
+
+ protected CompilationUnit ParseStub (string continuation, bool appendSemicolon = true)
+ {
+ var mt = GetMemberTextToCaret ();
+ if (mt == null)
+ return null;
+
+ string memberText = mt.Item1;
+ bool wrapInClass = mt.Item2;
+
+ var wrapper = new StringBuilder ();
+ if (wrapInClass) {
+ wrapper.Append ("class Stub {");
+ wrapper.AppendLine ();
+ }
+
+ wrapper.Append (memberText);
+ wrapper.Append (continuation);
+ AppendMissingClosingBrackets (wrapper, memberText, appendSemicolon);
+
+ if (wrapInClass)
+ wrapper.Append ('}');
+
+ TextLocation memberLocation;
+ if (currentMember != null) {
+ memberLocation = currentMember.Region.Begin;
+ } else if (currentType != null) {
+ memberLocation = currentType.Region.Begin;
+ } else {
+ memberLocation = new TextLocation (1, 1);
+ }
+
+ using (var stream = new System.IO.StringReader (wrapper.ToString ())) {
+ var parser = new CSharpParser ();
+ return parser.Parse (stream, wrapInClass ? memberLocation.Line - 2 : 0);
+ }
+ }
+
+ string cachedText = null;
+
+ protected virtual void Reset ()
+ {
+ cachedText = null;
+ }
+
+ protected Tuple<string, bool> GetMemberTextToCaret ()
+ {
+ int startOffset;
+ if (currentMember != null) {
+ startOffset = document.GetOffset (currentMember.Region.BeginLine, currentMember.Region.BeginColumn);
+ } else if (currentType != null) {
+ startOffset = document.GetOffset (currentType.Region.BeginLine, currentType.Region.BeginColumn);
+ } else {
+ startOffset = 0;
+ }
+ if (cachedText == null)
+ cachedText = document.GetText (startOffset, offset - startOffset);
+
+ return Tuple.Create (cachedText, startOffset != 0);
+ }
+
+ protected Tuple<CSharpParsedFile, AstNode, CompilationUnit> GetInvocationBeforeCursor (bool afterBracket)
+ {
+ CompilationUnit baseUnit;
+ if (currentMember == null) {
+ baseUnit = ParseStub ("", false);
+ var section = baseUnit.GetNodeAt<AttributeSection> (location.Line, location.Column - 2);
+ var attr = section != null ? section.Attributes.LastOrDefault () : null;
+ if (attr != null) {
+ // insert target type into compilation unit, to respect the
+ attr.Remove ();
+ var node = Unit.GetNodeAt (location) ?? Unit;
+ node.AddChild (attr, AttributeSection.AttributeRole);
+ return Tuple.Create (CSharpParsedFile, (AstNode)attr, Unit);
+ }
+ }
+
+ if (currentMember == null && currentType == null) {
+ return null;
+ }
+ baseUnit = ParseStub (afterBracket ? "" : "x");
+
+ var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
+ var mref = baseUnit.GetNodeAt (location.Line, location.Column - 1, n => n is InvocationExpression || n is ObjectCreateExpression);
+ AstNode expr;
+ if (mref is InvocationExpression) {
+ expr = ((InvocationExpression)mref).Target;
+ } else if (mref is ObjectCreateExpression) {
+ expr = mref;
+ } else {
+ return null;
+ }
+
+ /* var member = Unit.GetNodeAt<AttributedNode> (memberLocation);
+ var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation);
+ member2.Remove ();
+ member.ReplaceWith (member2);
+ var tsvisitor = new TypeSystemConvertVisitor (ProjectContent, CSharpParsedFile.FileName);
+ baseUnit.AcceptVisitor (tsvisitor, null);*/
+ return Tuple.Create (CSharpParsedFile, (AstNode)expr, baseUnit);
+
+ /*
+
+ ///////
+ if (currentMember == null && currentType == null)
+ return null;
+
+ CSharpParser parser = new CSharpParser ();
+ int startOffset;
+ if (currentMember != null) {
+ startOffset = document.Editor.LocationToOffset (currentMember.Region.BeginLine, currentMember.Region.BeginColumn);
+ } else {
+ startOffset = document.Editor.LocationToOffset (currentType.Region.BeginLine, currentType.Region.BeginColumn);
+ }
+ string memberText = Document.Editor.GetTextBetween (startOffset, Document.Editor.Caret.Offset - 1);
+
+ var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
+ StringBuilder wrapper = new StringBuilder ();
+ wrapper.Append ("class Stub {");
+ wrapper.AppendLine ();
+ wrapper.Append (memberText);
+
+ if (afterBracket) {
+ wrapper.Append ("();");
+ } else {
+ wrapper.Append ("x);");
+ }
+
+ wrapper.Append (" SomeCall (); } } }");
+ var stream = new System.IO.StringReader (wrapper.ToString ());
+ var baseUnit = parser.Parse (stream, memberLocation.Line - 2);
+ stream.Close ();
+ var expr = baseUnit.GetNodeAt<Expression> (document.Editor.Caret.Line, document.Editor.Caret.Column);
+ if (expr is InvocationExpression) {
+ expr = ((InvocationExpression)expr).Target;
+ }
+ if (expr == null)
+ return null;
+ var member = Unit.GetNodeAt<AttributedNode> (memberLocation);
+ var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation);
+ member2.Remove ();
+ member.ReplaceWith (member2);
+
+ var tsvisitor = new TypeSystemConvertVisitor (ProjectContext, Document.FileName);
+ Unit.AcceptVisitor (tsvisitor, null);
+ return Tuple.Create (tsvisitor.ParsedFile, expr, Unit);*/
+ }
+
+ protected Tuple<ResolveResult, CSharpResolver> ResolveExpression (CSharpParsedFile file, AstNode expr, CompilationUnit unit)
+ {
+ if (expr == null)
+ return null;
+ AstNode resolveNode;
+ if (expr is Expression || expr is AstType) {
+ resolveNode = expr;
+ } else if (expr is VariableDeclarationStatement) {
+ resolveNode = ((VariableDeclarationStatement)expr).Type;
+ } else {
+ resolveNode = expr;
+ }
+
+ var csResolver = new CSharpResolver (ctx, System.Threading.CancellationToken.None);
+ var navigator = new NodeListResolveVisitorNavigator (new[] { resolveNode });
+ var visitor = new ResolveVisitor (csResolver, file, navigator);
+ visitor.Scan (unit);
+// Print (unit);
+ var state = visitor.GetResolverStateBefore (resolveNode);
+ var result = visitor.GetResolveResult (resolveNode);
+ return Tuple.Create (result, state);
+ }
+
+ protected static void Print (AstNode node)
+ {
+ var v = new CSharpOutputVisitor (Console.Out, new CSharpFormattingOptions ());
+ node.AcceptVisitor (v, null);
+ }
+
+ #endregion
+ }
} \ No newline at end of file
diff --git a/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs b/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs
index c946dba60b..6aaa6716ea 100644
--- a/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs
+++ b/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs
@@ -1,201 +1,201 @@
-//
-// CSharpParameterCompletionEngine.cs
-//
-// Author:
-// Mike Krüger <mkrueger@xamarin.com>
-//
-// Copyright (c) 2011 Xamarin Inc. (http://xamarin.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-using System;
-using ICSharpCode.NRefactory.Editor;
-using ICSharpCode.NRefactory.Completion;
-using System.Collections.Generic;
-using ICSharpCode.NRefactory.Semantics;
-using ICSharpCode.NRefactory.TypeSystem;
-using ICSharpCode.NRefactory.CSharp.Resolver;
-
-namespace ICSharpCode.NRefactory.CSharp.Completion
-{
- public class CSharpParameterCompletionEngine : CSharpCompletionEngineBase
- {
- internal IParameterCompletionDataFactory factory;
-
- public CSharpParameterCompletionEngine (IDocument document, IParameterCompletionDataFactory factory)
- {
- this.document = document;
- this.factory = factory;
- }
-
- public Tuple<CSharpParsedFile, AstNode, CompilationUnit> GetIndexerBeforeCursor ()
- {
- CompilationUnit baseUnit;
- if (currentMember == null && currentType == null)
- return null;
- baseUnit = ParseStub ("x] = a[1");
-
- var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
- var mref = baseUnit.GetNodeAt (location, n => n is IndexerExpression);
- Print (baseUnit);
- AstNode expr;
- if (mref is IndexerExpression) {
- expr = ((IndexerExpression)mref).Target;
- } else {
- return null;
- }
-
- var member = Unit.GetNodeAt<AttributedNode> (memberLocation);
- var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation);
- member2.Remove ();
- member.ReplaceWith (member2);
- var tsvisitor = new TypeSystemConvertVisitor (ProjectContent, CSharpParsedFile.FileName);
- Unit.AcceptVisitor (tsvisitor, null);
- return Tuple.Create (tsvisitor.ParsedFile, (AstNode)expr, Unit);
- }
-
- public IParameterDataProvider GetParameterDataProvider (int offset)
- {
- if (offset <= 0)
- return null;
- SetOffset (offset);
- char completionChar = document.GetCharAt (offset - 1);
- if (completionChar != '(' && completionChar != '<' && completionChar != '[')
- return null;
- if (IsInsideCommentOrString ())
- return null;
-
- var invoke = GetInvocationBeforeCursor (true) ?? GetIndexerBeforeCursor ();
- if (invoke == null)
- return null;
-
- ResolveResult resolveResult;
- switch (completionChar) {
- case '(':
- if (invoke.Item2 is ObjectCreateExpression) {
- var createType = ResolveExpression (invoke.Item1, ((ObjectCreateExpression)invoke.Item2).Type, invoke.Item3);
- return factory.CreateConstructorProvider (createType.Item1.Type);
- }
-
- if (invoke.Item2 is ICSharpCode.NRefactory.CSharp.Attribute) {
- var attribute = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
- if (attribute == null || attribute.Item1 == null)
- return null;
- return factory.CreateConstructorProvider (attribute.Item1.Type);
- }
-
- var invocationExpression = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
-
- if (invocationExpression == null || invocationExpression.Item1 == null || invocationExpression.Item1.IsError)
- return null;
- resolveResult = invocationExpression.Item1;
- if (resolveResult is MethodGroupResolveResult)
- return factory.CreateMethodDataProvider (resolveResult as MethodGroupResolveResult);
- if (resolveResult is MemberResolveResult) {
- if (resolveResult.Type.Kind == TypeKind.Delegate)
- return factory.CreateDelegateDataProvider (resolveResult.Type);
- var mr = resolveResult as MemberResolveResult;
- if (mr.Member is IMethod)
- return factory.CreateMethodDataProvider ((IMethod)mr.Member);
- }
-
-//
-// 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 '<':
-// if (string.IsNullOrEmpty (result.Expression))
-// return null;
-// return new NRefactoryTemplateParameterDataProvider (textEditorData, resolver, GetUsedNamespaces (), result, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
-
- case '[':
- var indexerExpression = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
- if (indexerExpression == null || indexerExpression.Item1 == null || indexerExpression.Item1.IsError)
- return null;
-
- return factory.CreateIndexerParameterDataProvider (indexerExpression.Item1.Type, invoke.Item2);
- }
- return null;
- }
-
- List<string> GetUsedNamespaces ()
- {
- var scope = CSharpParsedFile.GetUsingScope (location);
- var result = new List<string> ();
- while (scope != null) {
- result.Add (scope.NamespaceName);
- foreach (var u in scope.Usings) {
- var ns = u.ResolveNamespace (ctx);
- if (ns == null)
- continue;
- result.Add (ns.NamespaceName);
- }
- scope = scope.Parent;
- }
- return result;
- }
- /*
- public override bool GetParameterCompletionCommandOffset (out int cpos)
- {
- // Start calculating the parameter offset from the beginning of the
- // current member, instead of the beginning of the file.
- cpos = textEditorData.Caret.Offset - 1;
- var parsedDocument = Document.ParsedDocument;
- if (parsedDocument == null)
- return false;
- IMember mem = currentMember;
- if (mem == null || (mem is IType))
- return false;
- int startPos = textEditorData.LocationToOffset (mem.Region.BeginLine, mem.Region.BeginColumn);
- int parenDepth = 0;
- int chevronDepth = 0;
- while (cpos > startPos) {
- char c = textEditorData.GetCharAt (cpos);
- if (c == ')')
- parenDepth++;
- if (c == '>')
- chevronDepth++;
- if (parenDepth == 0 && c == '(' || chevronDepth == 0 && c == '<') {
- int p = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, cpos + 1, startPos);
- if (p != -1) {
- cpos++;
- return true;
- } else {
- return false;
- }
- }
- if (c == '(')
- parenDepth--;
- if (c == '<')
- chevronDepth--;
- cpos--;
- }
- return false;
- }*/
- }
-}
-
+//
+// CSharpParameterCompletionEngine.cs
+//
+// Author:
+// Mike Krüger <mkrueger@xamarin.com>
+//
+// Copyright (c) 2011 Xamarin Inc. (http://xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using ICSharpCode.NRefactory.Editor;
+using ICSharpCode.NRefactory.Completion;
+using System.Collections.Generic;
+using ICSharpCode.NRefactory.Semantics;
+using ICSharpCode.NRefactory.TypeSystem;
+using ICSharpCode.NRefactory.CSharp.Resolver;
+
+namespace ICSharpCode.NRefactory.CSharp.Completion
+{
+ public class CSharpParameterCompletionEngine : CSharpCompletionEngineBase
+ {
+ internal IParameterCompletionDataFactory factory;
+
+ public CSharpParameterCompletionEngine (IDocument document, IParameterCompletionDataFactory factory)
+ {
+ this.document = document;
+ this.factory = factory;
+ }
+
+ public Tuple<CSharpParsedFile, AstNode, CompilationUnit> GetIndexerBeforeCursor ()
+ {
+ CompilationUnit baseUnit;
+ if (currentMember == null && currentType == null)
+ return null;
+ baseUnit = ParseStub ("x] = a[1");
+
+ var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
+ var mref = baseUnit.GetNodeAt (location, n => n is IndexerExpression);
+ Print (baseUnit);
+ AstNode expr;
+ if (mref is IndexerExpression) {
+ expr = ((IndexerExpression)mref).Target;
+ } else {
+ return null;
+ }
+
+ var member = Unit.GetNodeAt<AttributedNode> (memberLocation);
+ var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation);
+ member2.Remove ();
+ member.ReplaceWith (member2);
+ var tsvisitor = new TypeSystemConvertVisitor (ProjectContent, CSharpParsedFile.FileName);
+ Unit.AcceptVisitor (tsvisitor, null);
+ return Tuple.Create (tsvisitor.ParsedFile, (AstNode)expr, Unit);
+ }
+
+ public IParameterDataProvider GetParameterDataProvider (int offset)
+ {
+ if (offset <= 0)
+ return null;
+ SetOffset (offset);
+ char completionChar = document.GetCharAt (offset - 1);
+ if (completionChar != '(' && completionChar != '<' && completionChar != '[')
+ return null;
+ if (IsInsideCommentOrString ())
+ return null;
+
+ var invoke = GetInvocationBeforeCursor (true) ?? GetIndexerBeforeCursor ();
+ if (invoke == null)
+ return null;
+
+ ResolveResult resolveResult;
+ switch (completionChar) {
+ case '(':
+ if (invoke.Item2 is ObjectCreateExpression) {
+ var createType = ResolveExpression (invoke.Item1, ((ObjectCreateExpression)invoke.Item2).Type, invoke.Item3);
+ return factory.CreateConstructorProvider (createType.Item1.Type);
+ }
+
+ if (invoke.Item2 is ICSharpCode.NRefactory.CSharp.Attribute) {
+ var attribute = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
+ if (attribute == null || attribute.Item1 == null)
+ return null;
+ return factory.CreateConstructorProvider (attribute.Item1.Type);
+ }
+
+ var invocationExpression = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
+
+ if (invocationExpression == null || invocationExpression.Item1 == null || invocationExpression.Item1.IsError)
+ return null;
+ resolveResult = invocationExpression.Item1;
+ if (resolveResult is MethodGroupResolveResult)
+ return factory.CreateMethodDataProvider (resolveResult as MethodGroupResolveResult);
+ if (resolveResult is MemberResolveResult) {
+ if (resolveResult.Type.Kind == TypeKind.Delegate)
+ return factory.CreateDelegateDataProvider (resolveResult.Type);
+ var mr = resolveResult as MemberResolveResult;
+ if (mr.Member is IMethod)
+ return factory.CreateMethodDataProvider ((IMethod)mr.Member);
+ }
+
+//
+// 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 '<':
+// if (string.IsNullOrEmpty (result.Expression))
+// return null;
+// return new NRefactoryTemplateParameterDataProvider (textEditorData, resolver, GetUsedNamespaces (), result, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
+
+ case '[':
+ var indexerExpression = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
+ if (indexerExpression == null || indexerExpression.Item1 == null || indexerExpression.Item1.IsError)
+ return null;
+
+ return factory.CreateIndexerParameterDataProvider (indexerExpression.Item1.Type, invoke.Item2);
+ }
+ return null;
+ }
+
+ List<string> GetUsedNamespaces ()
+ {
+ var scope = CSharpParsedFile.GetUsingScope (location);
+ var result = new List<string> ();
+ while (scope != null) {
+ result.Add (scope.NamespaceName);
+ foreach (var u in scope.Usings) {
+ var ns = u.ResolveNamespace (ctx);
+ if (ns == null)
+ continue;
+ result.Add (ns.NamespaceName);
+ }
+ scope = scope.Parent;
+ }
+ return result;
+ }
+ /*
+ public override bool GetParameterCompletionCommandOffset (out int cpos)
+ {
+ // Start calculating the parameter offset from the beginning of the
+ // current member, instead of the beginning of the file.
+ cpos = textEditorData.Caret.Offset - 1;
+ var parsedDocument = Document.ParsedDocument;
+ if (parsedDocument == null)
+ return false;
+ IMember mem = currentMember;
+ if (mem == null || (mem is IType))
+ return false;
+ int startPos = textEditorData.LocationToOffset (mem.Region.BeginLine, mem.Region.BeginColumn);
+ int parenDepth = 0;
+ int chevronDepth = 0;
+ while (cpos > startPos) {
+ char c = textEditorData.GetCharAt (cpos);
+ if (c == ')')
+ parenDepth++;
+ if (c == '>')
+ chevronDepth++;
+ if (parenDepth == 0 && c == '(' || chevronDepth == 0 && c == '<') {
+ int p = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, cpos + 1, startPos);
+ if (p != -1) {
+ cpos++;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ if (c == '(')
+ parenDepth--;
+ if (c == '<')
+ chevronDepth--;
+ cpos--;
+ }
+ return false;
+ }*/
+ }
+}
+
diff --git a/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/IParameterCompletionDataFactory.cs b/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/IParameterCompletionDataFactory.cs
index 48d8c5a308..56321bdb18 100644
--- a/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/IParameterCompletionDataFactory.cs
+++ b/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/IParameterCompletionDataFactory.cs
@@ -39,7 +39,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
IParameterDataProvider CreateMethodDataProvider (IMethod method);
IParameterDataProvider CreateDelegateDataProvider (IType type);
-
+
IParameterDataProvider CreateIndexerParameterDataProvider (IType type, AstNode resolvedNode);
}
diff --git a/main/contrib/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs b/main/contrib/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
index 8e5cd77ffd..0e562e3e7b 100644
--- a/main/contrib/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
+++ b/main/contrib/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
@@ -1462,10 +1462,9 @@ namespace ICSharpCode.NRefactory.CSharp
var result = new ExpressionStatement ();
if (statementExpression.Expression == null)
return result;
- object expr = statementExpression.Expression.Accept (this);
- if (expr != null) {
- result.AddChild ((Expression)expr, ExpressionStatement.Roles.Expression);
- }
+ var expr = statementExpression.Expression.Accept (this) as Expression;
+ if (expr != null)
+ result.AddChild (expr, ExpressionStatement.Roles.Expression);
var location = LocationsBag.GetLocations (statementExpression);
if (location != null)
result.AddChild (new CSharpTokenNode (Convert (location[0]), 1), ExpressionStatement.Roles.Semicolon);
diff --git a/main/contrib/ICSharpCode.NRefactory.CSharp/Parser/TypeSystemConvertVisitor.cs b/main/contrib/ICSharpCode.NRefactory.CSharp/Parser/TypeSystemConvertVisitor.cs
index 1eac3f9091..8e03c367d2 100644
--- a/main/contrib/ICSharpCode.NRefactory.CSharp/Parser/TypeSystemConvertVisitor.cs
+++ b/main/contrib/ICSharpCode.NRefactory.CSharp/Parser/TypeSystemConvertVisitor.cs
@@ -710,6 +710,9 @@ namespace ICSharpCode.NRefactory.CSharp
m.IsShadowing = (modifiers & Modifiers.New) != 0;
m.IsStatic = (modifiers & Modifiers.Static) != 0;
m.IsVirtual = (modifiers & Modifiers.Virtual) != 0;
+ m.IsPartial = (modifiers & Modifiers.Partial) != 0;
+
+
}
static Accessibility? GetAccessibility(Modifiers modifiers)
diff --git a/main/contrib/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs b/main/contrib/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs
index f22e56b43b..8bd8303982 100644
--- a/main/contrib/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs
+++ b/main/contrib/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs
@@ -3239,16 +3239,16 @@ namespace Mono.CSharp
bool docAppend = false;
if (doc_processing && peek_char () == '*') {
int ch = get_char ();
- if (position_stack.Count == 0)
- sbag.PushCommentChar (ch);
// But when it is /**/, just do nothing.
if (peek_char () == '/') {
ch = get_char ();
if (position_stack.Count == 0) {
- sbag.PushCommentChar (ch);
sbag.EndComment (line, col + 1);
}
continue;
+ } else {
+ if (position_stack.Count == 0)
+ sbag.PushCommentChar (ch);
}
if (doc_state == XmlCommentState.Allowed)
docAppend = true;
@@ -3264,16 +3264,15 @@ namespace Mono.CSharp
}
while ((d = get_char ()) != -1){
- if (position_stack.Count == 0)
- sbag.PushCommentChar (d);
if (d == '*' && peek_char () == '/'){
- if (position_stack.Count == 0)
- sbag.PushCommentChar ('/');
get_char ();
if (position_stack.Count == 0)
sbag.EndComment (line, col + 1);
comments_seen = true;
break;
+ } else {
+ if (position_stack.Count == 0)
+ sbag.PushCommentChar (d);
}
if (docAppend)
xml_comment_buffer.Append ((char) d);
diff --git a/main/contrib/ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs b/main/contrib/ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs
index 4b8b067770..8b68564132 100644
--- a/main/contrib/ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs
+++ b/main/contrib/ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs
@@ -483,6 +483,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
get { return false; }
}
+ bool IMember.IsPartial {
+ get { return false; }
+ }
+
EntityType IEntity.EntityType {
get { return EntityType.Operator; }
}
diff --git a/main/contrib/ICSharpCode.NRefactory/TypeSystem/IMember.cs b/main/contrib/ICSharpCode.NRefactory/TypeSystem/IMember.cs
index 6674e02d23..99ad30e552 100644
--- a/main/contrib/ICSharpCode.NRefactory/TypeSystem/IMember.cs
+++ b/main/contrib/ICSharpCode.NRefactory/TypeSystem/IMember.cs
@@ -73,6 +73,13 @@ namespace ICSharpCode.NRefactory.TypeSystem
bool IsOverridable {
get;
}
+
+ /// <summary>
+ /// Gets if the member is partial. Returns true when the member is "partial".
+ /// </summary>
+ bool IsPartial {
+ get;
+ }
}
#if WITH_CONTRACTS
diff --git a/main/contrib/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractMember.cs b/main/contrib/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractMember.cs
index 0c4c69f7a1..a3fb7316c9 100644
--- a/main/contrib/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractMember.cs
+++ b/main/contrib/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractMember.cs
@@ -53,6 +53,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
const ushort FlagVirtual = 0x0010;
const ushort FlagOverride = 0x0020;
const ushort FlagStatic = 0x0040;
+ const ushort FlagPartial = 0x0080;
+
// Flags of form 0xY000 are reserved for use in derived classes (DefaultMethod etc.)
protected override void FreezeInternal()
@@ -144,6 +146,15 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
}
+ public bool IsPartial {
+ get { return flags[FlagPartial]; }
+ set {
+ CheckBeforeMutation();
+ flags[FlagPartial] = value;
+ }
+ }
+
+
public bool IsOverridable {
get {
return (IsAbstract || IsVirtual || IsOverride) && !IsSealed;
diff --git a/main/contrib/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMember.cs b/main/contrib/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMember.cs
index cc9c88c0f4..2a9616ab40 100644
--- a/main/contrib/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMember.cs
+++ b/main/contrib/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMember.cs
@@ -166,6 +166,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return memberDefinition.IsProtectedAndInternal; }
}
+ public bool IsPartial {
+ get { return memberDefinition.IsPartial; }
+ }
+
public IProjectContent ProjectContent {
get { return memberDefinition.ProjectContent; }
}