use of org.eclipse.n4js.ts.types.TClassifier in project n4js by eclipse.
the class N4JSMemberRedefinitionValidator method addIssueToMemberOrInterfaceReference.
private void addIssueToMemberOrInterfaceReference(RedefinitionType redefinitionType, TMember overriding, TMember implemented, String message, String issueCode, String... issueData) {
if (redefinitionType == RedefinitionType.overridden && overriding.getContainingType() != getCurrentClassifier()) {
throw new IllegalStateException("must not happen as member is not consumed");
}
TClassifier currentClassifier = getCurrentClassifier();
if (overriding.getContainingType() == currentClassifier) {
addIssue(message, overriding.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, issueCode, issueData);
} else {
MemberCollector memberCollector = containerTypesHelper.fromContext(getCurrentClassifierDefinition());
ContainerType<?> bequestingType = memberCollector.directSuperTypeBequestingMember(currentClassifier, implemented);
Optional<ParameterizedTypeRef> optRef = StreamSupport.stream(getCurrentClassifierDefinition().getImplementedOrExtendedInterfaceRefs().spliterator(), false).filter(ref -> ref.getDeclaredType() == bequestingType).findAny();
ParameterizedTypeRef ref = optRef.get();
EStructuralFeature feature = ref.eContainingFeature();
List<?> list = (List<?>) getCurrentClassifierDefinition().eGet(feature);
int index = list.indexOf(ref);
addIssue(message, getCurrentClassifierDefinition(), feature, index, issueCode, issueData);
}
}
use of org.eclipse.n4js.ts.types.TClassifier in project n4js by eclipse.
the class N4JSMemberRedefinitionValidator method messageMissingImplementations.
private void messageMissingImplementations(List<TMember> abstractMembers) {
TClassifier classifier = getCurrentClassifier();
if (!jsVariantHelper.allowMissingImplementation(classifier)) {
String message = getMessageForCLF_MISSING_IMPLEMENTATION(classifier.getName(), validatorMessageHelper.descriptions(abstractMembers));
addIssue(message, CLF_MISSING_IMPLEMENTATION);
} else {
// to be removed, only temporary (IDE-1236)
String message = getMessageForCLF_MISSING_IMPLEMENTATION_EXT(classifier.getName(), validatorMessageHelper.descriptions(abstractMembers));
addIssue(message, CLF_MISSING_IMPLEMENTATION_EXT);
}
}
use of org.eclipse.n4js.ts.types.TClassifier 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);
}
}
use of org.eclipse.n4js.ts.types.TClassifier 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);
}
}
}
}
}
use of org.eclipse.n4js.ts.types.TClassifier in project n4js by eclipse.
the class N4JSMemberRedefinitionValidator method checkMemberRedefinitions.
/**
* Checks constraints defined in chapter 5.4. Redefinition of Members.
*/
@Check
public void checkMemberRedefinitions(N4ClassifierDefinition n4ClassifierDefinition) {
if (!(n4ClassifierDefinition.getDefinedType() instanceof TClassifier)) {
// wrongly parsed
return;
}
TClassifier tClassifier = (TClassifier) n4ClassifierDefinition.getDefinedType();
getContext().put(TClassifier.class, tClassifier);
RuleEnvironment g = RuleEnvironmentExtensions.newRuleEnvironment(tClassifier);
getContext().put(RuleEnvironment.class, g);
// the context for type variables
ParameterizedTypeRef classTypeRef = TypeUtils.createTypeRef(tClassifier);
getContext().put(TYPE_VAR_CONTEXT, classTypeRef);
MemberCube memberCube = createMemberValidationList();
final boolean isClass = tClassifier instanceof TClass;
final Map<ParameterizedTypeRef, MemberList<TMember>> nonAccessibleAbstractMembersBySuperTypeRef = new HashMap<>();
for (Entry<NameStaticPair, MemberMatrix> entry : memberCube.entrySet()) {
MemberMatrix mm = entry.getValue();
// Set to collect all owned members that are lacking an override annotation.
Collection<TMember> membersMissingOverrideAnnotation = new HashSet<>();
if (isClass) {
constraints_67_MemberOverride_checkEntry(mm, membersMissingOverrideAnnotation);
}
if (mm.hasImplemented()) {
// first mix in
if (holdConstraints_68_Consumption(mm)) {
// then check if everything is implemented
constraints_69_Implementation(mm, membersMissingOverrideAnnotation);
}
}
constraints_60_InheritedConsumedCovariantSpecConstructor(tClassifier, mm);
constraints_66_NonOverride(mm);
constraints_42_45_46_AbstractMember(mm, nonAccessibleAbstractMembersBySuperTypeRef);
unusedGenericTypeVariable(mm);
checkUnpairedAccessorConsumption(mm, n4ClassifierDefinition);
checkUnpairedAccessorFilling(mm, n4ClassifierDefinition);
messageMissingOverrideAnnotation(mm, membersMissingOverrideAnnotation);
}
final boolean foundImpossibleExtendsImplements = !nonAccessibleAbstractMembersBySuperTypeRef.isEmpty();
if (foundImpossibleExtendsImplements) {
messageImpossibleExtendsImplements(n4ClassifierDefinition, nonAccessibleAbstractMembersBySuperTypeRef);
}
if (!foundImpossibleExtendsImplements) {
// avoid consequential errors
constraints_41_AbstractClass(tClassifier, memberCube);
}
}
Aggregations