private ObjectType( NominalType nominalType, PersistentMap<String, Property> props, FunctionType fn, boolean isLoose, ObjectKind objectKind) { Preconditions.checkArgument( fn == null || fn.isQmarkFunction() || fn.isLoose() == isLoose, "isLoose: %s, fn: %s", isLoose, fn); Preconditions.checkArgument(FunctionType.isInhabitable(fn)); Preconditions.checkArgument( fn == null || nominalType != null, "Cannot create function %s without nominal type", fn); if (nominalType != null) { Preconditions.checkArgument( !nominalType.isClassy() || !isLoose, "Cannot create loose objectType with nominal type %s", nominalType); Preconditions.checkArgument( fn == null || nominalType.isFunction(), "Cannot create objectType of nominal type %s with function (%s)", nominalType, fn); Preconditions.checkArgument( !nominalType.isFunction() || fn != null, "Cannot create Function instance without a FunctionType"); } this.nominalType = nominalType; this.props = props; this.fn = fn; this.isLoose = isLoose; this.objectKind = objectKind; }
ObjectType specialize(ObjectType other) { Preconditions.checkState(areRelatedClasses(this.nominalType, other.nominalType)); if (this == TOP_OBJECT && other.objectKind.isUnrestricted()) { return other; } NominalType resultNomType = NominalType.pickSubclass(this.nominalType, other.nominalType); ObjectKind ok = ObjectKind.meet(this.objectKind, other.objectKind); if (resultNomType != null && resultNomType.isClassy()) { Preconditions.checkState(this.fn == null && other.fn == null); PersistentMap<String, Property> newProps = meetPropsHelper(true, resultNomType, this.props, other.props); if (newProps == BOTTOM_MAP) { return BOTTOM_OBJECT; } return new ObjectType(resultNomType, newProps, null, false, ok); } FunctionType thisFn = this.fn; boolean isLoose = this.isLoose; if (resultNomType != null && resultNomType.isFunction() && this.fn == null) { thisFn = other.fn; isLoose = other.fn.isLoose(); } PersistentMap<String, Property> newProps = meetPropsHelper(true, resultNomType, this.props, other.props); if (newProps == BOTTOM_MAP) { return BOTTOM_OBJECT; } FunctionType newFn = thisFn == null ? null : thisFn.specialize(other.fn); if (!FunctionType.isInhabitable(newFn)) { return BOTTOM_OBJECT; } return new ObjectType(resultNomType, newProps, newFn, isLoose, ok); }
static ObjectType join(ObjectType obj1, ObjectType obj2) { if (obj1 == TOP_OBJECT || obj2 == TOP_OBJECT) { return TOP_OBJECT; } NominalType nom1 = obj1.nominalType; NominalType nom2 = obj2.nominalType; Preconditions.checkState(areRelatedClasses(nom1, nom2)); if (obj1.equals(obj2)) { return obj1; } boolean isLoose = obj1.isLoose || obj2.isLoose; FunctionType fn = FunctionType.join(obj1.fn, obj2.fn); PersistentMap<String, Property> props; if (isLoose) { fn = fn == null ? null : fn.withLoose(); props = joinPropsLoosely(obj1.props, obj2.props); } else { props = joinProps(obj1.props, obj2.props, nom1, nom2); } NominalType nominal = NominalType.pickSuperclass(nom1, nom2); // TODO(blickly): Split TOP_OBJECT from empty object and remove this case if (nominal == null || !nominal.isFunction()) { fn = null; } return ObjectType.makeObjectType( nominal, props, fn, isLoose, ObjectKind.join(obj1.objectKind, obj2.objectKind)); }
public boolean isInterfaceDefinition() { if (objs == null || objs.size() > 1) { return false; } FunctionType ft = Iterables.getOnlyElement(objs).getFunType(); return ft != null && ft.isInterfaceDefinition(); }
@Override public String toString() { StringBuilder sb = new StringBuilder(); if (result != null) { sb.append(result.toString()); sb.append(" = "); } sb.append(name); sb.append(' '); FunctionType ftype = (FunctionType) function.getType(); sb.append(ftype.isVarargs() ? ftype.getDefinition() : ftype.getReturnType().toString()); sb.append(" "); sb.append(function.toString()); sb.append('('); for (int i = 0; i < args.length; i++) { if (i > 0) { sb.append(", "); } sb.append(args[i].getType()); sb.append(' '); sb.append(args[i]); } sb.append(')'); return sb.toString(); }
static ObjectType meet(ObjectType obj1, ObjectType obj2) { Preconditions.checkState(areRelatedClasses(obj1.nominalType, obj2.nominalType)); if (obj1 == TOP_OBJECT) { return obj2; } else if (obj2 == TOP_OBJECT) { return obj1; } NominalType resultNomType = NominalType.pickSubclass(obj1.nominalType, obj2.nominalType); FunctionType fn = FunctionType.meet(obj1.fn, obj2.fn); if (!FunctionType.isInhabitable(fn)) { return BOTTOM_OBJECT; } boolean isLoose = obj1.isLoose && obj2.isLoose || fn != null && fn.isLoose(); if (resultNomType != null && resultNomType.isFunction() && fn == null) { fn = obj1.fn == null ? obj2.fn : obj1.fn; isLoose = fn.isLoose(); } PersistentMap<String, Property> props; if (isLoose) { props = joinPropsLoosely(obj1.props, obj2.props); } else { props = meetPropsHelper(false, resultNomType, obj1.props, obj2.props); } if (props == BOTTOM_MAP) { return BOTTOM_OBJECT; } ObjectKind ok = ObjectKind.meet(obj1.objectKind, obj2.objectKind); return new ObjectType(resultNomType, props, fn, isLoose, ok); }
void setupServerData(LocalDisplay[] dpys) throws RemoteException, VisADException { Unit super_degree = CommonUnit.degree.scale(2.5); RealType lon = RealType.getRealType("lon", super_degree); DataReference ref = loadFile(); if (ref == null) { System.err.println("must specify netCDF file name"); System.exit(1); return; } FieldImpl netcdf_data = (FieldImpl) ref.getData(); // compute ScalarMaps from type components FunctionType ftype = (FunctionType) netcdf_data.getType(); RealTupleType dtype = ftype.getDomain(); MathType rntype = ftype.getRange(); int n = dtype.getDimension(); dpys[0].addMap(new ScalarMap((RealType) dtype.getComponent(0), Display.XAxis)); if (n > 1) { dpys[0].addMap(new ScalarMap((RealType) dtype.getComponent(1), Display.YAxis)); } if (n > 2) { dpys[0].addMap(new ScalarMap((RealType) dtype.getComponent(2), Display.ZAxis)); } if (rntype instanceof RealType) { dpys[0].addMap(new ScalarMap((RealType) rntype, Display.Green)); if (n <= 2) { dpys[0].addMap(new ScalarMap((RealType) rntype, Display.ZAxis)); } } else if (rntype instanceof RealTupleType) { int m = ((RealTupleType) rntype).getDimension(); RealType rr = (RealType) ((RealTupleType) rntype).getComponent(0); dpys[0].addMap(new ScalarMap(rr, Display.Green)); if (n <= 2) { if (m > 1) { rr = (RealType) ((RealTupleType) rntype).getComponent(1); } dpys[0].addMap(new ScalarMap(rr, Display.ZAxis)); } } dpys[0].addMap(new ConstantMap(0.5, Display.Red)); dpys[0].addMap(new ConstantMap(0.0, Display.Blue)); dpys[0].addReference(ref, null); System.out.println("now saving data as 'save.nc' and re-reading"); Plain plain = new Plain(); try { plain.save("save.nc", netcdf_data, true); netcdf_data = (FieldImpl) plain.open("save.nc"); } catch (IOException e) { System.err.println("Couldn't open \"save.nc\": " + e.getMessage()); System.exit(1); return; } }
@Override public void draw(Canvas canvas) { // Draw the bounding boxes drawBoundingBoxes(canvas); // Set the right values for the paint operatorPaint.setColor(getColor()); operatorPaint.setTextSize(findTextSize()); // Get our operator bounding boxes Rect[] operatorBounding = this.getOperatorBoundingBoxes(); // Draws the operator canvas.save(); Rect textBounding = new Rect(); operatorPaint.getTextBounds(type.getName(), 0, type.getName().length(), textBounding); canvas.translate( (operatorBounding[0].width() - textBounding.width()) / 2, (operatorBounding[0].height() - textBounding.height()) / 2); canvas.drawText( type.getName(), operatorBounding[0].left - textBounding.left, operatorBounding[0].top - textBounding.top, operatorPaint); canvas.restore(); // Use stroke style for the parentheses operatorPaint.setStyle(Paint.Style.STROKE); // Draw the left bracket canvas.save(); canvas.clipRect(operatorBounding[1], Region.Op.INTERSECT); RectF bracket = new RectF(operatorBounding[1]); bracket.inset(0, -operatorPaint.getStrokeWidth()); bracket.offset(bracket.width() / 4, 0); canvas.drawArc(bracket, 100.0f, 160.0f, false, operatorPaint); canvas.restore(); // Draw the right bracket canvas.save(); canvas.clipRect(operatorBounding[2], Region.Op.INTERSECT); bracket = new RectF(operatorBounding[2]); bracket.inset(0, -operatorPaint.getStrokeWidth()); bracket.offset(-bracket.width() / 4, 0); canvas.drawArc(bracket, -80.0f, 160.0f, false, operatorPaint); canvas.restore(); // Set the paint back to fill style operatorPaint.setStyle(Paint.Style.FILL); // Draw the children drawChildren(canvas); }
/** * Calculates the size of this function when using the given font size * * @param fontSize The font size * @return The size of this {@link MathConstant} */ protected Rect getSize(float fontSize) { // Set the text size operatorPaint.setTextSize(fontSize); // Calculate the total width and the height of the text Rect out = new Rect(0, 0, 0, 0); operatorPaint.getTextBounds(type.getName(), 0, type.getName().length(), out); out.offsetTo(0, 0); // Return the size return out; }
public FunctionType buildFunction() { FunctionType result = FunctionType.normalized( requiredFormals, optionalFormals, restFormals, returnType, nominalType, receiverType, outerVars, typeParameters, loose); result.checkValid(); return result; }
// We never infer properties as optional on loose objects, // and we don't warn about possibly inexistent properties. boolean isLooseSubtypeOf(ObjectType other) { Preconditions.checkState(isLoose || other.isLoose); if (other == TOP_OBJECT) { return true; } if (!isLoose) { if (!objectKind.isSubtypeOf(other.objectKind)) { return false; } for (String pname : other.props.keySet()) { QualifiedName qname = new QualifiedName(pname); if (!mayHaveProp(qname) || !getProp(qname).isSubtypeOf(other.getProp(qname))) { return false; } } } else { // this is loose, other may be loose for (String pname : props.keySet()) { QualifiedName qname = new QualifiedName(pname); if (other.mayHaveProp(qname) && !getProp(qname).isSubtypeOf(other.getProp(qname))) { return false; } } } if (other.fn == null) { return this.fn == null || other.isLoose(); } else if (this.fn == null) { return isLoose; } return fn.isLooseSubtypeOf(other.fn); }
@Override public int compareTo(FunctionSignature o) { int cmpVal = name.compareTo(o.name); if (cmpVal != 0) { return cmpVal; } cmpVal = functionType.name().compareTo(o.functionType.name()); if (cmpVal != 0) { return cmpVal; } cmpVal = returnType.getType().name().compareTo(o.returnType.getType().name()); if (cmpVal != 0) { return cmpVal; } for (int i = 0; i < Math.min(paramTypes.length, o.paramTypes.length); i++) { cmpVal = paramTypes[i].getType().name().compareTo(o.paramTypes[i].getType().name()); if (cmpVal != 0) { return cmpVal; } } return o.paramTypes.length - paramTypes.length; }
@Override public final void writeToXML(Document doc, Element el) { Element e = doc.createElement(NAME); e.setAttribute(ATTR_TYPE, type.getXmlName()); getChild(0).writeToXML(doc, e); el.appendChild(e); }
@Override public String toString() { String childString = getChild(0).toString(); if (childString.startsWith("(") && childString.endsWith(")")) childString = childString.substring(1, childString.length() - 1); return type.getXmlName() + '(' + childString + ')'; }
ObjectType substituteGenerics(Map<String, JSType> concreteTypes) { if (concreteTypes.isEmpty()) { return this; } PersistentMap<String, Property> newProps = PersistentMap.create(); for (Map.Entry<String, Property> propsEntry : this.props.entrySet()) { String pname = propsEntry.getKey(); Property newProp = propsEntry.getValue().substituteGenerics(concreteTypes); newProps = newProps.with(pname, newProp); } FunctionType newFn = fn == null ? null : fn.substituteGenerics(concreteTypes); return makeObjectType( nominalType == null ? null : nominalType.instantiateGenerics(concreteTypes), newProps, newFn, newFn != null && newFn.isQmarkFunction() || isLoose, objectKind); }
@Override public boolean equals(Object o) { if (this == o) { return true; } else if (o == null || getClass() != o.getClass()) { return false; } else { return (signature.equals(((FunctionSignature) o).signature) && type.equals(((FunctionSignature) o).type) && Arrays.equals(arguments, ((FunctionSignature) o).arguments)); } }
StringBuilder appendTo(StringBuilder builder) { if (!hasNonPrototypeProperties()) { if (fn != null) { return fn.appendTo(builder); } else if (getNominalType() != null) { return getNominalType().appendTo(builder); } } if (nominalType != null && !nominalType.getName().equals("Function")) { nominalType.appendTo(builder); } else if (isStruct()) { builder.append("struct"); } else if (isDict()) { builder.append("dict"); } if (fn != null) { builder.append("<|"); fn.appendTo(builder); builder.append("|>"); } if (nominalType == null || !props.isEmpty()) { builder.append('{'); boolean firstIteration = true; for (String pname : new TreeSet<>(props.keySet())) { if (firstIteration) { firstIteration = false; } else { builder.append(", "); } builder.append(pname); builder.append(':'); props.get(pname).appendTo(builder); } builder.append('}'); } if (isLoose) { builder.append(" (loose)"); } return builder; }
public FunctionType getFunType() { if (objs == null) { return null; } if (objs.size() == 1) { // The common case is fast return Iterables.getOnlyElement(objs).getFunType(); } FunctionType result = FunctionType.TOP_FUNCTION; for (ObjectType obj : objs) { result = FunctionType.meet(result, obj.getFunType()); } return result; }
/** * Consumes either a "classic" function jsdoc with @param, @return, etc, or a jsdoc with @type * {function ...} and finds the types of the formal parameters and the return value. It returns a * builder because the callers of this function must separately handle @constructor, @interface, * etc. * * <p>constructorType is non-null iff this function is a constructor or interface declaration. */ public FunctionAndSlotType getFunctionType( JSDocInfo jsdoc, String functionName, Node declNode, RawNominalType constructorType, RawNominalType ownerType, DeclaredTypeRegistry registry) { FunctionTypeBuilder builder = new FunctionTypeBuilder(); if (ownerType != null) { builder.addReceiverType(ownerType.getInstanceAsJSType()); } try { if (jsdoc != null && jsdoc.getType() != null) { JSType simpleType = getDeclaredTypeOfNode(jsdoc, ownerType, registry); if (simpleType.isUnknown() || simpleType.isTop()) { return qmarkFunctionDeclared; } FunctionType funType = simpleType.getFunType(); if (funType != null) { JSType slotType = simpleType.isFunctionType() ? null : simpleType; DeclaredFunctionType declType = funType.toDeclaredFunctionType(); if (ownerType != null && funType.getThisType() == null) { declType = declType.withReceiverType(ownerType.getInstanceAsJSType()); } return new FunctionAndSlotType(slotType, declType); } else { warnings.add(JSError.make(declNode, FUNCTION_WITH_NONFUNC_JSDOC)); jsdoc = null; } } DeclaredFunctionType declType = getFunTypeFromTypicalFunctionJsdoc( jsdoc, functionName, declNode, constructorType, ownerType, registry, builder); return new FunctionAndSlotType(null, declType); } catch (FunctionTypeBuilder.WrongParameterOrderException e) { warnings.add(JSError.make(declNode, WRONG_PARAMETER_ORDER)); return qmarkFunctionDeclared; } }
/** create parallel coordinates display for data */ public static void parallel(DisplayImpl display, FlatField data) throws VisADException, RemoteException { FunctionType ftype = (FunctionType) data.getType(); RealType index = (RealType) ftype.getDomain().getComponent(0); RealTupleType range = (RealTupleType) ftype.getRange(); int ncoords = range.getDimension(); int nrows = data.getLength(); Set index_set = data.getDomainSet(); float[][] samples = data.getFloats(false); RealType x = RealType.getRealType("coordinate"); RealType y = RealType.getRealType("value"); SetType xy = new SetType(new RealTupleType(x, y)); FunctionType ptype = new FunctionType(index, xy); FieldImpl pfield = new FieldImpl(ptype, index_set); for (int j = 0; j < nrows; j++) { float[][] locs = new float[2][ncoords]; for (int i = 0; i < ncoords; i++) { locs[0][i] = i; locs[1][i] = samples[i][j]; } Gridded2DSet set = new Gridded2DSet(xy, locs, ncoords); pfield.setSample(j, set, false); } // create a DataReference for river system DataReference parallel_ref = new DataReferenceImpl("parallel"); parallel_ref.setData(pfield); display.addMap(new ScalarMap(x, Display.XAxis)); display.addMap(new ScalarMap(y, Display.YAxis)); // enable axis scales display.getGraphicsModeControl().setScaleEnable(true); // link display to parallel display display.addReference(parallel_ref); }
@Override public boolean equals(Object obj) { if (obj instanceof FunctionSignature) { FunctionSignature other = (FunctionSignature) obj; boolean eq = functionType.equals(other.functionType); eq = eq && name.equals(other.name); eq = eq && TUtil.checkEquals(paramTypes, other.paramTypes); eq = eq && returnType.equals(other.returnType); return eq; } else { return false; } }
static ObjectType makeObjectType( NominalType nominalType, PersistentMap<String, Property> props, FunctionType fn, boolean isLoose, ObjectKind ok) { if (props == null) { props = PersistentMap.create(); } else if (containsBottomProp(props) || !FunctionType.isInhabitable(fn)) { return BOTTOM_OBJECT; } if (fn != null && !props.containsKey("prototype")) { props = props.with("prototype", UNKNOWN_PROP); } return new ObjectType(nominalType, props, fn, isLoose, ok); }
@Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(signature); sb.append("#").append(type.name()); sb.append("("); int i = 0; for (DataType type : arguments) { sb.append(type.getType()); sb.append("[").append(type.getLength()).append("]"); if (i < arguments.length - 1) { sb.append(","); } i++; } sb.append(")"); return sb.toString(); }
/** * Unify the two types symmetrically, given that we have already instantiated the type variables * of interest in {@code t1} and {@code t2}, treating JSType.UNKNOWN as a "hole" to be filled. * * @return The unified type, or null if unification fails */ static ObjectType unifyUnknowns(ObjectType t1, ObjectType t2) { NominalType nt1 = t1.nominalType; NominalType nt2 = t2.nominalType; NominalType nt; if (nt1 == null && nt2 == null) { nt = null; } else if (nt1 == null || nt2 == null) { return null; } else { nt = NominalType.unifyUnknowns(nt1, nt2); if (nt == null) { return null; } } FunctionType newFn = null; if (t1.fn != null || t2.fn != null) { newFn = FunctionType.unifyUnknowns(t1.fn, t2.fn); if (newFn == null) { return null; } } PersistentMap<String, Property> newProps = PersistentMap.create(); for (String propName : t1.props.keySet()) { Property prop1 = t1.props.get(propName); Property prop2 = t2.props.get(propName); if (prop2 == null) { return null; } Property p = Property.unifyUnknowns(prop1, prop2); if (p == null) { return null; } newProps = newProps.with(propName, p); } return makeObjectType( nt, newProps, newFn, t1.isLoose || t2.isLoose, ObjectKind.join(t1.objectKind, t2.objectKind)); }
/** * Unify {@code this}, which may contain free type variables, with {@code other}, a concrete type, * modifying the supplied {@code typeMultimap} to add any new template varaible type bindings. * * @return Whether unification succeeded */ boolean unifyWithSubtype( ObjectType other, List<String> typeParameters, Multimap<String, JSType> typeMultimap) { if (fn != null) { if (other.fn == null || !fn.unifyWithSubtype(other.fn, typeParameters, typeMultimap)) { return false; } } if (nominalType != null && other.nominalType != null) { return nominalType.unifyWithSubtype(other.nominalType, typeParameters, typeMultimap); } if (nominalType != null || other.nominalType != null) { return false; } for (String propName : this.props.keySet()) { Property thisProp = props.get(propName); Property otherProp = other.props.get(propName); if (otherProp == null || !thisProp.unifyWithSubtype(otherProp, typeParameters, typeMultimap)) { return false; } } return true; }
void setupServerData(LocalDisplay[] dpys) throws RemoteException, VisADException { DefaultFamily df = new DefaultFamily("loader"); DataReference ref1 = loadFile(df, file1, "img1"); if (ref1 == null) { System.err.println("\"" + file1 + "\" is not a valid file"); System.exit(1); return; } DataReference ref2 = loadFile(df, file2, "img2"); if (ref2 == null) { System.err.println("\"" + file2 + "\" is not a valid file"); System.exit(1); return; } FlatField img1 = (FlatField) ref1.getData(); FlatField img2 = (FlatField) ref2.getData(); /* if (!img1.getType().equals(img2.getType())) { System.err.println("Incompatible file types:"); System.err.println(" " + file1 + ": " + img1.getType()); System.err.println(" " + file2 + ": " + img2.getType()); System.exit(1); return; } */ // compute ScalarMaps from type components FunctionType ftype = (FunctionType) img1.getType(); RealTupleType dtype = ftype.getDomain(); RealTupleType rtype = (RealTupleType) ftype.getRange(); /* map domain elements to spatial axes */ final int dLen = dtype.getDimension(); for (int i = 0; i < dLen; i++) { ScalarType scalT; DisplayRealType dpyRT; switch (i) { case 0: dpyRT = Display.XAxis; break; case 1: dpyRT = Display.YAxis; break; case 2: dpyRT = Display.ZAxis; break; default: dpyRT = null; break; } if (dpyRT != null) { dpys[0].addMap(new ScalarMap((RealType) dtype.getComponent(i), dpyRT)); } } /* map range elements to colors */ final int rLen = rtype.getDimension(); for (int i = 0; i < rLen; i++) { ScalarType scalT; DisplayRealType dpyRT; switch (i) { case 0: dpyRT = Display.Red; break; case 1: dpyRT = Display.Green; break; case 2: dpyRT = Display.Blue; break; default: dpyRT = null; break; } if (dpyRT != null) { dpys[0].addMap(new ScalarMap((RealType) rtype.getComponent(i), dpyRT)); } } dpys[0].addReference(ref1, null); dpys[0].addReference(ref2, null); dpys[0].addActivityHandler(new SwitchGIFs(dpys[0])); }
/** * Implement the Dart function subtype rule. Unlike the classic arrow rule (return type is * covariant, and parameter types are contravariant), in Dart they must just be assignable. */ private boolean isSubtypeOfFunction(FunctionType t, FunctionType s) { if (s.getKind() == TypeKind.DYNAMIC || t.getKind() == TypeKind.DYNAMIC) { return true; } // Classic: return type is covariant; Dart: assignable. if (!isAssignable(t.getReturnType(), s.getReturnType())) { // A function that returns a value can be used as a function where you ignore the value. if (!s.getReturnType().equals(typeProvider.getVoidType())) { return false; } } Type tRest = t.getRest(); Type sRest = s.getRest(); if ((tRest == null) != (sRest == null)) { return false; } if (tRest != null) { // Classic: parameter types are contravariant; Dart: assignable. if (!isAssignable(sRest, tRest)) { return false; } } { Map<String, Type> sOpti = s.getOptionalParameterTypes(); Map<String, Type> tOpti = t.getOptionalParameterTypes(); if (tOpti.size() < sOpti.size()) { return false; } Iterator<Entry<String, Type>> tList = tOpti.entrySet().iterator(); Iterator<Entry<String, Type>> sList = sOpti.entrySet().iterator(); while (sList.hasNext()) { if (!tList.hasNext()) { return false; } Entry<String, Type> sEntry = sList.next(); Entry<String, Type> tEntry = tList.next(); if (!isAssignable(tEntry.getValue(), sEntry.getValue())) { return false; } } } Map<String, Type> tNamed = t.getNamedParameterTypes(); Map<String, Type> sNamed = s.getNamedParameterTypes(); if (tNamed.isEmpty() && !sNamed.isEmpty()) { return false; } // T's named parameters must be in the same order and assignable to S's but // maybe a superset. if (!sNamed.isEmpty()) { LinkedHashMap<String, Type> tMap = (LinkedHashMap<String, Type>) (tNamed); LinkedHashMap<String, Type> sMap = (LinkedHashMap<String, Type>) (sNamed); if (!tMap.keySet().containsAll(sMap.keySet())) { return false; } for (Entry<String, Type> entry : sMap.entrySet()) { String name = entry.getKey(); Type sType = sMap.get(name); Type tType = tMap.get(name); if (!isAssignable(tType, sType)) { return false; } } // Iterator<Entry<String, Type>> tList = tMap.entrySet().iterator(); // Iterator<Entry<String, Type>> sList = sMap.entrySet().iterator(); // // t named parameters must start with the named parameters of s // while (sList.hasNext()) { // if (!tList.hasNext()) { // return false; // } // Entry<String, Type> sEntry = sList.next(); // Entry<String, Type> tEntry = tList.next(); // if (!sEntry.getKey().equals(tEntry.getKey())) { // return false; // } // // Classic: parameter types are contravariant; Dart: assignable. // if (!isAssignable(tEntry.getValue(), sEntry.getValue())) { // return false; // } // } } // Classic: parameter types are contravariant; Dart: assignable. return areAssignable(s.getParameterTypes().iterator(), t.getParameterTypes().iterator()); }
private JSTypes(boolean inCompatibilityMode) { Map<String, JSType> types = JSType.createScalars(this); this.BOOLEAN = Preconditions.checkNotNull(types.get("BOOLEAN")); this.BOTTOM = Preconditions.checkNotNull(types.get("BOTTOM")); this.FALSE_TYPE = Preconditions.checkNotNull(types.get("FALSE_TYPE")); this.FALSY = Preconditions.checkNotNull(types.get("FALSY")); this.NULL = Preconditions.checkNotNull(types.get("NULL")); this.NUMBER = Preconditions.checkNotNull(types.get("NUMBER")); this.STRING = Preconditions.checkNotNull(types.get("STRING")); this.TOP = Preconditions.checkNotNull(types.get("TOP")); this.TOP_SCALAR = Preconditions.checkNotNull(types.get("TOP_SCALAR")); this.TRUE_TYPE = Preconditions.checkNotNull(types.get("TRUE_TYPE")); this.TRUTHY = Preconditions.checkNotNull(types.get("TRUTHY")); this.UNDEFINED = Preconditions.checkNotNull(types.get("UNDEFINED")); this.UNKNOWN = Preconditions.checkNotNull(types.get("UNKNOWN")); this.UNDEFINED_OR_BOOLEAN = Preconditions.checkNotNull(types.get("UNDEFINED_OR_BOOLEAN")); this.UNDEFINED_OR_NUMBER = Preconditions.checkNotNull(types.get("UNDEFINED_OR_NUMBER")); this.UNDEFINED_OR_STRING = Preconditions.checkNotNull(types.get("UNDEFINED_OR_STRING")); this.NULL_OR_BOOLEAN = Preconditions.checkNotNull(types.get("NULL_OR_BOOLEAN")); this.NULL_OR_NUMBER = Preconditions.checkNotNull(types.get("NULL_OR_NUMBER")); this.NULL_OR_STRING = Preconditions.checkNotNull(types.get("NULL_OR_STRING")); this.NULL_OR_UNDEFINED = Preconditions.checkNotNull(types.get("NULL_OR_UNDEFINED")); this.NUMBER_OR_STRING = Preconditions.checkNotNull(types.get("NUMBER_OR_STRING")); Map<String, FunctionType> functions = FunctionType.createInitialFunctionTypes(this); this.QMARK_FUNCTION = Preconditions.checkNotNull(functions.get("QMARK_FUNCTION")); this.BOTTOM_FUNCTION = Preconditions.checkNotNull(functions.get("BOTTOM_FUNCTION")); this.TOP_FUNCTION = Preconditions.checkNotNull(functions.get("TOP_FUNCTION")); this.LOOSE_TOP_FUNCTION = Preconditions.checkNotNull(functions.get("LOOSE_TOP_FUNCTION")); this.BOTTOM_PROPERTY_MAP = PersistentMap.of("_", Property.make(this.BOTTOM, this.BOTTOM)); this.allowMethodsAsFunctions = inCompatibilityMode; this.looseSubtypingForLooseObjects = inCompatibilityMode; this.bivariantArrayGenerics = inCompatibilityMode; this.MAP_TO_UNKNOWN = new Map<String, JSType>() { @Override public void clear() { throw new UnsupportedOperationException(); } @Override public boolean containsKey(Object k) { return true; } @Override public boolean containsValue(Object v) { return v == UNKNOWN; } @Override public Set<Map.Entry<String, JSType>> entrySet() { throw new UnsupportedOperationException(); } @Override public JSType get(Object k) { return UNKNOWN; } @Override public boolean isEmpty() { return false; } @Override public Set<String> keySet() { throw new UnsupportedOperationException(); } @Override public JSType put(String k, JSType v) { throw new UnsupportedOperationException(); } @Override public void putAll(Map<? extends String, ? extends JSType> m) { throw new UnsupportedOperationException(); } @Override public JSType remove(Object k) { throw new UnsupportedOperationException(); } @Override public int size() { throw new UnsupportedOperationException(); } @Override public Collection<JSType> values() { return ImmutableSet.of(UNKNOWN); } @Override public int hashCode() { throw new UnsupportedOperationException(); } @Override public boolean equals(Object o) { return o == this; } }; }
static ObjectType fromFunction(FunctionType fn, NominalType fnNominal) { return ObjectType.makeObjectType(fnNominal, null, fn, fn.isLoose(), ObjectKind.UNRESTRICTED); }
ObjectType withFunction(FunctionType ft, NominalType fnNominal) { Preconditions.checkState(!this.isLoose); Preconditions.checkState(!ft.isLoose() || ft.isQmarkFunction()); return makeObjectType(fnNominal, this.props, ft, false, this.objectKind); }