Search in sources :

Example 6 with AbstractModule

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

the class PolyfillValidatorFragment method holdPolyfillName.

/**
 * Constraints (Polyfill Class) 156.2 polyfill name and module
 */
private boolean holdPolyfillName(PolyfillValidationState state) {
    if (!state.name.equals(state.filledType.getName())) {
        // (Polyfill Class) 156.2
        final String msg = getMessageForCLF_POLYFILL_DIFFERENT_NAME(state.name, keywordProvider.keyword(state.filledType), state.filledType.getName());
        addIssue(state, msg, CLF_POLYFILL_DIFFERENT_NAME);
        return false;
    }
    final boolean isGlobalFilled = GLOBAL.hasAnnotation(state.filledType);
    final boolean isGlobalPoly = GLOBAL.hasAnnotation(state.polyType);
    if (isGlobalFilled != isGlobalPoly) {
        // (Polyfill Class) 156.2
        final String msg = getMessageForCLF_POLYFILL_DIFFERENT_GLOBALS(state.name, isGlobalPoly ? "global" : "not global", isGlobalFilled ? "global" : "not global");
        addIssue(state, msg, CLF_POLYFILL_DIFFERENT_GLOBALS);
        return false;
    }
    if (!isGlobalFilled) {
        final AbstractModule polyModule = state.polyType.getContainingModule();
        final AbstractModule filledModule = state.filledType.getContainingModule();
        if (polyModule instanceof TModule && filledModule instanceof TModule) {
            // avoid consequential errors
            if (!polyModule.getModuleSpecifier().equals(filledModule.getModuleSpecifier())) {
                // (Polyfill Class)
                // 156.2
                final String msg = getMessageForCLF_POLYFILL_DIFFERENT_MODULE_SPECIFIER(state.name, polyModule.getModuleSpecifier(), filledModule.getModuleSpecifier());
                addIssue(state, msg, CLF_POLYFILL_DIFFERENT_MODULE_SPECIFIER);
                return false;
            }
        }
    }
    return true;
}
Also used : TModule(org.eclipse.n4js.ts.types.TModule) AbstractModule(org.eclipse.n4js.ts.types.AbstractModule)

Example 7 with AbstractModule

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

the class PolyfillValidatorFragment method holdsSameJavascriptVariant.

/**
 * Constraint 155 (static polyfill layout), no. 4
 */
private boolean holdsSameJavascriptVariant(PolyfillValidationState state) {
    final AbstractModule fillerModule = state.polyType.getContainingModule();
    final AbstractModule filledModule = state.filledType.getContainingModule();
    if (fillerModule instanceof TModule && filledModule instanceof TModule && ((TModule) fillerModule).isN4jsdModule() != ((TModule) filledModule).isN4jsdModule()) {
        final String fileExt = ((TModule) fillerModule).isN4jsdModule() ? N4JSGlobals.N4JSD_FILE_EXTENSION : N4JSGlobals.N4JS_FILE_EXTENSION;
        final String msg = getMessageForCLF_POLYFILL_STATIC_DIFFERENT_VARIANT(state.name, "." + fileExt);
        addIssue(state, msg, CLF_POLYFILL_STATIC_DIFFERENT_VARIANT);
        return false;
    }
    return true;
}
Also used : TModule(org.eclipse.n4js.ts.types.TModule) AbstractModule(org.eclipse.n4js.ts.types.AbstractModule)

Example 8 with AbstractModule

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

the class PolyfillValidatorFragment method holdsSinglePolyfillSource.

/**
 * Constraints 129 (Applying Polyfills) No member must be filled by more than one polyfill.
 */
private boolean holdsSinglePolyfillSource(PolyfillValidationState state) {
    EList<TMember> myPolyMember = state.polyType.getOwnedMembers();
    // a) find references to the filled type
    // b) check, that they are in the same Project
    // c) search for clashing contributions.
    XtextResource res = (XtextResource) state.polyType.eResource();
    IResourceDescriptions index = resourceDescriptionsProvider.getResourceDescriptions(res);
    // a+b) all polyfills to same calssifier in same project:
    IContainer container = containerManager.getContainer(res.getResourceServiceProvider().getResourceDescriptionManager().getResourceDescription(res), index);
    // Iterable over all exported Polyfills
    Iterable<IEObjectDescription> iterEObj = container.getExportedObjects(TypesPackage.Literals.TCLASSIFIER, PolyfillUtils.getNonStaticPolyfillFQN(state.filledType, qualifiedNameProvider), false);
    // collection of involved TModules for each Member.
    ListMultimap<TMember, TModule> clashProviders = LinkedListMultimap.create();
    for (IEObjectDescription pivotObjectDescription : iterEObj) {
        EObject eob = pivotObjectDescription.getEObjectOrProxy();
        // Resolve
        if (eob.eIsProxy()) {
            eob = EcoreUtil.resolve(eob, res);
            if (!eob.eIsProxy()) {
                Resource filledResource = eob.eResource();
                if (filledResource instanceof N4JSResource) {
                    ((N4JSResource) filledResource).performPostProcessing(state.cancelIndicator);
                }
            }
        }
        if (eob == state.polyType) {
            // saw myself .-.
            continue;
        }
        EList<TMember> pivotPolyMember = ((TClassifier) eob).getOwnedMembers();
        ListMultimap<TMember, TMember> clashing = findClashingMembersByName(myPolyMember, pivotPolyMember);
        for (TMember myMember : clashing.keySet()) {
            // only interested in the module, so first is sufficient
            AbstractModule module = clashing.get(myMember).get(0).getContainingModule();
            if (module instanceof TModule) {
                // declared modules never contain polyfills
                clashProviders.put(myMember, (TModule) module);
            }
        }
    }
    List<TMember> sortedMembers = new ArrayList<>(clashProviders.keySet());
    Collections.sort(sortedMembers, (m1, m2) -> m1.getName().compareTo(m2.getName()));
    for (TMember myMember : sortedMembers) {
        // Combine list of Modules involved in the polyfill clash.
        String uris = Stream.concat(Stream.of(myMember.getContainingModule()), clashProviders.get(myMember).stream()).map(u -> u.getQualifiedName().toString()).sorted().reduce("", (a, b) -> a + PREFIX_LIST + b);
        if (uris.startsWith(PREFIX_LIST))
            uris = uris.substring(PREFIX_LIST.length());
        int lastPrefix_idx = uris.lastIndexOf(PREFIX_LIST);
        if (lastPrefix_idx >= 0) {
            StringBuffer sb = new StringBuffer(uris);
            uris = sb.replace(lastPrefix_idx, lastPrefix_idx + PREFIX_LIST.length(), " and ").toString();
        }
        // give Qualified name filled in Property.
        String memberAxis = myMember.getContainingType().getName() + "." + myMember.getName();
        // Issue on filled Member-name declaration:
        String msg = IssueCodes.getMessageForCLF_POLYFILL_MULTIPOLYFILLS_MEMBER_CONFLICT(uris, memberAxis);
        state.host.addIssue(msg, myMember.getAstElement(), N4JSPackage.Literals.PROPERTY_NAME_OWNER__DECLARED_NAME, IssueCodes.CLF_POLYFILL_MULTIPOLYFILLS_MEMBER_CONFLICT);
    }
    return true;
}
Also used : TClassifier(org.eclipse.n4js.ts.types.TClassifier) Resource(org.eclipse.emf.ecore.resource.Resource) XtextResource(org.eclipse.xtext.resource.XtextResource) N4JSResource(org.eclipse.n4js.resource.N4JSResource) ArrayList(java.util.ArrayList) XtextResource(org.eclipse.xtext.resource.XtextResource) IEObjectDescription(org.eclipse.xtext.resource.IEObjectDescription) AbstractModule(org.eclipse.n4js.ts.types.AbstractModule) IResourceDescriptions(org.eclipse.xtext.resource.IResourceDescriptions) EObject(org.eclipse.emf.ecore.EObject) N4JSResource(org.eclipse.n4js.resource.N4JSResource) TMember(org.eclipse.n4js.ts.types.TMember) IContainer(org.eclipse.xtext.resource.IContainer) TModule(org.eclipse.n4js.ts.types.TModule)

Example 9 with AbstractModule

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

the class KeyUtils method getSpecKeyWithoutProjectFolder.

/**
 * @return a unique key for the given element. The source folder is not part of the key. Instead, only the module
 *         name is used.
 */
public static String getSpecKeyWithoutProjectFolder(RepoRelativePathHolder rrph, IdentifiableElement element) {
    if (element instanceof TMember) {
        ContainerType<?> containingType = ((TMember) element).getContainingType();
        String specKeyOfType = getSpecKeyWithoutProjectFolder(rrph, containingType);
        String specKey = specKeyOfType + "." + element.getName();
        return specKey;
    }
    AbstractModule module = element.getContainingModule();
    if (module == null) {
        return "GLOBAL.";
    } else {
        RepoRelativePath rrp = rrph.get(element);
        String elementName = nameFromElement(rrph, element);
        String key = getSpecKeyWithoutProjectFolder(rrp, elementName);
        return key;
    }
}
Also used : TMember(org.eclipse.n4js.ts.types.TMember) AbstractModule(org.eclipse.n4js.ts.types.AbstractModule)

Example 10 with AbstractModule

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

the class SpecInfosByName method createTypeSpecInfo.

void createTypeSpecInfo(Type type, RepoRelativePathHolder rrph) {
    SpecInfo typeInfo = new SpecInfo(type);
    String regionName = KeyUtils.getSpecKeyWithoutProjectFolder(rrph, type);
    specInfoByName.put(regionName, typeInfo);
    Collection<SpecInfo> identicalSpecInfo = specInfoByName.get(regionName);
    if (identicalSpecInfo.size() > 1) {
        SpecInfo polyfillAware = null;
        List<SpecInfo> polyfilling = new LinkedList<>();
        for (SpecInfo si : identicalSpecInfo) {
            Type moduleType = si.specElementRef.getElementAsType();
            if (moduleType != null) {
                AbstractModule typeModule = moduleType.getContainingModule();
                if (typeModule.isStaticPolyfillModule()) {
                    polyfilling.add(si);
                } else if (typeModule.isStaticPolyfillAware()) {
                    polyfillAware = si;
                }
            }
        }
        if (polyfillAware != null) {
            Type polyfillAwareType = polyfillAware.specElementRef.getElementAsType();
            for (SpecInfo si : polyfilling) {
                si.specElementRef.polyfillAware = polyfillAwareType;
            }
        }
    }
}
Also used : ContainerType(org.eclipse.n4js.ts.types.ContainerType) Type(org.eclipse.n4js.ts.types.Type) LinkedList(java.util.LinkedList) AbstractModule(org.eclipse.n4js.ts.types.AbstractModule)

Aggregations

AbstractModule (org.eclipse.n4js.ts.types.AbstractModule)15 TModule (org.eclipse.n4js.ts.types.TModule)5 TMember (org.eclipse.n4js.ts.types.TMember)4 ENotificationImpl (org.eclipse.emf.ecore.impl.ENotificationImpl)3 Resource (org.eclipse.emf.ecore.resource.Resource)3 LinkedHashSet (java.util.LinkedHashSet)2 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 URI (org.eclipse.emf.common.util.URI)1 EObject (org.eclipse.emf.ecore.EObject)1 XMIResource (org.eclipse.emf.ecore.xmi.XMIResource)1 XMLResource (org.eclipse.emf.ecore.xmi.XMLResource)1 RepoRelativePath (org.eclipse.n4js.jsdoc2spec.RepoRelativePath)1 ImportDeclaration (org.eclipse.n4js.n4JS.ImportDeclaration)1 NamedImportSpecifier (org.eclipse.n4js.n4JS.NamedImportSpecifier)1 NamespaceImportSpecifier (org.eclipse.n4js.n4JS.NamespaceImportSpecifier)1 Script (org.eclipse.n4js.n4JS.Script)1 ScriptElement (org.eclipse.n4js.n4JS.ScriptElement)1 N4JSResource (org.eclipse.n4js.resource.N4JSResource)1 ProjectComparisonEntry (org.eclipse.n4js.tooling.compare.ProjectComparisonEntry)1