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

com.google.gwt.dev.util.JsniRef Maven / Gradle / Ivy

There is a newer version: 2.10.0
Show newest version
/*
 * Copyright 2008 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.util;

import com.google.gwt.core.ext.typeinfo.JniConstants;
import com.google.gwt.thirdparty.guava.common.base.Strings;
import com.google.gwt.thirdparty.guava.common.collect.Lists;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A parsed Java reference from within a JSNI method.
 */
public class JsniRef {
  /**
   * Special field name for referring to a class literal.
   */
  public static final String CLASS = "class";

  /**
   * Special method name for a class constructor.
   */
  public static final String NEW = "new";

  /**
   * A parameter list indicating a match to any overload.
   */
  public static final String WILDCARD_PARAM_LIST = "*";

  /**
   * A regex pattern for a Java reference in JSNI code. Its groups are:
   * 
    *
  1. the class name *
  2. the field or method name *
  3. the method parameter types, including the surrounding parentheses *
  4. the method parameter types, excluding the parentheses *
*/ private static Pattern JsniRefPattern = Pattern.compile("@?([^:@\\[\\]]*)((?:\\[\\])*)::([^(]+)(\\((.*)\\))?"); /** * Parse a Java reference from JSNI code. This parser is forgiving; it does * not always detect invalid references. If the refString is improperly * formatted, returns null. */ public static JsniRef parse(String refString) { Matcher matcher = JsniRefPattern.matcher(refString); if (!matcher.matches()) { return null; } String className = matcher.group(1); int arrayDimensions = matcher.group(2).length() / 2; String memberName = matcher.group(3); String paramTypesString = null; String[] paramTypes = null; if (matcher.group(4) != null) { paramTypesString = matcher.group(5); if (!paramTypesString.equals(WILDCARD_PARAM_LIST)) { paramTypes = computeParamTypes(paramTypesString); if (paramTypes == null) { return null; } } } return new JsniRef(className, arrayDimensions, memberName, paramTypesString, paramTypes); } private static String[] computeParamTypes(String paramTypesString) { List types = Lists.newArrayList(); StringBuilder nextType = new StringBuilder(); boolean inRef = false; for (char c : paramTypesString.toCharArray()) { nextType.append(c); if (inRef) { if (c == JniConstants.DESC_REF_END) { types.add(StringInterner.get().intern(nextType.toString())); nextType.setLength(0); inRef = false; } } else { switch (c) { case JniConstants.DESC_BOOLEAN: case JniConstants.DESC_BYTE: case JniConstants.DESC_CHAR: case JniConstants.DESC_DOUBLE: case JniConstants.DESC_FLOAT: case JniConstants.DESC_INT: case JniConstants.DESC_LONG: case JniConstants.DESC_SHORT: case JniConstants.DESC_VOID: types.add(StringInterner.get().intern(nextType.toString())); nextType.setLength(0); break; case JniConstants.DESC_ARRAY: // Nothing special to do. break; case JniConstants.DESC_REF: inRef = true; break; default: // Bad input. return null; } } } return types.toArray(Empty.STRINGS); } private final String className; private String resolvedClassName; private String resolvedNemberSignature; private final String memberName; private final String[] paramTypes; private final String paramTypesString; private final int arrayDimensions; protected JsniRef(String className, int arrayDimensions, String memberName, String paramTypesString, String[] paramTypes) { this.className = className; this.memberName = memberName; this.arrayDimensions = arrayDimensions; this.paramTypesString = paramTypesString; this.paramTypes = paramTypes; } public String className() { return className; } @Override public boolean equals(Object obj) { return (obj instanceof JsniRef) && toString().equals(obj.toString()); } @Override public int hashCode() { return toString().hashCode(); } public boolean isField() { return paramTypesString == null; } public boolean isMethod() { return paramTypesString != null; } /** * Whether this method reference matches all overloads of the specified class * and method name. Only valid for method references. */ public boolean matchesAnyOverload() { return paramTypesString.equals(WILDCARD_PARAM_LIST); } public String memberName() { return memberName; } public String memberSignature() { String ret = memberName; if (isMethod()) { ret += "(" + paramTypesString + ")"; } return ret; } /** * Return the list of parameter types for the method referred to by this * reference. Only valid for method references where * {@link #matchesAnyOverload()} is false. */ public String[] paramTypes() { assert !matchesAnyOverload(); return paramTypes; } public String paramTypesString() { return paramTypesString; } public void setResolvedClassName(String resolvedClassName) { this.resolvedClassName = StringInterner.get().intern(resolvedClassName); } public void setResolvedMemberWithSignature(String resolvedMemberSignature) { this.resolvedNemberSignature = StringInterner.get().intern(resolvedMemberSignature); } public String getResolvedClassName() { return resolvedClassName; } public String getFullResolvedClassName() { return resolvedClassName == null ? null : resolvedClassName + Strings.repeat("[]", arrayDimensions); } public String getResolvedReference() { String fullResolvedClassName = getFullResolvedClassName(); return fullResolvedClassName == null || resolvedClassName == null ? null : "@" + fullResolvedClassName + "::" + resolvedNemberSignature; } public String getResolvedMemberSignature() { return resolvedNemberSignature; } public String fullClassName() { return className + Strings.repeat("[]", arrayDimensions); } @Override public String toString() { return "@" + fullClassName() + "::" + memberSignature(); } public boolean isArray() { return arrayDimensions > 0; } public int getDimensions() { return arrayDimensions; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy