/******************************************************************************* * Copyright (c) 2013 itemis AG (http://www.itemis.eu) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.eclipse.emf.ecore.xcore.scoping.types; import java.util.List; import org.eclipse.xtext.common.types.JvmDeclaredType; import org.eclipse.xtext.common.types.JvmType; import org.eclipse.xtext.common.types.xtext.AbstractTypeScope; import org.eclipse.xtext.naming.QualifiedName; import org.eclipse.xtext.resource.EObjectDescription; import org.eclipse.xtext.resource.IEObjectDescription; import org.eclipse.xtext.scoping.impl.ImportNormalizer; import org.eclipse.xtext.util.Strings; import com.google.common.collect.Iterables; public class TypeScopeWithWildcardImports extends AbstractXcoreScope { private final ImportNormalizer[][] imports; private final AbstractTypeScope typeScope; private final AbstractXcoreScope parent; public TypeScopeWithWildcardImports(ImportNormalizer[][] imports, AbstractTypeScope typeScope) { this.imports = imports; this.typeScope = typeScope; this.parent = null; } public TypeScopeWithWildcardImports(List<ImportNormalizer> imports, AbstractTypeScope typeScope, AbstractXcoreScope parent) { this.imports = new ImportNormalizer[][] { imports.toArray(new ImportNormalizer[imports.size()]) }; this.typeScope = typeScope; this.parent = parent; } @Override public IEObjectDescription getSingleElement(QualifiedName name) { for (int i = 0; i < imports.length; i++) { ImportNormalizer[] chunk = imports[i]; IEObjectDescription result = null; for (int j = 0; j < chunk.length; j++) { ImportNormalizer normalizer = chunk[j]; QualifiedName resolvedName = normalizer.resolve(name); if (resolvedName != null) { IEObjectDescription candidate = typeScope.getSingleElement(resolvedName, true); if (candidate != null) { if (result == null) { result = candidate; } else { return null; } } } } if (result != null) { return result; } } return getSingleElementFromParent(name); } protected IEObjectDescription getSingleElementFromParent(QualifiedName name) { return parent != null ? parent.getSingleElement(name) : typeScope.getSingleElement(name); } @Override protected void doGetElements(JvmType type, List<IEObjectDescription> result) { if (type instanceof JvmDeclaredType) { JvmDeclaredType declaredType = (JvmDeclaredType) type; String packageName = declaredType.getPackageName(); if (!Strings.isEmpty(packageName)) { int packageNameEnd = packageName.length() + 1; QualifiedName qualifiedPackageName = QualifiedName.create(Strings.split(packageName, '.')); int qualifiedPackageNameSegmentCount = qualifiedPackageName.getSegmentCount(); QualifiedName withDot = null; String withDollar = null; for (int i = 0; i < imports.length; i++) { ImportNormalizer[] chunk = imports[i]; for (int j = 0; j < chunk.length; j++) { ImportNormalizer normalizer = chunk[j]; QualifiedName namespacePrefix = normalizer.getImportedNamespacePrefix(); if (namespacePrefix.equals(qualifiedPackageName)) { if (withDot == null) { withDot = QualifiedName.create(Strings.split(type.getQualifiedName('.'), '.')); withDollar = type.eContainer() instanceof JvmType ? type.getQualifiedName('$').substring(packageNameEnd) : null; } result.add(EObjectDescription.create(withDot.skipFirst(qualifiedPackageNameSegmentCount), type)); if (withDollar != null) { result.add(EObjectDescription.create(withDollar, type)); } } } } } if (parent != null) { parent.doGetElements(type, result); } else { Iterables.addAll(result, typeScope.getElements(type)); } } } }