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); 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.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) { throw new Error(this.getClass().getName() + ".genSigLineForDecl(SignatureList list)" + " not declared"); } public void TypeDecl.genSigLineForDecl(SignatureList list, boolean decl) { //System.out.println("************ TypeDecl.genSigLine("+decl+").... for "+getName()); if(decl){ getType().genSigLineForDecl(list, decl); }else{ list.addTypeRef(this, "//TODO (from list.addTypeRef)"); } } public void SampleDecl.genSigLineForDecl(SignatureList list, boolean decl) { //System.out.println("************ SampleDecl.genSigLine("+decl+").... for "+getName()); getType().genSigLineForDecl(list, decl); } public void VoidType.genSigLineForDecl(SignatureList list, boolean decl) { list.addInt(LABCOMM_STRUCT, "void"); list.addInt(0, null); } public void SampleRefType.genSigLineForDecl(SignatureList list, boolean decl) { list.addInt(LABCOMM_SAMPLE_REF, "sample"); } public void PrimType.genSigLineForDecl(SignatureList list, boolean decl) { list.addInt(getToken(), null); } public void UserType.genSigLineForDecl(SignatureList list, boolean decl) { if(decl){ //System.out.println("************ UserType.genSigLine("+decl+").... for "+getName()); TypeDecl thet=lookupType(getName()); //System.out.println("************ thet: "+thet.getName() +":"+thet.getType()); thet.genSigLineForDecl(list, decl); }else{ //System.out.println("************ UserType.genSigLine("+decl+").... for "+getName()); TypeDecl thet = lookupType(getName()); // System.out.println("************ thet: "+thet.getName() +":"+thet.getType()); list.addTypeRef(thet, null); } } public void ArrayType.genSigLineForDecl(SignatureList list, boolean decl) { list.addInt(LABCOMM_ARRAY, signatureComment()); list.indent(); list.addInt(getNumExp(), null); for (int i = 0 ; i < getNumExp() ; i++) { getExp(i).genSigLineForDecl(list, false); } getType().genSigLineForDecl(list, false); list.unindent(); list.add(null, "}"); } public void StructType.genSigLineForDecl(SignatureList list, boolean decl) { 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); } list.unindent(); list.add(null, "}"); } public void Field.genSigLineForDecl(SignatureList list, boolean decl) { list.addString(getName(), signatureComment()); getType().genSigLineForDecl(list, decl); } public void IntegerLiteral.genSigLineForDecl(SignatureList list, boolean decl) { list.addInt(Integer.parseInt(getValue()), null); } public void VariableSize.genSigLineForDecl(SignatureList list, boolean decl) { list.addInt(0, null); } }