Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -213,13 +213,20 @@ private String getStringRepresentation(Set<String> attributes) {
buffer.append('(').append(PropertyAnnotation.toAttributeString(attributes)).append(") ");
}

String objcType = nameTable.getObjCType(varType);
TypeElement declaringClass = ElementUtil.getDeclaringClass(varElement);
boolean allowGenerics = !typeUtil.isProtoClass(varType);
boolean enableGenerics =
allowGenerics
&& (options.asObjCGenericDecl()
|| TypeUtil.hasGenerateObjectiveCGenerics(varType)
|| (declaringClass != null
&& TypeUtil.hasGenerateObjectiveCGenerics(declaringClass)));
String objcType = nameTable.getObjCTypeDeclaration(varType, enableGenerics, declaringClass);
buffer.append(objcType);
if (!objcType.endsWith("*")) {
buffer.append(' ');
}
buffer.append(propertyName);
TypeElement declaringClass = ElementUtil.getDeclaringClass(varElement);
boolean inSwiftNameContext =
declaringClass != null
&& (nameTable.packageHasSwiftNameAnnotation(declaringClass)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,11 @@ protected void printInterfaceGenerics() {
if (generateObjectiveCGenerics(typeElement.asType())) {
List<String> genericNames = nameTable.getClassObjCGenericTypeNames(typeElement.asType());
if (!genericNames.isEmpty()) {
printf("<%s>", String.join(", ", genericNames));
List<String> covariantNames = new java.util.ArrayList<>();
for (String name : genericNames) {
covariantNames.add("__covariant " + name);
}
printf("<%s>", String.join(", ", covariantNames));
}
}
}
Expand Down Expand Up @@ -579,10 +583,22 @@ protected void printStaticFieldDeclaration(
private void printStaticFieldFullDeclaration(VariableDeclarationFragment fragment) {
VariableElement var = fragment.getVariableElement();
boolean isVolatile = ElementUtil.isVolatile(var);
String objcType = nameTable.getObjCTypeDeclaration(var.asType());
String objcTypePadded = paddedType(objcType, var);
String declType = paddedType(getDeclarationType(var), var);
boolean allowGenerics = !typeUtil.isProtoClass(var.asType());
boolean enableGenerics =
allowGenerics
&& (generateObjectiveCGenerics(var.asType())
|| generateObjectiveCGenerics(typeElement.asType()));
String objcType = nameTable.getObjCTypeDeclaration(var.asType(), enableGenerics, typeElement);
String declType = getDeclarationType(var);
String name = nameTable.getVariableShortName(var);
if (objcType.contains(",")) {
String typedefName = typeName + "_" + name + "_typedef";
printf("typedef %s %s;\n", objcType, typedefName);
objcType = typedefName;
declType = typedefName;
}
String objcTypePadded = paddedType(objcType, var);
declType = paddedType(declType, var);
boolean isFinal = ElementUtil.isFinal(var);
boolean isPrimitive = var.asType().getKind().isPrimitive();
boolean isConstant = ElementUtil.isPrimitiveConstant(var);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,13 @@ protected String getDeclarationType(VariableElement var) {
if (ElementUtil.isVolatile(var)) {
return "volatile_" + NameTable.getPrimitiveObjCType(type);
} else {
return nameTable.getObjCType(type);
boolean allowGenerics = !typeUtil.isProtoClass(type);
boolean enableGenerics =
allowGenerics
&& ElementUtil.isStatic(var)
&& (generateObjectiveCGenerics(type)
|| generateObjectiveCGenerics(typeElement.asType()));
return nameTable.getObjCTypeDeclaration(type, enableGenerics, typeElement);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,15 +297,21 @@ private void printStaticFieldExterns() {
}
for (VariableDeclarationFragment fragment : getStaticFields()) {
VariableElement var = fragment.getVariableElement();
String objcTypePadded = paddedType(nameTable.getObjCTypeDeclaration(var.asType()), var);
boolean allowGenerics = !typeUtil.isProtoClass(var.asType());
boolean enableGenerics =
allowGenerics
&& (generateObjectiveCGenerics(var.asType())
|| generateObjectiveCGenerics(typeElement.asType()));
String objcType = nameTable.getObjCTypeDeclaration(var.asType(), enableGenerics, typeElement);
String objcTypePadded = paddedType(objcType, var);
String name = nameTable.getVariableShortName(var);
newline();
printf("extern %s%s_get_%s(void);\n", objcTypePadded, typeName, name);
if (!ElementUtil.isFinal(var)) {
printf("extern %s%s_set_%s(%svalue);\n", objcTypePadded, typeName, name, objcTypePadded);
if (var.asType().getKind().isPrimitive() && !ElementUtil.isVolatile(var)) {
String objcType = nameTable.getObjCTypeDeclaration(var.asType());
printf("extern %s *%s_getRef_%s(void);\n", objcType, typeName, name);
String primitiveType = nameTable.getObjCTypeDeclaration(var.asType());
printf("extern %s *%s_getRef_%s(void);\n", primitiveType, typeName, name);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,25 @@ private void maybeAddCast(Expression expr, TypeMirror expectedType, boolean shou
}
}

private boolean isObjcGenericAssignable(TypeMirror t1, TypeMirror t2) {
if (t1 instanceof DeclaredType && t2 instanceof DeclaredType) {
DeclaredType dt1 = (DeclaredType) t1;
DeclaredType dt2 = (DeclaredType) t2;
List<? extends TypeMirror> args1 = dt1.getTypeArguments();
List<? extends TypeMirror> args2 = dt2.getTypeArguments();
if (args1.size() == args2.size() && !args1.isEmpty()) {
for (int i = 0; i < args1.size(); i++) {
TypeMirror arg1 = args1.get(i);
TypeMirror arg2 = args2.get(i);
if (!typeUtil.isObjcAssignable(arg1, arg2) || !isObjcGenericAssignable(arg1, arg2)) {
return false;
}
}
}
}
return true;
}

private boolean needsCast(Expression expr, TypeMirror expectedType, boolean shouldCastFromId) {
TypeMirror declaredType = getDeclaredType(expr);
if (declaredType == null) {
Expand All @@ -203,6 +222,12 @@ private boolean needsCast(Expression expr, TypeMirror expectedType, boolean shou
// expected type, then the compiler already has sufficient type info.
|| typeUtil.isObjcAssignable(declaredType, exprType)
|| (expectedType != null && typeUtil.isObjcAssignable(declaredType, expectedType))) {
if (options.asObjCGenericDecl()) {
if (!isObjcGenericAssignable(declaredType, exprType)
|| (expectedType != null && !isObjcGenericAssignable(declaredType, expectedType))) {
return true;
}
}
return false;
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.google.devtools.j2objc.ast.FieldDeclaration;
import com.google.devtools.j2objc.ast.FunctionDeclaration;
import com.google.devtools.j2objc.ast.MethodDeclaration;
import com.google.devtools.j2objc.ast.PackageDeclaration;
import com.google.devtools.j2objc.ast.RecordDeclaration;
import com.google.devtools.j2objc.ast.SingleVariableDeclaration;
import com.google.devtools.j2objc.ast.Type;
Expand Down Expand Up @@ -123,6 +124,61 @@ private void addForwardDecl(TypeMirror type) {
forwardDecls.addAll(Sets.difference(Import.getImports(type, unit.getEnv()), declaredTypes));
}

private boolean isCoreJrePackage(String name) {
if (name.startsWith("java.")) {
return true;
}
if (name.startsWith("javax.")) {
return name.startsWith("javax.crypto.")
|| name.equals("javax.crypto")
|| name.startsWith("javax.net.")
|| name.equals("javax.net")
|| name.startsWith("javax.security.")
|| name.equals("javax.security")
|| name.startsWith("javax.xml.")
|| name.equals("javax.xml");
}
return name.startsWith("android.")
|| name.equals("android")
|| name.startsWith("org.xml.")
|| name.equals("org.xml")
|| name.startsWith("org.w3c.")
|| name.equals("org.w3c")
|| name.startsWith("org.json.")
|| name.equals("org.json");
}

private boolean isJreType(Import imp) {
String qName = imp.getJavaQualifiedName();
if (qName == null) {
return false;
}
return isCoreJrePackage(qName);
}

private boolean isCurrentUnitJre() {
PackageDeclaration pkg = unit.getPackage();
if (pkg == null || pkg.isDefaultPackage()) {
return false;
}
String pkgName = pkg.getName().getFullyQualifiedName();
return isCoreJrePackage(pkgName);
}

private void addGenericParameter(TypeMirror type) {
if (isCurrentUnitJre()) {
addForwardDecl(type);
return;
}
for (Import imp : Import.getImports(type, unit.getEnv())) {
if (isJreType(imp)) {
superTypes.add(imp);
} else {
forwardDecls.add(imp);
}
}
}

private void addSuperType(TypeElement type) {
if (type != null) {
Import.addImports(type.asType(), superTypes, unit.getEnv());
Expand All @@ -145,6 +201,9 @@ public boolean visit(AnnotationTypeMemberDeclaration node) {
public boolean visit(FieldDeclaration node) {
if (filter.include(node) && includeInnerTypes) {
addForwardDecl(node.getTypeMirror());
for (TypeMirror fieldGeneric : objCForwardDeclaredGenericParameters(node.getTypeMirror())) {
addGenericParameter(fieldGeneric);
}
}
return false;
}
Expand Down Expand Up @@ -174,13 +233,13 @@ public boolean visit(FunctionDeclaration node) {
addForwardDecl(node.getReturnType());
for (TypeMirror returnGeneric :
objCForwardDeclaredGenericParameters(node.getReturnType().getTypeMirror())) {
addForwardDecl(returnGeneric);
addGenericParameter(returnGeneric);
}
for (SingleVariableDeclaration param : node.getParameters()) {
addForwardDecl(param.getVariableElement().asType());
for (TypeMirror paramGeneric :
objCForwardDeclaredGenericParameters(param.getVariableElement().asType())) {
addForwardDecl(paramGeneric);
addGenericParameter(paramGeneric);
}
}
}
Expand All @@ -193,12 +252,12 @@ public boolean visit(MethodDeclaration node) {
addForwardDecl(node.getReturnTypeMirror());
for (TypeMirror returnGeneric :
objCForwardDeclaredGenericParameters(node.getReturnTypeMirror())) {
addForwardDecl(returnGeneric);
addGenericParameter(returnGeneric);
}
for (VariableElement param : node.getExecutableElement().getParameters()) {
addForwardDecl(param.asType());
for (TypeMirror paramGeneric : objCForwardDeclaredGenericParameters(param.asType())) {
addForwardDecl(paramGeneric);
addGenericParameter(paramGeneric);
}
}
}
Expand Down
Loading