예제 #1
0
 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());
     }
   }
 }
  private ITypeModel processTypeReference(CtTypeReference<?> typeReference) {
    String qualifiedName = typeReference.getQualifiedName();
    ITypeModel existingType = registry.getType(qualifiedName);
    if (existingType != null) {
      return new ProxyType(registry, qualifiedName);
    }

    CtClass<Object> ctClass = factory.Class().get(qualifiedName);
    if (ctClass != null) {
      return processType(ctClass);
    }

    CtType<Object> ctType = factory.Type().get(qualifiedName);
    if (ctType != null) {
      return processType(ctType);
    }

    TypeModel type = new TypeModel();
    type.setFullyQualifiedName(qualifiedName);
    registry.registerType(type);

    fillReference(type, typeReference);

    Collection<CtExecutableReference<?>> methods = typeReference.getDeclaredExecutables();
    for (CtExecutableReference<?> m : methods) {
      IMethodModel methodModel = processMethodReference(m);
      type.addMethod(methodModel);
    }
    Collection<CtFieldReference<?>> fields = typeReference.getDeclaredFields();
    for (CtFieldReference<?> m : fields) {
      IFieldModel methodModel = processFieldReference(m);
      type.addField(methodModel);
    }
    return new ProxyType(registry, qualifiedName);
  }
예제 #3
0
  @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());
  }
  protected Map<Statement, Double> buildCodeFragmentFor(CtType cl, Coverage coverage) {
    Factory factory = cl.getFactory();
    Map<Statement, Double> codeFragments = new LinkedHashMap<>();

    for (CtMethod<?> mth : (Set<CtMethod>) cl.getMethods()) {
      if (!mth.getModifiers().contains(ModifierKind.ABSTRACT)
          && !mth.getModifiers().contains(ModifierKind.PRIVATE)) {
        //                    && getCoverageForMethod(coverage, cl, mth) != 1.0) {

        CtExecutableReference executableRef = factory.Executable().createReference(mth);
        executableRef.setStatic(mth.getModifiers().contains(ModifierKind.STATIC));
        CtInvocation invocation =
            factory.Code().createInvocation(buildVarRef(cl.getReference(), factory), executableRef);
        invocation.setArguments(
            mth.getParameters()
                .stream()
                .map(param -> buildVarRef(param.getType(), factory))
                .collect(Collectors.toList()));
        invocation.setType(mth.getType());
        Statement stmt = new Statement(invocation);
        codeFragments.put(stmt, getCoverageForMethod(coverage, cl, mth));
      }
    }
    return codeFragments;
  }
예제 #5
0
 @Test
 public void printerCanPrintInvocationWithoutException() throws Exception {
   String packageName = "spoon.test.subclass.prettyprinter";
   String className = "DefaultPrettyPrinterExample";
   String qualifiedName = packageName + "." + className;
   SpoonCompiler comp = new Launcher().createCompiler();
   List<SpoonResource> fileToBeSpooned =
       SpoonResourceHelper.resources(
           "./src/test/resources/printer-test/" + qualifiedName.replace('.', '/') + ".java");
   assertEquals(1, fileToBeSpooned.size());
   comp.addInputSources(fileToBeSpooned);
   List<SpoonResource> classpath =
       SpoonResourceHelper.resources(
           "./src/test/resources/printer-test/DefaultPrettyPrinterDependency.jar");
   assertEquals(1, classpath.size());
   comp.setSourceClasspath(classpath.get(0).getPath());
   comp.build();
   Factory factory = comp.getFactory();
   CtType<?> theClass = factory.Type().get(qualifiedName);
   List<CtInvocation<?>> elements =
       Query.getElements(theClass, new TypeFilter<CtInvocation<?>>(CtInvocation.class));
   assertEquals(3, elements.size());
   CtInvocation<?> mathAbsInvocation = elements.get(1);
   assertEquals("java.lang.Math.abs(message.length())", mathAbsInvocation.toString());
 }
예제 #6
0
 /** return all executables of this class */
 public static Collection<CtExecutableReference<?>> getAllExecutables(
     Class<?> clazz, Factory factory) {
   Collection<CtExecutableReference<?>> l = new ArrayList<CtExecutableReference<?>>();
   for (Method m : clazz.getDeclaredMethods()) {
     l.add(factory.Method().createReference(m));
   }
   for (Constructor<?> c : clazz.getDeclaredConstructors()) {
     l.add(factory.Constructor().createReference(c));
   }
   return l;
 }
예제 #7
0
  @Test
  public void testClone() throws Exception {
    final Factory factory = build(Adobada.class);
    final CtClass<Adobada> adobada = factory.Class().get(Adobada.class);
    final CtMethod<?> m2 = adobada.getMethod("m2");

    CtMethod<?> clone = m2.clone();
    clone.setVisibility(ModifierKind.PRIVATE);

    assertEquals(ModifierKind.PUBLIC, m2.getModifiers().iterator().next());
  }
  protected CtVariableRead buildVarRef(CtTypeReference type, Factory factory) {
    CtTypeReference<Object> typeRef = factory.Core().clone(type);

    CtLocalVariable<Object> localVar = factory.Core().createLocalVariable();
    localVar.setType(typeRef);
    localVar.setSimpleName("var_" + type.getSimpleName() + "_" + System.currentTimeMillis());

    CtVariableReadImpl varRead = new CtVariableReadImpl();
    varRead.setVariable(factory.Code().createLocalVariableReference(localVar));
    return varRead;
  }
예제 #9
0
 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());
     }
   }
 }
예제 #10
0
  @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());
  }
예제 #11
0
  @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());
  }
예제 #12
0
  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());
  }
예제 #13
0
  @Test
  public void testConstructorCallFactory() throws Exception {
    CtTypeReference<ArrayList> ctTypeReference =
        factory.Code().createCtTypeReference(ArrayList.class);
    CtConstructorCall<ArrayList> constructorCall =
        factory.Code().createConstructorCall(ctTypeReference);
    assertEquals("new java.util.ArrayList()", constructorCall.toString());

    CtConstructorCall<ArrayList> constructorCallWithParameter =
        factory.Code().createConstructorCall(ctTypeReference, constructorCall);

    assertEquals(
        "new java.util.ArrayList(new java.util.ArrayList())",
        constructorCallWithParameter.toString());
  }
예제 #14
0
 /** Gets all the field references for a given class (including the superclasses'). */
 public static Collection<CtFieldReference<?>> getAllFields(Class<?> c, Factory factory) {
   Collection<CtFieldReference<?>> l = new ArrayList<CtFieldReference<?>>();
   for (Field f : getAllFields(c)) {
     l.add(factory.Field().createReference(f));
   }
   return l;
 }
예제 #15
0
파일: APITest.java 프로젝트: fanlong/spoon
 @Test
 public void testBasicAPIUsage() throws Exception {
   // this test shows a basic usage of the Launcher API without command line
   // and asserts there is no exception
   SpoonAPI spoon = new Launcher();
   spoon.addInputResource("src/test/resources/spoon/test/api");
   spoon.setSourceOutputDirectory("target/spooned");
   spoon.run();
   Factory factory = spoon.getFactory();
   for (CtPackage p : factory.Package().getAll()) {
     spoon.getEnvironment().debugMessage("package: " + p.getQualifiedName());
   }
   for (CtType<?> s : factory.Class().getAll()) {
     spoon.getEnvironment().debugMessage("class: " + s.getQualifiedName());
   }
 }
예제 #16
0
  @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);
  }
예제 #17
0
 @Test
 public void testAccessToStringOnPostIncrement() throws Exception {
   // contract: a target to a post increment on a variable access write brackets.
   Factory factory = createFactory();
   CtClass<?> clazz =
       factory.Code()
           .createCodeSnippetStatement( //
               "class X {" //
                   + "public void foo() {" //
                   + " Integer i = 1;" //
                   + " (i++).toString();" //
                   + " int k = 0;" //
                   + " k++;" //
                   + "}};")
           .compile();
   CtMethod<?> foo = (CtMethod<?>) clazz.getMethods().toArray()[0];
   assertEquals("(i++).toString()", foo.getBody().getStatement(1).toString());
   assertEquals("k++", foo.getBody().getStatement(3).toString());
 }
예제 #18
0
 @Test
 public void testAddSameMethodsTwoTimes() throws Exception {
   final Factory factory = createFactory();
   final CtClass<Object> tacos = factory.Class().create("Tacos");
   final CtMethod<Void> method =
       factory.Method()
           .create(
               tacos,
               new HashSet<>(),
               factory.Type().voidType(),
               "m",
               new ArrayList<>(),
               new HashSet<>());
   try {
     tacos.addMethod(method.clone());
   } catch (ConcurrentModificationException e) {
     fail();
   }
 }
예제 #19
0
  @Test
  public void testTransformationOnConstructorWithInsertBegin() throws Exception {
    final CtConstructor<?> ctConstructor =
        aClass.getElements(new TypeFilter<CtConstructor<?>>(CtConstructor.class)).get(0);
    ctConstructor.getBody().insertBegin(factory.Code().createCodeSnippetStatement("int i = 0"));

    assertEquals(2, ctConstructor.getBody().getStatements().size());
    assertEquals("super()", ctConstructor.getBody().getStatement(0).toString());

    TestUtils.canBeBuilt("./target/spooned/spoon/test/constructor/testclasses/", 8);
  }
예제 #20
0
  @Test
  public void superInvocationWithEnclosingInstance() throws Exception {

    /**
     * To extend a nested class an enclosing instance must be provided to call the super
     * constructor.
     */
    String sourcePath = "./src/test/resources/spoon/test/prettyprinter/NestedSuperCall.java";
    List<SpoonResource> files = SpoonResourceHelper.resources(sourcePath);
    assertEquals(1, files.size());

    SpoonCompiler comp = new Launcher().createCompiler();
    comp.addInputSources(files);
    comp.build();

    Factory factory = comp.getFactory();
    CtType<?> theClass = factory.Type().get("spoon.test.prettyprinter.NestedSuperCall");

    assertTrue(theClass.toString().contains("nc.super(\"a\")"));
  }
  @Override
  public CtElement[] getMutatedEntries(CtBinaryOperator<?> element, Factory factory) {
    ArrayList<CtElement> ret = new ArrayList<CtElement>();

    if (element == null) return emptySet();

    for (BinaryOperatorKind kind : operators) {
      if (element.getKind() != kind) {
        CtExpression<?> right_c = factory.Core().clone(element.getRightHandOperand());
        CtExpression<?> left_c = factory.Core().clone(element.getLeftHandOperand());
        CtBinaryOperator<?> binaryOp = factory.Code().createBinaryOperator(left_c, right_c, kind);
        // Set parent
        right_c.setParent(binaryOp);
        left_c.setParent(binaryOp);
        ret.add(binaryOp);
      }
    }

    return ret.toArray(new CtElement[1]);
  }
예제 #22
0
 @Before
 public void setUp() throws Exception {
   SpoonAPI launcher = new Launcher();
   launcher.run(
       new String[] {
         "-i", "./src/test/java/spoon/test/constructor/testclasses/",
         "-o", "./target/spooned/"
       });
   factory = launcher.getFactory();
   aClass = factory.Class().get(Tacos.class);
 }
예제 #23
0
 @Test
 public void callParamConstructor() throws Exception {
   CtClass<Object> aClass = factory.Class().get(AClass.class);
   CtConstructor<Object> constructor = aClass.getConstructors().iterator().next();
   assertEquals(
       "{"
           + System.lineSeparator()
           + "    enclosingInstance.super();"
           + System.lineSeparator()
           + "}",
       constructor.getBody().toString());
 }
예제 #24
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();
  }
예제 #25
0
  public CtStatement apply(CtType<?> targetType) {
    CtClass<?> c;
    Factory factory;

    // we first need a factory
    if (targetType != null) {
      // if it's template with reference replacement
      factory = targetType.getFactory();
    } else {
      // else we have at least one template parameter with a factory
      factory = getFactory();
    }

    c = factory.Class().get(this.getClass());
    if (c == null) {
      c = factory.Class().get(this.getClass());
    }
    // we substitute the first statement of method statement
    CtStatement result =
        factory.Core().clone(c.getMethod("statement").getBody().getStatements().get(0));
    new SubstitutionVisitor(factory, targetType, this).scan(result);
    return result;
  }
예제 #26
0
 @Test
 public void testTransformationOnConstructorWithInsertBefore() throws Exception {
   final CtConstructor<?> ctConstructor =
       aClass.getElements(new TypeFilter<CtConstructor<?>>(CtConstructor.class)).get(0);
   try {
     ctConstructor
         .getBody()
         .getStatement(0)
         .insertBefore(factory.Code().createCodeSnippetStatement("int i = 0"));
     fail();
   } catch (RuntimeException ignore) {
   }
   assertEquals(1, ctConstructor.getBody().getStatements().size());
   assertEquals("super()", ctConstructor.getBody().getStatement(0).toString());
 }
예제 #27
0
  @Test
  public void testDefaultMethodInInterface() throws Exception {
    final CtInterface<?> ctInterface =
        (CtInterface<?>) factory.Type().get(InterfaceWithDefaultMethods.class);

    final CtMethod<?> ctMethod = ctInterface.getMethodsByName("getZonedDateTime").get(0);
    assertTrue("The method in the interface must to be default", ctMethod.isDefaultMethod());

    final String expected =
        "default java.time.ZonedDateTime getZonedDateTime(java.lang.String zoneString) {"
            + System.lineSeparator()
            + "    return java.time.ZonedDateTime.of(getLocalDateTime(), spoon.test.interfaces.testclasses.InterfaceWithDefaultMethods.getZoneId(zoneString));"
            + System.lineSeparator()
            + "}";
    assertEquals("The default method must to be well printed", expected, ctMethod.toString());
  }
예제 #28
0
  @Test
  public void testRedefinesStaticMethodInSubInterface() throws Exception {
    final CtInterface<?> ctInterface =
        (CtInterface<?>) factory.Type().get(RedefinesStaticMethodInterface.class);

    assertEquals(
        "Sub interface must have only one method in its interface",
        1,
        ctInterface.getMethods().size());
    assertEquals(
        "Sub interface must have 6+12(from java.lang.Object) methods in its interface and its super interfaces",
        18,
        ctInterface.getAllMethods().size());

    final CtMethod<?> getZoneIdMethod = ctInterface.getMethodsByName("getZoneId").get(0);
    assertFalse(
        "Method in the sub interface mustn't be a static method",
        getZoneIdMethod.getModifiers().contains(ModifierKind.STATIC));
    assertEquals(
        "Interface of the static method must be the sub interface",
        RedefinesStaticMethodInterface.class,
        getZoneIdMethod.getDeclaringType().getActualClass());
  }
예제 #29
0
  @Test
  public void testRedefinesDefaultMethodInSubInterface() throws Exception {
    final CtInterface<?> ctInterface =
        (CtInterface<?>) factory.Type().get(RedefinesDefaultMethodInterface.class);

    assertEquals(
        "Sub interface must have only one method in its interface",
        1,
        ctInterface.getMethods().size());
    assertEquals(
        "Sub interface must have 6+12(from java.lang.Object) methods in its interface and its super interfaces",
        18,
        ctInterface.getAllMethods().size());

    final CtMethod<?> getZonedDateTimeMethod =
        ctInterface.getMethodsByName("getZonedDateTime").get(0);
    assertFalse(
        "Method in the sub interface mustn't be a default method",
        getZonedDateTimeMethod.isDefaultMethod());
    assertEquals(
        "Interface of the default method must be the sub interface",
        RedefinesDefaultMethodInterface.class,
        getZonedDateTimeMethod.getDeclaringType().getActualClass());
  }
예제 #30
0
  @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;
  }