blob: f56953c85da70271434f0153da1600f243599ccb [file] [log] [blame]
Dan Sinclair6e581892020-03-02 15:47:43 -05001
2// Copyright 2020 The Tint Authors.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#ifndef SRC_SOURCE_H_
17#define SRC_SOURCE_H_
18
Ben Clayton5bee67f2020-10-30 20:44:53 +000019#include <string>
20#include <vector>
21
Dan Sinclair6e581892020-03-02 15:47:43 -050022namespace tint {
23
Ben Clayton5bee67f2020-10-30 20:44:53 +000024/// Source describes a range of characters within a source file.
25class Source {
26 public:
Ben Clayton1d982362021-02-18 21:40:19 +000027 /// FileContent describes the content of a source file.
28 class FileContent {
29 public:
30 /// Constructs the FileContent with the given file content.
31 /// @param data the file contents
32 explicit FileContent(const std::string& data);
33
34 /// Destructor
35 ~FileContent();
36
37 /// un-split file content
38 const std::string data;
39 /// #data split by lines
40 const std::vector<std::string> lines;
41 };
42
Ben Clayton5bee67f2020-10-30 20:44:53 +000043 /// File describes a source file, including path and content.
44 class File {
45 public:
46 /// Constructs the File with the given file path and content.
Ben Clayton1d982362021-02-18 21:40:19 +000047 /// @param p the path for this file
48 /// @param c the file contents
49 inline File(const std::string& p, const std::string& c)
50 : path(p), content(c) {}
51
Ben Clayton5bee67f2020-10-30 20:44:53 +000052 ~File();
53
dan sinclair3d0e2732020-11-02 16:03:38 +000054 /// file path (optional)
55 const std::string path;
56 /// file content
Ben Clayton1d982362021-02-18 21:40:19 +000057 const FileContent content;
Ben Clayton5bee67f2020-10-30 20:44:53 +000058 };
59
60 /// Location holds a 1-based line and column index.
Ben Clayton5bee67f2020-10-30 20:44:53 +000061 class Location {
62 public:
Ben Clayton2d89d982020-11-02 18:02:18 +000063 /// the 1-based line number. 0 represents no line information.
Ben Clayton5bee67f2020-10-30 20:44:53 +000064 size_t line = 0;
Ben Clayton2d89d982020-11-02 18:02:18 +000065 /// the 1-based column number. 0 represents no column information.
Ben Clayton5bee67f2020-10-30 20:44:53 +000066 size_t column = 0;
67 };
68
69 /// Range holds a Location interval described by [begin, end).
70 class Range {
71 public:
72 /// Constructs a zero initialized Range.
73 inline Range() = default;
74
Ben Claytonf8971ae2020-12-02 15:31:08 +000075 /// Constructs a zero-length Range starting at `loc`
76 /// @param loc the start and end location for the range
Ben Clayton5bee67f2020-10-30 20:44:53 +000077 inline explicit Range(const Location& loc) : begin(loc), end(loc) {}
78
Ben Claytonf8971ae2020-12-02 15:31:08 +000079 /// Constructs the Range beginning at `b` and ending at `e`
80 /// @param b the range start location
81 /// @param e the range end location
Ben Clayton5bee67f2020-10-30 20:44:53 +000082 inline Range(const Location& b, const Location& e) : begin(b), end(e) {}
83
Ben Clayton6d612ad2021-02-24 14:15:02 +000084 /// Return a column-shifted Range
85 /// @param n the number of characters to shift by
86 /// @returns a Range with a #begin and #end column shifted by `n`
87 inline Range operator+(size_t n) const {
88 return Range{{begin.line, begin.column + n}, {end.line, end.column + n}};
89 }
90
dan sinclair3d0e2732020-11-02 16:03:38 +000091 /// The location of the first character in the range.
92 Location begin;
93 /// The location of one-past the last character in the range.
94 Location end;
Ben Clayton5bee67f2020-10-30 20:44:53 +000095 };
96
97 /// Constructs the Source with an zero initialized Range and null File.
Ben Clayton1d982362021-02-18 21:40:19 +000098 inline Source() : range() {}
Ben Clayton5bee67f2020-10-30 20:44:53 +000099
Ben Claytonf8971ae2020-12-02 15:31:08 +0000100 /// Constructs the Source with the Range `rng` and a null File
Ben Clayton2d89d982020-11-02 18:02:18 +0000101 /// @param rng the source range
Ben Clayton5bee67f2020-10-30 20:44:53 +0000102 inline explicit Source(const Range& rng) : range(rng) {}
103
Ben Claytonf8971ae2020-12-02 15:31:08 +0000104 /// Constructs the Source with the Range `loc` and a null File
Ben Clayton2d89d982020-11-02 18:02:18 +0000105 /// @param loc the start and end location for the source range
Ben Clayton5bee67f2020-10-30 20:44:53 +0000106 inline explicit Source(const Location& loc) : range(Range(loc)) {}
107
Ben Clayton1d982362021-02-18 21:40:19 +0000108 /// Constructs the Source with the Range `rng` and File `file`
Ben Clayton2d89d982020-11-02 18:02:18 +0000109 /// @param rng the source range
Ben Clayton1d982362021-02-18 21:40:19 +0000110 /// @param file the source file
111 inline Source(const Range& rng, File const* file)
112 : range(rng), file_path(file->path), file_content(&file->content) {}
Ben Clayton5bee67f2020-10-30 20:44:53 +0000113
Ben Clayton1d982362021-02-18 21:40:19 +0000114 /// Constructs the Source with the Range `rng`, file path `path` and content
115 /// `content`
116 /// @param rng the source range
117 /// @param path the source file path
118 /// @param content the source file content
119 inline Source(const Range& rng,
120 const std::string& path,
Ben Clayton33a8cdd2021-02-24 13:31:22 +0000121 const FileContent* content = nullptr)
Ben Clayton1d982362021-02-18 21:40:19 +0000122 : range(rng), file_path(path), file_content(content) {}
123
Ben Clayton33a8cdd2021-02-24 13:31:22 +0000124 /// @returns a Source that points to the begin range of this Source.
125 inline Source Begin() const {
126 return Source(Range{range.begin}, file_path, file_content);
127 }
128
129 /// @returns a Source that points to the end range of this Source.
130 inline Source End() const {
131 return Source(Range{range.end}, file_path, file_content);
132 }
133
Ben Clayton6d612ad2021-02-24 14:15:02 +0000134 /// Return a column-shifted Source
135 /// @param n the number of characters to shift by
136 /// @returns a Source with the range's columns shifted by `n`
137 inline Source operator+(size_t n) const {
138 return Source(range + n, file_path, file_content);
139 }
140
Ben Clayton1d982362021-02-18 21:40:19 +0000141 /// range is the span of text this source refers to in #file_path
Ben Clayton5bee67f2020-10-30 20:44:53 +0000142 Range range;
Ben Clayton1d982362021-02-18 21:40:19 +0000143 /// file is the optional file path this source refers to
144 std::string file_path;
145 /// file is the optional source content this source refers to
146 const FileContent* file_content = nullptr;
Dan Sinclair6e581892020-03-02 15:47:43 -0500147};
148
Ben Clayton1d982362021-02-18 21:40:19 +0000149/// Writes the Source::FileContent to the std::ostream.
150/// @param out the std::ostream to write to
151/// @param content the file content to write
152/// @returns out so calls can be chained
153inline std::ostream& operator<<(std::ostream& out,
154 const Source::FileContent& content) {
155 out << content.data;
156 return out;
157}
158
Dan Sinclair6e581892020-03-02 15:47:43 -0500159} // namespace tint
160
161#endif // SRC_SOURCE_H_