1
2
3
4
5
6 #include <sngcpp/ast/SourceFile.hpp>
7 #include <sngcpp/ast/Visitor.hpp>
8 #include <sngcpp/ast/Writer.hpp>
9 #include <sngcpp/ast/Reader.hpp>
10 #include <soulng/util/Unicode.hpp>
11 #include <soulng/util/Sha1.hpp>
12
13 namespace sngcpp { namespace ast {
14
15 using namespace soulng::unicode;
16 using namespace soulng::util;
17
18 SourceFileNode::SourceFileNode() : Node(NodeType::sourceFileNode), sourceFileIndex(-1), processed()
19 {
20 }
21
22 SourceFileNode::SourceFileNode(const Span& span_, const std::string& sourceFilePath_, const std::string& relativeSourceFilePath_, const std::u32string& projectName_) :
23 Node(NodeType::sourceFileNode, span_), globalNs(new NamespaceNode(span_)), sourceFilePath(sourceFilePath_), relativeSourceFilePath(relativeSourceFilePath_), projectName(projectName_),
24 sourceFileIndex(-1), processed(false)
25 {
26 std::string fileName = relativeSourceFilePath;
27 for (char& c : fileName)
28 {
29 if (c == '/' || c == '\\' || c == ':')
30 {
31 c = '_';
32 }
33 }
34 fileName.append(1, '_').append(GetSha1MessageDigest(sourceFilePath));
35 fileName.append(".html");
36 id = U"file/" + ToUtf32(fileName);
37 }
38
39 void SourceFileNode::AddUsingDirectiveOrDeclaration(Node* usingDirectivesAndDeclaration)
40 {
41 usingDirectivesAndDeclarations.push_back(usingDirectivesAndDeclaration);
42 }
43
44 void SourceFileNode::Accept(Visitor& visitor)
45 {
46 visitor.Visit(*this);
47 }
48
49 void SourceFileNode::Write(Writer& writer)
50 {
51 Node::Write(writer);
52 writer.GetBinaryWriter().Write(sourceFilePath);
53 writer.GetBinaryWriter().Write(relativeSourceFilePath);
54 writer.GetBinaryWriter().Write(projectName);
55 writer.GetBinaryWriter().Write(htmlSourceFilePath);
56 writer.GetBinaryWriter().Write(id);
57 globalNs->Write(writer);
58 int32_t n = lineStarts.size();
59 writer.GetBinaryWriter().Write(n);
60 for (int32_t i = 0; i < n; ++i)
61 {
62 writer.GetBinaryWriter().Write(int32_t(lineStarts[i]));
63 }
64 int32_t numHeaderfiles = headerFilePaths.size();
65 writer.GetBinaryWriter().Write(numHeaderfiles);
66 for (int32_t i = 0; i < numHeaderfiles; ++i)
67 {
68 writer.GetBinaryWriter().Write(headerFilePaths[i]);
69 }
70 writer.GetBinaryWriter().Write(text);
71 }
72
73 void SourceFileNode::Read(Reader& reader)
74 {
75 Node::Read(reader);
76 sourceFilePath = reader.GetBinaryReader().ReadUtf8String();
77 relativeSourceFilePath = reader.GetBinaryReader().ReadUtf8String();
78 projectName = reader.GetBinaryReader().ReadUtf32String();
79 htmlSourceFilePath = reader.GetBinaryReader().ReadUtf8String();
80 id = reader.GetBinaryReader().ReadUtf32String();
81 globalNs.reset(reader.ReadNamespaceNode());
82 int32_t n = reader.GetBinaryReader().ReadInt();
83 for (int32_t i = 0; i < n; ++i)
84 {
85 lineStarts.push_back(reader.GetBinaryReader().ReadInt());
86 }
87 int32_t numHeaderfiles = reader.GetBinaryReader().ReadInt();
88 for (int32_t i = 0; i < numHeaderfiles; ++i)
89 {
90 headerFilePaths.push_back(reader.GetBinaryReader().ReadUtf8String());
91 }
92 text = reader.GetBinaryReader().ReadUtf32String();
93 }
94
95 void SourceFileNode::ComputeLineStarts()
96 {
97 int index = 0;
98 bool startOfLine = true;
99 for (char32_t c : text)
100 {
101 if (startOfLine)
102 {
103 lineStarts.push_back(index);
104 startOfLine = false;
105 }
106 if (c == U'\n')
107 {
108 startOfLine = true;
109 }
110 ++index;
111 }
112 }
113
114 SourceFileSequenceNode::SourceFileSequenceNode() : BinaryNode(NodeType::sourceFileSequenceNode)
115 {
116 }
117
118 SourceFileSequenceNode::SourceFileSequenceNode(const Span& span_, Node* left_, Node* right_) : BinaryNode(NodeType::sourceFileSequenceNode, span_, left_, right_)
119 {
120 }
121
122 void SourceFileSequenceNode::Accept(Visitor& visitor)
123 {
124 visitor.Visit(*this);
125 }
126
127 class SourceFileResolverVisitor : public Visitor
128 {
129 public:
130 SourceFileResolverVisitor(std::std::vector<SourceFileNode*>&sourceFiles_):sourceFiles(sourceFiles_)
131 {
132 }
133 void Visit(SourceFileNode& sourceFileNode) override
134 {
135 sourceFiles.push_back(&sourceFileNode);
136 }
137 void Visit(SourceFileSequenceNode& sourceFileSequenceNode) override
138 {
139 sourceFileSequenceNode.Left()->Accept(*this);
140 sourceFileSequenceNode.Right()->Accept(*this);
141 }
142 private:
143 std::std::vector<SourceFileNode*>&sourceFiles;
144 };
145
146 void ResolveSourceFiles(Node* ast, std::std::vector<SourceFileNode*>&sourceFiles)
147 {
148 SourceFileResolverVisitor resolver(sourceFiles);
149 ast->Accept(resolver);
150 }
151
152 } }