protected override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var position = completionContext.Position;
			var document = completionContext.Document;
			var syntaxTree = ctx.SyntaxTree;
			if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
				syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
				return Task.FromResult (Enumerable.Empty<CompletionData> ());
			if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken))
				return Task.FromResult (Enumerable.Empty<CompletionData> ());
			var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax;
			if (ma == null)
				return Task.FromResult (Enumerable.Empty<CompletionData> ());

			var model = ctx.CSharpSyntaxContext.SemanticModel;

			var symbolInfo = model.GetSymbolInfo (ma.Expression);
			if (symbolInfo.Symbol == null || symbolInfo.Symbol.Kind != SymbolKind.Parameter)
				return Task.FromResult (Enumerable.Empty<CompletionData> ());
			var list = new List<CompletionData> ();
			var within = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);
			var addedSymbols = new HashSet<string> ();

			foreach (var ano in ma.AncestorsAndSelf ().OfType<AnonymousMethodExpressionSyntax> ()) {
				Analyze (engine, model, ma.Expression, within, list, ano.ParameterList, symbolInfo.Symbol, addedSymbols, cancellationToken);
			}

			foreach (var ano in ma.AncestorsAndSelf ().OfType<ParenthesizedLambdaExpressionSyntax> ()) {
				Analyze (engine, model, ma.Expression, within, list, ano.ParameterList, symbolInfo.Symbol, addedSymbols, cancellationToken);
			}

			return Task.FromResult ((IEnumerable<CompletionData>)list);
		}
		protected override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult result, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var document = completionContext.Document;
			var position = completionContext.Position;

			var tree = ctx.SyntaxTree;
			var model = ctx.SemanticModel;
			if (tree.IsInNonUserCode (position, cancellationToken))
				return Task.FromResult (Enumerable.Empty<CompletionData> ());

			if (!ctx.CSharpSyntaxContext.IsAnyExpressionContext)
				return Task.FromResult (Enumerable.Empty<CompletionData> ());
			var enclosingType = model.GetEnclosingNamedType (position, cancellationToken);
			var memberMethods = enclosingType.GetMembers ().OfType<IMethodSymbol> ().Where (m => m.MethodKind == MethodKind.Ordinary).ToArray ();

			var list = new List<CompletionData> ();
			foreach (var type in ctx.InferredTypes) {
				if (type.TypeKind != TypeKind.Delegate)
					continue;

				AddCompatibleMethods (engine, list, type, memberMethods, cancellationToken);

				string delegateName = null;

				if (ctx.TargetToken.IsKind (SyntaxKind.PlusEqualsToken)) {
					delegateName = GuessEventHandlerBaseName (ctx.LeftToken.Parent, ctx.ContainingTypeDeclaration);
				}

				AddDelegateHandlers (list, ctx.TargetToken.Parent, model, engine, result, type, position, delegateName, cancellationToken);
			}
			if (list.Count > 0) {
				result.AutoSelect = false;
			}
			return Task.FromResult ((IEnumerable<CompletionData>)list);
		}
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var document = completionContext.Document;
			var position = completionContext.Position;

			var tree = ctx.SyntaxTree;

			if (tree.IsInNonUserCode(position, cancellationToken))
				return Enumerable.Empty<CompletionData> ();

			var targetToken = tree.FindTokenOnLeftOfPosition(position, cancellationToken).GetPreviousTokenIfTouchingWord(position);
			if (targetToken.IsKind(SyntaxKind.AliasKeyword) && targetToken.Parent.IsKind(SyntaxKind.ExternAliasDirective))
			{
				var compilation = await document.GetCSharpCompilationAsync(cancellationToken).ConfigureAwait(false);
				var aliases = compilation.ExternalReferences.Where(r => r.Properties.Aliases != null).SelectMany(r => r.Properties.Aliases).ToSet();

				if (aliases.Any())
				{
					var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false);
					var usedAliases = root.ChildNodes().OfType<ExternAliasDirectiveSyntax>().Where(e => !e.Identifier.IsMissing).Select(e => e.Identifier.ValueText);
					foreach (var used in usedAliases) {
						aliases.Remove (used); 
					}
					aliases.Remove(MetadataReferenceProperties.GlobalAlias);
					return aliases.Select (e => engine.Factory.CreateGenericData (this, e, GenericDataType.Undefined));
				}
			}

			return Enumerable.Empty<CompletionData> ();
		}
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var position = completionContext.Position;
			var document = completionContext.Document;
			var span = new TextSpan(position, 0);
			var semanticModel = await document.GetCSharpSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false);
			var syntaxTree = semanticModel.SyntaxTree;
			//	var ctx = await completionContext.GetSyntaxContextAsync (engine.Workspace, cancellationToken).ConfigureAwait (false);

			if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
				syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
			{
				return Enumerable.Empty<CompletionData> ();
			}

			if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken))
			{
				return Enumerable.Empty<CompletionData> ();
			}

			var node = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken)
				.GetPreviousTokenIfTouchingWord(position)
				.Parent;

			if (node.Kind() == SyntaxKind.ExplicitInterfaceSpecifier)
			{
				return await GetCompletionsOffOfExplicitInterfaceAsync(
					engine, document, semanticModel, position, ((ExplicitInterfaceSpecifierSyntax)node).Name, cancellationToken).ConfigureAwait(false);
			}

			return Enumerable.Empty<CompletionData> ();
		}
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var document = completionContext.Document;
			var position = completionContext.Position;
			var semanticModel = ctx.SemanticModel;

			if (ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null && 
			    ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.Argument)) {
				SourceText text;
				if (!completionContext.Document.TryGetText (out text)) {
					text = await completionContext.Document.GetTextAsync ();
				}
				var currentChar = text [completionContext.Position - 1];
				if (ctx.TargetToken.Parent == null || !ctx.TargetToken.Parent.IsKind(SyntaxKind.StringLiteralExpression) ||
				    ctx.TargetToken.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.Argument) ||
				    ctx.TargetToken.Parent.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.Parent.IsKind(SyntaxKind.ArgumentList) ||
				    ctx.TargetToken.Parent.Parent.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.Parent.Parent.IsKind(SyntaxKind.InvocationExpression)) {
					return Enumerable.Empty<CompletionData> ();
				}
				var formatArgument = GetFormatItemNumber(document, position);
				var invocationExpression = ctx.TargetToken.Parent.Parent.Parent.Parent as InvocationExpressionSyntax;
				return GetFormatCompletionData(engine, semanticModel, invocationExpression, formatArgument, currentChar);
			}

			return Enumerable.Empty<CompletionData> ();
		}
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var model = ctx.SemanticModel;
			var tree = ctx.SyntaxTree;
			if (tree.IsInNonUserCode (completionContext.Position, cancellationToken))
				return Enumerable.Empty<CompletionData> ();

			var token = tree.FindTokenOnLeftOfPosition (completionContext.Position, cancellationToken);
			if (token.IsMandatoryNamedParameterPosition ())
				return Enumerable.Empty<CompletionData> ();
			var result = new List<CompletionData> ();

			// check if it's the first parameter and set autoselect == false if a parameterless version exists.
			if (token.IsKind (SyntaxKind.OpenParenToken)) {
				var parent = token.Parent?.Parent;
				if (parent == null)
					return Enumerable.Empty<CompletionData> ();
				var symbolInfo = model.GetSymbolInfo (parent);
				foreach (var symbol in new [] { symbolInfo.Symbol }.Concat (symbolInfo.CandidateSymbols)) {
					if (symbol != null && symbol.IsKind (SymbolKind.Method)) {
						if (symbol.GetParameters ().Length == 0) {
							completionResult.AutoSelect = false;
							break;
						}
					}
				}
			}

			foreach (var _type in ctx.InferredTypes) {
				var type = _type;
				if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) {
					type = type.GetTypeArguments ().FirstOrDefault ();
					if (type == null)
						continue;
				}

				if (type.TypeKind != TypeKind.Enum)
					continue;
				if (!type.IsEditorBrowsable ())
					continue;

				// Does type have any aliases?
				ISymbol alias = await type.FindApplicableAlias (completionContext.Position, model, cancellationToken).ConfigureAwait (false);

				var displayString = RoslynCompletionData.SafeMinimalDisplayString (type, model, completionContext.Position, SymbolDisplayFormat.CSharpErrorMessageFormat);
				if (string.IsNullOrEmpty (completionResult.DefaultCompletionString)) {
					completionResult.DefaultCompletionString = displayString;
					completionResult.AutoCompleteEmptyMatch = true;

				}
				if (!IsReachable (model,  type, token.Parent))
					result.Add (engine.Factory.CreateSymbolCompletionData (this, type, displayString));
				foreach (IFieldSymbol field in type.GetMembers ().OfType<IFieldSymbol> ()) {
					if (field.DeclaredAccessibility == Accessibility.Public && (field.IsConst || field.IsStatic)) {
						result.Add (engine.Factory.CreateEnumMemberCompletionData (this, alias, field));
					}
				}
			}
			return result;
		}
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var document = completionContext.Document;
			var position = completionContext.Position;
			var tree = ctx.SyntaxTree;

			//DeclarationModifiers modifiers;
			SyntaxToken token;

			var semanticModel = ctx.SemanticModel;
			var enclosingSymbol = semanticModel.GetEnclosingSymbol (position, cancellationToken) as INamedTypeSymbol;

			// Only inside classes and structs
			if (enclosingSymbol == null || !(enclosingSymbol.TypeKind == TypeKind.Struct || enclosingSymbol.TypeKind == TypeKind.Class)) {
				return Enumerable.Empty<CompletionData> ();
			}

			if (!IsPartialCompletionContext (tree, position, cancellationToken/*, out modifiers*/, out token)) {
				if (enclosingSymbol != null && (token.IsKind (SyntaxKind.OpenBraceToken) || token.IsKind (SyntaxKind.CloseBraceToken) || token.IsKind (SyntaxKind.SemicolonToken))) {
					return CreateCompletionData (engine, semanticModel, position, enclosingSymbol, token, false, cancellationToken);
				}
				return Enumerable.Empty<CompletionData> ();
			}

			return CreateCompletionData (engine, semanticModel, position, enclosingSymbol, token, true, cancellationToken);
		}
		public override async Task<bool> IsExclusiveAsync (CompletionContext completionContext, SyntaxContext syntaxContext, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
		{
			// We're exclusive if this context could only be an object initializer and not also a
			// collection initializer. If we're initializing something that could be initialized as
			// an object or as a collection, say we're not exclusive. That way the rest of
			// intellisense can be used in the collection intitializer.
			// 
			// Consider this case:

			// class c : IEnumerable<int> 
			// { 
			// public void Add(int addend) { }
			// public int foo; 
			// }

			// void foo()
			// {
			//    var b = new c {|
			// }

			// There we could initialize b using either an object initializer or a collection
			// initializer. Since we don't know which the user will use, we'll be non-exclusive, so
			// the other providers can help the user write the collection initializer, if they want
			// to.
			var document = completionContext.Document;
			var position = completionContext.Position;
			var tree = await document.GetCSharpSyntaxTreeAsync (cancellationToken).ConfigureAwait (false);

			if (tree.IsInNonUserCode (position, cancellationToken)) {
				return false;
			}

			var token = tree.FindTokenOnLeftOfPosition (position, cancellationToken);
			token = token.GetPreviousTokenIfTouchingWord (position);

			if (token.Parent == null) {
				return false;
			}

			var expression = token.Parent.Parent as ExpressionSyntax;
			if (expression == null) {
				return false;
			}

			var semanticModel = await document.GetCSharpSemanticModelForNodeAsync (expression, cancellationToken).ConfigureAwait (false);
			var initializedType = semanticModel.GetTypeInfo (expression, cancellationToken).Type;
			if (initializedType == null) {
				return false;
			}

			// Non-exclusive if initializedType can be initialized as a collection.
			if (initializedType.CanSupportCollectionInitializer ()) {
				return false;
			}

			// By default, only our member names will show up.
			return true;
		}
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var document = completionContext.Document;
			var position = completionContext.Position;

			return await document.GetUnionResultsFromDocumentAndLinks(
				UnionCompletionItemComparer.Instance,
				async (doc, ct) => await GetSpeculativeTCompletions(engine, doc, position, ct).ConfigureAwait(false),
				cancellationToken).ConfigureAwait(false);
		}
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var document = completionContext.Document;
			var position = completionContext.Position;

			var syntaxTree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

			if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
				syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken) ||
				syntaxTree.GetContainingTypeOrEnumDeclaration(position, cancellationToken) is EnumDeclarationSyntax)
			{
				return Enumerable.Empty<CompletionData>();
			}

			// var span = new TextSpan(position, 0);
//			var semanticModel = await document.GetCSharpSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false);
			if (syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
			{
				var directive = syntaxTree.GetRoot(cancellationToken).FindTokenOnLeftOfPosition(position, includeDirectives: true).GetAncestor<DirectiveTriviaSyntax>();
				if (directive.DirectiveNameToken.IsKind(
					SyntaxKind.IfKeyword,
					SyntaxKind.RegionKeyword,
					SyntaxKind.ElseKeyword,
					SyntaxKind.ElifKeyword,
					SyntaxKind.ErrorKeyword,
					SyntaxKind.LineKeyword,
					SyntaxKind.PragmaKeyword,
					SyntaxKind.EndIfKeyword,
					SyntaxKind.UndefKeyword,
					SyntaxKind.EndRegionKeyword,
					SyntaxKind.WarningKeyword))
				{
					return Enumerable.Empty<CompletionData>();
				}

				return await GetSnippetCompletionItemsAsync(cancellationToken).ConfigureAwait(false);
			}
			var tokenLeftOfPosition = syntaxTree.FindTokenOnLeftOfPosition (position, cancellationToken);

			if (syntaxTree.IsGlobalStatementContext(position, cancellationToken) ||
				syntaxTree.IsExpressionContext(position, tokenLeftOfPosition, true, cancellationToken) ||
				syntaxTree.IsStatementContext(position, tokenLeftOfPosition, cancellationToken) ||
				syntaxTree.IsTypeContext(position, cancellationToken) ||
				syntaxTree.IsTypeDeclarationContext(position, tokenLeftOfPosition, cancellationToken) ||
				syntaxTree.IsNamespaceContext(position, cancellationToken) ||
				syntaxTree.IsMemberDeclarationContext(position, tokenLeftOfPosition, cancellationToken) ||
				syntaxTree.IsLabelContext(position, cancellationToken))
			{
				return await GetSnippetCompletionItemsAsync(cancellationToken).ConfigureAwait(false);
			}

			return Enumerable.Empty<CompletionData>();
		}
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var model = ctx.SemanticModel;

			var result = new List<CompletionData> ();
			if (ctx.IsPreProcessorExpressionContext) {
				var parseOptions = model.SyntaxTree.Options as CSharpParseOptions;
				foreach (var define in parseOptions.PreprocessorSymbolNames) {
					result.Add(engine.Factory.CreateGenericData (this, define, GenericDataType.PreprocessorSymbol));
				}
			}
			return result;
		}
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			// var ctx = await completionContext.GetSyntaxContextAsync (engine.Workspace, cancellationToken).ConfigureAwait (false);
			var document = completionContext.Document;
			var semanticModel = ctx.SemanticModel;
			var tree = ctx.SyntaxTree;
			if (tree.IsInNonUserCode(completionContext.Position, cancellationToken))
				return Enumerable.Empty<CompletionData> ();

			var text = await document.GetTextAsync (cancellationToken).ConfigureAwait (false);

			var startLineNumber = text.Lines.IndexOf (completionContext.Position);

			// modifiers* override modifiers* type? |
			Accessibility seenAccessibility;
			//DeclarationModifiers modifiers;
			var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken);
			if (token.Parent == null)
				return Enumerable.Empty<CompletionData> ();

			var parentMember = token.Parent.AncestorsAndSelf ().OfType<MemberDeclarationSyntax> ().FirstOrDefault (m => !m.IsKind (SyntaxKind.IncompleteMember));

			if (!(parentMember is BaseTypeDeclarationSyntax) &&

				/* May happen in case: 
				 * 
				 * override $
				 * public override string Foo () {} 
				 */
				!(token.IsKind (SyntaxKind.OverrideKeyword) && token.Span.Start <= parentMember.Span.Start))
				return Enumerable.Empty<CompletionData> ();

            var position = completionContext.Position;
            var startToken = token.GetPreviousTokenIfTouchingWord(position);
			ITypeSymbol returnType;
			SyntaxToken tokenBeforeReturnType;
			TryDetermineReturnType (startToken, semanticModel, cancellationToken, out returnType, out tokenBeforeReturnType);
			if (returnType == null) {
				var enclosingType = semanticModel.GetEnclosingSymbol (position, cancellationToken) as INamedTypeSymbol;
				if (enclosingType != null && (startToken.IsKind (SyntaxKind.OpenBraceToken) || startToken.IsKind (SyntaxKind.CloseBraceToken) || startToken.IsKind (SyntaxKind.SemicolonToken))) {
					return CreateCompletionData (engine, semanticModel, position, returnType, Accessibility.NotApplicable, startToken, tokenBeforeReturnType, false, cancellationToken);
				}
			}

			if (!TryDetermineModifiers(ref tokenBeforeReturnType, text, startLineNumber, out seenAccessibility/*, out modifiers*/) ||
			    !TryCheckForTrailingTokens (tree, text, startLineNumber, position, cancellationToken)) {
				return Enumerable.Empty<CompletionData> ();
			}

			return CreateCompletionData (engine, semanticModel, position, returnType, seenAccessibility, startToken, tokenBeforeReturnType, true, cancellationToken);
		}
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var document = completionContext.Document;
			var position = completionContext.Position;

			var syntaxTree = ctx.SyntaxTree;
			if (syntaxTree.IsInNonUserCode(position, cancellationToken))
			{
				return null;
			}

			var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken);
			token = token.GetPreviousTokenIfTouchingWord(position);

			if (token.Kind() != SyntaxKind.OpenParenToken && token.Kind() != SyntaxKind.CommaToken)
			{
				return null;
			}

			var attributeArgumentList = token.Parent as AttributeArgumentListSyntax;
			var attributeSyntax = token.Parent.Parent as AttributeSyntax;
			if (attributeSyntax == null || attributeArgumentList == null)
			{
				return null;
			}

			// We actually want to collect two sets of named parameters to present the user.  The
			// normal named parameters that come from the attribute constructors.  These will be
			// presented like "foo:".  And also the named parameters that come from the writable
			// fields/properties in the attribute.  These will be presented like "bar =".  

			var existingNamedParameters = GetExistingNamedParameters(attributeArgumentList, position);

			var workspace = document.Project.Solution.Workspace;
			var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(attributeSyntax, cancellationToken).ConfigureAwait(false);
			var nameColonItems = await GetNameColonItemsAsync(engine, workspace, semanticModel, position, token, attributeSyntax, existingNamedParameters, cancellationToken).ConfigureAwait(false);
			var nameEqualsItems = await GetNameEqualsItemsAsync(engine, workspace, semanticModel, position, token, attributeSyntax, existingNamedParameters, cancellationToken).ConfigureAwait(false);

			// If we're after a name= parameter, then we only want to show name= parameters.
			if (IsAfterNameEqualsArgument(token))
			{
				return nameEqualsItems;
			}

			return nameColonItems.Concat(nameEqualsItems);
		}
		protected override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var document = completionContext.Document;
			var position = completionContext.Position;
			var semanticModel = ctx.SemanticModel;
			if (info.TriggerCharacter == '\\') {
				if (ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null &&
				ctx.TargetToken.Parent.Parent.IsKind (SyntaxKind.Argument)) {
					var argument = ctx.TargetToken.Parent.Parent as ArgumentSyntax;

					var symbolInfo = semanticModel.GetSymbolInfo (ctx.TargetToken.Parent.Parent.Parent.Parent);
					if (symbolInfo.Symbol == null)
						return TaskUtil.EmptyEnumerable<CompletionData> ();

					if (SemanticHighlightingVisitor<int>.IsRegexMatchMethod (symbolInfo)) {
						if (((ArgumentListSyntax)argument.Parent).Arguments [1] != argument)
							return TaskUtil.EmptyEnumerable<CompletionData> ();
						completionResult.AutoSelect = false;
						return Task.FromResult (GetFormatCompletionData (engine, argument.Expression.ToString () [0] == '@'));
					}
					if (SemanticHighlightingVisitor<int>.IsRegexConstructor (symbolInfo)) {
						if (((ArgumentListSyntax)argument.Parent).Arguments [0] != argument)
							return TaskUtil.EmptyEnumerable<CompletionData> ();
						completionResult.AutoSelect = false;
						return Task.FromResult (GetFormatCompletionData (engine, argument.Expression.ToString () [0] == '@'));
					}
				}
			} else {
				var ma = ctx.TargetToken.Parent as MemberAccessExpressionSyntax;
				if (ma != null) {
					var symbolInfo = semanticModel.GetSymbolInfo (ma.Expression);
					var typeInfo = semanticModel.GetTypeInfo (ma.Expression);
					var type = typeInfo.Type;
					if (type != null && type.Name == "Match"  && type.ContainingNamespace.GetFullName () == "System.Text.RegularExpressions" ) {
						var items = new List<CompletionData>();
						foreach (var grp in GetGroups (ctx, symbolInfo.Symbol)) {
							items.Add (engine.Factory.CreateGenericData (this, "Groups[\"" + grp + "\"]", GenericDataType.Undefined));
						}

						return Task.FromResult ((IEnumerable<CompletionData>)items);
					}
				}
			}
			return TaskUtil.EmptyEnumerable<CompletionData> ();
		}
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult result, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var list = new List<CompletionData> ();

			var newExpression = GetObjectCreationNewExpression (ctx.SyntaxTree, completionContext.Position, cancellationToken);
			if (newExpression == null) {
				if (ctx.SyntaxTree.IsInNonUserCode(completionContext.Position, cancellationToken) ||
					ctx.SyntaxTree.IsPreProcessorDirectiveContext(completionContext.Position, cancellationToken))
					return Enumerable.Empty<CompletionData> ();

//				if (!nkr.IsValid (completionContext.Position, ctx.CSharpSyntaxContext, cancellationToken))
//					return Enumerable.Empty<ICompletionData> ();

				var tokenOnLeftOfPosition = ctx.SyntaxTree.FindTokenOnLeftOfPosition (completionContext.Position, cancellationToken);
				if (!tokenOnLeftOfPosition.IsKind (SyntaxKind.EqualsToken) && !tokenOnLeftOfPosition.Parent.IsKind (SyntaxKind.EqualsValueClause))
					return Enumerable.Empty<CompletionData> ();
	
				foreach (var inferredType in SyntaxContext.InferenceService.InferTypes (ctx.CSharpSyntaxContext.SemanticModel, completionContext.Position, cancellationToken)) {
					if (inferredType.IsEnumType () || inferredType.IsInterfaceType () || inferredType.IsAbstract)
						continue;
					foreach (var symbol in await GetPreselectedSymbolsWorker(ctx.CSharpSyntaxContext, inferredType, completionContext.Position - 1, cancellationToken)) {
						var symbolCompletionData = engine.Factory.CreateObjectCreation (this, inferredType, symbol, completionContext.Position, false);
						list.Add (symbolCompletionData);
					}	
				}
				return list;
			}

			var type = SyntaxContext.InferenceService.InferType (ctx.CSharpSyntaxContext.SemanticModel, newExpression, objectAsDefault: false, cancellationToken: cancellationToken);

			foreach (var symbol in await GetPreselectedSymbolsWorker(ctx.CSharpSyntaxContext, type, completionContext.Position, cancellationToken)) {
				var symbolCompletionData = engine.Factory.CreateObjectCreation (this, type, symbol, newExpression.SpanStart, true);
				list.Add (symbolCompletionData);
				if (string.IsNullOrEmpty (result.DefaultCompletionString))
					result.DefaultCompletionString = symbolCompletionData.DisplayText;
			}
			foreach (var keyword in primitiveTypesKeywords) {
				list.Add (engine.Factory.CreateGenericData (this, keyword, GenericDataType.Keyword));
			}
			return list;
		}
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var position = completionContext.Position;
			var document = completionContext.Document;
			var syntaxTree = ctx.SyntaxTree;
			if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
				syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
				return Enumerable.Empty<CompletionData> ();
			if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken))
				return Enumerable.Empty<CompletionData> ();
			var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax;
			if (ma == null)
				return Enumerable.Empty<CompletionData> ();

			var model = ctx.CSharpSyntaxContext.SemanticModel;

			var symbolInfo = model.GetSymbolInfo (ma.Expression);
			if (symbolInfo.Symbol == null)
				return Enumerable.Empty<CompletionData> ();

			var list = new List<CompletionData> ();
			var within = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);
			var addedSymbols = new HashSet<string> ();
			foreach (var ifStmSyntax in ma.Expression.AncestorsAndSelf ().OfType<IfStatementSyntax> ()) {
				var condition = ifStmSyntax.Condition.SkipParens ();
				if (condition == null || !condition.IsKind (SyntaxKind.IsExpression))
					continue;
				var isExpr = ((BinaryExpressionSyntax)condition);
				var leftSymbol = model.GetSymbolInfo (isExpr.Left);

				if (leftSymbol.Symbol == symbolInfo.Symbol) {
					var type = model.GetTypeInfo (isExpr.Right).Type;
					if (type != null) {
						Analyze (engine, ma.Expression, type, within, list, addedSymbols, cancellationToken);
					}
				}
			}

			return list;
		}
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var model = ctx.SemanticModel;
			var tree = ctx.SyntaxTree;
			if (tree.IsInNonUserCode(completionContext.Position, cancellationToken))
				return Enumerable.Empty<CompletionData> ();

			var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken);
			if (token.IsMandatoryNamedParameterPosition())
				return Enumerable.Empty<CompletionData> ();
			var result = new List<CompletionData> ();

			foreach (var _type in ctx.InferredTypes) {
				var type = _type;
				if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) {
					type = type.GetTypeArguments().FirstOrDefault();
					if (type == null)
						continue;
				}

				if (type.TypeKind != TypeKind.Enum)
					continue;
				if (!type.IsEditorBrowsable ())
					continue;

				// Does type have any aliases?
				ISymbol alias = await type.FindApplicableAlias(completionContext.Position, model, cancellationToken).ConfigureAwait(false);

				if (string.IsNullOrEmpty(completionResult.DefaultCompletionString))
					completionResult.DefaultCompletionString = type.Name;

				result.Add (engine.Factory.CreateSymbolCompletionData(this, type, RoslynCompletionData.SafeMinimalDisplayString (type, model, completionContext.Position, SymbolDisplayFormat.CSharpErrorMessageFormat)));
				foreach (IFieldSymbol field in type.GetMembers().OfType<IFieldSymbol>()) {
					if (field.DeclaredAccessibility == Accessibility.Public && (field.IsConst || field.IsStatic)) {
						result.Add (engine.Factory.CreateEnumMemberCompletionData(this, alias, field));
					}
				}
			}
			return result;
		}
		public override async Task<bool> IsExclusiveAsync (CompletionContext completionContext, SyntaxContext ctx, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
		{
			var document = completionContext.Document;
			var position = completionContext.Position;
			var tree = ctx.SyntaxTree;

			//DeclarationModifiers modifiers;
			SyntaxToken token;

			var semanticModel = ctx.SemanticModel;
			var enclosingSymbol = semanticModel.GetEnclosingSymbol (position, cancellationToken) as INamedTypeSymbol;

			// Only inside classes and structs
			if (enclosingSymbol == null || !(enclosingSymbol.TypeKind == TypeKind.Struct || enclosingSymbol.TypeKind == TypeKind.Class)) {
				return false;
			}

			if (!IsPartialCompletionContext (tree, position, cancellationToken/*, out modifiers*/, out token)) {
				return false;
			}

			return true;

		}
示例#19
0
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult result, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var list = new List <CompletionData> ();

            var newExpression = GetObjectCreationNewExpression(ctx.SyntaxTree, completionContext.Position, cancellationToken);

            if (newExpression == null)
            {
                if (ctx.SyntaxTree.IsInNonUserCode(completionContext.Position, cancellationToken) ||
                    ctx.SyntaxTree.IsPreProcessorDirectiveContext(completionContext.Position, cancellationToken))
                {
                    return(Enumerable.Empty <CompletionData> ());
                }

//				if (!nkr.IsValid (completionContext.Position, ctx.CSharpSyntaxContext, cancellationToken))
//					return Enumerable.Empty<ICompletionData> ();

                var tokenOnLeftOfPosition = ctx.SyntaxTree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken);
                if (!tokenOnLeftOfPosition.IsKind(SyntaxKind.EqualsToken) && !tokenOnLeftOfPosition.Parent.IsKind(SyntaxKind.EqualsValueClause))
                {
                    return(Enumerable.Empty <CompletionData> ());
                }

                foreach (var inferredType in SyntaxContext.InferenceService.InferTypes(ctx.CSharpSyntaxContext.SemanticModel, completionContext.Position, cancellationToken))
                {
                    if (inferredType.IsEnumType() || inferredType.IsInterfaceType() || inferredType.IsAbstract)
                    {
                        continue;
                    }
                    foreach (var symbol in await GetPreselectedSymbolsWorker(ctx.CSharpSyntaxContext, inferredType, completionContext.Position - 1, cancellationToken))
                    {
                        var symbolCompletionData = engine.Factory.CreateObjectCreation(this, inferredType, symbol, completionContext.Position, false);
                        list.Add(symbolCompletionData);
                    }
                }
                return(list);
            }


            var expr             = newExpression;
            var assignmentParent = expr.Parent as AssignmentExpressionSyntax;

            // HACK: Work around for a little bug in InferTypes see #41388 - may be obsolete in future roslyn versions. (after 1.2)
            bool skipInference = false;

            if (assignmentParent?.Left == expr)
            {
                skipInference = true;
            }

            if (!skipInference)
            {
                var type = SyntaxContext.InferenceService.InferType(ctx.CSharpSyntaxContext.SemanticModel, expr, objectAsDefault: false, cancellationToken: cancellationToken);

                foreach (var symbol in await GetPreselectedSymbolsWorker(ctx.CSharpSyntaxContext, type, completionContext.Position, cancellationToken))
                {
                    var symbolCompletionData = engine.Factory.CreateObjectCreation(this, type, symbol, newExpression.SpanStart, true);
                    list.Add(symbolCompletionData);
                    if (string.IsNullOrEmpty(result.DefaultCompletionString))
                    {
                        result.DefaultCompletionString = symbolCompletionData.DisplayText;
                        result.AutoCompleteEmptyMatch  = true;
                    }
                }
            }

            for (int i = 0; i < primitiveTypesKeywords.Length; i++)
            {
                var keyword = primitiveTypesKeywords [i];
                list.Add(engine.Factory.CreateKeywordCompletion(this, keyword));
            }

            return(list);
        }
示例#20
0
        public async Task <CompletionResult> GetCompletionDataAsync(CompletionContext completionContext, CompletionTriggerInfo info, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (completionContext == null)
            {
                throw new ArgumentNullException("completionContext");
            }

            var document      = completionContext.Document;
            var semanticModel = await completionContext.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var position = completionContext.Position;
            var text     = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            var ctx = await completionContext.GetSyntaxContextAsync(workspace, cancellationToken);

            ctx.SemanticModel = semanticModel;

            // case lambda parameter (n1, $
            if (ctx.TargetToken.IsKind(SyntaxKind.CommaToken) &&
                ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null &&
                ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.ParenthesizedLambdaExpression))
            {
                return(CompletionResult.Empty);
            }

            var result = new CompletionResult {
                SyntaxContext = ctx
            };

            if (position > 0)
            {
                var nonExclusiveHandlers = new List <CompletionContextHandler> ();
                var exclusiveHandlers    = new List <CompletionContextHandler> ();
                var toRetriggerHandlers  = new List <CompletionContextHandler> ();
                IEnumerable <CompletionContextHandler> handlerList;
                if (completionContext.UseDefaultContextHandlers)
                {
                    handlerList = handlers.Concat(completionContext.AdditionalContextHandlers);
                }
                else
                {
                    handlerList = completionContext.AdditionalContextHandlers;
                }

                foreach (var handler in handlerList)
                {
                    if (info.CompletionTriggerReason == CompletionTriggerReason.CompletionCommand || info.CompletionTriggerReason == CompletionTriggerReason.BackspaceOrDeleteCommand || handler.IsTriggerCharacter(text, position - 1))
                    {
                        if (await handler.IsExclusiveAsync(completionContext, ctx, info, cancellationToken))
                        {
                            exclusiveHandlers.Add(handler);
                        }
                        else
                        {
                            nonExclusiveHandlers.Add(handler);
                        }
                    }
                    else
                    {
                        toRetriggerHandlers.Add(handler);
                    }
                }

                foreach (var handler in exclusiveHandlers)
                {
                    var handlerResult = await handler.GetCompletionDataAsync(result, this, completionContext, info, ctx, cancellationToken);

                    //if (handlerResult != null) {
                    //	Console.WriteLine ("-----" + handler);
                    //	foreach (var item in handlerResult) {
                    //		Console.WriteLine (item.DisplayText);
                    //	}
                    //} else {
                    //	Console.WriteLine ("-----" + handler + " == NULL");
                    //}
                    if (handlerResult != null)
                    {
                        result.AddRange(handlerResult);
                    }
                }

                if (result.Count == 0)
                {
                    foreach (var handler in nonExclusiveHandlers)
                    {
                        var handlerResult = await handler.GetCompletionDataAsync(result, this, completionContext, info, ctx, cancellationToken);

                        //if (handlerResult != null) {
                        //	Console.WriteLine ("-----" + handler);
                        //	foreach (var item in handlerResult) {
                        //		Console.WriteLine (item.DisplayText);
                        //	}
                        //} else {
                        //	Console.WriteLine ("-----" + handler + " == NULL");
                        //}
                        if (handlerResult != null && handlerResult.Any())
                        {
                            result.AddRange(handlerResult);
                        }
                        else
                        {
                            toRetriggerHandlers.Add(handler);
                        }
                    }

                    if (result.Count > 0)
                    {
                        info = info.WithCompletionTriggerReason(CompletionTriggerReason.RetriggerCommand);
                        foreach (var handler in toRetriggerHandlers)
                        {
                            var handlerResult = await handler.GetCompletionDataAsync(result, this, completionContext, info, ctx, cancellationToken);

                            if (handlerResult != null)
                            {
                                result.AddRange(handlerResult);
                            }
                        }
                    }
                }
            }

            // prevent auto selection for "<number>." case
            if (ctx.TargetToken.IsKind(SyntaxKind.DotToken))
            {
                var accessExpr = ctx.TargetToken.Parent as MemberAccessExpressionSyntax;
                if (accessExpr != null &&
                    accessExpr.Expression != null &&
                    accessExpr.Expression.IsKind(SyntaxKind.NumericLiteralExpression))
                {
                    result.AutoSelect = false;
                }
            }

            if (ctx.LeftToken.Parent != null &&
                ctx.LeftToken.Parent.Parent != null &&
                ctx.TargetToken.Parent != null && !ctx.TargetToken.Parent.IsKind(SyntaxKind.NameEquals) &&
                ctx.LeftToken.Parent.Parent.IsKind(SyntaxKind.AnonymousObjectMemberDeclarator))
            {
                result.AutoSelect = false;
            }

            if (ctx.TargetToken.IsKind(SyntaxKind.OpenParenToken) && ctx.TargetToken.GetPreviousToken().IsKind(SyntaxKind.OpenParenToken))
            {
                var validTypes = TypeGuessing.GetValidTypes(semanticModel, ctx.TargetToken.Parent, cancellationToken);
                result.AutoSelect = !validTypes.Any(t => t.IsDelegateType());
            }

            foreach (var type in ctx.InferredTypes)
            {
                if (type.TypeKind == TypeKind.Delegate)
                {
                    result.AutoSelect = false;
                    break;
                }
            }
            if (ctx.CSharpSyntaxContext.IsPossibleTupleContext)
            {
                result.AutoSelect = false;
            }
            return(result);
        }
        protected override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var document = completionContext.Document;
            var position = completionContext.Position;
            var tree     = ctx.SyntaxTree;

            //DeclarationModifiers modifiers;
            SyntaxToken token;

            var semanticModel   = ctx.SemanticModel;
            var enclosingSymbol = semanticModel.GetEnclosingSymbol(position, cancellationToken) as INamedTypeSymbol;

            // Only inside classes and structs
            if (enclosingSymbol == null || !(enclosingSymbol.TypeKind == TypeKind.Struct || enclosingSymbol.TypeKind == TypeKind.Class))
            {
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }

            if (!IsPartialCompletionContext(tree, position, cancellationToken /*, out modifiers*/, out token))
            {
                if (enclosingSymbol != null && (token.IsKind(SyntaxKind.OpenBraceToken) || token.IsKind(SyntaxKind.CloseBraceToken) || token.IsKind(SyntaxKind.SemicolonToken)))
                {
                    return(Task.FromResult(CreateCompletionData(engine, semanticModel, position, enclosingSymbol, token, false, cancellationToken)));
                }
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }

            return(Task.FromResult(CreateCompletionData(engine, semanticModel, position, enclosingSymbol, token, true, cancellationToken)));
        }
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var model = ctx.SemanticModel;

            var result = new List <CompletionData> ();

            if (ctx.IsPreProcessorExpressionContext)
            {
                var parseOptions = model.SyntaxTree.Options as CSharpParseOptions;
                foreach (var define in parseOptions.PreprocessorSymbolNames)
                {
                    result.Add(engine.Factory.CreateGenericData(this, define, GenericDataType.PreprocessorSymbol));
                }
            }
            return(result);
        }
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var document      = completionContext.Document;
            var position      = completionContext.Position;
            var workspace     = document.Project.Solution.Workspace;
            var semanticModel = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false);

            var typeAndLocation = GetInitializedType(document, semanticModel, position, cancellationToken);

            if (typeAndLocation == null)
            {
                return(Enumerable.Empty <CompletionData> ());
            }

            var initializedType     = typeAndLocation.Item1 as INamedTypeSymbol;
            var initializerLocation = typeAndLocation.Item2;

            if (initializedType == null)
            {
                return(Enumerable.Empty <CompletionData> ());
            }

            // Find the members that can be initialized. If we have a NamedTypeSymbol, also get the overridden members.
            IEnumerable <ISymbol> members = semanticModel.LookupSymbols(position, initializedType);

            members = members.Where(m => IsInitializable(m, initializedType) &&
                                    m.CanBeReferencedByName &&
                                    IsLegalFieldOrProperty(m) &&
                                    !m.IsImplicitlyDeclared);

            // Filter out those members that have already been typed
            var alreadyTypedMembers  = GetInitializedMembers(semanticModel.SyntaxTree, position, cancellationToken);
            var uninitializedMembers = members.Where(m => !alreadyTypedMembers.Contains(m.Name));

            uninitializedMembers = uninitializedMembers.Where(m => m.IsEditorBrowsable());

            // var text = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);
            // var changes = GetTextChangeSpan(text, position);
            var list = new List <CompletionData> ();

            // Return the members
            foreach (var member in uninitializedMembers)
            {
                list.Add(engine.Factory.CreateSymbolCompletionData(this, member));
            }
            return(list);
        }
        protected override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var model = ctx.SemanticModel;

            if (ctx.CSharpSyntaxContext.IsInNonUserCode)
            {
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }

            if (ctx.TargetToken.IsKind(SyntaxKind.OverrideKeyword))
            {
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }

            if (info.CompletionTriggerReason == CompletionTriggerReason.CharTyped && info.TriggerCharacter == ' ')
            {
                if (!ctx.CSharpSyntaxContext.IsEnumBaseListContext && !ctx.LeftToken.IsKind(SyntaxKind.EqualsToken) && !ctx.LeftToken.IsKind(SyntaxKind.EqualsEqualsToken))
                {
                    return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
                }
//				completionResult.AutoCompleteEmptyMatch = false;
            }

            var result = new List <CompletionData> ();

            foreach (var r in recommender)
            {
                var recommended = r.RecommendKeywords(completionContext.Position, ctx.CSharpSyntaxContext, cancellationToken);
                if (recommended == null)
                {
                    continue;
                }
                foreach (var kw in recommended)
                {
                    result.Add(engine.Factory.CreateKeywordCompletion(this, kw.Keyword, kw.Kind));
                }
            }

//			if (ctx.IsPreProcessorKeywordContext) {
//				foreach (var kw in preprocessorKeywords)
//					result.Add(factory.CreateGenericData (this, kw, GenericDataType.PreprocessorKeyword));
//			}
//

//			if (parent.IsKind(SyntaxKind.TypeParameterConstraintClause)) {
//				result.Add(factory.CreateGenericData (this, "new()", GenericDataType.PreprocessorKeyword));
//			}
            return(Task.FromResult((IEnumerable <CompletionData>)result));
        }
示例#25
0
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            if (info.IsDebugger)
            {
                return(null);
            }
            if (info.CompletionTriggerReason == CompletionTriggerReason.BackspaceOrDeleteCommand)
            {
                return(null);
            }
            var document = completionContext.Document;
            var position = completionContext.Position;

            var tree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            var token        = tree.FindTokenOnLeftOfPosition(position, cancellationToken);
            var parentTrivia = token.GetAncestor <DocumentationCommentTriviaSyntax>();

            if (parentTrivia == null)
            {
                return(null);
            }

            var items = new List <CompletionData>();
            var text  = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            var span = GetTextChangeSpan(text, position);

            var attachedToken = parentTrivia.ParentTrivia.Token;

            if (attachedToken.Kind() == SyntaxKind.None)
            {
                return(null);
            }

            var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(attachedToken.Parent, cancellationToken).ConfigureAwait(false);

            ISymbol declaredSymbol    = null;
            var     memberDeclaration = attachedToken.GetAncestor <MemberDeclarationSyntax>();

            if (memberDeclaration != null)
            {
                declaredSymbol = semanticModel.GetDeclaredSymbol(memberDeclaration, cancellationToken);
            }
            else
            {
                var typeDeclaration = attachedToken.GetAncestor <TypeDeclarationSyntax>();
                if (typeDeclaration != null)
                {
                    declaredSymbol = semanticModel.GetDeclaredSymbol(typeDeclaration, cancellationToken);
                }
            }

            if (declaredSymbol != null)
            {
                items.AddRange(GetTagsForSymbol(engine, declaredSymbol, span, parentTrivia, token));
            }

            if (token.Parent.Kind() == SyntaxKind.XmlEmptyElement || token.Parent.Kind() == SyntaxKind.XmlText ||
                (token.Parent.IsKind(SyntaxKind.XmlElementEndTag) && token.IsKind(SyntaxKind.GreaterThanToken)) ||
                (token.Parent.IsKind(SyntaxKind.XmlName) && token.Parent.IsParentKind(SyntaxKind.XmlEmptyElement)))
            {
                if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement)
                {
                    items.AddRange(GetNestedTags(engine, span));
                }

                if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == "list")
                {
                    items.AddRange(GetListItems(engine, span));
                }

                if (token.Parent.IsParentKind(SyntaxKind.XmlEmptyElement) & token.Parent.Parent.IsParentKind(SyntaxKind.XmlElement))
                {
                    var element = (XmlElementSyntax)token.Parent.Parent.Parent;
                    if (element.StartTag.Name.LocalName.ValueText == "list")
                    {
                        items.AddRange(GetListItems(engine, span));
                    }
                }

                if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == "listheader")
                {
                    items.AddRange(GetListHeaderItems(engine, span));
                }

                if (token.Parent.Parent is DocumentationCommentTriviaSyntax)
                {
                    items.AddRange(GetTopLevelSingleUseNames(engine, parentTrivia, span));
                    items.AddRange(GetTopLevelRepeatableItems(engine, span));
                }
            }

            if (token.Parent.Kind() == SyntaxKind.XmlElementStartTag)
            {
                var startTag = (XmlElementStartTagSyntax)token.Parent;

                if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == "list")
                {
                    items.AddRange(GetListItems(engine, span));
                }

                if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == "listheader")
                {
                    items.AddRange(GetListHeaderItems(engine, span));
                }
            }

            items.AddRange(GetAlwaysVisibleItems(engine, span));
            return(items);
        }
示例#26
0
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var document = completionContext.Document;
            var position = completionContext.Position;

            return(await document.GetUnionResultsFromDocumentAndLinks(
                       UnionCompletionItemComparer.Instance,
                       async (doc, ct) => await GetSpeculativeTCompletions(engine, doc, position, ct).ConfigureAwait(false),
                       cancellationToken).ConfigureAwait(false));
        }
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var document   = completionContext.Document;
            var position   = completionContext.Position;
            var syntaxTree = ctx.SyntaxTree;

            if (syntaxTree.IsInNonUserCode(position, cancellationToken))
            {
                return(null);
            }

            var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken);

            token = token.GetPreviousTokenIfTouchingWord(position);

            if (token.Kind() != SyntaxKind.OpenParenToken &&
                token.Kind() != SyntaxKind.OpenBracketToken &&
                token.Kind() != SyntaxKind.CommaToken)
            {
                return(null);
            }

            var argumentList = token.Parent as BaseArgumentListSyntax;

            if (argumentList == null)
            {
                return(null);
            }

            var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(argumentList, cancellationToken).ConfigureAwait(false);

            var parameterLists = GetParameterLists(semanticModel, position, argumentList.Parent, cancellationToken);

            if (parameterLists == null)
            {
                return(null);
            }

            var existingNamedParameters = GetExistingNamedParameters(argumentList, position);

            parameterLists = parameterLists.Where(pl => IsValid(pl, existingNamedParameters));

            var unspecifiedParameters = parameterLists.SelectMany(pl => pl)
                                        .Where(p => !existingNamedParameters.Contains(p.Name))
                                        .Distinct(this);

            // var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            return(unspecifiedParameters
                   .Select(p => engine.Factory.CreateGenericData(this, p.Name + ":", GenericDataType.NamedParameter)));
        }
		protected async Task<bool> IsExclusiveAsync(Document document, int caretPosition, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
		{
			var syntaxTree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
			var token = syntaxTree.FindTokenOnLeftOfPosition(caretPosition, cancellationToken)
				.GetPreviousTokenIfTouchingWord(caretPosition);

			return IsAfterNameColonArgument(token) || IsAfterNameEqualsArgument(token);
		}
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			if (info.IsDebugger)
			{
				return null;
			}
			var document = completionContext.Document;
			var position = completionContext.Position;

			var tree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
			var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken);
			var parentTrivia = token.GetAncestor<DocumentationCommentTriviaSyntax>();

			if (parentTrivia == null)
			{
				return null;
			}

			var items = new List<CompletionData>();
			var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
			var span = GetTextChangeSpan(text, position);

			var attachedToken = parentTrivia.ParentTrivia.Token;
			if (attachedToken.Kind() == SyntaxKind.None)
			{
				return null;
			}

			var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(attachedToken.Parent, cancellationToken).ConfigureAwait(false);

			ISymbol declaredSymbol = null;
			var memberDeclaration = attachedToken.GetAncestor<MemberDeclarationSyntax>();
			if (memberDeclaration != null)
			{
				declaredSymbol = semanticModel.GetDeclaredSymbol(memberDeclaration, cancellationToken);
			}
			else
			{
				var typeDeclaration = attachedToken.GetAncestor<TypeDeclarationSyntax>();
				if (typeDeclaration != null)
				{
					declaredSymbol = semanticModel.GetDeclaredSymbol(typeDeclaration, cancellationToken);
				}
			}

			if (declaredSymbol != null)
			{
				items.AddRange(GetTagsForSymbol(engine, declaredSymbol, span, parentTrivia, token));
			}

			if (token.Parent.Kind() == SyntaxKind.XmlEmptyElement || token.Parent.Kind() == SyntaxKind.XmlText ||
				(token.Parent.IsKind(SyntaxKind.XmlElementEndTag) && token.IsKind(SyntaxKind.GreaterThanToken)) ||
				(token.Parent.IsKind(SyntaxKind.XmlName) && token.Parent.IsParentKind(SyntaxKind.XmlEmptyElement)))
			{
				if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement)
				{
					items.AddRange(GetNestedTags(engine, span));
				}

				if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == "list")
				{
					items.AddRange(GetListItems(engine, span));
				}

				if (token.Parent.IsParentKind(SyntaxKind.XmlEmptyElement) & token.Parent.Parent.IsParentKind(SyntaxKind.XmlElement))
				{
					var element = (XmlElementSyntax)token.Parent.Parent.Parent;
					if (element.StartTag.Name.LocalName.ValueText == "list")
					{
						items.AddRange(GetListItems(engine, span));
					}
				}

				if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == "listheader")
				{
					items.AddRange(GetListHeaderItems(engine, span));
				}

				if (token.Parent.Parent is DocumentationCommentTriviaSyntax)
				{
					items.AddRange(GetTopLevelSingleUseNames(engine, parentTrivia, span));
					items.AddRange(GetTopLevelRepeatableItems(engine, span));
				}
			}

			if (token.Parent.Kind() == SyntaxKind.XmlElementStartTag)
			{
				var startTag = (XmlElementStartTagSyntax)token.Parent;

				if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == "list")
				{
					items.AddRange(GetListItems(engine, span));
				}

				if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == "listheader")
				{
					items.AddRange(GetListHeaderItems(engine, span));
				}
			}

			items.AddRange(GetAlwaysVisibleItems(engine, span));
			return items;
		}
		public override async Task<bool> IsExclusiveAsync(CompletionContext completionContext, SyntaxContext syntaxContext, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
		{
			var syntaxTree = await completionContext.Document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
			var token = syntaxTree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken)
			                      .GetPreviousTokenIfTouchingWord(completionContext.Position);

			return IsAfterNameColonArgument(token) || IsAfterNameEqualsArgument(token);
		}
示例#31
0
        protected override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var position   = completionContext.Position;
            var document   = completionContext.Document;
            var syntaxTree = ctx.SyntaxTree;

            if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
                syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
            {
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }
            if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken))
            {
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }
            var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax;

            if (ma == null)
            {
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }

            var model = ctx.CSharpSyntaxContext.SemanticModel;

            var symbolInfo = model.GetSymbolInfo(ma.Expression);

            if (symbolInfo.Symbol == null || symbolInfo.Symbol.Kind != SymbolKind.Parameter)
            {
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }
            var list         = new List <CompletionData> ();
            var within       = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);
            var addedSymbols = new HashSet <string> ();

            foreach (var ano in ma.AncestorsAndSelf().OfType <AnonymousMethodExpressionSyntax> ())
            {
                Analyze(engine, model, ma.Expression, within, list, ano.ParameterList, symbolInfo.Symbol, addedSymbols, cancellationToken);
            }

            foreach (var ano in ma.AncestorsAndSelf().OfType <ParenthesizedLambdaExpressionSyntax> ())
            {
                Analyze(engine, model, ma.Expression, within, list, ano.ParameterList, symbolInfo.Symbol, addedSymbols, cancellationToken);
            }

            return(Task.FromResult((IEnumerable <CompletionData>)list));
        }
示例#32
0
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var document = completionContext.Document;
            var position = completionContext.Position;

            var syntaxTree = ctx.SyntaxTree;

            if (syntaxTree.IsInNonUserCode(position, cancellationToken))
            {
                return(null);
            }

            var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken);

            token = token.GetPreviousTokenIfTouchingWord(position);

            if (token.Kind() != SyntaxKind.OpenParenToken && token.Kind() != SyntaxKind.CommaToken)
            {
                return(null);
            }

            var attributeArgumentList = token.Parent as AttributeArgumentListSyntax;
            var attributeSyntax       = token.Parent.Parent as AttributeSyntax;

            if (attributeSyntax == null || attributeArgumentList == null)
            {
                return(null);
            }

            // We actually want to collect two sets of named parameters to present the user.  The
            // normal named parameters that come from the attribute constructors.  These will be
            // presented like "foo:".  And also the named parameters that come from the writable
            // fields/properties in the attribute.  These will be presented like "bar =".

            var existingNamedParameters = GetExistingNamedParameters(attributeArgumentList, position);

            var workspace     = document.Project.Solution.Workspace;
            var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(attributeSyntax, cancellationToken).ConfigureAwait(false);

            var nameColonItems = await GetNameColonItemsAsync(engine, workspace, semanticModel, position, token, attributeSyntax, existingNamedParameters, cancellationToken).ConfigureAwait(false);

            var nameEqualsItems = await GetNameEqualsItemsAsync(engine, workspace, semanticModel, position, token, attributeSyntax, existingNamedParameters, cancellationToken).ConfigureAwait(false);

            // If we're after a name= parameter, then we only want to show name= parameters.
            if (IsAfterNameEqualsArgument(token))
            {
                return(nameEqualsItems);
            }

            return(nameColonItems.Concat(nameEqualsItems));
        }
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult result, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var list = new List<CompletionData> ();

			var newExpression = GetObjectCreationNewExpression (ctx.SyntaxTree, completionContext.Position, cancellationToken);

			if (newExpression == null) {
				if (ctx.SyntaxTree.IsInNonUserCode(completionContext.Position, cancellationToken) ||
					ctx.SyntaxTree.IsPreProcessorDirectiveContext(completionContext.Position, cancellationToken))
					return Enumerable.Empty<CompletionData> ();

//				if (!nkr.IsValid (completionContext.Position, ctx.CSharpSyntaxContext, cancellationToken))
//					return Enumerable.Empty<ICompletionData> ();

				var tokenOnLeftOfPosition = ctx.SyntaxTree.FindTokenOnLeftOfPosition (completionContext.Position, cancellationToken);
				if (!tokenOnLeftOfPosition.IsKind (SyntaxKind.EqualsToken) && !tokenOnLeftOfPosition.Parent.IsKind (SyntaxKind.EqualsValueClause))
					return Enumerable.Empty<CompletionData> ();
	
				foreach (var inferredType in SyntaxContext.InferenceService.InferTypes (ctx.CSharpSyntaxContext.SemanticModel, completionContext.Position, cancellationToken)) {
					if (inferredType.IsEnumType () || inferredType.IsInterfaceType () || inferredType.IsAbstract)
						continue;
					foreach (var symbol in await GetPreselectedSymbolsWorker(ctx.CSharpSyntaxContext, inferredType, completionContext.Position - 1, cancellationToken)) {
						var symbolCompletionData = engine.Factory.CreateObjectCreation (this, inferredType, symbol, completionContext.Position, false);
						list.Add (symbolCompletionData);
					}	
				}
				return list;
			}


			var expr = newExpression;
			var assignmentParent = expr.Parent as AssignmentExpressionSyntax;

			// HACK: Work around for a little bug in InferTypes see #41388 - may be obsolete in future roslyn versions. (after 1.2)
			bool skipInference = false;
			if (assignmentParent?.Left == expr) {
				skipInference = true;
			}

			if (!skipInference) {
				var type = SyntaxContext.InferenceService.InferType (ctx.CSharpSyntaxContext.SemanticModel, expr, objectAsDefault: false, cancellationToken: cancellationToken);

				foreach (var symbol in await GetPreselectedSymbolsWorker (ctx.CSharpSyntaxContext, type, completionContext.Position, cancellationToken)) {
					var symbolCompletionData = engine.Factory.CreateObjectCreation (this, type, symbol, newExpression.SpanStart, true);
					list.Add (symbolCompletionData);
					if (string.IsNullOrEmpty (result.DefaultCompletionString)) {
						result.DefaultCompletionString = symbolCompletionData.DisplayText;
						result.AutoCompleteEmptyMatch = true;
					}
				}
			}

			for (int i = 0; i < primitiveTypesKeywords.Length; i++) {
				var keyword = primitiveTypesKeywords [i];
				list.Add (engine.Factory.CreateKeywordCompletion (this, keyword, primitiveTypesKeywordKinds[i]));
			}

			return list;
		}
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            // var ctx = await completionContext.GetSyntaxContextAsync (engine.Workspace, cancellationToken).ConfigureAwait (false);
            var document      = completionContext.Document;
            var semanticModel = ctx.SemanticModel;
            var tree          = ctx.SyntaxTree;

            if (tree.IsInNonUserCode(completionContext.Position, cancellationToken))
            {
                return(Enumerable.Empty <CompletionData> ());
            }

            var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            var startLineNumber = text.Lines.IndexOf(completionContext.Position);

            // modifiers* override modifiers* type? |
            Accessibility seenAccessibility;
            //DeclarationModifiers modifiers;
            var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken);

            if (token.Parent == null)
            {
                return(Enumerable.Empty <CompletionData> ());
            }

            var parentMember = token.Parent.AncestorsAndSelf().OfType <MemberDeclarationSyntax> ().FirstOrDefault(m => !m.IsKind(SyntaxKind.IncompleteMember));

            if (!(parentMember is BaseTypeDeclarationSyntax) &&

                /* May happen in case:
                 *
                 * override $
                 * public override string Foo () {}
                 */
                !(token.IsKind(SyntaxKind.OverrideKeyword) && token.Span.Start <= parentMember.Span.Start))
            {
                return(Enumerable.Empty <CompletionData> ());
            }

            var         position   = completionContext.Position;
            var         startToken = token.GetPreviousTokenIfTouchingWord(position);
            ITypeSymbol returnType;
            SyntaxToken tokenBeforeReturnType;

            TryDetermineReturnType(startToken, semanticModel, cancellationToken, out returnType, out tokenBeforeReturnType);
            if (returnType == null)
            {
                var enclosingType = semanticModel.GetEnclosingSymbol(position, cancellationToken) as INamedTypeSymbol;
                if (enclosingType != null && (startToken.IsKind(SyntaxKind.OpenBraceToken) || startToken.IsKind(SyntaxKind.CloseBraceToken) || startToken.IsKind(SyntaxKind.SemicolonToken)))
                {
                    return(CreateCompletionData(engine, semanticModel, position, returnType, Accessibility.NotApplicable, startToken, tokenBeforeReturnType, false, cancellationToken));
                }
            }

            if (!TryDetermineModifiers(ref tokenBeforeReturnType, text, startLineNumber, out seenAccessibility /*, out modifiers*/) ||
                !TryCheckForTrailingTokens(tree, text, startLineNumber, position, cancellationToken))
            {
                return(Enumerable.Empty <CompletionData> ());
            }

            return(CreateCompletionData(engine, semanticModel, position, returnType, seenAccessibility, startToken, tokenBeforeReturnType, true, cancellationToken));
        }
示例#35
0
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var position      = completionContext.Position;
            var document      = completionContext.Document;
            var span          = new TextSpan(position, 0);
            var semanticModel = await document.GetCSharpSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false);

            var syntaxTree = semanticModel.SyntaxTree;

            //	var ctx = await completionContext.GetSyntaxContextAsync (engine.Workspace, cancellationToken).ConfigureAwait (false);

            if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
                syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
            {
                return(Enumerable.Empty <CompletionData> ());
            }

            if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken))
            {
                return(Enumerable.Empty <CompletionData> ());
            }

            var node = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken)
                       .GetPreviousTokenIfTouchingWord(position)
                       .Parent;

            if (node.Kind() == SyntaxKind.ExplicitInterfaceSpecifier)
            {
                return(await GetCompletionsOffOfExplicitInterfaceAsync(
                           engine, document, semanticModel, position, ((ExplicitInterfaceSpecifierSyntax)node).Name, cancellationToken).ConfigureAwait(false));
            }

            return(Enumerable.Empty <CompletionData> ());
        }
示例#36
0
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var tree = await completionContext.Document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            if (tree.IsInNonUserCode(completionContext.Position, cancellationToken) ||
                tree.IsPreProcessorDirectiveContext(completionContext.Position, cancellationToken) ||
                info.CompletionTriggerReason != CompletionTriggerReason.CompletionCommand)
            {
                return(Enumerable.Empty <CompletionData>());
            }

            var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken);

            if (token.Span.End == completionContext.Position)
            {
                return(Enumerable.Empty <CompletionData>());
            }
            var parent = token.Parent.AncestorsAndSelf().OfType <GenericNameSyntax> ().FirstOrDefault() ?? token.Parent;

            if (!parent.Parent.IsKind(SyntaxKind.IncompleteMember) &&
                !IsLocal(parent) &&
                !parent.Parent.IsKind(SyntaxKind.Parameter) &&
                !parent.Parent.IsKind(SyntaxKind.ForEachStatement))
            {
                return(Enumerable.Empty <CompletionData>());
            }

            if (info.TriggerCharacter != ' ' &&
                parent.Parent.IsKind(SyntaxKind.ExpressionStatement))
            {
                return(Enumerable.Empty <CompletionData>());
            }
            var list = new List <CompletionData> ();

            if (parent.IsKind(SyntaxKind.PredefinedType))
            {
                switch (token.Kind())
                {
                case SyntaxKind.ObjectKeyword:
                    list.Add(engine.Factory.CreateGenericData(this, "o", GenericDataType.NameProposal));
                    list.Add(engine.Factory.CreateGenericData(this, "obj", GenericDataType.NameProposal));
                    return(list);

                case SyntaxKind.BoolKeyword:
                    list.Add(engine.Factory.CreateGenericData(this, "b", GenericDataType.NameProposal));
                    list.Add(engine.Factory.CreateGenericData(this, "pred", GenericDataType.NameProposal));
                    return(list);

                case SyntaxKind.CharKeyword:
                    list.Add(engine.Factory.CreateGenericData(this, "c", GenericDataType.NameProposal));
                    list.Add(engine.Factory.CreateGenericData(this, "ch", GenericDataType.NameProposal));
                    return(list);

                case SyntaxKind.StringKeyword:
                    list.Add(engine.Factory.CreateGenericData(this, "str", GenericDataType.NameProposal));
                    return(list);

                case SyntaxKind.DoubleKeyword:
                case SyntaxKind.FloatKeyword:
                case SyntaxKind.DecimalKeyword:
                    list.Add(engine.Factory.CreateGenericData(this, "d", GenericDataType.NameProposal));
                    list.Add(engine.Factory.CreateGenericData(this, "f", GenericDataType.NameProposal));
                    list.Add(engine.Factory.CreateGenericData(this, "m", GenericDataType.NameProposal));
                    return(list);

                default:
                    list.Add(engine.Factory.CreateGenericData(this, "i", GenericDataType.NameProposal));
                    list.Add(engine.Factory.CreateGenericData(this, "j", GenericDataType.NameProposal));
                    list.Add(engine.Factory.CreateGenericData(this, "k", GenericDataType.NameProposal));
                    return(list);
                }
            }
            else
            {
                var incompleteMember = parent.Parent as IncompleteMemberSyntax;
                if (incompleteMember != null)
                {
                    return(list);
                }
                var gns          = parent as GenericNameSyntax;
                var names        = WordParser.BreakWords(gns != null ? gns.Identifier.ToString() : token.ToString().Trim());
                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]);
                    }
                    list.Add(engine.Factory.CreateGenericData(this, possibleName.ToString(), GenericDataType.NameProposal));
                }
            }
            return(list);
        }
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var document = completionContext.Document;
            var position = completionContext.Position;

            var tree = ctx.SyntaxTree;

            if (tree.IsInNonUserCode(position, cancellationToken))
            {
                return(Enumerable.Empty <CompletionData> ());
            }

            var targetToken = tree.FindTokenOnLeftOfPosition(position, cancellationToken).GetPreviousTokenIfTouchingWord(position);

            if (targetToken.IsKind(SyntaxKind.AliasKeyword) && targetToken.Parent.IsKind(SyntaxKind.ExternAliasDirective))
            {
                var compilation = await document.GetCSharpCompilationAsync(cancellationToken).ConfigureAwait(false);

                var aliases = compilation.ExternalReferences.Where(r => r.Properties.Aliases != null).SelectMany(r => r.Properties.Aliases).ToSet();

                if (aliases.Any())
                {
                    var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false);

                    var usedAliases = root.ChildNodes().OfType <ExternAliasDirectiveSyntax>().Where(e => !e.Identifier.IsMissing).Select(e => e.Identifier.ValueText);
                    foreach (var used in usedAliases)
                    {
                        aliases.Remove(used);
                    }
                    aliases.Remove(MetadataReferenceProperties.GlobalAlias);
                    return(aliases.Select(e => engine.Factory.CreateGenericData(this, e, GenericDataType.Undefined)));
                }
            }

            return(Enumerable.Empty <CompletionData> ());
        }
示例#38
0
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var document = completionContext.Document;
            var position = completionContext.Position;

            var syntaxTree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
                syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken) ||
                syntaxTree.GetContainingTypeOrEnumDeclaration(position, cancellationToken) is EnumDeclarationSyntax)
            {
                return(Enumerable.Empty <CompletionData>());
            }

            // var span = new TextSpan(position, 0);
//			var semanticModel = await document.GetCSharpSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false);
            if (syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
            {
                var directive = syntaxTree.GetRoot(cancellationToken).FindTokenOnLeftOfPosition(position, includeDirectives: true).GetAncestor <DirectiveTriviaSyntax>();
                if (directive.DirectiveNameToken.IsKind(
                        SyntaxKind.IfKeyword,
                        SyntaxKind.RegionKeyword,
                        SyntaxKind.ElseKeyword,
                        SyntaxKind.ElifKeyword,
                        SyntaxKind.ErrorKeyword,
                        SyntaxKind.LineKeyword,
                        SyntaxKind.PragmaKeyword,
                        SyntaxKind.EndIfKeyword,
                        SyntaxKind.UndefKeyword,
                        SyntaxKind.EndRegionKeyword,
                        SyntaxKind.WarningKeyword))
                {
                    return(Enumerable.Empty <CompletionData>());
                }

                return(await GetSnippetCompletionItemsAsync(cancellationToken).ConfigureAwait(false));
            }
            var tokenLeftOfPosition = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken);

            if (syntaxTree.IsGlobalStatementContext(position, cancellationToken) ||
                syntaxTree.IsExpressionContext(position, tokenLeftOfPosition, true, cancellationToken) ||
                syntaxTree.IsStatementContext(position, tokenLeftOfPosition, cancellationToken) ||
                syntaxTree.IsTypeContext(position, cancellationToken) ||
                syntaxTree.IsTypeDeclarationContext(position, tokenLeftOfPosition, cancellationToken) ||
                syntaxTree.IsNamespaceContext(position, cancellationToken) ||
                syntaxTree.IsMemberDeclarationContext(position, tokenLeftOfPosition, cancellationToken) ||
                syntaxTree.IsLabelContext(position, cancellationToken))
            {
                return(await GetSnippetCompletionItemsAsync(cancellationToken).ConfigureAwait(false));
            }

            return(Enumerable.Empty <CompletionData>());
        }
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var model = ctx.SemanticModel;
            var tree  = ctx.SyntaxTree;

            if (tree.IsInNonUserCode(completionContext.Position, cancellationToken))
            {
                return(Enumerable.Empty <CompletionData> ());
            }

            var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken);

            if (token.IsMandatoryNamedParameterPosition())
            {
                return(Enumerable.Empty <CompletionData> ());
            }
            var result = new List <CompletionData> ();

            foreach (var _type in ctx.InferredTypes)
            {
                var type = _type;
                if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
                {
                    type = type.GetTypeArguments().FirstOrDefault();
                    if (type == null)
                    {
                        continue;
                    }
                }

                if (type.TypeKind != TypeKind.Enum)
                {
                    continue;
                }
                if (!type.IsEditorBrowsable())
                {
                    continue;
                }

                // Does type have any aliases?
                ISymbol alias = await type.FindApplicableAlias(completionContext.Position, model, cancellationToken).ConfigureAwait(false);

                if (string.IsNullOrEmpty(completionResult.DefaultCompletionString))
                {
                    completionResult.DefaultCompletionString = type.Name;
                }

                result.Add(engine.Factory.CreateSymbolCompletionData(this, type, RoslynCompletionData.SafeMinimalDisplayString(type, model, completionContext.Position, SymbolDisplayFormat.CSharpErrorMessageFormat)));
                foreach (IFieldSymbol field in type.GetMembers().OfType <IFieldSymbol>())
                {
                    if (field.DeclaredAccessibility == Accessibility.Public && (field.IsConst || field.IsStatic))
                    {
                        result.Add(engine.Factory.CreateEnumMemberCompletionData(this, alias, field));
                    }
                }
            }
            return(result);
        }
        public override async Task <bool> IsExclusiveAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            // We're exclusive if this context could only be an object initializer and not also a
            // collection initializer. If we're initializing something that could be initialized as
            // an object or as a collection, say we're not exclusive. That way the rest of
            // intellisense can be used in the collection intitializer.
            //
            // Consider this case:

            // class c : IEnumerable<int>
            // {
            // public void Add(int addend) { }
            // public int foo;
            // }

            // void foo()
            // {
            //    var b = new c {|
            // }

            // There we could initialize b using either an object initializer or a collection
            // initializer. Since we don't know which the user will use, we'll be non-exclusive, so
            // the other providers can help the user write the collection initializer, if they want
            // to.
            var tree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            if (tree.IsInNonUserCode(position, cancellationToken))
            {
                return(false);
            }

            var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken);

            token = token.GetPreviousTokenIfTouchingWord(position);

            if (token.Parent == null)
            {
                return(false);
            }

            var expression = token.Parent.Parent as ExpressionSyntax;

            if (expression == null)
            {
                return(false);
            }

            var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(expression, cancellationToken).ConfigureAwait(false);

            var initializedType = semanticModel.GetTypeInfo(expression, cancellationToken).Type;

            if (initializedType == null)
            {
                return(false);
            }

            // Non-exclusive if initializedType can be initialized as a collection.
            if (initializedType.CanSupportCollectionInitializer())
            {
                return(false);
            }

            // By default, only our member names will show up.
            return(true);
        }
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var document      = completionContext.Document;
            var position      = completionContext.Position;
            var semanticModel = ctx.SemanticModel;

            if (ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null &&
                ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.Argument))
            {
                SourceText text;
                if (!completionContext.Document.TryGetText(out text))
                {
                    text = await completionContext.Document.GetTextAsync();
                }
                var currentChar = text [completionContext.Position - 1];
                if (ctx.TargetToken.Parent == null || !ctx.TargetToken.Parent.IsKind(SyntaxKind.StringLiteralExpression) ||
                    ctx.TargetToken.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.Argument) ||
                    ctx.TargetToken.Parent.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.Parent.IsKind(SyntaxKind.ArgumentList) ||
                    ctx.TargetToken.Parent.Parent.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.Parent.Parent.IsKind(SyntaxKind.InvocationExpression))
                {
                    return(Enumerable.Empty <CompletionData> ());
                }
                var formatArgument       = GetFormatItemNumber(document, position);
                var invocationExpression = ctx.TargetToken.Parent.Parent.Parent.Parent as InvocationExpressionSyntax;
                return(GetFormatCompletionData(engine, semanticModel, invocationExpression, formatArgument, currentChar));
            }

            return(Enumerable.Empty <CompletionData> ());
        }
        public override Task <bool> IsExclusiveAsync(CompletionContext completionContext, SyntaxContext ctx, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var document = completionContext.Document;
            var position = completionContext.Position;
            var tree     = ctx.SyntaxTree;

            //DeclarationModifiers modifiers;
            SyntaxToken token;

            var semanticModel   = ctx.SemanticModel;
            var enclosingSymbol = semanticModel.GetEnclosingSymbol(position, cancellationToken) as INamedTypeSymbol;

            // Only inside classes and structs
            if (enclosingSymbol == null || !(enclosingSymbol.TypeKind == TypeKind.Struct || enclosingSymbol.TypeKind == TypeKind.Class))
            {
                return(Task.FromResult(false));
            }

            if (!IsPartialCompletionContext(tree, position, cancellationToken /*, out modifiers*/, out token))
            {
                return(Task.FromResult(false));
            }

            return(Task.FromResult(true));
        }
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var position   = completionContext.Position;
            var document   = completionContext.Document;
            var syntaxTree = ctx.SyntaxTree;

            if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
                syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
            {
                return(Enumerable.Empty <CompletionData> ());
            }
            if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken))
            {
                return(Enumerable.Empty <CompletionData> ());
            }
            var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax;

            if (ma == null)
            {
                return(Enumerable.Empty <CompletionData> ());
            }

            var model = ctx.CSharpSyntaxContext.SemanticModel;

            var symbolInfo = model.GetSymbolInfo(ma.Expression);

            if (symbolInfo.Symbol == null)
            {
                return(Enumerable.Empty <CompletionData> ());
            }

            var list         = new List <CompletionData> ();
            var within       = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);
            var addedSymbols = new HashSet <string> ();

            foreach (var ifStmSyntax in ma.Expression.AncestorsAndSelf().OfType <IfStatementSyntax> ())
            {
                var condition = ifStmSyntax.Condition.SkipParens();
                if (condition == null || !condition.IsKind(SyntaxKind.IsExpression))
                {
                    continue;
                }
                var isExpr     = ((BinaryExpressionSyntax)condition);
                var leftSymbol = model.GetSymbolInfo(isExpr.Left);

                if (leftSymbol.Symbol == symbolInfo.Symbol)
                {
                    var type = model.GetTypeInfo(isExpr.Right).Type;
                    if (type != null)
                    {
                        Analyze(engine, ma.Expression, type, within, list, addedSymbols, cancellationToken);
                    }
                }
            }

            return(list);
        }
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var document = completionContext.Document;
			var position = completionContext.Position;
			var workspace = document.Project.Solution.Workspace;
			var semanticModel = await document.GetSemanticModelForSpanAsync (new TextSpan (position, 0), cancellationToken).ConfigureAwait (false);
			var typeAndLocation = GetInitializedType (document, semanticModel, position, cancellationToken);
			if (typeAndLocation == null)
				return Enumerable.Empty<CompletionData> ();

			var initializedType = typeAndLocation.Item1 as INamedTypeSymbol;
			var initializerLocation = typeAndLocation.Item2;
			if (initializedType == null)
				return Enumerable.Empty<CompletionData> ();

			// Find the members that can be initialized. If we have a NamedTypeSymbol, also get the overridden members.
			IEnumerable<ISymbol> members = semanticModel.LookupSymbols (position, initializedType);
			members = members.Where (m => IsInitializable (m, initializedType) &&
				 m.CanBeReferencedByName &&
				 IsLegalFieldOrProperty (m) &&
				 !m.IsImplicitlyDeclared);

			// Filter out those members that have already been typed
			var alreadyTypedMembers = GetInitializedMembers (semanticModel.SyntaxTree, position, cancellationToken);
			var uninitializedMembers = members.Where (m => !alreadyTypedMembers.Contains (m.Name));

			uninitializedMembers = uninitializedMembers.Where (m => m.IsEditorBrowsable ());

			// var text = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);
			// var changes = GetTextChangeSpan(text, position);
			var list = new List<CompletionData> ();

			// Return the members
			foreach (var member in uninitializedMembers) {
				list.Add (engine.Factory.CreateSymbolCompletionData (this, member));
			}
			return list;
		}
		public async Task<CompletionResult> GetCompletionDataAsync(CompletionContext completionContext, CompletionTriggerInfo info, CancellationToken cancellationToken = default(CancellationToken))
		{
			if (completionContext == null)
				throw new ArgumentNullException ("completionContext");

			var document = completionContext.Document;
			var semanticModel = await completionContext.GetSemanticModelAsync (cancellationToken).ConfigureAwait(false);
			var position = completionContext.Position;
			var text = await document.GetTextAsync (cancellationToken).ConfigureAwait (false);
			var ctx = await completionContext.GetSyntaxContextAsync (workspace, cancellationToken);
			ctx.SemanticModel = semanticModel;

			// case lambda parameter (n1, $
			if (ctx.TargetToken.IsKind (SyntaxKind.CommaToken) &&
				ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null &&
				ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.ParenthesizedLambdaExpression)) 
				return CompletionResult.Empty;

			var result = new CompletionResult { SyntaxContext = ctx };

			if (position > 0) {
				var nonExclusiveHandlers = new List<CompletionContextHandler> ();
				var exclusiveHandlers = new List<CompletionContextHandler> ();
				var toRetriggerHandlers = new List<CompletionContextHandler> ();
				IEnumerable<CompletionContextHandler> handlerList;
				if (completionContext.UseDefaultContextHandlers) {
					handlerList = handlers.Concat (completionContext.AdditionalContextHandlers);
				} else {
					handlerList = completionContext.AdditionalContextHandlers;
				}

				foreach (var handler in handlerList) {
					if (info.CompletionTriggerReason == CompletionTriggerReason.CompletionCommand || handler.IsTriggerCharacter (text, position - 1)) {
						if (await handler.IsExclusiveAsync (completionContext, ctx, info, cancellationToken)) {
							exclusiveHandlers.Add (handler);
						} else {
							nonExclusiveHandlers.Add (handler);
						}
					} else {
						toRetriggerHandlers.Add (handler);
					}
				}

				foreach (var handler in exclusiveHandlers) {
					var handlerResult = handler.GetCompletionDataAsync (result, this, completionContext, info, ctx, cancellationToken).Result;
					//if (handlerResult != null) {
					//	Console.WriteLine ("-----" + handler);
					//	foreach (var item in handlerResult) {
					//		Console.WriteLine (item.DisplayText);
					//	}
					//} else {
					//	Console.WriteLine ("-----" + handler + " == NULL");
					//}
					if (handlerResult != null)
						result.AddRange (handlerResult);
				}

				if (result.Count == 0) {
					foreach (var handler in nonExclusiveHandlers) {
						var handlerResult = await handler.GetCompletionDataAsync (result, this, completionContext, info, ctx, cancellationToken);
						//if (handlerResult != null) {
						//	Console.WriteLine ("-----" + handler);
						//	foreach (var item in handlerResult) {
						//		Console.WriteLine (item.DisplayText);
						//	}
						//} else {
						//	Console.WriteLine ("-----" + handler + " == NULL");
						//}
						if (handlerResult != null && handlerResult.Any ()) {
							result.AddRange (handlerResult);
						} else {
							toRetriggerHandlers.Add (handler);
						}
					}

					if (result.Count > 0) {
						info = info.WithCompletionTriggerReason (CompletionTriggerReason.RetriggerCommand);
						foreach (var handler in toRetriggerHandlers) {
							var handlerResult = await handler.GetCompletionDataAsync (result, this, completionContext, info, ctx, cancellationToken);
							if (handlerResult != null)
								result.AddRange (handlerResult);
						}
					}
				}
			}

			// prevent auto selection for "<number>." case
			if (ctx.TargetToken.IsKind(SyntaxKind.DotToken)) {
				var accessExpr = ctx.TargetToken.Parent as MemberAccessExpressionSyntax;
				if (accessExpr != null &&
					accessExpr.Expression != null &&
					accessExpr.Expression.IsKind(SyntaxKind.NumericLiteralExpression))  {
					result.AutoSelect = false;
				}
			}

			if (ctx.LeftToken.Parent != null &&
				ctx.LeftToken.Parent.Parent != null &&
				ctx.TargetToken.Parent != null && !ctx.TargetToken.Parent.IsKind(SyntaxKind.NameEquals) &&
				ctx.LeftToken.Parent.Parent.IsKind(SyntaxKind.AnonymousObjectMemberDeclarator))
				result.AutoSelect = false;

			if (ctx.TargetToken.IsKind (SyntaxKind.OpenParenToken) && ctx.TargetToken.GetPreviousToken ().IsKind (SyntaxKind.OpenParenToken)) {
				var validTypes = TypeGuessing.GetValidTypes (semanticModel, ctx.TargetToken.Parent, cancellationToken);
				result.AutoSelect = !validTypes.Any (t => t.IsDelegateType ());
			}

			foreach (var type in ctx.InferredTypes) {
				if (type.TypeKind == TypeKind.Delegate) {
					result.AutoSelect = false;
					break;
				}
			}
			
			return result;
		}
示例#46
0
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var model = ctx.SemanticModel;
            var tree  = ctx.SyntaxTree;

            if (tree.IsInNonUserCode(completionContext.Position, cancellationToken))
            {
                return(Enumerable.Empty <CompletionData> ());
            }

            var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken);

            if (token.IsKind(SyntaxKind.DotToken) || token.IsMandatoryNamedParameterPosition())
            {
                return(Enumerable.Empty <CompletionData> ());
            }
            var result = new List <CompletionData> ();

            // check if it's the first parameter and set autoselect == false if a parameterless version exists.
            if (token.IsKind(SyntaxKind.OpenParenToken))
            {
                var parent = token.Parent?.Parent;
                if (parent == null)
                {
                    return(Enumerable.Empty <CompletionData> ());
                }
                var symbolInfo = model.GetSymbolInfo(parent);
                foreach (var symbol in new [] { symbolInfo.Symbol }.Concat(symbolInfo.CandidateSymbols))
                {
                    if (symbol != null && symbol.IsKind(SymbolKind.Method))
                    {
                        if (symbol.GetParameters().Length == 0)
                        {
                            completionResult.AutoSelect = false;
                            break;
                        }
                    }
                }
            }

            foreach (var _type in ctx.InferredTypes)
            {
                var type = _type;
                if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
                {
                    type = type.GetTypeArguments().FirstOrDefault();
                    if (type == null)
                    {
                        continue;
                    }
                }

                if (type.TypeKind != TypeKind.Enum)
                {
                    continue;
                }
                if (!type.IsEditorBrowsable())
                {
                    continue;
                }

                // Does type have any aliases?
                ISymbol alias = await type.FindApplicableAlias(completionContext.Position, model, cancellationToken).ConfigureAwait(false);

                var displayString = RoslynCompletionData.SafeMinimalDisplayString(type, model, completionContext.Position, SymbolDisplayFormat.CSharpErrorMessageFormat);
                if (string.IsNullOrEmpty(completionResult.DefaultCompletionString))
                {
                    completionResult.DefaultCompletionString = displayString;
                    completionResult.AutoCompleteEmptyMatch  = true;
                }
                if (!IsReachable(model, type, token.Parent))
                {
                    result.Add(engine.Factory.CreateSymbolCompletionData(this, type, displayString));
                }
                foreach (IFieldSymbol field in type.GetMembers().OfType <IFieldSymbol> ())
                {
                    if (field.DeclaredAccessibility == Accessibility.Public && (field.IsConst || field.IsStatic))
                    {
                        result.Add(engine.Factory.CreateEnumMemberCompletionData(this, alias, field));
                    }
                }
            }
            return(result);
        }
示例#47
0
        public async Task <IEnumerable <CompletionData> > GetCompletionDataAsync(CompletionResult result, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken = default(CancellationToken))
        {
            // If we were triggered by typign a character, then do a semantic check to make sure
            // we're still applicable.  If not, then return immediately.
            if (info.CompletionTriggerReason == CompletionTriggerReason.CharTyped)
            {
                var isSemanticTriggerCharacter = await IsSemanticTriggerCharacterAsync(completionContext.Document, completionContext.Position - 1, cancellationToken).ConfigureAwait(false);

                if (!isSemanticTriggerCharacter)
                {
                    return(null);
                }
            }

            return(await GetItemsWorkerAsync(result, engine, completionContext, info, ctx, cancellationToken).ConfigureAwait(false));
        }
		protected override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var semanticModel = ctx.SemanticModel;
			var result = new List<CompletionData> ();
			if (info.TriggerCharacter == ' ') {
				var newExpression = ObjectCreationContextHandler.GetObjectCreationNewExpression (ctx.SyntaxTree, completionContext.Position, cancellationToken);
				if (newExpression == null && info.CompletionTriggerReason == CompletionTriggerReason.CharTyped  && !ctx.LeftToken.IsKind (SyntaxKind.EqualsToken) && !ctx.LeftToken.IsKind (SyntaxKind.EqualsEqualsToken))
					return Task.FromResult (Enumerable.Empty<CompletionData> ());

				completionResult.AutoCompleteEmptyMatch = false;
			}

			var parent = ctx.TargetToken.Parent;
			bool isInAttribute = ctx.CSharpSyntaxContext.IsAttributeNameContext;
			bool isInBaseList = parent != null && parent.IsKind (SyntaxKind.BaseList);
			bool isInUsingDirective = parent != null && parent.Parent != null && parent.Parent.IsKind (SyntaxKind.UsingDirective) && !parent.IsKind (SyntaxKind.QualifiedName);
			var isInQuery = ctx.CSharpSyntaxContext.IsInQuery;
			var completionDataLookup = new Dictionary<Tuple<string, SymbolKind>, ISymbolCompletionData> ();
			bool isInCatchTypeExpression = parent != null && parent.IsKind (SyntaxKind.CatchDeclaration) || 
			                               parent.IsKind (SyntaxKind.QualifiedName) && parent.Parent != null && parent.Parent.IsKind (SyntaxKind.CatchDeclaration);
			Action<ISymbolCompletionData> addData = d => {
				var key = Tuple.Create (d.DisplayText, d.Symbol.Kind);
				ISymbolCompletionData data;
				if (completionDataLookup.TryGetValue (key, out data)) {
					data.AddOverload (d);
					return;
				}
				completionDataLookup.Add (key, d);
				result.Add (d);
			};

			var completionCategoryLookup = new Dictionary<string, CompletionCategory> ();
			foreach (var symbol in Recommender.GetRecommendedSymbolsAtPosition (semanticModel, completionContext.Position, engine.Workspace, null, cancellationToken)) {
				if (symbol.Kind == SymbolKind.NamedType) {
					if (isInAttribute) {
						var type = (ITypeSymbol)symbol;
						if (type.IsAttribute ()) {
							var v = type.Name.Substring (0, type.Name.Length - "Attribute".Length);
							var needsEscaping = SyntaxFacts.GetKeywordKind(v) != SyntaxKind.None;
							needsEscaping = needsEscaping || (isInQuery && SyntaxFacts.IsQueryContextualKeyword(SyntaxFacts.GetContextualKeywordKind(v)));
							if (!needsEscaping) {
								addData (engine.Factory.CreateSymbolCompletionData (this, symbol, v));
								continue;
							}
						}
					}
					if (isInBaseList) {
						var type = (ITypeSymbol)symbol;
						if (type.IsSealed || type.IsStatic)
							continue;
					}
					if (isInCatchTypeExpression) {
						var type = (ITypeSymbol)symbol;
						if (!IsException (type))
							continue;
					}
				}

				if (isInUsingDirective && symbol.Kind != SymbolKind.Namespace)
					continue;

				var newData = engine.Factory.CreateSymbolCompletionData (this, symbol, symbol.Name.EscapeIdentifier (isInQuery));
				ISymbol categorySymbol;
				var method = symbol as IMethodSymbol;
				if (method != null) {
					if (method.IsReducedExtension ()) {
						categorySymbol = method.ReceiverType;
					} else {
						categorySymbol = (ISymbol)symbol.ContainingType;
					}
				} else {
					categorySymbol = (ISymbol)symbol.ContainingType ?? symbol.ContainingNamespace;
				}
				if (categorySymbol != null) {
					CompletionCategory category;
					var key = categorySymbol.ToDisplayString ();
					if (!completionCategoryLookup.TryGetValue (key, out category)) {
						completionCategoryLookup [key] = category = engine.Factory.CreateCompletionDataCategory (categorySymbol);
					}
					newData.CompletionCategory = category;
				}
				addData (newData);
			}
			return Task.FromResult ((IEnumerable<CompletionData>)result);
		}
        protected override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var position   = completionContext.Position;
            var document   = completionContext.Document;
            var syntaxTree = ctx.SyntaxTree;

            if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
                syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
            {
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }
            if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken))
            {
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }
            var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax;

            if (ma == null)
            {
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }

            var model = ctx.CSharpSyntaxContext.SemanticModel;

            var symbolInfo = model.GetSymbolInfo(ma.Expression);

            if (symbolInfo.Symbol == null)
            {
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }

            var        list         = new List <CompletionData> ();
            var        within       = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);
            var        addedSymbols = new HashSet <string> ();
            SyntaxNode ancestor     = ma.Expression;

            while (ancestor != null)
            {
                // check parent if for direct type check
                var ifStmSyntax = ancestor as IfStatementSyntax;
                if (ifStmSyntax != null)
                {
                    var condition = SkipParens(ifStmSyntax.Condition);
                    if (condition != null && condition.IsKind(SyntaxKind.IsExpression))
                    {
                        var isExpr     = ((BinaryExpressionSyntax)condition);
                        var leftSymbol = model.GetSymbolInfo(isExpr.Left);

                        if (leftSymbol.Symbol == symbolInfo.Symbol)
                        {
                            var type = model.GetTypeInfo(isExpr.Right).Type;
                            if (type != null)
                            {
                                Analyze(engine, ma.Expression, type, model.GetTypeInfo(isExpr.Left).Type, within, list, addedSymbols, cancellationToken);
                            }
                        }
                    }
                    // skip if else ... if else
                    if (ancestor.Parent is ElseClauseSyntax)
                    {
                        while (ancestor is IfStatementSyntax || ancestor is ElseClauseSyntax)
                        {
                            ancestor = ancestor.Parent;
                        }
                        continue;
                    }
                    goto loop;
                }

                // check parent block if an if is there that checks the type
                var blockSyntax = ancestor as BlockSyntax;
                if (blockSyntax != null)
                {
                    foreach (var ifStmt in blockSyntax.Statements.OfType <IfStatementSyntax> ())
                    {
                        if (ifStmt.Span.End >= ma.Span.Start)
                        {
                            break;
                        }
                        var  condition  = SkipParens(ifStmt.Condition);
                        bool wasNegated = false;
                        if (condition.IsKind(SyntaxKind.LogicalNotExpression))
                        {
                            condition  = SkipParens(((PrefixUnaryExpressionSyntax)condition).Operand);
                            wasNegated = true;
                        }
                        if (condition == null || !condition.IsKind(SyntaxKind.IsExpression))
                        {
                            goto loop;
                        }
                        var stmt = ifStmt.Statement;
                        if (stmt is BlockSyntax)
                        {
                            stmt = ((BlockSyntax)stmt).Statements.LastOrDefault();
                        }
                        if (!wasNegated ||
                            stmt == null ||
                            !stmt.IsKind(SyntaxKind.ReturnStatement) && !stmt.IsKind(SyntaxKind.ContinueStatement) && !stmt.IsKind(SyntaxKind.BreakStatement) && !stmt.IsKind(SyntaxKind.ThrowStatement))
                        {
                            goto loop;
                        }

                        var isExpr     = ((BinaryExpressionSyntax)condition);
                        var leftSymbol = model.GetSymbolInfo(isExpr.Left);
                        if (leftSymbol.Symbol == symbolInfo.Symbol)
                        {
                            var type = model.GetTypeInfo(isExpr.Right).Type;
                            if (type != null)
                            {
                                Analyze(engine, ma.Expression, type, model.GetTypeInfo(isExpr.Left).Type, within, list, addedSymbols, cancellationToken);
                            }
                        }
                    }
                }

                var binOp = ancestor as BinaryExpressionSyntax;
                if (binOp != null && binOp.IsKind(SyntaxKind.LogicalAndExpression))
                {
                    if (SkipParens(binOp.Left).IsKind(SyntaxKind.IsExpression))
                    {
                        var isExpr     = (BinaryExpressionSyntax)SkipParens(binOp.Left);
                        var leftSymbol = model.GetSymbolInfo(isExpr.Left);

                        if (leftSymbol.Symbol == symbolInfo.Symbol)
                        {
                            var type = model.GetTypeInfo(isExpr.Right).Type;
                            if (type != null)
                            {
                                Analyze(engine, ma.Expression, type, model.GetTypeInfo(isExpr.Left).Type, within, list, addedSymbols, cancellationToken);
                            }
                        }
                    }
                }

                loop : ancestor = ancestor.Parent;
            }

            return(Task.FromResult((IEnumerable <CompletionData>)list));
        }
示例#50
0
        public override async Task <bool> IsExclusiveAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var syntaxTree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken)
                        .GetPreviousTokenIfTouchingWord(position);

            return(IsAfterNameColonArgument(token) || IsAfterNameEqualsArgument(token));
        }
		protected override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var position = completionContext.Position;
			var document = completionContext.Document;
			var syntaxTree = ctx.SyntaxTree;
			if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
				syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
				return Task.FromResult (Enumerable.Empty<CompletionData> ());
			if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken))
				return Task.FromResult (Enumerable.Empty<CompletionData> ());
			var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax;
			if (ma == null)
				return Task.FromResult (Enumerable.Empty<CompletionData> ());

			var model = ctx.CSharpSyntaxContext.SemanticModel;

			var symbolInfo = model.GetSymbolInfo (ma.Expression);
			if (symbolInfo.Symbol == null)
				return Task.FromResult (Enumerable.Empty<CompletionData> ());

			var list = new List<CompletionData> ();
			var within = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);
			var addedSymbols = new HashSet<string> ();
			SyntaxNode ancestor = ma.Expression;
			while (ancestor != null) {
				// check parent if for direct type check
				var ifStmSyntax = ancestor as IfStatementSyntax;
				if (ifStmSyntax != null) {
					var condition = ifStmSyntax.Condition.SkipParens ();
					if (condition != null && condition.IsKind (SyntaxKind.IsExpression)) {
						var isExpr = ((BinaryExpressionSyntax)condition);
						var leftSymbol = model.GetSymbolInfo (isExpr.Left);

						if (leftSymbol.Symbol == symbolInfo.Symbol) {
							var type = model.GetTypeInfo (isExpr.Right).Type;
							if (type != null) {
								Analyze (engine, ma.Expression, type, model.GetTypeInfo (isExpr.Left).Type, within, list, addedSymbols, cancellationToken);
							}
						}
					}
					// skip if else ... if else
					if (ancestor.Parent is ElseClauseSyntax) {
						while (ancestor is IfStatementSyntax || ancestor is ElseClauseSyntax)
							ancestor = ancestor.Parent;
						continue;
					}
					goto loop;
				}

				// check parent block if an if is there that checks the type
				var blockSyntax = ancestor as BlockSyntax;
				if (blockSyntax != null) {
					foreach (var ifStmt in blockSyntax.Statements.OfType<IfStatementSyntax> ()) {
						if (ifStmt.Span.End >= ma.Span.Start)
							break;
						var condition = ifStmt.Condition.SkipParens ();
						bool wasNegated = false;
						if (condition.IsKind (SyntaxKind.LogicalNotExpression)) {
							condition = ((PrefixUnaryExpressionSyntax)condition).Operand.SkipParens ();
							wasNegated = true;
						}
						if (condition == null || !condition.IsKind (SyntaxKind.IsExpression))
							goto loop;
						var stmt = ifStmt.Statement;
						if (stmt is BlockSyntax) {
							stmt = ((BlockSyntax)stmt).Statements.LastOrDefault ();
						}
						if (!wasNegated || 
						    stmt == null ||
							!stmt.IsKind (SyntaxKind.ReturnStatement) && !stmt.IsKind (SyntaxKind.ContinueStatement) && !stmt.IsKind (SyntaxKind.BreakStatement) && !stmt.IsKind (SyntaxKind.ThrowStatement))
							goto loop;

						var isExpr = ((BinaryExpressionSyntax)condition);
						var leftSymbol = model.GetSymbolInfo (isExpr.Left);
						if (leftSymbol.Symbol == symbolInfo.Symbol) {
							var type = model.GetTypeInfo (isExpr.Right).Type;
							if (type != null) {
								Analyze (engine, ma.Expression, type, model.GetTypeInfo (isExpr.Left).Type, within, list, addedSymbols, cancellationToken);
							}
						}
					}
				}

				var binOp = ancestor as BinaryExpressionSyntax;
				if (binOp != null && binOp.IsKind (SyntaxKind.LogicalAndExpression)) {
					if (binOp.Left.SkipParens ().IsKind (SyntaxKind.IsExpression)) {
						var isExpr = ((BinaryExpressionSyntax)binOp.Left.SkipParens ());
						var leftSymbol = model.GetSymbolInfo (isExpr.Left);

						if (leftSymbol.Symbol == symbolInfo.Symbol) {
							var type = model.GetTypeInfo (isExpr.Right).Type;
							if (type != null) {
								Analyze (engine, ma.Expression, type, model.GetTypeInfo (isExpr.Left).Type, within, list, addedSymbols, cancellationToken);
							}
						}
					}
				}

				loop: ancestor = ancestor.Parent;
			}

			return Task.FromResult ((IEnumerable<CompletionData>)list);
		}
示例#52
0
 public virtual Task <bool> IsExclusiveAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
 {
     return(Task.FromResult(false));
 }
示例#53
0
        protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var semanticModel = ctx.SemanticModel;
            var result        = new List <CompletionData> ();

            if (info.TriggerCharacter == ' ')
            {
                var newExpression = ObjectCreationContextHandler.GetObjectCreationNewExpression(ctx.SyntaxTree, completionContext.Position, cancellationToken);
                if (newExpression == null && info.CompletionTriggerReason == CompletionTriggerReason.CharTyped && !ctx.LeftToken.IsKind(SyntaxKind.EqualsToken) && !ctx.LeftToken.IsKind(SyntaxKind.EqualsEqualsToken))
                {
                    return(Enumerable.Empty <CompletionData> ());
                }

                completionResult.AutoCompleteEmptyMatch = false;
            }

            var  parent                  = ctx.TargetToken.Parent;
            bool isInAttribute           = ctx.CSharpSyntaxContext.IsAttributeNameContext;
            bool isInBaseList            = parent != null && parent.IsKind(SyntaxKind.BaseList);
            bool isInUsingDirective      = parent != null && parent.Parent != null && parent.Parent.IsKind(SyntaxKind.UsingDirective) && !parent.IsKind(SyntaxKind.QualifiedName);
            var  isInQuery               = ctx.CSharpSyntaxContext.IsInQuery;
            var  completionDataLookup    = new Dictionary <Tuple <string, SymbolKind>, ISymbolCompletionData> ();
            bool isInCatchTypeExpression = parent.IsKind(SyntaxKind.CatchDeclaration) ||
                                           parent.IsKind(SyntaxKind.QualifiedName) && parent != null && parent.Parent.IsKind(SyntaxKind.CatchDeclaration);
            Action <ISymbolCompletionData> addData = d => {
                var key = Tuple.Create(d.DisplayText, d.Symbol.Kind);
                ISymbolCompletionData data;
                if (completionDataLookup.TryGetValue(key, out data))
                {
                    data.AddOverload(d);
                    return;
                }
                completionDataLookup.Add(key, d);
                result.Add(d);
            };

            var completionCategoryLookup = new Dictionary <string, CompletionCategory> ();

            foreach (var symbol in Recommender.GetRecommendedSymbolsAtPosition(semanticModel, completionContext.Position, engine.Workspace, null, cancellationToken))
            {
                if (symbol.Kind == SymbolKind.NamedType)
                {
                    if (isInAttribute)
                    {
                        var type = (ITypeSymbol)symbol;
                        if (type.IsAttribute())
                        {
                            var v             = type.Name.Substring(0, type.Name.Length - "Attribute".Length);
                            var needsEscaping = SyntaxFacts.GetKeywordKind(v) != SyntaxKind.None;
                            needsEscaping = needsEscaping || (isInQuery && SyntaxFacts.IsQueryContextualKeyword(SyntaxFacts.GetContextualKeywordKind(v)));
                            if (!needsEscaping)
                            {
                                addData(engine.Factory.CreateSymbolCompletionData(this, symbol, v));
                                continue;
                            }
                        }
                    }
                    if (isInBaseList)
                    {
                        var type = (ITypeSymbol)symbol;
                        if (type.IsSealed || type.IsStatic)
                        {
                            continue;
                        }
                    }
                    if (isInCatchTypeExpression)
                    {
                        var type = (ITypeSymbol)symbol;
                        if (!IsException(type))
                        {
                            continue;
                        }
                    }
                }

                if (isInUsingDirective && symbol.Kind != SymbolKind.Namespace)
                {
                    continue;
                }

                var newData        = engine.Factory.CreateSymbolCompletionData(this, symbol, symbol.Name.EscapeIdentifier(isInQuery));
                var categorySymbol = (ISymbol)symbol.ContainingType ?? symbol.ContainingNamespace;
                if (categorySymbol != null)
                {
                    CompletionCategory category;
                    var key = categorySymbol.ToDisplayString();
                    if (!completionCategoryLookup.TryGetValue(key, out category))
                    {
                        completionCategoryLookup [key] = category = engine.Factory.CreateCompletionDataCategory(categorySymbol);
                    }
                    newData.CompletionCategory = category;
                }
                addData(newData);
            }
            return(result);
        }
示例#54
0
 protected abstract Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult result, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken);
示例#55
0
        protected override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult result, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
        {
            var document = completionContext.Document;
            var position = completionContext.Position;

            var tree  = ctx.SyntaxTree;
            var model = ctx.SemanticModel;

            if (tree.IsInNonUserCode(position, cancellationToken))
            {
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }

            if (!ctx.CSharpSyntaxContext.IsAnyExpressionContext)
            {
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }
            var enclosingType = model.GetEnclosingNamedType(position, cancellationToken);

            if (enclosingType == null)
            {
                return(Task.FromResult(Enumerable.Empty <CompletionData> ()));
            }

            var list = new List <CompletionData> ();

            foreach (var type in ctx.InferredTypes)
            {
                if (type.TypeKind != TypeKind.Delegate)
                {
                    continue;
                }


                string delegateName = null;

                if (ctx.TargetToken.IsKind(SyntaxKind.PlusEqualsToken))
                {
                    delegateName = GuessEventHandlerBaseName(ctx.LeftToken.Parent, ctx.ContainingTypeDeclaration);
                }

                AddDelegateHandlers(list, ctx.TargetToken.Parent, model, engine, result, type, position, delegateName, cancellationToken);
            }
            if (list.Count > 0)
            {
                result.AutoSelect = false;
            }
            return(Task.FromResult((IEnumerable <CompletionData>)list));
        }
 public virtual Task <bool> IsExclusiveAsync(CompletionContext completionContext, SyntaxContext syntaxContext, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
 {
     return(Task.FromResult(false));
 }
		protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken)
		{
			var tree = await completionContext.Document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
			if (tree.IsInNonUserCode(completionContext.Position, cancellationToken) ||
				tree.IsPreProcessorDirectiveContext(completionContext.Position, cancellationToken) || 
				info.CompletionTriggerReason != CompletionTriggerReason.CompletionCommand)
				return Enumerable.Empty<CompletionData>();

			var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken);
			if (token.Span.End == completionContext.Position)
				return Enumerable.Empty<CompletionData>();
			var parent = token.Parent.AncestorsAndSelf ().OfType<GenericNameSyntax> ().FirstOrDefault () ?? token.Parent;

			if (!parent.Parent.IsKind (SyntaxKind.IncompleteMember) &&
			    !IsLocal(parent) &&
			    !parent.Parent.IsKind (SyntaxKind.Parameter) &&
			    !parent.Parent.IsKind (SyntaxKind.ForEachStatement)) {
				return Enumerable.Empty<CompletionData>();
			}

			if (info.TriggerCharacter != ' ' &&
				parent.Parent.IsKind (SyntaxKind.ExpressionStatement)) {
				return Enumerable.Empty<CompletionData>();
			}
			var list = new List<CompletionData> ();

			if (parent.IsKind(SyntaxKind.PredefinedType)) {			
				switch (token.Kind()) {
				case SyntaxKind.ObjectKeyword:
					list.Add (engine.Factory.CreateGenericData(this, "o", GenericDataType.NameProposal));
					list.Add (engine.Factory.CreateGenericData(this, "obj", GenericDataType.NameProposal));
					return list;
				case SyntaxKind.BoolKeyword:
					list.Add (engine.Factory.CreateGenericData(this, "b", GenericDataType.NameProposal));
					list.Add (engine.Factory.CreateGenericData(this, "pred", GenericDataType.NameProposal));
					return list;
				case SyntaxKind.CharKeyword:
		       		list.Add (engine.Factory.CreateGenericData(this, "c", GenericDataType.NameProposal));
					list.Add (engine.Factory.CreateGenericData(this, "ch", GenericDataType.NameProposal));
					return list;
				case SyntaxKind.StringKeyword:
					list.Add (engine.Factory.CreateGenericData(this, "str", GenericDataType.NameProposal));
					return list;
				case SyntaxKind.DoubleKeyword:
				case SyntaxKind.FloatKeyword:
				case SyntaxKind.DecimalKeyword:
					list.Add (engine.Factory.CreateGenericData(this, "d", GenericDataType.NameProposal));
					list.Add (engine.Factory.CreateGenericData(this, "f", GenericDataType.NameProposal));
					list.Add (engine.Factory.CreateGenericData(this, "m", GenericDataType.NameProposal));
					return list;
				default:
					list.Add (engine.Factory.CreateGenericData(this, "i", GenericDataType.NameProposal));
					list.Add (engine.Factory.CreateGenericData(this, "j", GenericDataType.NameProposal));
					list.Add (engine.Factory.CreateGenericData(this, "k", GenericDataType.NameProposal));
					return list;
				}
			} else {
				var incompleteMember = parent.Parent as IncompleteMemberSyntax;
				if (incompleteMember != null)
					return list;
				var gns = parent as GenericNameSyntax;
				var names = WordParser.BreakWords (gns != null ? gns.Identifier.ToString () : token.ToString ().Trim ());
				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]);
					}
					list.Add (engine.Factory.CreateGenericData (this, possibleName.ToString (), GenericDataType.NameProposal));
				}
			}
			return list;
		}