Пример #1
0
        private void CheckIfStringLengthIsSufficientForAutoNumbering(SymbolAnalysisContext context, AttributeInformation attributeInformation,
                                                                     DacPropertyInfo dacProperty)
        {
            var dbBoundStringAttribute = attributeInformation.Context.FieldAttributes.PXDBStringAttribute;
            var unboundStringAttribute = attributeInformation.Context.FieldAttributes.PXStringAttribute;
            var stringAttributes       = dacProperty.Attributes
                                         .Where(a => IsStringAttribute(a, attributeInformation, dbBoundStringAttribute, unboundStringAttribute))
                                         .ToList();

            if (stringAttributes.Count != 1)
            {
                return;
            }

            AttributeInfo stringAttribute  = stringAttributes[0];
            int?          stringLength     = GetStringLengthFromStringAttribute(stringAttribute);
            int           minAllowedLength = attributeInformation.Context.AttributeTypes.AutoNumberAttribute.MinAutoNumberLength;

            if (stringLength.HasValue && stringLength < minAllowedLength)
            {
                var attributeLocation = GetLocationToReportInsufficientStringLength(context, stringAttribute, stringLength.Value);
                var diagnostic        = Diagnostic.Create(Descriptors.PX1020_InsufficientStringLengthForDacPropertyWithAutoNumbering, attributeLocation, minAllowedLength);
                context.ReportDiagnosticWithSuppressionCheck(diagnostic, attributeInformation.Context.CodeAnalysisSettings);
            }
        }
        private static void CheckDacProperty(DacPropertyInfo property, SymbolAnalysisContext symbolContext, PXContext pxContext,
                                             FieldTypeAttributesRegister fieldAttributesRegister)
        {
            symbolContext.CancellationToken.ThrowIfCancellationRequested();
            ImmutableArray <AttributeInfo> attributes = property.Attributes;

            if (attributes.IsDefaultOrEmpty)
            {
                return;
            }

            var attributesWithInfos = GetFieldTypeAttributesInfos(attributes, fieldAttributesRegister, symbolContext.CancellationToken);

            if (attributesWithInfos.Count == 0)
            {
                return;
            }

            bool validSpecialTypes = CheckForMultipleSpecialAttributes(symbolContext, pxContext, attributesWithInfos);

            symbolContext.CancellationToken.ThrowIfCancellationRequested();

            if (!validSpecialTypes)
            {
                return;
            }

            CheckForPXDBCalcedAndUnboundTypeAttributes(symbolContext, pxContext, property.Symbol, attributesWithInfos);
            CheckForFieldTypeAttributes(property, symbolContext, pxContext, attributesWithInfos);
        }
        private static void AnalyzeProperty(DacPropertyInfo property, SymbolAnalysisContext context, PXContext pxContext,
                                            IEnumerable <INamedTypeSymbol> typeAttributesSet)
        {
            var attributeTypes = property.Symbol.GetAttributes()
                                 .Select(a => a.AttributeClass)
                                 .ToList(capacity: 4);

            bool hasListAttribute = attributeTypes.Any(type => type.ImplementsInterface(pxContext.IPXLocalizableList));

            if (!hasListAttribute)
            {
                return;
            }

            //TODO we need to use FieldTypeAttributesRegister to perform complete analysis with consideration for aggregate attributes
            bool hasTypeAttribute = attributeTypes.Any(propertyAttributeType =>
                                                       typeAttributesSet.Any(typeAttribute => propertyAttributeType.InheritsFromOrEquals(typeAttribute)));

            if (!hasTypeAttribute)
            {
                context.ReportDiagnosticWithSuppressionCheck(
                    Diagnostic.Create(Descriptors.PX1002_MissingTypeListAttributeAnalyzer, property.Symbol.Locations.FirstOrDefault()),
                    pxContext.CodeAnalysisSettings);
            }
        }
        private static void AnalyzeUnboundProperty(SymbolAnalysisContext symbolContext, PXContext pxContext, DacSemanticModel dacOrExtension,
                                                   DacPropertyInfo property)
        {
            var(pxDefaultAttribute, hasPersistingCheckNothing) = GetPXDefaultInfo(pxContext, property);

            if (pxDefaultAttribute == null || hasPersistingCheckNothing)
            {
                return;
            }

            var attributeLocation = GetAttributeLocation(pxDefaultAttribute, symbolContext.CancellationToken);

            if (attributeLocation == null)
            {
                return;
            }

            var diagnosticProperties = ImmutableDictionary <string, string> .Empty
                                       .Add(DiagnosticProperty.IsBoundField, bool.FalseString);

            var descriptor = dacOrExtension.DacType == DacType.Dac
                                ? Descriptors.PX1030_DefaultAttibuteToExistingRecordsOnDAC
                                : Descriptors.PX1030_DefaultAttibuteToExistingRecordsError;
            var diagnostic = Diagnostic.Create(descriptor, attributeLocation, diagnosticProperties);

            symbolContext.ReportDiagnosticWithSuppressionCheck(diagnostic, pxContext.CodeAnalysisSettings);
        }
        private void AnalyzeMethodInvocationInDacProperty(DacPropertyInfo property, HashSet <INamedTypeSymbol> whiteList,
                                                          SymbolAnalysisContext context, PXContext pxContext, SemanticModel semanticModel)
        {
            foreach (SyntaxNode node in property.Node.DescendantNodes())
            {
                context.CancellationToken.ThrowIfCancellationRequested();

                if (node is InvocationExpressionSyntax invocation)
                {
                    ISymbol symbol = semanticModel.GetSymbolInfo(invocation, context.CancellationToken).Symbol;

                    if (symbol == null || !(symbol is IMethodSymbol method) || method.IsStatic || method.IsExtensionMethod)
                    {
                        continue;
                    }

                    bool inWhitelist = whiteList.Contains(method.ContainingType) ||
                                       whiteList.Contains(method.ContainingType.ConstructedFrom);
                    if (inWhitelist)
                    {
                        continue;
                    }

                    context.ReportDiagnosticWithSuppressionCheck(
                        Diagnostic.Create(Descriptors.PX1032_DacPropertyCannotContainMethodInvocations, invocation.GetLocation()),
                        pxContext.CodeAnalysisSettings);
                }
                else if (node is ObjectCreationExpressionSyntax)
                {
                    context.ReportDiagnosticWithSuppressionCheck(
                        Diagnostic.Create(Descriptors.PX1032_DacPropertyCannotContainMethodInvocations, node.GetLocation()),
                        pxContext.CodeAnalysisSettings);
                }
            }
        }
        private static void AnalyzeProperty(SymbolAnalysisContext symbolContext, PXContext pxContext, DacSemanticModel dacOrExtension,
                                            DacPropertyInfo property)
        {
            switch (property.EffectiveBoundType)
            {
            case BoundType.Unbound:
                AnalyzeUnboundProperty(symbolContext, pxContext, dacOrExtension, property);
                return;

            case BoundType.DbBound
                when dacOrExtension.DacType == DacType.DacExtension: // Analyze bound property only for extensions
                AnalyzeBoundPropertyAttributes(symbolContext, pxContext, property);
                return;
            }
        }
Пример #7
0
        private void ReportDacPropertyTypeIsNotString(SymbolAnalysisContext context, PXContext pxContext, DacPropertyInfo dacProperty)
        {
            var autoNumberingAttribute = dacProperty.Attributes.FirstOrDefault(a => a.IsAutoNumberAttribute);
            var propertyTypeLocation   = dacProperty.Node.Type.GetLocation();

            if (propertyTypeLocation != null)
            {
                var diagnostic = Diagnostic.Create(Descriptors.PX1019_AutoNumberOnDacPropertyWithNonStringType, propertyTypeLocation);

                context.ReportDiagnosticWithSuppressionCheck(diagnostic, pxContext.CodeAnalysisSettings);
            }

            var attributeLocation = autoNumberingAttribute?.AttributeData.GetLocation(context.CancellationToken);

            if (attributeLocation != null)
            {
                var diagnostic = Diagnostic.Create(Descriptors.PX1019_AutoNumberOnDacPropertyWithNonStringType, attributeLocation);

                context.ReportDiagnosticWithSuppressionCheck(diagnostic, pxContext.CodeAnalysisSettings);
            }
        }
Пример #8
0
        private void CheckDacProperty(SymbolAnalysisContext context, AttributeInformation attributeInformation, DacPropertyInfo dacProperty)
        {
            if (dacProperty.PropertyType.SpecialType != SpecialType.System_String)
            {
                ReportDacPropertyTypeIsNotString(context, attributeInformation.Context, dacProperty);
                return;
            }

            context.CancellationToken.ThrowIfCancellationRequested();
            CheckIfStringLengthIsSufficientForAutoNumbering(context, attributeInformation, dacProperty);
        }
        private IEnumerable <SyntaxTrivia> GetForeignKeyExampleTemplates(INamedTypeSymbol dacTypeSymbol, List <DacPropertyInfo> dacPropertiesWithForeignKeys)
        {
            var emptyLineComment = string.Empty.ToSingleLineComment();

            yield return(Resources.PX1034FixTemplateLine1.ToSingleLineComment());

            yield return(EndOfLine(Environment.NewLine));

            string fkExampleWithUseOfReferencedDacPrimaryKey = string.Format(Resources.PX1034FixTemplateLine2, dacTypeSymbol.Name);

            yield return(fkExampleWithUseOfReferencedDacPrimaryKey.ToSingleLineComment());

            yield return(EndOfLine(Environment.NewLine));

            yield return(emptyLineComment);

            yield return(EndOfLine(Environment.NewLine));

            yield return(Resources.PX1034FixTemplateLine3.ToSingleLineComment());

            yield return(EndOfLine(Environment.NewLine));

            string fkExampleWithoutPK_WithSimplePrimaryKey = string.Format(Resources.PX1034FixTemplateLine4, dacTypeSymbol.Name);

            yield return(fkExampleWithoutPK_WithSimplePrimaryKey.ToSingleLineComment());

            yield return(EndOfLine(Environment.NewLine));

            yield return(emptyLineComment);

            yield return(EndOfLine(Environment.NewLine));

            yield return(Resources.PX1034FixTemplateLine5.ToSingleLineComment());

            yield return(EndOfLine(Environment.NewLine));

            string fkExampleWithoutPK_WithCompositePrimaryKey        = string.Format(Resources.PX1034FixTemplateLine6, dacTypeSymbol.Name);
            string fkExampleWithoutPK_WithCompositePrimaryKeyComment = $"/* {fkExampleWithoutPK_WithCompositePrimaryKey} */";

            yield return(Comment(fkExampleWithoutPK_WithCompositePrimaryKeyComment));

            yield return(EndOfLine(Environment.NewLine));

            if (dacPropertiesWithForeignKeys.Count == 0)
            {
                yield break;
            }

            yield return(emptyLineComment);

            yield return(EndOfLine(Environment.NewLine));

            yield return(Resources.PX1034FixTemplateLine7.ToSingleLineComment());

            yield return(EndOfLine(Environment.NewLine));

            for (int i = 0; i < dacPropertiesWithForeignKeys.Count; i++)
            {
                DacPropertyInfo propertyWithForeignKey = dacPropertiesWithForeignKeys[i];
                string          propertyName           = propertyWithForeignKey.Symbol.Name;

                if (i < dacPropertiesWithForeignKeys.Count - 1)
                {
                    propertyName += ",";
                }

                yield return(propertyName.ToSingleLineComment());

                yield return(EndOfLine(Environment.NewLine));
            }
        }
Пример #10
0
        public PropertyNodeViewModel(DacMemberCategoryNodeViewModel dacMemberCategoryVM, DacPropertyInfo propertyInfo, bool isExpanded = false) :
            base(dacMemberCategoryVM, dacMemberCategoryVM, propertyInfo, isExpanded)
        {
            var extraInfos = GetExtraInfos();

            ExtraInfos = new ExtendedObservableCollection <ExtraInfoViewModel>(extraInfos);
        }
Пример #11
0
 public PropertyNodeViewModel(DacMemberCategoryNodeViewModel dacMemberCategoryVM, DacPropertyInfo propertyInfo, bool isExpanded = false) :
     base(dacMemberCategoryVM, propertyInfo, isExpanded)
 {
 }
        private static void AnalyzeBoundPropertyAttributes(SymbolAnalysisContext symbolContext, PXContext pxContext, DacPropertyInfo property)
        {
            var pxDefaultAttribute = GetInvalidPXDefaultAttributeFromBoundProperty(pxContext, property);

            if (pxDefaultAttribute == null)
            {
                return;
            }

            var attributeLocation = GetAttributeLocation(pxDefaultAttribute, symbolContext.CancellationToken);

            if (attributeLocation == null)
            {
                return;
            }

            var diagnosticProperties = ImmutableDictionary <string, string> .Empty
                                       .Add(DiagnosticProperty.IsBoundField, bool.TrueString);

            var diagnostic = Diagnostic.Create(Descriptors.PX1030_DefaultAttibuteToExistingRecordsWarning, attributeLocation, diagnosticProperties);

            symbolContext.ReportDiagnosticWithSuppressionCheck(diagnostic, pxContext.CodeAnalysisSettings);
        }
        private static (AttributeData PXDefaultAttribute, bool HasPersistingCheckNothing) GetPXDefaultInfo(PXContext pxContext, DacPropertyInfo property)
        {
            var defaultAttributes = property.Attributes.Where(a => a.IsDefaultAttribute).ToList();

            if (defaultAttributes.Count != 1)                   //We don't check in case of multiple pxdefault
            {
                return(null, false);
            }

            var pxDefaultAttribute        = defaultAttributes[0].AttributeData;
            var hasPersistingCheckNothing = (from arg in pxDefaultAttribute.NamedArguments
                                             where TypeNames.PersistingCheck.Equals(arg.Key, StringComparison.Ordinal)
                                             select arg.Value.Value)
                                            .Any(value => value is int persistingCheck &&
                                                 persistingCheck == (int)PXPersistingCheckValues.Nothing);

            return(pxDefaultAttribute, hasPersistingCheckNothing);
        }
        private static AttributeData GetInvalidPXDefaultAttributeFromBoundProperty(PXContext pxContext, DacPropertyInfo property)
        {
            var(pxDefaultAttribute, hasPersistingCheckNothing) = GetPXDefaultInfo(pxContext, property);

            if (pxDefaultAttribute == null || hasPersistingCheckNothing)
            {
                return(null);
            }

            // If Dac extension contains PXDefaultAttribute without PersistingCheck.Nothing
            // we need to look to attribute wich it overrides:
            // if base attribute is also doesn't contain PersistingCheck.Nothing it is legitimately
            foreach (DacPropertyInfo overridenProperty in property.JustOverridenItems())
            {
                var(pxDefaultAttributeBase, hasPersistingCheckNothingBase) = GetPXDefaultInfo(pxContext, overridenProperty);

                if (pxDefaultAttributeBase == null)
                {
                    continue;
                }

                return(hasPersistingCheckNothingBase    //The values from the latest appropriate override should be used
                                        ? pxDefaultAttribute
                                        : null);
            }

            return(pxDefaultAttribute);
        }