aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Laszlo Csomor <laszlocsomor@google.com>2015-02-16 16:57:12 +0000
committerGravatar Han-Wen Nienhuys <hanwen@google.com>2015-02-16 16:57:12 +0000
commitaded1c2dbd0e06e60ff768094ab9efcc9c680911 (patch)
tree34a70b2e26176edafce88a0949e5a17d15a96723
parent924daad8869c679b09b687e87f3b829da1dc4d3a (diff)
Lots of comments, clarification and correction in Skylark docs.
-- MOS_MIGRATED_REVID=86436572
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/Artifact.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/MethodLibrary.java36
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/SkylarkFileType.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java13
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkCommandLine.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java35
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/Label.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java5
12 files changed, 80 insertions, 62 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
index 2f2272b378..95bb3abbfa 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
@@ -329,13 +329,20 @@ public class Artifact implements FileType.HasFilename, Comparable<Artifact>, Act
*/
@Override
@SkylarkCallable(name = "path", structField = true,
- doc = "The execution path of this file, relative to the execution directory.")
+ doc = "The execution path of this file, relative to the execution directory. It consists of "
+ + "two parts, an optional first part called the <i>root</i> (see also the <a "
+ + "href=\"#modules.root\">root</a> module), and the second part which is the "
+ + "<code>short_path</code>. The root may be empty, which it usually is for non-generated "
+ + "files. For generated files it usually contains a configuration-specific path fragment that"
+ + " encodes things like the target CPU architecture that was used while building said file.")
public final String getExecPathString() {
return getExecPath().getPathString();
}
@SkylarkCallable(name = "short_path", structField = true,
- doc = "The path of this file relative to its root.")
+ doc = "The path of this file relative to its root. This excludes the aforementioned "
+ + "<i>root</i>, i.e. configuration-specific fragments of the path. This is also the path "
+ + "under which the file is mapped if its in the runfiles of a binary.")
public final String getRootRelativePathString() {
return getRootRelativePath().getPathString();
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
index 8e80211b10..5fac33d7a4 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
@@ -1393,7 +1393,7 @@ public final class BuildConfiguration implements Serializable {
* the native path separator, i.e., the path separator for the machine that they run on.
*/
@SkylarkCallable(name = "host_path_separator", structField = true,
- doc = "Returns the separator for PATH variable, which is ':' on Unix.")
+ doc = "Returns the separator for PATH environment variable, which is ':' on Unix.")
public String getHostPathSeparator() {
// TODO(bazel-team): This needs to change when we support Windows.
return ":";
diff --git a/src/main/java/com/google/devtools/build/lib/packages/MethodLibrary.java b/src/main/java/com/google/devtools/build/lib/packages/MethodLibrary.java
index 65b4540965..4430ba7f87 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/MethodLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/MethodLibrary.java
@@ -598,14 +598,15 @@ public class MethodLibrary {
};
@SkylarkBuiltin(name = "set", returnType = SkylarkNestedSet.class,
- doc = "Creates a set from the <code>items</code>, that supports nesting. "
- + "The nesting is applied to other nested sets among <code>items</code>.<br>"
- + "Examples:<br>"
- + "<pre class=language-python>set([1, set([2, 3]), 2])\n"
- + "set([1, 2, 3], order=\"compile\")</pre>",
+ doc = "Creates a set from the <code>items</code>. The set supports nesting other sets of the"
+ + " same element type in it. For this reason sets are also referred to as <i>nested sets</i>"
+ + " (all Skylark sets are nested sets). A desired iteration order can also be specified.<br>"
+ + " Examples:<br><pre class=language-python>set([1, set([2, 3]), 2])\n"
+ + "set([1, 2, 3], order=\"compile\")</pre>",
optionalParams = {
@Param(name = "items", type = SkylarkList.class,
- doc = "The items to initialize the set with."),
+ doc = "The items to initialize the set with. May contain both standalone items and other"
+ + " sets."),
@Param(name = "order", type = String.class,
doc = "The ordering strategy for the set if it's nested, "
+ "possible values are: <code>stable</code> (default), <code>compile</code>, "
@@ -636,8 +637,8 @@ public class MethodLibrary {
};
@SkylarkBuiltin(name = "enumerate", returnType = SkylarkList.class,
- doc = "Return a list of pairs, with the index (int) and the item from the input list.\n"
- + "<pre class=language-python>"
+ doc = "Return a list of pairs (two-element lists), with the index (int) and the item from"
+ + " the input list.\n<pre class=language-python>"
+ "enumerate([24, 21, 84]) == [[0, 24], [1, 21], [2, 84]]</pre>\n",
mandatoryParams = {
@Param(name = "list", type = SkylarkList.class,
@@ -660,7 +661,7 @@ public class MethodLibrary {
};
@SkylarkBuiltin(name = "range", returnType = SkylarkList.class,
- doc = "Creates a list where items go from <code>start</code> to <end>, using a "
+ doc = "Creates a list where items go from <code>start</code> to <code>end</code>, using a "
+ "<code>step</code> increment. If a single argument is provided, items will "
+ "range from 0 to that element."
+ "<pre class=language-python>range(4) == [0, 1, 2, 3]\n"
@@ -671,9 +672,10 @@ public class MethodLibrary {
doc = "Value of the first element"),
},
optionalParams = {
- @Param(name = "end", type = SkylarkList.class,
- doc = "Generation of the list stops before <code>end</code> is reached."),
- @Param(name = "step", type = String.class,
+ @Param(name = "end", type = Integer.class,
+ doc = "The first item <i>not</i> to be included in the resulting list; "
+ + "generation of the list stops before <code>end</code> is reached."),
+ @Param(name = "step", type = Integer.class,
doc = "The increment (default is 1). It may be negative.")})
private static final Function range =
new MixedModeFunction("range", ImmutableList.of("start", "stop", "step"), 1, false) {
@@ -684,10 +686,10 @@ public class MethodLibrary {
int stop;
if (args[1] == null) {
start = 0;
- stop = Type.INTEGER.convert(args[0], "stop");
+ stop = Type.INTEGER.convert(args[0], "end");
} else {
start = Type.INTEGER.convert(args[0], "start");
- stop = Type.INTEGER.convert(args[1], "stop");
+ stop = Type.INTEGER.convert(args[1], "end");
}
int step = args[2] == null ? 1 : Type.INTEGER.convert(args[2], "step");
if (step == 0) {
@@ -800,7 +802,7 @@ public class MethodLibrary {
};
@SkylarkBuiltin(name = "dir", returnType = SkylarkList.class,
- doc = "Returns the list of the names (list of strings) of the fields and "
+ doc = "Returns a list strings: the names of the fields and "
+ "methods of the parameter object.",
mandatoryParams = {@Param(name = "object", doc = "The object to check.")})
private static final Function dir = new MixedModeFunction(
@@ -909,9 +911,9 @@ public class MethodLibrary {
+ "c = \"\"\"multiline string\"\"\"</pre>"
+ "Strings are iterable and support the <code>in</code> operator. Examples:<br>"
+ "<pre class=language-python>\"a\" in \"abc\" # evaluates as True\n"
- + "l = []\n"
+ + "x = []\n"
+ "for s in \"abc\":\n"
- + " l += [s] # l == [\"a\", \"b\", \"c\"]</pre>")
+ + " x += [s] # x == [\"a\", \"b\", \"c\"]</pre>")
public static final class StringModule {}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkFileType.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkFileType.java
index f6098cfeba..73cfd6e051 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkFileType.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkFileType.java
@@ -24,7 +24,9 @@ import com.google.devtools.build.lib.util.FileTypeSet;
/**
* A wrapper class for FileType and FileTypeSet functionality in Skylark.
*/
-@SkylarkModule(name = "FileType", doc = "File type for file filtering.")
+@SkylarkModule(name = "FileType",
+ doc = "File type for file filtering. Can be used to filter collections of labels for certain "
+ + "file types.")
public class SkylarkFileType {
private final FileType fileType;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
index dfd6a9276d..4907ad83ab 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
@@ -48,14 +48,14 @@ import java.util.Map;
public final class SkylarkAttr {
private static final String MANDATORY_DOC =
- "set to true if users have to explicitely specify the value";
+ "set to True if users have to explicitely specify the value";
private static final String ALLOW_FILES_DOC =
"whether File targets are allowed. Can be True, False (default), or "
+ "a FileType filter.";
private static final String ALLOW_RULES_DOC =
- "which rule targets (name of the classes) are allowed."
+ "which rule targets (name of the classes) are allowed. "
+ "This is deprecated (kept only for compatiblity), use providers instead.";
private static final String FLAGS_DOC =
@@ -69,8 +69,9 @@ public final class SkylarkAttr {
+ "For example, use DATA_CFG or HOST_CFG.";
private static final String EXECUTABLE_DOC =
- "set to True if the labels have to be executable. Access the labels with "
- + "ctx.executable.<attribute_name>";
+ "set to True if the labels have to be executable. This means the label refers to an "
+ + "executable file, or to a rule that outputs an executable file. Access the labels with "
+ + "<code>ctx.executable.&lt;attribute_name&gt;</code>.";
private static Attribute.Builder<?> createAttribute(Type<?> type, Map<String, Object> arguments,
FuncallExpression ast, SkylarkEnvironment env) throws EvalException, ConversionException {
@@ -202,8 +203,8 @@ public final class SkylarkAttr {
@Param(name = "allow_rules", type = SkylarkList.class, generic1 = String.class,
doc = ALLOW_RULES_DOC),
@Param(name = "single_file", doc =
- "if true, the label must correspond to a single File. "
- + "Access it through ctx.file.<attribute_name>."),
+ "if True, the label must correspond to a single File. "
+ + "Access it through <code>ctx.file.&lt;attribute_name&gt;</code>."),
@Param(name = "cfg", type = ConfigurationTransition.class, doc = CONFIGURATION_DOC)})
private static SkylarkFunction label = new SkylarkFunction("label") {
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkCommandLine.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkCommandLine.java
index e51805e3e3..dbf72184a0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkCommandLine.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkCommandLine.java
@@ -67,8 +67,9 @@ public class SkylarkCommandLine {
@Param(name = "items", type = SkylarkNestedSet.class, generic1 = Artifact.class,
doc = "The set of structs to transform."),
@Param(name = "template", type = String.class,
- doc = "The template to use for the transformation, %{path} and %{short_path} "
- + "being substituted with the corresponding fields of each file.")})
+ doc = "The template to use for the transformation, <code>%{path}</code> and "
+ + "<code>%{short_path}</code> being substituted with the corresponding fields of each"
+ + " file.")})
private static SimpleSkylarkFunction template = new SimpleSkylarkFunction("template") {
@Override
public Object call(Map<String, Object> params, Location loc)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
index 4fe9cf0863..37cd3986bb 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
@@ -211,8 +211,9 @@ public class SkylarkRuleClassFunctions {
+ "to an attribute object (see 'attr' module). Attributes starting with <code>_</code> "
+ "are private, and can be used to add an implicit dependency on a label."),
@Param(name = "outputs", doc = "outputs of this rule. "
- + "It is a dictionary mapping from string to a template name. For example: "
- + "<code>{\"ext\": \"${name}.ext\"}</code>. <br>"
+ + "It is a dictionary mapping from string to a template name. "
+ + "For example: <code>{\"ext\": \"${name}.ext\"}</code>. <br>"
+ + "The dictionary key becomes a field in <code>ctx.outputs</code>. "
// TODO(bazel-team): Make doc more clear, wrt late-bound attributes.
+ "It may also be a function (which receives <code>ctx.attr</code> as argument) "
+ "returning such a dictionary."),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
index fc06677fdc..885fe8a88f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
@@ -74,6 +74,13 @@ public final class SkylarkRuleContext {
public static final String PROVIDER_CLASS_PREFIX = "com.google.devtools.build.lib.";
+ private static final String DOC_NEW_FILE_TAIL = "Does not actually create a file on the file "
+ + "system, just declares that some action will do so. You must create an action that "
+ + "generates the file. If the file should be visible to other rules, declare a rule output "
+ + "instead when possible. Doing so enables Blaze to associate a label with the file that "
+ + "rules can refer to (allowing finer dependency control) instead of referencing the whole "
+ + "rule.";
+
static final LoadingCache<String, Class<?>> classCache = CacheBuilder.newBuilder()
.initialCapacity(10)
.maximumSize(100)
@@ -273,8 +280,8 @@ public final class SkylarkRuleContext {
doc = "A <code>struct</code> containing executable files defined in label type "
+ "attributes marked as <code>executable=True</code>. The struct fields correspond "
+ "to the attribute names. The struct value is always a <code>file</code>s or "
- + "<code>None</code>. If a non-mandatory attribute is not specified in the rule "
- + "the corresponding struct value is <code>None</code>. If a label type is not "
+ + "<code>None</code>. If an optional attribute is not specified in the rule "
+ + "then the corresponding struct value is <code>None</code>. If a label type is not "
+ "marked as <code>executable=True</code>, no corresponding struct field is generated.")
public SkylarkClassObject getExecutable() {
return executableObject;
@@ -287,8 +294,8 @@ public final class SkylarkRuleContext {
doc = "A <code>struct</code> containing files defined in label type "
+ "attributes marked as <code>single_file=True</code>. The struct fields correspond "
+ "to the attribute names. The struct value is always a <code>file</code> or "
- + "<code>None</code>. If a non-mandatory attribute is not specified in the rule "
- + "the corresponding struct value is <code>None</code>. If a label type is not "
+ + "<code>None</code>. If an optional attribute is not specified in the rule "
+ + "then the corresponding struct value is <code>None</code>. If a label type is not "
+ "marked as <code>single_file=True</code>, no corresponding struct field is generated.")
public SkylarkClassObject getFile() {
return fileObject;
@@ -300,7 +307,7 @@ public final class SkylarkRuleContext {
@SkylarkCallable(name = "files", structField = true,
doc = "A <code>struct</code> containing files defined in label or label list "
+ "type attributes. The struct fields correspond to the attribute names. The struct "
- + "values are <code>list</code> of <code>file</code>s. If a non-mandatory attribute is "
+ + "values are <code>list</code> of <code>file</code>s. If an optional attribute is "
+ "not specified in the rule, an empty list is generated.")
public SkylarkClassObject getFiles() {
return filesObject;
@@ -312,7 +319,7 @@ public final class SkylarkRuleContext {
@SkylarkCallable(name = "target", structField = true,
doc = "A <code>struct</code> containing prerequisite targets defined in label type "
+ "attributes. The struct fields correspond to the attribute names. The struct value "
- + "is always a <code>target</code> or <code>None</code>. If a non-mandatory attribute "
+ + "is always a <code>target</code> or <code>None</code>. If an optional attribute "
+ "is not specified in the rule, the corresponding struct value is <code>None</code>.")
public SkylarkClassObject getTarget() {
return targetObject;
@@ -324,7 +331,7 @@ public final class SkylarkRuleContext {
@SkylarkCallable(name = "targets", structField = true,
doc = "A <code>struct</code> containing prerequisite targets defined in label or label list "
+ "type attributes. The struct fields correspond to the attribute names. The struct "
- + "values are <code>list</code> of <code>target</code>s. If a non-mandatory attribute is "
+ + "values are <code>list</code> of <code>target</code>s. If an optional attribute is "
+ "not specified in the rule, an empty list is generated.")
public SkylarkClassObject getTargets() {
return targetsObject;
@@ -368,7 +375,7 @@ public final class SkylarkRuleContext {
+ "if no value is specified in the rule."
+ "<li>For every output list type attribute a struct field is generated with the "
+ "same name and corresponding <code>list</code> of <code>file</code>s value "
- + "(an empty list if no value is specified in the rule.</ul>")
+ + "(an empty list if no value is specified in the rule).</ul>")
public SkylarkClassObject outputs() {
return outputsObject;
}
@@ -406,10 +413,7 @@ public final class SkylarkRuleContext {
}
}
- @SkylarkCallable(doc =
- "Creates a file with the given filename. You must create an action that generates "
- + "the file. If the file should be publicly visible, declare a rule "
- + "output instead when possible.")
+ @SkylarkCallable(doc = "Creates a file object with the given filename. " + DOC_NEW_FILE_TAIL)
public Artifact newFile(Root root, String filename) {
PathFragment fragment = ruleContext.getLabel().getPackageFragment();
for (String pathFragmentString : filename.split("/")) {
@@ -418,11 +422,8 @@ public final class SkylarkRuleContext {
return ruleContext.getAnalysisEnvironment().getDerivedArtifact(fragment, root);
}
- @SkylarkCallable(doc =
- "Creates a new file, derived from the given file and suffix. "
- + "You must create an action that generates "
- + "the file. If the file should be publicly visible, declare a rule "
- + "output instead when possible.")
+ @SkylarkCallable(doc = "Creates a new file object, derived from the given file and suffix. "
+ + DOC_NEW_FILE_TAIL)
public Artifact newFile(Root root, Artifact baseArtifact, String suffix) {
PathFragment original = baseArtifact.getRootRelativePath();
PathFragment fragment = original.replaceName(original.getBaseName() + suffix);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
index c6ca475b7c..ce21c42025 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
@@ -87,7 +87,8 @@ public class SkylarkRuleImplementationFunctions {
@Param(name = "command", doc = "shell command to execute"),
@Param(name = "command_line", doc = "a command line to execute"),
@Param(name = "progress_message", type = String.class,
- doc = "progress message to show to the user during the build"),
+ doc = "progress message to show to the user during the build, e.g. \"Compiling foo.cc to"
+ + " create foo.o\""),
@Param(name = "use_default_shell_env", type = Boolean.class,
doc = "whether the action should use the built in shell environment or not"),
@Param(name = "env", type = Map.class, doc = "sets the dictionary of environment variables"),
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Label.java b/src/main/java/com/google/devtools/build/lib/syntax/Label.java
index 89db4ded1a..f250c50897 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Label.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Label.java
@@ -265,7 +265,7 @@ public final class Label implements Comparable<Label>, Serializable {
@SkylarkCallable(name = "package", structField = true,
doc = "The package part of this label. "
+ "For instance:<br>"
- + "<pre class=language-python>label(\"//pkg/foo:abc\").package == \"pkg/foo\"</pre>")
+ + "<pre class=language-python>Label(\"//pkg/foo:abc\").package == \"pkg/foo\"</pre>")
public String getPackageName() {
return packageIdentifier.getPackageFragment().getPathString();
}
@@ -300,7 +300,7 @@ public final class Label implements Comparable<Label>, Serializable {
@SkylarkCallable(name = "name", structField = true,
doc = "The name of this label within the package. "
+ "For instance:<br>"
- + "<pre class=language-python>label(\"//pkg/foo:abc\").name == \"abc\"</pre>")
+ + "<pre class=language-python>Label(\"//pkg/foo:abc\").name == \"abc\"</pre>")
public String getName() {
return name;
}
@@ -348,10 +348,11 @@ public final class Label implements Comparable<Label>, Serializable {
* @param relName the relative label name; must be non-empty.
*/
@SkylarkCallable(name = "relative", doc =
- "Resolves a relative or absolute label name.<br>"
- + "For example:<br><ul>"
+ "Resolves a label that is either absolute (starts with <code>//</code>) or relative to the"
+ + " current package.<br>"
+ + "For example:<br><ul>"
+ "<li><code>:quux</code> relative to <code>//foo/bar:baz</code> is "
- + "<code>//foo/bar:quux</code></li>"
+ + "<code>//foo/bar:quux</code></li>"
+ "<li><code>//wiz:quux</code> relative to <code>//foo/bar:baz</code> is "
+ "<code>//wiz:quux</code></li></ul>")
public Label getRelative(String relName) throws SyntaxException {
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java
index ef9fe1014e..89c26dad1b 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java
@@ -30,15 +30,15 @@ import java.util.List;
*/
@SkylarkModule(name = "list",
doc = "A language built-in type to support lists. Example of list literal:<br>"
- + "<pre class=language-python>l = [1, 2, 3]</pre>"
+ + "<pre class=language-python>x = [1, 2, 3]</pre>"
+ "Accessing elements is possible using indexing (starts from <code>0</code>):<br>"
- + "<pre class=language-python>e = l[1] # e == 2</pre>"
+ + "<pre class=language-python>e = x[1] # e == 2</pre>"
+ "Lists support the <code>+</code> operator to concatenate two lists. Example:<br>"
- + "<pre class=language-python>l = [1, 2] + [3, 4] # l == [1, 2, 3, 4]\n"
- + "l = [\"a\", \"b\"]\n"
- + "l += [\"c\"] # l == [\"a\", \"b\", \"c\"]</pre>"
+ + "<pre class=language-python>x = [1, 2] + [3, 4] # x == [1, 2, 3, 4]\n"
+ + "x = [\"a\", \"b\"]\n"
+ + "x += [\"c\"] # x == [\"a\", \"b\", \"c\"]</pre>"
+ "List elements have to be of the same type, <code>[1, 2, \"c\"]</code> results in an "
- + "error. Lists - just like everything - are immutable, therefore <code>l[1] = \"a\""
+ + "error. Lists - just like everything - are immutable, therefore <code>x[1] = \"a\""
+ "</code> is not supported.")
public abstract class SkylarkList implements Iterable<Object> {
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java
index 5efdd2eb58..5b9929892f 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java
@@ -34,9 +34,10 @@ import javax.annotation.Nullable;
* A generic type safe NestedSet wrapper for Skylark.
*/
@SkylarkModule(name = "set",
- doc = "A language built-in type to supports (nested) sets. "
+ doc = "A language built-in type that supports (nested) sets. "
+ "Sets can be created using the global <code>set</code> function, and they "
- + "support the <code>+</code> operator to extends and nest sets. Examples:<br>"
+ + "support the <code>+</code> operator to extend the set with more elements or to nest "
+ + "other sets inside of it. Examples:<br>"
+ "<pre class=language-python>s = set([1, 2])\n"
+ "s += [3] # s == {1, 2, 3}\n"
+ "s += set([4, 5]) # s == {1, 2, 3, {4, 5}}</pre>"