blob: 4390ef2e8038a6af46631eb4a9958927fdb51d2c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013, 2018 CEA LIST and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* E.D.Willink(CEA LIST) - Initial API and implementation
*******************************************************************************/
package org.eclipse.ocl.examples.codegen.common;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.ocl.pivot.Constraint;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.TupleLiteralPart;
import org.eclipse.ocl.pivot.TupleType;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.Variable;
public class NameQueries
{
public static abstract class NameAllocation<T>
{
private Map<T, String> mappings = new HashMap<T, String>();
private Set<String> used = new HashSet<String>();
protected abstract String computeUniqueText(T string);
public String get(T string) {
String uniqueString = mappings.get(string);
if (uniqueString == null) {
uniqueString = computeUniqueText(string);
used.add(uniqueString);
mappings.put(string, uniqueString);
}
return uniqueString;
}
protected boolean isUsed(String string) {
return used.contains(string);
}
}
public static class TuplePartAllocation
{
private Map<String, Map<Type, String>> mappings = new HashMap<String, Map<Type, String>>();
private Set<String> used = new HashSet<String>();
protected String computeUniqueText(String partName, Type partType) {
StringBuilder s = new StringBuilder();
appendJavaCharacters(s, partName);
s.append('_');
appendJavaCharacters(s, String.valueOf(partType));
if (isUsed(s.toString())) {
for (int i = 1; true; i++) {
if (!isUsed(s.toString() + '_' + Integer.toString(i))) {
s.append(i);
break;
}
}
}
return s.toString();
}
public String get(String partName, Type partType) {
Map<Type, String> typeMaps = mappings.get(partName);
if (typeMaps == null) {
typeMaps = new HashMap<Type, String>();
mappings.put(partName, typeMaps);
}
String uniqueString = typeMaps.get(partType);
if (uniqueString == null) {
uniqueString = computeUniqueText(partName, partType);
used.add(uniqueString);
typeMaps.put(partType, uniqueString);
}
return uniqueString;
}
protected boolean isUsed(String string) {
return used.contains(string);
}
}
private static Map<Element, NameAllocation<Constraint>> uniqueConstraints = new HashMap<Element, NameAllocation<Constraint>>();
private static Map<Element, NameAllocation<Operation>> uniqueOperations = new HashMap<Element, NameAllocation<Operation>>();
private static Map<Element, NameAllocation<org.eclipse.ocl.pivot.Package>> uniquePackages = new HashMap<Element, NameAllocation<org.eclipse.ocl.pivot.Package>>();
private static Map<Element, NameAllocation<Property>> uniqueProperties = new HashMap<Element, NameAllocation<Property>>();
private static Map<Element, NameAllocation<String>> uniqueStrings = new HashMap<Element, NameAllocation<String>>();
private static Map<Element, TuplePartAllocation> uniqueTupleParts = new HashMap<Element, TuplePartAllocation>();
private static Map<Element, NameAllocation<TupleType>> uniqueTupleTypes = new HashMap<Element, NameAllocation<TupleType>>();
private static Map<Element, NameAllocation<Type>> uniqueTypes = new HashMap<Element, NameAllocation<Type>>();
private static Map<Element, NameAllocation<Variable>> uniqueVariables = new HashMap<Element, NameAllocation<Variable>>();
protected static void appendJavaCharacters(StringBuilder s, String string) {
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
if (Character.isJavaIdentifierPart(c)) {
s.append(c);
}
else {
s.append('_');
}
}
}
protected static void appendJavaCharacters(StringBuilder s, String string, int iMax) {
for (int i = 0; i < Math.min(iMax, string.length()); i++) {
char c = string.charAt(i);
if (Character.isJavaIdentifierPart(c)) {
s.append(c);
}
else {
s.append('_');
}
}
}
/**
* Return a valid Java identifier suffix encoding of string that is unique within the scope of element.
*/
public static String getUniqueText(Element context, Constraint constraint) {
NameAllocation<Constraint> allocation = uniqueConstraints.get(context);
if (allocation == null) {
allocation = new NameAllocation<Constraint>()
{
@Override
protected String computeUniqueText(Constraint constraint) {
StringBuilder s = new StringBuilder();
String name = constraint.getName();
if (name == null) {
@SuppressWarnings("unchecked")
List<Constraint> constraints = (List<Constraint>) constraint.eContainer().eGet(constraint.eContainmentFeature());
name = Integer.toString(constraints.indexOf(constraint));
}
appendJavaCharacters(s, name);
if (isUsed(s.toString())) {
s.append("___");
if (isUsed(s.toString())) {
for (int i = 1; true; i++) {
if (!isUsed(s.toString() + Integer.toString(i))) {
s.append(i);
break;
}
}
}
}
return s.toString();
}
};
uniqueConstraints.put(context, allocation);
}
return allocation.get(constraint);
}
/**
* Return a valid Java identifier suffix encoding of an operation name that is unique within the scope of element.
*/
public static String getUniqueText(Element context, Operation operation) {
NameAllocation<Operation> allocation = uniqueOperations.get(context);
if (allocation == null) {
allocation = new NameAllocation<Operation>()
{
@Override
protected String computeUniqueText(Operation operation) {
StringBuilder s = new StringBuilder();
appendJavaCharacters(s, operation.getOwningClass().getName());
s.append('_');
int arity = operation.getOwnedParameters().size();
String string = operation.getName();
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
if (Character.isJavaIdentifierPart(c)) {
s.append(c);
}
else if (c == '=') {
s.append("_eq_");
}
else if (c == '+') {
s.append("_add_");
}
else if (c == '-') {
if (arity == 0) {
s.append("_neg_");
}
else {
s.append("_sub_");
}
}
else if (c == '/') {
s.append("_div_");
}
else if (c == '*') {
s.append("_mul_");
}
else if (c == '<') {
s.append("_lt_");
}
else if (c == '>') {
s.append("_gt_");
}
else {
s.append('_');
}
}
if (isUsed(s.toString())) {
for (int i = 1; true; i++) {
if (!isUsed(s.toString() + '_' + Integer.toString(i))) {
s.append(i);
break;
}
}
}
return s.toString();
}
};
uniqueOperations.put(context, allocation);
}
return allocation.get(operation);
}
/**
* Return a valid Java identifier suffix encoding of a property name that is unique within the scope of element.
*/
public static String getUniqueText(Element context, org.eclipse.ocl.pivot.Package pkg) {
NameAllocation<org.eclipse.ocl.pivot.Package> allocation = uniquePackages.get(context);
if (allocation == null) {
allocation = new NameAllocation<org.eclipse.ocl.pivot.Package>()
{
@Override
protected String computeUniqueText(org.eclipse.ocl.pivot.Package pkg) {
StringBuilder s = new StringBuilder();
appendJavaCharacters(s, pkg.getName());
if (isUsed(s.toString())) {
for (int i = 1; true; i++) {
if (!isUsed(s.toString() + '_' + Integer.toString(i))) {
s.append(i);
break;
}
}
}
return s.toString();
}
};
uniquePackages.put(context, allocation);
}
return allocation.get(pkg);
}
/**
* Return a valid Java identifier suffix encoding of a property name that is unique within the scope of element.
*/
public static String getUniqueText(Element context, Property property) {
if (property.eContainer() instanceof TupleType) {
TuplePartAllocation allocation = uniqueTupleParts.get(context);
if (allocation == null) {
allocation = new TuplePartAllocation();
uniqueTupleParts.put(context, allocation);
}
return allocation.get(property.getName(), property.getType());
}
NameAllocation<Property> allocation = uniqueProperties.get(context);
if (allocation == null) {
allocation = new NameAllocation<Property>()
{
@Override
protected String computeUniqueText(Property property) {
StringBuilder s = new StringBuilder();
appendJavaCharacters(s, property.getOwningClass().getName());
s.append('_');
appendJavaCharacters(s, property.getName());
if (isUsed(s.toString())) {
for (int i = 1; true; i++) {
if (!isUsed(s.toString() + '_' + Integer.toString(i))) {
s.append(i);
break;
}
}
}
return s.toString();
}
};
uniqueProperties.put(context, allocation);
}
return allocation.get(property);
}
/**
* Return a valid Java identifier suffix encoding of string that is unique within the scope of element.
*/
public static String getUniqueText(Element context, String string) {
NameAllocation<String> allocation = uniqueStrings.get(context);
if (allocation == null) {
allocation = new NameAllocation<String>()
{
@Override
protected String computeUniqueText(String string) {
StringBuilder s = new StringBuilder();
int iSize = string.length();
int iMax = 8;
appendJavaCharacters(s, string, iMax);
if ((iSize > 8) || isUsed(s.toString())) {
s.append("___");
if (isUsed(s.toString())) {
for (int i = 1; true; i++) {
if (!isUsed(s.toString() + Integer.toString(i))) {
s.append(i);
break;
}
}
}
}
return s.toString();
}
};
uniqueStrings.put(context, allocation);
}
return allocation.get(string);
}
/**
* Return a valid Java identifier suffix encoding of a property name that is unique within the scope of element.
*/
public static String getUniqueText(Element context, TupleLiteralPart part) {
TuplePartAllocation allocation = uniqueTupleParts.get(context);
if (allocation == null) {
allocation = new TuplePartAllocation();
uniqueTupleParts.put(context, allocation);
}
return allocation.get(part.getName(), part.getType());
}
/**
* Return a valid Java identifier suffix encoding of a property name that is unique within the scope of element.
*/
public static String getUniqueText(Element context, TupleType type) {
NameAllocation<TupleType> allocation = uniqueTupleTypes.get(context);
if (allocation == null) {
allocation = new NameAllocation<TupleType>()
{
@Override
protected String computeUniqueText(TupleType type) {
StringBuilder s = new StringBuilder();
String name = String.valueOf(type);
appendJavaCharacters(s, name);
if (isUsed(s.toString())) {
for (int i = 1; true; i++) {
if (!isUsed(s.toString() + '_' + Integer.toString(i))) {
s.append(i);
break;
}
}
}
return s.toString();
}
};
uniqueTupleTypes.put(context, allocation);
}
return allocation.get(type);
}
/**
* Return a valid Java identifier suffix encoding of a property name that is unique within the scope of element.
*/
public static String getUniqueText(Element context, Type type) {
NameAllocation<Type> allocation = uniqueTypes.get(context);
if (allocation == null) {
allocation = new NameAllocation<Type>()
{
@Override
protected String computeUniqueText(Type type) {
StringBuilder s = new StringBuilder();
appendJavaCharacters(s, String.valueOf(type));
if (isUsed(s.toString())) {
for (int i = 1; true; i++) {
if (!isUsed(s.toString() + '_' + Integer.toString(i))) {
s.append(i);
break;
}
}
}
return s.toString();
}
};
uniqueTypes.put(context, allocation);
}
return allocation.get(type);
}
/**
* Return a valid Java identifier suffix encoding of a variable name that is unique within the scope of element.
*/
public static String getUniqueText(Element context, Variable variable) {
NameAllocation<Variable> allocation = uniqueVariables.get(context);
if (allocation == null) {
allocation = new NameAllocation<Variable>()
{
@Override
protected String computeUniqueText(Variable variable) {
StringBuilder s = new StringBuilder();
appendJavaCharacters(s, variable.getName());
if (isUsed(s.toString())) {
for (int i = 1; true; i++) {
String suffix = '_' + Integer.toString(i);
if (!isUsed(s.toString() + suffix)) {
s.append(suffix);
break;
}
}
}
return s.toString();
}
};
uniqueVariables.put(context, allocation);
}
String string = allocation.get(variable);
// System.out.println(string + " for " + variable);
return string;
}
}