|
| 1 | +using Rubberduck.Parsing.Grammar; |
| 2 | +using Rubberduck.Parsing.Symbols; |
| 3 | +using System; |
| 4 | +using System.Collections.Generic; |
| 5 | +using System.Linq; |
| 6 | + |
| 7 | +namespace Rubberduck.Refactorings.EncapsulateField |
| 8 | +{ |
| 9 | + public interface IEncapsulateFieldCodeBuilder |
| 10 | + { |
| 11 | + (string Get, string Let, string Set) BuildPropertyBlocks(PropertyAttributeSet propertyAttributeSet); |
| 12 | + string BuildUserDefinedTypeDeclaration(IObjectStateUDT objectStateUDT, IEnumerable<IEncapsulateFieldCandidate> candidates); |
| 13 | + string BuildObjectStateFieldDeclaration(IObjectStateUDT objectStateUDT); |
| 14 | + } |
| 15 | + |
| 16 | + public class EncapsulateFieldCodeBuilder : IEncapsulateFieldCodeBuilder |
| 17 | + { |
| 18 | + private const string FourSpaces = " "; |
| 19 | + private static string _doubleSpace = $"{Environment.NewLine}{Environment.NewLine}"; |
| 20 | + |
| 21 | + private readonly ICodeBuilder _codeBuilder; |
| 22 | + |
| 23 | + public EncapsulateFieldCodeBuilder(ICodeBuilder codeBuilder) |
| 24 | + { |
| 25 | + _codeBuilder = codeBuilder; |
| 26 | + } |
| 27 | + |
| 28 | + public (string Get, string Let, string Set) BuildPropertyBlocks(PropertyAttributeSet propertyAttributes) |
| 29 | + { |
| 30 | + string propertyLet = null; |
| 31 | + string propertySet = null; |
| 32 | + |
| 33 | + if (propertyAttributes.GenerateLetter) |
| 34 | + { |
| 35 | + var letterContent = $"{FourSpaces}{propertyAttributes.BackingField} = {propertyAttributes.ParameterName}"; |
| 36 | + if (!_codeBuilder.TryBuildPropertyLetCodeBlock(propertyAttributes.Declaration, propertyAttributes.PropertyName, out propertyLet, content: letterContent)) |
| 37 | + { |
| 38 | + throw new ArgumentException(); |
| 39 | + } |
| 40 | + } |
| 41 | + |
| 42 | + if (propertyAttributes.GenerateSetter) |
| 43 | + { |
| 44 | + var setterContent = $"{FourSpaces}{Tokens.Set} {propertyAttributes.BackingField} = {propertyAttributes.ParameterName}"; |
| 45 | + if (!_codeBuilder.TryBuildPropertySetCodeBlock(propertyAttributes.Declaration, propertyAttributes.PropertyName, out propertySet, content: setterContent)) |
| 46 | + { |
| 47 | + throw new ArgumentException(); |
| 48 | + } |
| 49 | + } |
| 50 | + |
| 51 | + var getterContent = $"{propertyAttributes.PropertyName} = {propertyAttributes.BackingField}"; |
| 52 | + if (propertyAttributes.UsesSetAssignment) |
| 53 | + { |
| 54 | + getterContent = $"{Tokens.Set} {getterContent}"; |
| 55 | + } |
| 56 | + |
| 57 | + if (propertyAttributes.AsTypeName.Equals(Tokens.Variant) && !propertyAttributes.Declaration.IsArray) |
| 58 | + { |
| 59 | + getterContent = string.Join(Environment.NewLine, |
| 60 | + $"{Tokens.If} IsObject({propertyAttributes.BackingField}) {Tokens.Then}", |
| 61 | + $"{FourSpaces}{Tokens.Set} {propertyAttributes.PropertyName} = {propertyAttributes.BackingField}", |
| 62 | + Tokens.Else, |
| 63 | + $"{FourSpaces}{propertyAttributes.PropertyName} = {propertyAttributes.BackingField}", |
| 64 | + $"{Tokens.End} {Tokens.If}", |
| 65 | + Environment.NewLine); |
| 66 | + } |
| 67 | + |
| 68 | + if (!_codeBuilder.TryBuildPropertyGetCodeBlock(propertyAttributes.Declaration, propertyAttributes.PropertyName, out var propertyGet, content: $"{FourSpaces}{getterContent}")) |
| 69 | + { |
| 70 | + throw new ArgumentException(); |
| 71 | + } |
| 72 | + |
| 73 | + return (propertyGet, propertyLet, propertySet); |
| 74 | + } |
| 75 | + |
| 76 | + public string BuildUserDefinedTypeDeclaration(IObjectStateUDT objectStateUDT, IEnumerable<IEncapsulateFieldCandidate> candidates) |
| 77 | + { |
| 78 | + var selected = candidates.Where(c => c.EncapsulateFlag); |
| 79 | + |
| 80 | + var newUDTMembers = selected |
| 81 | + .Select(m => (m.Declaration as VariableDeclaration, m.BackingIdentifier)); |
| 82 | + |
| 83 | + return _codeBuilder.BuildUserDefinedTypeDeclaration(objectStateUDT.AsTypeName, newUDTMembers); |
| 84 | + } |
| 85 | + |
| 86 | + public string BuildObjectStateFieldDeclaration(IObjectStateUDT objectStateUDT) |
| 87 | + { |
| 88 | + return $"{Accessibility.Private} {objectStateUDT.IdentifierName} {Tokens.As} {objectStateUDT.AsTypeName}"; |
| 89 | + } |
| 90 | + } |
| 91 | +} |
0 commit comments