blob: 1d81aff43f95386569f85237a4c168a3bf30654d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2019 Nicolaj Hoess.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Nicolaj Hoess - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.corext.template.java;
import java.util.List;
import org.eclipse.jdt.internal.ui.text.template.contentassist.MultiVariable;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.templates.TemplateContext;
import org.eclipse.jface.text.templates.TemplateVariable;
import org.eclipse.jface.text.templates.TemplateVariableResolver;
import org.eclipse.text.edits.TextEdit;
public class NewFieldResolver extends TemplateVariableResolver {
private static final String ASSIGNMENT_OPERATOR= "="; //$NON-NLS-1$
private static final int IS_PUBLIC_ARG= 1;
private static final boolean IS_PUBLIC_DEFAULT_VALUE= false;
private static final int IS_FORCE_STATIC_ARG= 2;
private static final boolean IS_FORCE_STATIC_DEFAULT_VALUE= false;
private static final int IS_FINAL_FIELD_ARG= 3;
private static final boolean IS_FINAL_FIELD_DEFAULT_VALUE= false;
private static final int INIT_VALUE_ARG= 4;
private static final boolean INIT_VALUE_DEFAULT_VALUE= false;
private final String defaultType;
public NewFieldResolver() {
this("java.lang.Object"); //$NON-NLS-1$
}
NewFieldResolver(String defaultType) {
this.defaultType= defaultType;
}
private int findAbsolutePositionOfFieldNameBeginning(IDocument doc, TextEdit te, String name) {
try {
String temp= doc.get(te.getOffset(), te.getLength());
if (temp.contains(ASSIGNMENT_OPERATOR)) {
temp= temp.substring(0, temp.indexOf(ASSIGNMENT_OPERATOR));
}
int nameOcc= temp.lastIndexOf(name);
if (nameOcc != -1) {
return te.getOffset() + nameOcc;
}
// Variable name not included
// Let's see if we can determine the position with some basic logic
// This case should not happen but maybe it's not bad to have a fallback
int offset= temp.length();
boolean semicolonFound= false;
while (offset >= 0 && semicolonFound == false) {
if (temp.charAt(offset) == ' ' && semicolonFound)
return te.getOffset() + offset;
if (temp.charAt(offset) == ';')
semicolonFound= true;
}
} catch (BadLocationException e) {
// continue
}
return te.getOffset();
}
/*
* @see org.eclipse.jface.text.templates.TemplateVariableResolver#resolve(org.eclipse.jface.text.templates.TemplateVariable, org.eclipse.jface.text.templates.TemplateContext)
*/
@Override
public void resolve(TemplateVariable variable, TemplateContext context) {
List<String> params= variable.getVariableType().getParams();
String param;
if (params.size() == 0)
param= defaultType;
else
param= params.get(0);
JavaPostfixContext jc= (JavaPostfixContext) context;
TemplateVariable ref= jc.getTemplateVariable(param);
MultiVariable mv= (MultiVariable) variable;
String type= param;
if (ref instanceof MultiVariable) {
// Reference is another variable
JavaVariable refVar= (JavaVariable) ref;
jc.addDependency(refVar, mv);
type= refVar.getParamType();
}
boolean publicField= getParamValue(params, IS_PUBLIC_ARG, IS_PUBLIC_DEFAULT_VALUE);
boolean forceStatic= getParamValue(params, IS_FORCE_STATIC_ARG, IS_FORCE_STATIC_DEFAULT_VALUE);
boolean finalField= getParamValue(params, IS_FINAL_FIELD_ARG, IS_FINAL_FIELD_DEFAULT_VALUE);
boolean initValue= getParamValue(params, INIT_VALUE_ARG, INIT_VALUE_DEFAULT_VALUE);
String newType= type;
String[] names= jc.suggestFieldName(newType, finalField, forceStatic);
mv.setChoices(names);
TextEdit te= jc.addField(newType, names[0], publicField, forceStatic, finalField, (initValue && ref instanceof JavaVariable) ? getValueFromVariable((JavaVariable) ref) : null);
if (te != null) {
jc.markAsUsed(names[0]);
// We can apply it to the context
jc.applyTextEdit(te);
mv.setResolved(true);
jc.registerOutOfRangeOffset(mv, findAbsolutePositionOfFieldNameBeginning(jc.getDocument(), te, names[0]) - jc.getAffectedSourceRegion().getOffset());
} else {
// Field was not created so doing nothing probably is the only option
}
}
private boolean getParamValue(List<String> params, int paramPos, boolean defaultValue) {
if (params.size() >= paramPos + 1) {
String val= params.get(paramPos);
return Boolean.parseBoolean(val);
}
return defaultValue;
}
private String getValueFromVariable(JavaVariable var) {
for (String s : var.getValues()) {
if (s != null && s.trim().length() > 0) {
return s;
}
}
return null;
}
}