| 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; | |
| } | |
| } |