Skip to content

Commit

Permalink
Fix APSTUD-2963 - Scope Selector doesn't match when segments are betw…
Browse files Browse the repository at this point in the history
…een compound segments in scope
  • Loading branch information
sgtcoolguy committed Jul 14, 2011
1 parent af0dce2 commit 5df2665
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 12 deletions.
30 changes: 24 additions & 6 deletions plugins/com.aptana.scripting/src/com/aptana/scope/AndSelector.java
Expand Up @@ -7,6 +7,7 @@
*/
package com.aptana.scope;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

Expand Down Expand Up @@ -38,20 +39,37 @@ public boolean matches(MatchContext context)
{
context.pushCurrentStep();

result = this._left.matches(context) && this._right.matches(context);
if (result)
if (this._left.matches(context))
{
matchResults = this._left.matchResults();
if (matchResults.isEmpty())
{
matchResults = this._right.matchResults();
matchResults = new ArrayList<Integer>();
}
else
while (true)
{
matchResults.addAll(this._right.matchResults());
context.pushCurrentStep();
if (this._right.matches(context))
{
// matched at current step, append match results
matchResults.addAll(this._right.matchResults());
result = true;
context.popCurrentStep();
break;
}
// didn't match at this step, mark down a zero
matchResults.add(0);
context.popCurrentStep();
if (context.canAdvance())
{
context.advance();
}
else
{
break;
}
}
}

context.popCurrentStep(!result);
}

Expand Down
Expand Up @@ -111,4 +111,9 @@ public String toString()
{
return this.getCurrentStep();
}

public boolean canAdvance()
{
return _currentIndex < _steps.length - 1;
}
}
Expand Up @@ -43,8 +43,10 @@ public static IScopeSelector bestMatch(Collection<IScopeSelector> selectors, Str
return null;
}

List<IScopeSelector> reversed = new ArrayList<IScopeSelector>(selectors);
Collections.reverse(reversed);
IScopeSelector bestMatch = null;
for (IScopeSelector selector : selectors)
for (IScopeSelector selector : reversed)
{
if (selector == null)
{
Expand Down
6 changes: 1 addition & 5 deletions plugins/com.aptana.theme/src/com/aptana/theme/Theme.java
Expand Up @@ -395,11 +395,7 @@ protected DelayedTextAttribute getParent(String scope)
private IScopeSelector findMatch(String scope)
{
Collection<IScopeSelector> selectors = new ArrayList<IScopeSelector>();
// See APSTUD-2790. In Textmate the last matching rule wins, so to get that behavior we reverse the rule list
// before matching.
List<ThemeRule> reversed = new ArrayList<ThemeRule>(coloringRules);
Collections.reverse(reversed);
for (ThemeRule rule : reversed)
for (ThemeRule rule : coloringRules)
{
if (rule.isSeparator())
{
Expand Down
Expand Up @@ -301,4 +301,93 @@ public void testAPSTUD2790()
assertEquals(doctype, ScopeSelector.bestMatch(Arrays.asList(entityName, doctype), scope));
}

public void testMatchWhenScopeHasSegmentsBetweenScopeSelectorSegments()
{
ScopeSelector textSourceSelector = new ScopeSelector("text source");
assertTrue(
"Selector should match, but doesn't",
textSourceSelector
.matches("text.haml meta.line.ruby.haml source.ruby.embedded.haml comment.line.number-sign.ruby"));
assertTrue("Selector should match, but doesn't",
textSourceSelector.matches("text.haml meta.line.ruby.haml source.ruby.embedded.haml"));
}

public void testBestMatchWhenScopeHasSegmentsBetweenScopeSelectorSegments()
{
String scope = "text.haml meta.line.ruby.haml source.ruby.embedded.haml";

IScopeSelector textSourceSelector = new ScopeSelector("text source");
IScopeSelector metaSourceSelector = new ScopeSelector("meta source");

assertTrue("Selector should match, but doesn't", textSourceSelector.matches(scope));
assertEquals(Arrays.asList(4, 0, 6), textSourceSelector.matchResults());

assertTrue("Selector should match, but doesn't", metaSourceSelector.matches(scope));
assertEquals(Arrays.asList(0, 4, 6), metaSourceSelector.matchResults());

assertEquals(metaSourceSelector,
ScopeSelector.bestMatch(Arrays.asList(textSourceSelector, metaSourceSelector), scope));
}

public void testNegativeLookaheadAppliesAsANDToTrailingScopes()
{
String scope = "text.haml";

IScopeSelector textMinusMetaSelector = new ScopeSelector("text -meta");
IScopeSelector textMinusMetaSourceSelector = new ScopeSelector("text -meta source");
IScopeSelector textSourceSelector = new ScopeSelector("text source");

assertTrue("Selector should match, but doesn't", textMinusMetaSelector.matches(scope));
assertEquals(Arrays.asList(4), textMinusMetaSelector.matchResults());

assertTrue("Selector should match, but doesn't", textMinusMetaSourceSelector.matches(scope));
assertEquals(Arrays.asList(4), textMinusMetaSourceSelector.matchResults());

assertFalse("Selector shouldn't match, but does", textSourceSelector.matches(scope));

// Last one wins
assertEquals(
textMinusMetaSourceSelector,
ScopeSelector.bestMatch(
Arrays.asList(textSourceSelector, textMinusMetaSelector, textMinusMetaSourceSelector), scope));
assertEquals(
textMinusMetaSelector,
ScopeSelector.bestMatch(
Arrays.asList(textMinusMetaSourceSelector, textSourceSelector, textMinusMetaSelector), scope));
}

public void testAdvancedScenario()
{
String scope = "text.haml meta.line.ruby.haml source.ruby.embedded.haml comment.line.number-sign.ruby";

IScopeSelector textSourceSelector = new ScopeSelector("text source");
IScopeSelector metaSourceSelector = new ScopeSelector("meta source");
IScopeSelector textMinusMetaSelector = new ScopeSelector("text -meta");
IScopeSelector textMinusMetaSourceSelector = new ScopeSelector("text -meta source");

assertTrue("Selector should match, but doesn't", textSourceSelector.matches(scope));
assertEquals(Arrays.asList(4, 0, 6, 0), textSourceSelector.matchResults());

assertTrue("Selector should match, but doesn't", metaSourceSelector.matches(scope));
assertEquals(Arrays.asList(0, 4, 6, 0), metaSourceSelector.matchResults());

assertFalse("Selector shouldn't match, but does", textMinusMetaSelector.matches(scope));
assertFalse("Selector shouldn't match, but does", textMinusMetaSourceSelector.matches(scope));

assertEquals(metaSourceSelector, ScopeSelector.bestMatch(Arrays.asList(textSourceSelector, metaSourceSelector,
textMinusMetaSelector, textMinusMetaSourceSelector), scope));

// Scope 2
String scope2 = "text.haml meta.line.ruby.haml";

assertFalse("Selector shouldn't match, but does", textSourceSelector.matches(scope2));
assertFalse("Selector shouldn't match but does", metaSourceSelector.matches(scope2));
assertFalse("Selector shouldn't match, but does", textMinusMetaSelector.matches(scope2));

assertTrue("Selector should match, but doesn't", textMinusMetaSourceSelector.matches(scope2));
assertEquals(Arrays.asList(4, 0), textMinusMetaSourceSelector.matchResults());

assertEquals(textMinusMetaSourceSelector, ScopeSelector.bestMatch(Arrays.asList(textSourceSelector,
metaSourceSelector, textMinusMetaSelector, textMinusMetaSourceSelector), scope2));
}
}

0 comments on commit 5df2665

Please sign in to comment.