From d4138ba1830b4fabb4a3489db7ebfca1126ae059 Mon Sep 17 00:00:00 2001 From: jdyjjj <1410234026@qq.com> Date: Thu, 21 Apr 2022 11:14:19 +0800 Subject: [PATCH 1/3] Fix 604 --- .../com/squareup/javapoet/MethodSpec.java | 13 +- .../com/squareup/javapoet/MethodSpecTest.java | 839 +++++++++--------- 2 files changed, 440 insertions(+), 412 deletions(-) diff --git a/src/main/java/com/squareup/javapoet/MethodSpec.java b/src/main/java/com/squareup/javapoet/MethodSpec.java index 67722c774..ce337910d 100644 --- a/src/main/java/com/squareup/javapoet/MethodSpec.java +++ b/src/main/java/com/squareup/javapoet/MethodSpec.java @@ -451,8 +451,17 @@ public Builder addCode(CodeBlock codeBlock) { } public Builder addComment(String format, Object... args) { - code.add("// " + format + "\n", args); - return this; + String[] lines = format.split("\\R"); + if(lines.length==1){ + code.add("// " + format + "\n", args); + return this; + }else { + for (String line : lines) { + code.add("// " + line + "\n"); + } + return this; + } +// return this; } public Builder defaultValue(String format, Object... args) { diff --git a/src/test/java/com/squareup/javapoet/MethodSpecTest.java b/src/test/java/com/squareup/javapoet/MethodSpecTest.java index e180f200c..e1d8fa606 100644 --- a/src/test/java/com/squareup/javapoet/MethodSpecTest.java +++ b/src/test/java/com/squareup/javapoet/MethodSpecTest.java @@ -63,422 +63,441 @@ private TypeElement getElement(Class clazz) { return elements.getTypeElement(clazz.getCanonicalName()); } - @Test public void nullAnnotationsAddition() { - try { - MethodSpec.methodBuilder("doSomething").addAnnotations(null); - fail(); - } catch (IllegalArgumentException expected) { - assertThat(expected).hasMessageThat().isEqualTo("annotationSpecs == null"); - } - } - - @Test public void nullTypeVariablesAddition() { - try { - MethodSpec.methodBuilder("doSomething").addTypeVariables(null); - fail(); - } catch (IllegalArgumentException expected) { - assertThat(expected).hasMessageThat().isEqualTo("typeVariables == null"); - } - } - - @Test public void nullParametersAddition() { - try { - MethodSpec.methodBuilder("doSomething").addParameters(null); - fail(); - } catch (IllegalArgumentException expected) { - assertThat(expected).hasMessageThat().isEqualTo("parameterSpecs == null"); - } - } - - @Test public void nullExceptionsAddition() { - try { - MethodSpec.methodBuilder("doSomething").addExceptions(null); - fail(); - } catch (IllegalArgumentException expected) { - assertThat(expected).hasMessageThat().isEqualTo("exceptions == null"); - } - } - - @Target(ElementType.PARAMETER) - @interface Nullable { - } - - abstract static class Everything { - @Deprecated protected abstract Runnable everything( - @Nullable String thing, List things) throws IOException, SecurityException; - } - - abstract static class Generics { - T run(R param) throws V { - return null; - } - } - - abstract static class HasAnnotation { - @Override public abstract String toString(); - } - - interface Throws { - void fail() throws R; - } - - interface ExtendsOthers extends Callable, Comparable, - Throws { - } - - interface ExtendsIterableWithDefaultMethods extends Iterable { - } - - final class FinalClass { - void method() { - } - } - - abstract static class InvalidOverrideMethods { - final void finalMethod() { - } - - private void privateMethod() { - } - - static void staticMethod() { - } - } - - @Test public void overrideEverything() { - TypeElement classElement = getElement(Everything.class); - ExecutableElement methodElement = getOnlyElement(methodsIn(classElement.getEnclosedElements())); - MethodSpec method = MethodSpec.overriding(methodElement).build(); - assertThat(method.toString()).isEqualTo("" - + "@java.lang.Override\n" - + "protected java.lang.Runnable " - + "everything(\n" - + " java.lang.String arg0, java.util.List arg1) throws java.io.IOException,\n" - + " java.lang.SecurityException {\n" - + "}\n"); - } - - @Test public void overrideGenerics() { - TypeElement classElement = getElement(Generics.class); - ExecutableElement methodElement = getOnlyElement(methodsIn(classElement.getEnclosedElements())); - MethodSpec method = MethodSpec.overriding(methodElement) - .addStatement("return null") - .build(); - assertThat(method.toString()).isEqualTo("" - + "@java.lang.Override\n" - + " T run(R param) throws V {\n" - + " return null;\n" - + "}\n"); - } - - @Test public void overrideDoesNotCopyOverrideAnnotation() { - TypeElement classElement = getElement(HasAnnotation.class); - ExecutableElement exec = getOnlyElement(methodsIn(classElement.getEnclosedElements())); - MethodSpec method = MethodSpec.overriding(exec).build(); - assertThat(method.toString()).isEqualTo("" - + "@java.lang.Override\n" - + "public java.lang.String toString() {\n" - + "}\n"); - } - - @Test public void overrideDoesNotCopyDefaultModifier() { - TypeElement classElement = getElement(ExtendsIterableWithDefaultMethods.class); - DeclaredType classType = (DeclaredType) classElement.asType(); - List methods = methodsIn(elements.getAllMembers(classElement)); - ExecutableElement exec = findFirst(methods, "spliterator"); - MethodSpec method = MethodSpec.overriding(exec, classType, types).build(); - assertThat(method.toString()).isEqualTo("" - + "@java.lang.Override\n" - + "public java.util.Spliterator spliterator() {\n" - + "}\n"); - } - - @Test public void overrideExtendsOthersWorksWithActualTypeParameters() { - TypeElement classElement = getElement(ExtendsOthers.class); - DeclaredType classType = (DeclaredType) classElement.asType(); - List methods = methodsIn(elements.getAllMembers(classElement)); - ExecutableElement exec = findFirst(methods, "call"); - MethodSpec method = MethodSpec.overriding(exec, classType, types).build(); - assertThat(method.toString()).isEqualTo("" - + "@java.lang.Override\n" - + "public java.lang.Integer call() throws java.lang.Exception {\n" - + "}\n"); - exec = findFirst(methods, "compareTo"); - method = MethodSpec.overriding(exec, classType, types).build(); - assertThat(method.toString()).isEqualTo("" - + "@java.lang.Override\n" - + "public int compareTo(" + ExtendsOthers.class.getCanonicalName() + " arg0) {\n" - + "}\n"); - exec = findFirst(methods, "fail"); - method = MethodSpec.overriding(exec, classType, types).build(); - assertThat(method.toString()).isEqualTo("" - + "@java.lang.Override\n" - + "public void fail() throws java.lang.IllegalStateException {\n" - + "}\n"); - } - - @Test public void overrideFinalClassMethod() { - TypeElement classElement = getElement(FinalClass.class); - List methods = methodsIn(elements.getAllMembers(classElement)); - try { - MethodSpec.overriding(findFirst(methods, "method")); - fail(); - } catch (IllegalArgumentException expected) { - assertThat(expected).hasMessageThat().isEqualTo( - "Cannot override method on final class com.squareup.javapoet.MethodSpecTest.FinalClass"); - } - } - - @Test public void overrideInvalidModifiers() { - TypeElement classElement = getElement(InvalidOverrideMethods.class); - List methods = methodsIn(elements.getAllMembers(classElement)); - try { - MethodSpec.overriding(findFirst(methods, "finalMethod")); - fail(); - } catch (IllegalArgumentException expected) { - assertThat(expected).hasMessageThat().isEqualTo("cannot override method with modifiers: [final]"); - } - try { - MethodSpec.overriding(findFirst(methods, "privateMethod")); - fail(); - } catch (IllegalArgumentException expected) { - assertThat(expected).hasMessageThat().isEqualTo("cannot override method with modifiers: [private]"); - } - try { - MethodSpec.overriding(findFirst(methods, "staticMethod")); - fail(); - } catch (IllegalArgumentException expected) { - assertThat(expected).hasMessageThat().isEqualTo("cannot override method with modifiers: [static]"); - } - } - - abstract static class AbstractClassWithPrivateAnnotation { - - private @interface PrivateAnnotation{ } - - abstract void foo(@PrivateAnnotation final String bar); - } - - @Test public void overrideDoesNotCopyParameterAnnotations() { - TypeElement abstractTypeElement = getElement(AbstractClassWithPrivateAnnotation.class); - ExecutableElement fooElement = ElementFilter.methodsIn(abstractTypeElement.getEnclosedElements()).get(0); - ClassName implClassName = ClassName.get("com.squareup.javapoet", "Impl"); - TypeSpec type = TypeSpec.classBuilder(implClassName) - .superclass(abstractTypeElement.asType()) - .addMethod(MethodSpec.overriding(fooElement).build()) - .build(); - JavaFileObject jfo = JavaFile.builder(implClassName.packageName, type).build().toJavaFileObject(); - Compilation compilation = javac().compile(jfo); - assertThat(compilation).succeeded(); - } - - @Test public void equalsAndHashCode() { - MethodSpec a = MethodSpec.constructorBuilder().build(); - MethodSpec b = MethodSpec.constructorBuilder().build(); - assertThat(a.equals(b)).isTrue(); - assertThat(a.hashCode()).isEqualTo(b.hashCode()); - a = MethodSpec.methodBuilder("taco").build(); - b = MethodSpec.methodBuilder("taco").build(); - assertThat(a.equals(b)).isTrue(); - assertThat(a.hashCode()).isEqualTo(b.hashCode()); - TypeElement classElement = getElement(Everything.class); - ExecutableElement methodElement = getOnlyElement(methodsIn(classElement.getEnclosedElements())); - a = MethodSpec.overriding(methodElement).build(); - b = MethodSpec.overriding(methodElement).build(); - assertThat(a.equals(b)).isTrue(); - assertThat(a.hashCode()).isEqualTo(b.hashCode()); - } - - @Test public void withoutParameterJavaDoc() { - MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") - .addModifiers(Modifier.PRIVATE) - .addParameter(TypeName.DOUBLE, "money") - .addJavadoc("Gets the best Taco\n") - .build(); - assertThat(methodSpec.toString()).isEqualTo("" - + "/**\n" - + " * Gets the best Taco\n" - + " */\n" - + "private void getTaco(double money) {\n" - + "}\n"); - } - - @Test public void withParameterJavaDoc() { - MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") - .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "money") - .addJavadoc("the amount required to buy the taco.\n") - .build()) - .addParameter(ParameterSpec.builder(TypeName.INT, "count") - .addJavadoc("the number of Tacos to buy.\n") - .build()) - .addJavadoc("Gets the best Taco money can buy.\n") - .build(); - assertThat(methodSpec.toString()).isEqualTo("" - + "/**\n" - + " * Gets the best Taco money can buy.\n" - + " *\n" - + " * @param money the amount required to buy the taco.\n" - + " * @param count the number of Tacos to buy.\n" - + " */\n" - + "void getTaco(double money, int count) {\n" - + "}\n"); - } - - @Test public void withParameterJavaDocAndWithoutMethodJavadoc() { - MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") - .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "money") - .addJavadoc("the amount required to buy the taco.\n") - .build()) - .addParameter(ParameterSpec.builder(TypeName.INT, "count") - .addJavadoc("the number of Tacos to buy.\n") - .build()) - .build(); - assertThat(methodSpec.toString()).isEqualTo("" - + "/**\n" - + " * @param money the amount required to buy the taco.\n" - + " * @param count the number of Tacos to buy.\n" - + " */\n" - + "void getTaco(double money, int count) {\n" - + "}\n"); - } - - @Test public void duplicateExceptionsIgnored() { - ClassName ioException = ClassName.get(IOException.class); - ClassName timeoutException = ClassName.get(TimeoutException.class); - MethodSpec methodSpec = MethodSpec.methodBuilder("duplicateExceptions") - .addException(ioException) - .addException(timeoutException) - .addException(timeoutException) - .addException(ioException) - .build(); - assertThat(methodSpec.exceptions).isEqualTo(Arrays.asList(ioException, timeoutException)); - assertThat(methodSpec.toBuilder().addException(ioException).build().exceptions) - .isEqualTo(Arrays.asList(ioException, timeoutException)); - } - - @Test public void nullIsNotAValidMethodName() { - try { - MethodSpec.methodBuilder(null); - fail("NullPointerException expected"); - } catch (NullPointerException e) { - assertThat(e.getMessage()).isEqualTo("name == null"); - } - } - - @Test public void addModifiersVarargsShouldNotBeNull() { - try { - MethodSpec.methodBuilder("taco") - .addModifiers((Modifier[]) null); - fail("NullPointerException expected"); - } catch (NullPointerException e) { - assertThat(e.getMessage()).isEqualTo("modifiers == null"); - } - } - - @Test public void modifyMethodName() { - MethodSpec methodSpec = MethodSpec.methodBuilder("initialMethod") - .build() - .toBuilder() - .setName("revisedMethod") - .build(); - - assertThat(methodSpec.toString()).isEqualTo("" + "void revisedMethod() {\n" + "}\n"); - } - - @Test public void modifyAnnotations() { - MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") - .addAnnotation(Override.class) - .addAnnotation(SuppressWarnings.class); - - builder.annotations.remove(1); - assertThat(builder.build().annotations).hasSize(1); - } - - @Test public void modifyModifiers() { - MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC); - - builder.modifiers.remove(1); - assertThat(builder.build().modifiers).containsExactly(Modifier.PUBLIC); - } - - @Test public void modifyParameters() { - MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") - .addParameter(int.class, "source"); - - builder.parameters.remove(0); - assertThat(builder.build().parameters).isEmpty(); - } - - @Test public void modifyTypeVariables() { - TypeVariableName t = TypeVariableName.get("T"); - MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") - .addTypeVariable(t) - .addTypeVariable(TypeVariableName.get("V")); - - builder.typeVariables.remove(1); - assertThat(builder.build().typeVariables).containsExactly(t); - } - - @Test public void ensureTrailingNewline() { - MethodSpec methodSpec = MethodSpec.methodBuilder("method") - .addCode("codeWithNoNewline();") - .build(); - - assertThat(methodSpec.toString()).isEqualTo("" - + "void method() {\n" - + " codeWithNoNewline();\n" - + "}\n"); - } - - /** Ensures that we don't add a duplicate newline if one is already present. */ - @Test public void ensureTrailingNewlineWithExistingNewline() { - MethodSpec methodSpec = MethodSpec.methodBuilder("method") - .addCode("codeWithNoNewline();\n") // Have a newline already, so ensure we're not adding one - .build(); - - assertThat(methodSpec.toString()).isEqualTo("" - + "void method() {\n" - + " codeWithNoNewline();\n" - + "}\n"); - } - - @Test public void controlFlowWithNamedCodeBlocks() { +// @Test public void nullAnnotationsAddition() { +// try { +// MethodSpec.methodBuilder("doSomething").addAnnotations(null); +// fail(); +// } catch (IllegalArgumentException expected) { +// assertThat(expected).hasMessageThat().isEqualTo("annotationSpecs == null"); +// } +// } +// +// @Test public void nullTypeVariablesAddition() { +// try { +// MethodSpec.methodBuilder("doSomething").addTypeVariables(null); +// fail(); +// } catch (IllegalArgumentException expected) { +// assertThat(expected).hasMessageThat().isEqualTo("typeVariables == null"); +// } +// } +// +// @Test public void nullParametersAddition() { +// try { +// MethodSpec.methodBuilder("doSomething").addParameters(null); +// fail(); +// } catch (IllegalArgumentException expected) { +// assertThat(expected).hasMessageThat().isEqualTo("parameterSpecs == null"); +// } +// } +// +// @Test public void nullExceptionsAddition() { +// try { +// MethodSpec.methodBuilder("doSomething").addExceptions(null); +// fail(); +// } catch (IllegalArgumentException expected) { +// assertThat(expected).hasMessageThat().isEqualTo("exceptions == null"); +// } +// } +// +// @Target(ElementType.PARAMETER) +// @interface Nullable { +// } +// +// abstract static class Everything { +// @Deprecated protected abstract Runnable everything( +// @Nullable String thing, List things) throws IOException, SecurityException; +// } +// +// abstract static class Generics { +// T run(R param) throws V { +// return null; +// } +// } +// +// abstract static class HasAnnotation { +// @Override public abstract String toString(); +// } +// +// interface Throws { +// void fail() throws R; +// } +// +// interface ExtendsOthers extends Callable, Comparable, +// Throws { +// } +// +// interface ExtendsIterableWithDefaultMethods extends Iterable { +// } +// +// final class FinalClass { +// void method() { +// } +// } +// +// abstract static class InvalidOverrideMethods { +// final void finalMethod() { +// } +// +// private void privateMethod() { +// } +// +// static void staticMethod() { +// } +// } +// +// @Test public void overrideEverything() { +// TypeElement classElement = getElement(Everything.class); +// ExecutableElement methodElement = getOnlyElement(methodsIn(classElement.getEnclosedElements())); +// MethodSpec method = MethodSpec.overriding(methodElement).build(); +// assertThat(method.toString()).isEqualTo("" +// + "@java.lang.Override\n" +// + "protected java.lang.Runnable " +// + "everything(\n" +// + " java.lang.String arg0, java.util.List arg1) throws java.io.IOException,\n" +// + " java.lang.SecurityException {\n" +// + "}\n"); +// } +// +// @Test public void overrideGenerics() { +// TypeElement classElement = getElement(Generics.class); +// ExecutableElement methodElement = getOnlyElement(methodsIn(classElement.getEnclosedElements())); +// MethodSpec method = MethodSpec.overriding(methodElement) +// .addStatement("return null") +// .build(); +// assertThat(method.toString()).isEqualTo("" +// + "@java.lang.Override\n" +// + " T run(R param) throws V {\n" +// + " return null;\n" +// + "}\n"); +// } +// +// @Test public void overrideDoesNotCopyOverrideAnnotation() { +// TypeElement classElement = getElement(HasAnnotation.class); +// ExecutableElement exec = getOnlyElement(methodsIn(classElement.getEnclosedElements())); +// MethodSpec method = MethodSpec.overriding(exec).build(); +// assertThat(method.toString()).isEqualTo("" +// + "@java.lang.Override\n" +// + "public java.lang.String toString() {\n" +// + "}\n"); +// } +// +// @Test public void overrideDoesNotCopyDefaultModifier() { +// TypeElement classElement = getElement(ExtendsIterableWithDefaultMethods.class); +// DeclaredType classType = (DeclaredType) classElement.asType(); +// List methods = methodsIn(elements.getAllMembers(classElement)); +// ExecutableElement exec = findFirst(methods, "spliterator"); +// MethodSpec method = MethodSpec.overriding(exec, classType, types).build(); +// assertThat(method.toString()).isEqualTo("" +// + "@java.lang.Override\n" +// + "public java.util.Spliterator spliterator() {\n" +// + "}\n"); +// } +// +// @Test public void overrideExtendsOthersWorksWithActualTypeParameters() { +// TypeElement classElement = getElement(ExtendsOthers.class); +// DeclaredType classType = (DeclaredType) classElement.asType(); +// List methods = methodsIn(elements.getAllMembers(classElement)); +// ExecutableElement exec = findFirst(methods, "call"); +// MethodSpec method = MethodSpec.overriding(exec, classType, types).build(); +// assertThat(method.toString()).isEqualTo("" +// + "@java.lang.Override\n" +// + "public java.lang.Integer call() throws java.lang.Exception {\n" +// + "}\n"); +// exec = findFirst(methods, "compareTo"); +// method = MethodSpec.overriding(exec, classType, types).build(); +// assertThat(method.toString()).isEqualTo("" +// + "@java.lang.Override\n" +// + "public int compareTo(" + ExtendsOthers.class.getCanonicalName() + " arg0) {\n" +// + "}\n"); +// exec = findFirst(methods, "fail"); +// method = MethodSpec.overriding(exec, classType, types).build(); +// assertThat(method.toString()).isEqualTo("" +// + "@java.lang.Override\n" +// + "public void fail() throws java.lang.IllegalStateException {\n" +// + "}\n"); +// } +// +// @Test public void overrideFinalClassMethod() { +// TypeElement classElement = getElement(FinalClass.class); +// List methods = methodsIn(elements.getAllMembers(classElement)); +// try { +// MethodSpec.overriding(findFirst(methods, "method")); +// fail(); +// } catch (IllegalArgumentException expected) { +// assertThat(expected).hasMessageThat().isEqualTo( +// "Cannot override method on final class com.squareup.javapoet.MethodSpecTest.FinalClass"); +// } +// } +// +// @Test public void overrideInvalidModifiers() { +// TypeElement classElement = getElement(InvalidOverrideMethods.class); +// List methods = methodsIn(elements.getAllMembers(classElement)); +// try { +// MethodSpec.overriding(findFirst(methods, "finalMethod")); +// fail(); +// } catch (IllegalArgumentException expected) { +// assertThat(expected).hasMessageThat().isEqualTo("cannot override method with modifiers: [final]"); +// } +// try { +// MethodSpec.overriding(findFirst(methods, "privateMethod")); +// fail(); +// } catch (IllegalArgumentException expected) { +// assertThat(expected).hasMessageThat().isEqualTo("cannot override method with modifiers: [private]"); +// } +// try { +// MethodSpec.overriding(findFirst(methods, "staticMethod")); +// fail(); +// } catch (IllegalArgumentException expected) { +// assertThat(expected).hasMessageThat().isEqualTo("cannot override method with modifiers: [static]"); +// } +// } +// +// abstract static class AbstractClassWithPrivateAnnotation { +// +// private @interface PrivateAnnotation{ } +// +// abstract void foo(@PrivateAnnotation final String bar); +// } +// +// @Test public void overrideDoesNotCopyParameterAnnotations() { +// TypeElement abstractTypeElement = getElement(AbstractClassWithPrivateAnnotation.class); +// ExecutableElement fooElement = ElementFilter.methodsIn(abstractTypeElement.getEnclosedElements()).get(0); +// ClassName implClassName = ClassName.get("com.squareup.javapoet", "Impl"); +// TypeSpec type = TypeSpec.classBuilder(implClassName) +// .superclass(abstractTypeElement.asType()) +// .addMethod(MethodSpec.overriding(fooElement).build()) +// .build(); +// JavaFileObject jfo = JavaFile.builder(implClassName.packageName, type).build().toJavaFileObject(); +// Compilation compilation = javac().compile(jfo); +// assertThat(compilation).succeeded(); +// } +// +// @Test public void equalsAndHashCode() { +// MethodSpec a = MethodSpec.constructorBuilder().build(); +// MethodSpec b = MethodSpec.constructorBuilder().build(); +// assertThat(a.equals(b)).isTrue(); +// assertThat(a.hashCode()).isEqualTo(b.hashCode()); +// a = MethodSpec.methodBuilder("taco").build(); +// b = MethodSpec.methodBuilder("taco").build(); +// assertThat(a.equals(b)).isTrue(); +// assertThat(a.hashCode()).isEqualTo(b.hashCode()); +// TypeElement classElement = getElement(Everything.class); +// ExecutableElement methodElement = getOnlyElement(methodsIn(classElement.getEnclosedElements())); +// a = MethodSpec.overriding(methodElement).build(); +// b = MethodSpec.overriding(methodElement).build(); +// assertThat(a.equals(b)).isTrue(); +// assertThat(a.hashCode()).isEqualTo(b.hashCode()); +// } +// +// @Test public void withoutParameterJavaDoc() { +// MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") +// .addModifiers(Modifier.PRIVATE) +// .addParameter(TypeName.DOUBLE, "money") +// .addJavadoc("Gets the best Taco\n") +// .build(); +// assertThat(methodSpec.toString()).isEqualTo("" +// + "/**\n" +// + " * Gets the best Taco\n" +// + " */\n" +// + "private void getTaco(double money) {\n" +// + "}\n"); +// } +// +// @Test public void withParameterJavaDoc() { +// MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") +// .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "money") +// .addJavadoc("the amount required to buy the taco.\n") +// .build()) +// .addParameter(ParameterSpec.builder(TypeName.INT, "count") +// .addJavadoc("the number of Tacos to buy.\n") +// .build()) +// .addJavadoc("Gets the best Taco money can buy.\n") +// .build(); +// assertThat(methodSpec.toString()).isEqualTo("" +// + "/**\n" +// + " * Gets the best Taco money can buy.\n" +// + " *\n" +// + " * @param money the amount required to buy the taco.\n" +// + " * @param count the number of Tacos to buy.\n" +// + " */\n" +// + "void getTaco(double money, int count) {\n" +// + "}\n"); +// } +// +// @Test public void withParameterJavaDocAndWithoutMethodJavadoc() { +// MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") +// .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "money") +// .addJavadoc("the amount required to buy the taco.\n") +// .build()) +// .addParameter(ParameterSpec.builder(TypeName.INT, "count") +// .addJavadoc("the number of Tacos to buy.\n") +// .build()) +// .build(); +// assertThat(methodSpec.toString()).isEqualTo("" +// + "/**\n" +// + " * @param money the amount required to buy the taco.\n" +// + " * @param count the number of Tacos to buy.\n" +// + " */\n" +// + "void getTaco(double money, int count) {\n" +// + "}\n"); +// } +// +// @Test public void duplicateExceptionsIgnored() { +// ClassName ioException = ClassName.get(IOException.class); +// ClassName timeoutException = ClassName.get(TimeoutException.class); +// MethodSpec methodSpec = MethodSpec.methodBuilder("duplicateExceptions") +// .addException(ioException) +// .addException(timeoutException) +// .addException(timeoutException) +// .addException(ioException) +// .build(); +// assertThat(methodSpec.exceptions).isEqualTo(Arrays.asList(ioException, timeoutException)); +// assertThat(methodSpec.toBuilder().addException(ioException).build().exceptions) +// .isEqualTo(Arrays.asList(ioException, timeoutException)); +// } +// +// @Test public void nullIsNotAValidMethodName() { +// try { +// MethodSpec.methodBuilder(null); +// fail("NullPointerException expected"); +// } catch (NullPointerException e) { +// assertThat(e.getMessage()).isEqualTo("name == null"); +// } +// } +// +// @Test public void addModifiersVarargsShouldNotBeNull() { +// try { +// MethodSpec.methodBuilder("taco") +// .addModifiers((Modifier[]) null); +// fail("NullPointerException expected"); +// } catch (NullPointerException e) { +// assertThat(e.getMessage()).isEqualTo("modifiers == null"); +// } +// } +// +// @Test public void modifyMethodName() { +// MethodSpec methodSpec = MethodSpec.methodBuilder("initialMethod") +// .build() +// .toBuilder() +// .setName("revisedMethod") +// .build(); +// +// assertThat(methodSpec.toString()).isEqualTo("" + "void revisedMethod() {\n" + "}\n"); +// } +// +// @Test public void modifyAnnotations() { +// MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") +// .addAnnotation(Override.class) +// .addAnnotation(SuppressWarnings.class); +// +// builder.annotations.remove(1); +// assertThat(builder.build().annotations).hasSize(1); +// } +// +// @Test public void modifyModifiers() { +// MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") +// .addModifiers(Modifier.PUBLIC, Modifier.STATIC); +// +// builder.modifiers.remove(1); +// assertThat(builder.build().modifiers).containsExactly(Modifier.PUBLIC); +// } +// +// @Test public void modifyParameters() { +// MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") +// .addParameter(int.class, "source"); +// +// builder.parameters.remove(0); +// assertThat(builder.build().parameters).isEmpty(); +// } +// +// @Test public void modifyTypeVariables() { +// TypeVariableName t = TypeVariableName.get("T"); +// MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") +// .addTypeVariable(t) +// .addTypeVariable(TypeVariableName.get("V")); +// +// builder.typeVariables.remove(1); +// assertThat(builder.build().typeVariables).containsExactly(t); +// } +// +// @Test public void ensureTrailingNewline() { +// MethodSpec methodSpec = MethodSpec.methodBuilder("method") +// .addCode("codeWithNoNewline();") +// .build(); +// +// assertThat(methodSpec.toString()).isEqualTo("" +// + "void method() {\n" +// + " codeWithNoNewline();\n" +// + "}\n"); +// } +// +// /** Ensures that we don't add a duplicate newline if one is already present. */ +// @Test public void ensureTrailingNewlineWithExistingNewline() { +// MethodSpec methodSpec = MethodSpec.methodBuilder("method") +// .addCode("codeWithNoNewline();\n") // Have a newline already, so ensure we're not adding one +// .build(); +// +// assertThat(methodSpec.toString()).isEqualTo("" +// + "void method() {\n" +// + " codeWithNoNewline();\n" +// + "}\n"); +// } +// +// @Test public void controlFlowWithNamedCodeBlocks() { +// Map m = new HashMap<>(); +// m.put("field", "valueField"); +// m.put("threshold", "5"); +// +// MethodSpec methodSpec = MethodSpec.methodBuilder("method") +// .beginControlFlow(named("if ($field:N > $threshold:L)", m)) +// .nextControlFlow(named("else if ($field:N == $threshold:L)", m)) +// .endControlFlow() +// .build(); +// +// assertThat(methodSpec.toString()).isEqualTo("" +// + "void method() {\n" +// + " if (valueField > 5) {\n" +// + " } else if (valueField == 5) {\n" +// + " }\n" +// + "}\n"); +// } +// +// @Test public void doWhileWithNamedCodeBlocks() { +// Map m = new HashMap<>(); +// m.put("field", "valueField"); +// m.put("threshold", "5"); +// +// MethodSpec methodSpec = MethodSpec.methodBuilder("method") +// .beginControlFlow("do") +// .addStatement(named("$field:N--", m)) +// .endControlFlow(named("while ($field:N > $threshold:L)", m)) +// .build(); +// +// assertThat(methodSpec.toString()).isEqualTo("" +// + "void method() {\n" + +// " do {\n" + +// " valueField--;\n" + +// " } while (valueField > 5);\n" + +// "}\n"); +// } + + @Test public void testnew() { Map m = new HashMap<>(); m.put("field", "valueField"); m.put("threshold", "5"); MethodSpec methodSpec = MethodSpec.methodBuilder("method") - .beginControlFlow(named("if ($field:N > $threshold:L)", m)) - .nextControlFlow(named("else if ($field:N == $threshold:L)", m)) - .endControlFlow() - .build(); - - assertThat(methodSpec.toString()).isEqualTo("" - + "void method() {\n" - + " if (valueField > 5) {\n" - + " } else if (valueField == 5) {\n" - + " }\n" - + "}\n"); - } - - @Test public void doWhileWithNamedCodeBlocks() { - Map m = new HashMap<>(); - m.put("field", "valueField"); - m.put("threshold", "5"); - - MethodSpec methodSpec = MethodSpec.methodBuilder("method") - .beginControlFlow("do") - .addStatement(named("$field:N--", m)) - .endControlFlow(named("while ($field:N > $threshold:L)", m)) - .build(); + .beginControlFlow("do") + .addStatement(named("$field:N--", m)) + .endControlFlow(named("while ($field:N > $threshold:L)", m)) + .build(); - assertThat(methodSpec.toString()).isEqualTo("" - + "void method() {\n" + - " do {\n" + - " valueField--;\n" + - " } while (valueField > 5);\n" + - "}\n"); + assertThat(MethodSpec.constructorBuilder().addComment("Test: $S", "foo\nbar").build().toString()).isEqualTo("" + + "void method() {\n" + + " do {\n" + + " valueField--;\n" + + " } while (valueField > 5);\n" + + "}\n"); } private static CodeBlock named(String format, Map args){ From e2fd698564bf985cc30a3918abc7e4ae57b40046 Mon Sep 17 00:00:00 2001 From: jdyjjj <1410234026@qq.com> Date: Sat, 23 Apr 2022 10:16:44 +0800 Subject: [PATCH 2/3] Update MethodSpecTest.java --- .../com/squareup/javapoet/MethodSpecTest.java | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/squareup/javapoet/MethodSpecTest.java b/src/test/java/com/squareup/javapoet/MethodSpecTest.java index e1d8fa606..15e39c1ed 100644 --- a/src/test/java/com/squareup/javapoet/MethodSpecTest.java +++ b/src/test/java/com/squareup/javapoet/MethodSpecTest.java @@ -479,6 +479,40 @@ private TypeElement getElement(Class clazz) { // " valueField--;\n" + // " } while (valueField > 5);\n" + // "}\n"); +// } + +// @Test public void multilineComments() { +// MethodSpec main = MethodSpec.methodBuilder("main") +// .addModifiers(Modifier.PUBLIC, Modifier.STATIC) +// .returns(void.class) +// .addParameter(String[].class, "args") +// .addComment("Hello\nmultiline\ncomments!") +// .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!") +// .build(); +// +// assertThat(main.toString()).isEqualTo("" + +// "public static void main(java.lang.String[] args) {\n" + +// " // Hello\n" + +// " // multiline\n" + +// " // comments!\n" + +// " java.lang.System.out.println(\"Hello, JavaPoet!\");\n" + +// "}\n"); +// } +// +// @Test public void singleLineComments() { +// MethodSpec main = MethodSpec.methodBuilder("main") +// .addModifiers(Modifier.PUBLIC, Modifier.STATIC) +// .returns(void.class) +// .addParameter(String[].class, "args") +// .addComment("Hello single line comments!") +// .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!") +// .build(); +// +// assertThat(main.toString()).isEqualTo("" + +// "public static void main(java.lang.String[] args) {\n" + +// " // Hello single line comments!\n" + +// " java.lang.System.out.println(\"Hello, JavaPoet!\");\n" + +// "}\n"); // } @Test public void testnew() { @@ -491,8 +525,8 @@ private TypeElement getElement(Class clazz) { .addStatement(named("$field:N--", m)) .endControlFlow(named("while ($field:N > $threshold:L)", m)) .build(); - - assertThat(MethodSpec.constructorBuilder().addComment("Test: $S", "foo\nbar").build().toString()).isEqualTo("" +// assertThat(MethodSpec.constructorBuilder().addComment("Test: $L", "foo\nbar").build().toString()).isEqualTo("" + assertThat(MethodSpec.constructorBuilder().addComment("Test: $L", "foo\nbar").build().toString()).isEqualTo("" + "void method() {\n" + " do {\n" + " valueField--;\n" + From cf501ab4a3f5fda28455b0a1d1f917fc93b5da67 Mon Sep 17 00:00:00 2001 From: jdyjjj <1410234026@qq.com> Date: Tue, 17 May 2022 23:02:47 +0800 Subject: [PATCH 3/3] Fix #604 Multiline Strings Forcefully Wrapping With Concatenation Causing Issues --- .../java/com/squareup/javapoet/CodeBlock.java | 27 + .../com/squareup/javapoet/MethodSpec.java | 13 +- src/main/java/com/squareup/javapoet/Util.java | 2 +- .../com/squareup/javapoet/MethodSpecTest.java | 883 +++++++++--------- 4 files changed, 458 insertions(+), 467 deletions(-) diff --git a/src/main/java/com/squareup/javapoet/CodeBlock.java b/src/main/java/com/squareup/javapoet/CodeBlock.java index 02542f58b..768fcbb0b 100644 --- a/src/main/java/com/squareup/javapoet/CodeBlock.java +++ b/src/main/java/com/squareup/javapoet/CodeBlock.java @@ -349,6 +349,33 @@ private Object argToLiteral(Object o) { } private String argToString(Object o) { + if(o instanceof String){ + int index = -1; + StringBuilder str= new StringBuilder(); + char temp = '\\'; + for(int i=0;i<((String) o).length();i++){ + if(((String) o).charAt(i)==10){ + if(i==0) { + str.append(temp).append("n"); + index=i+1; + }else if(index==-1) { + str.append(((String) o).substring(0, i)).append(temp).append("n"); + index=i+1; + }else { + str.append(((String) o).substring(index, i)).append(temp).append("n"); + index=i+1; + } + } + } + if(index==-1){ + return o != null ? String.valueOf(o) : null; + } + if(index!=((String) o).length() ){ + str.append(((String) o).substring(index, ((String) o).length())); + } + return str.toString(); + + } return o != null ? String.valueOf(o) : null; } diff --git a/src/main/java/com/squareup/javapoet/MethodSpec.java b/src/main/java/com/squareup/javapoet/MethodSpec.java index ce337910d..67722c774 100644 --- a/src/main/java/com/squareup/javapoet/MethodSpec.java +++ b/src/main/java/com/squareup/javapoet/MethodSpec.java @@ -451,17 +451,8 @@ public Builder addCode(CodeBlock codeBlock) { } public Builder addComment(String format, Object... args) { - String[] lines = format.split("\\R"); - if(lines.length==1){ - code.add("// " + format + "\n", args); - return this; - }else { - for (String line : lines) { - code.add("// " + line + "\n"); - } - return this; - } -// return this; + code.add("// " + format + "\n", args); + return this; } public Builder defaultValue(String format, Object... args) { diff --git a/src/main/java/com/squareup/javapoet/Util.java b/src/main/java/com/squareup/javapoet/Util.java index e0eabadab..6d1575b71 100644 --- a/src/main/java/com/squareup/javapoet/Util.java +++ b/src/main/java/com/squareup/javapoet/Util.java @@ -96,7 +96,7 @@ static String characterLiteralWithoutSingleQuotes(char c) { case '\r': return "\\r"; /* \u000d: carriage return (CR) */ case '\"': return "\""; /* \u0022: double quote (") */ case '\'': return "\\'"; /* \u0027: single quote (') */ - case '\\': return "\\\\"; /* \u005c: backslash (\) */ + case '\\': return "\\"; /* \u005c: backslash (\) */ default: return isISOControl(c) ? String.format("\\u%04x", (int) c) : Character.toString(c); } diff --git a/src/test/java/com/squareup/javapoet/MethodSpecTest.java b/src/test/java/com/squareup/javapoet/MethodSpecTest.java index 15e39c1ed..cdb552d92 100644 --- a/src/test/java/com/squareup/javapoet/MethodSpecTest.java +++ b/src/test/java/com/squareup/javapoet/MethodSpecTest.java @@ -63,459 +63,406 @@ private TypeElement getElement(Class clazz) { return elements.getTypeElement(clazz.getCanonicalName()); } -// @Test public void nullAnnotationsAddition() { -// try { -// MethodSpec.methodBuilder("doSomething").addAnnotations(null); -// fail(); -// } catch (IllegalArgumentException expected) { -// assertThat(expected).hasMessageThat().isEqualTo("annotationSpecs == null"); -// } -// } -// -// @Test public void nullTypeVariablesAddition() { -// try { -// MethodSpec.methodBuilder("doSomething").addTypeVariables(null); -// fail(); -// } catch (IllegalArgumentException expected) { -// assertThat(expected).hasMessageThat().isEqualTo("typeVariables == null"); -// } -// } -// -// @Test public void nullParametersAddition() { -// try { -// MethodSpec.methodBuilder("doSomething").addParameters(null); -// fail(); -// } catch (IllegalArgumentException expected) { -// assertThat(expected).hasMessageThat().isEqualTo("parameterSpecs == null"); -// } -// } -// -// @Test public void nullExceptionsAddition() { -// try { -// MethodSpec.methodBuilder("doSomething").addExceptions(null); -// fail(); -// } catch (IllegalArgumentException expected) { -// assertThat(expected).hasMessageThat().isEqualTo("exceptions == null"); -// } -// } -// -// @Target(ElementType.PARAMETER) -// @interface Nullable { -// } -// -// abstract static class Everything { -// @Deprecated protected abstract Runnable everything( -// @Nullable String thing, List things) throws IOException, SecurityException; -// } -// -// abstract static class Generics { -// T run(R param) throws V { -// return null; -// } -// } -// -// abstract static class HasAnnotation { -// @Override public abstract String toString(); -// } -// -// interface Throws { -// void fail() throws R; -// } -// -// interface ExtendsOthers extends Callable, Comparable, -// Throws { -// } -// -// interface ExtendsIterableWithDefaultMethods extends Iterable { -// } -// -// final class FinalClass { -// void method() { -// } -// } -// -// abstract static class InvalidOverrideMethods { -// final void finalMethod() { -// } -// -// private void privateMethod() { -// } -// -// static void staticMethod() { -// } -// } -// -// @Test public void overrideEverything() { -// TypeElement classElement = getElement(Everything.class); -// ExecutableElement methodElement = getOnlyElement(methodsIn(classElement.getEnclosedElements())); -// MethodSpec method = MethodSpec.overriding(methodElement).build(); -// assertThat(method.toString()).isEqualTo("" -// + "@java.lang.Override\n" -// + "protected java.lang.Runnable " -// + "everything(\n" -// + " java.lang.String arg0, java.util.List arg1) throws java.io.IOException,\n" -// + " java.lang.SecurityException {\n" -// + "}\n"); -// } -// -// @Test public void overrideGenerics() { -// TypeElement classElement = getElement(Generics.class); -// ExecutableElement methodElement = getOnlyElement(methodsIn(classElement.getEnclosedElements())); -// MethodSpec method = MethodSpec.overriding(methodElement) -// .addStatement("return null") -// .build(); -// assertThat(method.toString()).isEqualTo("" -// + "@java.lang.Override\n" -// + " T run(R param) throws V {\n" -// + " return null;\n" -// + "}\n"); -// } -// -// @Test public void overrideDoesNotCopyOverrideAnnotation() { -// TypeElement classElement = getElement(HasAnnotation.class); -// ExecutableElement exec = getOnlyElement(methodsIn(classElement.getEnclosedElements())); -// MethodSpec method = MethodSpec.overriding(exec).build(); -// assertThat(method.toString()).isEqualTo("" -// + "@java.lang.Override\n" -// + "public java.lang.String toString() {\n" -// + "}\n"); -// } -// -// @Test public void overrideDoesNotCopyDefaultModifier() { -// TypeElement classElement = getElement(ExtendsIterableWithDefaultMethods.class); -// DeclaredType classType = (DeclaredType) classElement.asType(); -// List methods = methodsIn(elements.getAllMembers(classElement)); -// ExecutableElement exec = findFirst(methods, "spliterator"); -// MethodSpec method = MethodSpec.overriding(exec, classType, types).build(); -// assertThat(method.toString()).isEqualTo("" -// + "@java.lang.Override\n" -// + "public java.util.Spliterator spliterator() {\n" -// + "}\n"); -// } -// -// @Test public void overrideExtendsOthersWorksWithActualTypeParameters() { -// TypeElement classElement = getElement(ExtendsOthers.class); -// DeclaredType classType = (DeclaredType) classElement.asType(); -// List methods = methodsIn(elements.getAllMembers(classElement)); -// ExecutableElement exec = findFirst(methods, "call"); -// MethodSpec method = MethodSpec.overriding(exec, classType, types).build(); -// assertThat(method.toString()).isEqualTo("" -// + "@java.lang.Override\n" -// + "public java.lang.Integer call() throws java.lang.Exception {\n" -// + "}\n"); -// exec = findFirst(methods, "compareTo"); -// method = MethodSpec.overriding(exec, classType, types).build(); -// assertThat(method.toString()).isEqualTo("" -// + "@java.lang.Override\n" -// + "public int compareTo(" + ExtendsOthers.class.getCanonicalName() + " arg0) {\n" -// + "}\n"); -// exec = findFirst(methods, "fail"); -// method = MethodSpec.overriding(exec, classType, types).build(); -// assertThat(method.toString()).isEqualTo("" -// + "@java.lang.Override\n" -// + "public void fail() throws java.lang.IllegalStateException {\n" -// + "}\n"); -// } -// -// @Test public void overrideFinalClassMethod() { -// TypeElement classElement = getElement(FinalClass.class); -// List methods = methodsIn(elements.getAllMembers(classElement)); -// try { -// MethodSpec.overriding(findFirst(methods, "method")); -// fail(); -// } catch (IllegalArgumentException expected) { -// assertThat(expected).hasMessageThat().isEqualTo( -// "Cannot override method on final class com.squareup.javapoet.MethodSpecTest.FinalClass"); -// } -// } -// -// @Test public void overrideInvalidModifiers() { -// TypeElement classElement = getElement(InvalidOverrideMethods.class); -// List methods = methodsIn(elements.getAllMembers(classElement)); -// try { -// MethodSpec.overriding(findFirst(methods, "finalMethod")); -// fail(); -// } catch (IllegalArgumentException expected) { -// assertThat(expected).hasMessageThat().isEqualTo("cannot override method with modifiers: [final]"); -// } -// try { -// MethodSpec.overriding(findFirst(methods, "privateMethod")); -// fail(); -// } catch (IllegalArgumentException expected) { -// assertThat(expected).hasMessageThat().isEqualTo("cannot override method with modifiers: [private]"); -// } -// try { -// MethodSpec.overriding(findFirst(methods, "staticMethod")); -// fail(); -// } catch (IllegalArgumentException expected) { -// assertThat(expected).hasMessageThat().isEqualTo("cannot override method with modifiers: [static]"); -// } -// } -// -// abstract static class AbstractClassWithPrivateAnnotation { -// -// private @interface PrivateAnnotation{ } -// -// abstract void foo(@PrivateAnnotation final String bar); -// } -// -// @Test public void overrideDoesNotCopyParameterAnnotations() { -// TypeElement abstractTypeElement = getElement(AbstractClassWithPrivateAnnotation.class); -// ExecutableElement fooElement = ElementFilter.methodsIn(abstractTypeElement.getEnclosedElements()).get(0); -// ClassName implClassName = ClassName.get("com.squareup.javapoet", "Impl"); -// TypeSpec type = TypeSpec.classBuilder(implClassName) -// .superclass(abstractTypeElement.asType()) -// .addMethod(MethodSpec.overriding(fooElement).build()) -// .build(); -// JavaFileObject jfo = JavaFile.builder(implClassName.packageName, type).build().toJavaFileObject(); -// Compilation compilation = javac().compile(jfo); -// assertThat(compilation).succeeded(); -// } -// -// @Test public void equalsAndHashCode() { -// MethodSpec a = MethodSpec.constructorBuilder().build(); -// MethodSpec b = MethodSpec.constructorBuilder().build(); -// assertThat(a.equals(b)).isTrue(); -// assertThat(a.hashCode()).isEqualTo(b.hashCode()); -// a = MethodSpec.methodBuilder("taco").build(); -// b = MethodSpec.methodBuilder("taco").build(); -// assertThat(a.equals(b)).isTrue(); -// assertThat(a.hashCode()).isEqualTo(b.hashCode()); -// TypeElement classElement = getElement(Everything.class); -// ExecutableElement methodElement = getOnlyElement(methodsIn(classElement.getEnclosedElements())); -// a = MethodSpec.overriding(methodElement).build(); -// b = MethodSpec.overriding(methodElement).build(); -// assertThat(a.equals(b)).isTrue(); -// assertThat(a.hashCode()).isEqualTo(b.hashCode()); -// } -// -// @Test public void withoutParameterJavaDoc() { -// MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") -// .addModifiers(Modifier.PRIVATE) -// .addParameter(TypeName.DOUBLE, "money") -// .addJavadoc("Gets the best Taco\n") -// .build(); -// assertThat(methodSpec.toString()).isEqualTo("" -// + "/**\n" -// + " * Gets the best Taco\n" -// + " */\n" -// + "private void getTaco(double money) {\n" -// + "}\n"); -// } -// -// @Test public void withParameterJavaDoc() { -// MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") -// .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "money") -// .addJavadoc("the amount required to buy the taco.\n") -// .build()) -// .addParameter(ParameterSpec.builder(TypeName.INT, "count") -// .addJavadoc("the number of Tacos to buy.\n") -// .build()) -// .addJavadoc("Gets the best Taco money can buy.\n") -// .build(); -// assertThat(methodSpec.toString()).isEqualTo("" -// + "/**\n" -// + " * Gets the best Taco money can buy.\n" -// + " *\n" -// + " * @param money the amount required to buy the taco.\n" -// + " * @param count the number of Tacos to buy.\n" -// + " */\n" -// + "void getTaco(double money, int count) {\n" -// + "}\n"); -// } -// -// @Test public void withParameterJavaDocAndWithoutMethodJavadoc() { -// MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") -// .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "money") -// .addJavadoc("the amount required to buy the taco.\n") -// .build()) -// .addParameter(ParameterSpec.builder(TypeName.INT, "count") -// .addJavadoc("the number of Tacos to buy.\n") -// .build()) -// .build(); -// assertThat(methodSpec.toString()).isEqualTo("" -// + "/**\n" -// + " * @param money the amount required to buy the taco.\n" -// + " * @param count the number of Tacos to buy.\n" -// + " */\n" -// + "void getTaco(double money, int count) {\n" -// + "}\n"); -// } -// -// @Test public void duplicateExceptionsIgnored() { -// ClassName ioException = ClassName.get(IOException.class); -// ClassName timeoutException = ClassName.get(TimeoutException.class); -// MethodSpec methodSpec = MethodSpec.methodBuilder("duplicateExceptions") -// .addException(ioException) -// .addException(timeoutException) -// .addException(timeoutException) -// .addException(ioException) -// .build(); -// assertThat(methodSpec.exceptions).isEqualTo(Arrays.asList(ioException, timeoutException)); -// assertThat(methodSpec.toBuilder().addException(ioException).build().exceptions) -// .isEqualTo(Arrays.asList(ioException, timeoutException)); -// } -// -// @Test public void nullIsNotAValidMethodName() { -// try { -// MethodSpec.methodBuilder(null); -// fail("NullPointerException expected"); -// } catch (NullPointerException e) { -// assertThat(e.getMessage()).isEqualTo("name == null"); -// } -// } -// -// @Test public void addModifiersVarargsShouldNotBeNull() { -// try { -// MethodSpec.methodBuilder("taco") -// .addModifiers((Modifier[]) null); -// fail("NullPointerException expected"); -// } catch (NullPointerException e) { -// assertThat(e.getMessage()).isEqualTo("modifiers == null"); -// } -// } -// -// @Test public void modifyMethodName() { -// MethodSpec methodSpec = MethodSpec.methodBuilder("initialMethod") -// .build() -// .toBuilder() -// .setName("revisedMethod") -// .build(); -// -// assertThat(methodSpec.toString()).isEqualTo("" + "void revisedMethod() {\n" + "}\n"); -// } -// -// @Test public void modifyAnnotations() { -// MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") -// .addAnnotation(Override.class) -// .addAnnotation(SuppressWarnings.class); -// -// builder.annotations.remove(1); -// assertThat(builder.build().annotations).hasSize(1); -// } -// -// @Test public void modifyModifiers() { -// MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") -// .addModifiers(Modifier.PUBLIC, Modifier.STATIC); -// -// builder.modifiers.remove(1); -// assertThat(builder.build().modifiers).containsExactly(Modifier.PUBLIC); -// } -// -// @Test public void modifyParameters() { -// MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") -// .addParameter(int.class, "source"); -// -// builder.parameters.remove(0); -// assertThat(builder.build().parameters).isEmpty(); -// } -// -// @Test public void modifyTypeVariables() { -// TypeVariableName t = TypeVariableName.get("T"); -// MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") -// .addTypeVariable(t) -// .addTypeVariable(TypeVariableName.get("V")); -// -// builder.typeVariables.remove(1); -// assertThat(builder.build().typeVariables).containsExactly(t); -// } -// -// @Test public void ensureTrailingNewline() { -// MethodSpec methodSpec = MethodSpec.methodBuilder("method") -// .addCode("codeWithNoNewline();") -// .build(); -// -// assertThat(methodSpec.toString()).isEqualTo("" -// + "void method() {\n" -// + " codeWithNoNewline();\n" -// + "}\n"); -// } -// -// /** Ensures that we don't add a duplicate newline if one is already present. */ -// @Test public void ensureTrailingNewlineWithExistingNewline() { -// MethodSpec methodSpec = MethodSpec.methodBuilder("method") -// .addCode("codeWithNoNewline();\n") // Have a newline already, so ensure we're not adding one -// .build(); -// -// assertThat(methodSpec.toString()).isEqualTo("" -// + "void method() {\n" -// + " codeWithNoNewline();\n" -// + "}\n"); -// } -// -// @Test public void controlFlowWithNamedCodeBlocks() { -// Map m = new HashMap<>(); -// m.put("field", "valueField"); -// m.put("threshold", "5"); -// -// MethodSpec methodSpec = MethodSpec.methodBuilder("method") -// .beginControlFlow(named("if ($field:N > $threshold:L)", m)) -// .nextControlFlow(named("else if ($field:N == $threshold:L)", m)) -// .endControlFlow() -// .build(); -// -// assertThat(methodSpec.toString()).isEqualTo("" -// + "void method() {\n" -// + " if (valueField > 5) {\n" -// + " } else if (valueField == 5) {\n" -// + " }\n" -// + "}\n"); -// } -// -// @Test public void doWhileWithNamedCodeBlocks() { -// Map m = new HashMap<>(); -// m.put("field", "valueField"); -// m.put("threshold", "5"); -// -// MethodSpec methodSpec = MethodSpec.methodBuilder("method") -// .beginControlFlow("do") -// .addStatement(named("$field:N--", m)) -// .endControlFlow(named("while ($field:N > $threshold:L)", m)) -// .build(); -// -// assertThat(methodSpec.toString()).isEqualTo("" -// + "void method() {\n" + -// " do {\n" + -// " valueField--;\n" + -// " } while (valueField > 5);\n" + -// "}\n"); -// } - -// @Test public void multilineComments() { -// MethodSpec main = MethodSpec.methodBuilder("main") -// .addModifiers(Modifier.PUBLIC, Modifier.STATIC) -// .returns(void.class) -// .addParameter(String[].class, "args") -// .addComment("Hello\nmultiline\ncomments!") -// .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!") -// .build(); -// -// assertThat(main.toString()).isEqualTo("" + -// "public static void main(java.lang.String[] args) {\n" + -// " // Hello\n" + -// " // multiline\n" + -// " // comments!\n" + -// " java.lang.System.out.println(\"Hello, JavaPoet!\");\n" + -// "}\n"); -// } -// -// @Test public void singleLineComments() { -// MethodSpec main = MethodSpec.methodBuilder("main") -// .addModifiers(Modifier.PUBLIC, Modifier.STATIC) -// .returns(void.class) -// .addParameter(String[].class, "args") -// .addComment("Hello single line comments!") -// .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!") -// .build(); -// -// assertThat(main.toString()).isEqualTo("" + -// "public static void main(java.lang.String[] args) {\n" + -// " // Hello single line comments!\n" + -// " java.lang.System.out.println(\"Hello, JavaPoet!\");\n" + -// "}\n"); -// } - - @Test public void testnew() { + @Test public void nullAnnotationsAddition() { + try { + MethodSpec.methodBuilder("doSomething").addAnnotations(null); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("annotationSpecs == null"); + } + } + + @Test public void nullTypeVariablesAddition() { + try { + MethodSpec.methodBuilder("doSomething").addTypeVariables(null); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("typeVariables == null"); + } + } + + @Test public void nullParametersAddition() { + try { + MethodSpec.methodBuilder("doSomething").addParameters(null); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("parameterSpecs == null"); + } + } + + @Test public void nullExceptionsAddition() { + try { + MethodSpec.methodBuilder("doSomething").addExceptions(null); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("exceptions == null"); + } + } + + @Target(ElementType.PARAMETER) + @interface Nullable { + } + + abstract static class Everything { + @Deprecated protected abstract Runnable everything( + @Nullable String thing, List things) throws IOException, SecurityException; + } + + abstract static class Generics { + T run(R param) throws V { + return null; + } + } + + abstract static class HasAnnotation { + @Override public abstract String toString(); + } + + interface Throws { + void fail() throws R; + } + + interface ExtendsOthers extends Callable, Comparable, + Throws { + } + + interface ExtendsIterableWithDefaultMethods extends Iterable { + } + + final class FinalClass { + void method() { + } + } + + abstract static class InvalidOverrideMethods { + final void finalMethod() { + } + + private void privateMethod() { + } + + static void staticMethod() { + } + } + + @Test public void overrideEverything() { + TypeElement classElement = getElement(Everything.class); + ExecutableElement methodElement = getOnlyElement(methodsIn(classElement.getEnclosedElements())); + MethodSpec method = MethodSpec.overriding(methodElement).build(); + assertThat(method.toString()).isEqualTo("" + + "@java.lang.Override\n" + + "protected java.lang.Runnable " + + "everything(\n" + + " java.lang.String arg0, java.util.List arg1) throws java.io.IOException,\n" + + " java.lang.SecurityException {\n" + + "}\n"); + } + + @Test public void overrideGenerics() { + TypeElement classElement = getElement(Generics.class); + ExecutableElement methodElement = getOnlyElement(methodsIn(classElement.getEnclosedElements())); + MethodSpec method = MethodSpec.overriding(methodElement) + .addStatement("return null") + .build(); + assertThat(method.toString()).isEqualTo("" + + "@java.lang.Override\n" + + " T run(R param) throws V {\n" + + " return null;\n" + + "}\n"); + } + + @Test public void overrideDoesNotCopyOverrideAnnotation() { + TypeElement classElement = getElement(HasAnnotation.class); + ExecutableElement exec = getOnlyElement(methodsIn(classElement.getEnclosedElements())); + MethodSpec method = MethodSpec.overriding(exec).build(); + assertThat(method.toString()).isEqualTo("" + + "@java.lang.Override\n" + + "public java.lang.String toString() {\n" + + "}\n"); + } + + @Test public void overrideDoesNotCopyDefaultModifier() { + TypeElement classElement = getElement(ExtendsIterableWithDefaultMethods.class); + DeclaredType classType = (DeclaredType) classElement.asType(); + List methods = methodsIn(elements.getAllMembers(classElement)); + ExecutableElement exec = findFirst(methods, "spliterator"); + MethodSpec method = MethodSpec.overriding(exec, classType, types).build(); + assertThat(method.toString()).isEqualTo("" + + "@java.lang.Override\n" + + "public java.util.Spliterator spliterator() {\n" + + "}\n"); + } + + @Test public void overrideExtendsOthersWorksWithActualTypeParameters() { + TypeElement classElement = getElement(ExtendsOthers.class); + DeclaredType classType = (DeclaredType) classElement.asType(); + List methods = methodsIn(elements.getAllMembers(classElement)); + ExecutableElement exec = findFirst(methods, "call"); + MethodSpec method = MethodSpec.overriding(exec, classType, types).build(); + assertThat(method.toString()).isEqualTo("" + + "@java.lang.Override\n" + + "public java.lang.Integer call() throws java.lang.Exception {\n" + + "}\n"); + exec = findFirst(methods, "compareTo"); + method = MethodSpec.overriding(exec, classType, types).build(); + assertThat(method.toString()).isEqualTo("" + + "@java.lang.Override\n" + + "public int compareTo(" + ExtendsOthers.class.getCanonicalName() + " arg0) {\n" + + "}\n"); + exec = findFirst(methods, "fail"); + method = MethodSpec.overriding(exec, classType, types).build(); + assertThat(method.toString()).isEqualTo("" + + "@java.lang.Override\n" + + "public void fail() throws java.lang.IllegalStateException {\n" + + "}\n"); + } + + @Test public void overrideFinalClassMethod() { + TypeElement classElement = getElement(FinalClass.class); + List methods = methodsIn(elements.getAllMembers(classElement)); + try { + MethodSpec.overriding(findFirst(methods, "method")); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo( + "Cannot override method on final class com.squareup.javapoet.MethodSpecTest.FinalClass"); + } + } + + @Test public void overrideInvalidModifiers() { + TypeElement classElement = getElement(InvalidOverrideMethods.class); + List methods = methodsIn(elements.getAllMembers(classElement)); + try { + MethodSpec.overriding(findFirst(methods, "finalMethod")); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("cannot override method with modifiers: [final]"); + } + try { + MethodSpec.overriding(findFirst(methods, "privateMethod")); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("cannot override method with modifiers: [private]"); + } + try { + MethodSpec.overriding(findFirst(methods, "staticMethod")); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().isEqualTo("cannot override method with modifiers: [static]"); + } + } + + abstract static class AbstractClassWithPrivateAnnotation { + + private @interface PrivateAnnotation{ } + + abstract void foo(@PrivateAnnotation final String bar); + } + + @Test public void overrideDoesNotCopyParameterAnnotations() { + TypeElement abstractTypeElement = getElement(AbstractClassWithPrivateAnnotation.class); + ExecutableElement fooElement = ElementFilter.methodsIn(abstractTypeElement.getEnclosedElements()).get(0); + ClassName implClassName = ClassName.get("com.squareup.javapoet", "Impl"); + TypeSpec type = TypeSpec.classBuilder(implClassName) + .superclass(abstractTypeElement.asType()) + .addMethod(MethodSpec.overriding(fooElement).build()) + .build(); + JavaFileObject jfo = JavaFile.builder(implClassName.packageName, type).build().toJavaFileObject(); + Compilation compilation = javac().compile(jfo); + assertThat(compilation).succeeded(); + } + + @Test public void equalsAndHashCode() { + MethodSpec a = MethodSpec.constructorBuilder().build(); + MethodSpec b = MethodSpec.constructorBuilder().build(); + assertThat(a.equals(b)).isTrue(); + assertThat(a.hashCode()).isEqualTo(b.hashCode()); + a = MethodSpec.methodBuilder("taco").build(); + b = MethodSpec.methodBuilder("taco").build(); + assertThat(a.equals(b)).isTrue(); + assertThat(a.hashCode()).isEqualTo(b.hashCode()); + TypeElement classElement = getElement(Everything.class); + ExecutableElement methodElement = getOnlyElement(methodsIn(classElement.getEnclosedElements())); + a = MethodSpec.overriding(methodElement).build(); + b = MethodSpec.overriding(methodElement).build(); + assertThat(a.equals(b)).isTrue(); + assertThat(a.hashCode()).isEqualTo(b.hashCode()); + } + + @Test public void withoutParameterJavaDoc() { + MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") + .addModifiers(Modifier.PRIVATE) + .addParameter(TypeName.DOUBLE, "money") + .addJavadoc("Gets the best Taco\n") + .build(); + assertThat(methodSpec.toString()).isEqualTo("" + + "/**\n" + + " * Gets the best Taco\n" + + " */\n" + + "private void getTaco(double money) {\n" + + "}\n"); + } + + @Test public void withParameterJavaDoc() { + MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") + .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "money") + .addJavadoc("the amount required to buy the taco.\n") + .build()) + .addParameter(ParameterSpec.builder(TypeName.INT, "count") + .addJavadoc("the number of Tacos to buy.\n") + .build()) + .addJavadoc("Gets the best Taco money can buy.\n") + .build(); + assertThat(methodSpec.toString()).isEqualTo("" + + "/**\n" + + " * Gets the best Taco money can buy.\n" + + " *\n" + + " * @param money the amount required to buy the taco.\n" + + " * @param count the number of Tacos to buy.\n" + + " */\n" + + "void getTaco(double money, int count) {\n" + + "}\n"); + } + + @Test public void withParameterJavaDocAndWithoutMethodJavadoc() { + MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") + .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "money") + .addJavadoc("the amount required to buy the taco.\n") + .build()) + .addParameter(ParameterSpec.builder(TypeName.INT, "count") + .addJavadoc("the number of Tacos to buy.\n") + .build()) + .build(); + assertThat(methodSpec.toString()).isEqualTo("" + + "/**\n" + + " * @param money the amount required to buy the taco.\n" + + " * @param count the number of Tacos to buy.\n" + + " */\n" + + "void getTaco(double money, int count) {\n" + + "}\n"); + } + + @Test public void duplicateExceptionsIgnored() { + ClassName ioException = ClassName.get(IOException.class); + ClassName timeoutException = ClassName.get(TimeoutException.class); + MethodSpec methodSpec = MethodSpec.methodBuilder("duplicateExceptions") + .addException(ioException) + .addException(timeoutException) + .addException(timeoutException) + .addException(ioException) + .build(); + assertThat(methodSpec.exceptions).isEqualTo(Arrays.asList(ioException, timeoutException)); + assertThat(methodSpec.toBuilder().addException(ioException).build().exceptions) + .isEqualTo(Arrays.asList(ioException, timeoutException)); + } + + @Test public void nullIsNotAValidMethodName() { + try { + MethodSpec.methodBuilder(null); + fail("NullPointerException expected"); + } catch (NullPointerException e) { + assertThat(e.getMessage()).isEqualTo("name == null"); + } + } + + @Test public void addModifiersVarargsShouldNotBeNull() { + try { + MethodSpec.methodBuilder("taco") + .addModifiers((Modifier[]) null); + fail("NullPointerException expected"); + } catch (NullPointerException e) { + assertThat(e.getMessage()).isEqualTo("modifiers == null"); + } + } + + @Test public void modifyMethodName() { + MethodSpec methodSpec = MethodSpec.methodBuilder("initialMethod") + .build() + .toBuilder() + .setName("revisedMethod") + .build(); + + assertThat(methodSpec.toString()).isEqualTo("" + "void revisedMethod() {\n" + "}\n"); + } + + @Test public void modifyAnnotations() { + MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") + .addAnnotation(Override.class) + .addAnnotation(SuppressWarnings.class); + + builder.annotations.remove(1); + assertThat(builder.build().annotations).hasSize(1); + } + + @Test public void modifyModifiers() { + MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") + .addModifiers(Modifier.PUBLIC, Modifier.STATIC); + + builder.modifiers.remove(1); + assertThat(builder.build().modifiers).containsExactly(Modifier.PUBLIC); + } + + @Test public void modifyParameters() { + MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") + .addParameter(int.class, "source"); + + builder.parameters.remove(0); + assertThat(builder.build().parameters).isEmpty(); + } + + @Test public void modifyTypeVariables() { + TypeVariableName t = TypeVariableName.get("T"); + MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") + .addTypeVariable(t) + .addTypeVariable(TypeVariableName.get("V")); + + builder.typeVariables.remove(1); + assertThat(builder.build().typeVariables).containsExactly(t); + } + + @Test public void ensureTrailingNewline() { + MethodSpec methodSpec = MethodSpec.methodBuilder("method") + .addCode("codeWithNoNewline();") + .build(); + + assertThat(methodSpec.toString()).isEqualTo("" + + "void method() {\n" + + " codeWithNoNewline();\n" + + "}\n"); + } + + /** Ensures that we don't add a duplicate newline if one is already present. */ + @Test public void ensureTrailingNewlineWithExistingNewline() { + MethodSpec methodSpec = MethodSpec.methodBuilder("method") + .addCode("codeWithNoNewline();\n") // Have a newline already, so ensure we're not adding one + .build(); + + assertThat(methodSpec.toString()).isEqualTo("" + + "void method() {\n" + + " codeWithNoNewline();\n" + + "}\n"); + } + + @Test public void controlFlowWithNamedCodeBlocks() { + Map m = new HashMap<>(); + m.put("field", "valueField"); + m.put("threshold", "5"); + + MethodSpec methodSpec = MethodSpec.methodBuilder("method") + .beginControlFlow(named("if ($field:N > $threshold:L)", m)) + .nextControlFlow(named("else if ($field:N == $threshold:L)", m)) + .endControlFlow() + .build(); + + assertThat(methodSpec.toString()).isEqualTo("" + + "void method() {\n" + + " if (valueField > 5) {\n" + + " } else if (valueField == 5) {\n" + + " }\n" + + "}\n"); + } + + @Test public void doWhileWithNamedCodeBlocks() { Map m = new HashMap<>(); m.put("field", "valueField"); m.put("threshold", "5"); @@ -525,8 +472,8 @@ private TypeElement getElement(Class clazz) { .addStatement(named("$field:N--", m)) .endControlFlow(named("while ($field:N > $threshold:L)", m)) .build(); -// assertThat(MethodSpec.constructorBuilder().addComment("Test: $L", "foo\nbar").build().toString()).isEqualTo("" - assertThat(MethodSpec.constructorBuilder().addComment("Test: $L", "foo\nbar").build().toString()).isEqualTo("" + + assertThat(methodSpec.toString()).isEqualTo("" + "void method() {\n" + " do {\n" + " valueField--;\n" + @@ -534,6 +481,32 @@ private TypeElement getElement(Class clazz) { "}\n"); } + @Test public void newLineAsStringCommentWithout$S() { + MethodSpec methodSpec = MethodSpec.methodBuilder("method") + .returns(void.class) + .addComment("The result of\\nissue \\\\n#604!") + .build(); + + assertThat(methodSpec.toString()).isEqualTo("" + + "void method() {\n" + + " // The result of\\nissue \\\\n#604!\n" + + "}\n"); + } + + @Test public void newLineAsStringCommentWith$S() { + MethodSpec methodSpec = MethodSpec.methodBuilder("method") + .returns(void.class) + .addComment("The result is: $S", "fixed \n issue \n #604!") + .build(); + + assertThat(methodSpec.toString()).isEqualTo("" + + "void method() {\n" + + " // The result is: \"fixed \\n issue \\n #604!\"\n" + + "}\n"); + } + + + private static CodeBlock named(String format, Map args){ return CodeBlock.builder().addNamed(format, args).build(); }