Search in sources :

Example 1 with AstAfterPreprocessing

use of com.google.devtools.build.lib.packages.Preprocessor.AstAfterPreprocessing in project bazel by bazelbuild.

the class PackageFactory method createPackageFromPreprocessingResult.

/****************************************************************************
   * Package creation.
   */
/**
   * Loads, scans parses and evaluates the build file at "buildFile", and
   * creates and returns a Package builder instance capable of building a package identified by
   * "packageId".
   *
   * <p>This method returns a builder to allow the caller to do additional work, if necessary.
   *
   * <p>This method assumes "packageId" is a valid package name according to the
   * {@link LabelValidator#validatePackageName} heuristic.
   *
   * <p>See {@link #evaluateBuildFile} for information on AST retention.
   *
   * <p>Executes {@code globber.onCompletion()} on completion and executes
   * {@code globber.onInterrupt()} on an {@link InterruptedException}.
   */
// Used outside of bazel!
public Package.Builder createPackageFromPreprocessingResult(String workspaceName, PackageIdentifier packageId, Path buildFile, Preprocessor.Result preprocessingResult, List<Statement> preludeStatements, Map<String, Extension> imports, ImmutableList<Label> skylarkFileDependencies, RuleVisibility defaultVisibility, Globber globber) throws InterruptedException {
    StoredEventHandler localReporterForParsing = new StoredEventHandler();
    // Run the lexer and parser with a local reporter, so that errors from other threads do not
    // show up below.
    BuildFileAST buildFileAST = parseBuildFile(packageId, preprocessingResult.result, preludeStatements, localReporterForParsing);
    AstAfterPreprocessing astAfterPreprocessing = new AstAfterPreprocessing(preprocessingResult, buildFileAST, localReporterForParsing);
    return createPackageFromPreprocessingAst(workspaceName, packageId, buildFile, astAfterPreprocessing, imports, skylarkFileDependencies, defaultVisibility, globber);
}
Also used : StoredEventHandler(com.google.devtools.build.lib.events.StoredEventHandler) AstAfterPreprocessing(com.google.devtools.build.lib.packages.Preprocessor.AstAfterPreprocessing) BuildFileAST(com.google.devtools.build.lib.syntax.BuildFileAST)

Example 2 with AstAfterPreprocessing

use of com.google.devtools.build.lib.packages.Preprocessor.AstAfterPreprocessing in project bazel by bazelbuild.

the class PackageFunction method loadPackage.

/**
   * Constructs a {@link Package} object for the given package using legacy package loading.
   * Note that the returned package may be in error.
   *
   * <p>May return null if the computation has to be restarted.
   *
   * <p>Exactly one of {@code replacementContents} and {@code buildFileValue} will be
   * non-{@code null}. The former indicates that we have a faux BUILD file with the given contents
   * and the latter indicates that we have a legitimate BUILD file and should actually do
   * preprocessing.
   */
@Nullable
private CacheEntryWithGlobDeps<Package.Builder> loadPackage(String workspaceName, @Nullable String replacementContents, PackageIdentifier packageId, Path buildFilePath, @Nullable FileValue buildFileValue, RuleVisibility defaultVisibility, List<Statement> preludeStatements, Path packageRoot, Environment env) throws InterruptedException, PackageFunctionException {
    CacheEntryWithGlobDeps<Package.Builder> packageFunctionCacheEntry = packageFunctionCache.getIfPresent(packageId);
    if (packageFunctionCacheEntry == null) {
        profiler.startTask(ProfilerTask.CREATE_PACKAGE, packageId.toString());
        if (packageProgress != null) {
            packageProgress.startReadPackage(packageId);
        }
        try {
            CacheEntryWithGlobDeps<AstAfterPreprocessing> astCacheEntry = astCache.getIfPresent(packageId);
            if (astCacheEntry == null) {
                if (showLoadingProgress.get()) {
                    env.getListener().handle(Event.progress("Loading package: " + packageId));
                }
                // We use a LegacyGlobber that doesn't sort the matches for each individual glob pattern,
                // since we want to sort the final result anyway.
                LegacyGlobber legacyGlobber = packageFactory.createLegacyGlobberThatDoesntSort(buildFilePath.getParentDirectory(), packageId, packageLocator);
                SkyframeHybridGlobber skyframeGlobber = new SkyframeHybridGlobber(packageId, packageRoot, env, legacyGlobber);
                Preprocessor.Result preprocessingResult;
                if (replacementContents == null) {
                    Preconditions.checkNotNull(buildFileValue, packageId);
                    byte[] buildFileBytes;
                    try {
                        buildFileBytes = buildFileValue.isSpecialFile() ? FileSystemUtils.readContent(buildFilePath) : FileSystemUtils.readWithKnownFileSize(buildFilePath, buildFileValue.getSize());
                    } catch (IOException e) {
                        // transient.
                        throw new PackageFunctionException(new BuildFileContainsErrorsException(packageId, e.getMessage()), Transience.TRANSIENT);
                    }
                    try {
                        preprocessingResult = packageFactory.preprocess(buildFilePath, packageId, buildFileBytes, skyframeGlobber);
                    } catch (IOException e) {
                        throw new PackageFunctionException(new BuildFileContainsErrorsException(packageId, "preprocessing failed" + e.getMessage(), e), Transience.TRANSIENT);
                    }
                } else {
                    ParserInputSource replacementSource = ParserInputSource.create(replacementContents, buildFilePath.asFragment());
                    preprocessingResult = Preprocessor.Result.noPreprocessing(replacementSource);
                }
                StoredEventHandler astParsingEventHandler = new StoredEventHandler();
                BuildFileAST ast = PackageFactory.parseBuildFile(packageId, preprocessingResult.result, preludeStatements, astParsingEventHandler);
                // If no globs were fetched during preprocessing, then there's no need to reuse the
                // legacy globber instance during BUILD file evaluation since the performance argument
                // below does not apply.
                Set<SkyKey> globDepsRequested = skyframeGlobber.getGlobDepsRequested();
                LegacyGlobber legacyGlobberToStore = globDepsRequested.isEmpty() ? null : legacyGlobber;
                astCacheEntry = new CacheEntryWithGlobDeps<>(new AstAfterPreprocessing(preprocessingResult, ast, astParsingEventHandler), globDepsRequested, legacyGlobberToStore);
                astCache.put(packageId, astCacheEntry);
            }
            AstAfterPreprocessing astAfterPreprocessing = astCacheEntry.value;
            Set<SkyKey> globDepsRequestedDuringPreprocessing = astCacheEntry.globDepKeys;
            SkylarkImportResult importResult;
            try {
                importResult = fetchImportsFromBuildFile(buildFilePath, packageId, astAfterPreprocessing.ast, env, skylarkImportLookupFunctionForInlining);
            } catch (NoSuchPackageException e) {
                throw new PackageFunctionException(e, Transience.PERSISTENT);
            } catch (InterruptedException e) {
                astCache.invalidate(packageId);
                throw e;
            }
            if (importResult == null) {
                return null;
            }
            astCache.invalidate(packageId);
            // If a legacy globber was used to evaluate globs during preprocessing, it's important that
            // we reuse that globber during BUILD file evaluation for performance, in the case that
            // globs were fetched lazily during preprocessing. See Preprocessor.Factory#considersGlobs.
            LegacyGlobber legacyGlobber = astCacheEntry.legacyGlobber != null ? astCacheEntry.legacyGlobber : packageFactory.createLegacyGlobber(buildFilePath.getParentDirectory(), packageId, packageLocator);
            SkyframeHybridGlobber skyframeGlobber = new SkyframeHybridGlobber(packageId, packageRoot, env, legacyGlobber);
            Package.Builder pkgBuilder = packageFactory.createPackageFromPreprocessingAst(workspaceName, packageId, buildFilePath, astAfterPreprocessing, importResult.importMap, importResult.fileDependencies, defaultVisibility, skyframeGlobber);
            Set<SkyKey> globDepsRequested = ImmutableSet.<SkyKey>builder().addAll(globDepsRequestedDuringPreprocessing).addAll(skyframeGlobber.getGlobDepsRequested()).build();
            packageFunctionCacheEntry = new CacheEntryWithGlobDeps<>(pkgBuilder, globDepsRequested, null);
            numPackagesLoaded.incrementAndGet();
            if (packageProgress != null) {
                packageProgress.doneReadPackage(packageId);
            }
            packageFunctionCache.put(packageId, packageFunctionCacheEntry);
        } finally {
            profiler.completeTask(ProfilerTask.CREATE_PACKAGE);
        }
    }
    return packageFunctionCacheEntry;
}
Also used : ParserInputSource(com.google.devtools.build.lib.syntax.ParserInputSource) SkyKey(com.google.devtools.build.skyframe.SkyKey) BuildFileContainsErrorsException(com.google.devtools.build.lib.packages.BuildFileContainsErrorsException) LegacyGlobber(com.google.devtools.build.lib.packages.PackageFactory.LegacyGlobber) AstAfterPreprocessing(com.google.devtools.build.lib.packages.Preprocessor.AstAfterPreprocessing) IOException(java.io.IOException) StoredEventHandler(com.google.devtools.build.lib.events.StoredEventHandler) NoSuchPackageException(com.google.devtools.build.lib.packages.NoSuchPackageException) Preprocessor(com.google.devtools.build.lib.packages.Preprocessor) Package(com.google.devtools.build.lib.packages.Package) BuildFileAST(com.google.devtools.build.lib.syntax.BuildFileAST) Nullable(javax.annotation.Nullable)

Aggregations

StoredEventHandler (com.google.devtools.build.lib.events.StoredEventHandler)2 AstAfterPreprocessing (com.google.devtools.build.lib.packages.Preprocessor.AstAfterPreprocessing)2 BuildFileAST (com.google.devtools.build.lib.syntax.BuildFileAST)2 BuildFileContainsErrorsException (com.google.devtools.build.lib.packages.BuildFileContainsErrorsException)1 NoSuchPackageException (com.google.devtools.build.lib.packages.NoSuchPackageException)1 Package (com.google.devtools.build.lib.packages.Package)1 LegacyGlobber (com.google.devtools.build.lib.packages.PackageFactory.LegacyGlobber)1 Preprocessor (com.google.devtools.build.lib.packages.Preprocessor)1 ParserInputSource (com.google.devtools.build.lib.syntax.ParserInputSource)1 SkyKey (com.google.devtools.build.skyframe.SkyKey)1 IOException (java.io.IOException)1 Nullable (javax.annotation.Nullable)1