/*******************************************************************************
* Copyright (c) 2015 CWI
* 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:
*
* * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI
*******************************************************************************/
package org.rascalmpl.value.impl;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.rascalmpl.value.IAnnotatable;
import org.rascalmpl.value.IConstructor;
import org.rascalmpl.value.IList;
import org.rascalmpl.value.IValue;
import org.rascalmpl.value.IWithKeywordParameters;
import org.rascalmpl.value.exceptions.FactTypeUseException;
import org.rascalmpl.value.io.StandardTextWriter;
import org.rascalmpl.value.type.Type;
import org.rascalmpl.value.type.TypeStore;
import org.rascalmpl.value.visitors.IValueVisitor;
import io.usethesource.capsule.ImmutableMap;
public class ConstructorWithKeywordParametersFacade implements IConstructor {
protected final IConstructor content;
protected final ImmutableMap<String, IValue> parameters;
public ConstructorWithKeywordParametersFacade(final IConstructor content, final ImmutableMap<String, IValue> parameters) {
this.content = content;
this.parameters = parameters;
}
public Type getType() {
return content.getType();
}
public <T, E extends Throwable> T accept(IValueVisitor<T, E> v) throws E {
return v.visitConstructor(this);
}
public IValue get(int i) throws IndexOutOfBoundsException {
return content.get(i);
}
public IConstructor set(int i, IValue newChild) throws IndexOutOfBoundsException {
IConstructor newContent = content.set(i, newChild);
return new ConstructorWithKeywordParametersFacade(newContent, parameters); // TODO: introduce wrap() here as well
}
public int arity() {
return content.arity();
}
public String toString() {
return StandardTextWriter.valueToString(this);
}
public String getName() {
return content.getName();
}
public Iterable<IValue> getChildren() {
return content.getChildren();
}
public Iterator<IValue> iterator() {
return content.iterator();
}
public IConstructor replace(int first, int second, int end, IList repl)
throws FactTypeUseException, IndexOutOfBoundsException {
throw new UnsupportedOperationException("Replace not supported on constructor.");
}
public boolean equals(Object o) {
if(o == this) return true;
if(o == null) return false;
if(o.getClass() == getClass()){
ConstructorWithKeywordParametersFacade other = (ConstructorWithKeywordParametersFacade) o;
return content.equals(other.content) &&
parameters.equals(other.parameters);
}
return false;
}
@Override
public boolean isEqual(IValue other) {
if (!(other instanceof ConstructorWithKeywordParametersFacade)) {
if (other instanceof IConstructor) {
IConstructor oc = ((IConstructor)other);
if (content.isEqual(oc) && oc.mayHaveKeywordParameters()) {
IWithKeywordParameters<? extends IConstructor> ocw = oc.asWithKeywordParameters();
return ocw.getParameters().equals(parameters);
}
else {
return false;
}
}
else {
return false;
}
}
// TODO: the equals here should be isEqual
ConstructorWithKeywordParametersFacade o = (ConstructorWithKeywordParametersFacade) other;
return content.isEqual(o.content) && o.parameters.equals(parameters);
}
@Override
public int hashCode() {
return 131 + 3 * content.hashCode() + 101 * parameters.hashCode();
}
@Override
public boolean isAnnotatable() {
return false;
}
@Override
public IAnnotatable<? extends IConstructor> asAnnotatable() {
throw new UnsupportedOperationException("can not annotate a constructor which already has keyword parameters");
}
@Override
public boolean mayHaveKeywordParameters() {
return true;
}
@Override
public IWithKeywordParameters<? extends IConstructor> asWithKeywordParameters() {
return new AbstractDefaultWithKeywordParameters<IConstructor>(content, parameters) {
@Override
protected IConstructor wrap(IConstructor content, ImmutableMap<String, IValue> parameters) {
return new ConstructorWithKeywordParametersFacade(content, parameters);
}
@Override
public boolean hasParameters() {
return parameters != null && parameters.size() > 0;
}
@Override
public Set<String> getParameterNames() {
return parameters.keySet();
}
@Override
public Map<String, IValue> getParameters() {
return Collections.unmodifiableMap(parameters);
}
};
}
@Override
public Type getConstructorType() {
return content.getConstructorType();
}
@Override
public Type getUninstantiatedConstructorType() {
return content.getUninstantiatedConstructorType();
}
@Override
public IValue get(String label) {
return content.get(label);
}
@Override
public IConstructor set(String label, IValue newChild) throws FactTypeUseException {
return new ConstructorWithKeywordParametersFacade(content.set(label, newChild), parameters);
}
@Override
public boolean has(String label) {
return content.has(label);
}
@Override
public Type getChildrenTypes() {
return content.getChildrenTypes();
}
@Override
public boolean declaresAnnotation(TypeStore store, String label) {
return content.declaresAnnotation(store, label);
}
}