Пример #1
0
 Either <CompleterError, bool> IsBindable(IPropertySymbol property, BindableInfo bindableInfo)
 {
     if (bindableInfo?.IsBindable ?? false)
     {
         if (property.IsSealed)
         {
             return(CompleterError.CreatePropertyError(property, Messages.POCO_PropertyIsSealed));
         }
         if (!property.IsVirtual)
         {
             return(CompleterError.CreatePropertyError(property, Messages.POCO_PropertyIsNotVirual));
         }
         if (property.IsReadOnly)
         {
             return(CompleterError.CreatePropertyError(property, Messages.POCO_PropertyHasNoSetter));
         }
         if (property.GetMethod.DeclaredAccessibility != Microsoft.CodeAnalysis.Accessibility.Public)
         {
             return(CompleterError.CreatePropertyError(property, Messages.POCO_PropertyHasNoPublicGetter));
         }
     }
     return(property.IsVirtual &&
            (bindableInfo?.IsBindable ?? true) &&
            property.DeclaredAccessibility == Microsoft.CodeAnalysis.Accessibility.Public &&
            property.GetMethod.DeclaredAccessibility == Microsoft.CodeAnalysis.Accessibility.Public &&
            property.IsAutoImplemented() || bindableInfo.Return(bi => bi.IsBindable, () => false));
 }
Пример #2
0
        CompleterResult GetImplementations()
        {
            Func <Func <string, string>, string, Func <CompleterError>, Either <CompleterError, string> > getImplementation = (getImpl, interfaceName, check) => {
                var interfaceType = model.Compilation.GetTypeByMetadataName(interfaceName);
                if (type.AllInterfaces.Contains(interfaceType))
                {
                    var error = check.With(x => x());
                    if (error != null)
                    {
                        return(error);
                    }
                    return(string.Empty);
                }
                return(getImpl(type.Name).AddTabs(1));
            };
            const string IDataErrorInfoName = "System.ComponentModel.IDataErrorInfo";
            Func <string, string, string> getIDataErrorInfoPropertyImplementation = (implementation, name) =>
                                                                                    type.Properties().Any(m => (m.Name == IDataErrorInfoName + "." + name) || (m.DeclaredAccessibility == Microsoft.CodeAnalysis.Accessibility.Public && m.Name == name))
                     ? null
                     : implementation;
            var iDataErrorInfoType          = model.Compilation.GetTypeByMetadataName(IDataErrorInfoName);
            var dataErrorInfoImplementation = type.AllInterfaces.Contains(iDataErrorInfoType)
                ? (
                getIDataErrorInfoPropertyImplementation(DataErrorInfoErrorImplementation, "Error")
                +
                getIDataErrorInfoPropertyImplementation(DataErrorInfoIndexerImplementation, "this[]")
                ) : null;
            Func <CompleterError> checkRaisePropertyChangedMethod = () => {
                Func <CompleterError> error     = () => CompleterError.CreateForTypeName(type, Messages.POCO_RaisePropertyChangedMethodNotFound.Format(type.Name));
                var raisePropertyChangedMethods = methods.GetValueOrDefault("RaisePropertyChanged", ImmutableArray <IMethodSymbol> .Empty);
                if (raisePropertyChangedMethods.IsEmpty)
                {
                    return(error());
                }
                var raisePropertyChangedMethod = raisePropertyChangedMethods.FirstOrDefault(method => {
                    if (method.Parameters.Length != 1)
                    {
                        return(false);
                    }
                    var parameter = method.Parameters.Single();
                    return(parameter.RefKind == RefKind.None && parameter.Type.SpecialType == SpecialType.System_String);
                });
                if (raisePropertyChangedMethod == null)
                {
                    return(error());
                }
                return(null);
            };

            return(new[] {
                getImplementation(INPCImplemetation, "System.ComponentModel.INotifyPropertyChanged", checkRaisePropertyChangedMethod),
                getImplementation(ParentViewModelImplementation, "DevExpress.Mvvm.ISupportParentViewModel", null),
                getImplementation(SupportServicesImplementation, "DevExpress.Mvvm.ISupportServices", null),
                dataErrorInfoImplementation,
            }
                   .AggregateEither(errors => errors.ToImmutableArray(), values => values.ConcatStringsWithNewLines()));
        }
Пример #3
0
        IEnumerable <CompleterError> GetClassErrors()
        {
            if (type.IsSealed)
            {
                yield return(CompleterError.CreateForTypeName(type, Messages.POCO_SealedClass.Format(type.Name)));
            }
            var iPOCOViewModeType = model.Compilation.GetTypeByMetadataName("DevExpress.Mvvm.POCO.IPOCOViewModel");

            if (type.AllInterfaces.Contains(iPOCOViewModeType))
            {
                yield return(CompleterError.CreateForTypeName(type, Messages.POCO_TypeImplementsIPOCOViewModel.Format(type.Name)));
            }
        }
Пример #4
0
        Either <CompleterError, string> GenerateCommand(IMethodSymbol method, CommandInfo commandInfo)
        {
            var isAsync     = method.ReturnType == taskType;
            var commandName = commandInfo?.Name ?? (method.Name + "Command");

            if (type.GetMembers(commandName).Any())
            {
                return(CompleterError.CreateMethodError(method, Messages.POCO_MemberWithSameCommandNameAlreadyExists));
            }

            var methodName       = method.Name;
            var genericParameter = method.Parameters.SingleOrDefault()
                                   .With(x => "<" + x.Type.DisplayString(model, x.Location()) + ">");

            if (!method.ReturnsVoid && method.ReturnType != taskType)
            {
                if (genericParameter == null)
                {
                    methodName = $"() => {methodName}()";
                }
                else
                {
                    methodName = $"x => {methodName}(x)";
                }
            }
            var commandTypeName = (isAsync ? "AsyncCommand" : "DelegateCommand") + genericParameter;
            var propertyType    = isAsync
                ? "AsyncCommand" + genericParameter
                : (genericParameter.With(x => $"DelegateCommand{x}") ?? "ICommand");
            var canExecuteMethodName = (commandInfo?.CanExecuteMethodName ?? (GetMethods("Can" + methodName).SingleOrDefault()?.Name ?? "null"));
            var canExecuteMethod     = canExecuteMethodName.With(x => GetMethods(x).SingleOrDefault());

            if (commandInfo?.CanExecuteMethodName != null && canExecuteMethod == null)
            {
                return(CompleterError.CreateMethodError(method, Messages.POCO_MethodNotFound, commandInfo.CanExecuteMethodName));
            }
            if (canExecuteMethod != null)
            {
                if (!Enumerable.SequenceEqual(canExecuteMethod.Parameters.Select(x => x.Type), method.Parameters.Select(x => x.Type)) ||
                    !canExecuteMethod.Parameters.All(x => x.RefKind == RefKind.None))
                {
                    return(CompleterError.CreateMethodError(canExecuteMethod, Messages.POCO_CanExecuteMethodHasIncorrectParameters));
                }
            }
            var allowMultipleExecution = (commandInfo?.AllowMultipleExecution ?? false) ? ", allowMultipleExecution: true" : null;
            var useCommandManager      = !(commandInfo?.UseCommandManager ?? true) ? ", useCommandManager: false" : null;

            return
                ($@"{commandTypeName} _{commandName};
public {propertyType} {commandName} {{ get {{ return _{commandName} ?? (_{commandName} = new {commandTypeName}({methodName}{canExecuteMethodName.With(x => ", " + x)}{allowMultipleExecution}{useCommandManager})); }} }}");
        }
Пример #5
0
 Either <CompleterError, bool> IsCommandMethod(IMethodSymbol method, CommandInfo commandInfo)
 {
     if (commandInfo?.IsCommand ?? false)
     {
         if (method.Parameters.Length > 1)
         {
             return(CompleterError.CreateMethodError(method, Messages.POCO_MethodCannotHaveMoreThanOneParameter));
         }
         if (method.Parameters.Length == 1 && method.Parameters.Single().RefKind != RefKind.None)
         {
             return(CompleterError.CreateMethodError(method, Messages.POCO_MethodCannotHaveOutORRefParameters));
         }
     }
     return((commandInfo?.IsCommand ?? (method.DeclaredAccessibility == Microsoft.CodeAnalysis.Accessibility.Public)) &&
            method.MethodKind == MethodKind.Ordinary &&
            !method.IsStatic &&
            (method.ReturnsVoid || method.ReturnType == taskType || (commandInfo?.IsCommand ?? false)) &&
            (!method.Parameters.Any() || (method.Parameters.Length == 1 && method.Parameters.Single().RefKind == RefKind.None)));
 }
Пример #6
0
        Either <CompleterError, string> GenerateProperty(IPropertySymbol property, BindableInfo bindableInfo)
        {
            Func <Chang, string, Either <CompleterError, MethodCallInfo> > getCallInfo = (chang, attributeMethodName) => {
                var methodName = attributeMethodName ?? $"On{property.Name}Chang{chang}".If(x => property.IsAutoImplemented());
                if (methodName != null && GetMethods(methodName).Length > 1)
                {
                    return(CompleterError.CreatePropertyError(property, Messages.POCO_MoreThanOnePropertyChangedMethod(chang)));
                }
                var method = methodName.With(x => GetMethods(x).SingleOrDefault());
                if (method == null && attributeMethodName != null)
                {
                    return(CompleterError.CreateForPropertyName(property, Messages.POCO_PropertyChangedMethodNotFound(chang).Format(attributeMethodName)));
                }
                if (method != null)
                {
                    if (method.Parameters.Length > 1)
                    {
                        return(CompleterError.CreateMethodError(method, Messages.POCO_PropertyChangedCantHaveMoreThanOneParameter(chang)));
                    }
                    if (!method.ReturnsVoid)
                    {
                        return(CompleterError.CreateMethodError(method, Messages.POCO_PropertyChangedCantHaveReturnType(chang)));
                    }
                    if (method.Parameters.Length == 1 && method.Parameters.Single().Type != property.Type)
                    {
                        return(CompleterError.CreateParameterError(method.Parameters.Single(), Messages.POCO_PropertyChangedMethodArgumentTypeShouldMatchPropertyType(chang)));
                    }
                }
                var needParameter = method.Return(x => x.Parameters.Length == 1, () => false);
                var valueName     = needParameter ? (chang == Chang.ed ? "oldValue" : "value") : null;
                var methodCall    = method.With(x => $"{x.Name}({valueName});".AddTabs(2));
                return(new MethodCallInfo(methodCall, needParameter));
            };

            return(from changed in getCallInfo(Chang.ed, bindableInfo?.OnPropertyChangedMethodName)
                   from changing in getCallInfo(Chang.ing, bindableInfo?.OnPropertyChangingMethodName)
                   select GenerateProperty(property, changed, changing));
        }