public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var document = context.Document; var span = context.Span; var cancellationToken = context.CancellationToken; var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var token = root.FindToken(span.Start); if (!token.Span.IntersectsWith(span)) { return; } var service = document.GetRequiredLanguageService <IImplementInterfaceService>(); var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var options = ImplementTypeOptions.From(document.Project); var actions = token.Parent.GetAncestorsOrThis <TypeSyntax>() .Where(_interfaceName) .Select(n => service.GetCodeActions(document, options, model, n, cancellationToken)) .FirstOrDefault(a => !a.IsEmpty); if (actions.IsDefaultOrEmpty) { return; } context.RegisterFixes(actions, context.Diagnostics); }
public static ImplementInterfaceCodeAction CreateImplementRemainingExplicitlyCodeAction( AbstractImplementInterfaceService service, Document document, ImplementTypeOptions options, State state) { return(new ImplementInterfaceCodeAction(service, document, options, state, explicitly: true, abstractly: false, onlyRemaining: true, throughMember: null)); }
private IEnumerable <CodeAction> GetActions(Document document, ImplementTypeOptions options, State state) { if (state == null) { yield break; } if (state.MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented.Length > 0) { yield return(ImplementInterfaceCodeAction.CreateImplementCodeAction(this, document, options, state)); if (ShouldImplementDisposePattern(state, explicitly: false)) { yield return(ImplementInterfaceWithDisposePatternCodeAction.CreateImplementWithDisposePatternCodeAction(this, document, options, state)); } var delegatableMembers = GetDelegatableMembers(state); foreach (var member in delegatableMembers) { yield return(ImplementInterfaceCodeAction.CreateImplementThroughMemberCodeAction(this, document, options, state, member)); } if (state.ClassOrStructType.IsAbstract) { yield return(ImplementInterfaceCodeAction.CreateImplementAbstractlyCodeAction(this, document, options, state)); } } if (state.MembersWithoutExplicitImplementation.Length > 0) { yield return(ImplementInterfaceCodeAction.CreateImplementExplicitlyCodeAction(this, document, options, state)); if (ShouldImplementDisposePattern(state, explicitly: true)) { yield return(ImplementInterfaceWithDisposePatternCodeAction.CreateImplementExplicitlyWithDisposePatternCodeAction(this, document, options, state)); } } if (AnyImplementedImplicitly(state)) { yield return(ImplementInterfaceCodeAction.CreateImplementRemainingExplicitlyCodeAction(this, document, options, state)); } }
internal ImplementInterfaceCodeAction( AbstractImplementInterfaceService service, Document document, ImplementTypeOptions options, State state, bool explicitly, bool abstractly, bool onlyRemaining, ISymbol throughMember) { Service = service; Document = document; Options = options; State = state; Abstractly = abstractly; _onlyRemaining = onlyRemaining; Explicitly = explicitly; ThroughMember = throughMember; _equivalenceKey = ComputeEquivalenceKey(state, explicitly, abstractly, onlyRemaining, throughMember, GetType().FullName); }
public async Task <Document> ImplementInterfaceAsync(Document document, ImplementTypeOptions options, SyntaxNode node, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Refactoring_ImplementInterface, cancellationToken)) { var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var state = State.Generate(this, document, model, node, cancellationToken); if (state == null) { return(document); } // While implementing just one default action, like in the case of pressing enter after interface name in VB, // choose to implement with the dispose pattern as that's the Dev12 behavior. var action = ShouldImplementDisposePattern(state, explicitly: false) ? ImplementInterfaceWithDisposePatternCodeAction.CreateImplementWithDisposePatternCodeAction(this, document, options, state) : ImplementInterfaceCodeAction.CreateImplementCodeAction(this, document, options, state); return(await action.GetUpdatedDocumentAsync(cancellationToken).ConfigureAwait(false)); } }
private IEnumerable <CodeAction> GetActions(Document document, ImplementTypeOptions options, State state) { if (state == null) { yield break; } if (state.MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented.Length > 0) { var totalMemberCount = 0; var inaccessibleMemberCount = 0; foreach (var(_, members) in state.MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented) { foreach (var member in members) { totalMemberCount++; if (AccessibilityHelper.IsLessAccessibleThan(member, state.ClassOrStructType)) { inaccessibleMemberCount++; } } } // If all members to implement are inaccessible, then "Implement interface" codeaction // will be the same as "Implement interface explicitly", so there is no point in having both of them if (totalMemberCount != inaccessibleMemberCount) { yield return(ImplementInterfaceCodeAction.CreateImplementCodeAction(this, document, options, state)); } if (ShouldImplementDisposePattern(state, explicitly: false)) { yield return(ImplementInterfaceWithDisposePatternCodeAction.CreateImplementWithDisposePatternCodeAction(this, document, options, state)); } var delegatableMembers = GetDelegatableMembers(state); foreach (var member in delegatableMembers) { yield return(ImplementInterfaceCodeAction.CreateImplementThroughMemberCodeAction(this, document, options, state, member)); } if (state.ClassOrStructType.IsAbstract) { yield return(ImplementInterfaceCodeAction.CreateImplementAbstractlyCodeAction(this, document, options, state)); } } if (state.MembersWithoutExplicitImplementation.Length > 0) { yield return(ImplementInterfaceCodeAction.CreateImplementExplicitlyCodeAction(this, document, options, state)); if (ShouldImplementDisposePattern(state, explicitly: true)) { yield return(ImplementInterfaceWithDisposePatternCodeAction.CreateImplementExplicitlyWithDisposePatternCodeAction(this, document, options, state)); } } if (AnyImplementedImplicitly(state)) { yield return(ImplementInterfaceCodeAction.CreateImplementRemainingExplicitlyCodeAction(this, document, options, state)); } }
public ImmutableArray <CodeAction> GetCodeActions(Document document, ImplementTypeOptions options, SemanticModel model, SyntaxNode node, CancellationToken cancellationToken) { var state = State.Generate(this, document, model, node, cancellationToken); return(GetActions(document, options, state).ToImmutableArray()); }
public IEntityBase ImplementToNewType(PersistentTypeKind newTypeKind, string newTypeName, ImplementTypeOptions options) { throw new NotImplementedException(); }
public void ImplementToType(IEntityBase targetType, ImplementTypeOptions options) { throw new NotImplementedException(); }
public void ImplementToType(IEntityBase targetType, ImplementTypeOptions options) { this.Store.MakeActionWithinTransaction(string.Format("Implementing interface '{0}' to existing type '{1}'", this.Name, targetType.Name), () => InternalImplementToType(targetType, options)); }
public IEntityBase ImplementToNewType(PersistentTypeKind newTypeKind, string newTypeName, ImplementTypeOptions options) { if (!newTypeKind.In(PersistentTypeKind.Entity, PersistentTypeKind.Structure)) { throw new ArgumentOutOfRangeException("newTypeKind", "Interface can be implemented only be Entities or Structures!"); } EntityBase newEntity = null; this.Store.MakeActionWithinTransaction(string.Format("Implementing new '{0}': {1} from interface '{2}'", newTypeName, newTypeKind, this.Name), delegate { newEntity = newTypeKind == PersistentTypeKind.Entity ? (EntityBase) new Entity(this.Partition) : new Structure(this.Partition); newEntity.Access = this.Access; newEntity.Documentation = this.Documentation; newEntity.Name = newTypeName; this.EntityModel.PersistentTypes.Add(newEntity); InternalImplementToType(newEntity, options); }); return(newEntity); }
private void InternalImplementToType(IEntityBase targetType, ImplementTypeOptions options) { EntityBase entityBase = (EntityBase)targetType; List <PropertyBase> addedProperties = new List <PropertyBase>(); foreach (PropertyBase property in this.Properties) { if (!entityBase.ContainsProperty(property.PropertyKind, property.Name)) { PropertyBase copiedProperty = (PropertyBase)property.Copy(new[] { PersistentTypeHasProperties.PersistentTypeDomainRoleId }); entityBase.Properties.Add(copiedProperty); addedProperties.Add(copiedProperty); } } foreach (NavigationProperty navigationProperty in this.NavigationProperties) { if (!entityBase.ContainsProperty(PropertyKind.Navigation, navigationProperty.Name)) { NavigationProperty copiedNavigationProperty = (NavigationProperty)navigationProperty.Copy(new[] { PersistentTypeHasNavigationProperties.PersistentTypeOfNavigationPropertyDomainRoleId, }); entityBase.NavigationProperties.Add(copiedNavigationProperty); copiedNavigationProperty.PersistentTypeHasAssociations.SourcePersistentType = entityBase; addedProperties.Add(copiedNavigationProperty); } } foreach (EntityIndex entityIndex in this.Indexes) { if (!entityBase.ContainsIndex(entityIndex)) { EntityIndex copiedIndex = (EntityIndex)entityIndex.Copy(new[] { InterfaceHasIndexes.InterfaceOfIndexDomainRoleId }); entityBase.Indexes.Add(copiedIndex); } } if (Util.IsFlagSet(ImplementTypeOptions.CopyInheritedInterfaces, options)) { foreach (Interface inheritedInterface in this.InheritedInterfaces) { if (!entityBase.InheritedInterfaces.Contains(inheritedInterface)) { entityBase.InheritedInterfaces.Add(inheritedInterface); } } } if (!targetType.InheritedInterfaces.Contains(this)) { entityBase.InheritedInterfaces.Add(this); } var duplicatedInfo = PersistentTypeValidation.FindDuplicatedPropertieInInheritanceTree(targetType, null); foreach (var addedProperty in addedProperties) { Func <IPropertyBase, bool> foundPropertyFunc = item => item.PropertyKind == addedProperty.PropertyKind && Util.StringEqual(item.Name, addedProperty.Name, true); addedProperty.IsInherited = duplicatedInfo.PropertiesWithDifferentType.Any(foundPropertyFunc) || duplicatedInfo.PropertiesWithSameType.Any(foundPropertyFunc); } }