blob: 416a30e2cd4b071b30560d94bdaf4bfba5b4018d [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
Antonio Maiorano6ce58be2021-03-09 21:51:50 +000019#include <iostream>
Ben Clayton5bee67f2020-10-30 20:44:53 +000020#include <string>
21#include <vector>
22
Dan Sinclair6e581892020-03-02 15:47:43 -050023namespace tint {
24
Ben Clayton5bee67f2020-10-30 20:44:53 +000025/// Source describes a range of characters within a source file.
26class Source {
27 public:
Ben Clayton1d982362021-02-18 21:40:19 +000028 /// FileContent describes the content of a source file.
29 class FileContent {
30 public:
31 /// Constructs the FileContent with the given file content.
32 /// @param data the file contents
33 explicit FileContent(const std::string& data);
34
35 /// Destructor
36 ~FileContent();
37
38 /// un-split file content
39 const std::string data;
40 /// #data split by lines
41 const std::vector<std::string> lines;
42 };
43
Ben Clayton5bee67f2020-10-30 20:44:53 +000044 /// File describes a source file, including path and content.
45 class File {
46 public:
47 /// Constructs the File with the given file path and content.
Ben Clayton1d982362021-02-18 21:40:19 +000048 /// @param p the path for this file
49 /// @param c the file contents
50 inline File(const std::string& p, const std::string& c)
51 : path(p), content(c) {}
52
Ben Clayton5bee67f2020-10-30 20:44:53 +000053 ~File();
54
dan sinclair3d0e2732020-11-02 16:03:38 +000055 /// file path (optional)
56 const std::string path;
57 /// file content
Ben Clayton1d982362021-02-18 21:40:19 +000058 const FileContent content;
Ben Clayton5bee67f2020-10-30 20:44:53 +000059 };
60
61 /// Location holds a 1-based line and column index.
Ben Clayton5bee67f2020-10-30 20:44:53 +000062 class Location {
63 public:
Ben Clayton2d89d982020-11-02 18:02:18 +000064 /// the 1-based line number. 0 represents no line information.
Ben Clayton5bee67f2020-10-30 20:44:53 +000065 size_t line = 0;
Ben Clayton2d89d982020-11-02 18:02:18 +000066 /// the 1-based column number. 0 represents no column information.
Ben Clayton5bee67f2020-10-30 20:44:53 +000067 size_t column = 0;
68 };
69
70 /// Range holds a Location interval described by [begin, end).
71 class Range {
72 public:
73 /// Constructs a zero initialized Range.
74 inline Range() = default;
75
Ben Claytonf8971ae2020-12-02 15:31:08 +000076 /// Constructs a zero-length Range starting at `loc`
77 /// @param loc the start and end location for the range
Ben Clayton5bee67f2020-10-30 20:44:53 +000078 inline explicit Range(const Location& loc) : begin(loc), end(loc) {}
79
Ben Claytonf8971ae2020-12-02 15:31:08 +000080 /// Constructs the Range beginning at `b` and ending at `e`
81 /// @param b the range start location
82 /// @param e the range end location
Ben Clayton5bee67f2020-10-30 20:44:53 +000083 inline Range(const Location& b, const Location& e) : begin(b), end(e) {}
84
Ben Clayton6d612ad2021-02-24 14:15:02 +000085 /// Return a column-shifted Range
86 /// @param n the number of characters to shift by
87 /// @returns a Range with a #begin and #end column shifted by `n`
88 inline Range operator+(size_t n) const {
89 return Range{{begin.line, begin.column + n}, {end.line, end.column + n}};
90 }
91
dan sinclair3d0e2732020-11-02 16:03:38 +000092 /// The location of the first character in the range.
93 Location begin;
94 /// The location of one-past the last character in the range.
95 Location end;
Ben Clayton5bee67f2020-10-30 20:44:53 +000096 };
97
98 /// Constructs the Source with an zero initialized Range and null File.
Ben Clayton1d982362021-02-18 21:40:19 +000099 inline Source() : range() {}
Ben Clayton5bee67f2020-10-30 20:44:53 +0000100
Ben Claytonf8971ae2020-12-02 15:31:08 +0000101 /// Constructs the Source with the Range `rng` and a null File
Ben Clayton2d89d982020-11-02 18:02:18 +0000102 /// @param rng the source range
Ben Clayton5bee67f2020-10-30 20:44:53 +0000103 inline explicit Source(const Range& rng) : range(rng) {}
104
Ben Claytonf8971ae2020-12-02 15:31:08 +0000105 /// Constructs the Source with the Range `loc` and a null File
Ben Clayton2d89d982020-11-02 18:02:18 +0000106 /// @param loc the start and end location for the source range
Ben Clayton5bee67f2020-10-30 20:44:53 +0000107 inline explicit Source(const Location& loc) : range(Range(loc)) {}
108
Ben Clayton1d982362021-02-18 21:40:19 +0000109 /// Constructs the Source with the Range `rng` and File `file`
Ben Clayton2d89d982020-11-02 18:02:18 +0000110 /// @param rng the source range
Ben Clayton1d982362021-02-18 21:40:19 +0000111 /// @param file the source file
112 inline Source(const Range& rng, File const* file)
113 : range(rng), file_path(file->path), file_content(&file->content) {}
Ben Clayton5bee67f2020-10-30 20:44:53 +0000114
Ben Clayton1d982362021-02-18 21:40:19 +0000115 /// Constructs the Source with the Range `rng`, file path `path` and content
116 /// `content`
117 /// @param rng the source range
118 /// @param path the source file path
119 /// @param content the source file content
120 inline Source(const Range& rng,
121 const std::string& path,
Ben Clayton33a8cdd2021-02-24 13:31:22 +0000122 const FileContent* content = nullptr)
Ben Clayton1d982362021-02-18 21:40:19 +0000123 : range(rng), file_path(path), file_content(content) {}
124
Ben Clayton33a8cdd2021-02-24 13:31:22 +0000125 /// @returns a Source that points to the begin range of this Source.
126 inline Source Begin() const {
127 return Source(Range{range.begin}, file_path, file_content);
128 }
129
130 /// @returns a Source that points to the end range of this Source.
131 inline Source End() const {
132 return Source(Range{range.end}, file_path, file_content);
133 }
134
Ben Clayton6d612ad2021-02-24 14:15:02 +0000135 /// Return a column-shifted Source
136 /// @param n the number of characters to shift by
137 /// @returns a Source with the range's columns shifted by `n`
138 inline Source operator+(size_t n) const {
139 return Source(range + n, file_path, file_content);
140 }
141
Ben Clayton1d982362021-02-18 21:40:19 +0000142 /// range is the span of text this source refers to in #file_path
Ben Clayton5bee67f2020-10-30 20:44:53 +0000143 Range range;
Ben Clayton1d982362021-02-18 21:40:19 +0000144 /// file is the optional file path this source refers to
145 std::string file_path;
146 /// file is the optional source content this source refers to
147 const FileContent* file_content = nullptr;
Dan Sinclair6e581892020-03-02 15:47:43 -0500148};
149
Ben Clayton1d982362021-02-18 21:40:19 +0000150/// Writes the Source::FileContent to the std::ostream.
151/// @param out the std::ostream to write to
152/// @param content the file content to write
153/// @returns out so calls can be chained
154inline std::ostream& operator<<(std::ostream& out,
155 const Source::FileContent& content) {
156 out << content.data;
157 return out;
158}
159
Dan Sinclair6e581892020-03-02 15:47:43 -0500160} // namespace tint
161
162#endif // SRC_SOURCE_H_