org.eclipse.xtext.scoping.impl.MapBasedScope Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2010 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.xtext.scoping.impl;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import com.google.common.collect.Iterables;
/**
* A scope implemented using a {@link Map} used for efficient lookup of ordinary named
* {@link org.eclipse.xtext.resource.EObjectDescription EObjectDescriptions}.
*
* This implementation assumes, that the keys of the {@link Map} correspond to the keys of the contained {@link org.eclipse.xtext.resource.EObjectDescription}.
* Additionally it assumes, that those keys are equal to description.getName().toLowerCase()
.
*
* When looking up elements using {@link #getElements(QualifiedName)} this implementation looks up the the elements from the map, hence are much
* more efficient for many {@link IEObjectDescription}s.
*
* @author Sven Efftinge - Initial contribution and API
* @author Sebastian Zarnekow
*/
public class MapBasedScope extends AbstractScope {
public static IScope createScope(IScope parent, Iterable descriptions, boolean ignoreCase) {
Map map = null;
for(IEObjectDescription description: descriptions) {
if (map == null)
map = new LinkedHashMap(4);
QualifiedName name = ignoreCase ? description.getName().toLowerCase() : description.getName();
IEObjectDescription previous = map.put(name, description);
// we are optimistic that no duplicate names are used
// however, if the name was already used, the first one should win
if (previous != null) {
map.put(name, previous);
}
}
if (map == null || map.isEmpty()) {
return parent;
}
return new MapBasedScope(parent, map, ignoreCase);
}
/**
* @since 2.3
*/
public static IScope createScope(IScope parent, Collection descriptions) {
if (descriptions.size() == 1) {
IEObjectDescription description = Iterables.getOnlyElement(descriptions);
return new MapBasedScope(parent, Collections.singletonMap(description.getName(), description), false);
} else if (descriptions.isEmpty()) {
return parent;
}
return createScope(parent, descriptions, false);
}
public static IScope createScope(IScope parent, Iterable descriptions) {
return createScope(parent, descriptions, false);
}
private Map elements;
protected MapBasedScope(IScope parent, Map elements, boolean ignoreCase) {
super(parent, ignoreCase);
this.elements = elements;
}
@Override
protected Iterable getAllLocalElements() {
return elements.values();
}
@Override
protected Iterable getLocalElementsByName(QualifiedName name) {
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);
}
@Override
protected boolean isShadowed(IEObjectDescription fromParent) {
if (isIgnoreCase()) {
boolean result = elements.containsKey(fromParent.getName().toLowerCase());
return result;
} else {
boolean result = elements.containsKey(fromParent.getName());
return result;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy