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 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 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);
		}
        /// <summary>
        /// Given a Symbol, creates the completion item for it.
        /// </summary>
        private CompletionItem CreateItem(
            string displayText,
            string insertionText,
            List<ISymbol> symbols,
            SyntaxContext context,
            Dictionary<ISymbol, List<ProjectId>> invalidProjectMap,
            List<ProjectId> totalProjects,
            bool preselect)
        {
            Contract.ThrowIfNull(symbols);

            SupportedPlatformData supportedPlatformData = null;
            if (invalidProjectMap != null)
            {
                List<ProjectId> invalidProjects = null;
                foreach (var symbol in symbols)
                {
                    if (invalidProjectMap.TryGetValue(symbol, out invalidProjects))
                    {
                        break;
                    }
                }

                if (invalidProjects != null)
                {
                    supportedPlatformData = new SupportedPlatformData(invalidProjects, totalProjects, context.Workspace);
                }
            }

            return CreateItem(displayText, insertionText, symbols, context, preselect, supportedPlatformData);
        }
		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 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);
		}
		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 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 override IEnumerable<INamedTypeSymbol> LookupCandidateSymbols(SyntaxContext context, INamedTypeSymbol declaredSymbol, CancellationToken cancellationToken)
        {
            var candidates = base.LookupCandidateSymbols(context, declaredSymbol, cancellationToken);

            // The base class applies a broad filter when finding candidates, but since C# requires
            // that all parts have the "partial" modifier, the results can be trimmed further here.
            return candidates?.Where(symbol => symbol.DeclaringSyntaxReferences.Any(reference => IsPartialTypeDeclaration(reference.GetSyntax(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 override (string displayText, string insertionText) GetDisplayAndInsertionText(ISymbol symbol, SyntaxContext context)
        {
            if (symbol is IAliasSymbol)
            {
                return (symbol.Name, symbol.Name);
            }

            return base.GetDisplayAndInsertionText(symbol, context);
        }
        protected override ValueTuple<string, string> GetDisplayAndInsertionText(ISymbol symbol, SyntaxContext context)
        {
            if (symbol is IAliasSymbol)
            {
                return ValueTuple.Create(symbol.Name, symbol.Name);
            }

            return base.GetDisplayAndInsertionText(symbol, context);
        }
		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;
		}
        private CompletionItem CreateCompletionItem(
            INamedTypeSymbol symbol, SyntaxContext context)
        {
            var displayAndInsertionText = GetDisplayAndInsertionText(symbol, context);

            return SymbolCompletionItem.Create(
                displayText: displayAndInsertionText.Item1,
                insertionText: displayAndInsertionText.Item2,
                symbol: symbol,
                contextPosition: context.Position,
                properties: GetProperties(symbol, context),
                rules: CompletionItemRules.Default);
        }
		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);
		}
        public static string GetInsertionText(ISymbol symbol, SyntaxContext context)
        {
            if (CommonCompletionUtilities.TryRemoveAttributeSuffix(symbol, context, out var name))
            {
                // Cannot escape Attribute name with the suffix removed. Only use the name with
                // the suffix removed if it does not need to be escaped.
                if (name.Equals(name.EscapeIdentifier()))
                {
                    return name;
                }
            }

            return symbol.Name.EscapeIdentifier(isQueryContext: context.IsInQuery);
        }
        protected override async Task<ImmutableArray<ISymbol>> GetPreselectedSymbolsWorker(SyntaxContext context, int position, OptionSet options, CancellationToken cancellationToken)
        {
            var result = await base.GetPreselectedSymbolsWorker(context, position, options, cancellationToken).ConfigureAwait(false);
            if (result.Any())
            {
                var type = (ITypeSymbol)result.Single();
                var alias = await type.FindApplicableAlias(position, context.SemanticModel, cancellationToken).ConfigureAwait(false);
                if (alias != null)
                {
                    return ImmutableArray.Create(alias);
                }
            }

            return result;
        }
 protected override CompletionItem CreateItem(
     string displayText, string insertionText, List<ISymbol> symbols,
     SyntaxContext context, bool preselect,
     SupportedPlatformData supportedPlatformData)
 {
     return SymbolCompletionItem.Create(
         displayText: displayText,
         insertionText: insertionText,
         filterText: GetFilterText(symbols[0], displayText, context),
         contextPosition: context.Position,
         symbols: symbols,
         supportedPlatforms: supportedPlatformData,
         matchPriority: MatchPriority.Preselect, // Always preselect
         tags: s_Tags,
         rules: GetCompletionItemRules(symbols, context));
 }
        /// <summary>
        /// Given a list of symbols, creates the list of completion items for them.
        /// </summary>
        protected IEnumerable<CompletionItem> CreateItems(
            IEnumerable<ISymbol> symbols,
            SyntaxContext context,
            Dictionary<ISymbol, List<ProjectId>> invalidProjectMap,
            List<ProjectId> totalProjects,
            bool preselect)
        {
            var tree = context.SyntaxTree;

            var q = from symbol in symbols
                    let texts = GetDisplayAndInsertionText(symbol, context)
                    group symbol by texts into g
                    select this.CreateItem(g.Key.Item1, g.Key.Item2, g.ToList(), context, invalidProjectMap, totalProjects, preselect);

            return q.ToList();
        }
		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 override CompletionItem CreateItem(string displayText, string insertionText, List<ISymbol> symbols, SyntaxContext context, bool preselect, SupportedPlatformData supportedPlatformData)
        {
            var matchPriority = preselect ? ComputeSymbolMatchPriority(symbols[0]) : MatchPriority.Default;
            var rules = GetCompletionItemRules(symbols, context, preselect);
            if (preselect)
            {
                rules = rules.WithSelectionBehavior(PreselectedItemSelectionBehavior);
            }

            return SymbolCompletionItem.Create(
                displayText: displayText,
                insertionText: insertionText,
                filterText: GetFilterText(symbols[0], displayText, context),
                contextPosition: context.Position,
                symbols: symbols,
                supportedPlatforms: supportedPlatformData,
                matchPriority: matchPriority,
                rules: rules);
        }
		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;
		}
        protected virtual IEnumerable<INamedTypeSymbol> LookupCandidateSymbols(SyntaxContext context, INamedTypeSymbol declaredSymbol, CancellationToken cancellationToken)
        {
            if (declaredSymbol == null)
            {
                throw new ArgumentNullException(nameof(declaredSymbol));
            }

            SemanticModel semanticModel = context.SemanticModel;

            INamespaceOrTypeSymbol containingSymbol = declaredSymbol.ContainingSymbol as INamespaceOrTypeSymbol;

            if (containingSymbol == null)
            {
                return SpecializedCollections.EmptyEnumerable<INamedTypeSymbol>();
            }

            return semanticModel.LookupNamespacesAndTypes(context.Position, containingSymbol)
                                .OfType<INamedTypeSymbol>()
                                .Where(symbol => declaredSymbol.TypeKind == symbol.TypeKind &&
                                                 NotNewDeclaredMember(symbol, context) &&
                                                 InSameProject(symbol, semanticModel.Compilation));
        }
        protected override async Task<ImmutableArray<ISymbol>> GetPreselectedSymbolsWorker(SyntaxContext context, int position, OptionSet options, CancellationToken cancellationToken)
        {
            var recommender = context.GetLanguageService<IRecommendationService>();
            var typeInferrer = context.GetLanguageService<ITypeInferenceService>();

            var inferredTypes = typeInferrer.InferTypes(context.SemanticModel, position, cancellationToken)
                .Where(t => t.SpecialType != SpecialType.System_Void)
                .ToSet();
            if (inferredTypes.Count == 0)
            {
                return ImmutableArray<ISymbol>.Empty;
            }

            var symbols = await recommender.GetRecommendedSymbolsAtPositionAsync(
                context.Workspace, 
                context.SemanticModel, 
                position, 
                options, 
                cancellationToken).ConfigureAwait(false);

            // Don't preselect intrinsic type symbols so we can preselect their keywords instead.
            return symbols.WhereAsArray(s => inferredTypes.Contains(GetSymbolType(s)) && !IsInstrinsic(s));
        }
		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;

		}
 private Task <ImmutableArray <ISymbol> > GetSymbolsAsync(int position, bool preselect, SyntaxContext context, OptionSet options, CancellationToken cancellationToken)
 {
     try
     {
         return(preselect
             ? GetPreselectedSymbolsAsync(context, position, options, cancellationToken)
             : GetSymbolsAsync(context, position, options, cancellationToken));
     }
     catch (Exception e) when(FatalError.ReportUnlessCanceled(e))
     {
         throw ExceptionUtilities.Unreachable;
     }
 }
Beispiel #32
0
 private static bool ShouldSoftSelectInArgumentList(CompletionContext completionContext, SyntaxContext context, bool preselect)
 {
     return(!preselect &&
            completionContext.Trigger.Kind == CompletionTriggerKind.Insertion &&
            context.IsOnArgumentListBracketOrComma &&
            IsArgumentListTriggerCharacter(completionContext.Trigger.Character));
 }
 protected override (string displayText, string suffix, string insertionText) GetDisplayAndSuffixAndInsertionText(ISymbol symbol, SyntaxContext context)
 => CompletionUtilities.GetDisplayAndSuffixAndInsertionText(symbol, context);
 protected override bool ShouldProvideCompletion(CompletionContext completionContext, SyntaxContext syntaxContext)
 => syntaxContext.IsTypeContext;
 protected abstract Task <ImmutableArray <ISymbol> > GetSymbolsWorker(SyntaxContext context, int position, OptionSet options, CancellationToken cancellationToken);
 protected abstract (string displayText, string insertionText) GetDisplayAndInsertionText(ISymbol symbol, SyntaxContext context);
 protected virtual Task <ImmutableArray <ISymbol> > GetPreselectedSymbolsWorker(SyntaxContext context, int position, OptionSet options, CancellationToken cancellationToken)
 {
     return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
 }
        protected async override Task <bool> ShouldProvidePreselectedItemsAsync(CompletionContext completionContext, SyntaxContext syntaxContext, Document document, int position, Lazy <ImmutableArray <ITypeSymbol> > inferredTypes, OptionSet options)
        {
            var sourceText = await document.GetTextAsync(CancellationToken.None).ConfigureAwait(false);

            if (ShouldTriggerInArgumentLists(sourceText, options))
            {
                // Avoid preselection & hard selection when triggered via insertion in an argument list.
                // If an item is hard selected, then a user trying to type MethodCall() will get
                // MethodCall(someVariable) instead. We need only soft selected items to prevent this.
                if (completionContext.Trigger.Kind == CompletionTriggerKind.Insertion &&
                    position > 0 &&
                    await IsTriggerInArgumentListAsync(document, position - 1, CancellationToken.None).ConfigureAwait(false) == true)
                {
                    return(false);
                }
            }

            return(true);
        }
 private Task <ImmutableArray <ISymbol> > GetSymbolsWorker(int position, bool preselect, SyntaxContext context, OptionSet options, CancellationToken cancellationToken)
 {
     return(preselect
         ? GetPreselectedSymbolsWorker(context, position, options, cancellationToken)
         : GetSymbolsWorker(context, position, options, cancellationToken));
 }
Beispiel #40
0
        protected override async Task <ImmutableArray <ISymbol> > GetPreselectedSymbolsWorker(SyntaxContext context, int position, OptionSet options, CancellationToken cancellationToken)
        {
            var recommender  = context.GetLanguageService <IRecommendationService>();
            var typeInferrer = context.GetLanguageService <ITypeInferenceService>();

            var inferredTypes = typeInferrer.InferTypes(context.SemanticModel, position, cancellationToken)
                                .Where(t => t.SpecialType != SpecialType.System_Void)
                                .ToSet();

            if (inferredTypes.Count == 0)
            {
                return(ImmutableArray <ISymbol> .Empty);
            }

            var symbols = await recommender.GetRecommendedSymbolsAtPositionAsync(
                context.Workspace,
                context.SemanticModel,
                context.Position,
                options,
                cancellationToken).ConfigureAwait(false);

            // Don't preselect intrinsic type symbols so we can preselect their keywords instead.
            return(symbols.WhereAsArray(s => inferredTypes.Contains(GetSymbolType(s)) && !IsInstrinsic(s)));
        }
Beispiel #41
0
        protected override Task <ImmutableArray <ISymbol> > GetSymbolsAsync(SyntaxContext context, int position, OptionSet options, CancellationToken cancellationToken)
        {
            var recommender = context.GetLanguageService <IRecommendationService>();

            return(recommender.GetRecommendedSymbolsAtPositionAsync(context.Workspace, context.SemanticModel, position, options, cancellationToken));
        }
Beispiel #42
0
 protected abstract ImmutableDictionary <string, string> GetProperties(
     INamedTypeSymbol symbol, SyntaxContext context);
Beispiel #43
0
 private static bool NotNewDeclaredMember(INamedTypeSymbol symbol, SyntaxContext context)
 {
     return(symbol.DeclaringSyntaxReferences
            .Select(reference => reference.GetSyntax())
            .Any(node => !(node.SyntaxTree == context.SyntaxTree && node.Span.IntersectsWith(context.Position))));
 }
 protected abstract CompletionItemRules GetCompletionItemRules(IReadOnlyList <ISymbol> symbols, SyntaxContext context);
 protected override Task <ImmutableArray <ISymbol> > GetPreselectedSymbolsWorker(
     SyntaxContext context, int position, OptionSet options, CancellationToken cancellationToken)
 {
     return(GetSymbolsWorkerInternal(context, position, options, preselect: true, cancellationToken));
 }
        protected override async Task AddCompletionItemsAsync(CompletionContext completionContext, SyntaxContext syntaxContext, HashSet <string> namespacesInScope, bool isExpandedCompletion, CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.Completion_TypeImportCompletionProvider_GetCompletionItemsAsync, cancellationToken))
            {
                var telemetryCounter            = new TelemetryCounter();
                var typeImportCompletionService = completionContext.Document.GetRequiredLanguageService <ITypeImportCompletionService>();

                var itemsFromAllAssemblies = await typeImportCompletionService.GetAllTopLevelTypesAsync(
                    completionContext.Document.Project,
                    syntaxContext,
                    forceCacheCreation : isExpandedCompletion,
                    completionContext.CompletionOptions,
                    cancellationToken).ConfigureAwait(false);

                if (itemsFromAllAssemblies == null)
                {
                    telemetryCounter.CacheMiss = true;
                }
                else
                {
                    var aliasTargetNamespaceToTypeNameMap = GetAliasTypeDictionary(completionContext.Document, syntaxContext, cancellationToken);
                    foreach (var items in itemsFromAllAssemblies)
                    {
                        AddItems(items, completionContext, namespacesInScope, aliasTargetNamespaceToTypeNameMap, telemetryCounter);
                    }
                }

                telemetryCounter.Report();
            }
        }
        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));
        }
Beispiel #48
0
        protected override async Task <ImmutableArray <ISymbol> > GetPreselectedSymbolsAsync(SyntaxContext context, int position, OptionSet options, CancellationToken cancellationToken)
        {
            var recommender = context.GetLanguageService <IRecommendationService>();

            var inferredTypes = context.InferredTypes.Where(t => t.SpecialType != SpecialType.System_Void).ToSet();

            if (inferredTypes.Count == 0)
            {
                return(ImmutableArray <ISymbol> .Empty);
            }

            var symbols = await recommender.GetRecommendedSymbolsAtPositionAsync(
                context.Workspace,
                context.SemanticModel,
                context.Position,
                options,
                cancellationToken).ConfigureAwait(false);

            // Don't preselect intrinsic type symbols so we can preselect their keywords instead. We will also ignore nullability for purposes of preselection
            // -- if a method is returning a string? but we've inferred we're assigning to a string or vice versa we'll still count those as the same.
            return(symbols.WhereAsArray(s => inferredTypes.Contains(GetSymbolType(s), SymbolEqualityComparer.Default) && !IsInstrinsic(s)));
        }
 protected override Task <ImmutableArray <ISymbol> > GetSymbolsAsync(SyntaxContext context, int position, OptionSet options, CancellationToken cancellationToken)
 {
     return(Recommender.GetImmutableRecommendedSymbolsAtPositionAsync(
                context.SemanticModel, position, context.Workspace, options, cancellationToken));
 }
Beispiel #50
0
        private async Task AddCompletionItemsAsync(CompletionContext completionContext, SyntaxContext syntaxContext, TelemetryCounter telemetryCounter, CancellationToken cancellationToken)
        {
            var document  = completionContext.Document;
            var project   = document.Project;
            var workspace = project.Solution.Workspace;
            var typeImportCompletionService = document.GetLanguageService <ITypeImportCompletionService>();

            // Find all namespaces in scope at current cursor location,
            // which will be used to filter so the provider only returns out-of-scope types.
            var namespacesInScope = GetNamespacesInScope(document, syntaxContext, cancellationToken);

            var tasksToGetCompletionItems = ArrayBuilder <Task <ImmutableArray <CompletionItem> > > .GetInstance();

            // Get completion items from current project.
            var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            tasksToGetCompletionItems.Add(Task.Run(() => typeImportCompletionService.GetTopLevelTypesAsync(
                                                       project,
                                                       syntaxContext,
                                                       isInternalsVisible: true,
                                                       cancellationToken)));

            // Get declarations from directly referenced projects and PEs.
            // This can be parallelized because we don't add items to CompletionContext
            // until all the collected tasks are completed.
            var referencedAssemblySymbols = compilation.GetReferencedAssemblySymbols();

            tasksToGetCompletionItems.AddRange(
                referencedAssemblySymbols.Select(symbol => Task.Run(() => HandleReferenceAsync(symbol))));

            // We want to timebox the operation that might need to traverse all the type symbols and populate the cache,
            // the idea is not to block completion for too long (likely to happen the first time import completion is triggered).
            // The trade-off is we might not provide unimported types until the cache is warmed up.
            var combinedTask = Task.WhenAll(tasksToGetCompletionItems.ToImmutableAndFree());

            if (await Task.WhenAny(combinedTask, Task.Delay(TimeoutInMilliseconds, cancellationToken)).ConfigureAwait(false) == combinedTask)
            {
                // No timeout. We now have all completion items ready.
                var completionItemsToAdd = await combinedTask.ConfigureAwait(false);

                foreach (var completionItems in completionItemsToAdd)
                {
                    AddItems(completionItems, completionContext, namespacesInScope, telemetryCounter);
                }
            }
            else
            {
                // If timed out, we don't want to cancel the computation so next time the cache would be populated.
                // We do not keep track if previous compuation for a given project/PE reference is still running. So there's a chance
                // we queue same computation again later. However, we expect such computation for an individual reference to be relatively
                // fast so the actual cycles wasted would be insignificant.
                telemetryCounter.TimedOut = true;
            }

            telemetryCounter.ReferenceCount = referencedAssemblySymbols.Length;

            return;

            async Task <ImmutableArray <CompletionItem> > HandleReferenceAsync(IAssemblySymbol referencedAssemblySymbol)
            {
                cancellationToken.ThrowIfCancellationRequested();

                // Skip reference with only non-global alias.
                var metadataReference = compilation.GetMetadataReference(referencedAssemblySymbol);

                if (metadataReference.Properties.Aliases.IsEmpty ||
                    metadataReference.Properties.Aliases.Any(alias => alias == MetadataReferenceProperties.GlobalAlias))
                {
                    var assemblyProject = project.Solution.GetProject(referencedAssemblySymbol, cancellationToken);
                    if (assemblyProject != null && assemblyProject.SupportsCompilation)
                    {
                        return(await typeImportCompletionService.GetTopLevelTypesAsync(
                                   assemblyProject,
                                   syntaxContext,
                                   isInternalsVisible : compilation.Assembly.IsSameAssemblyOrHasFriendAccessTo(referencedAssemblySymbol),
                                   cancellationToken).ConfigureAwait(false));
                    }
                    else if (metadataReference is PortableExecutableReference peReference)
                    {
                        return(typeImportCompletionService.GetTopLevelTypesFromPEReference(
                                   project.Solution,
                                   compilation,
                                   peReference,
                                   syntaxContext,
                                   isInternalsVisible: compilation.Assembly.IsSameAssemblyOrHasFriendAccessTo(referencedAssemblySymbol),
                                   cancellationToken));
                    }
                }

                return(ImmutableArray <CompletionItem> .Empty);
            }
 /// <summary>
 /// The decision for whether to provide preselected items can be contextual, e.g. based on trigger character and syntax location
 /// </summary>
 protected virtual Task <bool> ShouldProvidePreselectedItemsAsync(CompletionContext completionContext, SyntaxContext syntaxContext, Document document, int position, Lazy <ImmutableArray <ITypeSymbol> > inferredTypes, OptionSet options)
 => SpecializedTasks.True;
Beispiel #52
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.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);
        }
Beispiel #53
0
 protected abstract CompletionItemRules GetCompletionItemRules(List <ISymbol> symbols, SyntaxContext context, bool preselect);
		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.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> ();
		}
Beispiel #55
0
 public bool IsApplicable(SyntaxContext syntaxContext, Options.Options options)
 {
     return(true);
 }
        private Task <ImmutableArray <ISymbol> > GetSymbolsWorkerInternal(
            SyntaxContext context, int position, OptionSet options, bool preselect, CancellationToken cancellationToken)
        {
            var newExpression = GetObjectCreationNewExpression(context.SyntaxTree, position, cancellationToken);

            if (newExpression == null)
            {
                return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
            }

            var typeInferenceService = context.GetLanguageService <ITypeInferenceService>();
            var type = typeInferenceService.InferType(
                context.SemanticModel, position, objectAsDefault: false, cancellationToken: cancellationToken);

            // Unwrap an array type fully.  We only want to offer the underlying element type in the
            // list of completion items.
            var isArray = false;

            while (type is IArrayTypeSymbol)
            {
                isArray = true;
                type    = ((IArrayTypeSymbol)type).ElementType;
            }

            if (type == null ||
                (isArray && preselect))
            {
                // In the case of array creation, we don't offer a preselected/hard-selected item because
                // the user may want an implicitly-typed array creation

                return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
            }

            // Unwrap nullable
            if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
            {
                type = type.GetTypeArguments().FirstOrDefault();
            }

            if (type.SpecialType == SpecialType.System_Void)
            {
                return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
            }

            if (type.ContainsAnonymousType())
            {
                return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
            }

            if (!type.CanBeReferencedByName)
            {
                return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
            }

            // Normally the user can't say things like "new IList".  Except for "IList[] x = new |".
            // In this case we do want to allow them to preselect certain types in the completion
            // list even if they can't new them directly.
            if (!isArray)
            {
                if (type.TypeKind == TypeKind.Interface ||
                    type.TypeKind == TypeKind.Pointer ||
                    type.TypeKind == TypeKind.Dynamic ||
                    type.IsAbstract)
                {
                    return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
                }

                if (type.TypeKind == TypeKind.TypeParameter &&
                    !((ITypeParameterSymbol)type).HasConstructorConstraint)
                {
                    return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
                }
            }

            if (!type.IsEditorBrowsable(options.GetOption(RecommendationOptions.HideAdvancedMembers, context.SemanticModel.Language), context.SemanticModel.Compilation))
            {
                return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
            }

            return(Task.FromResult(ImmutableArray.Create((ISymbol)type)));
        }
Beispiel #57
0
 protected abstract Task AddCompletionItemsAsync(CompletionContext completionContext, SyntaxContext syntaxContext, HashSet <string> namespacesInScope, CancellationToken cancellationToken);
 internal ScriptSourceFile(FileInfo scriptFile, SyntaxContext syntaxContext)
 {
     this.ScriptFile    = scriptFile;
     this.Reader        = new StreamReader(scriptFile.OpenRead(), true);
     this.SyntaxContext = syntaxContext;
 }
        private bool IsCandidateProject(SyntaxContext context, CancellationToken cancellationToken)
        {
            var syntaxFacts = context.GetLanguageService <ISyntaxFactsService>();

            return(!syntaxFacts.IsInInactiveRegion(context.SyntaxTree, context.Position, cancellationToken));
        }
Beispiel #60
0
        protected override CompletionItem CreateItem(string displayText, string insertionText, List <ISymbol> symbols, SyntaxContext context, bool preselect, SupportedPlatformData supportedPlatformData)
        {
            var rules         = GetCompletionItemRules(symbols, context, preselect);
            var matchPriority = preselect ? ComputeSymbolMatchPriority(symbols[0]) : MatchPriority.Default;

            rules = rules.WithMatchPriority(matchPriority);

            if (preselect)
            {
                rules = rules.WithSelectionBehavior(PreselectedItemSelectionBehavior);
            }

            return(SymbolCompletionItem.CreateWithNameAndKind(
                       displayText: displayText,
                       symbols: symbols,
                       rules: rules,
                       contextPosition: context.Position,
                       insertionText: insertionText,
                       filterText: GetFilterText(symbols[0], displayText, context),
                       supportedPlatforms: supportedPlatformData));
        }