internal static CompilationUnitSyntax ImplementINotifyPropertyChanged(CompilationUnitSyntax root, SemanticModel model, IEnumerable<ExpandablePropertyInfo> properties, Workspace workspace) { var typeDeclaration = properties.First().PropertyDeclaration.FirstAncestorOrSelf<TypeDeclarationSyntax>(); var backingFieldLookup = Enumerable.ToDictionary(properties, info => info.PropertyDeclaration, info => info.BackingFieldName); root = root.ReplaceNodes(properties.Select(p => p.PropertyDeclaration as SyntaxNode).Concat(new[] { typeDeclaration }), (original, updated) => original.IsKind(SyntaxKind.PropertyDeclaration) ? ExpandProperty((PropertyDeclarationSyntax)original, backingFieldLookup[(PropertyDeclarationSyntax)original]) as SyntaxNode : ExpandType((TypeDeclarationSyntax)original, (TypeDeclarationSyntax)updated, properties.Where(p => p.NeedsBackingField), model, workspace)); return root .WithUsing("System.Collections.Generic") .WithUsing("System.ComponentModel"); }
internal static CompilationUnitSyntax ImplementFullProperty(CompilationUnitSyntax root, SemanticModel model, PropertyDeclarationSyntax propertyDecl, Workspace workspace) { TypeDeclarationSyntax typeDecl = propertyDecl.FirstAncestorOrSelf<TypeDeclarationSyntax>(); string propertyName = propertyDecl.Identifier.ValueText; string backingFieldName = $"_{char.ToLower(propertyName[0])}{propertyName.Substring(1)}"; ITypeSymbol propertyTypeSymbol = model.GetDeclaredSymbol(propertyDecl).Type; root = root.ReplaceNodes(new SyntaxNode[] { propertyDecl, typeDecl }, (original, updated) => original.IsKind(SyntaxKind.PropertyDeclaration) ? ExpandProperty((PropertyDeclarationSyntax)original, (PropertyDeclarationSyntax)updated, backingFieldName) as SyntaxNode : ExpandType((TypeDeclarationSyntax)original, (TypeDeclarationSyntax)updated, propertyTypeSymbol, backingFieldName, model, workspace) as SyntaxNode ); return root; }
public CompilationUnitSyntax TransformRoot(CompilationUnitSyntax root) { root = root.ReplaceNodes(_nodeToAnnotations.Keys, (originalNode, rewrittenNode) => { var ret = rewrittenNode.WithAdditionalAnnotations(_nodeToAnnotations[originalNode]); return ret; }); foreach (var kvp in _annotationToTransformation) { Dictionary<SyntaxNode, SyntaxNode> originalNodeMap = new Dictionary<SyntaxNode, SyntaxNode>(); foreach (var originalNodeKvp in _originalNodeLookup) { var annotatedNodes = root.GetAnnotatedNodes(originalNodeKvp.Key).ToList(); SyntaxNode annotatedNode = annotatedNodes.SingleOrDefault(); if (annotatedNode != null) { originalNodeMap[annotatedNode] = originalNodeKvp.Value; } } var syntaxAnnotation = kvp.Key; var transformation = kvp.Value; var nodesToTransform = root.GetAnnotatedNodes(syntaxAnnotation); root = transformation(root, nodesToTransform, originalNodeMap); } return root; }
static CompilationUnitSyntax DumpEvents(CompilationUnitSyntax root) { Dictionary<SyntaxNode, SyntaxNode> changes = new Dictionary<SyntaxNode, SyntaxNode>(); var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>(); foreach (var @class in classes) { var events = @class.Members.OfType<EventDeclarationSyntax>(); foreach (var @event in events) { AccessorDeclarationSyntax add, remove; BlockSyntax newBody = SyntaxFactory.Block(SyntaxFactory.ParseStatement("throw new NotImplementedException();")); AccessorDeclarationSyntax adder = SyntaxFactory.AccessorDeclaration(SyntaxKind.AddAccessorDeclaration,newBody); AccessorDeclarationSyntax remover = SyntaxFactory.AccessorDeclaration(SyntaxKind.RemoveAccessorDeclaration, newBody); SyntaxList<AccessorDeclarationSyntax> syntaxes = new SyntaxList<AccessorDeclarationSyntax>(); syntaxes = syntaxes.Add(adder); syntaxes = syntaxes.Add(remover); AccessorListSyntax accessors = SyntaxFactory.AccessorList(syntaxes); EventDeclarationSyntax modifiedEvent = @event.WithAccessorList(accessors); changes.Add(@event, modifiedEvent); } } root = root.ReplaceNodes(changes.Keys, (n1, n2) => changes[n1]); return root; }
static CompilationUnitSyntax DumpProperties(CompilationUnitSyntax root) { Dictionary<SyntaxNode, SyntaxNode> changes = new Dictionary<SyntaxNode, SyntaxNode>(); var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>(); foreach (var @class in classes) { var properties = @class.Members.OfType<PropertyDeclarationSyntax>(); foreach (var property in properties) { AccessorDeclarationSyntax getter, setter; TryGetAccessors(property, out getter, out setter); BlockSyntax newBody = SyntaxFactory.Block(SyntaxFactory.ParseStatement("throw new NotImplementedException();")); BlockSyntax getterBody = null; BlockSyntax setterBody = null; PropertyDeclarationSyntax modifiedProperty = null; if (getter != null) { getterBody = getter.Body; if (getterBody == null) continue; changes.Add(getterBody, newBody); } if (setter != null) { setterBody = setter.Body; if (setterBody == null) continue; changes.Add(setterBody, newBody); } } } root = root.ReplaceNodes(changes.Keys, (n1, n2) => changes[n1]); return root; }
static CompilationUnitSyntax DumpConstructors(CompilationUnitSyntax root) { Dictionary<SyntaxNode, SyntaxNode> changes = new Dictionary<SyntaxNode, SyntaxNode>(); var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>(); foreach (var @class in classes) { var constructors = @class.Members.OfType<ConstructorDeclarationSyntax>(); var destructors = @class.Members.OfType<DestructorDeclarationSyntax>(); foreach (var c in constructors) { BlockSyntax newBody = SyntaxFactory.Block(SyntaxFactory.ParseStatement("throw new NotImplementedException();")); BlockSyntax body = c.Body; if (body == null) continue; var modifiedMethod = c.ReplaceNode(body, newBody); changes.Add(c, modifiedMethod); } foreach (var c in destructors) { BlockSyntax newBody = SyntaxFactory.Block(SyntaxFactory.ParseStatement("throw new NotImplementedException();")); BlockSyntax body = c.Body; if (body == null) continue; var modifiedMethod = c.ReplaceNode(body, newBody); changes.Add(c, modifiedMethod); } } root = root.ReplaceNodes(changes.Keys, (n1, n2) => changes[n1]); return root; }