Search in sources :

Example 41 with Optional

use of java.util.Optional in project buck by facebook.

the class JavaFileParser method extractFeaturesFromJavaCode.

public JavaFileFeatures extractFeaturesFromJavaCode(String code) {
    // For now, we will harcode this. Ultimately, we probably want to make this configurable via
    // .buckconfig. For example, the Buck project itself is diligent about disallowing wildcard
    // imports, but the one exception is the Java code generated via Thrift in src-gen.
    final boolean shouldThrowForUnsupportedWildcardImport = false;
    final AtomicBoolean isPoisonedByUnsupportedWildcardImport = new AtomicBoolean(false);
    final CompilationUnit compilationUnit = makeCompilationUnitFromSource(code);
    final ImmutableSortedSet.Builder<String> providedSymbols = ImmutableSortedSet.naturalOrder();
    final ImmutableSortedSet.Builder<String> requiredSymbols = ImmutableSortedSet.naturalOrder();
    final ImmutableSortedSet.Builder<String> exportedSymbols = ImmutableSortedSet.naturalOrder();
    final ImmutableSortedSet.Builder<String> requiredSymbolsFromExplicitImports = ImmutableSortedSet.naturalOrder();
    compilationUnit.accept(new ASTVisitor() {

        @Nullable
        private String packageName;

        /** Maps simple name to fully-qualified name. */
        private Map<String, String> simpleImportedTypes = new HashMap<>();

        /**
       * Maps wildcard import prefixes, such as {@code "java.util"} to the types in the respective
       * package if a wildcard import such as {@code import java.util.*} is used.
       */
        private Map<String, ImmutableSet<String>> wildcardImports = new HashMap<>();

        @Override
        public boolean visit(PackageDeclaration node) {
            Preconditions.checkState(packageName == null, "There should be at most one package declaration");
            packageName = node.getName().getFullyQualifiedName();
            return false;
        }

        // providedSymbols
        @Override
        public boolean visit(TypeDeclaration node) {
            // Local classes can be declared inside of methods. Skip over these.
            if (node.getParent() instanceof TypeDeclarationStatement) {
                return true;
            }
            String fullyQualifiedName = getFullyQualifiedTypeName(node);
            if (fullyQualifiedName != null) {
                providedSymbols.add(fullyQualifiedName);
            }
            @SuppressWarnings("unchecked") List<Type> interfaceTypes = node.superInterfaceTypes();
            for (Type interfaceType : interfaceTypes) {
                tryAddType(interfaceType, DependencyType.EXPORTED);
            }
            Type superclassType = node.getSuperclassType();
            if (superclassType != null) {
                tryAddType(superclassType, DependencyType.EXPORTED);
            }
            return true;
        }

        @Override
        public boolean visit(EnumDeclaration node) {
            String fullyQualifiedName = getFullyQualifiedTypeName(node);
            if (fullyQualifiedName != null) {
                providedSymbols.add(fullyQualifiedName);
            }
            return true;
        }

        @Override
        public boolean visit(AnnotationTypeDeclaration node) {
            String fullyQualifiedName = getFullyQualifiedTypeName(node);
            if (fullyQualifiedName != null) {
                providedSymbols.add(fullyQualifiedName);
            }
            return true;
        }

        // requiredSymbols
        /**
       * Uses heuristics to try to figure out what type of QualifiedName this is. Returns a non-null
       * value if this is believed to be a reference that qualifies as a "required symbol"
       * relationship.
       */
        @Override
        public boolean visit(QualifiedName node) {
            QualifiedName ancestor = findMostQualifiedAncestor(node);
            ASTNode parent = ancestor.getParent();
            if (!(parent instanceof PackageDeclaration) && !(parent instanceof ImportDeclaration)) {
                String symbol = ancestor.getFullyQualifiedName();
                // lookup.
                if (CharMatcher.javaUpperCase().matches(symbol.charAt(0))) {
                    addTypeFromDotDelimitedSequence(symbol, DependencyType.REQUIRED);
                }
            }
            return false;
        }

        /**
       * @param expr could be "Example", "Example.field", "com.example.Example". Note it could also
       *     be a built-in type, such as "java.lang.Integer", in which case it will not be added to
       *     the set of required symbols.
       */
        private void addTypeFromDotDelimitedSequence(String expr, DependencyType dependencyType) {
            // check it against JAVA_LANG_TYPES.
            if (startsWithUppercaseChar(expr)) {
                int index = expr.indexOf('.');
                if (index >= 0) {
                    String leftmostComponent = expr.substring(0, index);
                    if (JAVA_LANG_TYPES.contains(leftmostComponent)) {
                        return;
                    }
                }
            }
            expr = qualifyWithPackageNameIfNecessary(expr);
            addSymbol(expr, dependencyType);
        }

        @Override
        public boolean visit(ImportDeclaration node) {
            String fullyQualifiedName = node.getName().getFullyQualifiedName();
            // third-party code. As such, we will tolerate these for some of the common cases.
            if (node.isOnDemand()) {
                ImmutableSet<String> value = SUPPORTED_WILDCARD_IMPORTS.get(fullyQualifiedName);
                if (value != null) {
                    wildcardImports.put(fullyQualifiedName, value);
                    return false;
                } else if (shouldThrowForUnsupportedWildcardImport) {
                    throw new RuntimeException(String.format("Use of wildcard 'import %s.*' makes it impossible to statically determine " + "required symbols in this file. Please enumerate explicit imports.", fullyQualifiedName));
                } else {
                    isPoisonedByUnsupportedWildcardImport.set(true);
                    return false;
                }
            }
            // Only worry about the dependency on the enclosing type.
            Optional<String> simpleName = getSimpleNameFromFullyQualifiedName(fullyQualifiedName);
            if (simpleName.isPresent()) {
                String name = simpleName.get();
                int index = fullyQualifiedName.indexOf("." + name);
                String enclosingType = fullyQualifiedName.substring(0, index + name.length() + 1);
                requiredSymbolsFromExplicitImports.add(enclosingType);
                simpleImportedTypes.put(name, enclosingType);
            } else {
                LOG.warn("Suspicious import lacks obvious enclosing type: %s", fullyQualifiedName);
                // The one example we have seen of this in the wild is
                // "org.whispersystems.curve25519.java.curve_sigs". In practice, we still need to add it
                // as a required symbol in this case.
                requiredSymbols.add(fullyQualifiedName);
            }
            return false;
        }

        @Override
        public boolean visit(MethodInvocation node) {
            if (node.getExpression() == null) {
                return true;
            }
            String receiver = node.getExpression().toString();
            if (looksLikeAType(receiver)) {
                addTypeFromDotDelimitedSequence(receiver, DependencyType.REQUIRED);
            }
            return true;
        }

        /** An annotation on a member with zero arguments. */
        @Override
        public boolean visit(MarkerAnnotation node) {
            DependencyType dependencyType = findDependencyTypeForAnnotation(node);
            addSimpleTypeName(node.getTypeName(), dependencyType);
            return true;
        }

        /** An annotation on a member with named arguments. */
        @Override
        public boolean visit(NormalAnnotation node) {
            DependencyType dependencyType = findDependencyTypeForAnnotation(node);
            addSimpleTypeName(node.getTypeName(), dependencyType);
            return true;
        }

        /** An annotation on a member with a single, unnamed argument. */
        @Override
        public boolean visit(SingleMemberAnnotation node) {
            DependencyType dependencyType = findDependencyTypeForAnnotation(node);
            addSimpleTypeName(node.getTypeName(), dependencyType);
            return true;
        }

        private DependencyType findDependencyTypeForAnnotation(Annotation annotation) {
            ASTNode parentNode = annotation.getParent();
            if (parentNode == null) {
                return DependencyType.REQUIRED;
            }
            if (parentNode instanceof BodyDeclaration) {
                // Note that BodyDeclaration is an abstract class. Its subclasses are things like
                // FieldDeclaration and MethodDeclaration. We want to be sure that an annotation on any
                // non-private declaration is considered an exported symbol.
                BodyDeclaration declaration = (BodyDeclaration) parentNode;
                int modifiers = declaration.getModifiers();
                if ((modifiers & Modifier.PRIVATE) == 0) {
                    return DependencyType.EXPORTED;
                }
            }
            return DependencyType.REQUIRED;
        }

        @Override
        public boolean visit(SimpleType node) {
            // This method is responsible for finding the overwhelming majority of the required symbols
            // in the AST.
            tryAddType(node, DependencyType.REQUIRED);
            return true;
        }

        // exportedSymbols
        @Override
        public boolean visit(MethodDeclaration node) {
            // Types from private method signatures need not be exported.
            if ((node.getModifiers() & Modifier.PRIVATE) != 0) {
                return true;
            }
            Type returnType = node.getReturnType2();
            if (returnType != null) {
                tryAddType(returnType, DependencyType.EXPORTED);
            }
            @SuppressWarnings("unchecked") List<SingleVariableDeclaration> params = node.parameters();
            for (SingleVariableDeclaration decl : params) {
                tryAddType(decl.getType(), DependencyType.EXPORTED);
            }
            @SuppressWarnings("unchecked") List<Type> exceptions = node.thrownExceptionTypes();
            for (Type exception : exceptions) {
                tryAddType(exception, DependencyType.EXPORTED);
            }
            return true;
        }

        @Override
        public boolean visit(FieldDeclaration node) {
            // Types from private fields need not be exported.
            if ((node.getModifiers() & Modifier.PRIVATE) == 0) {
                tryAddType(node.getType(), DependencyType.EXPORTED);
            }
            return true;
        }

        private void tryAddType(Type type, DependencyType dependencyType) {
            if (type.isSimpleType()) {
                SimpleType simpleType = (SimpleType) type;
                Name simpleTypeName = simpleType.getName();
                String simpleName = simpleTypeName.toString();
                // rather than simply required.
                if (!CharMatcher.javaUpperCase().matchesAllOf(simpleName) || (dependencyType == DependencyType.EXPORTED && simpleImportedTypes.containsKey(simpleName))) {
                    addSimpleTypeName(simpleTypeName, dependencyType);
                }
            } else if (type.isArrayType()) {
                ArrayType arrayType = (ArrayType) type;
                tryAddType(arrayType.getElementType(), dependencyType);
            } else if (type.isParameterizedType()) {
                ParameterizedType parameterizedType = (ParameterizedType) type;
                tryAddType(parameterizedType.getType(), dependencyType);
                @SuppressWarnings("unchecked") List<Type> argTypes = parameterizedType.typeArguments();
                for (Type argType : argTypes) {
                    tryAddType(argType, dependencyType);
                }
            }
        }

        private void addSimpleTypeName(Name simpleTypeName, DependencyType dependencyType) {
            String simpleName = simpleTypeName.toString();
            if (JAVA_LANG_TYPES.contains(simpleName)) {
                return;
            }
            String fullyQualifiedNameForSimpleName = simpleImportedTypes.get(simpleName);
            if (fullyQualifiedNameForSimpleName != null) {
                // May need to promote from required to exported in this case.
                if (dependencyType == DependencyType.EXPORTED) {
                    addSymbol(fullyQualifiedNameForSimpleName, DependencyType.EXPORTED);
                }
                return;
            }
            // the iterator most of the time.
            if (!wildcardImports.isEmpty()) {
                for (Map.Entry<String, ImmutableSet<String>> entry : wildcardImports.entrySet()) {
                    Set<String> types = entry.getValue();
                    if (types.contains(simpleName)) {
                        String packageName = entry.getKey();
                        addSymbol(packageName + "." + simpleName, dependencyType);
                        return;
                    }
                }
            }
            String symbol = simpleTypeName.getFullyQualifiedName();
            symbol = qualifyWithPackageNameIfNecessary(symbol);
            addSymbol(symbol, dependencyType);
        }

        private void addSymbol(String symbol, DependencyType dependencyType) {
            ((dependencyType == DependencyType.REQUIRED) ? requiredSymbols : exportedSymbols).add(symbol);
        }

        private String qualifyWithPackageNameIfNecessary(String symbol) {
            if (!startsWithUppercaseChar(symbol)) {
                return symbol;
            }
            // If the symbol starts with a capital letter, then we assume that it is a reference to
            // a type in the same package.
            int index = symbol.indexOf('.');
            if (index >= 0) {
                symbol = symbol.substring(0, index);
            }
            if (packageName != null) {
                symbol = packageName + "." + symbol;
            }
            return symbol;
        }
    });
    // TODO(bolinfest): Special treatment for exportedSymbols when poisoned by wildcard import.
    ImmutableSortedSet<String> totalExportedSymbols = exportedSymbols.build();
    // If we were poisoned by an unsupported wildcard import, then we should rely exclusively on
    // the explicit imports to determine the required symbols.
    Set<String> totalRequiredSymbols = new HashSet<>();
    if (isPoisonedByUnsupportedWildcardImport.get()) {
        totalRequiredSymbols.addAll(requiredSymbolsFromExplicitImports.build());
    } else {
        totalRequiredSymbols.addAll(requiredSymbolsFromExplicitImports.build());
        totalRequiredSymbols.addAll(requiredSymbols.build());
    }
    // Make sure that required and exported symbols are disjoint sets.
    totalRequiredSymbols.removeAll(totalExportedSymbols);
    return new JavaFileFeatures(providedSymbols.build(), ImmutableSortedSet.copyOf(totalRequiredSymbols), totalExportedSymbols);
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) HashSet(java.util.HashSet) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) HashMap(java.util.HashMap) MethodInvocation(org.eclipse.jdt.core.dom.MethodInvocation) FieldDeclaration(org.eclipse.jdt.core.dom.FieldDeclaration) QualifiedName(org.eclipse.jdt.core.dom.QualifiedName) Name(org.eclipse.jdt.core.dom.Name) ArrayType(org.eclipse.jdt.core.dom.ArrayType) ParameterizedType(org.eclipse.jdt.core.dom.ParameterizedType) SimpleType(org.eclipse.jdt.core.dom.SimpleType) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) ASTNode(org.eclipse.jdt.core.dom.ASTNode) NormalAnnotation(org.eclipse.jdt.core.dom.NormalAnnotation) List(java.util.List) LinkedList(java.util.LinkedList) PackageDeclaration(org.eclipse.jdt.core.dom.PackageDeclaration) HashSet(java.util.HashSet) CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) Optional(java.util.Optional) SingleMemberAnnotation(org.eclipse.jdt.core.dom.SingleMemberAnnotation) MethodDeclaration(org.eclipse.jdt.core.dom.MethodDeclaration) SingleVariableDeclaration(org.eclipse.jdt.core.dom.SingleVariableDeclaration) QualifiedName(org.eclipse.jdt.core.dom.QualifiedName) AnnotationTypeDeclaration(org.eclipse.jdt.core.dom.AnnotationTypeDeclaration) SingleMemberAnnotation(org.eclipse.jdt.core.dom.SingleMemberAnnotation) MarkerAnnotation(org.eclipse.jdt.core.dom.MarkerAnnotation) Annotation(org.eclipse.jdt.core.dom.Annotation) NormalAnnotation(org.eclipse.jdt.core.dom.NormalAnnotation) ASTVisitor(org.eclipse.jdt.core.dom.ASTVisitor) EnumDeclaration(org.eclipse.jdt.core.dom.EnumDeclaration) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ArrayType(org.eclipse.jdt.core.dom.ArrayType) ParameterizedType(org.eclipse.jdt.core.dom.ParameterizedType) SimpleType(org.eclipse.jdt.core.dom.SimpleType) Type(org.eclipse.jdt.core.dom.Type) MarkerAnnotation(org.eclipse.jdt.core.dom.MarkerAnnotation) TypeDeclarationStatement(org.eclipse.jdt.core.dom.TypeDeclarationStatement) ImportDeclaration(org.eclipse.jdt.core.dom.ImportDeclaration) BodyDeclaration(org.eclipse.jdt.core.dom.BodyDeclaration) AbstractTypeDeclaration(org.eclipse.jdt.core.dom.AbstractTypeDeclaration) AnnotationTypeDeclaration(org.eclipse.jdt.core.dom.AnnotationTypeDeclaration) TypeDeclaration(org.eclipse.jdt.core.dom.TypeDeclaration) Nullable(javax.annotation.Nullable)

Example 42 with Optional

use of java.util.Optional in project buck by facebook.

the class PythonTestDescription method createBuildRule.

@Override
public <A extends Arg> PythonTest createBuildRule(TargetGraph targetGraph, final BuildRuleParams params, final BuildRuleResolver resolver, final A args) throws HumanReadableException, NoSuchBuildTargetException {
    PythonPlatform pythonPlatform = pythonPlatforms.getValue(params.getBuildTarget()).orElse(pythonPlatforms.getValue(args.platform.<Flavor>map(InternalFlavor::of).orElse(pythonPlatforms.getFlavors().iterator().next())));
    CxxPlatform cxxPlatform = cxxPlatforms.getValue(params.getBuildTarget()).orElse(defaultCxxPlatform);
    SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver);
    SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
    Path baseModule = PythonUtil.getBasePath(params.getBuildTarget(), args.baseModule);
    Optional<ImmutableMap<BuildTarget, Version>> selectedVersions = targetGraph.get(params.getBuildTarget()).getSelectedVersions();
    ImmutableMap<Path, SourcePath> srcs = PythonUtil.getModules(params.getBuildTarget(), resolver, ruleFinder, pathResolver, pythonPlatform, cxxPlatform, "srcs", baseModule, args.srcs, args.platformSrcs, args.versionedSrcs, selectedVersions);
    ImmutableMap<Path, SourcePath> resources = PythonUtil.getModules(params.getBuildTarget(), resolver, ruleFinder, pathResolver, pythonPlatform, cxxPlatform, "resources", baseModule, args.resources, args.platformResources, args.versionedResources, selectedVersions);
    // Convert the passed in module paths into test module names.
    ImmutableSet.Builder<String> testModulesBuilder = ImmutableSet.builder();
    for (Path name : srcs.keySet()) {
        testModulesBuilder.add(PythonUtil.toModuleName(params.getBuildTarget(), name.toString()));
    }
    ImmutableSet<String> testModules = testModulesBuilder.build();
    // Construct a build rule to generate the test modules list source file and
    // add it to the build.
    BuildRule testModulesBuildRule = createTestModulesSourceBuildRule(params, getTestModulesListPath(params.getBuildTarget(), params.getProjectFilesystem()), testModules);
    resolver.addToIndex(testModulesBuildRule);
    String mainModule;
    if (args.mainModule.isPresent()) {
        mainModule = args.mainModule.get();
    } else {
        mainModule = PythonUtil.toModuleName(params.getBuildTarget(), getTestMainName().toString());
    }
    // Build up the list of everything going into the python test.
    PythonPackageComponents testComponents = PythonPackageComponents.of(ImmutableMap.<Path, SourcePath>builder().put(getTestModulesListName(), testModulesBuildRule.getSourcePathToOutput()).put(getTestMainName(), pythonBuckConfig.getPathToTestMain(params.getProjectFilesystem())).putAll(srcs).build(), resources, ImmutableMap.of(), ImmutableSet.of(), args.zipSafe);
    PythonPackageComponents allComponents = PythonUtil.getAllComponents(params, resolver, ruleFinder, testComponents, pythonPlatform, cxxBuckConfig, cxxPlatform, args.linkerFlags.stream().map(MacroArg.toMacroArgFunction(PythonUtil.MACRO_HANDLER, params.getBuildTarget(), params.getCellRoots(), resolver)::apply).collect(MoreCollectors.toImmutableList()), pythonBuckConfig.getNativeLinkStrategy(), args.preloadDeps);
    // Build the PEX using a python binary rule with the minimum dependencies.
    PythonBinary binary = binaryDescription.createPackageRule(params.withBuildTarget(getBinaryBuildTarget(params.getBuildTarget())), resolver, ruleFinder, pythonPlatform, cxxPlatform, mainModule, args.extension, allComponents, args.buildArgs, args.packageStyle.orElse(pythonBuckConfig.getPackageStyle()), PythonUtil.getPreloadNames(resolver, cxxPlatform, args.preloadDeps));
    resolver.addToIndex(binary);
    ImmutableList.Builder<Pair<Float, ImmutableSet<Path>>> neededCoverageBuilder = ImmutableList.builder();
    for (NeededCoverageSpec coverageSpec : args.neededCoverage) {
        BuildRule buildRule = resolver.getRule(coverageSpec.getBuildTarget());
        if (params.getDeps().contains(buildRule) && buildRule instanceof PythonLibrary) {
            PythonLibrary pythonLibrary = (PythonLibrary) buildRule;
            ImmutableSortedSet<Path> paths;
            if (coverageSpec.getPathName().isPresent()) {
                Path path = coverageSpec.getBuildTarget().getBasePath().resolve(coverageSpec.getPathName().get());
                if (!pythonLibrary.getPythonPackageComponents(pythonPlatform, cxxPlatform).getModules().keySet().contains(path)) {
                    throw new HumanReadableException("%s: path %s specified in needed_coverage not found in target %s", params.getBuildTarget(), path, buildRule.getBuildTarget());
                }
                paths = ImmutableSortedSet.of(path);
            } else {
                paths = ImmutableSortedSet.copyOf(pythonLibrary.getPythonPackageComponents(pythonPlatform, cxxPlatform).getModules().keySet());
            }
            neededCoverageBuilder.add(new Pair<Float, ImmutableSet<Path>>(coverageSpec.getNeededCoverageRatio(), paths));
        } else {
            throw new HumanReadableException("%s: needed_coverage requires a python library dependency. Found %s instead", params.getBuildTarget(), buildRule);
        }
    }
    Supplier<ImmutableMap<String, String>> testEnv = () -> ImmutableMap.copyOf(Maps.transformValues(args.env, MACRO_HANDLER.getExpander(params.getBuildTarget(), params.getCellRoots(), resolver)));
    // Generate and return the python test rule, which depends on the python binary rule above.
    return PythonTest.from(params, ruleFinder, testEnv, binary, args.labels, neededCoverageBuilder.build(), args.testRuleTimeoutMs.map(Optional::of).orElse(defaultTestRuleTimeoutMs), args.contacts);
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) SourcePath(com.facebook.buck.rules.SourcePath) ImmutableSet(com.google.common.collect.ImmutableSet) BuildRule(com.facebook.buck.rules.BuildRule) Pair(com.facebook.buck.model.Pair) SourcePath(com.facebook.buck.rules.SourcePath) Path(java.nio.file.Path) Optional(java.util.Optional) CxxPlatform(com.facebook.buck.cxx.CxxPlatform) SourcePathRuleFinder(com.facebook.buck.rules.SourcePathRuleFinder) SourcePathResolver(com.facebook.buck.rules.SourcePathResolver) ImmutableMap(com.google.common.collect.ImmutableMap) HumanReadableException(com.facebook.buck.util.HumanReadableException)

Example 43 with Optional

use of java.util.Optional in project buck by facebook.

the class CachingBuildEngine method processBuildRule.

private ListenableFuture<BuildResult> processBuildRule(final BuildRule rule, final BuildEngineBuildContext buildContext, final ExecutionContext executionContext, final OnDiskBuildInfo onDiskBuildInfo, final BuildInfoRecorder buildInfoRecorder, final BuildableContext buildableContext, final ConcurrentLinkedQueue<ListenableFuture<Void>> asyncCallbacks) {
    // If we've already seen a failure, exit early.
    if (!buildContext.isKeepGoing() && firstFailure != null) {
        return Futures.immediateFuture(BuildResult.canceled(rule, firstFailure));
    }
    final RuleKeyFactories ruleKeyFactory = ruleKeyFactories.apply(rule.getProjectFilesystem());
    try (BuildRuleEvent.Scope scope = BuildRuleEvent.resumeSuspendScope(buildContext.getEventBus(), rule, buildRuleDurationTracker, ruleKeyFactory.getDefaultRuleKeyFactory())) {
        // 1. Check if it's already built.
        Optional<RuleKey> cachedRuleKey = onDiskBuildInfo.getRuleKey(BuildInfo.MetadataKey.RULE_KEY);
        final RuleKey defaultRuleKey = ruleKeyFactory.getDefaultRuleKeyFactory().build(rule);
        if (defaultRuleKey.equals(cachedRuleKey.orElse(null))) {
            return Futures.transform(markRuleAsUsed(rule, buildContext.getEventBus()), Functions.constant(BuildResult.success(rule, BuildRuleSuccessType.MATCHING_RULE_KEY, CacheResult.localKeyUnchangedHit())));
        }
        // 2. Rule key cache lookup.
        ListenableFuture<CacheResult> rulekeyCacheResult = cacheActivityService.submit(() -> {
            CacheResult cacheResult = tryToFetchArtifactFromBuildCacheAndOverlayOnTopOfProjectFilesystem(rule, defaultRuleKey, buildContext.getArtifactCache(), // TODO(shs96c): This should be a shared between all tests, not one per cell
            rule.getProjectFilesystem(), buildContext);
            if (cacheResult.getType().isSuccess()) {
                fillMissingBuildMetadataFromCache(cacheResult, buildInfoRecorder, BuildInfo.MetadataKey.INPUT_BASED_RULE_KEY, BuildInfo.MetadataKey.DEP_FILE_RULE_KEY, BuildInfo.MetadataKey.DEP_FILE);
            }
            return cacheResult;
        }, CACHE_CHECK_RESOURCE_AMOUNTS);
        return Futures.transformAsync(rulekeyCacheResult, ruleAsyncFunction(rule, buildContext.getEventBus(), (cacheResult) -> handleRuleKeyCacheResult(rule, buildContext, executionContext, onDiskBuildInfo, buildInfoRecorder, buildableContext, asyncCallbacks, ruleKeyFactory, cacheResult)), serviceByAdjustingDefaultWeightsTo(SCHEDULING_MORE_WORK_RESOURCE_AMOUNTS));
    }
}
Also used : OptionalCompat(com.facebook.buck.util.OptionalCompat) NoSuchFileException(java.nio.file.NoSuchFileException) GZIPInputStream(java.util.zip.GZIPInputStream) ArtifactCache(com.facebook.buck.artifact_cache.ArtifactCache) BufferedInputStream(java.io.BufferedInputStream) StepRunner(com.facebook.buck.step.StepRunner) BuckEvent(com.facebook.buck.event.BuckEvent) RuleKeyCalculationEvent(com.facebook.buck.event.RuleKeyCalculationEvent) ObjectMappers(com.facebook.buck.util.ObjectMappers) MoreFutures(com.facebook.buck.util.concurrent.MoreFutures) SettableFuture(com.google.common.util.concurrent.SettableFuture) ArtifactCompressionEvent(com.facebook.buck.event.ArtifactCompressionEvent) ProjectFilesystem(com.facebook.buck.io.ProjectFilesystem) RuleKeyAndInputs(com.facebook.buck.rules.keys.RuleKeyAndInputs) Map(java.util.Map) RuleKeyFactories(com.facebook.buck.rules.keys.RuleKeyFactories) TypeReference(com.fasterxml.jackson.core.type.TypeReference) ArtifactInfo(com.facebook.buck.artifact_cache.ArtifactInfo) Path(java.nio.file.Path) WeightedListeningExecutorService(com.facebook.buck.util.concurrent.WeightedListeningExecutorService) Function(com.google.common.base.Function) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) Set(java.util.Set) SizeLimiter(com.facebook.buck.rules.keys.SizeLimiter) DefaultFileHashCache(com.facebook.buck.util.cache.DefaultFileHashCache) BuildTarget(com.facebook.buck.model.BuildTarget) Sets(com.google.common.collect.Sets) List(java.util.List) Stream(java.util.stream.Stream) StepFailedException(com.facebook.buck.step.StepFailedException) LazyPath(com.facebook.buck.io.LazyPath) ByteStreams(com.google.common.io.ByteStreams) DependencyFileEntry(com.facebook.buck.rules.keys.DependencyFileEntry) Optional(java.util.Optional) GZIPOutputStream(java.util.zip.GZIPOutputStream) MoreFunctions(com.facebook.buck.util.MoreFunctions) RuleKeyFactoryManager(com.facebook.buck.rules.keys.RuleKeyFactoryManager) ListeningExecutorService(com.google.common.util.concurrent.ListeningExecutorService) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) BuckEventBus(com.facebook.buck.event.BuckEventBus) ProjectFileHashCache(com.facebook.buck.util.cache.ProjectFileHashCache) MoreExecutors(com.google.common.util.concurrent.MoreExecutors) Step(com.facebook.buck.step.Step) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) ConsoleEvent(com.facebook.buck.event.ConsoleEvent) BufferedOutputStream(java.io.BufferedOutputStream) ArrayList(java.util.ArrayList) ConcurrentMap(java.util.concurrent.ConcurrentMap) ExecutionContext(com.facebook.buck.step.ExecutionContext) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) ThrowableConsoleEvent(com.facebook.buck.event.ThrowableConsoleEvent) ResourceAmounts(com.facebook.buck.util.concurrent.ResourceAmounts) Atomics(com.google.common.util.concurrent.Atomics) Nonnull(javax.annotation.Nonnull) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) Nullable(javax.annotation.Nullable) SupportsInputBasedRuleKey(com.facebook.buck.rules.keys.SupportsInputBasedRuleKey) MoreCollectors(com.facebook.buck.util.MoreCollectors) OutputStream(java.io.OutputStream) Logger(com.facebook.buck.log.Logger) Functions(com.google.common.base.Functions) CacheResultType(com.facebook.buck.artifact_cache.CacheResultType) Files(java.nio.file.Files) HashCode(com.google.common.hash.HashCode) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Throwables(com.google.common.base.Throwables) IOException(java.io.IOException) HumanReadableException(com.facebook.buck.util.HumanReadableException) Maps(com.google.common.collect.Maps) FutureCallback(com.google.common.util.concurrent.FutureCallback) ExecutionException(java.util.concurrent.ExecutionException) ContextualProcessExecutor(com.facebook.buck.util.ContextualProcessExecutor) Futures(com.google.common.util.concurrent.Futures) BorrowablePath(com.facebook.buck.io.BorrowablePath) Paths(java.nio.file.Paths) CacheResult(com.facebook.buck.artifact_cache.CacheResult) FileHashCache(com.facebook.buck.util.cache.FileHashCache) Unzip(com.facebook.buck.zip.Unzip) Preconditions(com.google.common.base.Preconditions) AsyncFunction(com.google.common.util.concurrent.AsyncFunction) VisibleForTesting(com.google.common.annotations.VisibleForTesting) MoreFiles(com.facebook.buck.io.MoreFiles) SupportsDependencyFileRuleKey(com.facebook.buck.rules.keys.SupportsDependencyFileRuleKey) Collections(java.util.Collections) InputStream(java.io.InputStream) RuleKeyFactories(com.facebook.buck.rules.keys.RuleKeyFactories) SupportsInputBasedRuleKey(com.facebook.buck.rules.keys.SupportsInputBasedRuleKey) SupportsDependencyFileRuleKey(com.facebook.buck.rules.keys.SupportsDependencyFileRuleKey) CacheResult(com.facebook.buck.artifact_cache.CacheResult)

Example 44 with Optional

use of java.util.Optional in project buck by facebook.

the class PrebuiltOcamlLibraryDescription method createBuildRule.

@Override
public <A extends Arg> OcamlLibrary createBuildRule(TargetGraph targetGraph, final BuildRuleParams params, BuildRuleResolver resolver, final A args) {
    final BuildTarget target = params.getBuildTarget();
    final boolean bytecodeOnly = args.bytecodeOnly.orElse(false);
    final String libDir = args.libDir.orElse("lib");
    final String libName = args.libName.orElse(target.getShortName());
    final String nativeLib = args.nativeLib.orElse(String.format("%s.cmxa", libName));
    final String bytecodeLib = args.bytecodeLib.orElse(String.format("%s.cma", libName));
    final ImmutableList<String> cLibs = args.cLibs;
    final Path libPath = target.getBasePath().resolve(libDir);
    final Path includeDir = libPath.resolve(args.includeDir.orElse(""));
    final Optional<SourcePath> staticNativeLibraryPath = bytecodeOnly ? Optional.empty() : Optional.of(new PathSourcePath(params.getProjectFilesystem(), libPath.resolve(nativeLib)));
    final SourcePath staticBytecodeLibraryPath = new PathSourcePath(params.getProjectFilesystem(), libPath.resolve(bytecodeLib));
    final ImmutableList<SourcePath> staticCLibraryPaths = cLibs.stream().map(input -> new PathSourcePath(params.getProjectFilesystem(), libPath.resolve(input))).collect(MoreCollectors.toImmutableList());
    final SourcePath bytecodeLibraryPath = new PathSourcePath(params.getProjectFilesystem(), libPath.resolve(bytecodeLib));
    SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver);
    return new PrebuiltOcamlLibrary(params, ruleFinder, staticNativeLibraryPath, staticBytecodeLibraryPath, staticCLibraryPaths, bytecodeLibraryPath, libPath, includeDir);
}
Also used : SourcePath(com.facebook.buck.rules.SourcePath) PathSourcePath(com.facebook.buck.rules.PathSourcePath) Path(java.nio.file.Path) SourcePath(com.facebook.buck.rules.SourcePath) PathSourcePath(com.facebook.buck.rules.PathSourcePath) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) TargetGraph(com.facebook.buck.rules.TargetGraph) SourcePathRuleFinder(com.facebook.buck.rules.SourcePathRuleFinder) SourcePath(com.facebook.buck.rules.SourcePath) VersionPropagator(com.facebook.buck.versions.VersionPropagator) BuildTarget(com.facebook.buck.model.BuildTarget) SuppressFieldNotInitialized(com.facebook.infer.annotation.SuppressFieldNotInitialized) AbstractDescriptionArg(com.facebook.buck.rules.AbstractDescriptionArg) ImmutableList(com.google.common.collect.ImmutableList) PathSourcePath(com.facebook.buck.rules.PathSourcePath) Optional(java.util.Optional) BuildRuleResolver(com.facebook.buck.rules.BuildRuleResolver) BuildRuleParams(com.facebook.buck.rules.BuildRuleParams) Path(java.nio.file.Path) Description(com.facebook.buck.rules.Description) MoreCollectors(com.facebook.buck.util.MoreCollectors) BuildTarget(com.facebook.buck.model.BuildTarget) PathSourcePath(com.facebook.buck.rules.PathSourcePath) SourcePathRuleFinder(com.facebook.buck.rules.SourcePathRuleFinder)

Example 45 with Optional

use of java.util.Optional in project buck by facebook.

the class DaemonicCellState method invalidateIfBuckConfigHasChanged.

void invalidateIfBuckConfigHasChanged(Cell cell, Path buildFile) {
    // TODO(mzlee): Check whether usedConfigs includes the buildFileName
    ImmutableMap<String, ImmutableMap<String, Optional<String>>> usedConfigs;
    try (AutoCloseableLock readLock = rawAndComputedNodesLock.readLock()) {
        usedConfigs = buildFileConfigs.get(buildFile);
    }
    if (usedConfigs == null) {
        // TODO(mzlee): Figure out when/how we can safely update this
        this.cell.set(cell);
        return;
    }
    for (Map.Entry<String, ImmutableMap<String, Optional<String>>> keyEnt : usedConfigs.entrySet()) {
        for (Map.Entry<String, Optional<String>> valueEnt : keyEnt.getValue().entrySet()) {
            Optional<String> value = cell.getBuckConfig().getValue(keyEnt.getKey(), valueEnt.getKey());
            if (!value.equals(valueEnt.getValue())) {
                invalidatePath(buildFile);
                this.cell.set(cell);
                return;
            }
        }
    }
}
Also used : Optional(java.util.Optional) AutoCloseableLock(com.facebook.buck.util.concurrent.AutoCloseableLock) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap)

Aggregations

Optional (java.util.Optional)3042 List (java.util.List)1831 Map (java.util.Map)1086 ArrayList (java.util.ArrayList)1032 Collectors (java.util.stream.Collectors)971 Set (java.util.Set)768 IOException (java.io.IOException)742 HashMap (java.util.HashMap)644 Test (org.junit.Test)526 Collections (java.util.Collections)506 Arrays (java.util.Arrays)454 Collection (java.util.Collection)442 Logger (org.slf4j.Logger)432 LoggerFactory (org.slf4j.LoggerFactory)425 HashSet (java.util.HashSet)386 Objects (java.util.Objects)324 ImmutableList (com.google.common.collect.ImmutableList)290 Stream (java.util.stream.Stream)282 ImmutableMap (com.google.common.collect.ImmutableMap)243 Function (java.util.function.Function)226