com.google.javascript.jscomp.bundle.Source Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of closure-compiler-unshaded Show documentation
Show all versions of closure-compiler-unshaded Show documentation
Closure Compiler is a JavaScript optimizing compiler. It parses your
JavaScript, analyzes it, removes dead code and rewrites and minimizes
what's left. It also checks syntax, variable references, and types, and
warns about common JavaScript pitfalls. It is used in many of Google's
JavaScript apps, including Gmail, Google Web Search, Google Maps, and
Google Docs.
/*
* Copyright 2017 The Closure Compiler Authors.
*
* 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.javascript.jscomp.bundle;
import static java.util.Arrays.asList;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.errorprone.annotations.CheckReturnValue;
import com.google.errorprone.annotations.Immutable;
import com.google.javascript.jscomp.deps.DependencyInfo;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.function.Function;
import org.jspecify.nullness.Nullable;
/** An abstract representation of a source file. */
@AutoValue
@GwtIncompatible
@Immutable
public abstract class Source {
/** The path of this source. This may refer to a path on disk or a path on the HTTP server. */
public abstract Path path();
/** The text of any source map applicable to this file. */
public abstract String sourceMap();
/** The source URL associated with this file. */
public abstract String sourceUrl();
/** The URL for a source map associated with this file. */
public abstract String sourceMappingUrl();
/**
* Any runtime libraries necessary for this source. Any transformation that adds a runtime library
* to any sources must be responsible to never add the same library as a substring to a different
* source (so that the "no duplicates" invariant of Set will work correctly).
*/
public abstract ImmutableSet runtimes();
/** The load flags, specifying module type and language level. */
public abstract ImmutableMap loadFlags();
/** A best estimate of the size of this source (in case the source itself is not yet loaded. */
public abstract int estimatedSize();
/** The actual code in this source file. */
public final String code() {
return codeSupplier().get();
}
/** The untransformed code from the original source file. */
public final String originalCode() {
return originalCodeSupplier().get();
}
/** Copies the data from this source to a new builder. */
public abstract Builder toBuilder();
/** Makes a new empty builder. */
public static Builder builder() {
return new AutoValue_Source.Builder()
.setPath(DEV_NULL)
.setCode("")
.setOriginalCodeSupplier(null)
.setSourceMap("")
.setSourceUrl("")
.setSourceMappingUrl("")
.setRuntimes(ImmutableSet.of())
.setLoadFlags(ImmutableMap.of())
.setEstimatedSize(0);
}
private static final Path DEV_NULL = Paths.get("/dev/null");
// Internal-only properties: the code suppliers are necessary for lazy bundling,
// but we cannot use an ordinary supplier since we need guarantees about equals and
// hash code. Thus, we use an internal-only Supplier subtype.
abstract Lazy codeSupplier();
abstract @Nullable Lazy originalCodeSupplier();
/** Builder for Source instances. */
@AutoValue.Builder
@GwtIncompatible
public abstract static class Builder {
public abstract Builder setPath(Path path);
public abstract Builder setSourceMap(String sourceMap);
public abstract Builder setSourceUrl(String sourceUrl);
public abstract Builder setSourceMappingUrl(String sourceMappingUrl);
public abstract Builder setRuntimes(ImmutableSet runtimes);
public abstract Builder setLoadFlags(ImmutableMap flags);
public abstract Builder setEstimatedSize(int estimatedSize);
public final Builder setCode(Supplier code) {
return setCodeSupplier(Lazy.memoize(code));
}
public final Builder setCode(String code) {
return setCodeSupplier(Lazy.ofInstance(code));
}
public final Builder setOriginalCode(String code) {
return setOriginalCodeSupplier(Lazy.ofInstance(code));
}
public final Builder addRuntime(String... runtimes) {
return setRuntimes(
ImmutableSet.builder().addAll(runtimes()).addAll(asList(runtimes)).build());
}
public final Builder setDependencyInfo(DependencyInfo info) {
// TODO(sdh): consider whether to set path.
return setLoadFlags(info.getLoadFlags());
}
public final Source build() {
if (originalCodeSupplier() == null) {
setOriginalCodeSupplier(codeSupplier());
}
return autoBuild();
}
// Internal-only getters and setters.
abstract Builder setCodeSupplier(Lazy code);
abstract Builder setOriginalCodeSupplier(@Nullable Lazy code);
abstract ImmutableSet runtimes();
abstract Lazy codeSupplier();
abstract Source autoBuild();
abstract @Nullable Lazy originalCodeSupplier();
}
/** An automorphic transformation on sources. */
@FunctionalInterface
public interface Transformer {
/** The main transformation method. */
Source transform(Source input);
static Transformer of(Function