@Override public boolean equals(Object obj) { return obj instanceof MultipleNodeKindTest && uType.equals(((MultipleNodeKindTest)obj).uType); }
@Override public boolean equals(Object obj) { return obj instanceof MultipleNodeKindTest && uType.equals(((MultipleNodeKindTest)obj).uType); }
/** * Get the basic kind of object that this ItemType matches: for a NodeTest, this is the kind of node, * or Type.Node if it matches different kinds of nodes. * * @return the node kind matched by this node test */ public int getPrimitiveType() { UType mask = getUType(); if (mask.equals(UType.ELEMENT)) { return Type.ELEMENT; } if (mask.equals(UType.ATTRIBUTE)) { return Type.ATTRIBUTE; } if (mask.equals(UType.DOCUMENT)) { return Type.DOCUMENT; } return Type.NODE; }
/** * Get the basic kind of object that this ItemType matches: for a NodeTest, this is the kind of node, * or Type.Node if it matches different kinds of nodes. * * @return the node kind matched by this node test */ public int getPrimitiveType() { UType mask = getUType(); if (mask.equals(UType.ELEMENT)) { return Type.ELEMENT; } if (mask.equals(UType.ATTRIBUTE)) { return Type.ATTRIBUTE; } if (mask.equals(UType.DOCUMENT)) { return Type.DOCUMENT; } return Type.NODE; }
private boolean mayReturnStreamedNodes(Expression exp) { // bug 3465: expressions returning streamed nodes cannot be loop-lifted, // because such nodes must not be bound to a variable // TODO: attempt a more rigorous analysis - see bug 3465 return streaming && !exp.getItemType().getUType().intersection(UType.ANY_NODE).equals(UType.VOID); }
/** * Determine whether two primitive atomic types are comparable under the rules for ValueComparisons * (that is, untyped atomic values treated as strings), using the "eq" operator * * @param t1 the first type to compared. * This must be a primitive atomic type as defined by {@link ItemType#getPrimitiveType} * @param t2 the second type to compared. * This must be a primitive atomic type as defined by {@link ItemType#getPrimitiveType} * @return true if the types are comparable, as defined by the rules of the "eq" operator; false if they * are not comparable, or if we don't yet know (because some subtypes of the static type are comparable * and others are not) */ public static boolean isGuaranteedComparable(UType t1, UType t2) { if (t1 == t2) { return true; // short cut } if (t1 == UType.UNTYPED_ATOMIC || t1 == UType.ANY_URI) { t1 = UType.STRING; } if (t2 == UType.UNTYPED_ATOMIC || t2 == UType.ANY_URI) { t2 = UType.STRING; } if (NUMERIC.subsumes(t1)) { t1 = NUMERIC; } if (NUMERIC.subsumes(t2)) { t2 = NUMERIC; } return t1.equals(t2); }
private boolean mayReturnStreamedNodes(Expression exp) { // bug 3465: expressions returning streamed nodes cannot be loop-lifted, // because such nodes must not be bound to a variable // TODO: attempt a more rigorous analysis - see bug 3465 return streaming && !exp.getItemType().getUType().intersection(UType.ANY_NODE).equals(UType.VOID); }
/** * Determine whether two primitive atomic types are comparable under the rules for ValueComparisons * (that is, untyped atomic values treated as strings), using the "eq" operator * * @param t1 the first type to compared. * This must be a primitive atomic type as defined by {@link ItemType#getPrimitiveType} * @param t2 the second type to compared. * This must be a primitive atomic type as defined by {@link ItemType#getPrimitiveType} * @return true if the types are comparable, as defined by the rules of the "eq" operator; false if they * are not comparable, or if we don't yet know (because some subtypes of the static type are comparable * and others are not) */ public static boolean isGuaranteedComparable(UType t1, UType t2) { if (t1 == t2) { return true; // short cut } if (t1 == UType.UNTYPED_ATOMIC || t1 == UType.ANY_URI) { t1 = UType.STRING; } if (t2 == UType.UNTYPED_ATOMIC || t2 == UType.ANY_URI) { t2 = UType.STRING; } if (NUMERIC.subsumes(t1)) { t1 = NUMERIC; } if (NUMERIC.subsumes(t2)) { t2 = NUMERIC; } return t1.equals(t2); }
public void addRule(Pattern pattern, Rule newRule) { UType uType = pattern.getUType(); if (uType.equals(UType.ELEMENT)) { int fp = pattern.getFingerprint(); addRuleToNamedOrUnnamedChain( newRule, fp, unnamedElementRuleChain, namedElementRuleChains); } else if (uType.equals(UType.ATTRIBUTE)) { int fp = pattern.getFingerprint(); addRuleToNamedOrUnnamedChain( newRule, fp, unnamedAttributeRuleChain, namedAttributeRuleChains); } else if (uType.equals(UType.DOCUMENT)) { addRuleToList(newRule, documentRuleChain); } else if (uType.equals(UType.TEXT)) { addRuleToList(newRule, textRuleChain); } else if (uType.equals(UType.COMMENT)) { addRuleToList(newRule, commentRuleChain); } else if (uType.equals(UType.PI)) { addRuleToList(newRule, processingInstructionRuleChain); } else if (uType.equals(UType.NAMESPACE)) { addRuleToList(newRule, namespaceRuleChain); } else if (UType.ANY_ATOMIC.subsumes(uType)) { addRuleToList(newRule, atomicValueRuleChain); } else if (UType.FUNCTION.subsumes(uType)) { addRuleToList(newRule, functionItemRuleChain); } else { addRuleToList(newRule, genericRuleChain); } }
public void addRule(Pattern pattern, Rule newRule) { UType uType = pattern.getUType(); if (uType.equals(UType.ELEMENT)) { int fp = pattern.getFingerprint(); addRuleToNamedOrUnnamedChain( newRule, fp, unnamedElementRuleChain, namedElementRuleChains); } else if (uType.equals(UType.ATTRIBUTE)) { int fp = pattern.getFingerprint(); addRuleToNamedOrUnnamedChain( newRule, fp, unnamedAttributeRuleChain, namedAttributeRuleChains); } else if (uType.equals(UType.DOCUMENT)) { addRuleToList(newRule, documentRuleChain); } else if (uType.equals(UType.TEXT)) { addRuleToList(newRule, textRuleChain); } else if (uType.equals(UType.COMMENT)) { addRuleToList(newRule, commentRuleChain); } else if (uType.equals(UType.PI)) { addRuleToList(newRule, processingInstructionRuleChain); } else if (uType.equals(UType.NAMESPACE)) { addRuleToList(newRule, namespaceRuleChain); } else if (UType.ANY_ATOMIC.subsumes(uType)) { addRuleToList(newRule, atomicValueRuleChain); } else if (UType.FUNCTION.subsumes(uType)) { addRuleToList(newRule, functionItemRuleChain); } else { addRuleToList(newRule, genericRuleChain); } }
/** * Determine whether a node test is a peer node test. A peer node test is one that, if it * matches a node, cannot match any of its descendants. For example, text() is a peer node-test. * * @param test the node test * @return true if nodes selected by this node-test will never contain each other as descendants */ private static boolean isPeerNodeTest(NodeTest test) { if (test == null) { return false; } UType uType = test.getUType(); if (uType.overlaps(UType.ELEMENT)) { // can match elements; for the moment, assume these can contain each other return false; } else if (uType.overlaps(UType.DOCUMENT)) { // can match documents; return false if we can also match non-documents return uType.equals(UType.DOCUMENT); } else { return true; } }
/** * Determine whether a node test is a peer node test. A peer node test is one that, if it * matches a node, cannot match any of its descendants. For example, text() is a peer node-test. * * @param test the node test * @return true if nodes selected by this node-test will never contain each other as descendants */ private static boolean isPeerNodeTest(NodeTest test) { if (test == null) { return false; } UType uType = test.getUType(); if (uType.overlaps(UType.ELEMENT)) { // can match elements; for the moment, assume these can contain each other return false; } else if (uType.overlaps(UType.DOCUMENT)) { // can match documents; return false if we can also match non-documents return uType.equals(UType.DOCUMENT); } else { return true; } }
/** * Obtain (that is, create or get) an itemType that matches all items whose primitive type is one * of the types present in this UType. * @return a corresponding ItemType */ public ItemType toItemType() { Set<PrimitiveUType> p = decompose(); if (p.isEmpty()) { return ErrorType.getInstance(); } else if (p.size() == 1) { return p.toArray(new PrimitiveUType[1])[0].toItemType(); } else if (ANY_NODE.subsumes(this)) { return AnyNodeTest.getInstance(); } else if (equals(NUMERIC)) { return NumericType.getInstance(); } else if (ANY_ATOMIC.subsumes(this)) { return BuiltInAtomicType.ANY_ATOMIC; } else { return AnyItemType.getInstance(); } }
/** * Obtain (that is, create or get) an itemType that matches all items whose primitive type is one * of the types present in this UType. * @return a corresponding ItemType */ public ItemType toItemType() { Set<PrimitiveUType> p = decompose(); if (p.isEmpty()) { return ErrorType.getInstance(); } else if (p.size() == 1) { return p.toArray(new PrimitiveUType[1])[0].toItemType(); } else if (ANY_NODE.subsumes(this)) { return AnyNodeTest.getInstance(); } else if (equals(NUMERIC)) { return NumericType.getInstance(); } else if (ANY_ATOMIC.subsumes(this)) { return BuiltInAtomicType.ANY_ATOMIC; } else { return AnyItemType.getInstance(); } }
/** * Convert the pattern to a typed pattern, in which an element name is treated as * schema-element(N) * * @param val either "strict" or "lax" depending on the value of xsl:mode/@typed * @return either the original pattern unchanged, or a new pattern as the result of the * conversion * @throws net.sf.saxon.trans.XPathException if the pattern cannot be converted */ @Override public Pattern convertToTypedPattern(String val) throws XPathException { if (upperPattern.getUType().equals(UType.DOCUMENT)) { // suggests a pattern starting with a leading slash Pattern b2 = basePattern.convertToTypedPattern(val); if (b2 == basePattern) { return this; } else { return new AncestorQualifiedPattern(b2, upperPattern, upwardsAxis); } } else { Pattern u2 = upperPattern.convertToTypedPattern(val); if (u2 == upperPattern) { return this; } else { return new AncestorQualifiedPattern(basePattern, u2, upwardsAxis); } } }
/** * Convert the pattern to a typed pattern, in which an element name is treated as * schema-element(N) * * @param val either "strict" or "lax" depending on the value of xsl:mode/@typed * @return either the original pattern unchanged, or a new pattern as the result of the * conversion * @throws net.sf.saxon.trans.XPathException if the pattern cannot be converted */ @Override public Pattern convertToTypedPattern(String val) throws XPathException { if (upperPattern.getUType().equals(UType.DOCUMENT)) { // suggests a pattern starting with a leading slash Pattern b2 = basePattern.convertToTypedPattern(val); if (b2 == basePattern) { return this; } else { return new AncestorQualifiedPattern(b2, upperPattern, upwardsAxis); } } else { Pattern u2 = upperPattern.convertToTypedPattern(val); if (u2 == upperPattern) { return this; } else { return new AncestorQualifiedPattern(basePattern, u2, upwardsAxis); } } }
if (actualUType.equals(UType.UNTYPED_ATOMIC) && keydef.isConvertUntypedToOther()) { if (untypedKeys == null) { untypedKeys = new ArrayList<>(20);
if (it instanceof NodeTest) { UType possibleNodeKinds = it.getUType(); if (possibleNodeKinds.equals(UType.ATTRIBUTE)) { XPathException de = new XPathException("Cannot create an attribute node whose parent is a document node"); de.setErrorCode(isXSLT ? "XTDE0420" : "XPTY0004"); de.setLocator(component.getLocation()); throw de; } else if (possibleNodeKinds.equals(UType.NAMESPACE)) { XPathException de = new XPathException("Cannot create a namespace node whose parent is a document node"); de.setErrorCode(isXSLT ? "XTDE0420" : "XQTY0024"); de.setLocator(component.getLocation()); throw de; } else if (possibleNodeKinds.equals(UType.ELEMENT)) { elementCount++; if (elementCount > 1 &&
public Expression optimize(ExpressionVisitor visitor, ContextItemStaticInfo contextItemType) throws XPathException { Expression exp = super.optimize(visitor, contextItemType); if (exp == this) { if (resultItemType == null) { resultItemType = computeItemType(visitor.getConfiguration().getTypeHierarchy()); } if (visitor.isOptimizeForStreaming()) { UType type = contextItemType.getItemType().getUType(); if (!type.intersection(MultipleNodeKindTest.LEAF.getUType()).equals(UType.VOID)) { Expression copyOf = new CopyOf( new ContextItemExpression(), false, getValidationAction(), getSchemaType(), false); NodeTest leafTest = new MultipleNodeKindTest(type.intersection(MultipleNodeKindTest.LEAF.getUType())); Expression[] conditions = new Expression[]{ new InstanceOfExpression( new ContextItemExpression(), SequenceType.makeSequenceType(leafTest, StaticProperty.EXACTLY_ONE)), Literal.makeLiteral(BooleanValue.TRUE, this)}; Expression[] actions = new Expression[]{copyOf, this}; Choose choose = new Choose(conditions, actions); ExpressionTool.copyLocationInfo(this, choose); return choose; } } } return exp; }
public Expression optimize(ExpressionVisitor visitor, ContextItemStaticInfo contextItemType) throws XPathException { Expression exp = super.optimize(visitor, contextItemType); if (exp == this) { if (resultItemType == null) { resultItemType = computeItemType(visitor.getConfiguration().getTypeHierarchy()); } if (visitor.isOptimizeForStreaming()) { UType type = contextItemType.getItemType().getUType(); if (!type.intersection(MultipleNodeKindTest.LEAF.getUType()).equals(UType.VOID)) { Expression copyOf = new CopyOf( new ContextItemExpression(), false, getValidationAction(), getSchemaType(), false); NodeTest leafTest = new MultipleNodeKindTest(type.intersection(MultipleNodeKindTest.LEAF.getUType())); Expression[] conditions = new Expression[]{ new InstanceOfExpression( new ContextItemExpression(), SequenceType.makeSequenceType(leafTest, StaticProperty.EXACTLY_ONE)), Literal.makeLiteral(BooleanValue.TRUE, this)}; Expression[] actions = new Expression[]{copyOf, this}; Choose choose = new Choose(conditions, actions); ExpressionTool.copyLocationInfo(this, choose); return choose; } } } return exp; }