in modules/asc/src/java/macromedia/asc/semantics/FlowAnalyzer.java [5315:5545]
public Value evaluate(Context cx, AttributeListNode node)
{
if( node.namespace_ids.size() != 0 || node.namespaces.size() != 0 )
{
return null;
}
ObjectValue obj = null;
ReferenceValue ref = null;
// Use these for keeping track of if we have already seen a given attribute.
// This is used for error checking (attributes should not appear more than once)
boolean setPrivate = false;
boolean setProtected = false;
boolean setPublic = false;
boolean setInternal = false;
boolean setDynamic = false;
boolean setVirtual = false;
boolean setFinal = false;
boolean setOverride = false;
boolean setStatic = false;
boolean setNative = false;
boolean setPrototype = false;
for (int i = 0, size = node.items.size(); i < size; i++)
{
Node n = node.items.get(i);
if( n != null )
{
if( n.hasAttribute(PRIVATE) )
{
if( setPrivate )
{
cx.error(n.pos(), kError_DuplicateAttribute, PRIVATE);
}
setPrivate = node.hasPrivate = true;
}
else
if( n.hasAttribute(PROTECTED) )
{
if( setProtected )
{
cx.error(n.pos(), kError_DuplicateAttribute, PROTECTED);
}
setProtected = node.hasProtected = true;
}
else
if( n.hasAttribute(PUBLIC) )
{
if( setPublic )
{
cx.error(n.pos(), kError_DuplicateAttribute, PUBLIC);
}
setPublic = node.hasPublic = true;
}
else
if( n.hasAttribute(INTERNAL) )
{
if( setInternal )
{
cx.error(n.pos(), kError_DuplicateAttribute, INTERNAL);
}
setInternal = node.hasInternal = true;
}
else
{
if( n.hasAttribute(PROTOTYPE) )
{
if( setPrototype )
{
cx.error(n.pos(), kError_DuplicateAttribute, PROTOTYPE);
}
setPrototype = node.hasPrototype = true;
}
rt_unresolved_sets.last().addAll(unresolved);
unresolved.clear();
Value val1 = n.evaluate(cx,this);
ns_unresolved_sets.last().addAll(unresolved);
unresolved.clear();
ref = ((val1 instanceof ReferenceValue) ? (ReferenceValue)val1 : null);
if( ref != null )
{
Value val2 = ref.getValue(cx);
obj = ((val2 instanceof ObjectValue) ? (ObjectValue)val2 : null);
if( obj!=null )
{
if( obj == ObjectValue.intrinsicAttribute ) {
node.hasIntrinsic = true;
cx.error(n.pos(), kError_Unsupported_Intrinsic);
}
else
if( obj == ObjectValue.staticAttribute ) {
if( setStatic )
{
cx.error(n.pos(), kError_DuplicateAttribute, STATIC);
}
setStatic = node.hasStatic = true;
if( !(cx.scope().builder instanceof InstanceBuilder) && !(cx.scope().builder instanceof ClassBuilder))
{
cx.error(n.pos(), kError_InvalidStatic);
}
}
else
if( obj == ObjectValue.dynamicAttribute ) {
if( setDynamic )
{
cx.error(n.pos(), kError_DuplicateAttribute, "dynamic");
}
setDynamic = node.hasDynamic = true;
}
else
if( obj == ObjectValue.virtualAttribute ) {
if( setVirtual )
{
cx.error(n.pos(), kError_DuplicateAttribute, "virtual");
}
setVirtual = node.hasVirtual = true; // error if has final too
if( !(cx.scope().builder instanceof InstanceBuilder) && !(cx.scope().builder instanceof ClassBuilder) )
{
cx.error(n.pos(), kError_InvalidVirtual);
}
}
else
if( obj == ObjectValue.finalAttribute ) {
if( setFinal )
{
cx.error(n.pos(), kError_DuplicateAttribute, "final");
}
setFinal = node.hasFinal = true; // error if has virtual too
}
else
if( obj == ObjectValue.overrideAttribute ) {
if( setOverride )
{
cx.error(n.pos(), kError_DuplicateAttribute, "override");
}
setOverride = node.hasOverride = true;
if( !(cx.scope().builder instanceof InstanceBuilder) && !(cx.scope().builder instanceof ClassBuilder) )
{
cx.error(n.pos(), kError_InvalidOverride);
}
}
else
if( obj == ObjectValue.nativeAttribute ) {
if( setNative )
{
cx.error(n.pos(), kError_DuplicateAttribute, "native");
}
setNative = node.hasNative = true;
}
else
{
if( obj != null )
{
if( "false".equals(obj.name) )
{
node.hasFalse = true;
}
if( !(cx.scope().builder instanceof ClassBuilder || cx.scope().builder instanceof InstanceBuilder) )
{
cx.error(node.pos(), kError_InvalidNamespace);
}
else
{
node.namespaces.push_back(obj);
node.namespace_ids.push_back(ref.name);
}
}
}
}
else
{
if( !(cx.scope().builder instanceof ClassBuilder || cx.scope().builder instanceof InstanceBuilder) )
{
cx.error(node.pos(), kError_InvalidNamespace);
}
else
{
node.namespaces.push_back(cx.getUnresolvedNamespace(cx, node, ref));
node.namespace_ids.push_back(ref.name);
}
}
}
else
{
cx.error(node.pos(), kError_InvalidAttribute);
}
}
}
}
if (node.namespaces.size() != 0)
{
boolean foundUserNamespace = false;
for (ObjectValue ns : node.namespaces)
{
if (!(ns instanceof NamespaceValue))
{
// Error: Not a namespace attribute
cx.error(node.pos(), kError_InvalidAttribute);
}
else if (!foundUserNamespace)
{
foundUserNamespace = true;
node.setUserNamespace(ns);
}
else
{
cx.error(node.pos(), kError_MultipleNamespaceAttributes);
break;
}
}
}
// Only one of public, private, protected, internal may be used.
if (((node.hasPrivate?1:0) + (node.hasPublic?1:0) + (node.hasProtected?1:0) + (node.hasInternal?1:0)) > 1)
{
cx.error(node.pos(), kError_ConflictingAccessSpecifiers);
}
if (node.hasUserNamespace() && (node.hasPrivate || node.hasPublic || node.hasProtected || node.hasInternal))
{
cx.error(node.pos(), kError_NamespaceAccessSpecifiers);
}
return null;
}