{
watcher.addChangeEvent("resultForBinding");
}
else if (srcTypeName != null)
{
AbcClass watchedClass = typeTable.getClass(srcTypeName);
if (watchedClass != null)
{
if ( watchedClass.isSubclassOf(standardDefs.CLASS_OBJECTPROXY) )
{
watcher.setPartOfAnonObjectGraph(true);
}
List metaData = watchedClass.getMetaData(BINDABLE, true);
boolean foundEvents = addBindables(watcher, metaData);
boolean foundSource = false;
Variable variable = getVariable(context, watchedClass, ref, multiName);
if (variable != null)
{
metaData = variable.getMetaData(BINDABLE);
foundEvents = addBindables(watcher, metaData) || foundEvents;
metaData = variable.getMetaData(CHANGE_EVENT);
foundEvents = addChangeEvents(watcher, metaData) || foundEvents;
metaData = variable.getMetaData(NON_COMMITTING_CHANGE_EVENT);
foundEvents = addNonCommittingChangeEvents(watcher, metaData) || foundEvents;
// Object has a public static const variable names "length", which is
// some legacy compatibility crap left over from EMCA script 262, so
// we ignore it.
if (variable.isConst() &&
!(multiName.getLocalPart().equals("length") &&
variable.getDeclaringClassName().equals(SymbolTable.OBJECT)))
{
// We didn't really find any events, but we want
// to follow the same code path below as if we did.
foundEvents = true;
// TODO will this ever be something besides a PropertyWatcher?
if (watcher instanceof PropertyWatcher)
{
((PropertyWatcher) watcher).suppress();
}
}
// See comment above.
if (!(multiName.getLocalPart().equals("length") &&
variable.getDeclaringClassName().equals(SymbolTable.OBJECT)))
{
checkForStaticProperty(variable.isStatic(), watcher, srcTypeName);
}
foundSource = true;
}
if (!foundEvents)
{
Method getter = getGetter(context, watchedClass, ref, multiName);
if (getter != null)
{
metaData = getter.getMetaData(BINDABLE);
foundEvents = addBindables(watcher, metaData) || foundEvents;
metaData = getter.getMetaData(CHANGE_EVENT);
foundEvents = addChangeEvents(watcher, metaData) || foundEvents;
metaData = getter.getMetaData(NON_COMMITTING_CHANGE_EVENT);
foundEvents = addNonCommittingChangeEvents( watcher, metaData) || foundEvents;
checkForStaticProperty(getter.isStatic(), watcher, srcTypeName);
foundSource = true;
}
Method setter = getSetter(context, watchedClass, ref, multiName);
if (setter != null)
{
metaData = setter.getMetaData(BINDABLE);
foundEvents = addBindables(watcher, metaData) || foundEvents;
metaData = setter.getMetaData(CHANGE_EVENT);
foundEvents = addChangeEvents(watcher, metaData) || foundEvents;
metaData = setter.getMetaData(NON_COMMITTING_CHANGE_EVENT);
foundEvents = addNonCommittingChangeEvents(watcher, metaData) || foundEvents;
checkForStaticProperty(setter.isStatic(), watcher, srcTypeName);
foundSource = true;
}
else
{
if (getter != null)
{
// getters without setters are de facto const, use same bypass as above for const vars
foundEvents = true;
}
}
}
if (!foundSource)
{
Method function = getMethod(context, watchedClass, ref, multiName);
if (function != null)
{
metaData = function.getMetaData(BINDABLE);
foundEvents = addBindables(watcher, metaData) || foundEvents;
metaData = function.getMetaData(CHANGE_EVENT);
foundEvents = addChangeEvents(watcher, metaData) || foundEvents;
metaData = function.getMetaData(NON_COMMITTING_CHANGE_EVENT);
foundEvents = addNonCommittingChangeEvents(watcher, metaData) || foundEvents;
foundSource = true;
if (!foundEvents && callExpressionStack.isEmpty())
{
foundEvents = true;
// TODO will this ever be something besides a PropertyWatcher?
if (watcher instanceof PropertyWatcher)
{
((PropertyWatcher)watcher).suppress();
}
}
}
}
if ((!foundSource) && watchedClass.isSubclassOf(standardDefs.CLASS_ABSTRACTSERVICE))
{
watcher.setOperation(true);
}
else if (!foundEvents &&
!(watcher instanceof FunctionReturnWatcher) &&
!(watcher instanceof XMLWatcher) &&
!watcher.isOperation())
{
/***
* NOTE: when we've failed to find change events for properties of untyped or Object-typed parents, we go
* ahead and generate code to create a runtime PropertyWatcher with no change events specified. The lack
* of change events tells the runtime PW to introspect RTTI to discover change events associated with the
* actual type of the actual value being assigned to the property.
* OTOH for strongly-typed properties, we still require change events to be reachable at compile time.
*/
if (!(watchedClass.getName().equals(SymbolTable.OBJECT) || watchedClass.getName().equals(SymbolTable.NOTYPE)))
{
// TODO do we still want this to be configurable?
if (showBindingWarnings)
{
context.localizedWarning2(pos, new UnableToDetectChanges(name));