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; } }
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); } }
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)); } }
public PropertyNodeViewModel(DacMemberCategoryNodeViewModel dacMemberCategoryVM, DacPropertyInfo propertyInfo, bool isExpanded = false) : base(dacMemberCategoryVM, dacMemberCategoryVM, propertyInfo, isExpanded) { var extraInfos = GetExtraInfos(); ExtraInfos = new ExtendedObservableCollection <ExtraInfoViewModel>(extraInfos); }
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); }