Merge commit '5135a036' into remed/lane-S7
This commit is contained in:
+1
-1
@@ -21,7 +21,7 @@
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Max concurrent reads</label>
|
||||
<InputNumber @bind-Value="_form.MaxConcurrentReads" @bind-Value:after="EmitAsync" class="form-control form-control-sm" />
|
||||
<div class="form-text">Read work items in flight at once. Default 8; 1 = sequential.</div>
|
||||
<div class="form-text">Read work items in flight at once. Default 8; 1 = sequential (libplctag). The native transport always uses at least 64 — it packs concurrent reads into one request.</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-check form-switch mt-4">
|
||||
|
||||
+16
-2
@@ -15,8 +15,22 @@
|
||||
</div>
|
||||
<div class="col-md-3"><label class="form-label">Data type</label>
|
||||
<select class="form-select form-select-sm" value="@_m.DataType" @onchange="@(e => Update(() => _m.DataType = ParseEnum(e.Value, FocasDataType.Int32)))">
|
||||
@foreach (var v in Enum.GetValues<FocasDataType>()) { <option value="@v">@v</option> }
|
||||
</select></div>
|
||||
@foreach (var v in Enum.GetValues<FocasDataType>())
|
||||
{
|
||||
@* String is only readable from the fixed tree (FocasTagDefinitionFactory.DescribeDataTypeMismatch):
|
||||
offered there, and kept visible when a loaded blob already carries it so the select never lies. *@
|
||||
if (v != FocasDataType.String || _m.DataType == FocasDataType.String
|
||||
|| FocasTagDefinitionFactory.DescribeDataTypeMismatch(v, _m.Address) is null)
|
||||
{
|
||||
<option value="@v">@v</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
@if (FocasTagDefinitionFactory.DescribeDataTypeMismatch(_m.DataType, _m.Address) is { } typeError)
|
||||
{
|
||||
<div class="form-text text-danger small">@typeError</div>
|
||||
}
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="focas-writable" disabled checked="false" />
|
||||
|
||||
@@ -50,7 +50,7 @@ public sealed record ScriptTagInfo(string Path, string Kind, string DataType, st
|
||||
/// else. Verified chain: <c>AddressSpaceComposer</c> harvests the <c>ctx.GetTag("…")</c> literals
|
||||
/// (via <c>EquipmentScriptPaths.ExtractDependencyRefs</c>) into <c>DependencyRefs</c>; those become
|
||||
/// <c>VirtualTagActor._dependencyRefs</c>, registered with <c>DependencyMuxActor</c>, whose
|
||||
/// <c>_byRef</c> map is keyed (Ordinal) by <c>DriverInstanceActor.AttributeValuePublished.FullReference</c>
|
||||
/// <c>_byRef</c> map is keyed (Ordinal) by <c>DriverInstanceActor.AttributeValueItem.FullReference</c>
|
||||
/// — and in v3 a driver's wire reference <b>is the RawPath</b>
|
||||
/// (<c>DriverHostActor._nodeIdByDriverRef</c> is keyed <c>(DriverInstanceId, RawPath)</c>).
|
||||
/// </para>
|
||||
|
||||
@@ -268,7 +268,16 @@ public sealed class ScriptAnalysisService
|
||||
var typeInfo = model.GetTypeInfo(memberAccess.Expression);
|
||||
var type = typeInfo.Type ?? typeInfo.ConvertedType;
|
||||
if (type == null) return null;
|
||||
return type.GetMembers()
|
||||
// The type's own members, then the INSTANCE members it inherits (stopping before System.Object, whose
|
||||
// ToString/GetHashCode noise was never offered). Without the base chain, a member declared only on
|
||||
// ScriptContext — ctx.CancellationToken — compiled and published but never completed. Inherited statics
|
||||
// (ScriptContext.Deadband) are left out: they are not reachable through an instance receiver. This applies to
|
||||
// EVERY receiver, not only ctx: a struct or enum receiver now also offers the System.ValueType /
|
||||
// System.Enum instance members it inherits (CompareTo, HasFlag, ...), all of which compile.
|
||||
var inherited = new List<ISymbol>();
|
||||
for (var b = type.BaseType; b is not null && b.SpecialType != SpecialType.System_Object; b = b.BaseType)
|
||||
inherited.AddRange(b.GetMembers().Where(m => !m.IsStatic));
|
||||
return type.GetMembers().Concat(inherited)
|
||||
.Where(m => m.CanBeReferencedByName && !m.IsImplicitlyDeclared)
|
||||
// NotApplicable covers members (e.g. some BCL/special members) that carry no explicit accessibility but are referenceable.
|
||||
.Where(m => m.DeclaredAccessibility == Accessibility.Public || m.DeclaredAccessibility == Accessibility.NotApplicable)
|
||||
|
||||
@@ -80,6 +80,10 @@ public sealed class FocasTagConfigModel
|
||||
// ahead of the parse consult below and is never replaced by it.
|
||||
if (FocasAddress.TryParse(Address) is null) return DescribeUnparseableAddress(Address);
|
||||
|
||||
// The driver's own address/data-type rule (String only on FIXED: paths) — checked on the typed fields so a
|
||||
// model built in the editor is judged too, not only a loaded blob the parse gate below can see.
|
||||
if (FocasTagDefinitionFactory.DescribeDataTypeMismatch(DataType, Address) is { } typeError) return typeError;
|
||||
|
||||
// Parse-gate backstop. ⚠️ It gates on the PARSE VERDICT, never on Inspect being non-empty: FOCAS's
|
||||
// inspector emits advisories for blobs the reader ACCEPTS (an unparseable address, an authored
|
||||
// 'writable':true on a read-only wire), and promoting those to authoring errors would make the modal
|
||||
|
||||
Reference in New Issue
Block a user