/*******************************************************************************
* This file is part of the Symfony eclipse plugin.
*
* (c) Robert Gruendler <r.gruendler@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
******************************************************************************/
package com.dubture.symfony.core.util.text;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.php.internal.core.util.text.PHPTextSequenceUtilities;
import org.eclipse.php.internal.core.util.text.TextSequence;
import com.dubture.symfony.core.model.SymfonyModelAccess;
/**
*
* {@link SymfonyTextSequenceUtilities} is a utility class for {@link TextSequence}.
* Use it to check if you're inside a special pattern - ie. a servicecontainer
* getter function function like:
*
* <pre>
*
* $this->get(|
*
* or
*
* $this->container->get('
*
* </pre>
*
*
* @see PHPTextSequenceUtilities
*
* @author Robert Gruendler <r.gruendler@gmail.com>
*
*/
@SuppressWarnings("restriction")
public class SymfonyTextSequenceUtilities {
private static final Pattern SERVICE_PATTERN = Pattern.compile("(\\$this->get\\(|\\$this->container->get\\(|->getContainer\\(\\)->get\\()");
private static final Pattern GET_PATTERN = Pattern.compile("(->get\\()");
private static final Pattern REPOSITORY_PATTERN = Pattern.compile("\\->getRepository\\(");
private static final Pattern TRANSLATION_PATTERN = Pattern.compile("(\\->transChoice\\(|\\->trans\\()");
private SymfonyTextSequenceUtilities() {
}
/**
* Retrieve the startOffset of a ViewPath inside a textSeauence
*
*
* @param textSequence
* @return
*/
public static int readViewPathStartIndex(CharSequence textSequence) {
int startPosition = textSequence.length() -1;
return readLiteralStartIndex(textSequence, startPosition);
}
/**
* Checks for the existance of a service container function, ie. $this->get( or $this->container->get(
* @param sequence
* @return
*/
public static int isInServiceContainerFunction(CharSequence sequence) {
Matcher matcher = SERVICE_PATTERN.matcher(sequence);
while (matcher.find()) {
int pos = matcher.end();
int lastMethodCall = sequence.toString().lastIndexOf("(");
if (lastMethodCall > pos)
return -1;
return pos;
}
return -1;
}
/**
* Checks for the existance of a get function, ie. ->get(
* @param sequence
* @return
*/
public static int isGetFunction(CharSequence sequence) {
Matcher matcher = GET_PATTERN.matcher(sequence);
while (matcher.find()) {
int pos = matcher.end();
int lastMethodCall = sequence.toString().lastIndexOf("(");
if (lastMethodCall > pos)
return -1;
return pos;
}
return -1;
}
/**
* Check if the sequence is a method call for a doctrine repository ie
*
* $this->getDoctrine()->getRepository(|
*
* @param sequence
* @return
*/
public static int isInEntityFunctionParameter(CharSequence sequence) {
Matcher matcher = REPOSITORY_PATTERN.matcher(sequence);
while (matcher.find()) {
int pos = matcher.end();
int lastMethodCall = sequence.toString().lastIndexOf("(");
if (lastMethodCall > pos)
return -1;
return pos;
}
return -1;
}
public static int isInTranslationFunctionParameter(CharSequence sequence) {
Matcher matcher = TRANSLATION_PATTERN.matcher(sequence);
while (matcher.find()) {
int pos = matcher.end();
int lastMethodCall = sequence.toString().lastIndexOf("(");
if (lastMethodCall > pos)
return -1;
return pos;
}
return -1;
}
public static String removeQuotes(String source) {
return source.replaceAll("['\"]", "");
}
/**
* Retrieve the service name from a PHP method call,
* ie: $this->get('session') will return the session literal.
*
* @param sequence
* @return
*/
public static String getServiceFromMethodParam(TextSequence sequence) {
String source = sequence.toString();
int start = source.indexOf("(") +1;
int end = source.indexOf(")") -1;
if (start < 0 || end < 0 || (end < start))
return null;
return removeQuotes(source.substring(start, end));
}
/**
*
* Extract the methodName of a TextSequence, ie,
*
* "$this->generate('" will return generate
*
* @param statement
* @return
*/
public static String getMethodName(CharSequence statement) {
String text = statement.toString();
int start = text.indexOf("->");
int end = text.lastIndexOf("(");
int current = end;
while( current > 0 && current > start) {
char c = text.charAt(current--);
if (c == '>') {
return text.substring(current+2, end);
}
}
return null;
}
/**
* Check if the TextSequence is inside PHP method accepting
* viewPath parameters.
*
* @param statement
* @param project
* @return
*/
public static boolean isInViewPathFunctionParameter(TextSequence statement, IScriptProject project) {
String method = getMethodName(statement);
if (method == null)
return false;
return SymfonyModelAccess.getDefault().hasViewMethod(method, project);
}
/**
* Check if the TextSequence is a function which accept route parameters.
*
*
* @param statement
* @param project
* @return
*/
public static boolean isInRouteFunctionParameter(TextSequence statement,
IScriptProject project) {
String method = getMethodName(statement);
if (method == null)
return false;
return SymfonyModelAccess.getDefault().hasRouteMethod(method, project);
}
/**
*
* Read to the start index of a String literal.
*
* @param textSequence
* @param startPosition
* @return
*/
public static int readLiteralStartIndex(CharSequence textSequence, int startPosition) {
while (startPosition > 0) {
char ch = textSequence.charAt(startPosition - 1);
if (!Character.isLetterOrDigit(ch) && ch != ':' && ch != '.' && ch != '_' && ch != '/') {
break;
}
startPosition--;
}
if (startPosition > 0 && startPosition < textSequence.length()
&& (textSequence.charAt(startPosition) == '"' || textSequence.charAt(startPosition) == '\'' )) {
startPosition++;
}
return startPosition;
}
/**
*
* Read to the end index of a String literal.
*
* @param textSequence
* @param startPosition
* @return
*/
public static int readLiteralEndIndex(CharSequence textSequence, int startPosition) {
int max = textSequence.length() -1;
while (startPosition < max) {
char ch = textSequence.charAt(startPosition);
if (!Character.isLetterOrDigit(ch) && ch != ':' && ch != '.' && ch != '_') {
break;
}
startPosition++;
}
if (startPosition > 0
&& (textSequence.charAt(startPosition-1) == '"' || textSequence.charAt(startPosition-1) == '\'' )) {
startPosition--;
}
return startPosition;
}
}