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);
                }
            }
        }
예제 #2
0
        public override void Analyze(SymbolAnalysisContext context, PXContext pxContext, PXGraphSemanticModel graph)
        {
            ITypeSymbol declaredPrimaryDacType = graph.Symbol.GetDeclaredPrimaryDacFromGraphOrGraphExtension(pxContext);

            if (declaredPrimaryDacType == null || context.CancellationToken.IsCancellationRequested)
            {
                return;
            }

            bool hasViewForPrimaryDac = graph.Views.Select(view => view.DAC).Contains(declaredPrimaryDacType);

            if (hasViewForPrimaryDac || context.CancellationToken.IsCancellationRequested)
            {
                return;
            }

            Location location = GetLocation(graph, declaredPrimaryDacType, context);

            if (location == null)
            {
                return;
            }

            context.ReportDiagnosticWithSuppressionCheck(
                Diagnostic.Create(Descriptors.PX1018_NoPrimaryViewForPrimaryDac, location),
                pxContext.CodeAnalysisSettings);
        }
        public override void Analyze(SymbolAnalysisContext context, PXContext pxContext, DacSemanticModel dac)
        {
            context.CancellationToken.ThrowIfCancellationRequested();

            var  dacAttributes           = dac.Symbol.GetAttributes();
            var  pxCacheNameAttribute    = pxContext.AttributeTypes.PXCacheNameAttribute;
            var  pxHiddenAttribute       = pxContext.AttributeTypes.PXHiddenAttribute;
            bool hasPXCacheNameAttribute = false;
            bool hasPXHiddenAttribute    = false;

            foreach (var attribute in dacAttributes.Where(a => a.AttributeClass != null))
            {
                if (attribute.AttributeClass.InheritsFromOrEquals(pxCacheNameAttribute))
                {
                    hasPXCacheNameAttribute = true;
                }

                if (attribute.AttributeClass.InheritsFromOrEquals(pxHiddenAttribute))
                {
                    hasPXHiddenAttribute = true;
                }

                if (hasPXCacheNameAttribute || hasPXHiddenAttribute)
                {
                    return;
                }
            }

            var diagnostic = Diagnostic.Create(Descriptors.PX1094_DacShouldHaveUiAttribute,
                                               dac.Node.Identifier.GetLocation());

            context.ReportDiagnosticWithSuppressionCheck(diagnostic, pxContext.CodeAnalysisSettings);
        }
예제 #4
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 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);
        }
        public override void Analyze(SymbolAnalysisContext context, PXContext pxContext, DacSemanticModel dac)
        {
            foreach (DacFieldInfo dacField in dac.DeclaredFields)
            {
                context.CancellationToken.ThrowIfCancellationRequested();

                if (dacField.Symbol.BaseType.SpecialType != SpecialType.System_Object || AlreadyStronglyTyped(dacField.Symbol, pxContext))
                {
                    continue;
                }

                Location location = dacField.Symbol.Locations.FirstOrDefault();

                if (location != null && dac.PropertiesByNames.TryGetValue(dacField.Name, out DacPropertyInfo property))
                {
                    string propertyTypeName = GetPropertyTypeName(property.Symbol, pxContext);

                    if (propertyTypeName == null || !PropertyTypeToFieldType.ContainsKey(propertyTypeName))
                    {
                        continue;
                    }

                    var args = ImmutableDictionary.CreateBuilder <string, string>();
                    args.Add(CorrespondingPropertyType, propertyTypeName);
                    context.ReportDiagnosticWithSuppressionCheck(
                        Diagnostic.Create(Descriptors.PX1060_LegacyBqlField, location, args.ToImmutable(), dacField.Name),
                        pxContext.CodeAnalysisSettings);
                }
            }
        }
        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);
            }
        }
        protected virtual void ReportKeyDeclarationWithWrongName(SymbolAnalysisContext symbolContext, PXContext context, DacSemanticModel dac,
                                                                 INamedTypeSymbol keyDeclaration, RefIntegrityDacKeyType dacKeyType)
        {
            var                  keyDeclarationNode = keyDeclaration.GetSyntax(symbolContext.CancellationToken);
            Location             location           = (keyDeclarationNode as ClassDeclarationSyntax)?.Identifier.GetLocation() ?? keyDeclarationNode?.GetLocation();
            Location             dacLocation        = dac.Node.GetLocation();
            DiagnosticDescriptor px1036Descriptor   = GetWrongKeyNameDiagnosticDescriptor(dacKeyType);

            if (location == null || dacLocation == null || px1036Descriptor == null)
            {
                return;
            }

            var additionalLocations  = new[] { dacLocation };
            var diagnosticProperties = new Dictionary <string, string>
            {
                { nameof(RefIntegrityDacKeyType), dacKeyType.ToString() }
            };

            if (dacKeyType == RefIntegrityDacKeyType.UniqueKey)
            {
                diagnosticProperties.Add(nameof(UniqueKeyCodeFixType), UniqueKeyCodeFixType.SingleUniqueKey.ToString());
            }

            symbolContext.ReportDiagnosticWithSuppressionCheck(
                Diagnostic.Create(px1036Descriptor, location, additionalLocations, diagnosticProperties.ToImmutableDictionary()),
                context.CodeAnalysisSettings);
        }
 private void AnalyzeMethodDeclarationInDac(MethodDeclarationSyntax method, SymbolAnalysisContext context, PXContext pxContext)
 {
     if (!method.IsStatic())
     {
         context.ReportDiagnosticWithSuppressionCheck(
             Diagnostic.Create(Descriptors.PX1031_DacCannotContainInstanceMethods, method.Identifier.GetLocation()),
             pxContext.CodeAnalysisSettings);
     }
 }
예제 #10
0
 public override void Analyze(SymbolAnalysisContext context, PXContext pxContext, DacSemanticModel dac)
 {
     if (dac.Symbol.BaseType.Name == TypeNames.PXCacheExtension)
     {
         if (!dac.Symbol.IsSealed)
         {
             context.ReportDiagnosticWithSuppressionCheck(
                 Diagnostic.Create(Descriptors.PX1011_InheritanceFromPXCacheExtension, dac.Symbol.Locations.First()),
                 pxContext.CodeAnalysisSettings);
         }
     }
     else
     {
         context.ReportDiagnosticWithSuppressionCheck(
             Diagnostic.Create(Descriptors.PX1009_InheritanceFromPXCacheExtension, dac.Symbol.Locations.First()),
             pxContext.CodeAnalysisSettings);
     }
 }
        private void CheckBigGroupOfKeysForPrimaryKeyAndUniqueKeysContainer(SymbolAnalysisContext symbolContext, PXContext context, DacSemanticModel dac,
                                                                            List <INamedTypeSymbol> keyDeclarations,
                                                                            Dictionary <INamedTypeSymbol, List <ITypeSymbol> > dacFieldsByKey)
        {
            var primaryKey = keyDeclarations.Find(key => key.Name == ReferentialIntegrity.PrimaryKeyClassName);

            if (primaryKey == null)
            {
                //If there is no primary key - try to find suitable unique key and rename it. Otherwise report no primary key in DAC
                ProcessDacWithoutPrimaryKeyAndWithSeveralUniqueKeys(symbolContext, context, dac, keyDeclarations, dacFieldsByKey);
                return;
            }

            INamedTypeSymbol uniqueKeysContainer = dac.Symbol.GetTypeMembers(ReferentialIntegrity.UniqueKeyClassName)
                                                   .FirstOrDefault();

            //We can register code fix only if there is no UK nested type in DAC or there is a public static UK class. Otherwise we will break the code.
            bool registerCodeFix = uniqueKeysContainer == null ||
                                   (uniqueKeysContainer.DeclaredAccessibility == Accessibility.Public && uniqueKeysContainer.IsStatic);

            List <INamedTypeSymbol> keysNotInContainer = GetKeysNotInContainer(keyDeclarations, uniqueKeysContainer, primaryKey);

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

            symbolContext.CancellationToken.ThrowIfCancellationRequested();

            Location dacLocation = dac.Node.GetLocation();
            var      keysNotInContainerLocations = GetKeysLocations(keysNotInContainer, symbolContext.CancellationToken).ToList(capacity: keysNotInContainer.Count);

            if (dacLocation == null || keysNotInContainerLocations.Count == 0)
            {
                return;
            }

            var dacLocationArray     = new[] { dacLocation };
            var diagnosticProperties = new Dictionary <string, string>
            {
                { nameof(RefIntegrityDacKeyType), RefIntegrityDacKeyType.UniqueKey.ToString() },
                { nameof(UniqueKeyCodeFixType), UniqueKeyCodeFixType.MultipleUniqueKeys.ToString() },
                { DiagnosticProperty.RegisterCodeFix, registerCodeFix.ToString() }
            }
            .ToImmutableDictionary();

            foreach (Location keyLocation in keysNotInContainerLocations)
            {
                var otherKeyLocations   = keysNotInContainerLocations.Where(location => location != keyLocation);
                var additionalLocations = dacLocationArray.Concat(otherKeyLocations);

                symbolContext.ReportDiagnosticWithSuppressionCheck(
                    Diagnostic.Create(Descriptors.PX1036_WrongDacMultipleUniqueKeyDeclarations, keyLocation, additionalLocations, diagnosticProperties),
                    context.CodeAnalysisSettings);
            }
        }
예제 #12
0
            public override void VisitInvocationExpression(InvocationExpressionSyntax node)
            {
                _context.CancellationToken.ThrowIfCancellationRequested();

                var methodSymbol = _semanticModel.GetSymbolInfo(node).Symbol as IMethodSymbol;

                if (methodSymbol != null && IsMethodForbidden(methodSymbol))
                {
                    bool found = node.ArgumentList.Arguments
                                 .Where(arg => arg.Expression != null)
                                 .Select(arg => _semanticModel.GetSymbolInfo(arg.Expression).Symbol as ILocalSymbol)
                                 .Any(variable => variable != null && _rowVariables.Contains(variable));

                    if (!found)
                    {
                        var walker = new EventArgsRowWalker(_semanticModel, _pxContext);
                        node.ArgumentList.Accept(walker);

                        found = walker.Success;
                    }

                    if (found && _analysisMode == RowChangesAnalysisMode.ChangesForbiddenForRowFromEventArgs)
                    {
                        _context.ReportDiagnosticWithSuppressionCheck(
                            Diagnostic.Create(
                                _pxContext.CodeAnalysisSettings.IsvSpecificAnalyzersEnabled
                                                                        ? Descriptors.PX1047_RowChangesInEventHandlersForbiddenForArgs
                                                                        : Descriptors.PX1047_RowChangesInEventHandlersForbiddenForArgs_NonISV,
                                node.GetLocation(),
                                _messageArgs),
                            _pxContext.CodeAnalysisSettings);
                    }
                    else if (!found && _analysisMode == RowChangesAnalysisMode.ChangesAllowedOnlyForRowFromEventArgs)
                    {
                        _context.ReportDiagnosticWithSuppressionCheck(
                            Diagnostic.Create(
                                Descriptors.PX1048_RowChangesInEventHandlersAllowedForArgsOnly,
                                node.GetLocation(),
                                _messageArgs),
                            _pxContext.CodeAnalysisSettings);
                    }
                }
            }
        private void ReportNoPrimaryKeyDeclarationsInDac(SymbolAnalysisContext symbolContext, PXContext context, DacSemanticModel dac)
        {
            Location location = dac.Node.Identifier.GetLocation() ?? dac.Node.GetLocation();

            if (location != null)
            {
                symbolContext.ReportDiagnosticWithSuppressionCheck(
                    Diagnostic.Create(Descriptors.PX1033_MissingDacPrimaryKeyDeclaration, location),
                    context.CodeAnalysisSettings);
            }
        }
예제 #14
0
        private void RegisterDiagnosticForIdentifier(SyntaxToken identifier, PXContext pxContext, SymbolAnalysisContext context)
        {
            bool isDeletedDatabaseRecord          = string.Equals(identifier.ValueText, DeletedDatabaseRecord, StringComparison.OrdinalIgnoreCase);
            DiagnosticDescriptor descriptorToShow =
                isDeletedDatabaseRecord && !pxContext.CodeAnalysisSettings.IsvSpecificAnalyzersEnabled
                                        ? Descriptors.PX1027_ForbiddenFieldsInDacDeclaration_NonISV
                                        : Descriptors.PX1027_ForbiddenFieldsInDacDeclaration;

            context.ReportDiagnosticWithSuppressionCheck(
                Diagnostic.Create(descriptorToShow, identifier.GetLocation(), identifier.ValueText),
                pxContext.CodeAnalysisSettings);
        }
예제 #15
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);
            }
        }
예제 #16
0
        public override void Analyze(SymbolAnalysisContext context, PXContext pxContext, PXGraphSemanticModel pxGraph)
        {
            context.CancellationToken.ThrowIfCancellationRequested();
            var constructorLocations = pxGraph.Symbol.InstanceConstructors.Where(constructor => !constructor.IsImplicitlyDeclared)
                                       .SelectMany(constructor => constructor.Locations);

            foreach (Location location in constructorLocations)
            {
                context.ReportDiagnosticWithSuppressionCheck(
                    Diagnostic.Create(Descriptors.PX1040_ConstructorInGraphExtension, location),
                    pxContext.CodeAnalysisSettings);
            }
        }
예제 #17
0
        private static void AnalyzeDacField(DacFieldInfo dacFieldInfo, SymbolAnalysisContext symbolContext, PXContext pxContext)
        {
            symbolContext.CancellationToken.ThrowIfCancellationRequested();

            if (dacFieldInfo.Symbol.IsAbstract)
            {
                return;
            }

            symbolContext.ReportDiagnosticWithSuppressionCheck(
                Diagnostic.Create(Descriptors.PX1024_DacNonAbstractFieldType, dacFieldInfo.Node.Identifier.GetLocation()),
                pxContext.CodeAnalysisSettings);
        }
        private static void AnalyzeDelegate(SymbolAnalysisContext syntaxContext, PXContext pxContext)
        {
            IMethodSymbol method = syntaxContext.Symbol as IMethodSymbol;

            if (!IsDiagnosticValid(method, syntaxContext, pxContext))
            {
                return;
            }

            var declaration       = method.DeclaringSyntaxReferences[0];
            var methodDeclaration = declaration.GetSyntax(syntaxContext.CancellationToken) as MethodDeclarationSyntax;

            if (methodDeclaration?.Body == null || syntaxContext.CancellationToken.IsCancellationRequested)
            {
                return;
            }

            SemanticModel semanticModel = syntaxContext.Compilation.GetSemanticModel(declaration.SyntaxTree);
            ILocalSymbol  refStartRow   = GetReferenceToStartRow(methodDeclaration, semanticModel, pxContext, syntaxContext.CancellationToken);

            if (refStartRow == null || syntaxContext.CancellationToken.IsCancellationRequested)
            {
                return;
            }

            var(selectSymbol, selectInvocation) = GetSelectSymbolAndInvocationNode(methodDeclaration, refStartRow, pxContext, semanticModel,
                                                                                   syntaxContext.CancellationToken);
            if (selectSymbol == null || selectInvocation == null || syntaxContext.CancellationToken.IsCancellationRequested)
            {
                return;
            }

            AssignmentExpressionSyntax lastAssigment = GetLastStartRowResetAssignment(methodDeclaration);

            if (lastAssigment != null && lastAssigment.SpanStart > selectInvocation.Span.End)
            {
                return;
            }

            bool registerCodeFix      = RegisterCodeFix(methodDeclaration, selectInvocation);
            var  diagnosticProperties = new Dictionary <string, string>
            {
                { DiagnosticProperty.RegisterCodeFix, registerCodeFix.ToString() }
            }.ToImmutableDictionary();

            syntaxContext.ReportDiagnosticWithSuppressionCheck(
                Diagnostic.Create(
                    Descriptors.PX1010_StartRowResetForPaging, selectInvocation.GetLocation(), diagnosticProperties),
                pxContext.CodeAnalysisSettings);
        }
        public override void Analyze(SymbolAnalysisContext context, PXContext pxContext, DacSemanticModel dacOrDacExtenstion)
        {
            context.CancellationToken.ThrowIfCancellationRequested();

            var dacConstructors = dacOrDacExtenstion.GetMemberNodes <ConstructorDeclarationSyntax>();

            foreach (var constructor in dacConstructors)
            {
                context.CancellationToken.ThrowIfCancellationRequested();

                context.ReportDiagnosticWithSuppressionCheck(
                    Diagnostic.Create(Descriptors.PX1028_ConstructorInDacDeclaration, constructor.Identifier.GetLocation()),
                    pxContext.CodeAnalysisSettings);
            }
        }
        private bool ReportKeyWithUnboundDacField(SymbolAnalysisContext symbolContext, PXContext context, INamedTypeSymbol key, ClassDeclarationSyntax keyNode,
                                                  ITypeSymbol unboundDacFieldInKey)
        {
            var location = GetUnboundDacFieldLocation(keyNode, unboundDacFieldInKey) ?? keyNode.Identifier.GetLocation() ?? keyNode.GetLocation();

            if (location == null)
            {
                return(false);
            }

            symbolContext.ReportDiagnosticWithSuppressionCheck(
                Diagnostic.Create(Descriptors.PX1037_UnboundDacFieldInKeyDeclaration, location),
                context.CodeAnalysisSettings);
            return(true);
        }
        private static void RegisterDiagnosticForAction(ISymbol actionSymbol, string primaryDacName,
                                                        ImmutableDictionary <string, string> diagnosticProperties,
                                                        SymbolAnalysisContext symbolContext, PXContext pxContext)
        {
            SyntaxNode symbolSyntax = actionSymbol.GetSyntax(symbolContext.CancellationToken);
            Location   location     = GetLocation(symbolSyntax);

            if (location == null)
            {
                return;
            }

            symbolContext.ReportDiagnosticWithSuppressionCheck(
                Diagnostic.Create(Descriptors.PX1012_PXActionOnNonPrimaryView, location, diagnosticProperties,
                                  actionSymbol.Name, primaryDacName), pxContext.CodeAnalysisSettings);
        }
        private static void ReportDiagnostic(DiagnosticDescriptor descriptor, SymbolAnalysisContext symbolContext, PXContext pxContext,
                                             IEnumerable <DataViewInfo> viewsToShowDiagnostic, ITypeSymbol dac, ITypeSymbol baseDac)
        {
            foreach (DataViewInfo view in viewsToShowDiagnostic)
            {
                Location viewLocation = view.Symbol.Locations.FirstOrDefault();

                if (viewLocation == null)
                {
                    continue;
                }

                symbolContext.ReportDiagnosticWithSuppressionCheck(
                    Diagnostic.Create(descriptor, viewLocation, dac.Name, baseDac.Name), pxContext.CodeAnalysisSettings);
            }
        }
        public void Analyze(SymbolAnalysisContext symbolContext, PXContext pxContext, DacSemanticModel dacExtension)
        {
            symbolContext.CancellationToken.ThrowIfCancellationRequested();

            // ShouldAnalyze already filtered everything and left only DAC extensions without IsActive
            // We just need to report them
            Location location = dacExtension.Node.Identifier.GetLocation();

            if (location == null)
            {
                return;
            }

            symbolContext.ReportDiagnosticWithSuppressionCheck(
                Diagnostic.Create(Descriptors.PX1016_NoIsActiveMethodForDacExtension, location),
                pxContext.CodeAnalysisSettings);
        }
            public override void VisitIdentifierName(IdentifierNameSyntax node)
            {
                ThrowIfCancellationRequested();

                TypeInfo typeInfo = _semanticModel.GetTypeInfo(node, _context.CancellationToken);

                if (typeInfo.Type == null || !typeInfo.Type.IsPXGraphOrExtension(_pxContext))
                {
                    return;
                }

                _context.ReportDiagnosticWithSuppressionCheck(
                    Diagnostic.Create(Descriptors.PX1029_PXGraphUsageInDac, node.GetLocation()),
                    _pxContext.CodeAnalysisSettings);

                base.VisitIdentifierName(node);
            }
        private void AnalyzeNamedType(SymbolAnalysisContext context, PXContext pxContext)
        {
            context.CancellationToken.ThrowIfCancellationRequested();

            var typeSymbol = (INamedTypeSymbol)context.Symbol;

            if (typeSymbol != null && typeSymbol.InheritsFrom(pxContext.PXGraphExtensionType) &&
                !typeSymbol.IsGraphExtensionBaseType())
            {
                foreach (var constructor in typeSymbol.InstanceConstructors
                         .Where(c => !c.IsImplicitlyDeclared))
                {
                    context.ReportDiagnosticWithSuppressionCheck(Diagnostic.Create(
                                                                     Descriptors.PX1040_ConstructorInGraphExtension, constructor.Locations.First()), pxContext.CodeAnalysisSettings);
                }
            }
        }
        private bool CheckThatAllKeysHaveUniqueSetsOfFields(SymbolAnalysisContext symbolContext, PXContext context,
                                                            List <INamedTypeSymbol> keyDeclarations, Dictionary <INamedTypeSymbol, List <ITypeSymbol> > dacFieldsByKey)
        {
            if (keyDeclarations.Count < 2 || dacFieldsByKey.Count == 0)
            {
                return(true);
            }

            // First obtain groups of keys which use same DAC fields.
            var keysGroupedByFields = GetKeysGroupedBySetOfFields(keyDeclarations, dacFieldsByKey, symbolContext.CancellationToken);

            // Get the groups of more than one key which use the same DAC fields set. Split these groups by their target DAC.
            // We don't do this for all keys at the previous step as a optimization for the most frequent case.
            // To split the key groups by their target DACs we need to extract the target DAC from them. Most of the keys use a unique set of DAC fields anyway,
            // so we don't need to make this redundant extraction for them.
            var duplicateKeySets = keysGroupedByFields.Values.Where(keys => keys.Count > 1)
                                   .SelectMany(keys => GetDuplicateKeysGroupsForSameTargetDAC(context, keys));
            bool allFieldsUnique = true;

            // We group keys by sets of used fields and then report each set with duplicate keys separately,
            // passing the locations of other duplicate fields in a set to code fix.
            // This way if there are two different sets of duplicate keys the code fix will affect only the set to which it was applied
            foreach (List <INamedTypeSymbol> duplicateKeys in duplicateKeySets)
            {
                allFieldsUnique = false;
                var locations = duplicateKeys.Select(declaration => declaration.GetSyntax(symbolContext.CancellationToken))
                                .OfType <ClassDeclarationSyntax>()
                                .Select(keyClassDeclaration => keyClassDeclaration.Identifier.GetLocation() ??
                                        keyClassDeclaration.GetLocation())
                                .Where(location => location != null)
                                .ToList(capacity: duplicateKeys.Count);

                for (int i = 0; i < locations.Count; i++)
                {
                    Location location       = locations[i];
                    var      otherLocations = locations.Where((_, index) => index != i);

                    symbolContext.ReportDiagnosticWithSuppressionCheck(
                        Diagnostic.Create(Descriptors.PX1035_MultipleKeyDeclarationsInDacWithSameFields, location, otherLocations),
                        context.CodeAnalysisSettings);
                }
            }

            return(allFieldsUnique);
        }
            public override void VisitObjectCreationExpression(ObjectCreationExpressionSyntax node)
            {
                if (node.Type == null || !(_semanticModel.GetSymbolInfo(node.Type).Symbol is ITypeSymbol typeSymbol))
                {
                    base.VisitObjectCreationExpression(node);
                    return;
                }

                DiagnosticDescriptor descriptor = GetDiagnosticDescriptor(typeSymbol);

                if (descriptor != null)
                {
                    _context.ReportDiagnosticWithSuppressionCheck(Diagnostic.Create(descriptor, node.GetLocation()),
                                                                  _pxContext.CodeAnalysisSettings);
                }

                base.VisitObjectCreationExpression(node);
            }
        public void Analyze(SymbolAnalysisContext symbolContext, PXContext pxContext, PXGraphSemanticModel graphExtension)
        {
            symbolContext.CancellationToken.ThrowIfCancellationRequested();

            // ShouldAnalyze already filtered everything and left only graph extensions without IsActive
            // We just need to report them
            var      syntaxNode = graphExtension.Symbol.GetSyntax(symbolContext.CancellationToken);
            Location location   = (syntaxNode as ClassDeclarationSyntax)?.Identifier.GetLocation() ?? syntaxNode?.GetLocation();

            if (location == null)
            {
                return;
            }

            symbolContext.ReportDiagnosticWithSuppressionCheck(
                Diagnostic.Create(Descriptors.PX1016_NoIsActiveMethodForGraphExtension, location),
                pxContext.CodeAnalysisSettings);
        }
        private static void CheckIdentifierForUnderscores(SyntaxToken identifier, SymbolAnalysisContext context, PXContext pxContext)
        {
            if (!identifier.ValueText.Contains("_"))
            {
                return;
            }

            bool registerCodeFix = !IdentifierContainsOnlyUnderscores(identifier.ValueText);

            var diagnosticProperties = new Dictionary <string, string>
            {
                { DiagnosticProperty.RegisterCodeFix, registerCodeFix.ToString() }
            }.ToImmutableDictionary();

            context.ReportDiagnosticWithSuppressionCheck(
                Diagnostic.Create(Descriptors.PX1026_UnderscoresInDacDeclaration, identifier.GetLocation(), diagnosticProperties),
                pxContext.CodeAnalysisSettings);
        }
예제 #30
0
        private void CheckActionHandlerReturnType(SymbolAnalysisContext context, PXContext pxContext, MethodDeclarationSyntax node, IMethodSymbol symbol)
        {
            context.CancellationToken.ThrowIfCancellationRequested();

            if (pxContext.SystemTypes.IEnumerable.Equals(symbol.ReturnType))
            {
                return;
            }

            if (!StartsLongOperation(pxContext, context.Compilation, node, context.CancellationToken))
            {
                return;
            }

            var diagnostic = Diagnostic.Create(
                Descriptors.PX1013_PXActionHandlerInvalidReturnType,
                node.Identifier.GetLocation());

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