Giter Site home page Giter Site logo

`equals()` semantics on `CtType`? about spoon HOT 6 OPEN

tdegueul avatar tdegueul commented on June 6, 2024
`equals()` semantics on `CtType`?

from spoon.

Comments (6)

tdegueul avatar tdegueul commented on June 6, 2024 3

Spoon should currently compare types by considering them in isolation, detached from the rest of the model

This makes sense and explains this behavior.

But the wrapper was something they can implement in their code, not in Spoon itself :)

Of course. I had to implement a little workaround for my use case, but it does not mean that Spoon should work any differently. Thank you both for clarifying.

from spoon.

algomaster99 avatar algomaster99 commented on June 6, 2024

Hi! This seems like a bug that we do not consider the package of the type in our EqualsVisitor. Something like this should work

diff --git a/src/main/java/spoon/support/visitor/equals/EqualsChecker.java b/src/main/java/spoon/support/visitor/equals/EqualsChecker.java
index 20117347a..6a0e7d9ee 100644
--- a/src/main/java/spoon/support/visitor/equals/EqualsChecker.java
+++ b/src/main/java/spoon/support/visitor/equals/EqualsChecker.java
@@ -22,6 +22,8 @@ import spoon.reflect.declaration.CtMethod;
 import spoon.reflect.declaration.CtModifiable;
 import spoon.reflect.declaration.CtNamedElement;
 import spoon.reflect.declaration.CtParameter;
+import spoon.reflect.declaration.CtType;
+import spoon.reflect.declaration.CtTypeInformation;
 import spoon.reflect.path.CtRole;
 import spoon.reflect.reference.CtArrayTypeReference;
 import spoon.reflect.reference.CtExecutableReference;
@@ -119,6 +121,15 @@ public class EqualsChecker extends CtInheritanceScanner {
 		super.scanCtCodeSnippet(snippet);
 	}
 
+	@Override
+	public <T> void scanCtTypeInformation(CtTypeInformation typeInformation) {
+		final CtTypeInformation peek = (CtTypeInformation) this.other;
+		if (!typeInformation.getQualifiedName().equals(peek.getQualifiedName())) {
+			setNotEqual(null);
+		}
+		super.scanCtTypeInformation(typeInformation);
+	}
+
 	@Override
 	public <T, A extends T> void visitCtAssignment(CtAssignment<T, A> assignment) {
 		if (!(assignment instanceof CtOperatorAssignment) && this.other instanceof CtOperatorAssignment) {

However, we must also check for implicit packages, java.lang, somewhere. What do you think @I-Al-Istannen , @SirYwell ?

from spoon.

I-Al-Istannen avatar I-Al-Istannen commented on June 6, 2024

That is an interesting question. I think currently equality checks whether the elements have the same content and attributes, ignoring the parents. As the qualified name is a derived property (based on the parent chain) it is not included in the comparison.
Spoon should currently compare types by considering them in isolation, detached from the rest of the model. This also seems congruent with your findings.

Currently you can easily emulate the nominal behaviour by using a Map<String, CtType> instead. In fact, if equality would take the package name into account it would be a mix of nominal and structural. Your types are only equal if they are in the same package and have the same structure. I am not sold that this is less surprising than always comparing the content (excluding parents). If you always want purely nominal behaviour, maybe a NominalType wrapper class around a CtType is an elegant solution? This also saves you from walking the complete tree on every equals/hashcode computation, which quickly adds up.

WDYT @MartinWitt @SirYwell?

from spoon.

algomaster99 avatar algomaster99 commented on June 6, 2024

NominalType wrapper class around a CtType is an elegant solution? This also saves you from walking the complete tree on every equals/hashcode computation, which quickly adds up.

So based on Nominal type system, it would check two things:

  1. Name of the declaration (fully qualified name in this case)
  2. The declaration (the content of the type)

How would you compare the type declaration without visiting each child's node?

from spoon.

I-Al-Istannen avatar I-Al-Istannen commented on June 6, 2024

You don't. I thought they only wanted equality to be based on the name. Doing both (full name and content) sounds a bit weird to me at first glance.

But the wrapper was something they can implement in their code, not in Spoon itself :)

from spoon.

algomaster99 avatar algomaster99 commented on June 6, 2024

Doing both (full name and content)

Hmmm. If full names are the same, then classes must be the same; if different, they must be different.

from spoon.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.