can create class objects either from plain source code or from symbol information. Even when source code is read, symbol information is needed to resolve the base class. Furhter base classes will be resolved recursivly.
Example #1
0
 /// <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);
        }
Example #5
0
        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));
        }