private async Task <bool> TryInitializeAsync( TService service, SemanticDocument semanticDocument, SyntaxNode node, CancellationToken cancellationToken) { if (node is not TSimpleNameSyntax) { return(false); } SimpleName = (TSimpleNameSyntax)node; var syntaxFacts = semanticDocument.Document.GetLanguageService <ISyntaxFactsService>(); syntaxFacts.GetNameAndArityOfSimpleName(SimpleName, out var name, out _); Name = name; NameIsVerbatim = syntaxFacts.IsVerbatimIdentifier(SimpleName.GetFirstToken()); if (string.IsNullOrWhiteSpace(Name)) { return(false); } // We only support simple names or dotted names. i.e. "(some + expr).Goo" is not a // valid place to generate a type for Goo. if (!service.TryInitializeState(semanticDocument, SimpleName, cancellationToken, out var generateTypeServiceStateOptions)) { return(false); } if (char.IsLower(name[0]) && !semanticDocument.SemanticModel.Compilation.IsCaseSensitive) { // It's near universal in .NET that types start with a capital letter. As such, // if this name starts with a lowercase letter, don't even bother to offer // "generate type". The user most likely wants to run 'Add Import' (which will // then fix up a case where they typed an existing type name in lowercase, // intending the fix to case correct it). return(false); } NameOrMemberAccessExpression = generateTypeServiceStateOptions.NameOrMemberAccessExpression; ObjectCreationExpressionOpt = generateTypeServiceStateOptions.ObjectCreationExpressionOpt; var semanticModel = semanticDocument.SemanticModel; var info = semanticModel.GetSymbolInfo(SimpleName, cancellationToken); if (info.Symbol != null) { // This bound, so no need to generate anything. return(false); } var semanticFacts = semanticDocument.Document.GetLanguageService <ISemanticFactsService>(); if (!semanticFacts.IsTypeContext(semanticModel, NameOrMemberAccessExpression.SpanStart, cancellationToken) && !semanticFacts.IsExpressionContext(semanticModel, NameOrMemberAccessExpression.SpanStart, cancellationToken) && !semanticFacts.IsStatementContext(semanticModel, NameOrMemberAccessExpression.SpanStart, cancellationToken) && !semanticFacts.IsInsideNameOfExpression(semanticModel, NameOrMemberAccessExpression, cancellationToken) && !semanticFacts.IsNamespaceContext(semanticModel, NameOrMemberAccessExpression.SpanStart, cancellationToken)) { return(false); } // If this isn't something that can be created, then don't bother offering to create // it. if (info.CandidateReason == CandidateReason.NotCreatable) { return(false); } if (info.CandidateReason is CandidateReason.Inaccessible or CandidateReason.NotReferencable or CandidateReason.OverloadResolutionFailure) { // We bound to something inaccessible, or overload resolution on a // constructor call failed. Don't want to offer GenerateType here. return(false); } if (ObjectCreationExpressionOpt != null) { // If we're new'ing up something illegal, then don't offer generate type. var typeInfo = semanticModel.GetTypeInfo(ObjectCreationExpressionOpt, cancellationToken); if (typeInfo.Type.IsModuleType()) { return(false); } } await DetermineNamespaceOrTypeToGenerateInAsync(service, semanticDocument, cancellationToken).ConfigureAwait(false); // Now, try to infer a possible base type for this new class/interface. InferBaseType(service, semanticDocument, cancellationToken); IsInterface = GenerateInterface(service); IsStruct = GenerateStruct(service, semanticModel, cancellationToken); IsAttribute = BaseTypeOrInterfaceOpt != null && BaseTypeOrInterfaceOpt.Equals(semanticModel.Compilation.AttributeType()); IsException = BaseTypeOrInterfaceOpt != null && BaseTypeOrInterfaceOpt.Equals(semanticModel.Compilation.ExceptionType()); IsMembersWithModule = generateTypeServiceStateOptions.IsMembersWithModule; IsTypeGeneratedIntoNamespaceFromMemberAccess = generateTypeServiceStateOptions.IsTypeGeneratedIntoNamespaceFromMemberAccess; IsInterfaceOrEnumNotAllowedInTypeContext = generateTypeServiceStateOptions.IsInterfaceOrEnumNotAllowedInTypeContext; IsDelegateAllowed = generateTypeServiceStateOptions.IsDelegateAllowed; IsDelegateOnly = generateTypeServiceStateOptions.IsDelegateOnly; IsEnumNotAllowed = generateTypeServiceStateOptions.IsEnumNotAllowed; DelegateMethodSymbol = generateTypeServiceStateOptions.DelegateCreationMethodSymbol; IsClassInterfaceTypes = generateTypeServiceStateOptions.IsClassInterfaceTypes; IsSimpleNameGeneric = service.IsGenericName(SimpleName); PropertiesToGenerate = generateTypeServiceStateOptions.PropertiesToGenerate; if (IsAttribute && TypeToGenerateInOpt.GetAllTypeParameters().Any()) { TypeToGenerateInOpt = null; } return(TypeToGenerateInOpt != null || NamespaceToGenerateInOpt != null); }