Search in sources :

Example 1 with TSetter

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;
}
Also used : TSetter(org.eclipse.n4js.ts.types.TSetter) TField(org.eclipse.n4js.ts.types.TField) MemberAccessModifier(org.eclipse.n4js.ts.types.MemberAccessModifier)

Example 2 with TSetter

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;
}
Also used : TSetter(org.eclipse.n4js.ts.types.TSetter)

Example 3 with TSetter

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;
}
Also used : NameStaticPair(org.eclipse.n4js.ts.types.util.NameStaticPair) TSetter(org.eclipse.n4js.ts.types.TSetter) TField(org.eclipse.n4js.ts.types.TField) TInterface(org.eclipse.n4js.ts.types.TInterface) TGetter(org.eclipse.n4js.ts.types.TGetter) ArrayList(java.util.ArrayList) AccessorTuple(org.eclipse.n4js.ts.types.util.AccessorTuple)

Example 4 with TSetter

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;
}
Also used : NameStaticPair(org.eclipse.n4js.ts.types.util.NameStaticPair) TSetter(org.eclipse.n4js.ts.types.TSetter) TField(org.eclipse.n4js.ts.types.TField) HashMap(java.util.HashMap) TGetter(org.eclipse.n4js.ts.types.TGetter) AccessorTuple(org.eclipse.n4js.ts.types.util.AccessorTuple) TMember(org.eclipse.n4js.ts.types.TMember) HashSet(java.util.HashSet)

Example 5 with TSetter

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;
}
Also used : TSetter(org.eclipse.n4js.ts.types.TSetter) TGetter(org.eclipse.n4js.ts.types.TGetter) AccessorTuple(org.eclipse.n4js.ts.types.util.AccessorTuple)

Aggregations

TSetter (org.eclipse.n4js.ts.types.TSetter)12 TGetter (org.eclipse.n4js.ts.types.TGetter)7 TField (org.eclipse.n4js.ts.types.TField)6 TMethod (org.eclipse.n4js.ts.types.TMethod)4 AccessorTuple (org.eclipse.n4js.ts.types.util.AccessorTuple)4 TMember (org.eclipse.n4js.ts.types.TMember)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 EObject (org.eclipse.emf.ecore.EObject)2 TInterface (org.eclipse.n4js.ts.types.TInterface)2 NameStaticPair (org.eclipse.n4js.ts.types.util.NameStaticPair)2 Pair (org.eclipse.xtext.xbase.lib.Pair)2 LinkedHashMultimap (com.google.common.collect.LinkedHashMultimap)1 Inject (com.google.inject.Inject)1 Singleton (com.google.inject.Singleton)1 Collections (java.util.Collections)1 Collections.emptyList (java.util.Collections.emptyList)1 Iterator (java.util.Iterator)1 LinkedHashSet (java.util.LinkedHashSet)1