package org.jetbrains.ether.dependencyView;
import org.jetbrains.ether.RW;
import org.objectweb.asm.Type;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* Created by IntelliJ IDEA.
* User: db
* Date: 01.02.11
* Time: 5:03
* To change this template use File | Settings | File Templates.
*/
public class MethodRepr extends ProtoMember {
private static TypeRepr.AbstractType[] dummyAbstractType = new TypeRepr.AbstractType[0];
public final TypeRepr.AbstractType[] argumentTypes;
public final Set<TypeRepr.AbstractType> exceptions;
public abstract class Diff extends Difference {
public abstract Specifier<TypeRepr.AbstractType> exceptions();
public abstract boolean defaultAdded ();
public abstract boolean defaultRemoved ();
}
@Override
public Difference difference(final Proto past) {
final Difference diff = super.difference(past);
final Difference.Specifier<TypeRepr.AbstractType> excs = Difference.make(((MethodRepr) past).exceptions, exceptions);
return new Diff() {
@Override
public int addedModifiers() {
return diff.addedModifiers();
}
@Override
public int removedModifiers() {
return diff.removedModifiers();
}
@Override
public boolean no() {
return base() == NONE && !defaultAdded() && !defaultRemoved() && excs.unchanged();
}
@Override
public boolean defaultAdded() {
return hasValue() && !((MethodRepr) past).hasValue();
}
@Override
public boolean defaultRemoved() {
return !hasValue() && ((MethodRepr) past).hasValue();
}
@Override
public Specifier<TypeRepr.AbstractType> exceptions() {
return excs;
}
@Override
public int base() {
return diff.base();
}
@Override
public boolean packageLocalOn() {
return diff.packageLocalOn();
}
};
}
public void updateClassUsages(final Set<UsageRepr.Usage> s) {
type.updateClassUsages(s);
for (int i = 0; i < argumentTypes.length; i++) {
argumentTypes[i].updateClassUsages(s);
}
if (exceptions != null)
for (TypeRepr.AbstractType typ : exceptions) {
typ.updateClassUsages(s);
}
}
public MethodRepr(final int a, final String n, final String s, final String d, final String[] e, final Object value) {
super(a, s, StringCache.get(n), TypeRepr.getType(Type.getReturnType(d)), value);
exceptions = (Set<TypeRepr.AbstractType>) TypeRepr.createClassType(e, new HashSet<TypeRepr.AbstractType>());
argumentTypes = TypeRepr.getType(Type.getArgumentTypes(d));
}
public MethodRepr(final BufferedReader r) {
super(r);
argumentTypes = RW.readMany(r, TypeRepr.reader, new ArrayList<TypeRepr.AbstractType>()).toArray(dummyAbstractType);
exceptions = (Set<TypeRepr.AbstractType>) RW.readMany(r, TypeRepr.reader, new HashSet<TypeRepr.AbstractType>());
}
public void write(final BufferedWriter w) {
super.write(w);
RW.writeln(w, argumentTypes, TypeRepr.fromAbstractType);
RW.writeln(w, exceptions);
}
public static RW.Reader<MethodRepr> reader = new RW.Reader<MethodRepr>() {
public MethodRepr read(final BufferedReader r) {
return new MethodRepr(r);
}
};
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final MethodRepr that = (MethodRepr) o;
return name .equals(that.name ) &&
type .equals(that.type) &&
Arrays.equals(argumentTypes, that.argumentTypes);
}
@Override
public int hashCode() {
return 31 * (31 * Arrays.hashCode(argumentTypes) + type.hashCode()) + name.hashCode();
}
public UsageRepr.Usage createUsage (final StringCache.S owner) {
final StringBuilder buf = new StringBuilder();
buf.append("(");
for (TypeRepr.AbstractType t : argumentTypes) {
buf.append(t.getDescr());
}
buf.append(")");
buf.append(type.getDescr());
return UsageRepr.createMethodUsage(name.value, owner.value, buf.toString());
}
}