private GenerateNameType LoadNameAndType(XPathNodeType nodeType, QilNode ndName, bool isStart, bool callChk) {
QilName ndLiteralName;
string prefix, localName, ns;
GenerateNameType nameType;
Debug.Assert(ndName.XmlType.TypeCode == XmlTypeCode.QName, "Element or attribute name must have QName type.");
this.helper.LoadQueryOutput();
// 0. Default is to pop names off stack
nameType = GenerateNameType.StackName;
// 1. Literal names
if (ndName.NodeType == QilNodeType.LiteralQName) {
// If checks need to be made on End construction, then always pop names from stack
if (isStart || !callChk) {
ndLiteralName = ndName as QilName;
prefix = ndLiteralName.Prefix;
localName = ndLiteralName.LocalName;
ns = ndLiteralName.NamespaceUri;
// Check local name, namespace parts in debug code
Debug.Assert(ValidateNames.ValidateName(prefix, localName, ns, nodeType, ValidateNames.Flags.AllExceptPrefixMapping));
// If the namespace is empty,
if (ndLiteralName.NamespaceUri.Length == 0) {
// Then always call method on XmlQueryOutput
this.helper.Emit(OpCodes.Ldstr, ndLiteralName.LocalName);
return GenerateNameType.LiteralLocalName;
}
// If prefix is not valid for the node type,
if (!ValidateNames.ValidateName(prefix, localName, ns, nodeType, ValidateNames.Flags.CheckPrefixMapping)) {
// Then construct a new prefix at run-time
if (isStart) {
this.helper.Emit(OpCodes.Ldstr, localName);
this.helper.Emit(OpCodes.Ldstr, ns);
this.helper.Construct(XmlILConstructors.QName);
nameType = GenerateNameType.QName;
}
}
else {
// Push string parts
this.helper.Emit(OpCodes.Ldstr, prefix);
this.helper.Emit(OpCodes.Ldstr, localName);
this.helper.Emit(OpCodes.Ldstr, ns);
nameType = GenerateNameType.LiteralName;
}
}
}
else {
if (isStart) {
// 2. Copied names
if (ndName.NodeType == QilNodeType.NameOf) {
// Preserve prefix of source node, so just push navigator onto stack
NestedVisitEnsureStack((ndName as QilUnary).Child);
nameType = GenerateNameType.CopiedName;
}
// 3. Parsed tag names (foo:bar)
else if (ndName.NodeType == QilNodeType.StrParseQName) {
// Preserve prefix from parsed tag name
VisitStrParseQName(ndName as QilBinary, true);
// Type of name depends upon data-type of name argument
if ((ndName as QilBinary).Right.XmlType.TypeCode == XmlTypeCode.String)
nameType = GenerateNameType.TagNameAndNamespace;
else
nameType = GenerateNameType.TagNameAndMappings;
}
// 4. Other computed qnames
else {
// Push XmlQualifiedName onto the stack
NestedVisitEnsureStack(ndName);
nameType = GenerateNameType.QName;
}
}
}
return nameType;
}