@SuppressWarnings("javadoc") @Test public void testLoadingBuiltInTypes() { BuiltInTypeScope scope = BuiltInTypeScope.get(resourceSet); IEObjectDescription anyType = scope.getSingleElement(QualifiedName.create("any")); Assert.assertNotNull(anyType); String s = ""; for (Resource resource : resourceSet.getResources()) { if (resource.getErrors().size() > 0) { for (Diagnostic d : resource.getErrors()) { s += "\n " + d.getMessage() + " at " + resource.getURI() + ":" + d.getLine(); } } } Assert.assertEquals("Resources definine built-in types must have no error." , "", s); }
@Override protected IEObjectDescription getCheckedDescription(String name, TMember member) { IEObjectDescription description = EObjectDescription.create(member.getName(), member); QualifiedName qn = QualifiedName.create(name); for (IScope currSubScope : subScopes) { IEObjectDescription subDescription = currSubScope.getSingleElement(qn); boolean descrWithError = subDescription == null || subDescription instanceof IEObjectDescriptionWithError; if (descrWithError) { return createComposedMemberDescriptionWithErrors(description); } } return description; }
@Override public boolean apply(String nameWithPosition) { String name = getNameFromNameWithPosition(nameWithPosition); String position = getPositionFromNameWithPosition(nameWithPosition); QualifiedName qualifiedName = converter.toQualifiedName(name); IEObjectDescription desc = scope.getSingleElement(qualifiedName); if (desc != null && !(desc instanceof IEObjectDescriptionWithError) && !(desc instanceof UnresolvableObjectDescription)) { if (!Strings.isNullOrEmpty(position)) { String nameWithPositionOfScopeELement = descriptionToNameWithPosition(currentURI, withLineNumber, desc); String positionOfScopeElement = getPositionFromNameWithPosition(nameWithPositionOfScopeELement); if (position.equals(positionOfScopeElement)) { return true; } } else { return true; } } return false; }
@Override @SuppressWarnings({ "rawtypes", "unchecked", "static-access" }) protected Comparator getItemsComparator() { return Ordering.natural().nullsLast().from(new Comparator() { @Override public int compare(final Object o1, final Object o2) { if (o1 instanceof IEObjectDescription && o2 instanceof IEObjectDescription) { final IEObjectDescription d1 = (IEObjectDescription) o1; final IEObjectDescription d2 = (IEObjectDescription) o2; final QualifiedName fqn1 = d1.getQualifiedName(); final QualifiedName fqn2 = d2.getQualifiedName(); if (null != fqn1 && null != fqn2) { return nullToEmpty(fqn1.getLastSegment()).compareToIgnoreCase( nullToEmpty(fqn2.getLastSegment())); } } return Objects.hashCode(o1) - Objects.hashCode(o2); } }); }
public ArrayList<IEObjectDescription> getTypes(final Extension ext) { ArrayList<IEObjectDescription> _xblockexpression = null; { ArrayList<IEObjectDescription> res = new ArrayList<IEObjectDescription>(); EList<DataType> _types = ext.getTypes(); for (final DataType k : _types) { res.add(EObjectDescription.create(QualifiedName.create(k.getName()), k)); } EList<Extension> _import = ext.getImport(); for (final Extension importExtension : _import) { EList<DataType> _types_1 = importExtension.getTypes(); for (final DataType k_1 : _types_1) { res.add(EObjectDescription.create(QualifiedName.create(importExtension.getName(), k_1.getName()), k_1)); } } _xblockexpression = res; } return _xblockexpression; }
/** Creates a new named import of 'name' from 'module' */ private ImportDeclaration createNamedImport(String name, IN4JSProject contextProject, TExportableElement te, Adapter nodelessMarker) { TModule tmodule = te.getContainingModule(); IN4JSProject targetProject = core.findProject(te.eResource().getURI()).orNull(); String moduleQN; if (targetProject != null && tmodule.getQualifiedName().toString().equals(targetProject.getMainModule())) { // If the project has a main module, use project import instead. moduleQN = targetProject.getProjectId(); } else { // Standard case moduleQN = te.getContainingModule().getQualifiedName(); } QualifiedName qn = qualifiedNameConverter.toQualifiedName(moduleQN); String firstSegment = qn.getFirstSegment(); IN4JSProject project = ImportSpecifierUtil.getDependencyWithID(firstSegment, contextProject); return createImportDeclaration(qn, name, project, nodelessMarker, this::addNamedImport); }
/** Creates a new default import with name 'name' from object description. */ private ImportDeclaration createNamespaceImport(String name, IN4JSProject contextProject, TExportableElement te, Adapter nodelessMarker) { String moduleQN = te.getContainingModule().getQualifiedName(); QualifiedName qn = qualifiedNameConverter.toQualifiedName(moduleQN); String firstSegment = qn.getFirstSegment(); IN4JSProject project = ImportSpecifierUtil.getDependencyWithID(firstSegment, contextProject); if (project == null) { IN4JSProject projectByNamespace = ImportSpecifierUtil.getDependencyWithID(name, contextProject); IN4JSProject projectByEObject = core.findProject(te.eResource().getURI()).orNull(); if (projectByNamespace != null && projectByEObject != null && projectByNamespace.getLocation() == projectByEObject.getLocation()) project = projectByNamespace; } return createImportDeclaration(qn, name, project, nodelessMarker, this::addNamespaceImport); }
@Override public Iterable<IEObjectDescription> getElements(QualifiedName name) { switch (computeImportType(name, this.contextProject)) { case PROJECT_IMPORT: final String firstSegment = name.getFirstSegment(); final IN4JSProject targetProject = findProject(firstSegment, contextProject); return getElementsWithDesiredProjectID(ImportSpecifierUtil.getMainModuleOfProject(targetProject), name.getFirstSegment()); case COMPLETE_IMPORT: return getElementsWithDesiredProjectID(name.skipFirst(1), name.getFirstSegment()); case SIMPLE_IMPORT: return parent.getElements(name); default: return Collections.emptyList(); } }
/** * Returns description for given element, name is assumed to consist of a single segment containing the simple name * of the member. If no subScope contains a member with given name, null is returned. In other error cases (no or * wrong access, mixed types etc.), {@link IEObjectDescriptionWithError}, and in particular * {@link UnionMemberDescriptionWithError}, will be returned. */ @Override protected IEObjectDescription getSingleLocalElementByName(QualifiedName qualifiedName) { String name = qualifiedName.getLastSegment(); TMember member = getOrCreateComposedMember(name); if (member == null) { // no such member, no need for "merging" descriptions, there won't be any return null; } if (isErrorPlaceholder(member)) { return createComposedMemberDescriptionWithErrors(EObjectDescription.create(member.getName(), member)); } IEObjectDescription description = getCheckedDescription(name, member); return description; }
/** * Update _entryPointModelElement with pretty name */ private void updateMainElementName(){ try { Resource model = getModel(); EObject mainElement = null; if(model != null){ mainElement = model.getEObject(_entryPointModelElementText.getText()); } if(mainElement != null){ org.eclipse.xtext.naming.DefaultDeclarativeQualifiedNameProvider nameprovider = new DefaultDeclarativeQualifiedNameProvider(); QualifiedName qname = nameprovider.getFullyQualifiedName(mainElement); String objectName = qname != null ? qname.toString(): mainElement.toString(); String prettyName = objectName+ " : "+mainElement.eClass().getName(); _entryPointModelElementLabel.setText(prettyName); } } catch (Exception e) { } }
/** * Add the necessary text edits to the accumulating result. Optionally return the offset of the alias. */ private AliasLocation toTextEdit(QualifiedName qualifiedName, String optionalAlias, int insertionOffset, MultiTextEdit result) { QualifiedName moduleName = qualifiedName.skipLast(1); // the following code for enhancing existing ImportDeclarations makes use of the Xtext serializer, which is not // yet compatible with fragments in Xtext grammars (as of Xtext 2.9.1) -> deactivated for now // @formatter:off // String moduleNameAsString = unquoted(syntacticModuleName(moduleName)); // for (ImportDeclaration existing : existingImports) { // String importedModuleName = existing.getModule().getQualifiedName(); // if (moduleNameAsString.equals(importedModuleName)) { // return enhanceExistingImportDeclaration(existing, qualifiedName, optionalAlias, result); // } // } // @formatter:on return addNewImportDeclaration(moduleName, qualifiedName, optionalAlias, insertionOffset, result); }
@SuppressWarnings("unchecked") @Override protected void registerDescription(final IResourceDescription description, final Map<QualifiedName, Object> target) { for (final IEObjectDescription object : description.getExportedObjects()) { final QualifiedName lowerCase = object.getName().toLowerCase(); final Object existing = target.put(lowerCase, description); if (existing != null && existing != description) { Set<IResourceDescription> set = null; if (existing instanceof IResourceDescription) { // The linked hash set is the difference comparing to the super class. set = Sets.newLinkedHashSetWithExpectedSize(2); set.add((IResourceDescription) existing); } else { set = (Set<IResourceDescription>) existing; } set.add(description); target.put(lowerCase, set); } } }
private List<Type> getPolyfillTypesFromScope(QualifiedName fqn) { IScope contextScope = polyfillScopeAccess.getRecordingPolyfillScope(contextResource); List<Type> types = new ArrayList<>(); // contextScope.getElements(fqn) returns all polyfills, since shadowing is handled differently // for them! for (IEObjectDescription descr : contextScope.getElements(fqn)) { Type polyfillType = (Type) descr.getEObjectOrProxy(); if (polyfillType.eIsProxy()) { // TODO review: this seems odd... is this a test setup problem (since we do not use the // index // there and load the resource separately)? polyfillType = (Type) EcoreUtil.resolve(polyfillType, contextResource); if (polyfillType.eIsProxy()) { throw new IllegalStateException("unexpected proxy"); } } types.add(polyfillType); } // } return types; }
/** * Returns true if the given container type is a polyfill of the bottom type. * <p> * Note: we compare via FQN here, since the bottom type may not stem from the index but from the type model * derived from the AST. In that case, the type instance, although similar, differs from the type instance * from the index. */ private boolean isDirectPolyfill(ContainerType<?> containerType) { if (!containerType.isStaticPolyfill() || !(bottomType instanceof TClassifier)) { return false; } QualifiedName qn = N4TSQualifiedNameProvider.getStaticPolyfillFQN((TClassifier) bottomType, qualifiedNameProvider); if (containerType instanceof TClass) { // short cut return qn.equals(qualifiedNameProvider.getFullyQualifiedName(containerType)); } if (containerType instanceof TN4Classifier) { return Iterables.any(((TN4Classifier) containerType).getSuperClassifierRefs(), ref -> qn.equals(qualifiedNameProvider.getFullyQualifiedName(ref.getDeclaredType()))); } return false; }
/** * @see IN4JSSourceContainer#findArtifact(QualifiedName, Optional) */ public URI findArtifact(IN4JSSourceContainer sourceContainer, QualifiedName name, Optional<String> fileExtension) { final String ext = fileExtension.or("").trim(); final String extWithDot = !ext.isEmpty() && !ext.startsWith(".") ? "." + ext : ext; final String pathStr = name.toString("/") + extWithDot; // no need for IQualifiedNameConverter here! if (sourceContainer.isLibrary()) { return null; // TODO support for finding artifacts in libraries } else { URI artifactLocation = workspace.findArtifactInFolder(sourceContainer.getLocation(), pathStr); if (null == artifactLocation) { artifactLocation = externalLibraryWorkspace.findArtifactInFolder(sourceContainer.getLocation(), pathStr); } return artifactLocation; } }
@Override protected void buildMap(Resource resource, Map<QualifiedName, IEObjectDescription> elements) { IDefaultResourceDescriptionStrategy strategy = ((XtextResource) resource).getResourceServiceProvider() .get(IDefaultResourceDescriptionStrategy.class); TreeIterator<EObject> allProperContents = EcoreUtil.getAllProperContents(resource, false); IAcceptor<IEObjectDescription> acceptor = new IAcceptor<IEObjectDescription>() { @Override public void accept(IEObjectDescription description) { elements.put(description.getQualifiedName(), description); } }; while (allProperContents.hasNext()) { EObject content = allProperContents.next(); if (!strategy.createEObjectDescriptions(content, acceptor)) { allProperContents.prune(); } } }
@Override public IEObjectDescription getSingleElement(QualifiedName name) { IEObjectDescription result = null; for (IScope currScope : childScopes) { final IEObjectDescription currResult = currScope.getSingleElement(name); if (currResult != null) { if (!(currResult instanceof IEObjectDescriptionWithError)) { return currResult; // no error, use scope order as precedence (first one wins) and return } if (result == null) { result = currResult; // with error, maybe we find something w/o error in following scope, do not // return yet } } } return result; // return null or (first) description with error }
@Override protected IEObjectDescription getCheckedDescription(String name, TMember member) { IEObjectDescription description = EObjectDescription.create(member.getName(), member); QualifiedName qn = QualifiedName.create(name); boolean allDescrWithError = true; for (IScope currSubScope : subScopes) { IEObjectDescription subDescription = currSubScope.getSingleElement(qn); boolean descrWithError = subDescription == null || subDescription instanceof IEObjectDescriptionWithError; allDescrWithError &= descrWithError; } if (allDescrWithError) { return createComposedMemberDescriptionWithErrors(description); } return description; }
/***/ public static boolean indexContainsElement(final String fileUri, final String eObjectName) { IResourceDescriptions descriptions = getBuilderState(); URI uri = URI.createURI("platform:/resource" + fileUri); IResourceDescription description = descriptions.getResourceDescription(uri); if (description != null) { return description .getExportedObjects(EcorePackage.Literals.EOBJECT, QualifiedName.create(eObjectName), false) .iterator().hasNext(); } return false; }
@SuppressWarnings("javadoc") @Test public void testResolveSuperTypeOfBuiltInType() { BuiltInTypeScope scope = BuiltInTypeScope.get(resourceSet); IEObjectDescription intDescription = scope.getSingleElement(QualifiedName.create("i18nKey")); // trigger loading PrimitiveType intType = (PrimitiveType) intDescription.getEObjectOrProxy(); PrimitiveType assCompatType = intType.getAssignmentCompatible(); Assert.assertFalse(assCompatType.eIsProxy()); Assert.assertEquals("string", assCompatType.getName()); }
@SuppressWarnings("javadoc") @Test public void testResolveAllBuiltInTypes() { BuiltInTypeScope scope = BuiltInTypeScope.get(resourceSet); scope.getSingleElement(QualifiedName.create("any")); // trigger loading Assert.assertEquals(5, resourceSet.getResources().size()); EcoreUtil.resolveAll(resourceSet); Assert.assertEquals(5, resourceSet.getResources().size()); Map<EObject, Collection<Setting>> unresolvedProxies = EcoreUtil.UnresolvedProxyCrossReferencer .find(resourceSet); Assert.assertTrue(unresolvedProxies.toString(), unresolvedProxies.isEmpty()); }
/** * Positive tests */ @Test public void test() { String[] actual = SpecTestInfo.parseName(QualifiedName.create(input)); for (int i = 0; i < 3; i++) { Assert.assertEquals(ARGNAME[i] + " failed", expected[i], actual[i]); } }
@Override protected boolean initMessageAndCode(List<String> missingFrom, MapOfIndexes<String> indexesPerMemberType, QualifiedName name, boolean readOnlyField, IEObjectDescription[] descriptions, MapOfIndexes<String> indexesPerCode) { return initMemberTypeConflict(indexesPerMemberType) || initSubMessages(descriptions, indexesPerCode) || initDefault(); }
/** WARNING: fqnProvider may be <code>null</code>, but then the lower/greater info will be unreliable! */ /* package */ static int compare(IQualifiedNameProvider fqnProvider, Type t1, Type t2) { if (t1 == t2) { return 0; } if (t1 == null) { return -1; } if (t2 == null) { return 1; } if (fqnProvider != null) { // standard behavior relying on a fqnProvider final QualifiedName name1 = fqnProvider.getFullyQualifiedName(t1); final QualifiedName name2 = fqnProvider.getFullyQualifiedName(t2); if (name1 == null && name2 == null) { // since we know t1!=null && t2!=null, this means t1 and t2 are types without a FQN (i.e. for which // fqnProvider returns null), e.g. type variables, and since we know t1!=t2 (from above) we must // report a difference here! return 1; } if (name1 == null) { return -1; } if (name2 == null) { return 1; } return name1.compareTo(name2); } else { // fall-back behavior if fqnProvider not available return 1; // note: we already know t1!=t2 } }
@Override public QualifiedName getFullyQualifiedName(EObject obj) { String name = SimpleAttributeResolver.NAME_RESOLVER.apply(obj); if (name == null || name.length() == 0) return null; return converter.toQualifiedName(name); }
/** * Returns the matching (internal) name of the polyfill matching the given classifier. There are no polyfills of * polyfills, so the returned name is independent from the polyfill flag of the given classifier. */ public static QualifiedName getPolyfillFQN(TClassifier tClassifier, IQualifiedNameProvider qualifiedNameProvider) { QualifiedName prefix = qualifiedNameProvider.getFullyQualifiedName(EcoreUtil.getRootContainer(tClassifier)); if ("n4ts".equals(tClassifier.eResource().getURI().fileExtension())) { // } instanceof TObjectPrototype) { prefix = append(prefix, GLOBAL_NAMESPACE_SEGMENT); // TODO this has to be removed, instead, also n4ts files should use "#" as global namespace segment } prefix = append(prefix, POLYFILL_SEGMENT); return append(prefix, tClassifier.getName()); }
@Override public Iterable<IEObjectDescription> getElements(QualifiedName name) { Iterable<IEObjectDescription> parent = super.getElements(name); return Iterables.transform(parent, new Function<IEObjectDescription, IEObjectDescription>() { @Override public IEObjectDescription apply(IEObjectDescription input) { return resolve(input); } }); }
/** * Null-safe appending of segments. If segment is null, null is returned. If prefix is null, a new qualified name * (with non-null segment) is created. */ protected static QualifiedName append(QualifiedName prefix, String segment) { if (segment == null) { return null; } if (prefix == null) { return QualifiedName.create(segment); } return prefix.append(segment); }
/** * Prefixing a qualified name. If the prefix segment is null, the suffix is returned, else if the suffix is null a * QN with only one segment is returned. Otherwise segment gets prefixed to suffix. */ protected static QualifiedName prepend(String segment, QualifiedName suffix) { if (segment == null) { return suffix; } QualifiedName qn = QualifiedName.create(segment); if (suffix != null) { qn = qn.append(suffix); } return qn; }
/** * Returns true if the given name describes a polyfill, that is if it's second last segment matches * {@link #POLYFILL_SEGMENT}. */ public static boolean isPolyfill(QualifiedName name) { if (name == null || name.getSegmentCount() < 2) { return false; } // as long as Module-polyfill is not enforced, we check for presence and then adapt: int polyModuleOffest = isModulePolyfill(name) ? 1 : 0; return POLYFILL_SEGMENT.equals(name.getSegment(name.getSegmentCount() - (2 + polyModuleOffest))); }
/** * Return corresponding FQN for staticPolyfill (prefixed with !MPOLY * * @param name * non-filled name * @return fqn of filling, not present if name itself denotes a static polyfill or is null. */ public static Optional<QualifiedName> toStaticPolyfillFQN(QualifiedName name) { if (name != null && name.getSegmentCount() > 0 && !MODULE_POLYFILL_SEGMENT.equals(name.getSegment(0))) { return Optional.of(prepend(MODULE_POLYFILL_SEGMENT, name)); } else return Optional.empty(); }
@Override public String getDimensionLabel(Dimension<?> dimension) { return dimensionToLabel.computeIfAbsent(dimension, d -> { EObject container = dimension.eContainer(); final String modelElement; if (container != null) { Object originalObject; if (container instanceof GenericTracedObject) { originalObject = ((GenericTracedObject) container).getOriginalObject(); } else { originalObject = getOriginalObject(container); } if (originalObject != null) { final QualifiedName fqn = nameProvider.getFullyQualifiedName((EObject) originalObject); modelElement = fqn == null ? "" : fqn.getLastSegment() + "."; } else { modelElement = ""; } } else { modelElement = ""; } final String result; if (dimension instanceof GenericDimension) { result = ((GenericDimension) dimension).getDynamicProperty().getName(); } else { final String dimensionName = dimension.eClass().getName(); final String tmp = dimensionName.substring(0, dimensionName.indexOf("_Dimension")); result = tmp.substring(tmp.lastIndexOf("_") + 1); } return modelElement + result; }); }
@Override protected Iterable<IEObjectDescription> getLocalElementsByName(QualifiedName name) { if (elements == null) { elements = createElements(); } IEObjectDescription result = null; if (isIgnoreCase()) { result = elements.get(name.toLowerCase()); } else { result = elements.get(name); } if (result == null) return Collections.emptyList(); return Collections.singleton(result); }
/** * Returns a reference to the instance with the given qualified name. * * @return an optional reference. */ protected <T extends EObject> T getEObjectOrProxy(QualifiedName qn) { IEObjectDescription description = getSingleElement(qn); if (description == null) throw new IllegalStateException(qn + " is not contained in this scope"); @SuppressWarnings("unchecked") T result = (T) description.getEObjectOrProxy(); return result; }
@Override protected boolean initMessageAndCode(List<String> missingFrom, MapOfIndexes<String> indexesPerMemberType, QualifiedName name, boolean readOnlyField, IEObjectDescription[] descriptions, MapOfIndexes<String> indexesPerCode) { return initMissingFrom(missingFrom) || initDifferentMemberTypes(indexesPerMemberType, name, readOnlyField) || initSubMessages(descriptions, indexesPerCode) || initDefault(); }
@Override public boolean matchItem(final Object item) { if (item instanceof IEObjectDescription) { final QualifiedName fqn = ((IEObjectDescription) item).getQualifiedName(); if (null != fqn) { return matches(fqn.getLastSegment()) || matches(fqn.toString()); } } return false; }
@Override public boolean matchItem(final Object item) { if (item instanceof IEObjectDescription) { final QualifiedName fqn = ((IEObjectDescription) item).getQualifiedName(); if (null != fqn) { return matches(fqn.getLastSegment()); } } return false; }
@Override public boolean apply(IEObjectDescription candidate) { QualifiedName qualifiedName = candidate.getQualifiedName(); // Don't propose any erroneous descriptions. return !AbstractDescriptionWithError.isErrorDescription_XTEND_MVN_BUG_HACK(candidate) && !N4TSQualifiedNameProvider.GLOBAL_NAMESPACE_SEGMENT.equals(qualifiedName.getFirstSegment()) && !N4TSQualifiedNameProvider.isModulePolyfill(qualifiedName) && !N4TSQualifiedNameProvider.isPolyfill(qualifiedName); }
private boolean initialize() { if (message == null) { IEObjectDescription[] descriptions = new IEObjectDescription[subScopes.length]; MapOfIndexes<String> indexesPerMemberType = new MapOfIndexes<>(); // use string here, since EnumLiteral is // not a TMember! MapOfIndexes<String> indexesPerCode = new MapOfIndexes<>(); List<String> missingFrom = new ArrayList<>(); final QualifiedName name = getName(); boolean readOnlyField = false; for (int i = 0; i < max; i++) { IEObjectDescription description = subScopes[i].getSingleElement(name); if (description != null) { descriptions[i] = description; EObject eobj = description.getEObjectOrProxy(); String type = getMemberTypeName(eobj); indexesPerMemberType.add(type, i); if (description instanceof IEObjectDescriptionWithError) { String subCode = ((IEObjectDescriptionWithError) description).getIssueCode(); indexesPerCode.add(subCode, i); } if ("field".equals(type)) { readOnlyField |= !((TField) eobj).isWriteable(); } } else { missingFrom.add(getNameForSubScope(i)); } } return initMessageAndCode(missingFrom, indexesPerMemberType, name, readOnlyField, descriptions, indexesPerCode); } return false; }