@lcap/nasl 3.6.0-alpha.7 → 3.6.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/automate/engine/index.d.ts +4 -0
- package/out/automate/engine/index.js +443 -0
- package/out/automate/engine/index.js.map +1 -0
- package/out/automate/engine/operators.d.ts +26 -0
- package/out/automate/engine/operators.js +364 -0
- package/out/automate/engine/operators.js.map +1 -0
- package/out/automate/engine/uniqueName.d.ts +12 -0
- package/out/automate/engine/uniqueName.js +116 -0
- package/out/automate/engine/uniqueName.js.map +1 -0
- package/out/automate/engine/utils.d.ts +25 -0
- package/out/automate/engine/utils.js +440 -0
- package/out/automate/engine/utils.js.map +1 -0
- package/out/automate/engine/viewCache.d.ts +19 -0
- package/out/automate/engine/viewCache.js +45 -0
- package/out/automate/engine/viewCache.js.map +1 -0
- package/out/automate/template/myProcess.d.ts +10 -0
- package/out/automate/template/myProcess.js +11502 -0
- package/out/automate/template/myProcess.js.map +1 -0
- package/out/automate/upgrader/2.12.d.ts +7 -0
- package/out/automate/upgrader/2.12.js +63 -0
- package/out/automate/upgrader/2.12.js.map +1 -0
- package/out/automate/upgrader/2.14-components.d.ts +1115 -0
- package/out/automate/upgrader/2.14-components.js +1087 -0
- package/out/automate/upgrader/2.14-components.js.map +1 -0
- package/out/automate/upgrader/2.14.d.ts +10 -0
- package/out/automate/upgrader/2.14.js +236 -0
- package/out/automate/upgrader/2.14.js.map +1 -0
- package/out/automate/upgrader/2.14.old.d.ts +1 -0
- package/out/automate/upgrader/2.14.old.js +125 -0
- package/out/automate/upgrader/2.14.old.js.map +1 -0
- package/out/automate/upgrader/2.16.d.ts +10 -0
- package/out/automate/upgrader/2.16.js +75 -0
- package/out/automate/upgrader/2.16.js.map +1 -0
- package/out/automate/upgrader/2.17.d.ts +21 -0
- package/out/automate/upgrader/2.17.js +557 -0
- package/out/automate/upgrader/2.17.js.map +1 -0
- package/out/automate/upgrader/2.18.d.ts +10 -0
- package/out/automate/upgrader/2.18.js +107 -0
- package/out/automate/upgrader/2.18.js.map +1 -0
- package/out/automate/upgrader/2.20.d.ts +17 -0
- package/out/automate/upgrader/2.20.js +68 -0
- package/out/automate/upgrader/2.20.js.map +1 -0
- package/out/bak/translator.d.ts +1 -0
- package/out/bak/translator.js +305 -0
- package/out/bak/translator.js.map +1 -0
- package/out/breakpoint/generator/AfterStartNode.d.ts +7 -0
- package/out/breakpoint/generator/AfterStartNode.js +30 -0
- package/out/breakpoint/generator/AfterStartNode.js.map +1 -0
- package/out/breakpoint/generator/BeforeEndNode.d.ts +7 -0
- package/out/breakpoint/generator/BeforeEndNode.js +28 -0
- package/out/breakpoint/generator/BeforeEndNode.js.map +1 -0
- package/out/breakpoint/generator/BreakpointNode.d.ts +18 -0
- package/out/breakpoint/generator/BreakpointNode.js +293 -0
- package/out/breakpoint/generator/BreakpointNode.js.map +1 -0
- package/out/breakpoint/generator/CallbackNode.d.ts +4 -0
- package/out/breakpoint/generator/CallbackNode.js +37 -0
- package/out/breakpoint/generator/CallbackNode.js.map +1 -0
- package/out/breakpoint/generator/FragmentNode.d.ts +4 -0
- package/out/breakpoint/generator/FragmentNode.js +18 -0
- package/out/breakpoint/generator/FragmentNode.js.map +1 -0
- package/out/breakpoint/generator/index.d.ts +4 -0
- package/out/breakpoint/generator/index.js +119 -0
- package/out/breakpoint/generator/index.js.map +1 -0
- package/out/breakpoint/index.d.ts +3 -0
- package/out/breakpoint/index.js +20 -0
- package/out/breakpoint/index.js.map +1 -0
- package/out/breakpoint/shared/constants.d.ts +37 -0
- package/out/breakpoint/shared/constants.js +108 -0
- package/out/breakpoint/shared/constants.js.map +1 -0
- package/out/breakpoint/shared/index.d.ts +3 -0
- package/out/breakpoint/shared/index.js +33 -0
- package/out/breakpoint/shared/index.js.map +1 -0
- package/out/breakpoint/shared/operations.d.ts +10 -0
- package/out/breakpoint/shared/operations.js +25 -0
- package/out/breakpoint/shared/operations.js.map +1 -0
- package/out/breakpoint/shared/socket.d.ts +48 -0
- package/out/breakpoint/shared/socket.js +257 -0
- package/out/breakpoint/shared/socket.js.map +1 -0
- package/out/breakpoint/shared/utils.d.ts +27 -0
- package/out/breakpoint/shared/utils.js +217 -0
- package/out/breakpoint/shared/utils.js.map +1 -0
- package/out/breakpoint/store/core.d.ts +80 -0
- package/out/breakpoint/store/core.js +416 -0
- package/out/breakpoint/store/core.js.map +1 -0
- package/out/breakpoint/store/dock.d.ts +1 -0
- package/out/breakpoint/store/dock.js +160 -0
- package/out/breakpoint/store/dock.js.map +1 -0
- package/out/breakpoint/store/index.d.ts +2 -0
- package/out/breakpoint/store/index.js +19 -0
- package/out/breakpoint/store/index.js.map +1 -0
- package/out/common/BaseNode.d.ts +377 -0
- package/out/common/BaseNode.js +1432 -0
- package/out/common/BaseNode.js.map +1 -0
- package/out/common/Command.d.ts +21 -0
- package/out/common/Command.js +79 -0
- package/out/common/Command.js.map +1 -0
- package/out/common/ComponentAPI.d.ts +112 -0
- package/out/common/ComponentAPI.js +3 -0
- package/out/common/ComponentAPI.js.map +1 -0
- package/out/common/EventEmitter.d.ts +61 -0
- package/out/common/EventEmitter.js +71 -0
- package/out/common/EventEmitter.js.map +1 -0
- package/out/common/Messager.d.ts +91 -0
- package/out/common/Messager.js +205 -0
- package/out/common/Messager.js.map +1 -0
- package/out/common/asyncFuncMap.d.ts +2 -0
- package/out/common/asyncFuncMap.js +16 -0
- package/out/common/asyncFuncMap.js.map +1 -0
- package/out/common/index.d.ts +4 -0
- package/out/common/index.js +21 -0
- package/out/common/index.js.map +1 -0
- package/out/common/utils.d.ts +2 -0
- package/out/common/utils.js +18 -0
- package/out/common/utils.js.map +1 -0
- package/out/concepts/Abort__.d.ts +28 -0
- package/out/concepts/Abort__.js +80 -0
- package/out/concepts/Abort__.js.map +1 -0
- package/out/concepts/AbstractInterface__.d.ts +22 -0
- package/out/concepts/AbstractInterface__.js +56 -0
- package/out/concepts/AbstractInterface__.js.map +1 -0
- package/out/concepts/Anchor__.d.ts +48 -0
- package/out/concepts/Anchor__.js +200 -0
- package/out/concepts/Anchor__.js.map +1 -0
- package/out/concepts/AnonymousFunction__.d.ts +180 -0
- package/out/concepts/AnonymousFunction__.js +555 -0
- package/out/concepts/AnonymousFunction__.js.map +1 -0
- package/out/concepts/App__.d.ts +1818 -0
- package/out/concepts/App__.js +2983 -0
- package/out/concepts/App__.js.map +1 -0
- package/out/concepts/Argument__.d.ts +70 -0
- package/out/concepts/Argument__.js +270 -0
- package/out/concepts/Argument__.js.map +1 -0
- package/out/concepts/Assignee__.d.ts +291 -0
- package/out/concepts/Assignee__.js +461 -0
- package/out/concepts/Assignee__.js.map +1 -0
- package/out/concepts/AssignmentLine__.d.ts +44 -0
- package/out/concepts/AssignmentLine__.js +114 -0
- package/out/concepts/AssignmentLine__.js.map +1 -0
- package/out/concepts/Assignment__.d.ts +77 -0
- package/out/concepts/Assignment__.js +338 -0
- package/out/concepts/Assignment__.js.map +1 -0
- package/out/concepts/Attribute__.d.ts +112 -0
- package/out/concepts/Attribute__.js +208 -0
- package/out/concepts/Attribute__.js.map +1 -0
- package/out/concepts/AuthInterface__.d.ts +38 -0
- package/out/concepts/AuthInterface__.js +74 -0
- package/out/concepts/AuthInterface__.js.map +1 -0
- package/out/concepts/AuthLogicForCallInterface__.d.ts +141 -0
- package/out/concepts/AuthLogicForCallInterface__.js +514 -0
- package/out/concepts/AuthLogicForCallInterface__.js.map +1 -0
- package/out/concepts/AuthLogic__.d.ts +69 -0
- package/out/concepts/AuthLogic__.js +210 -0
- package/out/concepts/AuthLogic__.js.map +1 -0
- package/out/concepts/BackendVariable__.d.ts +145 -0
- package/out/concepts/BackendVariable__.js +502 -0
- package/out/concepts/BackendVariable__.js.map +1 -0
- package/out/concepts/Backend__.d.ts +134 -0
- package/out/concepts/Backend__.js +280 -0
- package/out/concepts/Backend__.js.map +1 -0
- package/out/concepts/BatchAssignment__.d.ts +255 -0
- package/out/concepts/BatchAssignment__.js +881 -0
- package/out/concepts/BatchAssignment__.js.map +1 -0
- package/out/concepts/BinaryExpression__.d.ts +76 -0
- package/out/concepts/BinaryExpression__.js +422 -0
- package/out/concepts/BinaryExpression__.js.map +1 -0
- package/out/concepts/BindAttribute__.d.ts +329 -0
- package/out/concepts/BindAttribute__.js +1130 -0
- package/out/concepts/BindAttribute__.js.map +1 -0
- package/out/concepts/BindDirective__.d.ts +170 -0
- package/out/concepts/BindDirective__.js +573 -0
- package/out/concepts/BindDirective__.js.map +1 -0
- package/out/concepts/BindEvent__.d.ts +254 -0
- package/out/concepts/BindEvent__.js +959 -0
- package/out/concepts/BindEvent__.js.map +1 -0
- package/out/concepts/BindStyle__.d.ts +142 -0
- package/out/concepts/BindStyle__.js +453 -0
- package/out/concepts/BindStyle__.js.map +1 -0
- package/out/concepts/Block__.d.ts +84 -0
- package/out/concepts/Block__.js +215 -0
- package/out/concepts/Block__.js.map +1 -0
- package/out/concepts/BooleanLiteral__.d.ts +38 -0
- package/out/concepts/BooleanLiteral__.js +97 -0
- package/out/concepts/BooleanLiteral__.js.map +1 -0
- package/out/concepts/BusinessComponent__.d.ts +641 -0
- package/out/concepts/BusinessComponent__.js +1944 -0
- package/out/concepts/BusinessComponent__.js.map +1 -0
- package/out/concepts/BusinessLogic__.d.ts +38 -0
- package/out/concepts/BusinessLogic__.js +358 -0
- package/out/concepts/BusinessLogic__.js.map +1 -0
- package/out/concepts/CallAuthInterface__.d.ts +130 -0
- package/out/concepts/CallAuthInterface__.js +438 -0
- package/out/concepts/CallAuthInterface__.js.map +1 -0
- package/out/concepts/CallConnector__.d.ts +49 -0
- package/out/concepts/CallConnector__.js +257 -0
- package/out/concepts/CallConnector__.js.map +1 -0
- package/out/concepts/CallEvent__.d.ts +101 -0
- package/out/concepts/CallEvent__.js +280 -0
- package/out/concepts/CallEvent__.js.map +1 -0
- package/out/concepts/CallFunction__.d.ts +162 -0
- package/out/concepts/CallFunction__.js +600 -0
- package/out/concepts/CallFunction__.js.map +1 -0
- package/out/concepts/CallInterface__.d.ts +136 -0
- package/out/concepts/CallInterface__.js +814 -0
- package/out/concepts/CallInterface__.js.map +1 -0
- package/out/concepts/CallLogic__.d.ts +235 -0
- package/out/concepts/CallLogic__.js +1361 -0
- package/out/concepts/CallLogic__.js.map +1 -0
- package/out/concepts/CallQueryComponent__.d.ts +435 -0
- package/out/concepts/CallQueryComponent__.js +1235 -0
- package/out/concepts/CallQueryComponent__.js.map +1 -0
- package/out/concepts/Comment__.d.ts +35 -0
- package/out/concepts/Comment__.js +94 -0
- package/out/concepts/Comment__.js.map +1 -0
- package/out/concepts/CompletionProperty__.d.ts +107 -0
- package/out/concepts/CompletionProperty__.js +239 -0
- package/out/concepts/CompletionProperty__.js.map +1 -0
- package/out/concepts/ConfigGroup__.d.ts +127 -0
- package/out/concepts/ConfigGroup__.js +258 -0
- package/out/concepts/ConfigGroup__.js.map +1 -0
- package/out/concepts/ConfigPropertyValue__.d.ts +47 -0
- package/out/concepts/ConfigPropertyValue__.js +93 -0
- package/out/concepts/ConfigPropertyValue__.js.map +1 -0
- package/out/concepts/ConfigProperty__.d.ts +153 -0
- package/out/concepts/ConfigProperty__.js +321 -0
- package/out/concepts/ConfigProperty__.js.map +1 -0
- package/out/concepts/Configuration__.d.ts +126 -0
- package/out/concepts/Configuration__.js +236 -0
- package/out/concepts/Configuration__.js.map +1 -0
- package/out/concepts/Connection__.d.ts +165 -0
- package/out/concepts/Connection__.js +330 -0
- package/out/concepts/Connection__.js.map +1 -0
- package/out/concepts/ConnectorTrigger__.d.ts +81 -0
- package/out/concepts/ConnectorTrigger__.js +138 -0
- package/out/concepts/ConnectorTrigger__.js.map +1 -0
- package/out/concepts/Connector__.d.ts +929 -0
- package/out/concepts/Connector__.js +1343 -0
- package/out/concepts/Connector__.js.map +1 -0
- package/out/concepts/Constant__.d.ts +121 -0
- package/out/concepts/Constant__.js +331 -0
- package/out/concepts/Constant__.js.map +1 -0
- package/out/concepts/CountersignPolicy__.d.ts +28 -0
- package/out/concepts/CountersignPolicy__.js +62 -0
- package/out/concepts/CountersignPolicy__.js.map +1 -0
- package/out/concepts/DataSource__.d.ts +168 -0
- package/out/concepts/DataSource__.js +460 -0
- package/out/concepts/DataSource__.js.map +1 -0
- package/out/concepts/DatabaseTypeAnnotation__.d.ts +34 -0
- package/out/concepts/DatabaseTypeAnnotation__.js +65 -0
- package/out/concepts/DatabaseTypeAnnotation__.js.map +1 -0
- package/out/concepts/DefaultValue__.d.ts +104 -0
- package/out/concepts/DefaultValue__.js +242 -0
- package/out/concepts/DefaultValue__.js.map +1 -0
- package/out/concepts/Destination__.d.ts +160 -0
- package/out/concepts/Destination__.js +799 -0
- package/out/concepts/Destination__.js.map +1 -0
- package/out/concepts/End__.d.ts +27 -0
- package/out/concepts/End__.js +115 -0
- package/out/concepts/End__.js.map +1 -0
- package/out/concepts/EntityIndex__.d.ts +98 -0
- package/out/concepts/EntityIndex__.js +201 -0
- package/out/concepts/EntityIndex__.js.map +1 -0
- package/out/concepts/EntityProperty__.d.ts +293 -0
- package/out/concepts/EntityProperty__.js +824 -0
- package/out/concepts/EntityProperty__.js.map +1 -0
- package/out/concepts/Entity__.d.ts +339 -0
- package/out/concepts/Entity__.js +764 -0
- package/out/concepts/Entity__.js.map +1 -0
- package/out/concepts/EnumItem__.d.ts +67 -0
- package/out/concepts/EnumItem__.js +131 -0
- package/out/concepts/EnumItem__.js.map +1 -0
- package/out/concepts/Enum__.d.ts +138 -0
- package/out/concepts/Enum__.js +321 -0
- package/out/concepts/Enum__.js.map +1 -0
- package/out/concepts/Event__.d.ts +160 -0
- package/out/concepts/Event__.js +294 -0
- package/out/concepts/Event__.js.map +1 -0
- package/out/concepts/ExternalDestination__.d.ts +78 -0
- package/out/concepts/ExternalDestination__.js +309 -0
- package/out/concepts/ExternalDestination__.js.map +1 -0
- package/out/concepts/ForEachStatement__.d.ts +173 -0
- package/out/concepts/ForEachStatement__.js +497 -0
- package/out/concepts/ForEachStatement__.js.map +1 -0
- package/out/concepts/FrontendLibrary__.d.ts +216 -0
- package/out/concepts/FrontendLibrary__.js +364 -0
- package/out/concepts/FrontendLibrary__.js.map +1 -0
- package/out/concepts/FrontendType__.d.ts +308 -0
- package/out/concepts/FrontendType__.js +606 -0
- package/out/concepts/FrontendType__.js.map +1 -0
- package/out/concepts/FrontendVariable__.d.ts +36 -0
- package/out/concepts/FrontendVariable__.js +77 -0
- package/out/concepts/FrontendVariable__.js.map +1 -0
- package/out/concepts/Frontend__.d.ts +420 -0
- package/out/concepts/Frontend__.js +915 -0
- package/out/concepts/Frontend__.js.map +1 -0
- package/out/concepts/Function__.d.ts +420 -0
- package/out/concepts/Function__.js +805 -0
- package/out/concepts/Function__.js.map +1 -0
- package/out/concepts/I18nInfo__.d.ts +46 -0
- package/out/concepts/I18nInfo__.js +90 -0
- package/out/concepts/I18nInfo__.js.map +1 -0
- package/out/concepts/Identifier__.d.ts +59 -0
- package/out/concepts/Identifier__.js +326 -0
- package/out/concepts/Identifier__.js.map +1 -0
- package/out/concepts/IfStatement__.d.ts +161 -0
- package/out/concepts/IfStatement__.js +372 -0
- package/out/concepts/IfStatement__.js.map +1 -0
- package/out/concepts/ImportedInterface__.d.ts +20 -0
- package/out/concepts/ImportedInterface__.js +48 -0
- package/out/concepts/ImportedInterface__.js.map +1 -0
- package/out/concepts/Integration__.d.ts +146 -0
- package/out/concepts/Integration__.js +296 -0
- package/out/concepts/Integration__.js.map +1 -0
- package/out/concepts/InterfaceParam__.d.ts +146 -0
- package/out/concepts/InterfaceParam__.js +342 -0
- package/out/concepts/InterfaceParam__.js.map +1 -0
- package/out/concepts/Interface__.d.ts +328 -0
- package/out/concepts/Interface__.js +892 -0
- package/out/concepts/Interface__.js.map +1 -0
- package/out/concepts/JSBlock__.d.ts +37 -0
- package/out/concepts/JSBlock__.js +104 -0
- package/out/concepts/JSBlock__.js.map +1 -0
- package/out/concepts/JavaLogic__.d.ts +45 -0
- package/out/concepts/JavaLogic__.js +109 -0
- package/out/concepts/JavaLogic__.js.map +1 -0
- package/out/concepts/LogicItem__.d.ts +155 -0
- package/out/concepts/LogicItem__.js +284 -0
- package/out/concepts/LogicItem__.js.map +1 -0
- package/out/concepts/Logic__.d.ts +649 -0
- package/out/concepts/Logic__.js +1939 -0
- package/out/concepts/Logic__.js.map +1 -0
- package/out/concepts/MatchCase__.d.ts +261 -0
- package/out/concepts/MatchCase__.js +706 -0
- package/out/concepts/MatchCase__.js.map +1 -0
- package/out/concepts/Match__.d.ts +127 -0
- package/out/concepts/Match__.js +731 -0
- package/out/concepts/Match__.js.map +1 -0
- package/out/concepts/MemberExpression__.d.ts +80 -0
- package/out/concepts/MemberExpression__.js +529 -0
- package/out/concepts/MemberExpression__.js.map +1 -0
- package/out/concepts/MetadataType__.d.ts +236 -0
- package/out/concepts/MetadataType__.js +464 -0
- package/out/concepts/MetadataType__.js.map +1 -0
- package/out/concepts/MicroApp__.d.ts +54 -0
- package/out/concepts/MicroApp__.js +80 -0
- package/out/concepts/MicroApp__.js.map +1 -0
- package/out/concepts/Module__.d.ts +1171 -0
- package/out/concepts/Module__.js +1747 -0
- package/out/concepts/Module__.js.map +1 -0
- package/out/concepts/MsgTriggerEvent__.d.ts +140 -0
- package/out/concepts/MsgTriggerEvent__.js +236 -0
- package/out/concepts/MsgTriggerEvent__.js.map +1 -0
- package/out/concepts/MsgTriggerLauncher__.d.ts +129 -0
- package/out/concepts/MsgTriggerLauncher__.js +226 -0
- package/out/concepts/MsgTriggerLauncher__.js.map +1 -0
- package/out/concepts/MultiApprovalPolicy__.d.ts +26 -0
- package/out/concepts/MultiApprovalPolicy__.js +59 -0
- package/out/concepts/MultiApprovalPolicy__.js.map +1 -0
- package/out/concepts/Namespace__.d.ts +1086 -0
- package/out/concepts/Namespace__.js +1555 -0
- package/out/concepts/Namespace__.js.map +1 -0
- package/out/concepts/NewComposite__.d.ts +353 -0
- package/out/concepts/NewComposite__.js +1277 -0
- package/out/concepts/NewComposite__.js.map +1 -0
- package/out/concepts/NewList__.d.ts +141 -0
- package/out/concepts/NewList__.js +470 -0
- package/out/concepts/NewList__.js.map +1 -0
- package/out/concepts/NewMap__.d.ts +231 -0
- package/out/concepts/NewMap__.js +604 -0
- package/out/concepts/NewMap__.js.map +1 -0
- package/out/concepts/New__.d.ts +23 -0
- package/out/concepts/New__.js +65 -0
- package/out/concepts/New__.js.map +1 -0
- package/out/concepts/NullLiteral__.d.ts +29 -0
- package/out/concepts/NullLiteral__.js +77 -0
- package/out/concepts/NullLiteral__.js.map +1 -0
- package/out/concepts/NumericLiteral__.d.ts +59 -0
- package/out/concepts/NumericLiteral__.js +177 -0
- package/out/concepts/NumericLiteral__.js.map +1 -0
- package/out/concepts/OqlQueryComponent__.d.ts +76 -0
- package/out/concepts/OqlQueryComponent__.js +351 -0
- package/out/concepts/OqlQueryComponent__.js.map +1 -0
- package/out/concepts/OverriddenLogic__.d.ts +634 -0
- package/out/concepts/OverriddenLogic__.js +1661 -0
- package/out/concepts/OverriddenLogic__.js.map +1 -0
- package/out/concepts/Paginate__.d.ts +97 -0
- package/out/concepts/Paginate__.js +267 -0
- package/out/concepts/Paginate__.js.map +1 -0
- package/out/concepts/ParamWithGroup__.d.ts +39 -0
- package/out/concepts/ParamWithGroup__.js +85 -0
- package/out/concepts/ParamWithGroup__.js.map +1 -0
- package/out/concepts/Param__.d.ts +182 -0
- package/out/concepts/Param__.js +524 -0
- package/out/concepts/Param__.js.map +1 -0
- package/out/concepts/Point__.d.ts +34 -0
- package/out/concepts/Point__.js +65 -0
- package/out/concepts/Point__.js.map +1 -0
- package/out/concepts/ProcessComponent__.d.ts +222 -0
- package/out/concepts/ProcessComponent__.js +340 -0
- package/out/concepts/ProcessComponent__.js.map +1 -0
- package/out/concepts/ProcessElement__.d.ts +665 -0
- package/out/concepts/ProcessElement__.js +1354 -0
- package/out/concepts/ProcessElement__.js.map +1 -0
- package/out/concepts/ProcessOutcome__.d.ts +34 -0
- package/out/concepts/ProcessOutcome__.js +97 -0
- package/out/concepts/ProcessOutcome__.js.map +1 -0
- package/out/concepts/ProcessOutcomes__.d.ts +34 -0
- package/out/concepts/ProcessOutcomes__.js +104 -0
- package/out/concepts/ProcessOutcomes__.js.map +1 -0
- package/out/concepts/Process__.d.ts +615 -0
- package/out/concepts/Process__.js +1117 -0
- package/out/concepts/Process__.js.map +1 -0
- package/out/concepts/QueryAggregateExpression__.d.ts +54 -0
- package/out/concepts/QueryAggregateExpression__.js +140 -0
- package/out/concepts/QueryAggregateExpression__.js.map +1 -0
- package/out/concepts/QueryFieldExpression__.d.ts +56 -0
- package/out/concepts/QueryFieldExpression__.js +142 -0
- package/out/concepts/QueryFieldExpression__.js.map +1 -0
- package/out/concepts/QueryFromExpression__.d.ts +101 -0
- package/out/concepts/QueryFromExpression__.js +227 -0
- package/out/concepts/QueryFromExpression__.js.map +1 -0
- package/out/concepts/QueryGroupByExpression__.d.ts +50 -0
- package/out/concepts/QueryGroupByExpression__.js +142 -0
- package/out/concepts/QueryGroupByExpression__.js.map +1 -0
- package/out/concepts/QueryJoinExpression__.d.ts +188 -0
- package/out/concepts/QueryJoinExpression__.js +327 -0
- package/out/concepts/QueryJoinExpression__.js.map +1 -0
- package/out/concepts/QueryLimitExpression__.d.ts +60 -0
- package/out/concepts/QueryLimitExpression__.js +159 -0
- package/out/concepts/QueryLimitExpression__.js.map +1 -0
- package/out/concepts/QueryOrderByExpression__.d.ts +71 -0
- package/out/concepts/QueryOrderByExpression__.js +172 -0
- package/out/concepts/QueryOrderByExpression__.js.map +1 -0
- package/out/concepts/QuerySelectExpression__.d.ts +206 -0
- package/out/concepts/QuerySelectExpression__.js +308 -0
- package/out/concepts/QuerySelectExpression__.js.map +1 -0
- package/out/concepts/Rect__.d.ts +42 -0
- package/out/concepts/Rect__.js +71 -0
- package/out/concepts/Rect__.js.map +1 -0
- package/out/concepts/Return__.d.ts +147 -0
- package/out/concepts/Return__.js +429 -0
- package/out/concepts/Return__.js.map +1 -0
- package/out/concepts/Role__.d.ts +62 -0
- package/out/concepts/Role__.js +151 -0
- package/out/concepts/Role__.js.map +1 -0
- package/out/concepts/SelectMembers__.d.ts +145 -0
- package/out/concepts/SelectMembers__.js +300 -0
- package/out/concepts/SelectMembers__.js.map +1 -0
- package/out/concepts/SequentialPolicy__.d.ts +20 -0
- package/out/concepts/SequentialPolicy__.js +48 -0
- package/out/concepts/SequentialPolicy__.js.map +1 -0
- package/out/concepts/Slot__.d.ts +77 -0
- package/out/concepts/Slot__.js +141 -0
- package/out/concepts/Slot__.js.map +1 -0
- package/out/concepts/SqlQueryComponent__.d.ts +74 -0
- package/out/concepts/SqlQueryComponent__.js +269 -0
- package/out/concepts/SqlQueryComponent__.js.map +1 -0
- package/out/concepts/Start__.d.ts +27 -0
- package/out/concepts/Start__.js +69 -0
- package/out/concepts/Start__.js.map +1 -0
- package/out/concepts/StaticString__.d.ts +49 -0
- package/out/concepts/StaticString__.js +91 -0
- package/out/concepts/StaticString__.js.map +1 -0
- package/out/concepts/StringInterpolation__.d.ts +118 -0
- package/out/concepts/StringInterpolation__.js +284 -0
- package/out/concepts/StringInterpolation__.js.map +1 -0
- package/out/concepts/StringLiteral__.d.ts +45 -0
- package/out/concepts/StringLiteral__.js +159 -0
- package/out/concepts/StringLiteral__.js.map +1 -0
- package/out/concepts/StructureProperty__.d.ts +154 -0
- package/out/concepts/StructureProperty__.js +338 -0
- package/out/concepts/StructureProperty__.js.map +1 -0
- package/out/concepts/Structure__.d.ts +250 -0
- package/out/concepts/Structure__.js +508 -0
- package/out/concepts/Structure__.js.map +1 -0
- package/out/concepts/SwitchCase__.d.ts +97 -0
- package/out/concepts/SwitchCase__.js +305 -0
- package/out/concepts/SwitchCase__.js.map +1 -0
- package/out/concepts/SwitchStatement__.d.ts +87 -0
- package/out/concepts/SwitchStatement__.js +234 -0
- package/out/concepts/SwitchStatement__.js.map +1 -0
- package/out/concepts/Theme__.d.ts +40 -0
- package/out/concepts/Theme__.js +84 -0
- package/out/concepts/Theme__.js.map +1 -0
- package/out/concepts/Transactional__.d.ts +90 -0
- package/out/concepts/Transactional__.js +149 -0
- package/out/concepts/Transactional__.js.map +1 -0
- package/out/concepts/TriggerEvent__.d.ts +54 -0
- package/out/concepts/TriggerEvent__.js +137 -0
- package/out/concepts/TriggerEvent__.js.map +1 -0
- package/out/concepts/TriggerLauncher__.d.ts +81 -0
- package/out/concepts/TriggerLauncher__.js +197 -0
- package/out/concepts/TriggerLauncher__.js.map +1 -0
- package/out/concepts/TypeAnnotation__.d.ts +305 -0
- package/out/concepts/TypeAnnotation__.js +1095 -0
- package/out/concepts/TypeAnnotation__.js.map +1 -0
- package/out/concepts/TypeParam__.d.ts +28 -0
- package/out/concepts/TypeParam__.js +71 -0
- package/out/concepts/TypeParam__.js.map +1 -0
- package/out/concepts/UnaryExpression__.d.ts +52 -0
- package/out/concepts/UnaryExpression__.js +191 -0
- package/out/concepts/UnaryExpression__.js.map +1 -0
- package/out/concepts/Unparsed__.d.ts +36 -0
- package/out/concepts/Unparsed__.js +91 -0
- package/out/concepts/Unparsed__.js.map +1 -0
- package/out/concepts/UseComponent__.d.ts +34 -0
- package/out/concepts/UseComponent__.js +65 -0
- package/out/concepts/UseComponent__.js.map +1 -0
- package/out/concepts/ValidationRule__.d.ts +152 -0
- package/out/concepts/ValidationRule__.js +535 -0
- package/out/concepts/ValidationRule__.js.map +1 -0
- package/out/concepts/Variable__.d.ts +164 -0
- package/out/concepts/Variable__.js +505 -0
- package/out/concepts/Variable__.js.map +1 -0
- package/out/concepts/ViewBlock__.d.ts +38 -0
- package/out/concepts/ViewBlock__.js +68 -0
- package/out/concepts/ViewBlock__.js.map +1 -0
- package/out/concepts/ViewComponent__.d.ts +568 -0
- package/out/concepts/ViewComponent__.js +809 -0
- package/out/concepts/ViewComponent__.js.map +1 -0
- package/out/concepts/ViewElement__.d.ts +656 -0
- package/out/concepts/ViewElement__.js +2727 -0
- package/out/concepts/ViewElement__.js.map +1 -0
- package/out/concepts/View__.d.ts +747 -0
- package/out/concepts/View__.js +2633 -0
- package/out/concepts/View__.js.map +1 -0
- package/out/concepts/WhileStatement__.d.ts +100 -0
- package/out/concepts/WhileStatement__.js +269 -0
- package/out/concepts/WhileStatement__.js.map +1 -0
- package/out/concepts/basics/constants.d.ts +1 -0
- package/out/concepts/basics/constants.js +6 -0
- package/out/concepts/basics/constants.js.map +1 -0
- package/out/concepts/basics/stdlib/index.d.ts +16 -0
- package/out/concepts/basics/stdlib/index.js +90 -0
- package/out/concepts/basics/stdlib/index.js.map +1 -0
- package/out/concepts/basics/stdlib/nasl.auth.d.ts +9 -0
- package/out/concepts/basics/stdlib/nasl.auth.js +206 -0
- package/out/concepts/basics/stdlib/nasl.auth.js.map +1 -0
- package/out/concepts/basics/stdlib/nasl.browser.d.ts +5 -0
- package/out/concepts/basics/stdlib/nasl.browser.js +158 -0
- package/out/concepts/basics/stdlib/nasl.browser.js.map +1 -0
- package/out/concepts/basics/stdlib/nasl.collection.d.ts +9 -0
- package/out/concepts/basics/stdlib/nasl.collection.js +57 -0
- package/out/concepts/basics/stdlib/nasl.collection.js.map +1 -0
- package/out/concepts/basics/stdlib/nasl.configuration.d.ts +5 -0
- package/out/concepts/basics/stdlib/nasl.configuration.js +65 -0
- package/out/concepts/basics/stdlib/nasl.configuration.js.map +1 -0
- package/out/concepts/basics/stdlib/nasl.core.d.ts +7 -0
- package/out/concepts/basics/stdlib/nasl.core.js +47 -0
- package/out/concepts/basics/stdlib/nasl.core.js.map +1 -0
- package/out/concepts/basics/stdlib/nasl.event.d.ts +5 -0
- package/out/concepts/basics/stdlib/nasl.event.js +34 -0
- package/out/concepts/basics/stdlib/nasl.event.js.map +1 -0
- package/out/concepts/basics/stdlib/nasl.http.d.ts +9 -0
- package/out/concepts/basics/stdlib/nasl.http.js +174 -0
- package/out/concepts/basics/stdlib/nasl.http.js.map +1 -0
- package/out/concepts/basics/stdlib/nasl.interface.d.ts +9 -0
- package/out/concepts/basics/stdlib/nasl.interface.js +49 -0
- package/out/concepts/basics/stdlib/nasl.interface.js.map +1 -0
- package/out/concepts/basics/stdlib/nasl.io.d.ts +5 -0
- package/out/concepts/basics/stdlib/nasl.io.js +61 -0
- package/out/concepts/basics/stdlib/nasl.io.js.map +1 -0
- package/out/concepts/basics/stdlib/nasl.logging.d.ts +5 -0
- package/out/concepts/basics/stdlib/nasl.logging.js +65 -0
- package/out/concepts/basics/stdlib/nasl.logging.js.map +1 -0
- package/out/concepts/basics/stdlib/nasl.process.d.ts +9 -0
- package/out/concepts/basics/stdlib/nasl.process.js +643 -0
- package/out/concepts/basics/stdlib/nasl.process.js.map +1 -0
- package/out/concepts/basics/stdlib/nasl.ui.d.ts +9 -0
- package/out/concepts/basics/stdlib/nasl.ui.js +1038 -0
- package/out/concepts/basics/stdlib/nasl.ui.js.map +1 -0
- package/out/concepts/basics/stdlib/nasl.util.d.ts +6 -0
- package/out/concepts/basics/stdlib/nasl.util.js +2285 -0
- package/out/concepts/basics/stdlib/nasl.util.js.map +1 -0
- package/out/concepts/basics/stdlib/nasl.validation.d.ts +5 -0
- package/out/concepts/basics/stdlib/nasl.validation.js +574 -0
- package/out/concepts/basics/stdlib/nasl.validation.js.map +1 -0
- package/out/concepts/basics/stdlib/reference2TypeAnnotationList.d.ts +4 -0
- package/out/concepts/basics/stdlib/reference2TypeAnnotationList.js +47 -0
- package/out/concepts/basics/stdlib/reference2TypeAnnotationList.js.map +1 -0
- package/out/concepts/basics/stdlib/timeZone.d.ts +5 -0
- package/out/concepts/basics/stdlib/timeZone.js +196 -0
- package/out/concepts/basics/stdlib/timeZone.js.map +1 -0
- package/out/concepts/basics/types/coreTypeList.d.ts +2 -0
- package/out/concepts/basics/types/coreTypeList.js +15 -0
- package/out/concepts/basics/types/coreTypeList.js.map +1 -0
- package/out/concepts/basics/types/index.d.ts +16 -0
- package/out/concepts/basics/types/index.js +35 -0
- package/out/concepts/basics/types/index.js.map +1 -0
- package/out/concepts/index.d.ts +7 -0
- package/out/concepts/index.js +41 -0
- package/out/concepts/index.js.map +1 -0
- package/out/concepts/index__.d.ts +138 -0
- package/out/concepts/index__.js +155 -0
- package/out/concepts/index__.js.map +1 -0
- package/out/concepts/types__.d.ts +0 -0
- package/out/concepts/types__.js +1 -0
- package/out/concepts/types__.js.map +1 -0
- package/out/concepts/utils/asserts.d.ts +6982 -0
- package/out/concepts/utils/asserts.js +9276 -0
- package/out/concepts/utils/asserts.js.map +1 -0
- package/out/concepts/utils/quick-info.d.ts +13 -0
- package/out/concepts/utils/quick-info.js +51 -0
- package/out/concepts/utils/quick-info.js.map +1 -0
- package/out/concepts/utils/types.d.ts +450 -0
- package/out/concepts/utils/types.js +3 -0
- package/out/concepts/utils/types.js.map +1 -0
- package/out/config.d.ts +43 -0
- package/out/config.js +72 -0
- package/out/config.js.map +1 -0
- package/out/decorators/index.d.ts +67 -0
- package/out/decorators/index.js +213 -0
- package/out/decorators/index.js.map +1 -0
- package/out/decorators/promise.d.ts +7 -0
- package/out/decorators/promise.js +28 -0
- package/out/decorators/promise.js.map +1 -0
- package/out/enums/KEYWORDS.d.ts +6 -0
- package/out/enums/KEYWORDS.js +1248 -0
- package/out/enums/KEYWORDS.js.map +1 -0
- package/out/enums/LEVEL_NAME_MAP.d.ts +26 -0
- package/out/enums/LEVEL_NAME_MAP.js +30 -0
- package/out/enums/LEVEL_NAME_MAP.js.map +1 -0
- package/out/eventBus.d.ts +3 -0
- package/out/eventBus.js +7 -0
- package/out/eventBus.js.map +1 -0
- package/out/generator/compileComponent.d.ts +11 -0
- package/out/generator/compileComponent.js +12 -0
- package/out/generator/compileComponent.js.map +1 -0
- package/out/generator/genBundleFiles.d.ts +37 -0
- package/out/generator/genBundleFiles.js +678 -0
- package/out/generator/genBundleFiles.js.map +1 -0
- package/out/generator/genHash.d.ts +7 -0
- package/out/generator/genHash.js +39 -0
- package/out/generator/genHash.js.map +1 -0
- package/out/generator/genMetaData.d.ts +31 -0
- package/out/generator/genMetaData.js +365 -0
- package/out/generator/genMetaData.js.map +1 -0
- package/out/generator/genReleaseBody.d.ts +72 -0
- package/out/generator/genReleaseBody.js +333 -0
- package/out/generator/genReleaseBody.js.map +1 -0
- package/out/generator/icestark.d.ts +2 -0
- package/out/generator/icestark.js +50 -0
- package/out/generator/icestark.js.map +1 -0
- package/out/generator/index.d.ts +7 -0
- package/out/generator/index.js +24 -0
- package/out/generator/index.js.map +1 -0
- package/out/generator/microApp.d.ts +2 -0
- package/out/generator/microApp.js +36 -0
- package/out/generator/microApp.js.map +1 -0
- package/out/generator/permission.d.ts +14 -0
- package/out/generator/permission.js +296 -0
- package/out/generator/permission.js.map +1 -0
- package/out/generator/qiankun.d.ts +2 -0
- package/out/generator/qiankun.js +54 -0
- package/out/generator/qiankun.js.map +1 -0
- package/out/generator/styleReplacer.d.ts +3 -0
- package/out/generator/styleReplacer.js +68 -0
- package/out/generator/styleReplacer.js.map +1 -0
- package/out/index.d.ts +13 -0
- package/out/index.js +67 -0
- package/out/index.js.map +1 -0
- package/out/manager/diagnostic.d.ts +35 -0
- package/out/manager/diagnostic.js +64 -0
- package/out/manager/diagnostic.js.map +1 -0
- package/out/manager/stepRecorder.d.ts +20 -0
- package/out/manager/stepRecorder.js +114 -0
- package/out/manager/stepRecorder.js.map +1 -0
- package/out/natural/componentData.d.ts +31 -0
- package/out/natural/componentData.js +85 -0
- package/out/natural/componentData.js.map +1 -0
- package/out/natural/genNaturalTS.d.ts +3 -0
- package/out/natural/genNaturalTS.js +87 -0
- package/out/natural/genNaturalTS.js.map +1 -0
- package/out/natural/index.d.ts +4 -0
- package/out/natural/index.js +21 -0
- package/out/natural/index.js.map +1 -0
- package/out/natural/naslStdlibMap.d.ts +1 -0
- package/out/natural/naslStdlibMap.js +35 -0
- package/out/natural/naslStdlibMap.js.map +1 -0
- package/out/natural/prompt/analyzeClaims.d.ts +1 -0
- package/out/natural/prompt/analyzeClaims.js +21 -0
- package/out/natural/prompt/analyzeClaims.js.map +1 -0
- package/out/natural/prompt/executeClaims.d.ts +1 -0
- package/out/natural/prompt/executeClaims.js +73 -0
- package/out/natural/prompt/executeClaims.js.map +1 -0
- package/out/natural/transformTSCode.d.ts +7 -0
- package/out/natural/transformTSCode.js +931 -0
- package/out/natural/transformTSCode.js.map +1 -0
- package/out/sentry/index.d.ts +34 -0
- package/out/sentry/index.js +149 -0
- package/out/sentry/index.js.map +1 -0
- package/out/server/createUiTs.d.ts +17 -0
- package/out/server/createUiTs.js +268 -0
- package/out/server/createUiTs.js.map +1 -0
- package/out/server/entity2LogicNamespace.d.ts +10 -0
- package/out/server/entity2LogicNamespace.js +382 -0
- package/out/server/entity2LogicNamespace.js.map +1 -0
- package/out/server/event.d.ts +30 -0
- package/out/server/event.js +151 -0
- package/out/server/event.js.map +1 -0
- package/out/server/extendBaseNode.d.ts +1 -0
- package/out/server/extendBaseNode.js +605 -0
- package/out/server/extendBaseNode.js.map +1 -0
- package/out/server/formatTsUtils.d.ts +36 -0
- package/out/server/formatTsUtils.js +854 -0
- package/out/server/formatTsUtils.js.map +1 -0
- package/out/server/getConnector.d.ts +14 -0
- package/out/server/getConnector.js +101 -0
- package/out/server/getConnector.js.map +1 -0
- package/out/server/getExtensionModules.d.ts +3 -0
- package/out/server/getExtensionModules.js +34 -0
- package/out/server/getExtensionModules.js.map +1 -0
- package/out/server/getFunctions.d.ts +3 -0
- package/out/server/getFunctions.js +20 -0
- package/out/server/getFunctions.js.map +1 -0
- package/out/server/getInterfaces.d.ts +2 -0
- package/out/server/getInterfaces.js +48 -0
- package/out/server/getInterfaces.js.map +1 -0
- package/out/server/getLogging.d.ts +1 -0
- package/out/server/getLogging.js +9 -0
- package/out/server/getLogging.js.map +1 -0
- package/out/server/getLogics.d.ts +5 -0
- package/out/server/getLogics.js +454 -0
- package/out/server/getLogics.js.map +1 -0
- package/out/server/getMemberIdentifier.d.ts +17 -0
- package/out/server/getMemberIdentifier.js +594 -0
- package/out/server/getMemberIdentifier.js.map +1 -0
- package/out/server/getProcessComponents.d.ts +2 -0
- package/out/server/getProcessComponents.js +13 -0
- package/out/server/getProcessComponents.js.map +1 -0
- package/out/server/getProcesses.d.ts +33 -0
- package/out/server/getProcesses.js +647 -0
- package/out/server/getProcesses.js.map +1 -0
- package/out/server/getScope.d.ts +13 -0
- package/out/server/getScope.js +61 -0
- package/out/server/getScope.js.map +1 -0
- package/out/server/getValidates.d.ts +3 -0
- package/out/server/getValidates.js +14 -0
- package/out/server/getValidates.js.map +1 -0
- package/out/server/index.d.ts +5 -0
- package/out/server/index.js +43 -0
- package/out/server/index.js.map +1 -0
- package/out/server/naslServer.d.ts +375 -0
- package/out/server/naslServer.js +4735 -0
- package/out/server/naslServer.js.map +1 -0
- package/out/server/naslStdlibMap.d.ts +2 -0
- package/out/server/naslStdlibMap.js +54 -0
- package/out/server/naslStdlibMap.js.map +1 -0
- package/out/server/process2LogicNamespace.d.ts +26 -0
- package/out/server/process2LogicNamespace.js +109 -0
- package/out/server/process2LogicNamespace.js.map +1 -0
- package/out/server/translator.d.ts +26 -0
- package/out/server/translator.js +847 -0
- package/out/server/translator.js.map +1 -0
- package/out/service/creator/add.configs.d.ts +1 -0
- package/out/service/creator/add.configs.js +103 -0
- package/out/service/creator/add.configs.js.map +1 -0
- package/out/service/creator/errHandles.d.ts +18 -0
- package/out/service/creator/errHandles.js +71 -0
- package/out/service/creator/errHandles.js.map +1 -0
- package/out/service/creator/index.d.ts +1 -0
- package/out/service/creator/index.js +87 -0
- package/out/service/creator/index.js.map +1 -0
- package/out/service/datasource/api.d.ts +12 -0
- package/out/service/datasource/api.js +14 -0
- package/out/service/datasource/api.js.map +1 -0
- package/out/service/datasource/index.d.ts +2 -0
- package/out/service/datasource/index.js +10 -0
- package/out/service/datasource/index.js.map +1 -0
- package/out/service/defaultErrorMessage.json +98 -0
- package/out/service/logic/api.d.ts +9 -0
- package/out/service/logic/api.js +11 -0
- package/out/service/logic/api.js.map +1 -0
- package/out/service/logic/checktypeSocket.d.ts +5 -0
- package/out/service/logic/checktypeSocket.js +55 -0
- package/out/service/logic/checktypeSocket.js.map +1 -0
- package/out/service/logic/index.d.ts +2 -0
- package/out/service/logic/index.js +10 -0
- package/out/service/logic/index.js.map +1 -0
- package/out/service/storage/api.d.ts +54 -0
- package/out/service/storage/api.js +42 -0
- package/out/service/storage/api.js.map +1 -0
- package/out/service/storage/index.d.ts +2 -0
- package/out/service/storage/index.js +10 -0
- package/out/service/storage/index.js.map +1 -0
- package/out/service/storage/init.d.ts +105 -0
- package/out/service/storage/init.js +1232 -0
- package/out/service/storage/init.js.map +1 -0
- package/out/service/storage/jsoner.d.ts +36 -0
- package/out/service/storage/jsoner.js +148 -0
- package/out/service/storage/jsoner.js.map +1 -0
- package/out/service/storage/map.d.ts +4 -0
- package/out/service/storage/map.js +54 -0
- package/out/service/storage/map.js.map +1 -0
- package/out/service/storage/service.d.ts +25 -0
- package/out/service/storage/service.js +80 -0
- package/out/service/storage/service.js.map +1 -0
- package/out/service/storage/storagePoint.d.ts +17 -0
- package/out/service/storage/storagePoint.js +76 -0
- package/out/service/storage/storagePoint.js.map +1 -0
- package/out/service/video/BaseService.d.ts +7 -0
- package/out/service/video/BaseService.js +61 -0
- package/out/service/video/BaseService.js.map +1 -0
- package/out/service/video/MainCallbackService.d.ts +12 -0
- package/out/service/video/MainCallbackService.js +183 -0
- package/out/service/video/MainCallbackService.js.map +1 -0
- package/out/service/video/VideoTranscribe.d.ts +15 -0
- package/out/service/video/VideoTranscribe.js +96 -0
- package/out/service/video/VideoTranscribe.js.map +1 -0
- package/out/service/video/publishService.d.ts +1 -0
- package/out/service/video/publishService.js +58 -0
- package/out/service/video/publishService.js.map +1 -0
- package/out/templator/genCallComponentLogic.d.ts +17 -0
- package/out/templator/genCallComponentLogic.js +29 -0
- package/out/templator/genCallComponentLogic.js.map +1 -0
- package/out/templator/genCreateBlock.d.ts +10 -0
- package/out/templator/genCreateBlock.js +372 -0
- package/out/templator/genCreateBlock.js.map +1 -0
- package/out/templator/genCurdEditMultipleKeyBlock.d.ts +8 -0
- package/out/templator/genCurdEditMultipleKeyBlock.js +527 -0
- package/out/templator/genCurdEditMultipleKeyBlock.js.map +1 -0
- package/out/templator/genCurdMultipleKeyBlock.d.ts +61 -0
- package/out/templator/genCurdMultipleKeyBlock.js +1378 -0
- package/out/templator/genCurdMultipleKeyBlock.js.map +1 -0
- package/out/templator/genEditTableBlock.d.ts +51 -0
- package/out/templator/genEditTableBlock.js +325 -0
- package/out/templator/genEditTableBlock.js.map +1 -0
- package/out/templator/genEnumSelectBlock.d.ts +10 -0
- package/out/templator/genEnumSelectBlock.js +53 -0
- package/out/templator/genEnumSelectBlock.js.map +1 -0
- package/out/templator/genGetBlock.d.ts +6 -0
- package/out/templator/genGetBlock.js +139 -0
- package/out/templator/genGetBlock.js.map +1 -0
- package/out/templator/genGridViewBlock.d.ts +55 -0
- package/out/templator/genGridViewBlock.js +359 -0
- package/out/templator/genGridViewBlock.js.map +1 -0
- package/out/templator/genListViewBlock.d.ts +19 -0
- package/out/templator/genListViewBlock.js +148 -0
- package/out/templator/genListViewBlock.js.map +1 -0
- package/out/templator/genQueryComponent.d.ts +34 -0
- package/out/templator/genQueryComponent.js +344 -0
- package/out/templator/genQueryComponent.js.map +1 -0
- package/out/templator/genSelectBlock.d.ts +45 -0
- package/out/templator/genSelectBlock.js +415 -0
- package/out/templator/genSelectBlock.js.map +1 -0
- package/out/templator/genTableBlock.d.ts +55 -0
- package/out/templator/genTableBlock.js +421 -0
- package/out/templator/genTableBlock.js.map +1 -0
- package/out/templator/genUpdateBlock.d.ts +6 -0
- package/out/templator/genUpdateBlock.js +414 -0
- package/out/templator/genUpdateBlock.js.map +1 -0
- package/out/templator/index.d.ts +19 -0
- package/out/templator/index.js +38 -0
- package/out/templator/index.js.map +1 -0
- package/out/templator/utils.d.ts +683 -0
- package/out/templator/utils.js +472 -0
- package/out/templator/utils.js.map +1 -0
- package/out/translator/constant.d.ts +6 -0
- package/out/translator/constant.js +10 -0
- package/out/translator/constant.js.map +1 -0
- package/out/translator/index.d.ts +3 -0
- package/out/translator/index.js +20 -0
- package/out/translator/index.js.map +1 -0
- package/out/translator/types.d.ts +49 -0
- package/out/translator/types.js +3 -0
- package/out/translator/types.js.map +1 -0
- package/out/translator/utils.d.ts +44 -0
- package/out/translator/utils.js +241 -0
- package/out/translator/utils.js.map +1 -0
- package/out/utils/cookie.d.ts +9 -0
- package/out/utils/cookie.js +62 -0
- package/out/utils/cookie.js.map +1 -0
- package/out/utils/env.d.ts +2 -0
- package/out/utils/env.js +6 -0
- package/out/utils/env.js.map +1 -0
- package/out/utils/i18nInfo.d.ts +5 -0
- package/out/utils/i18nInfo.js +36 -0
- package/out/utils/i18nInfo.js.map +1 -0
- package/out/utils/index.d.ts +61 -0
- package/out/utils/index.js +386 -0
- package/out/utils/index.js.map +1 -0
- package/out/utils/logger.d.ts +7 -0
- package/out/utils/logger.js +23 -0
- package/out/utils/logger.js.map +1 -0
- package/out/utils/sortTsString.d.ts +1 -0
- package/out/utils/sortTsString.js +44 -0
- package/out/utils/sortTsString.js.map +1 -0
- package/out/utils/string.d.ts +64 -0
- package/out/utils/string.js +153 -0
- package/out/utils/string.js.map +1 -0
- package/out/utils/time-slicing/constant.d.ts +35 -0
- package/out/utils/time-slicing/constant.js +40 -0
- package/out/utils/time-slicing/constant.js.map +1 -0
- package/out/utils/time-slicing/controller.d.ts +53 -0
- package/out/utils/time-slicing/controller.js +294 -0
- package/out/utils/time-slicing/controller.js.map +1 -0
- package/out/utils/time-slicing/index.d.ts +5 -0
- package/out/utils/time-slicing/index.js +26 -0
- package/out/utils/time-slicing/index.js.map +1 -0
- package/out/utils/time-slicing/page-state.d.ts +2 -0
- package/out/utils/time-slicing/page-state.js +14 -0
- package/out/utils/time-slicing/page-state.js.map +1 -0
- package/out/utils/time-slicing/performance.d.ts +11 -0
- package/out/utils/time-slicing/performance.js +50 -0
- package/out/utils/time-slicing/performance.js.map +1 -0
- package/out/utils/time-slicing/runner.d.ts +12 -0
- package/out/utils/time-slicing/runner.js +52 -0
- package/out/utils/time-slicing/runner.js.map +1 -0
- package/out/utils/time-slicing/tool.d.ts +24 -0
- package/out/utils/time-slicing/tool.js +47 -0
- package/out/utils/time-slicing/tool.js.map +1 -0
- package/out/utils/time-slicing/utils.d.ts +62 -0
- package/out/utils/time-slicing/utils.js +47 -0
- package/out/utils/time-slicing/utils.js.map +1 -0
- package/out/utils/time-slicing/wrapper.d.ts +18 -0
- package/out/utils/time-slicing/wrapper.js +55 -0
- package/out/utils/time-slicing/wrapper.js.map +1 -0
- package/out/utils/traverse.d.ts +36 -0
- package/out/utils/traverse.js +143 -0
- package/out/utils/traverse.js.map +1 -0
- package/out/utils/types.d.ts +13 -0
- package/out/utils/types.js +3 -0
- package/out/utils/types.js.map +1 -0
- package/out/utils/window.d.ts +7 -0
- package/out/utils/window.js +14 -0
- package/out/utils/window.js.map +1 -0
- package/package.json +1 -1
- package/sandbox/stdlib/nasl.oql.ts +2 -2
- package/src/concepts/NewComposite__.ts +2 -2
- package/src/server/translator.ts +1 -1
- package/src/templator/genTableBlock.ts +5 -1
- package/test/concepts/new-composite/__snapshots__/getQuickInfoOffset.spec.ts.snap +7 -7
- package/test/concepts/new-composite/__snapshots__/toEmbeddedTS.spec.ts.snap +11 -7
- package/test/concepts/view-element/__snapshots__/toEmbeddedTS.spec.ts.snap +139 -189
- package/test/concepts/view-element/__snapshots__/toVue.spec.ts.snap +9 -1
|
@@ -0,0 +1,4735 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
25
|
+
if (mod && mod.__esModule) return mod;
|
|
26
|
+
var result = {};
|
|
27
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
28
|
+
__setModuleDefault(result, mod);
|
|
29
|
+
return result;
|
|
30
|
+
};
|
|
31
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
32
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
33
|
+
};
|
|
34
|
+
var NaslServer_1;
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.NaslServer = exports.getDisplayString2Type = void 0;
|
|
37
|
+
/// #if process.env.BUILD_TARGET === 'node'
|
|
38
|
+
const fs = __importStar(require("fs-extra"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const worker_threads_1 = require("worker_threads");
|
|
41
|
+
const decimal_js_1 = require("decimal.js");
|
|
42
|
+
const config_1 = require("../config");
|
|
43
|
+
const sentry_1 = require("../sentry");
|
|
44
|
+
const Messager_1 = __importDefault(require("../common/Messager"));
|
|
45
|
+
const getMemberIdentifier_1 = require("./getMemberIdentifier");
|
|
46
|
+
const concepts_1 = require("../concepts");
|
|
47
|
+
const utils = __importStar(require("../utils"));
|
|
48
|
+
const jsoner = __importStar(require("../service/storage/jsoner"));
|
|
49
|
+
const createUiTs_1 = __importStar(require("./createUiTs"));
|
|
50
|
+
const storage_1 = __importDefault(require("../service/storage"));
|
|
51
|
+
const translator_1 = require("../translator");
|
|
52
|
+
const translator_2 = require("./translator");
|
|
53
|
+
const common_1 = require("../common");
|
|
54
|
+
const diagnostic_1 = require("../manager/diagnostic");
|
|
55
|
+
const coreTypeList_1 = require("../concepts/basics/types/coreTypeList");
|
|
56
|
+
const formatTsUtils_1 = require("./formatTsUtils");
|
|
57
|
+
const naslStdlibMap_1 = __importDefault(require("./naslStdlibMap"));
|
|
58
|
+
const EventEmitter_1 = require("../common/EventEmitter");
|
|
59
|
+
const utils_1 = require("../utils");
|
|
60
|
+
const decorators_1 = require("../decorators");
|
|
61
|
+
const utils_2 = require("../automate/engine/utils");
|
|
62
|
+
const EmbeddedTSFileLineMap = {
|
|
63
|
+
Entity: 3,
|
|
64
|
+
};
|
|
65
|
+
const EmbeddedTSFileOffsetMap = {
|
|
66
|
+
Variable: 12,
|
|
67
|
+
FrontendVariable: 12,
|
|
68
|
+
// Backend:12,
|
|
69
|
+
BackendVariable: 12,
|
|
70
|
+
ConfigProperty: 12,
|
|
71
|
+
};
|
|
72
|
+
const SentryMessager = (0, sentry_1.sentryMonitorTSWorkerMessager)(Messager_1.default);
|
|
73
|
+
let isChangeInterface = false; // 判断是否导入接口
|
|
74
|
+
let actionArr = []; //用于导入接口收集更改的节点
|
|
75
|
+
let timer = null; //超时器用于收集导入接口相关
|
|
76
|
+
// naslStdlib文件缓存;作为全局变量给多实例用复用
|
|
77
|
+
const __naslStdlibFileCacheMap = new Map();
|
|
78
|
+
/**
|
|
79
|
+
* 业务组件先特殊处理一下
|
|
80
|
+
* 获取业务组件的位置信息
|
|
81
|
+
*/
|
|
82
|
+
function getBusinessComponentPos(fileNode) {
|
|
83
|
+
if (fileNode.concept === 'BusinessComponent') {
|
|
84
|
+
const sourceMap = fileNode?.sourceMap?.get(fileNode);
|
|
85
|
+
if (sourceMap) {
|
|
86
|
+
const { start } = sourceMap;
|
|
87
|
+
return {
|
|
88
|
+
...start,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// 联合类型切割取出类型
|
|
94
|
+
function getDisplayString2Type(displayString) {
|
|
95
|
+
const targetString = displayString.match(/value:\s(\S+)\)/)?.[1];
|
|
96
|
+
let targetType = null;
|
|
97
|
+
if (targetString?.startsWith('nasl.core.')) {
|
|
98
|
+
targetType = targetString.slice(10);
|
|
99
|
+
}
|
|
100
|
+
// 取出匹配的内容
|
|
101
|
+
const reg = /<([^()]+)>/g;
|
|
102
|
+
// 解决extends 导致类型缺失的问题
|
|
103
|
+
displayString = displayString?.replace('T extends ', '') || '';
|
|
104
|
+
const types = reg.exec(displayString);
|
|
105
|
+
// 取出提示的类型,组成是数组
|
|
106
|
+
const typeList = (types?.[1].split(' | ') ?? []).map((item) => {
|
|
107
|
+
if (/<([^()]+)>/g.exec(item)) {
|
|
108
|
+
return item;
|
|
109
|
+
}
|
|
110
|
+
if (item.includes(' ')) {
|
|
111
|
+
const strs = item.split(' ');
|
|
112
|
+
const type = strs[strs.length - 1];
|
|
113
|
+
return type;
|
|
114
|
+
}
|
|
115
|
+
if (item.includes('.')) {
|
|
116
|
+
const strs = item.split('.');
|
|
117
|
+
const type = strs[strs.length - 1];
|
|
118
|
+
return type;
|
|
119
|
+
}
|
|
120
|
+
return item;
|
|
121
|
+
});
|
|
122
|
+
if (targetType) {
|
|
123
|
+
return typeList.filter((item) => item !== targetType);
|
|
124
|
+
}
|
|
125
|
+
return typeList;
|
|
126
|
+
}
|
|
127
|
+
exports.getDisplayString2Type = getDisplayString2Type;
|
|
128
|
+
function isCoreDateTimeType(n) {
|
|
129
|
+
return n?.expression?.__TypeAnnotation?.typeName === 'DateTime' &&
|
|
130
|
+
n?.expression?.__TypeAnnotation?.typeNamespace === 'nasl.core';
|
|
131
|
+
}
|
|
132
|
+
function isFunctionWithFixedTimeZoneParam(calleeName) {
|
|
133
|
+
const fns = ['CurrDateTime', 'CurrDate', 'CurrTime', 'FormatDateTime'];
|
|
134
|
+
return fns.includes(calleeName);
|
|
135
|
+
}
|
|
136
|
+
const timeZoneArgumentIndexMap = new Map([
|
|
137
|
+
['ToString', 1],
|
|
138
|
+
['CurrDateTime', 0],
|
|
139
|
+
['CurrDate', 0],
|
|
140
|
+
['CurrTime', 0],
|
|
141
|
+
['FormatDateTime', 2],
|
|
142
|
+
['jsonSerialize', 1],
|
|
143
|
+
['GetDateCount', 2],
|
|
144
|
+
['GetSpecificDaysOfWeek', 3]
|
|
145
|
+
]);
|
|
146
|
+
const allComponent = {};
|
|
147
|
+
let NaslServer = NaslServer_1 = class NaslServer {
|
|
148
|
+
constructor() {
|
|
149
|
+
/** naslStdlib文件缓存 */
|
|
150
|
+
this.naslStdlibFileCacheMap = __naslStdlibFileCacheMap;
|
|
151
|
+
/**
|
|
152
|
+
* 按道理 fileSourceMap: new Map<string, SourceMap>() 比较合理,
|
|
153
|
+
* 但是要多维护一层 vertex 增删 -> file 增删的关系问题,
|
|
154
|
+
* 先用挂在点上面,简单的方法实现,后期再考虑解耦
|
|
155
|
+
*/
|
|
156
|
+
this.file2NodeMap = new Map();
|
|
157
|
+
/** TS 翻译的源码 */
|
|
158
|
+
this.tsFiles = new Map();
|
|
159
|
+
/// #if process.env.NODE_ENV === 'development'
|
|
160
|
+
/**
|
|
161
|
+
* 调试时是否储存 ts 文件
|
|
162
|
+
*/
|
|
163
|
+
this.openDebugEmbedded = true;
|
|
164
|
+
/// #endif
|
|
165
|
+
this.elementsLogic = {};
|
|
166
|
+
// 需要执行修改的文件
|
|
167
|
+
this.changeStackList = [];
|
|
168
|
+
// 包含组件逻辑调用的逻辑map
|
|
169
|
+
this.logicSetWithComponentLogic = new Set();
|
|
170
|
+
/// #if process.env.BUILD_TARGET === 'node'
|
|
171
|
+
if (globalThis.process)
|
|
172
|
+
// For TS build
|
|
173
|
+
this.worker = new worker_threads_1.Worker(path.join(__dirname, '../../ts-worker/src/index.js'));
|
|
174
|
+
// worker = new Worker(path.join(__dirname, '../../../src/static/ts-worker.js'));
|
|
175
|
+
/// #endif
|
|
176
|
+
/// #if process.env.BUILD_TARGET !== 'node'
|
|
177
|
+
if (globalThis.window)
|
|
178
|
+
// For TS build
|
|
179
|
+
/* !!!如果改动这里需要看下关联的对应文件:webpack/ts-worker/loader.js */
|
|
180
|
+
this.worker = new worker_threads_1.Worker('/ts-worker.js');
|
|
181
|
+
/// #endif
|
|
182
|
+
// 要Check的文件
|
|
183
|
+
this.filesToCheck = new Set();
|
|
184
|
+
// 单个文件正在change,不允许同时两个文件一起change
|
|
185
|
+
this.singleFileChangeIng = false;
|
|
186
|
+
this.diagnosticManager = new diagnostic_1.DiagnosticManager();
|
|
187
|
+
this.messager = new SentryMessager({
|
|
188
|
+
protocol: 'ts-worker',
|
|
189
|
+
sender: 'ide',
|
|
190
|
+
context: this,
|
|
191
|
+
timeout: 120000,
|
|
192
|
+
getReceiver: () => this.worker,
|
|
193
|
+
getSender: () => this.worker,
|
|
194
|
+
handleMessage: async ({ data }) => {
|
|
195
|
+
if (data && data.event === 'publishDiagnostics') {
|
|
196
|
+
const records = await this._resolveDiagnosticRecords(data.records);
|
|
197
|
+
await this.diagnosticManager.pushAll(records);
|
|
198
|
+
try {
|
|
199
|
+
// 结束诊断和标注
|
|
200
|
+
(0, common_1.invokeCommand)('naslServer:endWork');
|
|
201
|
+
(0, common_1.invokeCommand)('naslServer:nodeChange');
|
|
202
|
+
this.embeddedTSEmitter.emit('naslServer:endWork');
|
|
203
|
+
this.embeddedTSEmitter.emit('naslServer:nodeChange');
|
|
204
|
+
}
|
|
205
|
+
catch (e) {
|
|
206
|
+
console.log('no "naslServer:nodeChange" event received');
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
// 监听所有改变操作
|
|
212
|
+
this.embeddedTSEmitter = new EventEmitter_1.EventEmitter();
|
|
213
|
+
this.embeddedTSEmitter.on('change', ({ value: eventValue }) => {
|
|
214
|
+
eventValue.forEach((item) => {
|
|
215
|
+
/**
|
|
216
|
+
* 多个行为进行合并
|
|
217
|
+
* 合并规则是
|
|
218
|
+
* 1.[a,b,c,c] 在cc的时候,在已有一个c,又来一个c的时候,file级别的节点
|
|
219
|
+
* 就可以前面的内容去掉,只保留最后一个, 但是如果前面那个有携带file
|
|
220
|
+
* 2.[a,b,c,b,c] 在bc已存在,又来了bc 这就都要保留,因为可能顺序有相关性,不能去掉
|
|
221
|
+
* 理论上只处理同时几个操作 合并,
|
|
222
|
+
* 3.有field的也直接保留
|
|
223
|
+
*/
|
|
224
|
+
try {
|
|
225
|
+
const changeEvent = item.originEvent;
|
|
226
|
+
const changeNode = changeEvent.target;
|
|
227
|
+
const { fileNode } = this.getCurrentSource(changeNode);
|
|
228
|
+
// 这个方法是 5.0 加入标准库的,但是这里 ts 版本是 4.x,ci 会挂,所以需要忽略
|
|
229
|
+
// @ts-ignore
|
|
230
|
+
const findLastIndex = this.changeStackList.findLastIndex((changeStackItem) => {
|
|
231
|
+
const { target } = changeStackItem;
|
|
232
|
+
const { fileNode: targetFileNode } = this.getCurrentSource(target);
|
|
233
|
+
return targetFileNode === fileNode;
|
|
234
|
+
});
|
|
235
|
+
// 如果当前找到了节点,而且节点在数组的最后一项,说明此次可以合并
|
|
236
|
+
if (findLastIndex !== -1 && findLastIndex === this.changeStackList.length - 1) {
|
|
237
|
+
// 最后一项有field就直接保留,新的也不塞,直接return
|
|
238
|
+
if (this.changeStackList[findLastIndex]?.field) {
|
|
239
|
+
// 如果当前列表里有,这个文件节点,最后一个是field的话,直接return掉,不用塞这个update了
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
// 如果最后一项是普通的update的话,就可以去掉,后面那个会在塞过来
|
|
243
|
+
this.changeStackList.pop();
|
|
244
|
+
}
|
|
245
|
+
this.changeStackList.push(item.originEvent);
|
|
246
|
+
}
|
|
247
|
+
catch (err) {
|
|
248
|
+
console.log(err);
|
|
249
|
+
this.changeStackList.push(item.originEvent);
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
// 如果有长度开始执行状态机
|
|
253
|
+
if (this.changeStackList.length) {
|
|
254
|
+
this.changeFileNext();
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
start() {
|
|
259
|
+
return this.messager.requestCommand('start');
|
|
260
|
+
}
|
|
261
|
+
terminate() {
|
|
262
|
+
this.worker.terminate();
|
|
263
|
+
}
|
|
264
|
+
async createUiTs(components, optinos) {
|
|
265
|
+
const { tsCode, baseComponnets } = optinos;
|
|
266
|
+
// console.log('baseComponnets', baseComponnets);
|
|
267
|
+
Object.assign(allComponent, components);
|
|
268
|
+
const { code, elementsLogic } = await (0, createUiTs_1.default)(allComponent);
|
|
269
|
+
await this.addFile({
|
|
270
|
+
file: 'nasl.ui.definition.ts',
|
|
271
|
+
// eslint-disable-next-line import/no-webpack-loader-syntax, global-require, import/extensions
|
|
272
|
+
fileContent: require('!!raw-loader!../../sandbox/stdlib/nasl.ui.definition.ts').default,
|
|
273
|
+
}, { cache: true });
|
|
274
|
+
// 放入生產的uits文件
|
|
275
|
+
await this.addFile({
|
|
276
|
+
file: 'nasl.ui.extra.ts',
|
|
277
|
+
fileContent: code,
|
|
278
|
+
}, { cache: true });
|
|
279
|
+
// 添加基础组件的方法到elementsLogic
|
|
280
|
+
Object.assign(elementsLogic, (0, createUiTs_1.createEleLogins)(baseComponnets));
|
|
281
|
+
// 基础组件
|
|
282
|
+
await this.addFile({
|
|
283
|
+
file: 'nasl.ui.component.ts',
|
|
284
|
+
fileContent: tsCode,
|
|
285
|
+
}, { cache: true });
|
|
286
|
+
Object.keys(naslStdlibMap_1.default).forEach(async (libFileName) => {
|
|
287
|
+
await this.addFile({
|
|
288
|
+
file: `/${libFileName}`,
|
|
289
|
+
fileContent: naslStdlibMap_1.default[libFileName],
|
|
290
|
+
}, { cache: true });
|
|
291
|
+
});
|
|
292
|
+
this.elementsLogic = elementsLogic;
|
|
293
|
+
// 全部文件加载完毕开始初始化
|
|
294
|
+
await this.getDiagnosticRecordsAndPushAll();
|
|
295
|
+
}
|
|
296
|
+
*contentToFile(module) {
|
|
297
|
+
if (!module) {
|
|
298
|
+
return [];
|
|
299
|
+
}
|
|
300
|
+
const self = this;
|
|
301
|
+
const results = [];
|
|
302
|
+
const getTsFile = function* getTsFile(node, name, pre) {
|
|
303
|
+
const isContinue = pre ? (input) => input instanceof pre : () => true;
|
|
304
|
+
try {
|
|
305
|
+
if (!isContinue(node)) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
const result = yield* node.toEmbeddedTSFile();
|
|
309
|
+
results.push(result);
|
|
310
|
+
node.sourceMap = result.sourceMap;
|
|
311
|
+
self.file2NodeMap.set(result.filePath, node);
|
|
312
|
+
}
|
|
313
|
+
catch (err) {
|
|
314
|
+
if (process.env.NODE_ENV === 'development') {
|
|
315
|
+
console.warn(node.nodePath ? node.nodePath : name, '代码转换失败', err);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
const getTsFiles = function* getTsFiles(nodes, name, pre) {
|
|
320
|
+
for (const node of nodes ?? []) {
|
|
321
|
+
yield* getTsFile(node, name, pre);
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
const concat = (arr, key) => {
|
|
325
|
+
return arr.reduce((ans, item) => ans.concat(item[key]), []);
|
|
326
|
+
};
|
|
327
|
+
const view2TSFile = function* view2TSFile(views) {
|
|
328
|
+
if (!views || views.length === 0) {
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
for (const view of views) {
|
|
332
|
+
yield* getTsFile(view, 'view');
|
|
333
|
+
if (view.children) {
|
|
334
|
+
yield* view2TSFile(view.children);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
// 禁用的依赖库不生成代码 区分 undefined 和 false
|
|
339
|
+
if (module instanceof concepts_1.Module && module.type === 'extension' && module.enable === false) {
|
|
340
|
+
return [];
|
|
341
|
+
}
|
|
342
|
+
const { structures = [], metadataTypes = [], frontendTypes = [], interfaces = [], enums = [], logics = [], authLogics = [], authLogicsForCallInterface = [], processes = [], dataSources = [], triggerLaunchers = [], connections = [], roles = [], overriddenLogics = [], backend, configuration, } = module;
|
|
343
|
+
const { namespaces = [], } = module;
|
|
344
|
+
const { frontends = [] } = module;
|
|
345
|
+
yield* getTsFiles(structures, 'structure');
|
|
346
|
+
yield* getTsFiles(metadataTypes, 'metadataType');
|
|
347
|
+
if (module instanceof concepts_1.App) {
|
|
348
|
+
yield* getTsFiles(overriddenLogics, 'overriddenLogic', concepts_1.OverriddenLogic);
|
|
349
|
+
yield* getTsFiles(backend?.variables ?? [], 'backend_variable');
|
|
350
|
+
for (const frontendType of frontendTypes) {
|
|
351
|
+
yield* getTsFile(frontendType, 'frontendType');
|
|
352
|
+
for (const dep of frontendType.componentDependencies) {
|
|
353
|
+
results.push(...(yield* self.contentToFile(dep)));
|
|
354
|
+
}
|
|
355
|
+
for (const frontend of frontendType.frontends) {
|
|
356
|
+
yield* getTsFile(frontend, 'frontend');
|
|
357
|
+
yield* getTsFiles(frontend.variables, 'frontend_variable');
|
|
358
|
+
yield* getTsFiles(concat(frontend.bindEvents, 'logics'), 'frontend_bindEvent_logic');
|
|
359
|
+
if (!config_1.config.closeViews) {
|
|
360
|
+
yield* view2TSFile(frontend.views);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
// 业务组件
|
|
364
|
+
yield* getTsFiles(frontendType.businessComponents, 'businessComponents');
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
// 依赖库
|
|
369
|
+
yield* getTsFiles(concat(frontends, 'logics'), 'frontend_logic');
|
|
370
|
+
}
|
|
371
|
+
yield* getTsFiles(dataSources, 'dataSource');
|
|
372
|
+
yield* getTsFiles(concat(dataSources, 'entities'), 'dataSource_entity');
|
|
373
|
+
yield* getTsFiles(interfaces, 'interface');
|
|
374
|
+
yield* getTsFiles(enums, 'enum');
|
|
375
|
+
yield* getTsFiles(logics, 'logic');
|
|
376
|
+
yield* getTsFiles(authLogics, 'authLogic', concepts_1.Logic);
|
|
377
|
+
yield* getTsFiles(authLogicsForCallInterface, 'authLogicForCallInterface', concepts_1.Logic);
|
|
378
|
+
yield* getTsFiles(processes, 'process');
|
|
379
|
+
if (module instanceof concepts_1.Connector) {
|
|
380
|
+
yield* getTsFiles(triggerLaunchers, 'triggerLauncher');
|
|
381
|
+
yield* getTsFiles(authLogicsForCallInterface, 'authLogicForCallInterface');
|
|
382
|
+
yield* getTsFiles(concat(namespaces, 'logics'), 'namespaces_logic');
|
|
383
|
+
}
|
|
384
|
+
if (module instanceof concepts_1.App) {
|
|
385
|
+
yield* getTsFiles(roles, 'role');
|
|
386
|
+
yield* getTsFiles(connections, 'connection');
|
|
387
|
+
yield* getTsFiles(triggerLaunchers, 'triggerLauncher');
|
|
388
|
+
}
|
|
389
|
+
for (const group of configuration?.groups ?? []) {
|
|
390
|
+
if (group.name === 'custom') {
|
|
391
|
+
yield* getTsFiles(group?.properties ?? [], 'configuration_group_property');
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return results;
|
|
395
|
+
}
|
|
396
|
+
async openApp(app) {
|
|
397
|
+
console.time('生成 TS 文件');
|
|
398
|
+
const self = this;
|
|
399
|
+
const results = await utils.timeSlicingWithGenerator(getAllTsFiles());
|
|
400
|
+
const files = results.map((result) => ({
|
|
401
|
+
file: result.filePath,
|
|
402
|
+
fileContent: result.code,
|
|
403
|
+
}));
|
|
404
|
+
await this.writeFiles(files);
|
|
405
|
+
this._debugInFileStorage(app, files);
|
|
406
|
+
// 修改名称回调
|
|
407
|
+
(0, common_1.registerCommand)('tsRename.change', (value, callback, toast) => {
|
|
408
|
+
callback(value, toast);
|
|
409
|
+
});
|
|
410
|
+
// 删除回调
|
|
411
|
+
(0, common_1.registerCommand)('tsDelete.change', (callback) => {
|
|
412
|
+
callback();
|
|
413
|
+
});
|
|
414
|
+
console.timeEnd('生成 TS 文件');
|
|
415
|
+
function* getAllTsFiles() {
|
|
416
|
+
const files = yield* self.contentToFile(app);
|
|
417
|
+
const otherModules = [
|
|
418
|
+
...app.integration?.connectors ?? [],
|
|
419
|
+
...app.dependencies ?? [],
|
|
420
|
+
...app.interfaceDependencies ?? [],
|
|
421
|
+
];
|
|
422
|
+
for (const item of otherModules) {
|
|
423
|
+
files.push(...yield* self.contentToFile(item));
|
|
424
|
+
}
|
|
425
|
+
return files;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
async refreshApp(app) {
|
|
429
|
+
// 清除所有问题
|
|
430
|
+
this.diagnosticManager.clear();
|
|
431
|
+
// 刷新要清除文件列表
|
|
432
|
+
this.file2NodeMap.clear();
|
|
433
|
+
await this.deleteDirectoryFiles({ directoryName: '/embedded' });
|
|
434
|
+
// 清楚check count的数量
|
|
435
|
+
await this.messager.requestCommand('_clearTimeout');
|
|
436
|
+
// 重新加载app下内容
|
|
437
|
+
await this.openApp(app);
|
|
438
|
+
// 重新check一遍所有内容
|
|
439
|
+
await this.getDiagnosticRecordsAndPushAll();
|
|
440
|
+
// check内容后,会自动走增量类型标注完善全部类型
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* 初始化之前添加文件
|
|
444
|
+
*/
|
|
445
|
+
addFile(file, { cache = false } = {}) {
|
|
446
|
+
cache && this.cacheFile(file);
|
|
447
|
+
return this.messager.requestCommand('addFile', file);
|
|
448
|
+
}
|
|
449
|
+
// 缓存添加过的文件
|
|
450
|
+
cacheFile(options) {
|
|
451
|
+
__naslStdlibFileCacheMap.set(options.file, options);
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* 只新增文件
|
|
455
|
+
* @param {*} files
|
|
456
|
+
*/
|
|
457
|
+
writeFiles(files) {
|
|
458
|
+
files.forEach(({ file, fileContent }) => this.tsFiles.set(file, fileContent));
|
|
459
|
+
return this.messager.requestCommand('writeFiles', files);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* 新增、修改
|
|
463
|
+
* 删除文件 文件用修改内容为空模拟,防止报错
|
|
464
|
+
* @param {*} args
|
|
465
|
+
*/
|
|
466
|
+
updateFiles(args) {
|
|
467
|
+
args.outputFiles.forEach(({ file, fileContent }) => this.tsFiles.set(file, fileContent));
|
|
468
|
+
return this.messager.requestCommand('updateFiles', args);
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* 清除一个目录下的所有文件
|
|
472
|
+
*/
|
|
473
|
+
deleteDirectoryFiles(args) {
|
|
474
|
+
Array.from(this.tsFiles.keys())
|
|
475
|
+
.filter((key) => key.startsWith(args.directoryName))
|
|
476
|
+
.forEach((key) => this.tsFiles.delete(key));
|
|
477
|
+
return this.messager.requestCommand('deleteDirectoryFiles', args);
|
|
478
|
+
}
|
|
479
|
+
async _debugInFileStorage(node, openFiles) {
|
|
480
|
+
let app = node;
|
|
481
|
+
if (node.concept !== 'App') {
|
|
482
|
+
app = node.rootNode || node.app;
|
|
483
|
+
}
|
|
484
|
+
/// #if process.env.NODE_ENV === 'development'
|
|
485
|
+
// 首次尝试请求
|
|
486
|
+
await storage_1.default.post(`/api/App/debugEmbedded?id=${app.id}`, openFiles[0]).catch(() => (this.openDebugEmbedded = false));
|
|
487
|
+
if (this.openDebugEmbedded && globalThis.window) {
|
|
488
|
+
// For TS build
|
|
489
|
+
try {
|
|
490
|
+
let canDebug = true;
|
|
491
|
+
await storage_1.default.post(`/api/App/debugEmbedded?id=${app.id}`, openFiles[0]).catch(() => (canDebug = false));
|
|
492
|
+
if (canDebug) {
|
|
493
|
+
await Promise.all(openFiles.map(async (file) => {
|
|
494
|
+
const res = await storage_1.default.post(`/api/App/debugEmbedded?id=${app.id}`, file);
|
|
495
|
+
return res.data;
|
|
496
|
+
}));
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
catch (e) {
|
|
500
|
+
// ..
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
/// #endif
|
|
504
|
+
/// #if process.env.BUILD_TARGET === 'node'
|
|
505
|
+
if (globalThis.process) {
|
|
506
|
+
// For TS build
|
|
507
|
+
try {
|
|
508
|
+
await Promise.all(openFiles.map(async (file) => fs.outputFile(path.join(__dirname, '../debug/apps', app.id, file.file), file.fileContent)));
|
|
509
|
+
}
|
|
510
|
+
catch (e) {
|
|
511
|
+
console.error(e);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
/// #endif
|
|
515
|
+
}
|
|
516
|
+
open() {
|
|
517
|
+
return this.messager.requestCommand('open');
|
|
518
|
+
}
|
|
519
|
+
updateOpen(args) {
|
|
520
|
+
return this.messager.requestCommand('updateOpen', args);
|
|
521
|
+
}
|
|
522
|
+
fileReferences(filePath) {
|
|
523
|
+
return this.messager.requestCommand('fileReferences', filePath);
|
|
524
|
+
}
|
|
525
|
+
async references(args) {
|
|
526
|
+
return (await this.messager.requestCommand('references', args))?.response;
|
|
527
|
+
}
|
|
528
|
+
getValueSelectCompletion(node, value, noFilterList) {
|
|
529
|
+
const { currentSource, fileNode } = this.getCurrentSource(node);
|
|
530
|
+
// console.log(currentSource, fileNode);
|
|
531
|
+
if (currentSource && fileNode) {
|
|
532
|
+
return this._getValueSelectCompletion({
|
|
533
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
534
|
+
range: {
|
|
535
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
536
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character),
|
|
537
|
+
},
|
|
538
|
+
value,
|
|
539
|
+
noFilterList,
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
console.log('没找到节点', node, currentSource, fileNode);
|
|
543
|
+
}
|
|
544
|
+
_getValueSelectCompletion(args) {
|
|
545
|
+
return this.messager.requestCommand('getValueSelectCompletion', args);
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* 获取 Convert 的可选类型
|
|
549
|
+
* @param node 传入当前已经选择的变量
|
|
550
|
+
* @returns 可以选择的类型数组
|
|
551
|
+
*/
|
|
552
|
+
async getConvertTypeInfo(node) {
|
|
553
|
+
if (node && node instanceof concepts_1.BaseNode) {
|
|
554
|
+
const callFunction = node.parentNode.parentNode;
|
|
555
|
+
/**
|
|
556
|
+
* currentSource callFunction 的节点,要去到当前节点的位置
|
|
557
|
+
* nasl.util.Convert(xxx),所以取到的位置要 + `nasl.util.C` 的长度
|
|
558
|
+
* fileNode
|
|
559
|
+
*/
|
|
560
|
+
const { currentSource, fileNode } = this.getCurrentSource(callFunction);
|
|
561
|
+
if (!currentSource) {
|
|
562
|
+
return [];
|
|
563
|
+
}
|
|
564
|
+
try {
|
|
565
|
+
const quickInfo = await this._getTypeQuickinfo({
|
|
566
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
567
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
568
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character) + `nasl.util.C`.length,
|
|
569
|
+
});
|
|
570
|
+
if (quickInfo.responseRequired) {
|
|
571
|
+
const displayString = quickInfo?.response?.displayString || '';
|
|
572
|
+
const typeList = getDisplayString2Type(displayString);
|
|
573
|
+
const res = [];
|
|
574
|
+
typeList.forEach((type) => {
|
|
575
|
+
const typeAnnotation = coreTypeList_1.primitiveTypeList.find((typeAnnotation) => typeAnnotation.typeName === type);
|
|
576
|
+
if (typeAnnotation) {
|
|
577
|
+
res.push(typeAnnotation);
|
|
578
|
+
}
|
|
579
|
+
else if (type === 'unknown' || type === 'never') {
|
|
580
|
+
return null;
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
if (!res.length) {
|
|
584
|
+
return [];
|
|
585
|
+
}
|
|
586
|
+
return [{ title: '基础类型', children: res }];
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
catch (err) {
|
|
590
|
+
console.log(err);
|
|
591
|
+
// 如果有异常就先放开全部可选,兜底逻辑
|
|
592
|
+
return [];
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
else {
|
|
596
|
+
// 字符串 和 inter
|
|
597
|
+
return [{ title: '基础类型', children: [coreTypeList_1.primitiveTypeList[4]] }];
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* 获取表格的dataschema类型
|
|
602
|
+
* @param node 当前表格节点
|
|
603
|
+
* @param allType 是不是需要全部类型 默认不要
|
|
604
|
+
* @returns 全部类型的str 或者 最后一个.后的内容
|
|
605
|
+
*/
|
|
606
|
+
async getDataSchemaType(node, allType = false) {
|
|
607
|
+
if (!(node instanceof concepts_1.ViewElement))
|
|
608
|
+
return;
|
|
609
|
+
const { currentSource, fileNode } = this.getCurrentSource(node);
|
|
610
|
+
if (!currentSource) {
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
const quickInfo = await this._getTypeQuickinfo({
|
|
614
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
615
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
616
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character) + `new nasl.ui.`.length,
|
|
617
|
+
});
|
|
618
|
+
if (quickInfo.responseRequired) {
|
|
619
|
+
const displayString = quickInfo?.response?.displayString || '';
|
|
620
|
+
const flag = displayString.includes('<') && displayString.includes('>');
|
|
621
|
+
const types = /<([^()]+)>/g.exec(displayString);
|
|
622
|
+
let typeStr = types && types[1];
|
|
623
|
+
// 从 {entity1:Entity1(defaultDS);},unknown,unknown,unknown 取出{entity1:Entity1(defaultDS);}
|
|
624
|
+
typeStr = typeStr?.split(',')[0];
|
|
625
|
+
if (flag) {
|
|
626
|
+
// 自定义结构的展示
|
|
627
|
+
if (typeStr.includes('__name: "AStructure_')) {
|
|
628
|
+
return typeStr
|
|
629
|
+
.replaceAll(' ', '')
|
|
630
|
+
.replaceAll('\n', '')
|
|
631
|
+
.replace(/__name:"AStructure_\w{8}";/g, '')
|
|
632
|
+
.replace(/dataSources.([^.]+).entities.([^;]+)/g, ($1, $2, $3) => `${$3}(${$2})`);
|
|
633
|
+
}
|
|
634
|
+
if (typeStr.startsWith('{') && typeStr.endsWith('}')) {
|
|
635
|
+
/**
|
|
636
|
+
* {
|
|
637
|
+
text: nasl.core.String;
|
|
638
|
+
value: nasl.core.String;
|
|
639
|
+
}
|
|
640
|
+
*/
|
|
641
|
+
return typeStr.replaceAll(' ', '').replaceAll('\n', '').replaceAll('nasl.core.', '');
|
|
642
|
+
}
|
|
643
|
+
let str = '';
|
|
644
|
+
// 取出T的值
|
|
645
|
+
typeStr = (0, formatTsUtils_1.getPlatformType)(typeStr);
|
|
646
|
+
// 如果要全量的内容
|
|
647
|
+
if (allType) {
|
|
648
|
+
return typeStr;
|
|
649
|
+
}
|
|
650
|
+
// 取出剩下的剩下的类型的最后一项
|
|
651
|
+
if (/<([^()]+)>/g.exec(typeStr)) {
|
|
652
|
+
str = typeStr;
|
|
653
|
+
}
|
|
654
|
+
else if (typeStr.includes('.')) {
|
|
655
|
+
const strs = typeStr.split('.');
|
|
656
|
+
const type = strs[strs.length - 1];
|
|
657
|
+
str = type;
|
|
658
|
+
}
|
|
659
|
+
else {
|
|
660
|
+
str = typeStr;
|
|
661
|
+
}
|
|
662
|
+
str = str === 'any' || str === 'unknown' || str === 'never' ? '' : str;
|
|
663
|
+
return str;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
return '';
|
|
667
|
+
}
|
|
668
|
+
async getDataSchemaStructureOrTypeAnnotation(node) {
|
|
669
|
+
if (!(node instanceof concepts_1.ViewElement))
|
|
670
|
+
return;
|
|
671
|
+
const { currentSource, fileNode } = this.getCurrentSource(node);
|
|
672
|
+
if (!currentSource) {
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
const quickInfo = await this._getTypeQuickinfo({
|
|
676
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
677
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
678
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character) + `new nasl.ui.`.length,
|
|
679
|
+
});
|
|
680
|
+
if (quickInfo.responseRequired) {
|
|
681
|
+
const displayString = quickInfo?.response?.displayString || '';
|
|
682
|
+
const flag = displayString.includes('<') && displayString.includes('>');
|
|
683
|
+
if (!flag)
|
|
684
|
+
return;
|
|
685
|
+
const types = /<([^()]+)>/g.exec(displayString);
|
|
686
|
+
const typeStr = types && types[1];
|
|
687
|
+
const app = node.getAncestor('App');
|
|
688
|
+
if (typeStr.includes('__name: "AStructure_')) {
|
|
689
|
+
const properties = [];
|
|
690
|
+
typeStr.replace(/([^:\s]+):\s+([^;]+);/g, ($1, name, typeKey) => {
|
|
691
|
+
if (name === '__name')
|
|
692
|
+
return;
|
|
693
|
+
typeKey = `app.${typeKey}`;
|
|
694
|
+
const keys = typeKey.split('.');
|
|
695
|
+
const typeName = keys.pop();
|
|
696
|
+
const typeNamespace = keys.join('.');
|
|
697
|
+
properties.push(concepts_1.StructureProperty.from({
|
|
698
|
+
name,
|
|
699
|
+
typeAnnotation: concepts_1.TypeAnnotation.from({
|
|
700
|
+
typeKind: 'reference',
|
|
701
|
+
typeName,
|
|
702
|
+
typeNamespace,
|
|
703
|
+
}),
|
|
704
|
+
}));
|
|
705
|
+
return '';
|
|
706
|
+
});
|
|
707
|
+
return concepts_1.TypeAnnotation.createTypeAnonymousStructure(properties);
|
|
708
|
+
}
|
|
709
|
+
if (typeStr.startsWith('structures'))
|
|
710
|
+
return app.findNodeByCompleteName(`app.${typeStr}`);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* ts的 quickInfo方法,查询指定位置的详情
|
|
715
|
+
* @param args 文件信息数组
|
|
716
|
+
* @returns 查询到的
|
|
717
|
+
*/
|
|
718
|
+
_getTypeQuickinfo(args) {
|
|
719
|
+
return this.messager.requestCommand('quickInfo', args);
|
|
720
|
+
}
|
|
721
|
+
_getQuickInfoFull(args) {
|
|
722
|
+
return this.messager.requestCommand('quickInfoFull', args);
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* 获取nasl节点的 指定位置的详情
|
|
726
|
+
* 而且可以返回正确类型
|
|
727
|
+
* @param args 文件信息数组
|
|
728
|
+
* @returns 查询到的
|
|
729
|
+
*/
|
|
730
|
+
async getNaslNodeQuickInfoFull(args) {
|
|
731
|
+
const result = await this._getQuickInfoFull(args);
|
|
732
|
+
return result;
|
|
733
|
+
}
|
|
734
|
+
_getTypeFull(args) {
|
|
735
|
+
return this.messager.requestCommand('typeFull', args);
|
|
736
|
+
}
|
|
737
|
+
_getTypeBatch(args) {
|
|
738
|
+
return this.messager.requestCommand('typeBatch', args);
|
|
739
|
+
}
|
|
740
|
+
async getNaslNodeTypeFull(args) {
|
|
741
|
+
const result = await this._getTypeFull(args);
|
|
742
|
+
return result;
|
|
743
|
+
}
|
|
744
|
+
async getNaslNodeTypeBatch(args) {
|
|
745
|
+
const result = await this._getTypeBatch(args);
|
|
746
|
+
return result;
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* 获取已经选中的内容的 下一级的内容
|
|
750
|
+
* @param node 已经选中的内容
|
|
751
|
+
* @param noFilterList 不过滤的key 的数据
|
|
752
|
+
* @returns 可以选择的数据数组
|
|
753
|
+
*/
|
|
754
|
+
getSelectNextCompletion(node, noFilterList) {
|
|
755
|
+
const { currentSource, fileNode } = this.getCurrentSource(node);
|
|
756
|
+
// console.log(currentSource, fileNode);
|
|
757
|
+
if (currentSource && fileNode) {
|
|
758
|
+
return this._getSelectNextCompletion({
|
|
759
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
760
|
+
range: {
|
|
761
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
762
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character),
|
|
763
|
+
},
|
|
764
|
+
noFilterList,
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
console.log('没找到节点', currentSource, fileNode);
|
|
768
|
+
}
|
|
769
|
+
_getSelectNextCompletion(args) {
|
|
770
|
+
return this.messager.requestCommand('getSelectNextCompletion', args);
|
|
771
|
+
}
|
|
772
|
+
getDiagnosticRecordsAndPushAll(fileNames) {
|
|
773
|
+
(0, common_1.invokeCommand)('naslServer:startWork');
|
|
774
|
+
return this.messager.requestCommand('getDiagnosticRecords', fileNames);
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* 节点异常是只能挂载单个,如果已经了就不赋值了
|
|
778
|
+
*/
|
|
779
|
+
baseNodeAssignmentTsError(node, tsErrorDetail) {
|
|
780
|
+
if (node.tsErrorDetail)
|
|
781
|
+
return;
|
|
782
|
+
node.tsErrorDetail = tsErrorDetail;
|
|
783
|
+
}
|
|
784
|
+
*_resolveDiagnosticRecordsWithGenerator(records) {
|
|
785
|
+
// 热更新类型标注
|
|
786
|
+
if (records.length) {
|
|
787
|
+
yield* this._incrementalAnnotationJSONWithGenerator(records);
|
|
788
|
+
}
|
|
789
|
+
const self = this;
|
|
790
|
+
console.time('处理诊断数据');
|
|
791
|
+
yield* utils.wrapForEachToGenerator(records, function* resolveRecord(record) {
|
|
792
|
+
if (!record || !record.node) {
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
const { node } = record;
|
|
796
|
+
// 先获取原来的节点先清除一下之前有异常的节点,下面重新赋值
|
|
797
|
+
const oldRecord = self.diagnosticManager.getRecord?.(record.id);
|
|
798
|
+
// 处理旧数据
|
|
799
|
+
if (oldRecord) {
|
|
800
|
+
yield* utils.wrapForEachToGenerator(oldRecord.semanticDiagnostics, (item) => {
|
|
801
|
+
if (item.node) {
|
|
802
|
+
delete item.node.tsErrorDetail;
|
|
803
|
+
// 如果logic中有报错就把标识置为true
|
|
804
|
+
if (item.node?.logic?.haveError) {
|
|
805
|
+
item.node.logic.haveError = false;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
});
|
|
809
|
+
yield* utils.wrapForEachToGenerator(oldRecord.suggestionDiagnostics, (item) => {
|
|
810
|
+
if (item.node) {
|
|
811
|
+
delete item.node.tsErrorDetail;
|
|
812
|
+
if (item.node && item.node instanceof concepts_1.Logic) {
|
|
813
|
+
item.node.isSmpty = false;
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
// 语义诊断
|
|
819
|
+
if (isChangeInterface) {
|
|
820
|
+
yield* self.existStructureFix(record.semanticDiagnostics, record.node, self);
|
|
821
|
+
}
|
|
822
|
+
// 单独处理 oql 语义错误提示
|
|
823
|
+
if (record.node instanceof concepts_1.Logic) {
|
|
824
|
+
yield* utils.wrapForEachToGenerator(record?.syntaxDiagnostics, function* test(item) {
|
|
825
|
+
const minRange = yield* self._findMinRangeWithGenerator(item, record.node);
|
|
826
|
+
if (minRange?.node instanceof concepts_1.OqlQueryComponent) {
|
|
827
|
+
if (item.text === 'Invalid character.') {
|
|
828
|
+
record.semanticDiagnostics.push(item);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
// 记录结构体数据
|
|
834
|
+
yield* utils.wrapForEachToGenerator(record.semanticDiagnostics, (diag) => {
|
|
835
|
+
(0, translator_2.checkAStructure_)(diag.text);
|
|
836
|
+
});
|
|
837
|
+
record.semanticDiagnostics = (yield* utils.wrapMapToGenerator(record.semanticDiagnostics, function* (diag) {
|
|
838
|
+
return yield* self._resolveDiagnosticWithGenerator(diag, record.node, record);
|
|
839
|
+
})).filter((diag) => !!diag);
|
|
840
|
+
record.semanticDiagnostics.push(...(yield* self._attachDiagnosticsWithGenerator(node)));
|
|
841
|
+
// 报错降级逻辑
|
|
842
|
+
record.semanticDiagnostics = (yield* utils.wrapMapToGenerator(record.semanticDiagnostics, (diagnostic) => {
|
|
843
|
+
// 错误降级如果属于草稿态的就降级
|
|
844
|
+
if (diagnostic?.node) {
|
|
845
|
+
let currentNode = diagnostic.node;
|
|
846
|
+
if (diagnostic.severity === 'warning') {
|
|
847
|
+
record.suggestionDiagnostics.push(diagnostic);
|
|
848
|
+
return null;
|
|
849
|
+
}
|
|
850
|
+
if (concepts_1.asserts.isStrictOqlQueryComponent(currentNode)) {
|
|
851
|
+
// OQL别名错误降级为警告
|
|
852
|
+
if (diagnostic.originalDiagnostic && diagnostic.originalDiagnostic?.text.includes('__OQL_ALIAS_WARNING__')) {
|
|
853
|
+
// 重置 图标和错误等级
|
|
854
|
+
diagnostic.severity = 'warning';
|
|
855
|
+
if (diagnostic.node?.tsErrorDetail) {
|
|
856
|
+
// 重置组件节点上的错误信息
|
|
857
|
+
diagnostic.node.tsErrorDetail.severity = 'warning';
|
|
858
|
+
}
|
|
859
|
+
record.suggestionDiagnostics.push(diagnostic);
|
|
860
|
+
return null;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
while (currentNode && currentNode?.parentNode?.concept !== 'App') {
|
|
864
|
+
if (currentNode.parentKey?.toLowerCase()?.includes('playground')) {
|
|
865
|
+
// 草稿区降级
|
|
866
|
+
// 重置 图标和错误等级
|
|
867
|
+
diagnostic.severity = 'warning';
|
|
868
|
+
if (diagnostic.node?.tsErrorDetail) {
|
|
869
|
+
// 重置组件节点上的错误信息
|
|
870
|
+
diagnostic.node.tsErrorDetail.severity = 'warning';
|
|
871
|
+
}
|
|
872
|
+
record.suggestionDiagnostics.push(diagnostic);
|
|
873
|
+
return null;
|
|
874
|
+
}
|
|
875
|
+
currentNode = currentNode.parentNode;
|
|
876
|
+
}
|
|
877
|
+
// 没有降级的继续遍历,如果在logic中,logic本身需要有error状态
|
|
878
|
+
// 如果logic中有报错就把标识置为true
|
|
879
|
+
if (diagnostic.node?.logic) {
|
|
880
|
+
diagnostic.node.logic.haveError = true;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
return diagnostic;
|
|
884
|
+
}))
|
|
885
|
+
.filter((diag) => !!diag);
|
|
886
|
+
// 处理后的警告异常提示信息
|
|
887
|
+
record.suggestionDiagnostics = (yield* utils.wrapMapToGenerator(record.suggestionDiagnostics, function* resolveSuggestionDiagnostic(diag) {
|
|
888
|
+
// 上面错误降级下来的
|
|
889
|
+
if (diag?.node) {
|
|
890
|
+
return diag;
|
|
891
|
+
// 一些已知警告的单独处理
|
|
892
|
+
}
|
|
893
|
+
if ([
|
|
894
|
+
`'__LogicEmpty' is declared but its value is never read.`,
|
|
895
|
+
`'__destinationEmpty__' is declared but its value is never read.`,
|
|
896
|
+
`'__devConfigValueEmpty' is declared but its value is never read.`,
|
|
897
|
+
`'__onlineConfigValueEmpty' is declared but its value is never read.`,
|
|
898
|
+
`'__UpdateNoProperty__' is declared but its value is never read.`,
|
|
899
|
+
].includes(diag.text)) {
|
|
900
|
+
return yield* self._resolveDiagnosticWithGenerator(diag, record.node, record);
|
|
901
|
+
}
|
|
902
|
+
if (diag.text.includes(` is declared but its value is never read.`)) {
|
|
903
|
+
// 局部变量和输入变量未使用的警告
|
|
904
|
+
const fromModule = record.node.parentNode.concept === 'Module';
|
|
905
|
+
const fromConnector = record.node.parentNode.concept === 'Connector';
|
|
906
|
+
if ((concepts_1.asserts.isStrictView(record.node) || concepts_1.asserts.isStrictLogic(record.node)) && !(fromModule || fromConnector)) {
|
|
907
|
+
/**
|
|
908
|
+
* javalogic不用提示
|
|
909
|
+
*/
|
|
910
|
+
if (concepts_1.asserts.isStrictLogic(record.node) && self._isJavalogic(record.node)) {
|
|
911
|
+
return null;
|
|
912
|
+
}
|
|
913
|
+
concepts_1.asserts.assertFileNode(record.node);
|
|
914
|
+
const minRange = yield* self._findMinRangeWithGenerator(diag, record.node);
|
|
915
|
+
if (minRange) {
|
|
916
|
+
/**
|
|
917
|
+
* 如果节点是入参类型
|
|
918
|
+
* 而且不是foreach中
|
|
919
|
+
* 而且不是事件逻辑的入参
|
|
920
|
+
*/
|
|
921
|
+
if (minRange.node instanceof concepts_1.Param &&
|
|
922
|
+
minRange.node.parentNode.concept !== 'ForEachStatement' &&
|
|
923
|
+
!minRange.node.getAncestor('BindEvent')) {
|
|
924
|
+
const diagnostic = {
|
|
925
|
+
node: minRange.node,
|
|
926
|
+
severity: 'warning',
|
|
927
|
+
message: `未使用的输入参数${minRange.node.name}`,
|
|
928
|
+
};
|
|
929
|
+
return diagnostic;
|
|
930
|
+
}
|
|
931
|
+
if (minRange.node instanceof concepts_1.Variable) {
|
|
932
|
+
const diagnostic = {
|
|
933
|
+
node: minRange.node,
|
|
934
|
+
severity: 'warning',
|
|
935
|
+
message: `未使用的变量${minRange.node.name}`,
|
|
936
|
+
};
|
|
937
|
+
return diagnostic;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
return null;
|
|
943
|
+
}))
|
|
944
|
+
.filter((diag) => !!diag);
|
|
945
|
+
record.suggestionDiagnostics.push(...yield* self._attachSuggestionDiagnosticsWithGenerator(node));
|
|
946
|
+
});
|
|
947
|
+
console.timeEnd('处理诊断数据');
|
|
948
|
+
return records;
|
|
949
|
+
}
|
|
950
|
+
/**
|
|
951
|
+
* 处理诊断结果
|
|
952
|
+
* @param records 结果
|
|
953
|
+
* @returns 过滤或者转换后的诊断结果
|
|
954
|
+
*/
|
|
955
|
+
_resolveDiagnosticRecords(records) {
|
|
956
|
+
return utils.timeSlicingWithGenerator(this._resolveDiagnosticRecordsWithGenerator(records));
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* 判断是否是Javalogic
|
|
960
|
+
*/
|
|
961
|
+
_isJavalogic(node) {
|
|
962
|
+
const body = node.body || [];
|
|
963
|
+
if (body && body.length && body[0].concept === 'JavaLogic') {
|
|
964
|
+
return true;
|
|
965
|
+
}
|
|
966
|
+
return false;
|
|
967
|
+
}
|
|
968
|
+
/**
|
|
969
|
+
* 额外的建议诊断
|
|
970
|
+
* @param fileNode 文件级别的节点
|
|
971
|
+
* @returns 诊断结果
|
|
972
|
+
*/
|
|
973
|
+
*_attachSuggestionDiagnosticsWithGenerator(fileNode) {
|
|
974
|
+
const diagnostics = [];
|
|
975
|
+
if (fileNode instanceof concepts_1.Logic || fileNode instanceof concepts_1.View) {
|
|
976
|
+
fileNode?.sourceMap.forEach((value, node) => {
|
|
977
|
+
// 表达式模式才需要校验返回值类型
|
|
978
|
+
if (node instanceof concepts_1.Match && node.isExpression) {
|
|
979
|
+
const { cases, expression } = node || {};
|
|
980
|
+
const typeAnnotationMap = {};
|
|
981
|
+
// 最多数的类型
|
|
982
|
+
let maxTypeAnnotationInfo = {
|
|
983
|
+
typeAnnotation: null,
|
|
984
|
+
count: 0,
|
|
985
|
+
};
|
|
986
|
+
if (Array.isArray(cases)) {
|
|
987
|
+
cases.forEach((caseItem, index) => {
|
|
988
|
+
let isDisabled = false;
|
|
989
|
+
// 是最后一项
|
|
990
|
+
if (index === cases.length - 1) {
|
|
991
|
+
let enumerableItems = [];
|
|
992
|
+
const currTypeAnnotation = expression?.__TypeAnnotation;
|
|
993
|
+
const { typeKind, typeNamespace, typeName, typeArguments } = currTypeAnnotation || {};
|
|
994
|
+
if (typeKind === 'union' && Array.isArray(typeArguments)) {
|
|
995
|
+
enumerableItems = typeArguments.map((typeArg) => {
|
|
996
|
+
let typeArgJson = typeArg;
|
|
997
|
+
if (typeArg instanceof concepts_1.TypeAnnotation) {
|
|
998
|
+
typeArgJson = typeArg.toJSON();
|
|
999
|
+
}
|
|
1000
|
+
return new concepts_1.TypeAnnotation(typeArgJson);
|
|
1001
|
+
});
|
|
1002
|
+
}
|
|
1003
|
+
else if (typeKind === 'reference') {
|
|
1004
|
+
const nameArr = [typeName];
|
|
1005
|
+
if (typeNamespace) {
|
|
1006
|
+
nameArr.unshift(typeNamespace);
|
|
1007
|
+
}
|
|
1008
|
+
const typeNode = node.app?.findNodeByCompleteName?.(nameArr.join('.')) || {};
|
|
1009
|
+
if (typeNode.concept === 'Enum') {
|
|
1010
|
+
const enums = (0, getMemberIdentifier_1.formatEnums)([typeNode]);
|
|
1011
|
+
const { children } = enums?.[0] || {};
|
|
1012
|
+
if (Array.isArray(children)) {
|
|
1013
|
+
enumerableItems = children.map((child) => child?.expression);
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
else if (typeKind === 'primitive' && typeNamespace === 'nasl.core' && typeName === 'Boolean') {
|
|
1018
|
+
enumerableItems = [
|
|
1019
|
+
new concepts_1.BooleanLiteral({
|
|
1020
|
+
value: 'true',
|
|
1021
|
+
}),
|
|
1022
|
+
new concepts_1.BooleanLiteral({
|
|
1023
|
+
value: 'false',
|
|
1024
|
+
}),
|
|
1025
|
+
];
|
|
1026
|
+
}
|
|
1027
|
+
if (Array.isArray(enumerableItems) && enumerableItems.length) {
|
|
1028
|
+
const map = {};
|
|
1029
|
+
cases.forEach((caseItem) => {
|
|
1030
|
+
const { patterns } = caseItem || {};
|
|
1031
|
+
if (Array.isArray(patterns)) {
|
|
1032
|
+
patterns.forEach((pattern) => {
|
|
1033
|
+
if (pattern instanceof concepts_1.TypeAnnotation) {
|
|
1034
|
+
const patternTypeKey = pattern.typeKey;
|
|
1035
|
+
map[patternTypeKey] = true;
|
|
1036
|
+
}
|
|
1037
|
+
else if (pattern instanceof concepts_1.MemberExpression || pattern instanceof concepts_1.BooleanLiteral) {
|
|
1038
|
+
const patternValue = pattern.getValue();
|
|
1039
|
+
map[patternValue] = true;
|
|
1040
|
+
}
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
});
|
|
1044
|
+
const enumerableKeys = Object.keys(map);
|
|
1045
|
+
if (enumerableKeys.length === enumerableItems.length) {
|
|
1046
|
+
isDisabled = true;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
if (!isDisabled) {
|
|
1051
|
+
const typeAnnotation = caseItem.__TypeAnnotation;
|
|
1052
|
+
// 仅处理有类型的情况,返回类型为void的情况由其他地方处理成报错
|
|
1053
|
+
if (typeAnnotation) {
|
|
1054
|
+
const sortedTypeKey = typeAnnotation?.sortedTypeKey;
|
|
1055
|
+
if (!typeAnnotationMap[sortedTypeKey]) {
|
|
1056
|
+
typeAnnotationMap[sortedTypeKey] = {
|
|
1057
|
+
typeAnnotation,
|
|
1058
|
+
cases: [],
|
|
1059
|
+
count: 0,
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
const typeAnnotationInfo = typeAnnotationMap[sortedTypeKey];
|
|
1063
|
+
typeAnnotationInfo.cases.push(caseItem);
|
|
1064
|
+
typeAnnotationInfo.count++;
|
|
1065
|
+
const { count } = typeAnnotationInfo;
|
|
1066
|
+
if (maxTypeAnnotationInfo.count < count) {
|
|
1067
|
+
maxTypeAnnotationInfo = {
|
|
1068
|
+
typeAnnotation,
|
|
1069
|
+
count,
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
1072
|
+
return typeAnnotation;
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
});
|
|
1076
|
+
}
|
|
1077
|
+
const { typeAnnotation: maxTypeAnnotation } = maxTypeAnnotationInfo;
|
|
1078
|
+
for (const sortedTypeKey in typeAnnotationMap) {
|
|
1079
|
+
const { typeAnnotation, cases } = typeAnnotationMap[sortedTypeKey];
|
|
1080
|
+
if (maxTypeAnnotation?.sortedTypeKey !== typeAnnotation?.sortedTypeKey) {
|
|
1081
|
+
if (Array.isArray(cases)) {
|
|
1082
|
+
cases.forEach((caseItem) => {
|
|
1083
|
+
const { body } = caseItem || {};
|
|
1084
|
+
const diagnostic = {
|
|
1085
|
+
node: caseItem,
|
|
1086
|
+
severity: 'warning',
|
|
1087
|
+
message: '分支类型不一致',
|
|
1088
|
+
};
|
|
1089
|
+
if (Array.isArray(body) && body.length) {
|
|
1090
|
+
const lastExpression = body[body.length - 1];
|
|
1091
|
+
diagnostic.node = lastExpression;
|
|
1092
|
+
diagnostic.message = `匹配:该分支类型与多数类型不一致,将产生Union类型。当前类型:${typeAnnotation?.headTitle},多数类型:${maxTypeAnnotation?.headTitle}`;
|
|
1093
|
+
this.baseNodeAssignmentTsError(lastExpression, diagnostic);
|
|
1094
|
+
diagnostics.push(diagnostic);
|
|
1095
|
+
}
|
|
1096
|
+
});
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
else if (node instanceof concepts_1.NewList && !node.typeAnnotation) {
|
|
1102
|
+
// 匿名函数返回值有可能是newList,需要过滤。代码来源:AnonymousFunction.__ts
|
|
1103
|
+
const grandParent = node.parentNode?.parentNode?.parentNode;
|
|
1104
|
+
if (grandParent instanceof concepts_1.CallLogic &&
|
|
1105
|
+
/dataSources\.[^.]+\.entities\.[^.]+\.logics/.test(grandParent.calleeNamespace) &&
|
|
1106
|
+
['update', 'updateBy', 'createOrUpdate', 'batchUpdate'].includes(grandParent.calleeName)) {
|
|
1107
|
+
return;
|
|
1108
|
+
}
|
|
1109
|
+
const { items } = node || {};
|
|
1110
|
+
const typeAnnotationMap = {};
|
|
1111
|
+
// 最多数的类型
|
|
1112
|
+
let maxTypeAnnotationInfo = {
|
|
1113
|
+
typeAnnotation: null,
|
|
1114
|
+
count: 0,
|
|
1115
|
+
};
|
|
1116
|
+
if (Array.isArray(items)) {
|
|
1117
|
+
items.forEach((item) => {
|
|
1118
|
+
const typeAnnotation = item.__TypeAnnotation;
|
|
1119
|
+
// 仅处理有类型的情况,返回类型为void的情况由其他地方处理成报错
|
|
1120
|
+
if (typeAnnotation) {
|
|
1121
|
+
const { sortedTypeKey } = typeAnnotation;
|
|
1122
|
+
if (!typeAnnotationMap[sortedTypeKey]) {
|
|
1123
|
+
typeAnnotationMap[sortedTypeKey] = {
|
|
1124
|
+
typeAnnotation,
|
|
1125
|
+
items: [],
|
|
1126
|
+
count: 0,
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1129
|
+
const typeAnnotationInfo = typeAnnotationMap[sortedTypeKey];
|
|
1130
|
+
typeAnnotationInfo.items.push(item);
|
|
1131
|
+
typeAnnotationInfo.count++;
|
|
1132
|
+
const { count } = typeAnnotationInfo;
|
|
1133
|
+
if (maxTypeAnnotationInfo.count < count) {
|
|
1134
|
+
maxTypeAnnotationInfo = {
|
|
1135
|
+
typeAnnotation,
|
|
1136
|
+
count,
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1142
|
+
const { typeAnnotation: maxTypeAnnotation } = maxTypeAnnotationInfo;
|
|
1143
|
+
for (const sortedTypeKey in typeAnnotationMap) {
|
|
1144
|
+
const { typeAnnotation, items } = typeAnnotationMap[sortedTypeKey];
|
|
1145
|
+
if (maxTypeAnnotation?.sortedTypeKey !== typeAnnotation?.sortedTypeKey) {
|
|
1146
|
+
if (Array.isArray(items)) {
|
|
1147
|
+
items.forEach((item) => {
|
|
1148
|
+
const diagnostic = {
|
|
1149
|
+
node: item,
|
|
1150
|
+
severity: 'warning',
|
|
1151
|
+
message: `NewList期望的类型是${maxTypeAnnotation?.headTitle}`,
|
|
1152
|
+
};
|
|
1153
|
+
this.baseNodeAssignmentTsError(item, diagnostic);
|
|
1154
|
+
diagnostics.push(diagnostic);
|
|
1155
|
+
});
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
else if (node instanceof concepts_1.NewMap && !node.typeAnnotation) {
|
|
1161
|
+
const { values } = node || {};
|
|
1162
|
+
const typeAnnotationMap = {};
|
|
1163
|
+
// 最多数的类型
|
|
1164
|
+
let maxTypeAnnotationInfo = {
|
|
1165
|
+
typeAnnotation: null,
|
|
1166
|
+
count: 0,
|
|
1167
|
+
};
|
|
1168
|
+
if (Array.isArray(values)) {
|
|
1169
|
+
values.forEach((value) => {
|
|
1170
|
+
if (!value)
|
|
1171
|
+
return;
|
|
1172
|
+
const typeAnnotation = value.__TypeAnnotation;
|
|
1173
|
+
// 仅处理有类型的情况,返回类型为void的情况由其他地方处理成报错
|
|
1174
|
+
if (typeAnnotation) {
|
|
1175
|
+
const { sortedTypeKey } = typeAnnotation;
|
|
1176
|
+
if (!typeAnnotationMap[sortedTypeKey]) {
|
|
1177
|
+
typeAnnotationMap[sortedTypeKey] = {
|
|
1178
|
+
typeAnnotation,
|
|
1179
|
+
values: [],
|
|
1180
|
+
count: 0,
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
const typeAnnotationInfo = typeAnnotationMap[sortedTypeKey];
|
|
1184
|
+
typeAnnotationInfo.values.push(value);
|
|
1185
|
+
typeAnnotationInfo.count++;
|
|
1186
|
+
const { count } = typeAnnotationInfo;
|
|
1187
|
+
if (maxTypeAnnotationInfo.count < count) {
|
|
1188
|
+
maxTypeAnnotationInfo = {
|
|
1189
|
+
typeAnnotation,
|
|
1190
|
+
count,
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
});
|
|
1195
|
+
}
|
|
1196
|
+
const { typeAnnotation: maxTypeAnnotation } = maxTypeAnnotationInfo;
|
|
1197
|
+
for (const sortedTypeKey in typeAnnotationMap) {
|
|
1198
|
+
const { typeAnnotation, values } = typeAnnotationMap[sortedTypeKey];
|
|
1199
|
+
if (maxTypeAnnotation?.sortedTypeKey !== typeAnnotation?.sortedTypeKey) {
|
|
1200
|
+
if (Array.isArray(values)) {
|
|
1201
|
+
values.forEach((value) => {
|
|
1202
|
+
const diagnostic = {
|
|
1203
|
+
node: value,
|
|
1204
|
+
severity: 'warning',
|
|
1205
|
+
message: `NewMap中values值所期望的类型是${maxTypeAnnotation?.headTitle}`,
|
|
1206
|
+
};
|
|
1207
|
+
this.baseNodeAssignmentTsError(value, diagnostic);
|
|
1208
|
+
diagnostics.push(diagnostic);
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
else if (node.concept === 'JSBlock') {
|
|
1215
|
+
// 初始js代码块先屏蔽掉
|
|
1216
|
+
if (node.code === `location.href = '/';`) {
|
|
1217
|
+
return null;
|
|
1218
|
+
}
|
|
1219
|
+
if (node?.code?.includes('use JSBlock')) {
|
|
1220
|
+
return null;
|
|
1221
|
+
}
|
|
1222
|
+
const diagnostic = {
|
|
1223
|
+
node,
|
|
1224
|
+
severity: 'warning',
|
|
1225
|
+
message: '不建议使用js代码块',
|
|
1226
|
+
};
|
|
1227
|
+
diagnostics.push(diagnostic);
|
|
1228
|
+
}
|
|
1229
|
+
else if (node.concept === 'Unparsed') {
|
|
1230
|
+
const diagnostic = {
|
|
1231
|
+
node,
|
|
1232
|
+
severity: 'warning',
|
|
1233
|
+
message: '不建议使用自定义表达式',
|
|
1234
|
+
};
|
|
1235
|
+
diagnostics.push(diagnostic);
|
|
1236
|
+
}
|
|
1237
|
+
else if (node instanceof concepts_1.CallQueryComponent) {
|
|
1238
|
+
// 可视化查询中不允许有复杂的数据结构
|
|
1239
|
+
const contentVariables = [];
|
|
1240
|
+
utils.traverse(({ node }) => {
|
|
1241
|
+
if (node?.parentNode?.concept !== 'MemberExpression') {
|
|
1242
|
+
if (node?.concept === 'MemberExpression') {
|
|
1243
|
+
contentVariables.push(node);
|
|
1244
|
+
}
|
|
1245
|
+
else if (node?.concept === 'Identifier') {
|
|
1246
|
+
// 因为要是父级是MemberExpression, 就放入了父级,子级就不需要了
|
|
1247
|
+
contentVariables.push(node);
|
|
1248
|
+
// QueryFromExpression QueryJoinExpression
|
|
1249
|
+
}
|
|
1250
|
+
else if ((node?.concept === 'QueryFieldExpression' && !node.isDotStar) ||
|
|
1251
|
+
node?.concept === 'QueryGroupByExpression') {
|
|
1252
|
+
contentVariables.push(node);
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
}, { node }, {
|
|
1256
|
+
mode: 'anyObject',
|
|
1257
|
+
excludedKeySet: new Set(['parentNode', '_events', 'globalDataMap', 'havingPlayground', 'wherePlayground']),
|
|
1258
|
+
});
|
|
1259
|
+
contentVariables?.forEach((variable) => {
|
|
1260
|
+
// 如果是复杂数据结构
|
|
1261
|
+
if (variable.__TypeAnnotation?.isComplexType()) {
|
|
1262
|
+
if (variable.__TypeAnnotation?.typeName === 'List' && variable.__TypeAnnotation?.typeArguments?.[0]?.typeKind === 'primitive') {
|
|
1263
|
+
return;
|
|
1264
|
+
}
|
|
1265
|
+
const diagnostic = {
|
|
1266
|
+
node,
|
|
1267
|
+
severity: 'warning',
|
|
1268
|
+
message: `数据查询中不可以使用复杂类型!当前类型:${variable.__TypeAnnotation?.typeChineseTitle}。`,
|
|
1269
|
+
};
|
|
1270
|
+
this.baseNodeAssignmentTsError(variable, diagnostic);
|
|
1271
|
+
diagnostics.push(diagnostic);
|
|
1272
|
+
}
|
|
1273
|
+
else if (variable.__TypeAnnotation?.hasSystemType(node.app)) {
|
|
1274
|
+
const diagnostic = {
|
|
1275
|
+
node,
|
|
1276
|
+
severity: 'warning',
|
|
1277
|
+
message: `数据查询中不可以使用或包含系统类型!当前类型:${variable.__TypeAnnotation?.typeChineseTitle}。`,
|
|
1278
|
+
};
|
|
1279
|
+
this.baseNodeAssignmentTsError(variable, diagnostic);
|
|
1280
|
+
diagnostics.push(diagnostic);
|
|
1281
|
+
}
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
return diagnostics;
|
|
1287
|
+
}
|
|
1288
|
+
// 是否包含组件逻辑
|
|
1289
|
+
hasComponentLogics(expression) {
|
|
1290
|
+
let flag = false;
|
|
1291
|
+
(0, utils_1.traverse)((current) => {
|
|
1292
|
+
const { node } = current || {};
|
|
1293
|
+
const { concept } = node || {};
|
|
1294
|
+
if (concept === 'CallLogic') {
|
|
1295
|
+
// 调用组件逻辑
|
|
1296
|
+
if (node.isComponentLogic) {
|
|
1297
|
+
flag = true;
|
|
1298
|
+
}
|
|
1299
|
+
else if (node.isViewLogic) {
|
|
1300
|
+
// 调用页面逻辑
|
|
1301
|
+
const logicNode = node.view?.logics?.find?.((viewLogic) => viewLogic.name === node.calleeName);
|
|
1302
|
+
if (logicNode) {
|
|
1303
|
+
if (this.logicSetWithComponentLogic.has(logicNode.nodePath)) {
|
|
1304
|
+
flag = true;
|
|
1305
|
+
}
|
|
1306
|
+
else {
|
|
1307
|
+
const logicItem = logicNode.body?.find?.((logicItem) => this.hasComponentLogics(logicItem));
|
|
1308
|
+
if (logicItem) {
|
|
1309
|
+
flag = true;
|
|
1310
|
+
this.logicSetWithComponentLogic.add(logicNode.nodePath);
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
}, {
|
|
1317
|
+
node: expression,
|
|
1318
|
+
}, {
|
|
1319
|
+
mode: 'anyObject',
|
|
1320
|
+
excludedKeySet: new Set([
|
|
1321
|
+
'parentNode',
|
|
1322
|
+
'sourceMap',
|
|
1323
|
+
'storageJSON',
|
|
1324
|
+
'tsErrorDetail',
|
|
1325
|
+
'NaslAnnotatedJSON',
|
|
1326
|
+
'calledFrom',
|
|
1327
|
+
'_events',
|
|
1328
|
+
'_collectingList',
|
|
1329
|
+
'_historyList',
|
|
1330
|
+
]),
|
|
1331
|
+
});
|
|
1332
|
+
return flag;
|
|
1333
|
+
}
|
|
1334
|
+
/** 是否被 触发器依赖, 如果存在,返回第一个触发器对应的名称 */
|
|
1335
|
+
isRefedByTriggerAndReturnFirstRef(fileNode) {
|
|
1336
|
+
return this._isHaveRef(fileNode).then((refs) => {
|
|
1337
|
+
const basePath = concepts_1.TriggerLauncher.getEmbeddedFileBasePath(fileNode.rootNode);
|
|
1338
|
+
let flag = false;
|
|
1339
|
+
let fRefName = '';
|
|
1340
|
+
try {
|
|
1341
|
+
for (const ref of refs) {
|
|
1342
|
+
const { file } = ref;
|
|
1343
|
+
if (file.startsWith(basePath)) {
|
|
1344
|
+
flag = true;
|
|
1345
|
+
// file: /embedded/tttta/triggerLaunchers/订阅配置_asd.ts
|
|
1346
|
+
fRefName = file.split(basePath)[1].split('.')[0];
|
|
1347
|
+
break;
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
catch (error) {
|
|
1352
|
+
console.error(error, refs);
|
|
1353
|
+
}
|
|
1354
|
+
return {
|
|
1355
|
+
isRefedByTrigger: flag,
|
|
1356
|
+
fRefName,
|
|
1357
|
+
};
|
|
1358
|
+
});
|
|
1359
|
+
// const refs = await this._isHaveRef(fileNode);
|
|
1360
|
+
// const basePath = TriggerLauncher.getEmbeddedFileBasePath(fileNode.rootNode as App);
|
|
1361
|
+
// let flag = false;
|
|
1362
|
+
// let fRefName = '';
|
|
1363
|
+
// try {
|
|
1364
|
+
// for (const ref of refs) {
|
|
1365
|
+
// const { file } = ref;
|
|
1366
|
+
// if (file.startsWith(basePath)) {
|
|
1367
|
+
// flag = true;
|
|
1368
|
+
// // file: /embedded/tttta/triggerLaunchers/订阅配置_asd.ts
|
|
1369
|
+
// fRefName = file.split(basePath)[1].split('.')[0];
|
|
1370
|
+
// break;
|
|
1371
|
+
// }
|
|
1372
|
+
// }
|
|
1373
|
+
// } catch (error) {
|
|
1374
|
+
// console.error(error, refs);
|
|
1375
|
+
// }
|
|
1376
|
+
// return {
|
|
1377
|
+
// isRefedByTrigger: flag,
|
|
1378
|
+
// fRefName,
|
|
1379
|
+
// };
|
|
1380
|
+
}
|
|
1381
|
+
/**
|
|
1382
|
+
* 是否符合 触发器规则
|
|
1383
|
+
* 规则:
|
|
1384
|
+
* 1. 入参仅有一个,且必须为string类型
|
|
1385
|
+
* 2. 不允许有返回值
|
|
1386
|
+
*/
|
|
1387
|
+
isTriggerRule(fileNode) {
|
|
1388
|
+
const { sourceMap } = fileNode;
|
|
1389
|
+
let paramsLength = 0;
|
|
1390
|
+
let returnLength = 0;
|
|
1391
|
+
let flag = true;
|
|
1392
|
+
sourceMap.forEach((_, k) => {
|
|
1393
|
+
if (k instanceof concepts_1.Param) {
|
|
1394
|
+
paramsLength++;
|
|
1395
|
+
const typeAnnotation = k.typeAnnotation || k.__TypeAnnotation;
|
|
1396
|
+
const { typeKind, typeName, typeNamespace } = typeAnnotation || {};
|
|
1397
|
+
const isString = typeKind === 'primitive' && typeName === 'String' && typeNamespace === 'nasl.core';
|
|
1398
|
+
if (!isString) {
|
|
1399
|
+
flag = false;
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
if (k instanceof concepts_1.Return) {
|
|
1403
|
+
returnLength++;
|
|
1404
|
+
}
|
|
1405
|
+
});
|
|
1406
|
+
return paramsLength === 1 && flag && returnLength === 0;
|
|
1407
|
+
}
|
|
1408
|
+
/**
|
|
1409
|
+
* 额外的诊断
|
|
1410
|
+
* @param fileNode 文件级别的节点
|
|
1411
|
+
* @returns 诊断结果
|
|
1412
|
+
*/
|
|
1413
|
+
*_attachDiagnosticsWithGenerator(fileNode) {
|
|
1414
|
+
// 每次诊断前先清空这个Set
|
|
1415
|
+
this.logicSetWithComponentLogic = new Set();
|
|
1416
|
+
const self = this;
|
|
1417
|
+
const diagnostics = [];
|
|
1418
|
+
if (fileNode instanceof concepts_1.View || fileNode instanceof concepts_1.BusinessComponent) {
|
|
1419
|
+
yield* utils.wrapIteratorToGenerator(fileNode.sourceMap.entries(), function* attachView([node, value]) {
|
|
1420
|
+
const likeComponent = node.getAncestor('View') || node.getAncestor('BusinessComponent');
|
|
1421
|
+
if (node instanceof concepts_1.ViewElement && likeComponent === fileNode) {
|
|
1422
|
+
if (node.tag) {
|
|
1423
|
+
yield* utils.wrapForEachToGenerator(node.bindAttrs, (bindAttr) => {
|
|
1424
|
+
if ((bindAttr.model || bindAttr.sync) && bindAttr.expression) {
|
|
1425
|
+
const bindExpression = bindAttr.expression;
|
|
1426
|
+
let diagnostic;
|
|
1427
|
+
if (bindExpression.concept === 'MemberExpression') {
|
|
1428
|
+
let current = bindExpression;
|
|
1429
|
+
if (bindExpression.isEnum()) {
|
|
1430
|
+
diagnostic = {
|
|
1431
|
+
node: bindExpression,
|
|
1432
|
+
severity: 'error',
|
|
1433
|
+
message: '页面组件属性表达式:该表达式不支持获取组件输入内容,请改为可赋值的变量或属性。',
|
|
1434
|
+
};
|
|
1435
|
+
}
|
|
1436
|
+
else {
|
|
1437
|
+
while (current.object) {
|
|
1438
|
+
if (current.object.concept !== 'MemberExpression' && current.object.concept !== 'Identifier') {
|
|
1439
|
+
diagnostic = {
|
|
1440
|
+
node: bindExpression,
|
|
1441
|
+
severity: 'error',
|
|
1442
|
+
message: '页面组件属性表达式:该表达式不支持获取组件输入内容,请改为可赋值的变量或属性。',
|
|
1443
|
+
};
|
|
1444
|
+
break;
|
|
1445
|
+
}
|
|
1446
|
+
current = current.object;
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
else if (bindExpression.concept !== 'Identifier') {
|
|
1451
|
+
diagnostic = {
|
|
1452
|
+
node: bindExpression,
|
|
1453
|
+
severity: 'error',
|
|
1454
|
+
message: '页面组件属性表达式:该表达式不支持获取组件输入内容,请改为可赋值的变量或属性。',
|
|
1455
|
+
};
|
|
1456
|
+
}
|
|
1457
|
+
if (diagnostic) {
|
|
1458
|
+
bindExpression.tsErrorDetail = diagnostic;
|
|
1459
|
+
diagnostics.push(diagnostic);
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
});
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
else if ((node instanceof concepts_1.Variable || node instanceof concepts_1.Return) && likeComponent === fileNode) {
|
|
1466
|
+
if (!node.typeAnnotation && !node.__TypeAnnotation) {
|
|
1467
|
+
const nodeTypeName = node.concept === 'Return' ? '输出参数' : '局部变量';
|
|
1468
|
+
let msg;
|
|
1469
|
+
yield* fileNode.traverseChildrenGenerator((nodeIn) => {
|
|
1470
|
+
if (nodeIn && (nodeIn instanceof concepts_1.BatchAssignment || (nodeIn instanceof concepts_1.Assignment && nodeIn.left?.name))) {
|
|
1471
|
+
// 子页面内部逻辑过滤
|
|
1472
|
+
if ((nodeIn.view || nodeIn.getAncestor('BusinessComponent')) !== fileNode)
|
|
1473
|
+
return;
|
|
1474
|
+
// 当局部变量、输出参数属于页面内逻辑时,需过滤同页面下不同逻辑下的同名变量
|
|
1475
|
+
if (node.logic && node.logic !== nodeIn.logic)
|
|
1476
|
+
return;
|
|
1477
|
+
// 跟变量无关的赋值过滤
|
|
1478
|
+
let jsCode = '';
|
|
1479
|
+
try {
|
|
1480
|
+
jsCode = nodeIn.toJS();
|
|
1481
|
+
}
|
|
1482
|
+
catch (err) {
|
|
1483
|
+
console.log(err);
|
|
1484
|
+
}
|
|
1485
|
+
if (!jsCode.startsWith(`${node.name} = `))
|
|
1486
|
+
return;
|
|
1487
|
+
// 页面局部变量
|
|
1488
|
+
if (node instanceof concepts_1.Variable && node.parentNode instanceof concepts_1.View) {
|
|
1489
|
+
// 跟页面局部变量无关的赋值过滤
|
|
1490
|
+
if (!jsCode.startsWith(`this.${node.name} = `))
|
|
1491
|
+
return;
|
|
1492
|
+
// 直接赋值 logic 内局部变量、输入参数直接提示系统无法推断类型
|
|
1493
|
+
if (nodeIn.logic?.params.find((param) => jsCode.startsWith(param.name)) ||
|
|
1494
|
+
nodeIn.logic?.virtualParams.find((vParam) => jsCode.startsWith(vParam.name)) ||
|
|
1495
|
+
nodeIn.logic?.variables.find((variable) => jsCode.startsWith(variable.name))) {
|
|
1496
|
+
if (!nodeIn.tsErrorDetail) {
|
|
1497
|
+
const diagnostic = {
|
|
1498
|
+
node: nodeIn,
|
|
1499
|
+
severity: 'error',
|
|
1500
|
+
message: `页面${nodeTypeName} ${node.name} 赋值页面逻辑内局部变量或输入参数时,系统无法推导类型。`,
|
|
1501
|
+
};
|
|
1502
|
+
nodeIn.tsErrorDetail = diagnostic;
|
|
1503
|
+
diagnostics.push(diagnostic);
|
|
1504
|
+
}
|
|
1505
|
+
msg = '系统无法推断类型。';
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
if (!nodeIn.tsErrorDetail) {
|
|
1509
|
+
const diagnostic = {
|
|
1510
|
+
node: nodeIn,
|
|
1511
|
+
severity: 'error',
|
|
1512
|
+
message: `${nodeIn.label}左边 ${node.name} 未设置类型,右边必须为有返回值的内容。`,
|
|
1513
|
+
};
|
|
1514
|
+
nodeIn.tsErrorDetail = diagnostic;
|
|
1515
|
+
diagnostics.push(diagnostic);
|
|
1516
|
+
}
|
|
1517
|
+
msg = '必须赋值有返回值的内容。';
|
|
1518
|
+
}
|
|
1519
|
+
});
|
|
1520
|
+
if (!msg)
|
|
1521
|
+
msg = '未设置类型或未赋值。直接赋值系统可以自动推断类型。';
|
|
1522
|
+
const diagnostic = {
|
|
1523
|
+
node,
|
|
1524
|
+
severity: 'error',
|
|
1525
|
+
message: `${nodeTypeName} ${node.name} ${msg}`,
|
|
1526
|
+
};
|
|
1527
|
+
node.tsErrorDetail = diagnostic;
|
|
1528
|
+
diagnostics.push(diagnostic);
|
|
1529
|
+
}
|
|
1530
|
+
const fileSourceCode = self.getNodeCode(fileNode, value);
|
|
1531
|
+
if (fileSourceCode.includes('|') && fileSourceCode.includes('.metadataTypes.')) {
|
|
1532
|
+
const typeAnnotation = node.typeAnnotation.toJSON();
|
|
1533
|
+
yield* self._treeMetadataType2CoreType(typeAnnotation, node.rootNode);
|
|
1534
|
+
const isDuplicate = yield* self._isDuplicateCoreType(typeAnnotation);
|
|
1535
|
+
if (isDuplicate) {
|
|
1536
|
+
const diagnostic = {
|
|
1537
|
+
node,
|
|
1538
|
+
severity: 'error',
|
|
1539
|
+
message: `变量 ${node.name} 类型定义包含相同的数据类型`,
|
|
1540
|
+
};
|
|
1541
|
+
diagnostics.push(diagnostic);
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
else if (node instanceof concepts_1.BindAttribute || node instanceof concepts_1.BindDirective || node instanceof concepts_1.BindStyle) {
|
|
1546
|
+
if (Array.isArray(node.bindExpressions)) {
|
|
1547
|
+
const exp = node.bindExpressions.find((bindExpression) => self.hasComponentLogics(bindExpression));
|
|
1548
|
+
if (exp) {
|
|
1549
|
+
// const element: any = node.getAncestor('ViewElement');
|
|
1550
|
+
// const api = config.allNodesAPI[element?.tag];
|
|
1551
|
+
// const attr = api?.attrs?.find?.((attr) => {
|
|
1552
|
+
// return attr.name === node.name;
|
|
1553
|
+
// });
|
|
1554
|
+
const map = {
|
|
1555
|
+
BindAttribute: '属性',
|
|
1556
|
+
BindDirective: '指令',
|
|
1557
|
+
BindStyle: '样式属性',
|
|
1558
|
+
};
|
|
1559
|
+
// “${attr?.title || node.title || node.name}”
|
|
1560
|
+
const diagnostic = {
|
|
1561
|
+
node,
|
|
1562
|
+
severity: 'error',
|
|
1563
|
+
message: `${map[node.concept]}表达式不能绑定组件逻辑`,
|
|
1564
|
+
};
|
|
1565
|
+
node.tsErrorDetail = diagnostic;
|
|
1566
|
+
diagnostics.push(diagnostic);
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
else if (node instanceof concepts_1.CallInterface) {
|
|
1571
|
+
const isAuthInterface = self.hasAuth(node);
|
|
1572
|
+
const interfaceName = node.calleewholeKey.slice(node.calleewholeKey.lastIndexOf('.') + 1);
|
|
1573
|
+
if (isAuthInterface) {
|
|
1574
|
+
const errorMsg = `${interfaceName} 接口有鉴权方式,不支持在前端调用`;
|
|
1575
|
+
const diagnostic = {
|
|
1576
|
+
node,
|
|
1577
|
+
severity: 'error',
|
|
1578
|
+
message: errorMsg,
|
|
1579
|
+
};
|
|
1580
|
+
diagnostics.push(diagnostic);
|
|
1581
|
+
node.tsErrorDetail = diagnostic;
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
else if (node instanceof concepts_1.Identifier) {
|
|
1585
|
+
// 变量如果选到了页面,因为ts会找到兄弟的同名变量,所以需要新增报错,通过类型来判断加不加
|
|
1586
|
+
// https://projectmanage.netease-official.lcap.163yun.com/dashboard/BugDetail?id=2696136968961024
|
|
1587
|
+
if (node.name && node.__TypeAnnotation?.typeKind === 'reference' && node.__TypeAnnotation?.typeNamespace?.endsWith('views')) {
|
|
1588
|
+
const errorMsg = `找不到 ${node.name}。`;
|
|
1589
|
+
const diagnostic = {
|
|
1590
|
+
node,
|
|
1591
|
+
severity: 'error',
|
|
1592
|
+
message: errorMsg,
|
|
1593
|
+
};
|
|
1594
|
+
diagnostics.push(diagnostic);
|
|
1595
|
+
node.tsErrorDetail = diagnostic;
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
else {
|
|
1599
|
+
self.checkNodeError(node, diagnostics);
|
|
1600
|
+
}
|
|
1601
|
+
});
|
|
1602
|
+
}
|
|
1603
|
+
else if (fileNode instanceof concepts_1.DataSource) {
|
|
1604
|
+
const dataSourceGroup = fileNode.rootNode.configuration?.getGroup('dataSource');
|
|
1605
|
+
if (dataSourceGroup) {
|
|
1606
|
+
const property = dataSourceGroup.getProperty(fileNode.name);
|
|
1607
|
+
if (property && property.values) {
|
|
1608
|
+
yield* utils.wrapForEachToGenerator(property.values, (propertyValue) => {
|
|
1609
|
+
if (!propertyValue.value && fileNode.name !== 'defaultDS') {
|
|
1610
|
+
const diagnostic = {
|
|
1611
|
+
node: fileNode,
|
|
1612
|
+
severity: 'error',
|
|
1613
|
+
message: `数据源配置:数据源${property.name}${propertyValue.env === 'dev' ? '开发环境' : '生产环境'}未配置数据信息`,
|
|
1614
|
+
// 保留原来的内容方便查询一些问题
|
|
1615
|
+
originalDiagnostic: {
|
|
1616
|
+
fileName: '',
|
|
1617
|
+
start: null,
|
|
1618
|
+
end: null,
|
|
1619
|
+
category: 'error',
|
|
1620
|
+
text: `Data Source is not config`,
|
|
1621
|
+
},
|
|
1622
|
+
};
|
|
1623
|
+
diagnostics.push(diagnostic);
|
|
1624
|
+
}
|
|
1625
|
+
else if (propertyValue.value) {
|
|
1626
|
+
const dataSource = fileNode;
|
|
1627
|
+
// 数据源有连接错误
|
|
1628
|
+
let envText;
|
|
1629
|
+
if (propertyValue.env === 'dev') {
|
|
1630
|
+
if (dataSource.__devConnectError) {
|
|
1631
|
+
envText = '开发';
|
|
1632
|
+
}
|
|
1633
|
+
else if (dataSource.__devConnectError === false) {
|
|
1634
|
+
return;
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
else if (propertyValue.env === 'online') {
|
|
1638
|
+
if (dataSource.__onlineConnectError) {
|
|
1639
|
+
envText = '生产';
|
|
1640
|
+
}
|
|
1641
|
+
else if (dataSource.__onlineConnectError === false) {
|
|
1642
|
+
return;
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
// 手动插入报错
|
|
1646
|
+
if (envText) {
|
|
1647
|
+
const diagnostic = {
|
|
1648
|
+
node: fileNode,
|
|
1649
|
+
severity: 'warning',
|
|
1650
|
+
message: `数据源配置:数据源 ${property.name} ${envText}环境数据源连接不通,请先检查${envText}环境数据源配置`,
|
|
1651
|
+
// 保留原来的内容方便查询一些问题
|
|
1652
|
+
originalDiagnostic: {
|
|
1653
|
+
fileName: '',
|
|
1654
|
+
start: null,
|
|
1655
|
+
end: null,
|
|
1656
|
+
category: 'warning',
|
|
1657
|
+
text: `DataSource connection error`,
|
|
1658
|
+
},
|
|
1659
|
+
};
|
|
1660
|
+
return diagnostics.push(diagnostic);
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
});
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
// 加上对实体属性存储类型的校验规则
|
|
1668
|
+
else if (fileNode instanceof concepts_1.Entity) {
|
|
1669
|
+
const entity = fileNode;
|
|
1670
|
+
const dbType = entity.dataSource.dataSourceSqlType;
|
|
1671
|
+
const { origin, properties } = entity || {};
|
|
1672
|
+
if (dbType && !['excel', 'table'].includes(origin) && Array.isArray(properties) && properties.length) {
|
|
1673
|
+
properties.forEach((property) => {
|
|
1674
|
+
if (property) {
|
|
1675
|
+
const { typeAnnotation, databaseTypeAnnotation, rules } = property;
|
|
1676
|
+
const { typeName } = typeAnnotation || {};
|
|
1677
|
+
const rulesMap = {};
|
|
1678
|
+
if (Array.isArray(rules)) {
|
|
1679
|
+
rules.forEach((rule) => {
|
|
1680
|
+
const match = rule?.match(/^([^()]+)\(([\d\-.]+)\)$/);
|
|
1681
|
+
if (match) {
|
|
1682
|
+
const [, key, value] = match;
|
|
1683
|
+
rulesMap[key] = value;
|
|
1684
|
+
}
|
|
1685
|
+
});
|
|
1686
|
+
}
|
|
1687
|
+
const diagnostic = {
|
|
1688
|
+
node: property,
|
|
1689
|
+
severity: 'error',
|
|
1690
|
+
message: '',
|
|
1691
|
+
};
|
|
1692
|
+
const dataBaseTyp = property.currentDataBaseType;
|
|
1693
|
+
typeAnnotation.tsErrorDetail = null;
|
|
1694
|
+
if (!dataBaseTyp && databaseTypeAnnotation) {
|
|
1695
|
+
const { typeName: databaseTypeName } = databaseTypeAnnotation;
|
|
1696
|
+
const errorMsg = `平台目前暂不支持${dbType}数据库的${databaseTypeName}存储类型`;
|
|
1697
|
+
diagnostic.message = errorMsg;
|
|
1698
|
+
const tsErrorDetail = {
|
|
1699
|
+
severity: 'error',
|
|
1700
|
+
errorPos: {
|
|
1701
|
+
typeName: errorMsg,
|
|
1702
|
+
},
|
|
1703
|
+
};
|
|
1704
|
+
databaseTypeAnnotation.tsErrorDetail = tsErrorDetail;
|
|
1705
|
+
}
|
|
1706
|
+
else {
|
|
1707
|
+
const { options } = dataBaseTyp || {};
|
|
1708
|
+
if (options) {
|
|
1709
|
+
if (databaseTypeAnnotation) {
|
|
1710
|
+
databaseTypeAnnotation.tsErrorDetail = null;
|
|
1711
|
+
const databaseTypeAnnotationErrorDetail = {
|
|
1712
|
+
severity: 'error',
|
|
1713
|
+
errorPos: {},
|
|
1714
|
+
};
|
|
1715
|
+
for (const key in options) {
|
|
1716
|
+
const option = options[key];
|
|
1717
|
+
const { comment, require, min, max } = option || {};
|
|
1718
|
+
const databaseTypeArg = databaseTypeAnnotation.arguments?.[key];
|
|
1719
|
+
// 如果必填的值没有填,报错
|
|
1720
|
+
if (require && !databaseTypeArg && key !== 'scale') {
|
|
1721
|
+
diagnostic.message = `${comment}不能为空`;
|
|
1722
|
+
databaseTypeAnnotationErrorDetail.errorPos[key] = `${comment}不能为空`;
|
|
1723
|
+
}
|
|
1724
|
+
else if (min && +min > +databaseTypeArg) {
|
|
1725
|
+
diagnostic.message = `${comment}不能小于最小值${min}`;
|
|
1726
|
+
databaseTypeAnnotationErrorDetail.errorPos[key] = `${comment}不能小于最小值${min}`;
|
|
1727
|
+
}
|
|
1728
|
+
else if (max && +max < +databaseTypeArg) {
|
|
1729
|
+
diagnostic.message = `${comment}不能大于最大值${max}`;
|
|
1730
|
+
databaseTypeAnnotationErrorDetail.errorPos[key] = `${comment}不能大于最大值${max}`;
|
|
1731
|
+
}
|
|
1732
|
+
if (Object.keys(databaseTypeAnnotationErrorDetail.errorPos).length) {
|
|
1733
|
+
databaseTypeAnnotation.tsErrorDetail = databaseTypeAnnotationErrorDetail;
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
const typeAnnotationErrorDetail = {
|
|
1738
|
+
severity: 'warning',
|
|
1739
|
+
errorPos: {},
|
|
1740
|
+
};
|
|
1741
|
+
const precisionOption = options?.precision;
|
|
1742
|
+
const { default: defaultVal } = precisionOption || {};
|
|
1743
|
+
const precision = databaseTypeAnnotation ? databaseTypeAnnotation.arguments?.precision : defaultVal;
|
|
1744
|
+
const ruleScale = typeAnnotation?.ruleMap?.scale;
|
|
1745
|
+
const scale = ruleScale !== undefined ? `${ruleScale}` : '';
|
|
1746
|
+
let ensureScale = true;
|
|
1747
|
+
switch (typeName) {
|
|
1748
|
+
case 'String': {
|
|
1749
|
+
const defaultVal = options.length?.default;
|
|
1750
|
+
const length = databaseTypeAnnotation ? databaseTypeAnnotation.arguments?.length : defaultVal;
|
|
1751
|
+
if (length) {
|
|
1752
|
+
[
|
|
1753
|
+
{
|
|
1754
|
+
key: 'minLength',
|
|
1755
|
+
text: '小',
|
|
1756
|
+
},
|
|
1757
|
+
{
|
|
1758
|
+
key: 'maxLength',
|
|
1759
|
+
text: '大',
|
|
1760
|
+
},
|
|
1761
|
+
].forEach(({ key, text }) => {
|
|
1762
|
+
const curLength = rulesMap[key];
|
|
1763
|
+
if (+curLength > +length) {
|
|
1764
|
+
const errorMsg = `最${text}长度超出存储长度`;
|
|
1765
|
+
const diag = {
|
|
1766
|
+
node: property,
|
|
1767
|
+
severity: 'warning',
|
|
1768
|
+
message: errorMsg,
|
|
1769
|
+
};
|
|
1770
|
+
diagnostics.push(diag);
|
|
1771
|
+
typeAnnotationErrorDetail.errorPos[key] = errorMsg;
|
|
1772
|
+
}
|
|
1773
|
+
});
|
|
1774
|
+
}
|
|
1775
|
+
else if (rulesMap?.maxLength && +dataBaseTyp?.max && +rulesMap.maxLength > +dataBaseTyp.max) {
|
|
1776
|
+
// 判断当前 最大长度 是不是比 数据库类型的最大长度 长,超过就报错
|
|
1777
|
+
const errorMsg = `最大长度超出存储长度`;
|
|
1778
|
+
const diag = {
|
|
1779
|
+
node: property,
|
|
1780
|
+
severity: 'warning',
|
|
1781
|
+
message: errorMsg,
|
|
1782
|
+
};
|
|
1783
|
+
diagnostics.push(diag);
|
|
1784
|
+
typeAnnotationErrorDetail.errorPos.maxLength = errorMsg;
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
case 'Long': {
|
|
1788
|
+
const { min: ruleMin, max: ruleMax } = dataBaseTyp;
|
|
1789
|
+
const minVal = rulesMap.min;
|
|
1790
|
+
const maxVal = rulesMap.max;
|
|
1791
|
+
// 最大最小值都要校验存储上下限
|
|
1792
|
+
[
|
|
1793
|
+
{
|
|
1794
|
+
key: 'min',
|
|
1795
|
+
name: '最小值',
|
|
1796
|
+
value: minVal,
|
|
1797
|
+
},
|
|
1798
|
+
{
|
|
1799
|
+
key: 'max',
|
|
1800
|
+
name: '最大值',
|
|
1801
|
+
value: maxVal,
|
|
1802
|
+
},
|
|
1803
|
+
].forEach(({ key, name, value }) => {
|
|
1804
|
+
if (ruleMin && value && new decimal_js_1.Decimal(ruleMin).greaterThan(new decimal_js_1.Decimal(value))) {
|
|
1805
|
+
// 超出存储下限
|
|
1806
|
+
const diag = {
|
|
1807
|
+
node: property,
|
|
1808
|
+
severity: 'warning',
|
|
1809
|
+
message: `${name}超出存储下限${ruleMin}`,
|
|
1810
|
+
};
|
|
1811
|
+
diagnostics.push(diag);
|
|
1812
|
+
typeAnnotationErrorDetail.errorPos[key] = `${name}超出存储下限`;
|
|
1813
|
+
}
|
|
1814
|
+
if (ruleMax && value && new decimal_js_1.Decimal(ruleMax).lessThan(new decimal_js_1.Decimal(value))) {
|
|
1815
|
+
// 超出存储上限
|
|
1816
|
+
const diag = {
|
|
1817
|
+
node: property,
|
|
1818
|
+
severity: 'warning',
|
|
1819
|
+
message: `${name}超出存储上限${ruleMax}`,
|
|
1820
|
+
};
|
|
1821
|
+
diagnostics.push(diag);
|
|
1822
|
+
typeAnnotationErrorDetail.errorPos[key] = `${name}超出存储上限`;
|
|
1823
|
+
}
|
|
1824
|
+
});
|
|
1825
|
+
break;
|
|
1826
|
+
}
|
|
1827
|
+
case 'Decimal': {
|
|
1828
|
+
if (precisionOption) {
|
|
1829
|
+
if (+precision < +scale) {
|
|
1830
|
+
const diag = {
|
|
1831
|
+
node: property,
|
|
1832
|
+
severity: 'error',
|
|
1833
|
+
message: '',
|
|
1834
|
+
};
|
|
1835
|
+
const errorMsg = `小数位数必须小于或等于精度${precision}`;
|
|
1836
|
+
diag.message = errorMsg;
|
|
1837
|
+
diagnostics.push(diag);
|
|
1838
|
+
ensureScale = false;
|
|
1839
|
+
typeAnnotationErrorDetail.errorPos.scale = errorMsg;
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
break;
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
const minVal = rulesMap.min;
|
|
1846
|
+
const maxVal = rulesMap.max;
|
|
1847
|
+
// 最 大/小 值不能 大/于 由精度和小数位数 确定的范围
|
|
1848
|
+
if (precisionOption && ensureScale) {
|
|
1849
|
+
const memoryStr = '9'.repeat(+precision);
|
|
1850
|
+
// 储存整数部分
|
|
1851
|
+
const memoryIntAbsStr = memoryStr.slice(0, +precision - +(scale || '0')) || '0';
|
|
1852
|
+
// 储存小数部分
|
|
1853
|
+
const memoryScaleStr = memoryStr.slice(0, +(scale || '0'));
|
|
1854
|
+
// 储存绝对值
|
|
1855
|
+
const memoryAbsVal = memoryIntAbsStr + (memoryScaleStr ? `.${memoryScaleStr}` : '');
|
|
1856
|
+
const decimalMemoryAbsVal = new decimal_js_1.Decimal(memoryAbsVal);
|
|
1857
|
+
[
|
|
1858
|
+
{
|
|
1859
|
+
key: 'min',
|
|
1860
|
+
text: '小',
|
|
1861
|
+
val: minVal,
|
|
1862
|
+
},
|
|
1863
|
+
{
|
|
1864
|
+
key: 'max',
|
|
1865
|
+
text: '大',
|
|
1866
|
+
val: maxVal,
|
|
1867
|
+
},
|
|
1868
|
+
].forEach(({ key, text, val }) => {
|
|
1869
|
+
if (val) {
|
|
1870
|
+
const decimalVal = new decimal_js_1.Decimal(val);
|
|
1871
|
+
// 是否是负数
|
|
1872
|
+
const isNegative = decimalVal.isNegative();
|
|
1873
|
+
// 填入的值的绝对值是否大于存储绝对值
|
|
1874
|
+
if (decimalMemoryAbsVal.lessThan(decimalVal.abs())) {
|
|
1875
|
+
const errorMsg = `最${text}值不得${isNegative ? '小' : '大'}于${isNegative ? '-' : ''}${memoryAbsVal}`;
|
|
1876
|
+
const diag = {
|
|
1877
|
+
node: property,
|
|
1878
|
+
severity: 'warning',
|
|
1879
|
+
message: errorMsg,
|
|
1880
|
+
};
|
|
1881
|
+
diagnostics.push(diag);
|
|
1882
|
+
typeAnnotationErrorDetail.errorPos[key] = errorMsg;
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
});
|
|
1886
|
+
}
|
|
1887
|
+
if (['Long', 'Decimal'].includes(typeName) && !typeAnnotationErrorDetail.errorPos.min) {
|
|
1888
|
+
if (minVal && maxVal && new decimal_js_1.Decimal(maxVal).lessThan(minVal)) {
|
|
1889
|
+
const errorMsg = '最小值不得大于最大值';
|
|
1890
|
+
const diag = {
|
|
1891
|
+
node: property,
|
|
1892
|
+
severity: 'warning',
|
|
1893
|
+
message: errorMsg,
|
|
1894
|
+
};
|
|
1895
|
+
diagnostics.push(diag);
|
|
1896
|
+
typeAnnotationErrorDetail.errorPos.min = errorMsg;
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
if (Object.keys(typeAnnotationErrorDetail.errorPos).length) {
|
|
1900
|
+
typeAnnotation.tsErrorDetail = typeAnnotationErrorDetail;
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
if (diagnostic.message) {
|
|
1905
|
+
property.__showAdvanced = true;
|
|
1906
|
+
diagnostics.push(diagnostic);
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
else if (fileNode instanceof concepts_1.Logic || fileNode instanceof concepts_1.OverriddenLogic) {
|
|
1913
|
+
const { isRefedByTrigger, fRefName } = yield this.isRefedByTriggerAndReturnFirstRef(fileNode);
|
|
1914
|
+
if (isRefedByTrigger && !this.isTriggerRule(fileNode)) {
|
|
1915
|
+
const diagnostic = {
|
|
1916
|
+
node: fileNode,
|
|
1917
|
+
severity: 'error',
|
|
1918
|
+
message: `${fileNode.name} 已被Kafka消息订阅配置 ${fRefName} 引用:该逻辑入参只有一个入参,入参类型为string;且不允许存在返回值。否则会导致无法接收Kafka消息`,
|
|
1919
|
+
};
|
|
1920
|
+
diagnostics.push(diagnostic);
|
|
1921
|
+
}
|
|
1922
|
+
yield* utils.wrapIteratorToGenerator(fileNode.sourceMap.entries(), function* wrapIterator([node, value]) {
|
|
1923
|
+
if (node instanceof concepts_1.OqlQueryComponent) {
|
|
1924
|
+
// 自动推导情况
|
|
1925
|
+
const typeAnnotation = yield* (0, formatTsUtils_1.type2TypeAnnotation)(node.__nodeType);
|
|
1926
|
+
if (!node.typeAnnotation && typeAnnotation) {
|
|
1927
|
+
if (typeAnnotation.typeName === 'List' && typeAnnotation.typeKind === 'generic') {
|
|
1928
|
+
const { typeArguments } = typeAnnotation;
|
|
1929
|
+
if (typeArguments.length && typeArguments[0].isComplexType()) {
|
|
1930
|
+
const diagnostic = {
|
|
1931
|
+
node,
|
|
1932
|
+
severity: 'error',
|
|
1933
|
+
message: `SQL查询:返回类型不支持单个复杂类型 ${typeArguments[0].headTitle}。`,
|
|
1934
|
+
};
|
|
1935
|
+
node.tsErrorDetail = diagnostic;
|
|
1936
|
+
diagnostics.push(diagnostic);
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
else if (node instanceof concepts_1.Return || node instanceof concepts_1.Variable) {
|
|
1942
|
+
const nodeTypeName = node.concept === 'Return' ? '输出参数' : '局部变量';
|
|
1943
|
+
if (!node.typeAnnotation && !node.__TypeAnnotation) {
|
|
1944
|
+
let used = false;
|
|
1945
|
+
fileNode?.sourceMap.forEach((valueIn, nodeIn) => {
|
|
1946
|
+
if (!used && nodeIn && (nodeIn instanceof concepts_1.BatchAssignment || (nodeIn instanceof concepts_1.Assignment && nodeIn.left?.name))) {
|
|
1947
|
+
let jsCode = '';
|
|
1948
|
+
try {
|
|
1949
|
+
jsCode = nodeIn.toJS();
|
|
1950
|
+
}
|
|
1951
|
+
catch (err) {
|
|
1952
|
+
console.log(err);
|
|
1953
|
+
}
|
|
1954
|
+
if (jsCode.startsWith(`${node.name} = `)) {
|
|
1955
|
+
used = true;
|
|
1956
|
+
if (!nodeIn.tsErrorDetail) {
|
|
1957
|
+
const diagnostic = {
|
|
1958
|
+
node: nodeIn,
|
|
1959
|
+
severity: 'error',
|
|
1960
|
+
message: `${nodeIn.label}左边 ${node.name} 未设置类型,右边必须为有返回值的内容。`,
|
|
1961
|
+
};
|
|
1962
|
+
nodeIn.tsErrorDetail = diagnostic;
|
|
1963
|
+
diagnostics.push(diagnostic);
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
});
|
|
1968
|
+
const msg = used ? '必须赋值有返回值的内容。' : '未设置类型或未赋值。直接赋值系统可以自动推断类型。';
|
|
1969
|
+
const diagnostic = {
|
|
1970
|
+
node,
|
|
1971
|
+
severity: 'error',
|
|
1972
|
+
message: `${nodeTypeName} ${node.name} ${msg}`,
|
|
1973
|
+
};
|
|
1974
|
+
node.__aStructureError = diagnostic;
|
|
1975
|
+
diagnostics.push(diagnostic);
|
|
1976
|
+
}
|
|
1977
|
+
else {
|
|
1978
|
+
node.__aStructureError = null;
|
|
1979
|
+
}
|
|
1980
|
+
const fileSourceCode = self.getNodeCode(fileNode, value);
|
|
1981
|
+
if (fileSourceCode.includes('|') && fileSourceCode.includes('.metadataTypes.')) {
|
|
1982
|
+
const typeAnnotation = node.typeAnnotation.toJSON();
|
|
1983
|
+
yield* self._treeMetadataType2CoreType(typeAnnotation, node.rootNode);
|
|
1984
|
+
const isDuplicate = yield* self._isDuplicateCoreType(typeAnnotation);
|
|
1985
|
+
if (isDuplicate) {
|
|
1986
|
+
const diagnostic = {
|
|
1987
|
+
node,
|
|
1988
|
+
severity: 'error',
|
|
1989
|
+
message: `${nodeTypeName} ${node.name} 类型定义包含相同的数据类型`,
|
|
1990
|
+
};
|
|
1991
|
+
diagnostics.push(diagnostic);
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
else if (node instanceof concepts_1.Param) {
|
|
1996
|
+
const fileSourceCode = self.getNodeCode(fileNode, value);
|
|
1997
|
+
if (fileSourceCode.includes('|') && fileSourceCode.includes('.metadataTypes.')) {
|
|
1998
|
+
const typeAnnotation = node.typeAnnotation.toJSON();
|
|
1999
|
+
yield* self._treeMetadataType2CoreType(typeAnnotation, node.rootNode);
|
|
2000
|
+
const isDuplicate = yield* self._isDuplicateCoreType(typeAnnotation);
|
|
2001
|
+
if (isDuplicate) {
|
|
2002
|
+
const diagnostic = {
|
|
2003
|
+
node,
|
|
2004
|
+
severity: 'error',
|
|
2005
|
+
message: `输入参数 ${node.name} 类型定义包含相同的数据类型`,
|
|
2006
|
+
};
|
|
2007
|
+
diagnostics.push(diagnostic);
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
self.checkNodeError(node, diagnostics);
|
|
2012
|
+
});
|
|
2013
|
+
}
|
|
2014
|
+
else if (fileNode instanceof concepts_1.Process) {
|
|
2015
|
+
yield* utils.wrapIteratorToGenerator(fileNode.sourceMap.entries(), ([node, value]) => {
|
|
2016
|
+
this.checkNodeError(node, diagnostics);
|
|
2017
|
+
});
|
|
2018
|
+
}
|
|
2019
|
+
else if (fileNode instanceof concepts_1.Connection) {
|
|
2020
|
+
const connectorPropertyNames = NaslServer_1.getPropertyNames(fileNode);
|
|
2021
|
+
const connectionPropertyNames = NaslServer_1.getPropertyNames(fileNode?.connector);
|
|
2022
|
+
const diagnostic = {
|
|
2023
|
+
node: fileNode,
|
|
2024
|
+
severity: 'error',
|
|
2025
|
+
message: `连接器 ${fileNode.name} 参数配置有更新`,
|
|
2026
|
+
// 保留原来的内容方便查询一些问题
|
|
2027
|
+
originalDiagnostic: {
|
|
2028
|
+
fileName: '',
|
|
2029
|
+
start: null,
|
|
2030
|
+
end: null,
|
|
2031
|
+
category: 'error',
|
|
2032
|
+
text: `Connection configuration is empty`,
|
|
2033
|
+
},
|
|
2034
|
+
};
|
|
2035
|
+
// Connector Connection 配置项是否相同
|
|
2036
|
+
const isSameConfig = connectorPropertyNames.filter((x) => !connectionPropertyNames.includes(x)).length === 0;
|
|
2037
|
+
// Connection 配置项是否有空值
|
|
2038
|
+
const hasEmptyConfig = (c) => {
|
|
2039
|
+
return c.properties.findIndex((configProperty) => {
|
|
2040
|
+
return configProperty.values.find((configPropertyValue) => {
|
|
2041
|
+
return configPropertyValue.value === '';
|
|
2042
|
+
});
|
|
2043
|
+
}) > -1;
|
|
2044
|
+
};
|
|
2045
|
+
if (connectorPropertyNames.length !== connectionPropertyNames.length) {
|
|
2046
|
+
diagnostics.push(diagnostic);
|
|
2047
|
+
}
|
|
2048
|
+
else if (!isSameConfig) {
|
|
2049
|
+
diagnostics.push(diagnostic);
|
|
2050
|
+
}
|
|
2051
|
+
else if (hasEmptyConfig(fileNode)) {
|
|
2052
|
+
diagnostics.push(diagnostic);
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
else if (fileNode instanceof concepts_1.MetadataType) {
|
|
2056
|
+
fileNode?.sourceMap.forEach((value, node) => {
|
|
2057
|
+
const rulesMap = {};
|
|
2058
|
+
const { rules, typeAnnotation } = node;
|
|
2059
|
+
if (Array.isArray(rules)) {
|
|
2060
|
+
rules.forEach((rule) => {
|
|
2061
|
+
if (`${rule?.toUI()}` == 'undefined' || `${rule.toUI()}` == 'null')
|
|
2062
|
+
return;
|
|
2063
|
+
const match = rule.toUI?.().match(/^([^()]+)\(([\d\-.]+)\)$/);
|
|
2064
|
+
if (match) {
|
|
2065
|
+
const [, key, value] = match;
|
|
2066
|
+
rulesMap[key] = value;
|
|
2067
|
+
}
|
|
2068
|
+
});
|
|
2069
|
+
}
|
|
2070
|
+
const { typeName } = typeAnnotation || {};
|
|
2071
|
+
const typeAnnotationErrorDetail = {
|
|
2072
|
+
severity: 'warning',
|
|
2073
|
+
errorPos: {},
|
|
2074
|
+
};
|
|
2075
|
+
const minVal = rulesMap.min;
|
|
2076
|
+
const maxVal = rulesMap.max;
|
|
2077
|
+
if (['Long', 'Decimal'].includes(typeName) && !typeAnnotationErrorDetail.errorPos.min) {
|
|
2078
|
+
if (minVal && maxVal) {
|
|
2079
|
+
if (new decimal_js_1.Decimal(maxVal).lessThan(minVal)) {
|
|
2080
|
+
const errorMsg = '最小值不得大于最大值';
|
|
2081
|
+
const diag = {
|
|
2082
|
+
node,
|
|
2083
|
+
severity: 'warning',
|
|
2084
|
+
message: errorMsg,
|
|
2085
|
+
};
|
|
2086
|
+
diagnostics.push(diag);
|
|
2087
|
+
typeAnnotationErrorDetail.errorPos.min = errorMsg;
|
|
2088
|
+
}
|
|
2089
|
+
else {
|
|
2090
|
+
typeAnnotationErrorDetail.errorPos = {};
|
|
2091
|
+
node.typeAnnotation.tsErrorDetail = null;
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
if (Object.keys(typeAnnotationErrorDetail.errorPos).length) {
|
|
2096
|
+
typeAnnotation.tsErrorDetail = typeAnnotationErrorDetail;
|
|
2097
|
+
}
|
|
2098
|
+
});
|
|
2099
|
+
}
|
|
2100
|
+
return diagnostics;
|
|
2101
|
+
}
|
|
2102
|
+
*_treeMetadataType2CoreType(type, app) {
|
|
2103
|
+
const self = this;
|
|
2104
|
+
yield* utils.wrapForEachToGenerator(type.typeArguments ?? [], function* wrapForEach(item) {
|
|
2105
|
+
if (item.typeNamespace?.endsWith('.metadataTypes')) {
|
|
2106
|
+
let originType = {};
|
|
2107
|
+
if (item.typeNamespace === 'app.metadataTypes') {
|
|
2108
|
+
originType = app.metadataTypes?.find((metadataType) => metadataType.name === item.typeName)?.typeAnnotation;
|
|
2109
|
+
}
|
|
2110
|
+
else if (item.typeNamespace?.startsWith('extensions.') && item.typeNamespace?.endsWith('.metadataTypes')) {
|
|
2111
|
+
const dependencyName = item.typeNamespace.replace('extensions.', '').replace('.metadataTypes', '');
|
|
2112
|
+
originType = app.dependencies?.find((dependency) => dependency.name === dependencyName)?.metadataTypes?.find((ele) => ele.name === item.typeName)?.typeAnnotation ?? {};
|
|
2113
|
+
}
|
|
2114
|
+
item.typeKind = 'primitive';
|
|
2115
|
+
item.typeNamespace = 'nasl.core';
|
|
2116
|
+
item.typeName = originType?.typeName;
|
|
2117
|
+
}
|
|
2118
|
+
yield* utils.wrapForEachToGenerator(type.typeArguments ?? [], function* wrapForEach2(ele) {
|
|
2119
|
+
yield* self._treeMetadataType2CoreType(ele, app);
|
|
2120
|
+
});
|
|
2121
|
+
});
|
|
2122
|
+
}
|
|
2123
|
+
*_isDuplicateCoreType(type) {
|
|
2124
|
+
const argsStringList = type.typeArguments?.map((item) => JSON.stringify(item)) || [];
|
|
2125
|
+
const setList = Array.from(new Set(argsStringList));
|
|
2126
|
+
if (argsStringList.length > setList.length) {
|
|
2127
|
+
return true;
|
|
2128
|
+
}
|
|
2129
|
+
let flag = false;
|
|
2130
|
+
for (const ele of type.typeArguments ?? []) {
|
|
2131
|
+
const subFlag = yield* this._isDuplicateCoreType(ele);
|
|
2132
|
+
if (subFlag) {
|
|
2133
|
+
flag = true;
|
|
2134
|
+
}
|
|
2135
|
+
}
|
|
2136
|
+
return flag;
|
|
2137
|
+
}
|
|
2138
|
+
checkNodeError(node, diagnostics) {
|
|
2139
|
+
if (!node)
|
|
2140
|
+
return;
|
|
2141
|
+
// 如果节点是match的看看节点里是不是有重复的
|
|
2142
|
+
if (node instanceof concepts_1.Match) {
|
|
2143
|
+
const typeMap = {};
|
|
2144
|
+
if (node.expression?.__TypeAnnotation) {
|
|
2145
|
+
const { typeName, typeNamespace } = node.expression.__TypeAnnotation;
|
|
2146
|
+
if (typeName === 'Union' || typeName === 'Boolean' || typeNamespace?.endsWith('enums')) {
|
|
2147
|
+
node.cases.forEach((item) => {
|
|
2148
|
+
if (Array.isArray(item.patterns)) {
|
|
2149
|
+
item.patterns.forEach((pattern) => {
|
|
2150
|
+
if (pattern instanceof concepts_1.TypeAnnotation) {
|
|
2151
|
+
if (typeMap[pattern.sortedTypeKey]) {
|
|
2152
|
+
typeMap[pattern.sortedTypeKey].push(pattern);
|
|
2153
|
+
}
|
|
2154
|
+
else {
|
|
2155
|
+
typeMap[pattern.sortedTypeKey] = [pattern];
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
else if (pattern instanceof concepts_1.MemberExpression) {
|
|
2159
|
+
if (pattern.completeName && pattern.object?.namespace?.endsWith('enums')) {
|
|
2160
|
+
const onlyKey = pattern.completeName;
|
|
2161
|
+
if (typeMap[onlyKey]) {
|
|
2162
|
+
typeMap[onlyKey].push(pattern);
|
|
2163
|
+
}
|
|
2164
|
+
else {
|
|
2165
|
+
typeMap[onlyKey] = [pattern];
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
else if (pattern instanceof concepts_1.BooleanLiteral) {
|
|
2170
|
+
const onlyKey = pattern.concept + pattern.value;
|
|
2171
|
+
if (typeMap[onlyKey]) {
|
|
2172
|
+
typeMap[onlyKey].push(pattern);
|
|
2173
|
+
}
|
|
2174
|
+
else {
|
|
2175
|
+
typeMap[onlyKey] = [pattern];
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
});
|
|
2179
|
+
}
|
|
2180
|
+
});
|
|
2181
|
+
}
|
|
2182
|
+
Object.keys(typeMap).forEach((item) => {
|
|
2183
|
+
if (typeMap[item].length > 1) {
|
|
2184
|
+
typeMap[item].forEach((nodeItem) => {
|
|
2185
|
+
const diagnostic = {
|
|
2186
|
+
node: nodeItem,
|
|
2187
|
+
severity: 'error',
|
|
2188
|
+
message: '匹配:重复添加类型',
|
|
2189
|
+
titleTip: '重复添加此项',
|
|
2190
|
+
};
|
|
2191
|
+
nodeItem.tsErrorDetail = diagnostic;
|
|
2192
|
+
diagnostics.push(diagnostic);
|
|
2193
|
+
});
|
|
2194
|
+
}
|
|
2195
|
+
});
|
|
2196
|
+
}
|
|
2197
|
+
else if (node.expression) {
|
|
2198
|
+
const diagnostic = {
|
|
2199
|
+
node: node.expression,
|
|
2200
|
+
severity: 'error',
|
|
2201
|
+
message: '类型不匹配,传入类型:void',
|
|
2202
|
+
};
|
|
2203
|
+
node.expression.tsErrorDetail = diagnostic;
|
|
2204
|
+
diagnostics.push(diagnostic);
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
if (node instanceof concepts_1.MatchCase && node.getAncestor('Match')?.isExpression && node.body.length === 0) {
|
|
2208
|
+
// 如果不是其他就标红
|
|
2209
|
+
if (node?.getIndexOfParent() !== (node.getAncestor('Match')?.cases?.length || 0) - 1) {
|
|
2210
|
+
const diagnostic = {
|
|
2211
|
+
node,
|
|
2212
|
+
severity: 'error',
|
|
2213
|
+
message: '匹配分支:返回内容不能为空',
|
|
2214
|
+
titleTip: '返回内容不能为空',
|
|
2215
|
+
};
|
|
2216
|
+
node.tsErrorDetail = diagnostic;
|
|
2217
|
+
diagnostics.push(diagnostic);
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
// 如果节点是match的patterns 里的
|
|
2221
|
+
if (node?.parentKey === 'patterns' && node.parentNode instanceof concepts_1.MatchCase) {
|
|
2222
|
+
const matchNode = node.getAncestor('Match');
|
|
2223
|
+
const matchExpressionType = matchNode?.expression?.__TypeAnnotation;
|
|
2224
|
+
// 判断union类型是不是重复
|
|
2225
|
+
// 先使用ts原始的报错,这个先注释掉
|
|
2226
|
+
if (node instanceof concepts_1.TypeAnnotation && matchExpressionType?.typeKind === 'union') {
|
|
2227
|
+
const haveType = matchExpressionType?.typeArguments.find((item) => item.sortedTypeKey === node.sortedTypeKey);
|
|
2228
|
+
if (!haveType) {
|
|
2229
|
+
const diagnostic = {
|
|
2230
|
+
node,
|
|
2231
|
+
severity: 'error',
|
|
2232
|
+
message: '匹配:选择类型不存在',
|
|
2233
|
+
titleTip: '该类型已被删除',
|
|
2234
|
+
};
|
|
2235
|
+
node.tsErrorDetail = diagnostic;
|
|
2236
|
+
diagnostics.push(diagnostic);
|
|
2237
|
+
}
|
|
2238
|
+
// 如果TypeAnnotation 还存在,但是本身已经不是union类型,就是已经从union换别的类型了就都要报错
|
|
2239
|
+
}
|
|
2240
|
+
else if (node instanceof concepts_1.TypeAnnotation && matchExpressionType?.typeKind !== 'union') {
|
|
2241
|
+
const diagnostic = {
|
|
2242
|
+
node,
|
|
2243
|
+
severity: 'error',
|
|
2244
|
+
message: '匹配:选择类型不存在',
|
|
2245
|
+
titleTip: '该类型已被删除',
|
|
2246
|
+
};
|
|
2247
|
+
node.tsErrorDetail = diagnostic;
|
|
2248
|
+
diagnostics.push(diagnostic);
|
|
2249
|
+
// 如果可枚举变量的 ,变量 还存在,但是本身已经是union类型,就是已经从别的类型 换了union就都要报错
|
|
2250
|
+
}
|
|
2251
|
+
else if (!(node instanceof concepts_1.TypeAnnotation) && matchExpressionType?.typeKind === 'union') {
|
|
2252
|
+
const diagnostic = {
|
|
2253
|
+
node,
|
|
2254
|
+
severity: 'error',
|
|
2255
|
+
message: '匹配:选择值不存在',
|
|
2256
|
+
titleTip: '该值无法匹配,请重新选择类型',
|
|
2257
|
+
};
|
|
2258
|
+
node.tsErrorDetail = diagnostic;
|
|
2259
|
+
diagnostics.push(diagnostic);
|
|
2260
|
+
}
|
|
2261
|
+
if (node.tsErrorDetail) {
|
|
2262
|
+
// 如果父级是枚举,而且子集选的是变量,就提示枚举值已被删除
|
|
2263
|
+
if (matchExpressionType?.typeNamespace?.includes('enums') && node instanceof concepts_1.MemberExpression) {
|
|
2264
|
+
node.tsErrorDetail.titleTip = '该枚举值已被删除';
|
|
2265
|
+
}
|
|
2266
|
+
else if (!node.tsErrorDetail.titleTip) {
|
|
2267
|
+
node.tsErrorDetail.titleTip = '该值已被删除';
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
// 如果forEach 中的each的内容是union类型就要提示报错
|
|
2272
|
+
if (node?.parentKey === 'each' && node?.__TypeAnnotation?.typeKind === 'union') {
|
|
2273
|
+
const diagnostic = {
|
|
2274
|
+
node,
|
|
2275
|
+
severity: 'error',
|
|
2276
|
+
message: 'ForEach:参数类型不一致!传入类型:联合类型。接受类型:List类型。',
|
|
2277
|
+
};
|
|
2278
|
+
node.tsErrorDetail = diagnostic;
|
|
2279
|
+
diagnostics.push(diagnostic);
|
|
2280
|
+
}
|
|
2281
|
+
if (node instanceof concepts_1.ForEachStatement && !node.end && node.each) {
|
|
2282
|
+
if (!['List'].includes(node.each.__TypeAnnotation?.typeName)) {
|
|
2283
|
+
const diagnostic = {
|
|
2284
|
+
node,
|
|
2285
|
+
severity: 'error',
|
|
2286
|
+
message: `ForEach:循环列表:参数类型不匹配!结束值自动推导失败。`,
|
|
2287
|
+
};
|
|
2288
|
+
node.tsErrorDetail = diagnostic;
|
|
2289
|
+
diagnostics.push(diagnostic);
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
if ((node instanceof concepts_1.OqlQueryComponent || node instanceof concepts_1.SqlQueryComponent) && node.parentNode instanceof concepts_1.Paginate && node.parentKey === 'list' && node.codeSourceMap && node.codeSourceMap.containsLimit) {
|
|
2293
|
+
const diagnostic = {
|
|
2294
|
+
node,
|
|
2295
|
+
severity: 'error',
|
|
2296
|
+
message: `SQL 查询已包含分页,请去除 SQL 查询中的 LIMIT 语句。`,
|
|
2297
|
+
};
|
|
2298
|
+
node.tsErrorDetail = diagnostic;
|
|
2299
|
+
diagnostics.push(diagnostic);
|
|
2300
|
+
}
|
|
2301
|
+
/**
|
|
2302
|
+
* 如果节点是内置函数
|
|
2303
|
+
* 穷举在线上的情况,不在线上就void报错, callinterface 因为原来有报错,所以就忽略掉
|
|
2304
|
+
* && 他在父级中,不在body
|
|
2305
|
+
* && 也不再 if的线上
|
|
2306
|
+
* && 也不再 switch的线上consequent
|
|
2307
|
+
* && 也不再草稿区域
|
|
2308
|
+
* && 不在 parentNode.parentNode(只用处理两层的,超过两层上就需要报错,只用直接是参数位第一层的需要) 是 callfunction 和 callInfterfase中,因为这两本身有强制类型,内置函数或者一些带T的声明那种,
|
|
2309
|
+
* && 而且也没有类型,就说明在槽位里,就需要报错
|
|
2310
|
+
*
|
|
2311
|
+
* 如果是内置函数而且也不在线上
|
|
2312
|
+
* 只有下面自己实现的函数才会报错
|
|
2313
|
+
*/
|
|
2314
|
+
if (node instanceof concepts_1.CallFunction &&
|
|
2315
|
+
node.parentKey !== 'body' &&
|
|
2316
|
+
node.parentKey !== 'alternate' &&
|
|
2317
|
+
node.parentKey !== 'playground' &&
|
|
2318
|
+
node.parentKey !== 'consequent' &&
|
|
2319
|
+
node.parentNode?.parentNode?.concept !== 'CallInterface' &&
|
|
2320
|
+
node.parentNode.concept !== 'Block' &&
|
|
2321
|
+
!node.__TypeAnnotation) {
|
|
2322
|
+
let showErr = false;
|
|
2323
|
+
if (node.parentNode?.parentNode?.concept === 'CallLogic') {
|
|
2324
|
+
// calllogic 中别的类型会强校验,但是内置函数,不会强制校验,下面这几个其实是走的内置函数的实现,所以需要手动增加一下校验
|
|
2325
|
+
const { calleeNamespace, calleeName } = node.parentNode.parentNode;
|
|
2326
|
+
if ((calleeNamespace === 'nasl.ui' || calleeNamespace === 'nasl.util') &&
|
|
2327
|
+
(['showMessage', 'consoleLog', 'jsonDeserialize',
|
|
2328
|
+
'jsonSerialize'].includes(calleeName))) {
|
|
2329
|
+
showErr = true;
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
else {
|
|
2333
|
+
showErr = true;
|
|
2334
|
+
}
|
|
2335
|
+
if (showErr) {
|
|
2336
|
+
const diagnostic = {
|
|
2337
|
+
node,
|
|
2338
|
+
severity: 'error',
|
|
2339
|
+
message: `类型不匹配,传入类型:void`,
|
|
2340
|
+
};
|
|
2341
|
+
node.tsErrorDetail = diagnostic;
|
|
2342
|
+
diagnostics.push(diagnostic);
|
|
2343
|
+
}
|
|
2344
|
+
}
|
|
2345
|
+
// newMap key或者value没填都要有报错
|
|
2346
|
+
if (node instanceof concepts_1.NewMap) {
|
|
2347
|
+
// 如果一项没有key 或者没有 value 就报错
|
|
2348
|
+
const findFlag = node.keys?.some((key, index) => !key || !node.values?.[index]);
|
|
2349
|
+
if (findFlag) {
|
|
2350
|
+
const diagnostic = {
|
|
2351
|
+
node,
|
|
2352
|
+
severity: 'error',
|
|
2353
|
+
message: `新建Map的key和value应该都必填`,
|
|
2354
|
+
};
|
|
2355
|
+
node.tsErrorDetail = diagnostic;
|
|
2356
|
+
diagnostics.push(diagnostic);
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
// 赋值语句左右list 和 map等可以 必须都一样
|
|
2360
|
+
if (node instanceof concepts_1.Assignment && !node.tsErrorDetail) {
|
|
2361
|
+
const leftType = node.left?.__TypeAnnotation || {};
|
|
2362
|
+
const rightType = node.right?.__TypeAnnotation || {};
|
|
2363
|
+
// 如果左边节点是 泛型,而且 左边泛型的名字 和 右边一样, 而且是list 或者map 就强制报错
|
|
2364
|
+
// 而且右边原来没有报错
|
|
2365
|
+
if (leftType.typeKind === 'generic' &&
|
|
2366
|
+
leftType.typeKind === rightType.typeKind &&
|
|
2367
|
+
leftType.typeName === rightType.typeName &&
|
|
2368
|
+
['Map', 'List'].includes(leftType.typeName)) {
|
|
2369
|
+
if (!node.right.tsErrorDetail && leftType.sortedTypeKey !== rightType.sortedTypeKey) {
|
|
2370
|
+
const excludeList = [
|
|
2371
|
+
'nasl.collection.List<nasl.core.String>',
|
|
2372
|
+
'nasl.collection.List<nasl.core.Email>',
|
|
2373
|
+
'nasl.collection.Map<nasl.core.String, nasl.core.String>',
|
|
2374
|
+
'nasl.collection.Map<nasl.core.String, nasl.core.Email>',
|
|
2375
|
+
];
|
|
2376
|
+
const excludeList2 = ['nasl.collection.List<>', 'nasl.collection.List<T>'];
|
|
2377
|
+
// 先特殊处理等 类型合并后就可以去掉了
|
|
2378
|
+
if (excludeList.includes(leftType.sortedTypeKey) && excludeList.includes(rightType.sortedTypeKey)) {
|
|
2379
|
+
return null;
|
|
2380
|
+
}
|
|
2381
|
+
if (excludeList2.includes(leftType.sortedTypeKey) || excludeList2.includes(rightType.sortedTypeKey)) {
|
|
2382
|
+
return null;
|
|
2383
|
+
}
|
|
2384
|
+
const diagnostic = {
|
|
2385
|
+
node: node.right,
|
|
2386
|
+
severity: 'error',
|
|
2387
|
+
message: `左右参数类型不一致!左边类型:${leftType.typeChineseTitle},右边类型:${rightType.typeChineseTitle}。`,
|
|
2388
|
+
};
|
|
2389
|
+
node.right.tsErrorDetail = diagnostic;
|
|
2390
|
+
diagnostics.push(diagnostic);
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
/**
|
|
2396
|
+
* 判断当前CallInterface 对应的 Interface 是否含有鉴权方式
|
|
2397
|
+
*/
|
|
2398
|
+
hasAuth(node) {
|
|
2399
|
+
const tInterface = (0, utils_2.getNodeByNodeCallee)(node.rootNode, node.calleewholeKey);
|
|
2400
|
+
return tInterface instanceof concepts_1.AuthInterface;
|
|
2401
|
+
}
|
|
2402
|
+
/* 接口导入查找 */
|
|
2403
|
+
*existStructureFix(semanticDiagnostics, node, that) {
|
|
2404
|
+
let module;
|
|
2405
|
+
yield* utils.wrapForEachToGenerator(semanticDiagnostics, (diag) => {
|
|
2406
|
+
const minRange = this._findMinRange(diag, node);
|
|
2407
|
+
if (diag.text?.includes('has no exported member named')) {
|
|
2408
|
+
if (minRange.node instanceof concepts_1.Logic) {
|
|
2409
|
+
return null;
|
|
2410
|
+
}
|
|
2411
|
+
const typeAnnotation = minRange.node instanceof concepts_1.TypeAnnotation ? minRange.node.upperNode.typeAnnotation : minRange.node.typeAnnotation;
|
|
2412
|
+
const regNamespace = /<(\S*)>/;
|
|
2413
|
+
const typeKey = (typeAnnotation?.typeKey.match(regNamespace) && typeAnnotation?.typeKey.match(regNamespace)[1]) || typeAnnotation?.typeKey;
|
|
2414
|
+
const typeKeyArr = typeKey.split('.');
|
|
2415
|
+
if (typeKeyArr[0] === 'apis') {
|
|
2416
|
+
const structureName = typeKeyArr[3];
|
|
2417
|
+
const moduleName = typeKeyArr[1];
|
|
2418
|
+
const { app } = typeAnnotation.upperNode;
|
|
2419
|
+
if (!app) {
|
|
2420
|
+
return null;
|
|
2421
|
+
}
|
|
2422
|
+
module = app.interfaceDependencies?.find((item) => item.name === moduleName);
|
|
2423
|
+
let existStructure = module?.structures?.find((item) => item.name.toUpperCase() === structureName.toUpperCase());
|
|
2424
|
+
if (!existStructure) {
|
|
2425
|
+
const realName = structureName.replace(/\d*$/, (m) => String(''));
|
|
2426
|
+
existStructure = module?.structures?.find((item) => item.name.toUpperCase() === realName.toUpperCase());
|
|
2427
|
+
}
|
|
2428
|
+
if (existStructure) {
|
|
2429
|
+
const editTypeAnnotation = JSON.parse(JSON.stringify(typeAnnotation?.toJSON() ?? {}).replace(new RegExp(structureName, 'g'), existStructure.name));
|
|
2430
|
+
actionArr.push({ target: typeAnnotation.parentNode, typeannotation: editTypeAnnotation });
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
return null;
|
|
2434
|
+
}
|
|
2435
|
+
});
|
|
2436
|
+
if (actionArr.length) {
|
|
2437
|
+
if (timer)
|
|
2438
|
+
return;
|
|
2439
|
+
timer = window.setTimeout(() => {
|
|
2440
|
+
const { app } = actionArr[0].target;
|
|
2441
|
+
app.emit('collect:start', {
|
|
2442
|
+
actionMsg: '设置导入接口数据类型错误',
|
|
2443
|
+
});
|
|
2444
|
+
module.isAdd && module.setIsAdd(false);
|
|
2445
|
+
actionArr.forEach((item) => {
|
|
2446
|
+
item.target.setDataType(concepts_1.TypeAnnotation.from(item.typeannotation));
|
|
2447
|
+
});
|
|
2448
|
+
app.emit('collect:end');
|
|
2449
|
+
actionArr = [];
|
|
2450
|
+
isChangeInterface = false;
|
|
2451
|
+
clearTimeout(timer);
|
|
2452
|
+
timer = null;
|
|
2453
|
+
}, 2000);
|
|
2454
|
+
}
|
|
2455
|
+
}
|
|
2456
|
+
/**
|
|
2457
|
+
* 单个问题的诊断处理
|
|
2458
|
+
* @param diagnostic 诊断问题
|
|
2459
|
+
* @param fileNode 页面节点
|
|
2460
|
+
* @returns 处理后的结果
|
|
2461
|
+
*/
|
|
2462
|
+
*_resolveDiagnosticWithGenerator(diagnostic, fileNode, record) {
|
|
2463
|
+
// 拓展模块中的翻译先过滤掉,因为有错用户也不能修改
|
|
2464
|
+
if ((fileNode.module || fileNode.connector) && !(fileNode instanceof concepts_1.ConfigProperty)) {
|
|
2465
|
+
return;
|
|
2466
|
+
}
|
|
2467
|
+
if (fileNode.concept === 'OverriddenLogic' && diagnostic.text === `'__LogicEmpty' is declared but its value is never read.`) {
|
|
2468
|
+
return;
|
|
2469
|
+
}
|
|
2470
|
+
const minRange = yield* this._findMinRangeWithGenerator(diagnostic, fileNode);
|
|
2471
|
+
const tsErrorDetail = {
|
|
2472
|
+
severity: diagnostic.category === 'error' ? 'error' : 'warning',
|
|
2473
|
+
message: (0, translator_2.translateDiagnosticMessage)(diagnostic.text),
|
|
2474
|
+
// 保留原来的内容方便查询一些问题
|
|
2475
|
+
originalDiagnostic: diagnostic,
|
|
2476
|
+
};
|
|
2477
|
+
yield;
|
|
2478
|
+
let result;
|
|
2479
|
+
if (minRange) {
|
|
2480
|
+
// 节点的error要置为true
|
|
2481
|
+
result = (0, translator_2.naslNodeTranslateMessage)(minRange, tsErrorDetail);
|
|
2482
|
+
yield;
|
|
2483
|
+
}
|
|
2484
|
+
else {
|
|
2485
|
+
// 没找到节点, 先把问题暴露出来
|
|
2486
|
+
result = tsErrorDetail;
|
|
2487
|
+
}
|
|
2488
|
+
if (result) {
|
|
2489
|
+
result.id = record.filePath + (result ? JSON.stringify({ start: result.originalDiagnostic.start, end: result.originalDiagnostic.end }) : '');
|
|
2490
|
+
}
|
|
2491
|
+
return result;
|
|
2492
|
+
}
|
|
2493
|
+
/**
|
|
2494
|
+
* 查找节点
|
|
2495
|
+
*
|
|
2496
|
+
* @description 生成器原型函数
|
|
2497
|
+
*/
|
|
2498
|
+
*_findMinRangeWithGenerator(diagnostic, fileNode) {
|
|
2499
|
+
let minRange;
|
|
2500
|
+
const { sourceMap } = fileNode;
|
|
2501
|
+
// 是否找到了行内准确的,是的话,就不走多行的
|
|
2502
|
+
let haveLineNode = false;
|
|
2503
|
+
for (const [node, item] of sourceMap.entries()) {
|
|
2504
|
+
/**
|
|
2505
|
+
* 当前内容的开始行 <= 诊断开始的行 &&
|
|
2506
|
+
* 当前内容的结束行 >= 诊断结束的行
|
|
2507
|
+
*/
|
|
2508
|
+
if ((0, translator_1.lsp2tspNumber)(item.start.line) <= diagnostic.start.line && (0, translator_1.lsp2tspNumber)(item.end.line) >= diagnostic.end.line) {
|
|
2509
|
+
// 如果找到某一行
|
|
2510
|
+
if ((0, translator_1.lsp2tspNumber)(item.start.line) === diagnostic.start.line && (0, translator_1.lsp2tspNumber)(item.end.line) === diagnostic.end.line) {
|
|
2511
|
+
// 在行的范围但是又不在列的范围,不用给默认值,给了反而不对,
|
|
2512
|
+
// 需要在列的范围内
|
|
2513
|
+
if ((0, translator_1.lsp2tspNumber)(item.start.character) <= diagnostic.start.offset &&
|
|
2514
|
+
(0, translator_1.lsp2tspNumber)(item.end.character) >= diagnostic.end.offset) {
|
|
2515
|
+
// 比列更靠近 ,满足条件且长度更短
|
|
2516
|
+
// 如果先走到下面有一个默认值了就像在if for里面有个表达式
|
|
2517
|
+
// if for的内容也是包括当前的所以会重新赋值
|
|
2518
|
+
if (!minRange || (item.end.offset - item.start.offset) < (minRange.item.end.offset - minRange.item.start.offset)) {
|
|
2519
|
+
minRange = { item, node };
|
|
2520
|
+
haveLineNode = true;
|
|
2521
|
+
}
|
|
2522
|
+
}
|
|
2523
|
+
}
|
|
2524
|
+
else {
|
|
2525
|
+
// 没有节点 或者 行差比较小比已有的小就可以
|
|
2526
|
+
// 一般出现在一大块上,多半是if for 等等没有参数
|
|
2527
|
+
if (!minRange) {
|
|
2528
|
+
minRange = { node, item };
|
|
2529
|
+
}
|
|
2530
|
+
else if (!haveLineNode) {
|
|
2531
|
+
if ((0, translator_1.lsp2tspNumber)(item.start.line) === diagnostic.start.line &&
|
|
2532
|
+
diagnostic.start.offset >= (0, translator_1.lsp2tspNumber)(item.start.character)) {
|
|
2533
|
+
// 如果当前遍历的内容的行和列都 小于之前的, 而且是有效的
|
|
2534
|
+
// 如果两个内容位置行数是一样的,就比较下找到内容的位置信息
|
|
2535
|
+
// 找到的内容的开始位置, 要大于申明内容开始的位置,要不就不包含在内了
|
|
2536
|
+
if (diagnostic.start.offset - item.start.character <= diagnostic.start.offset - minRange.item.start.character) {
|
|
2537
|
+
minRange = { node, item };
|
|
2538
|
+
}
|
|
2539
|
+
else if (diagnostic.start.offset < (0, translator_1.lsp2tspNumber)(minRange.item.start.character)) {
|
|
2540
|
+
minRange = { node, item };
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
else if (item.end.line - item.start.line <= minRange.item.end.line - minRange.item.start.line) {
|
|
2544
|
+
// 行都一致 ,比较列
|
|
2545
|
+
if (minRange.item.start.line === item.start.line && minRange.item.end.line === item.end.line) {
|
|
2546
|
+
// 如果两个起始和结束的行都一样,那么就比较开始列, 要比原来大,说明更精准
|
|
2547
|
+
if (item.start.character > minRange.item.start.character) {
|
|
2548
|
+
minRange = { node, item };
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
else {
|
|
2552
|
+
minRange = { node, item };
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
yield;
|
|
2559
|
+
}
|
|
2560
|
+
if (!minRange) {
|
|
2561
|
+
if (fileNode instanceof concepts_1.View || fileNode instanceof concepts_1.BusinessComponent) {
|
|
2562
|
+
return { node: fileNode, item: sourceMap.get(fileNode) };
|
|
2563
|
+
}
|
|
2564
|
+
if (process.env.NODE_ENV === 'development') {
|
|
2565
|
+
console.log(minRange, '需要特殊看下,为什么没找到内容-------------');
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
return minRange;
|
|
2569
|
+
}
|
|
2570
|
+
/**
|
|
2571
|
+
* 查找节点
|
|
2572
|
+
*
|
|
2573
|
+
* @description 同步模式
|
|
2574
|
+
*/
|
|
2575
|
+
_findMinRange(...args) {
|
|
2576
|
+
return utils.runGeneratorSync(this._findMinRangeWithGenerator(...args));
|
|
2577
|
+
}
|
|
2578
|
+
/**
|
|
2579
|
+
* 查看当前节点是不是有引用
|
|
2580
|
+
* @param node 节点
|
|
2581
|
+
* @returns 查找到的数组
|
|
2582
|
+
*/
|
|
2583
|
+
async _isHaveRef(node) {
|
|
2584
|
+
const { currentSource, fileNode } = this.getCurrentSource(node);
|
|
2585
|
+
let refsList = [];
|
|
2586
|
+
/**
|
|
2587
|
+
* 未完成创建的节点 ,或者异常情况 可能找不到节点
|
|
2588
|
+
*/
|
|
2589
|
+
if (currentSource) {
|
|
2590
|
+
const newRefs = await this.references({
|
|
2591
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
2592
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
2593
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character),
|
|
2594
|
+
});
|
|
2595
|
+
refsList = [...newRefs.refs];
|
|
2596
|
+
}
|
|
2597
|
+
else if (node instanceof concepts_1.Module && !(node instanceof concepts_1.Connector)) {
|
|
2598
|
+
const lists = node.logics || node.structures || node.enums;
|
|
2599
|
+
const moduleName = fileNode.getEmbeddedFilePath();
|
|
2600
|
+
if (lists.length) {
|
|
2601
|
+
const item = lists[0];
|
|
2602
|
+
const { fileNode } = this.getCurrentSource(item);
|
|
2603
|
+
if (fileNode) {
|
|
2604
|
+
const newRefs = await this.references({
|
|
2605
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
2606
|
+
line: 1,
|
|
2607
|
+
offset: 22, // 固定的位置,module的位置信息
|
|
2608
|
+
});
|
|
2609
|
+
refsList = newRefs.refs.filter((item) => !item.file.startsWith(moduleName));
|
|
2610
|
+
// 多塞一个 ,删除的时候就有值了, 上面过滤了之后可能是空的
|
|
2611
|
+
refsList.unshift(newRefs.refs[0]);
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2615
|
+
else if (node instanceof concepts_1.Connector) {
|
|
2616
|
+
// Conenctor 虽为 Module 的子类,但是具体引用逻辑与Module 并不一致,因此这边单独处理
|
|
2617
|
+
// 由于 在与后端定义 Connector Namespace 前缀时, Logics 相关定义为 connector,
|
|
2618
|
+
// 其余定义为 extension, 因此这边查找引用时,需要分别查找并去重复
|
|
2619
|
+
// 这里选择 logic 与 interface 作为 查找源,因为一个 Connector 必定至少含有一个 logic 和 interface
|
|
2620
|
+
const logicList = node.namespaces.find((ns) => ns.logics.length > 0)?.logics || [];
|
|
2621
|
+
const interfaceList = node.interfaces;
|
|
2622
|
+
const moduleName = fileNode.getEmbeddedFilePath();
|
|
2623
|
+
const appName = node.rootNode.name; // 获取rootNode的name,用于过滤引用
|
|
2624
|
+
if (logicList.length) {
|
|
2625
|
+
const item = logicList[0];
|
|
2626
|
+
const { fileNode } = this.getCurrentSource(item);
|
|
2627
|
+
if (fileNode) {
|
|
2628
|
+
const newRefs = await this.references({
|
|
2629
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
2630
|
+
line: 1,
|
|
2631
|
+
offset: 21, // 固定的位置, connector 前缀下 Connector 的位置信息
|
|
2632
|
+
});
|
|
2633
|
+
refsList = [...newRefs.refs];
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
if (interfaceList.length) {
|
|
2637
|
+
const item = interfaceList[0];
|
|
2638
|
+
const { fileNode } = this.getCurrentSource(item);
|
|
2639
|
+
if (fileNode) {
|
|
2640
|
+
const newRefs = await this.references({
|
|
2641
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
2642
|
+
line: 1,
|
|
2643
|
+
offset: 22, // 固定的位置, extension 前缀下 Connector 的位置信息
|
|
2644
|
+
});
|
|
2645
|
+
refsList = [...refsList, ...newRefs.refs];
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
// 根据 moduleName 中是否存在 dependencies 来判断是否为稳定态的Connector
|
|
2649
|
+
const isStable = moduleName.includes(`/embedded/${appName}/dependencies`);
|
|
2650
|
+
// 根据 item 的 file 去重
|
|
2651
|
+
refsList = refsList.filter((item, index, arr) => {
|
|
2652
|
+
const tempStable = item.file.includes(`/embedded/${appName}/dependencies`); // 约定
|
|
2653
|
+
const isGlobalLogic = item.file.includes(`/embedded/${appName}/logics`); // 约定
|
|
2654
|
+
// 关于 isGlobalLogic 单独判断的说明:
|
|
2655
|
+
// 全局逻辑与Connector 有直接关联的只有两种情况
|
|
2656
|
+
// 1. 全局逻辑通过 CallConnector 调用 Connector 中的方法,此时被 logicList 处查找的引用所检索
|
|
2657
|
+
// 2. 全局逻辑中参类型赋值为 Connector 中某一 structure ,此时被 interfaceList 处查找的引用所检索
|
|
2658
|
+
// 综上所述,检索到的全局逻辑相关一定是唯一的,且不重复的
|
|
2659
|
+
return isGlobalLogic || (isStable ? tempStable : !tempStable); // 稳定态的Connector 只能引用稳定态的Connector
|
|
2660
|
+
});
|
|
2661
|
+
}
|
|
2662
|
+
// 如果是DataSource就需要在单独,查一边来修改名字
|
|
2663
|
+
if (node instanceof concepts_1.DataSource) {
|
|
2664
|
+
// 过滤一把不需要改的信息
|
|
2665
|
+
refsList = refsList.filter((item) => {
|
|
2666
|
+
const dataSourceFile = fileNode.getEmbeddedFilePath();
|
|
2667
|
+
const entityFilePrefix = dataSourceFile.replace('.ts', '');
|
|
2668
|
+
/**
|
|
2669
|
+
* 特殊处理,因为关联属性或者关联实体等等都是在实体里,在实体中因为自己不可以是自己的类型
|
|
2670
|
+
* 所以全部过滤掉了,
|
|
2671
|
+
* 但是在datasource里面在实体里会有大量的引用,不需要全部修改.只需要处理除了11个函数之外的引用
|
|
2672
|
+
* 所以底部内容是11个函数,所以这里就 用entity的行数 减去11个函数的行数,然后其余的在进行处理
|
|
2673
|
+
* 进行过滤
|
|
2674
|
+
*/
|
|
2675
|
+
// 不要数据源下面的实体里的引用 ,保留原始的节点内容
|
|
2676
|
+
let flag = false;
|
|
2677
|
+
if (item.file.includes(entityFilePrefix)) {
|
|
2678
|
+
const entity = this.file2NodeMap.get(item.file);
|
|
2679
|
+
const { currentSource } = this.getCurrentSource(entity);
|
|
2680
|
+
// 42 11个函数的总行数
|
|
2681
|
+
if (item.end.line < currentSource.end.line - 42 && item.start.line > 1) {
|
|
2682
|
+
flag = true;
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
// 属于实体而且需要修改和查到 || 不是实体前缀的 || 他本身
|
|
2686
|
+
return flag || !item.file.includes(entityFilePrefix) || dataSourceFile === item.file;
|
|
2687
|
+
});
|
|
2688
|
+
}
|
|
2689
|
+
// 如果是entity就需要在单独,查一边来修改名字
|
|
2690
|
+
if (node instanceof concepts_1.Entity) {
|
|
2691
|
+
// 过滤一把不需要改的信息
|
|
2692
|
+
refsList = refsList.filter((item) => fileNode.getEmbeddedFilePath() !== item.file || item.isDefinition === true);
|
|
2693
|
+
// 防止死循环
|
|
2694
|
+
const forRefsList = [...refsList];
|
|
2695
|
+
for (let i = 0; i < forRefsList.length; i++) {
|
|
2696
|
+
const refItem = forRefsList[i];
|
|
2697
|
+
if (refItem.lineText?.includes('new nasl.langUtil.Collection')) {
|
|
2698
|
+
try {
|
|
2699
|
+
const fileNode = this.file2NodeMap.get(refItem.file);
|
|
2700
|
+
if (!fileNode)
|
|
2701
|
+
return;
|
|
2702
|
+
const minRange = this._findMinRange(refItem, fileNode);
|
|
2703
|
+
if (minRange.node && (minRange.node instanceof concepts_1.QueryFromExpression || minRange.node instanceof concepts_1.QueryJoinExpression)) {
|
|
2704
|
+
const callQueryComponent = minRange.node.getAncestor('CallQueryComponent');
|
|
2705
|
+
let callQueryComponentTypeAnnotation;
|
|
2706
|
+
callQueryComponent.logic.sourceMap.forEach((value, key) => {
|
|
2707
|
+
if (key.concept === 'TypeAnnotation' && key.parentNode === callQueryComponent) {
|
|
2708
|
+
callQueryComponentTypeAnnotation = key;
|
|
2709
|
+
}
|
|
2710
|
+
});
|
|
2711
|
+
const { currentSource: qcTypeAnnotationCurrentSource, fileNode: qcTypeCurrentFileNode } = callQueryComponentTypeAnnotation.getCurrentSource();
|
|
2712
|
+
const { currentSource: logicCurrentSource, fileNode: logicCurrentFileNode } = fileNode.getCurrentSource();
|
|
2713
|
+
const aggregateLength = callQueryComponent.select.selectAggregateElements.filter((item) => item.aggregateName && item.asName).length;
|
|
2714
|
+
const groupByLength = callQueryComponent.groupBy.filter((item) => item.groupElement?.propertyName && item.groupElement.asName).length;
|
|
2715
|
+
if (!groupByLength && !aggregateLength && callQueryComponentTypeAnnotation.typeKind === 'anonymousStructure') {
|
|
2716
|
+
// 拿到 List 的泛型(匿名数据结构)的所有属性
|
|
2717
|
+
const { properties } = callQueryComponentTypeAnnotation.properties[0].typeAnnotation.typeArguments[0];
|
|
2718
|
+
const targetProperty = properties.find((p) => p.name === utils.firstLowerCase(node.name));
|
|
2719
|
+
if (!targetProperty) {
|
|
2720
|
+
continue;
|
|
2721
|
+
}
|
|
2722
|
+
const { currentSource: propertyTypeCurrentSource } = targetProperty.typeAnnotation.getCurrentSource();
|
|
2723
|
+
// 减去 ": " 2个字符、减去属性名长度
|
|
2724
|
+
const propertyCharacter = propertyTypeCurrentSource.start.character - 2 - targetProperty.name.length;
|
|
2725
|
+
const propertyOffset = propertyCharacter - qcTypeAnnotationCurrentSource.start.character;
|
|
2726
|
+
const qcTypeCurrentFilePath = qcTypeCurrentFileNode.getEmbeddedFilePath();
|
|
2727
|
+
const qcTypeAnnotationCurrentCode = this.getNodeCode(qcTypeCurrentFileNode, qcTypeAnnotationCurrentSource);
|
|
2728
|
+
const logicCurrentCode = this.getNodeCode(qcTypeCurrentFileNode, logicCurrentSource);
|
|
2729
|
+
const qcTypeAnnotationOffset = logicCurrentCode.indexOf(qcTypeAnnotationCurrentCode);
|
|
2730
|
+
const declarationCodeArr = logicCurrentCode.slice(0, qcTypeAnnotationOffset).split('\n');
|
|
2731
|
+
const line = declarationCodeArr.length - 1;
|
|
2732
|
+
const character = declarationCodeArr[declarationCodeArr.length - 1].length;
|
|
2733
|
+
// eslint-disable-next-line no-await-in-loop
|
|
2734
|
+
const newRefs = await this.references({
|
|
2735
|
+
file: qcTypeCurrentFilePath,
|
|
2736
|
+
line: line + 2,
|
|
2737
|
+
offset: character + 1 + propertyOffset,
|
|
2738
|
+
});
|
|
2739
|
+
refsList.push(...newRefs.refs);
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
catch (e) {
|
|
2744
|
+
console.error('naslServer实体引用', e);
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
}
|
|
2748
|
+
// 不再当前文件里
|
|
2749
|
+
// 或者在当前列表但是位置小于entity的结束位置
|
|
2750
|
+
}
|
|
2751
|
+
if (node instanceof concepts_1.Return) {
|
|
2752
|
+
// 过滤一下最后出去的值
|
|
2753
|
+
refsList = refsList.filter((item) => !item.lineText.includes('return '));
|
|
2754
|
+
}
|
|
2755
|
+
// 如果是参数, 就需要把logic的引用 都查找出来就需要把他的父级的引用全部查找出来
|
|
2756
|
+
if (node instanceof concepts_1.Param && node.parentNode instanceof concepts_1.Logic && node.parentKey !== 'virtualParams') {
|
|
2757
|
+
const logicNode = node.parentNode;
|
|
2758
|
+
const { currentSource } = this.getCurrentSource(logicNode);
|
|
2759
|
+
const parentRefs = await this.references({
|
|
2760
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
2761
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
2762
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character),
|
|
2763
|
+
});
|
|
2764
|
+
// console.log(parentRefs.refs)
|
|
2765
|
+
refsList = [...refsList, ...parentRefs.refs];
|
|
2766
|
+
}
|
|
2767
|
+
// 如果是参数修改, 就需要把logic的引用 都查找出来就需要把他的父级的引用全部查找出来
|
|
2768
|
+
if (node instanceof concepts_1.Param && (node.parentNode instanceof concepts_1.View || node.parentNode instanceof concepts_1.Process)) {
|
|
2769
|
+
const viewNode = node.parentNode;
|
|
2770
|
+
const { currentSource, fileNode } = this.getCurrentSource(viewNode);
|
|
2771
|
+
const code = this.getNodeCode(fileNode, currentSource);
|
|
2772
|
+
const viewIndex = code.indexOf(' {');
|
|
2773
|
+
const viewRefs = await this.references({
|
|
2774
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
2775
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
2776
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character + viewIndex),
|
|
2777
|
+
});
|
|
2778
|
+
let filterViewRefs = [];
|
|
2779
|
+
if (node.parentNode instanceof concepts_1.View) {
|
|
2780
|
+
filterViewRefs = viewRefs.refs.filter((item) => item.lineText.includes('.$destination('));
|
|
2781
|
+
}
|
|
2782
|
+
else {
|
|
2783
|
+
// 如果是参数修改, 就需要把Process的引用查找出来
|
|
2784
|
+
filterViewRefs = viewRefs.refs.filter((item) => item.lineText.includes('.launch('));
|
|
2785
|
+
}
|
|
2786
|
+
refsList = [...refsList, ...filterViewRefs];
|
|
2787
|
+
}
|
|
2788
|
+
/**
|
|
2789
|
+
* 暂时不要了, 因为生成的结构发生了变化
|
|
2790
|
+
* view 因为不是嵌套的,所以不能用最前面的变量查找,所以要单独处理一下
|
|
2791
|
+
* 找到第一个 { 之前的变量 进行修改
|
|
2792
|
+
* 如果是VIew的查找,比较特殊,他查的是当前抛出的 {} 大括号前的
|
|
2793
|
+
* 最后一个,因为生成的规则不一样
|
|
2794
|
+
*/
|
|
2795
|
+
// if (node instanceof View) {
|
|
2796
|
+
// const code = currentSource.code;
|
|
2797
|
+
// const viewIndex = code.indexOf(' {');
|
|
2798
|
+
// const viewRefs = await naslServer.references({
|
|
2799
|
+
// file: (fileNode as FileNode).getEmbeddedFilePath(),
|
|
2800
|
+
// line: lsp2tspNumber(currentSource.start.line),
|
|
2801
|
+
// offset: lsp2tspNumber(currentSource.start.character + viewIndex),
|
|
2802
|
+
// });
|
|
2803
|
+
// refsList = [...viewRefs.refs];
|
|
2804
|
+
// }
|
|
2805
|
+
/**
|
|
2806
|
+
* elements 需要查的是__elements.后面的那个内容,过滤两个为了生成内容的节点
|
|
2807
|
+
*/
|
|
2808
|
+
if (node instanceof concepts_1.ViewElement) {
|
|
2809
|
+
if (currentSource) {
|
|
2810
|
+
const code = this.getNodeCode(fileNode, currentSource);
|
|
2811
|
+
const prefix = '__elements.';
|
|
2812
|
+
const prefixIndex = code.indexOf(prefix) !== -1 ? code.indexOf(prefix) : 0;
|
|
2813
|
+
const methodsNameIndex = prefixIndex + prefix.length;
|
|
2814
|
+
const methods = await this.references({
|
|
2815
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
2816
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
2817
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character + methodsNameIndex),
|
|
2818
|
+
});
|
|
2819
|
+
const methodRefs = [];
|
|
2820
|
+
methods.refs.forEach((item) => {
|
|
2821
|
+
// 定义里的格式,在删除的时候留下来占位
|
|
2822
|
+
// 重命名的时候会过滤
|
|
2823
|
+
// 这里只过滤 __elements.button = new nasl.ui.Button<any>这种格式
|
|
2824
|
+
// 处理声明组件名可能重复的问题, 查找引用不提示
|
|
2825
|
+
const find = methodRefs.find((findItem) => item.lineText === findItem.lineText && item.lineText.includes(': nasl.ui.'));
|
|
2826
|
+
if (!find) {
|
|
2827
|
+
methodRefs.push(item);
|
|
2828
|
+
}
|
|
2829
|
+
});
|
|
2830
|
+
refsList = [...methodRefs];
|
|
2831
|
+
}
|
|
2832
|
+
}
|
|
2833
|
+
if (node instanceof concepts_1.Process) {
|
|
2834
|
+
if (currentSource) {
|
|
2835
|
+
const code = this.getNodeCode(fileNode, currentSource);
|
|
2836
|
+
const prefix = '__ProcessIdentification__';
|
|
2837
|
+
let positions = [];
|
|
2838
|
+
let pos = code.indexOf(prefix);
|
|
2839
|
+
while (pos !== -1) {
|
|
2840
|
+
positions.push(pos);
|
|
2841
|
+
pos = code.indexOf(prefix, pos + prefix.length);
|
|
2842
|
+
}
|
|
2843
|
+
positions.shift();
|
|
2844
|
+
// 拿到标识下定义的const process = {...}
|
|
2845
|
+
positions = positions.map((position) => code.indexOf('const', position + prefix.length));
|
|
2846
|
+
const promises = positions.map((item) => this.references({
|
|
2847
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
2848
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
2849
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character + item),
|
|
2850
|
+
}));
|
|
2851
|
+
const results = await Promise.all(promises);
|
|
2852
|
+
results.forEach((constRefs) => {
|
|
2853
|
+
refsList = [...refsList, ...constRefs.refs];
|
|
2854
|
+
});
|
|
2855
|
+
}
|
|
2856
|
+
}
|
|
2857
|
+
if ((node instanceof concepts_1.Param || node instanceof concepts_1.Return) && node.parentNode instanceof concepts_1.Process) {
|
|
2858
|
+
const { currentSource, fileNode } = this.getCurrentSource(node.parentNode);
|
|
2859
|
+
if (currentSource) {
|
|
2860
|
+
const code = this.getNodeCode(fileNode, currentSource);
|
|
2861
|
+
const prefix = '__ProcessIdentification__';
|
|
2862
|
+
const positions = [];
|
|
2863
|
+
let pos = code.indexOf(prefix);
|
|
2864
|
+
pos = code.indexOf(node.name, pos + prefix.length);
|
|
2865
|
+
// pos === -1:两种情况:
|
|
2866
|
+
// 1、找到最后一个节点了,继续找找不下去了。
|
|
2867
|
+
// 2、创建、删除节点的时候也会找不到(本身这两种操作就不应该进到这个方法)
|
|
2868
|
+
while (pos !== -1) {
|
|
2869
|
+
positions.push(pos);
|
|
2870
|
+
pos = code.indexOf(prefix, pos + prefix.length);
|
|
2871
|
+
pos = pos === -1 ? pos : code.indexOf(node.name, pos + prefix.length);
|
|
2872
|
+
}
|
|
2873
|
+
positions.shift();
|
|
2874
|
+
// 拿到标识下定义的参数名字
|
|
2875
|
+
const promises = positions.map((item) => this.references({
|
|
2876
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
2877
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
2878
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character + item),
|
|
2879
|
+
}));
|
|
2880
|
+
const results = await Promise.all(promises);
|
|
2881
|
+
results.forEach((constRefs) => {
|
|
2882
|
+
refsList = [...refsList, ...constRefs.refs];
|
|
2883
|
+
});
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
if (node instanceof concepts_1.ProcessElement) {
|
|
2887
|
+
if (currentSource) {
|
|
2888
|
+
const code = this.getNodeCode(fileNode, currentSource);
|
|
2889
|
+
const prefix = '__ProcessIdentification__';
|
|
2890
|
+
let positions = [];
|
|
2891
|
+
let pos = code.indexOf(prefix);
|
|
2892
|
+
while (pos !== -1) {
|
|
2893
|
+
positions.push(pos);
|
|
2894
|
+
pos = code.indexOf(prefix, pos + prefix.length);
|
|
2895
|
+
}
|
|
2896
|
+
// 拿到标识下定义的const process = {...}
|
|
2897
|
+
positions = positions.map((position) => code.indexOf(`${node.name}:`, position + prefix.length));
|
|
2898
|
+
const promises = positions.map((item) => this.references({
|
|
2899
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
2900
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
2901
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character + item),
|
|
2902
|
+
}));
|
|
2903
|
+
const results = await Promise.all(promises);
|
|
2904
|
+
results.forEach((constRefs) => {
|
|
2905
|
+
refsList = [...refsList, ...constRefs.refs];
|
|
2906
|
+
});
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
if (node instanceof concepts_1.Return && node.parentNode instanceof concepts_1.ProcessElement) {
|
|
2910
|
+
const { currentSource, fileNode } = this.getCurrentSource(node.parentNode);
|
|
2911
|
+
if (currentSource) {
|
|
2912
|
+
// 流程任务出参查找引用需要查找到流程任务完成逻辑
|
|
2913
|
+
// const parentRefs = await this.references({
|
|
2914
|
+
// file: (fileNode as FileNode).getEmbeddedFilePath(),
|
|
2915
|
+
// line: lsp2tspNumber(currentSource.start.line),
|
|
2916
|
+
// offset: lsp2tspNumber(currentSource.start.character),
|
|
2917
|
+
// });
|
|
2918
|
+
// refsList = [...refsList, ...parentRefs.refs];
|
|
2919
|
+
// console.log(parentRefs.refs)
|
|
2920
|
+
// 流程任务出参查找引用比较特殊,需要查找到 const process = {...} 的引用
|
|
2921
|
+
const code = this.getNodeCode(fileNode, currentSource);
|
|
2922
|
+
const prefix = '__ProcessIdentification__';
|
|
2923
|
+
const positions = [];
|
|
2924
|
+
let pos = code.indexOf(prefix);
|
|
2925
|
+
// 需要再次定位到processelement对象上,避免process上存在同名参数
|
|
2926
|
+
pos = pos === -1 ? pos : code.indexOf(node.parentNode.name, pos + prefix.length);
|
|
2927
|
+
pos = pos === -1 ? pos : code.indexOf(node.name, pos + prefix.length);
|
|
2928
|
+
// pos === -1:两种情况:
|
|
2929
|
+
// 1、找到最后一个节点了,继续找找不下去了。
|
|
2930
|
+
// 2、创建、删除节点的时候也会找不到(本身这两种操作就不应该进到这个方法)
|
|
2931
|
+
while (pos !== -1) {
|
|
2932
|
+
positions.push(pos);
|
|
2933
|
+
pos = code.indexOf(prefix, pos + prefix.length);
|
|
2934
|
+
// 需要再次定位到processelement对象上,避免process上存在同名参数
|
|
2935
|
+
pos = pos === -1 ? pos : code.indexOf(node.parentNode.name, pos + node.parentNode.name.length);
|
|
2936
|
+
pos = pos === -1 ? pos : code.indexOf(node.name, pos + prefix.length);
|
|
2937
|
+
}
|
|
2938
|
+
// 拿到标识下定义的参数名字
|
|
2939
|
+
const promises = positions.map((item) => this.references({
|
|
2940
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
2941
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
2942
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character + item),
|
|
2943
|
+
}));
|
|
2944
|
+
const results = await Promise.all(promises);
|
|
2945
|
+
results.forEach((constRefs) => {
|
|
2946
|
+
if (constRefs.symbolDisplayString.includes('(parameter)')) {
|
|
2947
|
+
return;
|
|
2948
|
+
}
|
|
2949
|
+
refsList = [...refsList, ...constRefs.refs];
|
|
2950
|
+
});
|
|
2951
|
+
}
|
|
2952
|
+
}
|
|
2953
|
+
// console.log(refsList, 'refsList');
|
|
2954
|
+
return refsList;
|
|
2955
|
+
}
|
|
2956
|
+
/**
|
|
2957
|
+
* 查找引用,并且做一些 修改前的准备工作,
|
|
2958
|
+
* 有引用有的话,就返回集合
|
|
2959
|
+
* @param node 当前重命名的节点
|
|
2960
|
+
* @param newValue 传递过来的新值,给MemberExpression用的比较特殊
|
|
2961
|
+
* 而且,这个新值不一定会用到,MemberExpression在批量更新的时候,可以取到新的value, 这里需要位置信息防止 a.a.a.a 中的一个a发生修改
|
|
2962
|
+
* @returns 找到的引用
|
|
2963
|
+
*/
|
|
2964
|
+
_renamePrepare(node, refsList, newValue) {
|
|
2965
|
+
const oldName = node?.name;
|
|
2966
|
+
const result = refsList
|
|
2967
|
+
.map((record) => {
|
|
2968
|
+
const fileNode = this.file2NodeMap.get(record.file);
|
|
2969
|
+
if (!fileNode)
|
|
2970
|
+
return null;
|
|
2971
|
+
const minRange = this._findMinRange(record, fileNode);
|
|
2972
|
+
if (minRange) {
|
|
2973
|
+
// 节点上ts临时变量标识,如果有这个就不rename
|
|
2974
|
+
if (minRange.node.noTsReName) {
|
|
2975
|
+
return null;
|
|
2976
|
+
}
|
|
2977
|
+
// 如果节点是TypeAnnotation类型,
|
|
2978
|
+
// 很复杂,可能是多级嵌套结构
|
|
2979
|
+
// 不一定只修改typeName
|
|
2980
|
+
if (minRange.node instanceof concepts_1.TypeAnnotation) {
|
|
2981
|
+
// console.log(record);
|
|
2982
|
+
// 如果是fake的逻辑,内部的重命名都不需要修改
|
|
2983
|
+
// if ((minRange.node?.parentNode as any).logic && (minRange.node?.parentNode as any).logic?.fake) {
|
|
2984
|
+
// return null;
|
|
2985
|
+
// }
|
|
2986
|
+
minRange.setTypeMethods = 'setTypeName';
|
|
2987
|
+
}
|
|
2988
|
+
if (minRange.node instanceof concepts_1.CallConnector) {
|
|
2989
|
+
minRange.setTypeMethods = 'setCalleeConnectionName';
|
|
2990
|
+
}
|
|
2991
|
+
// 如果节点是logic修改引发calllogic修改
|
|
2992
|
+
if (minRange.node instanceof concepts_1.CallLogic && node instanceof concepts_1.Logic) {
|
|
2993
|
+
minRange.setTypeMethods = 'setCalleeName';
|
|
2994
|
+
}
|
|
2995
|
+
if (minRange.node instanceof concepts_1.CallLogic && node instanceof concepts_1.ViewElement) {
|
|
2996
|
+
minRange.setTypeMethods = 'setCalleeNamespace';
|
|
2997
|
+
minRange.newValue = `elements.${newValue}.logics`;
|
|
2998
|
+
}
|
|
2999
|
+
if (minRange.node instanceof concepts_1.CallEvent) {
|
|
3000
|
+
minRange.setTypeMethods = 'setCalleeName';
|
|
3001
|
+
}
|
|
3002
|
+
// 如果节点是实体修改引发calllogic修改
|
|
3003
|
+
if (minRange.node instanceof concepts_1.CallLogic &&
|
|
3004
|
+
(node instanceof concepts_1.Entity || node instanceof concepts_1.View || node instanceof concepts_1.Process || node instanceof concepts_1.ProcessElement)) {
|
|
3005
|
+
// 匹配到的内容,当前这一行的内容;
|
|
3006
|
+
// 因为要用下面的点位信息
|
|
3007
|
+
/**
|
|
3008
|
+
* 如果namespce是 'app.views.Student.views.404.views.505.views.update'
|
|
3009
|
+
* 在ts中会是'app.views.Student.views.$404.views.$505.views.update'
|
|
3010
|
+
* 但是505 要改名为 666 ,要存的是666
|
|
3011
|
+
* 'app.views.Student.views.404.views.666.views.update'
|
|
3012
|
+
* 1.取到转后的
|
|
3013
|
+
* 2.在匹配到的内容中取转后的namespace的位置
|
|
3014
|
+
* 3.然后把namespace中的 $替换成 ''
|
|
3015
|
+
*
|
|
3016
|
+
*/
|
|
3017
|
+
const { tsCalleeNamespace } = minRange.node;
|
|
3018
|
+
// 先看下标位置
|
|
3019
|
+
const { lineText } = record;
|
|
3020
|
+
const index = lineText.indexOf(tsCalleeNamespace);
|
|
3021
|
+
// 在把开始结束位置的-开始位置,来知道是哪里要替换
|
|
3022
|
+
const start = record.start.offset - index - 1;
|
|
3023
|
+
const end = record.end.offset - index - 1;
|
|
3024
|
+
// 新的完整的value
|
|
3025
|
+
let newTsNameSpace = tsCalleeNamespace.substring(0, start) + newValue + tsCalleeNamespace.substring(end, tsCalleeNamespace.length);
|
|
3026
|
+
newTsNameSpace = newTsNameSpace.replace(/.\$/g, '.');
|
|
3027
|
+
minRange.setTypeMethods = 'setCalleeNamespace';
|
|
3028
|
+
minRange.newValue = newTsNameSpace;
|
|
3029
|
+
}
|
|
3030
|
+
// 如果参数修改影响了 callLogic
|
|
3031
|
+
if (minRange.node instanceof concepts_1.CallLogic && node instanceof concepts_1.Param) {
|
|
3032
|
+
return null;
|
|
3033
|
+
// 逻辑第几个位置发生修改,对应的calllogic对应位置的内容要进行修改
|
|
3034
|
+
// minRange.setTypeMethods = 'setArgumentName';
|
|
3035
|
+
// const nodeArguments = minRange.node.arguments;
|
|
3036
|
+
// minRange.newValue = [...nodeArguments];
|
|
3037
|
+
// const LogicNode = node.parentNode;
|
|
3038
|
+
// const paramIndex = (LogicNode as Logic).params.findIndex((param) => param === node);
|
|
3039
|
+
// console.log(node, nodeArguments);
|
|
3040
|
+
// if (paramIndex !== -1) {
|
|
3041
|
+
// minRange.setTypeMethods = 'setArgumentName';
|
|
3042
|
+
// minRange.newValue = {
|
|
3043
|
+
// argument: nodeArguments[paramIndex],
|
|
3044
|
+
// newKeyword: newValue,
|
|
3045
|
+
// };
|
|
3046
|
+
// } else {
|
|
3047
|
+
// return null;
|
|
3048
|
+
// }
|
|
3049
|
+
}
|
|
3050
|
+
// 如果节点是Identifier表达式
|
|
3051
|
+
if (minRange.node instanceof concepts_1.Identifier) {
|
|
3052
|
+
// 匹配到的内容,当前这一行的内容;
|
|
3053
|
+
// 因为要用下面的点位信息
|
|
3054
|
+
const { name } = minRange.node;
|
|
3055
|
+
// 如果name不改,那就是要改命名空间
|
|
3056
|
+
if (node instanceof concepts_1.Frontend || newValue === name) {
|
|
3057
|
+
const { namespace } = minRange.node;
|
|
3058
|
+
// 先看下标位置
|
|
3059
|
+
const { lineText } = record;
|
|
3060
|
+
const index = lineText.indexOf(namespace);
|
|
3061
|
+
// 在把开始结束位置的-开始位置,来知道是哪里要替换
|
|
3062
|
+
const start = record.start.offset - index - 1;
|
|
3063
|
+
const end = record.end.offset - index - 1;
|
|
3064
|
+
// 新的完整的value
|
|
3065
|
+
const newTextValue = namespace.substring(0, start) + newValue + namespace.substring(end, namespace.length);
|
|
3066
|
+
minRange.setTypeMethods = 'setNamespace';
|
|
3067
|
+
minRange.newValue = newTextValue;
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
if (node instanceof concepts_1.Enum) {
|
|
3071
|
+
// 如果是枚举修改,枚举的值刚好在Identifier 中选了 就修改值
|
|
3072
|
+
if (minRange.node instanceof concepts_1.Identifier) {
|
|
3073
|
+
minRange.newValue = newValue;
|
|
3074
|
+
minRange.setTypeMethods = 'setName';
|
|
3075
|
+
}
|
|
3076
|
+
else if (minRange.node instanceof concepts_1.EntityProperty) {
|
|
3077
|
+
// 如果枚举自己改名引用到了实体字段,而不是实体字段下的类型,就说明是默认值,默认值可以不处理
|
|
3078
|
+
return null;
|
|
3079
|
+
}
|
|
3080
|
+
}
|
|
3081
|
+
// 如果修改逻辑,改到了Identifier表达式,只能说明是在属性里有使用了
|
|
3082
|
+
if (minRange.node instanceof concepts_1.Identifier && node instanceof concepts_1.Logic) {
|
|
3083
|
+
minRange.newValue = newValue;
|
|
3084
|
+
minRange.setTypeMethods = 'setName';
|
|
3085
|
+
}
|
|
3086
|
+
// 如果节点是MemberExpression表达式
|
|
3087
|
+
if (minRange.node instanceof concepts_1.MemberExpression) {
|
|
3088
|
+
// 枚举key的特殊性,因为它不是原来的key+value形式的
|
|
3089
|
+
// 是加了中括号啥的,所以直接赋值新值
|
|
3090
|
+
if (node instanceof concepts_1.EnumItem) {
|
|
3091
|
+
const newTextValue = `${node.parentNode.name}.${newValue}`;
|
|
3092
|
+
minRange.newValue = newTextValue;
|
|
3093
|
+
}
|
|
3094
|
+
else {
|
|
3095
|
+
// 匹配到的内容,当前这一行的内容;
|
|
3096
|
+
// 因为要用下面的点位信息
|
|
3097
|
+
const a = record.lineText;
|
|
3098
|
+
// 之前的内容
|
|
3099
|
+
const oldValue = minRange.node.getValue();
|
|
3100
|
+
const index = a.indexOf(oldValue);
|
|
3101
|
+
const start = record.start.offset - index - 1;
|
|
3102
|
+
const end = record.end.offset - index - 1;
|
|
3103
|
+
const newTextValue = oldValue.substring(0, start) + newValue + oldValue.substring(end, oldValue.length);
|
|
3104
|
+
// MemberExpression可能改的是多层中的某一个
|
|
3105
|
+
// 倒序, 对比看是哪里发生了修改
|
|
3106
|
+
// 比较特殊就把新匹配到的值返回内部自己看要改那个地方的值
|
|
3107
|
+
minRange.newValue = newTextValue;
|
|
3108
|
+
}
|
|
3109
|
+
}
|
|
3110
|
+
if (node instanceof concepts_1.Entity) {
|
|
3111
|
+
// 如果是修改实体,引发节点依赖实体发生改变的
|
|
3112
|
+
if (minRange.node instanceof concepts_1.EntityProperty) {
|
|
3113
|
+
minRange.setTypeMethods = 'setRelationEntity';
|
|
3114
|
+
}
|
|
3115
|
+
else if (minRange.node instanceof concepts_1.QueryFieldExpression) {
|
|
3116
|
+
if (minRange.node.parentKey === 'selectElements') {
|
|
3117
|
+
minRange.setTypeMethods = 'setEntityAsNameAndEffect';
|
|
3118
|
+
}
|
|
3119
|
+
else {
|
|
3120
|
+
minRange.setTypeMethods = 'setEntityAsName';
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
else if (minRange.node instanceof concepts_1.QueryGroupByExpression) {
|
|
3124
|
+
minRange.setTypeMethods = 'setEntityAsName';
|
|
3125
|
+
}
|
|
3126
|
+
else if (minRange.node instanceof concepts_1.QueryFromExpression || minRange.node instanceof concepts_1.QueryJoinExpression) {
|
|
3127
|
+
minRange.setTypeMethods = 'setEntityNameAndEffect';
|
|
3128
|
+
}
|
|
3129
|
+
else if (minRange.node instanceof concepts_1.BindAttribute && minRange.node.name === 'url') {
|
|
3130
|
+
// 如果是查找到 上传地址的链接引用
|
|
3131
|
+
let newName = newValue.replace(/[A-Z]/g, (item) => `-${item.toLowerCase()}`);
|
|
3132
|
+
newName = newName[0] === '-' ? newName.slice(1) : newName;
|
|
3133
|
+
const newTextValue = node.parentNode.name === 'defaultDS' ? `/api/${newName}/import` : `/api/${node.parentNode.name}/${newName}/import`;
|
|
3134
|
+
minRange.setTypeMethods = 'setUrlValue';
|
|
3135
|
+
minRange.newValue = newTextValue;
|
|
3136
|
+
}
|
|
3137
|
+
else if (minRange.node instanceof concepts_1.Identifier) {
|
|
3138
|
+
minRange.newValue = utils.firstLowerCase(newValue);
|
|
3139
|
+
}
|
|
3140
|
+
}
|
|
3141
|
+
// 如果是修改实体属性,要同步实体属性
|
|
3142
|
+
if (minRange.node instanceof concepts_1.EntityProperty &&
|
|
3143
|
+
node instanceof concepts_1.EntityProperty &&
|
|
3144
|
+
record.lineText.includes('@nasl.annotation.EntityRelation')) {
|
|
3145
|
+
minRange.setTypeMethods = 'setRelationProperty';
|
|
3146
|
+
}
|
|
3147
|
+
// 如果要修改索引的
|
|
3148
|
+
if (minRange.node instanceof concepts_1.EntityIndex) {
|
|
3149
|
+
const newPropertyNameList = [...minRange.node.propertyNames];
|
|
3150
|
+
const findIndex = newPropertyNameList.findIndex((item) => item === oldName);
|
|
3151
|
+
if (findIndex !== -1) {
|
|
3152
|
+
// 修改数组的值
|
|
3153
|
+
newPropertyNameList.splice(findIndex, 1, newValue);
|
|
3154
|
+
minRange.setTypeMethods = 'setPropertyNames';
|
|
3155
|
+
minRange.newValue = newPropertyNameList;
|
|
3156
|
+
}
|
|
3157
|
+
}
|
|
3158
|
+
// 如果是跳转逻辑的修改
|
|
3159
|
+
// 跳转逻辑本身页面 都需要带 View前缀
|
|
3160
|
+
if (node instanceof concepts_1.View && minRange.node instanceof concepts_1.Destination) {
|
|
3161
|
+
/**
|
|
3162
|
+
* 如果namespce是 'app.views.Student.views.404.views.505.views.update'
|
|
3163
|
+
* 在ts中会是'app.views.Student.views.$404.views.$505.views.update'
|
|
3164
|
+
* 但是505 要改名为 666 ,要存的是666
|
|
3165
|
+
* 'app.views.Student.views.404.views.666.views.update'
|
|
3166
|
+
* 1.取到转后的
|
|
3167
|
+
* 2.在匹配到的内容中取转后的namespace的位置
|
|
3168
|
+
* 3.然后把namespace中的 $替换成 ''
|
|
3169
|
+
*
|
|
3170
|
+
*/
|
|
3171
|
+
const { tsCalleeNamespace } = minRange.node;
|
|
3172
|
+
const { tsName } = minRange.node;
|
|
3173
|
+
const oldValue = `${tsCalleeNamespace}.${tsName}`;
|
|
3174
|
+
// 先看下标位置
|
|
3175
|
+
const { lineText } = record;
|
|
3176
|
+
const index = lineText.indexOf(oldValue);
|
|
3177
|
+
// 在把开始结束位置的-开始位置,来知道是哪里要替换
|
|
3178
|
+
const start = record.start.offset - index - 1;
|
|
3179
|
+
const end = record.end.offset - index - 1;
|
|
3180
|
+
if (start > tsCalleeNamespace.length) {
|
|
3181
|
+
minRange.setTypeMethods = 'setViewName';
|
|
3182
|
+
minRange.newValue = newValue;
|
|
3183
|
+
}
|
|
3184
|
+
else {
|
|
3185
|
+
// 新的完整的value
|
|
3186
|
+
let newTsNameSpace = tsCalleeNamespace.substring(0, start) + newValue + tsCalleeNamespace.substring(end, tsCalleeNamespace.length);
|
|
3187
|
+
minRange.setTypeMethods = 'setViewNamespace';
|
|
3188
|
+
newTsNameSpace = newTsNameSpace.replace(/\.\$/g, '.');
|
|
3189
|
+
minRange.newValue = newTsNameSpace;
|
|
3190
|
+
}
|
|
3191
|
+
}
|
|
3192
|
+
if (node instanceof concepts_1.Frontend && minRange.node instanceof concepts_1.Destination) {
|
|
3193
|
+
const { tsCalleeNamespace } = minRange.node;
|
|
3194
|
+
const { tsName } = minRange.node;
|
|
3195
|
+
const oldValue = `${tsCalleeNamespace}.${tsName}`;
|
|
3196
|
+
// 先看下标位置
|
|
3197
|
+
const { lineText } = record;
|
|
3198
|
+
const index = lineText.indexOf(oldValue);
|
|
3199
|
+
// 在把开始结束位置的-开始位置,来知道是哪里要替换
|
|
3200
|
+
const start = record.start.offset - index - 1;
|
|
3201
|
+
const end = record.end.offset - index - 1;
|
|
3202
|
+
if (start <= tsCalleeNamespace.length) {
|
|
3203
|
+
// 新的完整的value
|
|
3204
|
+
let newTsNameSpace = tsCalleeNamespace.substring(0, start) + newValue + tsCalleeNamespace.substring(end, tsCalleeNamespace.length);
|
|
3205
|
+
minRange.setTypeMethods = 'setViewNamespace';
|
|
3206
|
+
newTsNameSpace = newTsNameSpace.replace(/\.\$/g, '.');
|
|
3207
|
+
minRange.newValue = newTsNameSpace;
|
|
3208
|
+
}
|
|
3209
|
+
}
|
|
3210
|
+
// 如果是事件修改
|
|
3211
|
+
// 如果是view也需要加前缀
|
|
3212
|
+
// logic 和 views名称修改 可能会触发bindEvent修改
|
|
3213
|
+
if (minRange.node instanceof concepts_1.BindEvent) {
|
|
3214
|
+
// 页面逻辑直接赋值就可以, 因为是相对路径
|
|
3215
|
+
if (node instanceof concepts_1.ViewElement) {
|
|
3216
|
+
minRange.setTypeMethods = 'setCalleeNamespace';
|
|
3217
|
+
minRange.newValue = `elements.${newValue}.logics`;
|
|
3218
|
+
}
|
|
3219
|
+
else {
|
|
3220
|
+
/**
|
|
3221
|
+
* 如果namespce是 'app.views.Student.views.404.views.505.views.update'
|
|
3222
|
+
* 在ts中会是'app.views.Student.views.$404.views.$505.views.update'
|
|
3223
|
+
* 但是505 要改名为 666 ,要存的是666
|
|
3224
|
+
* 'app.views.Student.views.404.views.666.views.update'
|
|
3225
|
+
* 1.取到转后的
|
|
3226
|
+
* 2.在匹配到的内容中取转后的namespace的位置
|
|
3227
|
+
* 3.然后把namespace中的 $替换成 ''
|
|
3228
|
+
*/
|
|
3229
|
+
const { tsCalleeNamespace } = minRange.node;
|
|
3230
|
+
const oldValue = tsCalleeNamespace;
|
|
3231
|
+
// 先看下标位置
|
|
3232
|
+
const { lineText } = record;
|
|
3233
|
+
const index = lineText.indexOf(oldValue);
|
|
3234
|
+
// 在把开始结束位置的-开始位置,来知道是哪里要替换
|
|
3235
|
+
const start = record.start.offset - index - 1;
|
|
3236
|
+
const end = record.end.offset - index - 1;
|
|
3237
|
+
// 新的完整的value
|
|
3238
|
+
if (start > tsCalleeNamespace.length) {
|
|
3239
|
+
minRange.setTypeMethods = 'setCalleeName';
|
|
3240
|
+
minRange.newValue = newValue;
|
|
3241
|
+
}
|
|
3242
|
+
else {
|
|
3243
|
+
// 新的完整的value
|
|
3244
|
+
let newTsNameSpace = tsCalleeNamespace.substring(0, start) + newValue + tsCalleeNamespace.substring(end, tsCalleeNamespace.length);
|
|
3245
|
+
minRange.setTypeMethods = 'setCalleeNamespace';
|
|
3246
|
+
newTsNameSpace = newTsNameSpace.replace(/\.\$/g, '.');
|
|
3247
|
+
minRange.newValue = newTsNameSpace;
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
}
|
|
3251
|
+
if (minRange.node instanceof concepts_1.Destination && node instanceof concepts_1.Param) {
|
|
3252
|
+
// 因为view是key value 绑定所以需要重新赋值
|
|
3253
|
+
if (node.parentNode instanceof concepts_1.View) {
|
|
3254
|
+
const nodeArguments = minRange.node.arguments;
|
|
3255
|
+
const findArgument = nodeArguments.find((item) => node.name === item.keyword);
|
|
3256
|
+
if (findArgument) {
|
|
3257
|
+
minRange.setTypeMethods = 'setArgumentsKeyWord';
|
|
3258
|
+
minRange.newValue = {
|
|
3259
|
+
findArgument,
|
|
3260
|
+
newKeyword: newValue,
|
|
3261
|
+
};
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
else {
|
|
3265
|
+
// 如果是修改param查找到Destination就不操作
|
|
3266
|
+
return null;
|
|
3267
|
+
}
|
|
3268
|
+
}
|
|
3269
|
+
if (minRange.node instanceof concepts_1.Interface && node instanceof concepts_1.Logic) {
|
|
3270
|
+
minRange.setTypeMethods = 'setOriginLogicName';
|
|
3271
|
+
}
|
|
3272
|
+
// 如果是role改名,就需要查到变更后的数组
|
|
3273
|
+
if ((minRange.node instanceof concepts_1.View || minRange.node instanceof concepts_1.ViewElement) && node instanceof concepts_1.Role) {
|
|
3274
|
+
// oldName旧的节点存的值
|
|
3275
|
+
// newValue用户输入值
|
|
3276
|
+
// node.bindRoles 存的
|
|
3277
|
+
minRange.setTypeMethods = 'setBindRoles';
|
|
3278
|
+
const str = minRange.node.bindRoles.toString().replace(oldName, newValue);
|
|
3279
|
+
const newBindRoles = str.split(',');
|
|
3280
|
+
minRange.newValue = newBindRoles;
|
|
3281
|
+
}
|
|
3282
|
+
// 修改枚举值找到了EntityProperty就说明给了默认值
|
|
3283
|
+
if (node instanceof concepts_1.EnumItem) {
|
|
3284
|
+
if (minRange.node instanceof concepts_1.EntityProperty || minRange.node instanceof concepts_1.StructureProperty) {
|
|
3285
|
+
minRange.setTypeMethods = 'setDefaultValue';
|
|
3286
|
+
}
|
|
3287
|
+
if (minRange.node instanceof concepts_1.Param || minRange.node instanceof concepts_1.Variable || minRange.node instanceof concepts_1.Return) {
|
|
3288
|
+
minRange.setTypeMethods = 'setDefaultValue';
|
|
3289
|
+
}
|
|
3290
|
+
}
|
|
3291
|
+
// 如果修改的是dataSource属性
|
|
3292
|
+
if (node instanceof concepts_1.DataSource) {
|
|
3293
|
+
const setTypeNamespace = (typeNamespace, record) => {
|
|
3294
|
+
// 先看下标位置
|
|
3295
|
+
const { lineText } = record;
|
|
3296
|
+
const index = lineText.indexOf(typeNamespace);
|
|
3297
|
+
// 在把开始结束位置的-开始位置,来知道是哪里要替换
|
|
3298
|
+
const start = record.start.offset - index - 1;
|
|
3299
|
+
const end = record.end.offset - index - 1;
|
|
3300
|
+
// 新的完整的value
|
|
3301
|
+
const newTextValue = typeNamespace.substring(0, start) + newValue + typeNamespace.substring(end, typeNamespace.length);
|
|
3302
|
+
minRange.newValue = newTextValue;
|
|
3303
|
+
return newTextValue;
|
|
3304
|
+
};
|
|
3305
|
+
if (minRange.node instanceof concepts_1.TypeAnnotation) {
|
|
3306
|
+
minRange.setTypeMethods = 'setTypeNamespace';
|
|
3307
|
+
const newValue = setTypeNamespace(minRange.node.typeNamespace, record);
|
|
3308
|
+
minRange.newValue = newValue;
|
|
3309
|
+
}
|
|
3310
|
+
else if (minRange.node instanceof concepts_1.QueryFromExpression || minRange.node instanceof concepts_1.QueryJoinExpression) {
|
|
3311
|
+
minRange.setTypeMethods = 'setEntityNamespace';
|
|
3312
|
+
const newValue = setTypeNamespace(minRange.node.entityNamespace, record);
|
|
3313
|
+
minRange.newValue = newValue;
|
|
3314
|
+
}
|
|
3315
|
+
else if (minRange.node instanceof concepts_1.QueryFieldExpression) {
|
|
3316
|
+
return null;
|
|
3317
|
+
}
|
|
3318
|
+
else if (minRange.node instanceof concepts_1.CallLogic) {
|
|
3319
|
+
minRange.setTypeMethods = 'setCalleeNamespace';
|
|
3320
|
+
const newValue = setTypeNamespace(minRange.node.calleeNamespace, record);
|
|
3321
|
+
minRange.newValue = newValue;
|
|
3322
|
+
}
|
|
3323
|
+
else if (minRange.node instanceof concepts_1.EntityProperty) {
|
|
3324
|
+
minRange.setTypeMethods = 'setRelationNamespace';
|
|
3325
|
+
const newValue = setTypeNamespace(minRange.node.relationNamespace, record);
|
|
3326
|
+
minRange.newValue = newValue;
|
|
3327
|
+
}
|
|
3328
|
+
else if (minRange.node instanceof concepts_1.SqlQueryComponent || minRange.node instanceof concepts_1.OqlQueryComponent) {
|
|
3329
|
+
minRange.setTypeMethods = 'renameDataSource';
|
|
3330
|
+
}
|
|
3331
|
+
}
|
|
3332
|
+
if (minRange.node instanceof concepts_1.QueryFieldExpression && node instanceof concepts_1.EntityProperty) {
|
|
3333
|
+
minRange.setTypeMethods = 'setPropertyName';
|
|
3334
|
+
}
|
|
3335
|
+
if (minRange.node instanceof concepts_1.QueryGroupByExpression && node instanceof concepts_1.EntityProperty) {
|
|
3336
|
+
minRange.setTypeMethods = 'setPropertyName';
|
|
3337
|
+
}
|
|
3338
|
+
// 如果跳转链接或者页面变量同一个param和TypeAnnotation 有两个过滤掉一个
|
|
3339
|
+
if ((minRange.node instanceof concepts_1.Param || minRange.node instanceof concepts_1.Variable || minRange.node instanceof concepts_1.Return) &&
|
|
3340
|
+
(node instanceof concepts_1.Entity || node instanceof concepts_1.Enum || node instanceof concepts_1.Structure || node instanceof concepts_1.MetadataType)) {
|
|
3341
|
+
return null;
|
|
3342
|
+
}
|
|
3343
|
+
if (minRange.node instanceof concepts_1.Destination && (node instanceof concepts_1.Process || node instanceof concepts_1.ProcessElement)) {
|
|
3344
|
+
return null;
|
|
3345
|
+
}
|
|
3346
|
+
if (minRange.node instanceof concepts_1.Assignee && (node instanceof concepts_1.Process || node instanceof concepts_1.ProcessElement)) {
|
|
3347
|
+
return null;
|
|
3348
|
+
}
|
|
3349
|
+
// 枚举修改枚举名,比较特殊
|
|
3350
|
+
if (minRange.node instanceof concepts_1.EnumItem && node instanceof concepts_1.Enum) {
|
|
3351
|
+
// 什么都不做,用来跳过修改
|
|
3352
|
+
return null;
|
|
3353
|
+
}
|
|
3354
|
+
// params修改 查找bindevent不需要修改
|
|
3355
|
+
if (minRange.node instanceof concepts_1.BindEvent && node instanceof concepts_1.Param) {
|
|
3356
|
+
return null;
|
|
3357
|
+
}
|
|
3358
|
+
if (minRange.node instanceof concepts_1.Argument && node instanceof concepts_1.Param) {
|
|
3359
|
+
minRange.setTypeMethods = 'setKeyword';
|
|
3360
|
+
}
|
|
3361
|
+
/**
|
|
3362
|
+
* 理论上 logic setName只能自己触发,别的地方查到引用都不用重命名
|
|
3363
|
+
* 流程改名不触发Logic改名
|
|
3364
|
+
* 如果是修改param查找到logic就不操作
|
|
3365
|
+
* 除非想在内部修改别的内容所以暂时屏蔽掉
|
|
3366
|
+
*/
|
|
3367
|
+
if (minRange.node instanceof concepts_1.Logic && node !== minRange.node) {
|
|
3368
|
+
return null;
|
|
3369
|
+
}
|
|
3370
|
+
if (node instanceof concepts_1.Param && minRange.node instanceof concepts_1.Interface) {
|
|
3371
|
+
return null;
|
|
3372
|
+
}
|
|
3373
|
+
// 如果是被影响的是页面/业务组件
|
|
3374
|
+
if (minRange.node instanceof concepts_1.View || minRange.node instanceof concepts_1.BusinessComponent) {
|
|
3375
|
+
if (node instanceof concepts_1.View || node instanceof concepts_1.BusinessComponent) {
|
|
3376
|
+
// 如果是子页面修改
|
|
3377
|
+
// 父页面引起子页面改名,就可以不改了,自动同步
|
|
3378
|
+
// 页面中的业务组件,业务组件中的业务组件等都需要忽略
|
|
3379
|
+
if (minRange.node !== node) {
|
|
3380
|
+
return null;
|
|
3381
|
+
}
|
|
3382
|
+
}
|
|
3383
|
+
else if (!(node instanceof concepts_1.Role)) {
|
|
3384
|
+
/**
|
|
3385
|
+
* 无论是逻辑还是实体中的key,修改都不应该触发
|
|
3386
|
+
* 理论上除了组件自己改名可以触发
|
|
3387
|
+
* 下面这里 不属于Role是因为上面代码里有, 不符合 规范 的role改名存在所以先保留
|
|
3388
|
+
*/
|
|
3389
|
+
return null;
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
// 如果是被影响的是页面元素
|
|
3393
|
+
if (minRange.node instanceof concepts_1.ViewElement) {
|
|
3394
|
+
if (node instanceof concepts_1.ViewElement) {
|
|
3395
|
+
if (minRange.node !== node) {
|
|
3396
|
+
return null;
|
|
3397
|
+
}
|
|
3398
|
+
}
|
|
3399
|
+
else if (node instanceof concepts_1.BusinessComponent) {
|
|
3400
|
+
minRange.setTypeMethods = 'setTag';
|
|
3401
|
+
minRange.newValue = `bs-${newValue}`;
|
|
3402
|
+
}
|
|
3403
|
+
else if (!(node instanceof concepts_1.Role)) {
|
|
3404
|
+
/**
|
|
3405
|
+
* 无论是逻辑还是实体中的key,修改都不应该触发
|
|
3406
|
+
* 理论上除了组件自己改名可以触发
|
|
3407
|
+
* 下面这里 不属于Role是因为上面代码里有, 不符合 规范 的role改名存在所以先保留
|
|
3408
|
+
*/
|
|
3409
|
+
return null;
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3412
|
+
}
|
|
3413
|
+
else {
|
|
3414
|
+
console.log('没找到节点需要排查', record, fileNode.sourceMap);
|
|
3415
|
+
}
|
|
3416
|
+
return minRange;
|
|
3417
|
+
})
|
|
3418
|
+
// 过滤掉不需要操作的
|
|
3419
|
+
.filter((item) => !!item)
|
|
3420
|
+
// 排序:
|
|
3421
|
+
// QueryFieldExpression依赖Entity,把Entity放在QueryFieldExpression前,
|
|
3422
|
+
.sort((a, b) => {
|
|
3423
|
+
if (a.node.concept === 'QueryFieldExpression') {
|
|
3424
|
+
return 1;
|
|
3425
|
+
}
|
|
3426
|
+
if (b.node.concept === 'QueryFieldExpression') {
|
|
3427
|
+
return -1;
|
|
3428
|
+
}
|
|
3429
|
+
return 0;
|
|
3430
|
+
});
|
|
3431
|
+
return result;
|
|
3432
|
+
}
|
|
3433
|
+
// 增加参数的副作用,用于更新logic和view
|
|
3434
|
+
_addParamsEffect(refsList, node) {
|
|
3435
|
+
const parantNode = node?.parentNode;
|
|
3436
|
+
refsList.forEach((record) => {
|
|
3437
|
+
const fileNode = this.file2NodeMap.get(record.file);
|
|
3438
|
+
if (!fileNode)
|
|
3439
|
+
return null;
|
|
3440
|
+
const minRange = this._findMinRange(record, fileNode);
|
|
3441
|
+
if (minRange) {
|
|
3442
|
+
// 如果找到节点是callLogic就去更新
|
|
3443
|
+
if (node instanceof concepts_1.Param) {
|
|
3444
|
+
if (minRange.node instanceof concepts_1.CallLogic || minRange.node instanceof concepts_1.CallAuthInterface) {
|
|
3445
|
+
minRange.node.addCalleeArg(parantNode);
|
|
3446
|
+
}
|
|
3447
|
+
else if (minRange.node instanceof concepts_1.Destination) {
|
|
3448
|
+
// 跳转页面,可能在父级下增加参数,子的跳转页面也可以查找到引用
|
|
3449
|
+
// 精准匹配子页面的内容
|
|
3450
|
+
const viewNode = node.parentNode;
|
|
3451
|
+
if (viewNode instanceof concepts_1.View) {
|
|
3452
|
+
const viewNamespace = viewNode.getNamespace();
|
|
3453
|
+
if (viewNamespace === minRange.node.viewNamespace && viewNode.name === minRange.node.viewName) {
|
|
3454
|
+
minRange.node.addCalleeArg(parantNode);
|
|
3455
|
+
}
|
|
3456
|
+
}
|
|
3457
|
+
}
|
|
3458
|
+
}
|
|
3459
|
+
}
|
|
3460
|
+
});
|
|
3461
|
+
}
|
|
3462
|
+
_addParamsPrepare(node, refsList, needAdd) {
|
|
3463
|
+
if (needAdd) {
|
|
3464
|
+
const App = node?.rootNode;
|
|
3465
|
+
const parantNode = node?.parentNode;
|
|
3466
|
+
// 收集修改
|
|
3467
|
+
App.emit('collect:start', {
|
|
3468
|
+
actionMsg: '增加逻辑参数',
|
|
3469
|
+
});
|
|
3470
|
+
const index = node.getIndexOfParent();
|
|
3471
|
+
node.create({
|
|
3472
|
+
index,
|
|
3473
|
+
parentNode: parantNode,
|
|
3474
|
+
parentKey: node.parentKey,
|
|
3475
|
+
});
|
|
3476
|
+
this._addParamsEffect(refsList, node);
|
|
3477
|
+
// 结束修改 ,批量操作
|
|
3478
|
+
App.emit('collect:end');
|
|
3479
|
+
return node;
|
|
3480
|
+
}
|
|
3481
|
+
this._addParamsEffect(refsList, node);
|
|
3482
|
+
return node;
|
|
3483
|
+
}
|
|
3484
|
+
// 查找引用
|
|
3485
|
+
async findReferences(node) {
|
|
3486
|
+
let refsList = await this._isHaveRef(node);
|
|
3487
|
+
// 如果查找引用查到自己里面的引用不展示
|
|
3488
|
+
refsList = refsList.filter((item) =>
|
|
3489
|
+
// 自己引用自己的过滤掉
|
|
3490
|
+
// 删除的时候过滤一把组件删除提示
|
|
3491
|
+
// 展示组件自己屏蔽掉
|
|
3492
|
+
!item.isDefinition && !item.lineText.includes(' = new nasl.ui.'));
|
|
3493
|
+
// 最后返回的结果
|
|
3494
|
+
let result = new Map();
|
|
3495
|
+
// 树的构造,key: 一个file的node, 值是 [[logic, params],[logic, returns]]
|
|
3496
|
+
const resMap = new Map();
|
|
3497
|
+
// 普通节点和要输出的节点做一个映射,为了引用地址一样
|
|
3498
|
+
const nodeMap = new Map();
|
|
3499
|
+
try {
|
|
3500
|
+
refsList.forEach((record) => {
|
|
3501
|
+
const fileNode = this.file2NodeMap.get(record.file);
|
|
3502
|
+
if (!fileNode)
|
|
3503
|
+
return;
|
|
3504
|
+
const minRange = this._findMinRange(record, fileNode);
|
|
3505
|
+
// 过滤一把不需要改的信息
|
|
3506
|
+
if (minRange) {
|
|
3507
|
+
// 拼装树
|
|
3508
|
+
this._getTreeMap(minRange, fileNode, resMap, nodeMap);
|
|
3509
|
+
}
|
|
3510
|
+
});
|
|
3511
|
+
if (resMap.size > 0) {
|
|
3512
|
+
result = this.handleTreeMap(resMap);
|
|
3513
|
+
}
|
|
3514
|
+
}
|
|
3515
|
+
catch (err) {
|
|
3516
|
+
console.log(err);
|
|
3517
|
+
}
|
|
3518
|
+
return result;
|
|
3519
|
+
}
|
|
3520
|
+
// 通过当前节点,查找被引用的节点
|
|
3521
|
+
async nodeFindRefNodes(node) {
|
|
3522
|
+
let refsList = await this._isHaveRef(node);
|
|
3523
|
+
// 如果查找引用查到自己里面的引用不展示
|
|
3524
|
+
refsList = refsList.filter((item) =>
|
|
3525
|
+
// 自己引用自己的过滤掉
|
|
3526
|
+
// 删除的时候过滤一把组件删除提示
|
|
3527
|
+
// 展示组件自己屏蔽掉
|
|
3528
|
+
!item.isDefinition && !item.lineText.includes(' = new nasl.ui.'));
|
|
3529
|
+
// 最后返回的结果
|
|
3530
|
+
const result = new Set();
|
|
3531
|
+
try {
|
|
3532
|
+
refsList.forEach((record) => {
|
|
3533
|
+
const fileNode = this.file2NodeMap.get(record.file);
|
|
3534
|
+
if (!fileNode)
|
|
3535
|
+
return;
|
|
3536
|
+
const minRange = this._findMinRange(record, fileNode);
|
|
3537
|
+
result.add(minRange.node);
|
|
3538
|
+
});
|
|
3539
|
+
}
|
|
3540
|
+
catch (err) {
|
|
3541
|
+
console.log(err);
|
|
3542
|
+
}
|
|
3543
|
+
return [...result];
|
|
3544
|
+
}
|
|
3545
|
+
// 获取节点的上层渲染
|
|
3546
|
+
_getTreeMap(minRange, fileNode, resMap, nodeMap) {
|
|
3547
|
+
const minRangeNode = minRange.node;
|
|
3548
|
+
let currentNode = minRangeNode;
|
|
3549
|
+
let parantNode = currentNode;
|
|
3550
|
+
// 顺序队列
|
|
3551
|
+
const queue = [];
|
|
3552
|
+
// 先插入自己,如果没有在往上找,
|
|
3553
|
+
// 一直到file节点的父级
|
|
3554
|
+
while (parantNode && !(parantNode instanceof concepts_1.App)) {
|
|
3555
|
+
// 找到上一级 在map对象中构造出他的子集
|
|
3556
|
+
currentNode = parantNode;
|
|
3557
|
+
parantNode = parantNode.parentNode;
|
|
3558
|
+
// 如果第一次就塞入子集和父节点,以后就只用父节点了
|
|
3559
|
+
// 因为部分节点没有name,先过滤掉
|
|
3560
|
+
// if (currentNode.name) {
|
|
3561
|
+
// }
|
|
3562
|
+
// 排除一些不放入集合的节点
|
|
3563
|
+
let isNeedPush = true;
|
|
3564
|
+
// 如果不是ViewElement 或者 Assignment , 或者如果是的话, 排除l-root
|
|
3565
|
+
if (currentNode instanceof concepts_1.ViewElement && currentNode.tag === 'l-root')
|
|
3566
|
+
isNeedPush = false;
|
|
3567
|
+
else if (currentNode instanceof concepts_1.Argument)
|
|
3568
|
+
isNeedPush = false;
|
|
3569
|
+
else if (currentNode instanceof concepts_1.Assignment)
|
|
3570
|
+
isNeedPush = false;
|
|
3571
|
+
else if (currentNode instanceof concepts_1.TypeAnnotation)
|
|
3572
|
+
isNeedPush = false;
|
|
3573
|
+
else if (currentNode instanceof concepts_1.CallQueryComponent)
|
|
3574
|
+
isNeedPush = false;
|
|
3575
|
+
else if (currentNode instanceof concepts_1.QueryFromExpression)
|
|
3576
|
+
isNeedPush = false;
|
|
3577
|
+
else if (currentNode instanceof concepts_1.TypeAnnotation)
|
|
3578
|
+
isNeedPush = false;
|
|
3579
|
+
// 需要放到数组中
|
|
3580
|
+
if (isNeedPush) {
|
|
3581
|
+
// 名称
|
|
3582
|
+
// 赋值图标
|
|
3583
|
+
let icon = '';
|
|
3584
|
+
if (currentNode instanceof concepts_1.ViewElement)
|
|
3585
|
+
icon = 'element';
|
|
3586
|
+
else if (currentNode instanceof concepts_1.BindAttribute)
|
|
3587
|
+
icon = 'attr';
|
|
3588
|
+
else if (currentNode instanceof concepts_1.Destination)
|
|
3589
|
+
icon = 'logicNode';
|
|
3590
|
+
else if (currentNode instanceof concepts_1.CallLogic) {
|
|
3591
|
+
icon = 'interface';
|
|
3592
|
+
}
|
|
3593
|
+
// 相同节点使用一个引用
|
|
3594
|
+
if (nodeMap.get(currentNode)) {
|
|
3595
|
+
queue.unshift(nodeMap.get(currentNode));
|
|
3596
|
+
}
|
|
3597
|
+
else {
|
|
3598
|
+
const quoteNode = { node: currentNode, expanded: true, icon };
|
|
3599
|
+
nodeMap.set(currentNode, quoteNode);
|
|
3600
|
+
queue.unshift(quoteNode);
|
|
3601
|
+
}
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
// 一个logic 或者 view可能会有多个顺序队列
|
|
3605
|
+
if (resMap.get(currentNode)) {
|
|
3606
|
+
// 是否展示两个内容全等,但是两个queue的node可能不一样,但是只需要展示一个
|
|
3607
|
+
resMap.get(currentNode).push(queue);
|
|
3608
|
+
}
|
|
3609
|
+
else {
|
|
3610
|
+
resMap.set(currentNode, [queue]);
|
|
3611
|
+
}
|
|
3612
|
+
}
|
|
3613
|
+
handleTreeMap(resMap) {
|
|
3614
|
+
const treeNodeMap = new Map();
|
|
3615
|
+
resMap.forEach((value, fileNode) => {
|
|
3616
|
+
// 循环处理tree的queue
|
|
3617
|
+
const treeObj = this.handleTreeQueue(value);
|
|
3618
|
+
treeNodeMap.set(fileNode, treeObj);
|
|
3619
|
+
});
|
|
3620
|
+
return treeNodeMap;
|
|
3621
|
+
}
|
|
3622
|
+
/**
|
|
3623
|
+
* 处理tree的队列,把相同节点进行合并
|
|
3624
|
+
* 这里把当前二维数组进行一个整合
|
|
3625
|
+
* @param arr 当前页面下的queue的二维数组,一个数组下有多条链路
|
|
3626
|
+
* @returns 最后要使用到的节点和对应的子集
|
|
3627
|
+
*/
|
|
3628
|
+
handleTreeQueue(queueLists) {
|
|
3629
|
+
const map = new Map();
|
|
3630
|
+
let root = null;
|
|
3631
|
+
if (!queueLists.length)
|
|
3632
|
+
return;
|
|
3633
|
+
for (const queueList of queueLists) {
|
|
3634
|
+
let preNode = null;
|
|
3635
|
+
for (const queueItem of queueList) {
|
|
3636
|
+
if (!map.get(queueItem)) {
|
|
3637
|
+
map.set(queueItem, []);
|
|
3638
|
+
}
|
|
3639
|
+
if (preNode) {
|
|
3640
|
+
const find = map.get(preNode).find((item) => item === queueItem);
|
|
3641
|
+
if (!find) {
|
|
3642
|
+
map.get(preNode).push(queueItem);
|
|
3643
|
+
}
|
|
3644
|
+
}
|
|
3645
|
+
else {
|
|
3646
|
+
root = queueItem;
|
|
3647
|
+
}
|
|
3648
|
+
preNode = queueItem;
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
const children = this._recursionCreateResult(root, map);
|
|
3652
|
+
return children;
|
|
3653
|
+
}
|
|
3654
|
+
/**
|
|
3655
|
+
* 递归调用输出结果
|
|
3656
|
+
* @param root 一个根节点
|
|
3657
|
+
* @param map 当前所有节点的map对象
|
|
3658
|
+
* @returns 当前节点,最后输出所有节点
|
|
3659
|
+
*/
|
|
3660
|
+
_recursionCreateResult(root, map) {
|
|
3661
|
+
const children = (map.get(root) || []).map((item) => this._recursionCreateResult(item, map));
|
|
3662
|
+
if (children && children.length) {
|
|
3663
|
+
root.children = children;
|
|
3664
|
+
}
|
|
3665
|
+
return root;
|
|
3666
|
+
}
|
|
3667
|
+
/**
|
|
3668
|
+
* 获取
|
|
3669
|
+
* 当前this上下文 的Source 和 父级文件级别的节点
|
|
3670
|
+
*/
|
|
3671
|
+
getCurrentSource(node) {
|
|
3672
|
+
if (node instanceof concepts_1.App || node instanceof concepts_1.Theme)
|
|
3673
|
+
return { fileNode: null };
|
|
3674
|
+
let { sourceMap } = node;
|
|
3675
|
+
let fileNode = node;
|
|
3676
|
+
// 连接器 操作,上层结构是 Namespace, Namespace 并无含义,因此需要过滤掉
|
|
3677
|
+
const isConnectorLogic = node.getAncestor('Connector') && node.concept === 'Logic' && node.parentNode instanceof concepts_1.Namespace;
|
|
3678
|
+
// 如果没有sourceMap,就继续向上找 ,或者到module结束
|
|
3679
|
+
// 如果 节点找到 app 或者module 停止 或者entity找到DataSource为止
|
|
3680
|
+
// 如果当前节点是view就不要向上查找了
|
|
3681
|
+
// 配置参数的ConfigProperty也不需要向上找
|
|
3682
|
+
while (!sourceMap &&
|
|
3683
|
+
fileNode &&
|
|
3684
|
+
!(fileNode.parentNode instanceof concepts_1.App) &&
|
|
3685
|
+
!(fileNode.parentNode instanceof concepts_1.Integration) &&
|
|
3686
|
+
!(fileNode.parentNode instanceof concepts_1.Module) &&
|
|
3687
|
+
!(fileNode.parentNode instanceof concepts_1.DataSource) &&
|
|
3688
|
+
!(fileNode.parentNode instanceof concepts_1.Frontend) &&
|
|
3689
|
+
!(fileNode.parentNode instanceof concepts_1.Backend) &&
|
|
3690
|
+
!isConnectorLogic &&
|
|
3691
|
+
!(fileNode instanceof concepts_1.View) &&
|
|
3692
|
+
!(fileNode instanceof concepts_1.BusinessComponent) &&
|
|
3693
|
+
!(fileNode instanceof concepts_1.ConfigProperty)) {
|
|
3694
|
+
fileNode = fileNode.parentNode;
|
|
3695
|
+
sourceMap = fileNode?.sourceMap;
|
|
3696
|
+
}
|
|
3697
|
+
const currentSource = sourceMap && sourceMap.get(node);
|
|
3698
|
+
if (currentSource) {
|
|
3699
|
+
// 这里处理一些加了注解或者需要定制位置的节点的取值
|
|
3700
|
+
this.handlingCurrentSourceException(currentSource, node);
|
|
3701
|
+
return { currentSource, fileNode };
|
|
3702
|
+
}
|
|
3703
|
+
return { fileNode };
|
|
3704
|
+
}
|
|
3705
|
+
handlingCurrentSourceException(currentSource, node) {
|
|
3706
|
+
// 如果有前面的一些注解,元素在最后一行输出的值就给最后一行
|
|
3707
|
+
if (node instanceof concepts_1.EntityProperty) {
|
|
3708
|
+
if (currentSource.start.line !== currentSource.end.line) {
|
|
3709
|
+
currentSource.start = { ...currentSource.start, line: currentSource.end.line };
|
|
3710
|
+
}
|
|
3711
|
+
}
|
|
3712
|
+
}
|
|
3713
|
+
// 获取element方法的可选值
|
|
3714
|
+
getFieldKeySelectCompletion(node, fieldKey) {
|
|
3715
|
+
const { currentSource, fileNode } = this.getCurrentSource(node);
|
|
3716
|
+
if (currentSource && fileNode) {
|
|
3717
|
+
const range = {
|
|
3718
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
3719
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character),
|
|
3720
|
+
};
|
|
3721
|
+
// foreach 在最后一行自动补全
|
|
3722
|
+
if (node.concept === 'ForEachStatement') {
|
|
3723
|
+
range.line = currentSource.end.line;
|
|
3724
|
+
range.offset = 0;
|
|
3725
|
+
}
|
|
3726
|
+
else if (node.concept === 'BindAttribute') {
|
|
3727
|
+
range.offset += 7;
|
|
3728
|
+
}
|
|
3729
|
+
else if (node.concept === 'BindDirective') {
|
|
3730
|
+
range.offset += 5;
|
|
3731
|
+
}
|
|
3732
|
+
return this._getFieldKeySelectCompletion({
|
|
3733
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
3734
|
+
range,
|
|
3735
|
+
getFieldKey: fieldKey,
|
|
3736
|
+
});
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
_getFieldKeySelectCompletion(args) {
|
|
3740
|
+
return this.messager.requestCommand('getFieldKeySelectCompletion', args);
|
|
3741
|
+
}
|
|
3742
|
+
/**
|
|
3743
|
+
* 获取模块下多个CallInterface 被依赖的页面节点
|
|
3744
|
+
* 查找callInterface 被依赖的页面级别的节点,要让他们重新生成一次代码,因为多个Interface重新导入,需要查找到引用的额内容
|
|
3745
|
+
* 对应引用地方,需要重新生成,因为是生成方控制是不是必填的,
|
|
3746
|
+
* @param oldInterfaceModule 发生修改的module,查他下面的Interface被引用的地方
|
|
3747
|
+
* @returns 查找到的有引用这个内容的页面级别节点
|
|
3748
|
+
*/
|
|
3749
|
+
async findModulesCallInterfaceFileRef(oldInterfaceModule) {
|
|
3750
|
+
const oldInterfaces = oldInterfaceModule.interfaces;
|
|
3751
|
+
const fileNodes = new Set();
|
|
3752
|
+
for (let i = 0; i < oldInterfaces.length; i++) {
|
|
3753
|
+
const item = oldInterfaces[i];
|
|
3754
|
+
const refsList = await this._isHaveRef(item);
|
|
3755
|
+
refsList.forEach((record) => {
|
|
3756
|
+
if (record.isDefinition)
|
|
3757
|
+
return;
|
|
3758
|
+
const fileNode = this.file2NodeMap.get(record.file);
|
|
3759
|
+
if (fileNode) {
|
|
3760
|
+
fileNodes.add(fileNode);
|
|
3761
|
+
}
|
|
3762
|
+
});
|
|
3763
|
+
}
|
|
3764
|
+
return [...fileNodes];
|
|
3765
|
+
}
|
|
3766
|
+
/**
|
|
3767
|
+
* 查找calllogic 被依赖的页面级别的节点,要让他们重新生成一次代码,因为logic,参数必填非必填发生修改,
|
|
3768
|
+
* 对应引用地方,需要重新生成,因为是生成方控制是不是必填的,
|
|
3769
|
+
* @param logic 发生修改的logic
|
|
3770
|
+
* @returns 查找到的有引用这个内容的页面级别节点
|
|
3771
|
+
*/
|
|
3772
|
+
async findCallLogicFileRef(logic) {
|
|
3773
|
+
const fileNodes = new Set();
|
|
3774
|
+
const refsList = await this._isHaveRef(logic);
|
|
3775
|
+
refsList.forEach((record) => {
|
|
3776
|
+
if (record.isDefinition)
|
|
3777
|
+
return;
|
|
3778
|
+
const fileNode = this.file2NodeMap.get(record.file);
|
|
3779
|
+
if (fileNode) {
|
|
3780
|
+
fileNodes.add(fileNode);
|
|
3781
|
+
}
|
|
3782
|
+
});
|
|
3783
|
+
return [...fileNodes];
|
|
3784
|
+
}
|
|
3785
|
+
/** 获取当前节点的已知类型
|
|
3786
|
+
* @param node 当前要获取类型的节点
|
|
3787
|
+
* @returns 不需要去查就可以返回类型的节点
|
|
3788
|
+
*/
|
|
3789
|
+
getCurrentNodeKnownTypeAnnotation(node) {
|
|
3790
|
+
if (node.concept === 'StringLiteral' ||
|
|
3791
|
+
node.concept === 'StringInterpolation' ||
|
|
3792
|
+
node.concept === 'BooleanLiteral' ||
|
|
3793
|
+
node.concept === 'NullLiteral') {
|
|
3794
|
+
let type = 'String';
|
|
3795
|
+
switch (node.concept) {
|
|
3796
|
+
case 'NullLiteral':
|
|
3797
|
+
type = 'Null';
|
|
3798
|
+
break;
|
|
3799
|
+
case 'BooleanLiteral':
|
|
3800
|
+
type = 'Boolean';
|
|
3801
|
+
break;
|
|
3802
|
+
}
|
|
3803
|
+
return concepts_1.TypeAnnotation.createPrimitive(type);
|
|
3804
|
+
}
|
|
3805
|
+
// 如果是一元表达式,那么就是布尔值
|
|
3806
|
+
if (node instanceof concepts_1.UnaryExpression) {
|
|
3807
|
+
return concepts_1.TypeAnnotation.createPrimitive('Boolean');
|
|
3808
|
+
}
|
|
3809
|
+
// 这些原有类型的 比较的 返回值肯定就是布尔值,就不去调用ls
|
|
3810
|
+
if (node instanceof concepts_1.BinaryExpression && ['==', '!=', '>', '<', '>=', '<='].includes(node.operator)) {
|
|
3811
|
+
return concepts_1.TypeAnnotation.createPrimitive('Boolean');
|
|
3812
|
+
}
|
|
3813
|
+
// Convert和new都是自身携带类型的,就不进行修改
|
|
3814
|
+
if (node instanceof concepts_1.CallFunction && node.calleeNamespace === 'nasl.util' && ['Convert', 'New', 'FromString'].includes(node.calleeName)) {
|
|
3815
|
+
if (node.typeArguments.length) {
|
|
3816
|
+
return node.typeArguments[0];
|
|
3817
|
+
}
|
|
3818
|
+
}
|
|
3819
|
+
// Convert和new都是自身携带类型的,就不进行修改
|
|
3820
|
+
if (node instanceof concepts_1.CallLogic && node.calleeNamespace === 'nasl.util' && node.calleeName === 'jsonDeserialize') {
|
|
3821
|
+
if (node.typeArguments.length) {
|
|
3822
|
+
return node.typeArguments[0];
|
|
3823
|
+
}
|
|
3824
|
+
}
|
|
3825
|
+
// 特殊处理param有类型错误的
|
|
3826
|
+
if (node instanceof concepts_1.Param) {
|
|
3827
|
+
// index在nasl foreach上有脏数据
|
|
3828
|
+
if (node.parentKey === 'index' && node.parentNode instanceof concepts_1.ForEachStatement) {
|
|
3829
|
+
return concepts_1.TypeAnnotation.createPrimitive('Long');
|
|
3830
|
+
}
|
|
3831
|
+
}
|
|
3832
|
+
if (node instanceof concepts_1.CallQueryComponent || node instanceof concepts_1.SqlQueryComponent || node instanceof concepts_1.OqlQueryComponent) {
|
|
3833
|
+
return node.typeAnnotation;
|
|
3834
|
+
}
|
|
3835
|
+
// 老数据可能typeKind 的primitive缺失
|
|
3836
|
+
if (node instanceof concepts_1.NumericLiteral && node.typeAnnotation) {
|
|
3837
|
+
return concepts_1.TypeAnnotation.from({
|
|
3838
|
+
...node.typeAnnotation?.toJSON(),
|
|
3839
|
+
typeKind: 'primitive',
|
|
3840
|
+
});
|
|
3841
|
+
}
|
|
3842
|
+
}
|
|
3843
|
+
/**
|
|
3844
|
+
* 获取传入节点的 TypeAnnotation
|
|
3845
|
+
*
|
|
3846
|
+
* @description 生成器模式原型
|
|
3847
|
+
*/
|
|
3848
|
+
*_getQuickInfoNodesTypeMapWithGenerator(nodes) {
|
|
3849
|
+
const self = this;
|
|
3850
|
+
const args = [];
|
|
3851
|
+
// 要通过自己或者依赖关系拿的
|
|
3852
|
+
const getFromOthers = new Map();
|
|
3853
|
+
// 总共要返回出去的
|
|
3854
|
+
const types = new Map();
|
|
3855
|
+
const newQuickInfoNodes = [];
|
|
3856
|
+
yield* utils.wrapForEachToGenerator(nodes, function* getQuickInfoPosition(itemDetail, index) {
|
|
3857
|
+
const { node, filePath, item } = itemDetail;
|
|
3858
|
+
// 先按照顺序占位
|
|
3859
|
+
types.set(node, null);
|
|
3860
|
+
// 获取已知节点类型的类型
|
|
3861
|
+
const nodeTypeAnnotation = self.getCurrentNodeKnownTypeAnnotation(node);
|
|
3862
|
+
yield;
|
|
3863
|
+
if (nodeTypeAnnotation) {
|
|
3864
|
+
types.set(node, nodeTypeAnnotation);
|
|
3865
|
+
return;
|
|
3866
|
+
}
|
|
3867
|
+
// 要通过自己或者依赖关系拿的,二次遍历
|
|
3868
|
+
if (['Argument', 'Assignment', 'MatchCase'].includes(node.concept)) {
|
|
3869
|
+
getFromOthers.set(node, null);
|
|
3870
|
+
}
|
|
3871
|
+
if (['Return', 'Variable'].includes(node.concept) && node.typeAnnotation) {
|
|
3872
|
+
types.set(node, node.typeAnnotation);
|
|
3873
|
+
return;
|
|
3874
|
+
}
|
|
3875
|
+
// 如果 入参不是虚拟节点的,就不去请求类型
|
|
3876
|
+
// 只有虚拟节点的入参,才没有类型
|
|
3877
|
+
if (node.concept === 'Param' && (node.parentKey !== 'virtualParams' && node.parentKey !== 'item' && node.parentNode.concept !== 'AnonymousFunction')) {
|
|
3878
|
+
return;
|
|
3879
|
+
}
|
|
3880
|
+
if (![
|
|
3881
|
+
'Identifier',
|
|
3882
|
+
'BinaryExpression',
|
|
3883
|
+
'CallLogic',
|
|
3884
|
+
'CallFunction',
|
|
3885
|
+
'CallInterface',
|
|
3886
|
+
'MemberExpression',
|
|
3887
|
+
'Return',
|
|
3888
|
+
'Variable',
|
|
3889
|
+
'Match',
|
|
3890
|
+
'NewComposite',
|
|
3891
|
+
'NewList',
|
|
3892
|
+
'NewMap',
|
|
3893
|
+
'OqlQueryComponent',
|
|
3894
|
+
'QueryFieldExpression',
|
|
3895
|
+
'QueryGroupByExpression',
|
|
3896
|
+
'Param',
|
|
3897
|
+
'Paginate',
|
|
3898
|
+
'BackendVariable',
|
|
3899
|
+
'CallAuthInterface',
|
|
3900
|
+
].includes(node.concept))
|
|
3901
|
+
return;
|
|
3902
|
+
// 要去ls那边获取的
|
|
3903
|
+
newQuickInfoNodes.push(itemDetail);
|
|
3904
|
+
const fileDetail = {
|
|
3905
|
+
file: filePath,
|
|
3906
|
+
line: (0, translator_1.lsp2tspNumber)(item.start.line),
|
|
3907
|
+
offset: (0, translator_1.lsp2tspNumber)(item.start.character),
|
|
3908
|
+
};
|
|
3909
|
+
const getCode = (range) => {
|
|
3910
|
+
return self.tsFiles.get(filePath)?.slice(range.start.offset, range.end.offset) ?? '';
|
|
3911
|
+
};
|
|
3912
|
+
// 位置计算偏移
|
|
3913
|
+
if ('getQuickInfoOffset' in node) {
|
|
3914
|
+
Object.assign(fileDetail, node.getQuickInfoOffset(item, () => getCode(item)));
|
|
3915
|
+
}
|
|
3916
|
+
yield;
|
|
3917
|
+
// 位置计算偏移2
|
|
3918
|
+
// TODO: 之后考虑把这些偏移量计算全都挪到节点内部去
|
|
3919
|
+
if (node.concept === 'MemberExpression' ||
|
|
3920
|
+
node.concept === 'Identifier' ||
|
|
3921
|
+
node.concept === 'QueryFieldExpression' ||
|
|
3922
|
+
node.concept === 'QueryGroupByExpression') {
|
|
3923
|
+
const code = getCode(item);
|
|
3924
|
+
if (code.includes('.')) {
|
|
3925
|
+
const codeArr = code?.split('.');
|
|
3926
|
+
const lastLen = codeArr?.[codeArr.length - 1]?.length;
|
|
3927
|
+
// MemberExpression取最后一位当做类型
|
|
3928
|
+
const indexOf = code.length - lastLen;
|
|
3929
|
+
fileDetail.offset += indexOf;
|
|
3930
|
+
}
|
|
3931
|
+
}
|
|
3932
|
+
else if (node.concept === 'Match') {
|
|
3933
|
+
const code = getCode(item);
|
|
3934
|
+
// 去查return 后面的返回值,变成函数调用
|
|
3935
|
+
if (code?.endsWith(';\n')) {
|
|
3936
|
+
fileDetail.line = item.end.line - 1;
|
|
3937
|
+
}
|
|
3938
|
+
else {
|
|
3939
|
+
fileDetail.line = item.end.line;
|
|
3940
|
+
}
|
|
3941
|
+
const indexOf = code.indexOf('return __MatchExpressionFuntion');
|
|
3942
|
+
let newCode = code.substring(0, indexOf);
|
|
3943
|
+
newCode = newCode.substring(newCode.lastIndexOf('\n'), indexOf);
|
|
3944
|
+
fileDetail.offset = newCode.length + 'return '.length;
|
|
3945
|
+
}
|
|
3946
|
+
else if (['OqlQueryComponent'].includes(node.concept)) {
|
|
3947
|
+
fileDetail.offset += 10;
|
|
3948
|
+
}
|
|
3949
|
+
args.push(fileDetail);
|
|
3950
|
+
});
|
|
3951
|
+
const resultMap = (yield this.getNaslNodeTypeFull(args))?.response;
|
|
3952
|
+
yield* utils.wrapForEachToGenerator(args, function* wrapForEach({ file, line, offset }, index) {
|
|
3953
|
+
const item = resultMap?.[file]?.[line]?.[offset];
|
|
3954
|
+
const itemType = item?.[0]?.nodeType;
|
|
3955
|
+
const nodeTypeAnnotation = yield* (0, formatTsUtils_1.type2TypeAnnotation)(itemType);
|
|
3956
|
+
const { node } = newQuickInfoNodes[index];
|
|
3957
|
+
types.set(node, Object.freeze(nodeTypeAnnotation));
|
|
3958
|
+
const type = itemType ? (Object.isFrozen(itemType) ? itemType : Object.freeze(itemType)) : null;
|
|
3959
|
+
if (type) {
|
|
3960
|
+
node.__nodeType = type;
|
|
3961
|
+
}
|
|
3962
|
+
else {
|
|
3963
|
+
delete node.__nodeType;
|
|
3964
|
+
}
|
|
3965
|
+
});
|
|
3966
|
+
yield* utils.wrapIteratorToGenerator(getFromOthers.entries(), function* ([node]) {
|
|
3967
|
+
if (node instanceof concepts_1.Assignment) {
|
|
3968
|
+
if (!types.get(node.left)) {
|
|
3969
|
+
types.set(node.left, types.get(node.right));
|
|
3970
|
+
}
|
|
3971
|
+
}
|
|
3972
|
+
else if (node instanceof concepts_1.Argument) {
|
|
3973
|
+
// 如果Argument,但是没可以用的类型,就用原来logic的参数类型
|
|
3974
|
+
const argType = yield* self.getArgumentTypeAnnotationWithGenerator(node, newQuickInfoNodes, types);
|
|
3975
|
+
types.set(node, argType);
|
|
3976
|
+
}
|
|
3977
|
+
else if (node instanceof concepts_1.MatchCase) {
|
|
3978
|
+
// matchCase的类型
|
|
3979
|
+
// 直接从最后一项的返回值取,有就有没有就没有
|
|
3980
|
+
if (node.body?.length) {
|
|
3981
|
+
const last = node.body[node.body.length - 1];
|
|
3982
|
+
if (types.get(last)) {
|
|
3983
|
+
types.set(node, types.get(last));
|
|
3984
|
+
}
|
|
3985
|
+
}
|
|
3986
|
+
}
|
|
3987
|
+
});
|
|
3988
|
+
yield* utils.wrapIteratorToGenerator(types.entries(), ([node, value]) => {
|
|
3989
|
+
try {
|
|
3990
|
+
// 因为node可能是经过处理的TypeAnnotation
|
|
3991
|
+
node.__isCorrectTypeAnnotation = true;
|
|
3992
|
+
if (value) {
|
|
3993
|
+
if (node instanceof concepts_1.OqlQueryComponent) {
|
|
3994
|
+
// 自动推导情况
|
|
3995
|
+
const typeAnnotation = value;
|
|
3996
|
+
if (!node.typeAnnotation && typeAnnotation) {
|
|
3997
|
+
if (typeAnnotation.typeName === 'List' && typeAnnotation.typeKind === 'generic') {
|
|
3998
|
+
const { typeArguments } = typeAnnotation;
|
|
3999
|
+
if (typeArguments.length && typeArguments[0].isComplexType()) {
|
|
4000
|
+
delete node.__TypeAnnotation;
|
|
4001
|
+
return;
|
|
4002
|
+
}
|
|
4003
|
+
}
|
|
4004
|
+
}
|
|
4005
|
+
}
|
|
4006
|
+
if (value instanceof concepts_1.TypeAnnotation) {
|
|
4007
|
+
node.__TypeAnnotation = value;
|
|
4008
|
+
}
|
|
4009
|
+
else if (value.typeAnnotation) {
|
|
4010
|
+
node.__TypeAnnotation = value.typeAnnotation;
|
|
4011
|
+
}
|
|
4012
|
+
}
|
|
4013
|
+
else {
|
|
4014
|
+
// 清空原来已经赋值上去的类型,可能原来有现在没有了
|
|
4015
|
+
delete node.__TypeAnnotation;
|
|
4016
|
+
}
|
|
4017
|
+
}
|
|
4018
|
+
catch (err) {
|
|
4019
|
+
// if (globalThis.window) {
|
|
4020
|
+
// console.log(err);
|
|
4021
|
+
// }
|
|
4022
|
+
}
|
|
4023
|
+
});
|
|
4024
|
+
return types;
|
|
4025
|
+
}
|
|
4026
|
+
/**
|
|
4027
|
+
* 获取传入节点的 TypeAnnotation
|
|
4028
|
+
*/
|
|
4029
|
+
getQuickInfoNodesTypeMap(nodes, flag) {
|
|
4030
|
+
return utils.runGeneratorAsync(this._getQuickInfoNodesTypeMapWithGenerator(nodes));
|
|
4031
|
+
}
|
|
4032
|
+
// 全量标注并且返回json
|
|
4033
|
+
async getNaslAnnotatedJSON(app, releaseFlag) {
|
|
4034
|
+
if (this.changeStackList?.length) {
|
|
4035
|
+
throw new Error(`当前还有${this.changeStackList.length}个文件还在执行更新操作`);
|
|
4036
|
+
}
|
|
4037
|
+
const nodes = [];
|
|
4038
|
+
this.file2NodeMap.forEach((fileNode, filePath) => {
|
|
4039
|
+
// 先不排除view,传递给后端的时候,去除views下的标注
|
|
4040
|
+
if (!['DataSource', 'Enum', 'Role'].includes(fileNode.concept)) {
|
|
4041
|
+
fileNode.sourceMap.forEach((item, node) => {
|
|
4042
|
+
nodes.push({
|
|
4043
|
+
filePath,
|
|
4044
|
+
node,
|
|
4045
|
+
item,
|
|
4046
|
+
});
|
|
4047
|
+
});
|
|
4048
|
+
}
|
|
4049
|
+
});
|
|
4050
|
+
console.time('全量标注');
|
|
4051
|
+
const typesMap = await this.getQuickInfoNodesTypeMap(nodes, true);
|
|
4052
|
+
console.timeEnd('全量标注');
|
|
4053
|
+
const json = app.toJSON();
|
|
4054
|
+
console.log(json);
|
|
4055
|
+
if (releaseFlag) {
|
|
4056
|
+
// 全量标注后对json进行一些修改,为了服务端翻译处理
|
|
4057
|
+
this.annotationToJson(typesMap, json);
|
|
4058
|
+
}
|
|
4059
|
+
return json;
|
|
4060
|
+
}
|
|
4061
|
+
// 增量标注
|
|
4062
|
+
*_incrementalAnnotationJSONWithGenerator(records) {
|
|
4063
|
+
console.time('增量标注');
|
|
4064
|
+
const nodes = [];
|
|
4065
|
+
const self = this;
|
|
4066
|
+
yield* utils.wrapForEachToGenerator(records, function* findNodePosition(record) {
|
|
4067
|
+
const fileNode = self.file2NodeMap.get(record.filePath);
|
|
4068
|
+
if (!fileNode) {
|
|
4069
|
+
return;
|
|
4070
|
+
}
|
|
4071
|
+
record.id = fileNode.id;
|
|
4072
|
+
record.node = fileNode;
|
|
4073
|
+
if (['Structure', 'DataSource', 'Entity', 'Enum', 'Role', 'MetadataType'].includes(fileNode.concept) || !fileNode.sourceMap) {
|
|
4074
|
+
return;
|
|
4075
|
+
}
|
|
4076
|
+
yield* utils.wrapIteratorToGenerator(fileNode.sourceMap.entries(), ([nodeItem, item]) => {
|
|
4077
|
+
nodes.push({
|
|
4078
|
+
filePath: record.filePath,
|
|
4079
|
+
node: nodeItem,
|
|
4080
|
+
item,
|
|
4081
|
+
});
|
|
4082
|
+
});
|
|
4083
|
+
});
|
|
4084
|
+
yield* this._getQuickInfoNodesTypeMapWithGenerator(nodes);
|
|
4085
|
+
console.timeEnd('增量标注');
|
|
4086
|
+
}
|
|
4087
|
+
annotationToJson(typesMap, json) {
|
|
4088
|
+
typesMap.forEach((value, node) => {
|
|
4089
|
+
// 如果节点本身有类型就不去在塞一遍了
|
|
4090
|
+
// 有值而且没有类型再去设置
|
|
4091
|
+
// 但是Identifier 和 MemberExpression 都用标注出来的因为本身是变量,有类型也需要覆盖一下
|
|
4092
|
+
if (value && (node instanceof concepts_1.Argument) && node.getAncestor('Connector')?.concept === 'Connector') {
|
|
4093
|
+
const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
|
|
4094
|
+
if (jsonNode) {
|
|
4095
|
+
jsonNode.typeAnnotation = value?.toJSON();
|
|
4096
|
+
}
|
|
4097
|
+
}
|
|
4098
|
+
if (value && (!node.typeAnnotation || node instanceof concepts_1.Identifier || node instanceof concepts_1.MemberExpression)) {
|
|
4099
|
+
const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
|
|
4100
|
+
if (jsonNode) {
|
|
4101
|
+
jsonNode.typeAnnotation = value?.toJSON();
|
|
4102
|
+
}
|
|
4103
|
+
}
|
|
4104
|
+
// 旧版本数据查询需要确认是匿名数据结构的 ListTotal 类型
|
|
4105
|
+
if (node instanceof concepts_1.CallQueryComponent && !node.isAutoInfer()) {
|
|
4106
|
+
const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
|
|
4107
|
+
jsonNode.typeAnnotation = {
|
|
4108
|
+
concept: 'TypeAnnotation',
|
|
4109
|
+
typeKind: 'anonymousStructure',
|
|
4110
|
+
typeNamespace: null,
|
|
4111
|
+
typeName: null,
|
|
4112
|
+
typeArguments: [],
|
|
4113
|
+
inferred: false,
|
|
4114
|
+
ruleMap: null,
|
|
4115
|
+
properties: [
|
|
4116
|
+
{
|
|
4117
|
+
concept: 'StructureProperty',
|
|
4118
|
+
name: 'list',
|
|
4119
|
+
label: null,
|
|
4120
|
+
description: null,
|
|
4121
|
+
typeAnnotation: {
|
|
4122
|
+
concept: 'TypeAnnotation',
|
|
4123
|
+
typeKind: 'generic',
|
|
4124
|
+
typeNamespace: 'nasl.collection',
|
|
4125
|
+
typeName: 'List',
|
|
4126
|
+
typeArguments: [jsonNode.typeAnnotation],
|
|
4127
|
+
inferred: null,
|
|
4128
|
+
},
|
|
4129
|
+
required: null,
|
|
4130
|
+
defaultValue: null,
|
|
4131
|
+
},
|
|
4132
|
+
{
|
|
4133
|
+
concept: 'StructureProperty',
|
|
4134
|
+
name: 'total',
|
|
4135
|
+
label: null,
|
|
4136
|
+
description: null,
|
|
4137
|
+
typeAnnotation: {
|
|
4138
|
+
concept: 'TypeAnnotation',
|
|
4139
|
+
typeKind: 'primitive',
|
|
4140
|
+
typeNamespace: 'nasl.core',
|
|
4141
|
+
typeName: 'Long',
|
|
4142
|
+
typeArguments: null,
|
|
4143
|
+
inferred: null,
|
|
4144
|
+
},
|
|
4145
|
+
required: null,
|
|
4146
|
+
defaultValue: null,
|
|
4147
|
+
},
|
|
4148
|
+
],
|
|
4149
|
+
};
|
|
4150
|
+
}
|
|
4151
|
+
// 特殊处理param有类型错误的
|
|
4152
|
+
if (node instanceof concepts_1.Param) {
|
|
4153
|
+
// index在nasl foreach上有脏数据
|
|
4154
|
+
if (node.parentKey === 'index' && node.parentNode instanceof concepts_1.ForEachStatement) {
|
|
4155
|
+
const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
|
|
4156
|
+
jsonNode.typeAnnotation = concepts_1.TypeAnnotation.createPrimitive('Long').toJSON();
|
|
4157
|
+
}
|
|
4158
|
+
}
|
|
4159
|
+
if (node instanceof concepts_1.Match) {
|
|
4160
|
+
const matchExpression = node.expression;
|
|
4161
|
+
if (matchExpression?.__TypeAnnotation?.typeKind === 'union' &&
|
|
4162
|
+
(matchExpression instanceof concepts_1.Identifier || matchExpression instanceof concepts_1.MemberExpression)) {
|
|
4163
|
+
const { currentSource, fileNode } = matchExpression?.getCurrentSource();
|
|
4164
|
+
fileNode.sourceMap.forEach((item, itemNode) => {
|
|
4165
|
+
if (itemNode.concept === matchExpression.concept && (0, translator_1.isSameRange)(item, currentSource)) {
|
|
4166
|
+
const jsonNode = jsoner.queryNodeByPath(json, itemNode.getNodePath(false));
|
|
4167
|
+
jsonNode.typeAnnotation = matchExpression.__TypeAnnotation;
|
|
4168
|
+
}
|
|
4169
|
+
});
|
|
4170
|
+
}
|
|
4171
|
+
}
|
|
4172
|
+
// 特殊处理param有类型错误的
|
|
4173
|
+
if (value && (node instanceof concepts_1.Param)) {
|
|
4174
|
+
// index在nasl foreach上有脏数据
|
|
4175
|
+
if (node.parentKey === 'index' && node.parentNode instanceof concepts_1.ForEachStatement) {
|
|
4176
|
+
const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
|
|
4177
|
+
jsonNode.typeAnnotation = value.toJSON();
|
|
4178
|
+
}
|
|
4179
|
+
}
|
|
4180
|
+
if (value && (node instanceof concepts_1.NewComposite) && (node.typeAnnotation?.typeKind === 'anonymousStructure' || node.typeAnnotation?.typeKind === 'generic')) {
|
|
4181
|
+
const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
|
|
4182
|
+
jsonNode.typeAnnotation = value.toJSON();
|
|
4183
|
+
}
|
|
4184
|
+
// jsonSerializer 是 CallLogic,其余是 CallFunction
|
|
4185
|
+
if (node instanceof concepts_1.CallFunction || node instanceof concepts_1.CallLogic) {
|
|
4186
|
+
const tzArgIdx = timeZoneArgumentIndexMap.get(node.calleeName);
|
|
4187
|
+
const args = node.arguments;
|
|
4188
|
+
const tzArg = args ? args[tzArgIdx] : undefined;
|
|
4189
|
+
if (tzArgIdx && tzArg?.keyword === '时区' && !isCoreDateTimeType(node.arguments[0])) {
|
|
4190
|
+
if (!isFunctionWithFixedTimeZoneParam(node.calleeName)) {
|
|
4191
|
+
node.arguments.pop();
|
|
4192
|
+
}
|
|
4193
|
+
}
|
|
4194
|
+
}
|
|
4195
|
+
// 服务端需要默认值节点有类型来判断父节点是否是日期类型
|
|
4196
|
+
if (node instanceof concepts_1.DefaultValue && !value) {
|
|
4197
|
+
const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
|
|
4198
|
+
const parentNodeType = node.parentNode?.typeAnnotation || node.parentNode?.__TypeAnnotation;
|
|
4199
|
+
if (parentNodeType && jsonNode) {
|
|
4200
|
+
jsonNode.typeAnnotation = parentNodeType?.toJSON();
|
|
4201
|
+
}
|
|
4202
|
+
}
|
|
4203
|
+
});
|
|
4204
|
+
}
|
|
4205
|
+
/**
|
|
4206
|
+
* 获取getArgument的参数位的类型
|
|
4207
|
+
* 如果内部表达式的,就用表达式的,如果没有就试试用默认值的
|
|
4208
|
+
* 获取logic的默认值和原来Arg的类型和默认值对应
|
|
4209
|
+
*/
|
|
4210
|
+
*getArgumentTypeAnnotationWithGenerator(node, QuickInfoNodes, types) {
|
|
4211
|
+
// 直接复用内部expression的type类型
|
|
4212
|
+
if (node.parentNode instanceof concepts_1.CallLogic &&
|
|
4213
|
+
node.parentNode.calleeNamespace?.includes('entities') &&
|
|
4214
|
+
node.parentNode.calleeNamespace?.includes('logics') &&
|
|
4215
|
+
node.parentNode.calleeName === 'delete') {
|
|
4216
|
+
const nodeType = node.parentNode?.__nodeType;
|
|
4217
|
+
if (nodeType && Array.isArray(nodeType.fnParams)) {
|
|
4218
|
+
const index = node.parentNode.arguments.indexOf(node);
|
|
4219
|
+
const type = nodeType.fnParams[index]?.typeInfo;
|
|
4220
|
+
const nodeTypeAnnotation = yield* (0, formatTsUtils_1.type2TypeAnnotation)(type);
|
|
4221
|
+
if (nodeTypeAnnotation) {
|
|
4222
|
+
return nodeTypeAnnotation;
|
|
4223
|
+
}
|
|
4224
|
+
}
|
|
4225
|
+
yield;
|
|
4226
|
+
}
|
|
4227
|
+
// 获取返回值结果里找到父级的callLogic || CallInterface的类型填充进去Argument
|
|
4228
|
+
const App = node.app;
|
|
4229
|
+
const parent = node.parentNode;
|
|
4230
|
+
// 如果nasl包下的 ,很多声明都含有T啥的先用自己内部的
|
|
4231
|
+
if (!parent.calleeNamespace || parent.calleeNamespace?.startsWith('nasl')) {
|
|
4232
|
+
if (types.get(node.expression)) {
|
|
4233
|
+
return types.get(node.expression);
|
|
4234
|
+
}
|
|
4235
|
+
}
|
|
4236
|
+
// 用户自己声明的用用户的
|
|
4237
|
+
const callObj = App.findNodeByCompleteName(`${parent.calleeNamespace}.${parent.calleeName}`);
|
|
4238
|
+
yield;
|
|
4239
|
+
const index = parent.arguments.indexOf(node);
|
|
4240
|
+
const param = callObj?.params?.[index] || {};
|
|
4241
|
+
// 取出参数的类型
|
|
4242
|
+
// 设置类型
|
|
4243
|
+
return param.typeAnnotation;
|
|
4244
|
+
}
|
|
4245
|
+
async getCurrentTypeAnnotation(node, outTime = 600) {
|
|
4246
|
+
if (node.__TypeAnnotation) {
|
|
4247
|
+
return node.__TypeAnnotation;
|
|
4248
|
+
}
|
|
4249
|
+
return new Promise((resolve, reject) => {
|
|
4250
|
+
const myTimer = setTimeout(() => {
|
|
4251
|
+
console.warn(node, '没有获取到类型');
|
|
4252
|
+
clearTimeout(myTimer);
|
|
4253
|
+
clearInterval(mySetInterval);
|
|
4254
|
+
if (node.__isCorrectTypeAnnotation) {
|
|
4255
|
+
resolve(node.__TypeAnnotation);
|
|
4256
|
+
}
|
|
4257
|
+
else {
|
|
4258
|
+
resolve(null);
|
|
4259
|
+
}
|
|
4260
|
+
}, outTime);
|
|
4261
|
+
const mySetInterval = setInterval(() => {
|
|
4262
|
+
if (node.__isCorrectTypeAnnotation) {
|
|
4263
|
+
resolve(node.__TypeAnnotation);
|
|
4264
|
+
clearInterval(mySetInterval);
|
|
4265
|
+
clearTimeout(myTimer);
|
|
4266
|
+
}
|
|
4267
|
+
}, 50);
|
|
4268
|
+
});
|
|
4269
|
+
// const res = new Promise((resolve, reject) => {
|
|
4270
|
+
// Object.defineProperty(node, '__TypeAnnotation', {
|
|
4271
|
+
// //修改 // 若只指定get方法,不指定set方法,那就默认该属性是只读的
|
|
4272
|
+
// get() {
|
|
4273
|
+
// return this.__newTypeAnnotation;
|
|
4274
|
+
// },
|
|
4275
|
+
// set: (__TypeAnnotation) => {
|
|
4276
|
+
// try {
|
|
4277
|
+
// if (__TypeAnnotation) {
|
|
4278
|
+
// (this as any).__newTypeAnnotation = __TypeAnnotation;
|
|
4279
|
+
// resolve(__TypeAnnotation);
|
|
4280
|
+
// return;
|
|
4281
|
+
// }
|
|
4282
|
+
// // 如果一直没变化 500毫秒后就返回没查找到
|
|
4283
|
+
// setTimeout(() => {
|
|
4284
|
+
// (this as any).__newTypeAnnotation = __TypeAnnotation;
|
|
4285
|
+
// resolve(__TypeAnnotation || null);
|
|
4286
|
+
// }, 500);
|
|
4287
|
+
// } catch (err) {
|
|
4288
|
+
// console.log(err);
|
|
4289
|
+
// }
|
|
4290
|
+
// },
|
|
4291
|
+
// });
|
|
4292
|
+
// });
|
|
4293
|
+
// res.then((item) => { console.log(item) });
|
|
4294
|
+
// return res;
|
|
4295
|
+
}
|
|
4296
|
+
// 获取节点标注,去动态查
|
|
4297
|
+
async getBaseNodesTypeMap(nodes) {
|
|
4298
|
+
const args = nodes.map((item) => {
|
|
4299
|
+
const { currentSource, fileNode } = item.getCurrentSource();
|
|
4300
|
+
return {
|
|
4301
|
+
filePath: fileNode.getEmbeddedFilePath(),
|
|
4302
|
+
node: item,
|
|
4303
|
+
item: currentSource,
|
|
4304
|
+
};
|
|
4305
|
+
});
|
|
4306
|
+
const typesMap = await this.getQuickInfoNodesTypeMap(args);
|
|
4307
|
+
return typesMap;
|
|
4308
|
+
}
|
|
4309
|
+
_getTypeStrFull(args) {
|
|
4310
|
+
return this.messager.requestCommand('typeStrFull', args);
|
|
4311
|
+
}
|
|
4312
|
+
async getNaslNodeTypeStrFull(args) {
|
|
4313
|
+
const result = await this._getTypeStrFull(args);
|
|
4314
|
+
return result;
|
|
4315
|
+
}
|
|
4316
|
+
/**
|
|
4317
|
+
* 处理删除节点
|
|
4318
|
+
* @param fileNode 当前删除节点的文件级别节点
|
|
4319
|
+
* @param targetNode 当前操作的节点
|
|
4320
|
+
* @param result toTs生成的内容
|
|
4321
|
+
*/
|
|
4322
|
+
async handleDelete(fileNode, targetNode, result) {
|
|
4323
|
+
const filePath = fileNode.getEmbeddedFilePath();
|
|
4324
|
+
// 如果要删除,而且当前要删Logic就直接删除并且清除错误
|
|
4325
|
+
/**
|
|
4326
|
+
* 删除节点中的一个内容,删除了以后,就查一下引用的地方一起查一下异常
|
|
4327
|
+
*/
|
|
4328
|
+
let outputFiles = [];
|
|
4329
|
+
// 先特殊处理业务组件
|
|
4330
|
+
const pos = getBusinessComponentPos(fileNode);
|
|
4331
|
+
// 删除之前先查一下内容的依赖
|
|
4332
|
+
const newRefs = await this.references({
|
|
4333
|
+
file: result.filePath,
|
|
4334
|
+
line: pos?.line ?? EmbeddedTSFileLineMap[fileNode.concept] ?? 2,
|
|
4335
|
+
offset: pos?.offset ?? EmbeddedTSFileOffsetMap[fileNode.concept] ?? 6,
|
|
4336
|
+
});
|
|
4337
|
+
// 如果是要删除的内容,就是当前的file节点,要关闭当前文件,就把内容置为空
|
|
4338
|
+
if (fileNode === targetNode) {
|
|
4339
|
+
outputFiles = [{ file: filePath, fileContent: '' }];
|
|
4340
|
+
// 去掉原来存储的当前节点的nasl内存的存储,和错误的存储
|
|
4341
|
+
// 已经删除的就不用在去check错误了
|
|
4342
|
+
// check就会去取类型啥的,没有必要
|
|
4343
|
+
this.diagnosticManager.deleteOwn(fileNode.id);
|
|
4344
|
+
// 删除文件同时删除ls存储nasl 的引用
|
|
4345
|
+
this.file2NodeMap.delete(filePath);
|
|
4346
|
+
}
|
|
4347
|
+
else {
|
|
4348
|
+
// 如果是要删除logic一个小内容,要覆盖全部内容
|
|
4349
|
+
// 其余要删除的都是把原来的file节点的内容全部覆盖一把
|
|
4350
|
+
outputFiles = [{ file: result.filePath, fileContent: result.code }];
|
|
4351
|
+
}
|
|
4352
|
+
// 更新文件之后
|
|
4353
|
+
await this.updateFiles({ outputFiles });
|
|
4354
|
+
newRefs.refs.forEach((ref) => this.filesToCheck.add(ref.file));
|
|
4355
|
+
}
|
|
4356
|
+
/**
|
|
4357
|
+
* 除去rename场景下的更新
|
|
4358
|
+
* @param fileNode 文件级别的节点
|
|
4359
|
+
* @param targetNode 触发修改的节点
|
|
4360
|
+
* @param result 生成代码的code 和位置信息
|
|
4361
|
+
*/
|
|
4362
|
+
async handleChange(fileNode, targetNode, result, action) {
|
|
4363
|
+
this.file2NodeMap.set(result.filePath, fileNode);
|
|
4364
|
+
const outputFiles = [{ file: result.filePath, fileContent: result.code }];
|
|
4365
|
+
// 创建和更新都用update,内部会做判断
|
|
4366
|
+
await this.updateFiles({ outputFiles });
|
|
4367
|
+
// 先特殊处理业务组件
|
|
4368
|
+
const pos = getBusinessComponentPos(fileNode);
|
|
4369
|
+
// 查一下新函数名的依赖
|
|
4370
|
+
const newRefs = await this.references({
|
|
4371
|
+
file: result.filePath,
|
|
4372
|
+
line: pos?.line ?? EmbeddedTSFileLineMap[fileNode.concept] ?? 2,
|
|
4373
|
+
offset: pos?.offset ?? EmbeddedTSFileOffsetMap[fileNode.concept] ?? 6,
|
|
4374
|
+
});
|
|
4375
|
+
const files = new Set();
|
|
4376
|
+
newRefs.refs.forEach((ref) => {
|
|
4377
|
+
this.filesToCheck.add(ref.file);
|
|
4378
|
+
files.add(ref.file);
|
|
4379
|
+
});
|
|
4380
|
+
// 唤起建立连接弹框
|
|
4381
|
+
// 文件级别的建立连接采取提醒
|
|
4382
|
+
if (action === 'create' && targetNode.__init) {
|
|
4383
|
+
// 清除临时状态, 完成本次创建
|
|
4384
|
+
delete targetNode.__init;
|
|
4385
|
+
if (fileNode === targetNode && files.size > 1) {
|
|
4386
|
+
const confirmParms = {
|
|
4387
|
+
actionType: 'createEstablishConnection',
|
|
4388
|
+
node: fileNode,
|
|
4389
|
+
icon: 'success',
|
|
4390
|
+
};
|
|
4391
|
+
(0, common_1.invokeCommand)('tsConfirm.open', confirmParms, () => {
|
|
4392
|
+
// ..
|
|
4393
|
+
});
|
|
4394
|
+
}
|
|
4395
|
+
}
|
|
4396
|
+
}
|
|
4397
|
+
/**
|
|
4398
|
+
* 重命名的更新
|
|
4399
|
+
* @param fileNode 文件级别的节点
|
|
4400
|
+
* @param targetNode 触发修改的节点
|
|
4401
|
+
* @param result 生成代码的code 和位置信息
|
|
4402
|
+
* @param isRename 是不是修改名字
|
|
4403
|
+
* @param oldFilePath 如果是改名,文件级别的才会有这个参数,用于文件新增替换
|
|
4404
|
+
*/
|
|
4405
|
+
async handleRename(fileNode, targetNode, result, oldFilePath) {
|
|
4406
|
+
// rename 场景
|
|
4407
|
+
const outputFiles = [{ file: result.filePath, fileContent: result.code }];
|
|
4408
|
+
// 如果是要修改顶级文件名
|
|
4409
|
+
// file节点和当前改得是同一节点
|
|
4410
|
+
if (fileNode === targetNode) {
|
|
4411
|
+
this.file2NodeMap.delete(oldFilePath);
|
|
4412
|
+
this.file2NodeMap.set(result.filePath, fileNode);
|
|
4413
|
+
// 修改名字新的添加进去,旧的置为空
|
|
4414
|
+
outputFiles.unshift({ file: oldFilePath, fileContent: '' });
|
|
4415
|
+
// 先特殊处理业务组件
|
|
4416
|
+
const pos = getBusinessComponentPos(fileNode);
|
|
4417
|
+
// 查一下旧文件名的依赖
|
|
4418
|
+
const oldRefs = await this.references({
|
|
4419
|
+
file: oldFilePath,
|
|
4420
|
+
line: pos?.line ?? EmbeddedTSFileLineMap[fileNode.concept] ?? 2,
|
|
4421
|
+
offset: pos?.offset ?? EmbeddedTSFileOffsetMap[fileNode.concept] ?? 6,
|
|
4422
|
+
});
|
|
4423
|
+
oldRefs.refs.forEach((ref) => this.filesToCheck.add(ref.file));
|
|
4424
|
+
this.filesToCheck.delete(oldFilePath);
|
|
4425
|
+
// 更新文件之后
|
|
4426
|
+
await this.updateFiles({ outputFiles });
|
|
4427
|
+
// 查一下新函数名的依赖
|
|
4428
|
+
const newRefs = await this.references({
|
|
4429
|
+
file: result.filePath,
|
|
4430
|
+
line: EmbeddedTSFileLineMap[fileNode.concept] ?? 2,
|
|
4431
|
+
offset: EmbeddedTSFileOffsetMap[fileNode.concept] ?? 6,
|
|
4432
|
+
});
|
|
4433
|
+
const newRefFileList = new Set();
|
|
4434
|
+
newRefs.refs.forEach((ref) => {
|
|
4435
|
+
this.filesToCheck.add(ref.file);
|
|
4436
|
+
newRefFileList.add(ref.file);
|
|
4437
|
+
});
|
|
4438
|
+
// 文件级别重命名,有依赖才唤起弹框
|
|
4439
|
+
// 唤起重命名,提示有连接弹框
|
|
4440
|
+
// 重命名建立连接先不展示弹框了
|
|
4441
|
+
// if (newRefFileList.size > 1) {
|
|
4442
|
+
// const confirmParms = {
|
|
4443
|
+
// actionType: 'renameEstablishConnection',
|
|
4444
|
+
// node: fileNode,
|
|
4445
|
+
// icon: 'success',
|
|
4446
|
+
// };
|
|
4447
|
+
// invokeCommand('tsConfirm.open', confirmParms, () => {});
|
|
4448
|
+
// }
|
|
4449
|
+
}
|
|
4450
|
+
else if (targetNode instanceof concepts_1.ViewElement) {
|
|
4451
|
+
/**
|
|
4452
|
+
* 因为平台类型比较特殊
|
|
4453
|
+
* 修改之后只用查页面本身就好了
|
|
4454
|
+
*/
|
|
4455
|
+
// 更新文件之后
|
|
4456
|
+
await this.updateFiles({ outputFiles });
|
|
4457
|
+
const newRefs2 = await this.references({
|
|
4458
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
4459
|
+
line: EmbeddedTSFileLineMap[fileNode.concept] ?? 2,
|
|
4460
|
+
offset: EmbeddedTSFileOffsetMap[fileNode.concept] ?? 6,
|
|
4461
|
+
});
|
|
4462
|
+
newRefs2.refs.forEach((ref) => this.filesToCheck.add(ref.file));
|
|
4463
|
+
}
|
|
4464
|
+
else {
|
|
4465
|
+
// 查一下当前属性依赖的文件
|
|
4466
|
+
const { currentSource, fileNode } = this.getCurrentSource(targetNode);
|
|
4467
|
+
// 如果当前节点存在
|
|
4468
|
+
if (currentSource) {
|
|
4469
|
+
/**
|
|
4470
|
+
* 其余的节点修改之后直接查本身就可以了
|
|
4471
|
+
*/
|
|
4472
|
+
const oldRefs = await this.references({
|
|
4473
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
4474
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
4475
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character),
|
|
4476
|
+
});
|
|
4477
|
+
oldRefs.refs.forEach((ref) => this.filesToCheck.add(ref.file));
|
|
4478
|
+
// 更新文件之后
|
|
4479
|
+
await this.updateFiles({ outputFiles });
|
|
4480
|
+
const newRefs2 = await this.references({
|
|
4481
|
+
file: fileNode.getEmbeddedFilePath(),
|
|
4482
|
+
line: (0, translator_1.lsp2tspNumber)(currentSource.start.line),
|
|
4483
|
+
offset: (0, translator_1.lsp2tspNumber)(currentSource.start.character),
|
|
4484
|
+
});
|
|
4485
|
+
newRefs2.refs.forEach((ref) => this.filesToCheck.add(ref.file));
|
|
4486
|
+
}
|
|
4487
|
+
}
|
|
4488
|
+
}
|
|
4489
|
+
/**
|
|
4490
|
+
* 处理一些节点操作,子节点需要更新并且check的场景
|
|
4491
|
+
* 因为删除,新增父页面,或者重命名会一起
|
|
4492
|
+
* 删除或者新增view而且他有子集 就要执行同样的操作
|
|
4493
|
+
* @param action 当前操作类型
|
|
4494
|
+
* @param fileNode 文件节点
|
|
4495
|
+
* @param targetNode 操作节点 这里要两个相等才会走家去面对哦逻辑
|
|
4496
|
+
* @param oldpath 触发内容的oldpath
|
|
4497
|
+
*/
|
|
4498
|
+
async incidentalAction(action, fileNode, targetNode, oldpath) {
|
|
4499
|
+
if ((action === 'create' || action === 'delete' || (action === 'update' && oldpath)) && fileNode === targetNode) {
|
|
4500
|
+
// 删除、更改、新增端
|
|
4501
|
+
if (fileNode instanceof concepts_1.Frontend && (fileNode.views?.length || fileNode.variables?.length)) {
|
|
4502
|
+
const fileNodeChildren = [...fileNode.views, ...fileNode.variables];
|
|
4503
|
+
for (let i = 0; i < fileNodeChildren.length; i++) {
|
|
4504
|
+
const fileNodeItem = fileNodeChildren[i];
|
|
4505
|
+
const result = await utils.timeSlicingWithGenerator(fileNodeItem.toEmbeddedTSFile());
|
|
4506
|
+
fileNodeItem.sourceMap = result.sourceMap;
|
|
4507
|
+
if (action === 'create') {
|
|
4508
|
+
await this.handleChange(fileNodeItem, fileNodeItem, result, action);
|
|
4509
|
+
await this.incidentalAction(action, fileNodeItem, fileNodeItem);
|
|
4510
|
+
}
|
|
4511
|
+
else if (action === 'delete') {
|
|
4512
|
+
await this.handleDelete(fileNodeItem, fileNodeItem, result);
|
|
4513
|
+
await this.incidentalAction(action, fileNodeItem, fileNodeItem);
|
|
4514
|
+
}
|
|
4515
|
+
else if (action === 'update' && oldpath) {
|
|
4516
|
+
const parentPath = oldpath.replace('.ts', '/');
|
|
4517
|
+
const foldName = fileNodeItem.concept === 'View' ? 'views' : 'variables';
|
|
4518
|
+
const currentOldPath = `${parentPath + foldName}/${fileNodeItem.name}.ts`;
|
|
4519
|
+
// 因为重命名这里只有当前修改父级的 旧名称, 所以他的子集也要根据旧名称去查依赖 更新内容
|
|
4520
|
+
await this.handleRename(fileNodeItem, fileNodeItem, result, currentOldPath);
|
|
4521
|
+
await this.incidentalAction(action, fileNodeItem, fileNodeItem, currentOldPath);
|
|
4522
|
+
}
|
|
4523
|
+
}
|
|
4524
|
+
}
|
|
4525
|
+
// 删除或者新增页面
|
|
4526
|
+
if (fileNode instanceof concepts_1.View && fileNode.children?.length) {
|
|
4527
|
+
const fileNodeChildren = fileNode.children;
|
|
4528
|
+
for (let i = 0; i < fileNodeChildren.length; i++) {
|
|
4529
|
+
const fileNodeItem = fileNodeChildren[i];
|
|
4530
|
+
const result = await utils.timeSlicingWithGenerator(fileNodeItem.toEmbeddedTSFile());
|
|
4531
|
+
fileNodeItem.sourceMap = result.sourceMap;
|
|
4532
|
+
if (action === 'create') {
|
|
4533
|
+
await this.handleChange(fileNodeItem, fileNodeItem, result, action);
|
|
4534
|
+
await this.incidentalAction(action, fileNodeItem, fileNodeItem);
|
|
4535
|
+
}
|
|
4536
|
+
else if (action === 'delete') {
|
|
4537
|
+
await this.handleDelete(fileNodeItem, fileNodeItem, result);
|
|
4538
|
+
await this.incidentalAction(action, fileNodeItem, fileNodeItem);
|
|
4539
|
+
}
|
|
4540
|
+
else if (action === 'update' && oldpath) {
|
|
4541
|
+
const parentPath = oldpath.replace('.ts', '/');
|
|
4542
|
+
const currentOldPath = `${parentPath + fileNodeItem.name}.ts`;
|
|
4543
|
+
// 因为重命名这里只有当前修改父级的 旧名称, 所以他的子集也要根据旧名称去查依赖 更新内容
|
|
4544
|
+
await this.handleRename(fileNodeItem, fileNodeItem, result, currentOldPath);
|
|
4545
|
+
await this.incidentalAction(action, fileNodeItem, fileNodeItem, currentOldPath);
|
|
4546
|
+
}
|
|
4547
|
+
}
|
|
4548
|
+
}
|
|
4549
|
+
// 删除或新增模块
|
|
4550
|
+
// 需要把下面的哦内容全部都更新一遍
|
|
4551
|
+
if (fileNode instanceof concepts_1.Module) {
|
|
4552
|
+
if (fileNode.type === 'interface' && fileNode.isAdd && action === 'create') {
|
|
4553
|
+
isChangeInterface = true;
|
|
4554
|
+
}
|
|
4555
|
+
const module = targetNode;
|
|
4556
|
+
const results = await utils.timeSlicingWithGenerator(this.contentToFile(module));
|
|
4557
|
+
for (let i = 0; i < results.length; i++) {
|
|
4558
|
+
const result = results[i];
|
|
4559
|
+
const node = this.file2NodeMap.get(result.filePath);
|
|
4560
|
+
if (action === 'create') {
|
|
4561
|
+
await this.handleChange(node, node, result, action);
|
|
4562
|
+
}
|
|
4563
|
+
else {
|
|
4564
|
+
await this.handleDelete(node, node, result);
|
|
4565
|
+
}
|
|
4566
|
+
}
|
|
4567
|
+
// 删除模块通知更新列表
|
|
4568
|
+
if (action === 'delete') {
|
|
4569
|
+
try {
|
|
4570
|
+
// 如果已经
|
|
4571
|
+
(0, common_1.invokeCommand)('module.delete', true);
|
|
4572
|
+
}
|
|
4573
|
+
catch (err) {
|
|
4574
|
+
console.log('module.delete', '组件销毁了,不用唤起了');
|
|
4575
|
+
}
|
|
4576
|
+
}
|
|
4577
|
+
}
|
|
4578
|
+
/**
|
|
4579
|
+
* DataSource只会重命名时候,需要把子集全部重新生成一下
|
|
4580
|
+
*/
|
|
4581
|
+
if (fileNode instanceof concepts_1.DataSource) {
|
|
4582
|
+
fileNode.entities.forEach(async (entity) => {
|
|
4583
|
+
try {
|
|
4584
|
+
const result = await utils.timeSlicingWithGenerator(entity.toEmbeddedTSFile());
|
|
4585
|
+
const parentPath = oldpath.replace('.ts', '/');
|
|
4586
|
+
const currentOldPath = `${parentPath}/entities/${entity.name}.ts`;
|
|
4587
|
+
// 因为重命名这里只有当前修改父级的 旧名称, 所以他的子集也要根据旧名称去查依赖 更新内容
|
|
4588
|
+
await this.handleRename(entity, entity, result, currentOldPath);
|
|
4589
|
+
}
|
|
4590
|
+
catch (err) {
|
|
4591
|
+
console.log(err);
|
|
4592
|
+
}
|
|
4593
|
+
});
|
|
4594
|
+
}
|
|
4595
|
+
}
|
|
4596
|
+
}
|
|
4597
|
+
async receiveHandleChange($event) {
|
|
4598
|
+
this.singleFileChangeIng = true;
|
|
4599
|
+
// 行为
|
|
4600
|
+
const { action, oldObject = {}, object = {} } = $event;
|
|
4601
|
+
// 根据行为跳过更新文件
|
|
4602
|
+
// 如果更新国际化key,不需要修改ts文件
|
|
4603
|
+
if (Object.keys(object || {}).length === 1 && Object.keys(oldObject).length === 1) {
|
|
4604
|
+
if (object.i18nKey && !oldObject.i18nKey) {
|
|
4605
|
+
return;
|
|
4606
|
+
}
|
|
4607
|
+
if (object.i18nInfo && !oldObject.i18nInfo) {
|
|
4608
|
+
return;
|
|
4609
|
+
}
|
|
4610
|
+
if (!object.i18nKey && oldObject.i18nKey) {
|
|
4611
|
+
// 撤销重做 也跳过更新
|
|
4612
|
+
return;
|
|
4613
|
+
}
|
|
4614
|
+
if (!object.i18nInfo && oldObject.i18nInfo) {
|
|
4615
|
+
// 撤销重做 也跳过更新
|
|
4616
|
+
return;
|
|
4617
|
+
}
|
|
4618
|
+
}
|
|
4619
|
+
const targetNode = $event.target;
|
|
4620
|
+
console.log(targetNode, 'targetNode');
|
|
4621
|
+
// 连接器namespace 没有真实文件,不需要走删除
|
|
4622
|
+
if (targetNode instanceof concepts_1.Namespace && targetNode.parentNode instanceof concepts_1.Connector) {
|
|
4623
|
+
return;
|
|
4624
|
+
}
|
|
4625
|
+
// Connection 相关配置的更新不需要写入文件
|
|
4626
|
+
// i18nInfo 更新不需要写入文件
|
|
4627
|
+
if (targetNode?.parentNode instanceof concepts_1.Connection || targetNode instanceof concepts_1.I18nInfo) {
|
|
4628
|
+
return;
|
|
4629
|
+
}
|
|
4630
|
+
// 当前操作的文件节点
|
|
4631
|
+
const { fileNode } = this.getCurrentSource(targetNode);
|
|
4632
|
+
// 不处理系统配置参数
|
|
4633
|
+
if (fileNode instanceof concepts_1.ConfigProperty && fileNode?.parentNode?.name === 'system') {
|
|
4634
|
+
return;
|
|
4635
|
+
}
|
|
4636
|
+
// 如果是导入模块就,就引入对应模块,先不处理module和Configuration,下面的内容会自动创建
|
|
4637
|
+
if (!fileNode || fileNode instanceof concepts_1.Module || fileNode instanceof concepts_1.Configuration || fileNode instanceof concepts_1.Integration) {
|
|
4638
|
+
// module单独处理
|
|
4639
|
+
if (fileNode instanceof concepts_1.Module) {
|
|
4640
|
+
await this.incidentalAction(action, fileNode, targetNode);
|
|
4641
|
+
}
|
|
4642
|
+
return;
|
|
4643
|
+
}
|
|
4644
|
+
// debugger;
|
|
4645
|
+
if (process.env.NODE_ENV === 'development') {
|
|
4646
|
+
console.time('重新生成 TS 文件');
|
|
4647
|
+
}
|
|
4648
|
+
const fileTsPath = fileNode.getEmbeddedFilePath();
|
|
4649
|
+
const result = await utils.timeSlicingWithGenerator(fileNode.toEmbeddedTSFile());
|
|
4650
|
+
if (process.env.NODE_ENV === 'development') {
|
|
4651
|
+
console.timeEnd('重新生成 TS 文件');
|
|
4652
|
+
console.log('重新生成 TS 文件', fileTsPath);
|
|
4653
|
+
}
|
|
4654
|
+
// 当前操作的节点
|
|
4655
|
+
// 如果当前没有生成tsFile
|
|
4656
|
+
if (!result.sourceMap) {
|
|
4657
|
+
return;
|
|
4658
|
+
}
|
|
4659
|
+
// 修改触发修改文件
|
|
4660
|
+
this._debugInFileStorage(targetNode, [
|
|
4661
|
+
{
|
|
4662
|
+
file: result.filePath,
|
|
4663
|
+
fileContent: result.code,
|
|
4664
|
+
},
|
|
4665
|
+
]);
|
|
4666
|
+
fileNode.sourceMap = result.sourceMap;
|
|
4667
|
+
if (action === 'update' || action === 'create') {
|
|
4668
|
+
if ($event?.field !== 'name') {
|
|
4669
|
+
await this.handleChange(fileNode, targetNode, result, action);
|
|
4670
|
+
await this.incidentalAction(action, fileNode, targetNode);
|
|
4671
|
+
}
|
|
4672
|
+
else {
|
|
4673
|
+
const oldpath = fileNode.getEmbeddedFilePath($event.oldObject.name);
|
|
4674
|
+
await this.handleRename(fileNode, targetNode, result, oldpath);
|
|
4675
|
+
await this.incidentalAction(action, fileNode, targetNode, oldpath);
|
|
4676
|
+
}
|
|
4677
|
+
}
|
|
4678
|
+
// 删除
|
|
4679
|
+
if (action === 'delete') {
|
|
4680
|
+
await this.incidentalAction(action, fileNode, targetNode);
|
|
4681
|
+
await this.handleDelete(fileNode, targetNode, result);
|
|
4682
|
+
}
|
|
4683
|
+
return true;
|
|
4684
|
+
}
|
|
4685
|
+
changeFileNext() {
|
|
4686
|
+
if (!this.singleFileChangeIng) {
|
|
4687
|
+
const item = this.changeStackList.shift();
|
|
4688
|
+
this.receiveHandleChange(item)
|
|
4689
|
+
.catch((err) => {
|
|
4690
|
+
console.log(err, 'receiveHandleChangeErr');
|
|
4691
|
+
})
|
|
4692
|
+
.finally(async () => {
|
|
4693
|
+
// 每一个文件与change接触就把状态置为false,让下一个进入
|
|
4694
|
+
this.singleFileChangeIng = false;
|
|
4695
|
+
if (this.changeStackList.length) {
|
|
4696
|
+
this.changeFileNext();
|
|
4697
|
+
}
|
|
4698
|
+
else {
|
|
4699
|
+
if (process.env.NODE_ENV === 'development') {
|
|
4700
|
+
console.info('校验以下文件', Array.from(this.filesToCheck));
|
|
4701
|
+
}
|
|
4702
|
+
await this.getDiagnosticRecordsAndPushAll(Array.from(this.filesToCheck));
|
|
4703
|
+
this.filesToCheck.clear();
|
|
4704
|
+
}
|
|
4705
|
+
});
|
|
4706
|
+
}
|
|
4707
|
+
}
|
|
4708
|
+
/**
|
|
4709
|
+
* 获取 Connector 对应 Connector 的properties
|
|
4710
|
+
*/
|
|
4711
|
+
static getPropertyNames(fileNode) {
|
|
4712
|
+
const names = [];
|
|
4713
|
+
// TODO 如果不存在对应的 Connector 时,应该提示错误
|
|
4714
|
+
if (fileNode) {
|
|
4715
|
+
fileNode.properties.forEach((property) => {
|
|
4716
|
+
names.push(property.name);
|
|
4717
|
+
});
|
|
4718
|
+
}
|
|
4719
|
+
return names;
|
|
4720
|
+
}
|
|
4721
|
+
getNodeCode(fileNode, range) {
|
|
4722
|
+
return (this.tsFiles.get(fileNode.getEmbeddedFilePath()) ?? '').slice(range.start.offset, range.end.offset);
|
|
4723
|
+
}
|
|
4724
|
+
};
|
|
4725
|
+
__decorate([
|
|
4726
|
+
(0, decorators_1.withQueueExecute)('diagnostic')
|
|
4727
|
+
], NaslServer.prototype, "_resolveDiagnosticRecords", null);
|
|
4728
|
+
__decorate([
|
|
4729
|
+
(0, decorators_1.withQueueExecute)('annotation')
|
|
4730
|
+
], NaslServer.prototype, "getNaslAnnotatedJSON", null);
|
|
4731
|
+
NaslServer = NaslServer_1 = __decorate([
|
|
4732
|
+
sentry_1.sentryMonitorNaslServer
|
|
4733
|
+
], NaslServer);
|
|
4734
|
+
exports.NaslServer = NaslServer;
|
|
4735
|
+
//# sourceMappingURL=naslServer.js.map
|