blob: af375f3d702e21c5a4919710be33d243f56e3642 [file] [log] [blame]
package xdc.services.spec;
public class Cat {
static Session ses;
static Unit unit;
String code;
int ptrCnt = 0;
protected Cat( String code, int ptrCnt )
{
this.code = code;
this.ptrCnt = ptrCnt;
}
interface Indexed {
Cat mkBaseCat();
}
interface Obj {
Cat mkMbrCat( String id );
}
static void bindUnit( Unit unit )
{
Cat.unit = unit;
Cat.ses = unit.getSession();
}
String code() { return "?"; }
public String getCode()
{
String res = "";
for (int i = 0; i < this.ptrCnt; i++) {
res += "*";
}
return res + code();
}
public int getPtrCnt() { return this.ptrCnt; }
// Cat.Arr
public static class Arr extends Cat implements Indexed
{
private Arr( String code, int ptrCnt ) { super(code, ptrCnt); }
String code() { return "A!" + this.code; };
public Cat mkBaseCat() { return Cat.fromCode(this.code); }
}
// Cat.Fxn
public static class Fxn extends Cat
{
private Decl.Fxn fxnDecl;
private Fxn( String code, int ptrCnt ) { this(code, ptrCnt, null); }
private Fxn( String code, int ptrCnt, Decl.Fxn fxnDecl )
{
super(code, ptrCnt);
this.fxnDecl = fxnDecl;
}
String code() { return "F!" + this.code; };
public Decl.Fxn getDecl() { return this.fxnDecl; }
Cat mkRetCat() { return (Cat.fromCode(this.code)); }
}
// Cat.Ins
public static class Ins extends Cat implements Obj
{
private Ins( String code, int ptrCnt ) { super(code, ptrCnt); }
String code() { return "I!" + this.code; }
public Cat mkMbrCat( String id )
{
for (Unit u = Cat.ses.findUnit(this.code); u != null; u = u.getSuper()) {
Decl d = Cat.ses.findDecl(u, id);
if (d != null && d.isInst()) {
return Cat.fromDecl(d);
}
}
return null;
}
}
// Cat.Map
public static class Map extends Cat implements Indexed
{
private Map( String code, int ptrCnt ) { super(code, ptrCnt); }
String code() { return "M!" + this.code; };
public Cat mkBaseCat() { return Cat.fromCode(this.code); }
}
// Cat.Sca
public static class Sca extends Cat
{
private Sca( String code, int ptrCnt ) { super(code, ptrCnt); }
String code() { return this.code; };
}
// Cat.Str
public static class Str extends Cat implements Obj
{
private String altName = null;
private Str( String code, int ptrCnt )
{
super(code, ptrCnt);
int k = code.indexOf('#');
if (k != -1) {
this.altName = this.code.substring(k + 1);
this.code = this.code.substring(0, k);
}
}
String code() { return "S!" + this.code; }
public Cat mkMbrCat( String id )
{
Decl d = Cat.ses.findDecl(this.code + '.' + id);
if (d != null) {
return Cat.fromDecl(d);
}
Decl str = Cat.ses.findDecl(this.code);
if (str.overrides() != null) {
return Cat.fromDecl(Cat.ses.findDecl(str.overrides().getQualName() + '.' + id));
}
return null;
}
public final String getAltName() { return this.altName; }
}
// Cat.Uni
public static class Uni extends Cat implements Obj
{
private boolean isProxy = false;
private Uni( String code, int ptrCnt ) { super(code, ptrCnt); }
String code() { return "U!" + this.code; }
public Cat mkMbrCat( String id )
{
if (id.equals("$used")) {
return Cat.fromCode("b");
}
for (Unit u = Cat.ses.findUnit(this.code); u != null; u = u.getSuper()) {
Decl d = Cat.ses.findDecl(u, id);
if (d != null) {
// TODO check for isInst || create
return Cat.fromDecl(d);
}
}
return null;
}
public final boolean isProxy() { return this.isProxy; }
final void setProxy() { this.isProxy = true; }
}
// fromCode
static Cat fromCode( String tc )
{
int pcnt = 0;
for (int i = 0; i < tc.length(); i++) {
switch (tc.charAt(i)) {
case 'P':
pcnt++;
break;
case 'A':
return new Cat.Arr(tc.substring(i + 1), pcnt);
case 'F':
return new Cat.Fxn(tc.substring(i + 1), pcnt);
case 'I':
return new Cat.Ins(tc.substring(i + 2), pcnt);
case 'M':
return new Cat.Map(tc.substring(i + 1), pcnt);
case 'S':
return new Cat.Str(tc.substring(i + 2), pcnt);
case 'U':
return new Cat.Uni(tc.substring(i + 2), pcnt);
case 'b':
case 'e':
case 'f':
case 'n':
case 'o': // TODO instance support
case 's':
case 'v':
return new Cat.Sca(tc, pcnt);
default:
return null;
}
}
return null;
}
// fromDecl
static Cat fromDecl( Decl d )
{
if (d instanceof Decl.Struct) {
return new Cat.Str(d.getQualName(), 0);
}
if (d instanceof Decl.Fxn) {
Decl.Fxn fxn = (Decl.Fxn)d;
if (fxn.getType() instanceof Type.Creator) {
return new Cat.Fxn("o", 0, fxn);
}
else {
return new Cat.Fxn(Cat.recode(fxn.getType()), 0, fxn);
}
}
if (d instanceof Decl.Signature) {
return Cat.fromType(((Decl.Signature)d).getType());
}
if (d instanceof Decl.Imp) {
return Cat.fromUnit(((Decl.Imp)d).getUnit());
}
if (d instanceof Decl.Proxy) {
return Cat.fromProxy(((Decl.Proxy)d));
}
if (d instanceof Decl.EnumVal) {
return new Cat.Sca("e", 0);
}
return null;
}
// fromProxy
static Cat fromProxy( Decl.Proxy prx )
{
Cat.Uni res = new Cat.Uni(prx.getUnit().getSuper().getQualName(), 0);
res.setProxy();
return res;
}
// fromType
static Cat fromType( Type t )
{
return Cat.fromCode(Cat.recode(t));
}
// fromUnit
static Cat fromUnit( Unit u )
{
return new Cat.Uni(u.getQualName(), 0);
}
// recode
static String recode( Type t )
{
t = t.raw();
String tc = t.tcode();
Ref r = t.tspec().getRef();
if (tc.endsWith("E")) {
return recodeStr(r, tc);
// return recodeStr((Decl.Struct)(t.tspec().getRef().getNode()), tc);
}
if (tc.endsWith("S")) {
return recodeStr(r, tc);
// tc += "!" + t.tspec().getRef().getNode().getQualName();
}
if (tc.equals("o")) {
if (r.getId().equals("Module")) {
return "U!" + r.getScope();
}
}
if (tc.endsWith("o")) {
if (r.getId().equals("Instance")) {
tc = tc.substring(0, tc.length() - 1) + "I!" + r.getScope();
}
}
return tc;
}
// recodeStr
static String recodeStr( Ref ref, String tc )
{
Node node = ref.getNode();
Decl.Proxy prx = ref.getProxy();
if (prx != null && prx.getParent() == Cat.unit) {
tc = tc.substring(0, tc.length() - 1) + "S!" + node.getQualName() + "#" + prx.getName() + '.' + node.getName();
return tc;
}
tc = tc.substring(0, tc.length() - 1) + "S!" + node.getQualName();
// TODO why??
for (Unit u = Cat.unit; u != null; u = u.getSuper()) {
Decl d = Cat.ses.findDecl(u, node.getName());
if (d != null && d.overrides() == node) {
return tc.substring(0, tc.length() - 1) + "S!" + d.getQualName();
}
}
return tc;
}
// recodeStr
static String recodeStr( Decl.Struct str, String tc )
{
tc = tc.substring(0, tc.length() - 1) + "S!" + str.getQualName();
// TODO why??
for (Unit u = Cat.unit; u != null; u = u.getSuper()) {
Decl d = Cat.ses.findDecl(u, str.getName());
if (d != null && d.overrides() == str) {
return tc.substring(0, tc.length() - 1) + "S!" + d.getQualName();
}
}
return tc;
}
}