Package org.stjs.generator.writer.templates

Source Code of org.stjs.generator.writer.templates.DefaultTemplate

package org.stjs.generator.writer.templates;

import java.util.List;

import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;

import org.stjs.generator.GenerationContext;
import org.stjs.generator.GeneratorConstants;
import org.stjs.generator.javac.TreeUtils;
import org.stjs.generator.javascript.Keyword;
import org.stjs.generator.utils.JavaNodes;
import org.stjs.generator.writer.WriterContributor;
import org.stjs.generator.writer.WriterVisitor;
import org.stjs.generator.writer.expression.MethodInvocationWriter;

import com.sun.source.tree.MethodInvocationTree;

/**
* this is the standard generation template
*
* @author acraciun
*/
public class DefaultTemplate<JS> implements WriterContributor<MethodInvocationTree, JS> {

  private boolean isCallToSuperConstructor(MethodInvocationTree tree) {
    if (!TreeUtils.isSuperCall(tree)) {
      return false;
    }

    Element methodElement = TreeUtils.elementFromUse(tree);
    if (JavaNodes.isStatic(methodElement)) {
      // this is a call of type super.staticMethod(args) -> it should be handled as a simple call to staticMethod
      return false;
    }

    return true;
  }

  /**
   * super(args) -> SuperType.call(this, args)
   */
  private JS callToSuperConstructor(WriterVisitor<JS> visitor, MethodInvocationTree tree, GenerationContext<JS> context) {
    Element methodElement = TreeUtils.elementFromUse(tree);
    TypeElement typeElement = (TypeElement) methodElement.getEnclosingElement();

    String methodName = MethodInvocationWriter.buildMethodName(tree);

    // avoid useless call to super() when the super class is Object
    if (GeneratorConstants.SUPER.equals(methodName) && JavaNodes.sameRawType(typeElement.asType(), Object.class)) {
      return null;
    }

    // avoid call to super for synthetic types
    if (GeneratorConstants.SUPER.equals(methodName) && context.getCurrentWrapper().getEnclosingType().isSyntheticType()) {
      return null;
    }

    // transform it into superType.[prototype.method].call(this, args..);
    String typeName = context.getNames().getTypeName(context, typeElement);
    JS superType = context.js().name(GeneratorConstants.SUPER.equals(methodName) ? typeName : typeName + ".prototype." + methodName);

    List<JS> arguments = MethodInvocationWriter.buildArguments(visitor, tree, context);
    arguments.add(0, context.js().keyword(Keyword.THIS));
    return context.js().functionCall(context.js().property(superType, "call"), arguments);
  }

  @Override
  public JS visit(WriterVisitor<JS> visitor, MethodInvocationTree tree, GenerationContext<JS> context) {
    if (isCallToSuperConstructor(tree)) {
      return callToSuperConstructor(visitor, tree, context);
    }

    JS target = MethodInvocationWriter.buildTarget(visitor, context.<MethodInvocationTree> getCurrentWrapper());
    String name = MethodInvocationWriter.buildMethodName(tree);
    List<JS> arguments = MethodInvocationWriter.buildArguments(visitor, tree, context);
    return context.js().functionCall(context.js().property(target, name), arguments);
  }
}
TOP

Related Classes of org.stjs.generator.writer.templates.DefaultTemplate

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.