protected void initInputClassLoader() {
   ClassLoader cl = Thread.currentThread().getContextClassLoader();
   if (buildOnlyOutdatedFiles && getBinaryOutputDirectory() != null) {
     CompilerClassLoader ccl = getCompilerClassLoader(cl);
     if (ccl == null) {
       try {
         Launcher.LOGGER.debug(
             "setting classloader for " + getBinaryOutputDirectory().toURI().toURL());
         Thread.currentThread()
             .setContextClassLoader(
                 new CompilerClassLoader(
                     new URL[] {getBinaryOutputDirectory().toURI().toURL()},
                     factory.getEnvironment().getInputClassLoader()));
       } catch (Exception e) {
         Launcher.LOGGER.error(e.getMessage(), e);
       }
     }
   } else {
     if (!hasClassLoader(
         Thread.currentThread().getContextClassLoader(),
         factory.getEnvironment().getInputClassLoader())) {
       Thread.currentThread()
           .setContextClassLoader(factory.getEnvironment().getInputClassLoader());
     }
   }
 }
 protected void generateProcessedSourceFilesUsingTypes(Filter<CtType<?>> typeFilter) {
   if (factory.getEnvironment().getDefaultFileGenerator() != null) {
     factory.getEnvironment().debugMessage("Generating source using types...");
     ProcessingManager processing = new QueueProcessingManager(factory);
     processing.addProcessor(factory.getEnvironment().getDefaultFileGenerator());
     if (typeFilter != null) {
       processing.process(Query.getElements(factory.Package().getRootPackage(), typeFilter));
     } else {
       processing.process(factory.Package().getRootPackage());
     }
   }
 }
  @Test
  public void testPrintAMethodWithGeneric() throws Exception {
    final Launcher launcher = new Launcher();
    final Factory factory = launcher.getFactory();
    factory.getEnvironment().setAutoImports(true);
    final SpoonCompiler compiler = launcher.createCompiler();
    compiler.addInputSource(new File("./src/test/java/spoon/test/prettyprinter/testclasses/"));
    compiler.build();

    final CtClass<?> aClass = (CtClass<?>) factory.Type().get(AClass.class);
    final String expected =
        "public List<? extends ArrayList> aMethodWithGeneric() {"
            + System.lineSeparator()
            + "    return new ArrayList<>();"
            + System.lineSeparator()
            + "}";
    assertEquals(expected, aClass.getMethodsByName("aMethodWithGeneric").get(0).toString());

    final CtConstructorCall<?> constructorCall =
        aClass.getElements(new TypeFilter<CtConstructorCall<?>>(CtConstructorCall.class)).get(0);
    final CtTypeReference<?> ctTypeReference =
        constructorCall.getType().getActualTypeArguments().get(0);
    assertTrue(ctTypeReference instanceof CtImplicitTypeReference);
    assertEquals("Object", ctTypeReference.getSimpleName());
  }
  @Override
  public void process(Collection<Processor<? extends CtElement>> processors) {
    initInputClassLoader();

    // processing (consume all the processors)
    ProcessingManager processing = new QueueProcessingManager(factory);
    for (Processor<? extends CtElement> processorName : processors) {
      processing.addProcessor(processorName);
      factory.getEnvironment().debugMessage("Loaded processor " + processorName + ".");
    }

    processing.process(factory.Package().getRootPackage());
  }
  @Override
  public void instantiateAndProcess(List<String> processors) {
    initInputClassLoader();

    // processing (consume all the processors)
    ProcessingManager processing = new QueueProcessingManager(factory);
    for (String processorName : processors) {
      processing.addProcessor(processorName);
      factory.getEnvironment().debugMessage("Loaded processor " + processorName + ".");
    }

    processing.process(factory.Package().getRootPackage());
  }
Beispiel #6
0
  @Before
  public void setUp() throws Exception {
    final File testDirectory = new File("./src/test/java/spoon/test/interfaces/testclasses/");

    final Launcher launcher = new Launcher();

    this.factory = launcher.createFactory();
    factory.getEnvironment().setComplianceLevel(8);
    SpoonCompiler compiler = launcher.createCompiler(this.factory);

    compiler.addInputSource(testDirectory);
    compiler.build();
  }
  protected InputStream getCompilationUnitInputStream(String path) {
    Environment env = factory.getEnvironment();
    spoon.reflect.cu.CompilationUnit cu = factory.CompilationUnit().getMap().get(path);
    List<CtType<?>> toBePrinted = cu.getDeclaredTypes();

    PrettyPrinter printer = null;

    if (printer == null) {
      printer = new DefaultJavaPrettyPrinter(env);
    }
    printer.calculate(cu, toBePrinted);

    return new ByteArrayInputStream(printer.getResult().toString().getBytes());
  }
  @Test
  public void useFullyQualifiedNamesInCtElementImpl_toString() throws Exception {
    Factory factory = TestUtils.build(AClass.class);
    factory.getEnvironment().setAutoImports(false);

    final CtClass<?> aClass = (CtClass<?>) factory.Type().get(AClass.class);
    String computed = aClass.getMethodsByName("aMethod").get(0).toString();
    final String expected =
        "public java.util.List<?> aMethod() {"
            + nl
            + "    return new java.util.ArrayList<>();"
            + nl
            + "}";
    assertEquals(
        "the toString method of CtElementImpl should not shorten type names as it has no context or import statements",
        expected,
        computed);
  }
  @Override
  public boolean compileInputSources() {
    initInputClassLoader();
    factory.getEnvironment().debugMessage("compiling input sources: " + sources.getAllJavaFiles());
    long t = System.currentTimeMillis();
    javaCompliance = factory.getEnvironment().getComplianceLevel();

    Main batchCompiler = createBatchCompiler(false);
    List<String> args = new ArrayList<String>();
    args.add("-1." + javaCompliance);
    if (encoding != null) {
      args.add("-encoding");
      args.add(encoding);
    }
    args.add("-preserveAllLocals");
    args.add("-enableJavadoc");
    args.add("-noExit");
    args.add("-proc:none");
    if (getBinaryOutputDirectory() != null) {
      args.add("-d");
      args.add(getBinaryOutputDirectory().getAbsolutePath());
    } else {
      args.add("-d");
      args.add("none");
    }

    String finalClassPath = null;
    if (getSourceClasspath() != null) {
      finalClassPath = computeJdtClassPath();
    } else {
      ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
      if (currentClassLoader instanceof URLClassLoader) {
        URL[] urls = ((URLClassLoader) currentClassLoader).getURLs();
        if (urls != null && urls.length > 0) {
          String classpath = ".";
          for (URL url : urls) {
            classpath += File.pathSeparator + url.getFile();
          }
          if (classpath != null) {
            finalClassPath = classpath;
          }
        }
      }
    }

    args.add("-cp");
    args.add(finalClassPath);

    // Set<String> paths = new HashSet<String>();
    // for (SpoonFile file : sources.getAllJavaFiles()) {
    // paths.add(file.getParent().getPath());
    // }
    // args.addAll(paths);

    args.addAll(toStringList(sources.getAllJavaFiles()));

    // configure(args.toArray(new String[0]));

    batchCompiler.compile(args.toArray(new String[0]));

    factory
        .getEnvironment()
        .debugMessage("compiled in " + (System.currentTimeMillis() - t) + " ms");
    return probs.size() == 0;
  }
  protected void generateProcessedSourceFilesUsingCUs() {

    factory.getEnvironment().debugMessage("Generating source using compilation units...");
    // Check output directory
    if (outputDirectory == null) {
      throw new RuntimeException("You should set output directory before generating source files");
    }
    // Create spooned directory
    if (outputDirectory.isFile()) {
      throw new RuntimeException("Output must be a directory");
    }
    if (!outputDirectory.exists()) {
      if (!outputDirectory.mkdirs()) {
        throw new RuntimeException("Error creating output directory");
      }
    }

    try {
      outputDirectory = outputDirectory.getCanonicalFile();
    } catch (IOException e1) {
      throw new SpoonException(e1);
    }

    factory.getEnvironment().debugMessage("Generating source files to: " + outputDirectory);

    List<File> printedFiles = new ArrayList<File>();
    for (spoon.reflect.cu.CompilationUnit cu : factory.CompilationUnit().getMap().values()) {

      factory
          .getEnvironment()
          .debugMessage("Generating source for compilation unit: " + cu.getFile());

      CtType<?> element = cu.getMainType();

      CtPackage pack = element.getPackage();

      // create package directory
      File packageDir;
      if (pack.getQualifiedName().equals(CtPackage.TOP_LEVEL_PACKAGE_NAME)) {
        packageDir = new File(outputDirectory.getAbsolutePath());
      } else {
        // Create current package directory
        packageDir =
            new File(
                outputDirectory.getAbsolutePath()
                    + File.separatorChar
                    + pack.getQualifiedName().replace('.', File.separatorChar));
      }
      if (!packageDir.exists()) {
        if (!packageDir.mkdirs()) {
          throw new RuntimeException("Error creating output directory");
        }
      }

      // print type
      try {
        File file =
            new File(
                packageDir.getAbsolutePath()
                    + File.separatorChar
                    + element.getSimpleName()
                    + DefaultJavaPrettyPrinter.JAVA_FILE_EXTENSION);
        file.createNewFile();

        // the path must be given relatively to to the working directory
        InputStream is = getCompilationUnitInputStream(cu.getFile().getPath());

        IOUtils.copy(is, new FileOutputStream(file));

        if (!printedFiles.contains(file)) {
          printedFiles.add(file);
        }

      } catch (Exception e) {
        Launcher.LOGGER.error(e.getMessage(), e);
      }
    }
  }
  @Test
  public void autoImportUsesFullyQualifiedNameWhenImportedNameAlreadyPresent() throws Exception {
    Factory factory =
        TestUtils.build(
            spoon.test.prettyprinter.testclasses.sub.TypeIdentifierCollision.class,
            spoon.test.prettyprinter.testclasses.TypeIdentifierCollision.class);
    factory.getEnvironment().setAutoImports(true);

    final CtClass<?> aClass =
        (CtClass<?>)
            factory.Type().get(spoon.test.prettyprinter.testclasses.TypeIdentifierCollision.class);

    String expected =
        "public void setFieldUsingExternallyDefinedEnumWithSameNameAsLocal() {"
            + nl
            + "    localField = spoon.test.prettyprinter.testclasses.sub.TypeIdentifierCollision.ENUM.E1.ordinal();"
            + nl
            + "}";
    String computed =
        aClass
            .getMethodsByName("setFieldUsingExternallyDefinedEnumWithSameNameAsLocal")
            .get(0)
            .toString();
    assertEquals(
        "the externally defined enum should be fully qualified to avoid a name clash with the local enum of the same name",
        expected,
        computed);

    expected = // This is what is expected
        "public void setFieldUsingLocallyDefinedEnum() {"
            + nl
            + "    localField = ENUM.E1.ordinal();"
            + nl
            + "}";
    expected = // This is correct however it could be more concise.
        "public void setFieldUsingLocallyDefinedEnum() {"
            + nl
            + "    localField = TypeIdentifierCollision.ENUM.E1.ordinal();"
            + nl
            + "}";
    computed = aClass.getMethodsByName("setFieldUsingLocallyDefinedEnum").get(0).toString();
    assertEquals(expected, computed);

    expected =
        "public void setFieldOfClassWithSameNameAsTheCompilationUnitClass() {"
            + nl
            + "    spoon.test.prettyprinter.testclasses.sub.TypeIdentifierCollision.globalField = localField;"
            + nl
            + "}";
    computed =
        aClass
            .getMethodsByName("setFieldOfClassWithSameNameAsTheCompilationUnitClass")
            .get(0)
            .toString();
    assertEquals(
        "The static field of an external type with the same identifier as the compilation unit should be fully qualified",
        expected,
        computed);

    expected = // This is what is expected
        "public void referToTwoInnerClassesWithTheSameName() {"
            + nl
            + "    ClassA.VAR0 = ClassA.getNum();"
            + nl
            + "    Class1.ClassA.VAR1 = Class1.ClassA.getNum();"
            + nl
            + "}";
    expected = // This is correct however it could be more concise.
        "public void referToTwoInnerClassesWithTheSameName() {"
            + nl
            + "    TypeIdentifierCollision.Class0.ClassA.VAR0 = TypeIdentifierCollision.Class0.ClassA.getNum();"
            + nl
            + "    TypeIdentifierCollision.Class1.ClassA.VAR1 = TypeIdentifierCollision.Class1.ClassA.getNum();"
            + nl
            + "}";

    // Ensure the ClassA of Class0 takes precedence over an import statement for ClassA in Class1,
    // and it's identifier can be the short version.

    computed = aClass.getMethodsByName("referToTwoInnerClassesWithTheSameName").get(0).toString();
    assertEquals(
        "where inner types have the same identifier only one may be shortened and the other should be fully qualified",
        expected,
        computed);

    expected =
        "public enum ENUM {"
            + nl
            + "E1(spoon.test.prettyprinter.testclasses.sub.TypeIdentifierCollision.globalField,spoon.test.prettyprinter.testclasses.sub.TypeIdentifierCollision.ENUM.E1);"
            + nl
            + "    final int NUM;"
            + nl
            + "    final Enum<?> e;"
            + nl
            + "    private ENUM(int num ,Enum<?> e) {"
            + nl
            + "        NUM = num;"
            + nl
            + "        this.e = e;"
            + nl
            + "    }}";
    computed = aClass.getNestedType("ENUM").toString();
    assertEquals(
        "Parameters in an enum constructor should be fully typed when they refer to externally defined static field of a class with the same identifier as another locally defined type",
        expected,
        computed);
  }
Beispiel #12
0
 @Override
 public void setFactory(Factory factory) {
   this.factory = factory;
   LOGGER.setLevel(factory.getEnvironment().getLevel());
 }