use of org.eclipse.n4js.ts.types.TMember in project n4js by eclipse.
the class TMemberEntry method toString.
@Override
public String toString() {
String pre = (_static ? "static " : "") + name + ": {";
List<String> out = new ArrayList<>(8);
for (int i = 0; i < 4; i++) {
TMember m = members[i];
if (m != null) {
out.add(m.eClass().getName());
}
if (i != FIELD) {
m = members[i + ABSTRACT_OFFSET];
if (m != null) {
out.add("a." + m.eClass().getName());
}
}
}
return pre + Joiner.on(", ").join(out) + "}";
}
use of org.eclipse.n4js.ts.types.TMember 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.TMember in project n4js by eclipse.
the class N4JSMemberRedefinitionValidator method constraints_60_InheritedConsumedCovariantSpecConstructor.
/**
* Checks a certain special case of Constraints 60 related to @Spec constructors: if the classifier being
* validated does *not* have an owned constructor, normally nothing would be checked; in case of @Spec
* constructors, however, we have to check that the inherited/consumed constructor (if any) is compatible to itself
* within the classifier being validated:
*
* <pre>
* class C {
* @CovariantConstructor constructor(@Spec spec: ~i~this) {}
* }
* class D { // <-- must show error here, because inherited @Spec constructor not compatible to itself
* public badField;
* }
* </pre>
*/
private boolean constraints_60_InheritedConsumedCovariantSpecConstructor(TClassifier tClassifier, MemberMatrix mm) {
boolean isValid = true;
if (!mm.hasOwned()) {
final TMember firstInherited = mm.hasInherited() ? mm.inherited().iterator().next() : null;
if (firstInherited instanceof TMethod && firstInherited.isConstructor() && isCovarianceForConstructorsRequired(tClassifier, firstInherited)) {
isValid &= checkSpecConstructorOverrideCompatibility(tClassifier, (TMethod) firstInherited);
}
final TMember firstImplemented = mm.hasImplemented() ? mm.implemented().iterator().next() : null;
if (firstImplemented instanceof TMethod && firstImplemented.isConstructor() && isCovarianceForConstructorsRequired(tClassifier, firstImplemented)) {
isValid &= checkSpecConstructorOverrideCompatibility(tClassifier, (TMethod) firstImplemented);
}
}
return isValid;
}
use of org.eclipse.n4js.ts.types.TMember 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.TMember 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);
}
}
}
}
}
Aggregations