blob: bcaf0b02fe421f63ad6270a1f32cc4c101733527 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2020 Obeo.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.acceleo.aql.outline;
import org.eclipse.acceleo.ASTNode;
import org.eclipse.acceleo.Metamodel;
import org.eclipse.acceleo.Query;
import org.eclipse.acceleo.Template;
import org.eclipse.acceleo.Variable;
import org.eclipse.acceleo.aql.validation.AcceleoValidationUtils;
import org.eclipse.acceleo.aql.validation.IAcceleoValidationResult;
import org.eclipse.acceleo.util.AcceleoSwitch;
/**
* An {@link AcceleoSwitch} to produce the 'main' {@link AcceleoSymbol} representing an element from the AST
* of an Acceleo module.
*
* @author Florent Latombe
*/
public class AcceleoAstOutliner extends AcceleoSwitch<AcceleoSymbol> {
/**
* The {@link IAcceleoValidationResult}.
*/
private final IAcceleoValidationResult acceleoValidationResult;
/**
* Constructor.
*
* @param acceleoValidationResult
* the {@link IAcceleoValidationResult} resulting from validating the Acceleo contents of the
* elements we want to outline.
*/
public AcceleoAstOutliner(IAcceleoValidationResult acceleoValidationResult) {
this.acceleoValidationResult = acceleoValidationResult;
}
/**
* Creates a new {@link AcceleoSymbol} based on the known {@link IAcceleoValidationResult}.
*
* @param semanticElement
* the (non-{@code null}) {@link ASTNode} represented by the created symbol.
* @param symbolName
* the (non-{@code null}) name of the created symbol.
* @param symbolDetails
* the (maybe-{@code null}) additional details of the symbol.
* @return the newly-created non-{@code null} {@link AcceleoSymbol}.
*/
private AcceleoSymbol createSymbol(ASTNode semanticElement, String symbolName, String symbolDetails) {
return new AcceleoSymbol(semanticElement, this.acceleoValidationResult, symbolName, symbolDetails);
}
/**
* For a {@link Metamodel}, the symbol displays the namespace URI.
*
* @see org.eclipse.acceleo.util.AcceleoSwitch#caseMetamodel(org.eclipse.acceleo.Metamodel)
*/
@Override
public AcceleoSymbol caseMetamodel(Metamodel metamodel) {
String details = metamodel.getReferencedPackage().getNsURI();
return this.createSymbol(metamodel, metamodel.getReferencedPackage().getName(), details);
}
/**
* For a {@link Query}, the symbol displays the types of the parameters, the return type, and has children
* to represent the parameters (name and type).
*
* @see org.eclipse.acceleo.util.AcceleoSwitch#caseQuery(org.eclipse.acceleo.Query)
*/
@Override
public AcceleoSymbol caseQuery(Query query) {
final AcceleoSymbol res;
// Symbol name: "QueryName(TypeOfParameter1, TypeOfParameter2)"
String symbolName = query.getName();
if (!query.getParameters().isEmpty()) {
symbolName += "(";
symbolName += AcceleoValidationUtils.getVariablesListRepresentation(query.getParameters(),
this.acceleoValidationResult);
symbolName += ")";
}
// Symbol details: return type.
String symbolDetails = AcceleoValidationUtils.getPossibleTypesRepresentation(query,
this.acceleoValidationResult);
if (symbolName != null) {
AcceleoSymbol symbolForQuery = this.createSymbol(query, symbolName, symbolDetails);
// Children represent the parameters of the query.
for (Variable parameter : query.getParameters()) {
AcceleoSymbol symbolForParameter = this.doSwitch(parameter);
symbolForQuery.getChildren().add(symbolForParameter);
}
res = symbolForQuery;
} else {
res = null;
}
return res;
}
/**
* For a {@link Variable}, the symbol displays the name and type.
*
* @see org.eclipse.acceleo.util.AcceleoSwitch#caseVariable(org.eclipse.acceleo.Variable)
*/
@Override
public AcceleoSymbol caseVariable(Variable variable) {
String symbolName = variable.getName();
String symbolDetails = AcceleoValidationUtils.getPossibleTypesRepresentation(variable,
this.acceleoValidationResult);
AcceleoSymbol symbolForVariable = this.createSymbol(variable, symbolName, symbolDetails);
return symbolForVariable;
}
/**
* For a {@link Template}, the symbol displays the types of the parameters, the return type (String), and
* has children to represent the parameters (name and type) and the blocks of its body (if, for, etc.).
*
* @see org.eclipse.acceleo.util.AcceleoSwitch#caseTemplate(org.eclipse.acceleo.Template)
*/
@Override
public AcceleoSymbol caseTemplate(Template template) {
final AcceleoSymbol res;
// Symbol name: "TemplateName(TypeOfParameter1, TypeOfParameter2)"
String symbolName = template.getName();
if (!template.getParameters().isEmpty()) {
symbolName += "(";
symbolName += AcceleoValidationUtils.getVariablesListRepresentation(template.getParameters(),
this.acceleoValidationResult);
symbolName += ")";
}
// Symbol details: return type.
String symbolDetails = "String";
if (symbolName != null) {
AcceleoSymbol symbolForTemplate = this.createSymbol(template, symbolName, symbolDetails);
// Children for the parameters.
for (Variable parameter : template.getParameters()) {
AcceleoSymbol symbolForParameter = this.doSwitch(parameter);
symbolForTemplate.getChildren().add(symbolForParameter);
}
// TODO: complete this if we want the Outline View to have the same information as in Acceleo 3.
// i.e. have file/if/for/protected statements appear as children of the template they are in.
// Block bodyBlock = template.getBody();
// if (bodyBlock != null) {
// AcceleoSymbol symbolForBody = this.createSymbol(bodyBlock, "Template Body", "");
// symbolForTemplate.getChildren().add(symbolForBody);
// bodyBlock.getStatements().forEach(bodyStatement -> {
// symbolForBody.getChildren().add(this.doSwitch(bodyStatement));
// // TODO: implement cases for let, for, if, etc.
// });
// }
res = symbolForTemplate;
} else {
res = null;
}
return res;
}
}