/**
* Copyright (c) 2013-2016 Angelo ZERR.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
*/
package tern.server.protocol.completions;
import java.util.ArrayList;
import java.util.List;
import tern.utils.StringUtils;
/**
* Helper for tern type.
*
*/
public class TernTypeHelper {
public static final String STRING_TYPE = "string";
public static final String NUMBER_TYPE = "number";
public static final String BOOL_TYPE = "bool";
private static final String FUNCTION_REF = "fn";
private static final String FUNCTION_START = "fn(";
private static final String FUNCTION_ARRAY_START = "[fn(";
private TernTypeHelper() {
}
/**
* Returns true if the given type is fn() and false otherwise.
*
* @param type
* the tern type
* @return true if the given type is fn() and false otherwise.
*/
public static boolean isFunction(String type) {
return !StringUtils.isEmpty(type)
&& (type.startsWith(FUNCTION_START) || type
.startsWith(FUNCTION_ARRAY_START));
}
/**
* Return the function information of the given function name and type.
*
* @param name
* function name
* @param type
* function type
* @return the function information of the given function name and type.
*/
public static FunctionInfo parseFunction(String name, String type) {
type = type.startsWith("[") ? type.substring(1, type.length()) : type;
StringBuilder signature = name != null ? new StringBuilder(name) : null;
List<Parameter> parameters = null;
StringBuilder currentParamName = null;
boolean currentParamRequired = true;
StringBuilder currentParamType = null;
if (signature != null) {
signature.append("(");
}
int bracket = 0;
String afterStartFn = type.substring(2, type.length());
int i = 0;
for (i = 0; i < afterStartFn.length(); i++) {
char c = afterStartFn.charAt(i);
switch (c) {
case '(':
bracket++;
if (currentParamType != null)
currentParamType.append(c);
break;
case ')':
bracket--;
if (bracket >= 1 && currentParamType != null)
currentParamType.append(c);
break;
default:
if (bracket >= 1) {
if (currentParamType != null) {
if (c == ',') {
if (bracket < 2) {
parameters
.add(new Parameter(
currentParamName.toString(),
currentParamRequired,
currentParamType != null ? currentParamType
.toString() : null));
currentParamName = null;
currentParamRequired = true;
currentParamType = null;
} else {
currentParamType.append(c);
}
} else if (c != ' ') {
currentParamType.append(c);
}
} else {
if (currentParamName == null) {
if (c != ' ' && c != '?') {
currentParamName = new StringBuilder();
currentParamName.append(c);
}
} else {
if (c == ':') {
if (parameters == null) {
parameters = new ArrayList<Parameter>();
} else {
if (signature != null) {
signature.append(", ");
}
}
if (signature != null) {
signature.append(currentParamName
.toString());
}
currentParamType = new StringBuilder();
} else {
if (c == '?') {
currentParamRequired = false;
} else if (c != ' ') {
currentParamName.append(c);
}
}
}
}
}
}
if (bracket == 0)
break;
}
if (currentParamName != null) {
if (parameters == null) {
parameters = new ArrayList<Parameter>();
}
parameters.add(new Parameter(currentParamName.toString(),
currentParamRequired,
currentParamType != null ? currentParamType.toString()
: null));
currentParamName = null;
currentParamRequired = true;
currentParamType = null;
}
if (signature != null) {
signature.append(")");
}
StringBuilder s = null;
for (int j = i + 1; j < afterStartFn.length(); j++) {
char c = afterStartFn.charAt(j);
if (s != null) {
s.append(c);
} else {
if (c == '>') {
s = new StringBuilder();
}
}
}
String returnType = s != null ? s.toString().trim() : null;
return new FunctionInfo(parameters,
signature != null ? signature.toString() : null, returnType);
}
/**
* Returns true if the given type is "string" type and false otherwise.
*
* @param type
* @return true if the given type is "string" type and false otherwise.
*/
public static boolean isStringType(String type) {
return STRING_TYPE.equals(type);
}
/**
* Returns true if the given type is "number" type and false otherwise.
*
* @param type
* @return true if the given type is "number" type and false otherwise.
*/
public static boolean isNumberType(String type) {
return NUMBER_TYPE.equals(type);
}
/**
* Returns true if the given type is "bool" type and false otherwise.
*
* @param type
* @return true if the given type is "bool" type and false otherwise.
*/
public static boolean isBoolType(String type) {
return BOOL_TYPE.equals(type);
}
/**
* Returns true if the given type is "fn" type and false otherwise.
*
* @param type
* @return true if the given type is "fn" type and false otherwise.
*/
public static boolean isFunctionRefType(String type) {
return FUNCTION_REF.equals(type);
}
}