use of org.eclipse.n4js.ts.types.TSetter in project n4js by eclipse.
the class N4JSMemberRedefinitionValidator method constraints_65_overrideCompatible.
/**
* Constraints 65 (Override Compatible) and relation overrideCompatible.
*
* @param m
* the overriding member
* @param s
* the overridden or implemented member
* @param consumptionConflict
* check override or implementation override, the latter usually stems from a consumption conflict (so
* that s did not get consumed in the first place)
* @param mm
* member matrix, only to improve error message
* @return true if m is override compatible to s. Note that false does not necessarily means that an error occurred,
* since e.g., a getter does not effect a setter
*/
private OverrideCompatibilityResult constraints_65_overrideCompatible(RedefinitionType redefinitionType, TMember m, TMember s, boolean consumptionConflict, MemberMatrix mm) {
// 1. name and static modifier are always equal here, so we do not have to check that again
// 2. meta type
boolean metaTypeCompatible = MemberRedefinitionUtils.isMetaTypeCompatible(m, s);
if (!metaTypeCompatible) {
if (!consumptionConflict) {
// avoid consequential errors
messageOverrideMetaTypeIncompatible(redefinitionType, m, s, mm);
}
return OverrideCompatibilityResult.ERROR;
}
// 3. s not final
if (s.isFinal()) {
if (!consumptionConflict) {
// avoid consequential errors
messageOverrideFinal(redefinitionType, m, s);
}
return OverrideCompatibilityResult.ERROR;
}
final boolean sIsField = s instanceof TField;
final boolean sIsSetter = s instanceof TSetter;
final boolean mIsField = m instanceof TField;
// 4. s not const
if (sIsField) {
// const only defined on TField & TStructuralField
TField sF = (TField) s;
if (sF.isConst()) {
// By GHOLD-186 const redefinition is allowed for const fields
if (!((mIsField) && ((TField) m).isConst())) {
if (!consumptionConflict) {
// avoid consequential errors
messageOverrideConst(redefinitionType, m, sF);
}
return OverrideCompatibilityResult.ERROR;
}
}
}
// 5. must not override non-final/non-const field or setter with a @Final/const field
if (sIsField || sIsSetter) {
if (!s.isFinal() && !s.isConst()) {
if (mIsField && (m.isFinal() || m.isConst())) {
if (!consumptionConflict) {
// avoid consequential errors
messageOverrideWithFinalOrConstField(redefinitionType, m, s);
}
return OverrideCompatibilityResult.ERROR;
}
}
}
// 6. abstract
if (m.isAbstract() && !s.isAbstract()) {
if (!consumptionConflict) {
// avoid consequential errors
messageOverrideAbstract(redefinitionType, m, s);
}
return OverrideCompatibilityResult.ERROR;
}
// 7. type compatible
if (!m.isSetter() && !s.isSetter()) {
// in Method (including constructor), Getter, Field
Result<Boolean> result = isSubTypeResult(m, s);
if (result.failed()) {
if (!consumptionConflict) {
// avoid consequential errors
messageOverrideMemberTypeConflict(redefinitionType, m, s, result, mm);
}
return OverrideCompatibilityResult.ERROR;
}
}
boolean sIsConst = false;
if (sIsField) {
sIsConst = ((TField) s).isConst();
}
if ((m.isSetter() || m.isField()) && !s.isGetter() && !sIsConst) {
Result<Boolean> result = isSubTypeResult(s, m);
if (result.failed()) {
if (!consumptionConflict) {
// avoid consequential errors
messageOverrideMemberTypeConflict(redefinitionType, m, s, result, mm);
}
return OverrideCompatibilityResult.ERROR;
}
}
// 8.1 accessibility must not be reduced
if (AccessModifiers.checkedLess(m, s)) {
// fix modifiers in order to avoid strange behavior
if (!consumptionConflict) {
// avoid consequential errors
messageOverrideAccessibilityReduced(redefinitionType, m, s);
}
return OverrideCompatibilityResult.ERROR;
}
// 8.2 special accessibility handling of public@Internal and protected as they reduce each other
MemberAccessModifier fixedLeft = AccessModifiers.fixed(m);
MemberAccessModifier fixedRight = AccessModifiers.fixed(s);
if ((fixedLeft == MemberAccessModifier.PROTECTED && fixedRight == MemberAccessModifier.PUBLIC_INTERNAL) || (fixedLeft == MemberAccessModifier.PUBLIC_INTERNAL && fixedRight == MemberAccessModifier.PROTECTED)) {
messageOverrideAccessibilityReduced(redefinitionType, m, s);
return OverrideCompatibilityResult.ERROR;
}
return OverrideCompatibilityResult.COMPATIBLE;
}
use of org.eclipse.n4js.ts.types.TSetter in project n4js by eclipse.
the class SetterFactory method create.
@Override
public TSetter create(String name) {
TSetter setter = TypesFactory.eINSTANCE.createTSetter();
setter.setComposed(true);
setter.setName(name);
setter.setDeclaredMemberAccessModifier(getAccessability());
setter.setFpar(fpar.create());
return setter;
}
use of org.eclipse.n4js.ts.types.TSetter in project n4js by eclipse.
the class ConcreteMembersOrderedForTranspiler method mapToAccessorTuples.
/**
* Maps getters and setters to {@link AccessorTuple}s, used to generate proper setters-getters-pairs for property.
* The passed maps may be changed!
*
* @param getters
* list of getters
* @param fields
* list of fields
* @param io_setters
* map with owned getters, this map may be changed by this method
* @param io_inheritedGetters
* map with inherited getters, this map may be changed by this method
* @param io_inheritedSetters
* map with inherited getters, this map may be changed by this method
* @return list of accessor tuples.
*/
private static List<AccessorTuple> mapToAccessorTuples(Iterable<TGetter> getters, Map<NameStaticPair, TSetter> io_setters, Iterable<TField> fields, Map<NameStaticPair, TGetter> io_inheritedGetters, Map<NameStaticPair, TSetter> io_inheritedSetters) {
List<AccessorTuple> tuples = new ArrayList<>();
// add getters (alone & with corresponding setter)
for (TGetter getter : getters) {
AccessorTuple tuple = new AccessorTuple(getter.getName(), getter.isStatic());
tuple.setGetter(getter);
NameStaticPair nsp = NameStaticPair.of(getter);
// do not handle the thing twice
tuple.setSetter(io_setters.remove(nsp));
if (tuple.getSetter() == null) {
tuple.setInheritedSetter(io_inheritedSetters.remove(nsp));
}
tuples.add(tuple);
}
// add setters w/o getter:
for (TSetter setter : io_setters.values()) {
AccessorTuple tuple = new AccessorTuple(setter.getName(), setter.isStatic());
NameStaticPair nsp = NameStaticPair.of(setter);
tuple.setSetter(setter);
tuple.setInheritedGetter(io_inheritedGetters.remove(nsp));
tuples.add(tuple);
}
// remove the inherited references - the field will overwrite them.
for (TField field : fields) {
NameStaticPair nsp = NameStaticPair.of(field);
io_inheritedSetters.remove(nsp);
io_inheritedGetters.remove(nsp);
}
// find getters/setters defined in interfaces which need to be combined:
for (TSetter inhSetter : io_inheritedSetters.values()) {
TGetter inhGetter = io_inheritedGetters.remove(NameStaticPair.of(inhSetter));
if (inhGetter != null && inhSetter.getContainingType() != inhGetter.getContainingType() && (inhSetter.getContainingType() instanceof TInterface || inhGetter.getContainingType() instanceof TInterface)) {
// getter & setter are inherited from different types.
AccessorTuple tuple = new AccessorTuple(inhSetter.getName(), inhSetter.isStatic());
tuple.setInheritedGetter(inhGetter);
tuple.setInheritedSetter(inhSetter);
tuples.add(tuple);
}
}
return tuples;
}
use of org.eclipse.n4js.ts.types.TSetter in project n4js by eclipse.
the class ConcreteMembersOrderedForTranspiler method getConcreteFieldAccessors.
/**
* Helper method, returns all concrete field accessors as tuples of the given classifier, which may even contain
* fields if they override concrete getters or setter. Since getter/setters can only be defined as pairs, in case of
* single owned getter with inherited setter, a delegate is created for the setter (and vice versa).
*/
private static List<AccessorTuple> getConcreteFieldAccessors(List<TMember> ownedAndMixedInConcreteMember, List<TMember> concreteInheritedMembers) {
Set<TField> ownedAndMixedInFields = new HashSet<>();
Set<TGetter> ownedAndMixedInGetters = new HashSet<>();
Map<NameStaticPair, TSetter> ownedAndMixedInSetters = new HashMap<>();
for (TMember m : ownedAndMixedInConcreteMember) {
if (m instanceof TField) {
ownedAndMixedInFields.add((TField) m);
} else if (m instanceof TGetter) {
ownedAndMixedInGetters.add((TGetter) m);
} else if (m instanceof TSetter) {
ownedAndMixedInSetters.put(NameStaticPair.of(m), (TSetter) m);
}
}
Map<NameStaticPair, TGetter> inheritedGetters = new HashMap<>();
Map<NameStaticPair, TSetter> inheritedSetters = new HashMap<>();
for (TMember m : concreteInheritedMembers) {
if (m instanceof TGetter) {
if (!ownedAndMixedInGetters.contains(m)) {
inheritedGetters.put(NameStaticPair.of(m), (TGetter) m);
}
} else if (m instanceof TSetter) {
NameStaticPair nsp = NameStaticPair.of(m);
if (ownedAndMixedInSetters.get(nsp) != m) {
inheritedSetters.put(nsp, (TSetter) m);
}
}
}
List<AccessorTuple> ownedOrMixedInAccessorTouples = mapToAccessorTuples(ownedAndMixedInGetters, ownedAndMixedInSetters, ownedAndMixedInFields, inheritedGetters, inheritedSetters);
return ownedOrMixedInAccessorTouples;
}
use of org.eclipse.n4js.ts.types.TSetter in project n4js by eclipse.
the class ScriptApiTracker method createVirtFieldAccessorTuple.
private VirtualApiMissingFieldAccessorTuple createVirtFieldAccessorTuple(TField apiField) {
boolean statiC = apiField.isStatic();
String name = apiField.getName();
AccessorTuple copy = new AccessorTuple(name, statiC);
TSetter tset = TypesFactory.eINSTANCE.createTSetter();
tset.setName(name);
tset.setDeclaredStatic(statiC);
copy.setSetter(tset);
TGetter tget = TypesFactory.eINSTANCE.createTGetter();
tget.setName(name);
tget.setDeclaredStatic(statiC);
copy.setGetter(tget);
VirtualApiMissingFieldAccessorTuple ret = new VirtualApiMissingFieldAccessorTuple(copy);
ret.setGetter(new VirtualApiTGetter(name, tget));
ret.setSetter(new VirtualApiTSetter(name, tset));
return ret;
}
Aggregations