Search in sources :

Example 1 with AccessorTuple

use of org.eclipse.n4js.ts.types.util.AccessorTuple in project n4js by eclipse.

the class ConcreteMembersOrderedForTranspiler method create.

/**
 * Returns a tuple of collections used by transpiler to generate interface or class members.
 */
public static ConcreteMembersOrderedForTranspiler create(ContainerTypesHelper containerTypesHelper, TClassifier type, Script context) {
    MemberCollector collector = containerTypesHelper.fromContext(context);
    List<TMember> concreteInheritedMembers = (type instanceof TClass) ? collector.inheritedMembers((TClass) type) : emptyList();
    List<TMember> ownedAndMixedInConcreteMembers = collector.computeOwnedAndMixedInConcreteMembers(type);
    List<AccessorTuple> concreteAccessorTuples = getConcreteFieldAccessors(ownedAndMixedInConcreteMembers, concreteInheritedMembers);
    MemberList<TField> fieldsOverridingAccessors = getFieldsOverridingAccessor(ownedAndMixedInConcreteMembers, concreteInheritedMembers);
    // compute the list of mixed in fields, which do not override any Accessor (handled separately)
    MemberList<TField> fieldsPurelyMixedInNotOverridingAccessor = new MemberList<>();
    fieldsPurelyMixedInNotOverridingAccessor.addAll(ownedAndMixedInConcreteMembers.stream().filter(it -> it instanceof TField && // must stem from different type
    it.getContainingType() != type).map(it -> (TField) it).filter(// remove the ones overriding get/set
    it -> !fieldsOverridingAccessors.contains(it)).collect(Collectors.toList()));
    return new ConcreteMembersOrderedForTranspiler(concreteInheritedMembers, ownedAndMixedInConcreteMembers, concreteAccessorTuples, fieldsOverridingAccessors, fieldsPurelyMixedInNotOverridingAccessor);
}
Also used : Collections.emptyList(java.util.Collections.emptyList) TField(org.eclipse.n4js.ts.types.TField) Set(java.util.Set) TMember(org.eclipse.n4js.ts.types.TMember) HashMap(java.util.HashMap) Script(org.eclipse.n4js.n4JS.Script) TClass(org.eclipse.n4js.ts.types.TClass) AccessorTuple(org.eclipse.n4js.ts.types.util.AccessorTuple) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) TSetter(org.eclipse.n4js.ts.types.TSetter) NameStaticPair(org.eclipse.n4js.ts.types.util.NameStaticPair) HashSet(java.util.HashSet) TGetter(org.eclipse.n4js.ts.types.TGetter) List(java.util.List) ContainerTypesHelper(org.eclipse.n4js.utils.ContainerTypesHelper) TClassifier(org.eclipse.n4js.ts.types.TClassifier) TInterface(org.eclipse.n4js.ts.types.TInterface) Map(java.util.Map) MemberList(org.eclipse.n4js.ts.types.util.MemberList) MemberCollector(org.eclipse.n4js.utils.ContainerTypesHelper.MemberCollector) TField(org.eclipse.n4js.ts.types.TField) MemberList(org.eclipse.n4js.ts.types.util.MemberList) AccessorTuple(org.eclipse.n4js.ts.types.util.AccessorTuple) MemberCollector(org.eclipse.n4js.utils.ContainerTypesHelper.MemberCollector) TMember(org.eclipse.n4js.ts.types.TMember) TClass(org.eclipse.n4js.ts.types.TClass)

Example 2 with AccessorTuple

use of org.eclipse.n4js.ts.types.util.AccessorTuple in project n4js by eclipse.

the class ConcreteMembersOrderedForTranspiler method mapToAccessorTuples.

/**
 * Maps getters and setters to {@link AccessorTuple}s, used to generate proper setters-getters-pairs for property.
 * The passed maps may be changed!
 *
 * @param getters
 *            list of getters
 * @param fields
 *            list of fields
 * @param io_setters
 *            map with owned getters, this map may be changed by this method
 * @param io_inheritedGetters
 *            map with inherited getters, this map may be changed by this method
 * @param io_inheritedSetters
 *            map with inherited getters, this map may be changed by this method
 * @return list of accessor tuples.
 */
private static List<AccessorTuple> mapToAccessorTuples(Iterable<TGetter> getters, Map<NameStaticPair, TSetter> io_setters, Iterable<TField> fields, Map<NameStaticPair, TGetter> io_inheritedGetters, Map<NameStaticPair, TSetter> io_inheritedSetters) {
    List<AccessorTuple> tuples = new ArrayList<>();
    // add getters (alone & with corresponding setter)
    for (TGetter getter : getters) {
        AccessorTuple tuple = new AccessorTuple(getter.getName(), getter.isStatic());
        tuple.setGetter(getter);
        NameStaticPair nsp = NameStaticPair.of(getter);
        // do not handle the thing twice
        tuple.setSetter(io_setters.remove(nsp));
        if (tuple.getSetter() == null) {
            tuple.setInheritedSetter(io_inheritedSetters.remove(nsp));
        }
        tuples.add(tuple);
    }
    // add setters w/o getter:
    for (TSetter setter : io_setters.values()) {
        AccessorTuple tuple = new AccessorTuple(setter.getName(), setter.isStatic());
        NameStaticPair nsp = NameStaticPair.of(setter);
        tuple.setSetter(setter);
        tuple.setInheritedGetter(io_inheritedGetters.remove(nsp));
        tuples.add(tuple);
    }
    // remove the inherited references - the field will overwrite them.
    for (TField field : fields) {
        NameStaticPair nsp = NameStaticPair.of(field);
        io_inheritedSetters.remove(nsp);
        io_inheritedGetters.remove(nsp);
    }
    // find getters/setters defined in interfaces which need to be combined:
    for (TSetter inhSetter : io_inheritedSetters.values()) {
        TGetter inhGetter = io_inheritedGetters.remove(NameStaticPair.of(inhSetter));
        if (inhGetter != null && inhSetter.getContainingType() != inhGetter.getContainingType() && (inhSetter.getContainingType() instanceof TInterface || inhGetter.getContainingType() instanceof TInterface)) {
            // getter & setter are inherited from different types.
            AccessorTuple tuple = new AccessorTuple(inhSetter.getName(), inhSetter.isStatic());
            tuple.setInheritedGetter(inhGetter);
            tuple.setInheritedSetter(inhSetter);
            tuples.add(tuple);
        }
    }
    return tuples;
}
Also used : NameStaticPair(org.eclipse.n4js.ts.types.util.NameStaticPair) TSetter(org.eclipse.n4js.ts.types.TSetter) TField(org.eclipse.n4js.ts.types.TField) TInterface(org.eclipse.n4js.ts.types.TInterface) TGetter(org.eclipse.n4js.ts.types.TGetter) ArrayList(java.util.ArrayList) AccessorTuple(org.eclipse.n4js.ts.types.util.AccessorTuple)

Example 3 with AccessorTuple

use of org.eclipse.n4js.ts.types.util.AccessorTuple in project n4js by eclipse.

the class ConcreteMembersOrderedForTranspiler method getConcreteFieldAccessors.

/**
 * Helper method, returns all concrete field accessors as tuples of the given classifier, which may even contain
 * fields if they override concrete getters or setter. Since getter/setters can only be defined as pairs, in case of
 * single owned getter with inherited setter, a delegate is created for the setter (and vice versa).
 */
private static List<AccessorTuple> getConcreteFieldAccessors(List<TMember> ownedAndMixedInConcreteMember, List<TMember> concreteInheritedMembers) {
    Set<TField> ownedAndMixedInFields = new HashSet<>();
    Set<TGetter> ownedAndMixedInGetters = new HashSet<>();
    Map<NameStaticPair, TSetter> ownedAndMixedInSetters = new HashMap<>();
    for (TMember m : ownedAndMixedInConcreteMember) {
        if (m instanceof TField) {
            ownedAndMixedInFields.add((TField) m);
        } else if (m instanceof TGetter) {
            ownedAndMixedInGetters.add((TGetter) m);
        } else if (m instanceof TSetter) {
            ownedAndMixedInSetters.put(NameStaticPair.of(m), (TSetter) m);
        }
    }
    Map<NameStaticPair, TGetter> inheritedGetters = new HashMap<>();
    Map<NameStaticPair, TSetter> inheritedSetters = new HashMap<>();
    for (TMember m : concreteInheritedMembers) {
        if (m instanceof TGetter) {
            if (!ownedAndMixedInGetters.contains(m)) {
                inheritedGetters.put(NameStaticPair.of(m), (TGetter) m);
            }
        } else if (m instanceof TSetter) {
            NameStaticPair nsp = NameStaticPair.of(m);
            if (ownedAndMixedInSetters.get(nsp) != m) {
                inheritedSetters.put(nsp, (TSetter) m);
            }
        }
    }
    List<AccessorTuple> ownedOrMixedInAccessorTouples = mapToAccessorTuples(ownedAndMixedInGetters, ownedAndMixedInSetters, ownedAndMixedInFields, inheritedGetters, inheritedSetters);
    return ownedOrMixedInAccessorTouples;
}
Also used : NameStaticPair(org.eclipse.n4js.ts.types.util.NameStaticPair) TSetter(org.eclipse.n4js.ts.types.TSetter) TField(org.eclipse.n4js.ts.types.TField) HashMap(java.util.HashMap) TGetter(org.eclipse.n4js.ts.types.TGetter) AccessorTuple(org.eclipse.n4js.ts.types.util.AccessorTuple) TMember(org.eclipse.n4js.ts.types.TMember) HashSet(java.util.HashSet)

Example 4 with AccessorTuple

use of org.eclipse.n4js.ts.types.util.AccessorTuple in project n4js by eclipse.

the class ScriptApiTracker method computeMissingApiFields.

/**
 * Computes the list of virtual AccessorTuples for missing fields.
 *
 * @return List of {@link VirtualApiTField}
 */
private List<AccessorTuple> computeMissingApiFields(TClass declaration) {
    Optional<ProjectComparisonAdapter> optAdapt = firstProjectComparisonAdapter(declaration.eResource());
    if (optAdapt.isPresent()) {
        ProjectComparisonEntry compareEntry = optAdapt.get().getEntryFor(EcoreUtil2.getContainerOfType(declaration, TModule.class));
        ProjectComparisonEntry typeCompare = compareEntry.getChildForElementImpl(declaration);
        if (typeCompare != null) {
            return typeCompare.allChildren().filter(pce -> pce.getElementAPI() instanceof TField).filter(// only go for empty impl.
            pce -> pce.getElementImpl()[0] == null).map(pce -> {
                TField apiField = (TField) pce.getElementAPI();
                VirtualApiMissingFieldAccessorTuple ret = createVirtFieldAccessorTuple(apiField);
                return ret;
            }).collect(Collectors.toList());
        }
    }
    return emptyList();
}
Also used : 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) TField(org.eclipse.n4js.ts.types.TField) TModule(org.eclipse.n4js.ts.types.TModule) ProjectComparisonEntry(org.eclipse.n4js.compare.ProjectComparisonEntry)

Example 5 with AccessorTuple

use of org.eclipse.n4js.ts.types.util.AccessorTuple in project n4js by eclipse.

the class ScriptApiTracker method createVirtFieldAccessorTuple.

private VirtualApiMissingFieldAccessorTuple createVirtFieldAccessorTuple(TField apiField) {
    boolean statiC = apiField.isStatic();
    String name = apiField.getName();
    AccessorTuple copy = new AccessorTuple(name, statiC);
    TSetter tset = TypesFactory.eINSTANCE.createTSetter();
    tset.setName(name);
    tset.setDeclaredStatic(statiC);
    copy.setSetter(tset);
    TGetter tget = TypesFactory.eINSTANCE.createTGetter();
    tget.setName(name);
    tget.setDeclaredStatic(statiC);
    copy.setGetter(tget);
    VirtualApiMissingFieldAccessorTuple ret = new VirtualApiMissingFieldAccessorTuple(copy);
    ret.setGetter(new VirtualApiTGetter(name, tget));
    ret.setSetter(new VirtualApiTSetter(name, tset));
    return ret;
}
Also used : TSetter(org.eclipse.n4js.ts.types.TSetter) TGetter(org.eclipse.n4js.ts.types.TGetter) AccessorTuple(org.eclipse.n4js.ts.types.util.AccessorTuple)

Aggregations

TGetter (org.eclipse.n4js.ts.types.TGetter)8 TSetter (org.eclipse.n4js.ts.types.TSetter)8 AccessorTuple (org.eclipse.n4js.ts.types.util.AccessorTuple)8 TField (org.eclipse.n4js.ts.types.TField)7 ArrayList (java.util.ArrayList)6 TInterface (org.eclipse.n4js.ts.types.TInterface)6 TMember (org.eclipse.n4js.ts.types.TMember)6 HashMap (java.util.HashMap)5 HashSet (java.util.HashSet)5 List (java.util.List)5 Collectors (java.util.stream.Collectors)5 Script (org.eclipse.n4js.n4JS.Script)5 TClass (org.eclipse.n4js.ts.types.TClass)5 TClassifier (org.eclipse.n4js.ts.types.TClassifier)5 MemberList (org.eclipse.n4js.ts.types.util.MemberList)5 MemberCollector (org.eclipse.n4js.utils.ContainerTypesHelper.MemberCollector)5 Collections.emptyList (java.util.Collections.emptyList)4 Optional (java.util.Optional)4 Stream (java.util.stream.Stream)4 LinkedHashMultimap (com.google.common.collect.LinkedHashMultimap)3