Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

review: fix: prevent renaming CtRootPackage #1523

Merged
merged 6 commits into from
Sep 19, 2017
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/main/java/spoon/reflect/CtModelImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
*/
package spoon.reflect;

import spoon.SpoonException;
import spoon.processing.Processor;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtNamedElement;
import spoon.reflect.declaration.CtPackage;
import spoon.reflect.declaration.CtType;
import spoon.reflect.declaration.ParentNotInitializedException;
Expand Down Expand Up @@ -64,6 +66,19 @@ public String getSimpleName() {
return super.getSimpleName();
}

@Override
public <T extends CtNamedElement> T setSimpleName(String name) {
if (name == null || name.equals("")) {
return (T) this;
}

if (name.equals(CtPackage.TOP_LEVEL_PACKAGE_NAME)) {
return super.setSimpleName(name);
}

throw new SpoonException("CtRootPackage cannot be renamed.");
}

@Override
public String getQualifiedName() {
return "";
Expand Down
101 changes: 101 additions & 0 deletions src/test/java/spoon/test/pkg/PackageTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.junit.Test;
import spoon.Launcher;
import spoon.OutputType;
import spoon.SpoonException;
import spoon.SpoonModelBuilder;
import spoon.compiler.Environment;
import spoon.compiler.SpoonResourceHelper;
Expand All @@ -12,10 +13,17 @@
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtPackage;
import spoon.reflect.factory.Factory;
import spoon.reflect.visitor.DefaultJavaPrettyPrinter;
import spoon.reflect.visitor.PrettyPrinter;
import spoon.reflect.visitor.filter.NamedElementFilter;
import spoon.test.pkg.name.PackageTestClass;
import spoon.test.pkg.testclasses.ElementProcessor;
import spoon.testing.utils.ModelUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Collections;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
Expand Down Expand Up @@ -119,4 +127,97 @@ public void testAnnotationInPackageInfoWhenTemplatesCompiled() throws Exception
launcher.prettyprint();
canBeBuilt("./target/spooned/packageAndTemplate/spoon/test/pkg/package-info.java", 8);
}

@Test
public void testRenamePackageAndPrettyPrint() throws Exception {
final Launcher spoon = new Launcher();
spoon.addInputResource("./src/test/java/spoon/test/pkg/testclasses/Foo.java");
spoon.buildModel();

CtPackage ctPackage = spoon.getModel().getElements(new NamedElementFilter<CtPackage>(CtPackage.class, "spoon")).get(0);
ctPackage.setSimpleName("otherName");

CtClass foo = spoon.getModel().getElements(new NamedElementFilter<CtClass>(CtClass.class, "Foo")).get(0);
assertEquals("otherName.test.pkg.testclasses.Foo", foo.getQualifiedName());

PrettyPrinter prettyPrinter = new DefaultJavaPrettyPrinter(spoon.getEnvironment());
prettyPrinter.calculate(spoon.getFactory().CompilationUnit().create("./src/test/java/spoon/test/pkg/testclasses/Foo.java"), Collections.singletonList(foo));
String result = prettyPrinter.getResult();

assertTrue(result.contains("package otherName.test.pkg.testclasses;"));
}

@Test
public void testRenamePackageAndPrettyPrintNoclasspath() throws Exception {
final Launcher spoon = new Launcher();
spoon.addInputResource("./src/test/resources/noclasspath/app/Test.java");
spoon.getEnvironment().setNoClasspath(true);
spoon.buildModel();

CtPackage ctPackage = spoon.getModel().getElements(new NamedElementFilter<CtPackage>(CtPackage.class, "app")).get(0);
ctPackage.setSimpleName("otherName");

CtClass foo = spoon.getModel().getElements(new NamedElementFilter<CtClass>(CtClass.class, "Test")).get(0);
assertEquals("otherName.Test", foo.getQualifiedName());

PrettyPrinter prettyPrinter = new DefaultJavaPrettyPrinter(spoon.getEnvironment());
prettyPrinter.calculate(spoon.getFactory().CompilationUnit().create("./src/test/resources/noclasspath/app/Test.java"), Collections.singletonList(foo));
String result = prettyPrinter.getResult();

assertTrue(result.contains("package otherName;"));
}

@Test
public void testRenamePackageAndPrettyPrintWithProcessor() throws Exception {
String destPath = "./target/spoon-rename-processor";
final Launcher spoon = new Launcher();
spoon.addInputResource("./src/test/resources/noclasspath/app/Test.java");
spoon.getEnvironment().setNoClasspath(true);
spoon.addProcessor(new ElementProcessor());
spoon.setSourceOutputDirectory(destPath);
spoon.run();

String fileDir = destPath+"/newtest/Test.java";
File f = new File(fileDir);
assertTrue(f.exists());

BufferedReader reader = new BufferedReader(new FileReader(f));
assertTrue(reader.lines().anyMatch((s) -> {
return s.equals("package newtest;");
}));
}

@Test
public void testRenameRootPackage() throws Exception {
final Launcher spoon = new Launcher();
spoon.addInputResource("./src/test/resources/noclasspath/app/Test.java");
spoon.getEnvironment().setNoClasspath(true);
spoon.buildModel();

CtPackage rootPackage = spoon.getFactory().Package().getRootPackage();
try {
rootPackage.setSimpleName("test");
fail();
} catch (SpoonException e) {
assertTrue(e.getMessage().contains("CtRootPackage cannot be renamed"));
}
}

@Test
public void testRenameRootPackageWithNullOrEmpty() throws Exception {
final Launcher spoon = new Launcher();
spoon.addInputResource("./src/test/resources/noclasspath/app/Test.java");
spoon.getEnvironment().setNoClasspath(true);
spoon.buildModel();

CtPackage rootPackage = spoon.getFactory().Package().getRootPackage();
String rootPackageName = rootPackage.getSimpleName();
assertEquals(CtPackage.TOP_LEVEL_PACKAGE_NAME, rootPackageName);

rootPackage.setSimpleName("");
assertEquals(CtPackage.TOP_LEVEL_PACKAGE_NAME, rootPackageName);

rootPackage.setSimpleName(null);
assertEquals(CtPackage.TOP_LEVEL_PACKAGE_NAME, rootPackageName);
}
}
17 changes: 17 additions & 0 deletions src/test/java/spoon/test/pkg/testclasses/ElementProcessor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package spoon.test.pkg.testclasses;

import spoon.processing.AbstractProcessor;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtPackage;

/**
* Created by urli on 11/09/2017.
*/
public class ElementProcessor extends AbstractProcessor<CtElement> {
public void process(CtElement element) {
if(element instanceof CtPackage && element != getFactory().Package().getRootPackage()){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is a confusion, the goal is that client code indeed never has to write this.

so the implementation RootPackage.setSimpleName would simply be ... empty.

do you see what I mean?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you see what I mean?

Yes, I just kept going on my initial idea. I'll change that.

((CtPackage) element).setSimpleName("newtest");
}
}
}

7 changes: 7 additions & 0 deletions src/test/resources/noclasspath/app/Test.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package app;

public class Test {
public static void main(String[] args){
System.out.println("test");
}
}