/******************************************************************************* * Copyright (c) 2010 Martin Schnabel <mb0@mb0.org>. * 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.axdt.as3.scoping; import static com.google.common.collect.Lists.newArrayList; import java.util.List; import org.eclipse.emf.ecore.EClass; import org.eclipse.xtext.naming.QualifiedName; import org.eclipse.xtext.resource.IEObjectDescription; import org.eclipse.xtext.resource.ISelectable; import org.eclipse.xtext.resource.impl.AliasedEObjectDescription; import org.eclipse.xtext.scoping.IScope; import org.eclipse.xtext.scoping.impl.ImportNormalizer; import org.eclipse.xtext.scoping.impl.ImportScope; import com.google.common.collect.HashMultimap; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; public class As3ImportScope extends ImportScope { protected List<ImportNormalizer> normalizers; protected final EClass type; public As3ImportScope(List<ImportNormalizer> namespaceResolvers, IScope parent, ISelectable importFrom, EClass type, boolean ignoreCase) { super(namespaceResolvers, parent, importFrom, type, ignoreCase); this.type = type; } @Override protected List<ImportNormalizer> removeDuplicates( List<ImportNormalizer> namespaceResolvers) { normalizers = super.removeDuplicates(namespaceResolvers); return normalizers; } @Override protected Iterable<IEObjectDescription> getLocalElementsByName(QualifiedName name) { List<IEObjectDescription> result = newArrayList(); ImportNormalizer foundForNormalizer = null; ISelectable importFrom = getImportFrom(); for (ImportNormalizer normalizer : normalizers) { final QualifiedName resolvedName = normalizer.resolve(name); if (resolvedName != null) { Iterable<IEObjectDescription> resolvedElements = importFrom.getExportedObjects(type, resolvedName, isIgnoreCase()); for (IEObjectDescription resolvedElement : resolvedElements) { if (foundForNormalizer == null) foundForNormalizer = normalizer; QualifiedName alias = normalizer.deresolve(resolvedElement.getName()); if (alias == null) throw new IllegalStateException("Couldn't deresolve " + resolvedElement.getName() + " with import " + normalizer); final AliasedEObjectDescription aliasedEObjectDescription = new AliasedEObjectDescription(alias, resolvedElement); result.add(aliasedEObjectDescription); } } } return result; } @Override protected Iterable<IEObjectDescription> getAliasedElements(Iterable<IEObjectDescription> candidates) { Multimap<QualifiedName, IEObjectDescription> keyToDescription = LinkedHashMultimap.create(); Multimap<QualifiedName, ImportNormalizer> keyToNormalizer = HashMultimap.create(); for (IEObjectDescription imported : candidates) { QualifiedName fullyQualifiedName = imported.getName(); for (ImportNormalizer normalizer : normalizers) { QualifiedName alias = normalizer.deresolve(fullyQualifiedName); // XXX: dont use relative namespaces if (alias != null && alias.getSegmentCount() == 1) { QualifiedName key = alias; if (isIgnoreCase()) { key = key.toLowerCase(); } keyToDescription.put(key, new AliasedEObjectDescription(alias, imported)); keyToNormalizer.put(key, normalizer); } } } for (QualifiedName name : keyToNormalizer.keySet()) { if (keyToNormalizer.get(name).size() > 1) keyToDescription.removeAll(name); } return keyToDescription.values(); } protected boolean isShadowed(IEObjectDescription input) { QualifiedName name = input.getName(); int count = name.getSegmentCount(); if (count < 1 || count > 1) return false; return getLocalElementsByName(name).iterator().hasNext(); } }