!1011 fix:add sequenceable and expression function

Merge pull request !1011 from yue/master
This commit is contained in:
openharmony_ci
2022-05-27 01:45:44 +00:00
committed by Gitee
51 changed files with 3118 additions and 2518 deletions
+19 -1
View File
@@ -17,6 +17,16 @@ PARSER_SOURCE := $(wildcard $(PARSER_SOURCE_DIR)/*.cpp)
PARSER_OBJS_DIR := $(BUILD_DIR)/parser
PARSER_OBJS := $(addprefix $(PARSER_OBJS_DIR)/, $(patsubst %.cpp, %.o, $(notdir $(PARSER_SOURCE))))
PREPROCESSOR_SOURCE_DIR := $(PWD)/preprocessor
PREPROCESSOR_SOURCE := $(wildcard $(PREPROCESSOR_SOURCE_DIR)/*.cpp)
PREPROCESSOR_OBJS_DIR := $(BUILD_DIR)/preprocessor
PREPROCESSOR_OBJS := $(addprefix $(PREPROCESSOR_OBJS_DIR)/, $(patsubst %.cpp, %.o, $(notdir $(PREPROCESSOR_SOURCE))))
LEXER_SOURCE_DIR := $(PWD)/lexer
LEXER_SOURCE := $(wildcard $(LEXER_SOURCE_DIR)/*.cpp)
LEXER_OBJS_DIR := $(BUILD_DIR)/lexer
LEXER_OBJS := $(addprefix $(LEXER_OBJS_DIR)/, $(patsubst %.cpp, %.o, $(notdir $(LEXER_SOURCE))))
AST_SOURCE_DIR := $(PWD)/ast
AST_SOURCE := $(wildcard $(AST_SOURCE_DIR)/*.cpp)
AST_OBJS_DIR := $(BUILD_DIR)/ast
@@ -36,7 +46,7 @@ MAIN_SOURCE := $(wildcard *.cpp)
MAIN_OBJS := $(addprefix $(BUILD_DIR)/, $(patsubst %.cpp, %.o, $(MAIN_SOURCE)))
all:$(TARGET)
$(TARGET) : $(BOUNDS_CHECK_OBJS) $(UTIL_OBJS) $(AST_OBJS) $(PARSER_OBJS) $(CODEGEN_OBJS) $(MAIN_OBJS)
$(TARGET) : $(BOUNDS_CHECK_OBJS) $(UTIL_OBJS) $(AST_OBJS) $(LEXER_OBJS) $(PREPROCESSOR_OBJS) $(PARSER_OBJS) $(CODEGEN_OBJS) $(MAIN_OBJS)
$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) $^ -o $@
$(Q) echo $(TARGET):build successful.
@@ -52,6 +62,14 @@ $(PARSER_OBJS_DIR)/%.o : $(PARSER_SOURCE_DIR)/%.cpp
$(Q) mkdir -p $(PARSER_OBJS_DIR)
$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@
$(PREPROCESSOR_OBJS_DIR)/%.o : $(PREPROCESSOR_SOURCE_DIR)/%.cpp
$(Q) mkdir -p $(PREPROCESSOR_OBJS_DIR)
$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@
$(LEXER_OBJS_DIR)/%.o : $(LEXER_SOURCE_DIR)/%.cpp
$(Q) mkdir -p $(LEXER_OBJS_DIR)
$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@
$(AST_OBJS_DIR)/%.o : $(AST_SOURCE_DIR)/%.cpp
$(Q) mkdir -p $(AST_OBJS_DIR)
$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@
+19 -1
View File
@@ -17,6 +17,16 @@ PARSER_SOURCE:=$(wildcard $(PARSER_SOURCE_DIR)/*.cpp)
PARSER_OBJS_DIR:=$(BUILD_DIR)\parser
PARSER_OBJS:=$(addprefix $(PARSER_OBJS_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(PARSER_SOURCE))))
PREPROCESSOR_SOURCE_DIR := $(PWD)\preprocessor
PREPROCESSOR_SOURCE := $(wildcard $(PREPROCESSOR_SOURCE_DIR)/*.cpp)
PREPROCESSOR_OBJS_DIR := $(BUILD_DIR)\preprocessor
PREPROCESSOR_OBJS := $(addprefix $(PREPROCESSOR_OBJS_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(PREPROCESSOR_SOURCE))))
LEXER_SOURCE_DIR := $(PWD)\lexer
LEXER_SOURCE := $(wildcard $(LEXER_SOURCE_DIR)/*.cpp)
LEXER_OBJS_DIR := $(BUILD_DIR)\lexer
LEXER_OBJS := $(addprefix $(LEXER_OBJS_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(LEXER_SOURCE))))
AST_SOURCE_DIR:=$(PWD)\ast
AST_SOURCE:=$(wildcard $(AST_SOURCE_DIR)/*.cpp)
AST_OBJS_DIR:=$(BUILD_DIR)\ast
@@ -36,7 +46,7 @@ MAIN_SOURCE:=$(wildcard *.cpp)
MAIN_OBJS:=$(addprefix $(BUILD_DIR)\, $(patsubst %.cpp, %.o, $(MAIN_SOURCE)))
all : $(TARGET)
$(TARGET) : $(BOUNDS_CHECK_OBJS) $(UTIL_OBJS) $(AST_OBJS) $(PARSER_OBJS) $(CODEGEN_OBJS) $(MAIN_OBJS)
$(TARGET) : $(BOUNDS_CHECK_OBJS) $(UTIL_OBJS) $(AST_OBJS) $(LEXER_OBJS) $(PREPROCESSOR_OBJS) $(PARSER_OBJS) $(CODEGEN_OBJS) $(MAIN_OBJS)
$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) $^ -o $@
$(Q) echo $(TARGET):build successful.
@@ -52,6 +62,14 @@ $(PARSER_OBJS_DIR)\\%.o : $(PARSER_SOURCE_DIR)\\%.cpp
$(Q) if not exist $(PARSER_OBJS_DIR) (mkdir $(PARSER_OBJS_DIR))
$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@
$(PREPROCESSOR_OBJS_DIR)\\%.o : $(PREPROCESSOR_SOURCE_DIR)\\%.cpp
$(Q) if not exist $(PREPROCESSOR_OBJS_DIR) (mkdir $(PREPROCESSOR_OBJS_DIR))
$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@
$(LEXER_OBJS_DIR)\\%.o : $(LEXER_SOURCE_DIR)\\%.cpp
$(Q) if not exist $(LEXER_OBJS_DIR) (mkdir $(LEXER_OBJS_DIR))
$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@
$(AST_OBJS_DIR)\\%.o : $(AST_SOURCE_DIR)\\%.cpp
$(Q) if not exist $(AST_OBJS_DIR) (mkdir $(AST_OBJS_DIR))
$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@
+6 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -172,6 +172,11 @@ public:
return String::Format("%u.%u", majorVersion_, minorVersion_);
}
inline String GetIdlFilePath()
{
return idlFilePath_;
}
private:
ASTFileType astFileType_ = ASTFileType::AST_IFACE;
String name_;
+126
View File
@@ -0,0 +1,126 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "ast/ast_attribute.h"
#include "util/string_builder.h"
namespace OHOS {
namespace HDI {
String ASTTypeAttr::ToString()
{
StringBuilder sb;
std::vector<String> attrVec;
if (isFull_) {
attrVec.push_back("full");
}
if (isLite_) {
attrVec.push_back("lite");
}
if (attrVec.size() > 0) {
sb.Append("[");
for (size_t i = 0; i < attrVec.size(); i++) {
sb.Append(attrVec[i]);
if (i + 1 < attrVec.size()) {
sb.Append(", ");
}
}
sb.Append("]");
}
return sb.ToString();
}
String ASTTypeAttr::Dump(const String &prefix)
{
return prefix + ToString();
}
String ASTInfAttr::ToString()
{
StringBuilder sb;
std::vector<String> attrVec;
if (isFull_) {
attrVec.push_back("full");
}
if (isLite_) {
attrVec.push_back("lite");
}
if (isCallback_) {
attrVec.push_back("callback");
}
if (isOneWay_) {
attrVec.push_back("oneway");
}
if (attrVec.size() > 0) {
sb.Append("[");
for (size_t i = 0; i < attrVec.size(); i++) {
sb.Append(attrVec[i]);
if (i + 1 < attrVec.size()) {
sb.Append(", ");
}
}
sb.Append("]");
}
return sb.ToString();
}
String ASTInfAttr::Dump(const String &prefix)
{
return prefix + ToString();
}
String ASTMethodAttr::ToString()
{
StringBuilder sb;
std::vector<String> attrVec;
if (isFull_) {
attrVec.push_back("full");
}
if (isLite_) {
attrVec.push_back("lite");
}
if (isOneWay_) {
attrVec.push_back("oneway");
}
if (attrVec.size() > 0) {
sb.Append("[");
for (size_t i = 0; i < attrVec.size(); i++) {
sb.Append(attrVec[i]);
if (i + 1 < attrVec.size()) {
sb.Append(", ");
}
}
sb.Append("]");
}
return sb.ToString();
}
String ASTMethodAttr::Dump(const String &prefix)
{
return prefix + ToString();
}
String ASTParamAttr::ToString()
{
return String::Format("[%s]", (value_ == ParamAttr::PARAM_IN) ? "in" : "out");
}
String ASTParamAttr::Dump(const String &prefix)
{
return prefix + ToString();
}
} // namespace HDI
} // namespace OHOS
+72
View File
@@ -0,0 +1,72 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef OHOS_HDI_AST_ATTRIBUTE_H
#define OHOS_HDI_AST_ATTRIBUTE_H
#include "ast/ast_node.h"
#include "util/string.h"
namespace OHOS {
namespace HDI {
class ASTTypeAttr : public ASTNode {
public:
String ToString() override;
String Dump(const String &prefix) override;
public:
bool isFull_ = false;
bool isLite_ = false;
};
class ASTInfAttr : public ASTNode {
public:
String ToString() override;
String Dump(const String &prefix) override;
public:
bool isFull_ = false;
bool isLite_ = false;
bool isCallback_ = false;
bool isOneWay_ = false;
};
class ASTMethodAttr : public ASTNode {
public:
String ToString() override;
String Dump(const String &prefix) override;
public:
bool isFull_ = false;
bool isLite_ = false;
bool isOneWay_ = false;
};
enum class ParamAttr {
PARAM_IN,
PARAM_OUT,
};
class ASTParamAttr : public ASTNode {
public:
ASTParamAttr(ParamAttr value) : ASTNode(), value_(value) {}
String ToString() override;
String Dump(const String &prefix) override;
public:
ParamAttr value_;
};
} // namespace HDI
} // namespace OHOS
#endif // OHOS_HDI_AST_ATTRIBUTE_H
+11 -28
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -37,26 +37,8 @@ String ASTEnumType::ToString()
String ASTEnumType::Dump(const String &prefix)
{
StringBuilder sb;
std::vector<String> attributes;
if (isFull_) {
attributes.push_back("full");
}
if (isLite_) {
attributes.push_back("lite");
}
if (attributes.size() > 0) {
sb.Append("[");
for (size_t i = 0; i < attributes.size(); i++) {
sb.Append(attributes[i]);
if (i < attributes.size() - 1) {
sb.Append(',');
}
}
sb.Append("] ");
}
if (isDisplayBase_ && baseType_ != nullptr) {
sb.Append(prefix).Append(attr_->Dump(prefix)).Append(" ");
if (baseType_ != nullptr) {
sb.AppendFormat("enum %s : %s {\n", name_.string(), baseType_->ToString().string());
} else {
sb.AppendFormat("enum %s {\n", name_.string());
@@ -64,10 +46,11 @@ String ASTEnumType::Dump(const String &prefix)
if (members_.size() > 0) {
for (auto it : members_) {
if (it->isDefaultValue()) {
AutoPtr<ASTExpr> value = it->GetExprValue();
if (value == nullptr) {
sb.Append(" ").AppendFormat("%s,\n", it->GetName().string());
} else {
sb.Append(" ").AppendFormat("%s = %lu,\n", it->GetName().string(), it->GetValue());
sb.Append(" ").AppendFormat("%s = %s,\n", it->GetName().string(), value->Dump("").string());
}
}
}
@@ -126,10 +109,10 @@ String ASTEnumType::EmitCTypeDecl() const
sb.AppendFormat("enum %s {\n", name_.string());
for (auto it : members_) {
if (it->isDefaultValue()) {
if (it->GetExprValue() == nullptr) {
sb.Append(TAB).AppendFormat("%s,\n", it->GetName().string());
} else {
sb.Append(TAB).AppendFormat("%s = %lu,\n", it->GetName().string(), it->GetValue());
sb.Append(TAB).AppendFormat("%s = %lu,\n", it->GetName().string(), it->GetExprValue()->EmitCode().string());
}
}
@@ -140,17 +123,17 @@ String ASTEnumType::EmitCTypeDecl() const
String ASTEnumType::EmitCppTypeDecl() const
{
StringBuilder sb;
if (isDisplayBase_ && baseType_ != nullptr) {
if (baseType_ != nullptr) {
sb.AppendFormat("enum %s : %s {\n", name_.string(), baseType_->EmitCppType().string());
} else {
sb.AppendFormat("enum %s {\n", name_.string());
}
for (auto it : members_) {
if (it->isDefaultValue()) {
if (it->GetExprValue() == nullptr) {
sb.Append(TAB).AppendFormat("%s,\n", it->GetName().string());
} else {
sb.Append(TAB).AppendFormat("%s = %lu,\n", it->GetName().string(), it->GetValue());
sb.Append(TAB).AppendFormat("%s = %s,\n", it->GetName().string(), it->GetExprValue()->EmitCode().string());
}
}
+17 -38
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -9,6 +9,8 @@
#ifndef OHOS_HDI_ASTENUMTYPE_H
#define OHOS_HDI_ASTENUMTYPE_H
#include "ast/ast_attribute.h"
#include "ast/ast_expr.h"
#include "ast/ast_type.h"
#include "util/autoptr.h"
#include "util/string.h"
@@ -17,9 +19,9 @@
namespace OHOS {
namespace HDI {
class ASTEnumValue : public LightRefCountBase {
class ASTEnumValue : public ASTNode {
public:
explicit ASTEnumValue(const String &name) : mName_(name), isDefault_(true), mValue_(0) {}
explicit ASTEnumValue(const String &name) : mName_(name), value_(nullptr) {}
inline virtual ~ASTEnumValue() {}
@@ -38,27 +40,20 @@ public:
return mType_;
}
inline void SetValue(unsigned long value)
inline void SetExprValue(const AutoPtr<ASTExpr> &value)
{
isDefault_ = false;
mValue_ = value;
value_ = value;
}
inline unsigned long GetValue()
inline AutoPtr<ASTExpr> GetExprValue()
{
return mValue_;
}
inline bool isDefaultValue()
{
return isDefault_;
return value_;
}
private:
String mName_;
AutoPtr<ASTType> mType_;
bool isDefault_;
unsigned long mValue_;
AutoPtr<ASTExpr> value_;
};
class ASTEnumType : public ASTType {
@@ -73,34 +68,21 @@ public:
return name_;
}
inline void SetFull(bool full)
inline void SetAttribute(const AutoPtr<ASTTypeAttr> &attr)
{
isFull_ = full;
if (attr != nullptr) {
attr_ = attr;
}
}
inline bool IsFull()
{
return isFull_;
}
inline void SetLite(bool lite)
{
isLite_ = lite;
return attr_ != nullptr ? attr_->isFull_ : false;
}
inline bool IsLite()
{
return isLite_;
}
inline void SetDisplayBase(bool display)
{
isDisplayBase_ = display;
}
inline bool IsDisplayBase()
{
return isDisplayBase_;
return attr_ != nullptr ? attr_->isLite_ : false;
}
void SetBaseType(const AutoPtr<ASTType> &baseType);
@@ -172,11 +154,8 @@ public:
bool emitType, unsigned int innerLevel = 0) const override;
private:
bool isFull_ = false;
bool isLite_ = false;
bool isDisplayBase_ = false;
AutoPtr<ASTTypeAttr> attr_ = new ASTTypeAttr();
AutoPtr<ASTType> baseType_ = nullptr;
std::vector<AutoPtr<ASTEnumValue>> members_;
};
} // namespace HDI
+107
View File
@@ -0,0 +1,107 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "ast/ast_expr.h"
#include "util/string_builder.h"
namespace OHOS {
namespace HDI {
String ASTUnaryExpr::Dump(const String &prefix)
{
StringBuilder sb;
sb.Append(prefix);
if (isParenExpr) {
sb.Append("(");
}
sb.AppendFormat("%s%s", UnaryOpToString(op_).string(), expr_->Dump("").string());
if (isParenExpr) {
sb.Append(")");
}
return sb.ToString();
}
String ASTUnaryExpr::UnaryOpToString(UnaryOpKind op)
{
switch (op) {
case UnaryOpKind::PLUS:
return "+";
case UnaryOpKind::MINUS:
return "-";
case UnaryOpKind::TILDE:
return "~";
default:
return "unknown";
}
}
String ASTBinaryExpr::Dump(const String &prefix)
{
StringBuilder sb;
sb.Append(prefix);
if (isParenExpr) {
sb.Append("(");
}
sb.AppendFormat("%s %s %s", lExpr_->Dump("").string(), BinaryOpToString(op_).string(), rExpr_->Dump("").string());
if (isParenExpr) {
sb.Append(")");
}
return sb.ToString();
}
String ASTBinaryExpr::BinaryOpToString(BinaryOpKind op)
{
switch (op) {
case BinaryOpKind::MUL:
return "*";
case BinaryOpKind::DIV:
return "/";
case BinaryOpKind::MOD:
return "%";
case BinaryOpKind::ADD:
return "+";
case BinaryOpKind::SUB:
return "-";
case BinaryOpKind::LSHIFT:
return "<<";
case BinaryOpKind::RSHIFT:
return ">>";
case BinaryOpKind::AND:
return "&";
case BinaryOpKind::XOR:
return "^";
case BinaryOpKind::OR:
return "|";
default:
return "unknown";
}
}
String ASTNumExpr::Dump(const String &prefix)
{
StringBuilder sb;
sb.Append(prefix);
if (isParenExpr) {
sb.Append("(");
}
sb.AppendFormat("%s", value_.string());
if (isParenExpr) {
sb.Append("(");
}
return sb.ToString();
}
} // namespace HDI
} // namespace OHOS
+73
View File
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef OHOS_HDI_AST_EXPRE_H
#define OHOS_HDI_AST_EXPRE_H
#include "ast/ast_node.h"
#include "util/autoptr.h"
namespace OHOS {
namespace HDI {
class ASTExpr : public ASTNode {
public:
inline String EmitCode()
{
return Dump("");
}
bool isParenExpr = false;
};
enum class UnaryOpKind {
PLUS, // +
MINUS, // -
TILDE, // ~
};
class ASTUnaryExpr : public ASTExpr {
public:
String Dump(const String &prefix) override;
String UnaryOpToString(UnaryOpKind op);
public:
UnaryOpKind op_;
AutoPtr<ASTExpr> expr_;
};
enum class BinaryOpKind {
MUL, // *
DIV, // /
MOD, // %
ADD, // +
SUB, // -
LSHIFT, // <<
RSHIFT, // >>
AND, // &
XOR, // ^
OR, // |
};
class ASTBinaryExpr : public ASTExpr {
public:
String Dump(const String &prefix) override;
String BinaryOpToString(BinaryOpKind op);
public:
BinaryOpKind op_;
AutoPtr<ASTExpr> lExpr_;
AutoPtr<ASTExpr> rExpr_;
};
class ASTNumExpr : public ASTExpr {
public:
String Dump(const String &prefix) override;
String value_;
};
} // namespace HDI
} // namespace OHOS
#endif // OHOS_HDI_AST_EXPRE_H
+2 -27
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -51,33 +51,8 @@ String ASTInterfaceType::Dump(const String &prefix)
StringBuilder sb;
sb.Append(prefix);
std::vector<String> attributes;
if (isOneWay_) {
attributes.push_back("oneway");
}
if (isCallback_) {
attributes.push_back("callback");
}
if (isFull_) {
attributes.push_back("full");
}
if (isLite_) {
attributes.push_back("lite");
}
if (attributes.size() > 0) {
sb.Append("[");
for (size_t i = 0; i < attributes.size(); i++) {
sb.Append(attributes[i]);
if (i < attributes.size() - 1) {
sb.Append(',');
}
}
sb.Append("] ");
}
sb.Append(prefix).Append(attr_->Dump(prefix)).Append(" ");
sb.AppendFormat("interface %s {\n", name_.string());
for (auto method : methods_) {
String info = method->Dump(prefix + " ");
sb.Append(info);
+15 -27
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -9,6 +9,7 @@
#ifndef OHOS_HDI_ASTINTERFACETYPE_H
#define OHOS_HDI_ASTINTERFACETYPE_H
#include "ast/ast_attribute.h"
#include "ast/ast_method.h"
#include <vector>
@@ -32,25 +33,24 @@ public:
return license_;
}
inline void SetOneWay(bool oneway)
void SetAttribute(const AutoPtr<ASTInfAttr> &attr)
{
isOneWay_ = oneway;
if (attr != nullptr) {
attr_ = attr;
if (attr_->isCallback_) {
isSerializable_ = true;
}
}
}
inline bool IsOneWay()
{
return isOneWay_;
}
inline void SetCallback(bool callback)
{
isCallback_ = callback;
SetSerializable(callback);
return attr_->isOneWay_;
}
inline bool IsCallback()
{
return isCallback_;
return attr_->isCallback_;
}
inline void SetSerializable(bool isSerializable)
@@ -63,24 +63,14 @@ public:
return isSerializable_;
}
inline void SetFull(bool full)
{
isFull_ = full;
}
inline bool IsFull()
{
return isFull_;
}
inline void SetLite(bool lite)
{
isLite_ = lite;
return attr_->isFull_;
}
inline bool IsLite()
{
return isLite_;
return attr_->isLite_;
}
void AddMethod(const AutoPtr<ASTMethod> &method);
@@ -144,11 +134,9 @@ public:
private:
String license_;
bool isOneWay_ = false;
bool isCallback_ = false;
AutoPtr<ASTInfAttr> attr_ = new ASTInfAttr();
bool isSerializable_ = false;
bool isFull_ = false;
bool isLite_ = false;
std::vector<AutoPtr<ASTMethod>> methods_;
AutoPtr<ASTMethod> getVerMethod_;
};
+2 -24
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -32,29 +32,7 @@ String ASTMethod::Dump(const String &prefix)
{
StringBuilder sb;
sb.Append(prefix);
std::vector<String> attributes;
if (isOneWay_) {
attributes.push_back("oneway");
}
if (isFull_) {
attributes.push_back("full");
}
if (isLite_) {
attributes.push_back("lite");
}
if (attributes.size() > 0) {
sb.Append("[");
for (size_t i = 0; i < attributes.size(); i++) {
sb.Append(attributes[i]);
if (i < attributes.size() - 1) {
sb.Append(',');
}
}
sb.Append("] ");
}
sb.Append(prefix).Append(attr_->Dump(prefix)).Append(" ");
sb.Append(name_).Append('(');
if (parameters_.size() != 0) {
sb.Append('\n');
+9 -20
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -30,34 +30,26 @@ public:
return name_;
}
inline void SetOneWay(bool oneway)
inline void SetAttribute(const AutoPtr<ASTMethodAttr> &attr)
{
isOneWay_ = oneway;
if (attr != nullptr) {
attr_ == attr;
}
}
inline bool IsOneWay()
{
return isOneWay_;
}
inline void SetFull(bool full)
{
isFull_ = full;
return attr_->isOneWay_;
}
inline bool IsFull()
{
return isFull_;
}
inline void SetLite(bool lite)
{
isLite_ = lite;
return attr_->isFull_;
}
inline bool IsLite()
{
return isLite_;
return attr_->isLite_;
}
void AddParameter(const AutoPtr<ASTParameter> &parameter);
@@ -73,10 +65,7 @@ public:
private:
String name_;
bool isOneWay_ = false;
bool isFull_ = false;
bool isLite_ = false;
AutoPtr<ASTMethodAttr> attr_ = new ASTMethodAttr();
std::vector<AutoPtr<ASTParameter>> parameters_;
};
} // namespace HDI
-27
View File
@@ -1,27 +0,0 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "ast/ast_module.h"
namespace OHOS {
namespace HDI {
void ASTModule::AddAST(const String &astName, const AutoPtr<AST> ast)
{
asts_[astName] = ast;
}
AutoPtr<AST> ASTModule::GetAst(const String &astName)
{
auto astIter = asts_.find(astName);
if (astIter == asts_.end()) {
return nullptr;
}
return astIter->second;
}
} // namespace HDI
} // namespace OHOS
-38
View File
@@ -1,38 +0,0 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef OHOS_HDI_AST_MODULE_H
#define OHOS_HDI_AST_MODULE_H
#include <map>
#include "ast/ast.h"
namespace OHOS {
namespace HDI {
class ASTModule : public LightRefCountBase {
public:
using ASTMap = std::unordered_map<String, AutoPtr<AST>, StringHashFunc, StringEqualFunc>;
void AddAST(const String &astName, const AutoPtr<AST> ast);
AutoPtr<AST> GetAst(const String &astName);
inline const ASTMap &GetAllAsts() const
{
return asts_;
}
private:
// all ast data
ASTMap asts_;
};
} // namespace HDI
} // namespace OHOS
#endif // OHOS_HDI_AST_MODULE_H
+9 -9
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -20,7 +20,7 @@ String ASTParameter::Dump(const String &prefix)
sb.Append(prefix);
sb.Append('[');
if (attribute_ == ParamAttr::PARAM_IN) {
if (attr_->value_ == ParamAttr::PARAM_IN) {
sb.Append("in");
} else {
sb.Append("out");
@@ -56,12 +56,12 @@ String ASTParameter::EmitCParameter()
case TypeKind::TYPE_UNION:
case TypeKind::TYPE_VOID: {
StringBuilder paramStr;
if (attribute_ == ParamAttr::PARAM_IN) {
if (attr_->value_ == ParamAttr::PARAM_IN) {
paramStr.AppendFormat("%s %s", type_->EmitCType(TypeMode::PARAM_IN).string(), name_.string());
} else {
paramStr.AppendFormat("%s %s", type_->EmitCType(TypeMode::PARAM_OUT).string(), name_.string());
}
if (type_->GetTypeKind() == TypeKind::TYPE_STRING && attribute_ == ParamAttr::PARAM_OUT) {
if (type_->GetTypeKind() == TypeKind::TYPE_STRING && attr_->value_ == ParamAttr::PARAM_OUT) {
paramStr.AppendFormat(", uint32_t %sLen", name_.string());
}
return paramStr.ToString();
@@ -69,13 +69,13 @@ String ASTParameter::EmitCParameter()
case TypeKind::TYPE_ARRAY:
case TypeKind::TYPE_LIST: {
StringBuilder paramStr;
if (attribute_ == ParamAttr::PARAM_IN) {
if (attr_->value_ == ParamAttr::PARAM_IN) {
paramStr.AppendFormat("%s %s", type_->EmitCType(TypeMode::PARAM_IN).string(), name_.string());
} else {
paramStr.AppendFormat("%s %s", type_->EmitCType(TypeMode::PARAM_OUT).string(), name_.string());
}
paramStr.AppendFormat(
", uint32_t%s %sLen", (attribute_ == ParamAttr::PARAM_IN) ? "" : "*", name_.string());
", uint32_t%s %sLen", (attr_->value_ == ParamAttr::PARAM_IN) ? "" : "*", name_.string());
return paramStr.ToString();
}
default:
@@ -86,7 +86,7 @@ String ASTParameter::EmitCParameter()
String ASTParameter::EmitCppParameter()
{
if (attribute_ == ParamAttr::PARAM_IN) {
if (attr_->value_ == ParamAttr::PARAM_IN) {
return String::Format("%s %s", type_->EmitCppType(TypeMode::PARAM_IN).string(), name_.string());
} else {
return String::Format("%s %s", type_->EmitCppType(TypeMode::PARAM_OUT).string(), name_.string());
@@ -243,7 +243,7 @@ void ASTParameter::EmitCStubReadOutVar(const String &buffSizeName, const String
void ASTParameter::EmitJavaWriteVar(const String &parcelName, StringBuilder &sb, const String &prefix) const
{
if (attribute_ == ParamAttr::PARAM_IN) {
if (attr_->value_ == ParamAttr::PARAM_IN) {
type_->EmitJavaWriteVar(parcelName, name_, sb, prefix);
} else {
if (type_->GetTypeKind() == TypeKind::TYPE_ARRAY) {
@@ -258,7 +258,7 @@ void ASTParameter::EmitJavaWriteVar(const String &parcelName, StringBuilder &sb,
void ASTParameter::EmitJavaReadVar(const String &parcelName, StringBuilder &sb, const String &prefix) const
{
if (attribute_ == ParamAttr::PARAM_OUT) {
if (attr_->value_ == ParamAttr::PARAM_OUT) {
type_->EmitJavaReadVar(parcelName, name_, sb, prefix);
}
}
+7 -23
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -9,6 +9,7 @@
#ifndef OHOS_HDI_ASTPARAMETER_H
#define OHOS_HDI_ASTPARAMETER_H
#include "ast/ast_attribute.h"
#include "ast/ast_node.h"
#include "ast/ast_type.h"
#include "util/autoptr.h"
@@ -16,23 +17,16 @@
namespace OHOS {
namespace HDI {
// parameter attribute
enum class ParamAttr {
PARAM_IN,
PARAM_OUT,
};
class ASTParameter : public ASTNode {
public:
ASTParameter() : ASTNode() {}
ASTParameter(const String &name, ParamAttr attribute, const AutoPtr<ASTType> &type)
: ASTNode(), name_(name), attribute_(attribute), type_(type)
: ASTNode(), name_(name), attr_(new ASTParamAttr(attribute)), type_(type)
{
}
inline void SetName(const String &name)
ASTParameter(const String &name, const AutoPtr<ASTParamAttr> &attribute, const AutoPtr<ASTType> &type)
: ASTNode(), name_(name), attr_(attribute), type_(type)
{
name_ = name;
}
inline String GetName()
@@ -40,24 +34,14 @@ public:
return name_;
}
inline void SetType(const AutoPtr<ASTType> &type)
{
type_ = type;
}
inline AutoPtr<ASTType> GetType()
{
return type_;
}
inline void SetAttribute(ParamAttr attribute)
{
attribute_ = attribute;
}
inline ParamAttr GetAttribute()
{
return attribute_;
return attr_->value_;
}
String Dump(const String &prefix) override;
@@ -90,7 +74,7 @@ public:
private:
String name_;
AutoPtr<ASTType> type_ = nullptr;
ParamAttr attribute_ = ParamAttr::PARAM_IN;
AutoPtr<ASTParamAttr> attr_;
};
} // namespace HDI
} // namespace OHOS
+2 -24
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -34,37 +34,15 @@ String ASTStructType::ToString()
String ASTStructType::Dump(const String &prefix)
{
StringBuilder sb;
sb.Append(prefix);
std::vector<String> attributes;
if (isFull_) {
attributes.push_back("full");
}
if (isLite_) {
attributes.push_back("lite");
}
if (attributes.size() > 0) {
sb.Append("[");
for (size_t i = 0; i < attributes.size(); i++) {
sb.Append(attributes[i]);
if (i < attributes.size() - 1) {
sb.Append(',');
}
}
sb.Append("] ");
}
sb.Append(prefix).Append(attr_->Dump(prefix)).Append(" ");
sb.AppendFormat("struct %s {\n", name_.string());
if (members_.size() > 0) {
for (auto it : members_) {
sb.Append(prefix + " ");
sb.AppendFormat("%s %s;\n", std::get<1>(it)->ToString().string(), std::get<0>(it).string());
}
}
sb.Append(prefix).Append("};\n");
return sb.ToString();
}
+9 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -12,6 +12,7 @@
#include <tuple>
#include <vector>
#include "ast/ast_attribute.h"
#include "ast/ast_type.h"
#include "util/autoptr.h"
#include "util/string.h"
@@ -30,24 +31,21 @@ public:
return name_;
}
inline void SetFull(bool full)
inline void SetAttribute(const AutoPtr<ASTTypeAttr> &attr)
{
isFull_ = full;
if (attr != nullptr) {
attr_ = attr;
}
}
inline bool IsFull()
{
return isFull_;
}
inline void SetLite(bool lite)
{
isLite_ = lite;
return attr_ != nullptr ? attr_->isFull_ : false;
}
inline bool IsLite()
{
return isLite_;
return attr_ != nullptr ? attr_->isLite_ : false;
}
void AddMember(const AutoPtr<ASTType> &typeName, String name);
@@ -123,8 +121,7 @@ public:
const String &name, bool isClient, bool ownership, StringBuilder &sb, const String &prefix) const override;
private:
bool isFull_ = false;
bool isLite_ = false;
AutoPtr<ASTTypeAttr> attr_ = new ASTTypeAttr();
std::vector<std::tuple<String, AutoPtr<ASTType>>> members_;
};
} // namespace HDI
+5 -28
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -35,35 +35,15 @@ String ASTUnionType::ToString()
String ASTUnionType::Dump(const String &prefix)
{
StringBuilder sb;
sb.Append(prefix);
std::vector<String> attributes;
if (isFull_)
attributes.push_back("full");
if (isLite_)
attributes.push_back("lite");
if (attributes.size() > 0) {
sb.Append("[");
for (size_t i = 0; i < attributes.size(); i++) {
sb.Append(attributes[i]);
if (i < attributes.size() - 1) {
sb.Append(',');
}
}
sb.Append("] ");
}
sb.Append(prefix).Append(attr_->Dump(prefix)).Append(" ");
sb.AppendFormat("union %s {\n", name_.string());
if (members_.size() > 0) {
for (auto it : members_) {
sb.Append(prefix + " ");
sb.AppendFormat("%s %s;\n", std::get<1>(it)->ToString().string(), std::get<0>(it).string());
}
}
sb.Append(prefix).Append("};\n");
return sb.ToString();
}
@@ -174,8 +154,7 @@ void ASTUnionType::EmitCProxyReadVar(const String &parcelName, const String &nam
sb.Append(prefix).Append("uint32_t len = 0;\n");
sb.Append(prefix).AppendFormat(
"if (!HdfSbufReadBuffer(%s, (const void **)&%s, &len)) {\n", parcelName.string(), name.string());
sb.Append(prefix + TAB)
.AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.string());
sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.string());
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.string());
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.string());
sb.Append(prefix).Append("}\n\n");
@@ -200,8 +179,7 @@ void ASTUnionType::EmitCStubReadVar(const String &parcelName, const String &name
sb.Append(prefix).Append("uint32_t len = 0;\n");
sb.Append(prefix).AppendFormat(
"if (!HdfSbufReadBuffer(%s, (const void **)&%s, &len)) {\n", parcelName.string(), name.string());
sb.Append(prefix + TAB)
.AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.string());
sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.string());
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.string());
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.string());
sb.Append(prefix).Append("}\n\n");
@@ -265,8 +243,7 @@ void ASTUnionType::EmitCUnMarshalling(const String &name, const String &gotoLabe
sb.Append(prefix).AppendFormat("%s *%s = NULL;\n", EmitCType().string(), name.string());
sb.Append(prefix).Append("uint32_t len = 0;\n");
sb.Append(prefix).AppendFormat("if (!HdfSbufReadBuffer(data, (const void **)&%s, &len)) {\n", name.string());
sb.Append(prefix + TAB)
.AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.string());
sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.string());
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.string());
sb.Append(prefix).Append("}\n\n");
sb.Append(prefix).AppendFormat("if (%s == NULL || sizeof(%s) != len) {\n", name.string(), EmitCType().string());
+9 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -12,6 +12,7 @@
#include <tuple>
#include <vector>
#include "ast/ast_attribute.h"
#include "ast/ast_type.h"
#include "util/autoptr.h"
#include "util/string.h"
@@ -30,24 +31,21 @@ public:
return name_;
}
inline void SetFull(bool full)
inline void SetAttribute(const AutoPtr<ASTTypeAttr> &attr)
{
isFull_ = full;
if (attr != nullptr) {
attr_ = attr;
}
}
inline bool IsFull()
{
return isFull_;
}
inline void SetLite(bool lite)
{
isLite_ = lite;
return attr_ != nullptr ? attr_->isFull_ : false;
}
inline bool IsLite()
{
return isLite_;
return attr_ != nullptr ? attr_->isLite_ : false;
}
void AddMember(const AutoPtr<ASTType> &typeName, String name);
@@ -123,8 +121,7 @@ public:
const String &name, bool isClient, bool ownership, StringBuilder &sb, const String &prefix) const override;
private:
bool isFull_ = false;
bool isLite_ = false;
AutoPtr<ASTTypeAttr> attr_ = new ASTTypeAttr();
std::vector<std::tuple<String, AutoPtr<ASTType>>> members_;
};
} // namespace HDI
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2020-2021 Huawei Device Co., Ltd.
# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
#
# HDF is dual licensed: you can use it either under the terms of
# the GPL, or the BSD license, at your option.
@@ -286,7 +286,7 @@ def parse_out_dir(gen_dir, package_str, path_map):
root_package = package_path_vec[0]
root_package_path = package_path_vec[1]
temp_dir = package_str.replace(root_package, root_package_path)
temp_dir = package_str.replace(root_package, "")
temp_dir = temp_dir.replace(".", "/")
return gen_dir.replace(temp_dir, "")
+10 -8
View File
@@ -1,10 +1,11 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "codegen/code_emitter.h"
#include <cctype>
@@ -49,6 +50,8 @@ bool CodeEmitter::Reset(const AutoPtr<AST> &ast, const String &targetDirectory,
implFullName_ = interface_->GetNamespace()->ToString() + implName_;
} else if (ast_->GetASTFileType() == ASTFileType::AST_TYPES) {
baseName_ = ast_->GetName();
} else if (ast_->GetASTFileType() == ASTFileType::AST_SEQUENCEABLE) {
baseName_ = ast_->GetName();
}
majorVerName_ = String::Format("%s_MAJOR_VERSION", ConstantName(interfaceName_).string());
@@ -95,8 +98,8 @@ bool CodeEmitter::NeedFlag(const AutoPtr<ASTMethod> &method)
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
AutoPtr<ASTParameter> param = method->GetParameter(i);
AutoPtr<ASTType> type = param->GetType();
if (param->GetAttribute() == ParamAttr::PARAM_OUT && (type->IsStringType() || type->IsArrayType() ||
type->IsListType())) {
if (param->GetAttribute() == ParamAttr::PARAM_OUT &&
(type->IsStringType() || type->IsArrayType() || type->IsListType())) {
return true;
}
}
@@ -106,12 +109,11 @@ bool CodeEmitter::NeedFlag(const AutoPtr<ASTMethod> &method)
String CodeEmitter::GetFilePath(const String &outDir)
{
String outPath = outDir.EndsWith(File::separator) ? outDir.Substring(0, outDir.GetLength() - 1) : outDir;
String packagePath = Options::GetInstance().GetPackagePath(ast_->GetPackageName());
if (packagePath.EndsWith(File::separator)) {
return File::AdapterPath(String::Format("%s%c%s", outPath.string(), File::separator, packagePath.string()));
String subPath = Options::GetInstance().GetSubPath(ast_->GetPackageName());
if (subPath.IsEmpty()) {
return File::AdapterPath(String::Format("%s/", outPath.string(), subPath.string()));
} else {
return File::AdapterPath(String::Format("%s%c%s%c", outPath.string(), File::separator, packagePath.string(),
File::separator));
return File::AdapterPath(String::Format("%s/%s/", outPath.string(), subPath.string()));
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -109,7 +109,7 @@ protected:
String FileName(const String &name);
protected:
static constexpr char* TAB = " ";
static constexpr char *TAB = " ";
bool isKernelCode_ = false;
AutoPtr<AST> ast_ = nullptr;
AutoPtr<ASTInterfaceType> interface_ = nullptr;
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -56,7 +56,7 @@ bool CodeGenerator::Generate()
bool isModeKernel = options.DoGenerateKernelCode();
String codePart = options.GetCodePart();
for (auto &astPair : astModule_->GetAllAsts()) {
for (auto &astPair : allAst_) {
AutoPtr<AST> ast = astPair.second;
if (language.Equals("c")) {
GenerateCCode(ast, dir, codePart, isModeKernel);
+5 -7
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -9,7 +9,6 @@
#ifndef OHOS_HDI_CODEGENERATOR_H
#define OHOS_HDI_CODEGENERATOR_H
#include "ast/ast_module.h"
#include "codegen/code_emitter.h"
namespace OHOS {
@@ -18,10 +17,8 @@ using CodeEmitMap = std::unordered_map<String, AutoPtr<CodeEmitter>, StringHashF
class CodeGenerator : public LightRefCountBase {
public:
explicit CodeGenerator(const AutoPtr<ASTModule> &astModule)
: LightRefCountBase(), astModule_(astModule), targetDirectory_()
{
}
using StrAstMap = std::unordered_map<String, AutoPtr<AST>, StringHashFunc, StringEqualFunc>;
explicit CodeGenerator(const StrAstMap &allAst) : LightRefCountBase(), allAst_(allAst), targetDirectory_() {}
bool Generate();
@@ -30,9 +27,10 @@ private:
void GenerateCppCode(const AutoPtr<AST> &ast, const String &outDir, const String &codePart);
void GenerateJavaCode(const AutoPtr<AST> &ast, const String &outDir, const String &codePart);
AutoPtr<ASTModule> astModule_;
String targetDirectory_;
const StrAstMap &allAst_;
static CodeEmitMap cCodeEmitters_;
static CodeEmitMap cppCodeEmitters_;
static CodeEmitMap javaCodeEmitters_;
+3 -1
View File
@@ -64,7 +64,9 @@ void CppCodeEmitter::GetImportInclusions(HeaderFile::HeaderFileSet &headerFiles)
{
for (const auto &importPair : ast_->GetImports()) {
AutoPtr<AST> importAst = importPair.second;
String fileName = PackageToFilePath(importAst->GetFullName());
String fileName = (importAst->GetASTFileType() == ASTFileType::AST_SEQUENCEABLE) ?
PackageToFilePath(importAst->GetName()) :
PackageToFilePath(importAst->GetFullName());
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, fileName);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -153,8 +153,7 @@ void CppCustomTypesCodeEmitter::EmitCustomTypeUnmarshallingDecl(StringBuilder &s
void CppCustomTypesCodeEmitter::EmitCustomTypesSourceFile()
{
String filePath = File::AdapterPath(String::Format("%s/%s.cpp", directory_.string(),
FileName(baseName_).string()));
String filePath = File::AdapterPath(String::Format("%s/%s.cpp", directory_.string(), FileName(baseName_).string()));
File file(filePath, File::WRITE);
StringBuilder sb;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -36,8 +36,8 @@ void CppServiceImplCodeEmitter::EmitCode()
void CppServiceImplCodeEmitter::EmitImplHeaderFile()
{
String filePath = File::AdapterPath(String::Format("%s/%s.h", directory_.string(),
FileName(baseName_ + "Service").string()));
String filePath =
File::AdapterPath(String::Format("%s/%s.h", directory_.string(), FileName(baseName_ + "Service").string()));
File file(filePath, File::WRITE);
StringBuilder sb;
@@ -125,8 +125,8 @@ void CppServiceImplCodeEmitter::EmitServiceImplMethodDecl(
void CppServiceImplCodeEmitter::EmitImplSourceFile()
{
String filePath = File::AdapterPath(String::Format("%s/%s.cpp", directory_.string(),
FileName(baseName_ + "Service").string()));
String filePath =
File::AdapterPath(String::Format("%s/%s.cpp", directory_.string(), FileName(baseName_ + "Service").string()));
File file(filePath, File::WRITE);
StringBuilder sb;
@@ -201,7 +201,8 @@ void CppServiceImplCodeEmitter::EmitServiceImplMethodImpl(
void CppServiceImplCodeEmitter::EmitServiceImplGetMethodImpl(StringBuilder &sb, const String &prefix)
{
if (!interface_->IsSerializable()) {
sb.Append(prefix).AppendFormat("extern \"C\" %s *HdiImplGetInstance(void)\n", interfaceName_.string());
sb.Append(prefix).AppendFormat(
"extern \"C\" %s *%sImplGetInstance(void)\n", interfaceName_.string(), baseName_.string());
sb.Append(prefix).Append("{\n");
sb.Append(prefix + TAB).AppendFormat("return new (std::nothrow) %s();\n", implName_.string());
sb.Append(prefix).Append("}\n\n");
+493
View File
@@ -0,0 +1,493 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "lexer/lexer.h"
#include "util/logger.h"
#include "util/string_builder.h"
namespace OHOS {
namespace HDI {
Lexer::StrTokenTypeMap Lexer::keyWords_ = {
{"boolean", TokenType::BOOLEAN },
{"byte", TokenType::BYTE },
{"short", TokenType::SHORT },
{"int", TokenType::INT },
{"long", TokenType::LONG },
{"String", TokenType::STRING },
{"float", TokenType::FLOAT },
{"double", TokenType::DOUBLE },
{"FileDescriptor", TokenType::FD },
{"List", TokenType::LIST },
{"Map", TokenType::MAP },
{"SharedMemQueue", TokenType::SMQ },
{"char", TokenType::CHAR },
{"unsigned", TokenType::UNSIGNED },
{"enum", TokenType::ENUM },
{"struct", TokenType::STRUCT },
{"union", TokenType::UNION },
{"package", TokenType::PACKAGE },
{"sequenceable", TokenType::SEQ },
{"import", TokenType::IMPORT },
{"interface", TokenType::INTERFACE},
{"extends", TokenType::EXTENDS },
{"oneway", TokenType::ONEWAY },
{"callback", TokenType::CALLBACK },
{"full", TokenType::FULL },
{"lite", TokenType::LITE },
{"in", TokenType::IN },
{"out", TokenType::OUT },
};
Lexer::StrTokenTypeMap Lexer::symbols_ = {
{".", TokenType::DOT },
{",", TokenType::COMMA },
{":", TokenType::COLON },
{"=", TokenType::ASSIGN },
{";", TokenType::SEMICOLON },
{"{", TokenType::BRACES_LEFT },
{"}", TokenType::BRACES_RIGHT },
{"[", TokenType::BRACKETS_LEFT },
{"]", TokenType::BRACKETS_RIGHT },
{"(", TokenType::PARENTHESES_LEFT },
{")", TokenType::PARENTHESES_RIGHT },
{"<", TokenType::ANGLE_BRACKETS_LEFT },
{">", TokenType::ANGLE_BRACKETS_RIGHT},
{"+", TokenType::ADD },
{"-", TokenType::SUB },
{"*", TokenType::STAR },
{"/", TokenType::SLASH },
{"%", TokenType::PERCENT_SIGN },
{"<<", TokenType::LEFT_SHIFT },
{">>", TokenType::RIGHT_SHIFT },
{"&", TokenType::AND },
{"^", TokenType::XOR },
{"|", TokenType::OR },
{"~", TokenType::TILDE },
{"++", TokenType::PPLUS },
{"--", TokenType::MMINUS },
};
Lexer::Lexer() : file_(nullptr), havePeek_(false), curToken_() {}
bool Lexer::Reset(const String &filePath)
{
file_ = std::make_unique<File>(filePath, int(File::READ));
if (file_ == nullptr || !file_->IsValid()) {
return false;
}
havePeek_ = false;
return true;
}
Token Lexer::PeekToken(bool skipComment)
{
if (!havePeek_) {
ReadToken(curToken_, skipComment);
havePeek_ = true;
}
return curToken_;
}
Token Lexer::GetToken(bool skipComment)
{
if (!havePeek_) {
ReadToken(curToken_, skipComment);
}
havePeek_ = false;
return curToken_;
}
void Lexer::SkipCurrentLine()
{
while (!file_->IsEof()) {
char c = file_->GetChar();
if (c == '\n') {
file_->GetChar();
return;
}
}
}
bool Lexer::SkipCurrentLine(char untilChar)
{
while (!file_->IsEof()) {
int c = file_->GetChar();
if (c == untilChar) {
return true;
}
if (c == '\n') {
file_->GetChar();
return false;
}
}
return true;
}
void Lexer::Skip(char untilChar)
{
while (!file_->IsEof()) {
int c = file_->GetChar();
if (c == untilChar) {
return;
}
}
}
void Lexer::SkipToken(TokenType tokenType)
{
while (curToken_.kind_ != tokenType) {
GetToken(false);
}
}
void Lexer::SkipUntilToken(TokenType tokenType)
{
Token token = PeekToken();
while (token.kind_ != tokenType) {
GetToken(false);
token = PeekToken();
}
}
void Lexer::SkipEof()
{
while (!file_->IsEof()) {}
}
void Lexer::ReadToken(Token &token, bool skipComment)
{
char c = 0;
if (!file_->IsEof()) {
InitCurToken(token);
}
while (!file_->IsEof()) {
c = file_->PeekChar();
if (isspace(c)) {
file_->GetChar();
continue;
}
token.location_.row_ = file_->GetCharLineNumber();
token.location_.col_ = file_->GetCharColumnNumber();
if (isalpha(c) || c == '_') {
ReadId(token);
return;
} else if (isdigit(c)) {
ReadNum(token);
return;
} else if (c == '<') {
ReadShiftLeftOp(token);
return;
} else if (c == '>') {
ReadShiftRightOp(token);
return;
} else if (c == '+') {
ReadPPlusOp(token);
return;
} else if (c == '-') {
ReadMMinusOp(token);
return;
} else if (c == '/') {
ReadComment(token);
if ((token.kind_ == TokenType::COMMENT_BLOCK || token.kind_ == TokenType::COMMENT_LINE) && skipComment) {
InitCurToken(token);
continue;
}
return;
}
ReadSymbolToken(token);
return;
}
token.kind_ = TokenType::END_OF_FILE;
token.value_ = "";
}
void Lexer::InitCurToken(Token &token)
{
token.kind_ = TokenType::UNKNOWN;
token.location_.filePath_ = file_->GetPath();
token.location_.row_ = 0;
token.location_.col_ = 0;
token.value_ = "";
}
void Lexer::ReadId(Token &token)
{
char c = file_->GetChar();
StringBuilder sb;
sb.Append(c);
while (!file_->IsEof()) {
c = file_->PeekChar();
if (isalpha(c) || isdigit(c) || c == '_' || c == '.') {
c = file_->GetChar();
sb.Append(c);
continue;
}
if (isspace(c)) {
file_->GetChar();
}
break;
}
String key = sb.ToString();
auto it = keyWords_.find(key);
token.kind_ = (it == keyWords_.end()) ? TokenType::ID : it->second;
token.value_ = sb.ToString();
}
void Lexer::ReadNum(Token &token)
{
char c = file_->PeekChar();
switch (c) {
case '0': {
file_->GetChar();
c = file_->PeekChar();
if (c == 'b' || c == 'B') {
// binary number
ReadBinaryNum(token);
} else if (isdigit(c)) {
// octal number
return ReadOctNum(token);
} else if (c == 'X' || c == 'x') {
// hexadecimal number
return ReadHexNum(token);
} else {
// decimal number 0
token.kind_ = TokenType::NUM;
token.value_ = "0";
}
break;
}
default:
ReadDecNum(token);
break;
}
}
void Lexer::ReadBinaryNum(Token &token)
{
StringBuilder sb;
char c = file_->GetChar(); // read 'b' or 'B'
sb.AppendFormat("0%c", c);
bool err = true;
while (!file_->IsEof()) {
char c = file_->PeekChar();
if (c == '0' || c == '1') {
sb.Append(c);
file_->GetChar();
err = false;
} else {
break;
}
}
token.kind_ = err ? TokenType::UNKNOWN : TokenType::NUM;
token.value_ = sb.ToString();
}
void Lexer::ReadOctNum(Token &token)
{
StringBuilder sb;
sb.Append("0");
bool err = false;
while (!file_->IsEof()) {
char c = file_->PeekChar();
if (!isdigit(c)) {
break;
}
if (!(c >= '0' && c <= '7')) {
err = true;
}
sb.Append(c);
file_->GetChar();
}
token.kind_ = err ? TokenType::UNKNOWN : TokenType::NUM;
token.value_ = sb.ToString();
}
void Lexer::ReadHexNum(Token &token)
{
StringBuilder sb;
char c = file_->GetChar(); // read 'x' or 'X'
sb.AppendFormat("0%c", c);
bool err = true;
while (!file_->IsEof()) {
c = file_->PeekChar();
if (isdigit(c) || ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
sb.Append(c);
file_->GetChar();
err = false;
} else {
break;
}
}
token.kind_ = err ? TokenType::UNKNOWN : TokenType::NUM;
token.value_ = sb.ToString();
}
void Lexer::ReadDecNum(Token &token)
{
StringBuilder sb;
char c = file_->GetChar();
sb.Append(c);
while (!file_->IsEof()) {
c = file_->PeekChar();
if (!isdigit(c)) {
break;
}
sb.Append(c);
file_->GetChar();
}
token.kind_ = TokenType::NUM;
token.value_ = sb.ToString();
}
void Lexer::ReadShiftLeftOp(Token &token)
{
char c = file_->GetChar();
char next = file_->PeekChar();
if (next == '<') {
file_->GetChar();
token.kind_ = TokenType::LEFT_SHIFT;
token.value_ = "<<";
return;
}
String symbol = String::Format("%c", c);
auto iter = symbols_.find(symbol);
token.kind_ = (iter != symbols_.end()) ? iter->second : TokenType::UNKNOWN;
token.value_ = symbol;
}
void Lexer::ReadShiftRightOp(Token &token)
{
char c = file_->GetChar();
char next = file_->PeekChar();
if (next == '>') {
file_->GetChar();
token.kind_ = TokenType::RIGHT_SHIFT;
token.value_ = ">>";
return;
}
String symbol = String::Format("%c", c);
auto iter = symbols_.find(symbol);
token.kind_ = (iter != symbols_.end()) ? iter->second : TokenType::UNKNOWN;
token.value_ = symbol;
}
void Lexer::ReadPPlusOp(Token &token)
{
char c = file_->GetChar();
char next = file_->PeekChar();
if (next == '+') {
file_->GetChar();
token.kind_ = TokenType::PPLUS;
token.value_ = "++";
return;
}
String symbol = String::Format("%c", c);
auto iter = symbols_.find(symbol);
token.kind_ = (iter != symbols_.end()) ? iter->second : TokenType::UNKNOWN;
token.value_ = symbol;
}
void Lexer::ReadMMinusOp(Token &token)
{
char c = file_->GetChar();
char next = file_->PeekChar();
if (next == '-') {
file_->GetChar();
token.kind_ = TokenType::MMINUS;
token.value_ = "--";
return;
}
String symbol = String::Format("%c", c);
auto iter = symbols_.find(symbol);
token.kind_ = (iter != symbols_.end()) ? iter->second : TokenType::UNKNOWN;
token.value_ = symbol;
}
void Lexer::ReadComment(Token &token)
{
char c = file_->GetChar();
char next = file_->PeekChar();
if (next == '/') {
ReadLineComment(token);
return;
} else if (next == '*') {
ReadBlockComment(token);
return;
}
String symbol = String::Format("%c", c);
auto iter = symbols_.find(symbol);
token.kind_ = (iter != symbols_.end()) ? iter->second : TokenType::UNKNOWN;
token.value_ = symbol;
}
void Lexer::ReadLineComment(Token &token)
{
StringBuilder sb;
char c = file_->GetChar();
sb.AppendFormat("/%c", c);
while (!file_->IsEof()) {
c = file_->GetChar();
if (c == '\n') {
break;
}
sb.Append(c);
}
token.kind_ = TokenType::COMMENT_LINE;
token.value_ = sb.ToString();
}
void Lexer::ReadBlockComment(Token &token)
{
StringBuilder sb;
char c = file_->GetChar();
sb.AppendFormat("/%c", c);
while (!file_->IsEof()) {
c = file_->GetChar();
sb.Append(c);
if (c == '*' && file_->PeekChar() == '/') {
c = file_->GetChar();
sb.Append(c);
break;
}
}
token.kind_ = TokenType::COMMENT_BLOCK;
token.value_ = sb.ToString();
}
void Lexer::ReadSymbolToken(Token &token)
{
char c = file_->GetChar();
String symbol = String::Format("%c", c);
auto iter = symbols_.find(symbol);
token.kind_ = (iter != symbols_.end()) ? iter->second : TokenType::UNKNOWN;
token.value_ = symbol;
}
} // namespace HDI
} // namespace OHOS
+101
View File
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef OHOS_HDI_LEXER_H
#define OHOS_HDI_LEXER_H
#include <cstdlib>
#include <ctype.h>
#include <memory>
#include <unordered_map>
#include "lexer/token.h"
#include "util/file.h"
#include "util/string.h"
namespace OHOS {
namespace HDI {
class Lexer {
public:
Lexer();
~Lexer() = default;
bool Reset(const String &filePath);
inline String GetFilePath() const
{
return (file_ != nullptr) ? file_->GetPath() : "";
}
Token PeekToken(bool skipComment = true);
Token GetToken(bool skipComment = true);
void SkipCurrentLine();
bool SkipCurrentLine(char untilChar);
void Skip(char untilChar);
void SkipToken(TokenType tokenType);
void SkipUntilToken(TokenType tokenType);
void SkipEof();
private:
void ReadToken(Token &token, bool skipComment = true);
void InitCurToken(Token &token);
void ReadId(Token &token);
void ReadNum(Token &token);
void ReadBinaryNum(Token &token);
void ReadOctNum(Token &token);
void ReadHexNum(Token &token);
void ReadDecNum(Token &token);
void ReadShiftLeftOp(Token &token);
void ReadShiftRightOp(Token &token);
void ReadPPlusOp(Token &token);
void ReadMMinusOp(Token &token);
void ReadComment(Token &token);
void ReadLineComment(Token &token);
void ReadBlockComment(Token &token);
void ReadSymbolToken(Token &token);
private:
static constexpr char *TAG = "Lexer";
String filePath_;
std::unique_ptr<File> file_;
bool havePeek_;
Token curToken_;
private:
using StrTokenTypeMap = std::unordered_map<String, TokenType, StringHashFunc, StringEqualFunc>;
static StrTokenTypeMap keyWords_;
static StrTokenTypeMap symbols_;
};
} // namespace HDI
} // namespace OHOS
#endif // OHOS_HDI_LEXER_H
+104
View File
@@ -0,0 +1,104 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "lexer/token.h"
#include <unordered_map>
#include "util/file.h"
#include "util/string_builder.h"
namespace OHOS {
namespace HDI {
String Token::Dump()
{
StringBuilder sb;
sb.AppendFormat(
"{kind_:%u, row_:%u, col_:%u, value_:%s}", (size_t)kind_, location_.row_, location_.col_, value_.string());
return sb.ToString();
}
String LocInfo(const Token &token)
{
String fileName = token.location_.filePath_.Substring(token.location_.filePath_.LastIndexOf(File::separator) + 1);
return String::Format("%s:%u:%u", fileName.string(), token.location_.row_, token.location_.col_);
}
String TokenTypeToString(TokenType type)
{
static std::unordered_map<TokenType, String> tokenStrMap = {
{TokenType::BOOLEAN, "boolean" },
{TokenType::BYTE, "byte" },
{TokenType::SHORT, "short" },
{TokenType::INT, "int" },
{TokenType::LONG, "long" },
{TokenType::STRING, "String" },
{TokenType::FLOAT, "float" },
{TokenType::DOUBLE, "double" },
{TokenType::FD, "FileDescriptor"},
{TokenType::ASHMEM, "Ashmem" },
{TokenType::LIST, "List" },
{TokenType::MAP, "Map" },
{TokenType::SMQ, "SharedMemQueue"},
{TokenType::CHAR, "char" },
{TokenType::UNSIGNED, "unsigned" },
{TokenType::ENUM, "enum" },
{TokenType::STRUCT, "struct" },
{TokenType::UNION, "union" },
{TokenType::PACKAGE, "package" },
{TokenType::SEQ, "sequenceable" },
{TokenType::IMPORT, "import" },
{TokenType::INTERFACE, "interface" },
{TokenType::EXTENDS, "extends" },
{TokenType::ONEWAY, "oneway" },
{TokenType::CALLBACK, "callback" },
{TokenType::FULL, "full" },
{TokenType::LITE, "lite" },
{TokenType::IN, "in" },
{TokenType::OUT, "out" },
{TokenType::DOT, "." },
{TokenType::COMMA, "," },
{TokenType::COLON, ":" },
{TokenType::ASSIGN, "=" },
{TokenType::SEMICOLON, ";" },
{TokenType::BRACES_LEFT, "{" },
{TokenType::BRACES_RIGHT, "}" },
{TokenType::BRACKETS_LEFT, "[" },
{TokenType::BRACKETS_RIGHT, "]" },
{TokenType::PARENTHESES_LEFT, "(" },
{TokenType::PARENTHESES_RIGHT, ")" },
{TokenType::ANGLE_BRACKETS_LEFT, "<" },
{TokenType::ANGLE_BRACKETS_RIGHT, ">" },
};
auto it = tokenStrMap.find(type);
return (it != tokenStrMap.end()) ? it->second : "";
}
int TokenTypeToChar(TokenType type)
{
static std::unordered_map<TokenType, char> tokenCharMap = {
{TokenType::DOT, '.'},
{TokenType::COMMA, '.'},
{TokenType::COLON, ':'},
{TokenType::ASSIGN, '='},
{TokenType::SEMICOLON, ';'},
{TokenType::BRACES_LEFT, '{'},
{TokenType::BRACES_RIGHT, '}'},
{TokenType::BRACKETS_LEFT, '['},
{TokenType::BRACKETS_RIGHT, ']'},
{TokenType::PARENTHESES_LEFT, '('},
{TokenType::PARENTHESES_RIGHT, ')'},
{TokenType::ANGLE_BRACKETS_LEFT, '<'},
{TokenType::ANGLE_BRACKETS_RIGHT, '>'},
};
auto it = tokenCharMap.find(type);
return (it != tokenCharMap.end()) ? it->second : -1;
}
} // namespace HDI
} // namespace OHOS
+116
View File
@@ -0,0 +1,116 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef OHOS_HDI_TOKEN_H
#define OHOS_HDI_TOKEN_H
#include <util/string.h>
namespace OHOS {
namespace HDI {
enum class TokenType {
UNKNOWN = 0,
// types
VOID,
BOOLEAN, // "boolean"
BYTE, // "byte"
SHORT, // "short"
INT, // "int"
LONG, // "long"
STRING, // "String"
FLOAT, // "float"
DOUBLE, // "double"
FD, // "FileDescriptor"
ASHMEM, // "Ashmem"
LIST, // "List"
MAP, // "Map"
SMQ, // "SharedMemQueue"
CHAR, // "char"
// qualifier
UNSIGNED, // "unsigned"
// custom types
ENUM, // "enum"
STRUCT, // "struct"
UNION, // "union"
// keywords
PACKAGE, // "package"
SEQ, // "sequenceable"
IMPORT, // "import"
INTERFACE, // "interface"
EXTENDS, // "extends"
ONEWAY, // "oneway"
CALLBACK, // "callback"
FULL, // "full"
LITE, // "lite"
IN, // "in"
OUT, // "out"
DOT, // "."
COMMA, // ","
COLON, // ":"
ASSIGN, // "="
SEMICOLON, // ";"
BRACES_LEFT, // "{"
BRACES_RIGHT, // "}"
BRACKETS_LEFT, // "["
BRACKETS_RIGHT, // "]"
PARENTHESES_LEFT, // "("
PARENTHESES_RIGHT, // ")"
ANGLE_BRACKETS_LEFT, // "<"
ANGLE_BRACKETS_RIGHT, // ">"
ADD, // "+"
SUB, // "-"
STAR, // "*"
SLASH, // "/"
PERCENT_SIGN, // "%""
LEFT_SHIFT, // "<<"
RIGHT_SHIFT, // ">>"
AND, // "&"
XOR, // "^"
OR, // "|"
TILDE, // "~"
PPLUS, // "++"
MMINUS, // "--"
// others
ID,
NUM,
COMMENT_BLOCK,
COMMENT_LINE,
END_OF_FILE,
};
struct Location {
String filePath_;
size_t row_;
size_t col_;
};
struct Token {
TokenType kind_;
Location location_;
String value_;
String Dump();
};
struct TokenTypeCompare {
bool operator()(const Token &lhs, const Token &rhs)
{
return lhs.kind_ > rhs.kind_;
}
};
String LocInfo(const Token &token);
String TokenTypeToString(TokenType type);
int TokenTypeToChar(TokenType type);
} // namespace HDI
} // namespace OHOS
#endif // OHOS_HDI_TOKEN_H
+18 -5
View File
@@ -7,7 +7,8 @@
*/
#include "codegen/code_generator.h"
#include "parser/module_parser.h"
#include "parser/parser.h"
#include "preprocessor/preprocessor.h"
#include "util/file.h"
#include "util/logger.h"
#include "util/options.h"
@@ -48,17 +49,29 @@ int main(int argc, char **argv)
return 0;
}
ModuleParser moduleParser(options);
AutoPtr<ASTModule> astModule = moduleParser.Parse();
if (astModule == nullptr) {
Preprocessor preprocessor;
std::vector<String> sourceFiles;
if (!preprocessor.Preprocess(sourceFiles)) {
Logger::E("MAIN", "preprocess failed");
}
Parser parser;
if (!parser.Parse(sourceFiles)) {
Logger::E("MAIN", "parse file failed");
return -1;
}
if (options.DoDumpAST()) {
for (const auto &astPair : parser.GetAllAst()) {
printf("%s\n", astPair.second->Dump("").string());
}
}
if (!options.DoGenerateCode()) {
return 0;
}
if (!CodeGenerator(astModule).Generate()) {
if (!CodeGenerator(parser.GetAllAst()).Generate()) {
Logger::E("hdi-gen", "Generate \"%s\" codes failed.", options.GetTargetLanguage().string());
return -1;
}
-45
View File
@@ -1,45 +0,0 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "parser/file_detail.h"
#include "util/file.h"
#include "util/string_builder.h"
namespace OHOS {
namespace HDI {
void FileDetail::SetFilePath(const String &filePath)
{
idlFilePath_ = filePath;
int index = idlFilePath_.LastIndexOf(File::separator);
int end = idlFilePath_.LastIndexOf(".idl");
idlName_ = idlFilePath_.Substring((index == -1) ? 0 : (index + 1), end);
}
bool FileDetail::AddImport(const String &packageName)
{
if (imports_.find(packageName) != imports_.end()) {
return false;
}
imports_.emplace(packageName);
return true;
}
String FileDetail::Dump()
{
StringBuilder sb;
sb.AppendFormat("filePath:%s\n", idlFilePath_.string());
sb.AppendFormat("package:%s\n", packageName_.string());
sb.AppendFormat("import number:%d\n", imports_.size());
for (const auto &importName : imports_) {
sb.AppendFormat("import %s\n", importName.string());
}
return sb.ToString();
}
} // namespace HDI
} // namespace OHOS
-84
View File
@@ -1,84 +0,0 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef OHOS_HDI_FILE_DETAIL_H
#define OHOS_HDI_FILE_DETAIL_H
#include <unordered_set>
#include "util/options.h"
#include "util/string.h"
namespace OHOS {
namespace HDI {
class FileDetail {
public:
using StringSet = std::unordered_set<String, StringHashFunc, StringEqualFunc>;
void SetFilePath(const String &filePath);
inline String GetFilePath() const
{
return idlFilePath_;
}
void SetPackageName(const String &packageName)
{
packageName_ = packageName;
}
inline String GetPackageName() const
{
return packageName_;
}
inline String GetName() const
{
return idlName_;
}
inline String GetFullName() const
{
return packageName_ + "." + idlName_;
}
bool AddImport(const String &packageName);
void DelImport(const String &packageName)
{
imports_.erase(packageName);
}
inline size_t GetImportSize() const
{
return imports_.size();
}
inline const StringSet &GetImports() const
{
return imports_;
}
inline static String ImportsToPath(const String &importPkgName)
{
return Options::GetInstance().GetPackagePath(importPkgName) + ".idl";
}
String Dump();
private:
String idlFilePath_;
String rootPackageName_;
String packageName_;
String idlName_;
StringSet imports_;
};
} // namespace HDI
} // namespace OHOS
#endif // OHOS_HDI_FILE_DETAIL_H
-362
View File
@@ -1,362 +0,0 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "parser/lexer.h"
#include "util/string_builder.h"
namespace OHOS {
namespace HDI {
std::unordered_map<String, Token, StringHashFunc, StringEqualFunc> Lexer::keywords_ = {
{"boolean", Token::BOOLEAN },
{"byte", Token::BYTE },
{"callback", Token::CALLBACK },
{"char", Token::CHAR },
{"double", Token::DOUBLE },
{"enum", Token::ENUM },
{"extends", Token::EXTENDS },
{"float", Token::FLOAT },
{"full", Token::FULL },
{"import", Token::IMPORT },
{"in", Token::IN },
{"int", Token::INTEGER },
{"interface", Token::INTERFACE },
{"List", Token::LIST },
{"lite", Token::LITE },
{"long", Token::LONG },
{"Map", Token::MAP },
{"oneway", Token::ONEWAY },
{"out", Token::OUT },
{"package", Token::PACKAGE },
{"sequenceable", Token::SEQUENCEABLE },
{"short", Token::SHORT },
{"String", Token::STRING },
{"struct", Token::STRUCT },
{"union", Token::UNION },
{"unsigned", Token::UNSIGNED },
{"FileDescriptor", Token::FILEDESCRIPTOR},
{"SharedMemQueue", Token::SMEMQUEUE },
{"Ashmem", Token::ASHMEM },
};
std::unordered_map<char, Token> Lexer::delimiters_ = {
{'<', Token::ANGLE_BRACKETS_LEFT },
{'>', Token::ANGLE_BRACKETS_RIGHT},
{'{', Token::BRACES_LEFT },
{'}', Token::BRACES_RIGHT },
{'[', Token::BRACKETS_LEFT },
{']', Token::BRACKETS_RIGHT },
{',', Token::COMMA },
{'(', Token::PARENTHESES_LEFT },
{')', Token::PARENTHESES_RIGHT },
{'.', Token::DOT },
{':', Token::COLON },
{';', Token::SEMICOLON },
{'=', Token::ASSIGN }
};
std::unordered_map<Token, String> Lexer::tokenDumps_ = {
{Token::ANGLE_BRACKETS_LEFT, "<" },
{Token::ANGLE_BRACKETS_RIGHT, ">" },
{Token::BOOLEAN, "boolean" },
{Token::BRACES_LEFT, "{" },
{Token::BRACES_RIGHT, "}" },
{Token::BRACKETS_LEFT, "[" },
{Token::BRACKETS_RIGHT, "]" },
{Token::BYTE, "byte" },
{Token::CALLBACK, "callback" },
{Token::CHAR, "char" },
{Token::COLON, ":" },
{Token::COMMA, "," },
{Token::DOT, "." },
{Token::DOUBLE, "double" },
{Token::END_OF_FILE, "eof" },
{Token::ENUM, "enum" },
{Token::EXTENDS, "extends" },
{Token::FLOAT, "float" },
{Token::FULL, "full" },
{Token::IMPORT, "import" },
{Token::IN, "in" },
{Token::INTEGER, "int" },
{Token::INTERFACE, "interface" },
{Token::LITE, "lite" },
{Token::LIST, "List" },
{Token::LONG, "long" },
{Token::MAP, "Map" },
{Token::ONEWAY, "oneway" },
{Token::OUT, "out" },
{Token::PACKAGE, "package" },
{Token::SEQUENCEABLE, "sequenceable" },
{Token::STRUCT, "struct" },
{Token::PARENTHESES_LEFT, "(" },
{Token::PARENTHESES_RIGHT, ")" },
{Token::SEMICOLON, ";" },
{Token::SHORT, "short" },
{Token::STRING, "String" },
{Token::UNION, "union" },
{Token::UNSIGNED, "unsigned" },
{Token::FILEDESCRIPTOR, "FileDescriptor"},
{Token::SMEMQUEUE, "SharedMemQueue"},
{Token::ASHMEM, "Ashmem" },
};
Lexer::~Lexer()
{
if (currentFile_ != nullptr) {
currentFile_->Close();
}
}
bool Lexer::OpenSourceFile(const String &filePath)
{
currentFile_ = std::make_unique<File>(filePath, int(File::READ));
if (!currentFile_->IsValid()) {
return false;
}
return true;
}
Token Lexer::GetToken(bool skipComment)
{
if (!havePeek_) {
currentToken_ = ReadToken(skipComment);
}
havePeek_ = false;
return currentToken_;
}
Token Lexer::PeekToken(bool skipComment)
{
if (!havePeek_) {
currentToken_ = ReadToken(skipComment);
havePeek_ = true;
}
return currentToken_;
}
Token Lexer::ReadToken(bool skipComment)
{
while (!currentFile_->IsEof()) {
char c = currentFile_->GetChar();
tokenLineNo_ = currentFile_->GetCharLineNumber();
tokenColumnNo_ = currentFile_->GetCharColumnNumber();
if (IsSpace(c)) {
continue;
} else if (IsAlphabet(c) || c == '_') {
Token t = ReadIdentifier(c);
return t;
} else if (IsDecimalDigital(c)) {
Token t = ReadDecimalDigital(c);
return t;
}
auto iter = delimiters_.find(c);
if (iter != delimiters_.end()) {
return iter->second;
}
if (c == '/') {
if (currentFile_->PeekChar() == '/') {
ReadLineComment(c);
} else if (currentFile_->PeekChar() == '*') {
ReadBlockComment(c);
} else {
currentToken_ = Token::UNKNOWN;
return currentToken_;
}
if (skipComment) {
continue;
}
return currentToken_;
}
currentToken_ = Token::UNKNOWN;
return currentToken_;
}
currentToken_ = Token::END_OF_FILE;
return currentToken_;
}
Token Lexer::ReadIdentifier(char c)
{
StringBuilder sb;
sb.Append(c);
while (!currentFile_->IsEof()) {
c = currentFile_->PeekChar();
if (IsAlphabet(c) || c == '_' || IsDecimalDigital(c) || c == '.') {
c = currentFile_->GetChar();
sb.Append(c);
continue;
}
if (IsSpace(c)) {
currentFile_->GetChar();
}
break;
}
String key = sb.ToString();
auto it = keywords_.find(key);
if (it == keywords_.end()) {
identifier_ = key;
currentToken_ = Token::IDENTIFIER;
} else {
currentToken_ = it->second;
}
return currentToken_;
}
Token Lexer::ReadDecimalDigital(char c)
{
StringBuilder sb;
sb.Append(c);
while (!currentFile_->IsEof()) {
c = currentFile_->PeekChar();
if (IsDecimalDigital(c)) {
c = currentFile_->GetChar();
sb.Append(c);
continue;
} else {
break;
}
}
digit_ = sb.ToString();
currentToken_ = Token::DIGIT;
return currentToken_;
}
Token Lexer::ReadLineComment(char c)
{
StringBuilder sb;
sb.Append(c);
while (!currentFile_->IsEof()) {
c = currentFile_->GetChar();
if (c == '\n') {
break;
}
sb.Append(c);
}
comment_ = sb.ToString();
currentToken_ = Token::COMMENT_LINE;
return currentToken_;
}
Token Lexer::ReadBlockComment(char c)
{
StringBuilder sb;
sb.Append(c);
while (!currentFile_->IsEof()) {
c = currentFile_->GetChar();
sb.Append(c);
if (c == '*' && currentFile_->PeekChar() == '/') {
c = currentFile_->GetChar();
sb.Append(c);
break;
}
}
comment_ = sb.ToString();
currentToken_ = Token::COMMENT_BLOCK;
return currentToken_;
}
void Lexer::SkipCurrentLine()
{
while (!currentFile_->IsEof()) {
char c = currentFile_->GetChar();
if (c == '\n') {
currentFile_->GetChar();
return;
}
}
}
bool Lexer::SkipCurrentLine(char untilChar)
{
while (!currentFile_->IsEof()) {
int c = currentFile_->GetChar();
if (c == untilChar) {
return true;
}
if (c == '\n') {
currentFile_->GetChar();
return false;
}
}
return true;
}
void Lexer::Skip(char untilChar)
{
while (!currentFile_->IsEof()) {
int c = currentFile_->GetChar();
if (c == untilChar) {
return;
}
}
}
void Lexer::SkipEof()
{
while (!currentFile_->IsEof()) {}
}
int Lexer::TokenToChar(Token token)
{
switch (token) {
case Token::ANGLE_BRACKETS_LEFT:
return '<';
case Token::ANGLE_BRACKETS_RIGHT:
return '>';
case Token::BRACES_LEFT:
return '{';
case Token::BRACES_RIGHT:
return '}';
case Token::BRACKETS_LEFT:
return '[';
case Token::BRACKETS_RIGHT:
return ']';
case Token::COMMA:
return ',';
case Token::DOT:
return '.';
case Token::PARENTHESES_LEFT:
return '(';
case Token::PARENTHESES_RIGHT:
return ')';
case Token::COLON:
return ':';
case Token::SEMICOLON:
return ';';
default:
return -1;
}
}
String Lexer::DumpToken() const
{
auto iter = tokenDumps_.find(currentToken_);
if (iter != tokenDumps_.end()) {
return iter->second;
}
if (currentToken_ == Token::COMMENT_BLOCK || currentToken_ == Token::COMMENT_LINE) {
return comment_;
}
if (currentToken_ == Token::IDENTIFIER) {
return identifier_;
}
return "unknown token";
}
} // namespace HDI
} // namespace OHOS
-123
View File
@@ -1,123 +0,0 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef OHOS_HDI_LEXER_H
#define OHOS_HDI_LEXER_H
#include <cstdlib>
#include <ctype.h>
#include <memory>
#include <unordered_map>
#include "parser/token.h"
#include "util/file.h"
#include "util/string.h"
namespace OHOS {
namespace HDI {
class Lexer {
public:
Lexer() = default;
~Lexer();
bool OpenSourceFile(const String &filePath);
Token GetToken(bool skipComment = true);
Token PeekToken(bool skipComment = true);
inline String GetIdentifier() const
{
return identifier_;
}
inline unsigned long GetDigit() const
{
return std::atoll(digit_.string());
}
inline String GetComment() const
{
return comment_;
}
void SkipCurrentLine();
bool SkipCurrentLine(char untilChar);
void Skip(char untilChar);
void SkipEof();
inline String GetFilePath() const
{
if (currentFile_ == nullptr) {
return String("");
}
return currentFile_->GetPath();
}
String DumpToken() const;
inline int GetTokenLineNumber() const
{
return tokenLineNo_;
}
inline int GetTokenColumnNumber() const
{
return tokenColumnNo_;
}
static int TokenToChar(Token token);
private:
Token ReadToken(bool skipComment);
Token ReadIdentifier(char c);
Token ReadDecimalDigital(char c);
Token ReadLineComment(char c);
Token ReadBlockComment(char c);
inline static bool IsAlphabet(char c)
{
return isalpha(c);
}
inline static bool IsDecimalDigital(char c)
{
return isdigit(c);
}
inline static bool IsSpace(char c)
{
return isspace(c);
}
static const char *TAG;
static std::unordered_map<String, Token, StringHashFunc, StringEqualFunc> keywords_;
static std::unordered_map<char, Token> delimiters_;
static std::unordered_map<Token, String> tokenDumps_;
Token currentToken_ = Token::UNKNOWN;
int tokenLineNo_ = 0;
int tokenColumnNo_ = 0;
String identifier_;
String digit_;
String comment_;
bool havePeek_ = false;
std::unique_ptr<File> currentFile_;
};
} // namespace HDI
} // namespace OHOS
#endif // OHOS_HDI_LEXER_H
-172
View File
@@ -1,172 +0,0 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "parser/module_parser.h"
#include <queue>
#include "parser/parser.h"
#include "util/logger.h"
namespace OHOS {
namespace HDI {
const char *ModuleParser::TAG = "ModuleParser";
AutoPtr<ASTModule> ModuleParser::Parse()
{
if (!ParserDependencies()) {
return nullptr;
}
if (!CompileFiles()) {
return nullptr;
}
return module_;
}
bool ModuleParser::ParserDependencies()
{
if (option_.GetSourceFiles().size() == 1) {
if (!ParserAllImports(option_.GetSourceFiles()[0])) {
Logger::E(TAG, "Parsing all idl file failed.");
return false;
}
} else {
if (!ParserAllidlFile(option_.GetSourceFiles())) {
Logger::E(TAG, "Parsing all given idl file failed.");
return false;
}
}
if (!CheckCircularReference()) {
Logger::E(TAG, "has circle reference.");
return false;
}
return true;
}
bool ModuleParser::CompileFiles()
{
std::unique_ptr<Parser> parserPtr = std::make_unique<Parser>(option_, module_);
for (const auto &filePath : compileFiles_) {
if (!parserPtr->Parse(filePath)) {
Logger::E(TAG, "parse %s failed", filePath.string());
return false;
}
}
return true;
}
bool ModuleParser::ParserAllImports(const String &rootFilePath)
{
std::unique_ptr<Parser> parserPtr = std::make_unique<Parser>(option_);
std::shared_ptr<FileDetail> fileInfo = nullptr;
if (!parserPtr->Parse(rootFilePath, fileInfo)) {
return false;
}
if (fileInfo == nullptr) {
return false;
}
sourceFiles_[fileInfo->GetFullName()] = fileInfo;
return ParserAllImportsRecursion(fileInfo);
}
bool ModuleParser::ParserAllImportsRecursion(const std::shared_ptr<FileDetail> &fileInfo)
{
for (const auto &importName : fileInfo->GetImports()) {
if (sourceFiles_.find(importName) != sourceFiles_.end()) {
continue;
}
String filePath = FileDetail::ImportsToPath(importName);
std::unique_ptr<Parser> parserPtr = std::make_unique<Parser>(option_);
std::shared_ptr<FileDetail> file = nullptr;
if (!parserPtr->Parse(filePath, file)) {
Logger::E(TAG, "Parsing %s failed.", filePath.string());
return false;
}
if (file == nullptr) {
Logger::E(TAG, "Parsing %s failed, generator filedetail is nullptr.", filePath.string());
return false;
}
sourceFiles_[file->GetFullName()] = file;
if (!ParserAllImportsRecursion(file)) {
Logger::E(TAG, "Parsing %s file's import failed.", file->GetFilePath().string());
return false;
}
}
return true;
}
bool ModuleParser::ParserAllidlFile(const std::vector<String> &idlSourceFile)
{
std::unique_ptr<Parser> parserPtr = std::make_unique<Parser>(option_);
for (const auto &idlSourceFile : idlSourceFile) {
std::shared_ptr<FileDetail> fileInfo = nullptr;
if (!parserPtr->Parse(idlSourceFile, fileInfo)) {
return false;
}
if (fileInfo == nullptr) {
return false;
}
sourceFiles_[fileInfo->GetFullName()] = fileInfo;
}
return true;
}
bool ModuleParser::CheckCircularReference()
{
std::queue<std::shared_ptr<FileDetail>> fileQueue;
for (const auto &filePair : sourceFiles_) {
std::shared_ptr<FileDetail> fileNode = filePair.second;
if (fileNode->GetImportSize() == 0) {
fileQueue.push(fileNode);
}
}
compileFiles_.clear();
while (!fileQueue.empty()) {
std::shared_ptr<FileDetail> importFile = fileQueue.front();
fileQueue.pop();
compileFiles_.push_back(importFile->GetFilePath());
for (const auto &filePair : sourceFiles_) {
std::shared_ptr<FileDetail> fileNode = filePair.second;
if (fileNode->GetImportSize() > 0) {
fileNode->DelImport(importFile->GetFullName());
if (fileNode->GetImportSize() == 0) {
fileQueue.push(fileNode);
}
}
}
}
if (compileFiles_.size() < sourceFiles_.size()) {
return false;
}
return true;
}
} // namespace HDI
} // namespace OHOS
-72
View File
@@ -1,72 +0,0 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef OHOS_HDI_MODULE_PARSER_H
#define OHOS_HDI_MODULE_PARSER_H
#include <memory>
#include <set>
#include "ast/ast_module.h"
#include "parser/file_detail.h"
#include "util/options.h"
namespace OHOS {
namespace HDI {
class ModuleParser {
public:
using FileDetailMap = std::unordered_map<String, std::shared_ptr<FileDetail>, StringHashFunc, StringEqualFunc>;
explicit ModuleParser(const Options &option)
: option_(option),
sourceFiles_(),
searchedFile_(),
traceFilePtr_(nullptr),
allCirclesFile_(),
compileFiles_(),
module_(new ASTModule())
{
}
~ModuleParser() = default;
AutoPtr<ASTModule> Parse();
private:
// parser file and circular reference
bool ParserDependencies();
bool CompileFiles();
// parse all idl file involved in compilation.
bool ParserAllImports(const String &rootFilePath);
bool ParserAllImportsRecursion(const std::shared_ptr<FileDetail> &fileInfo);
bool ParserAllidlFile(const std::vector<String> &idlSourceFile);
// check circular reference and reverse topology sorting of all idl file
bool CheckCircularReference();
static const char *TAG;
const Options &option_;
FileDetailMap sourceFiles_;
std::set<String> searchedFile_;
std::shared_ptr<std::vector<String>> traceFilePtr_;
std::vector<std::vector<String>> allCirclesFile_;
std::vector<String> compileFiles_;
AutoPtr<ASTModule> module_;
};
} // namespace HDI
} // namespace OHOS
#endif // OHOS_HDI_MODULE_PARSER_H
File diff suppressed because it is too large Load Diff
+91 -65
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
@@ -10,16 +10,15 @@
#define OHOS_HDI_PARSER_H
#include <memory>
#include <set>
#include <vector>
#include "ast/ast.h"
#include "ast/ast_attribute.h"
#include "ast/ast_interface_type.h"
#include "ast/ast_method.h"
#include "ast/ast_module.h"
#include "ast/ast_type.h"
#include "parser/file_detail.h"
#include "parser/lexer.h"
#include "parser/token.h"
#include "lexer/lexer.h"
#include "util/autoptr.h"
#include "util/light_refcount_base.h"
#include "util/options.h"
@@ -27,19 +26,20 @@
namespace OHOS {
namespace HDI {
using AttrSet = std::set<Token, TokenTypeCompare>;
class Parser {
public:
Parser(const Options &options, const AutoPtr<ASTModule> &module = nullptr);
Parser() = default;
~Parser() = default;
bool Parse(const String &sourceFile);
bool Parse(const std::vector<String> &sourceFiles);
bool Parse(const String &sourceFile, std::shared_ptr<FileDetail> &fileDetailPtr);
inline AutoPtr<AST> GetAst() const
using StrAstMap = std::unordered_map<String, AutoPtr<AST>, StringHashFunc, StringEqualFunc>;
inline const StrAstMap &GetAllAst() const
{
return ast_;
return allAsts_;
}
private:
@@ -51,83 +51,110 @@ private:
bool isLite = false;
};
class ErrorInfo : public LightRefCountBase {
public:
String file_;
Token token_;
int lineNo_;
int columnNo_;
String message_;
AutoPtr<ErrorInfo> next_;
};
bool ParseOne(const String &sourceFile);
bool ParseIdlDetail(std::shared_ptr<FileDetail> &fileDetailPtr);
bool ParseIdlPackage(std::shared_ptr<FileDetail> &fileDetailPtr);
bool ParseIdlImport(std::shared_ptr<FileDetail> &fileDetailPtr);
bool Reset(const String &sourceFile);
bool ParseFile();
bool ParseLicense();
String ParseLicense();
bool ParsePackageName();
bool ParsePackage();
bool ParserPackageInfo(const String &packageFullName);
bool ParseImport();
bool ParseImports();
bool ParseSequenceable();
void ParseImportInfo();
bool ParseAttribute();
void ParseSequenceableInfo();
bool ParseInterface(const AutoPtr<Attribute> &attributes = nullptr);
bool ParseTypeDecls();
bool ParseInterfaceBody(const AutoPtr<ASTInterfaceType> &interface);
// parse attributes of type
void ParseAttribute();
bool ParseMethod(const AutoPtr<ASTInterfaceType> &interface);
AttrSet ParseAttributeInfo();
void SetVersionInterfaceMethod(const AutoPtr<ASTInterfaceType> &interface);
bool AprseAttrUnit(AttrSet &attrs);
bool ParseAttributeBody(AutoPtr<Attribute> &attributes);
// parse interface type
void ParseInterface(const AttrSet &attrs = {});
bool ParseAttributeParam(AutoPtr<Attribute> &attributes);
AutoPtr<ASTInfAttr> ParseInfAttrInfo(const AttrSet &attrs);
bool ParseParameterList(AutoPtr<ASTMethod> &method);
void ParseInterfaceBody(const AutoPtr<ASTInterfaceType> &interface);
bool ParseParameter(const AutoPtr<ASTMethod> &method);
AutoPtr<ASTMethod> ParseMethod();
bool ParseParamAttr(const AutoPtr<ASTParameter> &parameter);
AutoPtr<ASTMethodAttr> ParseMethodAttr();
AutoPtr<ASTMethod> CreateGetVersionMethod();
void ParseMethodParamList(const AutoPtr<ASTMethod> &method);
AutoPtr<ASTParameter> ParseParam();
AutoPtr<ASTParamAttr> ParseParamAttr();
// parse type
AutoPtr<ASTType> ParseType();
AutoPtr<ASTType> ParseUnsignedType(int typeLineNo, int typeColumnNo);
AutoPtr<ASTType> ParseList();
AutoPtr<ASTType> ParseMap();
AutoPtr<ASTType> ParseSharedMemQueueMetaType();
AutoPtr<ASTType> ParseUnsignedType();
AutoPtr<ASTType> ParseArrayType(const AutoPtr<ASTType> &elementType);
AutoPtr<ASTType> ParseCustomType();
AutoPtr<ASTType> ParseListType();
bool ParseEnumDefine(const AutoPtr<Attribute> &attributes = nullptr);
AutoPtr<ASTType> ParseMapType();
bool ParseEnumBaseType(const AutoPtr<ASTEnumType> &type);
AutoPtr<ASTType> ParseSmqType();
bool ParseEnumMember(const AutoPtr<ASTEnumType> &type);
AutoPtr<ASTType> ParseUserDefType();
bool ParseStructDefine(const AutoPtr<Attribute> &attributes = nullptr);
// parse declaration of enum
void ParseEnumDeclaration(const AttrSet &attrs = {});
bool ParseStructMember(const AutoPtr<ASTStructType> &type);
AutoPtr<ASTType> ParseEnumBaseType();
bool ParseUnionDefine(const AutoPtr<Attribute> &attributes = nullptr);
void ParserEnumMember(const AutoPtr<ASTEnumType> &enumType);
bool ParseUnionMember(const AutoPtr<ASTUnionType> &type);
// parse declaration of struct
void ParseStructDeclaration(const AttrSet &attrs = {});
bool CheckType(int lineNo, int columnNo, const AutoPtr<ASTType> &type);
void ParseStructMember(const AutoPtr<ASTStructType> &structType);
// parse declaration of union
void ParseUnionDeclaration(const AttrSet &attrs = {});
void ParseUnionMember(const AutoPtr<ASTUnionType> &unionType);
bool AddUnionMember(const AutoPtr<ASTUnionType> &unionType, const AutoPtr<ASTType> &type, const String &name);
AutoPtr<ASTTypeAttr> ParseUserDefTypeAttr(const AttrSet &attrs);
// parse expression
AutoPtr<ASTExpr> ParseExpr();
AutoPtr<ASTExpr> ParseAndExpr();
AutoPtr<ASTExpr> ParseXorExpr();
AutoPtr<ASTExpr> ParseOrExpr();
AutoPtr<ASTExpr> ParseShiftExpr();
AutoPtr<ASTExpr> ParseAddExpr();
AutoPtr<ASTExpr> ParseMulExpr();
AutoPtr<ASTExpr> ParseUnaryExpr();
AutoPtr<ASTExpr> ParsePrimaryExpr();
AutoPtr<ASTExpr> ParseNumExpr();
bool CheckType(const Token &token, const AutoPtr<ASTType> &type);
void SetAstFileType();
@@ -137,30 +164,29 @@ private:
bool CheckCallbackAst();
bool IsValidTypeName(const String &typeName);
bool CheckPackageName(const String &filePath, const String &packageName);
bool CheckImport(const String &importName);
inline static bool IsPrimitiveType(Token token)
{
return token >= Token::BOOLEAN && token <= Token::ASHMEM;
return token.kind_ >= TokenType::BOOLEAN && token.kind_ <= TokenType::ASHMEM;
}
bool AddAst();
bool AddAst(const AutoPtr<AST> &ast);
void LogError(const String &message);
void LogError(int lineNo, int columnNo, const String &message);
void LogError(const Token &token, const String &message);
void ShowError();
static const char *TAG;
static constexpr char *TAG = "Parser";
const Options &options_;
std::shared_ptr<Lexer> lexer_;
AutoPtr<ErrorInfo> errors_;
Lexer lexer_;
std::vector<String> errors_;
AutoPtr<AST> ast_;
AutoPtr<ASTModule> astModule_;
StrAstMap allAsts_;
};
} // namespace HDI
} // namespace OHOS
-73
View File
@@ -1,73 +0,0 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef OHOS_HDI_TOKEN_H
#define OHOS_HDI_TOKEN_H
namespace OHOS {
namespace HDI {
enum class Token {
UNKNOWN = 0,
// types
VOID,
BOOLEAN,
BYTE,
SHORT,
INTEGER,
LONG,
STRING,
FLOAT,
DOUBLE,
FILEDESCRIPTOR,
ASHMEM,
LIST,
MAP,
SMEMQUEUE,
CHAR,
// qualifier
UNSIGNED,
// custom types
STRUCT,
ENUM,
UNION,
// keywords
PACKAGE,
SEQUENCEABLE,
IMPORT,
INTERFACE,
EXTENDS,
ONEWAY,
CALLBACK,
FULL,
LITE,
IN,
OUT,
DOT, // '.'
COMMA, // ','
COLON, // ':'
ASSIGN, // '='
SEMICOLON, // ';'
BRACES_LEFT, // '{'
BRACES_RIGHT, // '}'
BRACKETS_LEFT, // '['
BRACKETS_RIGHT, // ']'
PARENTHESES_LEFT, // '('
PARENTHESES_RIGHT, // ')'
ANGLE_BRACKETS_LEFT, // '<'
ANGLE_BRACKETS_RIGHT, // '>'
// others
IDENTIFIER,
DIGIT,
COMMENT_BLOCK,
COMMENT_LINE,
END_OF_FILE,
};
} // namespace HDI
} // namespace OHOS
#endif // OHOS_HDI_TOKEN_H
+290
View File
@@ -0,0 +1,290 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "preprocessor/preprocessor.h"
#include <algorithm>
#include <queue>
#include "util/file.h"
#include "util/logger.h"
#include "util/options.h"
#include "util/string_builder.h"
namespace OHOS {
namespace HDI {
String FileDetail::Dump() const
{
StringBuilder sb;
sb.AppendFormat("filePath:%s\n", filePath_.string());
sb.AppendFormat("fileName:%s\n", fileName_.string());
sb.AppendFormat("packageName:%s\n", packageName_.string());
if (imports_.size() == 0) {
sb.Append("import:[]\n");
} else {
sb.Append("import:[\n");
for (const auto &importStr : imports_) {
sb.AppendFormat("%s,\n", importStr.string());
}
sb.Append("]\n");
}
return sb.ToString();
}
bool Preprocessor::Preprocess(std::vector<String> &compileSourceFiles)
{
std::vector<String> sourceFiles = Options::GetInstance().GetSourceFiles();
// check all path of idl files
if (!CheckAllFilesPath(sourceFiles)) {
return false;
}
// analyse impirt infomation of all idl file
FileDetailMap allFileDetails;
if (!AnalyseImportInfo(sourceFiles, allFileDetails)) {
return false;
}
// calculate the order of idl files to compile by counter-topological sorting
if (!CheckCircularReference(allFileDetails, compileSourceFiles)) {
return false;
}
return true;
}
bool Preprocessor::CheckAllFilesPath(const std::vector<String> &sourceFiles)
{
if (sourceFiles.empty()) {
Logger::E(TAG, "no source files");
return false;
}
bool ret = true;
for (const auto &filePath : sourceFiles) {
if (!File::CheckValid(filePath)) {
Logger::E(TAG, "invailed file path '%s'.", filePath.string());
ret = false;
}
}
return ret;
}
bool Preprocessor::AnalyseImportInfo(const std::vector<String> &sourceFiles, FileDetailMap &allFileDetails)
{
if (sourceFiles.size() == 1) {
FileDetail info;
if (!ParseFileDetail(sourceFiles[0], info)) {
return false;
}
allFileDetails[info.GetFullName()] = info;
if (!LoadOtherIdlFiles(info, allFileDetails)) {
return false;
}
} else {
for (const auto &sourceFile : sourceFiles) {
FileDetail info;
if (!ParseFileDetail(sourceFile, info)) {
return false;
}
allFileDetails[info.GetFullName()] = info;
}
}
return true;
}
bool Preprocessor::ParseFileDetail(const String &sourceFile, FileDetail &info)
{
Lexer lexer;
if (!lexer.Reset(sourceFile)) {
Logger::E(TAG, "failed to open file '%s'.", sourceFile.string());
return false;
}
info.filePath_ = lexer.GetFilePath();
int startIndex = info.filePath_.LastIndexOf(File::separator);
int endIndex = info.filePath_.LastIndexOf(".idl");
if (startIndex == -1 || endIndex == -1 || (startIndex >= endIndex)) {
Logger::E(TAG, "failed to get file name from '%s'.", info.filePath_.string());
return false;
}
info.fileName_ = info.filePath_.Substring(startIndex + 1, endIndex);
if (!ParsePackage(lexer, info)) {
return false;
}
if (!ParseImports(lexer, info)) {
return false;
}
return true;
}
bool Preprocessor::ParsePackage(Lexer &lexer, FileDetail &info)
{
Token token = lexer.PeekToken();
if (token.kind_ != TokenType::PACKAGE) {
Logger::E(TAG, "%s: expected 'package' before '%s' token", LocInfo(token).string(), token.value_.string());
return false;
}
lexer.GetToken();
token = lexer.PeekToken();
if (token.kind_ != TokenType::ID) {
Logger::E(TAG, "%s: expected package name before '%s' token", LocInfo(token).string(), token.value_.string());
return false;
}
info.packageName_ = token.value_;
lexer.GetToken();
token = lexer.PeekToken();
if (token.kind_ != TokenType::SEMICOLON) {
Logger::E(TAG, "%s:expected ';' before '%s' token", LocInfo(token).string(), token.value_.string());
return false;
}
lexer.GetToken();
return true;
}
bool Preprocessor::ParseImports(Lexer &lexer, FileDetail &info)
{
Token token = lexer.PeekToken();
while (token.kind_ == TokenType::IMPORT) {
lexer.GetToken();
token = lexer.PeekToken();
if (token.kind_ != TokenType::ID) {
Logger::E(
TAG, "%s: expected import name before '%s' token", LocInfo(token).string(), token.value_.string());
return false;
}
info.imports_.emplace(token.value_);
lexer.GetToken();
token = lexer.PeekToken();
if (token.kind_ != TokenType::SEMICOLON) {
Logger::E(TAG, "%s:expected ';' before '%s' token", LocInfo(token).string(), token.value_.string());
return false;
}
lexer.GetToken();
token = lexer.PeekToken();
}
return true;
}
bool Preprocessor::LoadOtherIdlFiles(const FileDetail &ownerFileDetail, FileDetailMap &allFileDetails)
{
for (const auto &importName : ownerFileDetail.imports_) {
if (allFileDetails.find(importName) != allFileDetails.end()) {
continue;
}
String otherFilePath = Options::GetInstance().GetPackagePath(importName) + ".idl";
FileDetail otherFileDetail;
if (!ParseFileDetail(otherFilePath, otherFileDetail)) {
return false;
}
allFileDetails[otherFileDetail.GetFullName()] = otherFileDetail;
if (!LoadOtherIdlFiles(otherFileDetail, allFileDetails)) {
Logger::E(TAG, "failed to load file detail by import '%s'", otherFileDetail.filePath_.string());
return false;
}
}
return true;
}
bool Preprocessor::CheckCircularReference(FileDetailMap &allFileDetails, std::vector<String> &compileSourceFiles)
{
std::queue<FileDetail> fileQueue;
for (const auto &filePair : allFileDetails) {
const FileDetail &file = filePair.second;
if (file.imports_.size() == 0) {
fileQueue.push(file);
}
}
compileSourceFiles.clear();
while (!fileQueue.empty()) {
FileDetail curFile = fileQueue.front();
fileQueue.pop();
compileSourceFiles.push_back(curFile.filePath_);
for (auto &filePair : allFileDetails) {
FileDetail &otherFile = filePair.second;
if (otherFile.imports_.empty()) {
continue;
}
auto position = otherFile.imports_.find(curFile.GetFullName());
if (position != otherFile.imports_.end()) {
otherFile.imports_.erase(position);
}
if (otherFile.imports_.size() == 0) {
fileQueue.push(otherFile);
}
}
}
if (compileSourceFiles.size() == allFileDetails.size()) {
return true;
}
PrintCyclefInfo(allFileDetails);
return false;
}
void Preprocessor::PrintCyclefInfo(FileDetailMap &allFileDetails)
{
for (FileDetailMap::iterator it = allFileDetails.begin(); it != allFileDetails.end();) {
if (it->second.imports_.size() == 0) {
allFileDetails.erase(it++);
} else {
it++;
}
}
for (const auto &filePair : allFileDetails) {
std::vector<String> traceNodes;
FindCycle(filePair.second.GetFullName(), allFileDetails, traceNodes);
}
}
void Preprocessor::FindCycle(const String &curNode, FileDetailMap &allFiles, std::vector<String> &trace)
{
auto iter = std::find_if(trace.begin(), trace.end(), [curNode](String name) {
return name.Equals(curNode);
});
if (iter != trace.end()) {
if (iter == trace.begin()) {
// print circular reference infomation
StringBuilder sb;
for (const auto &nodeName : trace) {
sb.AppendFormat("%s -> ", nodeName.string());
}
sb.AppendFormat("%s", curNode.string());
Logger::E(TAG, "error: there are circular reference:\n%s", sb.ToString().string());
}
return;
}
trace.push_back(curNode);
for (const auto &importFileName : allFiles[curNode].imports_) {
FindCycle(importFileName, allFiles, trace);
}
trace.pop_back();
}
} // namespace HDI
} // namespace OHOS
+69
View File
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef OHOS_HDI_PREPROCESSOR_H
#define OHOS_HDI_PREPROCESSOR_H
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "lexer/lexer.h"
#include "util/string.h"
namespace OHOS {
namespace HDI {
struct FileDetail {
public:
inline String GetFullName() const
{
return String::Format("%s.%s", packageName_.string(), fileName_.string());
}
String Dump() const;
public:
String filePath_;
String fileName_;
String packageName_;
std::unordered_set<String, StringHashFunc, StringEqualFunc> imports_;
};
class Preprocessor {
public:
using FileDetailMap = std::unordered_map<String, FileDetail, StringHashFunc, StringEqualFunc>;
// analyze idl files and return sorted ids files
bool Preprocess(std::vector<String> &compileSourceFiles);
private:
bool CheckAllFilesPath(const std::vector<String> &sourceFiles);
bool AnalyseImportInfo(const std::vector<String> &sourceFiles, FileDetailMap &allFileDetails);
bool ParseFileDetail(const String &sourceFile, FileDetail &info);
bool ParsePackage(Lexer &lexer, FileDetail &info);
bool ParseImports(Lexer &lexer, FileDetail &info);
bool LoadOtherIdlFiles(const FileDetail &ownerFileDetail, FileDetailMap &allFileDetails);
bool CheckCircularReference(FileDetailMap &allFileDetails, std::vector<String> &compileSourceFiles);
void PrintCyclefInfo(FileDetailMap &allFileDetails);
void FindCycle(const String &curNode, FileDetailMap &allFiles, std::vector<String> &trace);
private:
static constexpr char *TAG = "Preprocessor";
};
} // namespace HDI
} // namespace OHOS
#endif // OHOS_HDI_PREPROCESSOR_H
+74 -13
View File
@@ -75,7 +75,7 @@ char File::GetChar()
if (c != '\n') {
columnNo_++;
} else {
columnNo_ = 0;
columnNo_ = 1;
lineNo_++;
}
}
@@ -116,18 +116,17 @@ int File::Read()
return (count != 0) ? count : -1;
}
bool File::ReadData(void *data, size_t size) const
size_t File::ReadData(void *data, size_t size) const
{
if (data == nullptr || size == 0) {
return true;
return 0;
}
if (fd_ == nullptr) {
return false;
return 0;
}
size_t count = fread(data, size, 1, fd_);
return count == 1;
return fread(data, 1, size, fd_);
}
bool File::WriteData(const void *data, size_t size) const
@@ -210,20 +209,49 @@ bool File::CreateParentDir(const String &path)
String File::AdapterPath(const String &path)
{
#ifndef __MINGW32__
return path.Replace('\\', '/');
String newPath = path.Replace('\\', '/');
#else
return path.Replace('/', '\\');
String newPath = path.Replace('/', '\\');
#endif
// "foo/v1_0//ifoo.h" -> "foo/v1_0/ifoo.h"
StringBuilder adapterPath;
bool hasSep = false;
for (size_t i = 0; i < newPath.GetLength(); i++) {
char c = newPath[i];
if (c == File::separator) {
if (hasSep) {
continue;
}
adapterPath.Append(c);
hasSep = false;
} else {
adapterPath.Append(c);
}
}
return adapterPath.ToString();
}
size_t File::GetHashKey()
String File::RealPath(const String &path)
{
StringBuilder fileStr;
while (!IsEof()) {
fileStr.Append(GetChar());
if (path.IsEmpty()) {
return "";
}
return std::hash<std::string>()(fileStr.ToString().string());
String absPath;
String adapterPath = File::AdapterPath(path);
#ifdef __MINGW32__
char absolutePath[_MAX_PATH];
_fullpath(absolutePath, adapterPath.string(), _MAX_PATH);
absPath = absolutePath;
#else
char *absolutePath = realpath(adapterPath.string(), nullptr);
if (absolutePath != nullptr) {
absPath = absolutePath;
free(absolutePath);
}
#endif
return absPath;
}
bool File::CheckValid(const String &path)
@@ -243,5 +271,38 @@ bool File::CheckValid(const String &path)
return true;
}
String File::Pascal2UnderScoreCase(const String &name)
{
if (name.IsNull() || name.IsEmpty()) {
return name;
}
StringBuilder sb;
for (int i = 0; i < name.GetLength(); i++) {
char c = name[i];
if (isupper(c) != 0) {
// 2->Index of the last char array.
if (i > 1) {
sb.Append('_');
}
sb.Append(tolower(c));
} else {
sb.Append(c);
}
}
return sb.ToString();
}
size_t File::GetHashKey()
{
StringBuilder fileStr;
while (!IsEof()) {
fileStr.Append(GetChar());
}
return std::hash<std::string>()(fileStr.ToString().string());
}
} // namespace HDI
} // namespace OHOS
+8 -3
View File
@@ -47,7 +47,7 @@ public:
return columnNo_;
}
bool ReadData(void *data, size_t size) const;
size_t ReadData(void *data, size_t size) const;
bool WriteData(const void *data, size_t size) const;
@@ -63,6 +63,13 @@ public:
static String AdapterPath(const String &path);
static String RealPath(const String &path);
static bool CheckValid(const String &path);
// "FileName" -> "file_name"
static String Pascal2UnderScoreCase(const String &name);
size_t GetHashKey();
static constexpr unsigned int READ = 0x1;
@@ -78,8 +85,6 @@ public:
private:
int Read();
bool CheckValid(const String &path);
static constexpr int BUFFER_SIZE = 1024;
char buffer_[BUFFER_SIZE] = {0};
+75 -13
View File
@@ -117,12 +117,17 @@ void Options::AddPackagePath(const String &packagePath)
}
String package = packagePath.Substring(0, index);
String path = packagePath.Substring(index + 1);
String path = File::RealPath(packagePath.Substring(index + 1));
if (path.IsEmpty() || path.IsNull()) {
errors_.push_back(
String::Format("%s: invalid path '%s'.", program_.string(), packagePath.Substring(index + 1).string()));
return;
}
auto it = packagePath_.find(package);
if (it != packagePath_.end()) {
errors_.push_back(String::Format("%s: The '%s:%s' has been set.", program_.string(),
package.string(), path.string()));
errors_.push_back(
String::Format("%s: The '%s:%s' has been set.", program_.string(), package.string(), path.string()));
}
packagePath_[package] = path;
@@ -213,9 +218,9 @@ void Options::ShowUsage() const
/*
* For Example
* -r option: -r OHOS.Hdi:drivers/interface
* package:OHOS.Hdi.foo.v1_0
* rootPackage:OHOS.Hdi
* -r option: -r ohos.hdi:./drivers/interface
* package:ohos.hdi.foo.v1_0
* rootPackage:ohos.hdi
*/
String Options::GetRootPackage(const String &package)
{
@@ -226,13 +231,31 @@ String Options::GetRootPackage(const String &package)
}
}
return String("");
return "";
}
/*
* For Example
* -r option: -r OHOS.Hdi:drivers/interface
* package:OHOS.Hdi.foo.v1_0
* -r option: -r ohos.hdi:./drivers/interface
* package:ohos.hdi.foo.v1_0
* rootPath:./drivers/interface
*/
String Options::GetRootPath(const String &package)
{
const auto &packagePaths = GetPackagePath();
for (const auto &packageRoot : packagePaths) {
if (package.StartsWith(packageRoot.first)) {
return packageRoot.second;
}
}
return "";
}
/*
* For Example
* -r option: -r ohos.hdi:./drivers/interface
* package:ohos.hdi.foo.v1_0
* subPackage:foo.v1_0
*/
String Options::GetSubPackage(const String &package)
@@ -247,9 +270,29 @@ String Options::GetSubPackage(const String &package)
/*
* For Example
* -r option: -r OHOS.Hdi:drivers/interface
* package:OHOS.Hdi.foo.v1_0
* packagePath:drivers/interface/foo/v1_0
* -r option: -r ohos.hdi:./drivers/interface
* package:ohos.hdi.foo.v1_0
* subPackage:foo/v1_0
*/
String Options::GetSubPath(const String &package)
{
String rootPackage = GetRootPackage(package);
if (rootPackage.IsEmpty()) {
return package;
}
String subPath = package.Substring(rootPackage.GetLength() + 1).Replace('.', File::separator);
if (subPath.IsEmpty()) {
return "";
}
return subPath;
}
/*
* For Example
* -r option: -r ohos.hdi:./drivers/interface
* package:ohos.hdi.foo.v1_0
* packagePath:./drivers/interface/foo/v1_0
*/
String Options::GetPackagePath(const String &package)
{
@@ -271,7 +314,26 @@ String Options::GetPackagePath(const String &package)
rootPath = rootPath.Substring(0, rootPath.GetLength() - 1);
}
return package.Replace(rootPackage, rootPath).Replace('.', File::separator);
return package.Replace(0, rootPackage.GetLength(), rootPath).Replace('.', File::separator);
}
/*
* For Example
* -r option: -r ohos.hdi:./drivers/interface
* import: ohos.hdi.foo.v1_0.MyTypes
* packagePath:./drivers/interface/foo/v1_0/MyTypes.idl
*/
String Options::GetImportFilePath(const String &import)
{
int index = import.LastIndexOf('.');
if (index <= 0) {
return import;
}
String dir = GetPackagePath(import.Substring(0, index));
String ClassName = import.Substring(index + 1);
return String::Format("%s%c%s.idl", dir.string(), File::separator, ClassName.string());
}
} // namespace HDI
} // namespace OHOS
+6
View File
@@ -107,10 +107,16 @@ public:
String GetRootPackage(const String &package);
String GetRootPath(const String &package);
String GetSubPackage(const String &package);
String GetSubPath(const String &package);
String GetPackagePath(const String &package);
String GetImportFilePath(const String &import);
private:
Options()
: program_(),
+25 -7
View File
@@ -589,7 +589,7 @@ String String::Replace(const String &target, const String &replacement) const
return sb.ToString();
}
String &String::Replace(int position, int len, const String &other)
String String::Replace(int position, int len, const String &other) const
{
if (position < 0 || position > GetLength()) {
return *this;
@@ -605,13 +605,31 @@ String &String::Replace(int position, int len, const String &other)
String lStr = Substring(0, position);
String rStr = Substring(position + len);
String newStr;
newStr += lStr + other + rStr;
StringBuilder sb;
sb.Append(lStr).Append(other).Append(rStr);
return sb.ToString();
}
SharedData::Release(string_);
SharedData::AddRef(newStr.string_);
string_ = newStr.string_;
return *this;
std::vector<String> String::Split(const char separator) const
{
std::vector<String> result;
if (IsEmpty()) {
return result;
}
int startIndex = 0;
int endIndex = IndexOf(separator, startIndex);
while (endIndex != -1) {
result.push_back(Substring(startIndex, endIndex));
startIndex = endIndex + 1;
endIndex = IndexOf(separator, startIndex);
}
if (startIndex < GetLength()) {
result.push_back(Substring(startIndex));
}
return result;
}
std::vector<String> String::Split(const String &separator) const
+3 -1
View File
@@ -96,7 +96,9 @@ public:
String Replace(const String &target, const String &replacement) const;
String &Replace(int position, int len, const String &other);
String Replace(int position, int len, const String &other) const;
std::vector<String> Split(const char separator) const;
std::vector<String> Split(const String &separator) const;