eclipse plugin: Implement the remaining of the validation...

...routines, and allow the user to enable/disable the WML validation
This commit is contained in:
Timotei Dolean 2011-08-04 19:16:23 +00:00
parent d887324924
commit 9216c01fb8
6 changed files with 157 additions and 38 deletions

View file

@ -62,7 +62,8 @@ public class Constants
public static final String P_WAU_PORT = "wau_port"; //$NON-NLS-1$
/** Advanced preferences */
public static final String P_ADV_NO_TERRAIN_GFX = "adv_no_terrain_gfx"; //$NON-NLS-1$
public static final String P_NO_TERRAIN_GFX = "adv_no_terrain_gfx"; //$NON-NLS-1$
public static final String P_WML_VALIDATION = "adv_wml_validation"; //$NON-NLS-1$
/** Install preferences */
public static final String P_INST_DEFAULT_INSTALL = "inst_default"; //$NON-NLS-1$

View file

@ -8,11 +8,12 @@
*******************************************************************************/
package org.wesnoth.preferences;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.wesnoth.Constants;
import org.wesnoth.Messages;
import org.wesnoth.WesnothPlugin;
import org.eclipse.jface.preference.BooleanFieldEditor;
public class AdvancedPreferencePage extends AbstractPreferencePage
{
public AdvancedPreferencePage()
@ -26,9 +27,17 @@ public class AdvancedPreferencePage extends AbstractPreferencePage
@Override
protected void createFieldEditors()
{
addField(new BooleanFieldEditor(
Constants.P_ADV_NO_TERRAIN_GFX, Messages.AdvancedPreferencePage_1, 1,
getFieldEditorParent()),
Messages.AdvancedPreferencePage_2);
addField( new BooleanFieldEditor(
Constants.P_NO_TERRAIN_GFX, Messages.AdvancedPreferencePage_1,
BooleanFieldEditor.SEPARATE_LABEL,
getFieldEditorParent( ) ),
Messages.AdvancedPreferencePage_2 );
addField( new BooleanFieldEditor(
Constants.P_WML_VALIDATION, "WML Validation, parent",
BooleanFieldEditor.SEPARATE_LABEL,
getFieldEditorParent( ) ),
"If checked, the WML Editor will validate some of the " +
"written WML to check for semantic errors." );
}
}

View file

@ -11,13 +11,14 @@ package org.wesnoth.preferences;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
import org.eclipse.jface.preference.IPreferenceStore;
import org.wesnoth.Constants;
import org.wesnoth.WesnothPlugin;
import org.wesnoth.utils.StringUtils;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
import org.eclipse.jface.preference.IPreferenceStore;
/**
* Class used to initialize default preference values.
*/
@ -57,7 +58,8 @@ public class Preferences extends AbstractPreferenceInitializer
store.setDefault(Constants.P_WAU_PORT, 15002);
// advanced
store.setDefault(Constants.P_ADV_NO_TERRAIN_GFX, true);
store.setDefault(Constants.P_NO_TERRAIN_GFX, true);
store.setDefault( Constants.P_WML_VALIDATION, false );
// installs
store.setDefault(Constants.P_INST_DEFAULT_INSTALL, ""); //$NON-NLS-1$

View file

@ -135,7 +135,7 @@ public class PreprocessorUtils
arguments.add(macrosFile);
}
if (Preferences.getBool(Constants.P_ADV_NO_TERRAIN_GFX))
if (Preferences.getBool(Constants.P_NO_TERRAIN_GFX))
{
if (defines == null)
defines = new ArrayList<String>();

View file

@ -580,6 +580,18 @@ public class ResourceUtils
}
}
/**
* Returns the corresponding {@link IResource} from the specified
* EMF Resource
* @param emfResource The EMF Resource
* @return An {@link IResource} instance
*/
public static IResource getWorkspaceResource( Resource emfResource )
{
return ResourcesPlugin.getWorkspace( ).getRoot( ).
getFile( new Path( emfResource.getURI( ).toPlatformString( true ) ) );
}
/**
* Gets the WML Grammar root of the specified file
* @param file The file to get the WML model from

View file

@ -8,18 +8,19 @@
*******************************************************************************/
package org.wesnoth.validation;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.validation.Check;
import org.eclipse.xtext.validation.CheckType;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.wesnoth.Constants;
import org.wesnoth.Messages;
import org.wesnoth.installs.WesnothInstallsUtils;
import org.wesnoth.preferences.Preferences;
import org.wesnoth.projects.ProjectCache;
import org.wesnoth.projects.ProjectUtils;
import org.wesnoth.schema.SchemaParser;
import org.wesnoth.utils.ResourceUtils;
import org.wesnoth.utils.WMLUtils;
import org.wesnoth.wml.WMLExpression;
import org.wesnoth.wml.WMLKey;
import org.wesnoth.wml.WMLMacroCall;
@ -27,6 +28,16 @@ import org.wesnoth.wml.WMLRoot;
import org.wesnoth.wml.WMLTag;
import org.wesnoth.wml.WmlPackage;
import org.eclipse.core.resources.IResource;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.validation.Check;
import org.eclipse.xtext.validation.CheckType;
import com.google.common.collect.Iterables;
/**
* This represents the validator for config files
*
@ -38,16 +49,39 @@ import org.wesnoth.wml.WmlPackage;
*/
public class WMLJavaValidator extends AbstractWMLJavaValidator
{
// @Check(CheckType.FAST)
/**
* Returns the {@link SchemaParser} from the specified {@link EObject}
* @param object
* @return
*/
private SchemaParser getSchema( EObject object )
{
return SchemaParser.getInstance(
WesnothInstallsUtils.getInstallNameForResource(
ResourceUtils.getWorkspaceResource( object.eResource( ) ) ) );
}
private boolean isValidationEnabled( )
{
return Preferences.getBool( Constants.P_WML_VALIDATION );
}
@Check(CheckType.FAST)
public void checkFastTagName(WMLTag tag)
{
if ( !isValidationEnabled( ) )
return;
if (!tag.getName().equals(tag.getEndName()))
warning( Messages.WMLJavaValidator_0, WmlPackage.Literals.WML_TAG__END_NAME);
}
// @Check(CheckType.NORMAL)
@Check(CheckType.NORMAL)
public void checkNormalTagName(WMLTag tag)
{
if ( !isValidationEnabled( ) )
return;
ICompositeNode node = NodeModelUtils.getNode( tag );
if (node != null)
{
@ -61,12 +95,7 @@ public class WMLJavaValidator extends AbstractWMLJavaValidator
searchName = "root"; //$NON-NLS-1$
}
Resource resource = getCurrentObject( ).eResource( );
IResource file = ResourcesPlugin.getWorkspace( ).getRoot( ).
getFile( new Path( resource.getURI( ).toPlatformString( true ) ) );
WMLTag schemaTag = SchemaParser.getInstance(
WesnothInstallsUtils.getInstallNameForResource( file ) ).getTags().get(searchName);
WMLTag schemaTag = getSchema( tag ).getTags( ).get( searchName );
if ( schemaTag != null )
{
@ -79,33 +108,99 @@ public class WMLJavaValidator extends AbstractWMLJavaValidator
}
}
if (found == false)
warning( Messages.WMLJavaValidator_1, WmlPackage.Literals.WML_EXPRESSION__NAME );
warning( Messages.WMLJavaValidator_1,
WmlPackage.Literals.WML_EXPRESSION__NAME );
}
}
}
@Check(CheckType.EXPENSIVE)
public void checkExpensiveKeyValue(WMLKey key)
private void checkTagsCardinalities( SchemaParser schema,
Iterable< WMLTag > tags )
{
//TODO: add regex checking here
System.out.println(Messages.WMLJavaValidator_2);
Map< String, Integer > ocurrences = new HashMap<String, Integer>( );
for ( WMLTag tag : tags ) {
Integer currentValue = ocurrences.get( tag.getName( ) );
if ( currentValue == null )
currentValue = 0;
ocurrences.put( tag.getName( ), currentValue + 1 );
}
for ( Entry<String, Integer> entry : ocurrences.entrySet( ) ) {
WMLTag schemaTag = schema.getTags( ).get( entry.getKey( ) );
if ( schemaTag == null )
continue;
if ( schemaTag.getAllowedCount( ) < entry.getValue( ) )
warning( "Tag " + entry.getKey( ) + " cannot appear more" +
"than " + schemaTag.getAllowedCount( ) + " times. ",
WmlPackage.Literals.WML_EXPRESSION__NAME );
}
}
private void checkKeysCardinalities( WMLTag parentTag,
Iterable< WMLKey > keys )
{
Map< String, Integer > ocurrences = new HashMap<String, Integer>( );
for ( WMLKey key : keys ) {
Integer currentValue = ocurrences.get( key.getName( ) );
if ( currentValue == null )
currentValue = 0;
ocurrences.put( key.getName( ), currentValue + 1 );
}
for ( Entry<String, Integer> entry : ocurrences.entrySet( ) ) {
WMLKey schemaKey = WMLUtils.getKeyByName( parentTag, entry.getKey( ) );
if ( schemaKey == null )
continue;
if ( schemaKey.getAllowedCount( ) < entry.getValue( ) )
warning( "Key " + entry.getKey( ) + ", in tag " + parentTag.getName( )
+ "cannot appear more than " +
schemaKey.getAllowedCount( ) + " times. ",
WmlPackage.Literals.WML_EXPRESSION__NAME );
}
}
@Check(CheckType.NORMAL)
public void checkNormalWMLRootCardinality(WMLRoot root)
{
//TODO: add check for subtags cardinality
if ( !isValidationEnabled( ) )
return;
checkTagsCardinalities( getSchema( root ),
Iterables.filter( root.getExpressions( ), WMLTag.class ) );
}
@Check(CheckType.NORMAL)
public void checkNormalWMLTagCardinality(WMLTag tag)
{
//TODO: add check for subtags/subkeys cardinality
if ( !isValidationEnabled( ) )
return;
SchemaParser schema = getSchema( tag );
checkTagsCardinalities( schema,
Iterables.filter( tag.getExpressions( ), WMLTag.class ) );
checkKeysCardinalities( tag,
Iterables.filter( tag.getExpressions( ), WMLKey.class ) );
}
@Check(CheckType.FAST)
public void checkNormalWMLMacroExistance(WMLMacroCall call)
@Check(CheckType.NORMAL)
public void checkNormalWMLMacroExistance( WMLMacroCall call )
{
//TODO: add check for macro existance - by name
if ( !isValidationEnabled( ) )
return;
IResource resource = ResourceUtils.getWorkspaceResource( call.eResource( ) );
ProjectCache cache = ProjectUtils.getCacheForProject( resource.getProject( ) );
if ( ! cache.getDefines( ).containsKey( call.getName( ) ) )
warning( "Undefined macro: " + call.getName( ),
WmlPackage.Literals.WML_EXPRESSION__NAME );
}
}