diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java index 77a91e8543d1..3925239a98d2 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java @@ -10,22 +10,17 @@ import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.*; -class FieldProcessor { - private final Class typeClass; - +final class FieldProcessor { private final List fieldLoaders = new ArrayList<>(2); private final LinkedHashMap methodHandlerMap = new LinkedHashMap<>(); private final List volatileFields = new ArrayList<>(2); boolean lazyRead; private final InterfaceReader reader; - FieldProcessor(InterfaceReader reader, Class typeClass) { - this.typeClass = typeClass; + FieldProcessor(@NotNull InterfaceReader reader, @NotNull Class typeClass) { this.reader = reader; - } - void go() { - Method[] methods = typeClass.getDeclaredMethods(); + Method[] methods = typeClass.getMethods(); // todo sort by source location Arrays.sort(methods, new Comparator() { @Override @@ -34,58 +29,77 @@ class FieldProcessor { } }); - 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 { 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(); } } diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/InterfaceReader.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/InterfaceReader.java index a02b4ae8f18a..2cb6b9a28d07 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/InterfaceReader.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/InterfaceReader.java @@ -161,8 +161,6 @@ class InterfaceReader { } FieldProcessor fields = new FieldProcessor<>(this, typeClass); - fields.go(); - LinkedHashMap methodHandlerMap = fields.getMethodHandlerMap(); for (Method method : methodHandlerMap.keySet()) { Class returnType = method.getReturnType(); diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/MethodHandler.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/MethodHandler.java index a877b654c020..a9caa4e22929 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/MethodHandler.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/MethodHandler.java @@ -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 paramNames, @NotNull TextOutput out) { - out.append(m.getName()).append('('); + protected static void appendMethodSignatureJava(@NotNull Method method, @NotNull List 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.emptyList()); + protected static void writeMethodDeclarationJava(TextOutput out, Method method) { + writeMethodDeclarationJava(out, method, Collections.emptyList()); } protected static void writeMethodDeclarationJava(@NotNull TextOutput out, @NotNull Method m, @NotNull List paramNames) { diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PreparsedFieldMethodHandler.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PreparsedFieldMethodHandler.java deleted file mode 100644 index 19e7714a0bd2..000000000000 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PreparsedFieldMethodHandler.java +++ /dev/null @@ -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(); - } -} diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PrimitiveValueReader.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PrimitiveValueReader.java index 5e53088b9b39..4f950fc4bb44 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PrimitiveValueReader.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/PrimitiveValueReader.java @@ -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 diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReadDelegate.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReadDelegate.java index 56dcc310fa83..ca3253b1595b 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReadDelegate.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReadDelegate.java @@ -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 "); diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderGenerator.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderGenerator.java index c51ae4c55e0f..71150f1fad79 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderGenerator.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderGenerator.java @@ -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); diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderRoot.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderRoot.java index f7ce9eb9eb39..8a480f9ec819 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderRoot.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderRoot.java @@ -94,11 +94,11 @@ class ReaderRoot { return rootClass; } - public void writeStaticMethodJava(ClassScope scope) { + public void writeStaticMethodJava(@NotNull ClassScope scope) { TextOutput out = scope.getOutput(); - for (Map.Entry en : methodMap.entrySet()) { + for (Map.Entry entry : methodMap.entrySet()) { out.newLine(); - en.getValue().write(scope, en.getKey(), out); + entry.getValue().write(scope, entry.getKey(), out); out.newLine(); } } diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/TypeHandler.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/TypeHandler.java index 261b0e94e07c..983ce0c69d01 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/TypeHandler.java +++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/TypeHandler.java @@ -93,9 +93,9 @@ class TypeHandler { subtypeAspect.writeParseMethod(valueImplClassName, classScope, out); } - for (Map.Entry en : methodHandlerMap.entrySet()) { + for (Map.Entry entry : methodHandlerMap.entrySet()) { out.newLine(); - en.getValue().writeMethodImplementationJava(classScope, en.getKey(), out); + entry.getValue().writeMethodImplementationJava(classScope, entry.getKey(), out); out.newLine(); }