static void AddScriptReference(Assembly assembly) { if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } // remember the assembly for class map: s_assClassMap.AddPhpAssemblyNoLock(assembly); // reflect the module for imported symbols: var module = assembly.ManifestModule; // PhpPackageReferenceAttribute foreach (var r in module.GetCustomAttributes <PhpPackageReferenceAttribute>()) { Context.AddScriptReference(r.ScriptType); } // ImportPhpTypeAttribute foreach (var t in module.GetCustomAttributes <ImportPhpTypeAttribute>()) { TypesTable.DeclareAppType(PhpTypeInfoExtension.GetPhpTypeInfo(t.ImportedType)); } // ImportPhpFunctionsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpFunctionsAttribute>()) { // TODO: remember the container, do not reflect repetitiously foreach (var m in t.ContainerType.GetMethods()) { if (m.IsPublic && m.IsStatic && !m.IsPhpHidden()) { RoutinesTable.DeclareAppRoutine(m.Name, m); } } } // ImportPhpConstantsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpConstantsAttribute>()) { // TODO: remember the container, do not reflect repetitiously foreach (var m in t.ContainerType.GetMembers(BindingFlags.Static | BindingFlags.Public)) { if (m is FieldInfo fi && !fi.IsPhpHidden()) { Debug.Assert(fi.IsStatic && fi.IsPublic); if (fi.IsInitOnly || fi.IsLiteral) { ConstsMap.DefineAppConstant(fi.Name, PhpValue.FromClr(fi.GetValue(null))); } else { ConstsMap.DefineAppConstant(fi.Name, new Func <PhpValue>(() => PhpValue.FromClr(fi.GetValue(null)))); } }
protected Context() { // tables _functions = new RoutinesTable(); _types = new TypesTable(); _statics = new object[StaticIndexes.StaticsCount]; _constants = ConstsMap.Create(this); _scripts = ScriptsMap.Create(); }
internal bool DefineConstant(string name, PhpValue value, ref int idx, bool ignorecase = false) { var success = ConstsMap.DefineConstant(ref _constants, name, value, ref idx, ignorecase); if (success == false) { PhpException.Throw(PhpError.Notice, string.Format(Resources.ErrResources.constant_redefined, name)); } return(success); }
/// <summary> /// Initializes instance of context. /// </summary> /// <param name="services">Service provider. Can be <c>null</c> reference to use implicit services.</param> protected Context(IServiceProvider services) { _services = services; // tables _functions = new RoutinesTable(); _types = new TypesTable(); _statics = Array.Empty <object>(); _constants = ConstsMap.Create(this); _scripts = ScriptsMap.Create(); }
/// <summary> /// Retrieves a collection of client validation rules (which are next sent to browsers). /// </summary> /// <returns> /// A collection of client validation rules. /// </returns> public override IEnumerable <ModelClientValidationRule> GetClientValidationRules() { var rule = new ModelClientValidationRule { ErrorMessage = FormattedErrorMessage, ValidationType = ProvideUniqueValidationType("assertthat") }; rule.ValidationParameters.Add("expression", Expression); rule.ValidationParameters.Add("fieldsmap", FieldsMap.ToJson()); rule.ValidationParameters.Add("constsmap", ConstsMap.ToJson()); yield return(rule); }
/// <summary> /// Generates client validation rule with the basic set of parameters. /// </summary> /// <param name="type">The validation type.</param> /// <returns> /// Client validation rule with the basic set of parameters. /// </returns> /// <exception cref="System.ComponentModel.DataAnnotations.ValidationException"></exception> protected ModelClientValidationRule GetBasicRule(string type) { try { var rule = new ModelClientValidationRule { ErrorMessage = FormattedErrorMessage, ValidationType = ProvideUniqueValidationType(type) }; rule.ValidationParameters.Add("expression", Expression.ToJson()); Debug.Assert(FieldsMap != null); if (FieldsMap.Any()) { rule.ValidationParameters.Add("fieldsmap", FieldsMap.ToJson()); } Debug.Assert(ConstsMap != null); if (ConstsMap.Any()) { rule.ValidationParameters.Add("constsmap", ConstsMap.ToJson()); } Debug.Assert(EnumsMap != null); if (EnumsMap.Any()) { rule.ValidationParameters.Add("enumsmap", EnumsMap.ToJson()); } Debug.Assert(MethodsList != null); if (MethodsList.Any()) { rule.ValidationParameters.Add("methodslist", MethodsList.ToJson()); } Debug.Assert(ParsersMap != null); if (ParsersMap.Any()) { rule.ValidationParameters.Add("parsersmap", ParsersMap.ToJson()); } Debug.Assert(ErrFieldsMap != null); if (ErrFieldsMap.Any()) { rule.ValidationParameters.Add("errfieldsmap", ErrFieldsMap.ToJson()); } return(rule); } catch (Exception e) { throw new ValidationException( $"{GetType().Name}: collecting of client validation rules for {FieldName} field failed.", e); } }
/// <summary> /// Attaches client validation rule to the context. /// </summary> /// <param name="context">The Client Model Validation Context.</param> /// <param name="type">The validation type.</param> /// <param name="defaultErrorMessage">The default Error Message.</param> /// <returns> /// void /// </returns> /// <exception cref="System.ComponentModel.DataAnnotations.ValidationException"></exception> protected void AttachValidationRules(ClientModelValidationContext context, string type, string defaultErrorMessage) { var errorMessage = !string.IsNullOrEmpty(FormattedErrorMessage) ? FormattedErrorMessage : defaultErrorMessage; var uniqueValidationType = ProvideUniqueValidationType(type); try { MergeAttribute(context.Attributes, "data-val", "true"); MergeAttribute(context.Attributes, $"data-val-{uniqueValidationType}", errorMessage); MergeAttribute(context.Attributes, $"data-val-{uniqueValidationType}-expression", Expression.ToJson()); Debug.Assert(FieldsMap != null); if (FieldsMap.Any()) { MergeAttribute(context.Attributes, $"data-val-{uniqueValidationType}-fieldsmap", FieldsMap.ToJson()); } Debug.Assert(ConstsMap != null); if (ConstsMap.Any()) { MergeAttribute(context.Attributes, $"data-val-{uniqueValidationType}-constsmap", ConstsMap.ToJson()); } Debug.Assert(EnumsMap != null); if (EnumsMap.Any()) { MergeAttribute(context.Attributes, $"data-val-{uniqueValidationType}-enumsmap", EnumsMap.ToJson()); } Debug.Assert(MethodsList != null); if (MethodsList.Any()) { MergeAttribute(context.Attributes, $"data-val-{uniqueValidationType}-methodslist", MethodsList.ToJson()); } Debug.Assert(ParsersMap != null); if (ParsersMap.Any()) { MergeAttribute(context.Attributes, $"data-val-{uniqueValidationType}-parsersmap", ParsersMap.ToJson()); } Debug.Assert(ErrFieldsMap != null); if (ErrFieldsMap.Any()) { MergeAttribute(context.Attributes, $"data-val-{uniqueValidationType}-errfieldsmap", ErrFieldsMap.ToJson()); } } catch (Exception e) { throw new ValidationException( $"{GetType().Name}: collecting of client validation rules for {FieldName} field failed.", e); } }
public override void AddValidation(ClientModelValidationContext context) { SetupValidator(context.ModelMetadata); var validationId = GetUniqueValidationId(context); var formattedErrorMessage = GetErrorMessage(context); MergeAttribute(context.Attributes, "data-val", "true"); MergeAttribute(context.Attributes, $"data-val-{validationId}", formattedErrorMessage); MergeExpressiveAttribute(context, validationId, "expression", Attribute.Expression); if (AllowEmpty.HasValue) { MergeExpressiveAttribute(context, validationId, "allowempty", AllowEmpty); } if (FieldsMap != null && FieldsMap.Any()) { MergeExpressiveAttribute(context, validationId, "fieldsmap", FieldsMap); } if (ConstsMap != null && ConstsMap.Any()) { MergeExpressiveAttribute(context, validationId, "constsmap", ConstsMap); } if (EnumsMap != null && EnumsMap.Any()) { MergeExpressiveAttribute(context, validationId, "enumsmap", EnumsMap); } if (MethodsList != null && MethodsList.Any()) { MergeExpressiveAttribute(context, validationId, "methodslist", MethodsList); } if (ParsersMap != null && ParsersMap.Any()) { MergeExpressiveAttribute(context, validationId, "parsersmap", ParsersMap); } if (ErrFieldsMap != null && ErrFieldsMap.Any()) { MergeExpressiveAttribute(context, validationId, "errfieldsmap", ErrFieldsMap); } }
/// <summary> /// Retrieves a collection of client validation rules (rules sent to browsers). /// </summary> /// <returns> /// A collection of client validation rules. /// </returns> public override IEnumerable <ModelClientValidationRule> GetClientValidationRules() { var count = Storage.Get <int>(AnnotatedField) + 1; Assert.AttribsQuantityAllowed(count); Storage.Set(AnnotatedField, count); var suffix = count == 1 ? string.Empty : char.ConvertFromUtf32(95 + count); var rule = new ModelClientValidationRule { ErrorMessage = FormattedErrorMessage, ValidationType = string.Format("assertthat{0}", suffix) }; rule.ValidationParameters.Add("expression", Expression); rule.ValidationParameters.Add("fieldsmap", FieldsMap.ToJson()); rule.ValidationParameters.Add("constsmap", ConstsMap.ToJson()); yield return(rule); }
/// <summary> /// Reflects given assembly for PeachPie compiler specifics - compiled scripts, references to other assemblies, declared functions and classes. /// Scripts and declarations are loaded into application context (static). /// </summary> /// <param name="assembly">PeachPie compiler generated assembly.</param> /// <remarks>Not thread safe.</remarks> public static void AddScriptReference(Assembly assembly) { if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } if (assembly.GetType(ScriptInfo.ScriptTypeName) == null || !TryAddAssembly(assembly)) { // nothing to reflect return; } // reflect the module for imported symbols: var module = assembly.ManifestModule; // PhpPackageReferenceAttribute foreach (var r in module.GetCustomAttributes <PhpPackageReferenceAttribute>()) { AddPhpPackageReference(r.ScriptType); } // ImportPhpTypeAttribute foreach (var t in module.GetCustomAttributes <ImportPhpTypeAttribute>()) { TypesTable.DeclareAppType(PhpTypeInfoExtension.GetPhpTypeInfo(t.ImportedType)); } // ImportPhpFunctionsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpFunctionsAttribute>()) { if (ExtensionsAppContext.ExtensionsTable.VisitFunctionsContainer(t.ContainerType, out var attr)) { foreach (var m in t.ContainerType.GetMethods()) { if (m.IsPublic && m.IsStatic && !m.IsSpecialName && !m.IsPhpHidden()) { ExtensionsAppContext.ExtensionsTable.AddRoutine(attr, RoutinesTable.DeclareAppRoutine(m.Name, m)); } } } } // ImportPhpConstantsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpConstantsAttribute>()) { if (!s_processedConstantsContainers.Add(t.ContainerType)) { // already visited before continue; } // var extensionName = t.ContainerType.GetCustomAttribute <PhpExtensionAttribute>(false)?.FirstExtensionOrDefault; // reflect constants defined in the container foreach (var m in t.ContainerType.GetMembers(BindingFlags.Static | BindingFlags.Public)) { if (m is FieldInfo fi && !fi.IsPhpHidden()) { Debug.Assert(fi.IsStatic && fi.IsPublic); if (fi.IsInitOnly || fi.IsLiteral) { // constant ConstsMap.DefineAppConstant(fi.Name, PhpValue.FromClr(fi.GetValue(null)), false, extensionName); } else { // static field ConstsMap.DefineAppConstant(fi.Name, new Func <PhpValue>(() => PhpValue.FromClr(fi.GetValue(null))), false, extensionName); } }
/// <summary> /// Reflects given assembly for PeachPie compiler specifics - compiled scripts, references to other assemblies, declared functions and classes. /// Scripts and declarations are loaded into application context (static). /// </summary> /// <param name="assembly">PeachPie compiler generated assembly.</param> /// <remarks>Not thread safe.</remarks> public static void AddScriptReference(Assembly assembly) { if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } if (assembly.GetType(ScriptInfo.ScriptTypeName) == null || !s_processedAssemblies.Add(assembly)) { // nothing to reflect return; } s_processedAssembliesArr = ArrayUtils.AppendRange(assembly, s_processedAssembliesArr); // TODO: ImmutableArray<T> // remember the assembly for class map: s_assClassMap.AddPhpAssemblyNoLock(assembly); // reflect the module for imported symbols: var module = assembly.ManifestModule; // PhpPackageReferenceAttribute foreach (var r in module.GetCustomAttributes <PhpPackageReferenceAttribute>()) { if (r.ScriptType != null) // always true { AddScriptReference(r.ScriptType.Assembly); } } // ImportPhpTypeAttribute foreach (var t in module.GetCustomAttributes <ImportPhpTypeAttribute>()) { TypesTable.DeclareAppType(PhpTypeInfoExtension.GetPhpTypeInfo(t.ImportedType)); } // ImportPhpFunctionsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpFunctionsAttribute>()) { if (ExtensionsAppContext.ExtensionsTable.VisitFunctionsContainer(t.ContainerType, out var attr)) { foreach (var m in t.ContainerType.GetMethods()) { if (m.IsPublic && m.IsStatic && !m.IsPhpHidden()) { ExtensionsAppContext.ExtensionsTable.AddRoutine(attr, RoutinesTable.DeclareAppRoutine(m.Name, m)); } } } } // ImportPhpConstantsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpConstantsAttribute>()) { if (!s_processedConstantsContainers.Add(t.ContainerType)) { // already visited before continue; } // reflect constants defined in the container foreach (var m in t.ContainerType.GetMembers(BindingFlags.Static | BindingFlags.Public)) { if (m is FieldInfo fi && !fi.IsPhpHidden()) { Debug.Assert(fi.IsStatic && fi.IsPublic); if (fi.IsInitOnly || fi.IsLiteral) { ConstsMap.DefineAppConstant(fi.Name, PhpValue.FromClr(fi.GetValue(null))); } else { ConstsMap.DefineAppConstant(fi.Name, new Func <PhpValue>(() => PhpValue.FromClr(fi.GetValue(null)))); } }
public void Define(string name, PhpValue value, bool ignoreCase) => ConstsMap.DefineAppConstant(name, value, ignoreCase);
internal bool DefineConstant(string name, PhpValue value, ref int idx, bool ignorecase = false) => ConstsMap.DefineConstant(ref _constants, name, value, ref idx, ignorecase);