Skip to content
This repository
Browse code

Fix APSTUD-2963 - Scope Selector doesn't match when segments are betw…

…een compound segments in scope
  • Loading branch information...
commit 5df2665a677e02c28e321c470079c12de34c18c9 1 parent af0dce2
Christopher Williams authored July 14, 2011
30  plugins/com.aptana.scripting/src/com/aptana/scope/AndSelector.java
@@ -7,6 +7,7 @@
7 7
  */
8 8
 package com.aptana.scope;
9 9
 
  10
+import java.util.ArrayList;
10 11
 import java.util.Collections;
11 12
 import java.util.List;
12 13
 
@@ -38,20 +39,37 @@ public boolean matches(MatchContext context)
38 39
 		{
39 40
 			context.pushCurrentStep();
40 41
 
41  
-			result = this._left.matches(context) && this._right.matches(context);
42  
-			if (result)
  42
+			if (this._left.matches(context))
43 43
 			{
44 44
 				matchResults = this._left.matchResults();
45 45
 				if (matchResults.isEmpty())
46 46
 				{
47  
-					matchResults = this._right.matchResults();
  47
+					matchResults = new ArrayList<Integer>();
48 48
 				}
49  
-				else
  49
+				while (true)
50 50
 				{
51  
-					matchResults.addAll(this._right.matchResults());
  51
+					context.pushCurrentStep();
  52
+					if (this._right.matches(context))
  53
+					{
  54
+						// matched at current step, append match results
  55
+						matchResults.addAll(this._right.matchResults());
  56
+						result = true;
  57
+						context.popCurrentStep();
  58
+						break;
  59
+					}
  60
+					// didn't match at this step, mark down a zero
  61
+					matchResults.add(0);
  62
+					context.popCurrentStep();
  63
+					if (context.canAdvance())
  64
+					{
  65
+						context.advance();
  66
+					}
  67
+					else
  68
+					{
  69
+						break;
  70
+					}
52 71
 				}
53 72
 			}
54  
-
55 73
 			context.popCurrentStep(!result);
56 74
 		}
57 75
 
5  plugins/com.aptana.scripting/src/com/aptana/scope/MatchContext.java
@@ -111,4 +111,9 @@ public String toString()
111 111
 	{
112 112
 		return this.getCurrentStep();
113 113
 	}
  114
+
  115
+	public boolean canAdvance()
  116
+	{
  117
+		return _currentIndex < _steps.length - 1;
  118
+	}
114 119
 }
4  plugins/com.aptana.scripting/src/com/aptana/scope/ScopeSelector.java
@@ -43,8 +43,10 @@ public static IScopeSelector bestMatch(Collection<IScopeSelector> selectors, Str
43 43
 			return null;
44 44
 		}
45 45
 
  46
+		List<IScopeSelector> reversed = new ArrayList<IScopeSelector>(selectors);
  47
+		Collections.reverse(reversed);
46 48
 		IScopeSelector bestMatch = null;
47  
-		for (IScopeSelector selector : selectors)
  49
+		for (IScopeSelector selector : reversed)
48 50
 		{
49 51
 			if (selector == null)
50 52
 			{
6  plugins/com.aptana.theme/src/com/aptana/theme/Theme.java
@@ -395,11 +395,7 @@ protected DelayedTextAttribute getParent(String scope)
395 395
 	private IScopeSelector findMatch(String scope)
396 396
 	{
397 397
 		Collection<IScopeSelector> selectors = new ArrayList<IScopeSelector>();
398  
-		// See APSTUD-2790. In Textmate the last matching rule wins, so to get that behavior we reverse the rule list
399  
-		// before matching.
400  
-		List<ThemeRule> reversed = new ArrayList<ThemeRule>(coloringRules);
401  
-		Collections.reverse(reversed);
402  
-		for (ThemeRule rule : reversed)
  398
+		for (ThemeRule rule : coloringRules)
403 399
 		{
404 400
 			if (rule.isSeparator())
405 401
 			{
89  tests/com.aptana.scripting.tests/src/com/aptana/scope/ScopeSelectorTests.java
@@ -301,4 +301,93 @@ public void testAPSTUD2790()
301 301
 		assertEquals(doctype, ScopeSelector.bestMatch(Arrays.asList(entityName, doctype), scope));
302 302
 	}
303 303
 
  304
+	public void testMatchWhenScopeHasSegmentsBetweenScopeSelectorSegments()
  305
+	{
  306
+		ScopeSelector textSourceSelector = new ScopeSelector("text source");
  307
+		assertTrue(
  308
+				"Selector should match, but doesn't",
  309
+				textSourceSelector
  310
+						.matches("text.haml meta.line.ruby.haml source.ruby.embedded.haml comment.line.number-sign.ruby"));
  311
+		assertTrue("Selector should match, but doesn't",
  312
+				textSourceSelector.matches("text.haml meta.line.ruby.haml source.ruby.embedded.haml"));
  313
+	}
  314
+
  315
+	public void testBestMatchWhenScopeHasSegmentsBetweenScopeSelectorSegments()
  316
+	{
  317
+		String scope = "text.haml meta.line.ruby.haml source.ruby.embedded.haml";
  318
+
  319
+		IScopeSelector textSourceSelector = new ScopeSelector("text source");
  320
+		IScopeSelector metaSourceSelector = new ScopeSelector("meta source");
  321
+
  322
+		assertTrue("Selector should match, but doesn't", textSourceSelector.matches(scope));
  323
+		assertEquals(Arrays.asList(4, 0, 6), textSourceSelector.matchResults());
  324
+
  325
+		assertTrue("Selector should match, but doesn't", metaSourceSelector.matches(scope));
  326
+		assertEquals(Arrays.asList(0, 4, 6), metaSourceSelector.matchResults());
  327
+
  328
+		assertEquals(metaSourceSelector,
  329
+				ScopeSelector.bestMatch(Arrays.asList(textSourceSelector, metaSourceSelector), scope));
  330
+	}
  331
+
  332
+	public void testNegativeLookaheadAppliesAsANDToTrailingScopes()
  333
+	{
  334
+		String scope = "text.haml";
  335
+
  336
+		IScopeSelector textMinusMetaSelector = new ScopeSelector("text -meta");
  337
+		IScopeSelector textMinusMetaSourceSelector = new ScopeSelector("text -meta source");
  338
+		IScopeSelector textSourceSelector = new ScopeSelector("text source");
  339
+
  340
+		assertTrue("Selector should match, but doesn't", textMinusMetaSelector.matches(scope));
  341
+		assertEquals(Arrays.asList(4), textMinusMetaSelector.matchResults());
  342
+
  343
+		assertTrue("Selector should match, but doesn't", textMinusMetaSourceSelector.matches(scope));
  344
+		assertEquals(Arrays.asList(4), textMinusMetaSourceSelector.matchResults());
  345
+
  346
+		assertFalse("Selector shouldn't match, but does", textSourceSelector.matches(scope));
  347
+
  348
+		// Last one wins
  349
+		assertEquals(
  350
+				textMinusMetaSourceSelector,
  351
+				ScopeSelector.bestMatch(
  352
+						Arrays.asList(textSourceSelector, textMinusMetaSelector, textMinusMetaSourceSelector), scope));
  353
+		assertEquals(
  354
+				textMinusMetaSelector,
  355
+				ScopeSelector.bestMatch(
  356
+						Arrays.asList(textMinusMetaSourceSelector, textSourceSelector, textMinusMetaSelector), scope));
  357
+	}
  358
+
  359
+	public void testAdvancedScenario()
  360
+	{
  361
+		String scope = "text.haml meta.line.ruby.haml source.ruby.embedded.haml comment.line.number-sign.ruby";
  362
+
  363
+		IScopeSelector textSourceSelector = new ScopeSelector("text source");
  364
+		IScopeSelector metaSourceSelector = new ScopeSelector("meta source");
  365
+		IScopeSelector textMinusMetaSelector = new ScopeSelector("text -meta");
  366
+		IScopeSelector textMinusMetaSourceSelector = new ScopeSelector("text -meta source");
  367
+
  368
+		assertTrue("Selector should match, but doesn't", textSourceSelector.matches(scope));
  369
+		assertEquals(Arrays.asList(4, 0, 6, 0), textSourceSelector.matchResults());
  370
+
  371
+		assertTrue("Selector should match, but doesn't", metaSourceSelector.matches(scope));
  372
+		assertEquals(Arrays.asList(0, 4, 6, 0), metaSourceSelector.matchResults());
  373
+
  374
+		assertFalse("Selector shouldn't match, but does", textMinusMetaSelector.matches(scope));
  375
+		assertFalse("Selector shouldn't match, but does", textMinusMetaSourceSelector.matches(scope));
  376
+
  377
+		assertEquals(metaSourceSelector, ScopeSelector.bestMatch(Arrays.asList(textSourceSelector, metaSourceSelector,
  378
+				textMinusMetaSelector, textMinusMetaSourceSelector), scope));
  379
+
  380
+		// Scope 2
  381
+		String scope2 = "text.haml meta.line.ruby.haml";
  382
+
  383
+		assertFalse("Selector shouldn't match, but does", textSourceSelector.matches(scope2));
  384
+		assertFalse("Selector shouldn't match but does", metaSourceSelector.matches(scope2));
  385
+		assertFalse("Selector shouldn't match, but does", textMinusMetaSelector.matches(scope2));
  386
+
  387
+		assertTrue("Selector should match, but doesn't", textMinusMetaSourceSelector.matches(scope2));
  388
+		assertEquals(Arrays.asList(4, 0), textMinusMetaSourceSelector.matchResults());
  389
+
  390
+		assertEquals(textMinusMetaSourceSelector, ScopeSelector.bestMatch(Arrays.asList(textSourceSelector,
  391
+				metaSourceSelector, textMinusMetaSelector, textMinusMetaSourceSelector), scope2));
  392
+	}
304 393
 }

0 notes on commit 5df2665

Please sign in to comment.
Something went wrong with that request. Please try again.