/** * Form a UType as the union of two other UTypes * @param other the other UType * @return the UType representing the union of this UType and the other UType */ public UType union(UType other) { return new UType(bits | other.bits); }
/** * Given a context item type and an axis, determine the kinds of nodes that can be returned * @param origin the context item type, as a UType representing one or more node kinds * @param axis identifies the axis * @return the set of possible node kinds in the result of the axis expression, as a UType */ public static UType getTargetUType(UType origin, byte axis) { UType resultType = UType.VOID; Set<PrimitiveUType> origins = origin.intersection(UType.ANY_NODE).decompose(); for (PrimitiveUType u : origins) { UType r = axisTransitions.get(makeKey(u, axis)); resultType = resultType.union(r); } return resultType; }
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); }
/** * 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; } }
/** * Get extra diagnostic information about why a supplied item does not conform to this * item type, if available. If extra information is returned, it should be in the form of a complete * sentence, minus the closing full stop. No information should be returned for obvious cases. * * @param item the item that doesn't match this type * @param th the type hierarchy cache * @return optionally, a message explaining why the item does not match the type */ @Override public Optional<String> explainMismatch(Item item, TypeHierarchy th) { if (item instanceof NodeInfo) { UType actualKind = UType.getUType(item); if (!getUType().overlaps(actualKind)) { return Optional.of("The supplied value is " + actualKind.toStringWithIndefiniteArticle()); } return Optional.empty(); } else { return Optional.of("The supplied value is " + item.getGenre().getDescription()); } }
/** * 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(); } }
public NamespaceTest(NamePool pool, int nodeKind, String uri) { namePool = pool; this.nodeKind = nodeKind; this.uri = uri; this.uType = UType.fromTypeCode(nodeKind); }
/** * Get the UType of a Sequence * @param sequence the sequence whose UType is required * @return the UType of the item */ public static UType getUType(GroundedValue sequence) { UnfailingIterator iter = sequence.iterate(); Item item; UType u = UType.VOID; while ((item = iter.next()) != null) { u = u.union(getUType(item)); } return u; }
/** * Get the corresponding {@link net.sf.saxon.type.UType}. A UType is a union of primitive item * types. * * @return the smallest UType that subsumes this item type */ public UType getUType() { UType u1 = nodetest1.getUType(); UType u2 = nodetest2.getUType(); switch (operator) { case Token.UNION: return u1.union(u2); case Token.INTERSECT: return u1.intersection(u2); case Token.EXCEPT: return u1; default: throw new IllegalArgumentException("Unknown operator in Combined Node Test"); } }
public String toString() { FastStringBuffer fsb = new FastStringBuffer(FastStringBuffer.C64); LinkedList<PrimitiveUType> types = new LinkedList<>(uType.decompose()); format(types, fsb, ItemType::toString); return fsb.toString(); }
/** * Get the nodes with a given key value * * @param soughtValue The required key value * @return a list of the selected nodes, always in document order with no duplicates, or null * to represent an empty list * @throws XPathException if a dynamic error is encountered */ public List<NodeInfo> get(AtomicValue soughtValue) throws XPathException { if (untypedKeys != null && !keyTypesConvertedFromUntyped.subsumes(soughtValue.getUType())) { reindexUntypedValues(soughtValue.getPrimitiveType()); } return index.get(getCollationKey(soughtValue, collation, implicitTimezone)); }
/** * Get a UType indicating which kinds of items this Pattern can match. * * @return a UType indicating all the primitive types of item that the pattern can match. */ @Override public UType getUType() { return p1.getUType().intersection(p2.getUType()); }
private void computeSingleValued(TypeHierarchy th) { ItemType operandType = getOperandItemType(); if (th.relationship(operandType, ArrayItemType.ANY_ARRAY_TYPE) != TypeHierarchy.DISJOINT) { singleValued = false; } else { singleValued = untyped; if (!singleValued) { ItemType nodeType = getBaseExpression().getItemType(); if (nodeType instanceof NodeTest) { SchemaType st = ((NodeTest) nodeType).getContentType(); if (st == Untyped.getInstance() || st.isAtomicType() || (st.isComplexType() && st != AnyType.getInstance())) { singleValued = true; } if (!nodeType.getUType().overlaps(UType.ELEMENT.union(UType.ATTRIBUTE))) { singleValued = true; } } } } }
public MultipleNodeKindTest(UType u) { this.uType = u; if (UType.DOCUMENT.overlaps(u)) { nodeKindMask |= 1 << Type.DOCUMENT; } if (UType.ELEMENT.overlaps(u)) { nodeKindMask |= 1 << Type.ELEMENT; } if (UType.ATTRIBUTE.overlaps(u)) { nodeKindMask |= 1 << Type.ATTRIBUTE; } if (UType.TEXT.overlaps(u)) { nodeKindMask |= 1 << Type.TEXT; } if (UType.COMMENT.overlaps(u)) { nodeKindMask |= 1 << Type.COMMENT; } if (UType.PI.overlaps(u)) { nodeKindMask |= 1 << Type.PROCESSING_INSTRUCTION; } if (UType.NAMESPACE.overlaps(u)) { nodeKindMask |= 1 << Type.NAMESPACE; } }
@Override public boolean equals(Object obj) { return obj instanceof MultipleNodeKindTest && uType.equals(((MultipleNodeKindTest)obj).uType); }
/** * Returns a hash code value for the object. */ public int hashCode() { return uType.hashCode(); }
/** * Determine whether two primitive atomic types are comparable under the rules for GeneralComparisons * for the "=" operator (that is, untyped atomic values treated as comparable to anything) * * * @param t1 the first type to compared. * This must be a primitive atomic type as defined by {@link net.sf.saxon.type.ItemType#getPrimitiveType} * @param t2 the second type to compared. * This must be a primitive atomic type as defined by {@link net.sf.saxon.type.ItemType#getPrimitiveType} * @return true if the types are comparable, as defined by the rules of the "=" operator */ public static boolean isGenerallyComparable(UType t1, UType t2) { return t1 == UType.UNTYPED_ATOMIC || t2 == UType.UNTYPED_ATOMIC || isGuaranteedComparable(t1, t2); }
if (!reqItemType.matches(item, context.getConfiguration().getTypeHierarchy())) { XPathException err = new XPathException("Required type is " + reqItemType + "; supplied value has type " + UType.getUType(val.materialize())); err.setIsTypeError(true); err.setErrorCode("XPTY0004");