IDefinition def = resolve(project);
if (canEarlyBind(project, def))
return ((DefinitionBase)def).getMName(project);
ASScope scope = getASScope();
if (isQualifiedRef())
{
// If we're a qualified name, and the qualifier resolves to a compile
// time constant, return a QName
// otherwise emit a RTQname - the CG will have to take care of generating the code to
// evaluate the qualifier and place it on the stack.
IQualifiers qual = resolveQualifier(project);
Nsset namespaceSet;
int nameKind;
if (qual != null )
{
if( qual.getNamespaceCount() == 1 )
{
// Qualifier resolved to 1 namespace, so we can emit a QName
NamespaceDefinition ns = (NamespaceDefinition)qual.getFirst();
nameKind = isAttributeIdentifier() ? CONSTANT_QnameA : CONSTANT_Qname;
if (isMemberRef())
{
ExpressionNodeBase baseExpr = getBaseExpression();
if (baseExpr instanceof LanguageIdentifierNode &&
((LanguageIdentifierNode)baseExpr).getKind() == LanguageIdentifierKind.SUPER)
{
// If we're a super expression, adjust the namespace in case it's the protected namespace
IDefinition baseType = baseExpr.resolveType(project);
Set<INamespaceDefinition> nsset = ImmutableSet.of((INamespaceDefinition)ns);
nsset = scope.adjustNamespaceSetForSuper(baseType, nsset);
// We only started with 1 namespace, so we know that's how many we have
ns = (NamespaceDefinition)nsset.iterator().next();
}
}
// If the qualifier is the any namespace, then we want a null nsset
// instead of a nsset of length 1, with a null namespace in it.
if( ns == NamespaceDefinition.getAnyNamespaceReference() )
namespaceSet = null;
else
namespaceSet = new Nsset(ns.getAETNamespace());
}
else
{
// qualifier resolve to 1+ namespaces, so emit a multiname
Set<INamespaceDefinition> nsset = qual.getNamespaceSet();
nameKind = isAttributeIdentifier() ? CONSTANT_MultinameA : CONSTANT_Multiname;
namespaceSet = SemanticUtils.convertSetINamespaceToNsset(nsset);
}
}
else
{
namespaceSet = null;
nameKind = isAttributeIdentifier() ? CONSTANT_RTQnameA : CONSTANT_RTQname;
}
return new Name(nameKind, namespaceSet, getName());
}
Name name = null;
if (isMemberRef())
{
ExpressionNodeBase baseExpr = getBaseExpression();
if (baseExpr != null)
{
// Handle the case where we look like a member expression, but the base expression is really
// a reference to a package. For example 'a.b.c.Foo' where a.b.c is a known package name.
// This needs to generate a QName with a.b.c as the qualifier.
if (baseIsPackage())
{
String packageName = baseExpr.computeSimpleReference();
Workspace workspace = (Workspace)project.getWorkspace();
INamespaceReference qualifier = workspace.getPackageNamespaceDefinitionCache().get(packageName, false);
return new Name(isAttributeIdentifier() ? CONSTANT_QnameA : CONSTANT_Qname,
new Nsset(qualifier.resolveAETNamespace(project)), getName());
}
Set<INamespaceDefinition> namespaceSet = null;
IDefinition baseType = baseExpr.resolveType(project);
// If our base type is an interface, then we need to use the special
// interface namespace set (the namespace of the interface, plus the namespaces for all the interfaces
// it extends)
if (baseType instanceof InterfaceDefinition)
{
namespaceSet = ((InterfaceDefinition)baseType).getInterfaceNamespaceSet(project);
}
else if (baseExpr instanceof LanguageIdentifierNode &&
((LanguageIdentifierNode)baseExpr).getKind() == LanguageIdentifierKind.SUPER)
{
namespaceSet = scope.getNamespaceSetForSuper(project, baseType);
}
if (namespaceSet != null)
return makeName(namespaceSet, getName(), isAttributeIdentifier());
}
}
if (isNameNode())
{
BaseDefinitionNode defNode = getParentAsDefinition();
name = defNode.getDefinition().getMName(project);
}
else if (scope != null)
{
Set<INamespaceDefinition> namespaceSet = null;
if (isMemberRef())
{
// Member refs just use the open namespace set
namespaceSet = scope.getNamespaceSet(project);
}
else
{
// lexical refs may be influenced by the imports
namespaceSet = scope.getNamespaceSetForName(project, getName());
}
name = makeName(namespaceSet, getName(), isAttributeIdentifier());
}