import java.util.*; aspect Signature { syn boolean Decl.isSampleDecl(); eq TypeDecl.isSampleDecl() = false; eq SampleDecl.isSampleDecl() = true; syn boolean Decl.sendOnlyFlatSignatures(Java_env env) = (env.version==2006); eq Decl.getSignature().parentDecl() = this; eq Signature.getSignatureList().parentDecl() = parentDecl(); inh Decl Signature.parentDecl(); inh Decl SignatureList.parentDecl(); syn nta Signature Decl.getSignature() { SignatureList sl = new SignatureList(); genSigLineForDecl(sl, true, this); SignatureList fsl = new SignatureList(); flatSignature(fsl); Signature sig = new Signature(); sig.setSignatureList(sl); sig.setFlatSignatureList(fsl); setSignature(sig); return sig; } public String SignatureLine.getIndentString() { StringBuffer result = new StringBuffer(); int indent = getIndent(); for (int i = 0 ; i < indent ; i++) { result.append(" "); } return result.toString(); } syn byte[] SignatureLine.getData(int version) = null; // return new byte[0]; private Decl TypeRefSignatureLine.decl; public TypeRefSignatureLine.TypeRefSignatureLine(int indent, Decl decl, String comment) { super(indent, comment); this.decl = decl; } public void SignatureList.addTypeRef(Decl type, String comment) { addSignatureLine(new TypeRefSignatureLine(indent, type, comment)); } public ByteArraySignatureLine.ByteArraySignatureLine(int indent, byte[] data, String comment) { super(indent, comment); setData(data); } public IntSignatureLine.IntSignatureLine(int indent, int data, String comment) { super(indent, comment); setData(data); } public void SignatureList.add(byte[] data, String comment) { addSignatureLine(new ByteArraySignatureLine(indent, data, comment)); } public void SignatureList.addInt(int data, String comment) { addSignatureLine(new IntSignatureLine(indent, data, comment)); } protected byte[] DataSignatureLine.getIntBytes(int value, int version) { byte data[]; switch(version) { case 2006: // Use old encoding with 32 bit integers data = new byte[4]; for (int i = 0 ; i < 4 ; i++) { data[3 - i] = (byte)((value >> (8 * i)) & 0xff); } //add(data, comment); break; case 2014: // Use new encoding with varints byte[] tmp = new byte[5]; long v = value & 0xffffffff; int i, j; for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) { tmp[i] = (byte)(v & 0x7f); } byte[] packed = new byte[i]; for (i = i - 1, j = 0 ; i >= 0 ; i--, j++) { packed[j] = (byte)(tmp[i] | (i!=0?0x80:0x00)); } //add(packed, comment); data = packed; break; default: throw new RuntimeException("Unsupported version = "+version+". This should never happen."); } return data; } eq IntSignatureLine.getData(int version) { return getIntBytes(getData(), version); } public void SignatureList.addIntentions(Set<Intention> data, String comment) { //addString(TypeInstance.getIntentionString(data), comment); //create IntenionSignatureLine IntentionSignatureLine line = new IntentionSignatureLine(indent, comment, new List()); //TODO: refactor out creation of sorted list of intentions java.util.ArrayList<Intention> sorted = new ArrayList(data); java.util.Collections.sort(sorted, TypeInstance.intentionComp); for(Intention i : sorted) { line.addIntention(i); } addSignatureLine(line); } eq IntentionSignatureLine.getData(int version) { //String tmpString = TypeInstance.getIntentionString(getIntentions()); byte[] bs = TypeInstance.getIntentionBytes(getIntentions()); return bs; } public void SignatureList.addString(String data, String comment) { addSignatureLine(new StringSignatureLine(indent, comment, data)); } eq StringSignatureLine.getData(int version) { byte[] lenBytes = getIntBytes(getData().length(), version); byte[] data = new byte[lenBytes.length+getData().length()]; // first add the encoded length for (int i = 0 ; i < lenBytes.length ; i++) { data[i] = lenBytes[i]; } // and then the actual chars for (int i = 0 ; i < getData().length() ; i++) { int idx = lenBytes.length + i; data[idx] = (byte)(getData().charAt(i) & 0xff); } return data; } public int SignatureList.size() { return getNumSignatureLine(); } public String SignatureList.getIndent(int i) { StringBuffer result = new StringBuffer(); int indent = getSignatureLine(i).getIndent(); for (i = 0 ; i < indent ; i++) { result.append(" "); } return result.toString(); } public byte[] SignatureList.getData(int i, int version) { return getSignatureLine(i).getData(version); } public String SignatureList.getComment(int i) { return getSignatureLine(i).getComment(); } private int SignatureList.indent; public void SignatureList.indent() { indent++; } public void SignatureList.unindent() { indent--; } public void ASTNode.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) { throw new Error(this.getClass().getName() + ".genSigLineForDecl(SignatureList list)" + " not declared"); } public String TypeInstance.getIntentionString() { return getIntentionString(intentions()); } public static String TypeInstance.getIntentionString(List<Intention> intentions) { if(intentions==null) return ""; Iterator<Intention> it = intentions.iterator(); return getIntentionString(it); } public static String TypeInstance.getIntentionString(Set<Intention> intentions) { if(intentions==null) return ""; Iterator<Intention> it = intentions.iterator(); return getIntentionString(it); } public static String TypeInstance.getIntentionString(Iterator<Intention> it) { StringBuilder sb = new StringBuilder(); while(it.hasNext()) { Intention i = it.next(); sb.append(i.toString()); } return sb.toString(); } syn byte[] Intention.keyBytes() = getKey().getBytes(); syn byte[] Intention.valBytes() = getValue(); syn byte[] Intention.toByteArray() { byte[] k = keyBytes(); byte[] v = valBytes(); int klen = Utilities.size_packed32(k.length); int vlen = Utilities.size_packed32(v.length); int tlen = k.length + v.length + Utilities.size_packed32(klen) + Utilities.size_packed32(vlen); //int size = Utilities.size_packed32(tlen)+tlen; byte result[] = new byte[tlen]; int pos=0; // pos = Utilities.encodePacked32(tlen, result, pos, Utilities.size_packed32(tlen)); pos = Utilities.encodePacked32(k.length, result, pos, klen); for(byte kb : k) { result[pos++] = kb; } pos = Utilities.encodePacked32(v.length, result, pos, vlen); for(byte vb : v) { result[pos++] = vb; } return result; } public byte[] TypeInstance.getIntentionBytes() { return getIntentionBytes(intentions()); } public static byte[] TypeInstance.getIntentionBytes(List<Intention> intentions) { if(intentions==null) return new byte[0]; Iterator<Intention> it = intentions.iterator(); return getIntentionBytes(it); } public static byte[] TypeInstance.getIntentionBytes(Set<Intention> intentions) { if(intentions==null) return new byte[0]; Iterator<Intention> it = intentions.iterator(); return getIntentionBytes(it); } public static byte[] TypeInstance.getIntentionBytes(Iterator<Intention> it) { java.util.ArrayList<byte[]> tmp = new java.util.ArrayList<byte[]>(); int tmpLen=0; int numIntentions=0; while(it.hasNext()) { Intention i = it.next(); byte[] bs = i.toByteArray(); tmp.add(bs); tmpLen+=bs.length; numIntentions++; } byte result[] = new byte[tmpLen + Utilities.size_packed32(numIntentions)]; int pos = 0; pos = Utilities.encodePacked32(numIntentions, result, 0, Utilities.size_packed32(numIntentions)); for(byte[] bs : tmp) { for(byte b : bs) { result[pos++] = b; } } return result; } syn Set<Intention> Specification.emptyIntentions() = new HashSet<Intention>(); inh Set<Intention> ASTNode.noIntentions(); eq Specification.getChild(int i).noIntentions() = emptyIntentions(); syn Set<Intention> ASTNode.intentions(); eq ASTNode.intentions() = noIntentions(); eq TypeInstance.intentions() = intentionSet(); public void TypeInstance.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) { // debugAnnotations(this.getName()); // list.addString(inst.getIntentionString(), "intention string"); if(addIntentions()) { list.addIntentions(intentionSet(), "intentions"); } getDataType().genSigLineForDecl(list, decl, this); } public void TypeDecl.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) { //TODO intent if(decl){ getTypeInstance().genSigLineForDecl(list, decl, this); }else{ list.addTypeRef(this, "//TODO (from list.addTypeRef)"); } } public void SampleDecl.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) { //TODO intent getTypeInstance().genSigLineForDecl(list, decl, this); } public void VoidType.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) { list.addInt(LABCOMM_STRUCT, "void"); list.addInt(0, null); } // public void SampleRefType.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) { // list.addInt(LABCOMM_SAMPLE_REF, "sample"); // } public void PrimType.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) { list.addInt(getToken(), null); } /* For UserType, the decl parameter is ignored, as a UserType * will always be a TypeRef */ public void UserType.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) { TypeDecl thet = lookupType(getName()); list.addTypeRef(thet, null); } public void ArrayType.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) { list.addInt(LABCOMM_ARRAY, signatureComment()); list.indent(); list.addInt(getNumExp(), null); for (int i = 0 ; i < getNumExp() ; i++) { getExp(i).genSigLineForDecl(list, false, null); } getDataType().genSigLineForDecl(list, false, null); list.unindent(); list.add(null, "}"); } public void StructType.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) { list.addInt(LABCOMM_STRUCT, "struct { " + getNumField() + " fields"); list.indent(); list.addInt(getNumField(), null); for (int i = 0 ; i < getNumField() ; i++) { getField(i).genSigLineForDecl(list, false, inst); } list.unindent(); list.add(null, "}"); } // public void Field.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) { // //XXX make intention // list.addString(getName(), signatureComment()); // super.genSigLineForDecl(list, decl, inst); // //TODOintent // //getDataType().genSigLineForDecl(list, decl, inst); // } public void IntegerLiteral.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) { list.addInt(Integer.parseInt(getValue()), null); } public void VariableSize.genSigLineForDecl(SignatureList list, boolean decl, ASTNode inst) { list.addInt(0, null); } }