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;
}
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;
}
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;
}
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;
}
}
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;
}
}
}
}
Aggregations