mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-19 17:19:42 +03:00
fix(meta-compile): fix String/Number length loss, RegisterRecords format, CommonModule prefix
- Parse-AttributeShorthand: combine type + length/precision from separate JSON fields (String→String(N), Number→Number(D,F)) — fixes SDBL error "Строка без спецификации длины недопустима" - Constant valueType: same length combination fix - DefinedType: accept both valueType (singular) and valueTypes (plural) - ChartOfCharacteristicTypes: default String length 0→100 - Document RegisterRecords: <xr:Record> → <xr:Item xsi:type="xr:MDObjectRef"> - ScheduledJob.MethodName, EventSubscription.Handler: auto-prepend CommonModule. prefix - meta-validate check 13: support 3-part method format (CommonModule.Module.Proc) E2E verified: 18 types (21 objects) pass cf-init → meta-compile → LoadConfigFromFiles → UpdateDBCfg Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
87dc18b120
commit
dbb39b7a3e
@@ -345,9 +345,20 @@ function Parse-AttributeShorthand {
|
|||||||
|
|
||||||
# Object form
|
# Object form
|
||||||
$name = "$($val.name)"
|
$name = "$($val.name)"
|
||||||
|
# Build type string combining type + length/precision from separate JSON fields
|
||||||
|
$typeStr = if ($val.type) { "$($val.type)" } else { "" }
|
||||||
|
if ($typeStr -and -not $typeStr.Contains('(')) {
|
||||||
|
if ($typeStr -eq "String" -and $val.length) {
|
||||||
|
$typeStr = "String($($val.length))"
|
||||||
|
} elseif ($typeStr -eq "Number" -and $val.length) {
|
||||||
|
$prec = if ($val.precision) { $val.precision } else { 0 }
|
||||||
|
$nn = if ($val.nonneg -or $val.nonnegative) { ",nonneg" } else { "" }
|
||||||
|
$typeStr = "Number($($val.length),$prec$nn)"
|
||||||
|
}
|
||||||
|
}
|
||||||
return @{
|
return @{
|
||||||
name = $name
|
name = $name
|
||||||
type = if ($val.type) { "$($val.type)" } else { "" }
|
type = $typeStr
|
||||||
synonym = if ($val.synonym) { "$($val.synonym)" } else { Split-CamelCase $name }
|
synonym = if ($val.synonym) { "$($val.synonym)" } else { Split-CamelCase $name }
|
||||||
comment = if ($val.comment) { "$($val.comment)" } else { "" }
|
comment = if ($val.comment) { "$($val.comment)" } else { "" }
|
||||||
flags = @(if ($val.flags) { $val.flags } else { @() })
|
flags = @(if ($val.flags) { $val.flags } else { @() })
|
||||||
@@ -1078,7 +1089,7 @@ function Emit-DocumentProperties {
|
|||||||
if ($regRecords.Count -gt 0) {
|
if ($regRecords.Count -gt 0) {
|
||||||
X "$i<RegisterRecords>"
|
X "$i<RegisterRecords>"
|
||||||
foreach ($rr in $regRecords) {
|
foreach ($rr in $regRecords) {
|
||||||
X "$i`t<xr:Record>$rr</xr:Record>"
|
X "$i`t<xr:Item xsi:type=`"xr:MDObjectRef`">$rr</xr:Item>"
|
||||||
}
|
}
|
||||||
X "$i</RegisterRecords>"
|
X "$i</RegisterRecords>"
|
||||||
} else {
|
} else {
|
||||||
@@ -1139,8 +1150,17 @@ function Emit-ConstantProperties {
|
|||||||
Emit-MLText $i "Synonym" $synonym
|
Emit-MLText $i "Synonym" $synonym
|
||||||
X "$i<Comment/>"
|
X "$i<Comment/>"
|
||||||
|
|
||||||
# Type
|
# Type — combine valueType + length/precision from separate JSON fields
|
||||||
$valueType = if ($def.valueType) { "$($def.valueType)" } else { "String" }
|
$valueType = if ($def.valueType) { "$($def.valueType)" } else { "String" }
|
||||||
|
if ($valueType -and -not $valueType.Contains('(')) {
|
||||||
|
if ($valueType -eq "String" -and $def.length) {
|
||||||
|
$valueType = "String($($def.length))"
|
||||||
|
} elseif ($valueType -eq "Number" -and $def.length) {
|
||||||
|
$p = if ($def.precision) { $def.precision } else { 0 }
|
||||||
|
$nn = if ($def.nonneg -or $def.nonnegative) { ",nonneg" } else { "" }
|
||||||
|
$valueType = "Number($($def.length),$p$nn)"
|
||||||
|
}
|
||||||
|
}
|
||||||
Emit-ValueType $i $valueType
|
Emit-ValueType $i $valueType
|
||||||
|
|
||||||
X "$i<UseStandardCommands>true</UseStandardCommands>"
|
X "$i<UseStandardCommands>true</UseStandardCommands>"
|
||||||
@@ -1265,10 +1285,12 @@ function Emit-DefinedTypeProperties {
|
|||||||
Emit-MLText $i "Synonym" $synonym
|
Emit-MLText $i "Synonym" $synonym
|
||||||
X "$i<Comment/>"
|
X "$i<Comment/>"
|
||||||
|
|
||||||
# Type — composite type with multiple v8:Type entries
|
# Type — composite type with multiple v8:Type entries (accept both valueType and valueTypes)
|
||||||
$valueTypes = @()
|
$valueTypes = @()
|
||||||
if ($def.valueTypes) {
|
if ($def.valueTypes) {
|
||||||
$valueTypes = @($def.valueTypes)
|
$valueTypes = @($def.valueTypes)
|
||||||
|
} elseif ($def.valueType) {
|
||||||
|
$valueTypes = @($def.valueType)
|
||||||
}
|
}
|
||||||
if ($valueTypes.Count -gt 0) {
|
if ($valueTypes.Count -gt 0) {
|
||||||
X "$i<Type>"
|
X "$i<Type>"
|
||||||
@@ -1345,6 +1367,10 @@ function Emit-ScheduledJobProperties {
|
|||||||
X "$i<Comment/>"
|
X "$i<Comment/>"
|
||||||
|
|
||||||
$methodName = if ($def.methodName) { "$($def.methodName)" } else { "" }
|
$methodName = if ($def.methodName) { "$($def.methodName)" } else { "" }
|
||||||
|
# Ensure CommonModule. prefix
|
||||||
|
if ($methodName -and -not $methodName.StartsWith("CommonModule.")) {
|
||||||
|
$methodName = "CommonModule.$methodName"
|
||||||
|
}
|
||||||
X "$i<MethodName>$(Esc-Xml $methodName)</MethodName>"
|
X "$i<MethodName>$(Esc-Xml $methodName)</MethodName>"
|
||||||
|
|
||||||
$description = if ($def.description) { "$($def.description)" } else { $synonym }
|
$description = if ($def.description) { "$($def.description)" } else { $synonym }
|
||||||
@@ -1391,6 +1417,10 @@ function Emit-EventSubscriptionProperties {
|
|||||||
X "$i<Event>$event</Event>"
|
X "$i<Event>$event</Event>"
|
||||||
|
|
||||||
$handler = if ($def.handler) { "$($def.handler)" } else { "" }
|
$handler = if ($def.handler) { "$($def.handler)" } else { "" }
|
||||||
|
# Ensure CommonModule. prefix
|
||||||
|
if ($handler -and -not $handler.StartsWith("CommonModule.")) {
|
||||||
|
$handler = "CommonModule.$handler"
|
||||||
|
}
|
||||||
X "$i<Handler>$(Esc-Xml $handler)</Handler>"
|
X "$i<Handler>$(Esc-Xml $handler)</Handler>"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1556,7 +1586,7 @@ function Emit-ChartOfCharacteristicTypesProperties {
|
|||||||
X "$i`t<v8:Type>xs:boolean</v8:Type>"
|
X "$i`t<v8:Type>xs:boolean</v8:Type>"
|
||||||
X "$i`t<v8:Type>xs:string</v8:Type>"
|
X "$i`t<v8:Type>xs:string</v8:Type>"
|
||||||
X "$i`t<v8:StringQualifiers>"
|
X "$i`t<v8:StringQualifiers>"
|
||||||
X "$i`t`t<v8:Length>0</v8:Length>"
|
X "$i`t`t<v8:Length>100</v8:Length>"
|
||||||
X "$i`t`t<v8:AllowedLength>Variable</v8:AllowedLength>"
|
X "$i`t`t<v8:AllowedLength>Variable</v8:AllowedLength>"
|
||||||
X "$i`t</v8:StringQualifiers>"
|
X "$i`t</v8:StringQualifiers>"
|
||||||
X "$i`t<v8:Type>xs:decimal</v8:Type>"
|
X "$i`t<v8:Type>xs:decimal</v8:Type>"
|
||||||
|
|||||||
@@ -320,9 +320,18 @@ def parse_attribute_shorthand(val):
|
|||||||
return parsed
|
return parsed
|
||||||
# Object form
|
# Object form
|
||||||
name = str(val.get('name', ''))
|
name = str(val.get('name', ''))
|
||||||
|
# Build type string combining type + length/precision from separate JSON fields
|
||||||
|
type_str = str(val['type']) if val.get('type') else ''
|
||||||
|
if type_str and '(' not in type_str:
|
||||||
|
if type_str == 'String' and val.get('length'):
|
||||||
|
type_str = f"String({val['length']})"
|
||||||
|
elif type_str == 'Number' and val.get('length'):
|
||||||
|
prec = val.get('precision', 0)
|
||||||
|
nn = ',nonneg' if val.get('nonneg') or val.get('nonnegative') else ''
|
||||||
|
type_str = f"Number({val['length']},{prec}{nn})"
|
||||||
return {
|
return {
|
||||||
'name': name,
|
'name': name,
|
||||||
'type': str(val['type']) if val.get('type') else '',
|
'type': type_str,
|
||||||
'synonym': str(val['synonym']) if val.get('synonym') else split_camel_case(name),
|
'synonym': str(val['synonym']) if val.get('synonym') else split_camel_case(name),
|
||||||
'comment': str(val['comment']) if val.get('comment') else '',
|
'comment': str(val['comment']) if val.get('comment') else '',
|
||||||
'flags': list(val.get('flags', [])),
|
'flags': list(val.get('flags', [])),
|
||||||
@@ -968,7 +977,7 @@ def emit_document_properties(indent):
|
|||||||
if reg_records:
|
if reg_records:
|
||||||
X(f'{i}<RegisterRecords>')
|
X(f'{i}<RegisterRecords>')
|
||||||
for rr in reg_records:
|
for rr in reg_records:
|
||||||
X(f'{i}\t<xr:Record>{rr}</xr:Record>')
|
X(f'{i}\t<xr:Item xsi:type="xr:MDObjectRef">{rr}</xr:Item>')
|
||||||
X(f'{i}</RegisterRecords>')
|
X(f'{i}</RegisterRecords>')
|
||||||
else:
|
else:
|
||||||
X(f'{i}<RegisterRecords/>')
|
X(f'{i}<RegisterRecords/>')
|
||||||
@@ -1014,7 +1023,15 @@ def emit_constant_properties(indent):
|
|||||||
X(f'{i}<Name>{esc_xml(obj_name)}</Name>')
|
X(f'{i}<Name>{esc_xml(obj_name)}</Name>')
|
||||||
emit_mltext(i, 'Synonym', synonym)
|
emit_mltext(i, 'Synonym', synonym)
|
||||||
X(f'{i}<Comment/>')
|
X(f'{i}<Comment/>')
|
||||||
|
# Type — combine valueType + length/precision from separate JSON fields
|
||||||
value_type = str(defn['valueType']) if defn.get('valueType') else 'String'
|
value_type = str(defn['valueType']) if defn.get('valueType') else 'String'
|
||||||
|
if value_type and '(' not in value_type:
|
||||||
|
if value_type == 'String' and defn.get('length'):
|
||||||
|
value_type = f"String({defn['length']})"
|
||||||
|
elif value_type == 'Number' and defn.get('length'):
|
||||||
|
prec = defn.get('precision', 0)
|
||||||
|
nn = ',nonneg' if defn.get('nonneg') or defn.get('nonnegative') else ''
|
||||||
|
value_type = f"Number({defn['length']},{prec}{nn})"
|
||||||
emit_value_type(i, value_type)
|
emit_value_type(i, value_type)
|
||||||
X(f'{i}<UseStandardCommands>true</UseStandardCommands>')
|
X(f'{i}<UseStandardCommands>true</UseStandardCommands>')
|
||||||
X(f'{i}<DefaultForm/>')
|
X(f'{i}<DefaultForm/>')
|
||||||
@@ -1111,7 +1128,11 @@ def emit_defined_type_properties(indent):
|
|||||||
X(f'{i}<Name>{esc_xml(obj_name)}</Name>')
|
X(f'{i}<Name>{esc_xml(obj_name)}</Name>')
|
||||||
emit_mltext(i, 'Synonym', synonym)
|
emit_mltext(i, 'Synonym', synonym)
|
||||||
X(f'{i}<Comment/>')
|
X(f'{i}<Comment/>')
|
||||||
|
# Accept both valueType and valueTypes
|
||||||
value_types = list(defn.get('valueTypes', []))
|
value_types = list(defn.get('valueTypes', []))
|
||||||
|
if not value_types and defn.get('valueType'):
|
||||||
|
vt_raw = defn['valueType']
|
||||||
|
value_types = list(vt_raw) if isinstance(vt_raw, list) else [vt_raw]
|
||||||
if value_types:
|
if value_types:
|
||||||
X(f'{i}<Type>')
|
X(f'{i}<Type>')
|
||||||
for vt in value_types:
|
for vt in value_types:
|
||||||
@@ -1182,6 +1203,9 @@ def emit_scheduled_job_properties(indent):
|
|||||||
emit_mltext(i, 'Synonym', synonym)
|
emit_mltext(i, 'Synonym', synonym)
|
||||||
X(f'{i}<Comment/>')
|
X(f'{i}<Comment/>')
|
||||||
method_name = str(defn['methodName']) if defn.get('methodName') else ''
|
method_name = str(defn['methodName']) if defn.get('methodName') else ''
|
||||||
|
# Ensure CommonModule. prefix
|
||||||
|
if method_name and not method_name.startswith('CommonModule.'):
|
||||||
|
method_name = f'CommonModule.{method_name}'
|
||||||
X(f'{i}<MethodName>{esc_xml(method_name)}</MethodName>')
|
X(f'{i}<MethodName>{esc_xml(method_name)}</MethodName>')
|
||||||
description = str(defn['description']) if defn.get('description') else synonym
|
description = str(defn['description']) if defn.get('description') else synonym
|
||||||
X(f'{i}<Description>{esc_xml(description)}</Description>')
|
X(f'{i}<Description>{esc_xml(description)}</Description>')
|
||||||
@@ -1213,6 +1237,9 @@ def emit_event_subscription_properties(indent):
|
|||||||
event = str(defn['event']) if defn.get('event') else 'BeforeWrite'
|
event = str(defn['event']) if defn.get('event') else 'BeforeWrite'
|
||||||
X(f'{i}<Event>{event}</Event>')
|
X(f'{i}<Event>{event}</Event>')
|
||||||
handler = str(defn['handler']) if defn.get('handler') else ''
|
handler = str(defn['handler']) if defn.get('handler') else ''
|
||||||
|
# Ensure CommonModule. prefix
|
||||||
|
if handler and not handler.startswith('CommonModule.'):
|
||||||
|
handler = f'CommonModule.{handler}'
|
||||||
X(f'{i}<Handler>{esc_xml(handler)}</Handler>')
|
X(f'{i}<Handler>{esc_xml(handler)}</Handler>')
|
||||||
|
|
||||||
# --- 13b. Report, DataProcessor ---
|
# --- 13b. Report, DataProcessor ---
|
||||||
@@ -1366,7 +1393,7 @@ def emit_chart_of_characteristic_types_properties(indent):
|
|||||||
X(f'{i}\t<v8:Type>xs:boolean</v8:Type>')
|
X(f'{i}\t<v8:Type>xs:boolean</v8:Type>')
|
||||||
X(f'{i}\t<v8:Type>xs:string</v8:Type>')
|
X(f'{i}\t<v8:Type>xs:string</v8:Type>')
|
||||||
X(f'{i}\t<v8:StringQualifiers>')
|
X(f'{i}\t<v8:StringQualifiers>')
|
||||||
X(f'{i}\t\t<v8:Length>0</v8:Length>')
|
X(f'{i}\t\t<v8:Length>100</v8:Length>')
|
||||||
X(f'{i}\t\t<v8:AllowedLength>Variable</v8:AllowedLength>')
|
X(f'{i}\t\t<v8:AllowedLength>Variable</v8:AllowedLength>')
|
||||||
X(f'{i}\t</v8:StringQualifiers>')
|
X(f'{i}\t</v8:StringQualifiers>')
|
||||||
X(f'{i}\t<v8:Type>xs:decimal</v8:Type>')
|
X(f'{i}\t<v8:Type>xs:decimal</v8:Type>')
|
||||||
|
|||||||
@@ -1181,12 +1181,20 @@ if ($propsNode -and $mdType -in @("EventSubscription","ScheduledJob") -and $scri
|
|||||||
|
|
||||||
if ($methodRef) {
|
if ($methodRef) {
|
||||||
$parts = $methodRef.Split('.')
|
$parts = $methodRef.Split('.')
|
||||||
if ($parts.Count -ne 2) {
|
# Format: CommonModule.ModuleName.ProcedureName (3 parts) or ModuleName.ProcedureName (2 parts, legacy)
|
||||||
Report-Error "13. ${mdType}.${propLabel} = '$methodRef': expected format 'CommonModuleName.ProcedureName'"
|
if ($parts.Count -eq 3 -and $parts[0] -eq "CommonModule") {
|
||||||
$check13Ok = $false
|
$cmName = $parts[1]
|
||||||
} else {
|
$procName = $parts[2]
|
||||||
|
} elseif ($parts.Count -eq 2) {
|
||||||
$cmName = $parts[0]
|
$cmName = $parts[0]
|
||||||
$procName = $parts[1]
|
$procName = $parts[1]
|
||||||
|
} else {
|
||||||
|
Report-Error "13. ${mdType}.${propLabel} = '$methodRef': expected format 'CommonModule.ModuleName.ProcedureName'"
|
||||||
|
$check13Ok = $false
|
||||||
|
$cmName = $null
|
||||||
|
$procName = $null
|
||||||
|
}
|
||||||
|
if ($cmName) {
|
||||||
$cmXml = Join-Path (Join-Path $script:configDir "CommonModules") "$cmName.xml"
|
$cmXml = Join-Path (Join-Path $script:configDir "CommonModules") "$cmName.xml"
|
||||||
if (-not (Test-Path $cmXml)) {
|
if (-not (Test-Path $cmXml)) {
|
||||||
Report-Error "13. ${mdType}.${propLabel}: CommonModule '$cmName' not found (expected $cmXml)"
|
Report-Error "13. ${mdType}.${propLabel}: CommonModule '$cmName' not found (expected $cmXml)"
|
||||||
|
|||||||
@@ -1106,12 +1106,19 @@ if props_node is not None and md_type in ("EventSubscription", "ScheduledJob") a
|
|||||||
|
|
||||||
if method_ref:
|
if method_ref:
|
||||||
parts = method_ref.split(".")
|
parts = method_ref.split(".")
|
||||||
if len(parts) != 2:
|
# Format: CommonModule.ModuleName.ProcedureName (3 parts) or ModuleName.ProcedureName (2 parts, legacy)
|
||||||
report_error(f"13. {md_type}.{prop_label} = '{method_ref}': expected format 'CommonModuleName.ProcedureName'")
|
if len(parts) == 3 and parts[0] == "CommonModule":
|
||||||
check13_ok = False
|
cm_name = parts[1]
|
||||||
else:
|
proc_name = parts[2]
|
||||||
|
elif len(parts) == 2:
|
||||||
cm_name = parts[0]
|
cm_name = parts[0]
|
||||||
proc_name = parts[1]
|
proc_name = parts[1]
|
||||||
|
else:
|
||||||
|
report_error(f"13. {md_type}.{prop_label} = '{method_ref}': expected format 'CommonModule.ModuleName.ProcedureName'")
|
||||||
|
check13_ok = False
|
||||||
|
cm_name = None
|
||||||
|
proc_name = None
|
||||||
|
if cm_name:
|
||||||
cm_xml = os.path.join(config_dir, "CommonModules", f"{cm_name}.xml")
|
cm_xml = os.path.join(config_dir, "CommonModules", f"{cm_name}.xml")
|
||||||
if not os.path.exists(cm_xml):
|
if not os.path.exists(cm_xml):
|
||||||
report_error(f"13. {md_type}.{prop_label}: CommonModule '{cm_name}' not found (expected {cm_xml})")
|
report_error(f"13. {md_type}.{prop_label}: CommonModule '{cm_name}' not found (expected {cm_xml})")
|
||||||
|
|||||||
Reference in New Issue
Block a user