Skip to content

Commit

Permalink
Added support for propagating deprecated annotations.
Browse files Browse the repository at this point in the history
Added a flag to j2objc to enable deprecated attribute generation.
Downgraded deprecated warning currently promoted to error back down to warning to avoid breaking the existing builds.
	Change on 2013/03/20 by gridman <gridman@google.com>
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=44206226
  • Loading branch information
tomball committed Apr 10, 2013
1 parent 8add023 commit d1b630e
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 0 deletions.
3 changes: 3 additions & 0 deletions doc/man/j2objc.1
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ Specify a ProGuard usage report for dead code elimination.
\fB\-\-no\-inline\-field\-access\fR
Turn off in\-lining of generated field accessors.
.TP
\fB\-\-generate\-deprecated\fR
Generate deprecated attributes for deprecated methods, classes, and interfaces.
.TP
\fB\-\-no\-generate\-test\-main\fR
Turn off automatically generated main method for JUnit tests.
.TP
Expand Down
17 changes: 17 additions & 0 deletions translator/src/main/java/com/google/devtools/j2objc/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public class Options {
private static MemoryManagementOption memoryManagementOption = null;
private static boolean emitLineDirectives = false;
private static boolean warningsAsErrors = false;
private static boolean deprecatedDeclarations = false;
private static boolean inlineFieldAccess = true;
private static Map<String, String> methodMappings = Maps.newLinkedHashMap();
private static boolean generateTestMain = true;
Expand Down Expand Up @@ -213,6 +214,8 @@ public static String[] load(String[] args) throws IOException {
emitLineDirectives = true;
} else if (arg.equals("-Werror")) {
warningsAsErrors = true;
} else if (arg.equals("--generate-deprecated")) {
deprecatedDeclarations = true;
} else if (arg.equals("-q") || arg.equals("--quiet")) {
logger.setLevel(Level.WARNING);
} else if (arg.equals("-t") || arg.equals("--timing-info")) {
Expand Down Expand Up @@ -450,6 +453,20 @@ public static boolean treatWarningsAsErrors() {
return warningsAsErrors;
}

@VisibleForTesting
public static void enableDeprecatedDeclarations() {
deprecatedDeclarations = true;
}

@VisibleForTesting
public static void resetDeprecatedDeclarations() {
deprecatedDeclarations = false;
}

public static boolean generateDeprecatedDeclarations() {
return deprecatedDeclarations;
}

public static Map<String, String> getMethodMappings() {
return methodMappings;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,19 @@

import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IExtendedModifier;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
Expand All @@ -62,6 +65,8 @@
*/
public class ObjectiveCHeaderGenerator extends ObjectiveCSourceFileGenerator {

private static final String DEPRECATED_ATTRIBUTE = "__attribute__((deprecated))";

/**
* Generate an Objective-C header file for each type declared in a specified
* compilation unit.
Expand Down Expand Up @@ -106,6 +111,14 @@ public void generate(TypeDeclaration node) {

printConstantDefines(node);

if (Options.generateDeprecatedDeclarations()) {
@SuppressWarnings("unchecked")
List<IExtendedModifier> modifiers = node.modifiers();
if (hasDeprecated(modifiers)) {
println(DEPRECATED_ATTRIBUTE);
}
}

if (isInterface) {
printf("@protocol %s", typeName);
} else {
Expand Down Expand Up @@ -275,6 +288,15 @@ protected String methodDeclaration(MethodDeclaration m) {
return "";
}
String result = super.methodDeclaration(m);

if (Options.generateDeprecatedDeclarations()) {
@SuppressWarnings("unchecked")
List<IExtendedModifier> modifiers = m.modifiers();
if (hasDeprecated(modifiers)) {
result += " " + DEPRECATED_ATTRIBUTE;
}
}

return result + ";\n";
}

Expand Down Expand Up @@ -668,4 +690,26 @@ private String accessScope(int modifiers) {
}
return "@package";
}

/**
* Checks if the list of modifiers contains a Deprecated annotation.
*
* @param modifiers extended modifiers
* @return true if the list has {@link Deprecated @Deprecated}, false otherwise
*/
boolean hasDeprecated(List<IExtendedModifier> modifiers) {
for (IExtendedModifier modifier : modifiers) {
if (modifier.isAnnotation()) {
Annotation annotation = (Annotation) modifier;
Name annotationTypeName = annotation.getTypeName();
String expectedTypeName = annotationTypeName.isQualifiedName() ?
"java.lang.Deprecated" : "Deprecated";
if (expectedTypeName.equals(annotationTypeName.getFullyQualifiedName())) {
return true;
}
}
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ where possible options include:\n\
--mapping <file> Add a method mapping file\n\
--dead-code-report <file> Specify a ProGuard usage report for dead code elimination\n\
--mem-debug Generate code to display memory allocation graphs\n\
--generate-deprecated Generate deprecated attributes for deprecated methods,\
\n classes and interfaces.\n\
--generate-native-stubs Generate method bodies for native methods that do not have\
\n OCNI native code comments\
--no-inline-field-access Turn off in-lining of generated field accessors.\n\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.google.devtools.j2objc.gen;

import com.google.devtools.j2objc.GenerationTest;
import com.google.devtools.j2objc.Options;
import com.google.devtools.j2objc.util.NameTable;

import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
Expand All @@ -34,6 +35,12 @@
*/
public class ObjectiveCHeaderGeneratorTest extends GenerationTest {

@Override
protected void tearDown() throws Exception {
super.tearDown();
Options.resetDeprecatedDeclarations();
}

public void testInnerEnumWithPackage() throws IOException {
String translation = translateSourceFile(
"package mypackage;" +
Expand All @@ -54,6 +61,26 @@ public void testTypeNameTranslation() throws IOException {
assertTranslation(translation, "@interface Example ");
}

public void testDeprecatedTypeNameTranslation() throws IOException {
Options.enableDeprecatedDeclarations();
String translation = translateSourceFile(
"public @Deprecated class Example {}", "Example", "Example.h");
assertTranslation(translation, "__attribute__((deprecated))\n@interface Example ");
}

public void testDeprecatedTypeNameTranslationIsTurnedOff() throws IOException {
String translation = translateSourceFile(
"public @Deprecated class Example {}", "Example", "Example.h");
assertFalse(translation.contains("__attribute__((deprecated))"));
}

public void testFullyQualifiedDeprecatedTypeNameTranslation() throws IOException {
Options.enableDeprecatedDeclarations();
String translation = translateSourceFile(
"public @java.lang.Deprecated class Example {}", "Example", "Example.h");
assertTranslation(translation, "__attribute__((deprecated))\n@interface Example ");
}

public void testPackageTypeNameTranslation() throws IOException {
String translation = translateSourceFile(
"package unit.test; public class Example {}", "Example", "unit/test/Example.h");
Expand Down Expand Up @@ -111,13 +138,30 @@ public void testInterfaceTranslation() throws IOException {
assertTranslation(translation, "@protocol UnitTestExample");
}

public void testDeprecatedInterfaceTranslation() throws IOException {
Options.enableDeprecatedDeclarations();
String translation = translateSourceFile(
"package unit.test; public @Deprecated interface Example {}",
"Example", "unit/test/Example.h");
assertTranslation(translation, "__attribute__((deprecated))\n@protocol UnitTestExample");
}

public void testInterfaceWithMethodTranslation() throws IOException {
String translation = translateSourceFile(
"package unit.test; public interface Example { Example getExample(); }",
"Example", "unit/test/Example.h");
assertTranslation(translation, "(id<UnitTestExample>)getExample;");
}

public void testInterfaceWithDeprecatedMethodTranslation() throws IOException {
Options.enableDeprecatedDeclarations();
String translation = translateSourceFile(
"package unit.test; public interface Example { @Deprecated Example getExample(); }",
"Example", "unit/test/Example.h");
assertTranslation(translation,
"- (id<UnitTestExample>)getExample __attribute__((deprecated));");
}

public void testSuperInterfaceTranslation() throws IOException {
String translation = translateSourceFile(
"package unit.test; public interface Example extends Bar {} interface Bar {}",
Expand Down

0 comments on commit d1b630e

Please sign in to comment.