/**
* Copyright (c) 2011 Cloudsmith Inc. and other contributors, as listed below.
* 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
*
* Contributors:
* Cloudsmith
*
*/
package org.cloudsmith.geppetto.pp.dsl.adapters;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
/**
* The PPImportedNamesAdapter is used to record information about:
* <ul>
* <li>"imported" (x-referenced) names that have been searched in order to find a resolution.</li>
* <li>a set of resolutions (i.e. IEObjectDescriptions) that have been used to resolve an x-reference</li>
* <li>a set of unresolved names</li>
* </ul>
*
* @TODO: consider changing the name of this class as it handls more that just "imported names".
*/
public class PPImportedNamesAdapter extends AdapterImpl {
public static class Location {
private int line;
private int offset;
private int length;
Location(int line, int offset, int length) {
this.line = line;
this.offset = offset;
this.length = length;
}
/**
* @return the length
*/
public int getLength() {
return length;
}
/**
* @return the line
*/
public int getLine() {
return line;
}
/**
* @return the offset
*/
public int getOffset() {
return offset;
}
}
private final static List<QualifiedName> EMPTY = Collections.emptyList();
private final static Set<IEObjectDescription> EMPTY_DESCSET = Collections.emptySet();
private final static Set<QualifiedName> EMPTY_NAMESET = Collections.emptySet();
private final static Map<QualifiedName, List<Location>> EMPTY_UNRESOLVED = Collections.emptyMap();
Map<QualifiedName, List<Location>> unresolvedNames;
List<QualifiedName> importedNames;
Set<IEObjectDescription> resolvedDescriptions;
Set<IEObjectDescription> ambigousDescriptions;
/**
* Adds the given name to the set of searched names (names that influence the resolution).
*
* @param name
*/
public void add(QualifiedName name) {
synchronized(this) {
if(importedNames == null)
importedNames = Lists.newArrayList();
}
importedNames.add(name);
}
/**
* Adds a collection of ambiguous references to the set of x-references found to be ambiguous.
*
* @param ambiguities
*/
public void addAmbiguous(Collection<IEObjectDescription> ambiguities) {
synchronized(this) {
if(ambigousDescriptions == null)
ambigousDescriptions = Sets.newHashSet();
}
ambigousDescriptions.addAll(ambiguities);
}
/**
* Adds a single ambiguity to the set of x-references found to be ambiguous.
*
* @param ambiguities
*/
public void addAmbiguous(IEObjectDescription ambiguity) {
addAmbiguous(Sets.newHashSet(ambiguity));
}
/**
* Adds a collection of resolutions to the set of resolved x-references.
*
* @param resolved
*/
public void addResolved(Collection<IEObjectDescription> resolved) {
synchronized(this) {
if(resolvedDescriptions == null)
resolvedDescriptions = Sets.newHashSet();
}
resolvedDescriptions.addAll(resolved);
}
/**
* Adds a single resolution to the set of resolved x-references.
*
* @param desc
*/
public void addResolved(IEObjectDescription desc) {
addResolved(Sets.newHashSet(desc));
}
/**
* Adds a single name to the set of unresolved names.
*
* @param name
*/
public void addUnresolved(QualifiedName name, int line, int offset, int length) {
synchronized(this) {
if(unresolvedNames == null)
unresolvedNames = Maps.newHashMap(); // Sets.newHashSet();
if(unresolvedNames.get(name) == null)
unresolvedNames.put(name, Lists.<Location> newArrayList());
}
unresolvedNames.get(name).add(new Location(line, offset, length));
}
// /**
// * Adds a collection of names to the set of unresolved names.
// *
// * @param unresolved
// */
// private void addxUnresolved(Collection<QualifiedName> unresolved) {
// synchronized(this) {
// if(unresolvedNames == null)
// unresolvedNames = Maps.newHashMap(); // Sets.newHashSet();
// }
// unresolvedNames.addAll(unresolved);
// }
public void clear() {
importedNames = null;
unresolvedNames = null;
resolvedDescriptions = null;
}
/**
* @return the ambiguous IEObjectDescriptions or an empty Collection if there are no ambiguous x-references.
*/
public Collection<IEObjectDescription> getAmbiguousDescriptions() {
return Collections.unmodifiableSet(ambigousDescriptions != null
? ambigousDescriptions
: EMPTY_DESCSET);
}
/**
* @return the imported QualifiedNames or an empty list if there are no imported names.
*/
public List<QualifiedName> getNames() {
return Collections.unmodifiableList(importedNames != null
? importedNames
: EMPTY);
}
/**
* @return the resolved IEObjectDescriptions or an empty Collection if there are no resolved x-references.
*/
public Collection<IEObjectDescription> getResolvedDescriptions() {
return Collections.unmodifiableSet(resolvedDescriptions != null
? resolvedDescriptions
: EMPTY_DESCSET);
}
/**
* Returns all unresolved information in an unmodifiable map. The keys are the qualified name
* of an unresolved element, and there is one or more Locations describing where the qualified name
* is found in the resource.
*
* @return
*/
public Map<QualifiedName, List<Location>> getUnresolved() {
return unresolvedNames == null
? EMPTY_UNRESOLVED
: Collections.unmodifiableMap(unresolvedNames);
}
/**
* @return the unresolved names or an empty Collection if there are no unresolved x-references.
*/
public Collection<QualifiedName> getUnresolvedNames() {
return Collections.unmodifiableSet(unresolvedNames != null
? unresolvedNames.keySet()
: EMPTY_NAMESET);
}
@Override
public boolean isAdapterForType(Object type) {
return type == PPImportedNamesAdapter.class;
}
}