1 /** 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. 5 * Portions Copyright 2013-2018 Philip Helger + contributors 6 * 7 * The contents of this file are subject to the terms of either the GNU 8 * General Public License Version 2 only ("GPL") or the Common Development 9 * and Distribution License("CDDL") (collectively, the "License"). You 10 * may not use this file except in compliance with the License. You can 11 * obtain a copy of the License at 12 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html 13 * or packager/legal/LICENSE.txt. See the License for the specific 14 * language governing permissions and limitations under the License. 15 * 16 * When distributing the software, include this License Header Notice in each 17 * file and include the License file at packager/legal/LICENSE.txt. 18 * 19 * GPL Classpath Exception: 20 * Oracle designates this particular file as subject to the "Classpath" 21 * exception as provided by Oracle in the GPL Version 2 section of the License 22 * file that accompanied this code. 23 * 24 * Modifications: 25 * If applicable, add the following below the License Header, with the fields 26 * enclosed by brackets [] replaced by your own identifying information: 27 * "Portions Copyright [year] [name of copyright owner]" 28 * 29 * Contributor(s): 30 * If you wish your version of this file to be governed by only the CDDL or 31 * only the GPL Version 2, indicate your decision by adding "[Contributor] 32 * elects to include this software in this distribution under the [CDDL or GPL 33 * Version 2] license." If you don't indicate a single choice of license, a 34 * recipient has the option to distribute your version of this file under 35 * either the CDDL, the GPL Version 2 or to extend the choice of license to 36 * its licensees as provided above. However, if you add GPL Version 2 code 37 * and therefore, elected the GPL Version 2 license, then the option applies 38 * only if the new code is made subject to such option by the copyright 39 * holder. 40 */ 41 package com.helger.jcodemodel; 42 43 import javax.annotation.Nonnull; 44 import javax.annotation.Nullable; 45 46 import com.helger.jcodemodel.util.JCValueEnforcer; 47 48 /** 49 * This is a single Java 8 lambda method reference expression. 50 * 51 * @author Philip Helger 52 * @since 2.8.3 53 */ 54 public class JLambdaMethodRef implements IJExpression 55 { 56 private final boolean m_bStatic; 57 private final AbstractJType m_aType; 58 private final JVar m_aVar; 59 private final JInvocation m_aInvocation; 60 private final JMethod m_aMethod; 61 private final String m_sMethodName; 62 63 /** 64 * Constructor to reference the passed static method. It uses the name of the 65 * owning class as base (<code>owning::method</code>). 66 * 67 * @param aMethod 68 * The static method to reference. May not be <code>null</code>. 69 * @throws IllegalArgumentException 70 * If the passed method is not static 71 */ 72 public JLambdaMethodRef (@Nonnull final JMethod aMethod) 73 { 74 JCValueEnforcer.notNull (aMethod, "Method"); 75 JCValueEnforcer.isTrue (aMethod.mods ().isStatic (), 76 "Only static methods can be used with this constructor. Use the constructor with JVar for instance methods."); 77 78 m_bStatic = true; 79 m_aType = aMethod.owningClass (); 80 m_aVar = null; 81 m_aInvocation = null; 82 m_aMethod = aMethod; 83 m_sMethodName = null; 84 } 85 86 /** 87 * Constructor for a static constructor method reference 88 * (<code>type::new</code>). 89 * 90 * @param aType 91 * Type to reference the constructor from. May not be <code>null</code> 92 * . 93 */ 94 public JLambdaMethodRef (@Nonnull final AbstractJType aType) 95 { 96 this (aType, "new"); 97 } 98 99 /** 100 * Constructor for an arbitrary static method reference 101 * (<code>type::name</code>). 102 * 103 * @param aType 104 * Type the method belongs to. May not be <code>null</code>. 105 * @param sMethod 106 * Name of the static method to reference. May neither be 107 * <code>null</code> nor empty. 108 */ 109 public JLambdaMethodRef (@Nonnull final AbstractJType aType, @Nonnull final String sMethod) 110 { 111 JCValueEnforcer.notNull (aType, "Type"); 112 JCValueEnforcer.notEmpty (sMethod, "Method"); 113 114 m_bStatic = true; 115 m_aType = aType; 116 m_aVar = null; 117 m_aInvocation = null; 118 m_aMethod = null; 119 m_sMethodName = sMethod; 120 } 121 122 /** 123 * Constructor for an arbitrary instance method reference 124 * (<code>var::name</code>). 125 * 126 * @param aVar 127 * Variable containing the instance. May not be <code>null</code>. 128 * @param sMethod 129 * Name of the method to reference. May neither be <code>null</code> 130 * nor empty. 131 */ 132 public JLambdaMethodRef (@Nonnull final JVar aVar, @Nonnull final String sMethod) 133 { 134 JCValueEnforcer.notNull (aVar, "Var"); 135 JCValueEnforcer.notEmpty (sMethod, "Method"); 136 137 m_bStatic = false; 138 m_aType = aVar.type (); 139 m_aVar = aVar; 140 m_aInvocation = null; 141 m_aMethod = null; 142 m_sMethodName = sMethod; 143 } 144 145 /** 146 * Constructor for an arbitrary instance method reference 147 * (<code>var::name</code>). 148 * 149 * @param aVar 150 * Variable containing the instance. May not be <code>null</code>. 151 * @param aMethod 152 * The instance method to reference. May not be <code>null</code>. 153 */ 154 public JLambdaMethodRef (@Nonnull final JVar aVar, @Nonnull final JMethod aMethod) 155 { 156 JCValueEnforcer.notNull (aVar, "Var"); 157 JCValueEnforcer.notNull (aMethod, "Method"); 158 JCValueEnforcer.isFalse (aMethod.mods ().isStatic (), 159 "Only instance methods can be used with this constructor. Use the constructor with JMethod only for static methods."); 160 161 m_bStatic = false; 162 m_aType = aVar.type (); 163 m_aVar = aVar; 164 m_aInvocation = null; 165 m_aMethod = aMethod; 166 m_sMethodName = null; 167 } 168 169 /** 170 * Constructor for an arbitrary invocation method reference. 171 * 172 * @param aInvocation 173 * Variable containing the invocation. May not be <code>null</code>. 174 * @param sMethod 175 * Name of the method to reference. May neither be <code>null</code> 176 * nor empty. 177 */ 178 public JLambdaMethodRef (@Nonnull final JInvocation aInvocation, @Nonnull final String sMethod) 179 { 180 JCValueEnforcer.notNull (aInvocation, "Invocation"); 181 JCValueEnforcer.notEmpty (sMethod, "Method"); 182 183 m_bStatic = false; 184 m_aType = null; 185 m_aVar = null; 186 m_aInvocation = aInvocation; 187 m_aMethod = null; 188 m_sMethodName = sMethod; 189 } 190 191 /** 192 * Constructor for an arbitrary invocation method reference. 193 * 194 * @param aInvocation 195 * Variable containing the invocation. May not be <code>null</code>. 196 * @param aMethod 197 * The instance method to reference. May not be <code>null</code>. 198 */ 199 public JLambdaMethodRef (@Nonnull final JInvocation aInvocation, @Nonnull final JMethod aMethod) 200 { 201 JCValueEnforcer.notNull (aInvocation, "Invocation"); 202 JCValueEnforcer.notNull (aMethod, "Method"); 203 JCValueEnforcer.isFalse (aMethod.mods ().isStatic (), 204 "Only instance methods can be used with this constructor. Use the constructor with JMethod only for static methods."); 205 206 m_bStatic = false; 207 m_aType = aMethod.owningClass (); 208 m_aVar = null; 209 m_aInvocation = aInvocation; 210 m_aMethod = aMethod; 211 m_sMethodName = null; 212 } 213 214 /** 215 * @return <code>true</code> if this is a static reference, <code>false</code> 216 * if this is an instance reference. 217 */ 218 public boolean isStaticRef () 219 { 220 return m_bStatic; 221 } 222 223 /** 224 * @return The type owning the method. May be <code>null</code> if invoked 225 * with another JInvocation. 226 */ 227 @Nullable 228 public AbstractJType type () 229 { 230 return m_aType; 231 } 232 233 /** 234 * @return The variable for the instance reference. May be <code>null</code> 235 * if this is a static or invocation reference. 236 */ 237 @Nullable 238 public JVar var () 239 { 240 return m_aVar; 241 } 242 243 /** 244 * @return The invocation reference. May be <code>null</code> if this is a 245 * static or variable reference. 246 */ 247 @Nullable 248 public JInvocation invocation () 249 { 250 return m_aInvocation; 251 } 252 253 /** 254 * @return The owning method. May be <code>null</code> if a constructor with 255 * method name was used. 256 */ 257 @Nullable 258 public JMethod method () 259 { 260 return m_aMethod; 261 } 262 263 /** 264 * @return The name of the referenced method. Never <code>null</code>. 265 */ 266 @Nonnull 267 public String methodName () 268 { 269 return m_aMethod != null ? m_aMethod.name () : m_sMethodName; 270 } 271 272 @Override 273 public void generate (@Nonnull final IJFormatter f) 274 { 275 if (isStaticRef ()) 276 f.type (type ()); 277 else 278 if (m_aVar != null) 279 f.generable (m_aVar); 280 else 281 f.generable (m_aInvocation); 282 f.print ("::").print (methodName ()); 283 } 284 }