use of org.eclipse.n4js.ts.types.TMember in project n4js by eclipse.
the class ComposedMemberScope method getSingleLocalElementByName.
/**
* Returns description for given element, name is assumed to consist of a single segment containing the simple name
* of the member. If no subScope contains a member with given name, null is returned. In other error cases (no or
* wrong access, mixed types etc.), {@link IEObjectDescriptionWithError}, and in particular
* {@link UnionMemberDescriptionWithError}, will be returned.
*/
@Override
protected IEObjectDescription getSingleLocalElementByName(QualifiedName qualifiedName) {
String name = qualifiedName.getLastSegment();
TMember member = getOrCreateComposedMember(name);
if (member == null) {
// no such member, no need for "merging" descriptions, there won't be any
return null;
}
if (isErrorPlaceholder(member)) {
return createComposedMemberDescriptionWithErrors(EObjectDescription.create(member.getName(), member));
}
IEObjectDescription description = getCheckedDescription(name, member);
return description;
}
use of org.eclipse.n4js.ts.types.TMember in project n4js by eclipse.
the class TypingStrategyFilter method apply.
@Override
public boolean apply(IEObjectDescription description) {
if (typingStrategy == TypingStrategy.DEFAULT || typingStrategy == TypingStrategy.NOMINAL) {
return true;
}
EObject proxyOrInstance = description.getEObjectOrProxy();
if (proxyOrInstance == null || proxyOrInstance.eIsProxy()) {
return true;
}
if (!(proxyOrInstance instanceof TMember)) {
return true;
}
TMember member = (TMember) proxyOrInstance;
if (member.isStatic() || member.getMemberAccessModifier() != MemberAccessModifier.PUBLIC) {
return false;
}
if (member instanceof TMethod) {
switch(typingStrategy) {
case NOMINAL:
case DEFAULT:
return true;
case STRUCTURAL_FIELDS:
case STRUCTURAL_READ_ONLY_FIELDS:
case STRUCTURAL_WRITE_ONLY_FIELDS:
case STRUCTURAL_FIELD_INITIALIZER:
return false;
case STRUCTURAL:
// including constructors
return true;
}
}
if (member instanceof TGetter) {
switch(typingStrategy) {
case NOMINAL:
case DEFAULT:
case STRUCTURAL:
case STRUCTURAL_FIELDS:
case STRUCTURAL_READ_ONLY_FIELDS:
return true;
case STRUCTURAL_WRITE_ONLY_FIELDS:
return false;
case STRUCTURAL_FIELD_INITIALIZER:
ContainerType<?> type = member.getContainingType();
NameAndAccess naa = new NameAndAccess(member.getName(), true, false);
Map<NameAndAccess, ? extends TMember> members = type.getOwnedMembersByNameAndAccess();
boolean hasSetter = members.containsKey(naa);
return hasSetter;
}
}
if (member instanceof TSetter) {
switch(typingStrategy) {
case NOMINAL:
case DEFAULT:
case STRUCTURAL:
case STRUCTURAL_FIELDS:
case STRUCTURAL_WRITE_ONLY_FIELDS:
return true;
case STRUCTURAL_READ_ONLY_FIELDS:
case STRUCTURAL_FIELD_INITIALIZER:
return false;
}
}
if (member instanceof TField) {
TField field = (TField) member;
switch(typingStrategy) {
case NOMINAL:
case DEFAULT:
case STRUCTURAL:
case STRUCTURAL_FIELDS:
return true;
case STRUCTURAL_READ_ONLY_FIELDS:
return !isWriteAccess;
case STRUCTURAL_WRITE_ONLY_FIELDS:
return isWriteAccess;
case STRUCTURAL_FIELD_INITIALIZER:
boolean isAccessable = !isWriteAccess && (!field.isFinal() || !field.isHasExpression());
return isAccessable;
}
}
return true;
}
use of org.eclipse.n4js.ts.types.TMember in project n4js by eclipse.
the class N4JSASTUtils method isSemiLegalAssignmentToFinalFieldInCtor.
/**
* Returns true iff <code>expr</code> is a semi-legal assignment expression within a constructor to a final field of
* the same class. Here, "semi"-legal means that one requirement for a fully legal such assignment is <b>not</b>
* checked by this method: the requirement that the declaration of the assigned final field must not have an
* initializer expression. For a fully legal assignment to a final field this has to be checked by client code.
*/
public static boolean isSemiLegalAssignmentToFinalFieldInCtor(EObject expr, TMember writtenMember) {
if (!(expr instanceof AssignmentExpression))
return false;
final AssignmentExpression assExpr = (AssignmentExpression) expr;
// left-hand side must be a property access to 'this'
final Expression lhs = assExpr.getLhs();
if (!(lhs instanceof ParameterizedPropertyAccessExpression))
return false;
final ParameterizedPropertyAccessExpression paExpr = (ParameterizedPropertyAccessExpression) lhs;
if (!(paExpr.getTarget() instanceof ThisLiteral))
return false;
// BUT: check this only if we have a resolved property in paExpr (important if this method used from scoping)
if (paExpr.getProperty() != null && !paExpr.getProperty().eIsProxy()) {
if (writtenMember != null) {
// case 1: writtenMember provided as argument -> must be identical
if (paExpr.getProperty() != writtenMember)
return false;
} else {
// case 2: writtenMember not provided -> take from paExpr
if (paExpr.getProperty() instanceof TMember)
writtenMember = (TMember) paExpr.getProperty();
}
}
// written member must be a final field
if (!(writtenMember instanceof TField))
return false;
final TField field = (TField) writtenMember;
if (!field.isFinal())
return false;
// (IMPORTANT: we do not assert !field.isHasExpression() here, which would be required for a fully-legal write
// access)
// assExpr must be located in the constructor of the owner of 'field'
// (a) find type model element for the function containing the assignment expression
final FunctionDefinition containingFunction = getContainingFunction(assExpr);
if (containingFunction == null)
return false;
final Type containingTFunction = containingFunction.getDefinedType();
if (containingTFunction == null)
return false;
// (b) find constructor of the owner of the field
final ContainerType<?> ownerOfField = field.getContainingType();
if (ownerOfField == null)
return false;
final TMember ctorOfOwner = getOwnOrSuperCtor(ownerOfField);
if (ctorOfOwner == null)
return false;
// (c) compare
boolean simpleCompare = containingTFunction == ctorOfOwner;
if (simpleCompare) {
return true;
}
// filled type:
if (containingTFunction.eContainer() instanceof TClass) {
TClass containingTClass = (TClass) containingTFunction.eContainer();
if (containingTClass.isStaticPolyfill() && containingTClass.getSuperClassRef() != null && containingTClass.getSuperClassRef().getDeclaredType() instanceof TClass) {
// get replaced ctor:
TClass filledClass = (TClass) containingTClass.getSuperClassRef().getDeclaredType();
TMember replacedCtorOfFilledClass = getOwnOrSuperCtor(filledClass);
// compare (incl. null)
return replacedCtorOfFilledClass == ctorOfOwner;
}
}
return false;
}
use of org.eclipse.n4js.ts.types.TMember in project n4js by eclipse.
the class ContainerTypeImpl method getOrCreateOwnedMembersByNameAndAccess.
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public Map<NameAndAccess, ? extends TMember> getOrCreateOwnedMembersByNameAndAccess() {
Map<NameAndAccess, ? extends TMember> _ownedMembersByNameAndAccess = this.getOwnedMembersByNameAndAccess();
boolean _tripleEquals = (_ownedMembersByNameAndAccess == null);
if (_tripleEquals) {
Map<NameAndAccess, ? extends TMember> _switchResult = null;
int _size = this.getOwnedMembers().size();
switch(_size) {
case 0:
_switchResult = Collections.<NameAndAccess, TMember>emptyMap();
break;
case 1:
Map<NameAndAccess, ? extends TMember> _xblockexpression = null;
{
final MT singleMember = this.getOwnedMembers().get(0);
final NameAndAccess[] nameAndAccess = NameAndAccess.of(singleMember);
Map<NameAndAccess, ? extends TMember> _xifexpression = null;
int _length = nameAndAccess.length;
boolean _greaterThan = (_length > 1);
if (_greaterThan) {
Map<NameAndAccess, TMember> _xblockexpression_1 = null;
{
final HashMap<NameAndAccess, TMember> map = new HashMap<NameAndAccess, TMember>();
map.put(nameAndAccess[0], singleMember);
map.put(nameAndAccess[1], singleMember);
_xblockexpression_1 = Collections.<NameAndAccess, TMember>unmodifiableMap(map);
}
_xifexpression = _xblockexpression_1;
} else {
_xifexpression = Collections.<NameAndAccess, MT>singletonMap(nameAndAccess[0], singleMember);
}
_xblockexpression = _xifexpression;
}
_switchResult = _xblockexpression;
break;
default:
EList<MT> _ownedMembers = this.getOwnedMembers();
MemberByNameAndAccessMap _memberByNameAndAccessMap = new MemberByNameAndAccessMap(_ownedMembers);
_switchResult = Collections.<NameAndAccess, TMember>unmodifiableMap(_memberByNameAndAccessMap);
break;
}
final Map<NameAndAccess, ? extends TMember> newRegistry = _switchResult;
final Procedure0 _function = new Procedure0() {
public void apply() {
ContainerTypeImpl.this.setOwnedMembersByNameAndAccess(newRegistry);
}
};
EcoreUtilN4.doWithDeliver(false, _function, this);
}
return this.getOwnedMembersByNameAndAccess();
}
use of org.eclipse.n4js.ts.types.TMember in project n4js by eclipse.
the class ProjectComparisonEntry method isInherited.
/**
* Returns true iff the implementation element at index <code>implIdx</code> is a TMember that was directly or
* indirectly inherited/consumed from a super class or implemented interface. Always returns <code>false</code> if
* this is not an element entry.
*/
public boolean isInherited(int implIdx) {
final EObject implParent = parent != null ? parent.getElementImpl(implIdx) : null;
final EObject impl = getElementImpl(implIdx);
if (implParent instanceof ContainerType<?> && impl instanceof TMember) {
return impl.eContainer() != implParent;
}
return false;
}
Aggregations