diff --git a/src/main/java/spoon/generating/CloneVisitorGenerator.java b/src/main/java/spoon/generating/CloneVisitorGenerator.java index 537c81116f5..a99626407e6 100644 --- a/src/main/java/spoon/generating/CloneVisitorGenerator.java +++ b/src/main/java/spoon/generating/CloneVisitorGenerator.java @@ -51,6 +51,7 @@ import spoon.reflect.visitor.Query; import spoon.reflect.visitor.filter.OverridingMethodFilter; import spoon.reflect.visitor.filter.TypeFilter; +import spoon.support.reflect.CtModifierHandler; import spoon.support.visitor.clone.CloneBuilder; import java.util.ArrayList; @@ -405,6 +406,9 @@ private CtInvocation createGetterInvocation(CtParameter element, CtMethod< * Query to get the setter of given field. */ private CtMethod getSetterOf(final CtField ctField) { + if (ctField.getType().equals(getFactory().createCtTypeReference(CtModifierHandler.class))) { + return ctField.getDeclaringType().getMethodsByName("setModifiers").get(0); + } // Search by name convention. for (CtMethod ctMethod : ctField.getDeclaringType().getMethods()) { if (ctMethod.getSimpleName().startsWith("set") && ctMethod.getSimpleName().toLowerCase().contains(ctField.getSimpleName().toLowerCase())) { @@ -449,6 +453,9 @@ public boolean matches(CtMethod element) { * Query to get the getter of the given field. */ private CtMethod getGetterOf(CtField ctField) { + if (ctField.getType().equals(getFactory().createCtTypeReference(CtModifierHandler.class))) { + return ctField.getDeclaringType().getMethod("getModifiers"); + } // Search by name convention. for (CtMethod ctMethod : ctField.getDeclaringType().getMethods()) { if ((ctMethod.getSimpleName().startsWith("get") || ctMethod.getSimpleName().startsWith("is")) // diff --git a/src/main/java/spoon/support/reflect/CtModifierHandler.java b/src/main/java/spoon/support/reflect/CtModifierHandler.java new file mode 100644 index 00000000000..9831391e323 --- /dev/null +++ b/src/main/java/spoon/support/reflect/CtModifierHandler.java @@ -0,0 +1,152 @@ +/** + * Copyright (C) 2006-2017 INRIA and contributors + * Spoon - http://spoon.gforge.inria.fr/ + *

+ * This software is governed by the CeCILL-C License under French law and + * abiding by the rules of distribution of free software. You can use, modify + * and/or redistribute the software under the terms of the CeCILL-C license as + * circulated by CEA, CNRS and INRIA at http://www.cecill.info. + *

+ * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details. + *

+ * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package spoon.support.reflect; + +import spoon.reflect.declaration.CtElement; +import spoon.reflect.declaration.ModifierKind; +import spoon.reflect.factory.Factory; +import spoon.support.reflect.declaration.CtElementImpl; + +import java.io.Serializable; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Set; + +import static spoon.reflect.path.CtRole.MODIFIER; + +public class CtModifierHandler implements Serializable { + private static final long serialVersionUID = 1L; + + private Set modifiers = CtElementImpl.emptySet(); + + private CtElement element; + + public CtModifierHandler(CtElement element) { + this.element = element; + } + + public Factory getFactory() { + return element.getFactory(); + } + + public Set getModifiers() { + return modifiers; + } + + public boolean hasModifier(ModifierKind modifier) { + return getModifiers().contains(modifier); + } + + public CtModifierHandler setModifiers(Set modifiers) { + if (modifiers.size() > 0) { + getFactory().getEnvironment().getModelChangeListener().onSetDeleteAll(element, MODIFIER, this.modifiers, new HashSet<>(this.modifiers)); + this.modifiers.clear(); + for (ModifierKind modifier : modifiers) { + addModifier(modifier); + } + } + return this; + } + + public CtModifierHandler addModifier(ModifierKind modifier) { + if (modifiers == CtElementImpl.emptySet()) { + this.modifiers = EnumSet.noneOf(ModifierKind.class); + } + getFactory().getEnvironment().getModelChangeListener().onSetAdd(element, MODIFIER, this.modifiers, modifier); + modifiers.add(modifier); + return this; + } + + public boolean removeModifier(ModifierKind modifier) { + if (modifiers == CtElementImpl.emptySet()) { + return false; + } + getFactory().getEnvironment().getModelChangeListener().onSetDelete(element, MODIFIER, modifiers, modifier); + return modifiers.remove(modifier); + } + + public CtModifierHandler setVisibility(ModifierKind visibility) { + if (modifiers == CtElementImpl.emptySet()) { + this.modifiers = EnumSet.noneOf(ModifierKind.class); + } + if (hasModifier(visibility)) { + return this; + } + if (isPublic()) { + removeModifier(ModifierKind.PUBLIC); + } + if (isProtected()) { + removeModifier(ModifierKind.PROTECTED); + } + if (isPrivate()) { + removeModifier(ModifierKind.PRIVATE); + } + addModifier(visibility); + return this; + } + + public ModifierKind getVisibility() { + if (isPublic()) { + return ModifierKind.PUBLIC; + } + if (isProtected()) { + return ModifierKind.PROTECTED; + } + if (isPrivate()) { + return ModifierKind.PRIVATE; + } + return null; + } + + public boolean isPublic() { + return getModifiers().contains(ModifierKind.PUBLIC); + } + + public boolean isProtected() { + return getModifiers().contains(ModifierKind.PROTECTED); + } + + public boolean isPrivate() { + return getModifiers().contains(ModifierKind.PRIVATE); + } + + @Override + public int hashCode() { + return getModifiers().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof CtModifierHandler)) { + return false; + } + final CtModifierHandler other = (CtModifierHandler) obj; + if (getVisibility() == null) { + if (other.getVisibility() != null) { + return false; + } + } else if (other.getVisibility() == null) { + return false; + } else if (!getVisibility().equals(other.getVisibility())) { + return false; + } + if (getModifiers().size() != other.getModifiers().size()) { + return false; + } + return getModifiers().containsAll(other.getModifiers()); + } +} diff --git a/src/main/java/spoon/support/reflect/code/CtCatchVariableImpl.java b/src/main/java/spoon/support/reflect/code/CtCatchVariableImpl.java index 8f69edec19d..deddfabe808 100644 --- a/src/main/java/spoon/support/reflect/code/CtCatchVariableImpl.java +++ b/src/main/java/spoon/support/reflect/code/CtCatchVariableImpl.java @@ -32,17 +32,15 @@ import spoon.reflect.visitor.filter.SuperInheritanceHierarchyFunction; import spoon.support.DerivedProperty; import spoon.support.UnsettableProperty; +import spoon.support.reflect.CtModifierHandler; import spoon.support.reflect.declaration.CtElementImpl; import java.util.ArrayList; import java.util.Collections; -import java.util.EnumSet; -import java.util.HashSet; import java.util.List; import java.util.Set; import static spoon.reflect.ModelElementContainerDefaultCapacities.CATCH_VARIABLE_MULTI_TYPES_CONTAINER_DEFAULT_CAPACITY; -import static spoon.reflect.path.CtRole.MODIFIER; import static spoon.reflect.path.CtRole.NAME; import static spoon.reflect.path.CtRole.TYPE; @@ -56,7 +54,7 @@ public class CtCatchVariableImpl extends CtCodeElementImpl implements CtCatch List> types = emptyList(); @MetamodelPropertyField(role = CtRole.MODIFIER) - Set modifiers = CtElementImpl.emptySet(); + private CtModifierHandler modifierHandler = new CtModifierHandler(this); @Override public void accept(CtVisitor visitor) { @@ -177,7 +175,7 @@ public T setMultiTypes(List> @Override public Set getModifiers() { - return modifiers; + return modifierHandler.getModifiers(); } @Override @@ -187,44 +185,24 @@ public boolean hasModifier(ModifierKind modifier) { @Override public C setModifiers(Set modifiers) { - if (modifiers.size() > 0) { - getFactory().getEnvironment().getModelChangeListener().onSetDeleteAll(this, MODIFIER, this.modifiers, new HashSet<>(this.modifiers)); - this.modifiers.clear(); - for (ModifierKind modifier : modifiers) { - addModifier(modifier); - } - } + modifierHandler.setModifiers(modifiers); return (C) this; } @Override public C addModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - this.modifiers = EnumSet.noneOf(ModifierKind.class); - } - getFactory().getEnvironment().getModelChangeListener().onSetAdd(this, MODIFIER, this.modifiers, modifier); - modifiers.add(modifier); + modifierHandler.addModifier(modifier); return (C) this; } @Override public boolean removeModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - return false; - } - getFactory().getEnvironment().getModelChangeListener().onSetDelete(this, MODIFIER, modifiers, modifier); - return modifiers.remove(modifier); + return modifierHandler.removeModifier(modifier); } @Override public C setVisibility(ModifierKind visibility) { - if (modifiers == CtElementImpl.emptySet()) { - this.modifiers = EnumSet.noneOf(ModifierKind.class); - } - removeModifier(ModifierKind.PUBLIC); - removeModifier(ModifierKind.PROTECTED); - removeModifier(ModifierKind.PRIVATE); - addModifier(visibility); + modifierHandler.setVisibility(visibility); return (C) this; } diff --git a/src/main/java/spoon/support/reflect/code/CtLocalVariableImpl.java b/src/main/java/spoon/support/reflect/code/CtLocalVariableImpl.java index 0c8184b33cb..044fb241c94 100644 --- a/src/main/java/spoon/support/reflect/code/CtLocalVariableImpl.java +++ b/src/main/java/spoon/support/reflect/code/CtLocalVariableImpl.java @@ -31,14 +31,11 @@ import spoon.reflect.visitor.CtVisitor; import spoon.support.DerivedProperty; import spoon.support.UnsettableProperty; -import spoon.support.reflect.declaration.CtElementImpl; +import spoon.support.reflect.CtModifierHandler; -import java.util.EnumSet; -import java.util.HashSet; import java.util.Set; import static spoon.reflect.path.CtRole.DEFAULT_EXPRESSION; -import static spoon.reflect.path.CtRole.MODIFIER; import static spoon.reflect.path.CtRole.NAME; import static spoon.reflect.path.CtRole.TYPE; @@ -55,7 +52,7 @@ public class CtLocalVariableImpl extends CtStatementImpl implements CtLocalVa CtTypeReference type; @MetamodelPropertyField(role = CtRole.MODIFIER) - Set modifiers = CtElementImpl.emptySet(); + private CtModifierHandler modifierHandler = new CtModifierHandler(this); @Override public void accept(CtVisitor visitor) { @@ -111,7 +108,7 @@ public C setType(CtTypeReference type) { @Override public Set getModifiers() { - return modifiers; + return modifierHandler.getModifiers(); } @Override @@ -121,45 +118,24 @@ public boolean hasModifier(ModifierKind modifier) { @Override public C setModifiers(Set modifiers) { - if (modifiers.size() > 0) { - getFactory().getEnvironment().getModelChangeListener().onSetDeleteAll(this, MODIFIER, this.modifiers, new HashSet<>(this.modifiers)); - this.modifiers.clear(); - for (ModifierKind modifier : modifiers) { - addModifier(modifier); - } - - } + modifierHandler.setModifiers(modifiers); return (C) this; } @Override public C addModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - this.modifiers = EnumSet.noneOf(ModifierKind.class); - } - getFactory().getEnvironment().getModelChangeListener().onSetAdd(this, MODIFIER, this.modifiers, modifier); - modifiers.add(modifier); + modifierHandler.addModifier(modifier); return (C) this; } @Override public boolean removeModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - return false; - } - getFactory().getEnvironment().getModelChangeListener().onSetDelete(this, MODIFIER, modifiers, modifier); - return modifiers.remove(modifier); + return modifierHandler.removeModifier(modifier); } @Override public C setVisibility(ModifierKind visibility) { - if (modifiers == CtElementImpl.emptySet()) { - this.modifiers = EnumSet.noneOf(ModifierKind.class); - } - removeModifier(ModifierKind.PUBLIC); - removeModifier(ModifierKind.PROTECTED); - removeModifier(ModifierKind.PRIVATE); - addModifier(visibility); + modifierHandler.setVisibility(visibility); return (C) this; } diff --git a/src/main/java/spoon/support/reflect/declaration/CtAnonymousExecutableImpl.java b/src/main/java/spoon/support/reflect/declaration/CtAnonymousExecutableImpl.java index c3246e8e8db..850c144e7ff 100644 --- a/src/main/java/spoon/support/reflect/declaration/CtAnonymousExecutableImpl.java +++ b/src/main/java/spoon/support/reflect/declaration/CtAnonymousExecutableImpl.java @@ -29,19 +29,16 @@ import spoon.reflect.visitor.CtVisitor; import spoon.support.DerivedProperty; import spoon.support.UnsettableProperty; +import spoon.support.reflect.CtModifierHandler; -import java.util.EnumSet; -import java.util.HashSet; import java.util.List; import java.util.Set; -import static spoon.reflect.path.CtRole.MODIFIER; - public class CtAnonymousExecutableImpl extends CtExecutableImpl implements CtAnonymousExecutable { private static final long serialVersionUID = 1L; @MetamodelPropertyField(role = CtRole.MODIFIER) - Set modifiers = emptySet(); + private CtModifierHandler modifierHandler = new CtModifierHandler(this); @Override public void accept(CtVisitor visitor) { @@ -50,26 +47,18 @@ public void accept(CtVisitor visitor) { @Override public T addModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - modifiers = EnumSet.noneOf(ModifierKind.class); - } - getFactory().getEnvironment().getModelChangeListener().onSetAdd(this, MODIFIER, this.modifiers, modifier); - modifiers.add(modifier); + modifierHandler.addModifier(modifier); return (T) this; } @Override public boolean removeModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - return false; - } - getFactory().getEnvironment().getModelChangeListener().onSetDelete(this, MODIFIER, modifiers, modifier); - return modifiers.remove(modifier); + return modifierHandler.removeModifier(modifier); } @Override public Set getModifiers() { - return modifiers; + return modifierHandler.getModifiers(); } @Override @@ -88,30 +77,18 @@ public ModifierKind getVisibility() { @Override public boolean hasModifier(ModifierKind modifier) { - return modifiers.contains(modifier); + return modifierHandler.hasModifier(modifier); } @Override public T setModifiers(Set modifiers) { - if (modifiers.size() > 0) { - getFactory().getEnvironment().getModelChangeListener().onSetDelete(this, MODIFIER, this.modifiers, new HashSet<>(this.modifiers)); - this.modifiers.clear(); - for (ModifierKind modifier : modifiers) { - addModifier(modifier); - } - } + modifierHandler.setModifiers(modifiers); return (T) this; } @Override public T setVisibility(ModifierKind visibility) { - if (modifiers == CtElementImpl.emptySet()) { - modifiers = EnumSet.noneOf(ModifierKind.class); - } - removeModifier(ModifierKind.PUBLIC); - removeModifier(ModifierKind.PROTECTED); - removeModifier(ModifierKind.PRIVATE); - addModifier(visibility); + modifierHandler.setVisibility(visibility); return (T) this; } diff --git a/src/main/java/spoon/support/reflect/declaration/CtConstructorImpl.java b/src/main/java/spoon/support/reflect/declaration/CtConstructorImpl.java index 2d3177e35a3..d24f866f554 100644 --- a/src/main/java/spoon/support/reflect/declaration/CtConstructorImpl.java +++ b/src/main/java/spoon/support/reflect/declaration/CtConstructorImpl.java @@ -32,16 +32,14 @@ import spoon.reflect.visitor.CtVisitor; import spoon.support.DerivedProperty; import spoon.support.UnsettableProperty; +import spoon.support.reflect.CtModifierHandler; import java.util.ArrayList; -import java.util.EnumSet; -import java.util.HashSet; import java.util.List; import java.util.Set; import static spoon.reflect.ModelElementContainerDefaultCapacities.TYPE_TYPE_PARAMETERS_CONTAINER_DEFAULT_CAPACITY; import static spoon.reflect.path.CtRole.IS_SHADOW; -import static spoon.reflect.path.CtRole.MODIFIER; import static spoon.reflect.path.CtRole.TYPE_PARAMETER; public class CtConstructorImpl extends CtExecutableImpl implements CtConstructor { @@ -51,7 +49,7 @@ public class CtConstructorImpl extends CtExecutableImpl implements CtConst List formalCtTypeParameters = emptyList(); @MetamodelPropertyField(role = CtRole.MODIFIER) - Set modifiers = CtElementImpl.emptySet(); + private CtModifierHandler modifierHandler = new CtModifierHandler(this); @Override public void accept(CtVisitor visitor) { @@ -138,7 +136,7 @@ public boolean removeFormalCtTypeParameter(CtTypeParameter formalTypeParameter) @Override public Set getModifiers() { - return modifiers; + return modifierHandler.getModifiers(); } @Override @@ -148,59 +146,30 @@ public boolean hasModifier(ModifierKind modifier) { @Override public C setModifiers(Set modifiers) { - if (modifiers.size() > 0) { - getFactory().getEnvironment().getModelChangeListener().onSetDeleteAll(this, MODIFIER, this.modifiers, new HashSet<>(this.modifiers)); - this.modifiers.clear(); - for (ModifierKind modifier : modifiers) { - addModifier(modifier); - } - } + modifierHandler.setModifiers(modifiers); return (C) this; } @Override public C addModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - this.modifiers = EnumSet.noneOf(ModifierKind.class); - } - getFactory().getEnvironment().getModelChangeListener().onSetAdd(this, MODIFIER, this.modifiers, modifier); - modifiers.add(modifier); + modifierHandler.addModifier(modifier); return (C) this; } @Override public boolean removeModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - return false; - } - getFactory().getEnvironment().getModelChangeListener().onSetDelete(this, MODIFIER, modifiers, modifier); - return modifiers.remove(modifier); + return modifierHandler.removeModifier(modifier); } @Override public C setVisibility(ModifierKind visibility) { - if (modifiers == CtElementImpl.emptySet()) { - this.modifiers = EnumSet.noneOf(ModifierKind.class); - } - removeModifier(ModifierKind.PUBLIC); - removeModifier(ModifierKind.PROTECTED); - removeModifier(ModifierKind.PRIVATE); - addModifier(visibility); + modifierHandler.setVisibility(visibility); return (C) this; } @Override public ModifierKind getVisibility() { - if (getModifiers().contains(ModifierKind.PUBLIC)) { - return ModifierKind.PUBLIC; - } - if (getModifiers().contains(ModifierKind.PROTECTED)) { - return ModifierKind.PROTECTED; - } - if (getModifiers().contains(ModifierKind.PRIVATE)) { - return ModifierKind.PRIVATE; - } - return null; + return modifierHandler.getVisibility(); } @MetamodelPropertyField(role = CtRole.IS_SHADOW) diff --git a/src/main/java/spoon/support/reflect/declaration/CtFieldImpl.java b/src/main/java/spoon/support/reflect/declaration/CtFieldImpl.java index d99467bb942..25d057adb12 100644 --- a/src/main/java/spoon/support/reflect/declaration/CtFieldImpl.java +++ b/src/main/java/spoon/support/reflect/declaration/CtFieldImpl.java @@ -33,14 +33,12 @@ import spoon.reflect.visitor.CtVisitor; import spoon.support.DerivedProperty; import spoon.support.UnsettableProperty; +import spoon.support.reflect.CtModifierHandler; -import java.util.EnumSet; -import java.util.HashSet; import java.util.Set; import static spoon.reflect.path.CtRole.DEFAULT_EXPRESSION; import static spoon.reflect.path.CtRole.IS_SHADOW; -import static spoon.reflect.path.CtRole.MODIFIER; import static spoon.reflect.path.CtRole.TYPE; /** @@ -58,7 +56,7 @@ public class CtFieldImpl extends CtNamedElementImpl implements CtField { CtTypeReference type; @MetamodelPropertyField(role = CtRole.MODIFIER) - Set modifiers = CtElementImpl.emptySet(); + private CtModifierHandler modifierHandler = new CtModifierHandler(this); public CtFieldImpl() { super(); @@ -116,7 +114,7 @@ public C setType(CtTypeReference type) { @Override public Set getModifiers() { - return modifiers; + return modifierHandler.getModifiers(); } @Override @@ -126,59 +124,30 @@ public boolean hasModifier(ModifierKind modifier) { @Override public C setModifiers(Set modifiers) { - if (modifiers.size() > 0) { - getFactory().getEnvironment().getModelChangeListener().onSetDeleteAll(this, MODIFIER, this.modifiers, new HashSet<>(this.modifiers)); - this.modifiers.clear(); - for (ModifierKind modifier : modifiers) { - addModifier(modifier); - } - } + modifierHandler.setModifiers(modifiers); return (C) this; } @Override public C addModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - this.modifiers = EnumSet.noneOf(ModifierKind.class); - } - getFactory().getEnvironment().getModelChangeListener().onSetAdd(this, MODIFIER, this.modifiers, modifier); - modifiers.add(modifier); + modifierHandler.addModifier(modifier); return (C) this; } @Override public boolean removeModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - return false; - } - getFactory().getEnvironment().getModelChangeListener().onSetDelete(this, MODIFIER, modifiers, modifier); - return modifiers.remove(modifier); + return modifierHandler.removeModifier(modifier); } @Override public C setVisibility(ModifierKind visibility) { - if (modifiers == CtElementImpl.emptySet()) { - this.modifiers = EnumSet.noneOf(ModifierKind.class); - } - removeModifier(ModifierKind.PUBLIC); - removeModifier(ModifierKind.PROTECTED); - removeModifier(ModifierKind.PRIVATE); - addModifier(visibility); + modifierHandler.setVisibility(visibility); return (C) this; } @Override public ModifierKind getVisibility() { - if (getModifiers().contains(ModifierKind.PUBLIC)) { - return ModifierKind.PUBLIC; - } - if (getModifiers().contains(ModifierKind.PROTECTED)) { - return ModifierKind.PROTECTED; - } - if (getModifiers().contains(ModifierKind.PRIVATE)) { - return ModifierKind.PRIVATE; - } - return null; + return modifierHandler.getVisibility(); } @Override diff --git a/src/main/java/spoon/support/reflect/declaration/CtMethodImpl.java b/src/main/java/spoon/support/reflect/declaration/CtMethodImpl.java index bab5e8f12db..4ac2dce57fa 100644 --- a/src/main/java/spoon/support/reflect/declaration/CtMethodImpl.java +++ b/src/main/java/spoon/support/reflect/declaration/CtMethodImpl.java @@ -28,18 +28,16 @@ import spoon.reflect.path.CtRole; import spoon.reflect.reference.CtTypeReference; import spoon.reflect.visitor.CtVisitor; +import spoon.support.reflect.CtModifierHandler; import spoon.support.visitor.ClassTypingContext; import java.util.ArrayList; -import java.util.EnumSet; -import java.util.HashSet; import java.util.List; import java.util.Set; import static spoon.reflect.ModelElementContainerDefaultCapacities.TYPE_TYPE_PARAMETERS_CONTAINER_DEFAULT_CAPACITY; import static spoon.reflect.path.CtRole.IS_DEFAULT; import static spoon.reflect.path.CtRole.IS_SHADOW; -import static spoon.reflect.path.CtRole.MODIFIER; import static spoon.reflect.path.CtRole.TYPE; import static spoon.reflect.path.CtRole.TYPE_PARAMETER; @@ -61,7 +59,7 @@ public class CtMethodImpl extends CtExecutableImpl implements CtMethod List formalCtTypeParameters = emptyList(); @MetamodelPropertyField(role = CtRole.MODIFIER) - Set modifiers = CtElementImpl.emptySet(); + private CtModifierHandler modifierHandler = new CtModifierHandler(this); public CtMethodImpl() { super(); @@ -146,7 +144,7 @@ public boolean removeFormalCtTypeParameter(CtTypeParameter formalTypeParameter) @Override public Set getModifiers() { - return modifiers; + return modifierHandler.getModifiers(); } @Override @@ -156,59 +154,30 @@ public boolean hasModifier(ModifierKind modifier) { @Override public C setModifiers(Set modifiers) { - if (modifiers.size() > 0) { - getFactory().getEnvironment().getModelChangeListener().onSetDeleteAll(this, MODIFIER, this.modifiers, new HashSet<>(this.modifiers)); - this.modifiers.clear(); - for (ModifierKind modifier : modifiers) { - addModifier(modifier); - } - } + modifierHandler.setModifiers(modifiers); return (C) this; } @Override public C addModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - this.modifiers = EnumSet.noneOf(ModifierKind.class); - } - getFactory().getEnvironment().getModelChangeListener().onSetAdd(this, MODIFIER, this.modifiers, modifier); - modifiers.add(modifier); + modifierHandler.addModifier(modifier); return (C) this; } @Override public boolean removeModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - return false; - } - getFactory().getEnvironment().getModelChangeListener().onSetDelete(this, MODIFIER, modifiers, modifier); - return modifiers.remove(modifier); + return modifierHandler.removeModifier(modifier); } @Override public C setVisibility(ModifierKind visibility) { - if (modifiers == CtElementImpl.emptySet()) { - this.modifiers = EnumSet.noneOf(ModifierKind.class); - } - removeModifier(ModifierKind.PUBLIC); - removeModifier(ModifierKind.PROTECTED); - removeModifier(ModifierKind.PRIVATE); - addModifier(visibility); + modifierHandler.setVisibility(visibility); return (C) this; } @Override public ModifierKind getVisibility() { - if (getModifiers().contains(ModifierKind.PUBLIC)) { - return ModifierKind.PUBLIC; - } - if (getModifiers().contains(ModifierKind.PROTECTED)) { - return ModifierKind.PROTECTED; - } - if (getModifiers().contains(ModifierKind.PRIVATE)) { - return ModifierKind.PRIVATE; - } - return null; + return modifierHandler.getVisibility(); } @Override diff --git a/src/main/java/spoon/support/reflect/declaration/CtParameterImpl.java b/src/main/java/spoon/support/reflect/declaration/CtParameterImpl.java index f882dc77112..31d1b91b9df 100644 --- a/src/main/java/spoon/support/reflect/declaration/CtParameterImpl.java +++ b/src/main/java/spoon/support/reflect/declaration/CtParameterImpl.java @@ -31,14 +31,12 @@ import spoon.reflect.visitor.CtVisitor; import spoon.support.DerivedProperty; import spoon.support.UnsettableProperty; +import spoon.support.reflect.CtModifierHandler; -import java.util.EnumSet; -import java.util.HashSet; import java.util.Set; import static spoon.reflect.path.CtRole.IS_SHADOW; import static spoon.reflect.path.CtRole.IS_VARARGS; -import static spoon.reflect.path.CtRole.MODIFIER; import static spoon.reflect.path.CtRole.TYPE; /** @@ -56,7 +54,7 @@ public class CtParameterImpl extends CtNamedElementImpl implements CtParamete boolean varArgs = false; @MetamodelPropertyField(role = CtRole.MODIFIER) - Set modifiers = CtElementImpl.emptySet(); + private CtModifierHandler modifierHandler = new CtModifierHandler(this); public CtParameterImpl() { super(); @@ -114,7 +112,7 @@ public > C setVarArgs(boolean varArgs) { @Override public Set getModifiers() { - return modifiers; + return modifierHandler.getModifiers(); } @Override @@ -124,58 +122,30 @@ public boolean hasModifier(ModifierKind modifier) { @Override public C setModifiers(Set modifiers) { - if (modifiers.size() > 0) { - getFactory().getEnvironment().getModelChangeListener().onSetDeleteAll(this, MODIFIER, this.modifiers, new HashSet<>(this.modifiers)); - this.modifiers.clear(); - for (ModifierKind modifier : modifiers) { - addModifier(modifier); - } - } + modifierHandler.setModifiers(modifiers); return (C) this; } @Override public C addModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - this.modifiers = EnumSet.noneOf(ModifierKind.class); - } - getFactory().getEnvironment().getModelChangeListener().onSetAdd(this, MODIFIER, this.modifiers, modifier); - modifiers.add(modifier); + modifierHandler.addModifier(modifier); return (C) this; } @Override public boolean removeModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - return false; - } - getFactory().getEnvironment().getModelChangeListener().onSetDelete(this, MODIFIER, modifiers, modifier); - return modifiers.remove(modifier); + return modifierHandler.removeModifier(modifier); } @Override public C setVisibility(ModifierKind visibility) { - if (modifiers == CtElementImpl.emptySet()) { - this.modifiers = EnumSet.noneOf(ModifierKind.class); - } - removeModifier(ModifierKind.PUBLIC); - removeModifier(ModifierKind.PROTECTED); - removeModifier(ModifierKind.PRIVATE); - addModifier(visibility); + modifierHandler.setVisibility(visibility); return (C) this; } @Override public ModifierKind getVisibility() { - if (getModifiers().contains(ModifierKind.PUBLIC)) { - return ModifierKind.PUBLIC; - } - if (getModifiers().contains(ModifierKind.PROTECTED)) { - return ModifierKind.PROTECTED; - } - if (getModifiers().contains(ModifierKind.PRIVATE)) { - return ModifierKind.PRIVATE; - } + modifierHandler.getVisibility(); return null; } diff --git a/src/main/java/spoon/support/reflect/declaration/CtTypeImpl.java b/src/main/java/spoon/support/reflect/declaration/CtTypeImpl.java index fa62c3a0e81..f33dd96f12b 100644 --- a/src/main/java/spoon/support/reflect/declaration/CtTypeImpl.java +++ b/src/main/java/spoon/support/reflect/declaration/CtTypeImpl.java @@ -53,6 +53,7 @@ import spoon.support.UnsettableProperty; import spoon.support.comparator.CtLineElementComparator; import spoon.support.compiler.SnippetCompilationHelper; +import spoon.support.reflect.CtModifierHandler; import spoon.support.util.QualifiedNameBasedSortedSet; import spoon.support.util.SignatureBasedSortedSet; import spoon.support.util.SortedList; @@ -63,19 +64,17 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Set; import static spoon.reflect.ModelElementContainerDefaultCapacities.TYPE_TYPE_PARAMETERS_CONTAINER_DEFAULT_CAPACITY; -import static spoon.reflect.path.CtRole.CONSTRUCTOR; -import static spoon.reflect.path.CtRole.METHOD; import static spoon.reflect.path.CtRole.ANNONYMOUS_EXECUTABLE; +import static spoon.reflect.path.CtRole.CONSTRUCTOR; import static spoon.reflect.path.CtRole.FIELD; import static spoon.reflect.path.CtRole.INTERFACE; import static spoon.reflect.path.CtRole.IS_SHADOW; -import static spoon.reflect.path.CtRole.MODIFIER; +import static spoon.reflect.path.CtRole.METHOD; import static spoon.reflect.path.CtRole.NESTED_TYPE; import static spoon.reflect.path.CtRole.TYPE_PARAMETER; @@ -93,7 +92,7 @@ public abstract class CtTypeImpl extends CtNamedElementImpl implements CtType Set> interfaces = emptySet(); @MetamodelPropertyField(role = CtRole.MODIFIER) - Set modifiers = emptySet(); + private CtModifierHandler modifierHandler = new CtModifierHandler(this); @MetamodelPropertyField(role = {CtRole.TYPE_MEMBER, CtRole.FIELD, CtRole.CONSTRUCTOR, CtRole.ANNONYMOUS_EXECUTABLE, CtRole.METHOD, CtRole.NESTED_TYPE}) List typeMembers = emptyList(); @@ -458,7 +457,7 @@ public void compileAndReplaceSnippets() { @Override public Set getModifiers() { - return modifiers; + return modifierHandler.getModifiers(); } @Override @@ -468,59 +467,30 @@ public boolean hasModifier(ModifierKind modifier) { @Override public C setModifiers(Set modifiers) { - if (modifiers.size() > 0) { - getFactory().getEnvironment().getModelChangeListener().onSetDeleteAll(this, MODIFIER, this.modifiers, new HashSet<>(this.modifiers)); - this.modifiers.clear(); - for (ModifierKind modifier : modifiers) { - addModifier(modifier); - } - } + modifierHandler.setModifiers(modifiers); return (C) this; } @Override public C addModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - this.modifiers = EnumSet.of(modifier); - } - getFactory().getEnvironment().getModelChangeListener().onSetAdd(this, MODIFIER, this.modifiers, modifier); - modifiers.add(modifier); + modifierHandler.addModifier(modifier); return (C) this; } @Override public boolean removeModifier(ModifierKind modifier) { - if (modifiers == CtElementImpl.emptySet()) { - return false; - } - getFactory().getEnvironment().getModelChangeListener().onSetDelete(this, MODIFIER, modifiers, modifier); - return modifiers.remove(modifier); + return modifierHandler.removeModifier(modifier); } @Override public C setVisibility(ModifierKind visibility) { - if (modifiers == CtElementImpl.emptySet()) { - this.modifiers = EnumSet.noneOf(ModifierKind.class); - } - removeModifier(ModifierKind.PUBLIC); - removeModifier(ModifierKind.PROTECTED); - removeModifier(ModifierKind.PRIVATE); - addModifier(visibility); + modifierHandler.setVisibility(visibility); return (C) this; } @Override public ModifierKind getVisibility() { - if (getModifiers().contains(ModifierKind.PUBLIC)) { - return ModifierKind.PUBLIC; - } - if (getModifiers().contains(ModifierKind.PROTECTED)) { - return ModifierKind.PROTECTED; - } - if (getModifiers().contains(ModifierKind.PRIVATE)) { - return ModifierKind.PRIVATE; - } - return null; + return modifierHandler.getVisibility(); } @Override diff --git a/src/test/java/spoon/reflect/ast/AstCheckerTest.java b/src/test/java/spoon/reflect/ast/AstCheckerTest.java index b1e0dbc0183..6e206e5574f 100644 --- a/src/test/java/spoon/reflect/ast/AstCheckerTest.java +++ b/src/test/java/spoon/reflect/ast/AstCheckerTest.java @@ -86,6 +86,7 @@ public void testPushToStackChanges() throws Exception { final Launcher launcher = new Launcher(); launcher.getEnvironment().setNoClasspath(true); // Implementations. + launcher.addInputResource("./src/main/java/spoon/support/reflect/CtModifierHandler.java"); launcher.addInputResource("./src/main/java/spoon/support/reflect/code"); launcher.addInputResource("./src/main/java/spoon/support/reflect/declaration"); launcher.addInputResource("./src/main/java/spoon/support/reflect/reference"); @@ -131,7 +132,9 @@ private boolean isToBeProcessed(CtMethod candidate) { return candidate.getBody() != null // && candidate.getParameters().size() != 0 // && candidate.hasModifier(ModifierKind.PUBLIC) // - && (candidate.getSimpleName().startsWith("add") || candidate.getSimpleName().startsWith("set") || candidate.getSimpleName().startsWith("remove")) // + && (candidate.getSimpleName().startsWith("add") + || candidate.getSimpleName().startsWith("set") + || candidate.getSimpleName().startsWith("remove")) // && candidate.getDeclaringType().getSimpleName().startsWith("Ct") // && !isNotCandidate(candidate) // && !isSurcharged(candidate) // @@ -141,7 +144,8 @@ private boolean isToBeProcessed(CtMethod candidate) { } private boolean isNotCandidate(CtMethod candidate) { - return "setVisibility".equals(candidate.getSimpleName()) || notCandidates.contains(candidate.getDeclaringType().getSimpleName() + "#" + candidate.getSimpleName()); + return "setVisibility".equals(candidate.getSimpleName()) + || notCandidates.contains(candidate.getDeclaringType().getSimpleName() + "#" + candidate.getSimpleName()); } private boolean isSurcharged(CtMethod candidate) {