<extensions defaultExtensionNs="com.intellij">
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
- <applicationConfigurable implementation="org.intellij.images.options.impl.OptionsConfigurabe"/>
+ <applicationConfigurable instance="org.intellij.images.options.impl.OptionsConfigurabe"/>
<fileEditorProvider implementation="org.intellij.images.editor.impl.ImageFileEditorProvider"/>
<selectInTarget implementation="org.intellij.images.thumbnail.impl.ThumbnailSelectInTarget"/>
<applicationService serviceInterface="org.intellij.images.options.OptionsManager"
setModified(!options.equals(uiOptions));
}
- public static void show(Project project) {
- OptionsConfigurabe component = ShowSettingsUtil.getInstance().findApplicationConfigurable(OptionsConfigurabe.class);
- ShowSettingsUtil.getInstance().editConfigurable(project, component);
+ public static void show(Project project) {
+ final ShowSettingsUtil util = ShowSettingsUtil.getInstance();
+ util.editConfigurable(project, new OptionsConfigurabe());
}
@NonNls
public void actionPerformed(AnActionEvent e) {
Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
- ShowSettingsUtil.getInstance().editConfigurable(project, CompilerConfigurable.getInstance(project));
+ if (project == null) return;
+ final ShowSettingsUtil util = ShowSettingsUtil.getInstance();
+ util.editConfigurable(project, new CompilerConfigurable(project));
}
}
private final CompilerUIConfigurable myCompilerUIConfigurable;
private Configurable[] myKids;
- public static CompilerConfigurable getInstance(Project project) {
- return ShowSettingsUtil.getInstance().findProjectConfigurable(project, CompilerConfigurable.class);
- }
-
public CompilerConfigurable(Project project) {
myProject = project;
myCompilerUIConfigurable = new CompilerUIConfigurable(myProject);
@Override
public void visitErrorElement(PsiErrorElement element) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil
- .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", element.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", element.getText()));
}
@Override
public void visitAssignmentExpression(PsiAssignmentExpression expression) {
final PsiExpression rExpression = expression.getRExpression();
if(rExpression == null) {
- throw new EvaluateRuntimeException(
- EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText()))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())); return;
}
rExpression.accept(this);
Evaluator rEvaluator = myResult;
if(expression.getOperationSign().getTokenType() != JavaTokenType.EQ) {
- throw new EvaluateRuntimeException(
- EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.operation.not.supported", expression.getOperationSign().getText()))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.operation.not.supported", expression.getOperationSign().getText()));
}
final PsiExpression lExpression = expression.getLExpression();
final PsiType lType = lExpression.getType();
if(lType == null) {
- throw new EvaluateRuntimeException(
- EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", lExpression.getText()))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", lExpression.getText()));
}
if(!TypeConversionUtil.areTypesAssignmentCompatible(lType, rExpression)) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.incompatible.types", expression.getOperationSign().getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.incompatible.types", expression.getOperationSign().getText()));
}
lExpression.accept(this);
Evaluator lEvaluator = myResult;
@Override
public void visitStatement(PsiStatement statement) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.statement.not.supported", statement.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.statement.not.supported", statement.getText()));
}
@Override
Evaluator lResult = myResult;
final PsiExpression rOperand = expression.getROperand();
if(rOperand == null) {
- throw new EvaluateRuntimeException(
- EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText()))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())); return;
}
rOperand.accept(this);
Evaluator rResult = myResult;
IElementType opType = expression.getOperationSign().getTokenType();
PsiType expressionExpectedType = expression.getType();
if (expressionExpectedType == null) {
- throw new EvaluateRuntimeException(
- EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", expression.getText()))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", expression.getText()));
}
myResult = createBinaryEvaluator(lResult, lOperand.getType(), rResult, rOperand.getType(), opType, expressionExpectedType);
}
}
// handle '==' and '!=' separately
if (opCode == JavaTokenType.EQEQ || opCode == JavaTokenType.NE) {
- return (lType instanceof PsiPrimitiveType && rType instanceof PsiClassType) ||
- (lType instanceof PsiClassType && rType instanceof PsiPrimitiveType);
+ return lType instanceof PsiPrimitiveType && rType instanceof PsiClassType ||
+ lType instanceof PsiClassType && rType instanceof PsiPrimitiveType;
}
// all other operations at least one should be of class type
return lType instanceof PsiClassType || rType instanceof PsiClassType;
for (PsiElement declaredElement : declaredElements) {
if (declaredElement instanceof PsiLocalVariable) {
if (myCurrentFragmentEvaluator != null) {
- final PsiLocalVariable localVariable = ((PsiLocalVariable)declaredElement);
+ final PsiLocalVariable localVariable = (PsiLocalVariable)declaredElement;
final PsiType lType = localVariable.getType();
PsiExpression initializer = localVariable.getInitializer();
if (initializer != null) {
try {
- if (!TypeConversionUtil.areTypesAssignmentCompatible(localVariable.getType(), initializer)) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
- DebuggerBundle.message("evaluation.error.incompatible.variable.initializer.type", localVariable.getName())));
+ if (!TypeConversionUtil.areTypesAssignmentCompatible(lType, initializer)) {
+ throwEvaluateException(
+ DebuggerBundle.message("evaluation.error.incompatible.variable.initializer.type", localVariable.getName()));
}
final PsiType rType = initializer.getType();
initializer.accept(this);
}
}
- if(evaluators.size() > 0) {
+ if(!evaluators.isEmpty()) {
CodeFragmentEvaluator codeFragmentEvaluator = new CodeFragmentEvaluator(myCurrentFragmentEvaluator);
- codeFragmentEvaluator.setStatements(evaluators.toArray(new Evaluator[0]));
+ codeFragmentEvaluator.setStatements(evaluators.toArray(new Evaluator[evaluators.size()]));
myResult = codeFragmentEvaluator;
} else {
myResult = null;
final PsiExpression thenExpression = expression.getThenExpression();
final PsiExpression elseExpression = expression.getElseExpression();
if (thenExpression == null || elseExpression == null){
- throw new EvaluateRuntimeException(EvaluateExceptionUtil
- .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())); return;
}
PsiExpression condition = expression.getCondition();
condition.accept(this);
if (myResult == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil
- .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", condition.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", condition.getText())); return;
}
Evaluator conditionEvaluator = myResult;
thenExpression.accept(this);
if (myResult == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil
- .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", thenExpression.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", thenExpression.getText())); return;
}
Evaluator thenEvaluator = myResult;
elseExpression.accept(this);
if (myResult == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil
- .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", elseExpression.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", elseExpression.getText())); return;
}
Evaluator elseEvaluator = myResult;
myResult = new ConditionalExpressionEvaluator(conditionEvaluator, thenEvaluator, elseEvaluator);
LOG.debug("visitReferenceExpression " + expression);
}
PsiExpression qualifier = expression.getQualifierExpression();
- PsiElement element = expression.resolve();
+ JavaResolveResult resolveResult = expression.advancedResolve(true);
+ PsiElement element = resolveResult.getElement();
if (element instanceof PsiLocalVariable || element instanceof PsiParameter) {
final Value labeledValue = element.getUserData(CodeFragmentFactoryContextWrapper.LABEL_VARIABLE_VALUE_KEY);
}
//synthetic variable
final PsiFile containingFile = element.getContainingFile();
- if(containingFile instanceof PsiCodeFragment && myCurrentFragmentEvaluator != null && myVisitedFragments.contains(((PsiCodeFragment)containingFile))) {
+ if(containingFile instanceof PsiCodeFragment && myCurrentFragmentEvaluator != null && myVisitedFragments.contains(containingFile)) {
// psiVariable may live in PsiCodeFragment not only in debugger editors, for example Fabrique has such variables.
// So treat it as synthetic var only when this code fragment is located in DebuggerEditor,
// that's why we need to check that containing code fragment is the one we visited
aClass = getOuterClass(aClass);
}
if (aClass != null) {
- if(psiVar.getInitializer() != null) {
- Object value = JavaPsiFacade.getInstance(psiVar.getProject()).getConstantEvaluationHelper().computeConstantExpression(psiVar.getInitializer());
+ PsiExpression initializer = psiVar.getInitializer();
+ if(initializer != null) {
+ Object value = JavaPsiFacade.getInstance(psiVar.getProject()).getConstantEvaluationHelper().computeConstantExpression(initializer);
if(value != null) {
- myResult = new LiteralEvaluator(value, psiVar.getType().getCanonicalText());
+ PsiType type = resolveResult.getSubstitutor().substitute(psiVar.getType());
+ myResult = new LiteralEvaluator(value, type.getCanonicalText());
return;
}
}
myResult = new FieldEvaluator(objectEvaluator, filter, "val$" + localName);
return;
}
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
- DebuggerBundle.message("evaluation.error.local.variable.missing.from.class.closure", localName))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.local.variable.missing.from.class.closure", localName));
}
else if (element instanceof PsiField) {
final PsiField psiField = (PsiField)element;
final PsiClass fieldClass = psiField.getContainingClass();
if(fieldClass == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
- DebuggerBundle.message("evaluation.error.cannot.resolve.field.class", psiField.getName())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.cannot.resolve.field.class", psiField.getName())); return;
}
Evaluator objectEvaluator;
if (psiField.hasModifierProperty(PsiModifier.STATIC)) {
aClass = getOuterClass(aClass);
}
if (aClass == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
- DebuggerBundle.message("evaluation.error.cannot.sources.for.field.class", psiField.getName())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.cannot.sources.for.field.class", psiField.getName()));
}
objectEvaluator = new ThisEvaluator(iterationCount);
}
}
else {
//noinspection HardCodedStringLiteral
- final String elementDisplayString = (nameElement != null ? nameElement.getText() : "(null)");
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
- DebuggerBundle.message("evaluation.error.identifier.expected", elementDisplayString)));
+ final String elementDisplayString = nameElement != null ? nameElement.getText() : "(null)";
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.identifier.expected", elementDisplayString));
+ return;
}
if(qualifier != null) {
- final PsiElement qualifierTarget = (qualifier instanceof PsiReferenceExpression) ? ((PsiReferenceExpression)qualifier).resolve() : null;
+ final PsiElement qualifierTarget = qualifier instanceof PsiReferenceExpression
+ ? ((PsiReferenceExpression)qualifier).resolve() : null;
if (qualifierTarget instanceof PsiClass) {
// this is a call to a 'static' field
PsiClass psiClass = (PsiClass)qualifierTarget;
else {
PsiType type = qualifier.getType();
if(type == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
- DebuggerBundle.message("evaluation.error.qualifier.type.unknown", qualifier.getText()))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.qualifier.type.unknown", qualifier.getText()));
}
qualifier.accept(this);
if (myResult == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
- DebuggerBundle.message("evaluation.error.cannot.evaluate.qualifier", qualifier.getText()))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.cannot.evaluate.qualifier", qualifier.getText()));
}
myResult = new FieldEvaluator(myResult, FieldEvaluator.createClassFilter(type), name);
}
}
+ private static void throwEvaluateException(String message) throws EvaluateRuntimeException {
+ //noinspection ThrowableResultOfMethodCallIgnored
+ throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(message));
+ }
+
@Override
public void visitSuperExpression(PsiSuperExpression expression) {
if (LOG.isDebugEnabled()) {
if (qualifier != null) {
PsiElement targetClass = qualifier.resolve();
if (targetClass == null || getContextPsiClass() == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil
- .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", qualifier.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", qualifier.getText()));
}
try {
PsiClass aClass = getContextPsiClass();
}
}
catch (Exception e) {
+ //noinspection ThrowableResultOfMethodCallIgnored
throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(e));
}
}
}
PsiTypeElement checkType = expression.getCheckType();
if(checkType == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText()));
+ return;
}
PsiType type = checkType.getType();
expression.getOperand().accept(this);
@Override
public void visitPostfixExpression(PsiPostfixExpression expression) {
if(expression.getType() == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
- DebuggerBundle.message("evaluation.error.unknown.expression.type", expression.getText()))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", expression.getText()));
}
final PsiExpression operandExpression = expression.getOperand();
final IElementType operation = expression.getOperationSign().getTokenType();
final PsiType operandType = operandExpression.getType();
- final @Nullable PsiType unboxedOperandType = PsiPrimitiveType.getUnboxedType(operandType);
+ @Nullable final PsiType unboxedOperandType = PsiPrimitiveType.getUnboxedType(operandType);
Evaluator incrementImpl = createBinaryEvaluator(
operandEvaluator, operandType,
public void visitPrefixExpression(final PsiPrefixExpression expression) {
final PsiType expressionType = expression.getType();
if(expressionType == null) {
- throw new EvaluateRuntimeException(
- EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", expression.getText()))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", expression.getText()));
}
final PsiExpression operandExpression = expression.getOperand();
if (operandExpression == null) {
- throw new EvaluateRuntimeException(
- EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.operand", expression.getText()))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.operand", expression.getText()));
}
operandExpression.accept(this);
psiExpression.accept(this);
if (myResult == null) {
// cannot build evaluator
- throw new EvaluateRuntimeException(
- EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", psiExpression.getText()))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", psiExpression.getText()));
}
argumentEvaluators.add(myResult);
}
if (qualifier instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifier).resolve() instanceof PsiClass) {
// this is a call to a 'static' method
if (contextClass == null && type == null) {
- throw new EvaluateRuntimeException(
- EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.qualifier.type.unknown", qualifier.getText()))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.qualifier.type.unknown", qualifier.getText()));
}
assert contextClass != null;
objectEvaluator = new TypeEvaluator(contextClass);
}
if (objectEvaluator == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText()));
}
if (psiMethod != null && !psiMethod.isConstructor()) {
if (psiMethod.getReturnType() == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.unknown.method.return.type", psiMethod.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.unknown.method.return.type", psiMethod.getText()));
}
}
break; // actual arguments count is less than number of declared params
}
final PsiType declaredParamType = declaredParams[i].getType();
+ PsiType substituted = resolveResult.getSubstitutor().substitute(declaredParamType);
final PsiType actualArgType = argExpressions[i].getType();
- if (TypeConversionUtil.boxingConversionApplicable(declaredParamType, actualArgType)) {
+ if (TypeConversionUtil.boxingConversionApplicable(substituted, actualArgType)) {
final Evaluator argEval = argumentEvaluators.get(i);
- argumentEvaluators.set(i, (declaredParamType instanceof PsiPrimitiveType)? new UnBoxingEvaluator(argEval) : new BoxingEvaluator(argEval));
+ argumentEvaluators.set(i, substituted instanceof PsiPrimitiveType
+ ? new UnBoxingEvaluator(argEval) : new BoxingEvaluator(argEval));
}
}
}
public void visitLiteralExpression(PsiLiteralExpression expression) {
Object value = expression.getValue();
if(expression.getParsingError() != null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(expression.getParsingError()));
+ throwEvaluateException(expression.getParsingError());
}
myResult = new LiteralEvaluator(value, expression.getType().getCanonicalText());
}
public void visitArrayAccessExpression(PsiArrayAccessExpression expression) {
final PsiExpression indexExpression = expression.getIndexExpression();
if(indexExpression == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil
- .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())); return;
}
indexExpression.accept(this);
final Evaluator indexEvaluator = handleUnaryNumericPromotion(indexExpression.getType(), myResult);
dimensionEvaluator = handleUnaryNumericPromotion(dimensionExpression.getType(), myResult);
}
else {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
- DebuggerBundle.message("evaluation.error.invalid.array.dimension.expression", dimensionExpression.getText())));
+ throwEvaluateException(
+ DebuggerBundle.message("evaluation.error.invalid.array.dimension.expression", dimensionExpression.getText()));
}
}
else if (dimensions.length > 1){
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
- DebuggerBundle.message("evaluation.error.multi.dimensional.arrays.creation.not.supported"))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.multi.dimensional.arrays.creation.not.supported"));
}
Evaluator initializerEvaluator = null;
PsiArrayInitializerExpression arrayInitializer = expression.getArrayInitializer();
if (arrayInitializer != null) {
if (dimensionEvaluator != null) { // initializer already exists
- throw new EvaluateRuntimeException(EvaluateExceptionUtil
- .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText()));
}
arrayInitializer.accept(this);
if (myResult != null) {
initializerEvaluator = handleUnaryNumericPromotion(arrayInitializer.getType(), myResult);
}
else {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil
- .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", arrayInitializer.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", arrayInitializer.getText()));
}
/*
PsiExpression[] initializers = arrayInitializer.getInitializers();
*/
}
if (dimensionEvaluator == null && initializerEvaluator == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil
- .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText()));
}
myResult = new NewArrayInstanceEvaluator(
new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(expressionPsiType)),
LOG.assertTrue(expressionPsiType instanceof PsiClassType);
PsiClass aClass = ((PsiClassType)expressionPsiType).resolve();
if(aClass instanceof PsiAnonymousClass) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
- DebuggerBundle.message("evaluation.error.anonymous.class.evaluation.not.supported"))
- );
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.anonymous.class.evaluation.not.supported"));
}
PsiExpressionList argumentList = expression.getArgumentList();
if (argumentList == null) {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil
- .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())); return;
}
PsiExpression[] argExpressions = argumentList.getExpressions();
PsiMethod constructor = expression.resolveConstructor();
argumentEvaluators[idx] = myResult;
}
else {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil
- .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", argExpression.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", argExpression.getText()));
}
}
//noinspection HardCodedStringLiteral
- JVMName signature = (constructor != null)? JVMNameUtil.getJVMSignature(constructor) : JVMNameUtil.getJVMRawText("()V");
+ JVMName signature = constructor != null ? JVMNameUtil.getJVMSignature(constructor) : JVMNameUtil.getJVMRawText("()V");
myResult = new NewClassInstanceEvaluator(
new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(expressionPsiType)),
signature,
evaluators[idx] = handleUnaryNumericPromotion(initializer.getType(), myResult);
}
else {
- throw new EvaluateRuntimeException(EvaluateExceptionUtil
- .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", initializer.getText())));
+ throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", initializer.getText()));
}
}
myResult = new ArrayInitializerEvaluator(evaluators);
}
- private PsiClass getOuterClass(PsiClass aClass) {
+ private static PsiClass getOuterClass(PsiClass aClass) {
if(aClass == null) return null;
return PsiTreeUtil.getContextOfType(aClass, PsiClass.class, true);
}
project = ProjectManager.getInstance().getDefaultProject();
}
- ShowSettingsUtil.getInstance().editProjectConfigurable(project, ProjectStructureConfigurable.class, OptionsEditorDialog.DIMENSION_KEY);
+ ShowSettingsUtil.getInstance().editConfigurable(project, OptionsEditorDialog.DIMENSION_KEY, ProjectStructureConfigurable.getInstance(project));
}
}
\ No newline at end of file
public class TemplateProjectStructureAction extends AnAction implements DumbAware {
public void actionPerformed(final AnActionEvent e) {
Project defaultProject = ProjectManagerEx.getInstanceEx().getDefaultProject();
- ShowSettingsUtil.getInstance().editProjectConfigurable(defaultProject, ProjectStructureConfigurable.class, OptionsEditorDialog.DIMENSION_KEY);
+ ShowSettingsUtil.getInstance().editConfigurable(defaultProject, OptionsEditorDialog.DIMENSION_KEY, ProjectStructureConfigurable.getInstance(defaultProject));
}
}
\ No newline at end of file
*/
package com.intellij.openapi.roots.ui.configuration;
+import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleComponent;
import com.intellij.openapi.module.ModuleConfigurationEditor;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.options.ModuleConfigurableEP;
import javax.swing.*;
import java.util.ArrayList;
public class ModuleLevelConfigurablesEditorProvider implements ModuleConfigurationEditorProvider, ModuleComponent {
- public static final ExtensionPointName<Configurable> MODULE_CONFIGURABLES = ExtensionPointName.create("com.intellij.moduleConfigurable");
+ private static final ExtensionPointName<ModuleConfigurableEP> MODULE_CONFIGURABLES = ExtensionPointName.create("com.intellij.moduleConfigurable");
private final Module myModule;
for (final Configurable moduleConfigurable : moduleConfigurables) {
result.add(new ConfigurableWrapper(moduleConfigurable));
}
- for(Configurable configurable: Extensions.getExtensions(MODULE_CONFIGURABLES, myModule)) {
- result.add(new ConfigurableWrapper(configurable));
+ final ModuleConfigurableEP[] extensions = myModule.getExtensions(MODULE_CONFIGURABLES);
+ for(ModuleConfigurableEP extension : extensions) {
+ result.add(new ConfigurableWrapper(extension.createConfigurable()));
}
return result.toArray(new ModuleConfigurationEditor[result.size()]);
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
-import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import java.util.HashSet;
import java.util.Set;
-public class ProjectJdksConfigurable extends MasterDetailsComponent implements Configurable.Assistant {
+public class ProjectJdksConfigurable extends MasterDetailsComponent {
private final ProjectSdksModel myProjectJdksModel;
private final Project myProject;
import com.intellij.facet.Facet;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.options.*;
}
public static ProjectStructureConfigurable getInstance(final Project project) {
- return ShowSettingsUtil.getInstance().findProjectConfigurable(project, ProjectStructureConfigurable.class);
+ return ServiceManager.getService(project, ProjectStructureConfigurable.class);
}
public ProjectSdksModel getProjectJdksModel() {
import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import java.util.*;
import java.util.List;
-public abstract class BaseStructureConfigurable extends MasterDetailsComponent implements SearchableConfigurable, Disposable, Configurable.Assistant, Place.Navigator {
+public abstract class BaseStructureConfigurable extends MasterDetailsComponent implements SearchableConfigurable, Disposable, Place.Navigator {
protected StructureConfigurableContext myContext;
import com.intellij.facet.ui.MultipleFacetSettingsEditor;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
}
public static FacetStructureConfigurable getInstance(final @NotNull Project project) {
- return ShowSettingsUtil.getInstance().findProjectConfigurable(project, FacetStructureConfigurable.class);
+ return ServiceManager.getService(project, FacetStructureConfigurable.class);
}
public static boolean isEnabled() {
*/
package com.intellij.openapi.roots.ui.configuration.projectRoot;
+import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
-import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
public static GlobalLibrariesConfigurable getInstance(final Project project) {
- return ShowSettingsUtil.getInstance().findProjectConfigurable(project, GlobalLibrariesConfigurable.class);
+ return ServiceManager.getService(project, GlobalLibrariesConfigurable.class);
}
public LibraryTableModifiableModelProvider getModelProvider(final boolean editable) {
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.Sdk;
}
public static JdkListConfigurable getInstance(Project project) {
- return ShowSettingsUtil.getInstance().findProjectConfigurable(project, JdkListConfigurable.class);
+ return ServiceManager.getService(project, JdkListConfigurable.class);
}
public AbstractAddGroup createAddAction() {
import com.intellij.ide.util.projectWizard.ProjectWizardUtil;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.module.*;
import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
public static ModuleStructureConfigurable getInstance(final Project project) {
- return ShowSettingsUtil.getInstance().findProjectConfigurable(project, ModuleStructureConfigurable.class);
+ return ServiceManager.getService(project, ModuleStructureConfigurable.class);
}
public void setStartModuleWizard(final boolean show) {
*/
package com.intellij.openapi.roots.ui.configuration.projectRoot;
+import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
-import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
}
public static ProjectLibrariesConfigurable getInstance(final Project project) {
- return ShowSettingsUtil.getInstance().findProjectConfigurable(project, ProjectLibrariesConfigurable.class);
+ return ServiceManager.getService(project, ProjectLibrariesConfigurable.class);
}
protected String getAddText() {
import com.intellij.openapi.options.BeanConfigurable;
public class JavaCodeFoldingOptionsProvider extends BeanConfigurable<JavaCodeFoldingSettings> implements CodeFoldingOptionsProvider {
- protected JavaCodeFoldingOptionsProvider() {
+ public JavaCodeFoldingOptionsProvider() {
super(JavaCodeFoldingSettings.getInstance());
checkBox("COLLAPSE_ACCESSORS", ApplicationBundle.message("checkbox.collapse.simple.property.accessors"));
checkBox("COLLAPSE_INNER_CLASSES", ApplicationBundle.message("checkbox.collapse.inner.classes"));
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.psi.*;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Map;
import java.util.TreeMap;
-public class HyperlinksToClassesOption implements PrintOption {
+public class HyperlinksToClassesOption extends PrintOption {
private JCheckBox myCbGenerateHyperlinksToClasses;
private boolean isGenerateHyperlinksToClasses = false;
isGenerateHyperlinksToClasses = generateHyperlinksToClasses;
}
- public JComponent createComponent() {
- myCbGenerateHyperlinksToClasses = new JCheckBox(CodeEditorBundle.message("export.to.html.generate.hyperlinks.checkbox"), isGenerateHyperlinksToClasses);
- return myCbGenerateHyperlinksToClasses;
- }
-
- public boolean isModified() {
- return myCbGenerateHyperlinksToClasses.isSelected() != isGenerateHyperlinksToClasses;
- }
-
- public void apply() throws ConfigurationException {
- isGenerateHyperlinksToClasses = myCbGenerateHyperlinksToClasses.isSelected();
- }
-
- public void reset() {
- myCbGenerateHyperlinksToClasses.setSelected(isGenerateHyperlinksToClasses);
- }
-
- public void disposeUIResources() {
- myCbGenerateHyperlinksToClasses = null;
- }
-
@Nullable
public TreeMap<Integer, PsiReference> collectReferences(PsiFile psiFile, Map<PsiFile, PsiFile> filesMap) {
if (isGenerateHyperlinksToClasses()) {
return null;
}
+ @NotNull
+ @Override
+ public UnnamedConfigurable createConfigurable() {
+ return new HyperlinksToClassesConfigurable();
+ }
+
private static void findClassReferences(PsiElement psiElement, TreeMap<Integer, PsiReference> refMap, Map<PsiFile, PsiFile> filesMap, PsiFile psiFile) {
PsiReference ref = psiElement.getReference();
}
}
+ private class HyperlinksToClassesConfigurable implements UnnamedConfigurable {
+ public JComponent createComponent() {
+ myCbGenerateHyperlinksToClasses = new JCheckBox(CodeEditorBundle.message("export.to.html.generate.hyperlinks.checkbox"), isGenerateHyperlinksToClasses);
+ return myCbGenerateHyperlinksToClasses;
+ }
+
+ public boolean isModified() {
+ return myCbGenerateHyperlinksToClasses.isSelected() != isGenerateHyperlinksToClasses;
+ }
+
+ public void apply() throws ConfigurationException {
+ isGenerateHyperlinksToClasses = myCbGenerateHyperlinksToClasses.isSelected();
+ }
+
+ public void reset() {
+ myCbGenerateHyperlinksToClasses.setSelected(isGenerateHyperlinksToClasses);
+ }
+
+ public void disposeUIResources() {
+ }
+ }
}
\ No newline at end of file
public static PsiExpression[] findExpressionOccurrences(PsiElement scope, PsiExpression expr) {
List<PsiExpression> array = new ArrayList<PsiExpression>();
addExpressionOccurrences(RefactoringUtil.unparenthesizeExpression(expr), array, scope);
- boolean found = false;
- for (PsiExpression psiExpression : array) {
- if (PsiTreeUtil.isAncestor(expr, psiExpression, false) || PsiTreeUtil.isAncestor(psiExpression, expr, false)) {
- found = true;
- break;
+ if (expr.isPhysical()) {
+ boolean found = false;
+ for (PsiExpression psiExpression : array) {
+ if (PsiTreeUtil.isAncestor(expr, psiExpression, false) || PsiTreeUtil.isAncestor(psiExpression, expr, false)) {
+ found = true;
+ break;
+ }
}
+ if (!found) array.add(expr);
}
- if (!found) array.add(expr);
return array.toArray(new PsiExpression[array.size()]);
}
package com.intellij.codeInsight.completion;
-import com.intellij.codeInsight.completion.simple.PsiMethodInsertHandler;
import com.intellij.codeInsight.generation.GenerateMembersUtil;
import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.codeInsight.generation.PsiGenerationInfo;
}
}
- PsiMethodInsertHandler.insertParentheses(context, delegate, false, hasParams);
+ JavaCompletionUtil.insertParentheses(context, delegate, false, hasParams);
}
private static Runnable generateAnonymousBody(final Editor editor, PsiFile file) {
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
-import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
final int i = lookupString.indexOf('<');
if (i >= 0) length = i;
final int newOffset = addImportForClass(file, startOffset, startOffset + length, aClass);
- shortenReference(file, newOffset);
+ JavaCompletionUtil.shortenReference(file, newOffset);
}
else if (o instanceof PsiType){
PsiType type = ((PsiType)o).getDeepComponentType();
}
}
- //need to shorten references in type argument list
- private static void shortenReference(final PsiFile file, final int offset) throws IncorrectOperationException {
- final PsiDocumentManager manager = PsiDocumentManager.getInstance(file.getProject());
- final Document document = manager.getDocument(file);
- assert document != null;
- manager.commitDocument(document);
- final PsiReference ref = file.findReferenceAt(offset);
- if (ref instanceof PsiJavaCodeReferenceElement) {
- JavaCodeStyleManager.getInstance(file.getProject()).shortenClassReferences((PsiJavaCodeReferenceElement)ref);
- }
- }
-
private static int addImportForClass(PsiFile file, int startOffset, int endOffset, PsiClass aClass) throws IncorrectOperationException {
return JavaCompletionUtil.insertClassReference(aClass, file, startOffset, endOffset);
}
public class ImportStaticLookupActionProvider implements LookupActionProvider {
@Override
public void fillActions(final LookupElement element, Lookup lookup, Consumer<LookupElementAction> consumer) {
- if (!(element instanceof JavaGlobalMemberLookupElement)) {
+ if (!(element instanceof StaticallyImportable)) {
+ return;
+ }
+
+ final StaticallyImportable item = (StaticallyImportable)element;
+ if (!item.canBeImported()) {
return;
}
- final JavaGlobalMemberLookupElement item = (JavaGlobalMemberLookupElement)element;
final Icon checkIcon = Icons.CHECK_ICON;
- final Icon icon = item.isShouldImport() ? checkIcon : new EmptyIcon(checkIcon.getIconWidth(), checkIcon.getIconHeight());
+ final Icon icon = item.willBeImported() ? checkIcon : new EmptyIcon(checkIcon.getIconWidth(), checkIcon.getIconHeight());
consumer.consume(new LookupElementAction(icon, "Import statically") {
@Override
public Result performLookupAction() {
FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.IMPORT_STATIC);
- item.setShouldImport(!item.isShouldImport());
+ item.setShouldBeImported(!item.willBeImported());
return Result.REFRESH_ITEM;
}
});
*/
package com.intellij.codeInsight.completion;
-import com.intellij.codeInsight.CodeInsightSettings;
-import com.intellij.codeInsight.CodeInsightUtilBase;
-import com.intellij.codeInsight.ExpectedTypeInfo;
-import com.intellij.codeInsight.ExpectedTypeInfoImpl;
+import com.intellij.codeInsight.*;
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
import com.intellij.codeInsight.completion.scope.CompletionElement;
import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
+import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler;
import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.codeInsight.guess.GuessManager;
import com.intellij.codeInsight.lookup.*;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.util.*;
import com.intellij.psi.xml.XmlToken;
import com.intellij.psi.xml.XmlTokenType;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.NullableFunction;
-import com.intellij.util.PairFunction;
+import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import gnu.trove.THashSet;
}
}
+ JavaGlobalMemberNameCompletionContributor.completeStaticMembers(element).processMembersOfRegisteredClasses(matcher, new Consumer<LookupElement>() {
+ @Override
+ public void consume(LookupElement element) {
+ set.add(element);
+ }
+ });
+
return set;
}
}
public static LookupItem qualify(final LookupItem ret) {
- final PsiMember completionElement = (PsiMember)ret.getObject();
- final PsiClass containingClass = completionElement.getContainingClass();
- if (containingClass != null) {
- final String className = containingClass.getName();
- ret.setLookupString(className + "." + ret.getLookupString());
+ if (!(ret instanceof JavaMethodCallElement)) {
+ final PsiMember completionElement = (PsiMember)ret.getObject();
+ final PsiClass containingClass = completionElement.getContainingClass();
+ if (containingClass != null) {
+ final String className = containingClass.getName();
+ ret.setLookupString(className + "." + ret.getLookupString());
+ }
}
return ret.forceQualify();
}
toDelete.setGreedyToRight(true);
return toDelete;
}
+
+ public static void insertParentheses(final InsertionContext context, final LookupElement item, boolean overloadsMatter, boolean hasParams) {
+ final Editor editor = context.getEditor();
+ final TailType tailType = getTailType(item, context);
+ final PsiFile file = context.getFile();
+
+ context.setAddCompletionChar(false);
+
+
+ final boolean needLeftParenth = isToInsertParenth(file.findElementAt(context.getStartOffset()));
+ final boolean needRightParenth = shouldInsertRParenth(context.getCompletionChar(), tailType, hasParams);
+
+ if (needLeftParenth) {
+ final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(context.getProject());
+ ParenthesesInsertHandler.getInstance(hasParams,
+ styleSettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES,
+ styleSettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES && hasParams,
+ needRightParenth,
+ styleSettings.METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE
+ ).handleInsert(context, item);
+ }
+
+ if (needLeftParenth && hasParams) {
+ // Invoke parameters popup
+ AutoPopupController.getInstance(file.getProject()).autoPopupParameterInfo(editor, overloadsMatter ? null : (PsiElement)item.getObject());
+ }
+ if (tailType == TailType.SMART_COMPLETION || needLeftParenth && needRightParenth) {
+ tailType.processTail(editor, context.getTailOffset());
+ }
+ }
+
+ public static boolean shouldInsertRParenth(char completionChar, TailType tailType, boolean hasParams) {
+ if (tailType == TailType.SMART_COMPLETION) {
+ return false;
+ }
+
+ if (completionChar == '(' && !hasParams) {
+ //it's highly probable that the user will type ')' next and it may not be overwritten if the flag is off
+ return CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET;
+ }
+
+ return true;
+ }
+
+ @NotNull
+ public static TailType getTailType(final LookupElement item, InsertionContext context) {
+ final char completionChar = context.getCompletionChar();
+ if (completionChar == '!') return item instanceof LookupItem ? ((LookupItem)item).getTailType() : TailType.NONE;
+ if (completionChar == '(') {
+ final Object o = item.getObject();
+ if (o instanceof PsiMethod) {
+ final PsiMethod psiMethod = (PsiMethod)o;
+ return psiMethod.getParameterList().getParameters().length > 0 || psiMethod.getReturnType() != PsiType.VOID
+ ? TailType.NONE : TailType.SEMICOLON;
+ } else if (o instanceof PsiClass) { // it may be a constructor
+ return TailType.NONE;
+ }
+ }
+ if (completionChar == Lookup.COMPLETE_STATEMENT_SELECT_CHAR) return TailType.SMART_COMPLETION;
+ if (!context.shouldAddCompletionChar()) {
+ return TailType.NONE;
+ }
+
+ return LookupItem.handleCompletionChar(context.getEditor(), item, completionChar);
+ }
+
+ public static boolean isToInsertParenth(PsiElement place){
+ if (place == null) return true;
+ return !(place.getParent() instanceof PsiImportStaticReferenceElement);
+ }
+
+ //need to shorten references in type argument list
+ public static void shortenReference(final PsiFile file, final int offset) throws IncorrectOperationException {
+ final PsiDocumentManager manager = PsiDocumentManager.getInstance(file.getProject());
+ final Document document = manager.getDocument(file);
+ assert document != null;
+ manager.commitDocument(document);
+ final PsiReference ref = file.findReferenceAt(offset);
+ if (ref instanceof PsiJavaCodeReferenceElement) {
+ JavaCodeStyleManager.getInstance(file.getProject()).shortenClassReferences((PsiJavaCodeReferenceElement)ref);
+ }
+ }
}
((PsiJavaReference) ref).processVariants(processor);
for (final CompletionElement _item : processor.getResults()) {
- LookupItem item = (LookupItem)LookupItemUtil.objectToLookupItem(_item.getElement());
+ final Object element = _item.getElement();
+ LookupItem item = element instanceof PsiMethod ? new JavaMethodCallElement((PsiMethod)element) {
+ @Override
+ public void handleInsert(InsertionContext context) {
+ new MethodSignatureInsertHandler().handleInsert(context, this);
+ }
+ } : (LookupItem)LookupItemUtil.objectToLookupItem(element);
if (onlyConstants) {
Object o = item.getObject();
if (!(o instanceof PsiField)) continue;
if (isArg) {
item.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
}
- item.setInsertHandler(new MethodSignatureInsertHandler());
result.addElement(item);
}
}
/**
* @author peter
*/
-public class JavaGlobalMemberLookupElement extends LookupElement {
+public class JavaGlobalMemberLookupElement extends LookupElement implements StaticallyImportable {
private final PsiMethod myMethod;
private final PsiClass myContainingClass;
private final InsertHandler<JavaGlobalMemberLookupElement> myQualifiedInsertion;
public JavaGlobalMemberLookupElement(PsiMethod method,
PsiClass containingClass,
InsertHandler<JavaGlobalMemberLookupElement> qualifiedInsertion,
- InsertHandler<JavaGlobalMemberLookupElement> importInsertion) {
+ InsertHandler<JavaGlobalMemberLookupElement> importInsertion, boolean shouldImport) {
myMethod = method;
myContainingClass = containingClass;
myQualifiedInsertion = qualifiedInsertion;
myImportInsertion = importInsertion;
+ myShouldImport = shouldImport;
}
@NotNull
}
}
- public boolean isShouldImport() {
- return myShouldImport;
+ @Override
+ public void setShouldBeImported(boolean shouldImportStatic) {
+ myShouldImport = shouldImportStatic;
}
- public void setShouldImport(boolean shouldImport) {
- myShouldImport = shouldImport;
+ @Override
+ public boolean canBeImported() {
+ return true;
+ }
+
+ @Override
+ public boolean willBeImported() {
+ return myShouldImport;
}
@Override
package com.intellij.codeInsight.completion;
-import com.intellij.codeInsight.completion.simple.PsiMethodInsertHandler;
-import com.intellij.codeInsight.daemon.impl.quickfix.StaticImportMethodFix;
-import com.intellij.featureStatistics.FeatureUsageTracker;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.VariableLookupItem;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
/**
* @author peter
*/
public class JavaGlobalMemberNameCompletionContributor extends CompletionContributor {
- private static final InsertHandler<JavaGlobalMemberLookupElement> STATIC_METHOD_INSERT_HANDLER = new InsertHandler<JavaGlobalMemberLookupElement>() {
- @Override
- public void handleInsert(InsertionContext context, JavaGlobalMemberLookupElement item) {
- PsiMethodInsertHandler.INSTANCE.handleInsert(context, item);
- final PsiClass containingClass = item.getContainingClass();
- PsiDocumentManager.getInstance(containingClass.getProject()).commitDocument(context.getDocument());
- final PsiReferenceExpression ref = PsiTreeUtil
- .findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiReferenceExpression.class, false);
- if (ref != null) {
- ref.bindToElementViaStaticImport(containingClass);
- }
- }
- };
- private static final InsertHandler<JavaGlobalMemberLookupElement> QUALIFIED_METHOD_INSERT_HANDLER = new InsertHandler<JavaGlobalMemberLookupElement>() {
- @Override
- public void handleInsert(InsertionContext context, JavaGlobalMemberLookupElement item) {
- PsiMethodInsertHandler.INSTANCE.handleInsert(context, item);
- context.getDocument().insertString(context.getStartOffset(), ".");
- JavaCompletionUtil.insertClassReference(item.getContainingClass(), context.getFile(), context.getStartOffset());
- }
- };
-
@Override
public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) {
if (parameters.getCompletionType() != CompletionType.CLASS_NAME) {
return;
}
- processStaticMethods(result, position, QUALIFIED_METHOD_INSERT_HANDLER, STATIC_METHOD_INSERT_HANDLER);
+ completeStaticMembers(position).processStaticMethodsGlobally(result);
}
- public static void processStaticMethods(final CompletionResultSet result,
- final PsiElement position,
- final InsertHandler<JavaGlobalMemberLookupElement> qualifiedInsert,
- final InsertHandler<JavaGlobalMemberLookupElement> importInsert) {
- PrefixMatcher matcher = result.getPrefixMatcher();
- final Project project = position.getProject();
- final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
- final PsiShortNamesCache namesCache = JavaPsiFacade.getInstance(project).getShortNamesCache();
- final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(project).getResolveHelper();
- final String[] methodNames = ApplicationManager.getApplication().runReadAction(new Computable<String[]>() {
- public String[] compute() {
- return namesCache.getAllMethodNames();
- }
- });
- final boolean[] hintShown = {false};
- for (final String methodName : methodNames) {
- if (matcher.prefixMatches(methodName)) {
- final PsiMethod[] methods = ApplicationManager.getApplication().runReadAction(new Computable<PsiMethod[]>() {
- public PsiMethod[] compute() {
- return namesCache.getMethodsByName(methodName, scope);
+ public static StaticMemberProcessor completeStaticMembers(final PsiElement position) {
+ final StaticMemberProcessor processor = new StaticMemberProcessor(position) {
+ @NotNull
+ @Override
+ protected LookupElement createLookupElement(@NotNull PsiMember member, @NotNull final PsiClass containingClass, boolean shouldImport) {
+ if (member instanceof PsiMethod) {
+ final JavaMethodCallElement element = new JavaMethodCallElement((PsiMethod)member, true);
+ element.setShouldBeImported(shouldImport);
+ return element;
+ }
+ return new VariableLookupItem((PsiVariable)member) {
+ @Override
+ public void handleInsert(InsertionContext context) {
+ context.commitDocument();
+ final PsiReferenceExpression ref = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiReferenceExpression.class, false);
+ if (ref != null) {
+ ref.bindToElementViaStaticImport(containingClass);
+ }
+ super.handleInsert(context);
}
- });
- for (final PsiMethod method : methods) {
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- public void run() {
- if (method.hasModifierProperty(PsiModifier.STATIC) && resolveHelper.isAccessible(method, position, null)) {
- final PsiClass containingClass = method.getContainingClass();
- if (containingClass != null) {
- if (!JavaCompletionUtil.isInExcludedPackage(containingClass) && !StaticImportMethodFix.isExcluded(method)) {
- if (!hintShown[0] &&
- FeatureUsageTracker.getInstance().isToBeShown(JavaCompletionFeatures.IMPORT_STATIC, project) &&
- CompletionService.getCompletionService().getAdvertisementText() == null) {
- final String shortcut = getActionShortcut("EditorRight");
- if (shortcut != null) {
- CompletionService.getCompletionService().setAdvertisementText("To import the method statically, press " + shortcut);
- }
- hintShown[0] = true;
- }
-
- result.addElement(new JavaGlobalMemberLookupElement(method, containingClass, qualifiedInsert, importInsert));
- }
+ };
+ }
- }
- }
+ };
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ final PsiFile file = position.getContainingFile();
+ if (file instanceof PsiJavaFile) {
+ final PsiImportList importList = ((PsiJavaFile)file).getImportList();
+ if (importList != null) {
+ for (PsiImportStaticStatement statement : importList.getImportStaticStatements()) {
+ processor.importMembersOf(statement.resolveTargetClass());
}
- });
-
+ }
}
}
- }
+ });
+
+ return processor;
}
+
}
*/
package com.intellij.codeInsight.completion;
+import com.intellij.codeInsight.ExpectedTypeInfo;
+import com.intellij.codeInsight.ExpectedTypesProvider;
import com.intellij.codeInsight.TailType;
-import com.intellij.codeInsight.completion.simple.PsiMethodInsertHandler;
-import com.intellij.codeInsight.lookup.LookupItem;
-import com.intellij.codeInsight.lookup.TypedLookupItem;
+import com.intellij.codeInsight.completion.util.MethodParenthesesHandler;
+import com.intellij.codeInsight.lookup.*;
+import com.intellij.codeInsight.lookup.impl.JavaElementLookupRenderer;
+import com.intellij.featureStatistics.FeatureUsageTracker;
+import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.Key;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiSubstitutor;
-import com.intellij.psi.PsiType;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author peter
*/
-public class JavaMethodCallElement extends LookupItem<PsiMethod> implements TypedLookupItem {
+public class JavaMethodCallElement extends LookupItem<PsiMethod> implements TypedLookupItem, StaticallyImportable {
private static final Key<PsiSubstitutor> INFERENCE_SUBSTITUTOR = Key.create("INFERENCE_SUBSTITUTOR");
+ private final PsiClass myContainingClass;
+ private final PsiMethod myMethod;
+ private final boolean myCanImportStatic;
+ private boolean myShouldImportStatic;
- public JavaMethodCallElement(PsiMethod method) {
+ public JavaMethodCallElement(@NotNull PsiMethod method) {
+ this(method, false);
+ }
+
+ public JavaMethodCallElement(PsiMethod method, boolean canImportStatic) {
super(method, method.getName());
+ myMethod = method;
+ myContainingClass = method.getContainingClass();
+ myCanImportStatic = canImportStatic;
PsiType type = method.getReturnType();
setTailType(PsiType.VOID.equals(type) ? TailType.SEMICOLON : TailType.NONE);
- setInsertHandler(PsiMethodInsertHandler.INSTANCE);
}
public PsiType getType() {
return getSubstitutor().substitute(getInferenceSubstitutor().substitute(getObject().getReturnType()));
-
}
public void setInferenceSubstitutor(@NotNull final PsiSubstitutor substitutor) {
@NotNull
public PsiSubstitutor getSubstitutor() {
- final PsiSubstitutor substitutor = (PsiSubstitutor)getAttribute(LookupItem.SUBSTITUTOR);
+ final PsiSubstitutor substitutor = (PsiSubstitutor)getAttribute(SUBSTITUTOR);
return substitutor == null ? PsiSubstitutor.EMPTY : substitutor;
}
- public void setSubstitutor(@NotNull PsiSubstitutor substitutor) {
- setAttribute(SUBSTITUTOR, substitutor);
- }
-
@NotNull
public PsiSubstitutor getInferenceSubstitutor() {
final PsiSubstitutor substitutor = getAttribute(INFERENCE_SUBSTITUTOR);
return substitutor == null ? PsiSubstitutor.EMPTY : substitutor;
}
+
+ @Override
+ public void setShouldBeImported(boolean shouldImportStatic) {
+ assert myCanImportStatic;
+ myShouldImportStatic = shouldImportStatic;
+ }
+
+ @Override
+ public boolean canBeImported() {
+ return myCanImportStatic;
+ }
+
+ @Override
+ public boolean willBeImported() {
+ return myShouldImportStatic;
+ }
+
+ @Override
+ public void handleInsert(InsertionContext context) {
+ final Document document = context.getDocument();
+ final PsiFile file = context.getFile();
+ final PsiMethod method = getObject();
+
+ final LookupElement[] allItems = context.getElements();
+ final boolean overloadsMatter = allItems.length == 1 && getUserData(FORCE_SHOW_SIGNATURE_ATTR) == null;
+ final boolean hasParams = MethodParenthesesHandler.hasParams(this, allItems, overloadsMatter, method);
+ JavaCompletionUtil.insertParentheses(context, this, overloadsMatter, hasParams);
+
+ final int startOffset = context.getStartOffset();
+ final OffsetKey refStart = context.trackOffset(startOffset, true);
+ if (shouldInsertTypeParameters(context)) {
+ qualifyMethodCall(file, startOffset, document);
+ insertExplicitTypeParameters(context, refStart);
+ }
+ else if (myCanImportStatic || getAttribute(FORCE_QUALIFY) != null) {
+ context.commitDocument();
+ if (myCanImportStatic && myShouldImportStatic) {
+ final PsiReferenceExpression ref = PsiTreeUtil.findElementOfClassAtOffset(file, startOffset, PsiReferenceExpression.class, false);
+ if (ref != null) {
+ ref.bindToElementViaStaticImport(myContainingClass);
+ }
+ return;
+ }
+
+ qualifyMethodCall(file, startOffset, document);
+ }
+
+ final PsiType type = method.getReturnType();
+ if (context.getCompletionChar() == '!' && type != null && PsiType.BOOLEAN.isAssignableFrom(type)) {
+ context.commitDocument();
+ final int offset = context.getOffset(refStart);
+ final PsiMethodCallExpression methodCall = PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiMethodCallExpression.class, false);
+ if (methodCall != null) {
+ FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EXCLAMATION_FINISH);
+ document.insertString(methodCall.getTextRange().getStartOffset(), "!");
+ }
+ }
+
+ }
+
+ private boolean shouldInsertTypeParameters(InsertionContext context) {
+ final PsiElement leaf = context.getFile().findElementAt(context.getStartOffset());
+ if (PsiTreeUtil.getParentOfType(leaf, PsiExpressionList.class, true, PsiCodeBlock.class, PsiModifierListOwner.class) == null) {
+ if (PsiTreeUtil.getParentOfType(leaf, PsiConditionalExpression.class, true, PsiCodeBlock.class, PsiModifierListOwner.class) == null) {
+ return false;
+ }
+ }
+
+ return SmartCompletionDecorator.hasUnboundTypeParams(getObject());
+ }
+
+ private boolean insertExplicitTypeParameters(InsertionContext context, OffsetKey refStart) {
+ context.commitDocument();
+
+ PsiExpression expression = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getOffset(refStart), PsiExpression.class, false);
+ if (expression == null) return true;
+
+ final ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getExpectedTypes(expression, true);
+ if (expectedTypes == null) return true;
+
+ for (final ExpectedTypeInfo type : expectedTypes) {
+ if (type.isInsertExplicitTypeParams()) {
+ final String typeParams = getTypeParamsText(type.getType());
+ if (typeParams == null) {
+ return true;
+ }
+
+ context.getDocument().insertString(context.getOffset(refStart), typeParams);
+
+ JavaCompletionUtil.shortenReference(context.getFile(), context.getOffset(refStart));
+
+ break;
+ }
+ }
+
+ return true;
+ }
+
+ private void qualifyMethodCall(PsiFile file, final int startOffset, final Document document) {
+ final PsiReference reference = file.findReferenceAt(startOffset);
+ if (reference instanceof PsiReferenceExpression && ((PsiReferenceExpression)reference).isQualified()) {
+ return;
+ }
+
+ final PsiMethod method = getObject();
+ if (!method.hasModifierProperty(PsiModifier.STATIC)) {
+ document.insertString(startOffset, "this.");
+ return;
+ }
+
+ document.insertString(startOffset, ".");
+ JavaCompletionUtil.insertClassReference(myContainingClass, file, startOffset);
+ }
+
+ @Nullable
+ private String getTypeParamsText(PsiType expectedType) {
+ final PsiMethod method = getObject();
+ final PsiSubstitutor substitutor = SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, expectedType);
+ assert substitutor != null;
+ final PsiTypeParameter[] parameters = method.getTypeParameters();
+ assert parameters.length > 0;
+ final StringBuilder builder = new StringBuilder("<");
+ boolean first = true;
+ for (final PsiTypeParameter parameter : parameters) {
+ if (!first) builder.append(", ");
+ first = false;
+ PsiType type = substitutor.substitute(parameter);
+ if (type instanceof PsiWildcardType) {
+ type = ((PsiWildcardType)type).getExtendsBound();
+ }
+
+ if (type == null || type instanceof PsiCapturedWildcardType) return null;
+
+ final String text = type.getCanonicalText();
+ if (text.indexOf('?') >= 0) return null;
+
+ builder.append(text);
+ }
+ return builder.append(">").toString();
+ }
+
+ @Override
+ public void renderElement(LookupElementPresentation presentation) {
+ final String className = myContainingClass.getName();
+
+ presentation.setIcon(DefaultLookupItemRenderer.getRawIcon(this, presentation.isReal()));
+
+ final String methodName = myMethod.getName();
+ final boolean qualify = myCanImportStatic && !myShouldImportStatic || getAttribute(FORCE_QUALIFY) != null;
+ if (qualify && StringUtil.isNotEmpty(className)) {
+ presentation.setItemText(className + "." + methodName);
+ } else {
+ presentation.setItemText(methodName);
+ }
+
+ presentation.setStrikeout(JavaElementLookupRenderer.isToStrikeout(this));
+ presentation.setItemTextBold(getAttribute(HIGHLIGHTED_ATTR) != null);
+
+
+ final String params = PsiFormatUtil.formatMethod(myMethod, PsiSubstitutor.EMPTY,
+ PsiFormatUtil.SHOW_PARAMETERS,
+ PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE);
+ if (myShouldImportStatic && StringUtil.isNotEmpty(className)) {
+ presentation.setTailText(params + " in " + className);
+ } else {
+ presentation.setTailText(params);
+ }
+
+ final PsiType type = myMethod.getReturnType();
+ if (type != null) {
+ presentation.setTypeText(getSubstitutor().substitute(type).getPresentableText());
+ }
+ }
}
PsiReference ref = position.getContainingFile().findReferenceAt(startOffset);
if (ref!=null && completion instanceof PsiNamedElement) {
- if (completion instanceof PsiMethod || completion instanceof PsiField) {
+ if (completion instanceof PsiField) {
final PsiMember member = (PsiMember)completion;
if (item.getAttribute(LookupItem.FORCE_QUALIFY) != null
&& member.hasModifierProperty(PsiModifier.STATIC)
--- /dev/null
+package com.intellij.codeInsight.completion;
+
+import com.intellij.codeInsight.daemon.impl.quickfix.StaticImportMethodFix;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.featureStatistics.FeatureUsageTracker;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.util.Consumer;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Set;
+
+import static com.intellij.util.containers.CollectionFactory.hashSet;
+import static com.intellij.util.containers.ContainerUtil.addIfNotNull;
+
+/**
+* @author peter
+*/
+public abstract class StaticMemberProcessor {
+ private final Set<PsiClass> myStaticImportedClasses = hashSet();
+ private final PsiElement myPosition;
+ private final Project myProject;
+ private final PsiResolveHelper myResolveHelper;
+ private boolean myHintShown = false;
+
+ public StaticMemberProcessor(final PsiElement position) {
+ myPosition = position;
+ myProject = myPosition.getProject();
+ myResolveHelper = JavaPsiFacade.getInstance(myProject).getResolveHelper();
+ }
+
+ public void importMembersOf(@Nullable PsiClass psiClass) {
+ addIfNotNull(myStaticImportedClasses, psiClass);
+ }
+
+ public void processStaticMethodsGlobally(final CompletionResultSet resultSet) {
+ final Consumer<LookupElement> consumer = new Consumer<LookupElement>() {
+ @Override
+ public void consume(LookupElement element) {
+ resultSet.addElement(element);
+ }
+ };
+
+ final PrefixMatcher matcher = resultSet.getPrefixMatcher();
+ final GlobalSearchScope scope = GlobalSearchScope.allScope(myProject);
+ final PsiShortNamesCache namesCache = JavaPsiFacade.getInstance(myProject).getShortNamesCache();
+ final String[] methodNames = ApplicationManager.getApplication().runReadAction(new Computable<String[]>() {
+ public String[] compute() {
+ return namesCache.getAllMethodNames();
+ }
+ });
+ for (final String methodName : methodNames) {
+ if (matcher.prefixMatches(methodName)) {
+ final PsiMethod[] methods = ApplicationManager.getApplication().runReadAction(new Computable<PsiMethod[]>() {
+ public PsiMethod[] compute() {
+ return namesCache.getMethodsByName(methodName, scope);
+ }
+ });
+ for (final PsiMethod method : methods) {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ processMember(method, consumer);
+ }
+ });
+
+ }
+ }
+ }
+ }
+
+ public void processMembersOfRegisteredClasses(@Nullable final PrefixMatcher matcher, final Consumer<LookupElement> consumer) {
+ for (final PsiClass psiClass : myStaticImportedClasses) {
+ final PsiMethod[] classMethods = ApplicationManager.getApplication().runReadAction(new Computable<PsiMethod[]>() {
+ public PsiMethod[] compute() {
+ return psiClass.getAllMethods();
+ }
+ });
+ for (final PsiMethod method : classMethods) {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ if (matcher == null || matcher.prefixMatches(method.getName())) {
+ processMember(method, consumer);
+ }
+ }
+ });
+ }
+ final PsiField[] fields = ApplicationManager.getApplication().runReadAction(new Computable<PsiField[]>() {
+ public PsiField[] compute() {
+ return psiClass.getAllFields();
+ }
+ });
+ for (final PsiField field : fields) {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ if (matcher == null || matcher.prefixMatches(field.getName())) {
+ processMember(field, consumer);
+ }
+ }
+ });
+ }
+ }
+ }
+
+
+ private void processMember(final PsiMember member, final Consumer<LookupElement> consumer) {
+ if (member.hasModifierProperty(PsiModifier.STATIC) && myResolveHelper.isAccessible(member, myPosition, null)) {
+ final PsiClass containingClass = member.getContainingClass();
+ if (containingClass != null) {
+ if (!JavaCompletionUtil.isInExcludedPackage(containingClass) &&
+ (!(member instanceof PsiMethod) || !StaticImportMethodFix.isExcluded((PsiMethod)member))) {
+ final boolean shouldImport = myStaticImportedClasses.contains(containingClass);
+ if (!myHintShown &&
+ !shouldImport &&
+ FeatureUsageTracker.getInstance().isToBeShown(JavaCompletionFeatures.IMPORT_STATIC, myProject) &&
+ CompletionService.getCompletionService().getAdvertisementText() == null) {
+ final String shortcut = CompletionContributor.getActionShortcut("EditorRight");
+ if (shortcut != null) {
+ CompletionService.getCompletionService().setAdvertisementText("To import a method statically, press " + shortcut);
+ }
+ myHintShown = true;
+ }
+
+ consumer.consume(createLookupElement(member, containingClass, shouldImport));
+ }
+
+ }
+ }
+ }
+
+ @NotNull
+ protected abstract LookupElement createLookupElement(@NotNull PsiMember member, @NotNull PsiClass containingClass, boolean shouldImport);
+}
--- /dev/null
+package com.intellij.codeInsight.completion;
+
+/**
+ * @author peter
+ */
+public interface StaticallyImportable {
+ void setShouldBeImported(boolean shouldImportStatic);
+
+ boolean canBeImported();
+
+ boolean willBeImported();
+}
*/
public class JavaCompletionProcessor extends BaseScopeProcessor implements ElementClassHint {
public static final Key<Condition<String>> NAME_FILTER = Key.create("NAME_FILTER");
+ public static final Key<Boolean> JAVA_COMPLETION = Key.create("JAVA_COMPLETION");
private boolean myStatic = false;
private final Set<Object> myResultNames = new THashSet<Object>();
if (hintKey == NAME_FILTER) {
return (T)myMatcher;
}
+ if (hintKey == JAVA_COMPLETION) {
+ return (T)Boolean.TRUE;
+ }
return super.getHint(hintKey);
}
+++ /dev/null
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.codeInsight.completion.simple;
-
-import com.intellij.codeInsight.*;
-import com.intellij.codeInsight.completion.*;
-import com.intellij.codeInsight.completion.util.MethodParenthesesHandler;
-import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler;
-import com.intellij.codeInsight.lookup.Lookup;
-import com.intellij.codeInsight.lookup.LookupElement;
-import com.intellij.codeInsight.lookup.LookupItem;
-import com.intellij.featureStatistics.FeatureUsageTracker;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.CodeStyleSettings;
-import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
-import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.IncorrectOperationException;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @author peter
-*/
-public class PsiMethodInsertHandler implements InsertHandler<LookupElement> {
- private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.simple.PsiMethodInsertHandler");
- public static final PsiMethodInsertHandler INSTANCE = new PsiMethodInsertHandler();
-
- public static void insertParentheses(final InsertionContext context, final LookupElement item, boolean overloadsMatter, boolean hasParams) {
- final Editor editor = context.getEditor();
- final TailType tailType = getTailType(item, context);
- final PsiFile file = context.getFile();
-
- context.setAddCompletionChar(false);
-
-
- final boolean needLeftParenth = isToInsertParenth(file.findElementAt(context.getStartOffset()));
- final boolean needRightParenth = shouldInsertRParenth(context.getCompletionChar(), tailType, hasParams);
-
- if (needLeftParenth) {
- final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(context.getProject());
- ParenthesesInsertHandler.getInstance(hasParams,
- styleSettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES,
- styleSettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES && hasParams,
- needRightParenth,
- styleSettings.METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE
- ).handleInsert(context, item);
- }
-
- if (needLeftParenth && hasParams) {
- // Invoke parameters popup
- AutoPopupController.getInstance(file.getProject()).autoPopupParameterInfo(editor, overloadsMatter ? null : (PsiElement)item.getObject());
- }
- if (tailType == TailType.SMART_COMPLETION || needLeftParenth && needRightParenth) {
- tailType.processTail(editor, context.getTailOffset());
- }
- }
-
- public void handleInsert(final InsertionContext context, final LookupElement item) {
- final Editor editor = context.getEditor();
- final Document document = editor.getDocument();
- final PsiFile file = context.getFile();
- final int offset = editor.getCaretModel().getOffset();
- final PsiMethod method = (PsiMethod)item.getObject();
-
- final LookupElement[] allItems = context.getElements();
- final boolean overloadsMatter = allItems.length == 1 && item.getUserData(LookupItem.FORCE_SHOW_SIGNATURE_ATTR) == null;
-
- final boolean hasParams = MethodParenthesesHandler.hasParams(item, allItems, overloadsMatter, method);
-
- insertParentheses(context, item, overloadsMatter, hasParams);
-
- insertExplicitTypeParams(item, document, offset, file);
-
- final PsiType type = method.getReturnType();
- if (context.getCompletionChar() == '!' && type != null && PsiType.BOOLEAN.isAssignableFrom(type)) {
- PsiDocumentManager.getInstance(method.getProject()).commitDocument(document);
- final PsiMethodCallExpression methodCall = PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiMethodCallExpression.class, false);
- if (methodCall != null) {
- FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EXCLAMATION_FINISH);
- document.insertString(methodCall.getTextRange().getStartOffset(), "!");
- }
- }
-
- }
-
- private static boolean shouldInsertRParenth(char completionChar, TailType tailType, boolean hasParams) {
- if (tailType == TailType.SMART_COMPLETION) {
- return false;
- }
-
- if (completionChar == '(' && !hasParams) {
- //it's highly probable that the user will type ')' next and it may not be overwritten if the flag is off
- return CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET;
- }
-
- return true;
- }
-
- @NotNull
- private static TailType getTailType(final LookupElement item, InsertionContext context) {
- final char completionChar = context.getCompletionChar();
- if (completionChar == '!') return item instanceof LookupItem ? ((LookupItem)item).getTailType() : TailType.NONE;
- if (completionChar == '(') {
- final Object o = item.getObject();
- if (o instanceof PsiMethod) {
- final PsiMethod psiMethod = (PsiMethod)o;
- return psiMethod.getParameterList().getParameters().length > 0 || psiMethod.getReturnType() != PsiType.VOID
- ? TailType.NONE : TailType.SEMICOLON;
- } else if (o instanceof PsiClass) { // it may be a constructor
- return TailType.NONE;
- }
- }
- if (completionChar == Lookup.COMPLETE_STATEMENT_SELECT_CHAR) return TailType.SMART_COMPLETION;
- if (!context.shouldAddCompletionChar()) {
- return TailType.NONE;
- }
-
- return LookupItem.handleCompletionChar(context.getEditor(), item, completionChar);
- }
-
- public static boolean isToInsertParenth(PsiElement place){
- if (place == null) return true;
- return !(place.getParent() instanceof PsiImportStaticReferenceElement);
- }
-
- private static void insertExplicitTypeParams(final LookupElement item, final Document document, final int offset, PsiFile file) {
- final PsiMethod method = (PsiMethod)item.getObject();
- if (!SmartCompletionDecorator.hasUnboundTypeParams(method)) {
- return;
- }
-
- PsiDocumentManager.getInstance(file.getProject()).commitAllDocuments();
-
- PsiExpression expression = PsiTreeUtil.findElementOfClassAtOffset(file, offset - 1, PsiExpression.class, false);
- if (expression == null) return;
-
- final Project project = file.getProject();
- final ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getExpectedTypes(expression, true);
- if (expectedTypes == null) return;
-
- for (final ExpectedTypeInfo type : expectedTypes) {
- if (type.isInsertExplicitTypeParams()) {
- final OffsetMap map = new OffsetMap(document);
- final OffsetKey refOffsetKey = OffsetKey.create("refOffset");
- map.addOffset(refOffsetKey, offset - 1);
-
- final String typeParams = getTypeParamsText(method, type.getType());
- if (typeParams == null) {
- return;
- }
- final String qualifierText = getQualifierText(file, method, offset - 1);
-
- document.insertString(offset - method.getName().length(), qualifierText + typeParams);
- PsiDocumentManager.getInstance(project).commitDocument(document);
-
- final PsiReference reference = file.findReferenceAt(map.getOffset(refOffsetKey));
- if (reference instanceof PsiJavaCodeReferenceElement) {
- try {
- CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(
- JavaCodeStyleManager.getInstance(project).shortenClassReferences((PsiElement)reference));
- }
- catch (IncorrectOperationException e) {
- LOG.error(e);
- }
- }
- return;
- }
- }
-
-
- }
-
- private static String getQualifierText(PsiFile file, PsiMethod method, final int refOffset) {
- final PsiReference reference = file.findReferenceAt(refOffset);
- if (reference instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement)reference).isQualified()) {
- return "";
- }
-
- final PsiClass containingClass = method.getContainingClass();
- if (containingClass == null) {
- return "";
- }
-
- if (method.hasModifierProperty(PsiModifier.STATIC)) {
- return containingClass.getQualifiedName() + ".";
- }
-
- if (containingClass.getManager().areElementsEquivalent(containingClass, PsiTreeUtil.findElementOfClassAtOffset(file, refOffset, PsiClass.class, false))) {
- return "this.";
- }
-
- return containingClass.getQualifiedName() + ".this.";
- }
-
- @Nullable
- private static String getTypeParamsText(final PsiMethod method, PsiType expectedType) {
- final PsiSubstitutor substitutor = SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, expectedType);
- assert substitutor != null;
- final PsiTypeParameter[] parameters = method.getTypeParameters();
- assert parameters.length > 0;
- final StringBuilder builder = new StringBuilder("<");
- boolean first = true;
- for (final PsiTypeParameter parameter : parameters) {
- if (!first) builder.append(", ");
- first = false;
- final PsiType type = substitutor.substitute(parameter);
- if (type == null || type instanceof PsiWildcardType || type instanceof PsiCapturedWildcardType) return null;
-
- final String text = type.getCanonicalText();
- if (text.indexOf('?') >= 0) return null;
-
- builder.append(text);
- }
- return builder.append(">").toString();
- }
-}
package com.intellij.codeInsight.daemon.impl.actions;
import com.intellij.application.options.editor.AutoImportOptionsConfigurable;
-import com.intellij.application.options.editor.EditorOptionsProvider;
import com.intellij.application.options.editor.JavaAutoImportOptions;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
-import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
public void run() {
if (project.isDisposed()) return;
- final AutoImportOptionsConfigurable configurable = EditorOptionsProvider.EP_NAME.findExtension(AutoImportOptionsConfigurable.class);
+ final AutoImportOptionsConfigurable configurable = new AutoImportOptionsConfigurable();
ShowSettingsUtil.getInstance().editConfigurable(project, configurable, new Runnable() {
public void run() {
final JavaAutoImportOptions options = ContainerUtil.findInstance(configurable.getConfigurables(), JavaAutoImportOptions.class);
if (parameter == null) return null;
PsiType type = parameter.getType();
if (type instanceof PsiEllipsisType) type = ((PsiEllipsisType)type).toArrayType();
+ if (type instanceof PsiArrayType) return new PsiType[]{type};
final PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(type);
final PsiClass psiClass = result.getElement();
if (psiClass == null) return new PsiType[] {type};
return CodeStyleSettingsManager.getSettings(element.getProject()).SPACE_AFTER_COMMA;
}
- private static boolean isToStrikeout(LookupItem<?> item) {
+ public static boolean isToStrikeout(LookupItem<?> item) {
final List<PsiMethod> allMethods = item.getUserData(JavaCompletionUtil.ALL_METHODS_ATTRIBUTE);
if (allMethods != null){
for (PsiMethod method : allMethods) {
}
}
- declaration.done(JavaElementType.CLASS);
+ done(declaration, JavaElementType.CLASS);
return declaration;
}
if (builder.getTokenType() == JavaTokenType.LBRACE) {
final PsiBuilder.Marker constantInit = builder.mark();
parseClassBodyWithBraces(builder, false, false);
- constantInit.done(JavaElementType.ENUM_CONSTANT_INITIALIZER);
+ done(constantInit, JavaElementType.ENUM_CONSTANT_INITIALIZER);
}
- constant.done(JavaElementType.ENUM_CONSTANT);
+ done(constant, JavaElementType.ENUM_CONSTANT);
return constant;
}
else {
}
// adding a reference, not simple tokens allows "Browse ..." to work well
- final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, true, false);
+ final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, true, false, false);
if (ref == null) {
builder.advanceLexer();
}
final PsiBuilder.Marker error = typeParams.precede();
error.errorBefore(JavaErrorMessages.message("unexpected.token"), codeBlock);
}
- declaration.done(JavaElementType.CLASS_INITIALIZER);
+ done(declaration, JavaElementType.CLASS_INITIALIZER);
return declaration;
}
else {
}
}
- modList.done(JavaElementType.MODIFIER_LIST);
+ done(modList, JavaElementType.MODIFIER_LIST);
return Pair.create(modList, isEmpty);
}
final PsiBuilder.Marker receiver = builder.mark();
final PsiBuilder.Marker annotations = parseAnnotations(builder);
if (annotations != null) {
- receiver.done(JavaElementType.METHOD_RECEIVER);
+ done(receiver, JavaElementType.METHOD_RECEIVER);
}
else {
receiver.drop();
}
}
- declaration.done(anno ? JavaElementType.ANNOTATION_METHOD : JavaElementType.METHOD);
+ done(declaration, anno ? JavaElementType.ANNOTATION_METHOD : JavaElementType.METHOD);
return declaration;
}
}
// adding a reference, not simple tokens allows "Browse .." to work well
- final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, true, false);
+ final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, true, false, false);
if (ref == null && builder.getTokenType() != null) {
builder.advanceLexer();
}
invalidElements.error(errorMessage);
}
- paramList.done(JavaElementType.PARAMETER_LIST);
+ done(paramList, JavaElementType.PARAMETER_LIST);
return paramList;
}
final Pair<PsiBuilder.Marker, Boolean> modListInfo = parseModifierList(builder);
final PsiBuilder.Marker type = ellipsis ? ReferenceParser.parseTypeWithEllipsis(builder, true, true) :
- ReferenceParser.parseType(builder, true, true);
+ ReferenceParser.parseType(builder, true, true, false);
if (type == null && modListInfo.second) {
param.rollbackTo();
if (expect(builder, JavaTokenType.IDENTIFIER)) {
eatBrackets(builder);
- param.done(JavaElementType.PARAMETER);
+ done(param, JavaElementType.PARAMETER);
return param;
}
else {
}
if (builder.getTokenType() != JavaTokenType.COMMA) break;
- variable.done(varType);
+ done(variable, varType);
builder.advanceLexer();
if (builder.getTokenType() != JavaTokenType.IDENTIFIER) {
}
if (openMarker) {
- variable.done(varType);
+ done(variable, varType);
}
return declaration;
final PsiBuilder.Marker anno = builder.mark();
builder.advanceLexer();
- final PsiBuilder.Marker classRef = ReferenceParser.parseJavaCodeReference(builder, true, false, false);
+ final PsiBuilder.Marker classRef = ReferenceParser.parseJavaCodeReference(builder, true, false, false, false);
if (classRef == null) {
error(builder, JavaErrorMessages.message("expected.class.reference"));
}
parseAnnotationParameterList(builder);
- anno.done(JavaElementType.ANNOTATION);
+ done(anno, JavaElementType.ANNOTATION);
return anno;
}
PsiBuilder.Marker list = builder.mark();
if (!expect(builder, JavaTokenType.LPARENTH)) {
- list.done(JavaElementType.ANNOTATION_PARAMETER_LIST);
+ done(list, JavaElementType.ANNOTATION_PARAMETER_LIST);
return list;
}
if (expect(builder, JavaTokenType.RPARENTH)) {
- list.done(JavaElementType.ANNOTATION_PARAMETER_LIST);
+ done(list, JavaElementType.ANNOTATION_PARAMETER_LIST);
return list;
}
}
}
- list.done(JavaElementType.ANNOTATION_PARAMETER_LIST);
+ done(list, JavaElementType.ANNOTATION_PARAMETER_LIST);
return list;
}
if (mayBeSimple) {
parseAnnotationValue(builder);
if (builder.getTokenType() != JavaTokenType.EQ) {
- pair.done(JavaElementType.NAME_VALUE_PAIR);
+ done(pair, JavaElementType.NAME_VALUE_PAIR);
return false;
}
parseAnnotationValue(builder);
- pair.done(JavaElementType.NAME_VALUE_PAIR);
+ done(pair, JavaElementType.NAME_VALUE_PAIR);
return hasName;
}
builder.advanceLexer();
if (expect(builder, JavaTokenType.RBRACE)) {
- annoArray.done(JavaElementType.ANNOTATION_ARRAY_INITIALIZER);
+ done(annoArray, JavaElementType.ANNOTATION_ARRAY_INITIALIZER);
return annoArray;
}
}
}
- annoArray.done(JavaElementType.ANNOTATION_ARRAY_INITIALIZER);
+ done(annoArray, JavaElementType.ANNOTATION_ARRAY_INITIALIZER);
if (unclosed) {
annoArray.setCustomEdgeProcessors(null, GREEDY_RIGHT_EDGE_PROCESSOR);
}
final PsiBuilder.Marker copy = startMarker.precede();
startMarker.rollbackTo();
- final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, false, true, false);
+ final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, false, true, false, false);
if (ref == null || builder.getTokenType() != JavaTokenType.DOT) {
copy.rollbackTo();
return parsePrimary(builder, BreakPoint.P2);
else {
dotPos.drop();
final PsiBuilder.Marker refExpr = expr.precede();
- ReferenceParser.parseReferenceParameterList(builder, false);
+ ReferenceParser.parseReferenceParameterList(builder, false, false);
if (!JavaParserUtil.expectOrError(builder, JavaTokenType.IDENTIFIER, JavaErrorMessages.message("expected.identifier"))) {
refExpr.done(JavaElementType.REFERENCE_EXPRESSION);
final PsiBuilder.Marker newExpr = (start != null ? start.precede() : builder.mark());
builder.advanceLexer();
- ReferenceParser.parseReferenceParameterList(builder, false);
+ final boolean parseDiamonds = areDiamondsSupported(builder);
+ ReferenceParser.parseReferenceParameterList(builder, false, parseDiamonds);
final PsiBuilder.Marker refOrType;
final boolean parseAnnotations = areTypeAnnotationsSupported(builder) && builder.getTokenType() == JavaTokenType.AT;
final IElementType tokenType = builder.getTokenType();
if (tokenType == JavaTokenType.IDENTIFIER || parseAnnotations) {
- refOrType = ReferenceParser.parseJavaCodeReference(builder, true, true, parseAnnotations);
+ refOrType = ReferenceParser.parseJavaCodeReference(builder, true, true, parseAnnotations, parseDiamonds);
if (refOrType == null) {
error(builder, JavaErrorMessages.message("expected.identifier"));
newExpr.done(JavaElementType.NEW_EXPRESSION);
private static PsiBuilder.Marker parseClassObjectAccess(final PsiBuilder builder) {
final PsiBuilder.Marker expr = builder.mark();
- final PsiBuilder.Marker type = ReferenceParser.parseType(builder, false, false);
+ final PsiBuilder.Marker type = ReferenceParser.parseType(builder, false, false, false);
if (type == null) {
expr.drop();
return null;
import org.jetbrains.annotations.Nullable;
import static com.intellij.lang.PsiBuilderUtil.expect;
+import static com.intellij.lang.java.parser.JavaParserUtil.done;
+import static com.intellij.lang.java.parser.JavaParserUtil.exprType;
import static com.intellij.lang.java.parser.JavaParserUtil.semicolon;
public class FileParser {
+ public interface TopLevelDeclarationParser {
+ @Nullable PsiBuilder.Marker parse(PsiBuilder builder);
+ }
+
private static final TokenSet IMPORT_LIST_STOPPER_SET = TokenSet.orSet(
ElementType.MODIFIER_BIT_SET,
TokenSet.create(JavaTokenType.CLASS_KEYWORD, JavaTokenType.INTERFACE_KEYWORD, JavaTokenType.ENUM_KEYWORD, JavaTokenType.AT));
+ private static final TopLevelDeclarationParser TOP_LEVEL_DECLARATION_PARSER = new TopLevelDeclarationParser() {
+ public PsiBuilder.Marker parse(final PsiBuilder builder) {
+ return DeclarationParser.parse(builder, DeclarationParser.Context.FILE);
+ }
+ };
+
private FileParser() { }
public static void parse(final PsiBuilder builder) {
+ parseFile(builder, IMPORT_LIST_STOPPER_SET, TOP_LEVEL_DECLARATION_PARSER, JavaErrorMessages.message("expected.class.or.interface"));
+ }
+
+ public static void parseFile(final PsiBuilder builder, final TokenSet importListStoppers,
+ final TopLevelDeclarationParser declarationParser, final String errorMessage) {
parsePackageStatement(builder);
- parseImportList(builder);
+ final Pair<PsiBuilder.Marker, Boolean> impListInfo = parseImportList(builder, importListStoppers);
+ Boolean firstDeclarationOk = null;
+ PsiBuilder.Marker firstDeclaration = null;
PsiBuilder.Marker invalidElements = null;
while (!builder.eof()) {
if (builder.getTokenType() == JavaTokenType.SEMICOLON) {
if (invalidElements != null) {
- invalidElements.error(JavaErrorMessages.message("expected.class.or.interface"));
+ invalidElements.error(errorMessage);
invalidElements = null;
}
builder.advanceLexer();
+ if (firstDeclarationOk == null) firstDeclarationOk = false;
continue;
}
- final PsiBuilder.Marker declaration = DeclarationParser.parse(builder, DeclarationParser.Context.FILE);
+ final PsiBuilder.Marker declaration = declarationParser.parse(builder);
if (declaration != null) {
if (invalidElements != null) {
- invalidElements.errorBefore(JavaErrorMessages.message("expected.class.or.interface"), declaration);
+ invalidElements.errorBefore(errorMessage, declaration);
invalidElements = null;
}
+ if (firstDeclarationOk == null) {
+ firstDeclarationOk = exprType(declaration) != JavaElementType.MODIFIER_LIST;
+ if (firstDeclarationOk) {
+ firstDeclaration = declaration;
+ }
+ }
continue;
}
invalidElements = builder.mark();
}
builder.advanceLexer();
+ if (firstDeclarationOk == null) firstDeclarationOk = false;
}
if (invalidElements != null) {
- invalidElements.error(JavaErrorMessages.message("expected.class.or.interface"));
+ invalidElements.error(errorMessage);
+ }
+
+ if (impListInfo.second && firstDeclarationOk == Boolean.TRUE) {
+ impListInfo.first.setCustomEdgeProcessors(JavaParserUtil.PRECEDING_COMMENT_BINDER, null); // pass comments behind fake import list
+ firstDeclaration.setCustomEdgeProcessors(JavaParserUtil.SPECIAL_PRECEDING_COMMENT_BINDER, null);
}
}
if (!expect(builder, JavaTokenType.PACKAGE_KEYWORD)) {
final PsiBuilder.Marker modList = builder.mark();
DeclarationParser.parseAnnotations(builder);
- modList.done(JavaElementType.MODIFIER_LIST);
+ done(modList, JavaElementType.MODIFIER_LIST);
if (!expect(builder, JavaTokenType.PACKAGE_KEYWORD)) {
statement.rollbackTo();
return null;
}
}
- final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, false, false);
+ final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, false, false, false);
if (ref == null) {
statement.rollbackTo();
return null;
semicolon(builder);
- statement.done(JavaElementType.PACKAGE_STATEMENT);
+ done(statement, JavaElementType.PACKAGE_STATEMENT);
return statement;
}
- @NotNull
- private static Pair<PsiBuilder.Marker, Boolean> parseImportList(final PsiBuilder builder) {
- return parseImportList(builder, IMPORT_LIST_STOPPER_SET);
- }
-
@NotNull
public static Pair<PsiBuilder.Marker, Boolean> parseImportList(final PsiBuilder builder, final TokenSet stoppers) {
final PsiBuilder.Marker list = builder.mark();
}
}
- list.done(JavaElementType.IMPORT_LIST);
+ done(list, JavaElementType.IMPORT_LIST);
return Pair.create(list, isEmpty);
}
semicolon(builder);
}
- statement.done(type);
+ done(statement, type);
return statement;
}
}
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiParser;
import com.intellij.pom.java.LanguageLevel;
-import com.intellij.psi.impl.source.parsing.ParseUtil;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
FileParser.parse(builder);
root.done(rootType);
- final ASTNode rootNode = builder.getTreeBuilt();
- ParseUtil.bindComments(rootNode);
- return rootNode;
+ return builder.getTreeBuilt();
}
}
import com.intellij.codeInsight.daemon.JavaErrorMessages;
import com.intellij.lang.*;
import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.JavaTokenType;
+import com.intellij.psi.impl.source.tree.ElementType;
+import com.intellij.psi.impl.source.tree.JavaDocElementType;
+import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.diff.FlyweightCapableTreeStructure;
private static final Key<LanguageLevel> LANG_LEVEL_KEY = Key.create("JavaParserUtil.LanguageLevel");
public static final WhitespacesAndCommentsProcessor GREEDY_RIGHT_EDGE_PROCESSOR = new WhitespacesAndCommentsProcessor() {
- public int process(final List<IElementType> tokens) {
+ public int process(final List<IElementType> tokens, final boolean atStreamEdge, final TokenTextGetter getter) {
return tokens.size();
}
};
+ private static class PrecedingWhitespacesAndCommentsProcessor implements WhitespacesAndCommentsProcessor {
+ private final boolean myAfterEmptyImport;
+
+ public PrecedingWhitespacesAndCommentsProcessor(final boolean afterImport) {
+ this.myAfterEmptyImport = afterImport;
+ }
+
+ public int process(final List<IElementType> tokens, final boolean atStreamEdge, final TokenTextGetter
+ getter) {
+ if (tokens.size() == 0) return 0;
+
+ // 1. bind doc comment
+ for (int idx = tokens.size() - 1; idx >= 0; idx--) {
+ if (tokens.get(idx) == JavaDocElementType.DOC_COMMENT) return idx;
+ }
+
+ // 2. bind plain comments
+ int result = tokens.size();
+ for (int idx = tokens.size() - 1; idx >= 0; idx--) {
+ final IElementType tokenType = tokens.get(idx);
+ if (ElementType.JAVA_WHITESPACE_BIT_SET.contains(tokenType)) {
+ if (StringUtil.getLineBreakCount(getter.get(idx)) > 1) break;
+ }
+ else if (ElementType.JAVA_PLAIN_COMMENT_BIT_SET.contains(tokenType)) {
+ if (atStreamEdge ||
+ (idx == 0 && myAfterEmptyImport) ||
+ (idx > 0 && ElementType.JAVA_WHITESPACE_BIT_SET.contains(tokens.get(idx - 1)) && StringUtil.containsLineBreak(getter.get(idx - 1)))) {
+ result = idx;
+ }
+ }
+ else break;
+ }
+
+ return result;
+ }
+ }
+
+ private static class TrailingWhitespacesAndCommentsProcessor implements WhitespacesAndCommentsProcessor {
+ public int process(final List<IElementType> tokens, final boolean atStreamEdge, final TokenTextGetter getter) {
+ if (tokens.size() == 0) return 0;
+
+ int result = 0;
+ for (int idx = 0; idx < tokens.size(); idx++) {
+ final IElementType tokenType = tokens.get(idx);
+ if (ElementType.JAVA_WHITESPACE_BIT_SET.contains(tokenType)) {
+ if (StringUtil.containsLineBreak(getter.get(idx))) break;
+ }
+ else if (ElementType.JAVA_PLAIN_COMMENT_BIT_SET.contains(tokenType)) {
+ result = idx + 1;
+ }
+ else break;
+ }
+
+ return result;
+ }
+ }
+
+ private static final TokenSet PRECEDING_COMMENT_SET = ElementType.FULL_MEMBER_BIT_SET;
+ private static final TokenSet TRAILING_COMMENT_SET = TokenSet.orSet(
+ TokenSet.create(JavaElementType.PACKAGE_STATEMENT),
+ ElementType.IMPORT_STATEMENT_BASE_BIT_SET, ElementType.FULL_MEMBER_BIT_SET, ElementType.JAVA_STATEMENT_BIT_SET);
+
+ public static final WhitespacesAndCommentsProcessor PRECEDING_COMMENT_BINDER = new PrecedingWhitespacesAndCommentsProcessor(false);
+ public static final WhitespacesAndCommentsProcessor SPECIAL_PRECEDING_COMMENT_BINDER = new PrecedingWhitespacesAndCommentsProcessor(true);
+ public static final WhitespacesAndCommentsProcessor TRAILING_COMMENT_BINDER = new TrailingWhitespacesAndCommentsProcessor();
+
private JavaParserUtil() { }
public static void setLanguageLevel(final PsiBuilder builder, final LanguageLevel level) {
}
public static boolean areTypeAnnotationsSupported(final PsiBuilder builder) {
- final LanguageLevel level = getLanguageLevel(builder);
- return level.isAtLeast(LanguageLevel.JDK_1_7);
+ return getLanguageLevel(builder).isAtLeast(LanguageLevel.JDK_1_7);
+ }
+
+ public static boolean areDiamondsSupported(final PsiBuilder builder) {
+ return getLanguageLevel(builder).isAtLeast(LanguageLevel.JDK_1_7);
}
@NotNull
return level;
}
+ public static void done(final PsiBuilder.Marker marker, final IElementType type) {
+ marker.done(type);
+ final WhitespacesAndCommentsProcessor left = PRECEDING_COMMENT_SET.contains(type) ? PRECEDING_COMMENT_BINDER : null;
+ final WhitespacesAndCommentsProcessor right = TRAILING_COMMENT_SET.contains(type) ? TRAILING_COMMENT_BINDER : null;
+ marker.setCustomEdgeProcessors(left, right);
+ }
+
@Nullable
public static IElementType exprType(@Nullable final PsiBuilder.Marker marker) {
return marker != null ? ((LighterASTNode)marker).getTokenType() : null;
}
- // used instead of PsiBuilder.error() as it drops all but first subsequent error messages
+ // used instead of PsiBuilder.error() as it keeps all subsequent error messages
public static void error(final PsiBuilder builder, final String message) {
builder.mark().error(message);
}
import static com.intellij.lang.PsiBuilderUtil.expect;
import static com.intellij.lang.PsiBuilderUtil.nextTokenType;
import static com.intellij.lang.java.parser.JavaParserUtil.*;
+import static com.intellij.lang.java.parser.JavaParserUtil.emptyElement;
public class ReferenceParser {
@Nullable
public static TypeInfo parseType(final PsiBuilder builder) {
- return parseTypeWithInfo(builder, true, true);
+ return parseTypeWithInfo(builder, true, true, false);
}
@Nullable
- public static PsiBuilder.Marker parseType(final PsiBuilder builder, final boolean eatLastDot, final boolean wildcard) {
- final TypeInfo typeInfo = parseTypeWithInfo(builder, eatLastDot, wildcard);
+ public static PsiBuilder.Marker parseType(final PsiBuilder builder, final boolean eatLastDot, final boolean wildcard, final boolean diamonds) {
+ final TypeInfo typeInfo = parseTypeWithInfo(builder, eatLastDot, wildcard, diamonds);
return typeInfo != null ? typeInfo.marker : null;
}
@Nullable
public static PsiBuilder.Marker parseTypeWithEllipsis(final PsiBuilder builder, final boolean eatLastDot, final boolean wildcard) {
- final TypeInfo typeInfo = parseTypeWithInfo(builder, eatLastDot, wildcard);
+ final TypeInfo typeInfo = parseTypeWithInfo(builder, eatLastDot, wildcard, false);
if (typeInfo == null) return null;
PsiBuilder.Marker type = typeInfo.marker;
}
@Nullable
- private static TypeInfo parseTypeWithInfo(final PsiBuilder builder, final boolean eatLastDot, final boolean wildcard) {
+ private static TypeInfo parseTypeWithInfo(final PsiBuilder builder, final boolean eatLastDot, final boolean wildcard, final boolean diamonds) {
if (builder.getTokenType() == null) return null;
final TypeInfo typeInfo = new TypeInfo();
typeInfo.isPrimitive = true;
}
else if (tokenType == JavaTokenType.IDENTIFIER) {
- parseJavaCodeReference(builder, eatLastDot, true, annotationsSupported, false, false, typeInfo);
+ parseJavaCodeReference(builder, eatLastDot, true, annotationsSupported, false, false, diamonds, typeInfo);
}
else if (wildcard && tokenType == JavaTokenType.QUEST) {
type.drop();
typeInfo.marker = parseWildcardType(builder);
return typeInfo.marker != null ? typeInfo : null;
}
+ else if (diamonds && tokenType == JavaTokenType.GT) {
+ emptyElement(builder, JavaElementType.DIAMOND_TYPE);
+ type.done(JavaElementType.TYPE);
+ typeInfo.marker = type;
+ return typeInfo;
+ }
else {
type.drop();
return null;
builder.advanceLexer();
if (expect(builder, WILDCARD_KEYWORD_SET)) {
- final PsiBuilder.Marker boundType = parseType(builder, true, false);
+ final PsiBuilder.Marker boundType = parseType(builder, true, false, false);
if (boundType == null) {
error(builder, JavaErrorMessages.message("expected.type"));
}
@Nullable
public static PsiBuilder.Marker parseJavaCodeReference(final PsiBuilder builder, final boolean eatLastDot,
- final boolean parameterList, final boolean annotations) {
- return parseJavaCodeReference(builder, eatLastDot, parameterList, annotations, false, false, new TypeInfo());
+ final boolean parameterList, final boolean annotations, final boolean diamonds) {
+ return parseJavaCodeReference(builder, eatLastDot, parameterList, annotations, false, false, diamonds, new TypeInfo());
}
public static boolean parseImportCodeReference(final PsiBuilder builder, final boolean isStatic) {
final TypeInfo typeInfo = new TypeInfo();
- parseJavaCodeReference(builder, true, false, false, true, isStatic, typeInfo);
+ parseJavaCodeReference(builder, true, false, false, true, isStatic, false, typeInfo);
return !typeInfo.hasErrors;
}
private static PsiBuilder.Marker parseJavaCodeReference(final PsiBuilder builder, final boolean eatLastDot,
final boolean parameterList, final boolean annotations,
final boolean isImport, final boolean isStaticImport,
- final TypeInfo typeInfo) {
+ final boolean diamonds, final TypeInfo typeInfo) {
PsiBuilder.Marker refElement = builder.mark();
if (annotations) {
if (parameterList) {
typeInfo.isParameterized = (builder.getTokenType() == JavaTokenType.LT);
- parseReferenceParameterList(builder, true);
+ parseReferenceParameterList(builder, true, diamonds);
}
else {
if (!isStaticImport || builder.getTokenType() == JavaTokenType.DOT) {
if (parameterList) {
typeInfo.isParameterized = (builder.getTokenType() == JavaTokenType.LT);
- parseReferenceParameterList(builder, true);
+ parseReferenceParameterList(builder, true, diamonds);
}
else if (!isStaticImport || builder.getTokenType() == JavaTokenType.DOT) {
emptyElement(builder, JavaElementType.REFERENCE_PARAMETER_LIST);
}
@NotNull
- public static PsiBuilder.Marker parseReferenceParameterList(final PsiBuilder builder, final boolean wildcard) {
+ public static PsiBuilder.Marker parseReferenceParameterList(final PsiBuilder builder, final boolean wildcard, final boolean diamonds) {
final PsiBuilder.Marker list = builder.mark();
if (!expect(builder, JavaTokenType.LT)) {
list.done(JavaElementType.REFERENCE_PARAMETER_LIST);
}
while (true) {
- final PsiBuilder.Marker type = parseType(builder, true, wildcard);
+ final PsiBuilder.Marker type = parseType(builder, true, wildcard, diamonds);
if (type == null) {
error(builder, JavaErrorMessages.message("expected.identifier"));
}
if (expect(builder, start)) {
while (true) {
- final PsiBuilder.Marker classReference = parseJavaCodeReference(builder, true, true, true);
+ final PsiBuilder.Marker classReference = parseJavaCodeReference(builder, true, true, true, false);
if (classReference == null) {
error(builder, JavaErrorMessages.message("expected.identifier"));
}
final boolean greedyBlock = !expectOrError(builder, JavaTokenType.RBRACE, JavaErrorMessages.message("expected.rbrace"));
- codeBlock.done(JavaElementType.CODE_BLOCK);
+ done(codeBlock, JavaElementType.CODE_BLOCK);
if (greedyBlock) {
codeBlock.setCustomEdgeProcessors(null, GREEDY_RIGHT_EDGE_PROCESSOR);
}
else if (tokenType == JavaTokenType.SEMICOLON) {
final PsiBuilder.Marker empty = builder.mark();
builder.advanceLexer();
- empty.done(JavaElementType.EMPTY_STATEMENT);
+ done(empty, JavaElementType.EMPTY_STATEMENT);
return empty;
}
else if (tokenType == JavaTokenType.IDENTIFIER || tokenType == JavaTokenType.AT) {
final PsiBuilder.Marker declStatement = builder.mark();
final PsiBuilder.Marker decl = DeclarationParser.parse(builder, DeclarationParser.Context.CODE_BLOCK);
if (decl == null) {
- ReferenceParser.parseType(builder, false, false);
+ ReferenceParser.parseType(builder, false, false, false);
error(builder, JavaErrorMessages.message("expected.identifier"));
}
- declStatement.done(JavaElementType.DECLARATION_STATEMENT);
+ done(declStatement, JavaElementType.DECLARATION_STATEMENT);
return declStatement;
}
}
}
if (count > 1) {
pos.drop();
- list.done(JavaElementType.EXPRESSION_LIST);
+ done(list, JavaElementType.EXPRESSION_LIST);
semicolon(builder);
- statement.done(JavaElementType.EXPRESSION_LIST_STATEMENT);
+ done(statement, JavaElementType.EXPRESSION_LIST_STATEMENT);
return statement;
}
if (exprType(expr) != JavaElementType.REFERENCE_EXPRESSION) {
drop(list, pos);
semicolon(builder);
- statement.done(JavaElementType.EXPRESSION_STATEMENT);
+ done(statement, JavaElementType.EXPRESSION_STATEMENT);
return statement;
}
pos.rollbackTo();
final PsiBuilder.Marker decl = DeclarationParser.parse(builder, DeclarationParser.Context.CODE_BLOCK);
if (decl != null) {
final PsiBuilder.Marker statement = decl.precede();
- statement.done(JavaElementType.DECLARATION_STATEMENT);
+ done(statement, JavaElementType.DECLARATION_STATEMENT);
return statement;
}
final PsiBuilder.Marker statement = builder.mark();
advance(builder, 2);
parseStatement(builder);
- statement.done(JavaElementType.LABELED_STATEMENT);
+ done(statement, JavaElementType.LABELED_STATEMENT);
return statement;
}
final PsiBuilder.Marker statement = builder.mark();
ExpressionParser.parse(builder);
semicolon(builder);
- statement.done(JavaElementType.EXPRESSION_STATEMENT);
+ done(statement, JavaElementType.EXPRESSION_STATEMENT);
return statement;
}
builder.advanceLexer();
if (!parseExpressionInParenth(builder)) {
- statement.done(JavaElementType.IF_STATEMENT);
+ done(statement, JavaElementType.IF_STATEMENT);
return statement;
}
final PsiBuilder.Marker thenStatement = parseStatement(builder);
if (thenStatement == null) {
error(builder, JavaErrorMessages.message("expected.statement"));
- statement.done(JavaElementType.IF_STATEMENT);
+ done(statement, JavaElementType.IF_STATEMENT);
return statement;
}
if (!expect(builder, JavaTokenType.ELSE_KEYWORD)) {
- statement.done(JavaElementType.IF_STATEMENT);
+ done(statement, JavaElementType.IF_STATEMENT);
return statement;
}
error(builder, JavaErrorMessages.message("expected.statement"));
}
- statement.done(JavaElementType.IF_STATEMENT);
+ done(statement, JavaElementType.IF_STATEMENT);
return statement;
}
builder.advanceLexer();
if (!parseExpressionInParenth(builder)) {
- statement.done(JavaElementType.WHILE_STATEMENT);
+ done(statement, JavaElementType.WHILE_STATEMENT);
return statement;
}
error(builder, JavaErrorMessages.message("expected.statement"));
}
- statement.done(JavaElementType.WHILE_STATEMENT);
+ done(statement, JavaElementType.WHILE_STATEMENT);
return statement;
}
if (!expect(builder, JavaTokenType.LPARENTH)) {
error(builder, JavaErrorMessages.message("expected.lparen"));
- statement.done(JavaElementType.FOR_STATEMENT);
+ done(statement, JavaElementType.FOR_STATEMENT);
return statement;
}
if (init == null){
error(builder, JavaErrorMessages.message("expected.statement"));
if (!expect(builder, JavaTokenType.RPARENTH)) {
- statement.done(JavaElementType.FOR_STATEMENT);
+ done(statement, JavaElementType.FOR_STATEMENT);
return statement;
}
}
if (!expect(builder, JavaTokenType.SEMICOLON)) {
error(builder, JavaErrorMessages.message("expected.semicolon"));
if (!expect(builder, JavaTokenType.RPARENTH)) {
- statement.done(JavaElementType.FOR_STATEMENT);
+ done(statement, JavaElementType.FOR_STATEMENT);
return statement;
}
}
parseExpressionOrExpressionList(builder);
if (!expect(builder, JavaTokenType.RPARENTH)) {
error(builder, JavaErrorMessages.message("expected.rparen"));
- statement.done(JavaElementType.FOR_STATEMENT);
+ done(statement, JavaElementType.FOR_STATEMENT);
return statement;
}
}
error(builder, JavaErrorMessages.message("expected.statement"));
}
- statement.done(JavaElementType.FOR_STATEMENT);
+ done(statement, JavaElementType.FOR_STATEMENT);
return statement;
}
final PsiBuilder.Marker expressionStatement;
if (builder.getTokenType() != JavaTokenType.COMMA) {
expressionStatement = expr.precede();
- expressionStatement.done(JavaElementType.EXPRESSION_STATEMENT);
+ done(expressionStatement, JavaElementType.EXPRESSION_STATEMENT);
}
else {
final PsiBuilder.Marker expressionList = expr.precede();
}
while (builder.getTokenType() == JavaTokenType.COMMA);
- expressionList.done(JavaElementType.EXPRESSION_LIST);
- expressionStatement.done(JavaElementType.EXPRESSION_LIST_STATEMENT);
+ done(expressionList, JavaElementType.EXPRESSION_LIST);
+ done(expressionStatement, JavaElementType.EXPRESSION_LIST_STATEMENT);
}
}
error(builder, JavaErrorMessages.message("expected.rparen"));
}
- statement.done(JavaElementType.FOREACH_STATEMENT);
+ done(statement, JavaElementType.FOREACH_STATEMENT);
return statement;
}
final PsiBuilder.Marker body = parseStatement(builder);
if (body == null) {
error(builder, JavaErrorMessages.message("expected.statement"));
- statement.done(JavaElementType.DO_WHILE_STATEMENT);
+ done(statement, JavaElementType.DO_WHILE_STATEMENT);
return statement;
}
if (!expect(builder, JavaTokenType.WHILE_KEYWORD)) {
error(builder, JavaErrorMessages.message("expected.while"));
- statement.done(JavaElementType.DO_WHILE_STATEMENT);
+ done(statement, JavaElementType.DO_WHILE_STATEMENT);
return statement;
}
semicolon(builder);
}
- statement.done(JavaElementType.DO_WHILE_STATEMENT);
+ done(statement, JavaElementType.DO_WHILE_STATEMENT);
return statement;
}
builder.advanceLexer();
if (!parseExpressionInParenth(builder)) {
- statement.done(JavaElementType.SWITCH_STATEMENT);
+ done(statement, JavaElementType.SWITCH_STATEMENT);
return statement;
}
error(builder, JavaErrorMessages.message("expected.lbrace"));
}
- statement.done(JavaElementType.SWITCH_STATEMENT);
+ done(statement, JavaElementType.SWITCH_STATEMENT);
return statement;
}
expectOrError(builder, JavaTokenType.COLON, JavaErrorMessages.message("expected.colon"));
- statement.done(JavaElementType.SWITCH_LABEL_STATEMENT);
+ done(statement, JavaElementType.SWITCH_LABEL_STATEMENT);
return statement;
}
builder.advanceLexer();
expect(builder, JavaTokenType.IDENTIFIER);
semicolon(builder);
- statement.done(JavaElementType.BREAK_STATEMENT);
+ done(statement, JavaElementType.BREAK_STATEMENT);
return statement;
}
builder.advanceLexer();
expect(builder, JavaTokenType.IDENTIFIER);
semicolon(builder);
- statement.done(JavaElementType.CONTINUE_STATEMENT);
+ done(statement, JavaElementType.CONTINUE_STATEMENT);
return statement;
}
ExpressionParser.parse(builder);
semicolon(builder);
- statement.done(JavaElementType.RETURN_STATEMENT);
+ done(statement, JavaElementType.RETURN_STATEMENT);
return statement;
}
final PsiBuilder.Marker expr = ExpressionParser.parse(builder);
if (expr == null) {
error(builder, JavaErrorMessages.message("expected.expression"));
- statement.done(JavaElementType.THROW_STATEMENT);
+ done(statement, JavaElementType.THROW_STATEMENT);
return statement;
}
semicolon(builder);
- statement.done(JavaElementType.THROW_STATEMENT);
+ done(statement, JavaElementType.THROW_STATEMENT);
return statement;
}
builder.advanceLexer();
if (!parseExpressionInParenth(builder)) {
- statement.done(JavaElementType.SYNCHRONIZED_STATEMENT);
+ done(statement, JavaElementType.SYNCHRONIZED_STATEMENT);
return statement;
}
error(builder, JavaErrorMessages.message("expected.lbrace"));
}
- statement.done(JavaElementType.SYNCHRONIZED_STATEMENT);
+ done(statement, JavaElementType.SYNCHRONIZED_STATEMENT);
return statement;
}
final PsiBuilder.Marker tryBlock = parseCodeBlock(builder);
if (tryBlock == null) {
error(builder, JavaErrorMessages.message("expected.lbrace"));
- statement.done(JavaElementType.TRY_STATEMENT);
+ done(statement, JavaElementType.TRY_STATEMENT);
return statement;
}
if (!TRY_CLOSERS_SET.contains(builder.getTokenType())) {
error(builder, JavaErrorMessages.message("expected.catch.or.finally"));
- statement.done(JavaElementType.TRY_STATEMENT);
+ done(statement, JavaElementType.TRY_STATEMENT);
return statement;
}
}
}
- statement.done(JavaElementType.TRY_STATEMENT);
+ done(statement, JavaElementType.TRY_STATEMENT);
return statement;
}
if (!expect(builder, JavaTokenType.LPARENTH)) {
error(builder, JavaErrorMessages.message("expected.lparen"));
- section.done(JavaElementType.CATCH_SECTION);
+ done(section, JavaElementType.CATCH_SECTION);
return false;
}
if (!expect(builder, JavaTokenType.RPARENTH)) {
error(builder, JavaErrorMessages.message("expected.rparen"));
- section.done(JavaElementType.CATCH_SECTION);
+ done(section, JavaElementType.CATCH_SECTION);
return false;
}
final PsiBuilder.Marker body = parseCodeBlock(builder);
if (body == null) {
error(builder, JavaErrorMessages.message("expected.lbrace"));
- section.done(JavaElementType.CATCH_SECTION);
+ done(section, JavaElementType.CATCH_SECTION);
return false;
}
- section.done(JavaElementType.CATCH_SECTION);
+ done(section, JavaElementType.CATCH_SECTION);
return true;
}
final PsiBuilder.Marker expr = ExpressionParser.parse(builder);
if (expr == null) {
error(builder, JavaErrorMessages.message("expected.boolean.expression"));
- statement.done(JavaElementType.ASSERT_STATEMENT);
+ done(statement, JavaElementType.ASSERT_STATEMENT);
return statement;
}
final PsiBuilder.Marker expr2 = ExpressionParser.parse(builder);
if (expr2 == null) {
error(builder, JavaErrorMessages.message("expected.expression"));
- statement.done(JavaElementType.ASSERT_STATEMENT);
+ done(statement, JavaElementType.ASSERT_STATEMENT);
return statement;
}
}
semicolon(builder);
- statement.done(JavaElementType.ASSERT_STATEMENT);
+ done(statement, JavaElementType.ASSERT_STATEMENT);
return statement;
}
private static PsiBuilder.Marker parseBlockStatement(final PsiBuilder builder) {
final PsiBuilder.Marker statement = builder.mark();
parseCodeBlock(builder);
- statement.done(JavaElementType.BLOCK_STATEMENT);
+ done(statement, JavaElementType.BLOCK_STATEMENT);
return statement;
}
*/
package com.intellij.psi.impl.source;
+import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
import com.intellij.lang.StdLanguages;
if(rootPackage != null) rootPackage.processDeclarations(processor, state, null, place);
}
- // todo[dsl] class processing
final PsiImportList importList = getImportList();
final PsiImportStaticStatement[] importStaticStatements = importList.getImportStaticStatements();
if (importStaticStatements.length > 0) {
final StaticImportFilteringProcessor staticImportProcessor = new StaticImportFilteringProcessor(processor, null);
+ boolean forCompletion = Boolean.TRUE.equals(processor.getHint(JavaCompletionProcessor.JAVA_COMPLETION));
+
// single member processing
for (PsiImportStaticStatement importStaticStatement : importStaticStatements) {
- if (!importStaticStatement.isOnDemand()) {
+ if (!importStaticStatement.isOnDemand() && !forCompletion) {
final String referenceName = importStaticStatement.getReferenceName();
final PsiClass targetElement = importStaticStatement.resolveTargetClass();
if (targetElement != null) {
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.CompositePsiElement;
+import com.intellij.psi.impl.source.tree.ElementType;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.util.IncorrectOperationException;
@NotNull
public PsiAnnotation[] getAnnotations() {
- return getChildrenAsPsiElements(JavaElementType.ANNOTATIONS, PsiAnnotation.PSI_ANNOTATION_ARRAY_CONSTRUCTOR);
+ return getChildrenAsPsiElements(ElementType.ANNOTATIONS, PsiAnnotation.PSI_ANNOTATION_ARRAY_CONSTRUCTOR);
}
public PsiAnnotation findAnnotation(@NotNull @NonNls String qualifiedName) {
inserter.invoke();
}
- public static void bindComments(final ASTNode root) {
- JavaMissingTokenInserter.bindComments(root);
- }
-
private static class JavaMissingTokenInserter extends MissingTokenInserter {
public JavaMissingTokenInserter(final CompositeElement root,
final Lexer lexer,
}
public PsiVariable resolveReferencedVariable(@NotNull String referenceText, PsiElement context) {
+ return resolveVar(referenceText, context, null);
+ }
+
+ @Override
+ public PsiVariable resolveAccessibleReferencedVariable(@NotNull String referenceText, PsiElement context) {
+ final boolean[] problemWithAccess = new boolean[1];
+ PsiVariable variable = resolveVar(referenceText, context, problemWithAccess);
+ return problemWithAccess[0] ? null : variable;
+ }
+
+ @Nullable
+ private PsiVariable resolveVar(String referenceText, PsiElement context, boolean[] problemWithAccess) {
final FileElement holderElement = DummyHolderFactory.createHolder(myManager, context).getTreeElement();
TreeElement ref = Parsing.parseJavaCodeReferenceText(myManager, referenceText, holderElement.getCharTable());
if (ref == null) return null;
holderElement.rawAddChildren(ref);
PsiJavaCodeReferenceElement psiRef = (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(ref);
- return ResolveVariableUtil.resolveVariable(psiRef, null, null);
+ return ResolveVariableUtil.resolveVariable(psiRef, problemWithAccess, null);
}
public boolean isAccessible(@NotNull PsiMember member, @NotNull PsiElement place, @Nullable PsiClass accessObjectClass) {
TokenSet MEMBER_BIT_SET = TokenSet.create(CLASS, FIELD, ENUM_CONSTANT, METHOD, ANNOTATION_METHOD);
TokenSet FULL_MEMBER_BIT_SET = TokenSet.orSet(MEMBER_BIT_SET,
TokenSet.create(CLASS_INITIALIZER));
+ TokenSet ANNOTATIONS = TokenSet.create(ANNOTATION);
}
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IErrorCounterReparseableElementType;
import com.intellij.psi.tree.ILazyParseableElementType;
-import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.tree.java.IJavaElementType;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.CharTable;
IElementType MODIFIER_LIST = JavaStubElementTypes.MODIFIER_LIST;
IElementType ANNOTATION = JavaStubElementTypes.ANNOTATION;
- TokenSet ANNOTATIONS = TokenSet.create(ANNOTATION);
IElementType EXTENDS_LIST = JavaStubElementTypes.EXTENDS_LIST;
IElementType IMPLEMENTS_LIST = JavaStubElementTypes.IMPLEMENTS_LIST;
IElementType FIELD = JavaStubElementTypes.FIELD;
if (isEnum()) {
if (!ENUM_CONSTANT_LIST_ELEMENTS_BIT_SET.contains(first.getElementType())) {
ASTNode semicolonPlace = findEnumConstantListDelimiterPlace();
- if (semicolonPlace == null || semicolonPlace.getElementType() != SEMICOLON) {
+ boolean commentsOrWhiteSpaces = true;
+ for (ASTNode child = first; child != null; child = child.getTreeNext()) {
+ if (!StdTokenSets.WHITE_SPACE_OR_COMMENT_BIT_SET.contains(child.getElementType())) {
+ commentsOrWhiteSpaces = false;
+ break;
+ }
+ }
+ if (!commentsOrWhiteSpaces && (semicolonPlace == null || semicolonPlace.getElementType() != SEMICOLON)) {
final LeafElement semicolon = Factory.createSingleLeafElement(SEMICOLON, ";", 0, 1,
SharedImplUtil.findCharTableByTree(this), getManager());
addInternal(semicolon, semicolon, semicolonPlace, Boolean.FALSE);
import com.intellij.psi.impl.meta.MetaRegistry;
import com.intellij.psi.impl.source.JavaStubPsiElement;
import com.intellij.psi.impl.source.tree.ChildRole;
-import com.intellij.psi.impl.source.tree.JavaElementType;
+import com.intellij.psi.impl.source.tree.ElementType;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.meta.PsiMetaData;
import com.intellij.psi.scope.PsiScopeProcessor;
@NotNull
public PsiAnnotation[] getAnnotations() {
- return getStubOrPsiChildren(JavaElementType.ANNOTATIONS, PsiAnnotation.ARRAY_FACTORY);
+ return getStubOrPsiChildren(ElementType.ANNOTATIONS, PsiAnnotation.ARRAY_FACTORY);
}
public PsiAnnotation findAnnotation(@NotNull @NonNls String qualifiedName) {
return ((CompositeElement)oldParent).getChildRole(oldExpr) != ChildRole.LOPERAND &&
opType != JavaTokenType.PLUS &&
opType != JavaTokenType.ASTERISK &&
- opType != JavaTokenType.ANDAND;
+ opType != JavaTokenType.ANDAND &&
+ opType != JavaTokenType.OROR;
}
else if (i == JavaElementType.INSTANCE_OF_EXPRESSION) {
return priority < parentPriority;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
+import com.intellij.psi.impl.file.JavaDirectoryServiceImpl;
import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.openapi.project.Project;
import com.intellij.refactoring.util.RadioUpDownListener;
import com.intellij.refactoring.util.RefactoringUtil;
+import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.Nullable;
}
return false;
}
+
+ @Override
+ public boolean isMoveRedundant(PsiElement source, PsiElement target) {
+ if (target instanceof PsiDirectory && source instanceof PsiClass) {
+ try {
+ JavaDirectoryServiceImpl.checkCreateClassOrInterface((PsiDirectory)target, ((PsiClass)source).getName());
+ }
+ catch (IncorrectOperationException e) {
+ return true;
+ }
+ }
+ return super.isMoveRedundant(source, target);
+ }
}
*/
package com.intellij.refactoring.move.moveFilesOrDirectories;
+import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
+import com.intellij.psi.impl.file.JavaDirectoryServiceImpl;
import com.intellij.refactoring.copy.JavaCopyFilesOrDirectoriesHandler;
import com.intellij.refactoring.move.MoveCallback;
-import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Function;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
public class JavaMoveFilesOrDirectoriesHandler extends MoveFilesOrDirectoriesHandler {
@Override
}
@Override
- public void doMove(Project project, PsiElement[] elements, PsiElement targetContainer, MoveCallback callback) {
- super.doMove(project, elements, targetContainer, callback);
+ public void doMove(final Project project, PsiElement[] elements, PsiElement targetContainer, MoveCallback callback) {
+
+ MoveFilesOrDirectoriesUtil
+ .doMove(project, elements, new PsiElement[]{targetContainer}, callback, new Function<PsiElement[], PsiElement[]>() {
+ @Override
+ public PsiElement[] fun(final PsiElement[] elements) {
+ return new WriteCommandAction<PsiElement[]>(project, "Regrouping ...") {
+ @Override
+ protected void run(Result<PsiElement[]> result) throws Throwable {
+ final List<PsiElement> adjustedElements = new ArrayList<PsiElement>();
+ for (PsiElement element : elements) {
+ if (element instanceof PsiClass) {
+ final PsiFile containingFile = obtainContainingFile(element, elements);
+ if (containingFile != null && !adjustedElements.contains(containingFile)) {
+ adjustedElements.add(containingFile);
+ }
+ }
+ else {
+ adjustedElements.add(element);
+ }
+ }
+ result.setResult(adjustedElements.toArray(new PsiElement[adjustedElements.size()]));
+ }
+ }.execute().getResultObject();
+ }
+ });
+ }
+
+ @Nullable
+ private static PsiFile obtainContainingFile(PsiElement element, PsiElement[] elements) {
+ final PsiClass[] classes = ((PsiClassOwner)element.getParent()).getClasses();
+ final Set<PsiClass> nonMovedClasses = new HashSet<PsiClass>();
+ for (PsiClass aClass : classes) {
+ if (ArrayUtil.find(elements, aClass) < 0) {
+ nonMovedClasses.add(aClass);
+ }
+ }
+ final PsiFile containingFile = element.getContainingFile();
+ if (nonMovedClasses.isEmpty()) {
+ return containingFile;
+ }
+ else {
+ final PsiDirectory containingDirectory = containingFile.getContainingDirectory();
+ if (containingDirectory != null) {
+ try {
+ JavaDirectoryServiceImpl.checkCreateClassOrInterface(containingDirectory, ((PsiClass)element).getName());
+ final PsiElement createdClass = containingDirectory.add(element);
+ element.delete();
+ return createdClass.getContainingFile();
+ }
+ catch (IncorrectOperationException e) {
+ final Iterator<PsiClass> iterator = nonMovedClasses.iterator();
+ final PsiClass nonMovedClass = iterator.next();
+ final PsiElement createdFile = containingDirectory.add(nonMovedClass).getContainingFile();
+ nonMovedClass.delete();
+ while (iterator.hasNext()) {
+ final PsiClass currentClass = iterator.next();
+ createdFile.add(currentClass);
+ currentClass.delete();
+ }
+ return containingFile;
+ }
+ }
+ }
+ return null;
}
}
String newName,
final CollidingVariableVisitor collidingNameVisitor) {
final PsiVariable collidingVariable =
- JavaPsiFacade.getInstance(scope.getProject()).getResolveHelper().resolveReferencedVariable(newName, scope);
+ JavaPsiFacade.getInstance(scope.getProject()).getResolveHelper().resolveAccessibleReferencedVariable(newName, scope);
if (collidingVariable instanceof PsiLocalVariable || collidingVariable instanceof PsiParameter) {
final PsiElement commonParent = PsiTreeUtil.findCommonParent(element, collidingVariable);
if (commonParent != null) {
return;
}
JavaPsiFacade facade = JavaPsiFacade.getInstance(myScope.getProject());
- final PsiVariable oldVariable = facade.getResolveHelper().resolveReferencedVariable(name, myScope);
+ final PsiVariable oldVariable = facade.getResolveHelper().resolveAccessibleReferencedVariable(name, myScope);
myField = oldVariable instanceof PsiField ? (PsiField) oldVariable : null;
if (!(oldVariable instanceof PsiField)) {
myReferenceExpressions = null;
final String fieldName = newField.getName();
final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
final PsiElement element = occurrence.getUserData(ElementToWorkOn.PARENT);
- final PsiVariable psiVariable = facade.getResolveHelper().resolveReferencedVariable(fieldName, element != null ? element : occurrence);
+ final PsiVariable psiVariable = facade.getResolveHelper().resolveAccessibleReferencedVariable(fieldName, element != null ? element : occurrence);
final PsiElementFactory factory = facade.getElementFactory();
if (psiVariable != null && psiVariable.equals(newField)) {
return IntroduceVariableBase.replace(occurrence, factory.createExpressionFromText(fieldName, null), manager.getProject());
index++;
final PsiManager manager = place.getManager();
PsiResolveHelper helper = JavaPsiFacade.getInstance(manager.getProject()).getResolveHelper();
- PsiVariable refVar = helper.resolveReferencedVariable(name, place);
+ PsiVariable refVar = helper.resolveAccessibleReferencedVariable(name, place);
if (refVar != null && !manager.areElementsEquivalent(refVar, fieldToReplace)) continue;
class CancelException extends RuntimeException {
}
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.jsp.JspFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.usageView.UsageInfo;
}
final PsiElement psiElement = ((PsiElementUsage)usage).getElement();
final PsiFile containingFile = psiElement.getContainingFile();
+ PsiFile topLevelFile = InjectedLanguageUtil.getTopLevelFile(containingFile);
- if (!(containingFile instanceof PsiJavaFile) || containingFile instanceof JspFile) {
+ if (!(topLevelFile instanceof PsiJavaFile) || topLevelFile instanceof JspFile) {
return null;
}
- PsiElement containingClass = psiElement;
+ PsiElement containingClass = topLevelFile == containingFile ? psiElement : containingFile.getContext();
do {
containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class, true);
if (containingClass == null || ((PsiClass)containingClass).getQualifiedName() != null) break;
// check whether the element is in the import list
PsiImportList importList = PsiTreeUtil.getParentOfType(psiElement, PsiImportList.class, true);
if (importList != null) {
- final String fileName = getFileNameWithoutExtension(containingFile);
- final PsiClass[] classes = ((PsiJavaFile)containingFile).getClasses();
+ final String fileName = getFileNameWithoutExtension(topLevelFile);
+ final PsiClass[] classes = ((PsiJavaFile)topLevelFile).getClasses();
for (final PsiClass aClass : classes) {
if (fileName.equals(aClass.getName())) {
containingClass = aClass;
return new ClassUsageGroup((PsiClass)containingClass);
}
- final VirtualFile virtualFile = containingFile.getVirtualFile();
+ final VirtualFile virtualFile = topLevelFile.getVirtualFile();
if (virtualFile != null) {
- return new FileGroupingRule.FileUsageGroup(containingFile.getProject(), virtualFile);
+ return new FileGroupingRule.FileUsageGroup(topLevelFile.getProject(), virtualFile);
}
return null;
}
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.psi.*;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.usageView.UsageInfo;
public UsageGroup groupUsage(Usage usage) {
if (!(usage instanceof PsiElementUsage)) return null;
PsiElement psiElement = ((PsiElementUsage)usage).getElement();
- if (psiElement.getContainingFile() instanceof PsiJavaFile) {
- PsiElement containingMethod = psiElement;
+ PsiFile containingFile = psiElement.getContainingFile();
+ PsiFile topLevelFile = InjectedLanguageUtil.getTopLevelFile(containingFile);
+ if (topLevelFile instanceof PsiJavaFile) {
+ PsiElement containingMethod = topLevelFile == containingFile ? psiElement : containingFile.getContext();
do {
containingMethod = PsiTreeUtil.getParentOfType(containingMethod, PsiMethod.class, true);
if (containingMethod == null || ((PsiMethod)containingMethod).getContainingClass().getQualifiedName() != null) break;
--- /dev/null
+import java.io.File;
+
+public class Super {
+ protected <T> T foo() {}
+}
+
+public class Foo extends Super {
+ {
+ bar(this.<File>foo());<caret>
+ }
+
+ void bar(java.io.File s) {}
+}
--- /dev/null
+public class Super {
+ protected <T> T foo() {}
+}
+
+public class Foo extends Super {
+ {
+ bar(fo<caret>)
+ }
+
+ void bar(java.io.File s) {}
+}
--- /dev/null
+import static Bar.BAR;
+import static Bar.FOO;
+
+class Bar {
+ static String FOO;
+ static String BAR;
+}
+
+class Foo {
+
+ Object[] foo() {
+ String a = FOO;
+ String b = BAR;<caret>
+ }
+}
\ No newline at end of file
--- /dev/null
+import static Bar.FOO;
+
+class Bar {
+ static String FOO;
+ static String BAR;
+}
+
+class Foo {
+
+ Object[] foo() {
+ String a = FOO;
+ String b = BA<caret>
+ }
+}
\ No newline at end of file
--- /dev/null
+import static Bar.FOO
+
+class Bar {
+ static String FOO;
+ static String BAR;
+}
+
+class Foo {
+
+ Object[] foo() {
+ String b = FOO;<caret>
+ }
+}
\ No newline at end of file
--- /dev/null
+import static Bar.FOO
+
+class Bar {
+ static String FOO;
+ static String BAR;
+}
+
+class Foo {
+
+ Object[] foo() {
+ String b = FO<caret>
+ }
+}
\ No newline at end of file
}
{
- f(fo<caret>)
+ f(foo<caret>x)
}
}
\ No newline at end of file
--- /dev/null
+// "Create Field For Parameter 'p1'" "true"
+
+class Test{
+ private final String[] myP1;
+
+ void f(String[] p1){
+ myP1 = p1;
+ }
+}
+
--- /dev/null
+// "Create Field For Parameter 'p1'" "true"
+
+class Test{
+ void f(String[] p<caret>1){
+ }
+}
+
--- /dev/null
+class Foo {
+ {
+ new A<>();
+ }
+}
\ No newline at end of file
--- /dev/null
+PsiJavaFile:New15.java
+ PsiImportList
+ <empty list>
+ PsiClass:Foo
+ PsiModifierList:
+ <empty list>
+ PsiKeyword:class('class')
+ PsiWhiteSpace(' ')
+ PsiIdentifier:Foo('Foo')
+ PsiTypeParameterList
+ <empty list>
+ PsiReferenceList
+ <empty list>
+ PsiReferenceList
+ <empty list>
+ PsiWhiteSpace(' ')
+ PsiJavaToken:LBRACE('{')
+ PsiWhiteSpace('\n ')
+ PsiClassInitializer
+ PsiModifierList:
+ <empty list>
+ PsiCodeBlock
+ PsiJavaToken:LBRACE('{')
+ PsiWhiteSpace('\n ')
+ PsiExpressionStatement
+ PsiNewExpression:new A<>()
+ PsiKeyword:new('new')
+ PsiReferenceParameterList
+ <empty list>
+ PsiWhiteSpace(' ')
+ PsiJavaCodeReferenceElement:A<>
+ PsiIdentifier:A('A')
+ PsiReferenceParameterList
+ PsiJavaToken:LT('<')
+ PsiTypeElement:
+ PsiElement(DIAMOND_TYPE)
+ <empty list>
+ PsiJavaToken:GT('>')
+ PsiExpressionList
+ PsiJavaToken:LPARENTH('(')
+ PsiJavaToken:RPARENTH(')')
+ PsiJavaToken:SEMICOLON(';')
+ PsiWhiteSpace('\n ')
+ PsiJavaToken:RBRACE('}')
+ PsiWhiteSpace('\n')
+ PsiJavaToken:RBRACE('}')
\ No newline at end of file
--- /dev/null
+PsiJavaFile:Type7.java
+ PsiTypeElement:Diamond<>
+ PsiJavaCodeReferenceElement:Diamond<>
+ PsiIdentifier:Diamond('Diamond')
+ PsiReferenceParameterList
+ PsiJavaToken:LT('<')
+ PsiTypeElement:
+ PsiElement(DIAMOND_TYPE)
+ <empty list>
+ PsiJavaToken:GT('>')
\ No newline at end of file
--- /dev/null
+package d;
+public class MyClass{}
\ No newline at end of file
--- /dev/null
+package d;
+
+public class MyClass{}
+
+class Second{}
\ No newline at end of file
--- /dev/null
+class Base {
+ private int name = 0;
+}
+
+class Child extends Base {
+ void foo() {
+ int name = 1;
+ }
+}
\ No newline at end of file
--- /dev/null
+class Base {
+ private int name = 0;
+}
+
+class Child extends Base {
+ void foo() {
+ <selection>1</selection>
+ }
+}
\ No newline at end of file
--- /dev/null
+package t;
+
+class MyClass{}
+
+class MyOneMoreClass{}
\ No newline at end of file
--- /dev/null
+package s;
+class MyClass{}
+class MyOneMoreClass{}
\ No newline at end of file
--- /dev/null
+package s;
+
+class MyLocal{}
\ No newline at end of file
--- /dev/null
+package t;
+public class MyClass{}
--- /dev/null
+package s;
+public class MyClass{}
+class MyLocal{}