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

com.google.gwt.dev.javac.JsInteropUtil Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2014 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.javac;

import com.google.gwt.dev.jjs.ast.JConstructor;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JMember;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethod.JsPropertyType;
import com.google.gwt.thirdparty.guava.common.base.Strings;

import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;

import java.beans.Introspector;

/**
 * Utility functions to interact with JDT classes for JsInterop.
 */
public final class JsInteropUtil {

  public static final String JSEXPORT_CLASS = "com.google.gwt.core.client.js.JsExport";
  public static final String JSFUNCTION_CLASS = "com.google.gwt.core.client.js.JsFunction";
  public static final String JSNAMESPACE_CLASS = "com.google.gwt.core.client.js.JsNamespace";
  public static final String JSNOEXPORT_CLASS = "com.google.gwt.core.client.js.JsNoExport";
  public static final String JSPROPERTY_CLASS = "com.google.gwt.core.client.js.JsProperty";
  public static final String JSTYPE_CLASS = "com.google.gwt.core.client.js.JsType";
  public static final String JSTYPEPROTOTYPE_CLASS =
      "com.google.gwt.core.client.js.impl.PrototypeOfJsType";

  public static void maybeSetJsInteropProperties(JMethod method, Annotation... annotations) {
    setJsInteropProperties(method, annotations);
    if (JdtUtil.getAnnotation(annotations, JSPROPERTY_CLASS) != null) {
      setJsPropertyProperties(method);
    }
  }

  public static void maybeSetJsInteropProperties(JField field, Annotation... annotations) {
    setJsInteropProperties(field, annotations);
  }

  private static void setJsInteropProperties(JMember member, Annotation... annotations) {
    String namespace = null;
    AnnotationBinding jsNamespace = JdtUtil.getAnnotation(annotations, JSNAMESPACE_CLASS);
    if (jsNamespace != null) {
      namespace = JdtUtil.getAnnotationParameterString(jsNamespace, "value");
    }

    AnnotationBinding jsExport = JdtUtil.getAnnotation(annotations, JSEXPORT_CLASS);
    if (jsExport != null) {
      String value = JdtUtil.getAnnotationParameterString(jsExport, "value");
      String exportName = Strings.isNullOrEmpty(value) ? computeExportName(member) : value;
      member.setExportInfo(namespace, exportName);
    }

    /* Apply class wide JsInterop annotations */

    boolean ignore = JdtUtil.getAnnotation(annotations, JSNOEXPORT_CLASS) != null;
    if (ignore || !member.isPublic()) {
      return;
    }

    JDeclaredType enclosingType = member.getEnclosingType();

    if (enclosingType.isJsType() && member.needsVtable()) {
      member.setJsMemberName(member.getName());
    }

    if (enclosingType.isClassWideExport() && !member.needsVtable() && jsExport == null) {
      member.setExportInfo(namespace, computeExportName(member));
    }
  }

  private static void setJsPropertyProperties(JMethod method) {
    String methodName = method.getName();
    if (startsWithCamelCase(methodName, "set")) {
      method.setJsPropertyType(JsPropertyType.SET);
      method.setJsMemberName(Introspector.decapitalize(methodName.substring(3)));
    } else if (startsWithCamelCase(methodName, "get")) {
      method.setJsPropertyType(JsPropertyType.GET);
      method.setJsMemberName(Introspector.decapitalize(methodName.substring(3)));
    } else if (startsWithCamelCase(methodName, "is")) {
      method.setJsPropertyType(JsPropertyType.GET);
      method.setJsMemberName(Introspector.decapitalize(methodName.substring(2)));
    } else {
      method.setJsPropertyType(JsPropertyType.UNDEFINED);
    }
  }

  private static String computeExportName(JMember member) {
    // Constructors for nested class might have different name in the AST than the original source
    // so use the simple name of the enclosing type instead that always matches the source name.
    return member instanceof JConstructor ? member.getEnclosingType().getSimpleName()
        : member.getName();
  }

  public static boolean isJsType(TypeDeclaration x) {
    return JdtUtil.getAnnotation(x.annotations, JSTYPE_CLASS) != null;
  }

  public static boolean isJsPrototypeFlag(TypeDeclaration x) {
    return JdtUtil.getAnnotation(x.annotations, JSTYPEPROTOTYPE_CLASS) != null;
  }

  public static boolean isClassWideJsExport(TypeDeclaration x) {
    return JdtUtil.getAnnotation(x.annotations, JSEXPORT_CLASS) != null;
  }

  public static String maybeGetJsNamespace(TypeDeclaration x) {
    AnnotationBinding jsNamespace = JdtUtil.getAnnotation(x.annotations, JSNAMESPACE_CLASS);
    return JdtUtil.getAnnotationParameterString(jsNamespace, "value");
  }

  public static String maybeGetJsTypePrototype(TypeDeclaration x) {
    AnnotationBinding jsType = JdtUtil.getAnnotation(x.annotations, JSTYPE_CLASS);
    return JdtUtil.getAnnotationParameterString(jsType, "prototype");
  }

  public static boolean isJsFunction(TypeDeclaration x) {
    return JdtUtil.getAnnotation(x.annotations, JSFUNCTION_CLASS) != null;
  }

  private static boolean startsWithCamelCase(String string, String prefix) {
    return string.length() > prefix.length() && string.startsWith(prefix)
        && Character.isUpperCase(string.charAt(prefix.length()));
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy