From 04152c45ff86f4726a50df13f2b375bd98fdeadd Mon Sep 17 00:00:00 2001 From: Timotei Dolean Date: Tue, 26 Jul 2011 15:31:37 +0000 Subject: [PATCH] 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. --- utils/umc_dev/changelog | 3 + .../ui/contentassist/WMLProposalProvider.java | 13 ++- .../org/wesnoth/wml/core/SimpleWMLParser.java | 76 ++++++++++++--- .../src/org/wesnoth/wml/core/WMLVariable.java | 96 ++++++++++++------- 4 files changed, 137 insertions(+), 51 deletions(-) diff --git a/utils/umc_dev/changelog b/utils/umc_dev/changelog index c3921574e96..5392c8f544c 100644 --- a/utils/umc_dev/changelog +++ b/utils/umc_dev/changelog @@ -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 diff --git a/utils/umc_dev/org.wesnoth.ui/src/org/wesnoth/ui/contentassist/WMLProposalProvider.java b/utils/umc_dev/org.wesnoth.ui/src/org/wesnoth/ui/contentassist/WMLProposalProvider.java index 23907badd80..d99c8b7c137 100644 --- a/utils/umc_dev/org.wesnoth.ui/src/org/wesnoth/ui/contentassist/WMLProposalProvider.java +++ b/utils/umc_dev/org.wesnoth.ui/src/org/wesnoth/ui/contentassist/WMLProposalProvider.java @@ -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 variables = new ArrayList(); + + // 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; } } ); diff --git a/utils/umc_dev/org.wesnoth/src/org/wesnoth/wml/core/SimpleWMLParser.java b/utils/umc_dev/org.wesnoth/src/org/wesnoth/wml/core/SimpleWMLParser.java index a162d98969a..b2552f924c6 100644 --- a/utils/umc_dev/org.wesnoth/src/org/wesnoth/wml/core/SimpleWMLParser.java +++ b/utils/umc_dev/org.wesnoth/src/org/wesnoth/wml/core/SimpleWMLParser.java @@ -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_; diff --git a/utils/umc_dev/org.wesnoth/src/org/wesnoth/wml/core/WMLVariable.java b/utils/umc_dev/org.wesnoth/src/org/wesnoth/wml/core/WMLVariable.java index 5ebc63513c2..e774fd98e1d 100644 --- a/utils/umc_dev/org.wesnoth/src/org/wesnoth/wml/core/WMLVariable.java +++ b/utils/umc_dev/org.wesnoth/src/org/wesnoth/wml/core/WMLVariable.java @@ -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 > 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>(); + scopes_ = new ArrayList(); } 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> 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 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 ) ); + } + } }