public static void checkGenericType(TreeLogger logger, JClassType type) throws UnableToCompleteException { if (type.isGenericType() != null) { logger.log( Type.ERROR, "Type " + type.getParameterizedQualifiedSourceName() + "is parameterizied generic. RPC proxy " + "for parameterizied types is not supported."); throw new UnableToCompleteException(); } }
private void emitBody(SourceWriter w) throws NotFoundException { JClassType baseClass = context_.getTypeOracle().getType("org.rstudio.core.client.js.JsObjectInjector"); JClassType c = baseType_.asParameterizationOf(baseClass.isGenericType()); JType typeToInject = c.isParameterized().getTypeArgs()[0]; w.print("public native final void injectObject("); w.print(typeToInject.getQualifiedSourceName()); w.println(" value) /*-{"); w.indent(); w.println(baseExpression_ + " = {"); w.indent(); JMethod[] methods = typeToInject.isClassOrInterface().getMethods(); for (int i = 0; i < methods.length; i++) { JMethod method = methods[i]; final JParameter[] jParameters = method.getParameters(); StringBuilder argString = new StringBuilder(); for (int j = 0; j < jParameters.length; j++) { argString.append("_").append(j); if (j < jParameters.length - 1) argString.append(", "); } w.println(method.getName() + ": function(" + argString + ") {"); w.indent(); if (!method.getReturnType().getQualifiedSourceName().equals("void")) w.print("return "); w.print("value.@"); w.print(typeToInject.getQualifiedSourceName()); w.print("::"); w.print(method.getName()); w.print("("); for (JParameter param : jParameters) w.print(param.getType().getJNISignature()); w.print(")("); w.print(argString.toString()); w.println(");"); w.outdent(); w.print("}"); w.println((i < methods.length - 1) ? "," : ""); } w.outdent(); w.println("};"); w.outdent(); w.println("}-*/;"); }
/** * Returns <code>true</code> if the lhs and rhs are assignable without consideration of the * supertypes of the rhs. * * @param lhsType * @param rhsType * @return true if rhsType can be assigned to lhsType */ private static boolean areClassTypesAssignableNoSupers(JClassType lhsType, JClassType rhsType) { if (lhsType == rhsType) { // Done, these are the same types. return true; } if (lhsType == lhsType.getOracle().getJavaLangObject()) { // Done, any type can be assigned to object. return true; } /* * Get the generic base type, if there is one, for the lhs type and convert * it to a raw type if it is generic. */ if (lhsType.isGenericType() != null) { lhsType = lhsType.isGenericType().getRawType(); } if (rhsType.isGenericType() != null) { // Treat the generic rhs type as a raw type. rhsType = rhsType.isGenericType().getRawType(); } // Check for JTypeParameters. JTypeParameter lhsTypeParam = lhsType.isTypeParameter(); JTypeParameter rhsTypeParam = rhsType.isTypeParameter(); if (lhsTypeParam != null) { JClassType[] lhsTypeBounds = lhsTypeParam.getBounds(); for (JClassType lhsTypeBound : lhsTypeBounds) { if (!areClassTypesAssignable(lhsTypeBound, rhsType)) { // Done, the rhsType was not assignable to one of the bounds. return false; } } // Done, the rhsType was assignable to all of the bounds. return true; } else if (rhsTypeParam != null) { JClassType[] possibleSubtypeBounds = rhsTypeParam.getBounds(); for (JClassType possibleSubtypeBound : possibleSubtypeBounds) { if (areClassTypesAssignable(lhsType, possibleSubtypeBound)) { // Done, at least one bound is assignable to this type. return true; } } return false; } /* * Check for JWildcards. We have not examined this part in great detail * since there should not be top level wildcard types. */ JWildcardType lhsWildcard = lhsType.isWildcard(); JWildcardType rhsWildcard = rhsType.isWildcard(); if (lhsWildcard != null && rhsWildcard != null) { // Both types are wildcards. return areWildcardsAssignable(lhsWildcard, rhsWildcard); } else if (lhsWildcard != null) { // The lhs type is a wildcard but the rhs is not. // ? extends T, U OR ? super T, U JClassType[] lowerBounds = lhsWildcard.getLowerBounds(); if (lowerBounds.length > 0) { // ? super T will reach object no matter what the rhs type is return true; } else { return areClassTypesAssignable(lhsWildcard.getFirstBound(), rhsType); } } // Check for JArrayTypes. JArrayType lhsArray = lhsType.isArray(); JArrayType rhsArray = rhsType.isArray(); if (lhsArray != null) { if (rhsArray == null) { return false; } else { return areArraysAssignable(lhsArray, rhsArray); } } else if (rhsArray != null) { // Safe although perhaps not necessary return false; } // Check for JParameterizedTypes and JRawTypes. JMaybeParameterizedType lhsMaybeParameterized = lhsType.isMaybeParameterizedType(); JMaybeParameterizedType rhsMaybeParameterized = rhsType.isMaybeParameterizedType(); if (lhsMaybeParameterized != null && rhsMaybeParameterized != null) { if (lhsMaybeParameterized.getBaseType() == rhsMaybeParameterized.getBaseType()) { if (lhsMaybeParameterized.isRawType() != null || rhsMaybeParameterized.isRawType() != null) { /* * Any raw type can be assigned to or from any parameterization of its * generic type. */ return true; } assert (lhsMaybeParameterized.isRawType() == null && rhsMaybeParameterized.isRawType() == null); JParameterizedType lhsParameterized = lhsMaybeParameterized.isParameterized(); JParameterizedType rhsParameterized = rhsMaybeParameterized.isParameterized(); assert (lhsParameterized != null && rhsParameterized != null); return areTypeArgumentsAssignable(lhsParameterized, rhsParameterized); } } // Default to not being assignable. return false; }