Skip to content

Commit

Permalink
Added support for IService union parameter types.
Browse files Browse the repository at this point in the history
  • Loading branch information
ylussaud committed Apr 2, 2024
1 parent f6b74f9 commit 9c7aa15
Show file tree
Hide file tree
Showing 30 changed files with 511 additions and 154 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ public Visibility getVisibility() {
*/
@Override
public String getShortSignature() {
final List<IType> parameterTypes = getParameterTypes(getLookupEngine().getQueryEnvironment());
final IType[] argumentTypes = parameterTypes.toArray(new IType[parameterTypes.size()]);
final List<Set<IType>> parameterTypes = getParameterTypes(getLookupEngine().getQueryEnvironment());
final Object[] argumentTypes = parameterTypes.toArray(new Object[parameterTypes.size()]);

return serviceShortSignature(argumentTypes);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,13 @@ public String getName() {
}

@Override
public List<IType> computeParameterTypes(IReadOnlyQueryEnvironment queryEnvironment) {
List<IType> result = new ArrayList<IType>();
public List<Set<IType>> computeParameterTypes(IReadOnlyQueryEnvironment queryEnvironment) {
List<Set<IType>> result = new ArrayList<>();
final AstValidator validator = new AstValidator(new ValidationServices(queryEnvironment));
for (Variable var : getOrigin().getParameters()) {
IType rawType = validator.getDeclarationTypes(queryEnvironment, validator.validate(Collections
.emptyMap(), var.getType()).getPossibleTypes(var.getType().getAst())).iterator().next();
// TODO for now, using only the raw variable type, do we need special handling for collections?
result.add(rawType);
Set<IType> types = validator.getDeclarationTypes(queryEnvironment, validator.validate(Collections
.emptyMap(), var.getType()).getPossibleTypes(var.getType().getAst()));
result.add(types);
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,13 @@ public String getName() {
}

@Override
public List<IType> computeParameterTypes(IReadOnlyQueryEnvironment queryEnvironment) {
final List<IType> result = new ArrayList<IType>();
public List<Set<IType>> computeParameterTypes(IReadOnlyQueryEnvironment queryEnvironment) {
final List<Set<IType>> result = new ArrayList<>();
final AstValidator validator = new AstValidator(new ValidationServices(queryEnvironment));
for (Variable var : getOrigin().getParameters()) {
IType rawType = validator.getDeclarationTypes(queryEnvironment, validator.validate(Collections
.emptyMap(), var.getType()).getPossibleTypes(var.getType().getAst())).iterator().next();
// TODO for now, using only the raw variable type, do we need special handling for collections?
result.add(rawType);
Set<IType> types = validator.getDeclarationTypes(queryEnvironment, validator.validate(Collections
.emptyMap(), var.getType()).getPossibleTypes(var.getType().getAst()));
result.add(types);
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2023 Obeo.
* Copyright (c) 2023, 2024 Obeo.
* 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
Expand All @@ -13,6 +13,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.eclipse.acceleo.Module;
Expand Down Expand Up @@ -276,16 +277,26 @@ private List<IService<?>> getCompatibleServices(IService<?> service) {
List<IService<?>> newCompatibleServices = new ArrayList<>();
do {
for (IService<?> currentCompatibleService : currentCompatibleServices) {
final List<IType> serviceParameterTypes = currentCompatibleService.getParameterTypes(
final List<Set<IType>> serviceParameterTypes = currentCompatibleService.getParameterTypes(
queryEnvironment);
nextservice: for (IService<?> registeredService : possibleServices) {
final List<IType> registeredServiceParameterTypes = registeredService
nextService: for (IService<?> registeredService : possibleServices) {
final List<Set<IType>> registeredServiceParameterTypes = registeredService
.getParameterTypes(queryEnvironment);
for (int i = 0; i < currentCompatibleService.getNumberOfParameters(); i++) {
if (!serviceParameterTypes.get(i).isAssignableFrom(registeredServiceParameterTypes
.get(i)) && !registeredServiceParameterTypes.get(i).isAssignableFrom(
serviceParameterTypes.get(i))) {
continue nextservice;
boolean isAssignable = false;
for (IType serviceParameterType : serviceParameterTypes.get(i)) {
for (IType registeredServiceParameterType : registeredServiceParameterTypes
.get(i)) {
if (serviceParameterType.isAssignableFrom(registeredServiceParameterType)
|| registeredServiceParameterType.isAssignableFrom(
serviceParameterType)) {
isAssignable = true;
break;
}
}
if (!isAssignable) {
continue nextService;
}
}
}
if (!res.contains(registeredService)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2016, 2021 Obeo.
* Copyright (c) 2016, 2024 Obeo.
* 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
Expand Down Expand Up @@ -236,13 +236,19 @@ public Void caseStringLiteral(StringLiteral stringLiteral) {
@Override
public Void caseTypeSetLiteral(TypeSetLiteral typeSetLiteral) {
builder.append("{");
final StringBuilder previousBuilder = builder;
builder = new StringBuilder();
for (TypeLiteral type : typeSetLiteral.getTypes()) {
doSwitch(type);
builder.append(" | ");
if (!typeSetLiteral.getTypes().isEmpty()) {
final StringBuilder previousBuilder = builder;
builder = new StringBuilder();
try {
for (TypeLiteral type : typeSetLiteral.getTypes()) {
doSwitch(type);
builder.append(" | ");
}
previousBuilder.append(builder.substring(0, builder.length() - 3));
} finally {
builder = previousBuilder;
}
}
previousBuilder.append(builder.substring(0, builder.length() - 3));
builder.append(CLOSING_BRACKET);
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015, 2023 Obeo.
* Copyright (c) 2015, 2024 Obeo.
* 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
Expand Down Expand Up @@ -74,14 +74,14 @@ enum Visibility {
String getLongSignature();

/**
* Gets the {@link List} of parameter {@link IType}.
* Gets the {@link List} of parameter possible {@link IType}.
*
* @param queryEnvironment
* the {@link IReadOnlyQueryEnvironment}
* @return the {@link List} of parameter {@link IType}
* @since 4.1
* @return the {@link List} of parameter possible {@link IType}
* @since 8.0.0
*/
List<IType> getParameterTypes(IReadOnlyQueryEnvironment queryEnvironment);
List<Set<IType>> getParameterTypes(IReadOnlyQueryEnvironment queryEnvironment);

/**
* Gets the number of parameters including the receiver.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.StringJoiner;

import org.eclipse.acceleo.query.ast.Call;
import org.eclipse.acceleo.query.runtime.AcceleoQueryEvaluationException;
Expand Down Expand Up @@ -54,7 +55,7 @@ public abstract class AbstractService<O> implements IService<O> {
/**
* Parameters {@link IType} cache.
*/
private List<IType> parameterTypes;
private List<Set<IType>> parameterTypes;

/**
* Constructor with an {@link Object origin}.
Expand All @@ -77,7 +78,7 @@ public O getOrigin() {
}

@Override
public List<IType> getParameterTypes(IReadOnlyQueryEnvironment queryEnvironment) {
public List<Set<IType>> getParameterTypes(IReadOnlyQueryEnvironment queryEnvironment) {
if (knwonEnvironment != queryEnvironment || returnTypes == null) {
knwonEnvironment = queryEnvironment;
parameterTypes = computeParameterTypes(queryEnvironment);
Expand All @@ -93,7 +94,7 @@ public List<IType> getParameterTypes(IReadOnlyQueryEnvironment queryEnvironment)
* the {@link IReadOnlyQueryEnvironment}
* @return the {@link #getParameterTypes(IReadOnlyQueryEnvironment)}
*/
protected abstract List<IType> computeParameterTypes(IReadOnlyQueryEnvironment queryEnvironment);
protected abstract List<Set<IType>> computeParameterTypes(IReadOnlyQueryEnvironment queryEnvironment);

@Override
public Set<IType> getType(IReadOnlyQueryEnvironment queryEnvironment) {
Expand All @@ -116,20 +117,29 @@ public Set<IType> getType(IReadOnlyQueryEnvironment queryEnvironment) {

@Override
public boolean isEqualParameterTypes(IReadOnlyQueryEnvironment queryEnvironment, IService<?> service) {
final List<IType> paramTypes1 = getParameterTypes(queryEnvironment);
final List<IType> paramTypes2 = service.getParameterTypes(queryEnvironment);
final List<Set<IType>> paramTypes1 = getParameterTypes(queryEnvironment);
final List<Set<IType>> paramTypes2 = service.getParameterTypes(queryEnvironment);
boolean result;

if (paramTypes1.size() == paramTypes2.size()) {
final Iterator<IType> it1 = paramTypes1.iterator();
final Iterator<IType> it2 = paramTypes2.iterator();
final Iterator<Set<IType>> it1 = paramTypes1.iterator();
final Iterator<Set<IType>> it2 = paramTypes2.iterator();
result = true;
while (it1.hasNext()) {
IType paramType1 = it1.next();
IType paramType2 = it2.next();
if (!paramType2.equals(paramType1)) {
result = false;
break;
final Set<IType> types1 = it1.next();
final Set<IType> types2 = it2.next();
for (IType type1 : types1) {
boolean isEquals = false;
for (IType type2 : types2) {
if (type2.equals(type1)) {
isEquals = true;
break;
}
}
if (!isEquals) {
result = false;
break;
}
}
}
} else {
Expand All @@ -141,20 +151,29 @@ public boolean isEqualParameterTypes(IReadOnlyQueryEnvironment queryEnvironment,

public boolean isLowerOrEqualParameterTypes(IReadOnlyQueryEnvironment queryEnvironment,
IService<?> service) {
final List<IType> paramTypes1 = getParameterTypes(queryEnvironment);
final List<IType> paramTypes2 = service.getParameterTypes(queryEnvironment);
final List<Set<IType>> paramTypes1 = getParameterTypes(queryEnvironment);
final List<Set<IType>> paramTypes2 = service.getParameterTypes(queryEnvironment);
boolean result;

if (paramTypes1.size() == paramTypes2.size()) {
final Iterator<IType> it1 = paramTypes1.iterator();
final Iterator<IType> it2 = paramTypes2.iterator();
final Iterator<Set<IType>> it1 = paramTypes1.iterator();
final Iterator<Set<IType>> it2 = paramTypes2.iterator();
result = true;
while (it1.hasNext()) {
IType paramType1 = it1.next();
IType paramType2 = it2.next();
if (!paramType2.isAssignableFrom(paramType1)) {
result = false;
break;
final Set<IType> types1 = it1.next();
final Set<IType> types2 = it2.next();
for (IType paramType1 : types1) {
boolean isAssignable = false;
for (IType paramType2 : types2) {
if (paramType2.isAssignableFrom(paramType1)) {
isAssignable = true;
break;
}
}
if (!isAssignable) {
result = false;
break;
}
}
}
} else {
Expand All @@ -169,11 +188,20 @@ public boolean matches(IReadOnlyQueryEnvironment queryEnvironment, IType[] argum

boolean result = true;

final List<IType> parameterTypes = getParameterTypes(queryEnvironment);
final List<Set<IType>> parameterTypes = getParameterTypes(queryEnvironment);
for (int i = 0; i < parameterTypes.size() && result; i++) {
if (argumentTypes[i].getType() != null && !parameterTypes.get(i).isAssignableFrom(
argumentTypes[i])) {
result = false;
if (argumentTypes[i].getType() != null) {
boolean oneAssignable = false;
for (IType parameterType : parameterTypes.get(i)) {
if (parameterType.isAssignableFrom(argumentTypes[i])) {
oneAssignable = true;
break;
}
}
if (!oneAssignable) {
result = false;
break;
}
}
}
return result;
Expand Down Expand Up @@ -244,18 +272,43 @@ protected String serviceShortSignature(Object[] argumentTypes) {
} else {
first = false;
}
if (argType instanceof Class<?>) {
builder.append(((Class<?>)argType).getCanonicalName());
} else if (argType instanceof EClass) {
builder.append("EClass=" + ((EClass)argType).getName());
} else if (argType == null) {
builder.append("Object=null");
builder.append(getTypeString(argType));
}
return builder.append(')').toString();
}

/**
* Gets the {@link String} representation of the given type {@link Object}.
*
* @param argType
* the type {@link Object}
* @return the {@link String} representation of the given type {@link Object}
*/
private String getTypeString(Object argType) {
final String res;

if (argType instanceof Set<?>) {
if (((Set<?>)argType).size() > 1) {
final StringJoiner joiner = new StringJoiner(" | ");
for (Object type : (Set<?>)argType) {
joiner.add(getTypeString(type));
}
res = joiner.toString();
} else {
// should not happen
builder.append("Object=" + argType.toString());
res = getTypeString(((Set<?>)argType).iterator().next());
}
} else if (argType instanceof Class<?>) {
res = ((Class<?>)argType).getCanonicalName();
} else if (argType instanceof EClass) {
res = "EClass=" + ((EClass)argType).getName();
} else if (argType == null) {
res = "Object=null";
} else {
// should not happen
res = "Object=" + argType.toString();
}
return builder.append(')').toString();

return res;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2016, 2023 Obeo.
* Copyright (c) 2016, 2024 Obeo.
* 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
Expand All @@ -14,6 +14,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
Expand Down Expand Up @@ -117,16 +118,17 @@ public String getName() {
}

@Override
public List<IType> computeParameterTypes(IReadOnlyQueryEnvironment queryEnvironment) {
final List<IType> result = new ArrayList<IType>();
public List<Set<IType>> computeParameterTypes(IReadOnlyQueryEnvironment queryEnvironment) {
final List<Set<IType>> result = new ArrayList<>();

result.add(new EClassifierType(queryEnvironment, getOrigin().getEContainingClass()));
result.add(Collections.singleton(new EClassifierType(queryEnvironment, getOrigin()
.getEContainingClass())));
for (EParameter parameter : getOrigin().getEParameters()) {
final EClassifierType rawType = new EClassifierType(queryEnvironment, parameter.getEType());
if (parameter.isMany()) {
result.add(new SequenceType(queryEnvironment, rawType));
result.add(Collections.singleton(new SequenceType(queryEnvironment, rawType)));
} else {
result.add(rawType);
result.add(Collections.singleton(rawType));
}
}

Expand Down Expand Up @@ -306,8 +308,8 @@ public boolean matches(IReadOnlyQueryEnvironment queryEnvironment, IType[] argum

@Override
public String getShortSignature() {
final List<IType> parameterTypes = getParameterTypes(null);
final IType[] argumentTypes = parameterTypes.toArray(new IType[parameterTypes.size()]);
final List<Set<IType>> parameterTypes = getParameterTypes(null);
final Object[] argumentTypes = parameterTypes.toArray(new Object[parameterTypes.size()]);

return serviceShortSignature(argumentTypes);
}
Expand Down

0 comments on commit 9c7aa15

Please sign in to comment.