Search in sources :

Example 31 with TMember

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

Example 32 with TMember

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;
}
Also used : TSetter(org.eclipse.n4js.ts.types.TSetter) NameAndAccess(org.eclipse.n4js.ts.types.NameAndAccess) TMethod(org.eclipse.n4js.ts.types.TMethod) TField(org.eclipse.n4js.ts.types.TField) TGetter(org.eclipse.n4js.ts.types.TGetter) EObject(org.eclipse.emf.ecore.EObject) TMember(org.eclipse.n4js.ts.types.TMember)

Example 33 with TMember

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;
}
Also used : ContainerType(org.eclipse.n4js.ts.types.ContainerType) Type(org.eclipse.n4js.ts.types.Type) TField(org.eclipse.n4js.ts.types.TField) TMember(org.eclipse.n4js.ts.types.TMember) TClass(org.eclipse.n4js.ts.types.TClass)

Example 34 with TMember

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();
}
Also used : MemberByNameAndAccessMap(org.eclipse.n4js.ts.types.internal.MemberByNameAndAccessMap) NameAndAccess(org.eclipse.n4js.ts.types.NameAndAccess) Procedure0(org.eclipse.xtext.xbase.lib.Procedures.Procedure0) HashMap(java.util.HashMap) TMember(org.eclipse.n4js.ts.types.TMember) HashMap(java.util.HashMap) Map(java.util.Map) MemberByNameAndAccessMap(org.eclipse.n4js.ts.types.internal.MemberByNameAndAccessMap)

Example 35 with TMember

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

Aggregations

TMember (org.eclipse.n4js.ts.types.TMember)65 EObject (org.eclipse.emf.ecore.EObject)19 TClassifier (org.eclipse.n4js.ts.types.TClassifier)13 Type (org.eclipse.n4js.ts.types.Type)13 ContainerType (org.eclipse.n4js.ts.types.ContainerType)11 ArrayList (java.util.ArrayList)10 TClass (org.eclipse.n4js.ts.types.TClass)10 TField (org.eclipse.n4js.ts.types.TField)10 TMethod (org.eclipse.n4js.ts.types.TMethod)9 TModule (org.eclipse.n4js.ts.types.TModule)9 MemberList (org.eclipse.n4js.ts.types.util.MemberList)9 RuleEnvironment (org.eclipse.xsemantics.runtime.RuleEnvironment)9 HashSet (java.util.HashSet)8 HashMap (java.util.HashMap)7 NameStaticPair (org.eclipse.n4js.ts.types.util.NameStaticPair)7 MemberCollector (org.eclipse.n4js.utils.ContainerTypesHelper.MemberCollector)7 Optional (java.util.Optional)6 ParameterizedPropertyAccessExpression (org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression)6 EcoreUtil2 (org.eclipse.xtext.EcoreUtil2)6 Inject (com.google.inject.Inject)5