generator.javagenerator.cpp Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of qtjambi Show documentation
Show all versions of qtjambi Show documentation
Legacy QtJambi library for RapidWright, from: https://sourceforge.net/projects/qtjambi/files/4.5.2/
The newest version!
/****************************************************************************
**
** Copyright (C) 1992-2009 Nokia. All rights reserved.
**
** This file is part of Qt Jambi.
**
** ** $BEGIN_LICENSE$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at [email protected].
** $END_LICENSE$
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#include "javagenerator.h"
#include "reporthandler.h"
#include "docparser.h"
#include "jumptable.h"
#include
#include
#include
#include
#include
static Indentor INDENT;
JavaGenerator::JavaGenerator()
: m_doc_parser(0),
m_docs_enabled(false),
m_native_jump_table(false)
{
}
QString JavaGenerator::fileNameForClass(const AbstractMetaClass *java_class) const
{
return QString("%1.java").arg(java_class->name());
}
void JavaGenerator::writeFieldAccessors(QTextStream &s, const AbstractMetaField *field)
{
Q_ASSERT(field->isPublic() || field->isProtected());
const AbstractMetaClass *declaringClass = field->enclosingClass();
FieldModification mod = declaringClass->typeEntry()->fieldModification(field->name());
// Set function
if (mod.isWritable() && !field->type()->isConstant()) {
const AbstractMetaFunction *setter = field->setter();
if (declaringClass->hasFunction(setter)) {
QString warning =
QString("class '%1' already has setter '%2' for public field '%3'")
.arg(declaringClass->name()).arg(setter->name()).arg(field->name());
ReportHandler::warning(warning);
} else {
writeFunction(s, setter);
}
}
// Get function
const AbstractMetaFunction *getter = field->getter();
if (mod.isReadable()) {
if (declaringClass->hasFunction(getter)) {
QString warning =
QString("class '%1' already has getter '%2' for public field '%3'")
.arg(declaringClass->name()).arg(getter->name()).arg(field->name());
ReportHandler::warning(warning);
} else {
writeFunction(s, getter);
}
}
}
QString JavaGenerator::translateType(const AbstractMetaType *java_type, const AbstractMetaClass *context, Option option)
{
QString s;
if (context != 0 && java_type != 0 && context->typeEntry()->isGenericClass() && java_type->originalTemplateType() != 0)
java_type = java_type->originalTemplateType();
if (!java_type) {
s = "void";
} else if (java_type->isArray()) {
s = translateType(java_type->arrayElementType(), context) + "[]";
} else if (java_type->isEnum() || java_type->isFlags()) {
if (java_type->isEnum() && ((EnumTypeEntry *)java_type->typeEntry())->forceInteger()
|| java_type->isFlags() && ((FlagsTypeEntry *)java_type->typeEntry())->forceInteger()) {
if (option & BoxedPrimitive)
s = "java.lang.Integer";
else
s = "int";
} else {
if (option & EnumAsInts)
s = "int";
else
s = java_type->fullName();
}
} else {
if (java_type->isPrimitive() && (option & BoxedPrimitive)) {
s = static_cast(java_type->typeEntry())->javaObjectFullName();
} else if (java_type->isNativePointer()) {
s = "com.trolltech.qt.QNativePointer";
} else if (java_type->isContainer()) {
s = java_type->typeEntry()->qualifiedTargetLangName();
if ((option & SkipTemplateParameters) == 0) {
s += '<';
QList args = java_type->instantiations();
for (int i=0; i(java_type->typeEntry())->type() == ContainerTypeEntry::MultiMapContainer
&& i == 1;
if (isMultiMap)
s += "java.util.List<";
s += translateType(args.at(i), context, BoxedPrimitive);
if (isMultiMap)
s += ">";
}
s += '>';
}
} else {
const TypeEntry *type = java_type->typeEntry();
if (type->designatedInterface())
type = type->designatedInterface();
s = type->qualifiedTargetLangName();
}
}
return s;
}
QString JavaGenerator::argumentString(const AbstractMetaFunction *java_function,
const AbstractMetaArgument *java_argument,
uint options)
{
QString modified_type = java_function->typeReplaced(java_argument->argumentIndex() + 1);
QString arg;
if (modified_type.isEmpty())
arg = translateType(java_argument->type(), java_function->implementingClass(), (Option) options);
else
arg = modified_type.replace('$', '.');
if ((options & SkipName) == 0) {
arg += " ";
arg += java_argument->argumentName();
}
return arg;
}
void JavaGenerator::writeArgument(QTextStream &s,
const AbstractMetaFunction *java_function,
const AbstractMetaArgument *java_argument,
uint options)
{
s << argumentString(java_function, java_argument, options);
}
void JavaGenerator::writeIntegerEnum(QTextStream &s, const AbstractMetaEnum *java_enum)
{
const AbstractMetaEnumValueList &values = java_enum->values();
s << " public static class " << java_enum->name() << "{" << endl;
for (int i=0; itypeEntry()->isEnumValueRejected(value->name()))
continue;
if (m_doc_parser)
s << m_doc_parser->documentation(value);
s << " public static final int " << value->name() << " = " << value->value();
s << ";";
s << endl;
}
s << " } // end of enum " << java_enum->name() << endl << endl;
}
void JavaGenerator::writeEnum(QTextStream &s, const AbstractMetaEnum *java_enum)
{
if (m_doc_parser) {
s << m_doc_parser->documentation(java_enum);
}
if (java_enum->typeEntry()->forceInteger()) {
writeIntegerEnum(s, java_enum);
return;
}
// Check if enums in QObjects are declared in the meta object. If not
if ( (java_enum->enclosingClass()->isQObject() || java_enum->enclosingClass()->isQtNamespace())
&& !java_enum->hasQEnumsDeclaration()) {
s << " @QtBlockedEnum" << endl;
}
// Generates Java 1.5 type enums
s << " public enum " << java_enum->name()
<< " implements com.trolltech.qt.QtEnumerator {" << endl;
const AbstractMetaEnumValueList &values = java_enum->values();
EnumTypeEntry *entry = java_enum->typeEntry();
for (int i=0; itypeEntry()->isEnumValueRejected(enum_value->name()))
continue;
if (m_doc_parser)
s << m_doc_parser->documentation(enum_value);
s << " " << enum_value->name() << "(" << enum_value->value() << ")";
if (i != values.size() - 1 || entry->isExtensible()) {
s << "," << endl;
}
}
if (entry->isExtensible())
s << " CustomEnum(0)";
s << ";" << endl << endl;
s << " " << java_enum->name() << "(int value) { this.value = value; }" << endl
<< " public int value() { return value; }" << endl
<< endl;
// Write out the createQFlags() function if its a QFlags enum
if (entry->flags()) {
FlagsTypeEntry *flags_entry = entry->flags();
s << " public static " << flags_entry->targetLangName() << " createQFlags("
<< entry->targetLangName() << " ... values) {" << endl
<< " return new " << flags_entry->targetLangName() << "(values);" << endl
<< " }" << endl;
}
// The resolve functions. The public one that returns the right
// type and an internal one that has a generic signature. Makes it
// easier to find the right one from JNI.
s << " public static " << java_enum->name() << " resolve(int value) {" << endl
<< " return (" << java_enum->name() << ") resolve_internal(value);" << endl
<< " }" << endl
<< " private static Object resolve_internal(int value) {" << endl
<< " switch (value) {" << endl;
for (int i=0; itypeEntry()->isEnumValueRejected(e->name()))
continue;
s << " case " << e->value() << ": return " << e->name() << ";" << endl;
}
s << " }" << endl;
if (entry->isExtensible()) {
s << " if (enumCache == null)" << endl
<< " enumCache = new java.util.HashMapname()
<< ">();" << endl
<< " " << java_enum->name() << " e = enumCache.get(value);" << endl
<< " if (e == null) {" << endl
<< " e = (" << java_enum->name() << ") com.trolltech.qt.GeneratorUtilities.createExtendedEnum("
<< "value, CustomEnum.ordinal(), " << java_enum->name() << ".class, CustomEnum.name());"
<< endl
<< " enumCache.put(value, e);" << endl
<< " }" << endl
<< " return e;" << endl;
} else {
s << " throw new com.trolltech.qt.QNoSuchEnumValueException(value);" << endl;
}
s << " }" << endl;
s << " private final int value;" << endl
<< endl;
if (entry->isExtensible()) {
s << " private static java.util.HashMapname()
<< "> enumCache;";
}
s << " }" << endl;
// Write out the QFlags if present...
FlagsTypeEntry *flags_entry = entry->flags();
if (flags_entry) {
QString flagsName = flags_entry->targetLangName();
s << " public static class " << flagsName << " extends com.trolltech.qt.QFlags<"
<< java_enum->name() << "> {" << endl
<< " private static final long serialVersionUID = 1L;" << endl
<< " public " << flagsName << "(" << java_enum->name() << " ... args)"
<< " { super(args); }" << endl
<< " public " << flagsName << "(int value) { setValue(value); }" << endl
<< " }" << endl << endl;
}
}
void JavaGenerator::writePrivateNativeFunction(QTextStream &s, const AbstractMetaFunction *java_function)
{
int exclude_attributes = AbstractMetaAttributes::Public | AbstractMetaAttributes::Protected;
int include_attributes = 0;
if (java_function->isEmptyFunction())
exclude_attributes |= AbstractMetaAttributes::Native;
else
include_attributes |= AbstractMetaAttributes::Native;
// if (!java_function->isConstructor())
// include_attributes |= AbstractMetaAttributes::Static;
writeFunctionAttributes(s, java_function, include_attributes, exclude_attributes,
EnumAsInts
| (java_function->isEmptyFunction()
|| java_function->isNormal()
|| java_function->isSignal() ? 0 : SkipReturnType));
if (java_function->isConstructor())
s << "void ";
s << java_function->marshalledName();
s << "(";
AbstractMetaArgumentList arguments = java_function->arguments();
if (!java_function->isStatic() && !java_function->isConstructor())
s << "long __this__nativeId";
for (int i=0; iargumentRemoved(i+1)) {
if (i > 0 || (!java_function->isStatic() && !java_function->isConstructor()))
s << ", ";
if (!arg->type()->hasNativeId())
writeArgument(s, java_function, arg, EnumAsInts);
else
s << "long " << arg->argumentName();
}
}
s << ")";
// Make sure people don't call the private functions
if (java_function->isEmptyFunction()) {
s << endl
<< INDENT << "{" << endl
<< INDENT << " throw new com.trolltech.qt.QNoImplementationException();" << endl
<< INDENT << "}" << endl << endl;
} else {
s << ";" << endl;
}
}
static QString function_call_for_ownership(TypeSystem::Ownership owner)
{
if (owner == TypeSystem::CppOwnership) {
return "disableGarbageCollection()";
} else if (owner == TypeSystem::TargetLangOwnership) {
return "setJavaOwnership()";
} else if (owner == TypeSystem::DefaultOwnership) {
return "reenableGarbageCollection()";
} else {
Q_ASSERT(false);
return "bogus()";
}
}
void JavaGenerator::writeOwnershipForContainer(QTextStream &s, TypeSystem::Ownership owner,
AbstractMetaType *type, const QString &arg_name)
{
Q_ASSERT(type->isContainer());
s << INDENT << "for (" << type->instantiations().at(0)->fullName() << " i : "
<< arg_name << ")" << endl
<< INDENT << " if (i != null) i." << function_call_for_ownership(owner) << ";" << endl;
}
void JavaGenerator::writeOwnershipForContainer(QTextStream &s, TypeSystem::Ownership owner,
AbstractMetaArgument *arg)
{
writeOwnershipForContainer(s, owner, arg->type(), arg->argumentName());
}
static FunctionModificationList get_function_modifications_for_class_hierarchy(const AbstractMetaFunction *java_function)
{
FunctionModificationList mods;
const AbstractMetaClass *cls = java_function->implementingClass();
while (cls != 0) {
mods += java_function->modifications(cls);
if (cls == cls->baseClass())
break;
cls = cls->baseClass();
}
return mods;
}
void JavaGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaFunction *java_function,
CodeSnip::Position position)
{
FunctionModificationList mods = get_function_modifications_for_class_hierarchy(java_function);
foreach (FunctionModification mod, mods) {
if (mod.snips.count() <= 0)
continue ;
foreach (CodeSnip snip, mod.snips) {
if (snip.position != position)
continue ;
if (snip.language != TypeSystem::TargetLangCode)
continue ;
QString code;
QTextStream tmpStream(&code);
snip.formattedCode(tmpStream, INDENT);
ArgumentMap map = snip.argumentMap;
ArgumentMap::iterator it = map.begin();
for (;it!=map.end();++it) {
int pos = it.key() - 1;
QString meta_name = it.value();
if (pos >= 0 && pos < java_function->arguments().count()) {
code = code.replace(meta_name, java_function->arguments().at(pos)->argumentName());
} else {
QString debug = QString("argument map specifies invalid argument index %1"
"for function '%2'")
.arg(pos + 1).arg(java_function->name());
ReportHandler::warning(debug);
}
}
s << code << endl;
}
}
}
void JavaGenerator::writeJavaCallThroughContents(QTextStream &s, const AbstractMetaFunction *java_function, uint attributes)
{
writeInjectedCode(s, java_function, CodeSnip::Beginning);
if (java_function->implementingClass()->isQObject()
&& !java_function->isStatic()
&& !java_function->isConstructor()
&& java_function->name() != QLatin1String("thread")
&& java_function->name() != QLatin1String("disposeLater")) {
s << INDENT << "com.trolltech.qt.GeneratorUtilities.threadCheck(this);" << endl;
}
AbstractMetaArgumentList arguments = java_function->arguments();
if (!java_function->isConstructor()) {
TypeSystem::Ownership owner = java_function->ownership(java_function->implementingClass(), TypeSystem::TargetLangCode, -1);
if (owner != TypeSystem::InvalidOwnership)
s << INDENT << "this." << function_call_for_ownership(owner) << ";" << endl;
}
for (int i=0; itype();
if (!java_function->argumentRemoved(i+1)) {
TypeSystem::Ownership owner = java_function->ownership(java_function->implementingClass(), TypeSystem::TargetLangCode, i+1);
if (owner != TypeSystem::InvalidOwnership) {
s << INDENT << "if (" << arg->argumentName() << " != null) {" << endl;
{
Indentation indent(INDENT);
if (arg->type()->isContainer())
writeOwnershipForContainer(s, owner, arg);
else
s << INDENT << arg->argumentName() << "." << function_call_for_ownership(owner) << ";" << endl;
}
s << INDENT << "}" << endl;
}
if (type->isArray()) {
s << INDENT << "if (" << arg->argumentName() << ".length != " << type->arrayElementCount() << ")" << endl
<< INDENT << " " << "throw new IllegalArgumentException(\"Wrong number of elements in array. Found: \" + "
<< arg->argumentName() << ".length + \", expected: " << type->arrayElementCount() << "\");"
<< endl << endl;
}
if (type->isEnum()) {
EnumTypeEntry *et = (EnumTypeEntry *) type->typeEntry();
if (et->forceInteger()) {
if (!et->lowerBound().isEmpty()) {
s << INDENT << "if (" << arg->argumentName() << " < " << et->lowerBound() << ")" << endl
<< INDENT << " throw new IllegalArgumentException(\"Argument " << arg->argumentName()
<< " is less than lowerbound " << et->lowerBound() << "\");" << endl;
}
if (!et->upperBound().isEmpty()) {
s << INDENT << "if (" << arg->argumentName() << " > " << et->upperBound() << ")" << endl
<< INDENT << " throw new IllegalArgumentException(\"Argument " << arg->argumentName()
<< " is greated than upperbound " << et->upperBound() << "\");" << endl;
}
}
}
}
}
if (!java_function->isConstructor() && !java_function->isStatic()) {
s << INDENT << "if (nativeId() == 0)" << endl
<< INDENT << " throw new QNoNativeResourcesException(\"Function call on incomplete object of type: \" +getClass().getName());" << endl;
}
for (int i=0; inullPointersDisabled(java_function->implementingClass(), i + 1)) {
s << INDENT << "if (" << arguments.at(i)->argumentName() << " == null)" << endl
<< INDENT << " throw new NullPointerException(\"Argument '" << arguments.at(i)->argumentName() << "': null not expected.\");" << endl;
}
}
QList referenceCounts;
for (int i=0; ireferenceCounts(java_function->implementingClass(),
i == 0 ? -1 : i);
foreach (ReferenceCount refCount, referenceCounts)
writeReferenceCount(s, refCount, i == 0 ? "this" : arguments.at(i-1)->argumentName());
}
referenceCounts = java_function->referenceCounts(java_function->implementingClass(), 0);
AbstractMetaType *return_type = java_function->type();
QString new_return_type = QString(java_function->typeReplaced(0)).replace('$', '.');
bool has_return_type = new_return_type != "void"
&& (!new_return_type.isEmpty() || return_type != 0);
TypeSystem::Ownership owner = java_function->ownership(java_function->implementingClass(), TypeSystem::TargetLangCode, 0);
bool has_code_injections_at_the_end = false;
FunctionModificationList mods = get_function_modifications_for_class_hierarchy(java_function);
foreach (FunctionModification mod, mods) {
foreach (CodeSnip snip, mod.snips) {
if (snip.position == CodeSnip::End && snip.language == TypeSystem::TargetLangCode) {
has_code_injections_at_the_end = true;
break;
}
}
}
bool needs_return_variable = has_return_type
&& (owner != TypeSystem::InvalidOwnership || referenceCounts.size() > 0 || has_code_injections_at_the_end);
s << INDENT;
if (has_return_type && java_function->argumentReplaced(0).isEmpty()) {
if (needs_return_variable) {
if (new_return_type.isEmpty())
s << translateType(return_type, java_function->implementingClass());
else
s << new_return_type;
s << " __qt_return_value = ";
} else {
s << "return ";
}
if (return_type && return_type->isTargetLangEnum()) {
s << ((EnumTypeEntry *) return_type->typeEntry())->qualifiedTargetLangName() << ".resolve(";
} else if (return_type && return_type->isTargetLangFlags()) {
s << "new " << return_type->typeEntry()->qualifiedTargetLangName() << "(";
}
}
bool useJumpTable = java_function->jumpTableId() != -1;
if (useJumpTable) {
// The native function returns the correct type, we only have
// java.lang.Object so we may have to cast...
QString signature = JumpTablePreprocessor::signature(java_function);
// printf("return: %s::%s return=%p, replace-value=%s, replace-type=%s signature: %s\n",
// qPrintable(java_function->ownerClass()->name()),
// qPrintable(java_function->signature()),
// return_type,
// qPrintable(java_function->argumentReplaced(0)),
// qPrintable(new_return_type),
// qPrintable(signature));
if (has_return_type && signature.at(0) == 'L') {
if (new_return_type.length() > 0) {
// printf(" ---> replace-type: %s\n", qPrintable(new_return_type));
s << "(" << new_return_type << ") ";
} else if (java_function->argumentReplaced(0).isEmpty()) {
// printf(" ---> replace-value\n");
s << "(" << translateType(return_type, java_function->implementingClass()) << ") ";
}
}
s << "JTbl." << JumpTablePreprocessor::signature(java_function) << "("
<< java_function->jumpTableId() << ", ";
// Constructors and static functions don't have native id, but
// the functions expect them anyway, hence add '0'. Normal
// functions get their native ids added just below...
if (java_function->isConstructor() || java_function->isStatic())
s << "0, ";
} else {
if (attributes & SuperCall) {
s << "super.";
}
s << java_function->marshalledName() << "(";
}
if (!java_function->isConstructor() && !java_function->isStatic())
s << "nativeId()";
for (int i=0; itype();
if (!java_function->argumentRemoved(i+1)) {
if (i > 0 || (!java_function->isStatic() && !java_function->isConstructor()))
s << ", ";
if (type->isTargetLangEnum() || type->isTargetLangFlags()) {
s << arg->argumentName() << ".value()";
} else if (!type->hasNativeId()) {
s << arg->argumentName();
} else {
bool force_abstract = type->typeEntry()->isComplex() && (((static_cast(type->typeEntry()))->typeFlags() & ComplexTypeEntry::ForceAbstract) != 0);
if (!force_abstract) {
s << arg->argumentName() << " == null ? 0 : ";
} // else if (value type is abstract) then we will get a null pointer exception, which is all right
s << arg->argumentName() << ".nativeId()";
}
}
}
if (useJumpTable) {
if ((!java_function->isConstructor() && !java_function->isStatic()) || arguments.size() > 0)
s << ", ";
if (java_function->isStatic())
s << "null";
else
s << "this";
}
s << ")";
if ( !java_function->argumentReplaced(0).isEmpty() ) {
s << ";" << endl;
s << INDENT << "return " << java_function->argumentReplaced(0) << ";" << endl;
return;
}
if (return_type && (return_type->isTargetLangEnum() || return_type->isTargetLangFlags()))
s << ")";
foreach (ReferenceCount referenceCount, referenceCounts) {
writeReferenceCount(s, referenceCount, "__qt_return_value");
}
s << ";" << endl;
writeInjectedCode(s, java_function, CodeSnip::End);
if (needs_return_variable) {
if (owner != TypeSystem::InvalidOwnership) {
s << INDENT << "if (__qt_return_value != null) {" << endl;
if (return_type->isContainer())
writeOwnershipForContainer(s, owner, return_type, "__qt_return_value");
else
s << INDENT << " __qt_return_value." << function_call_for_ownership(owner) << ";" << endl;
s << INDENT << "}" << endl;
}
s << INDENT << "return __qt_return_value;" << endl;
}
if (java_function->isConstructor()) {
TypeSystem::Ownership owner = java_function->ownership(java_function->implementingClass(), TypeSystem::TargetLangCode, -1);
if (owner != TypeSystem::InvalidOwnership && java_function->isConstructor())
s << INDENT << "this." << function_call_for_ownership(owner) << ";" << endl;
}
}
void JavaGenerator::writeSignal(QTextStream &s, const AbstractMetaFunction *java_function)
{
Q_ASSERT(java_function->isSignal());
if (java_function->isModifiedRemoved(TypeSystem::TargetLangCode))
return ;
AbstractMetaArgumentList arguments = java_function->arguments();
int sz = arguments.count();
QString signalTypeName("Signal");
if (java_function->isPrivate()) {
signalTypeName = "PrivateSignal";
}
signalTypeName += QString::number(sz);
if (sz > 0) {
signalTypeName += "<";
for (int i=0; i 0)
signalTypeName += ", ";
QString modifiedType = java_function->typeReplaced(i+1);
if (modifiedType.isEmpty())
signalTypeName += translateType(arguments.at(i)->type(), java_function->implementingClass(), BoxedPrimitive);
else
signalTypeName += modifiedType;
}
signalTypeName += ">";
}
int exclude_attributes = AbstractMetaAttributes::Abstract
| AbstractMetaAttributes::Native;
int include_attributes = AbstractMetaAttributes::Public;
QString signalName = java_function->name();
FunctionModificationList mods = java_function->modifications(java_function->implementingClass());
foreach (FunctionModification mod, mods) {
if (mod.isAccessModifier()) {
exclude_attributes |= AbstractMetaAttributes::Public
| AbstractMetaAttributes::Protected
| AbstractMetaAttributes::Private
| AbstractMetaAttributes::Friendly;
include_attributes &= ~(exclude_attributes);
if (mod.isPublic())
include_attributes |= AbstractMetaAttributes::Public;
else if (mod.isProtected())
include_attributes |= AbstractMetaAttributes::Protected;
else if (mod.isPrivate())
include_attributes |= AbstractMetaAttributes::Private;
else if (mod.isFriendly())
include_attributes |= AbstractMetaAttributes::Friendly;
exclude_attributes &= ~(include_attributes);
}
}
// Insert Javadoc
if (m_doc_parser) {
QString signature = functionSignature(java_function,
include_attributes | NoBlockedSlot,
exclude_attributes);
QString docs = m_doc_parser->documentationForSignal(signature);
if (docs.isEmpty()) {
signature.replace(QLatin1String("public"), QLatin1String("protected"));
docs = m_doc_parser->documentationForSignal(signature);
}
s << m_doc_parser->documentationForSignal(signature);
}
writeFunctionAttributes(s, java_function, include_attributes, exclude_attributes,
SkipReturnType);
s << signalTypeName;
s << " " << signalName << " = new " << signalTypeName << "();" << endl;
// We don't write out the functions for private signals, because they cannot
// be emitted, hence they will never be used...
if (!java_function->isPrivate())
writeFunction(s, java_function,
AbstractMetaAttributes::Private,
AbstractMetaAttributes::Visibility & ~AbstractMetaAttributes::Private);
}
void JavaGenerator::retrieveModifications(const AbstractMetaFunction *java_function,
const AbstractMetaClass *java_class,
uint *exclude_attributes,
uint *include_attributes) const
{
FunctionModificationList mods = java_function->modifications(java_class);
// printf("name: %s has %d mods\n", qPrintable(java_function->signature()), mods.size());
foreach (FunctionModification mod, mods) {
if (mod.isAccessModifier()) {
// printf(" -> access mod to %x\n", mod.modifiers);
*exclude_attributes |= AbstractMetaAttributes::Public
| AbstractMetaAttributes::Protected
| AbstractMetaAttributes::Private
| AbstractMetaAttributes::Friendly;
if (mod.isPublic())
*include_attributes |= AbstractMetaAttributes::Public;
else if (mod.isProtected())
*include_attributes |= AbstractMetaAttributes::Protected;
else if (mod.isPrivate())
*include_attributes |= AbstractMetaAttributes::Private;
else if (mod.isFriendly())
*include_attributes |= AbstractMetaAttributes::Friendly;
}
if (mod.isFinal()) {
*include_attributes |= AbstractMetaAttributes::FinalInTargetLang;
} else if (mod.isNonFinal()) {
*exclude_attributes |= AbstractMetaAttributes::FinalInTargetLang;
}
}
*exclude_attributes &= ~(*include_attributes);
}
QString JavaGenerator::functionSignature(const AbstractMetaFunction *java_function,
uint included_attributes, uint excluded_attributes,
Option option,
int arg_count)
{
AbstractMetaArgumentList arguments = java_function->arguments();
int argument_count = arg_count < 0 ? arguments.size() : arg_count;
QString result;
QTextStream s(&result);
QString functionName = java_function->name();
// The actual function
if (!(java_function->isEmptyFunction() || java_function->isNormal() || java_function->isSignal()))
option = Option(option | SkipReturnType);
writeFunctionAttributes(s, java_function, included_attributes, excluded_attributes, option);
s << functionName << "(";
writeFunctionArguments(s, java_function, argument_count, option);
s << ")";
return result;
}
void JavaGenerator::setupForFunction(const AbstractMetaFunction *java_function,
uint *included_attributes,
uint *excluded_attributes) const
{
*excluded_attributes |= java_function->ownerClass()->isInterface() || java_function->isConstructor()
? AbstractMetaAttributes::Native | AbstractMetaAttributes::Final
: 0;
if (java_function->ownerClass()->isInterface())
*excluded_attributes |= AbstractMetaAttributes::Abstract;
if (java_function->needsCallThrough())
*excluded_attributes |= AbstractMetaAttributes::Native;
const AbstractMetaClass *java_class = java_function->ownerClass();
retrieveModifications(java_function, java_class, excluded_attributes, included_attributes);
}
void JavaGenerator::writeReferenceCount(QTextStream &s, const ReferenceCount &refCount,
const QString &argumentName)
{
if (refCount.action == ReferenceCount::Ignore)
return;
QString refCountVariableName = refCount.variableName;
if (!refCount.declareVariable.isEmpty() && refCount.action != ReferenceCount::Set) {
s << INDENT << "java.util.Collection