continue Firefox RDP

This commit is contained in:
Vladimir Krivosheev
2014-10-28 09:17:09 +01:00
parent 2c3e37ab0f
commit d679f53a3b
9 changed files with 73 additions and 78 deletions
@@ -10,22 +10,17 @@ import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.*;
class FieldProcessor<T> {
private final Class<T> typeClass;
final class FieldProcessor<T> {
private final List<FieldLoader> fieldLoaders = new ArrayList<>(2);
private final LinkedHashMap<Method, MethodHandler> methodHandlerMap = new LinkedHashMap<>();
private final List<VolatileFieldBinding> volatileFields = new ArrayList<>(2);
boolean lazyRead;
private final InterfaceReader reader;
FieldProcessor(InterfaceReader reader, Class<T> typeClass) {
this.typeClass = typeClass;
FieldProcessor(@NotNull InterfaceReader reader, @NotNull Class<T> typeClass) {
this.reader = reader;
}
void go() {
Method[] methods = typeClass.getDeclaredMethods();
Method[] methods = typeClass.getMethods();
// todo sort by source location
Arrays.sort(methods, new Comparator<Method>() {
@Override
@@ -34,58 +29,77 @@ class FieldProcessor<T> {
}
});
for (Method m : methods) {
Package aPackage = typeClass.getPackage();
for (Method method : methods) {
Class<?> methodClass = method.getDeclaringClass();
// use method from super if super located in the same package
if (methodClass != typeClass && methodClass.getPackage() != aPackage) {
continue;
}
if (method.getParameterTypes().length != 0) {
throw new JsonProtocolModelParseException("No parameters expected in " + method);
}
try {
processMethod(m);
String fieldName = checkAndGetJsonFieldName(method);
MethodHandler methodHandler;
JsonSubtypeCasting jsonSubtypeCaseAnnotation = method.getAnnotation(JsonSubtypeCasting.class);
if (jsonSubtypeCaseAnnotation != null) {
methodHandler = processManualSubtypeMethod(method, jsonSubtypeCaseAnnotation);
lazyRead = true;
}
else {
methodHandler = processFieldGetterMethod(method, fieldName);
}
methodHandlerMap.put(method, methodHandler);
}
catch (JsonProtocolModelParseException e) {
throw new JsonProtocolModelParseException("Problem with method " + m, e);
throw new JsonProtocolModelParseException("Problem with method " + method, e);
}
}
}
private void processMethod(Method m) {
if (m.getParameterTypes().length != 0) {
throw new JsonProtocolModelParseException("No parameters expected in " + m);
}
String fieldName = checkAndGetJsonFieldName(m);
MethodHandler methodHandler;
JsonSubtypeCasting jsonSubtypeCaseAnnotation = m.getAnnotation(JsonSubtypeCasting.class);
if (jsonSubtypeCaseAnnotation != null) {
methodHandler = processManualSubtypeMethod(m, jsonSubtypeCaseAnnotation);
lazyRead = true;
}
else {
methodHandler = processFieldGetterMethod(m, fieldName);
}
methodHandlerMap.put(m, methodHandler);
}
private MethodHandler processFieldGetterMethod(Method m, String fieldName) {
Type genericReturnType = m.getGenericReturnType();
private MethodHandler processFieldGetterMethod(@NotNull Method method, @NotNull String fieldName) {
Type genericReturnType = method.getGenericReturnType();
boolean nullable;
if (m.getAnnotation(JsonNullable.class) != null) {
if (method.getAnnotation(JsonNullable.class) != null) {
nullable = true;
}
else if (genericReturnType == String.class || genericReturnType == Enum.class) {
JsonField jsonField = m.getAnnotation(JsonField.class);
JsonField jsonField = method.getAnnotation(JsonField.class);
if (jsonField != null) {
nullable = jsonField.optional() && !jsonField.allowAnyPrimitiveValue() && !jsonField.allowAnyPrimitiveValueAndMap();
}
else {
nullable = m.getAnnotation(JsonOptionalField.class) != null;
nullable = method.getAnnotation(JsonOptionalField.class) != null;
}
}
else {
nullable = false;
}
ValueReader fieldTypeParser = reader.getFieldTypeParser(genericReturnType, nullable, false, m);
ValueReader fieldTypeParser = reader.getFieldTypeParser(genericReturnType, nullable, false, method);
if (fieldTypeParser != InterfaceReader.VOID_PARSER) {
fieldLoaders.add(new FieldLoader(fieldName, fieldTypeParser));
}
return new PreparsedFieldMethodHandler(fieldTypeParser == InterfaceReader.VOID_PARSER ? null : fieldName);
final String effectiveFieldName = fieldTypeParser == InterfaceReader.VOID_PARSER ? null : fieldName;
return new MethodHandler() {
@Override
void writeMethodImplementationJava(@NotNull ClassScope scope, @NotNull Method method, @NotNull TextOutput out) {
if (!nullable) {
out.append("@NotNull").newLine();
}
writeMethodDeclarationJava(out, method);
out.openBlock();
if (effectiveFieldName != null) {
out.append("return ").append(FieldLoader.FIELD_PREFIX).append(effectiveFieldName).semi();
}
out.closeBlock();
}
};
}
private MethodHandler processManualSubtypeMethod(final Method m, JsonSubtypeCasting jsonSubtypeCaseAnn) {
@@ -131,17 +145,18 @@ class FieldProcessor<T> {
return binding;
}
private static String checkAndGetJsonFieldName(Method m) {
if (m.getParameterTypes().length != 0) {
@NotNull
private static String checkAndGetJsonFieldName(@NotNull Method method) {
if (method.getParameterTypes().length != 0) {
throw new JsonProtocolModelParseException("Must have 0 parameters");
}
JsonField fieldAnn = m.getAnnotation(JsonField.class);
if (fieldAnn != null) {
String jsonLiteralName = fieldAnn.jsonLiteralName();
JsonField fieldAnnotation = method.getAnnotation(JsonField.class);
if (fieldAnnotation != null) {
String jsonLiteralName = fieldAnnotation.jsonLiteralName();
if (!jsonLiteralName.isEmpty()) {
return jsonLiteralName;
}
}
return m.getName();
return method.getName();
}
}
@@ -161,8 +161,6 @@ class InterfaceReader {
}
FieldProcessor<T> fields = new FieldProcessor<>(this, typeClass);
fields.go();
LinkedHashMap<Method, MethodHandler> methodHandlerMap = fields.getMethodHandlerMap();
for (Method method : methodHandlerMap.keySet()) {
Class<?> returnType = method.getReturnType();
@@ -14,10 +14,10 @@ import java.util.List;
abstract class MethodHandler {
abstract void writeMethodImplementationJava(ClassScope classScope, Method m, TextOutput out);
protected static void appendMethodSignatureJava(@NotNull Method m, @NotNull List<String> paramNames, @NotNull TextOutput out) {
out.append(m.getName()).append('(');
protected static void appendMethodSignatureJava(@NotNull Method method, @NotNull List<String> paramNames, @NotNull TextOutput out) {
out.append(method.getName()).append('(');
boolean firstArg = true;
Type[] types = m.getGenericParameterTypes();
Type[] types = method.getGenericParameterTypes();
for (int i = 0, length = types.length; i < length; i++) {
Type arg = types[i];
if (firstArg) {
@@ -32,8 +32,8 @@ abstract class MethodHandler {
out.append(')');
}
protected static void writeMethodDeclarationJava(TextOutput out, Method m) {
writeMethodDeclarationJava(out, m, Collections.<String>emptyList());
protected static void writeMethodDeclarationJava(TextOutput out, Method method) {
writeMethodDeclarationJava(out, method, Collections.<String>emptyList());
}
protected static void writeMethodDeclarationJava(@NotNull TextOutput out, @NotNull Method m, @NotNull List<String> paramNames) {
@@ -1,21 +0,0 @@
package org.jetbrains.protocolReader;
import java.lang.reflect.Method;
class PreparsedFieldMethodHandler extends MethodHandler {
private final String fieldName;
PreparsedFieldMethodHandler(String fieldName) {
this.fieldName = fieldName;
}
@Override
void writeMethodImplementationJava(ClassScope scope, Method m, TextOutput out) {
writeMethodDeclarationJava(out, m);
out.openBlock();
if (fieldName != null) {
out.append("return ").append(FieldLoader.FIELD_PREFIX).append(fieldName).semi();
}
out.closeBlock();
}
}
@@ -38,11 +38,13 @@ class PrimitiveValueReader extends ValueReader {
if (asRawString) {
out.append("readRawString(");
addReaderParameter(subtyping, out);
out.append(')');
}
else {
beginReadCall(readPostfix, subtyping, out, fieldName);
ValueReader.addReaderParameter(subtyping, out);
out.append(".next").append(readPostfix).append("()");
//beginReadCall(readPostfix, subtyping, out, fieldName);
}
out.append(')');
}
@Override
@@ -23,7 +23,7 @@ class ReadDelegate {
paramNames = hasNextNameParam ? STATIC_METHOD_PARAM_NAME_LIST2 : STATIC_METHOD_PARAM_NAME_LIST;
}
void write(ClassScope scope, Method method, TextOutput out) {
void write(@NotNull ClassScope scope, @NotNull Method method, @NotNull TextOutput out) {
MethodHandler.writeMethodDeclarationJava(out, method, paramNames);
out.openBlock();
out.append("return ");
@@ -121,6 +121,7 @@ public final class ReaderGenerator {
out.append("// Generated source");
out.newLine().append("package ").append(configuration.packageName).append(';');
out.newLine().newLine().append("import org.jetbrains.jsonProtocol.*;");
out.newLine().newLine().append("import org.jetbrains.annotations.NotNull;");
out.newLine().newLine().append("import static org.jetbrains.jsonProtocol.JsonReaders.*;");
out.newLine().newLine().append("public final class ").append(configuration.className).space();
out.append(configuration.root.getType().isInterface() ? "implements" : "extends").space().append(configuration.root.getType().getCanonicalName()).openBlock(false);
@@ -94,11 +94,11 @@ class ReaderRoot<R> {
return rootClass;
}
public void writeStaticMethodJava(ClassScope scope) {
public void writeStaticMethodJava(@NotNull ClassScope scope) {
TextOutput out = scope.getOutput();
for (Map.Entry<Method, ReadDelegate> en : methodMap.entrySet()) {
for (Map.Entry<Method, ReadDelegate> entry : methodMap.entrySet()) {
out.newLine();
en.getValue().write(scope, en.getKey(), out);
entry.getValue().write(scope, entry.getKey(), out);
out.newLine();
}
}
@@ -93,9 +93,9 @@ class TypeHandler<T> {
subtypeAspect.writeParseMethod(valueImplClassName, classScope, out);
}
for (Map.Entry<Method, MethodHandler> en : methodHandlerMap.entrySet()) {
for (Map.Entry<Method, MethodHandler> entry : methodHandlerMap.entrySet()) {
out.newLine();
en.getValue().writeMethodImplementationJava(classScope, en.getKey(), out);
entry.getValue().writeMethodImplementationJava(classScope, entry.getKey(), out);
out.newLine();
}