blob: 55cc3b9c8434b2025467ebefa6ef48414e9a01b0 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package com.google.devtools.build.lib.syntax;
15
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010016import com.google.common.collect.ImmutableList;
Googlerf0890f02019-10-01 07:28:48 -070017import java.util.Collections;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010018import java.util.List;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010019import javax.annotation.Nullable;
20
Googlerf0890f02019-10-01 07:28:48 -070021/**
22 * Syntax tree for a Starlark file, such as a Bazel BUILD or .bzl file.
23 *
24 * <p>Call {@link #parse} to parse a file. Parser errors are recorded in the syntax tree (see {@link
25 * #errors}), which may be incomplete.
26 */
27public final class StarlarkFile extends Node {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010028
brandjon990622b2017-07-11 19:56:45 +020029 private final ImmutableList<Statement> statements;
adonovan034220a2020-03-24 10:11:26 -070030 private final FileOptions options;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010031 private final ImmutableList<Comment> comments;
adonovanc7434352020-04-24 09:05:50 -070032 final List<SyntaxError> errors; // appended to by Resolver
Lukacs Berkif445ea12015-07-09 07:16:41 +000033
adonovan73509462020-04-27 15:19:33 -070034 // set by resolver
35 @Nullable Resolver.Function resolved;
36
adonovan07b15e62020-04-09 18:32:33 -070037 @Override
38 public int getStartOffset() {
39 return 0;
40 }
41
42 @Override
43 public int getEndOffset() {
adonovand51ac9b2020-04-10 10:15:08 -070044 return locs.size();
adonovan07b15e62020-04-09 18:32:33 -070045 }
46
Googler66d099e2019-09-26 08:07:06 -070047 private StarlarkFile(
adonovand51ac9b2020-04-10 10:15:08 -070048 FileLocations locs,
brandjon990622b2017-07-11 19:56:45 +020049 ImmutableList<Statement> statements,
adonovan034220a2020-03-24 10:11:26 -070050 FileOptions options,
51 ImmutableList<Comment> comments,
adonovan4a997742020-05-08 05:45:27 -070052 List<SyntaxError> errors) {
adonovand51ac9b2020-04-10 10:15:08 -070053 super(locs);
brandjon990622b2017-07-11 19:56:45 +020054 this.statements = statements;
adonovan034220a2020-03-24 10:11:26 -070055 this.options = options;
Laurent Le Brun8c8857d2016-08-04 10:22:16 +000056 this.comments = comments;
Googlerf0890f02019-10-01 07:28:48 -070057 this.errors = errors;
Miguel Alcon Pinto927f3b22016-08-22 14:21:30 +000058 }
59
adonovan034220a2020-03-24 10:11:26 -070060 // Creates a StarlarkFile from the given effective list of statements,
61 // which may include the prelude.
Googler66d099e2019-09-26 08:07:06 -070062 private static StarlarkFile create(
adonovand51ac9b2020-04-10 10:15:08 -070063 FileLocations locs,
adonovan034220a2020-03-24 10:11:26 -070064 ImmutableList<Statement> statements,
65 FileOptions options,
adonovan4a997742020-05-08 05:45:27 -070066 Parser.ParseResult result) {
adonovand51ac9b2020-04-10 10:15:08 -070067 return new StarlarkFile(
adonovan4a997742020-05-08 05:45:27 -070068 locs, statements, options, ImmutableList.copyOf(result.comments), result.errors);
Damien Martin-Guillerez5e95a462016-02-05 22:32:08 +000069 }
70
adonovan034220a2020-03-24 10:11:26 -070071 /** Extract a subtree containing only statements from i (included) to j (excluded). */
72 public StarlarkFile subTree(int i, int j) {
adonovand51ac9b2020-04-10 10:15:08 -070073 return new StarlarkFile(
74 this.locs,
75 this.statements.subList(i, j),
76 this.options,
77 /*comments=*/ ImmutableList.of(),
adonovan4a997742020-05-08 05:45:27 -070078 errors);
Miguel Alcon Pinto927f3b22016-08-22 14:21:30 +000079 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010080 /**
Googlerf0890f02019-10-01 07:28:48 -070081 * Returns an unmodifiable view of the list of scanner, parser, and (perhaps) resolver errors
82 * accumulated in this Starlark file.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010083 */
adonovanac1c41e2020-04-01 14:28:49 -070084 public List<SyntaxError> errors() {
Googlerf0890f02019-10-01 07:28:48 -070085 return Collections.unmodifiableList(errors);
86 }
87
88 /** Returns errors().isEmpty(). */
89 public boolean ok() {
90 return errors.isEmpty();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010091 }
92
Googlerf0890f02019-10-01 07:28:48 -070093 /** Returns an (immutable, ordered) list of statements in this BUILD file. */
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010094 public ImmutableList<Statement> getStatements() {
brandjon990622b2017-07-11 19:56:45 +020095 return statements;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010096 }
97
Googlerf0890f02019-10-01 07:28:48 -070098 /** Returns an (immutable, ordered) list of comments in this BUILD file. */
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010099 public ImmutableList<Comment> getComments() {
100 return comments;
101 }
102
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100103 @Override
104 public String toString() {
Googler66d099e2019-09-26 08:07:06 -0700105 return "<StarlarkFile with " + statements.size() + " statements>";
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100106 }
107
108 @Override
Googler4ace4652019-09-16 07:47:08 -0700109 public void accept(NodeVisitor visitor) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100110 visitor.visit(this);
111 }
112
113 /**
adonovan034220a2020-03-24 10:11:26 -0700114 * Parse the specified file, returning its syntax tree with the prelude statements inserted at the
Googlerf0890f02019-10-01 07:28:48 -0700115 * front of its statement list.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100116 */
Googler66d099e2019-09-26 08:07:06 -0700117 public static StarlarkFile parseWithPrelude(
adonovan034220a2020-03-24 10:11:26 -0700118 ParserInput input, List<Statement> prelude, FileOptions options) {
119 Parser.ParseResult result = Parser.parseFile(input, options);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100120
adonovan034220a2020-03-24 10:11:26 -0700121 ImmutableList.Builder<Statement> stmts = ImmutableList.builder();
122 stmts.addAll(prelude);
123 stmts.addAll(result.statements);
124
adonovan4a997742020-05-08 05:45:27 -0700125 return create(result.locs, stmts.build(), options, result);
Miguel Alcon Pinto927f3b22016-08-22 14:21:30 +0000126 }
127
Googlerf0890f02019-10-01 07:28:48 -0700128 /**
129 * Parse a Starlark file.
130 *
131 * <p>A syntax tree is always returned, even in case of error. Errors are recorded in the tree.
132 * Example usage:
133 *
134 * <pre>
adonovan034220a2020-03-24 10:11:26 -0700135 * StarlarkFile file = StarlarkFile.parse(input, options);
Googlerf0890f02019-10-01 07:28:48 -0700136 * if (!file.ok()) {
137 * Event.replayEventsOn(handler, file.errors());
138 * ...
139 * }
140 * </pre>
141 */
adonovan034220a2020-03-24 10:11:26 -0700142 public static StarlarkFile parse(ParserInput input, FileOptions options) {
143 Parser.ParseResult result = Parser.parseFile(input, options);
adonovan4a997742020-05-08 05:45:27 -0700144 return create(result.locs, ImmutableList.copyOf(result.statements), options, result);
adonovan034220a2020-03-24 10:11:26 -0700145 }
146
147 /** Parse a Starlark file with default options. */
148 public static StarlarkFile parse(ParserInput input) {
149 return parse(input, FileOptions.DEFAULT);
150 }
151
152 /** Returns the options specified when parsing this file. */
153 public FileOptions getOptions() {
154 return options;
laurentlb04b4c662017-08-07 20:03:40 +0200155 }
adonovan83290682020-05-18 09:08:43 -0700156
adonovan09d13702020-05-19 08:26:55 -0700157 /** Returns the name of this file, as specified to the parser. */
158 public String getName() {
159 return locs.file();
160 }
161
adonovan83290682020-05-18 09:08:43 -0700162 /** A ParseProfiler records the start and end times of parse operations. */
163 public interface ParseProfiler {
164 Object start(String filename);
165
166 void end(Object span);
167 }
168
169 /** Installs a global hook that will be notified of parse operations. */
170 public static void setParseProfiler(@Nullable ParseProfiler p) {
171 Parser.profiler = p;
172 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100173}