From 8bc35092c4b5bcef337dea4c7ea5b0c1fd0b4540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rard=20Paligot?= Date: Thu, 25 Aug 2016 13:47:54 +0200 Subject: [PATCH] fix(type): Fix exception in noclasspath due to PolyTypeBinding. (Closes #751) --- .../compiler/jdt/ReferenceBuilder.java | 6 +- src/test/java/spoon/test/type/TypeTest.java | 18 ++++ .../ternary-bug/data/IssueType.java | 4 + .../ternary-bug/data/entities/Issue.java | 40 ++++++++ .../transformators/IssueTransformator.java | 93 +++++++++++++++++++ 5 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/noclasspath/ternary-bug/data/IssueType.java create mode 100644 src/test/resources/noclasspath/ternary-bug/data/entities/Issue.java create mode 100644 src/test/resources/noclasspath/ternary-bug/transformators/IssueTransformator.java diff --git a/src/main/java/spoon/support/compiler/jdt/ReferenceBuilder.java b/src/main/java/spoon/support/compiler/jdt/ReferenceBuilder.java index 7e0d97cf04f..eac0ccacf4c 100644 --- a/src/main/java/spoon/support/compiler/jdt/ReferenceBuilder.java +++ b/src/main/java/spoon/support/compiler/jdt/ReferenceBuilder.java @@ -770,7 +770,11 @@ CtTypeReference getTypeReference(TypeBinding binding) { arrayref = tmp; } arrayref.setComponentType(getTypeReference(binding.leafComponentType())); - } else if (binding instanceof ProblemReferenceBinding || binding instanceof PolyTypeBinding) { + } else if (binding instanceof PolyTypeBinding) { + // JDT can't resolve the type of this binding and we only have a string. + // In this case, we return a type Object because we can't know more about it. + ref = this.jdtTreeBuilder.getFactory().Type().objectType(); + } else if (binding instanceof ProblemReferenceBinding) { // Spoon is able to analyze also without the classpath ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference(); ref.setSimpleName(new String(binding.readableName())); diff --git a/src/test/java/spoon/test/type/TypeTest.java b/src/test/java/spoon/test/type/TypeTest.java index f8ad78157bf..c5fba08fbba 100644 --- a/src/test/java/spoon/test/type/TypeTest.java +++ b/src/test/java/spoon/test/type/TypeTest.java @@ -22,6 +22,7 @@ import spoon.reflect.code.BinaryOperatorKind; import spoon.reflect.code.CtBinaryOperator; import spoon.reflect.code.CtBlock; +import spoon.reflect.code.CtConstructorCall; import spoon.reflect.code.CtFieldRead; import spoon.reflect.code.CtLambda; import spoon.reflect.code.CtLocalVariable; @@ -300,4 +301,21 @@ public void testDeclarationCreatedByFactory() throws Exception { assertNotNull(factory.Interface().create("fr.inria.ITest").getReference().getDeclaration()); assertNotNull(factory.Enum().create("fr.inria.ETest").getReference().getDeclaration()); } + + @Test + public void testPolyTypBindingInTernaryExpression() throws Exception { + Launcher launcher = new Launcher(); + launcher.addInputResource("./src/test/resources/noclasspath/ternary-bug"); + launcher.getEnvironment().setNoClasspath(true); + launcher.buildModel(); + + CtType aType = launcher.getFactory().Type().get("de.uni_bremen.st.quide.persistence.transformators.IssueTransformator"); + CtConstructorCall ctConstructorCall = aType.getElements(new TypeFilter(CtConstructorCall.class) { + @Override + public boolean matches(CtConstructorCall element) { + return "TOIssue".equals(element.getExecutable().getType().getSimpleName()) && super.matches(element); + } + }).get(0); + assertEquals(launcher.getFactory().Type().objectType(), ctConstructorCall.getExecutable().getParameters().get(9)); + } } diff --git a/src/test/resources/noclasspath/ternary-bug/data/IssueType.java b/src/test/resources/noclasspath/ternary-bug/data/IssueType.java new file mode 100644 index 00000000000..2d748bb34db --- /dev/null +++ b/src/test/resources/noclasspath/ternary-bug/data/IssueType.java @@ -0,0 +1,4 @@ +package de.uni_bremen.st.quide.persistence.data; + +public enum IssueType { +} diff --git a/src/test/resources/noclasspath/ternary-bug/data/entities/Issue.java b/src/test/resources/noclasspath/ternary-bug/data/entities/Issue.java new file mode 100644 index 00000000000..4e78499e135 --- /dev/null +++ b/src/test/resources/noclasspath/ternary-bug/data/entities/Issue.java @@ -0,0 +1,40 @@ +package de.uni_bremen.st.quide.persistence.data.entities; + +import java.time.ZonedDateTime; + +import de.uni_bremen.st.quide.persistence.data.IssueType; + +public class Issue { + public Long getId() { + return id; + } + + public String getIdentifier() { + return ""; + } + + public String getTitle() { + return ""; + } + + public String getDescription() { + return ""; + } + + public String getUrl() { + return ""; + } + + public ZonedDateTime getCreatedAt() { + return null; + } + + public ZonedDateTime getClosedAt() { + return null; + } + + public IssueType getIssueType() { + return null; + } + +} diff --git a/src/test/resources/noclasspath/ternary-bug/transformators/IssueTransformator.java b/src/test/resources/noclasspath/ternary-bug/transformators/IssueTransformator.java new file mode 100644 index 00000000000..28e3ce7af68 --- /dev/null +++ b/src/test/resources/noclasspath/ternary-bug/transformators/IssueTransformator.java @@ -0,0 +1,93 @@ +package de.uni_bremen.st.quide.persistence.transformators; + +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import de.uni_bremen.st.quide.datamodel.transferred_data.IViolation; +import de.uni_bremen.st.quide.datamodel.transferred_data.impl.TOIssue; +import de.uni_bremen.st.quide.persistence.IPersistence; +import de.uni_bremen.st.quide.persistence.data.entities.Filename; +import de.uni_bremen.st.quide.persistence.data.entities.Issue; +import de.uni_bremen.st.quide.persistence.data.entities.IssueLabel; +import de.uni_bremen.st.quide.persistence.data.entities.Version; +import de.uni_bremen.st.quide.persistence.data.relationships.FilenameVersion; +import de.uni_bremen.st.quide.persistence.exceptions.InvalidIDException; +import de.uni_bremen.st.quide.persistence.util.Condition; +import de.uni_bremen.st.quide.persistence.util.Condition.Type; + +@Component +public class IssueTransformator { + + @Autowired + private IPersistence persistence; + + public List getAllIssues() { + return getAll(null); + } + + public List getIssuesReferencedByVersion(long versionId) throws InvalidIDException { + Version version = persistence.checkID(Version.class, versionId); + + return getAll(Collections.singletonList(new Condition(Type.REVERSE_IN, "versions", version))); + } + + public List getIssuesModifyingFile(long fileId) throws InvalidIDException { + Filename filename = persistence.checkID(Filename.class, fileId); + + List conditions = Collections.singletonList(new Condition("filename", filename)); + + return persistence.getAll(FilenameVersion.class, conditions).stream() + .map(FilenameVersion::getStartVersion) + .map(Version::getIssues) + .flatMap(Set::stream) + .map(this::createIssue) + .collect(Collectors.toList()); + } + + public List getViolationsFixedByIssue(long issueId) { + return Collections.emptyList(); + } + + public List getViolationsCreatedByIssue(long issueId) { + return Collections.emptyList(); + } + + private TOIssue createIssue(Issue issue) { + final ZonedDateTime closedAt = issue.getClosedAt(); + + final Set labels = issue.getLabels().stream() + .map(IssueLabel::getName) + .collect(Collectors.toSet()); + + final Set versions = null; + + return new TOIssue( + issue.getId(), + issue.getIdentifier(), + issue.getTitle(), + issue.getDescription(), + issue.getUrl(), + "", + + labels, + versions, + + Date.from(issue.getCreatedAt().toInstant()), + closedAt == null ? null : Date.from(issue.getClosedAt().toInstant()), + + issue.getIssueType().toString()); + } + + private List getAll(List conditions) { + return persistence.getAll(Issue.class, conditions).stream() + .map(this::createIssue) + .collect(Collectors.toList()); + } +}