Skip to content

Commit

Permalink
[lang] Add operation extensions for Maps.
Browse files Browse the repository at this point in the history
see #250

Signed-off-by: Stéphane Galland <galland@arakhne.org>
  • Loading branch information
gallandarakhneorg committed Dec 4, 2014
1 parent e7e2b61 commit 5d7e00c
Show file tree
Hide file tree
Showing 8 changed files with 253 additions and 8 deletions.
2 changes: 2 additions & 0 deletions plugins/io.sarl.lang.core/META-INF/MANIFEST.MF
Expand Up @@ -7,6 +7,8 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-Vendor: %Bundle-Vendor
Export-Package: io.sarl.lang.annotation,
io.sarl.lang.core,
io.sarl.lang.scoping.batch,
io.sarl.lang.util
Import-Package: javax.inject
Require-Bundle: org.eclipse.xtext.xbase.lib;bundle-version="2.7.3"

@@ -0,0 +1,163 @@
/*
* $Id$
*
* SARL is an general-purpose agent programming language.
* More details on http://www.sarl.io
*
* Copyright (C) 2014 Sebastian RODRIGUEZ, Nicolas GAUD, Stéphane GALLAND.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.sarl.lang.scoping.batch;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentMap;

import org.eclipse.xtext.xbase.lib.Inline;
import org.eclipse.xtext.xbase.lib.Pair;

import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.Maps;


/** This is an extension library for {@link Map maps} in the SARL language.
* <p>
* This extension is provided for the elements that are not (yet) provided
* by the Xbase API.
*
* FIXME: Remove if Xbase or Xtend are providing these functions.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
@GwtCompatible
public class SARLMapExtensions {

private static <K, V> Map<K, V> cloneMap(Map<K, V> oldMap) {
if (oldMap instanceof TreeMap<?, ?>) {
return Maps.newTreeMap((TreeMap<K, V>) oldMap);
}
if (oldMap instanceof LinkedHashMap<?, ?>) {
return Maps.newLinkedHashMap(oldMap);
}
if (oldMap instanceof ConcurrentMap<?, ?>) {
Map<K, V> m = Maps.newConcurrentMap();
m.putAll(oldMap);
return m;
}
return Maps.newHashMap(oldMap);
}

/** Add the given pair into the map.
*
* @param map - the map to update.
* @param entry - the entry (key, value) to add into the map.
* @return the value previously associated to the key, or <code>null</code>
* if the key was not present in the map before the addition.
*/
@Inline(value="$1.put($2.getKey(), $2.getValue())")
public static <K, V> V operator_add(Map<K, V> map, Pair<? extends K, ? extends V> entry) {
return map.put(entry.getKey(), entry.getValue());
}

/** Add the given entries of the input map into the output map.
*
* @param outputMap - the map to update.
* @param inputMap - the entries to add.
* @return the outputMap
*/
public static <K, V> Map<K, V> operator_add(Map<K, V> outputMap, Map<? extends K, ? extends V> inputMap) {
outputMap.putAll(inputMap);
return outputMap;
}

/** Add the given pair to a given map for obtaining a new map.
*
* @param map - the map to consider.
* @param entry - the entry (key, value) to add into the map.
* @return a map with the content of the map and with the given entry.
*/
public static <K, V> Map<K, V> operator_plus(Map<K, V> map, Pair<? extends K, ? extends V> entry) {
Map<K, V> newMap = cloneMap(map);
newMap.put(entry.getKey(), entry.getValue());
return newMap;
}

/** Add the given pair to a given map for obtaining a new map.
*
* @param entry - the entry (key, value) to add into the map.
* @param map - the map to consider.
* @return a map with the content of the map and with the given entry.
*/
public static <K, V> Map<K, V> operator_plus(Pair<? extends K, ? extends V> entry, Map<K, V> map) {
Map<K, V> newMap = cloneMap(map);
newMap.put(entry.getKey(), entry.getValue());
return newMap;
}

/** Merge the given maps.
* If a key exists in the two maps, the value in the second map is retained.
*
* @param map - the first map.
* @param map2 - the second map.
* @return a map with the merged contents from the two maps.
*/
public static <K, V> Map<K, V> operator_plus(Map<K, V> map, Map<? extends K, ? extends V> map2) {
Map<K, V> newMap = cloneMap(map);
newMap.putAll(map2);
return newMap;
}

/** Remove a key from the given map.
*
* @param map - the map to update.
* @param key - the key to remove.
* @return the removed value, or <code>null</code> if the key was not
* present in the map.
*/
@Inline("$1.remove($2)")
public static <K, V> V operator_remove(Map<K, V> map, K key) {
return map.remove(key);
}

/** Create a copy of the given map without the given key.
*
* @param map - the map to update.
* @param key - the key to remove.
* @return the removed value, or <code>null</code> if the key was not
* present in the map.
*/
public static <K, V> Map<K, V> operator_minus(Map<K, V> map, K key) {
Map<K, V> newMap = cloneMap(map);
newMap.remove(key);
return newMap;
}

/** Replies the value associated to the key in the given map.
*
* @param map - the map.
* @param key - the key.
* @return the value, or <code>null</code> if the key is not
* present in the map.
*/
@Inline("$1.get($2)")
public static <K, V> V operator_mappedTo(Map<K, V> map, K key) {
return map.get(key);
}

}
3 changes: 2 additions & 1 deletion plugins/io.sarl.lang.ui/META-INF/MANIFEST.MF
Expand Up @@ -19,7 +19,8 @@ Require-Bundle: io.sarl.lang;bundle-version="[0.2.0,0.3.0)";visibility:=reexport
org.eclipse.ui;bundle-version="3.106.0",
org.eclipse.xtext.xbase.lib;bundle-version="2.7.3",
org.antlr.runtime;bundle-version="3.2.0",
org.eclipse.jdt.debug.ui;bundle-version="3.6.300"
org.eclipse.jdt.debug.ui;bundle-version="3.6.300",
org.eclipse.jdt.doc.user;bundle-version="3.10.1"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Export-Package: io.sarl.lang.ui,
io.sarl.lang.ui.contentassist,
Expand Down
2 changes: 2 additions & 0 deletions plugins/io.sarl.lang/META-INF/MANIFEST.MF
Expand Up @@ -22,13 +22,15 @@ Import-Package: org.eclipse.xtext.xbase.lib,
org.apache.log4j
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Export-Package: io.sarl.lang,
io.sarl.lang.controlflow,
io.sarl.lang.formatting,
io.sarl.lang.jvmmodel,
io.sarl.lang.parser.antlr,
io.sarl.lang.parser.antlr.internal,
io.sarl.lang.sarl,
io.sarl.lang.sarl.impl,
io.sarl.lang.sarl.util,
io.sarl.lang.scoping.batch,
io.sarl.lang.serializer,
io.sarl.lang.services,
io.sarl.lang.signature,
Expand Down
Expand Up @@ -1430,6 +1430,7 @@ public class XVariableDeclarationElements extends AbstractParserRuleElementFinde

////-----------------------------------------------
//// BELOW THIS POINT, THE RULES FROM XBASE ARE OVERLOADED
//// Variable declaration according to the SARL syntax (not the Xtext/Xtend)
//XVariableDeclaration returns xbase::XExpression:
// {xbase::XVariableDeclaration} (writeable?="var" | "val") (=> (name=ValidID ":" type=JvmTypeReference) | name=ValidID)
// ("=" right=XExpression)?;
Expand Down Expand Up @@ -1508,6 +1509,7 @@ public class JvmFormalParameterElements extends AbstractParserRuleElementFinder
private final Assignment cParameterTypeAssignment_2_1 = (Assignment)cGroup_2.eContents().get(1);
private final RuleCall cParameterTypeJvmTypeReferenceParserRuleCall_2_1_0 = (RuleCall)cParameterTypeAssignment_2_1.eContents().get(0);

//// Formal parameter declaration according to the SARL syntax (not the Xtext/Xtend)
//JvmFormalParameter returns jvm::JvmFormalParameter:
// {jvm::JvmFormalParameter} name=ValidID (":" parameterType=JvmTypeReference)?;
public ParserRule getRule() { return rule; }
Expand Down Expand Up @@ -1547,6 +1549,7 @@ public class FullJvmFormalParameterElements extends AbstractParserRuleElementFin
private final Assignment cParameterTypeAssignment_3 = (Assignment)cGroup.eContents().get(3);
private final RuleCall cParameterTypeJvmTypeReferenceParserRuleCall_3_0 = (RuleCall)cParameterTypeAssignment_3.eContents().get(0);

//// Formal parameter declaration according to the SARL syntax (not the Xtext/Xtend)
//FullJvmFormalParameter returns jvm::JvmFormalParameter:
// {jvm::JvmFormalParameter} name=ValidID ":" parameterType=JvmTypeReference;
public ParserRule getRule() { return rule; }
Expand Down Expand Up @@ -1632,6 +1635,7 @@ public class XForLoopExpressionElements extends AbstractParserRuleElementFinder
private final Assignment cEachExpressionAssignment_3 = (Assignment)cGroup.eContents().get(3);
private final RuleCall cEachExpressionXExpressionParserRuleCall_3_0 = (RuleCall)cEachExpressionAssignment_3.eContents().get(0);

//// The type of the for-loop's variable is following the SARL syntax (not the Xtext/Xtend)
//XForLoopExpression returns xbase::XExpression:
// => ({xbase::XForLoopExpression} "for" "(" declaredParam=XXLoopFormalParameter ":") forExpression=XExpression ")"
// eachExpression=XExpression;
Expand Down Expand Up @@ -2094,6 +2098,7 @@ public ParserRule getDefaultParameterValueRule() {

////-----------------------------------------------
//// BELOW THIS POINT, THE RULES FROM XBASE ARE OVERLOADED
//// Variable declaration according to the SARL syntax (not the Xtext/Xtend)
//XVariableDeclaration returns xbase::XExpression:
// {xbase::XVariableDeclaration} (writeable?="var" | "val") (=> (name=ValidID ":" type=JvmTypeReference) | name=ValidID)
// ("=" right=XExpression)?;
Expand All @@ -2105,6 +2110,7 @@ public ParserRule getXVariableDeclarationRule() {
return getXVariableDeclarationAccess().getRule();
}

//// Formal parameter declaration according to the SARL syntax (not the Xtext/Xtend)
//JvmFormalParameter returns jvm::JvmFormalParameter:
// {jvm::JvmFormalParameter} name=ValidID (":" parameterType=JvmTypeReference)?;
public JvmFormalParameterElements getJvmFormalParameterAccess() {
Expand All @@ -2115,6 +2121,7 @@ public ParserRule getJvmFormalParameterRule() {
return getJvmFormalParameterAccess().getRule();
}

//// Formal parameter declaration according to the SARL syntax (not the Xtext/Xtend)
//FullJvmFormalParameter returns jvm::JvmFormalParameter:
// {jvm::JvmFormalParameter} name=ValidID ":" parameterType=JvmTypeReference;
public FullJvmFormalParameterElements getFullJvmFormalParameterAccess() {
Expand All @@ -2137,6 +2144,7 @@ public ParserRule getXXLoopFormalParameterRule() {
return getXXLoopFormalParameterAccess().getRule();
}

//// The type of the for-loop's variable is following the SARL syntax (not the Xtext/Xtend)
//XForLoopExpression returns xbase::XExpression:
// => ({xbase::XForLoopExpression} "for" "(" declaredParam=XXLoopFormalParameter ":") forExpression=XExpression ")"
// eachExpression=XExpression;
Expand Down
5 changes: 4 additions & 1 deletion plugins/io.sarl.lang/src/io/sarl/lang/SARL.xtext
Expand Up @@ -227,18 +227,21 @@ DefaultParameterValue returns xbase::XExpression:
//-----------------------------------------------
// BELOW THIS POINT, THE RULES FROM XBASE ARE OVERLOADED

// Variable declaration according to the SARL syntax (not the Xtext/Xtend)
XVariableDeclaration returns xbase::XExpression:
{xbase::XVariableDeclaration}
(writeable?='var'|'val')
(=>(name=ValidID ':' type=JvmTypeReference) | name=ValidID)
('=' right=XExpression)?
;

// Formal parameter declaration according to the SARL syntax (not the Xtext/Xtend)
JvmFormalParameter returns jvm::JvmFormalParameter:
{jvm::JvmFormalParameter}
name=ValidID (=>':' parameterType=JvmTypeReference)?
;

// Formal parameter declaration according to the SARL syntax (not the Xtext/Xtend)
FullJvmFormalParameter returns jvm::JvmFormalParameter:
{jvm::JvmFormalParameter}
name=ValidID ':' parameterType=JvmTypeReference
Expand All @@ -252,9 +255,9 @@ XXLoopFormalParameter returns jvm::JvmFormalParameter:
( 'as' parameterType=JvmTypeReference )?
;

// The type of the for-loop's variable is following the SARL syntax (not the Xtext/Xtend)
XForLoopExpression returns xbase::XExpression:
=>({xbase::XForLoopExpression}
'for' '(' declaredParam=XXLoopFormalParameter ':') forExpression=XExpression ')'
eachExpression=XExpression
;

22 changes: 16 additions & 6 deletions plugins/io.sarl.lang/src/io/sarl/lang/SARLRuntimeModule.java
Expand Up @@ -20,20 +20,22 @@
*/
package io.sarl.lang;

import org.eclipse.xtext.validation.ConfigurableIssueCodesProvider;
import org.eclipse.xtext.xbase.controlflow.IEarlyExitComputer;
import org.eclipse.xtext.xbase.typesystem.util.ExtendedEarlyExitComputer;
import org.eclipse.xtext.xbase.validation.EarlyExitValidator;
import org.eclipse.xtext.xbase.validation.FeatureNameValidator;

import io.sarl.lang.controlflow.SARLEarlyExitComputer;
import io.sarl.lang.controlflow.SARLExtendedEarlyExitComputer;
import io.sarl.lang.scoping.batch.SARLImplicitlyImportedFeatures;
import io.sarl.lang.signature.ActionSignatureProvider;
import io.sarl.lang.signature.DefaultActionSignatureProvider;
import io.sarl.lang.validation.SARLConfigurableIssueCodesProvider;
import io.sarl.lang.validation.SARLEarlyExitValidator;
import io.sarl.lang.validation.SARLFeatureNameValidator;

import org.eclipse.xtext.validation.ConfigurableIssueCodesProvider;
import org.eclipse.xtext.xbase.controlflow.IEarlyExitComputer;
import org.eclipse.xtext.xbase.scoping.batch.ImplicitlyImportedFeatures;
import org.eclipse.xtext.xbase.typesystem.util.ExtendedEarlyExitComputer;
import org.eclipse.xtext.xbase.validation.EarlyExitValidator;
import org.eclipse.xtext.xbase.validation.FeatureNameValidator;

/**
* Use this class to register components to be used at runtime / without the
* Equinox extension registry.
Expand Down Expand Up @@ -78,6 +80,14 @@ public Class<? extends EarlyExitValidator> bindEarlyExitValidator() {
return SARLEarlyExitValidator.class;
}

/** Replies the type of the implicitly imported code extensions.
* @return the type of the implicitly imported code extensions.
*/
@SuppressWarnings("static-method")
public Class<? extends ImplicitlyImportedFeatures> bindImplicitlyImportedFeatures() {
return SARLImplicitlyImportedFeatures.class;
}

@Override
public Class<? extends ConfigurableIssueCodesProvider> bindConfigurableIssueCodesProvider() {
assert (
Expand Down
@@ -0,0 +1,56 @@
/*
* $Id$
*
* SARL is an general-purpose agent programming language.
* More details on http://www.sarl.io
*
* Copyright (C) 2014 Sebastian RODRIGUEZ, Nicolas GAUD, Stéphane GALLAND.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.sarl.lang.scoping.batch;

import java.util.List;

import org.eclipse.xtext.xbase.scoping.batch.ImplicitlyImportedFeatures;

import com.google.inject.Singleton;


/** Provider of the implicitly imported features in the SARL language.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
@Singleton
public class SARLImplicitlyImportedFeatures extends ImplicitlyImportedFeatures {

/**
*/
public SARLImplicitlyImportedFeatures() {
super();
}

@Override
protected List<Class<?>> getExtensionClasses() {
List<Class<?>> xtextList = super.getExtensionClasses();
// Insert at the beginning for ensuring the SARL extension is selected before any Xtext extension.
xtextList.add(0, SARLMapExtensions.class);
return xtextList;
}

}

0 comments on commit 5d7e00c

Please sign in to comment.