/** * Classify an expression according to its numeric type. kind==0: not a number. kind==1: a * non-real number kind==2: real number kind==3: floating-point kind==4: exact integer */ public static int classify(Type type) { int kind = 0; if (type instanceof PrimType) { char sig = type.getSignature().charAt(0); if (sig == 'V' || sig == 'Z' || sig == 'C') return 0; else if (sig == 'D' || sig == 'F') return 3; else return 4; } else if (type.isSubtype(Arithmetic.typeIntNum)) return 4; else if (type.isSubtype(Arithmetic.typeDFloNum)) return 3; else if (type.isSubtype(Arithmetic.typeRealNum)) return 2; else if (type.isSubtype(Arithmetic.typeNumeric)) return 1; else return 0; }
private Node buildFieldDecl(FieldDecl fd) throws SemanticException { Type t = fd.declType(); if (t.isSubtype(SJ_PROTOCOL_TYPE)) { if (!(fd instanceof SJFieldProtocolDecl)) { throw new SemanticException( "[SJProtocolDeclTypeBuilder] Protocols may only be declared using the protocol keyword: " + fd); } SJTypeNode tn = disambiguateSJTypeNode(this, ((SJProtocolDecl) fd).sessionType()); SJSessionType st = tn.type(); String sjname = fd.name(); // Should match that given by SJVariable.sjname. SJFieldInstance fi = (SJFieldInstance) fd.fieldInstance(); SJFieldProtocolInstance fpi = sjts.SJFieldProtocolInstance((SJFieldInstance) fd.fieldInstance(), st, sjname); fpi.setConstantValue( fi .constantValue()); // Currently, constant checker not run on custom nodes/type // objects. (Previously done by SJNoAliasTypeBuilder.) fd = fd.fieldInstance(fpi); fd = (FieldDecl) setSJProtocolDeclExt((SJProtocolDecl) fd, tn, sjname); updateSJFieldInstance(fi, fpi); } return fd; }
protected void mergeHandler( Type type, T store, List<Pair<Type, String>> handlers, Map<String, T> stores) { for (Pair<Type, String> p : handlers) { Type handler = p.first(); if (Type.isSubtype(handler, type)) { T nstore = propagate(handler, store); merge(p.second(), nstore, stores); return; // completely subsumed } else if (Type.isSubtype(type, handler)) { T nstore = propagate(handler, store); merge(p.second(), nstore, stores); // not completely subsumed type = Type.intersect(type, Type.Negation(handler)); } } }
public boolean acceptsSubstitution(Type type) { if (equals(type)) return true; SequenceType values = new SequenceType(this); SequenceType replacements = new SequenceType(type); try { for (InterfaceType bound : getInterfaces()) { bound = bound.replace(values, replacements); if (!type.isSubtype(bound)) return false; } ClassType replacedClass = classBound.replace(values, replacements); if (!type.isSubtype(replacedClass)) return false; } catch (InstantiationException e) { } return true; }
@Override public boolean isSubtype(Type t) { if (equals(t)) return true; if (t instanceof SequenceType) { SequenceType inputTypes = (SequenceType) t; if (types.size() != inputTypes.size()) return false; for (int i = 0; i < types.size(); i++) { if (types.get(i) != null) { Type inputType = inputTypes.get(i).getType(); Modifiers inputModifiers = inputTypes.get(i).getModifiers(); Type type = types.get(i).getType(); Modifiers modifiers = types.get(i).getModifiers(); if (!type.isSubtype(inputType)) return false; // if either type is immutable, it will work out no matter what // if both are mutable, their modifiers had better both be immutable or both mutable if (!type.getModifiers().isImmutable() && !inputType.getModifiers().isImmutable()) { // inputModifiers = modifiers // if this is immutable, storage reference must be readonly or immutable (temporary // readonly isn't good enough) if (modifiers.isImmutable() && !inputModifiers.isImmutable() && !inputModifiers.isReadonly()) return false; // you can't put a readonly thing into a mutable reference // but you can put a mutable thing into a readonly reference (but not an immutable one) if (modifiers.isReadonly() && !inputModifiers.isReadonly()) return false; if (inputModifiers.isImmutable() && !modifiers.isImmutable()) return false; } if (modifiers.isNullable() && !inputModifiers.isNullable()) return false; } } return true; } else return false; }
private Node buildFormal(Formal f) throws SemanticException // Based on buildLocalDecl. { Type t = f.declType(); SJLocalInstance li = (SJLocalInstance) f.localInstance(); if (t.isSubtype(SJ_ABSTRACT_CHANNEL_TYPE)) { if (!(f instanceof SJFormal)) { throw new SemanticException( "[SJProtocolDeclTypeBuilder] Session socket parameters should be declared by their session type: " + f); } SJTypeNode tn = disambiguateSJTypeNode(this, ((SJFormal) f).sessionType()); SJSessionType st = tn.type(); String sjname = f.name(); // Should match that given by SJVariable.sjname. f = f.localInstance(sjts.SJLocalProtocolInstance(li, st, sjname)); f = setSJFormalExt((SJFormal) f, tn, sjname); } return f; }
private Node buildLocalDecl(LocalDecl ld) throws SemanticException { Type t = ld.declType(); SJLocalInstance li = (SJLocalInstance) ld.localInstance(); // SJNamedInstance ni = null; if (t.isSubtype(SJ_PROTOCOL_TYPE)) // Mostly the same as for LocalDecl. { if (!(ld instanceof SJLocalProtocolDecl)) { throw new SemanticException( "[SJProtocolDeclTypeBuilder] Protocols may only be declared using the protocol keyword: " + ld); } SJTypeNode tn = disambiguateSJTypeNode(this, ((SJProtocolDecl) ld).sessionType()); SJSessionType st = tn.type(); String sjname = ld.name(); // Should match that given by SJVariable.sjname. ld = ld.localInstance(sjts.SJLocalProtocolInstance(li, st, sjname)); ld = (LocalDecl) setSJProtocolDeclExt((SJProtocolDecl) ld, tn, sjname); } return ld; }