All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dagger.internal.codegen.xprocessing.XCodeBlocks Maven / Gradle / Ivy

There is a newer version: 2.9
Show newest version
/*
 * Copyright (C) 2025 The Dagger Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package dagger.internal.codegen.xprocessing;

import static androidx.room.compiler.codegen.compat.XConverters.toJavaPoet;
import static androidx.room.compiler.codegen.compat.XConverters.toKotlinPoet;
import static com.google.common.collect.Streams.stream;
import static com.squareup.javapoet.MethodSpec.methodBuilder;
import static com.squareup.javapoet.TypeSpec.anonymousClassBuilder;
import static dagger.internal.codegen.xprocessing.XTypeNames.daggerProviderOf;
import static javax.lang.model.element.Modifier.PUBLIC;

import androidx.room.compiler.codegen.XClassName;
import androidx.room.compiler.codegen.XCodeBlock;
import androidx.room.compiler.codegen.XParameterSpec;
import androidx.room.compiler.codegen.XTypeName;
import androidx.room.compiler.codegen.compat.XConverters;
import androidx.room.compiler.processing.XType;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.squareup.javapoet.CodeBlock;
import java.util.stream.Collector;

/** Convenience methods for creating {@link XCodeBlock}s. */
public final class XCodeBlocks {
  /**
   * Returns an {@link XCodeBlock} with the given java implementation and an empty kotlin
   * implementation.
   *
   * 

This is a temporary stop gap to allow us to migrate from javapoet to xprocessing without * having to do a strict top-down approach. */ public static XCodeBlock toXPoet(CodeBlock codeBlock) { return XConverters.toXPoet(codeBlock, com.squareup.kotlinpoet.CodeBlock.of("")); } /** * Joins {@link XCodeBlock} instances in a manner suitable for use as method parameters (or * arguments). */ public static Collector toParametersCodeBlock() { // TODO(ronshapiro,jakew): consider adding zero-width spaces to help line breaking when the // formatter is off. If not, inline this return joining(", "); } /** Concatenates {@link XCodeBlock} instances separated by newlines for readability. */ public static Collector toConcatenatedCodeBlock() { return joining("\n", "", "\n"); } /** Returns a comma-separated version of {@code codeBlocks} as one unified {@link XCodeBlock}. */ public static XCodeBlock makeParametersCodeBlock(Iterable codeBlocks) { return stream(codeBlocks).collect(toParametersCodeBlock()); } /** * Returns a comma-separated {@link XCodeBlock} using the name of every parameter in {@code * parameters}. */ public static XCodeBlock parameterNames(Iterable parameters) { // TODO(ronshapiro): Add DaggerStreams.stream(Iterable) return stream(parameters) .map(p -> XCodeBlock.of("%N", p.getName())) // SUPPRESS_GET_NAME_CHECK .collect(toParametersCodeBlock()); } /** * Returns one unified {@link XCodeBlock} which joins each item in {@code codeBlocks} with a * newline. */ public static XCodeBlock concat(Iterable codeBlocks) { return stream(codeBlocks).collect(toConcatenatedCodeBlock()); } /** * Returns an anonymous {@link javax.inject.Provider} class with the single {@link * javax.inject.Provider#get()} method that returns the given {@code expression}. */ public static XCodeBlock anonymousProvider(XExpression expression) { return anonymousProvider( expression.type().asTypeName(), XCodeBlock.of("return %L;", expression.codeBlock())); } /** * Returns an anonymous {@link javax.inject.Provider} class with the single {@link * javax.inject.Provider#get()} method implemented by {@code body}. */ public static XCodeBlock anonymousProvider(XTypeName providedType, XCodeBlock body) { return toXPoet( CodeBlock.of( "$L", anonymousClassBuilder("") .superclass(toJavaPoet(daggerProviderOf(providedType))) .addMethod( methodBuilder("get") .addAnnotation(Override.class) .addModifiers(PUBLIC) .returns(toJavaPoet(providedType)) .addCode(toJavaPoet(body)) .build()) .build())); } /** Returns {@code expression} cast to a type. */ public static XCodeBlock cast(XCodeBlock expression, XClassName castTo) { return XCodeBlock.ofCast(castTo, expression); } public static XCodeBlock type(XType type) { return XCodeBlock.of("%T", type.asTypeName()); } public static XCodeBlock stringLiteral(String toWrap) { return XCodeBlock.of("%S", toWrap); } public static XCodeBlock join(Iterable codeBlocks, String separator) { return stream(codeBlocks).collect(joining(separator)); } public static Collector joining(String separator) { return Collector.of( () -> new XCodeBlockJoiner(separator, XCodeBlock.builder()), XCodeBlockJoiner::add, XCodeBlockJoiner::merge, XCodeBlockJoiner::join); } public static Collector joining( String separator, String prefix, String suffix) { XCodeBlock.Builder builder = XCodeBlock.builder(); if (prefix != null && !prefix.isEmpty()) { builder.add("%L", prefix); } return Collector.of( () -> new XCodeBlockJoiner(separator, builder), XCodeBlockJoiner::add, XCodeBlockJoiner::merge, joiner -> { if (suffix != null && !suffix.isEmpty()) { builder.add("%L", suffix); } return joiner.join(); }); } public static boolean isEmpty(XCodeBlock codeBlock) { // TODO(bcorso): Take into account kotlin code blocks. return toJavaPoet(codeBlock).isEmpty(); } private static final class XCodeBlockJoiner { private final String delimiter; private final XCodeBlock.Builder builder; private boolean first = true; XCodeBlockJoiner(String delimiter, XCodeBlock.Builder builder) { this.delimiter = delimiter; this.builder = builder; } @CanIgnoreReturnValue XCodeBlockJoiner add(XCodeBlock codeBlock) { if (!first) { if (!toKotlinPoet(codeBlock).isEmpty()) { toKotlinPoet(builder).add(delimiter); } if (!toJavaPoet(codeBlock).isEmpty()) { toJavaPoet(builder).add(delimiter); } } first = false; if (!toKotlinPoet(codeBlock).isEmpty()) { toKotlinPoet(builder).add(toKotlinPoet(codeBlock)); } if (!toJavaPoet(codeBlock).isEmpty()) { toJavaPoet(builder).add(toJavaPoet(codeBlock)); } return this; } @CanIgnoreReturnValue XCodeBlockJoiner merge(XCodeBlockJoiner other) { add(other.builder.build()); return this; } XCodeBlock join() { return builder.build(); } } private XCodeBlocks() {} }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy