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

com.google.gwt.dev.jjs.MagicMethodGenerator Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2015 Google Inc.
 *
 * 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 com.google.gwt.dev.jjs;


import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodCall;

/**
 * This is the expected type signature for magic method injectors;
 * you do not need to explicitly implement this interface,
 * or the suggested method name; however, implementing this interface
 * allows you shorter gwt module xml, since you are not required to supply
 * the full method name.
 *
 *  The full, brutal syntax to add magic method injection is as follows:
 
  <extend-configuration-property name="gwt.magic.methods"
    value="jsni.method.ref.To.replace(Ljsni/param/Signature;)Ljsni/returned/Signature; *= type.of.magic.method.Generator::staticGenerateMethod"/>
 
* You may omit the ::staticGenerateMethod if your type implements {@link MagicMethodGenerator}. * * The first half of the value is the fully qualified jsni signature of the method you wish to overwrite: * com.package.Clazz.method(Ljsni/param/Signatures;)Ljsni/return/Type; * If your parameters or return type are generic, supply the erased type (whatever the jsni syntax would be) * * In the middle, we use " *= ", without quotes, as the delimiter between signatures. * * The second half of the value is the generator for the AST injection, * either a Fully Qualified Class Name that does implement MagicMethodGenerator * or a fully qualified static method that has the same parameter signature as * {@link #injectMagic(TreeLogger, JMethodCall, JMethod, Context, UnifyAstView)} * * com.package.Clazz // implements MagicMethodGenerator * or * com.package.Clazz::staticMethodName // static method, same param signature as injectMagic * * This type signature will be maintained for gwt.magic.method configuration property, * and if we change the api to be more concise or to give you access to more runtime data, * we will provide a new configuration property (and possible make the old one emit deprecation warnings). * * @author James X. Nelson ([email protected], @james) * */ public interface MagicMethodGenerator{ /** * This is the magic method type signature used to replace a given JMethodCall * with generated AST expressions or generated classes using StandardGeneratorContext * obtained using {@link UnifyAstView#getRebindPermutationOracle()}. *

* Note that magic methods suffer from the same requirement as GWT.create: * if you want to know what a class is at generate time, you must accept a * class literal, and not a class reference. *

* If you wish to generate code that accepts class references, you must * generate some kind of collection-backed factory method which can accept * your class ref and do something useful based on runtime analysis. *

* A generator that accepts ONLY class literals will be capable of inlining * all requested code at the call site, * rather than monolithic-compiling a bunch of code into a given factory. *

* If you absolutely must send a class reference and need type data at generation time, * consider annotating the methods calling your magic method, * since class literals in parameter annotations are simple to extract * (you are given the encapsulating method call). *

* NOTE THAT MAGIC METHOD INJECTION DOES NOT WORK IN REGULAR GWT DEV MODE, * (or any pure java runtime). *

* It is a production-mode only enhancement, * and combined with other xapi modules, * can allow you to use reflection or other jvm-only features from shared code. *

* A typical cross-platform use case is to have the method body use GWT.isClient, * let the jvm do standard reflection, * (i.e. getting a class name from system properties, and reflectively calling a method). * while gwt dev can use GWT.create (and share generator code w/ magic method injector). *

* You may not put code that is uncompilable in gwt behind a magic method call; * dev mode and ast reader still has to choke it down. * If you want to use reflection, include * net.wetheinter:xapi-gwt-api (or xapi-gwt uber jar), * which include emulated support for the java reflection api. *

* You are recommended to use super dev mode; * Given that dev mode performance doesn't affect production mode performance, * we personally only ever start dev mode during testing and to use the java debugger. *

* @param logger - The logger to log to. * @param methodCall - The method call we are overwriting * @param enclosingMethod - The method encapsulating the method call we are replacing. * @param context - The method call context, so you can insert clinits / whatnot *

* DO NOT CALL context.replaceMe() or context.removeMe(); return a value instead. * @param ast - A view over UnifyAst, exposing our basic needs * @return - A JExpression to replace the method call with * * @see {@link MagicMethodTestGenerator} for a reference implementation. */ JExpression injectMagic(TreeLogger logger, JMethodCall methodCall, JMethod enclosingMethod, Context context, UnifyAstView ast) throws UnableToCompleteException; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy