@Override
void declareFunction(FunctionNode func)
{
func.parseFunctionBody(classScope.getProblems());
final FunctionDefinition funcDef = func.getDefinition();
final boolean is_constructor = func.isConstructor();
ICompilerProject project = classScope.getProject();
boolean isBindable = false;
if (funcDef instanceof AccessorDefinition)
{
IMetaTag[] metaTags = funcDef.getAllMetaTags();
for (IMetaTag metaTag : metaTags)
{
if (metaTag.getTagName().equals(BindableHelper.BINDABLE))
{
IMetaTagAttribute[] attrs = metaTag.getAllAttributes();
isBindable = attrs.length == 0;
}
}
if (!isBindable)
{
AccessorDefinition otherDef =
((AccessorDefinition)funcDef).resolveCorrespondingAccessor(classScope.getProject());
// ignore if not in your class def
if (otherDef != null && otherDef.getContainingScope().equals(funcDef.getContainingScope()))
{
metaTags = otherDef.getAllMetaTags();
for (IMetaTag metaTag : metaTags)
{
if (metaTag.getTagName().equals(BindableHelper.BINDABLE))
{
IMetaTagAttribute[] attrs = metaTag.getAllAttributes();
isBindable = attrs.length == 0;
}
}
}
}
}
functionSemanticChecks(func);
Name funcName = funcDef.getMName(classScope.getProject());
Name bindableName = null;
boolean wasOverride = false;
if (isBindable)
{
// move function into bindable namespace
bindableName = BindableHelper.getBackingPropertyName(funcName, "_" + this.classDefinition.getQualifiedName());
wasOverride = funcDef.isOverride();
funcDef.unsetOverride();
}
// Save the constructor function until
// we've seen all the instance variables
// that might need initialization.
if ( is_constructor )
{
if (this.ctorFunction == null)
this.ctorFunction = func;
else
{
// If we already have a ctor, must be multiply defined. Ignore it and generate problem
String name = this.className.getBaseName();
classScope.addProblem( new MultipleContructorDefinitionsProblem(func, name));
}
}
else
{
LexicalScope ls = funcDef.isStatic()? classStaticScope: classScope;
MethodInfo mi = classScope.getGenerator().generateFunction(func, ls, null, bindableName);
if ( mi != null )
{
ITraitVisitor tv = ls.traitsVisitor.visitMethodTrait(functionTraitKind(func, TRAIT_Method),
bindableName != null ? bindableName : funcName, 0, mi);
if (funcName != null && bindableName == null)
classScope.getMethodBodySemanticChecker().checkFunctionForConflictingDefinitions(func, funcDef);
if ( ! funcDef.isStatic() && bindableName == null)
if (funcDef.getNamespaceReference() instanceof NamespaceDefinition.IProtectedNamespaceDefinition)
this.iinfo.flags |= ABCConstants.CLASS_FLAG_protected;
ls.processMetadata(tv, getAllMetaTags(funcDef));
if ( func.hasModifier(ASModifier.FINAL))
tv.visitAttribute(Trait.TRAIT_FINAL, Boolean.TRUE);
// don't set override if we've moved it to the bindable namespace
if (!wasOverride && (func.hasModifier(ASModifier.OVERRIDE) || funcDef.isOverride()))
tv.visitAttribute(Trait.TRAIT_OVERRIDE, Boolean.TRUE);
tv.visitEnd();
}
}
if (isBindable)
{
if (wasOverride)
funcDef.setOverride();
if (funcDef instanceof GetterDefinition)
{
DefinitionBase bindableGetter = func.buildBindableGetter(funcName.getBaseName());
ASScope funcScope = (ASScope)funcDef.getContainingScope();
bindableGetter.setContainingScope(funcScope);
LexicalScope ls = funcDef.isStatic()? classStaticScope: classScope;
ls.generateBindableGetter(bindableGetter, funcName, bindableName,
funcDef.resolveType(project).getMName(project), getAllMetaTags(funcDef));
}
else
{
TypeDefinitionBase typeDef = funcDef.resolveType(project);
ASScope funcScope = (ASScope)funcDef.getContainingScope();
DefinitionBase bindableSetter = func.buildBindableSetter(funcName.getBaseName(),
funcScope,
funcDef.getTypeReference());
bindableSetter.setContainingScope(funcScope);
LexicalScope ls = funcDef.isStatic()? classStaticScope: classScope;
ls.generateBindableSetter(bindableSetter, funcName, bindableName,
typeDef.getMName(project), getAllMetaTags(funcDef));
}
}
}