firefox rdp — getters/setters, FunctionValue, null

This commit is contained in:
Vladimir Krivosheev
2015-01-09 13:10:54 +01:00
parent 3930eb0106
commit d9a6616eb0
14 changed files with 58 additions and 77 deletions
@@ -7,8 +7,8 @@ public class PrimitiveValue extends ValueBase {
public static final String NA_N_VALUE = "NaN";
public static final String INFINITY_VALUE = "Infinity";
public static final PrimitiveValue NULL_VALUE = new PrimitiveValue(ValueType.NULL, "null");
public static final PrimitiveValue UNDEFINED_VALUE = new PrimitiveValue(ValueType.UNDEFINED, "undefined");
public static final PrimitiveValue NULL = new PrimitiveValue(ValueType.NULL, "null");
public static final PrimitiveValue UNDEFINED = new PrimitiveValue(ValueType.UNDEFINED, "undefined");
public static final PrimitiveValue NAN = new PrimitiveValue(ValueType.NUMBER, NA_N_VALUE);
public static final PrimitiveValue INFINITY = new PrimitiveValue(ValueType.NUMBER, INFINITY_VALUE);
@@ -27,7 +27,7 @@ class ArrayReader extends ValueReader {
}
@Override
void writeReadCode(ClassScope scope, boolean subtyping, String fieldName, @NotNull TextOutput out) {
void writeReadCode(ClassScope scope, boolean subtyping, @NotNull TextOutput out) {
componentParser.writeArrayReadCode(scope, subtyping, out);
}
}
@@ -20,7 +20,7 @@ class EnumReader<T extends Enum<T>> extends ValueReader {
}
@Override
void writeReadCode(ClassScope scope, boolean subtyping, String fieldName, @NotNull TextOutput out) {
void writeReadCode(ClassScope scope, boolean subtyping, @NotNull TextOutput out) {
beginReadCall("Enum", subtyping, out);
out.comma().append(enumClass.getCanonicalName()).append(".class").append(')');
}
@@ -1,28 +1,25 @@
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.jetbrains.protocolReader;
import org.jetbrains.annotations.NotNull;
class FieldLoader {
public static final char FIELD_PREFIX = '_';
private final String fieldName;
final String name;
final String jsonName;
final ValueReader valueReader;
FieldLoader(String fieldName, ValueReader valueReader) {
this.fieldName = fieldName;
FieldLoader(@NotNull String name, @NotNull String jsonName, @NotNull ValueReader valueReader) {
this.name = name;
this.jsonName = jsonName;
this.valueReader = valueReader;
}
public String getFieldName() {
return fieldName;
}
public void writeFieldDeclaration(TextOutput out) {
out.append("private ");
public void writeFieldDeclaration(@NotNull TextOutput out) {
out.append("private").space();
valueReader.appendFinishedValueTypeName(out);
out.append(' ').append(FIELD_PREFIX).append(fieldName);
out.space().append(FIELD_PREFIX).append(name);
if (valueReader instanceof PrimitiveValueReader) {
String defaultValue = ((PrimitiveValueReader)valueReader).defaultValue;
if (defaultValue != null) {
@@ -11,9 +11,9 @@ import java.lang.reflect.Type;
import java.util.*;
final class FieldProcessor<T> {
private final List<FieldLoader> fieldLoaders = new ArrayList<>(2);
private final List<FieldLoader> fieldLoaders = new ArrayList<>();
private final LinkedHashMap<Method, MethodHandler> methodHandlerMap = new LinkedHashMap<>();
private final List<VolatileFieldBinding> volatileFields = new ArrayList<>(2);
private final List<VolatileFieldBinding> volatileFields = new ArrayList<>();
boolean lazyRead;
private final InterfaceReader reader;
@@ -29,29 +29,32 @@ final class FieldProcessor<T> {
}
});
Package aPackage = typeClass.getPackage();
Package classPackage = 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 (methodClass != typeClass) {
Package methodPackage = methodClass.getPackage();
// may be it will be useful later
// && !methodPackage.getName().equals("org.jetbrains.debugger.adapters")
if (methodPackage != classPackage) {
continue;
}
}
if (method.getParameterTypes().length != 0) {
if (method.getParameterCount() != 0) {
throw new JsonProtocolModelParseException("No parameters expected in " + method);
}
try {
String fieldName = checkAndGetJsonFieldName(method);
MethodHandler methodHandler;
JsonSubtypeCasting jsonSubtypeCaseAnnotation = method.getAnnotation(JsonSubtypeCasting.class);
if (jsonSubtypeCaseAnnotation != null) {
methodHandler = processManualSubtypeMethod(method, jsonSubtypeCaseAnnotation);
lazyRead = true;
if (jsonSubtypeCaseAnnotation == null) {
methodHandler = processFieldGetterMethod(method);
}
else {
methodHandler = processFieldGetterMethod(method, fieldName);
methodHandler = processManualSubtypeMethod(method, jsonSubtypeCaseAnnotation);
lazyRead = true;
}
methodHandlerMap.put(method, methodHandler);
}
@@ -61,36 +64,33 @@ final class FieldProcessor<T> {
}
}
private MethodHandler processFieldGetterMethod(@NotNull Method method, @NotNull String fieldName) {
@NotNull
private MethodHandler processFieldGetterMethod(@NotNull Method method) {
String jsonName = method.getName();
JsonField fieldAnnotation = method.getAnnotation(JsonField.class);
if (fieldAnnotation != null && !fieldAnnotation.name().isEmpty()) {
jsonName = fieldAnnotation.name();
}
Type genericReturnType = method.getGenericReturnType();
boolean addNotNullAnnotation;
boolean isPrimitive = genericReturnType instanceof Class ? ((Class)genericReturnType).isPrimitive() : !(genericReturnType instanceof ParameterizedType);
if (isPrimitive) {
addNotNullAnnotation = false;
}
else if (fieldAnnotation != null) {
addNotNullAnnotation = !fieldAnnotation.optional() && !fieldAnnotation.allowAnyPrimitiveValue() && !fieldAnnotation.allowAnyPrimitiveValueAndMap();
}
else {
JsonField jsonField = method.getAnnotation(JsonField.class);
if (jsonField != null) {
addNotNullAnnotation = !jsonField.optional() && !jsonField.allowAnyPrimitiveValue() && !jsonField.allowAnyPrimitiveValueAndMap();
}
else {
addNotNullAnnotation = method.getAnnotation(JsonOptionalField.class) == null;
}
addNotNullAnnotation = method.getAnnotation(JsonOptionalField.class) == null;
}
ValueReader fieldTypeParser;
try {
fieldTypeParser = reader.getFieldTypeParser(genericReturnType, false, method);
}
catch (Exception e) {
throw new RuntimeException("Cannot create field type parser for method " + method, e);
}
ValueReader fieldTypeParser = reader.getFieldTypeParser(genericReturnType, false, method);
if (fieldTypeParser != InterfaceReader.VOID_PARSER) {
fieldLoaders.add(new FieldLoader(fieldName, fieldTypeParser));
fieldLoaders.add(new FieldLoader(method.getName(), jsonName, fieldTypeParser));
}
final String effectiveFieldName = fieldTypeParser == InterfaceReader.VOID_PARSER ? null : fieldName;
final String effectiveFieldName = fieldTypeParser == InterfaceReader.VOID_PARSER ? null : method.getName();
return new MethodHandler() {
@Override
void writeMethodImplementationJava(@NotNull ClassScope scope, @NotNull Method method, @NotNull TextOutput out) {
@@ -150,19 +150,4 @@ final class FieldProcessor<T> {
volatileFields.add(binding);
return binding;
}
@NotNull
private static String checkAndGetJsonFieldName(@NotNull Method method) {
if (method.getParameterTypes().length != 0) {
throw new JsonProtocolModelParseException("Must have 0 parameters");
}
JsonField fieldAnnotation = method.getAnnotation(JsonField.class);
if (fieldAnnotation != null) {
String jsonLiteralName = fieldAnnotation.name();
if (!jsonLiteralName.isEmpty()) {
return jsonLiteralName;
}
}
return method.getName();
}
}
@@ -30,7 +30,7 @@ class InterfaceReader {
private static final PrimitiveValueReader RAW_STRING_PARSER = new PrimitiveValueReader("String", null, true);
private static final PrimitiveValueReader RAW_STRING_OR_MAP_PARSER = new PrimitiveValueReader("Object", null, true) {
@Override
void writeReadCode(ClassScope methodScope, boolean subtyping, String fieldName, @NotNull TextOutput out) {
void writeReadCode(ClassScope methodScope, boolean subtyping, @NotNull TextOutput out) {
out.append("readRawStringOrMap(");
addReaderParameter(subtyping, out);
out.append(')');
@@ -50,7 +50,7 @@ class InterfaceReader {
}
@Override
void writeReadCode(ClassScope scope, boolean subtyping, String fieldName, @NotNull TextOutput out) {
void writeReadCode(ClassScope scope, boolean subtyping, @NotNull TextOutput out) {
out.append("null");
}
};
@@ -43,7 +43,7 @@ class LazyCachedMethodHandler extends MethodHandler {
{
fieldBinding.writeGetExpression(out);
out.append(" = ");
parser.writeReadCode(classScope, true, null, classScope.getOutput());
parser.writeReadCode(classScope, true, classScope.getOutput());
out.semi();
}
if (parser.isThrowsIOException()) {
@@ -30,7 +30,7 @@ public class MapReader extends ValueReader {
}
@Override
void writeReadCode(ClassScope scope, boolean subtyping, String fieldName, @NotNull TextOutput out) {
void writeReadCode(ClassScope scope, boolean subtyping, @NotNull TextOutput out) {
beginReadCall("Map", subtyping, out);
if (componentParser == null) {
out.comma().append("null");
@@ -40,7 +40,7 @@ class ObjectValueReader<T> extends ValueReader {
}
@Override
void writeReadCode(ClassScope scope, boolean subtyping, String fieldName, @NotNull TextOutput out) {
void writeReadCode(ClassScope scope, boolean subtyping, @NotNull TextOutput out) {
refToType.type.writeInstantiateCode(scope.getRootClassScope(), subtyping, out);
out.append('(');
addReaderParameter(subtyping, out);
@@ -32,7 +32,7 @@ class PrimitiveValueReader extends ValueReader {
}
@Override
void writeReadCode(ClassScope methodScope, boolean subtyping, String fieldName, @NotNull TextOutput out) {
void writeReadCode(ClassScope methodScope, boolean subtyping, @NotNull TextOutput out) {
if (asRawString) {
out.append("readRawString(");
addReaderParameter(subtyping, out);
@@ -41,7 +41,7 @@ class PrimitiveValueReader extends ValueReader {
else {
ValueReader.addReaderParameter(subtyping, out);
out.append(".next").append(readPostfix).append("()");
//beginReadCall(readPostfix, subtyping, out, fieldName);
//beginReadCall(readPostfix, subtyping, out, name);
}
}
@@ -9,7 +9,7 @@ class RawValueReader extends ValueReader {
}
@Override
void writeReadCode(ClassScope scope, boolean subtyping, String fieldName, @NotNull TextOutput out) {
void writeReadCode(ClassScope scope, boolean subtyping, @NotNull TextOutput out) {
addReaderParameter(subtyping, out);
out.append(".subReader();").newLine();
addReaderParameter(subtyping, out);
@@ -13,7 +13,7 @@ public class StringIntPairValueReader extends ValueReader {
}
@Override
void writeReadCode(ClassScope scope, boolean subtyping, String fieldName, @NotNull TextOutput out) {
void writeReadCode(ClassScope scope, boolean subtyping, @NotNull TextOutput out) {
}
@Override
@@ -182,17 +182,16 @@ class TypeHandler<T> {
out.newLine();
}
String fieldName = fieldLoader.getFieldName();
out.append(operator).append(" (name");
out.append(".equals(\"").append(fieldName).append("\"))").openBlock();
out.append(".equals(\"").append(fieldLoader.jsonName).append("\"))").openBlock();
{
String primitiveValueName = fieldLoader.valueReader instanceof ObjectValueReader ? ((ObjectValueReader)fieldLoader.valueReader).primitiveValueName : null;
if (primitiveValueName != null) {
out.append("if (reader.peek() == com.google.gson.stream.JsonToken.BEGIN_OBJECT)").openBlock();
}
assignField(out, fieldName);
assignField(out, fieldLoader.name);
fieldLoader.valueReader.writeReadCode(classScope, false, fieldName, out);
fieldLoader.valueReader.writeReadCode(classScope, false, out);
out.semi();
if (primitiveValueName != null) {
@@ -17,7 +17,7 @@ abstract class ValueReader {
appendFinishedValueTypeName(out);
}
abstract void writeReadCode(ClassScope methodScope, boolean subtyping, String fieldName, @NotNull TextOutput out);
abstract void writeReadCode(ClassScope methodScope, boolean subtyping, @NotNull TextOutput out);
void writeArrayReadCode(@NotNull ClassScope scope, boolean subtyping, @NotNull TextOutput out) {
throw new UnsupportedOperationException();