size_t CLSSource::parseFunction(std::string& src, size_t start){ Function* function = new Function(); function->source = this; size_t i = src.find_first_of(" \t\n", start); i = src.find_first_not_of(" \t\n", i+1); size_t j = src.find_first_of(" \t\n(", i+1); function->name = src.substr(i, j-i); i = src.find_first_of("{", i); function->signature = src.substr(start, i-start); j = i+1; bool found = false; int scope = 0; while (!found) { if (src[j] == '{') { scope++; } if (src[j] == '}') { if (scope == 0) { found = true; }else{ scope--; } } j++; } function->block = src.substr(i, j-i); parseSignature(function); m_functions[function->name] = function; return j+1; }
static QValueList<QDBusData> parseSignature(QCString& signature) { // qDebug("parseSignature(%s)", signature.data()); QValueList<QDBusData> result; while (!signature.isEmpty()) { switch (signature[0]) { case '(': { signature = signature.mid(1); QValueList<QDBusData> memberList = parseSignature(signature); result << QDBusData::fromStruct(memberList); Q_ASSERT(!signature.isEmpty() && signature[0] == ')'); signature = signature.mid(1); break; } case ')': return result; case '{': { QDBusData::Type keyType = qSingleTypeForDBusSignature(signature[1]); QDBusData::Type valueType = qSingleTypeForDBusSignature(signature[2]); if (valueType != QDBusData::Invalid) { switch (keyType) { case QDBusData::Byte: result << QDBusData::fromByteKeyMap( QDBusDataMap<Q_UINT8>(valueType)); break; case QDBusData::Int16: result << QDBusData::fromInt16KeyMap( QDBusDataMap<Q_INT16>(valueType)); break; case QDBusData::UInt16: result << QDBusData::fromUInt16KeyMap( QDBusDataMap<Q_UINT16>(valueType)); break; case QDBusData::Int32: result << QDBusData::fromInt32KeyMap( QDBusDataMap<Q_INT32>(valueType)); break; case QDBusData::UInt32: result << QDBusData::fromUInt32KeyMap( QDBusDataMap<Q_UINT32>(valueType)); break; case QDBusData::Int64: result << QDBusData::fromInt64KeyMap( QDBusDataMap<Q_INT64>(valueType)); break; case QDBusData::UInt64: result << QDBusData::fromUInt64KeyMap( QDBusDataMap<Q_UINT64>(valueType)); break; case QDBusData::String: result << QDBusData::fromStringKeyMap( QDBusDataMap<QString>(valueType)); break; case QDBusData::ObjectPath: result << QDBusData::fromObjectPathKeyMap( QDBusDataMap<QDBusObjectPath>(valueType)); break; default: qWarning("QDBusMarshall: unsupported map key type %s " "at de-marshalling", QDBusData::typeName(keyType)); break; } signature = signature.mid(3); } else { signature = signature.mid(2); QValueList<QDBusData> valueContainer = parseSignature(signature); Q_ASSERT(valueContainer.count() == 1); switch (keyType) { case QDBusData::Byte: result << QDBusData::fromByteKeyMap( QDBusDataMap<Q_UINT8>(valueContainer[0])); break; case QDBusData::Int16: result << QDBusData::fromInt16KeyMap( QDBusDataMap<Q_INT16>(valueContainer[0])); break; case QDBusData::UInt16: result << QDBusData::fromUInt16KeyMap( QDBusDataMap<Q_UINT16>(valueContainer[0])); break; case QDBusData::Int32: result << QDBusData::fromInt32KeyMap( QDBusDataMap<Q_INT32>(valueContainer[0])); break; case QDBusData::UInt32: result << QDBusData::fromUInt32KeyMap( QDBusDataMap<Q_UINT32>(valueContainer[0])); break; case QDBusData::Int64: result << QDBusData::fromInt64KeyMap( QDBusDataMap<Q_INT64>(valueContainer[0])); break; case QDBusData::UInt64: result << QDBusData::fromUInt64KeyMap( QDBusDataMap<Q_UINT64>(valueContainer[0])); break; case QDBusData::String: result << QDBusData::fromStringKeyMap( QDBusDataMap<QString>(valueContainer[0])); break; case QDBusData::ObjectPath: result << QDBusData::fromObjectPathKeyMap( QDBusDataMap<QDBusObjectPath>(valueContainer[0])); break; default: qWarning("QDBusMarshall: unsupported map key type %s " "at de-marshalling", QDBusData::typeName(keyType)); break; } } Q_ASSERT(!signature.isEmpty() && signature[0] == '}'); signature = signature.mid(1); break; } case '}': return result; case 'a': { QDBusData::Type elementType = qSingleTypeForDBusSignature(signature[1]); if (elementType != QDBusData::Invalid) { QDBusDataList list(elementType); result << QDBusData::fromList(list); signature = signature.mid(2); } else { signature = signature.mid(1); bool array = signature[0] != '{'; QValueList<QDBusData> elementContainer = parseSignature(signature); Q_ASSERT(elementContainer.count() == 1); if (array) { QDBusDataList list(elementContainer[0]); result << QDBusData::fromList(list); } else result << elementContainer[0]; } break; } default: result << QDBusData(); signature = signature.mid(1); break; } } return result; }
static QDBusData qFetchParameter(DBusMessageIter *it) { switch (dbus_message_iter_get_arg_type(it)) { case DBUS_TYPE_BOOLEAN: return QDBusData::fromBool(qIterGet<dbus_bool_t>(it)); case DBUS_TYPE_BYTE: return QDBusData::fromByte(qIterGet<unsigned char>(it)); case DBUS_TYPE_INT16: return QDBusData::fromInt16(qIterGet<dbus_int16_t>(it)); case DBUS_TYPE_UINT16: return QDBusData::fromUInt16(qIterGet<dbus_uint16_t>(it)); case DBUS_TYPE_INT32: return QDBusData::fromInt32(qIterGet<dbus_int32_t>(it)); case DBUS_TYPE_UINT32: return QDBusData::fromUInt32(qIterGet<dbus_uint32_t>(it)); case DBUS_TYPE_INT64: return QDBusData::fromInt64(qIterGet<dbus_int64_t>(it)); case DBUS_TYPE_UINT64: return QDBusData::fromUInt64(qIterGet<dbus_uint64_t>(it)); case DBUS_TYPE_DOUBLE: return QDBusData::fromDouble(qIterGet<double>(it)); case DBUS_TYPE_STRING: case DBUS_TYPE_SIGNATURE: return QDBusData::fromString(QString::fromUtf8(qIterGet<char *>(it))); case DBUS_TYPE_OBJECT_PATH: return QDBusData::fromObjectPath(QDBusObjectPath(qIterGet<char *>(it))); case DBUS_TYPE_ARRAY: { int arrayType = dbus_message_iter_get_element_type(it); char* sig = dbus_message_iter_get_signature(it); QCString signature = sig; dbus_free(sig); QValueList<QDBusData> prototypeList = parseSignature(signature); if (arrayType == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter sub; dbus_message_iter_recurse(it, &sub); return qFetchMap(&sub, prototypeList[0]); // } else if (arrayType == DBUS_TYPE_BYTE) { // DBusMessageIter sub; // dbus_message_iter_recurse(it, &sub); // int len = dbus_message_iter_get_array_len(&sub); // char* data; // dbus_message_iter_get_fixed_array(&sub,&data,&len); // return QCString(data,len); // } else { } else { QDBusDataList list = prototypeList[0].toList(); DBusMessageIter arrayIt; dbus_message_iter_recurse(it, &arrayIt); while (dbus_message_iter_get_arg_type(&arrayIt) != DBUS_TYPE_INVALID) { list << qFetchParameter(&arrayIt); dbus_message_iter_next(&arrayIt); } return QDBusData::fromList(list); } } case DBUS_TYPE_VARIANT: { QDBusVariant dvariant; DBusMessageIter sub; dbus_message_iter_recurse(it, &sub); char* signature = dbus_message_iter_get_signature(&sub); dvariant.signature = QString::fromUtf8(signature); dbus_free(signature); dvariant.value = qFetchParameter(&sub); return QDBusData::fromVariant(dvariant); } case DBUS_TYPE_STRUCT: { QValueList<QDBusData> memberList; DBusMessageIter subIt; dbus_message_iter_recurse(it, &subIt); uint index = 0; while (dbus_message_iter_get_arg_type(&subIt) != DBUS_TYPE_INVALID) { memberList << qFetchParameter(&subIt); dbus_message_iter_next(&subIt); ++index; } return QDBusData::fromStruct(memberList); } #if 0 case DBUS_TYPE_INVALID: // TODO: check if there is better way to detect empty arrays return QDBusData(); break; #endif default: qWarning("QDBusMarshall: Don't know how to de-marshall type %d '%c'", dbus_message_iter_get_arg_type(it), dbus_message_iter_get_arg_type(it)); return QDBusData(); break; } }
RSourceIndex::RSourceIndex(const std::string& context, const std::string& code) : context_(context) { // convert code to wide std::wstring wCode = string_utils::utf8ToWide(code, context); // determine where the linebreaks are and initialize an iterator // used for scanning them std::vector<std::size_t> newlineLocs; std::size_t nextNL = 0; while ( (nextNL = wCode.find(L'\n', nextNL)) != std::string::npos ) newlineLocs.push_back(nextNL++); std::vector<std::size_t>::const_iterator newlineIter = newlineLocs.begin(); std::vector<std::size_t>::const_iterator endNewlines = newlineLocs.end(); // tokenize RTokens rTokens(wCode, RTokens::StripWhitespace | RTokens::StripComments); // scan for function, method, and class definitions (track indent level) int braceLevel = 0; std::wstring function(L"function"); std::wstring set(L"set"); std::wstring setGeneric(L"setGeneric"); std::wstring setGroupGeneric(L"setGroupGeneric"); std::wstring setMethod(L"setMethod"); std::wstring setClass(L"setClass"); std::wstring setClassUnion(L"setClassUnion"); std::wstring setRefClass(L"setRefClass"); std::wstring eqOp(L"="); std::wstring assignOp(L"<-"); std::wstring parentAssignOp(L"<<-"); for (std::size_t i=0; i<rTokens.size(); i++) { // initial name, qualifer, and type are nil RSourceItem::Type type = RSourceItem::None; std::wstring name; std::size_t tokenOffset = -1; bool isSetMethod = false; std::vector<RS4MethodParam> signature; // alias the token const RToken& token = rTokens.at(i); // see if this is a begin or end brace and update the level if (token.type() == RToken::LBRACE) { braceLevel++; continue; } else if (token.type() == RToken::RBRACE) { braceLevel--; continue; } // bail for non-identifiers else if (token.type() != RToken::ID) { continue; } // is this a potential method or class definition? if (token.contentStartsWith(set)) { RSourceItem::Type setType = RSourceItem::None; if (token.contentEquals(setMethod)) { isSetMethod = true; setType = RSourceItem::Method; } else if (token.contentEquals(setGeneric) || token.contentEquals(setGroupGeneric)) { setType = RSourceItem::Method; } else if (token.contentEquals(setClass) || token.contentEquals(setClassUnion) || token.contentEquals(setRefClass)) { setType = RSourceItem::Class; } else { continue; } // make sure there are at least 4 more tokens if ( (i + 3) >= rTokens.size()) continue; // check for the rest of the token sequene for a valid call to set* if ( (rTokens.at(i+1).type() != RToken::LPAREN) || (rTokens.at(i+2).type() != RToken::STRING) || (rTokens.at(i+3).type() != RToken::COMMA)) continue; // found a class or method definition (will find location below) type = setType; name = removeQuoteDelims(rTokens.at(i+2).content()); tokenOffset = token.offset(); // if this was a setMethod then try to lookahead for the signature if (isSetMethod) { parseSignature(rTokens.begin() + (i+4), rTokens.end(), &signature); } } // is this a function? else if (token.contentEquals(function)) { // if there is no room for an operator and identifier prior // to the function then bail if (i < 2) continue; // check for an assignment operator const RToken& opToken = rTokens.at(i-1); if ( opToken.type() != RToken::OPER) continue; if (!opToken.isOperator(eqOp) && !opToken.isOperator(assignOp) && !opToken.isOperator(parentAssignOp)) continue; // check for an identifier const RToken& idToken = rTokens.at(i-2); if ( idToken.type() != RToken::ID ) continue; // if there is another previous token make sure it isn't a // comma or an open paren if ( i > 2 ) { const RToken& prevToken = rTokens.at(i-3); if (prevToken.type() == RToken::LPAREN || prevToken.type() == RToken::COMMA) continue; } // if we got this far then this is a function definition type = RSourceItem::Function; name = idToken.content(); tokenOffset = idToken.offset(); } else { continue; } // compute the line by starting at the current line index and // finding the first newline which is after the idToken offset newlineIter = std::upper_bound(newlineIter, endNewlines, tokenOffset); std::size_t line = newlineIter - newlineLocs.begin() + 1; // compute column by comparing the offset to the PREVIOUS newline // (guard against no previous newline) std::size_t column; if (line > 1) column = tokenOffset - *(newlineIter - 1); else column = tokenOffset; // add to index items_.push_back(RSourceItem(type, string_utils::wideToUtf8(name), signature, braceLevel, line, column)); } }
JMethodCaller::JMethodCaller(const std::string& method) { parseSignature(method); }
JMethodCaller::JMethodCaller(const std::string& clazz, const std::string& method) : m_isValid(false), m_static(false) { m_clazz = clazz; parseSignature(method); }