eclipse plugin: Refactored the whole variable scoping code.

Now it is properly shown in the content assist only if the current
scope if found in the variable's list.
This commit is contained in:
Timotei Dolean 2011-07-26 15:31:37 +00:00
parent 76c02a1a05
commit 04152c45ff
4 changed files with 137 additions and 51 deletions

View file

@ -12,6 +12,9 @@ Eclipse plugin changelog
through the existing addons on any wesnoth addon server and
download them (as projects in workspace).
* The required Xtext version has been raised to 2.0
* Improved the content assist for:
- variables
- events
1.0.3
* Fixed bug #18080

View file

@ -42,6 +42,7 @@ import org.wesnoth.wml.WMLKey;
import org.wesnoth.wml.WMLTag;
import org.wesnoth.wml.core.WMLConfig;
import org.wesnoth.wml.core.WMLVariable;
import org.wesnoth.wml.core.WMLVariable.Scope;
import com.google.common.base.Function;
import com.google.common.base.Predicates;
@ -227,8 +228,10 @@ public class WMLProposalProvider extends AbstractWMLProposalProvider
acceptor.accept( createCompletionProposal( event, context ) );
}
} else {
// add variables
final int nodeOffset = NodeModelUtils.getNode( model ).getTotalOffset( );
List<String> variables = new ArrayList<String>();
// add CAC variables
variables.addAll( TemplateProvider.getInstance( ).getCAC( "variables" ) );
// filter variables by index
@ -239,9 +242,11 @@ public class WMLProposalProvider extends AbstractWMLProposalProvider
@Override
public String apply( WMLVariable from )
{
// if ( from.getScopeStartIndex( ) <= dependencyIndex_ &&
// dependencyIndex_ <= from.getScopeEndIndex( ) )
// return from.getName( );
for ( Scope scope : from.getScopes( ) ) {
if ( scope.contains( dependencyIndex_, nodeOffset ) )
return from.getName( );
}
return null;
}
} );

View file

@ -11,8 +11,8 @@ package org.wesnoth.wml.core;
import org.eclipse.core.resources.IFile;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.wesnoth.Logger;
import org.wesnoth.projects.ProjectCache;
import org.wesnoth.projects.ProjectUtils;
import org.wesnoth.utils.ResourceUtils;
@ -21,6 +21,7 @@ import org.wesnoth.wml.WMLKey;
import org.wesnoth.wml.WMLMacroCall;
import org.wesnoth.wml.WMLRoot;
import org.wesnoth.wml.WMLTag;
import org.wesnoth.wml.core.WMLVariable.Scope;
import com.google.common.base.Preconditions;
@ -32,6 +33,7 @@ public class SimpleWMLParser
protected WMLConfig config_;
protected IFile file_;
protected ProjectCache projectCache_;
protected int dependencyIndex_;
/**
* Creates a new parser for the specified file
@ -49,6 +51,8 @@ public class SimpleWMLParser
config_ = Preconditions.checkNotNull( config );
file_ = file;
projectCache_ = ProjectUtils.getCacheForProject( file.getProject( ) );
dependencyIndex_ = ResourceUtils.getDependencyIndex( file );
}
/**
@ -118,35 +122,81 @@ public class SimpleWMLParser
System.out.println( "parsed config: " + config_ );
}
protected void handleSetVariable( EObject context )
protected String getVariableNameByContext( EObject context )
{
WMLVariable variable = new WMLVariable( );
ICompositeNode node = NodeModelUtils.getNode( context ) ;
variable.setLocation( file_.getLocation( ).toOSString( ) );
// variable.setScopeStartIndex( ResourceUtils.getDependencyIndex( file_ ) );
variable.setOffset( node.getTotalOffset( ) );
String variableName = null;
if ( context instanceof WMLKey ) {
variable.setName( WMLUtils.getKeyValue( ( ( WMLKey ) context ).getValue( ) ) );
variableName = WMLUtils.getKeyValue( ( ( WMLKey ) context ).getValue( ) ) ;
} else if ( context instanceof WMLMacroCall ) {
WMLMacroCall macro = ( WMLMacroCall ) context;
if ( macro.getParameters( ).size( ) > 0 ) {
variable.setName( WMLUtils.toString( macro.getParameters( ).get( 0 ) ) );
variableName = WMLUtils.toString( macro.getParameters( ).get( 0 ) ) ;
}
}
if ( ! variable.getName( ).isEmpty( ) ) {
projectCache_.getVariables( ).put( variable.getName( ), variable );
System.out.println( "added variable: " + variable );
return variableName;
}
protected void handleSetVariable( EObject context )
{
String variableName = getVariableNameByContext( context );
if ( variableName == null ) {
Logger.getInstance( ).logWarn(
"setVariable: couldn't get variable name from context: " + context );
}
WMLVariable variable = projectCache_.getVariables( ).get( variableName );
if ( variable == null ) {
variable = new WMLVariable( variableName );
projectCache_.getVariables( ).put( variableName, variable );
}
int nodeOffset = NodeModelUtils.getNode( context ).getTotalOffset( );
for ( Scope scope : variable.getScopes( ) ) {
if ( scope.contains( dependencyIndex_, nodeOffset ) )
return; // nothing to do
}
// couldn't find any scope. Add a new one then.
variable.getScopes( ).add( new Scope( dependencyIndex_, nodeOffset ) );
System.out.println( "new scope for variable:" + variable );
}
protected void handleUnsetVariable( EObject context )
{
String variableName = getVariableNameByContext( context );
if ( variableName == null ) {
Logger.getInstance( ).logWarn(
"unsetVariable: couldn't get variable name from context: " + context );
}
WMLVariable variable = projectCache_.getVariables( ).get( variableName );
if ( variable == null )
return;
int nodeOffset = NodeModelUtils.getNode( context ).getTotalOffset( );
// get the first containing scope, and modify its end index/offset
for ( Scope scope : variable.getScopes( ) ) {
if ( scope.contains( dependencyIndex_, nodeOffset ) ) {
scope.EndIndex = dependencyIndex_;
scope.EndOffset = nodeOffset;
System.out.println( "new end for variable:" + variable );
return;
}
}
}
/**
* Returns the parsed WMLConfig
* @return Returns the parsed WMLConfig
*/
public WMLConfig getParsedConfig()
{
return config_;

View file

@ -12,8 +12,6 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.wesnoth.utils.Pair;
/**
* Represents a WML Variable
*/
@ -22,23 +20,14 @@ public class WMLVariable implements Serializable
private static final long serialVersionUID = 5293113569770337870L;
private String name_;
private String location_;
private int offset_;
private boolean isArray_;
private List< Pair<Integer, Integer> > scopes_;
private List< Scope > scopes_;
public WMLVariable()
{
this("", "", 0); //$NON-NLS-1$ //$NON-NLS-2$
}
public WMLVariable( String name, String location, int offset )
public WMLVariable( String name )
{
name_ = name;
location_ = location;
offset_ = offset;
scopes_ = new ArrayList<Pair<Integer,Integer>>();
scopes_ = new ArrayList<Scope>();
}
public String getName()
@ -49,22 +38,7 @@ public class WMLVariable implements Serializable
{
name_ = name;
}
public String getLocation()
{
return location_;
}
public void setLocation(String location)
{
location_ = location;
}
public int getOffset()
{
return offset_;
}
public void setOffset(int offset)
{
offset_ = offset;
}
public boolean isArray()
{
return isArray_;
@ -74,7 +48,7 @@ public class WMLVariable implements Serializable
isArray_ = isArray;
}
public List<Pair<Integer, Integer>> getScopes()
public List< Scope > getScopes()
{
return scopes_;
}
@ -85,16 +59,70 @@ public class WMLVariable implements Serializable
StringBuilder res = new StringBuilder( );
res.append( "Variable - Name: " + name_ );
res.append( "; Location:" + location_ );
res.append( "; Offset:" + offset_ );
if ( ! scopes_.isEmpty( ) ) {
res.append( "; Scopes: " );
for ( Pair<Integer,Integer> scope : scopes_ ) {
for ( Scope scope : scopes_ ) {
res.append( scope );
}
}
return res.toString( );
}
/**
* Represents a scope of the WMLVariable
*/
public static class Scope implements Serializable
{
private static final long serialVersionUID = -1919240125062707719L;
/**
* The index of the start defined file
*/
public int StartIndex;
/**
* The offset in the start file
*/
public int StartOffset;
/**
* The index of the end undefined file
*/
public int EndIndex;
/**
* The offset in the end file
*/
public int EndOffset;
public Scope( int startIndex, int startOffset )
{
StartIndex = startIndex;
StartOffset = startOffset;
EndIndex = EndOffset = Integer.MAX_VALUE;
}
@Override
public String toString()
{
return "( " + StartIndex + ":" + StartOffset + " -> " +
EndIndex + ":" + EndOffset + " )";
}
/**
* Returns true if the specified index and offset lie withing
* this scope
* @param index The index of the file
* @param offset The offset in the file
* @return True of false
*/
public boolean contains( int index, int offset )
{
return ( ( StartIndex == index && EndIndex == index &&
StartOffset <= index && index <= EndOffset ) ||
( StartIndex == index && EndIndex != index && offset > StartOffset ) ||
( EndIndex == index && StartIndex != index && offset < EndOffset ) ||
( StartIndex < index && index < EndIndex ) );
}
}
}