All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sootup.java.bytecode.inputlocation.JavaModulePathAnalysisInputLocation Maven / Gradle / Ivy

There is a newer version: 1.3.0
Show newest version
package sootup.java.bytecode.inputlocation;
/*-
 * #%L
 * Soot - a J*va Optimization Framework
 * %%
 * Copyright (C) 2018-2020 Andreas Dann, Christian Brüggemann and others
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 2.1 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */
import com.google.common.base.Preconditions;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import sootup.core.IdentifierFactory;
import sootup.core.frontend.ClassProvider;
import sootup.core.frontend.SootClassSource;
import sootup.core.inputlocation.AnalysisInputLocation;
import sootup.core.model.SourceType;
import sootup.core.transform.BodyInterceptor;
import sootup.core.types.ClassType;
import sootup.core.views.View;
import sootup.java.core.*;
import sootup.java.core.signatures.ModulePackageName;
import sootup.java.core.signatures.ModuleSignature;
import sootup.java.core.types.JavaClassType;

/**
 * An implementation of the {@link AnalysisInputLocation} interface for the Java modulepath. Handles
 * directories, archives (including wildcard denoted archives) as stated in the official
 * documentation:
 *
 * @author Andreas Dann created on 28.05.18
 * @see ModuleFinder
 */
public class JavaModulePathAnalysisInputLocation implements ModuleInfoAnalysisInputLocation {

  @Nonnull private final ModuleFinder moduleFinder;
  @Nonnull private final SourceType sourcetype;
  @Nonnull private final List bodyInterceptors;

  /**
   * Creates a {@link JavaModulePathAnalysisInputLocation} which locates classes in the given module
   * path.
   *
   * @param modulePath The class path to search in The {@link ClassProvider} for generating {@link
   *     SootClassSource}es for the files found on the class path
   */
  public JavaModulePathAnalysisInputLocation(@Nonnull Path modulePath) {
    this(modulePath, SourceType.Application);
  }

  public JavaModulePathAnalysisInputLocation(
      @Nonnull Path modulePath, @Nonnull SourceType sourcetype) {
    this(modulePath, FileSystems.getDefault(), sourcetype);
  }

  public JavaModulePathAnalysisInputLocation(
      @Nonnull Path modulePath, @Nonnull FileSystem fileSystem, @Nonnull SourceType sourcetype) {
    this(modulePath, fileSystem, sourcetype, new ArrayList<>());
  }

  /**
   * Creates a {@link JavaModulePathAnalysisInputLocation} which locates classes in the given module
   * path.
   *
   * @param modulePath The class path to search in The {@link ClassProvider} for generating {@link
   *     SootClassSource}es for the files found on the class path
   * @param fileSystem filesystem for the path
   */
  public JavaModulePathAnalysisInputLocation(
      @Nonnull Path modulePath,
      @Nonnull FileSystem fileSystem,
      @Nonnull SourceType sourcetype,
      @Nonnull List bodyInterceptors) {
    this.sourcetype = sourcetype;
    this.bodyInterceptors = bodyInterceptors;
    moduleFinder = new ModuleFinder(modulePath, fileSystem, sourcetype, bodyInterceptors);
  }

  @Nonnull
  public Optional getModuleInfo(ModuleSignature sig, View view) {
    return moduleFinder.getModuleInfo(sig);
  }

  @Nonnull
  public Set getModules(View view) {
    return moduleFinder.getModules();
  }

  @Override
  @Nonnull
  public Collection getClassSources(@Nonnull View view) {
    IdentifierFactory identifierFactory = view.getIdentifierFactory();
    Preconditions.checkArgument(
        identifierFactory instanceof JavaModuleIdentifierFactory,
        "Factory must be a JavaModuleSignatureFactory");

    Collection allModules = moduleFinder.getAllModules();
    return allModules.stream()
        .flatMap(sig -> getClassSourcesInternal(sig, view))
        .collect(Collectors.toList());
  }

  @Nonnull
  @Override
  public SourceType getSourceType() {
    return sourcetype;
  }

  @Override
  @Nonnull
  public List getBodyInterceptors() {
    return bodyInterceptors;
  }

  @Override
  @Nonnull
  public Collection getModulesClassSources(
      @Nonnull ModuleSignature moduleSignature, @Nonnull View view) {
    IdentifierFactory identifierFactory = view.getIdentifierFactory();
    Preconditions.checkArgument(
        identifierFactory instanceof JavaModuleIdentifierFactory,
        "Factory must be a JavaModuleSignatureFactory");
    return getClassSourcesInternal(moduleSignature, view).collect(Collectors.toList());
  }

  protected Stream getClassSourcesInternal(
      @Nonnull ModuleSignature moduleSignature, @Nonnull View view) {

    AnalysisInputLocation inputLocation = moduleFinder.getModule(moduleSignature);
    if (inputLocation == null) {
      return Stream.empty();
    }

    return inputLocation.getClassSources(view).stream().map(src -> (JavaSootClassSource) src);
  }

  @Override
  @Nonnull
  public Optional getClassSource(
      @Nonnull ClassType classType, @Nonnull View view) {
    JavaClassType klassType = (JavaClassType) classType;

    ModuleSignature modulename =
        ((ModulePackageName) klassType.getPackageName()).getModuleSignature();
    // get inputlocation from cache
    AnalysisInputLocation inputLocation = moduleFinder.getModule(modulename);

    if (inputLocation == null) {
      return Optional.empty();
    }

    return inputLocation.getClassSource(klassType, view).map(src -> (JavaSootClassSource) src);
  }

  @Override
  public int hashCode() {
    return moduleFinder.hashCode();
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof JavaModulePathAnalysisInputLocation)) {
      return false;
    }
    return moduleFinder.equals(((JavaModulePathAnalysisInputLocation) o).moduleFinder);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy