Exemplo n.º 1
0
        public static IMethodSymbol EnsureNonConflictingNames(
            this IMethodSymbol method, INamedTypeSymbol containingType, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken)
        {
            // The method's type parameters may conflict with the type parameters in the type
            // we're generating into.  In that case, rename them.
            var parameterNames = NameGenerator.EnsureUniqueness(
                method.Parameters.Select(p => p.Name).ToList(), isCaseSensitive: syntaxFacts.IsCaseSensitive);

            var outerTypeParameterNames =
                containingType.GetAllTypeParameters()
                .Select(tp => tp.Name)
                .Concat(method.Name)
                .Concat(containingType.Name);

            var unusableNames = parameterNames.Concat(outerTypeParameterNames).ToSet(
                syntaxFacts.IsCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase);

            var newTypeParameterNames = NameGenerator.EnsureUniqueness(
                method.TypeParameters.Select(tp => tp.Name).ToList(),
                n => !unusableNames.Contains(n));

            var updatedMethod = method.RenameTypeParameters(newTypeParameterNames);

            return(updatedMethod.RenameParameters(parameterNames));
        }
Exemplo n.º 2
0
            private string GetUniqueVariableNameInScope(SyntaxNode node, string variableNameBase)
            {
                var reservedNames = _withBlockTempVariableNames.Concat(node.DescendantNodesAndSelf()
                                                                       .SelectMany(syntaxNode => _semanticModel.LookupSymbols(syntaxNode.SpanStart).Select(s => s.Name)));

                return(NameGenerator.EnsureUniqueness(variableNameBase, reservedNames, true));
            }
Exemplo n.º 3
0
            public IMethodSymbol GenerateMethod(
                SyntaxGenerator factory,
                bool isAbstract,
                CancellationToken cancellationToken)
            {
                var parameters = DetermineParameters(cancellationToken);
                var returnType = DetermineReturnType(cancellationToken);
                var isUnsafe   = (parameters
                                  .Any(p => p.Type.IsUnsafe()) || returnType.IsUnsafe()) &&
                                 !State.IsContainedInUnsafeType;
                var method = CodeGenerationSymbolFactory.CreateMethodSymbol(
                    attributes: null,
                    accessibility: DetermineAccessibility(isAbstract),
                    modifiers: DeclarationModifiers.None.WithIsStatic(State.IsStatic).WithIsAbstract(isAbstract).WithIsUnsafe(isUnsafe),
                    returnType: returnType,
                    explicitInterfaceSymbol: null,
                    name: this.State.IdentifierToken.ValueText,
                    typeParameters: DetermineTypeParameters(cancellationToken),
                    parameters: parameters,
                    statements: GenerateStatements(factory, isAbstract, cancellationToken),
                    handlesExpressions: null,
                    returnTypeAttributes: null,
                    methodKind: State.MethodKind);

                // Ensure no conflicts between type parameter names and parameter names.
                var languageServiceProvider = this.Document.Project.Solution.Workspace.Services.GetLanguageServices(this.State.TypeToGenerateIn.Language);

                var equalityComparer       = true ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
                var reservedParameterNames = this.DetermineParameterNames(cancellationToken).ToSet(equalityComparer);
                var newTypeParameterNames  = NameGenerator.EnsureUniqueness(
                    method.TypeParameters.Select(t => t.Name).ToList(), n => !reservedParameterNames.Contains(n));

                return(method.RenameTypeParameters(newTypeParameterNames));
            }
 private SyntaxToken GenerateUniqueName(
     SemanticModel semanticModel, SyntaxNode location, SyntaxNode containerOpt,
     string baseName, IEnumerable <ISymbol> candidates, IEnumerable <string> usedNames, CancellationToken cancellationToken)
 {
     return(this.SyntaxFactsService.ToIdentifierToken(
                NameGenerator.EnsureUniqueness(
                    baseName, candidates.Select(s => s.Name).Concat(usedNames), this.SyntaxFactsService.IsCaseSensitive)));
 }
            private ISymbol GenerateProperty(
                Compilation compilation,
                IPropertySymbol property,
                Accessibility accessibility,
                DeclarationModifiers modifiers,
                bool generateAbstractly,
                bool useExplicitInterfaceSymbol,
                string memberName,
                ImplementTypePropertyGenerationBehavior propertyGenerationBehavior
                )
            {
                var factory            = Document.GetLanguageService <SyntaxGenerator>();
                var attributesToRemove = AttributesToRemove(compilation);

                var getAccessor = GenerateGetAccessor(
                    compilation,
                    property,
                    accessibility,
                    generateAbstractly,
                    useExplicitInterfaceSymbol,
                    propertyGenerationBehavior,
                    attributesToRemove
                    );

                var setAccessor = GenerateSetAccessor(
                    compilation,
                    property,
                    accessibility,
                    generateAbstractly,
                    useExplicitInterfaceSymbol,
                    propertyGenerationBehavior,
                    attributesToRemove
                    );

                var syntaxFacts =
                    Document.Project.LanguageServices.GetRequiredService <ISyntaxFactsService>();

                var parameterNames = NameGenerator.EnsureUniqueness(
                    property.Parameters.SelectAsArray(p => p.Name),
                    isCaseSensitive: syntaxFacts.IsCaseSensitive
                    );

                var updatedProperty = property.RenameParameters(parameterNames);

                updatedProperty = updatedProperty.RemoveInaccessibleAttributesAndAttributesOfTypes(
                    compilation.Assembly,
                    attributesToRemove
                    );

                return(CodeGenerationSymbolFactory.CreatePropertySymbol(
                           updatedProperty,
                           accessibility: accessibility,
                           modifiers: modifiers,
                           explicitInterfaceImplementations: useExplicitInterfaceSymbol
                      ? ImmutableArray.Create(property)
                      : default,
Exemplo n.º 6
0
        private async Task FixOneAsync(
            Document document,
            SemanticModel semanticModel,
            Diagnostic diagnostic,
            SyntaxEditor editor,
            SyntaxAnnotation annotation,
            CancellationToken cancellationToken
            )
        {
            var declarator = await GetMemberDeclaratorAsync(document, diagnostic, cancellationToken)
                             .ConfigureAwait(false);

            if (declarator == null)
            {
                return;
            }

            var semanticFacts = document.GetLanguageService <ISemanticFactsService>();
            var name          = semanticFacts.GenerateNameForExpression(
                semanticModel,
                GetExpression(declarator),
                capitalize: true,
                cancellationToken
                );

            if (string.IsNullOrEmpty(name))
            {
                return;
            }

            var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>();

            editor.ReplaceNode(
                declarator,
                (current, generator) =>
            {
                var currentDeclarator = (TAnonymousObjectMemberDeclaratorSyntax)current;
                var initializer       = (TAnonymousObjectInitializer)currentDeclarator.Parent;
                var existingNames     = GetAnonymousObjectMemberNames(initializer);
                var anonymousType     = current.Parent;
                var uniqueName        = NameGenerator.EnsureUniqueness(
                    name,
                    existingNames,
                    syntaxFacts.IsCaseSensitive
                    );

                var nameToken = generator.Identifier(uniqueName);
                if (annotation != null)
                {
                    nameToken = nameToken.WithAdditionalAnnotations(annotation);
                }

                return(WithName(currentDeclarator, nameToken));
            }
                );
        }
Exemplo n.º 7
0
 public SyntaxToken GenerateUniqueName(string baseName, IEnumerable <string> usedNames)
 {
     return(this.ToIdentifierToken(
                NameGenerator.EnsureUniqueness(
                    baseName,
                    usedNames,
                    this.SyntaxFacts.IsCaseSensitive
                    )
                ));
 }
Exemplo n.º 8
0
 private IParameterSymbol CreateParameterSymbol(
     IMethodSymbol method,
     ITypeSymbol parameterType,
     RefKind refKind,
     bool isOptional,
     string argumentNameSuggestion)
 {
     var uniqueName         = NameGenerator.EnsureUniqueness(argumentNameSuggestion, method.Parameters.Select(p => p.Name));
     var newParameterSymbol = CodeGenerationSymbolFactory.CreateParameterSymbol(
         attributes: default, refKind: refKind, isOptional: isOptional, isParams: false, type: parameterType, name: uniqueName);
Exemplo n.º 9
0
 public static ImmutableArray <ParameterName> GenerateNames(
     IList <string> reservedNames,
     ImmutableArray <bool> isFixed,
     ImmutableArray <string> parameterNames
     ) =>
 NameGenerator
 .EnsureUniqueness(parameterNames, isFixed)
 .Select((name, index) => new ParameterName(name, isFixed[index]))
 .Skip(reservedNames.Count)
 .ToImmutableArray();
            private string GetEventHandlerName(IEventSymbol eventSymbol, SyntaxToken plusEqualsToken, SemanticModel semanticModel, ISyntaxFactsService syntaxFactsService)
            {
                AssertIsBackground();
                var basename = string.Format("{0}_{1}", GetNameObjectPart(eventSymbol, plusEqualsToken, semanticModel, syntaxFactsService), eventSymbol.Name);

                basename = basename.ToPascalCase(trimLeadingTypePrefix: false);

                var reservedNames = semanticModel.LookupSymbols(plusEqualsToken.SpanStart).Select(m => m.Name);

                return(NameGenerator.EnsureUniqueness(basename, reservedNames));
            }
        protected ImmutableArray <ITypeParameterSymbol> GetTypeParameters(
            State state,
            SemanticModel semanticModel,
            IEnumerable <SyntaxNode> typeArguments,
            CancellationToken cancellationToken)
        {
            var arguments      = typeArguments.ToList();
            var arity          = arguments.Count;
            var typeParameters = ArrayBuilder <ITypeParameterSymbol> .GetInstance();

            // For anything that was a type parameter, just use the name (if we haven't already
            // used it).  Otherwise, synthesize new names for the parameters.
            var names   = new string[arity];
            var isFixed = new bool[arity];

            for (var i = 0; i < arity; i++)
            {
                var argument = i < arguments.Count ? arguments[i] : null;
                var type     = argument == null ? null : semanticModel.GetTypeInfo(argument, cancellationToken).Type;
                if (type is ITypeParameterSymbol)
                {
                    var name = type.Name;

                    // If we haven't seen this type parameter already, then we can use this name
                    // and 'fix' it so that it doesn't change. Otherwise, use it, but allow it
                    // to be changed if it collides with anything else.
                    isFixed[i] = !names.Contains(name);
                    names[i]   = name;
                    typeParameters.Add((ITypeParameterSymbol)type);
                }
                else
                {
                    names[i] = "T";
                    typeParameters.Add(null);
                }
            }

            // We can use a type parameter as long as it hasn't been used in an outer type.
            var canUse = state.TypeToGenerateInOpt == null
                ? default(Func <string, bool>)
                : s => state.TypeToGenerateInOpt.GetAllTypeParameters().All(t => t.Name != s);

            var uniqueNames = NameGenerator.EnsureUniqueness(names, isFixed, canUse: canUse);

            for (int i = 0; i < uniqueNames.Count; i++)
            {
                if (typeParameters[i] == null || typeParameters[i].Name != uniqueNames[i])
                {
                    typeParameters[i] = CodeGenerationSymbolFactory.CreateTypeParameterSymbol(uniqueNames[i]);
                }
            }

            return(typeParameters.ToImmutableAndFree());
        }
Exemplo n.º 12
0
            private ISymbol GenerateProperty(
                Compilation compilation,
                IPropertySymbol property,
                Accessibility accessibility,
                DeclarationModifiers modifiers,
                bool generateAbstractly,
                bool useExplicitInterfaceSymbol,
                string memberName,
                CancellationToken cancellationToken)
            {
                var factory = this.Document.GetLanguageService <SyntaxGenerator>();
                var comAliasNameAttribute = compilation.ComAliasNameAttributeType();

                var getAccessor = property.GetMethod == null
                    ? null
                    : CodeGenerationSymbolFactory.CreateAccessorSymbol(
                    property.GetMethod.RemoveInaccessibleAttributesAndAttributesOfType(
                        accessibleWithin: this.State.ClassOrStructType,
                        removeAttributeType: comAliasNameAttribute),
                    attributes: null,
                    accessibility: accessibility,
                    explicitInterfaceSymbol: useExplicitInterfaceSymbol ? property.GetMethod : null,
                    statements: GetGetAccessorStatements(compilation, property, generateAbstractly, cancellationToken));

                var setAccessor = property.SetMethod == null
                    ? null
                    : CodeGenerationSymbolFactory.CreateAccessorSymbol(
                    property.SetMethod.RemoveInaccessibleAttributesAndAttributesOfType(
                        accessibleWithin: this.State.ClassOrStructType,
                        removeAttributeType: comAliasNameAttribute),
                    attributes: null,
                    accessibility: accessibility,
                    explicitInterfaceSymbol: useExplicitInterfaceSymbol ? property.SetMethod : null,
                    statements: GetSetAccessorStatements(compilation, property, generateAbstractly, cancellationToken));

                var syntaxFacts    = Document.GetLanguageService <ISyntaxFactsService>();
                var parameterNames = NameGenerator.EnsureUniqueness(
                    property.Parameters.Select(p => p.Name).ToList(), isCaseSensitive: syntaxFacts.IsCaseSensitive);

                var updatedProperty = property.RenameParameters(parameterNames);

                updatedProperty = updatedProperty.RemoveAttributeFromParameters(comAliasNameAttribute);

                // TODO(cyrusn): Delegate through throughMember if it's non-null.
                return(CodeGenerationSymbolFactory.CreatePropertySymbol(
                           updatedProperty,
                           accessibility: accessibility,
                           modifiers: modifiers,
                           explicitInterfaceSymbol: useExplicitInterfaceSymbol ? property : null,
                           name: memberName,
                           getMethod: getAccessor,
                           setMethod: setAccessor));
            }
Exemplo n.º 13
0
        protected static SyntaxToken GenerateUniqueLocalName(
            SemanticDocument document,
            TExpressionSyntax expression,
            bool isConstant,
            CancellationToken cancellationToken)
        {
            var semanticModel = document.SemanticModel;
            var baseName      = semanticModel.GenerateNameForExpression(expression, capitalize: isConstant);
            var reservedNames = semanticModel.LookupSymbols(expression.SpanStart).Select(s => s.Name);

            return(NameGenerator.EnsureUniqueness(baseName, reservedNames, true).ToIdentifierToken());
        }
            private string GetEventHandlerName(
                IEventSymbol eventSymbol, SyntaxToken plusEqualsToken, SemanticModel semanticModel,
                ISyntaxFactsService syntaxFactsService, NamingRule namingRule)
            {
                AssertIsBackground();
                var objectPart = GetNameObjectPart(eventSymbol, plusEqualsToken, semanticModel, syntaxFactsService);
                var basename = namingRule.NamingStyle.CreateName(ImmutableArray.Create(
                    string.Format("{0}_{1}", objectPart, eventSymbol.Name)));

                var reservedNames = semanticModel.LookupSymbols(plusEqualsToken.SpanStart).Select(m => m.Name);

                return NameGenerator.EnsureUniqueness(basename, reservedNames);
            }
 CodeAction GetAction(Document document, SemanticModel model, SyntaxNode root, SyntaxNode node, MethodDeclarationSyntax method)
 {
     return(CodeActionFactory.Create(node.Span, DiagnosticSeverity.Info, GettextCatalog.GetString("Extract anonymous method"), t2 =>
     {
         var identifier = SyntaxFactory.IdentifierName(NameGenerator.EnsureUniqueness("Method", model.LookupSymbols(node.SpanStart).Select(s => s.Name)));
         var surroundingMemberDeclaration = node.GetAncestor <MemberDeclarationSyntax>();
         var rootWithTrackedMember = root.TrackNodes(node, surroundingMemberDeclaration);
         var newRoot = rootWithTrackedMember.ReplaceNode(rootWithTrackedMember.GetCurrentNode(node), identifier);
         newRoot = newRoot
                   .InsertNodesBefore(newRoot.GetCurrentNode(surroundingMemberDeclaration),
                                      new[] { method.WithTrailingTrivia(surroundingMemberDeclaration.GetTrailingTrivia()) });
         return Task.FromResult(document.WithSyntaxRoot(newRoot));
     }));
 }
Exemplo n.º 16
0
        protected static SyntaxToken GenerateUniqueFieldName(
            SemanticDocument document,
            TExpressionSyntax expression,
            bool isConstant,
            CancellationToken cancellationToken)
        {
            var semanticModel = document.SemanticModel;
            var baseName      = semanticModel.GenerateNameForExpression(expression, isConstant);

            // A field can't conflict with any existing member names.
            var declaringType = semanticModel.GetEnclosingNamedType(expression.SpanStart, cancellationToken);
            var reservedNames = declaringType.GetMembers().Select(m => m.Name);

            return(NameGenerator.EnsureUniqueness(baseName, reservedNames, true).ToIdentifierToken());
        }
        protected static SyntaxToken GenerateUniqueLocalName(
            SemanticDocument document,
            TExpressionSyntax expression,
            bool isConstant,
            CancellationToken cancellationToken)
        {
            var syntaxFacts   = document.Project.LanguageServices.GetService <ISyntaxFactsService>();
            var semanticFacts = document.Project.LanguageServices.GetService <ISemanticFactsService>();

            var semanticModel = document.SemanticModel;
            var baseName      = semanticFacts.GenerateNameForExpression(semanticModel, expression, capitalize: isConstant);
            var reservedNames = semanticModel.LookupSymbols(expression.SpanStart).Select(s => s.Name);

            return(syntaxFacts.ToIdentifierToken(
                       NameGenerator.EnsureUniqueness(baseName, reservedNames, syntaxFacts.IsCaseSensitive)));
        }
Exemplo n.º 18
0
        public static IList <string> GenerateParameterNames(
            this SemanticModel semanticModel,
            IEnumerable <AttributeArgumentSyntax> arguments,
            IList <string> reservedNames = null)
        {
            reservedNames = reservedNames ?? SpecializedCollections.EmptyList <string>();

            // We can't change the names of named parameters.  Any other names we're flexible on.
            var isFixed = reservedNames.Select(s => true).Concat(
                arguments.Select(a => a.NameEquals != null)).ToList();

            var parameterNames = reservedNames.Concat(
                arguments.Select(a => semanticModel.GenerateNameForArgument(a))).ToList();

            return(NameGenerator.EnsureUniqueness(parameterNames, isFixed).Skip(reservedNames.Count).ToList());
        }
Exemplo n.º 19
0
        public static string CreateUniqueEventName(
            Document document, string className, string objectName, string nameOfEvent, CancellationToken cancellationToken)
        {
            var type = document.Project.GetCompilationAsync(cancellationToken).WaitAndGetResult_Venus(cancellationToken).GetTypeByMetadataName(className);
            var name = objectName + "_" + nameOfEvent;

            var semanticModel = document.GetSemanticModelAsync(cancellationToken).WaitAndGetResult_Venus(cancellationToken);

            var tree          = document.GetSyntaxTreeSynchronously(cancellationToken);
            var typeNode      = type.DeclaringSyntaxReferences.Where(r => r.SyntaxTree == tree).Select(r => r.GetSyntax(cancellationToken)).First();
            var codeModel     = document.Project.LanguageServices.GetService <ICodeModelNavigationPointService>();
            var point         = codeModel.GetStartPoint(typeNode, EnvDTE.vsCMPart.vsCMPartBody);
            var reservedNames = semanticModel.LookupSymbols(point.Value.Position, type).Select(m => m.Name);

            return(NameGenerator.EnsureUniqueness(name, reservedNames, document.Project.LanguageServices.GetService <ISyntaxFactsService>().IsCaseSensitive));
        }
        public SyntaxToken GenerateUniqueName(
            SemanticModel semanticModel, SyntaxNode location, SyntaxNode containerOpt,
            string baseName, CancellationToken cancellationToken)
        {
            var syntaxFacts = this.SyntaxFactsService;

            var container = containerOpt ?? location.AncestorsAndSelf().FirstOrDefault(
                a => syntaxFacts.IsExecutableBlock(a) || syntaxFacts.IsMethodBody(a));
            var existingSymbols = semanticModel.GetExistingSymbols(container, cancellationToken);

            var reservedNames = semanticModel.LookupSymbols(location.SpanStart)
                                .Select(s => s.Name)
                                .Concat(existingSymbols.Select(s => s.Name));

            return(syntaxFacts.ToIdentifierToken(
                       NameGenerator.EnsureUniqueness(baseName, reservedNames, syntaxFacts.IsCaseSensitive)));
        }
        private ImmutableArray <ParameterName> GenerateParameterNames(
            SemanticDocument document,
            IEnumerable <Argument> arguments,
            IList <string> reservedNames,
            NamingRule parameterNamingRule,
            CancellationToken cancellationToken
            )
        {
            reservedNames ??= SpecializedCollections.EmptyList <string>();

            // We can't change the names of named parameters.  Any other names we're flexible on.
            var isFixed = reservedNames
                          .Select(s => true)
                          .Concat(arguments.Select(a => a.IsNamed))
                          .ToImmutableArray();

            var parameterNames = reservedNames
                                 .Concat(
                arguments.Select(
                    a =>
                    this.GenerateNameForArgument(
                        document.SemanticModel,
                        a,
                        cancellationToken
                        )
                    )
                )
                                 .ToImmutableArray();

            var syntaxFacts = document.Document.GetRequiredLanguageService <ISyntaxFactsService>();
            var comparer    = syntaxFacts.StringComparer;

            return(NameGenerator
                   .EnsureUniqueness(
                       parameterNames,
                       isFixed,
                       canUse: s => !reservedNames.Any(n => comparer.Equals(s, n))
                       )
                   .Select(
                       (name, index) => new ParameterName(name, isFixed[index], parameterNamingRule)
                       )
                   .Skip(reservedNames.Count)
                   .ToImmutableArray());
        }
Exemplo n.º 22
0
            public IMethodSymbol GenerateMethod(
                SyntaxGenerator factory,
                bool isAbstract,
                CancellationToken cancellationToken)
            {
                var parameters = DetermineParameters(cancellationToken);
                var returnType = DetermineReturnType(cancellationToken);
                var isUnsafe   = false;

                if (!State.IsContainedInUnsafeType)
                {
                    isUnsafe = returnType.IsUnsafe() || parameters.Any(p => p.Type.IsUnsafe());
                }

                var returnsByRef = DetermineReturnsByRef(cancellationToken);

                var method = CodeGenerationSymbolFactory.CreateMethodSymbol(
                    attributes: default(ImmutableArray <AttributeData>),
                    accessibility: DetermineAccessibility(isAbstract),
                    modifiers: new DeclarationModifiers(isStatic: State.IsStatic, isAbstract: isAbstract, isUnsafe: isUnsafe),
                    returnType: returnType,
                    returnsByRef: returnsByRef,
                    explicitInterfaceSymbol: null,
                    name: this.State.IdentifierToken.ValueText,
                    typeParameters: DetermineTypeParameters(cancellationToken),
                    parameters: parameters,
                    statements: GenerateStatements(factory, isAbstract, cancellationToken),
                    handlesExpressions: default(ImmutableArray <SyntaxNode>),
                    returnTypeAttributes: default(ImmutableArray <AttributeData>),
                    methodKind: State.MethodKind);

                // Ensure no conflicts between type parameter names and parameter names.
                var languageServiceProvider = this.Document.Project.Solution.Workspace.Services.GetLanguageServices(this.State.TypeToGenerateIn.Language);
                var syntaxFacts             = languageServiceProvider.GetService <ISyntaxFactsService>();

                var equalityComparer       = syntaxFacts.IsCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
                var reservedParameterNames = this.DetermineParameterNames(cancellationToken)
                                             .Select(p => p.BestNameForParameter)
                                             .ToSet(equalityComparer);
                var newTypeParameterNames = NameGenerator.EnsureUniqueness(
                    method.TypeParameters.Select(t => t.Name).ToList(), n => !reservedParameterNames.Contains(n));

                return(method.RenameTypeParameters(newTypeParameterNames));
            }
Exemplo n.º 23
0
        private static SyntaxNode GetNewMethodDeclaration(
            IMethodSymbol method,
            TArgumentSyntax argument,
            SeparatedSyntaxList <TArgumentSyntax> argumentList,
            SyntaxGenerator generator,
            SyntaxNode declaration,
            ISemanticFactsService semanticFacts,
            string argumentName,
            SyntaxNode expression,
            SemanticModel semanticModel,
            ITypeSymbol parameterType,
            CancellationToken cancellationToken)
        {
            if (!string.IsNullOrWhiteSpace(argumentName))
            {
                var newParameterSymbol = CodeGenerationSymbolFactory.CreateParameterSymbol(
                    attributes: default(ImmutableArray <AttributeData>),
                    refKind: RefKind.None,
                    isParams: false,
                    type: parameterType,
                    name: argumentName);

                var newParameterDeclaration = generator.ParameterDeclaration(newParameterSymbol);
                return(generator.AddParameters(declaration, new[] { newParameterDeclaration }));
            }
            else
            {
                var name = semanticFacts.GenerateNameForExpression(
                    semanticModel, expression, capitalize: false, cancellationToken: cancellationToken);
                var uniqueName = NameGenerator.EnsureUniqueness(name, method.Parameters.Select(p => p.Name));

                var newParameterSymbol = CodeGenerationSymbolFactory.CreateParameterSymbol(
                    attributes: default(ImmutableArray <AttributeData>),
                    refKind: RefKind.None,
                    isParams: false,
                    type: parameterType,
                    name: uniqueName);

                var argumentIndex           = argumentList.IndexOf(argument);
                var newParameterDeclaration = generator.ParameterDeclaration(newParameterSymbol);
                return(generator.InsertParameters(
                           declaration, argumentIndex, new[] { newParameterDeclaration }));
            }
        }
        protected static SyntaxToken GenerateUniqueFieldName(
            SemanticDocument document,
            TExpressionSyntax expression,
            bool isConstant,
            CancellationToken cancellationToken)
        {
            var syntaxFacts   = document.Project.LanguageServices.GetService <ISyntaxFactsService>();
            var semanticFacts = document.Project.LanguageServices.GetService <ISemanticFactsService>();

            var semanticModel = document.SemanticModel;
            var baseName      = semanticFacts.GenerateNameForExpression(semanticModel, expression, isConstant);

            // A field can't conflict with any existing member names.
            var declaringType = semanticModel.GetEnclosingNamedType(expression.SpanStart, cancellationToken);
            var reservedNames = declaringType.GetMembers().Select(m => m.Name);

            return(syntaxFacts.ToIdentifierToken(
                       NameGenerator.EnsureUniqueness(baseName, reservedNames, syntaxFacts.IsCaseSensitive)));
        }
            private ISymbol GenerateProperty(
                Compilation compilation,
                IPropertySymbol property,
                Accessibility accessibility,
                DeclarationModifiers modifiers,
                bool generateAbstractly,
                bool useExplicitInterfaceSymbol,
                string memberName,
                ImplementTypePropertyGenerationBehavior propertyGenerationBehavior,
                CancellationToken cancellationToken)
            {
                var factory            = this.Document.GetLanguageService <SyntaxGenerator>();
                var attributesToRemove = AttributesToRemove(compilation);

                var getAccessor = GenerateGetAccessor(
                    compilation, property, accessibility, generateAbstractly, useExplicitInterfaceSymbol,
                    propertyGenerationBehavior, attributesToRemove, cancellationToken);

                var setAccessor = GenerateSetAccessor(
                    compilation, property, accessibility, generateAbstractly, useExplicitInterfaceSymbol,
                    propertyGenerationBehavior, attributesToRemove, cancellationToken);

                var syntaxFacts    = Document.GetLanguageService <ISyntaxFactsService>();
                var parameterNames = NameGenerator.EnsureUniqueness(
                    property.Parameters.Select(p => p.Name).ToList(), isCaseSensitive: syntaxFacts.IsCaseSensitive);

                var updatedProperty = property.RenameParameters(parameterNames);

                updatedProperty = updatedProperty.RemoveAttributeFromParameters(attributesToRemove);

                // TODO(cyrusn): Delegate through throughMember if it's non-null.
                return(CodeGenerationSymbolFactory.CreatePropertySymbol(
                           updatedProperty,
                           accessibility: accessibility,
                           modifiers: modifiers,
                           explicitInterfaceSymbol: useExplicitInterfaceSymbol ? property : null,
                           name: memberName,
                           getMethod: getAccessor,
                           setMethod: setAccessor));
            }
        static MethodDeclarationSyntax GetMethod(SemanticModel context, TextSpan span, IMethodSymbol lambdaSymbol, BlockSyntax body)
        {
            TypeSyntax returnType = null;

            if (lambdaSymbol.ReturnsVoid)
            {
                returnType = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword));
            }
            else
            {
                var type = lambdaSymbol.ReturnType;
                returnType = type.TypeKind == TypeKind.Unknown ?
                             SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword)) :
                             SyntaxFactory.ParseTypeName(type.Name).WithAdditionalAnnotations(Simplifier.Annotation);
            }

            var methodParameters = SyntaxFactory.ParameterList(
                SyntaxFactory.SeparatedList(lambdaSymbol.Parameters.Select(p => SyntaxFactory.Parameter(
                                                                               SyntaxFactory.List <AttributeListSyntax>(),
                                                                               SyntaxFactory.TokenList(),
                                                                               SyntaxFactory.ParseTypeName(p.Type.Name),
                                                                               SyntaxFactory.Identifier(p.Name),
                                                                               null
                                                                               ))
                                            ));

            var method = SyntaxFactory.MethodDeclaration(returnType, NameGenerator.EnsureUniqueness("Method", context.LookupSymbols(span.Start).Select(s => s.Name)))
                         .WithParameterList(methodParameters)
                         .WithBody(body);

            if (lambdaSymbol.IsAsync)
            {
                method = method.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.AsyncKeyword)));
            }

            return(method.WithAdditionalAnnotations(Formatter.Annotation, Simplifier.Annotation));
        }
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;

            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
            {
                return;
            }
            var span = context.Span;

            if (!span.IsEmpty)
            {
                return;
            }
            var cancellationToken = context.CancellationToken;

            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            if (model.IsFromGeneratedCode(cancellationToken))
            {
                return;
            }
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            var token = root.FindToken(span.Start);

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

            var bracketedList = token.Parent.AncestorsAndSelf().OfType <ArgumentListSyntax>().FirstOrDefault();

            if (bracketedList == null)
            {
                return;
            }
            var elementAccess = bracketedList.AncestorsAndSelf().OfType <InvocationExpressionSyntax>().FirstOrDefault();

            if ((elementAccess == null) || (elementAccess.Expression == null))
            {
                return;
            }
            var elementType = model.GetTypeInfo(elementAccess.Expression);

            if (elementType.Type == null)
            {
                return;
            }

            if (!IsDictionary(elementType.Type as INamedTypeSymbol) && !elementType.Type.AllInterfaces.Any(IsDictionary))
            {
                return;
            }

            context.RegisterRefactoring(
                CodeActionFactory.Create(
                    span,
                    DiagnosticSeverity.Info,
                    string.Format(GettextCatalog.GetString("Check 'If {0}.TryGetValue({1}, val)'"), elementAccess.Expression, elementAccess.ArgumentList.Arguments.First()),
                    t2 =>
            {
                var reservedNames        = model.LookupSymbols(elementAccess.SpanStart).Select(s => s.Name);
                string localVariableName = NameGenerator.EnsureUniqueness("val", reservedNames, true);

                var parentStatement = elementAccess.Parent.AncestorsAndSelf().OfType <StatementSyntax>().FirstOrDefault();
                var dict            = IsDictionary(elementType.Type as INamedTypeSymbol) ? elementType.Type : elementType.Type.AllInterfaces.First(IsDictionary);

                var tempVariableDeclaration = SyntaxFactory.LocalDeclarationStatement(
                    SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.DimKeyword)),
                    SyntaxFactory.SeparatedList(new[] {
                    SyntaxFactory.VariableDeclarator(SyntaxFactory.SeparatedList(new[]
                    {
                        SyntaxFactory.ModifiedIdentifier(localVariableName)
                    }),
                                                     SyntaxFactory.SimpleAsClause(SyntaxFactory.ParseTypeName(dict.GetTypeArguments()[1].GetFullName())),
                                                     null)
                })).WithTrailingTrivia(parentStatement.GetTrailingTrivia());

                var newParent = SyntaxFactory.MultiLineIfBlock(
                    SyntaxFactory.IfStatement(
                        SyntaxFactory.Token(SyntaxKind.IfKeyword),
                        SyntaxFactory.InvocationExpression(
                            SyntaxFactory.MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                elementAccess.Expression,
                                SyntaxFactory.Token(SyntaxKind.DotToken),
                                SyntaxFactory.IdentifierName("TryGetValue")),
                            SyntaxFactory.ArgumentList(elementAccess.ArgumentList.Arguments)
                            .AddArguments(SyntaxFactory.SimpleArgument(SyntaxFactory.IdentifierName(localVariableName)))
                            ),
                        SyntaxFactory.Token(SyntaxKind.ThenKeyword)),
                    SyntaxFactory.List(new[] { parentStatement.ReplaceNode(elementAccess, SyntaxFactory.IdentifierName(localVariableName)) }),
                    SyntaxFactory.List <ElseIfBlockSyntax>(), null
                    ).WithLeadingTrivia(parentStatement.GetLeadingTrivia());

                return(Task.FromResult(document.WithSyntaxRoot(root.ReplaceNode(parentStatement,
                                                                                new SyntaxNode[] { tempVariableDeclaration.WithAdditionalAnnotations(Formatter.Annotation), newParent.WithAdditionalAnnotations(Formatter.Annotation) }))));
            }
                    )
                );
        }
Exemplo n.º 28
0
            private bool TryFindMatchingField(
                ImmutableArray <TArgumentSyntax> arguments,
                ImmutableArray <TAttributeArgumentSyntax>?attributeArguments,
                ImmutableArray <ParameterName> parameterNames,
                ImmutableArray <ITypeSymbol> parameterTypes,
                int index,
                Dictionary <string, ISymbol> parameterToExistingFieldMap,
                Dictionary <string, string> parameterToNewFieldMap,
                bool caseSensitive,
                out ImmutableArray <ParameterName> newParameterNames)
            {
                var parameterName         = parameterNames[index];
                var parameterType         = parameterTypes[index];
                var isFixed               = _service.IsNamedArgument(arguments[index]);
                var newParameterNamesList = parameterNames.ToList();

                // For non-out parameters, see if there's already a field there with the same name.
                // If so, and it has a compatible type, then we can just assign to that field.
                // Otherwise, we'll need to choose a different name for this member so that it
                // doesn't conflict with something already in the type. First check the current type
                // for a matching field.  If so, defer to it.
                var comparison = caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;

                foreach (var type in _state.TypeToGenerateIn.GetBaseTypesAndThis())
                {
                    var ignoreAccessibility = type.Equals(_state.TypeToGenerateIn);
                    var symbol = type.GetMembers()
                                 .FirstOrDefault(s => s.Name.Equals(parameterName.NameBasedOnArgument, comparison));

                    if (symbol != null)
                    {
                        if (ignoreAccessibility || IsSymbolAccessible(symbol))
                        {
                            if (IsViableFieldOrProperty(parameterType, symbol))
                            {
                                // Ok!  We can just the existing field.
                                parameterToExistingFieldMap[parameterName.BestNameForParameter] = symbol;
                            }
                            else
                            {
                                // Uh-oh.  Now we have a problem.  We can't assign this parameter to
                                // this field.  So we need to create a new field.  Find a name not in
                                // use so we can assign to that.
                                var newFieldName = NameGenerator.EnsureUniqueness(
                                    attributeArguments != null
                                        ? _service.GenerateNameForArgument(_document.SemanticModel, attributeArguments.Value[index], _cancellationToken)
                                        : _service.GenerateNameForArgument(_document.SemanticModel, arguments[index], _cancellationToken),
                                    GetUnavailableMemberNames().Concat(parameterToNewFieldMap.Values));

                                if (isFixed)
                                {
                                    // Can't change the parameter name, so map the existing parameter
                                    // name to the new field name.
                                    parameterToNewFieldMap[parameterName.NameBasedOnArgument] = newFieldName;
                                }
                                else
                                {
                                    // Can change the parameter name, so do so.
                                    var newParameterName = new ParameterName(newFieldName, isFixed: false);
                                    newParameterNamesList[index] = newParameterName;
                                    parameterToNewFieldMap[newParameterName.BestNameForParameter] = newFieldName;
                                }
                            }

                            newParameterNames = newParameterNamesList.ToImmutableArray();
                            return(true);
                        }
                    }
                }

                newParameterNames = newParameterNamesList.ToImmutableArray();
                return(false);
            }
Exemplo n.º 29
0
 private static IList <ParameterName> GenerateNames(IList <string> reservedNames, List <bool> isFixed, List <string> parameterNames)
 {
     return(NameGenerator.EnsureUniqueness(parameterNames, isFixed)
            .Select((name, index) => new ParameterName(name, isFixed[index]))
            .Skip(reservedNames.Count).ToList());
 }
Exemplo n.º 30
0
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;

            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
            {
                return;
            }
            var span = context.Span;

            if (!span.IsEmpty)
            {
                return;
            }
            var cancellationToken = context.CancellationToken;

            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            if (model.IsFromGeneratedCode(cancellationToken))
            {
                return;
            }
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            var token = root.FindToken(span.Start);

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

            var bracketedList = token.Parent.AncestorsAndSelf().OfType <BracketedArgumentListSyntax>().FirstOrDefault();

            if (bracketedList == null)
            {
                return;
            }
            var elementAccess = bracketedList.AncestorsAndSelf().OfType <ElementAccessExpressionSyntax>().FirstOrDefault();

            if (elementAccess == null)
            {
                return;
            }
            var elementType = model.GetTypeInfo(elementAccess.Expression);
            var type        = elementType.Type;

            if (type == null)
            {
                return;
            }
            if (!IsDictionary(type as INamedTypeSymbol) && !type.AllInterfaces.Any(IsDictionary))
            {
                return;
            }
            context.RegisterRefactoring(
                CodeActionFactory.Create(
                    span,
                    DiagnosticSeverity.Info,
                    string.Format(GettextCatalog.GetString("Use 'if ({0}.TryGetValue({1}, out val))'"), elementAccess.Expression, elementAccess.ArgumentList.Arguments.First()),
                    t2 =>
            {
                var reservedNames        = model.LookupSymbols(elementAccess.SpanStart).Select(s => s.Name);
                string localVariableName = NameGenerator.EnsureUniqueness("val", reservedNames, true);

                var parentStatement = elementAccess.Parent.AncestorsAndSelf().OfType <StatementSyntax>().FirstOrDefault();
                var newParent       = SyntaxFactory.IfStatement(
                    SyntaxFactory.InvocationExpression(
                        SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, elementAccess.Expression, SyntaxFactory.IdentifierName("TryGetValue")),
                        SyntaxFactory.ArgumentList(elementAccess.ArgumentList.Arguments.Add(SyntaxFactory.Argument(SyntaxFactory.IdentifierName(localVariableName)).WithRefOrOutKeyword(SyntaxFactory.Token(SyntaxKind.OutKeyword))))
                        ),
                    parentStatement.ReplaceNode(elementAccess, SyntaxFactory.IdentifierName(localVariableName))
                    ).WithAdditionalAnnotations(Formatter.Annotation);
                var dict = IsDictionary(elementType.Type as INamedTypeSymbol) ? elementType.Type : elementType.Type.AllInterfaces.First(IsDictionary);

                var varDecl = SyntaxFactory.LocalDeclarationStatement(
                    SyntaxFactory.VariableDeclaration(
                        dict.GetTypeArguments()[1].GenerateTypeSyntax(),
                        SyntaxFactory.SeparatedList(new[] { SyntaxFactory.VariableDeclarator(localVariableName) })
                        )
                    ).WithAdditionalAnnotations(Formatter.Annotation);

                SyntaxNode newRoot;

                if (parentStatement.Parent.IsKind(SyntaxKind.Block))
                {
                    newRoot = root.ReplaceNode(parentStatement, new SyntaxNode[] { varDecl, newParent });
                }
                else
                {
                    newRoot = root.ReplaceNode(parentStatement, SyntaxFactory.Block(varDecl, newParent).WithAdditionalAnnotations(Formatter.Annotation));
                }

                return(Task.FromResult(document.WithSyntaxRoot(newRoot)));
            }
                    )
                );
        }