/// <summary> /// Template method that checks if command can be executed and if yes, /// executes the command. Otherwise the original source code of the child is returned. /// </summary> /// <param name="semantic">semantic model of the child's and mixin's source code</param> /// <param name="settings">optional settings object</param> /// <returns>the modified class declaration of the child class after executing /// the command or the original child's source code if command could not be /// executed</returns> public ClassDeclarationSyntax Execute( ClassDeclarationSyntax childDeclaration, SemanticModel semantic, Settings settings = null) { var childClass = new ClassFactory(semantic).Create(childDeclaration); if (CanExecute(childClass, settings)) return InternalExecute(childClass, semantic, settings); return childClass.SourceCode; }
public MixinReference Create(SimpleBaseTypeSyntax typeOfMixinNode) { var typeOfMixin = _semantic.GetTypeInfo(typeOfMixinNode.Type).Type; // type could not be resolved => return here if (typeOfMixin.TypeKind == TypeKind.Error) return null; var mixinClass = new ClassFactory(_semantic).Create(typeOfMixin); var mixinName = mixinClass.Name.ConvertTypeNameToFieldName(); return new MixinReference(mixinName, mixinClass); }
public override void VisitSimpleBaseType(SimpleBaseTypeSyntax node) { var baseClassType = node.Type; var baseClassSymbolInfo = _semantic.GetSymbolInfo(baseClassType); if (baseClassSymbolInfo.Symbol != null) { var baseClassTypeSymbol = (ITypeSymbol)baseClassSymbolInfo.Symbol; // skip interfaces as base types (since they do not have an implementation // their methods will always be overridden by the mixins) if (baseClassTypeSymbol.TypeKind == TypeKind.Interface) return; var classFactory = new ClassFactory(_semantic); _subClass.BaseClass = classFactory.Create(baseClassTypeSymbol); } }
public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); // Find the node at the selection. var node = root.FindNode(context.Span); var model = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false); CompositeCommand command = null; // create mixin from base type var baseTypeSyntax = node as SimpleBaseTypeSyntax; // create command depending on the selected node if (baseTypeSyntax != null) { command = new CreateMixinFromInterfaceCommand(baseTypeSyntax, model); } else { var fieldDeclarationNode = GetContainingFieldDeclaration(node); if (fieldDeclarationNode != null) command = new CreateMixinFromFieldDeclarationCommand(fieldDeclarationNode, model); } if (command == null) return; // get service provider and read settings from storage var serviceProvider = Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider; var settings = new Settings(serviceProvider); var childClassDeclaration = node.FindContainingClass(); var childClass = new ClassFactory(model).Create(childClassDeclaration); if (!command.CanExecute(childClass, settings)) return; var action = CodeAction.Create( command.Title, c => CreateMixin(command, context.Document, childClass, c)); // Register this code action. context.RegisterRefactoring(action); }
public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) { // we take only the first declaration we found // so if this field definition has more than one variable declaration, // skip after the first one if (MixinReference != null) return; var fieldSymbol = (IFieldSymbol)_semantic.GetDeclaredSymbol(node); var typeOfField = fieldSymbol.Type; // type could not be resolved => return here if (typeOfField.TypeKind == TypeKind.Error) return; // also ignore native types (like int, string, double etc...) // we identify them by checking if the types are declared in the runtime itself // if yes, they are system types and we will skip them var module = typeOfField.ContainingModule; if (module != null && module.Name == CommonLanguageRuntimeLibrary) return; var classFactory = new ClassFactory(_semantic); // create the mixin reference, that is the name of the field and the type the field references MixinReference = new MixinReference(fieldSymbol.Name, classFactory.Create(typeOfField)); }