Search in sources :

Example 1 with SourceAwareIterator

use of org.eclipse.n4js.validation.validators.utils.MemberMatrix.SourceAwareIterator in project n4js by eclipse.

the class N4JSMemberRedefinitionValidator method checkUnpairedAccessorFilling.

private void checkUnpairedAccessorFilling(MemberMatrix mm, N4ClassifierDefinition definition) {
    if (definition.getDefinedType().isStaticPolyfill() && mm.hasMixedAccessorPair()) {
        FieldAccessor ownedAccessor = (FieldAccessor) Iterables.getFirst(mm.owned(), null);
        if (null == ownedAccessor) {
            // Should not happen, a mixed accessor pair implies at least one owned member
            return;
        }
        if (!(definition instanceof N4ClassDefinition)) {
            // Non-class static polyfills aren't allowed. Validated somewhere else.
            return;
        }
        TClass filledClass = MemberRedefinitionUtils.getFilledClass((N4ClassDefinition) definition);
        if (null == filledClass) {
            // Invalid static polyfill class. Validated somewhere else.
            return;
        }
        // Iterate over all inherited members
        SourceAwareIterator memberIterator = mm.actuallyInheritedAndMixedMembers();
        while (memberIterator.hasNext()) {
            TMember next = memberIterator.next();
            ContainerType<?> containingType = next.getContainingType();
            // Issue an error if the member isn't owned by the filled class
            if (containingType != filledClass) {
                messageMissingOwnedAccessor(ownedAccessor);
            }
        }
    }
}
Also used : SourceAwareIterator(org.eclipse.n4js.validation.validators.utils.MemberMatrix.SourceAwareIterator) TMember(org.eclipse.n4js.ts.types.TMember) FieldAccessor(org.eclipse.n4js.ts.types.FieldAccessor) TClass(org.eclipse.n4js.ts.types.TClass) N4ClassDefinition(org.eclipse.n4js.n4JS.N4ClassDefinition)

Example 2 with SourceAwareIterator

use of org.eclipse.n4js.validation.validators.utils.MemberMatrix.SourceAwareIterator in project n4js by eclipse.

the class N4JSMemberRedefinitionValidator method constraints_41_AbstractClass.

/**
 * Constraints 41 (Abstract Class)
 */
private boolean constraints_41_AbstractClass(TClassifier classifier, MemberCube memberCube) {
    List<TMember> abstractMembers = null;
    if (!classifier.isAbstract() && classifier instanceof TClass) {
        for (Entry<NameStaticPair, MemberMatrix> entry : memberCube.entrySet()) {
            MemberMatrix mm = entry.getValue();
            MemberList<TMember> l = new MemberList<>();
            Iterators.addAll(l, mm.actuallyInheritedAndMixedMembers());
            for (SourceAwareIterator iter = mm.actuallyInheritedAndMixedMembers(); iter.hasNext(); ) {
                TMember m = iter.next();
                if (m.isAbstract()) {
                    if (abstractMembers == null) {
                        abstractMembers = new ArrayList<>();
                    }
                    abstractMembers.add(m);
                }
            }
        }
    }
    if (abstractMembers != null) {
        messageMissingImplementations(abstractMembers);
        return false;
    }
    return true;
}
Also used : NameStaticPair(org.eclipse.n4js.ts.types.util.NameStaticPair) MemberList(org.eclipse.n4js.ts.types.util.MemberList) SourceAwareIterator(org.eclipse.n4js.validation.validators.utils.MemberMatrix.SourceAwareIterator) MemberMatrix(org.eclipse.n4js.validation.validators.utils.MemberMatrix) TMember(org.eclipse.n4js.ts.types.TMember) TClass(org.eclipse.n4js.ts.types.TClass)

Example 3 with SourceAwareIterator

use of org.eclipse.n4js.validation.validators.utils.MemberMatrix.SourceAwareIterator in project n4js by eclipse.

the class N4JSMemberRedefinitionValidator method constraints_69_Implementation.

/**
 * Constraints 69: Implementation of Interface Members
 *
 * This method doesn't add issues for missing override annotations but adds the missing-annotation-members to the
 * given collection.
 */
private void constraints_69_Implementation(MemberMatrix mm, Collection<TMember> membersMissingOverrideAnnotation) {
    String missingAccessor = null;
    List<TMember> missingAccessors = new MemberList<>();
    List<TMember> conflictingMembers = new MemberList<>();
    TClassifier currentClassifier = getCurrentClassifier();
    // avoid multiple errors on a single element (but not on
    Set<TMember> ownedErroneousMembers = null;
    for (TMember m : mm.implemented()) {
        if (mm.isConsumed(m)) {
            // m is mixed in, so it exits and we do not need other tests
            continue;
        }
        boolean bExistCompatibleMember = false;
        boolean bExistCompatibleGetter = false;
        boolean bExistCompatibleSetter = false;
        for (SourceAwareIterator iter = mm.ownedConsumedInheritedImplemented(); iter.hasNext(); ) {
            TMember m_ = iter.next();
            if (ownedErroneousMembers != null && !iter.isOwnedMember()) {
                // we found problems with owned members, we do not need more error messages.
                break;
            }
            // short cut and avoid multiple errors for single member
            if (m_ == m || ownedErroneousMembers != null && ownedErroneousMembers.contains(m_)) {
                if (iter.isInheritedMember()) {
                    // consumed by super class and then inherited
                    bExistCompatibleMember = true;
                }
                // we do not break since we want to find possible consumption problems
                continue;
            }
            // 1. m must be accessible and
            // 2.a & 2.b: m_ must be implementation-compatible to m
            OverrideCompatibilityResult compatibility = checkAccessibilityAndOverrideCompatibility(RedefinitionType.implemented, m_, m, !iter.isActualMember(), mm);
            if (compatibility == OverrideCompatibilityResult.ACCESSOR_PAIR) {
                continue;
            } else if (compatibility == OverrideCompatibilityResult.ERROR) {
                if (iter.isOwnedMember()) {
                    // do not skip other errors for owned members, usually accessor pairs
                    if (ownedErroneousMembers == null) {
                        ownedErroneousMembers = new HashSet<>();
                    }
                    ownedErroneousMembers.add(m_);
                } else if (iter.isActualMember()) {
                    // error message already
                    return;
                } else {
                    break;
                }
            } else if (iter.isActualMember()) {
                // mark found implementor
                if (m.isField()) {
                    if (m_.isGetter()) {
                        bExistCompatibleGetter = true;
                    } else if (m_.isSetter()) {
                        bExistCompatibleSetter = true;
                    } else {
                        bExistCompatibleMember = true;
                    }
                } else {
                    bExistCompatibleMember = true;
                }
                // 1 & 2 declared overridden
                if (!m_.isDeclaredOverride() && m_.getContainingType() == currentClassifier) {
                    membersMissingOverrideAnnotation.add(m_);
                }
            }
        }
        if (bExistCompatibleGetter != bExistCompatibleSetter) {
            missingAccessor = bExistCompatibleGetter ? "setter" : "getter";
            missingAccessors.add(m);
        } else if (!bExistCompatibleMember && !(bExistCompatibleGetter && bExistCompatibleSetter)) {
            conflictingMembers.add(m);
        }
    }
    if (ownedErroneousMembers != null) {
        // avoid consequential errors
        return;
    }
    if (!conflictingMembers.isEmpty()) {
        messageConflictingMixins(conflictingMembers);
    } else if (!missingAccessors.isEmpty()) {
        messageMissingAccessor(missingAccessor, missingAccessors);
    }
}
Also used : TClassifier(org.eclipse.n4js.ts.types.TClassifier) MemberList(org.eclipse.n4js.ts.types.util.MemberList) SourceAwareIterator(org.eclipse.n4js.validation.validators.utils.MemberMatrix.SourceAwareIterator) TMember(org.eclipse.n4js.ts.types.TMember) HashSet(java.util.HashSet)

Example 4 with SourceAwareIterator

use of org.eclipse.n4js.validation.validators.utils.MemberMatrix.SourceAwareIterator in project n4js by eclipse.

the class N4JSMemberRedefinitionValidator method constraints_42_45_46_AbstractMember.

/**
 * Constraints 42, 3 (Abstract Member)<br>
 * Constraints 45, 4 (Extending Interfaces)<br>
 * Constraints 46, 5 (Implementing Interfaces)
 *
 * This method doesn't add issues for missing override annotations but adds the missing-annotation-members to the
 * given collection.
 */
private void constraints_42_45_46_AbstractMember(MemberMatrix mm, Map<ParameterizedTypeRef, MemberList<TMember>> nonAccessibleAbstractMembersBySuperTypeRef) {
    N4ClassifierDefinition classifierDefinition = getCurrentClassifierDefinition();
    TClassifier classifier = getCurrentClassifier();
    TModule contextModule = EcoreUtil2.getContainerOfType(classifier, TModule.class);
    for (SourceAwareIterator iter = mm.allMembers(); iter.hasNext(); ) {
        TMember m = iter.next();
        if (!iter.isOwnedMember() && m.isAbstract()) {
            if (!memberVisibilityChecker.isVisibleWhenOverriding(contextModule, classifier, classifier, m)) {
                Iterable<ParameterizedTypeRef> superTypeRefs = FindClassifierInHierarchyUtils.findSuperTypesWithMember(classifierDefinition, m);
                for (ParameterizedTypeRef superTypeRef : superTypeRefs) {
                    MemberList<TMember> nonAccessible = nonAccessibleAbstractMembersBySuperTypeRef.get(superTypeRef);
                    if (nonAccessible == null) {
                        nonAccessible = new MemberList<>();
                        nonAccessibleAbstractMembersBySuperTypeRef.put(superTypeRef, nonAccessible);
                    }
                    nonAccessible.add(m);
                }
            }
        }
    }
}
Also used : TClassifier(org.eclipse.n4js.ts.types.TClassifier) ParameterizedTypeRef(org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef) N4ClassifierDefinition(org.eclipse.n4js.n4JS.N4ClassifierDefinition) SourceAwareIterator(org.eclipse.n4js.validation.validators.utils.MemberMatrix.SourceAwareIterator) TModule(org.eclipse.n4js.ts.types.TModule) TMember(org.eclipse.n4js.ts.types.TMember)

Example 5 with SourceAwareIterator

use of org.eclipse.n4js.validation.validators.utils.MemberMatrix.SourceAwareIterator in project n4js by eclipse.

the class N4JSMemberRedefinitionValidator method holdConstraints_68_Consumption.

/**
 * Constraints 68: Consumption of Interface Members
 *
 * Returns false if an error occurred which is not solvable in current classifier (i.e., incompatible meta types).
 */
private boolean holdConstraints_68_Consumption(MemberMatrix mm) {
    TClassifier currentType = getCurrentClassifier();
    MemberList<TMember> consumedMembers = new MemberList<>(2);
    for (TMember m : mm.implemented()) {
        boolean consume = true;
        for (SourceAwareIterator iter = mm.allMembers(); iter.hasNext(); ) {
            TMember m_ = iter.next();
            if (m_ == m && iter.isInterfaceMember()) {
                // again. Thus, we only consume if both members stem from interfaces
                continue;
            }
            // 1. meta type
            if ((m.isMethod() && !m_.isMethod()) || (!m.isMethod() && !(m_.isAccessor() || m_.isField()))) {
                if (iter.isInterfaceMember()) {
                    messageIncompatibleMembersToImplement(mm.implemented());
                    return false;
                } else if (iter.isInheritedMember()) {
                    messageIncompatibleInheritedMembersToImplement(m_, mm.implemented());
                    return false;
                } else {
                    return true;
                }
            }
            // 2 (abstract/owned), 3 (visibility) and 4 (type):
            boolean accessorPair = TypeUtils.isAccessorPair(m, m_);
            if (!accessorPair) {
                // 2. not abstract or owned
                if ((!m_.isAbstract() || m_.getContainingType() == currentType)) {
                    consume = false;
                    break;
                }
                // 3. access modifier
                if (AccessModifiers.less(m, m_)) {
                    consume = false;
                    break;
                }
                // 4. type
                if (!m_.isSetter()) {
                    if (!isSubType(m, m_)) {
                        consume = false;
                        break;
                    }
                }
                if (m_.isSetter() || m_.isField()) {
                    if (!isSubType(m_, m)) {
                        consume = false;
                        break;
                    }
                }
            }
        }
        if (consume) {
            if (!consumedMembers.contains(m)) {
                // in case an interface is (indirectly) redundantly implemented
                consumedMembers.add(m);
            }
        }
    }
    mm.markConsumed(consumedMembers);
    return true;
}
Also used : TClassifier(org.eclipse.n4js.ts.types.TClassifier) MemberList(org.eclipse.n4js.ts.types.util.MemberList) SourceAwareIterator(org.eclipse.n4js.validation.validators.utils.MemberMatrix.SourceAwareIterator) TMember(org.eclipse.n4js.ts.types.TMember)

Aggregations

TMember (org.eclipse.n4js.ts.types.TMember)5 SourceAwareIterator (org.eclipse.n4js.validation.validators.utils.MemberMatrix.SourceAwareIterator)5 TClassifier (org.eclipse.n4js.ts.types.TClassifier)3 MemberList (org.eclipse.n4js.ts.types.util.MemberList)3 TClass (org.eclipse.n4js.ts.types.TClass)2 HashSet (java.util.HashSet)1 N4ClassDefinition (org.eclipse.n4js.n4JS.N4ClassDefinition)1 N4ClassifierDefinition (org.eclipse.n4js.n4JS.N4ClassifierDefinition)1 ParameterizedTypeRef (org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef)1 FieldAccessor (org.eclipse.n4js.ts.types.FieldAccessor)1 TModule (org.eclipse.n4js.ts.types.TModule)1 NameStaticPair (org.eclipse.n4js.ts.types.util.NameStaticPair)1 MemberMatrix (org.eclipse.n4js.validation.validators.utils.MemberMatrix)1