Search in sources :

Example 46 with TMember

use of org.eclipse.n4js.ts.types.TMember in project n4js by eclipse.

the class StaticWriteAccessFilterScope method isAccepted.

@Override
protected boolean isAccepted(IEObjectDescription description) {
    EObject proxyOrInstance = description.getEObjectOrProxy();
    if (proxyOrInstance instanceof TMember && !proxyOrInstance.eIsProxy()) {
        TMember member = (TMember) proxyOrInstance;
        // this particular message to hide the better one.
        if (member.isStatic() && member.isWriteable() && /* i.e. (member.isField(), not const || member.isSetter()) */
        isWriteAccess()) {
            ContainerType<?> memberType = member.getContainingType();
            memberTypeName = memberType.getName();
            // Access only allowed for Direct access, so AST must be IdentifierRef.
            final boolean isTargetGivenByIdentifier = getTarget() instanceof IdentifierRef;
            if (!isTargetGivenByIdentifier) {
                // Not an IdentifierRef --> disallowed for write access.
                return false;
            }
            IdentifierRef idref = (IdentifierRef) getTarget();
            // this also covers aliased imports:
            if (idref.getId().getName().equals(memberTypeName)) {
                // correct name.
                return true;
            } else {
                // wrong name, disallowed
                // search for alias, for better error reporting.
                Script sc = EcoreUtil2.getContainerOfType(context, Script.class);
                Optional<NamedImportSpecifier> namedImport = sc.getScriptElements().stream().filter(se -> se instanceof ImportDeclaration).map(se -> (ImportDeclaration) se).flatMap(idecl -> {
                    return idecl.getImportSpecifiers().stream().filter(is -> is instanceof NamedImportSpecifier).map(is -> (NamedImportSpecifier) is);
                }).filter(s -> s.getImportedElement() == memberType).findFirst();
                if (namedImport.isPresent()) {
                    // if alias is present assign, otherwise null will be passed through
                    memberTypeAlias = namedImport.get().getAlias();
                }
                return false;
            }
        }
    }
    return true;
}
Also used : IndexedAccessExpression(org.eclipse.n4js.n4JS.IndexedAccessExpression) FilterWithErrorMarkerScope(org.eclipse.n4js.xtext.scoping.FilterWithErrorMarkerScope) IScope(org.eclipse.xtext.scoping.IScope) TMember(org.eclipse.n4js.ts.types.TMember) EObject(org.eclipse.emf.ecore.EObject) Script(org.eclipse.n4js.n4JS.Script) IEObjectDescriptionWithError(org.eclipse.n4js.xtext.scoping.IEObjectDescriptionWithError) NamedImportSpecifier(org.eclipse.n4js.n4JS.NamedImportSpecifier) ContainerType(org.eclipse.n4js.ts.types.ContainerType) ExpressionExtensions(org.eclipse.n4js.n4JS.extensions.ExpressionExtensions) ImportDeclaration(org.eclipse.n4js.n4JS.ImportDeclaration) ParameterizedPropertyAccessExpression(org.eclipse.n4js.n4JS.ParameterizedPropertyAccessExpression) EcoreUtil2(org.eclipse.xtext.EcoreUtil2) IdentifierRef(org.eclipse.n4js.n4JS.IdentifierRef) Optional(java.util.Optional) Expression(org.eclipse.n4js.n4JS.Expression) IEObjectDescription(org.eclipse.xtext.resource.IEObjectDescription) Script(org.eclipse.n4js.n4JS.Script) NamedImportSpecifier(org.eclipse.n4js.n4JS.NamedImportSpecifier) EObject(org.eclipse.emf.ecore.EObject) ImportDeclaration(org.eclipse.n4js.n4JS.ImportDeclaration) TMember(org.eclipse.n4js.ts.types.TMember) IdentifierRef(org.eclipse.n4js.n4JS.IdentifierRef)

Example 47 with TMember

use of org.eclipse.n4js.ts.types.TMember in project n4js by eclipse.

the class ComposedMemberInfo method initMemberAggregate.

// ///////////////////////// Init Methods ///////////////////////////
private synchronized void initMemberAggregate() {
    if (isInitialized)
        return;
    this.isSiblingMissing = siblings.contains(null);
    MemberType lastMType = null;
    for (Pair<TMember, RuleEnvironment> pair : siblings) {
        if (pair == null)
            continue;
        this.isEmpty = false;
        TMember member = pair.getKey();
        RuleEnvironment G = pair.getValue();
        lastMType = handleMemberTypes(lastMType, member);
        handleReadOnlyField(member);
        handleAccessibility(member);
        handleTypeRefLists(member, G);
        handleFParameters(member, G);
    }
    // init: fParameters
    List<TypeRef> currVariadicAccumulated = new LinkedList<>();
    for (ComposedFParInfo fpAggr : fParameters) {
        initFParAggregate(fpAggr);
        // handle: typeRefsVariadicAccumulated
        currVariadicAccumulated.addAll(fpAggr.typeRefsVariadic);
        fpAggr.typeRefsVariadicAccumulated.addAll(currVariadicAccumulated);
    }
    handleIsVariadicButLastFParIsDifferent();
    handleValidationProblems();
    this.isInitialized = true;
}
Also used : MemberType(org.eclipse.n4js.ts.types.MemberType) TypeRef(org.eclipse.n4js.ts.typeRefs.TypeRef) UnknownTypeRef(org.eclipse.n4js.ts.typeRefs.UnknownTypeRef) RuleEnvironment(org.eclipse.xsemantics.runtime.RuleEnvironment) TMember(org.eclipse.n4js.ts.types.TMember) LinkedList(java.util.LinkedList)

Example 48 with TMember

use of org.eclipse.n4js.ts.types.TMember in project n4js by eclipse.

the class ComposedMemberScope method createComposedMember.

/**
 * Key method of entire scoping for composed types e.g. union/intersection types. This creates a new TMember as a
 * combination of all members of the given name in the type's contained types. If those members cannot be combined
 * into a single valid member, this method creates a dummy placeholder.
 */
private TMember createComposedMember(String memberName) {
    // check all subScopes for a member of the given name and
    // merge the properties of the existing members into 'composedMember'
    final Resource resource = EcoreUtilN4.getResource(request.context, composedTypeRef);
    ComposedMemberInfoBuilder cmiBuilder = new ComposedMemberInfoBuilder();
    cmiBuilder.init(writeAccess, resource, ts);
    for (int idx = 0; idx < subScopes.length; idx++) {
        final IScope subScope = subScopes[idx];
        final TypeRef typeRef = composedTypeRef.getTypeRefs().get(idx);
        final Resource res = EcoreUtilN4.getResource(request.context, composedTypeRef);
        final RuleEnvironment GwithSubstitutions = ts.createRuleEnvironmentForContext(typeRef, res);
        final TMember member = findMemberInSubScope(subScope, memberName);
        cmiBuilder.addMember(member, GwithSubstitutions);
    }
    // produce result
    ComposedMemberInfo cmi = cmiBuilder.get();
    ComposedMemberFactory cmf = getComposedMemberFactory(cmi);
    if (!cmf.isEmpty()) {
        // at least one of the subScopes had an element of that name
        final TMember result;
        if (cmf.isValid()) {
            // success case: The element for that name can be merged into a valid composed member
            result = cmf.create(memberName);
        } else {
            // some of the subScopes do not have an element for that name OR
            // they do not form a valid composed member (e.g. they are of different kind)
            // -> produce a specific error message explaining the incompatibility
            // (this error placeholder will be wrapped with a UncommonMemberDescription
            // in #getSingleLocalElementByName(QualifiedName) above)
            result = createErrorPlaceholder(memberName);
        }
        // add composed member to ComposedTypeRef's cache (without notifications to avoid cache-clear)
        final ComposedMemberCache cache = getOrCreateComposedMemberCache();
        if (cache != null) {
            EcoreUtilN4.doWithDeliver(false, () -> {
                cache.getCachedComposedMembers().add(result);
            }, cache);
        }
        // if cache==null: simply do not cache the composed member (i.e. member won't be contained in a resource!)
        return result;
    } else {
        // -> produce the ordinary "Cannot resolve reference ..." error by returning 'null'
        return null;
    }
}
Also used : TypeRef(org.eclipse.n4js.ts.typeRefs.TypeRef) UnknownTypeRef(org.eclipse.n4js.ts.typeRefs.UnknownTypeRef) ComposedTypeRef(org.eclipse.n4js.ts.typeRefs.ComposedTypeRef) N4JSResource(org.eclipse.n4js.resource.N4JSResource) Resource(org.eclipse.emf.ecore.resource.Resource) IScope(org.eclipse.xtext.scoping.IScope) RuleEnvironment(org.eclipse.xsemantics.runtime.RuleEnvironment) ComposedMemberCache(org.eclipse.n4js.ts.types.ComposedMemberCache) TMember(org.eclipse.n4js.ts.types.TMember)

Example 49 with TMember

use of org.eclipse.n4js.ts.types.TMember in project n4js by eclipse.

the class AbstractMemberScope method getSingleLocalElementByName.

@Override
protected IEObjectDescription getSingleLocalElementByName(QualifiedName name) {
    if (name.getSegmentCount() != 1) {
        return null;
    }
    final String nameAsString = name.getFirstSegment();
    // both read/write required
    if (ExpressionExtensions.isBothReadFromAndWrittenTo(context)) {
        TMember reader = findMember(nameAsString, false, staticAccess);
        TMember writer = findMember(nameAsString, true, staticAccess);
        if (null == reader && null == writer) {
            // will be caught as error "Could not resolve reference"
            return null;
        }
        if (null == reader) {
            return new UnsatisfiedRWAccessDescription(EObjectDescription.create(writer.getName(), writer), true);
        }
        if (null == writer) {
            return new UnsatisfiedRWAccessDescription(EObjectDescription.create(reader.getName(), reader), false);
        }
        // pick arbitrarily the setter
        return createSingleElementDescription(writer);
    }
    // either read or write requirement that moreover is satisfied
    final boolean accessForWriteOperation = ExpressionExtensions.isLeftHandSide(context);
    TMember existingMember = findMember(nameAsString, accessForWriteOperation, staticAccess);
    if (existingMember != null) {
        return createSingleElementDescription(existingMember);
    }
    // wrong read/write
    existingMember = findMember(nameAsString, !accessForWriteOperation, staticAccess);
    if (existingMember != null) {
        // allowed special case: writing in the ctor to a final field that lacks init value
        final boolean isAssOfFinalInCtor = N4JSASTUtils.isSemiLegalAssignmentToFinalFieldInCtor(context.eContainer(), existingMember);
        final boolean isLegalAssOfFinalInCtor = isAssOfFinalInCtor && !((TField) existingMember).isHasExpression();
        if (isLegalAssOfFinalInCtor) {
            return createSingleElementDescription(existingMember);
        }
        // allowed special case: wrong read/write in a mode other than N4JS
        if (jsVariantHelper.allowWrongReadWrite(context)) {
            // cf. sec. 13.1
            return createSingleElementDescription(existingMember);
        }
        return new WrongWriteAccessDescription(EObjectDescription.create(existingMember.getName(), existingMember), accessForWriteOperation, isAssOfFinalInCtor);
    }
    // wrong static / non-static
    existingMember = findMember(nameAsString, accessForWriteOperation, !staticAccess);
    if (existingMember == null) {
        // if both read/write access and static access are wrong, we want to
        // complain (only) about "wrong static access" -> so include this case here
        existingMember = findMember(nameAsString, !accessForWriteOperation, !staticAccess);
    }
    if (existingMember != null) {
        return new WrongStaticAccessDescription(EObjectDescription.create(existingMember.getName(), existingMember), staticAccess);
    }
    return null;
}
Also used : WrongWriteAccessDescription(org.eclipse.n4js.scoping.utils.WrongWriteAccessDescription) TField(org.eclipse.n4js.ts.types.TField) TMember(org.eclipse.n4js.ts.types.TMember) WrongStaticAccessDescription(org.eclipse.n4js.scoping.utils.WrongStaticAccessDescription) UnsatisfiedRWAccessDescription(org.eclipse.n4js.scoping.utils.UnsatisfiedRWAccessDescription)

Example 50 with TMember

use of org.eclipse.n4js.ts.types.TMember in project n4js by eclipse.

the class AbstractMemberScope method getLocalElementsByEObject.

@Override
protected Iterable<IEObjectDescription> getLocalElementsByEObject(EObject object, URI uri) {
    if (object instanceof TMember) {
        final TMember tMember = (TMember) object;
        final String name = tMember.getName();
        final TMember existing = findMember(name, tMember.isWriteable(), staticAccess);
        if (existing == object) {
            return Collections.singletonList(EObjectDescription.create(existing.getName(), existing));
        }
    }
    return Collections.emptyList();
}
Also used : 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