Example #1
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);
  }
  @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);
  }
  @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);
  }