import { UnknownTagNameIssue } from "../../../api" ; import { UI5SemanticModel , BaseUI5Node , UI5Class , } from "@ui5-language-assistant/semantic-model-types" ; import { XMLElement , XMLToken } from "@xml-tools/ast" ; import { getUI5ClassByXMLElement , ui5NodeToFQN , getUI5NodeFromXMLElementNamespace , getUI5AggregationByXMLElement , isSameXMLNS , resolveXMLNS , } from "@ui5-language-assistant/logic-utils" ; import { validations , buildMessage , } from "@ui5-language-assistant/user-facing-text" ; import { CORE_NS } from "../../utils/special-namespaces" ; const { UNKNOWN_CLASS_IN_NS , UNKNOWN_CLASS_WITHOUT_NS , UNKNOWN_AGGREGATION_IN_CLASS , UNKNOWN_AGGREGATION_IN_CLASS_DIFF_NAMESPACE , UNKNOWN_TAG_NAME_IN_CLASS , UNKNOWN_TAG_NAME_IN_NS_UNDER_CLASS , UNKNOWN_TAG_NAME_IN_NS , UNKNOWN_TAG_NAME_NO_NS , } = validations ; export function validateUnknownTagName ( xmlElement , model ) { if ( xmlElement . syntax . openName == undefined || xmlElement . name === null ) { return [ ] ; } if ( xmlElement . ns !== undefined ) { return validateTagWithNamespace ( xmlElement as NamedXMLElementWithNS , model ) ; } else { return validateTagWithoutNamespace ( xmlElement as NamedXMLElement , model ) ; } } type NamedXMLElement = XMLElement & { name : string ; syntax : { openName : XMLToken ; } ; } ; type NamedXMLElementWithNS = NamedXMLElement & { ns : string ; } ; function validateTagWithNamespace ( xmlElement , model ) { const issueDefaults = { kind : "UnknownTagName" as const , offsetRange : { start : xmlElement . syntax . openName . startOffset , end : xmlElement . syntax . openName . endOffset , } , severity : "error" as const , } ; const { namespace : ui5Namespace } = getUI5NodeFromXMLElementNamespace ( xmlElement , model ) ; if ( ui5Namespace === undefined ) { return [ ] ; } if ( shouldIgnoreElement ( xmlElement ) || getUI5ClassByXMLElement ( xmlElement , model ) !== undefined || getUI5AggregationByXMLElement ( xmlElement , model ) !== undefined ) { return [ ] ; } if ( xmlElement . parent . type === "XMLElement" && isSameXMLNS ( xmlElement . parent , xmlElement ) && getUI5AggregationByXMLElement ( xmlElement . parent , model ) === undefined ) { return [ { ... issueDefaults , message : getUnknownTagNameMessage ( xmlElement . name , ui5Namespace , getUI5ClassByXMLElement ( xmlElement . parent , model ) ) , } , ] ; } return [ { ... issueDefaults , message : getUnknownClassMessage ( xmlElement . name , ui5Namespace ) , } , ] ; } function validateTagWithoutNamespace ( xmlElement , model ) { const issueDefaults = { kind : "UnknownTagName" as const , offsetRange : { start : xmlElement . syntax . openName . startOffset , end : xmlElement . syntax . openName . endOffset , } , severity : "error" as const , } ; const { namespace : ui5Namespace , isXmlnsDefined , } = getUI5NodeFromXMLElementNamespace ( xmlElement , model ) ; if ( isXmlnsDefined && ui5Namespace === undefined ) { return [ ] ; } if ( shouldIgnoreElement ( xmlElement ) || getUI5ClassByXMLElement ( xmlElement , model ) !== undefined || getUI5AggregationByXMLElement ( xmlElement , model ) !== undefined ) { return [ ] ; } if ( xmlElement . parent . type === "XMLDocument" ) { return [ { ... issueDefaults , message : getUnknownClassMessage ( xmlElement . name , ui5Namespace ) , } , ] ; } const parentUI5Class = getUI5ClassByXMLElement ( xmlElement . parent , model ) ; if ( parentUI5Class !== undefined ) { if ( parentUI5Class . defaultAggregation === undefined ) { return [ { ... issueDefaults , message : getUnknownAggregationMessage ( xmlElement . name , xmlElement . ns , parentUI5Class , xmlElement . parent . ns ) , } , ] ; } else { return [ { ... issueDefaults , message : getUnknownTagNameMessage ( xmlElement . name , ui5Namespace , parentUI5Class ) , } , ] ; } } const parentUI5Aggregation = getUI5AggregationByXMLElement ( xmlElement . parent , model ) ; if ( parentUI5Aggregation !== undefined ) { return [ { ... issueDefaults , message : getUnknownClassMessage ( xmlElement . name , ui5Namespace ) , } , ] ; } return [ { ... issueDefaults , message : getUnknownTagNameMessage ( xmlElement . name , ui5Namespace , undefined ) , } , ] ; } function shouldIgnoreElement ( xmlElement ) { return ( resolveXMLNS ( xmlElement ) === CORE_NS && ( ( xmlElement . parent . type === "XMLDocument" && xmlElement . name === "FragmentDefinition" ) || ( xmlElement . parent . type !== "XMLDocument" && xmlElement . name === "ExtensionPoint" ) ) ) ; } function getUnknownClassMessage ( name , ui5Namespace ) { if ( ui5Namespace !== undefined ) { return buildMessage ( UNKNOWN_CLASS_IN_NS . msg , name , ui5NodeToFQN ( ui5Namespace ) ) ; } return buildMessage ( UNKNOWN_CLASS_WITHOUT_NS . msg , name ) ; } function getUnknownAggregationMessage ( name , ns , ui5Class , classNS ) { if ( ns !== classNS ) { return buildMessage ( UNKNOWN_AGGREGATION_IN_CLASS_DIFF_NAMESPACE . msg , name , ui5NodeToFQN ( ui5Class ) ) ; } return buildMessage ( UNKNOWN_AGGREGATION_IN_CLASS . msg , name , ui5NodeToFQN ( ui5Class ) ) ; } function getUnknownTagNameMessage ( name , ui5Namespace , parentUI5Class ) { if ( parentUI5Class !== undefined && ui5Namespace !== undefined ) { return buildMessage ( UNKNOWN_TAG_NAME_IN_NS_UNDER_CLASS . msg , name , ui5NodeToFQN ( ui5Namespace ) , ui5NodeToFQN ( parentUI5Class ) ) ; } else if ( parentUI5Class !== undefined && ui5Namespace === undefined ) { return buildMessage ( UNKNOWN_TAG_NAME_IN_CLASS . msg , name , ui5NodeToFQN ( parentUI5Class ) ) ; } else if ( parentUI5Class === undefined && ui5Namespace !== undefined ) { return buildMessage ( UNKNOWN_TAG_NAME_IN_NS . msg , name , ui5NodeToFQN ( ui5Namespace ) ) ; } else { return buildMessage ( UNKNOWN_TAG_NAME_NO_NS . msg , name ) ; } }