idl工具支持解析cacheable关键字,生成sa支持proxy侧IPC缓存机制代码合入到idl_tool_2目录

Signed-off-by: 郭凡锋 <guofanfeng@huawei.com>
This commit is contained in:
guofanfeng 2024-05-22 10:14:44 +08:00
parent 929d5c81e4
commit 821058f85a
37 changed files with 1629 additions and 60 deletions

View File

@ -213,6 +213,16 @@ public:
return interfaceDefs_;
}
bool GetHasCacheableProxyMethods() const
{
return hasCacheableProxyMethods_;
}
void SetHasCacheableProxyMethods(bool cacheable)
{
hasCacheableProxyMethods_ = cacheable;
}
private:
AutoPtr<ASTNamespace> NewNameSpace(std::string nameSpace);
@ -233,6 +243,7 @@ private:
static TypeStringMap basicTypes_;
std::string idlFilePath_;
bool hasCacheableProxyMethods_ = false;
};
} // namespace Idl
} // namespace OHOS

View File

@ -99,5 +99,18 @@ std::string ASTParamAttr::Dump(const std::string &prefix)
{
return prefix + ToString();
}
bool ASTAttr::CacheableStrToInt()
{
if (!HasValue(ASTAttr::CACHEABLE)) {
return false;
}
try {
cacheableTime_ = static_cast<int32_t>(std::stoi(cacheableTimeString_));
} catch(...) {
return false;
}
return true;
}
} // namespace Idl
} // namespace OHOS

View File

@ -29,6 +29,7 @@ public:
static constexpr Attribute FULL = 0x1U << 2;
static constexpr Attribute ONEWAY = 0x1U << 3;
static constexpr Attribute CALLBACK = 0x1U << 4;
static constexpr Attribute CACHEABLE = 0x1U << 5;
explicit ASTAttr(Attribute value = ASTAttr::NONE) : value_(value) {}
@ -58,8 +59,27 @@ public:
bool Match(SystemLevel level) const;
int32_t GetCacheableTime()
{
return cacheableTime_;
}
std::string& GetCacheableTimeString()
{
return cacheableTimeString_;
}
void SetCacheableTimeString(const std::string &timeStr)
{
cacheableTimeString_ = timeStr;
}
bool CacheableStrToInt();
private:
Attribute value_;
int32_t cacheableTime_ = 0;
std::string cacheableTimeString_;
};
class ASTParamAttr : public ASTNode {

View File

@ -113,6 +113,28 @@ public:
std::string Dump(const std::string &prefix) override;
void SetCacheable(AutoPtr<ASTAttr> attr)
{
if (attr->HasValue(ASTAttr::CACHEABLE)) {
attr_->SetValue(ASTAttr::CACHEABLE);
attr_->SetCacheableTimeString(attr->GetCacheableTimeString());
}
}
bool SetCacheableTime()
{
return attr_->CacheableStrToInt();
}
int32_t GetCacheableTime()
{
return attr_->GetCacheableTime();
}
bool GetCacheable()
{
return attr_->HasValue(ASTAttr::CACHEABLE);
}
private:
void BuildSignature();

View File

@ -38,6 +38,9 @@ void SaCppClientProxyCodeEmitter::EmitInterfaceProxyHeaderFile()
sb.Append("\n");
sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).c_str());
sb.Append("#include <iremote_proxy.h>\n");
if ((ast_ != nullptr) && (ast_->GetHasCacheableProxyMethods() == true)) {
sb.Append("#include \"api_cache_manager.h\"\n");
}
sb.Append("\n");
EmitInterfaceProxyInHeaderFile(sb);
EmitTailMacro(sb, proxyFullName_);
@ -63,15 +66,103 @@ void SaCppClientProxyCodeEmitter::EmitInterfaceProxyInHeaderFile(StringBuilder &
EmitEndNamespace(sb);
}
void SaCppClientProxyCodeEmitter::EmitInterfaceProxyRegisterDeathRecipient(StringBuilder &sb,
const std::string &prefix) const
{
sb.Append(prefix).Append("if (remote != nullptr) {\n");
sb.Append(prefix + TAB).Append("if (!remote->IsProxyObject()) {\n");
if (logOn_) {
sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"remote is not proxy object!\");\n");
}
sb.Append(prefix + TAB + TAB).Append("return;\n");
sb.Append(prefix + TAB).Append("}\n");
sb.Append(prefix + TAB).AppendFormat("deathRecipient_ = new (std::nothrow) %s(*this);\n",
deathRecipientName_.c_str());
sb.Append(prefix + TAB).Append("if (deathRecipient_ == nullptr) {\n");
if (logOn_) {
sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"deathRecipient_ is nullptr!\");\n");
}
sb.Append(prefix + TAB + TAB).Append("return;\n");
sb.Append(prefix + TAB).Append("}\n");
sb.Append(prefix + TAB).Append("if (!remote->AddDeathRecipient(deathRecipient_)) {\n");
if (logOn_) {
sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"AddDeathRecipient failed!\");\n");
}
sb.Append(prefix + TAB + TAB).Append("return;\n");
sb.Append(prefix + TAB).Append("}\n");
sb.Append(prefix + TAB).Append("remote_ = remote;\n");
sb.Append(prefix).Append("}\n");
}
void SaCppClientProxyCodeEmitter::EmitInterfaceProxyAddCacheAbleAPI(StringBuilder &sb, const std::string &prefix) const
{
sb.Append(prefix).Append("{\n");
int methodNumber = interface_->GetMethodNumber();
for (int i = 0; i < methodNumber; i++) {
AutoPtr<ASTMethod> method = interface_->GetMethod(i);
if (!method->GetCacheable() || method->IsOneWay()) {
continue;
}
int32_t cacheableTime = method->GetCacheableTime();
if (cacheableTime != 0) {
sb.Append(prefix + TAB).AppendFormat(
"ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(), COMMAND_%s, %d000);\n",
ConstantName(method->GetName()).c_str(), cacheableTime);
} else {
sb.Append(prefix + TAB).AppendFormat(
"ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(), COMMAND_%s, 0);\n",
ConstantName(method->GetName()).c_str());
}
}
sb.Append("\n");
EmitInterfaceProxyRegisterDeathRecipient(sb, prefix + TAB);
sb.Append(prefix).Append("}\n");
}
void SaCppClientProxyCodeEmitter::EmitInterfaceProxyUnRegisterDeathRecipient(StringBuilder &sb,
const std::string &prefix) const
{
sb.Append(prefix).Append("{\n");
sb.Append(prefix + TAB).Append("if (remote_ == nullptr) {\n");
sb.Append(prefix + TAB).Append(TAB).Append("return;\n");
sb.Append(prefix + TAB).Append("}\n");
sb.Append(prefix + TAB).Append("if (deathRecipient_ == nullptr) {\n");
sb.Append(prefix + TAB).Append(TAB).Append("return;\n");
sb.Append(prefix + TAB).Append("}\n");
sb.Append(prefix + TAB).Append("remote_->RemoveDeathRecipient(deathRecipient_);\n");
sb.Append(prefix + TAB).Append("remote_ = nullptr;\n");
int methodNumber = interface_->GetMethodNumber();
if (methodNumber > 0) {
sb.Append("\n");
for (int i = 0; i < methodNumber; i++) {
AutoPtr<ASTMethod> method = interface_->GetMethod(i);
if (method->GetCacheable() && !method->IsOneWay()) {
sb.Append(prefix + TAB).AppendFormat(
"ApiCacheManager::GetInstance().DelCacheApi(GetDescriptor(), COMMAND_%s);\n",
ConstantName(method->GetName()).c_str());
}
}
}
sb.Append(prefix).Append("}\n");
}
void SaCppClientProxyCodeEmitter::EmitInterfaceProxyConstructor(StringBuilder &sb, const std::string &prefix) const
{
sb.Append(prefix).AppendFormat("explicit %s(\n", proxyName_.c_str());
sb.Append(prefix + TAB).Append("const sptr<IRemoteObject>& remote)\n");
sb.Append(prefix + TAB).AppendFormat(": IRemoteProxy<%s>(remote)\n", interfaceName_.c_str());
sb.Append(prefix).Append("{}\n");
if (ast_->GetHasCacheableProxyMethods()) {
EmitInterfaceProxyAddCacheAbleAPI(sb, prefix);
} else {
sb.Append(prefix).Append("{}\n");
}
sb.Append("\n");
sb.Append(prefix).AppendFormat("virtual ~%s()\n", proxyName_.c_str());
sb.Append(prefix).Append("{}\n");
if (ast_->GetHasCacheableProxyMethods()) {
EmitInterfaceProxyUnRegisterDeathRecipient(sb, prefix);
} else {
sb.Append(prefix).Append("{}\n");
}
}
void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodDecls(StringBuilder &sb, const std::string &prefix) const
@ -94,8 +185,35 @@ void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodDecl(AutoPtr<ASTMethod
sb.Append(") override;\n");
}
void SaCppClientProxyCodeEmitter::EmitInterfaceProxyDeathRecipient(StringBuilder &sb, const std::string &prefix) const
{
sb.Append(prefix).AppendFormat("class %s : public IRemoteObject::DeathRecipient {\n", deathRecipientName_.c_str());
sb.Append(prefix).Append("public:\n");
sb.Append(prefix + TAB).AppendFormat("explicit %s(%s &client) : client_(client) {}\n", deathRecipientName_.c_str(),
proxyName_.c_str());
sb.Append(prefix + TAB).AppendFormat("~%s() override = default;\n", deathRecipientName_.c_str());
sb.Append(prefix + TAB).Append("void OnRemoteDied(const wptr<IRemoteObject> &remote) override\n");
sb.Append(prefix + TAB).Append("{\n");
sb.Append(prefix + TAB + TAB).Append("client_.OnRemoteDied(remote);\n");
sb.Append(prefix + TAB).Append("}\n");
sb.Append(prefix).Append("private:\n");
sb.Append(prefix + TAB).AppendFormat("%s &client_;\n", proxyName_.c_str());
sb.Append(prefix).Append("};\n\n");
sb.Append(prefix).Append("void OnRemoteDied(const wptr<IRemoteObject> &remoteObject)\n");
sb.Append(prefix).Append("{\n");
sb.Append(prefix + TAB).Append("(void)remoteObject;\n");
sb.Append(prefix + TAB).Append("ApiCacheManager::GetInstance().ClearCache(GetDescriptor());\n");
sb.Append(prefix).Append("}\n");
sb.Append(prefix).Append("sptr<IRemoteObject> remote_ = nullptr;\n");
sb.Append(prefix).Append("sptr<IRemoteObject::DeathRecipient> deathRecipient_ = nullptr;\n");
}
void SaCppClientProxyCodeEmitter::EmitInterfaceProxyConstants(StringBuilder &sb, const std::string &prefix)
{
if (ast_->GetHasCacheableProxyMethods()) {
EmitInterfaceProxyDeathRecipient(sb, prefix);
}
EmitInterfaceMethodCommands(sb, prefix);
sb.Append("\n");
sb.Append(prefix).AppendFormat("static inline BrokerDelegator<%s> delegator_;\n", proxyName_.c_str());
@ -151,6 +269,31 @@ void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodImpl(AutoPtr<ASTMethod
EmitInterfaceProxyMethodBody(method, sb, prefix);
}
void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodPreSendRequest(AutoPtr<ASTMethod> &method, StringBuilder &sb,
const std::string &prefix) const
{
if ((method->GetCacheable()) && (!method->IsOneWay())) {
sb.Append("\n");
sb.Append(prefix + TAB).AppendFormat(
"bool hitCache = ApiCacheManager::GetInstance().PreSendRequest(GetDescriptor(), COMMAND_%s, data, reply);",
ConstantName(method->GetName()).c_str());
sb.Append("\n");
sb.Append(prefix + TAB).Append("if (hitCache == true) {\n");
EmitInterfaceProxyMethodErrCode(sb, prefix + TAB);
EmitInterfaceProxyMethodReply(method, sb, prefix + TAB);
sb.Append(prefix + TAB + TAB).Append("return ERR_OK;\n");
sb.Append(prefix + TAB).Append("}\n");
}
}
void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodPostSendRequest(AutoPtr<ASTMethod> &method, StringBuilder &sb,
const std::string &prefix) const
{
sb.Append(prefix + TAB).AppendFormat(
"ApiCacheManager::GetInstance().PostSendRequest(GetDescriptor(), COMMAND_%s, data, reply);\n",
ConstantName(method->GetName()).c_str());
}
void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodBody(AutoPtr<ASTMethod> &method, StringBuilder &sb,
const std::string &prefix) const
{
@ -179,6 +322,7 @@ void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodBody(AutoPtr<ASTMethod
EmitWriteMethodParameter(param, "data.", sb, prefix + TAB);
}
}
EmitInterfaceProxyMethodPreSendRequest(method, sb, prefix);
sb.Append("\n");
sb.Append(prefix + TAB).Append("sptr<IRemoteObject> remote = Remote();\n");
sb.Append(prefix + TAB).Append("if (remote == nullptr) {\n");
@ -198,31 +342,45 @@ void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodBody(AutoPtr<ASTMethod
EmitInterfaceProxyMethodRetValue(method, sb, prefix);
}
void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodErrCode(StringBuilder &sb, const std::string &prefix) const
{
sb.Append(prefix + TAB).Append("ErrCode errCode = reply.ReadInt32();\n");
sb.Append(prefix + TAB).Append("if (FAILED(errCode)) {\n");
if (logOn_) {
sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"Read Int32 failed!\");\n");
}
sb.Append(prefix + TAB).Append(" return errCode;\n");
sb.Append(prefix + TAB).Append("}\n");
}
void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodReply(AutoPtr<ASTMethod> &method, StringBuilder &sb,
const std::string &prefix) const
{
int paramNumber = method->GetParameterNumber();
for (int i = 0; i < paramNumber; i++) {
AutoPtr<ASTParameter> param = method->GetParameter(i);
if (param->GetAttribute() & ASTParamAttr::PARAM_OUT) {
EmitReadMethodParameter(param, "reply.", false, sb, prefix + TAB);
}
}
AutoPtr<ASTType> returnType = method->GetReturnType();
if (returnType->GetTypeKind() != TypeKind::TYPE_VOID) {
AutoPtr<SaTypeEmitter> typeEmitter = GetTypeEmitter(returnType);
typeEmitter->EmitCppReadVar("reply.", "result", sb, prefix + TAB, false);
}
}
void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodRetValue(AutoPtr<ASTMethod> &method, StringBuilder &sb,
const std::string &prefix) const
{
if (!method->IsOneWay()) {
sb.Append("\n");
sb.Append(prefix + TAB).Append("ErrCode errCode = reply.ReadInt32();\n");
sb.Append(prefix + TAB).Append("if (FAILED(errCode)) {\n");
if (logOn_) {
sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"Read Int32 failed!\");\n");
}
sb.Append(prefix + TAB).Append(" return errCode;\n");
sb.Append(prefix + TAB).Append("}\n");
EmitInterfaceProxyMethodErrCode(sb, prefix);
sb.Append("\n");
int paramNumber = method->GetParameterNumber();
for (int i = 0; i < paramNumber; i++) {
AutoPtr<ASTParameter> param = method->GetParameter(i);
if (param->GetAttribute() & ASTParamAttr::PARAM_OUT) {
EmitReadMethodParameter(param, "reply.", false, sb, prefix + TAB);
}
}
AutoPtr<ASTType> returnType = method->GetReturnType();
if (returnType->GetTypeKind() != TypeKind::TYPE_VOID) {
AutoPtr<SaTypeEmitter> typeEmitter = GetTypeEmitter(returnType);
typeEmitter->EmitCppReadVar("reply.", "result", sb, prefix + TAB, false);
if (method->GetCacheable()) {
EmitInterfaceProxyMethodPostSendRequest(method, sb, prefix);
}
EmitInterfaceProxyMethodReply(method, sb, prefix);
}
sb.Append(prefix + TAB).Append("return ERR_OK;\n");
sb.Append(prefix).Append("}\n");

View File

@ -33,12 +33,20 @@ private:
void EmitInterfaceProxyInHeaderFile(StringBuilder &sb);
void EmitInterfaceProxyRegisterDeathRecipient(StringBuilder &sb, const std::string &prefix) const;
void EmitInterfaceProxyAddCacheAbleAPI(StringBuilder &sb, const std::string &prefix) const;
void EmitInterfaceProxyUnRegisterDeathRecipient(StringBuilder &sb, const std::string &prefix) const;
void EmitInterfaceProxyConstructor(StringBuilder &sb, const std::string &prefix) const;
void EmitInterfaceProxyMethodDecls(StringBuilder &sb, const std::string &prefix) const;
void EmitInterfaceProxyMethodDecl(AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
void EmitInterfaceProxyDeathRecipient(StringBuilder &sb, const std::string &prefix) const;
void EmitInterfaceProxyConstants(StringBuilder &sb, const std::string &prefix);
void EmitInterfaceProxyCppFile();
@ -49,6 +57,17 @@ private:
void EmitInterfaceProxyMethodBody(AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
void EmitInterfaceProxyMethodPreSendRequest(AutoPtr<ASTMethod> &method, StringBuilder &sb,
const std::string &prefix) const;
void EmitInterfaceProxyMethodPostSendRequest(AutoPtr<ASTMethod> &method, StringBuilder &sb,
const std::string &prefix) const;
void EmitInterfaceProxyMethodErrCode(StringBuilder &sb, const std::string &prefix) const;
void EmitInterfaceProxyMethodReply(AutoPtr<ASTMethod> &method, StringBuilder &sb,
const std::string &prefix) const;
void EmitInterfaceProxyMethodRetValue(AutoPtr<ASTMethod> &method, StringBuilder &sb,
const std::string &prefix) const;
};

View File

@ -85,6 +85,8 @@ bool SACodeEmitter::Reset(const AutoPtr<AST> &ast, const std::string &targetDire
stubName_ = baseName_ + "Stub";
stubFullName_ = interface_->GetNamespace()->ToString() + stubName_;
deathRecipientName_ = StringHelper::StartWith(interfaceName_, "I") ? interfaceName_.substr(1) + "Recipient" :
interfaceName_ + "Recipient";
}
if (!ResolveDirectory(targetDirectory)) {

View File

@ -185,7 +185,7 @@ std::string CodeEmitter::FileName(const std::string &name) const
char c = name[i];
if (isupper(c) != 0) {
// 2->Index of the last char array.
if (i > 1) {
if ((i > 1) && (name[i - 1] != '.') && (name[i - 2] != '.')) {
sb.Append('_');
}
sb.Append(tolower(c));

View File

@ -145,6 +145,7 @@ protected:
std::string proxyFullName_;
std::string stubName_;
std::string stubFullName_;
std::string deathRecipientName_;
};
} // namespace Idl
} // namespace OHOS

View File

@ -52,6 +52,7 @@ Lexer::StrTokenTypeMap Lexer::keyWords_ = {
{"full", TokenType::FULL },
{"lite", TokenType::LITE },
{"mini", TokenType::MINI },
{"cacheable", TokenType::CACHEABLE },
{"in", TokenType::IN },
{"out", TokenType::OUT },
{"inout", TokenType::INOUT },
@ -182,6 +183,39 @@ void Lexer::SkipEof()
havePeek_ = false;
}
bool Lexer::ReadCacheableTime(Token &token)
{
bool ret = true;
StringBuilder sb;
while (!file_->IsEof()) {
char c = file_->PeekChar();
if (isspace(c)) {
file_->GetChar();
continue;
}
if (!isdigit(c)) {
if (c != ']' && c != ',') {
ret = false;
}
break;
}
sb.Append(c);
file_->GetChar();
}
if (ret == false) {
return ret;
}
token.value = sb.ToString();
if (token.value.empty()) {
return false;
}
return ret;
}
void Lexer::ReadToken(Token &token, bool skipComment)
{
if (!file_->IsEof()) {

View File

@ -65,6 +65,8 @@ public:
mode_ = mode;
}
bool ReadCacheableTime(Token &token);
private:
void ReadToken(Token &token, bool skipComment = true);

View File

@ -57,6 +57,7 @@ enum class TokenType {
FULL, // "full"
LITE, // "lite"
MINI, // "mini"
CACHEABLE, // "cacheable"
IN, // "in"
OUT, // "out"
INOUT, // "inout"

View File

@ -396,6 +396,18 @@ bool Parser::ParseAttrUnit(AttrSet &attrs)
lexer_.GetToken();
return true;
}
case TokenType::CACHEABLE: {
if (attrs.find(token) != attrs.end()) {
LogError(__func__, __LINE__, token, StringHelper::Format("Duplicate declared attributes cacheable"));
} else {
if (!lexer_.ReadCacheableTime(token)) {
LogError(__func__, __LINE__, token, StringHelper::Format("Cacheable time parse failed"));
}
attrs.insert(token);
}
lexer_.GetToken();
return true;
}
default:
LogError(__func__, __LINE__, token, StringHelper::Format("'%s' is a illegal attribute",
token.value.c_str()));
@ -554,7 +566,9 @@ void Parser::ParseInterfaceBody(const AutoPtr<ASTInterfaceType> &interface)
AutoPtr<ASTMethod> Parser::ParseMethod(const AutoPtr<ASTInterfaceType> &interface)
{
AutoPtr<ASTMethod> method = new ASTMethod();
method->SetAttribute(ParseMethodAttr());
AutoPtr<ASTAttr> methodAttr = ParseMethodAttr();
method->SetAttribute(methodAttr);
method->SetCacheable(methodAttr);
method->SetReturnType(ParseMethodReturnType());
// parser method name
@ -630,6 +644,10 @@ AutoPtr<ASTAttr> Parser::ParseMethodAttr()
case TokenType::ONEWAY:
methodAttr->SetValue(ASTAttr::ONEWAY);
break;
case TokenType::CACHEABLE:
methodAttr->SetValue(ASTAttr::CACHEABLE);
methodAttr->SetCacheableTimeString(attr.value);
break;
default:
LogError(__func__, __LINE__, attr, std::string("illegal attribute of interface"));
break;
@ -1859,11 +1877,19 @@ bool Parser::CheckIntfSaAstMethods()
for (size_t i = 0; i < interfaceType->GetMethodNumber(); i++) {
AutoPtr<ASTMethod> method = interfaceType->GetMethod(i);
if (method->GetAttribute()->GetValue() != ASTAttr::NONE &&
method->GetAttribute()->GetValue() != ASTAttr::ONEWAY) {
LogError(__func__, __LINE__, std::string("intf sa: method attr only support [oneway]"));
if (((method->GetAttribute()->GetValue()) & (~(ASTAttr::ONEWAY | ASTAttr::CACHEABLE))) != 0) {
LogError(__func__, __LINE__, std::string("intf sa: method attr support oneway or cacheable"));
return false;
}
if (method->GetAttribute()->HasValue(ASTAttr::CACHEABLE) &&
!method->GetAttribute()->HasValue(ASTAttr::ONEWAY)) {
auto ret = method->SetCacheableTime();
if (ret) {
ast_->SetHasCacheableProxyMethods(true);
} else {
LogError(__func__, __LINE__, std::string("intf sa: method attr cacheable time invalid"));
}
}
if ((onewayInterface || method->GetAttribute()->GetValue() == ASTAttr::ONEWAY) &&
!method->GetReturnType()->IsVoidType()) {
LogError(__func__, __LINE__,
@ -2009,23 +2035,6 @@ bool Parser::AddAst(const AutoPtr<AST> &ast)
return true;
}
void Parser::LogError(const char *funcName, int fileLine, const std::string &message)
{
errors_.push_back(StringHelper::Format("[%s:%d] error:%s", funcName, fileLine, message.c_str()));
}
void Parser::LogError(const char *funcName, int fileLine, const Token &token, const std::string &message)
{
errors_.push_back(StringHelper::Format("[%s:%d] [%s] error:%s",
funcName, fileLine, LocInfo(token).c_str(), message.c_str()));
}
void Parser::LogErrorBeforeToken(const char *funcName, int fileLine, const Token &token, const std::string &message)
{
errors_.push_back(StringHelper::Format("[%s:%d] [%s] error:%s before '%s' token",
funcName, fileLine, LocInfo(token).c_str(), message.c_str(), token.value.c_str()));
}
void Parser::ShowError()
{
for (const auto &errMsg : errors_) {

View File

@ -240,11 +240,22 @@ private:
bool AddAst(const AutoPtr<AST> &ast);
void LogError(const char *funcName, int fileLine, const std::string &message);
void LogError(const char *funcName, int fileLine, const std::string &message)
{
errors_.push_back(StringHelper::Format("[%s:%d] error:%s", funcName, fileLine, message.c_str()));
}
void LogError(const char *funcName, int fileLine, const Token &token, const std::string &message);
void LogError(const char *funcName, int fileLine, const Token &token, const std::string &message)
{
errors_.push_back(StringHelper::Format("[%s:%d] [%s] error:%s",
funcName, fileLine, LocInfo(token).c_str(), message.c_str()));
}
void LogErrorBeforeToken(const char *funcName, int fileLine, const Token &token, const std::string &message);
void LogErrorBeforeToken(const char *funcName, int fileLine, const Token &token, const std::string &message)
{
errors_.push_back(StringHelper::Format("[%s:%d] [%s] error:%s before '%s' token",
funcName, fileLine, LocInfo(token).c_str(), message.c_str(), token.value.c_str()));
}
void ShowError();

View File

@ -0,0 +1,34 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from test_base import Test
class KeywordCacheableTest001(Test):
def get_file_name(self):
return __file__
def run_cpp(self):
self.set_gen_cpp_env()
return self.run_choose(True)
def run(self):
return self.run_cpp()
if __name__ == "__main__":
KeywordCacheableTest001().test()

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
interface idl.OHOS.IFoo {
[cacheable 100]int test001([in] short param1);
[cacheable 0]void test002([in] int param1);
[cacheable 00000]void test003([in] float param1, [out] int param2);
[cacheable 00200]void test004([in] Map<long, long> inParam, [out] Map<long, long> outParam);
[cacheable 2147483647]void test005([in] short param1, [out] double param2);
}

View File

@ -0,0 +1,262 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "foo_proxy.h"
namespace idl {
namespace OHOS {
ErrCode FooProxy::test001(
short param1,
int32_t& result)
{
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERR_INVALID_VALUE;
}
if (!data.WriteInt32(param1)) {
return ERR_INVALID_DATA;
}
bool hitCache = ApiCacheManager::GetInstance().PreSendRequest(GetDescriptor(), COMMAND_TEST001, data, reply);
if (hitCache == true) {
ErrCode errCode = reply.ReadInt32();
if (FAILED(errCode)) {
return errCode;
}
result = reply.ReadInt32();
return ERR_OK;
}
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
return ERR_INVALID_DATA;
}
int32_t result = remote->SendRequest(COMMAND_TEST001, data, reply, option);
if (FAILED(result)) {
return result;
}
ErrCode errCode = reply.ReadInt32();
if (FAILED(errCode)) {
return errCode;
}
ApiCacheManager::GetInstance().PostSendRequest(GetDescriptor(), COMMAND_TEST001, data, reply);
result = reply.ReadInt32();
return ERR_OK;
}
ErrCode FooProxy::test002(
int32_t param1)
{
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERR_INVALID_VALUE;
}
if (!data.WriteInt32(param1)) {
return ERR_INVALID_DATA;
}
bool hitCache = ApiCacheManager::GetInstance().PreSendRequest(GetDescriptor(), COMMAND_TEST002, data, reply);
if (hitCache == true) {
ErrCode errCode = reply.ReadInt32();
if (FAILED(errCode)) {
return errCode;
}
return ERR_OK;
}
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
return ERR_INVALID_DATA;
}
int32_t result = remote->SendRequest(COMMAND_TEST002, data, reply, option);
if (FAILED(result)) {
return result;
}
ErrCode errCode = reply.ReadInt32();
if (FAILED(errCode)) {
return errCode;
}
ApiCacheManager::GetInstance().PostSendRequest(GetDescriptor(), COMMAND_TEST002, data, reply);
return ERR_OK;
}
ErrCode FooProxy::test003(
float param1,
int32_t& param2)
{
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERR_INVALID_VALUE;
}
if (!data.WriteFloat(param1)) {
return ERR_INVALID_DATA;
}
bool hitCache = ApiCacheManager::GetInstance().PreSendRequest(GetDescriptor(), COMMAND_TEST003, data, reply);
if (hitCache == true) {
ErrCode errCode = reply.ReadInt32();
if (FAILED(errCode)) {
return errCode;
}
param2 = reply.ReadInt32();
return ERR_OK;
}
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
return ERR_INVALID_DATA;
}
int32_t result = remote->SendRequest(COMMAND_TEST003, data, reply, option);
if (FAILED(result)) {
return result;
}
ErrCode errCode = reply.ReadInt32();
if (FAILED(errCode)) {
return errCode;
}
ApiCacheManager::GetInstance().PostSendRequest(GetDescriptor(), COMMAND_TEST003, data, reply);
param2 = reply.ReadInt32();
return ERR_OK;
}
ErrCode FooProxy::test004(
const std::unordered_map<long, long>& inParam,
std::unordered_map<long, long>& outParam)
{
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERR_INVALID_VALUE;
}
if (inParam.size() > MAP_MAX_SIZE) {
return ERR_INVALID_DATA;
}
data.WriteInt32(inParam.size());
for (auto it = inParam.begin(); it != inParam.end(); ++it) {
if (!data.WriteInt64((it->first))) {
return ERR_INVALID_DATA;
}
if (!data.WriteInt64((it->second))) {
return ERR_INVALID_DATA;
}
}
bool hitCache = ApiCacheManager::GetInstance().PreSendRequest(GetDescriptor(), COMMAND_TEST004, data, reply);
if (hitCache == true) {
ErrCode errCode = reply.ReadInt32();
if (FAILED(errCode)) {
return errCode;
}
int32_t outParamSize = reply.ReadInt32();
for (int32_t i = 0; i < outParamSize; ++i) {
long key = reply.ReadInt64();
long value = reply.ReadInt64();
outParam[key] = value;
}
return ERR_OK;
}
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
return ERR_INVALID_DATA;
}
int32_t result = remote->SendRequest(COMMAND_TEST004, data, reply, option);
if (FAILED(result)) {
return result;
}
ErrCode errCode = reply.ReadInt32();
if (FAILED(errCode)) {
return errCode;
}
ApiCacheManager::GetInstance().PostSendRequest(GetDescriptor(), COMMAND_TEST004, data, reply);
int32_t outParamSize = reply.ReadInt32();
for (int32_t i = 0; i < outParamSize; ++i) {
long key = reply.ReadInt64();
long value = reply.ReadInt64();
outParam[key] = value;
}
return ERR_OK;
}
ErrCode FooProxy::test005(
short param1,
double& param2)
{
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERR_INVALID_VALUE;
}
if (!data.WriteInt32(param1)) {
return ERR_INVALID_DATA;
}
bool hitCache = ApiCacheManager::GetInstance().PreSendRequest(GetDescriptor(), COMMAND_TEST005, data, reply);
if (hitCache == true) {
ErrCode errCode = reply.ReadInt32();
if (FAILED(errCode)) {
return errCode;
}
param2 = reply.ReadDouble();
return ERR_OK;
}
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
return ERR_INVALID_DATA;
}
int32_t result = remote->SendRequest(COMMAND_TEST005, data, reply, option);
if (FAILED(result)) {
return result;
}
ErrCode errCode = reply.ReadInt32();
if (FAILED(errCode)) {
return errCode;
}
ApiCacheManager::GetInstance().PostSendRequest(GetDescriptor(), COMMAND_TEST005, data, reply);
param2 = reply.ReadDouble();
return ERR_OK;
}
} // namespace OHOS
} // namespace idl

View File

@ -0,0 +1,120 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IDL_OHOS_FOOPROXY_H
#define IDL_OHOS_FOOPROXY_H
#include "ifoo.h"
#include <iremote_proxy.h>
#include "api_cache_manager.h"
namespace idl {
namespace OHOS {
class FooProxy : public IRemoteProxy<IFoo> {
public:
explicit FooProxy(
const sptr<IRemoteObject>& remote)
: IRemoteProxy<IFoo>(remote)
{
ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(), COMMAND_TEST001, 100000);
ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(), COMMAND_TEST002, 0);
ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(), COMMAND_TEST003, 0);
ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(), COMMAND_TEST004, 200000);
ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(), COMMAND_TEST005, 2147483647000);
if (remote != nullptr) {
if (!remote->IsProxyObject()) {
return;
}
deathRecipient_ = new (std::nothrow) FooRecipient(*this);
if (deathRecipient_ == nullptr) {
return;
}
if (!remote->AddDeathRecipient(deathRecipient_)) {
return;
}
remote_ = remote;
}
}
virtual ~FooProxy()
{
if (remote_ == nullptr) {
return;
}
if (deathRecipient_ == nullptr) {
return;
}
remote_->RemoveDeathRecipient(deathRecipient_);
remote_ = nullptr;
ApiCacheManager::GetInstance().DelCacheApi(GetDescriptor(), COMMAND_TEST001);
ApiCacheManager::GetInstance().DelCacheApi(GetDescriptor(), COMMAND_TEST002);
ApiCacheManager::GetInstance().DelCacheApi(GetDescriptor(), COMMAND_TEST003);
ApiCacheManager::GetInstance().DelCacheApi(GetDescriptor(), COMMAND_TEST004);
ApiCacheManager::GetInstance().DelCacheApi(GetDescriptor(), COMMAND_TEST005);
}
ErrCode test001(
short param1,
int32_t& result) override;
ErrCode test002(
int32_t param1) override;
ErrCode test003(
float param1,
int32_t& param2) override;
ErrCode test004(
const std::unordered_map<long, long>& inParam,
std::unordered_map<long, long>& outParam) override;
ErrCode test005(
short param1,
double& param2) override;
private:
class FooRecipient : public IRemoteObject::DeathRecipient {
public:
explicit FooRecipient(FooProxy &client) : client_(client) {}
~FooRecipient() override = default;
void OnRemoteDied(const wptr<IRemoteObject> &remote) override
{
client_.OnRemoteDied(remote);
}
private:
FooProxy &client_;
};
void OnRemoteDied(const wptr<IRemoteObject> &remoteObject)
{
(void)remoteObject;
ApiCacheManager::GetInstance().ClearCache(GetDescriptor());
}
sptr<IRemoteObject> remote_ = nullptr;
sptr<IRemoteObject::DeathRecipient> deathRecipient_ = nullptr;
static constexpr int32_t COMMAND_TEST001 = MIN_TRANSACTION_ID + 0;
static constexpr int32_t COMMAND_TEST002 = MIN_TRANSACTION_ID + 1;
static constexpr int32_t COMMAND_TEST003 = MIN_TRANSACTION_ID + 2;
static constexpr int32_t COMMAND_TEST004 = MIN_TRANSACTION_ID + 3;
static constexpr int32_t COMMAND_TEST005 = MIN_TRANSACTION_ID + 4;
static inline BrokerDelegator<FooProxy> delegator_;
};
} // namespace OHOS
} // namespace idl
#endif // IDL_OHOS_FOOPROXY_H

View File

@ -0,0 +1,119 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "foo_stub.h"
namespace idl {
namespace OHOS {
int32_t FooStub::OnRemoteRequest(
uint32_t code,
MessageParcel& data,
MessageParcel& reply,
MessageOption& option)
{
std::u16string localDescriptor = GetDescriptor();
std::u16string remoteDescriptor = data.ReadInterfaceToken();
if (localDescriptor != remoteDescriptor) {
return ERR_TRANSACTION_FAILED;
}
switch (code) {
case COMMAND_TEST001: {
short param1 = (short)data.ReadInt32();
int32_t result;
ErrCode errCode = test001(param1, result);
if (!reply.WriteInt32(errCode)) {
return ERR_INVALID_VALUE;
}
if (SUCCEEDED(errCode)) {
if (!reply.WriteInt32(result)) {
return ERR_INVALID_DATA;
}
}
return ERR_NONE;
}
case COMMAND_TEST002: {
int32_t param1 = data.ReadInt32();
ErrCode errCode = test002(param1);
if (!reply.WriteInt32(errCode)) {
return ERR_INVALID_VALUE;
}
return ERR_NONE;
}
case COMMAND_TEST003: {
float param1 = data.ReadFloat();
int32_t param2;
ErrCode errCode = test003(param1, param2);
if (!reply.WriteInt32(errCode)) {
return ERR_INVALID_VALUE;
}
if (SUCCEEDED(errCode)) {
if (!reply.WriteInt32(param2)) {
return ERR_INVALID_DATA;
}
}
return ERR_NONE;
}
case COMMAND_TEST004: {
std::unordered_map<long, long> inParam;
int32_t inParamSize = data.ReadInt32();
for (int32_t i = 0; i < inParamSize; ++i) {
long key = data.ReadInt64();
long value = data.ReadInt64();
inParam[key] = value;
}
std::unordered_map<long, long> outParam;
ErrCode errCode = test004(inParam, outParam);
if (!reply.WriteInt32(errCode)) {
return ERR_INVALID_VALUE;
}
if (SUCCEEDED(errCode)) {
if (outParam.size() > MAP_MAX_SIZE) {
return ERR_INVALID_DATA;
}
reply.WriteInt32(outParam.size());
for (auto it = outParam.begin(); it != outParam.end(); ++it) {
if (!reply.WriteInt64((it->first))) {
return ERR_INVALID_DATA;
}
if (!reply.WriteInt64((it->second))) {
return ERR_INVALID_DATA;
}
}
}
return ERR_NONE;
}
case COMMAND_TEST005: {
short param1 = (short)data.ReadInt32();
double param2;
ErrCode errCode = test005(param1, param2);
if (!reply.WriteInt32(errCode)) {
return ERR_INVALID_VALUE;
}
if (SUCCEEDED(errCode)) {
if (!reply.WriteDouble(param2)) {
return ERR_INVALID_DATA;
}
}
return ERR_NONE;
}
default:
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
return ERR_TRANSACTION_FAILED;
}
} // namespace OHOS
} // namespace idl

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IDL_OHOS_FOOSTUB_H
#define IDL_OHOS_FOOSTUB_H
#include "ifoo.h"
#include <iremote_stub.h>
namespace idl {
namespace OHOS {
class FooStub : public IRemoteStub<IFoo> {
public:
int32_t OnRemoteRequest(
uint32_t code,
MessageParcel& data,
MessageParcel& reply,
MessageOption& option) override;
private:
static constexpr int32_t COMMAND_TEST001 = MIN_TRANSACTION_ID + 0;
static constexpr int32_t COMMAND_TEST002 = MIN_TRANSACTION_ID + 1;
static constexpr int32_t COMMAND_TEST003 = MIN_TRANSACTION_ID + 2;
static constexpr int32_t COMMAND_TEST004 = MIN_TRANSACTION_ID + 3;
static constexpr int32_t COMMAND_TEST005 = MIN_TRANSACTION_ID + 4;
};
} // namespace OHOS
} // namespace idl
#endif // IDL_OHOS_FOOSTUB_H

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IDL_OHOS_IFOO_H
#define IDL_OHOS_IFOO_H
#include <unordered_map>
#include <iremote_broker.h>
namespace idl {
namespace OHOS {
class IFoo : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"idl.OHOS.IFoo");
virtual ErrCode test001(
short param1,
int32_t& result) = 0;
virtual ErrCode test002(
int32_t param1) = 0;
virtual ErrCode test003(
float param1,
int32_t& param2) = 0;
virtual ErrCode test004(
const std::unordered_map<long, long>& inParam,
std::unordered_map<long, long>& outParam) = 0;
virtual ErrCode test005(
short param1,
double& param2) = 0;
protected:
const int VECTOR_MAX_SIZE = 102400;
const int LIST_MAX_SIZE = 102400;
const int MAP_MAX_SIZE = 102400;
};
} // namespace OHOS
} // namespace idl
#endif // IDL_OHOS_IFOO_H

View File

@ -0,0 +1,34 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from test_base import Test
class KeywordCacheableTest002(Test):
def get_file_name(self):
return __file__
def run_cpp(self):
self.set_gen_cpp_env()
return self.run_choose(True)
def run(self):
return self.run_cpp()
if __name__ == "__main__":
KeywordCacheableTest002().test()

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
interface idl.OHOS.IFoo {
[cacheable 100, oneway]void test001([in] int param1);
[oneway, cacheable 0]void test002([in] double param1);
[cacheable 0]void test005([in] short param1, [out] double param2);
[cacheable 2]void test005([in] int param1, [out] int param2);
}

View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "foo_proxy.h"
namespace idl {
namespace OHOS {
ErrCode FooProxy::test001(
int32_t param1)
{
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_ASYNC);
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERR_INVALID_VALUE;
}
if (!data.WriteInt32(param1)) {
return ERR_INVALID_DATA;
}
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
return ERR_INVALID_DATA;
}
int32_t result = remote->SendRequest(COMMAND_TEST001, data, reply, option);
if (FAILED(result)) {
return result;
}
return ERR_OK;
}
ErrCode FooProxy::test002(
double param1)
{
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_ASYNC);
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERR_INVALID_VALUE;
}
if (!data.WriteDouble(param1)) {
return ERR_INVALID_DATA;
}
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
return ERR_INVALID_DATA;
}
int32_t result = remote->SendRequest(COMMAND_TEST002, data, reply, option);
if (FAILED(result)) {
return result;
}
return ERR_OK;
}
ErrCode FooProxy::test005(
short param1,
double& param2)
{
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERR_INVALID_VALUE;
}
if (!data.WriteInt32(param1)) {
return ERR_INVALID_DATA;
}
bool hitCache = ApiCacheManager::GetInstance().PreSendRequest(GetDescriptor(), COMMAND_TEST005, data, reply);
if (hitCache == true) {
ErrCode errCode = reply.ReadInt32();
if (FAILED(errCode)) {
return errCode;
}
param2 = reply.ReadDouble();
return ERR_OK;
}
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
return ERR_INVALID_DATA;
}
int32_t result = remote->SendRequest(COMMAND_TEST005, data, reply, option);
if (FAILED(result)) {
return result;
}
ErrCode errCode = reply.ReadInt32();
if (FAILED(errCode)) {
return errCode;
}
ApiCacheManager::GetInstance().PostSendRequest(GetDescriptor(), COMMAND_TEST005, data, reply);
param2 = reply.ReadDouble();
return ERR_OK;
}
ErrCode FooProxy::test005(
int32_t param1,
int32_t& param2)
{
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERR_INVALID_VALUE;
}
if (!data.WriteInt32(param1)) {
return ERR_INVALID_DATA;
}
bool hitCache = ApiCacheManager::GetInstance().PreSendRequest(GetDescriptor(), COMMAND_TEST005, data, reply);
if (hitCache == true) {
ErrCode errCode = reply.ReadInt32();
if (FAILED(errCode)) {
return errCode;
}
param2 = reply.ReadInt32();
return ERR_OK;
}
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
return ERR_INVALID_DATA;
}
int32_t result = remote->SendRequest(COMMAND_TEST005, data, reply, option);
if (FAILED(result)) {
return result;
}
ErrCode errCode = reply.ReadInt32();
if (FAILED(errCode)) {
return errCode;
}
ApiCacheManager::GetInstance().PostSendRequest(GetDescriptor(), COMMAND_TEST005, data, reply);
param2 = reply.ReadInt32();
return ERR_OK;
}
} // namespace OHOS
} // namespace idl

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IDL_OHOS_FOOPROXY_H
#define IDL_OHOS_FOOPROXY_H
#include "ifoo.h"
#include <iremote_proxy.h>
#include "api_cache_manager.h"
namespace idl {
namespace OHOS {
class FooProxy : public IRemoteProxy<IFoo> {
public:
explicit FooProxy(
const sptr<IRemoteObject>& remote)
: IRemoteProxy<IFoo>(remote)
{
ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(), COMMAND_TEST005, 0);
ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(), COMMAND_TEST005, 2000);
if (remote != nullptr) {
if (!remote->IsProxyObject()) {
return;
}
deathRecipient_ = new (std::nothrow) FooRecipient(*this);
if (deathRecipient_ == nullptr) {
return;
}
if (!remote->AddDeathRecipient(deathRecipient_)) {
return;
}
remote_ = remote;
}
}
virtual ~FooProxy()
{
if (remote_ == nullptr) {
return;
}
if (deathRecipient_ == nullptr) {
return;
}
remote_->RemoveDeathRecipient(deathRecipient_);
remote_ = nullptr;
ApiCacheManager::GetInstance().DelCacheApi(GetDescriptor(), COMMAND_TEST005);
ApiCacheManager::GetInstance().DelCacheApi(GetDescriptor(), COMMAND_TEST005);
}
ErrCode test001(
int32_t param1) override;
ErrCode test002(
double param1) override;
ErrCode test005(
short param1,
double& param2) override;
ErrCode test005(
int32_t param1,
int32_t& param2) override;
private:
class FooRecipient : public IRemoteObject::DeathRecipient {
public:
explicit FooRecipient(FooProxy &client) : client_(client) {}
~FooRecipient() override = default;
void OnRemoteDied(const wptr<IRemoteObject> &remote) override
{
client_.OnRemoteDied(remote);
}
private:
FooProxy &client_;
};
void OnRemoteDied(const wptr<IRemoteObject> &remoteObject)
{
(void)remoteObject;
ApiCacheManager::GetInstance().ClearCache(GetDescriptor());
}
sptr<IRemoteObject> remote_ = nullptr;
sptr<IRemoteObject::DeathRecipient> deathRecipient_ = nullptr;
static constexpr int32_t COMMAND_TEST001 = MIN_TRANSACTION_ID + 0;
static constexpr int32_t COMMAND_TEST002 = MIN_TRANSACTION_ID + 1;
static constexpr int32_t COMMAND_TEST005 = MIN_TRANSACTION_ID + 2;
static constexpr int32_t COMMAND_TEST005 = MIN_TRANSACTION_ID + 3;
static inline BrokerDelegator<FooProxy> delegator_;
};
} // namespace OHOS
} // namespace idl
#endif // IDL_OHOS_FOOPROXY_H

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "foo_stub.h"
namespace idl {
namespace OHOS {
int32_t FooStub::OnRemoteRequest(
uint32_t code,
MessageParcel& data,
MessageParcel& reply,
MessageOption& option)
{
std::u16string localDescriptor = GetDescriptor();
std::u16string remoteDescriptor = data.ReadInterfaceToken();
if (localDescriptor != remoteDescriptor) {
return ERR_TRANSACTION_FAILED;
}
switch (code) {
case COMMAND_TEST001: {
int32_t param1 = data.ReadInt32();
ErrCode errCode = test001(param1);
if (!reply.WriteInt32(errCode)) {
return ERR_INVALID_VALUE;
}
return ERR_NONE;
}
case COMMAND_TEST002: {
double param1 = data.ReadDouble();
ErrCode errCode = test002(param1);
if (!reply.WriteInt32(errCode)) {
return ERR_INVALID_VALUE;
}
return ERR_NONE;
}
case COMMAND_TEST005: {
short param1 = (short)data.ReadInt32();
double param2;
ErrCode errCode = test005(param1, param2);
if (!reply.WriteInt32(errCode)) {
return ERR_INVALID_VALUE;
}
if (SUCCEEDED(errCode)) {
if (!reply.WriteDouble(param2)) {
return ERR_INVALID_DATA;
}
}
return ERR_NONE;
}
case COMMAND_TEST005: {
int32_t param1 = data.ReadInt32();
int32_t param2;
ErrCode errCode = test005(param1, param2);
if (!reply.WriteInt32(errCode)) {
return ERR_INVALID_VALUE;
}
if (SUCCEEDED(errCode)) {
if (!reply.WriteInt32(param2)) {
return ERR_INVALID_DATA;
}
}
return ERR_NONE;
}
default:
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
return ERR_TRANSACTION_FAILED;
}
} // namespace OHOS
} // namespace idl

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IDL_OHOS_FOOSTUB_H
#define IDL_OHOS_FOOSTUB_H
#include "ifoo.h"
#include <iremote_stub.h>
namespace idl {
namespace OHOS {
class FooStub : public IRemoteStub<IFoo> {
public:
int32_t OnRemoteRequest(
uint32_t code,
MessageParcel& data,
MessageParcel& reply,
MessageOption& option) override;
private:
static constexpr int32_t COMMAND_TEST001 = MIN_TRANSACTION_ID + 0;
static constexpr int32_t COMMAND_TEST002 = MIN_TRANSACTION_ID + 1;
static constexpr int32_t COMMAND_TEST005 = MIN_TRANSACTION_ID + 2;
static constexpr int32_t COMMAND_TEST005 = MIN_TRANSACTION_ID + 3;
};
} // namespace OHOS
} // namespace idl
#endif // IDL_OHOS_FOOSTUB_H

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IDL_OHOS_IFOO_H
#define IDL_OHOS_IFOO_H
#include <iremote_broker.h>
namespace idl {
namespace OHOS {
class IFoo : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"idl.OHOS.IFoo");
virtual ErrCode test001(
int32_t param1) = 0;
virtual ErrCode test002(
double param1) = 0;
virtual ErrCode test005(
short param1,
double& param2) = 0;
virtual ErrCode test005(
int32_t param1,
int32_t& param2) = 0;
protected:
const int VECTOR_MAX_SIZE = 102400;
const int LIST_MAX_SIZE = 102400;
const int MAP_MAX_SIZE = 102400;
};
} // namespace OHOS
} // namespace idl
#endif // IDL_OHOS_IFOO_H

View File

@ -0,0 +1,34 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from test_base import Test
class KeywordCacheableTest003(Test):
def get_file_name(self):
return __file__
def run_cpp(self):
self.set_gen_cpp_env()
return self.run_choose(False)
def run(self):
return self.run_cpp()
if __name__ == "__main__":
KeywordCacheableTest003().test()

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
interface idl.OHOS.IFoo {
[cacheable 3.14]void test001(); // decimal
[cacheable -1]void test002(); // negative numbers
[cacheable 2147483648]void test003(); // exceed the maximum 32-bit integer
[cacheable 12ab34cd]void test004(); // invalid cacheable time
[cacheable]void test005(); // no cacheable time
[cacheable cacheable]void test006(); // no cacheable time
}

View File

@ -0,0 +1,16 @@
[IDL-GEN]: [ParseAttrUnit:405] [IFoo.idl:17:3] error:Cacheable time parse failed
[IDL-GEN]: [ParseAttributeInfo:373] [IFoo.idl:17:14] error:expected ',' or ']' before '.' token
[IDL-GEN]: [ParseAttrUnit:405] [IFoo.idl:18:6] error:Cacheable time parse failed
[IDL-GEN]: [ParseAttributeInfo:373] [IFoo.idl:18:16] error:expected ',' or ']' before '-' token
[IDL-GEN]: [ParseAttrUnit:405] [IFoo.idl:20:3] error:Cacheable time parse failed
[IDL-GEN]: [ParseAttributeInfo:373] [IFoo.idl:20:15] error:expected ',' or ']' before 'ab34cd' token
[IDL-GEN]: [ParseAttrUnit:405] [IFoo.idl:21:3] error:Cacheable time parse failed
[IDL-GEN]: [ParseAttrUnit:405] [IFoo.idl:22:3] error:Cacheable time parse failed
[IDL-GEN]: [ParseAttributeInfo:373] [IFoo.idl:22:13] error:expected ',' or ']' before 'cacheable' token
[IDL-GEN]: [CheckIntfSaAstMethods:1898] error:intf sa: method attr cacheable time invalid
[IDL-GEN]: [CheckIntfSaAstMethods:1898] error:intf sa: method attr cacheable time invalid
[IDL-GEN]: [CheckIntfSaAstMethods:1898] error:intf sa: method attr cacheable time invalid
[IDL-GEN]: [CheckIntfSaAstMethods:1898] error:intf sa: method attr cacheable time invalid
[IDL-GEN]: [CheckIntfSaAstMethods:1898] error:intf sa: method attr cacheable time invalid
[IDL-GEN]: [CheckIntfSaAstMethods:1898] error:intf sa: method attr cacheable time invalid
[IDL-GEN]: failed to parse file

View File

@ -13,10 +13,10 @@
* limitations under the License.
*/
sequenceable includedir..test.myseq;
sequenceable includedir...myseq2;
interface includedir..test.myinterface;
interface includedir...myinterface2;
sequenceable IncludeDir.Test..test.myseq;
sequenceable IncludeDir...myseq2;
interface IncludeDir.Test..test.myinterface;
interface IncludeDir...myinterface2;
interface test.IFoo {
void seq_test_func([in] myseq inParam, [out] myseq outParam, [inout] myseq inoutParam);

View File

@ -13,9 +13,9 @@
* limitations under the License.
*/
sequenceable includedir..test.myseq;
sequenceable includedir.Test..test.myseq;
sequenceable includedir...myseq2;
interface includedir..test.myinterface;
interface includedir.Test..test.myinterface;
interface includedir...myinterface2;
interface test.IFooTs {

View File

@ -17,9 +17,10 @@
#define TEST_IFOO_H
#include <iremote_broker.h>
#include "includedir.h"
#include "includedir/myinterface.h"
#include "includedir/myinterface2.h"
#include "include_dir.h"
#include "include_dir/myinterface2.h"
#include "include_dir/test.h"
#include "include_dir/test/myinterface.h"
using test::myseq;
using ::myseq2;

View File

@ -25,10 +25,10 @@ use ipc_rust::{
};
use ipc_rust::{MsgParcel, BorrowedMsgParcel};
use includedir::{test, myseq};
use includedir::{myseq2};
use includedir::{test, myinterface};
use includedir::{myinterface2};
use IncludeDir::Test::{test, myseq};
use IncludeDir::{myseq2};
use IncludeDir::Test::{test, myinterface};
use IncludeDir::{myinterface2};
pub enum IFooCode {

View File

@ -18,6 +18,7 @@
import os
import shutil
import re
from util import exec_command, compare_target_files, file_exists
from util import get_time_stamp, print_success, print_failure
@ -126,14 +127,53 @@ class Test:
return False
return compare_target_files(self.output_dir, self.target_dir)
def hdi_gen_fail_check_ignore_line(self, result: str, target: str):
fail_template = r"(.*): \[(\S+):\d+\] \[?(.*)error:(.*)"
result_lines = result.split("\n")
target_lines = target.split("\n")
if len(result_lines) != len(target_lines):
print_failure(f"[ERROR] result line(len(result_lines)) != target line(len(target_lines))")
return False
for result_line, target_line in zip(result_lines, target_lines):
lhd_obj = re.search(fail_template, result_line)
rhd_obj = re.search(fail_template, target_line)
if not lhd_obj and not rhd_obj:
if result_line == target_line:
continue
else:
print_failure(f"[ERROR] actual: {result_line}")
print_failure(f"[ERROR] expect: {target_line}")
return False
elif not lhd_obj or not rhd_obj:
print_failure(f"[ERROR] actual: {result_line}")
print_failure(f"[ERROR] expect: {target_line}")
return False
lhd_start_check_content = lhd_obj.group(1)
rhd_start_check_content = rhd_obj.group(1)
lhd_err_func_check_content = lhd_obj.group(2)
rhd_err_func_check_content = rhd_obj.group(2)
lhd_median_check_content = lhd_obj.group(3)
rhd_median_check_content = rhd_obj.group(3)
lhd_end_check_content = lhd_obj.group(4)
rhd_end_check_content = rhd_obj.group(4)
if lhd_start_check_content != rhd_start_check_content or \
lhd_err_func_check_content != rhd_err_func_check_content or \
lhd_median_check_content != rhd_median_check_content or \
lhd_end_check_content != rhd_end_check_content:
print_failure(f"[ERROR] actual: {result_line}")
print_failure(f"[ERROR] expect: {target_line}")
return False
return True
def run_fail(self):
status, result = exec_command(self.command)
expected_fail_output = ""
with open(os.path.join(self.target_dir, "fail_output.txt"), 'r') as target_output:
expected_fail_output = target_output.read()
if status != 0 and expected_fail_output == result:
if status != 0 and self.hdi_gen_fail_check_ignore_line(result, expected_fail_output):
return True
return False

View File

@ -71,6 +71,9 @@ def compare_target_files(first_file_path, second_file_path):
first_files = set([file[len(first_file_path):] for file in first_files_list])
second_files = set([file[len(second_file_path):-4] for file in second_files_list])
if len(first_files) != len(second_files):
print(f"[ERROR] result file num({len(first_files)}) != expect file num({len(second_files)})")
return False
common_files = first_files & second_files