/*******************************************************************************
* Copyright (c) 2013 Rene Schneider, GEBIT Solutions GmbH and others.
* 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
*******************************************************************************/
/*
* generated by Xtext
*/
package de.gebit.integrity.scoping;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.common.types.JvmAnnotationReference;
import org.eclipse.xtext.common.types.JvmEnumerationLiteral;
import org.eclipse.xtext.common.types.JvmField;
import org.eclipse.xtext.common.types.JvmGenericType;
import org.eclipse.xtext.common.types.JvmMember;
import org.eclipse.xtext.common.types.JvmOperation;
import org.eclipse.xtext.common.types.JvmType;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.JvmVisibility;
import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.EObjectDescription;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
import org.eclipse.xtext.scoping.impl.FilteringScope;
import org.eclipse.xtext.scoping.impl.SimpleScope;
import com.google.common.base.Predicate;
import com.google.inject.Inject;
import de.gebit.integrity.dsl.Call;
import de.gebit.integrity.dsl.ConstantDefinition;
import de.gebit.integrity.dsl.ConstantEntity;
import de.gebit.integrity.dsl.DslPackage;
import de.gebit.integrity.dsl.FixedParameterName;
import de.gebit.integrity.dsl.FixedResultName;
import de.gebit.integrity.dsl.ForkDefinition;
import de.gebit.integrity.dsl.ForkParameter;
import de.gebit.integrity.dsl.JavaConstantReference;
import de.gebit.integrity.dsl.MethodReference;
import de.gebit.integrity.dsl.Model;
import de.gebit.integrity.dsl.NamedResult;
import de.gebit.integrity.dsl.PackageDefinition;
import de.gebit.integrity.dsl.PackageStatement;
import de.gebit.integrity.dsl.Parameter;
import de.gebit.integrity.dsl.ParameterName;
import de.gebit.integrity.dsl.ParameterTableHeader;
import de.gebit.integrity.dsl.ParameterTableValue;
import de.gebit.integrity.dsl.ResultName;
import de.gebit.integrity.dsl.ResultTableHeader;
import de.gebit.integrity.dsl.Statement;
import de.gebit.integrity.dsl.Suite;
import de.gebit.integrity.dsl.SuiteDefinition;
import de.gebit.integrity.dsl.SuiteParameter;
import de.gebit.integrity.dsl.SuiteReturnDefinition;
import de.gebit.integrity.dsl.SuiteStatement;
import de.gebit.integrity.dsl.TableTest;
import de.gebit.integrity.dsl.Test;
import de.gebit.integrity.dsl.VariableDefinition;
import de.gebit.integrity.dsl.VariableEntity;
import de.gebit.integrity.dsl.VariableOrConstantEntity;
import de.gebit.integrity.fixtures.FixtureMethod;
import de.gebit.integrity.utils.IntegrityDSLUtil;
import de.gebit.integrity.utils.ParamAnnotationTypeTriplet;
import de.gebit.integrity.utils.ParameterUtil;
import de.gebit.integrity.utils.ResultFieldTuple;
/**
* This class contains custom scoping description.
*
* see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping on how and when to use it
*
* @author Rene Schneider - initial API and implementation
*
*/
public class DSLScopeProvider extends AbstractDeclarativeScopeProvider {
/**
* The qualified name converter.
*/
@Inject
private IQualifiedNameConverter qualifiedNameConverter;
/**
* Limits the fixed parameter names to those defined in a fixture method signature.
*
* @param aParameterName
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_FixedParameterName_annotation(FixedParameterName aParameterName, EReference aRef) {
MethodReference tempMethodRef = null;
if (aParameterName.eContainer() instanceof Parameter) {
Parameter tempParameter = (Parameter) aParameterName.eContainer();
if (tempParameter.eContainer() instanceof Test) {
tempMethodRef = ((Test) tempParameter.eContainer()).getDefinition().getFixtureMethod();
} else if (tempParameter.eContainer() instanceof Call) {
tempMethodRef = ((Call) tempParameter.eContainer()).getDefinition().getFixtureMethod();
} else if (tempParameter.eContainer() instanceof TableTest) {
tempMethodRef = ((TableTest) tempParameter.eContainer()).getDefinition().getFixtureMethod();
}
} else if (aParameterName.eContainer() instanceof ParameterTableHeader) {
ParameterTableHeader tempParameterHeader = (ParameterTableHeader) aParameterName.eContainer();
if (tempParameterHeader.eContainer() instanceof TableTest) {
tempMethodRef = ((TableTest) tempParameterHeader.eContainer()).getDefinition().getFixtureMethod();
}
} else if (aParameterName.eContainer() instanceof ForkParameter) {
ForkParameter tempForkParameter = (ForkParameter) aParameterName.eContainer();
ForkDefinition tempForkDef = (ForkDefinition) tempForkParameter.eContainer();
if (tempForkDef.getForkerClass() != null
&& (tempForkDef.getForkerClass().getType() instanceof JvmGenericType)) {
ArrayList<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
List<ParamAnnotationTypeTriplet> tempParamList = IntegrityDSLUtil
.getAllParamNamesFromForker((JvmGenericType) tempForkDef.getForkerClass().getType());
for (ParamAnnotationTypeTriplet tempParam : tempParamList) {
tempList.add(EObjectDescription.create(tempParam.getParamName(), tempParam.getAnnotation()));
}
return new SimpleScope(tempList);
}
}
if (tempMethodRef != null) {
ArrayList<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
List<ParamAnnotationTypeTriplet> tempParamList = IntegrityDSLUtil
.getAllParamNamesFromFixtureMethod(tempMethodRef);
for (ParamAnnotationTypeTriplet tempParam : tempParamList) {
tempList.add(EObjectDescription.create(tempParam.getParamName(), tempParam.getAnnotation()));
}
return new SimpleScope(tempList);
}
return IScope.NULLSCOPE;
}
/**
* Limits the fixture method references to actually existing methods with the necessary annotation.
*
*
* @param aMethodRef
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_MethodReference_method(MethodReference aMethodRef, EReference aRef) {
JvmType tempType = aMethodRef.getType();
List<IEObjectDescription> tempDescriptions = new ArrayList<IEObjectDescription>();
if (tempType instanceof JvmGenericType) {
JvmGenericType tempTypeInFocus = (JvmGenericType) tempType;
while (tempTypeInFocus != null) {
for (JvmMember tempMember : tempTypeInFocus.getMembers()) {
if (tempMember instanceof JvmOperation
&& ((JvmOperation) tempMember).getVisibility() == JvmVisibility.PUBLIC) {
boolean tempIsFixtureMethod = false;
for (JvmAnnotationReference tempAnnotation : tempMember.getAnnotations()) {
if (FixtureMethod.class.getName()
.equals(tempAnnotation.getAnnotation().getQualifiedName())) {
tempIsFixtureMethod = true;
break;
}
}
if (tempIsFixtureMethod) {
tempDescriptions.add(EObjectDescription.create(
QualifiedName.create(((JvmOperation) tempMember).getSimpleName()), tempMember));
}
}
}
JvmGenericType tempOldType = tempTypeInFocus;
tempTypeInFocus = null;
for (JvmTypeReference tempSuperType : tempOldType.getSuperTypes()) {
if ((tempSuperType.getType() instanceof JvmGenericType)
&& !((JvmGenericType) tempSuperType.getType()).isInterface()) {
tempTypeInFocus = (JvmGenericType) tempSuperType.getType();
break;
}
}
}
}
return new SimpleScope(tempDescriptions);
}
/**
* Limits Java constant references to "public static final" ones.
*
* @param aConstantRef
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_JavaConstantReference_constant(JavaConstantReference aConstantRef, EReference aRef) {
JvmType tempType = aConstantRef.getType();
List<IEObjectDescription> tempDescriptions = new ArrayList<IEObjectDescription>();
if (tempType instanceof JvmGenericType) {
recursivelyFindJavaConstants((JvmGenericType) tempType, tempDescriptions);
}
return new SimpleScope(tempDescriptions);
}
private void recursivelyFindJavaConstants(JvmGenericType aType, List<IEObjectDescription> someDescriptions) {
for (JvmField tempField : aType.getDeclaredFields()) {
if (!(tempField instanceof JvmEnumerationLiteral) && tempField.isStatic() && tempField.isFinal()
&& tempField.getVisibility() == JvmVisibility.PUBLIC) {
someDescriptions
.add(EObjectDescription.create(QualifiedName.create(tempField.getSimpleName()), tempField));
}
}
for (JvmTypeReference tempSuperType : aType.getSuperTypes()) {
if (tempSuperType.getType() instanceof JvmGenericType) {
recursivelyFindJavaConstants((JvmGenericType) tempSuperType.getType(), someDescriptions);
}
}
}
/**
* Limits suite parameters to actually defined parameters.
*
* @param aParameter
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_SuiteParameter_name(SuiteParameter aParameter, EReference aRef) {
SuiteDefinition tempSuiteDef = (SuiteDefinition) ((Suite) aParameter.eContainer()).getDefinition();
if (tempSuiteDef != null) {
ArrayList<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
for (VariableOrConstantEntity tempParam : ParameterUtil
.getVariableEntitiesForSuiteParameters(tempSuiteDef)) {
tempList.add(EObjectDescription.create(tempParam.getName(), tempParam));
}
return new SimpleScope(tempList);
}
return IScope.NULLSCOPE;
}
/**
* Determine valid enumeration values for the provided parameter name of the provided fixture method reference.
*
* @param aMethodRef
* @param aParameterName
* @return
*/
protected IScope determineParameterEnumValueScope(MethodReference aMethodRef, ParameterName aParameterName) {
if (aParameterName instanceof FixedParameterName) {
JvmAnnotationReference tempAnnotationRef = ((FixedParameterName) aParameterName).getAnnotation();
if (aMethodRef != null && tempAnnotationRef != null) {
ArrayList<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
List<JvmEnumerationLiteral> tempLiteralList = IntegrityDSLUtil
.getAllEnumLiteralsFromFixtureMethodParam(aMethodRef, tempAnnotationRef);
if (tempLiteralList != null) {
for (JvmEnumerationLiteral tempLiteral : tempLiteralList) {
tempList.add(EObjectDescription.create(tempLiteral.getSimpleName(), tempLiteral));
}
return new SimpleScope(tempList);
}
}
} else {
// TODO add arbitrary parameter name path
}
return IScope.NULLSCOPE;
}
/**
* Determine valid enumeration values for the default result type of the provided fixture method reference.
*
* @param aMethodRef
* @return
*/
protected IScope determineDefaultResultEnumValueScope(MethodReference aMethodRef) {
if (aMethodRef != null) {
ArrayList<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
List<JvmEnumerationLiteral> tempLiteralList = IntegrityDSLUtil
.getAllEnumLiteralsFromJvmTypeReference(aMethodRef.getMethod().getReturnType());
if (tempLiteralList != null) {
for (JvmEnumerationLiteral tempLiteral : tempLiteralList) {
tempList.add(EObjectDescription.create(tempLiteral.getSimpleName(), tempLiteral));
}
return new SimpleScope(tempList);
}
}
return IScope.NULLSCOPE;
}
/**
* Determine valid enumeration values for the default result type of the provided fixture method reference.
*
* @param aMethodRef
* @return
*/
protected IScope determineNamedResultEnumValueScope(MethodReference aMethodRef, JvmField aField) {
if (aMethodRef != null && aField != null) {
ArrayList<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
List<JvmEnumerationLiteral> tempLiteralList = IntegrityDSLUtil
.getAllEnumLiteralsFromJvmTypeReference(aField.getType());
if (tempLiteralList != null) {
for (JvmEnumerationLiteral tempLiteral : tempLiteralList) {
tempList.add(EObjectDescription.create(tempLiteral.getSimpleName(), tempLiteral));
}
return new SimpleScope(tempList);
}
}
return IScope.NULLSCOPE;
}
/**
* Limits enumeration values in parameters to actually existent enumeration literals.
*
* @param aParameter
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_EnumValue_enumValue(Parameter aParameter, EReference aRef) {
MethodReference tempMethodRef = null;
if (aParameter.eContainer() instanceof Test) {
tempMethodRef = ((Test) aParameter.eContainer()).getDefinition().getFixtureMethod();
} else if (aParameter.eContainer() instanceof Call) {
tempMethodRef = ((Call) aParameter.eContainer()).getDefinition().getFixtureMethod();
} else if (aParameter.eContainer() instanceof TableTest) {
tempMethodRef = ((TableTest) aParameter.eContainer()).getDefinition().getFixtureMethod();
}
return determineParameterEnumValueScope(tempMethodRef, aParameter.getName());
}
/**
* Lists enumeration values in tabletest parameters (which can be actual parameters or results, depending on the
* header of the column).
*
* @param aParameter
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_EnumValue_enumValue(ParameterTableValue aParameter, EReference aRef) {
MethodReference tempMethodRef = ((TableTest) aParameter.eContainer().eContainer()).getDefinition()
.getFixtureMethod();
EObject tempTableHeader = IntegrityDSLUtil.getTableHeaderForTableCell(aParameter);
if (tempTableHeader instanceof ParameterTableHeader) {
// it's a specific parameter column
return determineParameterEnumValueScope(tempMethodRef, ((ParameterTableHeader) tempTableHeader).getName());
} else if (tempTableHeader instanceof ResultTableHeader) {
// it's a named result
ResultName tempResultName = ((ResultTableHeader) tempTableHeader).getName();
if (tempResultName instanceof FixedResultName) {
return determineNamedResultEnumValueScope(tempMethodRef, ((FixedResultName) tempResultName).getField());
}
} else if (tempTableHeader instanceof TableTest) {
// it is the default result column
return determineDefaultResultEnumValueScope(tempMethodRef);
}
return IScope.NULLSCOPE;
}
/**
* Limit enum values in test results to actually existent enumeration literals.
*
* @param aTest
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_EnumValue_enumValue(Test aTest, EReference aRef) {
return determineDefaultResultEnumValueScope(aTest.getDefinition().getFixtureMethod());
}
/**
* Limit enum values in named test results to actually existent enumeration literals.
*
* @param aNamedResult
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_EnumValue_enumValue(NamedResult aNamedResult, EReference aRef) {
ResultName tempResultName = aNamedResult.getName();
if (tempResultName instanceof FixedResultName) {
if (aNamedResult.eContainer() instanceof Test) {
return determineNamedResultEnumValueScope(
((Test) aNamedResult.eContainer()).getDefinition().getFixtureMethod(),
((FixedResultName) tempResultName).getField());
}
}
return IScope.NULLSCOPE;
}
/**
* Limit named test results to actually existing fields in the result container object.
*
* @param aTest
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_FixedResultName_field(Test aTest, EReference aRef) {
MethodReference tempMethodRef = aTest.getDefinition().getFixtureMethod();
if (tempMethodRef != null) {
ArrayList<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
List<ResultFieldTuple> tempResultFields = IntegrityDSLUtil
.getAllResultNamesFromFixtureMethod(tempMethodRef);
for (ResultFieldTuple tempResultField : tempResultFields) {
tempList.add(EObjectDescription.create(tempResultField.getResultName(), tempResultField.getField()));
}
return new SimpleScope(tempList);
}
return IScope.NULLSCOPE;
}
/**
* Limit named test results to actually existing fields in the result container object.
*
* @param aCall
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_FixedResultName_field(Call aCall, EReference aRef) {
MethodReference tempMethodRef = aCall.getDefinition().getFixtureMethod();
if (tempMethodRef != null) {
ArrayList<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
List<ResultFieldTuple> tempResultFields = IntegrityDSLUtil
.getAllResultNamesFromFixtureMethod(tempMethodRef);
for (ResultFieldTuple tempResultField : tempResultFields) {
tempList.add(EObjectDescription.create(tempResultField.getResultName(), tempResultField.getField()));
}
return new SimpleScope(tempList);
}
return IScope.NULLSCOPE;
}
/**
* Limit named test results to actually existing fields in the result container object.
*
* @param aTableTest
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_FixedResultName_field(TableTest aTableTest, EReference aRef) {
MethodReference tempMethodRef = aTableTest.getDefinition().getFixtureMethod();
if (tempMethodRef != null) {
ArrayList<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
List<ResultFieldTuple> tempResultFields = IntegrityDSLUtil
.getAllResultNamesFromFixtureMethod(tempMethodRef);
for (ResultFieldTuple tempResultField : tempResultFields) {
tempList.add(EObjectDescription.create(tempResultField.getResultName(), tempResultField.getField()));
}
return new SimpleScope(tempList);
}
return IScope.NULLSCOPE;
}
/**
* Limit result variables for calls to actual variables.
*
* @param aCall
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_VariableVariable_name(Call aCall, EReference aRef) {
// fetch the host suite of the call
SuiteDefinition tempHostSuite = (SuiteDefinition) aCall.eContainer();
return determineVariableScope(aCall, tempHostSuite);
}
/**
* Prevents variables in parameters from being influenced by {@link #scope_Variable_name(Call, EReference)}, and
* filters out variables defined as suite parameters in other suites.
*
* @param aParam
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_Variable_name(Parameter aParam, EReference aRef) {
// fetch the host suite of the parameter (should be correct for calls, tabletests and tests)
SuiteDefinition tempHostSuite = (SuiteDefinition) aParam.eContainer().eContainer();
return determineVariableScope(aParam, tempHostSuite);
}
/**
* Determines variables/constants in scope for table test parameters or results.
*
* @param aTableTestRow
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_Variable_name(TableTest aTableTest, EReference aRef) {
SuiteDefinition tempHostSuite = (SuiteDefinition) aTableTest.eContainer();
return determineVariableScope(aTableTest, tempHostSuite);
}
/**
* Determines variables/constants in scope for test parameters or results.
*
* @param aTest
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_Variable_name(Test aTest, EReference aRef) {
SuiteDefinition tempHostSuite = (SuiteDefinition) aTest.eContainer();
return determineVariableScope(aTest, tempHostSuite);
}
/**
* Determines variables/constants in scope for suite parameters.
*
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_Variable_name(Suite aSuite, EReference aRef) {
SuiteDefinition tempHostSuite = (SuiteDefinition) aSuite.eContainer();
return determineVariableScope(aSuite, tempHostSuite);
}
/**
* <<<<<<< HEAD ======= Determines variables/constants in scope for variable definitions.
*
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_Variable_name(VariableDefinition aVariableDefinition, EReference aRef) {
EObject tempParent = aVariableDefinition.eContainer();
if (tempParent instanceof SuiteDefinition) {
return determineVariableScope(aVariableDefinition, (SuiteDefinition) tempParent);
} else if (tempParent instanceof PackageDefinition) {
return determineVariableScope((PackageDefinition) aVariableDefinition);
}
return null;
}
/**
* Determines variables/constants in scope for constant definitions.
*
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_Variable_name(ConstantDefinition aConstantDefinition, EReference aRef) {
EObject tempParent = aConstantDefinition.eContainer();
if (tempParent instanceof SuiteDefinition) {
return determineVariableScope(aConstantDefinition, (SuiteDefinition) tempParent);
} else if (tempParent instanceof PackageDefinition) {
return determineVariableScope((PackageDefinition) aConstantDefinition);
}
return null;
}
/**
* >>>>>>> v0.15.x_bugfix This basically performs a default import on everything in the local file by adding another
* scope entry for all suite definitions in the current file.
*
* @param aSuite
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_Suite_definition(Suite aSuite, EReference aRef) {
IScope tempScope = super.delegateGetScope(aSuite, aRef);
List<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
Model tempRootModel = IntegrityDSLUtil.findUpstreamContainer(Model.class, aSuite);
// Add definitions from current file (fully qualified and in short form, both are allowed - fully qualified was
// already added by super method, short form is now added here)
for (Statement tempStatement : tempRootModel.getStatements()) {
if (tempStatement instanceof PackageDefinition) {
for (PackageStatement tempPackageStatement : ((PackageDefinition) tempStatement).getStatements()) {
if (tempPackageStatement instanceof SuiteDefinition) {
tempList.add(EObjectDescription.create(((SuiteDefinition) tempPackageStatement).getName(),
tempPackageStatement));
}
}
}
}
return filterPrivateElements(new SimpleScope(tempScope, tempList), aSuite);
}
/**
* Filters out private forks.
*
* @param aSuite
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_Suite_fork(Suite aSuite, EReference aRef) {
IScope tempScope = super.delegateGetScope(aSuite, aRef);
List<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
Model tempRootModel = IntegrityDSLUtil.findUpstreamContainer(Model.class, aSuite);
// Add definitions from current file (fully qualified and in short form, both are allowed - fully qualified was
// already added by super method, short form is now added here)
for (Statement tempStatement : tempRootModel.getStatements()) {
if (tempStatement instanceof PackageDefinition) {
for (PackageStatement tempPackageStatement : ((PackageDefinition) tempStatement).getStatements()) {
if (tempPackageStatement instanceof ForkDefinition) {
tempList.add(EObjectDescription.create(((ForkDefinition) tempPackageStatement).getName(),
tempPackageStatement));
}
}
}
}
return filterPrivateElements(new SimpleScope(tempScope, tempList), aSuite);
}
/**
* Determines the scope of SuiteReturns.
*
* @param aSuite
* @param aRef
* @return
*/
// SUPPRESS CHECKSTYLE MethodName
public IScope scope_SuiteReturn_name(Suite aSuite, EReference aRef) {
SuiteDefinition tempSuiteDefinition = aSuite.getDefinition();
ArrayList<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
if (tempSuiteDefinition != null) {
for (SuiteReturnDefinition tempDefinition : tempSuiteDefinition.getReturn()) {
tempList.add(EObjectDescription.create(tempDefinition.getName().getName(), tempDefinition));
}
}
return new SimpleScope(tempList);
}
/**
* A small cache for visible global variables. Determining these is rather expensive, thus they're cached as long as
* only one model (file) is being scoped.
*/
private ArrayList<IEObjectDescription> cachedVisibleGlobalVariables = new ArrayList<IEObjectDescription>();
/**
* This is used to invalidate the {@link #cachedVisibleGlobalVariables}, as soon as scoping is done for a different
* model.
*/
private Model cachedVisibleGlobalVariablesResource;
private IScope addVisibleGlobalConstantsAndVariables(IScope aParentScope, EObject aStatement) {
Model tempRootModel = IntegrityDSLUtil.findUpstreamContainer(Model.class, aStatement);
ArrayList<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
if (cachedVisibleGlobalVariablesResource != tempRootModel) {
// Cache miss! Now we need to search all package vars/constants outside of the current model.
ArrayList<IEObjectDescription> tempCacheableList = new ArrayList<IEObjectDescription>();
IScope tempVariableScope = super.getScope(aStatement, DslPackage.Literals.VARIABLE_DEFINITION__NAME);
IScope tempConstantScope = super.getScope(aStatement, DslPackage.Literals.CONSTANT_DEFINITION__NAME);
for (IScope tempScope : new IScope[] { tempVariableScope, tempConstantScope }) {
for (IEObjectDescription tempVariableDefDescription : tempScope.getAllElements()) {
EObject tempVariableDef = tempVariableDefDescription.getEObjectOrProxy();
if (tempVariableDef.eIsProxy()) {
tempVariableDef = EcoreUtil.resolve(tempVariableDef, aStatement);
}
if (tempVariableDef.eContainer() != null) {
EObject tempPackageDef = tempVariableDef.eContainer().eContainer();
if (tempPackageDef instanceof PackageDefinition) {
Model tempPackageHostModel = IntegrityDSLUtil.findUpstreamContainer(Model.class,
tempPackageDef);
// Don't add definitions from current file here; they aren't cacheable and will get invalid
if (tempPackageHostModel != tempRootModel) {
tempCacheableList.add(tempVariableDefDescription);
}
}
}
}
}
cachedVisibleGlobalVariables = tempCacheableList;
cachedVisibleGlobalVariablesResource = tempRootModel;
}
tempList.addAll(cachedVisibleGlobalVariables);
// Add definitions from current file (fully qualified and in short form, both are allowed)
for (Statement tempStatement : tempRootModel.getStatements()) {
if (tempStatement instanceof PackageDefinition) {
for (PackageStatement tempPackageStatement : ((PackageDefinition) tempStatement).getStatements()) {
if (tempPackageStatement instanceof VariableDefinition) {
VariableEntity tempEntity = ((VariableDefinition) tempPackageStatement).getName();
tempList.add(EObjectDescription.create(tempEntity.getName(), tempEntity));
tempList.add(EObjectDescription.create(
qualifiedNameConverter.toQualifiedName(
IntegrityDSLUtil.getQualifiedVariableEntityName(tempEntity, false)),
tempEntity));
} else if (tempPackageStatement instanceof ConstantDefinition) {
ConstantEntity tempEntity = ((ConstantDefinition) tempPackageStatement).getName();
tempList.add(EObjectDescription.create(tempEntity.getName(), tempEntity));
tempList.add(EObjectDescription.create(
qualifiedNameConverter.toQualifiedName(
IntegrityDSLUtil.getQualifiedVariableEntityName(tempEntity, false)),
tempEntity));
}
}
}
}
// Finally, filter out private variables not in the current package
return filterPrivateElements(new SimpleScope(aParentScope, tempList), aStatement);
}
private IScope filterPrivateElements(IScope aScope, final EObject aStatement) {
PackageDefinition tempCurrentPackage = IntegrityDSLUtil.findUpstreamContainer(PackageDefinition.class,
aStatement);
final String tempCurrentPackageName = tempCurrentPackage == null ? "" : tempCurrentPackage.getName();
return new FilteringScope(aScope, new Predicate<IEObjectDescription>() {
@Override
public boolean apply(IEObjectDescription anInput) {
EObject tempObjectOrProxy = anInput.getEObjectOrProxy();
EObject tempObject;
if (tempObjectOrProxy.eIsProxy()) {
tempObject = EcoreUtil.resolve(tempObjectOrProxy, aStatement);
} else {
tempObject = tempObjectOrProxy;
}
if ((tempObject instanceof VariableEntity) || (tempObject instanceof ConstantEntity)) {
tempObject = tempObject.eContainer();
}
if (IntegrityDSLUtil.isPrivate(tempObject)) {
PackageDefinition tempPackage = IntegrityDSLUtil.findUpstreamContainer(PackageDefinition.class,
tempObject);
if (tempPackage != null) {
return tempCurrentPackageName.equals(tempPackage.getName());
} else {
return true;
}
}
return true;
}
});
}
private IScope determineVariableScope(EObject aStatement, SuiteDefinition aSuite) {
ArrayList<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
EObject tempStop = findSuiteStatementFromSubObject(aStatement);
for (SuiteStatement tempStatement : aSuite.getStatements()) {
if (tempStatement instanceof VariableDefinition) {
VariableEntity tempEntity = ((VariableDefinition) tempStatement).getName();
if (tempEntity != null) {
tempList.add(EObjectDescription.create(tempEntity.getName(), tempEntity));
}
} else if (tempStatement instanceof ConstantDefinition) {
ConstantEntity tempEntity = ((ConstantDefinition) tempStatement).getName();
if (tempEntity != null) {
tempList.add(EObjectDescription.create(tempEntity.getName(), tempEntity));
}
} else if (tempStatement == tempStop) {
break;
}
}
IScope tempScope = new SimpleScope(tempList);
// Now add global constants and variables.
tempScope = addVisibleGlobalConstantsAndVariables(tempScope, aStatement);
// And add suite parameters, which are handled like variables as well.
ArrayList<IEObjectDescription> tempSuiteParameterAndReturnList = new ArrayList<IEObjectDescription>();
for (VariableEntity tempSuiteParam : ParameterUtil.getVariableEntitiesForSuiteParameters(aSuite)) {
tempSuiteParameterAndReturnList.add(EObjectDescription.create(tempSuiteParam.getName(), tempSuiteParam));
}
// Just like suite return variables
for (SuiteReturnDefinition tempSuiteReturn : aSuite.getReturn()) {
tempSuiteParameterAndReturnList
.add(EObjectDescription.create(tempSuiteReturn.getName().getName(), tempSuiteReturn.getName()));
}
return new SimpleScope(tempScope, tempSuiteParameterAndReturnList);
}
private IScope determineVariableScope(PackageDefinition aPackageDef) {
ArrayList<IEObjectDescription> tempList = new ArrayList<IEObjectDescription>();
IScope tempScope = new SimpleScope(tempList);
// Add constants/variables defined in current package
for (PackageStatement tempStatement : aPackageDef.getStatements()) {
if (tempStatement instanceof VariableDefinition) {
VariableEntity tempEntity = ((VariableDefinition) tempStatement).getName();
if (tempEntity != null) {
tempList.add(EObjectDescription.create(tempEntity.getName(), tempEntity));
}
} else if (tempStatement instanceof ConstantDefinition) {
ConstantEntity tempEntity = ((ConstantDefinition) tempStatement).getName();
if (tempEntity != null) {
tempList.add(EObjectDescription.create(tempEntity.getName(), tempEntity));
}
}
}
// Add global constants and variables.
tempScope = addVisibleGlobalConstantsAndVariables(tempScope, aPackageDef);
return tempScope;
}
private EObject findSuiteStatementFromSubObject(EObject aSubObject) {
EObject tempObject = aSubObject.eContainer();
EObject tempParent = tempObject.eContainer();
while (tempParent != null) {
if (tempParent instanceof SuiteDefinition) {
return tempObject;
} else {
tempObject = tempParent;
tempParent = tempObject.eContainer();
}
}
return null;
}
// This is very useful for debugging scoping problems - it dumps out which declarative methods are actually
// being tried during the resolve period of a scope. REMOVE COMMENTS WITH CARE! NOT FOR CHECK-INs!
//
// @Override
// public IScope getScope(EObject aContext, EReference aReference) {
// System.out.println("Scope Request: scope_" + aReference.getEContainingClass().getName() + "_"
// + aReference.getName() + "(" + aContext.getClass().getName() + ")");
//
// return super.getScope(aContext, aReference);
// }
}