Skip to content

Commit fa7f2e0

Browse files
tomballcopybara-github
authored andcommitted
Generates code to reference protocol shadow classes from classes that implement the protocols. This allows access to protocol reflection metadata when app is built without -ObjC flag.
PiperOrigin-RevId: 628159766
1 parent 72835e4 commit fa7f2e0

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

translator/src/main/java/com/google/devtools/j2objc/Options.java

+12
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ public class Options {
111111
private boolean linkSourcePathHeaders = false;
112112
private boolean javacWarnings = true;
113113
private boolean stripReflectionErrors = false;
114+
private boolean linkProtocols = false;
114115

115116
private Mappings mappings = new Mappings();
116117
private FileUtil fileUtil = new FileUtil();
@@ -417,6 +418,8 @@ private void processArg(Iterator<String> args) throws IOException {
417418
headerMap.setIncludeGeneratedSources();
418419
} else if (arg.equals("-Xpublic-hdrs")) {
419420
fileUtil.setHeaderOutputDirectory(new File(getArgValue(args, arg)));
421+
} else if (arg.equals("-Xlink-protocols")) {
422+
linkProtocols = true;
420423
} else if (arg.equals("-use-arc")) {
421424
checkMemoryManagementOption(MemoryManagementOption.ARC);
422425
} else if (arg.equals("-Xstrict-field-assign")) {
@@ -1294,4 +1297,13 @@ public void setStripReflectionErrors(boolean b) {
12941297
public boolean stripReflectionErrors() {
12951298
return stripReflectionErrors;
12961299
}
1300+
1301+
public boolean linkProtocols() {
1302+
return linkProtocols;
1303+
}
1304+
1305+
@VisibleForTesting
1306+
public void setLinkProtocols(boolean b) {
1307+
linkProtocols = b;
1308+
}
12971309
}

translator/src/main/java/com/google/devtools/j2objc/gen/TypeImplementationGenerator.java

+21
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@
3030
import com.google.devtools.j2objc.ast.VariableDeclarationFragment;
3131
import com.google.devtools.j2objc.util.ElementUtil;
3232
import com.google.devtools.j2objc.util.NameTable;
33+
import com.google.devtools.j2objc.util.TranslationUtil;
3334
import com.google.devtools.j2objc.util.TypeUtil;
3435
import com.google.j2objc.annotations.Property;
3536
import java.lang.reflect.Modifier;
3637
import java.nio.file.Path;
3738
import java.nio.file.Paths;
39+
import java.util.ArrayList;
3840
import java.util.Iterator;
3941
import java.util.List;
4042
import java.util.Optional;
@@ -116,6 +118,7 @@ protected void generate() {
116118
printStaticAccessors();
117119
printInnerDeclarations();
118120
printInitializeMethod();
121+
printLinkProtocolsMethod();
119122
println("\n@end");
120123
}
121124

@@ -266,6 +269,24 @@ private void printTypeLiteralImplementation() {
266269
}
267270
}
268271

272+
private void printLinkProtocolsMethod() {
273+
if (!options.linkProtocols() || options.stripReflection()) {
274+
return;
275+
}
276+
List<String> interfaceNames = new ArrayList<>();
277+
for (TypeElement intrface : TranslationUtil.getInterfaceTypes(typeNode)) {
278+
interfaceNames.add(nameTable.getFullName(intrface));
279+
}
280+
if (!interfaceNames.isEmpty()) {
281+
newline();
282+
printf("+ (void)__linkProtocols {\n");
283+
for (String name : interfaceNames) {
284+
printf(" %s_class_();\n", NameTable.camelCaseQualifiedName(name));
285+
}
286+
printf("}\n");
287+
}
288+
}
289+
269290
private void printNameMapping() {
270291
if (!options.stripNameMapping()) {
271292
Optional<String> mapping = nameTable.getNameMapping(typeElement, typeName);

translator/src/test/java/com/google/devtools/j2objc/gen/TypeImplementationGeneratorTest.java

+11
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,15 @@ public void testSynthesizeProperties() throws IOException {
222222
assertTranslation(translation, "@synthesize foo = foo_;");
223223
assertNotInTranslation(translation, "@synthesize bar");
224224
}
225+
226+
public void testLinkProtocolsFunctions() throws IOException {
227+
options.setLinkProtocols(true);
228+
String source =
229+
"import java.io.Serializable;\n"
230+
+ "class Test implements Runnable, Serializable { public void run() {} }";
231+
String translation = translateSourceFile(source, "Test", "Test.m");
232+
assertTranslation(translation, "+ (void)__linkProtocols {");
233+
assertTranslation(translation, "JavaIoSerializable_class_();");
234+
assertTranslation(translation, "JavaLangRunnable_class_();");
235+
}
225236
}

0 commit comments

Comments
 (0)