Skip to content

Commit

Permalink
fixes #226: Autocomplete on suite parameters still doesn't work...
Browse files Browse the repository at this point in the history
...if suite is defined in other than current file.

Autocomplete now works, and also evaluates documentation comments
(@param and @Result fields), displaying them alongside the name in the
list.

This commit also introduces a validation, limiting each suite parameter
and result to only be used once in each suite invocation (duplicate
check).
  • Loading branch information
S1artie committed Feb 22, 2019
1 parent 07c21b4 commit 8b30896
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import de.gebit.integrity.dsl.SuiteDefinition;
import de.gebit.integrity.dsl.SuiteParameter;
import de.gebit.integrity.dsl.SuiteParameterDefinition;
import de.gebit.integrity.dsl.SuiteReturn;
import de.gebit.integrity.dsl.SuiteReturnDefinition;
import de.gebit.integrity.dsl.TableTest;
import de.gebit.integrity.dsl.TableTestRow;
Expand Down Expand Up @@ -98,6 +99,8 @@
import de.gebit.integrity.utils.JavaTypeUtil;
import de.gebit.integrity.utils.ParamAnnotationTypeTriplet;
import de.gebit.integrity.utils.ParameterUtil.UnresolvableVariableException;
import de.gebit.integrity.utils.ParsedDocumentationComment;
import de.gebit.integrity.utils.ParsedDocumentationComment.ParseException;
import de.gebit.integrity.utils.ResultFieldTuple;

/**
Expand Down Expand Up @@ -149,9 +152,9 @@ protected ConfigurableCompletionProposal doCreateProposal(String aProposal, Styl
Image anImage, int aPriority, ContentAssistContext aContext) {
int tempReplacementOffset = aContext.getReplaceRegion().getOffset();
int tempReplacementLength = aContext.getReplaceRegion().getLength();
ConfigurableCompletionProposal tempResult = new IntegrityConfigurableCompletionProposal(aProposal,
tempReplacementOffset, tempReplacementLength, aProposal.length(), anImage, aDisplayString, null,
aContext);
ConfigurableCompletionProposal tempResult
= new IntegrityConfigurableCompletionProposal(aProposal, tempReplacementOffset, tempReplacementLength,
aProposal.length(), anImage, aDisplayString, null, aContext);
tempResult.setPriority(aPriority);
tempResult.setMatcher(aContext.getMatcher());
tempResult.setReplaceContextLength(aContext.getReplaceContextLength());
Expand Down Expand Up @@ -404,8 +407,8 @@ private void completeParametersInternal(Set<String> someAlreadyUsedParameters, M
List<ParamAnnotationTypeTriplet> tempParamList = IntegrityDSLUtil.getAllParamNamesFromFixtureMethod(aMethod);
for (ParamAnnotationTypeTriplet tempParam : tempParamList) {
if (!someAlreadyUsedParameters.contains(tempParam.getParamName())) {
String tempJavadocDescription = tempJavadocMap != null
? tempJavadocMap.get(tempParam.getJavaParamName()) : null;
String tempJavadocDescription
= tempJavadocMap != null ? tempJavadocMap.get(tempParam.getJavaParamName()) : null;
String tempDisplayText = null;
if (tempJavadocDescription != null) {
tempDisplayText = tempParam.getParamName() + ": " + tempJavadocDescription;
Expand Down Expand Up @@ -513,8 +516,8 @@ private void completeArbitraryParameterOrResultNameInternal(EObject aModel, Cont
IType tempJDTType = resolveJDTTypeForJvmType(tempMethodReference.getType());
FixtureTypeWrapper tempFixtureClassWrapper = wrapType(tempJDTType);

ArbitraryParameterEnumerator tempEnumerator = tempFixtureClassWrapper
.instantiateArbitraryParameterEnumerator();
ArbitraryParameterEnumerator tempEnumerator
= tempFixtureClassWrapper.instantiateArbitraryParameterEnumerator();
if (tempEnumerator != null) {
resolveVariables(tempParameterMap);

Expand All @@ -540,7 +543,8 @@ private void completeArbitraryParameterOrResultNameInternal(EObject aModel, Cont
String tempPrefix = aPrefixPlusSignFlag ? "+" : "";
String tempSuffix = (aModel instanceof TableTest) ? ""
: (tempParameterDescription.getSuffix() != null
? tempParameterDescription.getSuffix().getText() : ": ");
? tempParameterDescription.getSuffix().getText()
: ": ");
if (!(aModel instanceof TableTest)
&& tempParameterDescription.isNestedObjectParam()) {
tempSuffix += "{}";
Expand All @@ -567,7 +571,8 @@ private void completeArbitraryParameterOrResultNameInternal(EObject aModel, Cont
}
String tempPrefix = aPrefixPlusSignFlag ? "+" : "";
String tempSuffix = tempResultDescription.getSuffix() != null
? tempResultDescription.getSuffix().getText() : " = ";
? tempResultDescription.getSuffix().getText()
: " = ";
if (tempResultDescription.isNestedObjectParam()) {
tempSuffix += "{}";
}
Expand All @@ -593,8 +598,8 @@ private void completeArbitraryParameterOrResultNameInternal(EObject aModel, Cont
if (tempParameterDescriptions != null) {
for (ArbitraryParameterDefinition tempParameterDescription : tempParameterDescriptions) {
if (tempParameterDescription.hasSubdefinitions()) {
ArbitraryParameterDefinition tempDefinition = tempParameterDescription
.getSubdefinitionByPath(aParameterPath);
ArbitraryParameterDefinition tempDefinition
= tempParameterDescription.getSubdefinitionByPath(aParameterPath);
if (tempDefinition != null && tempDefinition.hasSubdefinitions()) {
for (ArbitraryParameterDefinition tempSubdefinition : tempDefinition
.getSubdefinitions()) {
Expand Down Expand Up @@ -704,20 +709,20 @@ private void completeKeyValuePairInternal(EObject aModel, ContentAssistContext a
.findTypeByName(tempMethodReference.getMethod().getReturnType().getQualifiedName());
} else {
// First, search for parameters...
List<ParamAnnotationTypeTriplet> tempParamList = IntegrityDSLUtil
.getAllParamNamesFromFixtureMethod(tempMethodReference);
List<ParamAnnotationTypeTriplet> tempParamList
= IntegrityDSLUtil.getAllParamNamesFromFixtureMethod(tempMethodReference);
for (ParamAnnotationTypeTriplet tempPossibleParam : tempParamList) {
if (tempParamName.equals(tempPossibleParam.getParamName())) {
if (tempPossibleParam != null && tempPossibleParam.getType() != null
&& tempPossibleParam.getType().getType() != null) {
String tempQualifiedName = tempPossibleParam.getType().getType()
.getQualifiedName();
String tempQualifiedName
= tempPossibleParam.getType().getType().getQualifiedName();
// The qualified name can contain brackets here if it is an array. We don't care
// for arrays for the purpose of proposal providing, so we strip the array
// brackets.
if (tempQualifiedName.endsWith("[]")) {
tempQualifiedName = tempQualifiedName.substring(0,
tempQualifiedName.length() - 2);
tempQualifiedName
= tempQualifiedName.substring(0, tempQualifiedName.length() - 2);
}

tempRootType = IntegrityDSLUIUtil.findTypeByName(tempQualifiedName);
Expand All @@ -728,8 +733,8 @@ private void completeKeyValuePairInternal(EObject aModel, ContentAssistContext a

if (tempRootType == null) {
// If nothing was found, look into named test results
List<ResultFieldTuple> tempResultList = IntegrityDSLUtil
.getAllResultNamesFromFixtureMethod(tempMethodReference);
List<ResultFieldTuple> tempResultList
= IntegrityDSLUtil.getAllResultNamesFromFixtureMethod(tempMethodReference);
for (ResultFieldTuple tempPossibleResult : tempResultList) {
if (tempParamName.equals(tempPossibleResult.getResultName())) {
if (tempPossibleResult != null && tempPossibleResult.getField() != null) {
Expand Down Expand Up @@ -759,8 +764,8 @@ private void completeKeyValuePairInternal(EObject aModel, ContentAssistContext a
ResolvedTypeName tempResolvedTypeName = IntegrityDSLUIUtil
.getResolvedTypeName(tempField.getTypeSignature(), tempTypeInFocus);
if (tempResolvedTypeName.getGenericParameterTypes() == null) {
tempTypeInFocus = IntegrityDSLUIUtil
.findTypeByName(tempResolvedTypeName.getRawType());
tempTypeInFocus
= IntegrityDSLUIUtil.findTypeByName(tempResolvedTypeName.getRawType());
} else {
// We support 1 single generic parameter only here, since that's enough to deal
// with the also-supported collections like List<Integer> or Set<Boolean>
Expand Down Expand Up @@ -1083,8 +1088,8 @@ public void completeTableTestRow_Values(EObject aModel, Assignment anAssignment,
IType tempJDTType = resolveJDTTypeForJvmType(tempMethod.getType());
FixtureTypeWrapper tempFixtureClassWrapper = wrapType(tempJDTType);

tempConvertedResultValue = tempFixtureClassWrapper
.convertResultValueToFixtureDefinedType(
tempConvertedResultValue
= tempFixtureClassWrapper.convertResultValueToFixtureDefinedType(
tempMethod.getMethod().getSimpleName(), tempResultName,
tempResultValue);

Expand Down Expand Up @@ -1153,53 +1158,102 @@ public void completeParameterTableValue_Value(EObject aModel, Assignment anAssig
}
}

/**
* The suite result priority, relative to the default priority. Results should be higher prioritized than the
* default, so they appear on top of the list when autocompleting suite calls.
*/
protected static final int SUITE_RESULT_PRIORITY = 1;

/**
* The suite parameter property, relative to the default priority. Parameters must be placed before results, so they
* must be even higher prioritized.
*/
protected static final int SUITE_PARAMETER_PRIORITY = SUITE_RESULT_PRIORITY + 1;

@Override
// SUPPRESS CHECKSTYLE MethodName
public void completeSuiteParameter_Name(EObject aModel, Assignment anAssignment,
final ContentAssistContext aContext, final ICompletionProposalAcceptor anAcceptor) {
// filter out everything except suite parameters of the suite that is currently being called
super.completeSuiteParameter_Name(aModel, anAssignment, aContext, new ICompletionProposalAcceptor() {

@Override
public void accept(ICompletionProposal aProposal) {
if (aContext.getCurrentModel() instanceof Suite) {
Suite tempCurrentSuiteCall = (Suite) aContext.getCurrentModel();
SuiteDefinition tempCurrentSuiteDef = (tempCurrentSuiteCall).getDefinition();
if (aProposal instanceof IntegrityConfigurableCompletionProposal) {
SuiteDefinition tempSuiteDef = ((IntegrityConfigurableCompletionProposal) aProposal)
.getSuiteDefiningProposedParameter();
if (tempSuiteDef == tempCurrentSuiteDef) {
ConfigurableCompletionProposal tempProposal = (ConfigurableCompletionProposal) aProposal;

// now filter out the ones that are already present in the call
boolean tempAlreadyUsed = false;
for (SuiteParameter tempAlreadyUsedParam : tempCurrentSuiteCall.getParameters()) {
if (tempProposal.getReplacementString()
.equals(tempAlreadyUsedParam.getName().getName())) {
tempAlreadyUsed = true;
break;
}
}
if (!tempAlreadyUsed) {
tempProposal.setReplacementString(tempProposal.getReplacementString() + ": ");
if (aModel instanceof Suite) {
SuiteDefinition tempSuiteDef = ((Suite) aModel).getDefinition();
if (tempSuiteDef != null) {
for (SuiteParameterDefinition tempParam : tempSuiteDef.getParameters()) {
if (((Suite) aModel).getParameters().stream().map(SuiteParameter::getName)
.anyMatch(aName -> aName == tempParam.getName())) {
// Parameter already given -> skip for proposal purposes
continue;
}

// For some reason, Xtext doesn't get the cursor positions quite right on these
// proposals, so we calculate them manually here
tempProposal.setCursorPosition(tempProposal.getReplacementString().length());
ParsedDocumentationComment tempDoc = null;
if (tempSuiteDef.getDocumentation() != null) {
try {
tempDoc = new ParsedDocumentationComment(tempSuiteDef.getDocumentation(), null);
} catch (ParseException exc) {
// ignore if this fails, there's just no documentation then
}
}

anAcceptor.accept(aProposal);
}
String tempProposalText = tempParam.getName().getName() + ": ";
String tempProposalDisplayText = tempProposalText;
if (tempDoc != null) {
String tempParamDoc
= tempDoc.getParameterDocumentationTexts().get(tempParam.getName().getName());
if (tempParamDoc != null) {
tempProposalDisplayText = tempProposalDisplayText + tempParamDoc;
}
}

ICompletionProposal tempProposal
= createCompletionProposal(tempProposalText, new StyledString(tempProposalDisplayText),
null, getPriorityHelper().getDefaultPriority() + SUITE_PARAMETER_PRIORITY,
aContext.getPrefix(), aContext);
anAcceptor.accept(tempProposal);
}
}
}
}

@Override
public boolean canAcceptMoreProposals() {
return anAcceptor.canAcceptMoreProposals();
}
@Override
// SUPPRESS CHECKSTYLE MethodName
public void completeSuiteReturn_Name(EObject aModel, Assignment anAssignment, final ContentAssistContext aContext,
final ICompletionProposalAcceptor anAcceptor) {
if (aModel instanceof Suite) {
SuiteDefinition tempSuiteDef = ((Suite) aModel).getDefinition();
if (tempSuiteDef != null) {
for (SuiteReturnDefinition tempReturn : tempSuiteDef.getReturn()) {
if (((Suite) aModel).getReturn().stream().map(SuiteReturn::getName)
.anyMatch(aName -> aName == tempReturn.getName())) {
// Result already given -> skip for proposal purposes
continue;
}

});
ParsedDocumentationComment tempDoc = null;
if (tempSuiteDef.getDocumentation() != null) {
try {
tempDoc = new ParsedDocumentationComment(tempSuiteDef.getDocumentation(), null);
} catch (ParseException exc) {
// ignore if this fails, there's just no documentation then
}
}

String tempProposalText = tempReturn.getName().getName() + " -> ";
String tempProposalDisplayText = tempProposalText;
if (tempDoc != null) {
String tempReturnDoc
= tempDoc.getResultDocumentationTexts().get(tempReturn.getName().getName());
if (tempReturnDoc != null) {
tempProposalDisplayText = tempProposalDisplayText + tempReturnDoc;
}
}

ICompletionProposal tempProposal
= createCompletionProposal(tempProposalText, new StyledString(tempProposalDisplayText),
null, getPriorityHelper().getDefaultPriority() + SUITE_RESULT_PRIORITY,
aContext.getPrefix(), aContext);
anAcceptor.accept(tempProposal);
}
}
}
}

@Override
Expand All @@ -1220,8 +1274,9 @@ public void accept(ICompletionProposal aProposal) {

if (tempRef.eContainer() instanceof TestDefinition) {
if (aProposal instanceof IntegrityConfigurableCompletionProposal) {
JvmOperation tempOperation = (JvmOperation) ((IntegrityConfigurableCompletionProposal) aProposal)
.getAdditionalProposalInfoObject();
JvmOperation tempOperation
= (JvmOperation) ((IntegrityConfigurableCompletionProposal) aProposal)
.getAdditionalProposalInfoObject();
JvmTypeReference tempReturnType = tempOperation.getReturnType();
if (tempReturnType != null && tempReturnType.getType() instanceof JvmVoid) {
// This is a reference to a method which returns nothing. Filter these out!
Expand All @@ -1237,25 +1292,6 @@ public void accept(ICompletionProposal aProposal) {
});
}

@Override
// SUPPRESS CHECKSTYLE MethodName
public void completeSuiteReturn_Name(EObject aModel, Assignment anAssignment, final ContentAssistContext aContext,
final ICompletionProposalAcceptor anAcceptor) {
super.completeSuiteReturn_Name(aModel, anAssignment, aContext, new ICompletionProposalAcceptor() {

@Override
public void accept(ICompletionProposal aProposal) {
anAcceptor.accept(aProposal);
}

@Override
public boolean canAcceptMoreProposals() {
return anAcceptor.canAcceptMoreProposals();
}

});
}

@Override
public void completeDocumentationComment_Content(EObject aModel, Assignment anAssignment,
ContentAssistContext aContext, ICompletionProposalAcceptor anAcceptor) {
Expand Down Expand Up @@ -1394,9 +1430,9 @@ private void completeParameterValuesInternal(ParameterName aParameter, MethodRef
tempFixtureClassWrapper.convertParameterValuesToFixtureDefinedTypes(aMethod.getMethod().getSimpleName(),
aParamMap, aParameterPath, true);

List<CustomProposalDefinition> tempProposals = tempProposalProvider.defineParameterProposals(
aMethod.getMethod().getSimpleName(),
IntegrityDSLUtil.getParamNameStringFromParameterName(aParameter), aParamMap);
List<CustomProposalDefinition> tempProposals
= tempProposalProvider.defineParameterProposals(aMethod.getMethod().getSimpleName(),
IntegrityDSLUtil.getParamNameStringFromParameterName(aParameter), aParamMap);

acceptCustomProposals(tempProposals, aContext, anAcceptor);
} catch (JavaModelException exc) {
Expand Down
Loading

0 comments on commit 8b30896

Please sign in to comment.