// Copyright 2014 The Bazel Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.devtools.build.lib.syntax; import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.google.common.collect.ForwardingList; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; import com.google.common.collect.Iterables; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.skylarkinterface.SkylarkValue; import com.google.devtools.build.lib.util.Preconditions; import java.util.ArrayList; import java.util.List; /** * Glob matches and information about glob patterns, which are useful to * ide_build_info. Its implementation of the List interface is as an immutable * list of the matching files. Glob criteria can be retrieved through * {@link #getCriteria}. * * @param <E> the element this List contains (generally either String or Label) */ @SkylarkModule( name = "glob list", doc = "", documented = false) public final class GlobList<E> extends ForwardingList<E> implements SkylarkValue { /** Include/exclude criteria. */ private final ImmutableList<GlobCriteria> criteria; /** Matching files (usually either String or Label). */ private final ImmutableList<E> matches; /** * Constructs a list with {@code glob()} call results. * * @param includes the patterns that the glob includes * @param excludes the patterns that the glob excludes * @param matches the filenames that matched the includes/excludes criteria */ public static <T> GlobList<T> captureResults(List<String> includes, List<String> excludes, List<T> matches) { GlobCriteria criteria = GlobCriteria.fromGlobCall( ImmutableList.copyOf(includes), ImmutableList.copyOf(excludes)); return new GlobList<>(ImmutableList.of(criteria), matches); } /** * Parses a GlobInfo from its {@link #toExpression} representation. */ public static GlobList<String> parse(String text) { List<GlobCriteria> criteria = new ArrayList<>(); Iterable<String> globs = Splitter.on(" + ").split(text); for (String glob : globs) { criteria.add(GlobCriteria.parse(glob)); } return new GlobList<>(criteria, ImmutableList.<String>of()); } /** * Concatenates two lists into a new GlobList. If either of the lists is a * GlobList, its GlobCriteria are preserved. Otherwise a simple GlobCriteria * is created to represent the fixed list. */ public static <T> GlobList<T> concat( List<? extends T> list1, List<? extends T> list2) { // we add the list to both includes and matches, preserving order Builder<GlobCriteria> criteriaBuilder = ImmutableList.<GlobCriteria>builder(); if (list1 instanceof GlobList<?>) { criteriaBuilder.addAll(((GlobList<?>) list1).criteria); } else { criteriaBuilder.add(GlobCriteria.fromList(list1)); } if (list2 instanceof GlobList<?>) { criteriaBuilder.addAll(((GlobList<?>) list2).criteria); } else { criteriaBuilder.add(GlobCriteria.fromList(list2)); } List<T> matches = ImmutableList.copyOf(Iterables.concat(list1, list2)); return new GlobList<>(criteriaBuilder.build(), matches); } /** * Constructs a list with given criteria and matches. */ public GlobList(List<GlobCriteria> criteria, List<E> matches) { Preconditions.checkNotNull(criteria); Preconditions.checkNotNull(matches); this.criteria = ImmutableList.copyOf(criteria); this.matches = ImmutableList.copyOf(matches); } /** * Returns the criteria used to create this list, from which the * includes/excludes can be retrieved. */ public ImmutableList<GlobCriteria> getCriteria() { return criteria; } /** * Returns a String that represents this glob list as a BUILD expression. */ public String toExpression() { return Joiner.on(" + ").join(criteria); } @Override protected ImmutableList<E> delegate() { return matches; } @Override public boolean isImmutable() { return false; } @Override public void write(Appendable buffer, char quotationMark) { Printer.printList(buffer, this, false, quotationMark); } }