Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[henshin-dev] Bug when using Attribute Conditions

Hey,

First thanks for creating this cool tool. It's a lot of fun working with it. I found a bug while working with it though. Sometimes if you use Attribute Conditions that use the modulo operation (%) the interpreter fails with the exception that one of the attributes is unknwon.

After some research I found the problem in org.eclipse.emf.henshin.interpreter.info.ConditionInfo. There the condition is parsed and the code tries to extract all the used parameters. I guess this is so that the conditions can be executed as early as possible to prevent unused matching. The problem is that the method extractParameter is not splitting the string correctly. It is only splitting on some special characters not '%'. So when the js expressiong variable%10==0; is parsed it results in the token variable%10 which is not matching any of the defined parameters (variable % 10 == 0; works though).

To prevent this from happening it would be better to use a regular expression: [$_\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}][$_\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}]+ (http://mathiasbynens.be/notes/javascript-identifiers)

This should match most possible javascript variable names (it does not consider U+200C zero width non-joiner characters, U+200D zero width joiner characters).

Here is the patch I would like to contribute to fix the bug.

Best regards,
Manuel Hegner
Index: plugins/org.eclipse.emf.henshin.interpreter/src/org/eclipse/emf/henshin/interpreter/info/ConditionInfo.java
===================================================================
--- plugins/org.eclipse.emf.henshin.interpreter/src/org/eclipse/emf/henshin/interpreter/info/ConditionInfo.java	(revision 1989)
+++ plugins/org.eclipse.emf.henshin.interpreter/src/org/eclipse/emf/henshin/interpreter/info/ConditionInfo.java	(working copy)
@@ -9,12 +9,13 @@
  */
 package org.eclipse.emf.henshin.interpreter.info;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.eclipse.emf.henshin.model.AttributeCondition;
 import org.eclipse.emf.henshin.model.Parameter;
@@ -22,12 +23,14 @@
 
 public class ConditionInfo {
 	
+	private static final Pattern VALID_JS_VARIABLE_NAME=Pattern.compile("[$_\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}][$_\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}]+"); 
+	
 	private Map<String, Collection<String>> conditionParameters;
 	
 	public ConditionInfo(Rule rule) {
 		this.conditionParameters = new HashMap<String, Collection<String>>();
 		
-		Collection<String> parameterNames = new ArrayList<String>();
+		Collection<String> parameterNames = new HashSet<String>();
 		for (Parameter parameter : rule.getParameters()) {
 			parameterNames.add(parameter.getName());
 		}
@@ -41,17 +44,14 @@
 	
 	private Collection<String> extractParameter(String testString, Collection<String> parameterNames) {
 		Collection<String> usedParameters = new HashSet<String>();
-		StringTokenizer quoteParser = new StringTokenizer(testString, "\"\'");
+		StringTokenizer quoteParser = new StringTokenizer(testString, "\"\'"); //FIXME this can also lead to wrong results when escaped " or ' are used
 		while (quoteParser.hasMoreElements()) {
 			String nonQuotedString = quoteParser.nextToken();
-			StringTokenizer variableParser = new StringTokenizer(nonQuotedString, ".,()\t\r\n<>=!+[] ");
-			while (variableParser.hasMoreElements()) {
-				String subString = variableParser.nextToken();
-				for (String parameterName : parameterNames) {
-					if (parameterName.equals(subString)) {
-						usedParameters.add(parameterName);
-					}
-				}
+			Matcher m=VALID_JS_VARIABLE_NAME.matcher(nonQuotedString);
+			while(m.find()) {
+				String possibleVariableName=m.group();
+				if(parameterNames.contains(possibleVariableName))
+					usedParameters.add(possibleVariableName);
 			}
 			// discard the quoted part
 			if (quoteParser.hasMoreElements())

Back to the top