Search in sources :

Example 6 with TSetter

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

the class ScriptApiTracker method _computeMissingApiGetterSetter.

/**
 * Internal algorithm.
 */
private List<AccessorTuple> _computeMissingApiGetterSetter(TN4Classifier declaration, List<AccessorTuple> concreteAccessorTuples, Predicate<ProjectComparisonEntry> filterPredicate, boolean recursive) {
    Optional<ProjectComparisonAdapter> optAdapt = firstProjectComparisonAdapter(declaration.eResource());
    if (optAdapt.isPresent()) {
        ProjectComparisonAdapter projectComparisonAdapter = optAdapt.get();
        ProjectComparisonEntry compareEntry = projectComparisonAdapter.getEntryFor(EcoreUtil2.getContainerOfType(declaration, TModule.class));
        ProjectComparisonEntry typeCompare = compareEntry.getChildForElementImpl(declaration);
        if (typeCompare == null) {
            return Collections.emptyList();
        }
        Predicate<ProjectComparisonEntry> filter = (pce -> (pce.getElementAPI() instanceof TGetter) || (pce.getElementAPI() instanceof TSetter));
        filter = filter.and(pce -> pce.getElementImpl()[0] == null).and(filterPredicate);
        ArrayList<ProjectComparisonEntry> collectedPCEofGetterOrSetter = new ArrayList<>();
        Function<TN4Classifier, Consumer<? super ProjectComparisonEntry>> actionProvider = pivot -> pce -> {
            // Get or Set ??
            collectedPCEofGetterOrSetter.add(pce);
        };
        // recursive Extension will generate a stream of compareEntries.
        if (recursive)
            interfaceApiSupertypeWalker(filter, actionProvider, projectComparisonAdapter, (TN4Classifier) typeCompare.getElementAPI(), TN4Classifier.class);
        // ----
        /*-
				Cases of the Implementation: A getter or setter can
				- be given as AST (x)
				- be missing (m)
				- were not required by API (/)
				So we have 3*3=9 cases:
				get set
				(x) (x) --> all fine, pair will be transpiled
				(x) (m) --> code for getter will be transpiled, need to inject virtual setter code into existing tuple.
				(x) (/) --> all fine, getter will be transpiled
				(m) (x) --> code for setter will be transpiled, need to inject virtual getter code into existing tuple.
				(m) (m) --> need to create virtual accessor tuple (similar to missing field) with setter & getter
				(m) (/) --> need to create virtual accessor tuple with getter only
				(/) (x) --> all fine
				(/) (m) --> need to create virtual accessor tuple with setter only
				(/) (/) --> all fine nothing to be done.
			 */
        List<ProjectComparisonEntry> getSetList;
        if (recursive)
            getSetList = collectedPCEofGetterOrSetter;
        else
            getSetList = typeCompare.allChildren().filter(pce -> (pce.getElementAPI() instanceof TGetter) || (pce.getElementAPI() instanceof TSetter)).filter(filterPredicate).collect(Collectors.toList());
        HashMap<Pair<String, Boolean>, GetSetGroup> hmName2getset = new HashMap<>();
        for (ProjectComparisonEntry pce : getSetList) {
            TMember apiAsMember = ((TMember) pce.getElementAPI());
            String name = apiAsMember.getName();
            boolean staticCase = apiAsMember.isStatic();
            Pair<String, Boolean> key = Pair.of(name, staticCase);
            GetSetGroup group = hmName2getset.get(key);
            if (group == null) {
                group = new GetSetGroup(name, staticCase);
                hmName2getset.put(key, group);
            }
            if (pce.getElementAPI() instanceof TGetter) {
                // case getter:
                TGetter apiGetter = (TGetter) pce.getElementAPI();
                if (pce.getElementImpl(0) != null) {
                    // case (x) for getter-
                    group.getterIsInAST = true;
                } else {
                    // case (m) for getter-
                    group.getterIsInAST = false;
                    group.getter = new VirtualApiTGetter(name, apiGetter);
                }
            } else if (pce.getElementAPI() instanceof TSetter) {
                // case setter:
                TSetter apiSetter = (TSetter) pce.getElementAPI();
                if (pce.getElementImpl(0) != null) {
                    // case (x) for setter -
                    group.setterIsInAST = true;
                } else {
                    // case (m) for setter:
                    group.setterIsInAST = false;
                    group.setter = new VirtualApiTSetter(name, apiSetter);
                }
            }
        }
        // go over the list of known AccessorTupels and enhance them by adding virtual things.
        for (AccessorTuple conAccTupel : concreteAccessorTuples) {
            GetSetGroup getset = hmName2getset.remove(Pair.of(conAccTupel.getName(), conAccTupel.isStatic()));
            if (getset != null) {
                // some missings found:
                if (getset.hasGetter() && !getset.getterIsInAST && // could be mixed in by interface-default-impl different
                conAccTupel.getGetter() == null) // to the intended API-path c.f. GHOLD-212
                {
                    conAccTupel.setGetter(getset.getter);
                }
                if (getset.hasSetter() && !getset.setterIsInAST && // could be mixed in by interface-default-impl different
                conAccTupel.getSetter() == null) // to the intended API-path c.f. GHOLD-212
                {
                    conAccTupel.setSetter(getset.setter);
                }
            }
        }
        // remaining entries in hmName2getset need to translated into VirtualApiAccessors.
        List<AccessorTuple> ret = new ArrayList<>();
        for (GetSetGroup getset : hmName2getset.values()) {
            VirtualApiAccessorTuple vAccessTupel = new VirtualApiAccessorTuple(getset.name, getset.staticCases);
            if (getset.getter != null)
                vAccessTupel.setGetter(getset.getter);
            if (getset.setter != null)
                vAccessTupel.setSetter(getset.setter);
            ret.add(vAccessTupel);
        }
        return ret;
    }
    return emptyList();
}
Also used : TSetter(org.eclipse.n4js.ts.types.TSetter) ProjectComparisonEntry(org.eclipse.n4js.compare.ProjectComparisonEntry) Inject(com.google.inject.Inject) TClass(org.eclipse.n4js.ts.types.TClass) ParameterizedTypeRef(org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef) TSetter(org.eclipse.n4js.ts.types.TSetter) Logger(org.apache.log4j.Logger) TGetterImpl(org.eclipse.n4js.ts.types.impl.TGetterImpl) TMethodImpl(org.eclipse.n4js.ts.types.impl.TMethodImpl) Type(org.eclipse.n4js.ts.types.Type) MemberList(org.eclipse.n4js.ts.types.util.MemberList) N4InterfaceDeclaration(org.eclipse.n4js.n4JS.N4InterfaceDeclaration) TFieldImpl(org.eclipse.n4js.ts.types.impl.TFieldImpl) LinkedHashMultimap(com.google.common.collect.LinkedHashMultimap) Collections.emptyList(java.util.Collections.emptyList) Predicate(java.util.function.Predicate) TField(org.eclipse.n4js.ts.types.TField) EObject(org.eclipse.emf.ecore.EObject) PROVIDES_DEFAULT_IMPLEMENTATION(org.eclipse.n4js.AnnotationDefinition.PROVIDES_DEFAULT_IMPLEMENTATION) PROVIDES_INITIALZER(org.eclipse.n4js.AnnotationDefinition.PROVIDES_INITIALZER) TMethod(org.eclipse.n4js.ts.types.TMethod) Collectors(java.util.stream.Collectors) TGetter(org.eclipse.n4js.ts.types.TGetter) List(java.util.List) Stream(java.util.stream.Stream) TClassifier(org.eclipse.n4js.ts.types.TClassifier) Resource(org.eclipse.emf.ecore.resource.Resource) Optional(java.util.Optional) Pair(org.eclipse.xtext.xbase.lib.Pair) TypesFactory(org.eclipse.n4js.ts.types.TypesFactory) Singleton(com.google.inject.Singleton) HashMap(java.util.HashMap) TypeUtils(org.eclipse.n4js.ts.utils.TypeUtils) AccessorTuple(org.eclipse.n4js.ts.types.util.AccessorTuple) Function(java.util.function.Function) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) TModule(org.eclipse.n4js.ts.types.TModule) TN4Classifier(org.eclipse.n4js.ts.types.TN4Classifier) TInterface(org.eclipse.n4js.ts.types.TInterface) ProjectCompareHelper(org.eclipse.n4js.compare.ProjectCompareHelper) EcoreUtil2(org.eclipse.xtext.EcoreUtil2) TAnnotableElement(org.eclipse.n4js.ts.types.TAnnotableElement) MemberCollector(org.eclipse.n4js.utils.ContainerTypesHelper.MemberCollector) LinkedHashSet(java.util.LinkedHashSet) Iterator(java.util.Iterator) TMember(org.eclipse.n4js.ts.types.TMember) Script(org.eclipse.n4js.n4JS.Script) Consumer(java.util.function.Consumer) TypesPackage(org.eclipse.n4js.ts.types.TypesPackage) AdapterImpl(org.eclipse.emf.common.notify.impl.AdapterImpl) TSetterImpl(org.eclipse.n4js.ts.types.impl.TSetterImpl) Collections(java.util.Collections) HashMap(java.util.HashMap) TGetter(org.eclipse.n4js.ts.types.TGetter) ArrayList(java.util.ArrayList) Consumer(java.util.function.Consumer) AccessorTuple(org.eclipse.n4js.ts.types.util.AccessorTuple) TModule(org.eclipse.n4js.ts.types.TModule) ProjectComparisonEntry(org.eclipse.n4js.compare.ProjectComparisonEntry) Pair(org.eclipse.xtext.xbase.lib.Pair) TN4Classifier(org.eclipse.n4js.ts.types.TN4Classifier) TMember(org.eclipse.n4js.ts.types.TMember)

Example 7 with TSetter

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

the class ComposedMemberInfo method handleFParameters.

private void handleFParameters(TMember member, RuleEnvironment G) {
    EList<TFormalParameter> fpars = null;
    if (member instanceof TMethod) {
        TMethod method = (TMethod) member;
        fpars = method.getFpars();
    }
    if (member instanceof TSetter) {
        TSetter setter = (TSetter) member;
        fpars = new BasicEList<>();
        fpars.add(setter.getFpar());
    }
    if (fpars != null) {
        for (int i = 0; i < fpars.size(); i++) {
            TFormalParameter fpar = fpars.get(i);
            if (fParameters.size() <= i) {
                fParameters.add(new ComposedFParInfo());
            }
            ComposedFParInfo fpAggr = fParameters.get(i);
            Pair<TFormalParameter, RuleEnvironment> fpPair = new Pair<>(fpar, G);
            fpAggr.fpSiblings.add(fpPair);
        }
    }
}
Also used : TFormalParameter(org.eclipse.n4js.ts.types.TFormalParameter) TSetter(org.eclipse.n4js.ts.types.TSetter) TMethod(org.eclipse.n4js.ts.types.TMethod) RuleEnvironment(org.eclipse.xsemantics.runtime.RuleEnvironment) Pair(org.eclipse.xtext.xbase.lib.Pair)

Example 8 with TSetter

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

the class ComposedMemberScope method createErrorPlaceholder.

/**
 * To avoid having to do all computation over and over in case no valid composed member can be built, we also create
 * a member in the error case as a placeholder.
 * <p>
 * Note: we need to be able to store error place holders and/or successfully composed members for read- and
 * write-access independently (i.e. we might have, for example, a valid composed member for read access but an error
 * placeholder for write access); therefore we have to use getters/setters for error place holders.
 */
private TMember createErrorPlaceholder(String memberName) {
    if (writeAccess) {
        final TSetter s = TypeUtils.createTSetter(memberName, null, TypeRefsFactory.eINSTANCE.createUnknownTypeRef());
        s.setComposed(true);
        return s;
    } else {
        final TGetter g = TypesFactory.eINSTANCE.createTGetter();
        g.setComposed(true);
        g.setName(memberName);
        g.setDeclaredTypeRef(TypeRefsFactory.eINSTANCE.createUnknownTypeRef());
        return g;
    }
}
Also used : TSetter(org.eclipse.n4js.ts.types.TSetter) TGetter(org.eclipse.n4js.ts.types.TGetter)

Example 9 with TSetter

use of org.eclipse.n4js.ts.types.TSetter 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 10 with TSetter

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

the class TypeUtils method setMemberTypeRef.

/**
 * Convenience method setting the type of the given member. Sets the return type in case of getters and methods and
 * the type of the single fpar in case of setters. If the setter does not have an fpar yet, it will be created.
 */
public static void setMemberTypeRef(TMember m, TypeRef typeRef) {
    typeRef = TypeUtils.copyIfContained(typeRef);
    if (m instanceof TField)
        ((TField) m).setTypeRef(typeRef);
    else if (m instanceof TGetter)
        ((TGetter) m).setDeclaredTypeRef(typeRef);
    else if (m instanceof TSetter) {
        final TSetter s = (TSetter) m;
        if (s.getFpar() == null)
            s.setFpar(TypesFactory.eINSTANCE.createTFormalParameter());
        s.getFpar().setTypeRef(typeRef);
    } else if (m instanceof TMethod)
        ((TMethod) m).setReturnTypeRef(typeRef);
    else if (m != null)
        throw new IllegalArgumentException("unknown sub-class of TMember: " + m.getClass().getName());
}
Also used : TSetter(org.eclipse.n4js.ts.types.TSetter) TMethod(org.eclipse.n4js.ts.types.TMethod) TField(org.eclipse.n4js.ts.types.TField) TGetter(org.eclipse.n4js.ts.types.TGetter)

Aggregations

TSetter (org.eclipse.n4js.ts.types.TSetter)12 TGetter (org.eclipse.n4js.ts.types.TGetter)7 TField (org.eclipse.n4js.ts.types.TField)6 TMethod (org.eclipse.n4js.ts.types.TMethod)4 AccessorTuple (org.eclipse.n4js.ts.types.util.AccessorTuple)4 TMember (org.eclipse.n4js.ts.types.TMember)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 EObject (org.eclipse.emf.ecore.EObject)2 TInterface (org.eclipse.n4js.ts.types.TInterface)2 NameStaticPair (org.eclipse.n4js.ts.types.util.NameStaticPair)2 Pair (org.eclipse.xtext.xbase.lib.Pair)2 LinkedHashMultimap (com.google.common.collect.LinkedHashMultimap)1 Inject (com.google.inject.Inject)1 Singleton (com.google.inject.Singleton)1 Collections (java.util.Collections)1 Collections.emptyList (java.util.Collections.emptyList)1 Iterator (java.util.Iterator)1 LinkedHashSet (java.util.LinkedHashSet)1