Пример #1
0
        protected override void AnalyzeSymbol(SymbolAnalysisContext context, PXContext pxContext)
        {
            context.CancellationToken.ThrowIfCancellationRequested();

            if (!(context.Symbol is INamedTypeSymbol type))
            {
                return;
            }

            var inferredDacModel = DacSemanticModel.InferModel(pxContext, type, context.CancellationToken);

            if (inferredDacModel == null)
            {
                return;
            }

            ParallelOptions parallelOptions = new ParallelOptions
            {
                CancellationToken = context.CancellationToken
            };

            Parallel.ForEach(_innerAnalyzers, parallelOptions, innerAnalyzer =>
            {
                context.CancellationToken.ThrowIfCancellationRequested();

                if (innerAnalyzer.ShouldAnalyze(pxContext, inferredDacModel))
                {
                    innerAnalyzer.Analyze(context, pxContext, inferredDacModel);
                }
            });
        }
 protected virtual bool TryToInferDacOrDacExtensionSemanticModel(INamedTypeSymbol dacSymbol, PXContext context,
                                                                 out ISemanticModel dacSemanticModel,
                                                                 CancellationToken cancellationToken = default)
 {
     dacSemanticModel = DacSemanticModel.InferModel(context, dacSymbol, cancellationToken);
     return(dacSemanticModel != null);
 }
Пример #3
0
        private Task <Document> AddPrimaryKeyDeclarationToDacAsync(Document document, SyntaxNode root, ClassDeclarationSyntax dacNode, PXContext pxContext,
                                                                   INamedTypeSymbol dacTypeSymbol, CancellationToken cancellation)
        {
            cancellation.ThrowIfCancellationRequested();

            var dacSemanticModel           = DacSemanticModel.InferModel(pxContext, dacTypeSymbol, cancellation);
            List <DacPropertyInfo> dacKeys = dacSemanticModel?.DacProperties
                                             .Where(property => property.IsKey)
                                             .OrderBy(property => property.DeclarationOrder)
                                             .ToList(capacity: 4);

            if (dacKeys.IsNullOrEmpty() || dacKeys.Count > PXReferentialIntegritySymbols.MaxPrimaryKeySize)
            {
                return(Task.FromResult(document));
            }

            var primaryKeyNode = CreatePrimaryKeyNode(document, pxContext, dacSemanticModel, dacKeys);
            var newDacNode     = dacNode.WithMembers(
                dacNode.Members.Insert(0, primaryKeyNode));

            var changedRoot = root.ReplaceNode(dacNode, newDacNode);

            changedRoot = AddUsingsForReferentialIntegrityNamespace(changedRoot);
            var modifiedDocument = document.WithSyntaxRoot(changedRoot);

            return(Task.FromResult(modifiedDocument));
        }
        private List <DacPropertyInfo> GetDacPropertiesWithForeignKeys(PXContext pxContext, INamedTypeSymbol dacTypeSymbol, CancellationToken cancellation)
        {
            var foreignKeyAttributes = GetForeignKeyAttributes(pxContext);

            if (foreignKeyAttributes.Count == 0)
            {
                return(new List <DacPropertyInfo>());
            }

            var dacSemanticModel = DacSemanticModel.InferModel(pxContext, dacTypeSymbol, cancellation);

            if (dacSemanticModel == null || dacSemanticModel.DacType != DacType.Dac)
            {
                return(new List <DacPropertyInfo>());
            }

            var selectorAttribute                     = pxContext.AttributeTypes.PXSelectorAttribute.Type;
            var dimensionSelectorAttribute            = pxContext.AttributeTypes.PXDimensionSelectorAttribute;
            AttributeInformation attributeInformation = new AttributeInformation(pxContext);
            var dacPropertiesWithForeignKeys          =
                from dacProperty in dacSemanticModel.DacProperties
                where !dacProperty.Attributes.IsDefaultOrEmpty &&
                dacProperty.BoundType == BoundType.DbBound &&                                                                                           //only Bound FKs should work correctly
                dacProperty.Attributes.Any(attribute => IsForeignKeyAttribute(attribute))
                orderby dacProperty.DeclarationOrder ascending
                select dacProperty;

            return(dacPropertiesWithForeignKeys.ToList());

            //----------------------------------------Local Function----------------------------------------------------------------
            bool IsForeignKeyAttribute(AttributeInfo attribute)
            {
                const string selectorAttributeProperty = "SelectorAttribute";

                bool isDerivedFromOrAggregateForeignKeyAttribute =
                    foreignKeyAttributes.Exists(
                        foreignKeyAttribute => attributeInformation.IsAttributeDerivedFromClass(attribute.AttributeType, foreignKeyAttribute));

                if (isDerivedFromOrAggregateForeignKeyAttribute)
                {
                    return(true);
                }

                var selectorAttributeMembers = attribute.AttributeType.GetBaseTypesAndThis()
                                               .SelectMany(type => type.GetMembers(selectorAttributeProperty));


                var selectorAttributeCandidateMemberTypes = from type in attribute.AttributeType.GetBaseTypesAndThis()
                                                            .TakeWhile(attrType => attrType != pxContext.AttributeTypes.PXEventSubscriberAttribute)
                                                            from member in type.GetMembers(selectorAttributeProperty)
                                                            select member switch
                {
                    IPropertySymbol property => property.Type,
                    IFieldSymbol field => field.Type,
                    _ => null
                };

                return(selectorAttributeCandidateMemberTypes
                       .Any(memberType => memberType != null &&
                            (attributeInformation.IsAttributeDerivedFromClass(memberType, selectorAttribute) ||
                             attributeInformation.IsAttributeDerivedFromClass(memberType, dimensionSelectorAttribute))));
            }
        }