mirror of
https://github.com/openharmony/drivers_framework.git
synced 2026-08-27 10:51:15 -04:00
!1011 fix:add sequenceable and expression function
Merge pull request !1011 from yue/master
This commit is contained in:
@@ -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 $@
|
||||
|
||||
@@ -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 $@
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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_;
|
||||
};
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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> ¶meter);
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, "")
|
||||
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
+1093
-1109
File diff suppressed because it is too large
Load Diff
@@ -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> ¶meter);
|
||||
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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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};
|
||||
|
||||
@@ -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
|
||||
@@ -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_(),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user